{"version":3,"sources":["serviceWorker.js","redux/reducers/mapReducer.js","components/search/dropdowns.js","components/search/handleForm.js","components/search/search.js","components/infoModal/modalContent.js","components/infoModal/infoModal.js","components/navbar/navbar.js","components/sidebar/charts.js","components/footer/footer.js","components/sidebar/sidebar.js","components/map/layers.js","components/map/popups.js","components/map/boundaryFilters.js","components/map/map.js","components/printPage/printPage.js","components/crashMapContainer/crashMapContainer.js","App.js","redux/store.js","index.js","components/footer/img/footer-logo.png","components/infoModal/polygon.png","components/footer/img/email.png","components/footer/img/facebook.png","components/footer/img/instagram.png","components/footer/img/linkedin.png","components/footer/img/twitter.png","components/footer/img/youtube.png","components/sidebar/print.png"],"names":["Boolean","window","location","hostname","match","getOptions","method","mode","headers","Content-Type","postOptions","ksiFilter","defaultRange","from","to","urlRoute","URL","href","GET_DATA_FROM_KEYWORD","SET_MAP_CENTER","SET_MAP_BOUNDING","SET_SIDEBAR_HEADER_CONTEXT","GET_BOUNDING_BOX","SET_MAP_FILTER","GET_POLYGON_CRNS","SET_POLYGON_BBOX","SIDEBAR_CRASH_TYPE","SIDEBAR_RANGE","DEFAULT_RANGE","SET_SRC","get_polygon_crns","polyCRNS","type","getDataFromKeyword","boundaryObj","async","geoID","geojson","isKSI","api","undefined","stream","fetch","dispatch","data","get_data_from_keyword","json","error","console","alert","setMapFilter","filter","mapFilter","boundary","hasRange","Object","keys","range","length","filterType","noFilterCondition","tileType","parseInt","id","concat","rangeFilter","set_map_filter","setMapCenter","center","set_map_center","setMapBounding","bounding","set_map_bounding","setSidebarHeaderContext","area","set_sidebar_header_context","getBoundingBox","featureServer","codeType","query","toString","substring","ok","extent","xmin","log","bbox","get_bounding_box","xmax","ymax","ymin","setPolygonBbox","formattedBbox","polygonBbox","set_polygon_bbox","getDefaultRange","default_range","sidebarCrashType","crashType","sidebar_crash_type","sidebarRange","sidebar_range","setSrc","src","set_src","states","Pennsylvania","New Jersey","counties","Bucks","Chester","Delaware","Montgomery","Philadelphia","Gloucester","Camden","Burlington","Mercer","munis","Abington Township","Aldan Borough","Ambler Borough","Aston Township","Atglen Borough","Audubon Borough","Audubon Park Borough","Avondale Borough","Barrington Borough","Bass River Township","Bedminster Township","Bellmawr Borough","Bensalem Township","Berlin Borough","Berlin Township","Bethel Township","Beverly City","Birmingham Township","Bordentown City","Bordentown Township","Bridgeport Borough","Bridgeton Township","Bristol Borough","Bristol Township","Brookhaven Borough","Brooklawn Borough","Bryn Athyn Borough","Buckingham Township","Burlington City","Burlington Township","Caln Township","Camden City","Chadds Ford Township","Chalfont Borough","Charlestown Township","Cheltenham Township","Cherry Hill Township","Chesilhurst Borough","Chester City","Chester Heights Borough","Chester Township","Chesterfield Township","Cinnaminson Township","Clayton Borough","Clementon Borough","Clifton Heights Borough","Coatesville City","Collegeville Borough","Collingdale Borough","Collingswood Borough","Colwyn Borough","Concord Township","Conshohocken Borough","Darby Borough","Darby Township","Delanco Township","Delran Township","Deptford Township","Douglass Township","Downingtown Borough","Doylestown Borough","Doylestown Township","Dublin Borough","Durham Township","East Bradford Township","East Brandywine Township","East Caln Township","East Coventry Township","East Fallowfield Township","East Goshen Township","East Greenville Borough","East Greenwich Township","East Lansdowne Borough","East Marlborough Township","East Nantmeal Township","East Norriton Township","East Nottingham Township","East Pikeland Township","East Rockhill Township","East Vincent Township","East Whiteland Township","East Windsor Township","Eastampton Township","Easttown Township","Eddystone Borough","Edgewater Park Township","Edgmont Township","Elk Township (Chester Co)","Elk Township (Gloucester Co)","Elverson Borough","Evesham Township","Ewing Township","Falls Township","Fieldsboro Borough","Florence Township","Folcroft Borough","Franconia Township","Franklin Township (Chester Co)","Franklin Township (Gloucester Co)","Gibbsboro Borough","Glassboro Borough","Glenolden Borough","Gloucester City","Gloucester Township","Green Lane Borough","Greenwich Township","Haddon Heights Borough","Haddon Township","Haddonfield Borough","Hainesport Township","Hamilton Township","Harrison Township","Hatboro Borough","Hatfield Borough","Hatfield Township","Haverford Township","Haycock Township","Hi-Nella Borough","Highland Township","Hightstown Borough","Hilltown Township","Honey Brook Borough","Honey Brook Township","Hopewell Borough","Hopewell Township","Horsham Township","Hulmeville Borough","Ivyland Borough","Jenkintown Borough","Kennett Square Borough","Kennett Township","Langhorne Borough","Langhorne Manor Borough","Lansdale Borough","Lansdowne Borough","Laurel Springs Borough","Lawnside Borough","Lawrence Township","Limerick Township","Lindenwold Borough","Logan Township","London Britain Township","London Grove Township","Londonderry Township","Lower Chichester Township","Lower Frederick Township","Lower Gwynedd Township","Lower Makefield Township","Lower Merion Township","Lower Moreland Township","Lower Oxford Township","Lower Pottsgrove Township","Lower Providence Township","Lower Salford Township","Lower Southampton Township","Lumberton Township","Magnolia Borough","Malvern Borough","Mansfield Township","Mantua Township","Maple Shade Township","Marcus Hook Borough","Marlborough Township","Marple Township","Medford Lakes Borough","Medford Township","Media Borough","Merchantville Borough","Middletown Township (Bucks Co)","Middletown Township (Delaware Co)","Milford Township","Millbourne Borough","Modena Borough","Monroe Township","Montgomery Township","Moorestown Township","Morrisville Borough","Morton Borough","Mount Ephraim Borough","Mount Holly Township","Mount Laurel Township","Narberth Borough","National Park Borough","Nether Providence Township","New Britain Borough","New Britain Township","New Garden Township","New Hanover Township (Burlington Co)","New Hanover Township (Montgomery Co)","New Hope Borough","New London Township","Newfield Borough","Newlin Township","Newtown Borough","Newtown Township (Bucks Co)","Newtown Township (Delaware Co)","Nockamixon Township","Norristown Borough","North Coventry Township","North Hanover Township","North Wales Borough","Northampton Township","Norwood Borough","Oaklyn Borough","Oxford Borough","Palmyra Borough","Parkesburg Borough","Parkside Borough","Paulsboro Borough","Pemberton Borough","Pemberton Township","Penn Township","Penndel Borough","Pennington Borough","Pennsauken Township","Pennsburg Borough","Pennsbury Township","Perkasie Borough","Perkiomen Township","Phoenixville Borough","Pine Hill Borough","Pine Valley Borough","Pitman Borough","Plumstead Township","Plymouth Township","Pocopson Township","Pottstown Borough","Princeton","Prospect Park Borough","Quakertown Borough","Radnor Township","Red Hill Borough","Richland Township","Richlandtown Borough","Ridley Park Borough","Ridley Township","Riegelsville Borough","Riverside Township","Riverton Borough","Robbinsville Township","Rockledge Borough","Rose Valley Borough","Royersford Borough","Runnemede Borough","Rutledge Borough","Sadsbury Township","Salford Township","Schuylkill Township","Schwenksville Borough","Sellersville Borough","Shamong Township","Sharon Hill Borough","Silverdale Borough","Skippack Township","Solebury Township","Somerdale Borough","Souderton Borough","South Coatesville Borough","South Coventry Township","South Harrison Township","Southampton Township","Spring City Borough","Springfield Township (Bucks Co)","Springfield Township (Burlington Co)","Springfield Township (Delaware Co)","Springfield Township (Montgomery Co)","Stratford Borough","Swarthmore Borough","Swedesboro Borough","Tabernacle Township","Tavistock Borough","Telford Borough (Bucks Co)","Telford Borough (Montgomery Co)","Thornbury Township (Chester Co)","Thornbury Township (Delaware Co)","Tinicum Township (Bucks Co)","Tinicum Township (Delaware Co)","Towamencin Township","Trainer Borough","Trappe Borough","Tredyffrin Township","Trenton City","Trumbauersville Borough","Tullytown Borough","Upland Borough","Upper Chichester Township","Upper Darby Township","Upper Dublin Township","Upper Frederick Township","Upper Gwynedd Township","Upper Hanover Township","Upper Makefield Township","Upper Merion Township","Upper Moreland Township","Upper Oxford Township","Upper Pottsgrove Township","Upper Providence Township (Delaware Co)","Upper Providence Township (Montgomery Co)","Upper Salford Township","Upper Southampton Township","Upper Uwchlan Township","Uwchlan Township","Valley Township","Voorhees Township","Wallace Township","Warminster Township","Warrington Township","Warwick Township (Bucks Co)","Warwick Township (Chester Co)","Washington Township (Burlington Co)","Washington Township (Gloucester Co)","Waterford Township","Wenonah Borough","West Bradford Township","West Brandywine Township","West Caln Township","West Chester Borough","West Conshohocken Borough","West Deptford Township","West Fallowfield Township","West Goshen Township","West Grove Borough","West Marlborough Township","West Nantmeal Township","West Norriton Township","West Nottingham Township","West Pikeland Township","West Pottsgrove Township","West Rockhill Township","West Sadsbury Township","West Vincent Township","West Whiteland Township","West Windsor Township","Westampton Township","Westtown Township","Westville Borough","Whitemarsh Township","Whitpain Township","Willingboro Township","Willistown Township","Winslow Township","Woodbury City","Woodbury Heights Borough","Woodland Township","Woodlynne Borough","Woolwich Township","Worcester Township","Wrightstown Borough","Wrightstown Township","Yardley Borough","Yeadon Borough","philly","North Delaware Philadelphia","Central Philadelphia","Central Northeast Philadelphia","Lower Far Northeast Philadelphia","Lower North Philadelphia","Lower Northeast Philadelphia","Lower Northwest Philadelphia","Lower South Philadelphia","Lower Southwest Philadelphia","North Philadelphia","River Wards Philadelphia","South Philadelphia","University/Southwest Philadelphia","Upper Far Northeast Philadelphia","Upper North Philadelphia","Upper Northwest Philadelphia","West Philadelphia","West Park Philadelphia","geocode","handleSelect","value","sort","a","b","parseSearch","e","preventDefault","output","form","target","FormData","key","input","entries","name","encodeURIComponent","coords","connect","state","getData","boundingObj","Component","constructor","props","super","this","selectSearch","selectedSearch","setState","submitSearch","then","result","features","ksiCheck","sidebarName","dataObj","filterObj","geoParam","encodeURI","route","searchParams","set","history","replaceState","render","React","createElement","className","onSubmit","onChange","map","placeholder","modalContent","about","how","polygon","disclaimer","Modal","arguments","showModal","modal","style","display","justifyContent","alignItems","setAttribute","hideModal","clickModal","keyDownModal","code","handleTabs","selectedTab","split","tabsDiv","parentElement","contentDiv","nextElementSibling","allTabs","children","i","classList","remove","add","firstChild","removeChild","insertAdjacentHTML","componentDidMount","document","onkeydown","componentWillUnmount","removeEventListener","onClick","role","aria-modal","aria-labelledby","ref","el","onKeyDown","rel","Navbar","logo","alt","Search","addLabelCommas","tooltipItem","datasets","datasetIndex","index","toLocaleString","chartOptions","xlabel","ylabel","customPadding","tooltips","callbacks","label","legend","scales","xAxes","scaleLabel","labelString","fontColor","offset","yAxes","ticks","beginAtZero","userCallback","layout","padding","doughnutTooltipOptions","formatData","yearData","forEach","innerObj","innerKeys","innerKey","trend","push","years","labels","formatYears","severity","rawData","prop","backgroundColor","borderWidth","collisionType","yearsFormatted","makeCharts","collisionTypeChart","Non-collision","Rear-end","Head-on","Rear-to-rear (backing)","Angle","Sideswipe (same direction)","Sideswipe (opposite direction)","Hit fixed object","Hit pedestrian","Other or unknown","severityChart","Fatality","Suspected Serious Injury","Suspected Minor Injury","Possible Injury","Not Injured","Unknown Injury","Unknown if Injured","modeChart","Bicyclists","Pedestrians","Vehicle Occupants","trendChart","hasSetRange","year","hasAllYears","Footer","loading","email","facebook","twitter","instagram","linkedin","youtube","context","getCrashData","region","setCrashTypeFilter","setCrashRange","setMapLoading","status","set_map_loading","updateRange","formData","updateCrashType","selected","entry","nameArr","lastWord","pop","isCounty","isPPA","join","get","querySelector","toDataURL","getTotals","totalsObj","crashes","fatalities","severe","peds","bikes","reduce","total","num","compare","obj1","obj2","inner1","inner2","data2","handleRoute","params","allRadio","checked","ksiRadio","mapLoading","filterParams","componentDidUpdate","prevProps","checkOld","message","checkNew","current","areaHeader","toUpperCase","totals","chartsRange","chartHeight","innerWidth","dataFormatted","charts","severityOptions","bottom","trendOptions","doughnutOptions","print","defaultValue","defaultChecked","Line","options","Bar","height","Doughnut","countyOutline","source","source-layer","paint","line-width","line-color","countyFill","maxzoom","fill-color","municipalityOutline","minzoom","municipalityFill","phillyOutline","crashHeat","heatmap-weight","heatmap-intensity","heatmap-radius","heatmap-color","crashCircles","circle-color","circle-radius","circle-stroke-color","circle-stroke-width","getPopupInfo","crn","crash","fail","statusText","response","setPopup","popupInfo","Month","Year","Vehicles","catchPopupFail","createBoundaryHighlight","layer","width","color","removeBoundaryFilter","county","muni","setDefaultState","getPolygonCrashes","removePolyCRNS","resetControl","longitudeOffset","flyTo","zoom","pitch","showBoundaryOverlay","boundaryOverlay","setBoundary","highlight","setPaintProperty","draw","deleteAll","removeBoundary","newFilterType","regionalStats","delete","pathname","hoverGeographyFill","sourceLayer","getZoom","properties","removeFeatureState","setFeatureState","hover","hoveredArea","visibility","textContent","removeGeographyFill","clickGeography","popup","queryRenderedFeatures","point","featureID","geoid","countyName","handleBbox","bboxFormatted","JSON","stringify","coordinates","crs","handlePopup","crnArray","popups","html","crnOutput","setHTML","addTo","nextPopup","previousPopup","node","ReactDOM","findDOMNode","HTMLElement","wrapper","onclick","updateLegend","legendTitle","legendGradient","background","legendLabel","innerHTML","geo","geoParams","decodeURIComponent","MapboxDraw","displayControlsDefault","controls","trash","mapboxgl","accessToken","workerClass","require","default","Map","container","crashMap","preserveDrawingBuffer","navControl","NavigationControl","addControl","on","addSource","url","promoteId","mapLayers","getStyle","layers","firstSymbolId","addLayer","hoveredCircle","max_sever","Popup","closebutton","closeOnClick","setLngLat","lngLat","getCanvas","cursor","geometry","makeNewFilter","prevRange","prevFrom","setFilter","toggleFilter","polygonFilter","speed","curve","top","left","right","fitBounds","aria-label","title","aria-hidden","mapImg","defaultFrom","defaultTo","trendData","trendLabels","severityData","severityLabels","modeData","modeLabels","collisionTypeData","collissionTypeLabels","PrintTemplate","pageStyle","CrashMapContainer","Sidebar","PrintPage","App","createStore","action","assign","applyMiddleware","ReduxThunk","Provider","store","getElementById","navigator","serviceWorker","ready","registration","unregister","module","exports"],"mappings":"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","file":"static/js/main.45efdfb6.chunk.js","sourcesContent":["// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read http://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\nexport function register(config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit http://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl, config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See http://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl, config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl)\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","/**********************/\r\n/****** Helpers ******/ \r\n// Fetch Options\r\nconst getOptions = {\r\n method: 'GET',\r\n mode: 'cors',\r\n headers: {\r\n 'Content-Type': 'application/json; charset=utf-8',\r\n }\r\n}\r\nconst postOptions = {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'\r\n }\r\n}\r\n\r\n// Filters\r\nconst ksiFilter = [\r\n ['>', 'max_sever', -1],\r\n ['<', 'max_sever', 2],\r\n]\r\nconst rangeFilter = (from, to) => {\r\n return [\r\n ['>=', 'year', parseInt(from)],\r\n ['<=', 'year', parseInt(to)]\r\n ]\r\n}\r\n\r\n// default map range\r\nconst defaultRange = {\r\n from: 2018,\r\n to: 2022\r\n}\r\nconst urlRoute = new URL(window.location.href)\r\n\r\n/**********************/\r\n/****** ACTIONS ******/\r\nconst GET_DATA_FROM_KEYWORD = 'GET_DATA_FROM_KEYWORD'\r\nconst SET_MAP_CENTER = 'SET_MAP_CENTER'\r\nconst SET_MAP_BOUNDING = 'SET_MAP_BOUNDING'\r\nconst SET_SIDEBAR_HEADER_CONTEXT = 'SET_SIDEBAR_HEADER_CONTEXT'\r\nconst GET_BOUNDING_BOX = 'GET_BOUNDING_BOX'\r\nconst SET_MAP_FILTER = 'SET_MAP_FILTER'\r\nconst GET_POLYGON_CRNS = 'GET_POLYGON_CRNS'\r\nconst SET_POLYGON_BBOX = 'SET_POLYGON_BBOX'\r\nconst SIDEBAR_CRASH_TYPE = 'SIDEBAR_CRASH_TYPE'\r\nconst SIDEBAR_RANGE = 'SIDEBAR_RANGE'\r\nconst DEFAULT_RANGE = 'DEFAULT_RANGE'\r\nconst SET_SRC = 'SET_SRC'\r\nconst SET_MAP_LOADING = 'SET_MAP_LOADING'\r\n\r\n\r\n/*****************************/\r\n/****** ACTION CREATORS ******/\r\nconst get_data_from_keyword = data => ({ type: GET_DATA_FROM_KEYWORD, data })\r\nconst set_map_center = center => ({ type: SET_MAP_CENTER, center })\r\nconst set_map_bounding = bounding => ({ type: SET_MAP_BOUNDING, bounding })\r\nconst set_sidebar_header_context = area => ( { type: SET_SIDEBAR_HEADER_CONTEXT, area })\r\nconst get_bounding_box = bbox => ({ type: GET_BOUNDING_BOX, bbox })\r\nconst set_map_filter = filter => ({ type: SET_MAP_FILTER, filter })\r\nconst get_polygon_crns = polyCRNS => ({ type: GET_POLYGON_CRNS, polyCRNS })\r\nconst set_polygon_bbox = polygonBbox => ({type: SET_POLYGON_BBOX, polygonBbox })\r\nconst sidebar_crash_type = crashType => ({type: SIDEBAR_CRASH_TYPE, crashType})\r\nconst sidebar_range = range => ({type: SIDEBAR_RANGE, range})\r\nconst default_range = range => ({type: DEFAULT_RANGE, range})\r\nconst set_src = src => ({type: SET_SRC, src})\r\nconst set_map_loading = status => ({type: SET_MAP_LOADING, status })\r\n\r\n\r\n/***********************/\r\n/****** REDUCERS ******/\r\nexport default function mapReducer(state = [], action) {\r\n switch(action.type){\r\n case GET_DATA_FROM_KEYWORD:\r\n const data = action.data\r\n return Object.assign({}, state, { data })\r\n case SET_MAP_CENTER:\r\n const center = action.center\r\n return Object.assign({}, state, { center })\r\n case SET_MAP_BOUNDING:\r\n const bounding = action.bounding\r\n return Object.assign({}, state, { bounding })\r\n case SET_SIDEBAR_HEADER_CONTEXT:\r\n const area = action.area\r\n return Object.assign({}, state, { area })\r\n case GET_BOUNDING_BOX:\r\n const bbox = action.bbox\r\n return Object.assign({}, state, { bbox })\r\n case SET_MAP_FILTER:\r\n const filter = action.filter\r\n return Object.assign({}, state, { filter })\r\n case GET_POLYGON_CRNS:\r\n const polyCRNS = action.polyCRNS\r\n return Object.assign({}, state, { polyCRNS })\r\n case SET_POLYGON_BBOX:\r\n const polygonBbox = action.polygonBbox\r\n return Object.assign({}, state, { polygonBbox })\r\n case SIDEBAR_CRASH_TYPE:\r\n const crashType = action.crashType\r\n return Object.assign({}, state, { crashType })\r\n case SIDEBAR_RANGE:\r\n const range = action.range\r\n return Object.assign({}, state, { range })\r\n case DEFAULT_RANGE:\r\n const defaultRange = action.range\r\n return Object.assign({}, state, { defaultRange })\r\n case SET_SRC:\r\n const src = action.src\r\n return Object.assign({}, state, { src })\r\n default:\r\n return state\r\n }\r\n}\r\n\r\n\r\n/**************************/\r\n/****** DISPATCHERS ******/\r\n/// MAP Dispatchers\r\nexport const getDataFromKeyword = boundaryObj => async dispatch => {\r\n const { geoID, geojson, isKSI } = boundaryObj\r\n \r\n // handle geography & polygon queries \r\n const query = geojson === undefined ? `geoid=${geoID}&ksi_only=${isKSI}` : `geojson=${geojson}&ksi_only=${isKSI}`\r\n const api = `https://cloud.dvrpc.org/api/crash-data/v1/summary?${query}` \r\n\r\n try{\r\n const stream = await fetch(api, getOptions)\r\n const response = await stream.json()\r\n dispatch(get_data_from_keyword(response))\r\n }catch(error) {\r\n console.error(error)\r\n alert(`Sorry! Data could not be fetched at this moment. Please try again later.`)\r\n }\r\n}\r\nexport const setMapFilter = filter => dispatch => {\r\n // handle boundary, crash type and range\r\n let mapFilter = []\r\n const boundary = filter.boundary\r\n const hasRange = Object.keys(filter.range).length\r\n const type = filter.filterType\r\n let noFilterCondition = 0\r\n\r\n // check for boundary\r\n if(boundary) {\r\n const tileType = filter.tileType\r\n const id = parseInt(filter.id)\r\n mapFilter = ['all', ['==', tileType, id]]\r\n }else{\r\n mapFilter = ['all']\r\n noFilterCondition++\r\n }\r\n\r\n // handle range\r\n if(hasRange) {\r\n const {from, to} = filter.range\r\n mapFilter = mapFilter.concat(rangeFilter(from, to))\r\n } else {\r\n noFilterCondition++\r\n }\r\n\r\n // handle crash type\r\n if(type === 'KSI'){\r\n mapFilter = mapFilter.concat(ksiFilter)\r\n }else {\r\n noFilterCondition++\r\n }\r\n\r\n // if no boundary or range and type all, no filter\r\n if(noFilterCondition === 3) mapFilter = 'none'\r\n\r\n dispatch(set_map_filter(mapFilter))\r\n}\r\n\r\nexport const setMapCenter = center => dispatch => dispatch(set_map_center(center))\r\nexport const setMapBounding = bounding => dispatch => dispatch(set_map_bounding(bounding))\r\nexport const setSidebarHeaderContext = area => dispatch => dispatch(set_sidebar_header_context(area))\r\nexport const getBoundingBox = id => async dispatch => {\r\n const philly = id.toString()\r\n let featureServer;\r\n let codeType;\r\n let query;\r\n\r\n // select feature server and code type based on query type\r\n if(philly.substring(0, 6) === '421016') {\r\n // api expects geoid +100 for reasons\r\n id = parseInt(id) + 100\r\n \r\n query = `https://arcgis.dvrpc.org/portal/rest/services/Boundaries/DVRPC_MCD_PhiCPA/FeatureServer/0/query?where=geoid='${id}'&geometryType=esriGeometryEnvelope&outSR=4326&returnExtentOnly=true&f=json`\r\n }else {\r\n if(id.toString().length > 5 ) {\r\n featureServer = 'MunicipalBoundaries'\r\n codeType = `geoid_10='${id}'` \r\n } else {\r\n featureServer = 'CountyBoundaries'\r\n codeType = `FIPS='${id}'`\r\n }\r\n\r\n query = `https://arcgis.dvrpc.org/portal/rest/services/Boundaries/${featureServer}/FeatureServer/0/query?where=${codeType}&geometryType=esriGeometryEnvelope&outSR=4326&returnExtentOnly=true&f=json`\r\n }\r\n\r\n const stream = await fetch(query, postOptions)\r\n \r\n if(stream.ok) {\r\n const response = await stream.json()\r\n const extent = response.extent\r\n \r\n // ESRI returns the same object regardless of success or fail so check for extent AND contents of extent\r\n if (!extent || extent.xmin === \"NaN\") {\r\n console.log('bbox call returned null extent')\r\n alert('Sorry! The automatic pan/zoom feature service is currently unavailable.\\nPlease zoom to your selected geography using either your mouse or the +/- overlays on the map. Thank you.')\r\n return\r\n }\r\n const bbox = [extent.xmax, extent.ymax, extent.xmin, extent.ymin]\r\n\r\n dispatch(get_bounding_box(bbox))\r\n }else {\r\n console.error('esri bbox call failed ', stream)\r\n alert('Sorry! The automatic pan/zoom feature service is currently unavailable.\\nPlease zoom to your selected geography using either your mouse or the +/- overlays on the map. Thank you.')\r\n return\r\n }\r\n}\r\nexport const getPolygonCrashes = bbox => async dispatch => {\r\n try{\r\n const api = `https://cloud.dvrpc.org/api/crash-data/v1/crash-ids?geojson=${bbox}`\r\n const stream = await fetch(api, getOptions)\r\n const response = await stream.json()\r\n dispatch(get_polygon_crns(response))\r\n }catch(error) {\r\n console.error(error)\r\n alert(`Sorry! Data could not be fetched at this moment. Please try again later.`)\r\n }\r\n}\r\nexport const setPolygonBbox = formattedBbox => dispatch => dispatch(set_polygon_bbox(formattedBbox))\r\nexport const removePolyCRNS = () => dispatch => dispatch(get_polygon_crns(null))\r\n\r\n\r\n// SIDEBAR Dispatchers\r\nexport const getDefaultRange = () => dispatch => dispatch(default_range(defaultRange))\r\nexport const sidebarCrashType = type => dispatch => dispatch(sidebar_crash_type(type))\r\nexport const sidebarRange = range => dispatch => dispatch(sidebar_range(range))\r\nexport const setSrc = src => dispatch => dispatch(set_src(src))\r\n\r\n// Map State\r\nexport const setMapLoading = status => dispatch => dispatch(set_map_loading(status))\r\n\r\n// plain exports\r\nexport { defaultRange, urlRoute } // export the obj for layers.js b/c it's not a connected component","const states = {'Pennsylvania': 42,'New Jersey': 34}\r\nconst counties = { 'Bucks':42017,'Chester':42029,'Delaware':42045,'Montgomery':42091,'Philadelphia':42101,'Gloucester':34015,'Camden':34007,'Burlington':34005,'Mercer':34021 }\r\nconst munis = {'Abington Township':4209100156,'Aldan Borough':4204500676,'Ambler Borough':4209102264,'Aston Township':4204503336,'Atglen Borough':4202903384,'Audubon Borough':3400702200,'Audubon Park Borough':3400702230,'Avondale Borough':4202903656,'Barrington Borough':3400703250,'Bass River Township':3400503370,'Bedminster Township':4201704976,'Bellmawr Borough':3400704750,'Bensalem Township':4201705616,'Berlin Borough':3400705440,'Berlin Township':3400705470,'Bethel Township':4204506024,'Beverly City':3400505740,'Birmingham Township':4202906544,'Bordentown City':3400506670,'Bordentown Township':3400506700,'Bridgeport Borough':4209108568,'Bridgeton Township':4201708592,'Bristol Borough':4201708760,'Bristol Township':4201708768,'Brookhaven Borough':4204509080,'Brooklawn Borough':3400708170,'Bryn Athyn Borough':4209109696,'Buckingham Township':4201709816,'Burlington City':3400508920,'Burlington Township':3400508950,'Caln Township':4202910824,'Camden City':3400710000,'Chadds Ford Township':4204512442,'Chalfont Borough':4201712504,'Charlestown Township':4202912744,'Cheltenham Township':4209112968,'Cherry Hill Township':3400712280,'Chesilhurst Borough':3400712550,'Chester City':4204513208,'Chester Heights Borough':4204513232,'Chester Township':4204513212,'Chesterfield Township':3400512670,'Cinnaminson Township':3400512940,'Clayton Borough':3401513360,'Clementon Borough':3400713420,'Clifton Heights Borough':4204514264,'Coatesville City':4202914712,'Collegeville Borough':4209115192,'Collingdale Borough':4204515232,'Collingswood Borough':3400714260,'Colwyn Borough':4204515432,'Concord Township':4204515488,'Conshohocken Borough':4209115848,'Darby Borough':4204518152,'Darby Township':4204518160,'Delanco Township':3400517080,'Delran Township':3400517440,'Deptford Township':3401517710,'Douglass Township':4209119672,'Downingtown Borough':4202919752,'Doylestown Borough':4201719784,'Doylestown Township':4201719792,'Dublin Borough':4201720104,'Durham Township':4201720480,'East Bradford Township':4202920824,'East Brandywine Township':4202920864,'East Caln Township':4202920920,'East Coventry Township':4202921008,'East Fallowfield Township':4202921104,'East Goshen Township':4202921192,'East Greenville Borough':4209121200,'East Greenwich Township':3401519180,'East Lansdowne Borough':4204521384,'East Marlborough Township':4202921480,'East Nantmeal Township':4202921576,'East Norriton Township':4209121600,'East Nottingham Township':4202921624,'East Pikeland Township':4202921696,'East Rockhill Township':4201721760,'East Vincent Township':4202922000,'East Whiteland Township':4202922056,'East Windsor Township':3402119780,'Eastampton Township':3400518790,'Easttown Township':4202921928,'Eddystone Borough':4204522296,'Edgewater Park Township':3400520050,'Edgmont Township':4204522584,'Elk Township (Chester Co)': 4202923032,'Elk Township (Gloucester Co)':3401521060,'Elverson Borough':4202923440,'Evesham Township':3400522110,'Ewing Township':3402122185,'Falls Township':4201725112,'Fieldsboro Borough':3400523250,'Florence Township':3400523850,'Folcroft Borough':4204526408,'Franconia Township':4209127280,'Franklin Township (Chester Co)':4202927376,'Franklin Township (Gloucester Co)': 3401524840,'Gibbsboro Borough':3400726070,'Glassboro Borough':3401526340,'Glenolden Borough':4204529720,'Gloucester City':3400726820,'Gloucester Township':3400726760,'Green Lane Borough':4209131088,'Greenwich Township':3401528185,'Haddon Heights Borough':3400728800,'Haddon Township':3400728740,'Haddonfield Borough':3400728770,'Hainesport Township':3400529010,'Hamilton Township':3402129310,'Harrison Township':3401530180,'Hatboro Borough':4209133088,'Hatfield Borough':4209133112,'Hatfield Township':4209133120,'Haverford Township':4204533144,'Haycock Township':4201733224,'Hi-Nella Borough':3400732220,'Highland Township':4202934448,'Hightstown Borough':3402131620,'Hilltown Township':4201734952,'Honey Brook Borough':4202935528,'Honey Brook Township':4202935536,'Hopewell Borough':3402133150,'Hopewell Township':3402133180,'Horsham Township':4209135808,'Hulmeville Borough':4201736192,'Ivyland Borough':4201737304,'Jenkintown Borough':4209138000,'Kennett Square Borough':4202939352,'Kennett Township':4202939344,'Langhorne Borough':4201741392,'Langhorne Manor Borough':4201741416,'Lansdale Borough':4209141432,'Lansdowne Borough':4204541440,'Laurel Springs Borough':3400739210,'Lawnside Borough':3400739420,'Lawrence Township':3402139510,'Limerick Township':4209143312,'Lindenwold Borough':3400740440,'Logan Township':3401541160,'London Britain Township':4202944440,'London Grove Township':4202944480,'Londonderry Township':4202944456,'Lower Chichester Township':4204544888,'Lower Frederick Township':4209144912,'Lower Gwynedd Township':4209144920,'Lower Makefield Township':4201744968,'Lower Merion Township':4209144976,'Lower Moreland Township':4209145008,'Lower Oxford Township':4202945040,'Lower Pottsgrove Township':4209145072,'Lower Providence Township':4209145080,'Lower Salford Township':4209145096,'Lower Southampton Township':4201745112,'Lumberton Township':3400542060,'Magnolia Borough':3400742630,'Malvern Borough':4202946792,'Mansfield Township':3400543290,'Mantua Township':3401543440,'Maple Shade Township':3400543740,'Marcus Hook Borough':4204547344,'Marlborough Township':4209147592,'Marple Township':4204547616,'Medford Lakes Borough':3400545210,'Medford Township':3400545120,'Media Borough':4204548480,'Merchantville Borough':3400745510,'Middletown Township (Bucks Co)':4201749120,'Middletown Township (Delaware Co)':4204549136,'Milford Township':4201749384,'Millbourne Borough':4204549504,'Modena Borough':4202950232,'Monroe Township':3401547250,'Montgomery Township':4209150640,'Moorestown Township':3400547880,'Morrisville Borough':4201751144,'Morton Borough':4204551176,'Mount Ephraim Borough':3400748750,'Mount Holly Township':3400548900,'Mount Laurel Township':3400549020,'Narberth Borough':4209152664,'National Park Borough':3401549680,'Nether Providence Township':4204553104,'New Britain Borough':4201753296,'New Britain Township':4201753304,'New Garden Township':4202953608,'New Hanover Township (Burlington Co)':3400551510,'New Hanover Township (Montgomery Co)':4209153664,'New Hope Borough':4201753712,'New London Township':4202953816,'Newfield Borough':3401551390,'Newlin Township':4202953784,'Newtown Borough':4201754184,'Newtown Township (Bucks Co)':4201754192,'Newtown Township (Delaware Co)':4204554224,'Nockamixon Township':4201754576,'Norristown Borough':4209154656,'North Coventry Township':4202954936,'North Hanover Township':3400553070,'North Wales Borough':4209155512,'Northampton Township':4201754688,'Norwood Borough':4204555664,'Oaklyn Borough':3400753880,'Oxford Borough':4202957480,'Palmyra Borough':3400555800,'Parkesburg Borough':4202958032,'Parkside Borough':4204558176,'Paulsboro Borough':3401557150,'Pemberton Borough':3400557480,'Pemberton Township':3400557510,'Penn Township':4202958808,'Penndel Borough':4201758936,'Pennington Borough':3402157600,'Pennsauken Township':3400757660,'Pennsburg Borough':4209159120,'Pennsbury Township':4202959136,'Perkasie Borough':4201759384,'Perkiomen Township':4209159392,'Phoenixville Borough':4202960120,'Pine Hill Borough':3400758770,'Pine Valley Borough':3400758920,'Pitman Borough':3401559070,'Plumstead Township':4201761616,'Plymouth Township':4209161664,'Pocopson Township':4202961800,'Pottstown Borough':4209162416,'Princeton':3402160900,'Prospect Park Borough':4204562792,'Quakertown Borough':4201763048,'Radnor Township':4204563264,'Red Hill Borough':4209163808,'Richland Township':4201764536,'Richlandtown Borough':4201764584,'Ridley Park Borough':4204564832,'Ridley Township':4204564800,'Riegelsville Borough':4201764856,'Riverside Township':3400563510,'Riverton Borough':3400563660,'Robbinsville Township':3402163850,'Rockledge Borough':4209165568,'Rose Valley Borough':4204566192,'Royersford Borough':4209166576,'Runnemede Borough':3400765160,'Rutledge Borough':4204566928,'Sadsbury Township':4202967080,'Salford Township':4209167528,'Schuylkill Township':4202968288,'Schwenksville Borough':4209168328,'Sellersville Borough':4201769248,'Shamong Township':3400566810,'Sharon Hill Borough':4204569752,'Silverdale Borough':4201770744,'Skippack Township':4209171016,'Solebury Township':4201771752,'Somerdale Borough':3400768340,'Souderton Borough':4209171856,'South Coatesville Borough':4202972072,'South Coventry Township':4202972088,'South Harrison Township':3401569030,'Southampton Township':3400568610,'Spring City Borough':4202972920,'Springfield Township (Bucks Co)':4201773016,'Springfield Township (Burlington Co)':3400569990,'Springfield Township (Delaware Co)':4204573032,'Springfield Township (Montgomery Co)':4209173088,'Stratford Borough':3400771220,'Swarthmore Borough':4204575648,'Swedesboro Borough':3401571850,'Tabernacle Township':3400572060,'Tavistock Borough':3400772240,'Telford Borough (Bucks Co)':4201776304,'Telford Borough (Montgomery Co)':4209176304,'Thornbury Township (Chester Co)':4202976568,'Thornbury Township (Delaware Co)':4204576576,'Tinicum Township (Bucks Co)':4201776784,'Tinicum Township (Delaware Co)':4204576792,'Towamencin Township':4209177152,'Trainer Borough':4204577288,'Trappe Borough':4209177304,'Tredyffrin Township':4202977344,'Trenton City':3402174000,'Trumbauersville Borough':4201777704,'Tullytown Borough':4201777744,'Upland Borough':4204578712,'Upper Chichester Township':4204578776,'Upper Darby Township':4204579000,'Upper Dublin Township':4209179008,'Upper Frederick Township':4209179040,'Upper Gwynedd Township':4209179056,'Upper Hanover Township':4209179064,'Upper Makefield Township':4201779128,'Upper Merion Township':4209179136,'Upper Moreland Township':4209179176,'Upper Oxford Township':4202979208,'Upper Pottsgrove Township':4209179240,'Upper Providence Township (Delaware Co)':4204579248,'Upper Providence Township (Montgomery Co)':4209179256,'Upper Salford Township':4209179280,'Upper Southampton Township':4201779296,'Upper Uwchlan Township':4202979352,'Uwchlan Township':4202979480,'Valley Township':4202979544,'Voorhees Township':3400776220,'Wallace Township':4202980616,'Warminster Township':4201780952,'Warrington Township':4201781048,'Warwick Township (Bucks Co)':4201781144,'Warwick Township (Chester Co)':4202981160,'Washington Township (Burlington Co)':3400577150,'Washington Township (Gloucester Co)':3401577180,'Waterford Township':3400777630,'Wenonah Borough':3401578110,'West Bradford Township':4202982544,'West Brandywine Township':4202982576,'West Caln Township':4202982664,'West Chester Borough':4202982704,'West Conshohocken Borough':4209182736,'West Deptford Township':3401578800,'West Fallowfield Township':4202982936,'West Goshen Township':4202983080,'West Grove Borough':4202983104,'West Marlborough Township':4202983464,'West Nantmeal Township':4202983664,'West Norriton Township':4209183696,'West Nottingham Township':4202983712,'West Pikeland Township':4202983832,'West Pottsgrove Township':4209183912,'West Rockhill Township':4201783960,'West Sadsbury Township':4202983968,'West Vincent Township':4202984160,'West Whiteland Township':4202984192,'West Windsor Township':3402180240,'Westampton Township':3400578200,'Westtown Township':4202984104,'Westville Borough':3401580120,'Whitemarsh Township':4209184624,'Whitpain Township':4209184888,'Willingboro Township':3400581440,'Willistown Township':4202985352,'Winslow Township':3400781740,'Woodbury City':3401582120,'Woodbury Heights Borough':3401582180,'Woodland Township':3400582420,'Woodlynne Borough':3400782450,'Woolwich Township':3401582840,'Worcester Township':4209186496,'Wrightstown Borough':3400582960,'Wrightstown Township':4201786624,'Yardley Borough':4201786920,'Yeadon Borough':4204586968}\r\nconst philly = {\r\n 'North Delaware Philadelphia':4210160004,'Central Philadelphia':4210160003,'Central Northeast Philadelphia':4210160018,'Lower Far Northeast Philadelphia':4210160016,'Lower North Philadelphia':4210160007,'Lower Northeast Philadelphia':4210160014,'Lower Northwest Philadelphia':4210160008,'Lower South Philadelphia':4210160005,'Lower Southwest Philadelphia':4210160002,'North Philadelphia':4210160001,'River Wards Philadelphia':4210160009,'South Philadelphia':4210160012,'University/Southwest Philadelphia':4210160010,'Upper Far Northeast Philadelphia':4210160013,'Upper North Philadelphia':4210160015,'Upper Northwest Philadelphia':4210160017,'West Philadelphia':4210160011,'West Park Philadelphia':4210160006,\r\n}\r\nexport { munis, counties, states, philly }","import { counties, munis, states, philly } from './dropdowns.js'\r\n\r\n////\r\n// Functions to handle parsed form inputs\r\n////\r\n// runs the mapboxgl geocoder to turn address or boundary into coordinates\r\n// API reference: https://docs.mapbox.com/api/search/#mapboxplaces\r\nconst geocode = async query => {\r\n const token = 'pk.eyJ1IjoibW1vbHRhIiwiYSI6ImNqZDBkMDZhYjJ6YzczNHJ4cno5eTcydnMifQ.RJNJ7s7hBfrJITOBZBdcOA'\r\n const api = `https://api.mapbox.com/geocoding/v5/mapbox.places/${query}.json?access_token=${token}&autocomplete=true&bbox=-76.09405517578125,39.49211914385648,-74.32525634765625,40.614734298694216`\r\n \r\n try {\r\n const stream = await fetch(api)\r\n const result = await stream.json()\r\n \r\n return result\r\n } catch (error) {\r\n console.error(error)\r\n return false\r\n }\r\n}\r\n\r\n\r\n////\r\n// Functions to parse form inputs\r\n////\r\nconst handleSelect = value => {\r\n switch(value){\r\n case 'county':\r\n return Object.keys(counties).sort((a, b) => a + b)\r\n case 'municipality':\r\n return Object.keys(munis).sort((a, b) => a + b)\r\n case 'states':\r\n return states\r\n case 'philly':\r\n return Object.keys(philly).sort((a, b) => a + b)\r\n default:\r\n return false\r\n }\r\n}\r\n\r\n// parse form inputs and figure out what to do with them\r\nconst parseSearch = e => {\r\n e.preventDefault()\r\n\r\n const output = { \r\n type: '',\r\n geoID: '',\r\n isKSI: ''\r\n }\r\n\r\n const form = e.target\r\n const data = new FormData(form)\r\n let query;\r\n \r\n // extract form data\r\n for(var [key, input] of data.entries()) {\r\n switch(key) {\r\n case 'type':\r\n output.type = input\r\n break\r\n case 'boundary':\r\n output.name = input\r\n\r\n switch(output.type){\r\n case 'county':\r\n output.geoID = counties[input]\r\n break\r\n case 'municipality':\r\n output.geoID = munis[input]\r\n break\r\n case 'philly':\r\n output.geoID = philly[input]\r\n break\r\n default:\r\n output.geoID = states[input]\r\n }\r\n \r\n break\r\n default:\r\n query = encodeURIComponent(input)\r\n output.coords = geocode(query)\r\n output.name = input\r\n output.geoID = ''\r\n }\r\n }\r\n\r\n return output\r\n}\r\n\r\nexport { handleSelect, parseSearch }","import React, { Component } from 'react'\r\nimport { connect } from 'react-redux'\r\n\r\nimport { getDataFromKeyword, setMapCenter, setMapBounding, setSidebarHeaderContext, getBoundingBox, urlRoute, defaultRange } from '../../redux/reducers/mapReducer.js'\r\nimport * as form from './handleForm.js'\r\n\r\nimport './search.css'\r\n\r\nclass Search extends Component {\r\n constructor(props){\r\n super(props)\r\n\r\n this.state = {\r\n selectedSearch: ['Bucks','Chester','Delaware','Montgomery','Philadelphia','Gloucester','Camden','Burlington','Mercer'],\r\n route: urlRoute\r\n }\r\n }\r\n \r\n selectSearch = e => {\r\n const value = e.target.value\r\n const selectedSearch = form.handleSelect(value)\r\n\r\n this.setState({selectedSearch})\r\n }\r\n\r\n submitSearch = e => {\r\n const output = form.parseSearch(e)\r\n\r\n // zoom to area for address searches & exit\r\n if(output.coords) {\r\n output.coords.then(result => {\r\n const center = result.features[0].center\r\n this.props.setMapCenter(center)\r\n })\r\n return\r\n }\r\n\r\n // get KSI and range state from store\r\n const range = this.props.range || defaultRange\r\n const ksiCheck = this.props.crashType || 'KSI'\r\n output.isKSI = ksiCheck === 'KSI' ? 'yes' : 'no'\r\n\r\n // handle PPA being munis but not munis\r\n const tileType = output.type[0] === 'p' ? 'm' : output.type[0]\r\n let sidebarName;\r\n \r\n if(tileType === 'c') sidebarName = `${output.name} County`\r\n else sidebarName = output.name\r\n\r\n // create data, filter and boundary objects\r\n const dataObj = { geoID: output.geoID, isKSI: output.isKSI }\r\n const filterObj = {filterType: ksiCheck, tileType, id: output.geoID, range, boundary: true}\r\n const boundaryObj = { type: output.type, id: output.geoID, filter: filterObj }\r\n \r\n // dispatch actions to: set sidebar header, fetch the data and create a bounding box for the selected area\r\n this.props.setSidebarHeaderContext(sidebarName)\r\n this.props.getData(dataObj)\r\n this.props.setMapBounding(boundaryObj)\r\n this.props.getBoundingBox(output.geoID)\r\n\r\n // update URL\r\n const geoParam = `${output.geoID},${output.type},${encodeURI(output.name)}`\r\n \r\n this.state.route.searchParams.set('geom', geoParam)\r\n this.state.route.searchParams.set('filter', ksiCheck)\r\n \r\n window.history.replaceState(null, null, `?geom=${geoParam}&filter=${ksiCheck}`)\r\n }\r\n\r\n render() {\r\n const selectedSearch = this.state.selectedSearch\r\n\r\n return (\r\n
\r\n
\r\n \r\n
\r\n {selectedSearch ? (\r\n
\r\n \r\n
\r\n ) : (\r\n
\r\n \r\n
\r\n )\r\n }\r\n \r\n
\r\n )\r\n }\r\n}\r\n\r\nconst mapStateToProps = state => {\r\n return {\r\n crashType: state.crashType,\r\n range: state.range\r\n }\r\n}\r\n\r\nconst mapDispatchToProps = dispatch => {\r\n return {\r\n getData: boundaryObj => dispatch(getDataFromKeyword(boundaryObj)),\r\n setMapCenter: coords => dispatch(setMapCenter(coords)),\r\n setMapBounding: boundingObj => dispatch(setMapBounding(boundingObj)),\r\n setSidebarHeaderContext: area => dispatch(setSidebarHeaderContext(area)),\r\n getBoundingBox: id => dispatch(getBoundingBox(id))\r\n }\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Search);","import polygon from './polygon.png'\r\n\r\nexport const modalContent = {\r\n about: `\r\n

In transportation planning, crash data is a vital resource for identifying crash trends and needed safety improvements. DVRPC is consistent with state and local partners by employing a Vision Zero approach to crash data analysis: no loss of life in our region's roadways is acceptable. Roadway owners and policymakers should focus on preventing crashes that result in fatalities or serious injuries - the most severe crashes on the road.

\r\n Injury severity from crashes is divided into seven possible categories:\r\n
    \r\n
  1. Fatality Fatalities stemming from crashes may occur up to 30 days following the crash for the injury to be coded as fatal.
  2. \r\n
  3. Suspected Serious Injury The responding police officer suspects that the person sustained a serious, often incapacitating, injury.
  4. \r\n
  5. Suspected Minor Injury The responding police officer suspects that the person sustained an injury less sever than a serious injury, and the injury is \"evident\".
  6. \r\n
  7. Possible Injury The responding police officer suspects that the person sustained an injury of low severity, sometimes a \"complaint of pain,\" and the injury is not readily evident.
  8. \r\n
  9. \r\n
    \r\n Not Injured The responding police officer does not suspect that the person was injuried.\r\n
      \r\n
    • In Pennsylvania, if no one was injured than at least one vehicle must require a tow from the scene of the crash for that crash to be considered \"reportable.\"
    • \r\n
    • In New Jersey a crash is \"reportable\" if any one person involved is injured, or if there is damage to property of $500 or more.
    • \r\n
    \r\n
    \r\n
  10. \r\n
  11. Unknown Injury An injury is suspected but the severity of the injury is unknown.
  12. \r\n
  13. Unknown if Injured Data is unavailable regarding whether the person was injured.
  14. \r\n
\r\n

Following FHWA guidance, in 2016 most counties in Pennsylvania (except Philadelphia) adopted the term \"Suspected Serious Injury\" in place of \"Major Injury,\" \"Suspected Minor Injury\" in place of \"Moderate Injury,\" and \"Possible Injury\" in place of \"Minor Injury”. Philadelphia and DVRPC’s New Jersey counties adopted these changes in 2019. Although these new terms did not result in a significant change in the definition of these injury types, it did redistribute the crashes within injury categories resulting in an increase in crashes labeled \"Suspected Serious Injury\" and corresponding decreases in injuries labeled as lesser severity. More information on FHWA’s guidance can be found here and here (see P.5 Injury Status on page 34).

\r\n

Raw crash data tables for this tool were downloaded from the PennDOT Crash Download Map and the NJDOT Crash Tables webpage, for Pennsylvania and New Jersey data, respectively.

\r\n
\r\n

Contact: Kevin Murphy kmurphy@dvrpc.org

\r\n `,\r\n how: `\r\n \r\n `,\r\n disclaimer: `\r\n

This web page is a public resource of general information. The Delaware Valley Regional Planning Commission (DVRPC) makes no warranty, representation, or guarantee as to the content, sequence, accuracy, timeliness, or completeness of any of the spatial data or database information provided herein. DVRPC and partner state, local, and other agencies shall assume no liability for errors, omissions, or inaccuracies in the information provided regardless of how caused; or any decision made or action taken or not taken by any person relying on any information or data furnished within.

\r\n `\r\n }","import React, { Component } from 'react';\r\n\r\nimport { modalContent } from './modalContent.js'\r\nimport './infoModal.css';\r\n\r\nclass Modal extends Component {\r\n componentDidMount() {\r\n document.onkeydown = e => this.keyDownModal(e)\r\n }\r\n\r\n componentWillUnmount() {\r\n document.removeEventListener('keydown', this.keyDownModal, false)\r\n }\r\n\r\n showModal = () => {\r\n this.modal.style.display = 'flex'\r\n this.modal.style.justifyContent = 'center'\r\n this.modal.style.alignItems = 'center'\r\n this.modal.setAttribute('aria-hidden', 'false')\r\n }\r\n\r\n hideModal = () => {\r\n this.modal.style.display = 'none'\r\n this.modal.setAttribute('aria-hidden', 'true')\r\n }\r\n\r\n clickModal = e => {\r\n if (e.target === this.modal) this.hideModal()\r\n }\r\n\r\n keyDownModal = e => {\r\n if( e.code === 'Escape' && this.modal.style.display === 'flex') this.hideModal()\r\n }\r\n\r\n handleTabs = e => {\r\n const target = e.target\r\n const selectedTab = target.id.split('-')[1]\r\n const tabsDiv = target.parentElement\r\n const contentDiv = tabsDiv.nextElementSibling\r\n const allTabs = tabsDiv.children\r\n const length = allTabs.length\r\n \r\n // reset all tabs to default\r\n for(var i=0; i\r\n \r\n \r\n
this.modal = el} onClick={this.clickModal} onKeyDown={this.keyDownModal}>\r\n \r\n
\r\n \r\n

DVRPC Crash Data Viewer

\r\n\r\n
\r\n

About

\r\n

How To

\r\n

Disclaimer

\r\n
\r\n\r\n
\r\n

In transportation planning, crash data is a vital resource for identifying crash trends and needed safety improvements. DVRPC is consistent with state and local partners by employing a Vision Zero approach to crash data analysis: no loss of life in our region's roadways is acceptable. Roadway owners and policymakers should focus on preventing crashes that result in fatalities or serious injuries - the most severe crashes on the road.

\r\n \r\n Injury severity from crashes is divided into seven possible categories:\r\n \r\n
    \r\n
  1. Fatality Fatalities stemming from crashes may occur up to 30 days following the crash for the injury to be coded as fatal.
  2. \r\n
  3. Suspected Serious Injury The responding police officer suspects that the person sustained a serious, often incapacitating, injury.
  4. \r\n
  5. Suspected Minor Injury The responding police officer suspects that the person sustained an injury less sever than a serious injury, and the injury is \"evident\".
  6. \r\n
  7. Possible Injury The responding police officer suspects that the person sustained an injury of low severity, sometimes a \"complaint of pain,\" and the injury is not readily evident.
  8. \r\n
  9. \r\n
    \r\n Not Injured The responding police officer does not suspect that the person was injuried.\r\n
      \r\n
    • In Pennsylvania, if no one was injured than at least one vehicle must require a tow from the scene of the crash for that crash to be considered \"reportable.\"
    • \r\n
    • In New Jersey a crash is \"reportable\" if any one person involved is injured, or if there is damage to property of $500 or more.
    • \r\n
    \r\n
    \r\n
  10. \r\n
  11. Unknown Injury An injury is suspected but the severity of the injury is unknown.
  12. \r\n
  13. Unknown if Injured Data is unavailable regarding whether the person was injured.
  14. \r\n
\r\n \r\n

Following FHWA guidance, in 2016 most counties in Pennsylvania (except Philadelphia) adopted the term \"Suspected Serious Injury\" in place of \"Major Injury,\" \"Suspected Minor Injury\" in place of \"Moderate Injury,\" and \"Possible Injury\" in place of \"Minor Injury”. Philadelphia and DVRPC’s New Jersey counties adopted these changes in 2019. Although these new terms did not result in a significant change in the definition of these injury types, it did redistribute the crashes within injury categories resulting in an increase in crashes labeled \"Suspected Serious Injury\" and corresponding decreases in injuries labeled as lesser severity. More information on FHWA’s guidance can be found here and here (see P.5 Injury Status on page 34).

\r\n

Raw crash data tables for this tool were downloaded from the PennDOT Crash Download Map and the NJDOT Crash Tables webpage, for Pennsylvania and New Jersey data, respectively. The DVRPC Crash Data Viewer is updated annually when all crash data is available for the region; more recent crash data may be available for a particular state at the linked DOT websites.

\r\n \r\n
\r\n \r\n

Contact: Kevin Murphy kmurphy@dvrpc.org

\r\n
\r\n
\r\n
\r\n \r\n )\r\n }\r\n}\r\n\r\nexport default Modal","import React, { Component } from 'react';\r\n\r\nimport logo from '../footer/img/footer-logo.png'\r\n\r\nimport Search from '../search/search.js';\r\nimport Modal from '../infoModal/infoModal.js';\r\nimport './navbar.css';\r\n\r\nclass Navbar extends Component {\r\n render() {\r\n return (\r\n \r\n );\r\n }\r\n}\r\n\r\nexport default Navbar;\r\n","////\r\n// Functions to process chart data\r\n////\r\n// General chart options\r\nconst addLabelCommas = (tooltipItem, data) => data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].toLocaleString()\r\n\r\nconst chartOptions = (xlabel, ylabel, customPadding) =>{\r\n return {\r\n tooltips: {\r\n callbacks: {\r\n label: (tooltipItem, data) => addLabelCommas(tooltipItem, data)\r\n }\r\n },\r\n legend: {\r\n display: false\r\n },\r\n scales: {\r\n xAxes: [{\r\n scaleLabel: {\r\n display: true,\r\n labelString: xlabel,\r\n fontColor: '#0a0908'\r\n },\r\n offset: true\r\n }],\r\n yAxes: [{\r\n scaleLabel: {\r\n display: true,\r\n labelString: ylabel,\r\n fontColor: '#0a0908'\r\n },\r\n ticks: {\r\n beginAtZero: true,\r\n userCallback: value => value.toLocaleString()\r\n }\r\n }]\r\n },\r\n layout: {\r\n padding: customPadding\r\n }\r\n }\r\n}\r\nconst doughnutTooltipOptions = () => {\r\n return {\r\n tooltips: {\r\n callbacks: {\r\n label: (tooltipItem, data) => addLabelCommas(tooltipItem, data)\r\n }\r\n }\r\n }\r\n}\r\n\r\n// transform db response into a format the charting functions can consume\r\nconst formatData = (yearData, output) => {\r\n Object.keys(yearData).forEach(key => {\r\n const innerObj = yearData[key]\r\n\r\n if(!innerObj) return // escape empty years\r\n \r\n const innerKeys = Object.keys(innerObj)\r\n\r\n // extract data from years into correct locations\r\n if(innerKeys.length){\r\n innerKeys.forEach(innerKey => {\r\n output[key][innerKey] = output[key][innerKey] ? innerObj[innerKey] + output[key][innerKey] : innerObj[innerKey]\r\n })\r\n }else {\r\n output.trend.push(innerObj)\r\n }\r\n })\r\n}\r\n\r\n// make the charts\r\nconst trend = (data, years) => {\r\n years = formatYears(years)\r\n\r\n return {\r\n labels: years,\r\n datasets: [{\r\n data\r\n }]\r\n }\r\n}\r\n\r\nconst severity = rawData => {\r\n let labels = []\r\n let data = []\r\n\r\n for(const prop in rawData) {\r\n labels.push(prop)\r\n data.push(rawData[prop])\r\n }\r\n\r\n return {\r\n labels,\r\n datasets: [{\r\n data,\r\n backgroundColor: ['#c12433','#e67e88','#e6887e','#93c7db','#4ba3c3','#cacaca', '#e3e3e3']\r\n }]\r\n }\r\n}\r\n\r\nconst mode = rawData => {\r\n let labels = []\r\n let data = []\r\n\r\n for(const prop in rawData) {\r\n labels.push(prop)\r\n data.push(rawData[prop])\r\n }\r\n\r\n return {\r\n labels,\r\n datasets: [{\r\n data,\r\n backgroundColor: ['#6457a6', '#DB7C26','#c6e0ff'],\r\n borderWidth: 0\r\n }]\r\n }\r\n}\r\n\r\nconst collisionType = rawData => {\r\n let labels = []\r\n let data = []\r\n\r\n for(const prop in rawData) {\r\n labels.push(prop)\r\n data.push(rawData[prop])\r\n }\r\n\r\n return {\r\n labels,\r\n datasets: [{\r\n data,\r\n backgroundColor: ['#8dd3c7','#FFEC81','#bebada','#fb8072','#80b1d3','#fdb462','#b3de69','#fccde5','#d9d9d9', '#bc80bd'],\r\n borderWidth: 0\r\n }]\r\n }\r\n}\r\n\r\n// default call that formats all available years of data\r\nconst hasAllYears = (data, output) => {\r\n for(var year in data){\r\n const yearData = data[year]\r\n formatData(yearData, output)\r\n }\r\n\r\n return output\r\n}\r\n// accepts a custom range and formats specified years of data into a format that can be consuemd by chart functions\r\nconst hasSetRange = (data, range, output) => {\r\n for(var year in data){\r\n if(year >= range.from && year <= range.to){\r\n const yearData = data[year]\r\n formatData(yearData, output)\r\n }\r\n }\r\n\r\n return output\r\n}\r\n// Crashes over Time chart data\r\nconst formatYears = years => {\r\n let yearsFormatted = []\r\n\r\n if(years) {\r\n let {from, to} = years\r\n to = parseInt(to) + 1\r\n\r\n for(var i = from; i < to; i++) {\r\n yearsFormatted.push(i)\r\n }\r\n\r\n }else{\r\n yearsFormatted = [2014,2015,2016,2017,2018,2019,2020,2021,2022]\r\n }\r\n\r\n return yearsFormatted\r\n}\r\n\r\n\r\n////\r\n// Functions to build the charts\r\n////\r\n// initialize empty charts\r\nconst makePlaceholders = () => {\r\n const collisionTypeChart = collisionType({'Non-collision':0, 'Rear-end':0, 'Head-on':0, 'Rear-to-rear (backing)':0, 'Angle':0, 'Sideswipe (same direction)':0, 'Sideswipe (opposite direction)':0, 'Hit fixed object':0, 'Hit pedestrian':0, 'Other or unknown':0})\r\n const severityChart = severity({'Fatality':0,'Suspected Serious Injury':0,'Suspected Minor Injury':0,'Possible Injury':0,'Not Injured':0,'Unknown Injury':0,'Unknown if Injured':0})\r\n const modeChart = mode({Bicyclists: 0,Pedestrians: 0,'Vehicle Occupants':0})\r\n const trendChart = trend([0,0,0,0,0,0],null)\r\n \r\n return { collisionTypeChart, severityChart, modeChart, trendChart }\r\n}\r\n// using the API response to build the actual charts\r\nconst makeCharts = (data, range) => {\r\n if(!data) return makePlaceholders()\r\n\r\n let severityChart, modeChart, collisionTypeChart, trendChart;\r\n let output = {\r\n mode: {},\r\n severity: {},\r\n type: {},\r\n trend: []\r\n }\r\n\r\n // determine whether to build chart data for all years or a specified range of years\r\n range ? output = hasSetRange(data, range, output) : output = hasAllYears(data, output)\r\n severityChart = severity(output.severity)\r\n modeChart = mode(output.mode)\r\n collisionTypeChart = collisionType(output.type)\r\n trendChart = trend(output.trend, range)\r\n\r\n return { severityChart, modeChart, collisionTypeChart, trendChart }\r\n}\r\n\r\nexport { makeCharts, makePlaceholders, chartOptions, doughnutTooltipOptions }","import React, { Component } from 'react';\r\nimport \"./footer.css\";\r\n\r\n// imgs\r\nimport email from './img/email.png'\r\nimport facebook from './img/facebook.png'\r\nimport logo from './img/footer-logo.png'\r\nimport instagram from './img/instagram.png'\r\nimport linkedin from './img/linkedin.png'\r\nimport twitter from './img/twitter.png'\r\nimport youtube from './img/youtube.png'\r\n\r\nclass Footer extends Component {\r\n render() {\r\n return (\r\n \r\n );\r\n }\r\n}\r\n\r\nexport default Footer;\r\n","import React, { Component } from 'react';\r\nimport { connect } from 'react-redux'\r\nimport { Bar, Doughnut, Line } from 'react-chartjs-2';\r\n\r\nimport { counties, munis, philly } from '../search/dropdowns'\r\nimport * as charts from './charts.js'\r\nimport Footer from '../footer/footer.js'\r\nimport print from './print.png'\r\nimport { getDataFromKeyword, sidebarCrashType, sidebarRange, setSrc, setMapLoading, urlRoute, defaultRange } from '../../redux/reducers/mapReducer.js'\r\n\r\nimport './sidebar.css';\r\n\r\n\r\nclass Sidebar extends Component {\r\n constructor(props) {\r\n super(props)\r\n\r\n this.state = {\r\n data: 'default',\r\n context: 'the DVRPC region',\r\n crashType: 'KSI',\r\n from: defaultRange.from,\r\n to: defaultRange.to,\r\n loading: this.props.mapLoading,\r\n route: urlRoute\r\n }\r\n\r\n this.props.getCrashData({ geoID: '', isKSI: 'yes' })\r\n }\r\n\r\n updateRange = e => {\r\n e.preventDefault()\r\n\r\n let range = { from: 0, to: 0 }\r\n const form = e.target\r\n const formData = new FormData(form)\r\n\r\n //get the inputs from the dropdowns\r\n for (var [key, input] of formData.entries()) {\r\n if (key === 'from') {\r\n range.from = input\r\n } else {\r\n range.to = input\r\n }\r\n }\r\n\r\n // update store state\r\n this.props.setCrashRange(range)\r\n\r\n // setState to update data & trigger a re-render\r\n this.setState({\r\n from: range.from,\r\n to: range.to\r\n })\r\n }\r\n\r\n updateCrashType = e => {\r\n e.preventDefault()\r\n\r\n const form = e.target\r\n const data = new FormData(form)\r\n let selected;\r\n\r\n // extract data\r\n for (const entry of data) {\r\n selected = entry[1]\r\n }\r\n\r\n // use selected radio button to set map filter\r\n this.props.setCrashTypeFilter(selected)\r\n\r\n // update data and set crashType state\r\n if (selected !== this.state.crashType) {\r\n\r\n let context = this.props.context || this.state.context\r\n let isKSI = selected === 'KSI' ? 'yes' : 'no'\r\n\r\n // return special case for regional stats\r\n if (context === 'the DVRPC region') {\r\n this.setState({ crashType: selected, data: 'calc' })\r\n this.props.getCrashData({ geoID: '', isKSI })\r\n return\r\n }\r\n\r\n // handle Philly being both a county and muni\r\n if (context === 'Philadelphia City') context = 'Philadelphia County'\r\n\r\n let nameArr = context.split(' ')\r\n const lastWord = nameArr.pop()\r\n let isCounty = lastWord === 'County' ? true : false\r\n let isPPA = lastWord === 'Philadelphia' ? true : false\r\n nameArr = nameArr.join(' ')\r\n\r\n let geoID;\r\n let geojson;\r\n const bbox = this.props.polygonBbox\r\n\r\n // assign values to geoId and geojson\r\n if (isCounty) geoID = counties[nameArr]\r\n else if (isPPA) geoID = philly[nameArr + ' Philadelphia']\r\n else geoID = munis[context]\r\n\r\n geojson = bbox\r\n\r\n // update data and local state\r\n this.setState({ crashType: selected, data: 'calc' })\r\n this.props.getCrashData({ geoID, geojson, isKSI })\r\n\r\n // ignore polygons when updating URL\r\n if(!geojson) {\r\n this.state.route.searchParams.set('filter', selected)\r\n const geoParam = this.state.route.searchParams.get('geom')\r\n \r\n window.history.replaceState(null, null, `?geom=${geoParam}&filter=${selected}`)\r\n }\r\n }\r\n }\r\n\r\n setSrc = () => {\r\n const mapCanvas = document.querySelector('.mapboxgl-canvas')\r\n const src = mapCanvas.toDataURL()\r\n this.props.setSrc(src)\r\n }\r\n\r\n getTotals = data => {\r\n // default response\r\n let totalsObj = { crashes: 'calculating...', fatalities: 'calculating...', severe: 'calculating...', peds: 'calculating...', bikes: 'calculating...' }\r\n\r\n // formatted results response\r\n if (data === 'empty') {\r\n totalsObj = { crashes: 0, fatalities: 0, severe: 0, peds: 0, bikes: 0 }\r\n }\r\n else if (data && data.crashes.length) {\r\n totalsObj.crashes = data.crashes.reduce((total, num) => total + num).toLocaleString()\r\n totalsObj.fatalities = data.severity[0].toLocaleString()\r\n totalsObj.severe = data.severity[1].toLocaleString()\r\n totalsObj.peds = data.mode[1].toLocaleString()\r\n totalsObj.bikes = data.mode[0].toLocaleString()\r\n }\r\n\r\n return totalsObj\r\n }\r\n\r\n // shallow compare the first layer of objects. expects a nested object\r\n compare = (obj1, obj2) => {\r\n for (var data in obj1) {\r\n const inner1 = obj1[data]\r\n const inner2 = obj2[data]\r\n\r\n for (var data2 in inner1) {\r\n if (inner1[data2] !== inner2[data2]) return false\r\n break\r\n }\r\n }\r\n\r\n return true\r\n }\r\n\r\n // update dynamic text + form state\r\n handleRoute = params => {\r\n this.setState({ crashType: params })\r\n\r\n if(params === 'All') this.allRadio.checked = true\r\n else this.ksiRadio.checked = true\r\n }\r\n\r\n componentDidMount() {\r\n // listen for routing on load\r\n const filterParams = this.state.route.searchParams.get('filter')\r\n if(filterParams) this.handleRoute(filterParams)\r\n }\r\n\r\n componentDidUpdate(prevProps) {\r\n let checkOld = prevProps.data && prevProps.data.message ? false : prevProps.data\r\n\r\n // @REMINDER: this is a workaround to the API handling all 0's as a null response instead of a possible outcome\r\n // 'empty' state is to differentiate between no response (intial render) and empty response (no crashes in selected area)\r\n let checkNew = this.props.data && this.props.data.message ? false : this.props.data\r\n const current = this.state.data\r\n\r\n // handle default state\r\n if (checkNew && current === 'default') this.setState({ data: this.props.data })\r\n // handle updated state\r\n else if (checkNew) {\r\n let areEqual = checkOld ? this.compare(checkNew, checkOld) : false\r\n if (!areEqual) this.setState({ data: this.props.data })\r\n }\r\n // handle all 0 crash response\r\n else if (!checkNew && current !== 'empty') {\r\n this.setState({ data: 'empty' })\r\n }\r\n }\r\n\r\n render() {\r\n // set dynamic text\r\n let area = this.props.context || this.state.context\r\n const areaHeader = area.toUpperCase()\r\n let crashType = this.state.crashType\r\n let from = this.state.from\r\n let to = this.state.to\r\n let chartsRange = { from, to }\r\n let data = this.state.data;\r\n let totals;\r\n let chartHeight = window.innerWidth > 800 ? 200 : 187.5\r\n\r\n // populate chart data\r\n if (data && data !== 'empty') {\r\n data = charts.makeCharts(data, chartsRange)\r\n const dataFormatted = { crashes: data.trendChart.datasets[0].data, severity: data.severityChart.datasets[0].data, mode: data.modeChart.datasets[0].data }\r\n totals = this.getTotals(dataFormatted)\r\n\r\n } else {\r\n // handle undefined data (nonexistant or all 0 response both get lumped into here)\r\n totals = data === 'empty' ? this.getTotals(data) : this.getTotals()\r\n data = charts.makeCharts(null, chartsRange)\r\n }\r\n\r\n const severityOptions = charts.chartOptions('Injury type', 'Number of persons', { bottom: 15 })\r\n const trendOptions = charts.chartOptions('', 'Number of Crashes')\r\n const doughnutOptions = charts.doughnutTooltipOptions()\r\n\r\n return (\r\n
\r\n
\r\n\r\n
\r\n
\r\n

Crash StatisticsFOR {areaHeader}

\r\n
\r\n
\r\n\r\n \"print print statistics\r\n\r\n

This tool's default setting is limited to five years of killed and severe injury crashes (abbreviated as \"KSI\") for {defaultRange.from} to {defaultRange.to}. Five years of data is typically used by local, state, and federal partners in safety analyses.

\r\n

The following charts and map are showing results for {crashType} crash types from {from} to {to} in {area}. You can adjust the range and severity type using the forms below:

\r\n\r\n
\r\n
\r\n Select Date Range: \r\n\r\n
\r\n
\r\n \r\n\r\n \r\n
\r\n\r\n \r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n Select Severity Type: \r\n\r\n
\r\n
\r\n \r\n\r\n \r\n
\r\n\r\n \r\n
\r\n
\r\n
\r\n\r\n
\r\n\r\n

Totals

\r\n
    \r\n
  • Crashes {totals.crashes}
  • \r\n
  • Fatalities{totals.fatalities}
  • \r\n
  • Suspected Serious Injuries {totals.severe}
  • \r\n
  • Pedestrians Involved {totals.peds}
  • \r\n
  • Bicyclists Involved {totals.bikes}
  • \r\n
\r\n\r\n
\r\n

Crashes Over Time

\r\n\r\n \r\n\r\n
\r\n

This chart shows {crashType} crashes in {area} by crash severity from {from} to {to}. Crash trends can be useful for identifying if the frequency of crashes is increasing or decreasing over time, but it is important not to infer patterns from single-year spikes or drops in crashes or in datasets with limited data points.

\r\n
\r\n
\r\n\r\n
\r\n

Injury Severity

\r\n\r\n \r\n\r\n
\r\n

This chart shows people involved in {crashType} crashes in {area} by crash severity from {from} to {to}. Injury severity is divided into seven possible categories, as defined in the \"about\" section of the information modal. You can access it by clicking on \"about\" next to the DVRPC logo on the navbar.

\r\n
\r\n
\r\n\r\n
\r\n

Mode

\r\n\r\n \r\n\r\n
\r\n

This chart shows people involved in {crashType} crashes in {area} by mode from {from} to {to}. Pedestrians and bicyclists are often a focus of transportation safety planning efforts because they are the road users most vulnerable to severe injuries in the event of a crash. This is reflected in data that consistently shows pedestrians account for a disproportionate number of the injuries sustained on the road.

\r\n
\r\n
\r\n\r\n
\r\n

Collision Type

\r\n\r\n \r\n\r\n
\r\n

This chart shows {crashType} crashes in {area} by collision type from {from} to {to}. Collision type data can be especially useful for identifying trends at specific locations or along specific routes.

\r\n
\r\n
\r\n\r\n
\r\n
\r\n
\r\n );\r\n }\r\n}\r\n\r\nconst mapStateToProps = state => {\r\n return {\r\n data: state.data,\r\n context: state.area,\r\n polygonBbox: state.polygonBbox\r\n }\r\n}\r\n\r\nconst mapDispatchToProps = dispatch => {\r\n return {\r\n getCrashData: region => dispatch(getDataFromKeyword(region)),\r\n // getDefaultRange: () => dispatch(getDefaultRange()),\r\n setCrashTypeFilter: filter => dispatch(sidebarCrashType(filter)),\r\n setCrashRange: range => dispatch(sidebarRange(range)),\r\n setSrc: src => dispatch(setSrc(src)),\r\n setMapLoading: status => dispatch(setMapLoading(status))\r\n }\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Sidebar)\r\n","import { defaultRange } from \"../../redux/reducers/mapReducer\"\r\n\r\nconst countyOutline = {\r\n id: 'county-outline',\r\n type: 'line',\r\n source: 'Boundaries',\r\n 'source-layer': 'county',\r\n paint: {\r\n 'line-width': 1.5,\r\n 'line-color': '#969696'\r\n },\r\n filter: [\r\n '==',\r\n 'dvrpc',\r\n 'Yes'\r\n ]\r\n}\r\n\r\nconst countyFill = {\r\n id: 'county-fill',\r\n type: 'fill',\r\n source: 'Boundaries',\r\n 'source-layer': 'county',\r\n layout: {},\r\n maxzoom: 8.39,\r\n paint: {\r\n 'fill-color': ['case',\r\n ['boolean', ['feature-state', 'hover'], false],\r\n 'rgba(244,162,45,0.25)',\r\n 'rgba(0,0,0,0)'\r\n ]\r\n },\r\n filter: [\r\n '==',\r\n 'dvrpc',\r\n 'Yes'\r\n ]\r\n}\r\n\r\nconst municipalityOutline = {\r\n id: 'municipality-outline',\r\n type: 'line',\r\n source: 'Boundaries',\r\n 'source-layer': 'municipalities',\r\n minzoom: 8.4,\r\n paint: {\r\n 'line-width': 0.5,\r\n 'line-color': '#969696'\r\n }\r\n}\r\n\r\nconst municipalityFill = {\r\n id: 'municipality-fill',\r\n type: 'fill',\r\n source: 'Boundaries',\r\n 'source-layer': 'municipalities',\r\n layout: {},\r\n minzoom: 8.4,\r\n paint: {\r\n 'fill-color': ['case',\r\n ['boolean', ['feature-state', 'hover'], false],\r\n 'rgba(244,162,45,0.12)',\r\n 'rgba(0,0,0,0)'\r\n ]\r\n }\r\n}\r\n\r\n// geojson source\r\nconst phillyOutline = {\r\n id: 'philly-outline',\r\n type: 'line',\r\n source: 'PPA',\r\n minzoom: 8.4,\r\n paint: {\r\n 'line-width': 0.5,\r\n 'line-color': '#969696'\r\n }\r\n}\r\n\r\nconst crashHeat = {\r\n id: 'crash-heat',\r\n type: 'heatmap',\r\n source: 'Crashes',\r\n 'source-layer': 'crash',\r\n maxzoom: 11,\r\n filter: ['all',\r\n ['>', 'max_sever', -1],\r\n ['<', 'max_sever', 2],\r\n ['>=', 'year', defaultRange.from],\r\n ['<=', 'year', defaultRange.to]\r\n ],\r\n paint: {\r\n 'heatmap-weight': [\r\n 'interpolate', ['linear'], ['get', 'max_sever'],\r\n 0, 3,\r\n 1, 2.5,\r\n 2, 1.5,\r\n 3, 1,\r\n 4, 0.5,\r\n 5, 0.25\r\n ],\r\n 'heatmap-intensity': [\r\n 'interpolate', ['linear'], ['zoom'],\r\n 8.3, 1,\r\n 11, 1.5\r\n ],\r\n 'heatmap-radius': [\r\n 'interpolate', ['linear'], ['zoom'],\r\n 8.3, 1,\r\n 10, 2.7\r\n ],\r\n 'heatmap-color': [\r\n 'interpolate', ['linear'], ['heatmap-density'],\r\n 0, 'rgba(0,0,0,0)',\r\n 0.15, '#feebe2',\r\n 0.30, '#fcc5c0',\r\n 0.45, '#fa9fb5',\r\n 0.60, '#f768a1',\r\n 0.80, '#c51b8a',\r\n 1, '#7a0177'\r\n ]\r\n }\r\n}\r\n\r\nconst crashCircles = {\r\n id: 'crash-circles',\r\n type: 'circle',\r\n source: 'Crashes',\r\n 'source-layer': 'crash',\r\n minzoom: 11,\r\n filter: ['all',\r\n ['>', 'max_sever', -1],\r\n ['<', 'max_sever', 2],\r\n ['>=', 'year', defaultRange.from],\r\n ['<=', 'year', defaultRange.to]\r\n ],\r\n layout: {\r\n },\r\n paint: {\r\n 'circle-color': [\r\n 'match', ['get', 'max_sever'],\r\n 0, '#c12433',\r\n 1, '#de5260',\r\n 2, '#fc9da6',\r\n 3, '#6eb5cf',\r\n 4, '#b6dae7',\r\n 5, '#ffffff',\r\n 'rgba(255,255,255,0)'\r\n ],\r\n 'circle-radius': [\r\n 'interpolate', ['linear'], ['zoom'],\r\n 11, 2.6,\r\n 16, 8,\r\n ],\r\n 'circle-stroke-color': '#e1e1e1',\r\n 'circle-stroke-width': [\r\n 'case',\r\n ['boolean', ['feature-state', 'hover'], false],\r\n 2.5,\r\n 0\r\n ]\r\n }\r\n}\r\n\r\nexport { countyOutline, countyFill, municipalityOutline, municipalityFill, phillyOutline, crashHeat, crashCircles }","const options = {\r\n method: 'GET',\r\n mode: 'cors',\r\n headers: {\r\n 'Content-Type': 'application/json; charset=utf-8'\r\n }\r\n}\r\n\r\nconst getPopupInfo = async crash => {\r\n const crn = crash.crn\r\n const severity = crash.severity\r\n\r\n let output = {\r\n crn,\r\n severity,\r\n }\r\n\r\n const stream = await fetch(`https://cloud.dvrpc.org/api/crash-data/v1/crashes/${crn}`, options)\r\n \r\n // return an error message if the fetch fails\r\n if(!stream.ok) return {fail: stream.statusText, crn}\r\n\r\n // otherwise get the reponse body and combine it with the existing output fields\r\n let response = await stream.json()\r\n output = {...output, ...response}\r\n return output\r\n}\r\n\r\nconst setPopup = (popupInfo, index, length) => {\r\n return `\r\n

Crash Record Number: ${popupInfo.crn.substring(2)}

\r\n \r\n
\r\n \r\n

${index} of ${length}

\r\n \r\n
\r\n `\r\n}\r\n\r\n// handle popup failure\r\nconst catchPopupFail = crn => {\r\n return `\r\n

Sorry!

\r\n

Something went wrong and the data was unable to be fetched, please try again.

\r\n

If the issue persists, please contact kmurphy@dvrpc.org and let him know the data for crash number ${crn} is not available. Thank you.

\r\n `\r\n}\r\n\r\nexport { getPopupInfo, setPopup, catchPopupFail }","const createBoundaryHighlight = boundingObj => {\r\n let { type, id } = {...boundingObj}\r\n \r\n // handle PPA (add 100 because reasons...)\r\n if(type === 'philly') id = (parseInt(id) + 100)\r\n \r\n id = id.toString()\r\n\r\n const paintProps = { \r\n layer: `${type}-outline`,\r\n width: [\r\n 'match', ['get', 'geoid'],\r\n id, 4,\r\n 0.5\r\n ],\r\n color: [\r\n 'match', ['get', 'geoid'],\r\n id, '#FAA82D',\r\n '#969696'\r\n ]\r\n }\r\n\r\n return paintProps\r\n}\r\n\r\nconst removeBoundaryFilter = () => {\r\n return {\r\n county: {\r\n layer: 'county-outline',\r\n filter: ['==', 'dvrpc', 'Yes'],\r\n paint: {\r\n width: 1.5,\r\n color: '#969696'\r\n }\r\n },\r\n muni: {\r\n layer: 'municipality-outline',\r\n filter: null,\r\n paint: {\r\n width: 0.5,\r\n color: '#969696'\r\n }\r\n },\r\n philly: {\r\n layer: 'philly-outline',\r\n filter: null,\r\n paint: {\r\n width: 0.5,\r\n color: '#969696'\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport { createBoundaryHighlight, removeBoundaryFilter }","import React, { Component } from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport { connect } from 'react-redux'\r\nimport mapboxgl from \"mapbox-gl\";\r\nimport MapboxDraw from '@mapbox/mapbox-gl-draw';\r\n\r\nimport * as layers from './layers.js'\r\nimport * as popups from './popups.js';\r\nimport { createBoundaryHighlight, removeBoundaryFilter } from './boundaryFilters.js';\r\nimport { getDataFromKeyword, setSidebarHeaderContext, getBoundingBox, setMapBounding, setMapFilter, getPolygonCrashes, setPolygonBbox, removePolyCRNS, urlRoute, defaultRange } from '../../redux/reducers/mapReducer.js'\r\n\r\nimport './map.css';\r\n\r\nclass Map extends Component {\r\n constructor(props) {\r\n super(props)\r\n\r\n this.state = {\r\n boundary: null,\r\n polygon: false,\r\n popup: false,\r\n // draw is on local state so that removeBoundary() can access the instance of MapboxDraw to call draw.deleteAll()\r\n draw: new MapboxDraw({\r\n displayControlsDefault: false,\r\n controls: {\r\n polygon: true,\r\n // disable trash because we want the polygons and muni/county boundaries to follow the same flow (i.e. use the 'remove boundary' overlay for both)\r\n trash: false\r\n }\r\n }),\r\n zoom: window.innerWidth <= 420 ? 7.3 : 8.3,\r\n route: urlRoute\r\n }\r\n }\r\n \r\n\r\n /**********************/\r\n // Lifecycle Methods //\r\n /**********************/\r\n componentDidMount() {\r\n // mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_ACCESS_TOKEN\r\n mapboxgl.accessToken = 'pk.eyJ1IjoiY3J2YW5wb2xsYXJkIiwiYSI6Ii00ZklVS28ifQ.Ht4KwAM3ZUjo1dT2Erskgg'\r\n \r\n // @NOTE: do not delete this comment:\r\n // eslint-disable-next-line import/no-webpack-loader-syntax\r\n mapboxgl.workerClass = require('worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker').default //fix bable transpiling issues\r\n \r\n const longitudeOffset = window.innerWidth > 800 ? -75.80 : -75.2273\r\n \r\n // initialize the map\r\n this.map = new mapboxgl.Map({\r\n container: this.crashMap,\r\n style: 'mapbox://styles/mapbox/dark-v11',\r\n center: [longitudeOffset, 40.071],\r\n zoom: this.state.zoom,\r\n //@Note: this is a performance hit but necessary to export the map canvas for printing\r\n preserveDrawingBuffer: true\r\n })\r\n\r\n // add navigation, draw tool, extent and filter buttons\r\n const navControl = new mapboxgl.NavigationControl()\r\n this.map.addControl(navControl)\r\n this.map.addControl(this.state.draw, 'top-right')\r\n\r\n // add DVRPC regional outlines + crash data heat map\r\n this.map.on('load', () => {\r\n this.map.addSource(\"Boundaries\" , {\r\n type: 'vector',\r\n url: 'https://tiles.dvrpc.org/data/dvrpc-municipal.json',\r\n promoteId: 'geoid'\r\n })\r\n\r\n this.map.addSource(\"Crashes\", {\r\n type: 'vector',\r\n url: 'https://tiles.dvrpc.org/data/crash.json',\r\n promoteId: 'id'\r\n })\r\n\r\n this.map.addSource(\"PPA\", {\r\n type: 'geojson',\r\n data: 'https://arcgis.dvrpc.org/portal/rest/services/Boundaries/DVRPC_MCD_PhiCPA/FeatureServer/0/query?where=co_name%3D%27Philadelphia%27&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&distance=&units=esriSRUnit_Foot&relationParam=&outFields=geoid&returnGeometry=true&maxAllowableOffset=&geometryPrecision=&outSR=&havingClause=&gdbVersion=&historicMoment=&returnDistinctValues=false&returnIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&multipatchOption=xyFootprint&resultOffset=&resultRecordCount=&returnTrueCurves=false&returnExceededLimitFeatures=false&quantizationParameters=&returnCentroid=false&sqlFormat=none&resultType=&featureEncoding=esriDefault&datumTransformation=&f=geojson'\r\n })\r\n\r\n // Find the index of the first symbol layer in the map style. (from mapbox docs)\r\n const mapLayers = this.map.getStyle().layers;\r\n let firstSymbolId;\r\n\r\n for (const layer of mapLayers) {\r\n if (layer.type === 'symbol') {\r\n firstSymbolId = layer.id;\r\n break;\r\n }\r\n }\r\n\r\n // add county boundaries beneath road labels in streets v-12 spec\r\n this.map.addLayer(layers.countyOutline, 'settlement-subdivision-label')\r\n this.map.addLayer(layers.countyFill, firstSymbolId)\r\n\r\n // add municipal boundaries beneath road labels in streets-v12 spec\r\n this.map.addLayer(layers.municipalityOutline, 'settlement-subdivision-label')\r\n this.map.addLayer(layers.municipalityFill, firstSymbolId)\r\n\r\n // add PPA's\r\n this.map.addLayer(layers.phillyOutline, 'settlement-subdivision-label')\r\n\r\n // add crash data layers beneath relevant layers in streets-v12 spec\r\n this.map.addLayer(layers.crashHeat, 'settlement-subdivision-label')\r\n this.map.addLayer(layers.crashCircles, 'settlement-subdivision-label')\r\n\r\n // listen for routing on load\r\n const geoParams = this.state.route.searchParams.get('geom')\r\n const filterParams = this.state.route.searchParams.get('filter')\r\n\r\n if(geoParams) this.handleRoute({geoParams, filterParams})\r\n })\r\n\r\n // variables for hover state\r\n let hoveredCircle = null\r\n \r\n // add hover effect to geographies\r\n this.map.on('mousemove', 'municipality-fill', e => this.hoverGeographyFill(e))\r\n this.map.on('mouseleave', 'municipality-fill', () => this.removeGeographyFill())\r\n this.map.on('mousemove', 'county-fill', e => this.hoverGeographyFill(e))\r\n this.map.on('mouseleave', 'county-fill', () => this.removeGeographyFill())\r\n\r\n // handle click events\r\n this.map.on('click', 'municipality-fill', e => this.clickGeography(e))\r\n this.map.on('click', 'county-fill', e => this.clickGeography(e))\r\n this.map.on('click', 'crash-circles', e => {\r\n const features = e.features\r\n\r\n // extract array of crn and severity for all crashes at that clicked point\r\n const crnArray = features.map(crash => { return {crn: crash.properties.id, severity: crash.properties.max_sever} })\r\n let index = 0\r\n\r\n // initialize the mapbox popup object\r\n const popup = new mapboxgl.Popup({\r\n closebutton: true,\r\n closeOnClick: true\r\n }).setLngLat(e.lngLat)\r\n\r\n // create popup and handle pagination if necessary\r\n this.handlePopup(crnArray, index, popup)\r\n\r\n // put popup state on local state\r\n this.setState({popup: popup})\r\n })\r\n \r\n // update legend depending on zoom level (heatmap vs crash circles)\r\n this.map.on('zoomend', () => this.updateLegend())\r\n\r\n this.map.on('mousemove', 'crash-circles', e => {\r\n this.map.getCanvas().style.cursor = 'pointer'\r\n\r\n if(hoveredCircle){\r\n this.map.removeFeatureState({\r\n source: 'Crashes',\r\n sourceLayer: 'crash',\r\n id: hoveredCircle\r\n })\r\n }\r\n \r\n hoveredCircle = e.features[0].id\r\n \r\n this.map.setFeatureState(\r\n {\r\n source: 'Crashes',\r\n sourceLayer: 'crash',\r\n id: hoveredCircle\r\n },\r\n {\r\n hover: true\r\n }\r\n )\r\n })\r\n\r\n this.map.on('mouseleave', 'crash-circles', () => {\r\n if (hoveredCircle) {\r\n this.map.removeFeatureState({\r\n source: 'Crashes',\r\n sourceLayer: 'crash',\r\n id: hoveredCircle\r\n })\r\n }\r\n \r\n hoveredCircle = null;\r\n\r\n this.map.getCanvas().style.cursor = ''\r\n })\r\n\r\n // mutes other map other event listeners when the polygon draw tool is selected (shorts out when user finishes drawing b/c that also calls this function)\r\n this.map.on('draw.modechange', e => e.mode !== 'draw_polygon' ? null : this.setState({polygon: true}))\r\n\r\n // this fires after the polygon is done (i.e. double click to close polygon)\r\n this.map.on('draw.create', e => {\r\n const bbox = e.features[0].geometry.coordinates[0]\r\n this.props.setSidebarHeaderContext('Selected Area')\r\n this.handleBbox(bbox)\r\n this.showBoundaryOverlay()\r\n })\r\n\r\n // this fires when the polygon updates (for our use case, if it's moved via dragging)\r\n this.map.on('draw.update', e => {\r\n const bbox = e.features[0].geometry.coordinates[0]\r\n this.props.setSidebarHeaderContext('Selected Area')\r\n this.handleBbox(bbox)\r\n })\r\n }\r\n\r\n componentDidUpdate(prevProps) {\r\n // set form filters (crash type and range) to prevProps or default value to hold on to state if a recalculation doesn't occur\r\n const prevType = prevProps.crashType || 'KSI'\r\n const prevRange = prevProps.range || defaultRange\r\n let makeNewFilter = false\r\n\r\n const filterObj = {\r\n filterType: prevType,\r\n boundary: false,\r\n tileType: '',\r\n id: 0,\r\n range: prevRange\r\n }\r\n\r\n // add crashType filters & update legend\r\n if(this.props.crashType !== prevProps.crashType) {\r\n const crashType = this.props.crashType\r\n filterObj.filterType = crashType\r\n makeNewFilter = true\r\n this.updateLegend()\r\n }\r\n\r\n // add range filters\r\n if(this.props.range){\r\n const {to, from} = this.props.range\r\n\r\n // set range if first time or new range\r\n if(prevProps.range){\r\n const prevRange = prevProps.range\r\n const prevFrom = prevRange.from\r\n const prevTo = prevRange.to\r\n\r\n if(prevTo !== to || prevFrom !== from) {\r\n filterObj.range = {to, from}\r\n makeNewFilter = true\r\n }\r\n } else{\r\n filterObj.range = {to, from}\r\n makeNewFilter = true\r\n }\r\n }\r\n\r\n // update store filters\r\n if(makeNewFilter) {\r\n if(this.state.boundary) {\r\n const boundary = this.state.boundary\r\n filterObj.id = boundary.id\r\n filterObj.tileType = boundary.tileType\r\n filterObj.boundary = true\r\n }\r\n this.props.setMapFilter(filterObj)\r\n }\r\n\r\n // apply filters\r\n if(this.props.filter){\r\n let filter = this.props.filter === 'none' ? null : this.props.filter\r\n\r\n this.map.setFilter('crash-circles', filter)\r\n this.map.setFilter('crash-heat', filter)\r\n }\r\n\r\n // add boundaries and their corresponding filters/styles/sidebar stats\r\n if(this.props.bounding !== prevProps.bounding) {\r\n const { county, muni, philly } = removeBoundaryFilter()\r\n\r\n this.map.setFilter(county.layer, county.filter)\r\n this.map.setFilter(muni.layer, muni.filter)\r\n this.map.setFilter(philly.layer, philly.filter)\r\n\r\n this.map.setPaintProperty(county.layer, 'line-width', county.paint.width)\r\n this.map.setPaintProperty(county.layer, 'line-color', county.paint.color)\r\n this.map.setPaintProperty(muni.layer, 'line-width', muni.paint.width)\r\n this.map.setPaintProperty(muni.layer, 'line-color', muni.paint.color)\r\n this.map.setPaintProperty(philly.layer, 'line-width', philly.paint.width)\r\n this.map.setPaintProperty(philly.layer, 'line-color', philly.paint.color)\r\n\r\n // create new filter\r\n const boundingObj = this.props.bounding\r\n\r\n this.setBoundary(boundingObj)\r\n this.showBoundaryOverlay()\r\n\r\n // update map filter & circle toggle state when coming from search\r\n if(boundingObj.filter) {\r\n const toggleFilter = boundingObj.filter\r\n this.props.setMapFilter(toggleFilter)\r\n this.setState({boundary: toggleFilter})\r\n }\r\n }\r\n\r\n // apply polygon filter (special case)\r\n if(this.props.polyCRNS) {\r\n const fail = this.props.polyCRNS.message\r\n let crashType = this.props.crashType || 'KSI'\r\n let range = this.props.range || defaultRange\r\n let polygonFilter = fail ? ['all', ['in', 'id', '' ]] : ['all', ['in', 'id', ...this.props.polyCRNS]]\r\n\r\n // add range\r\n if(range) {\r\n const {from, to} = range\r\n const rangeFilter = [\r\n ['>=', 'year', parseInt(from)],\r\n ['<=', 'year', parseInt(to)] \r\n ]\r\n polygonFilter = polygonFilter.concat(rangeFilter)\r\n }\r\n\r\n // add crashtype\r\n if(crashType === 'KSI') {\r\n const ksiFilter = [\r\n ['>', 'max_sever', -1],\r\n ['<', 'max_sever', 2],\r\n ]\r\n polygonFilter = polygonFilter.concat(ksiFilter)\r\n }\r\n \r\n this.map.setFilter('crash-circles', polygonFilter)\r\n this.map.setFilter('crash-heat', polygonFilter)\r\n }\r\n\r\n // zoom to a new center when appropriate (address searches)\r\n if(prevProps.center !== this.props.center) {\r\n this.map.flyTo({\r\n center: this.props.center,\r\n zoom: 12,\r\n speed: 0.9,\r\n curve: 1.7\r\n })\r\n }\r\n\r\n // zoom to a bounding box when appropriate (all non-address searches)\r\n if(this.props.bbox && prevProps.bbox !== this.props.bbox) {\r\n if( window.innerWidth > 800 ) {\r\n // handle desktop offset\r\n const leftPad = (window.innerWidth * 0.33 + 30)\r\n const padding = {top: 30, bottom: 30, left: leftPad, right: 30}\r\n\r\n this.map.fitBounds(this.props.bbox, {padding})\r\n } else {\r\n this.map.fitBounds(this.props.bbox)\r\n }\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n this.map.remove()\r\n }\r\n\r\n \r\n /*****************/\r\n // Class Methods //\r\n /*****************/\r\n // reset map to default view\r\n resetControl = () => {\r\n const longitudeOffset = window.innerWidth > 800 ? -75.80 : -75.2273\r\n this.map.flyTo({center: [longitudeOffset, 40.071], zoom: this.state.zoom, pitch: 0})\r\n }\r\n\r\n // reveal the boundary overlay when a boundary is established\r\n showBoundaryOverlay = () => this.boundaryOverlay.classList.remove('hidden')\r\n\r\n // apply boundary filters and map styles\r\n setBoundary = boundaryObj => {\r\n \r\n // derive layer styles from boundaryObj\r\n const highlight = createBoundaryHighlight(boundaryObj)\r\n \r\n // make the appropraite paint changes\r\n this.map.setPaintProperty(highlight.layer, 'line-width', highlight.width)\r\n this.map.setPaintProperty(highlight.layer, 'line-color', highlight.color)\r\n\r\n // remove any existing polygons\r\n if(this.state.polygon){\r\n this.state.draw.deleteAll()\r\n this.props.removePolyCRNS()\r\n this.setState( { polygon: false })\r\n }\r\n }\r\n\r\n // hide the boundary overlay and reset map filters, styles and sidebar info to default\r\n removeBoundary = () => {\r\n // toggle overlay visibility\r\n this.boundaryOverlay.classList.add('hidden')\r\n\r\n // remove any existing polygons & empty polyCRNS state object\r\n if(this.state.polygon){\r\n this.state.draw.deleteAll()\r\n this.props.removePolyCRNS()\r\n }\r\n\r\n // update sidebar information\r\n let newFilterType;\r\n \r\n if(this.state.polygon) {\r\n newFilterType = this.props.crashType || 'KSI'\r\n } else {\r\n newFilterType = this.state.route.searchParams.get('filter')\r\n }\r\n\r\n let isKSI = newFilterType === 'KSI' ? 'yes' : 'no'\r\n\r\n const regionalStats = {geoID: '', isKSI}\r\n\r\n this.props.setDefaultState(regionalStats)\r\n this.props.setSidebarHeaderContext('the DVRPC region')\r\n\r\n // get default map filters and paint properties\r\n const { county, muni, philly } = removeBoundaryFilter()\r\n\r\n // remove filter while maintaining crash type filter (all or ksi)\r\n const range = this.props.range || defaultRange\r\n const filterObj = {filterType: newFilterType, range}\r\n\r\n // set store filter state\r\n // @UPDATe DONT touch this\r\n this.props.setMapFilter(filterObj)\r\n\r\n // update map\r\n this.map.setPaintProperty(county.layer, 'line-width', county.paint.width)\r\n this.map.setPaintProperty(county.layer, 'line-color', county.paint.color)\r\n this.map.setPaintProperty(muni.layer, 'line-width', muni.paint.width)\r\n this.map.setPaintProperty(muni.layer, 'line-color', muni.paint.color)\r\n this.map.setPaintProperty(philly.layer, 'line-width', philly.paint.width)\r\n this.map.setPaintProperty(philly.layer, 'line-color', philly.paint.color)\r\n \r\n // update boundary state to allow hover effects now that boundaries are removed & update polygon state to enable normal event listener interaction\r\n this.setState({\r\n boundary: null,\r\n polygon: false\r\n })\r\n\r\n // remove route\r\n this.state.route.searchParams.delete('geom')\r\n window.history.replaceState(null, null, window.location.pathname)\r\n }\r\n\r\n // add fill effect when hovering over a geography type (county or municipality)\r\n hoverGeographyFill = (e) => {\r\n // escape if a boundary is set or if the user is drawing a polygon\r\n if(this.state.boundary || this.state.polygon) return\r\n \r\n let features = e.features\r\n \r\n if(features.length > 0 ) {\r\n features = features[0]\r\n const sourceLayer = this.map.getZoom() < 8.4 ? 'county' : 'municipalities'\r\n const name = sourceLayer === 'county' ? features.properties.name + ' County' : features.properties.name\r\n\r\n // clear hover state\r\n this.map.removeFeatureState({\r\n source: 'Boundaries',\r\n sourceLayer\r\n })\r\n \r\n // update hover state\r\n this.map.setFeatureState(\r\n {source: 'Boundaries', sourceLayer, id: features.id},\r\n {hover: true}\r\n )\r\n\r\n // update the overlay text\r\n this.hoveredArea.style.visibility = 'visible'\r\n this.hoveredArea.children[0].textContent = name\r\n }\r\n }\r\n\r\n // remove fill effect when exiting the layer\r\n removeGeographyFill = () => {\r\n let sourceLayer = this.map.getZoom() < 8.4 ? 'county' : 'municipalities'\r\n\r\n this.map.removeFeatureState({\r\n source: 'Boundaries',\r\n sourceLayer\r\n })\r\n \r\n this.hoveredArea.style.visibility = 'hidden'\r\n }\r\n\r\n // draw a boundary, zoom to, filter crash data and update sidebar on muni click\r\n clickGeography = e => { \r\n // exit if an active geom exists\r\n if(this.state.polygon || this.state.boundary) return\r\n\r\n // exit & update state if popup exists b/c this will also close the popup\r\n if(this.state.popup) {\r\n this.setState({popup: false})\r\n return\r\n }\r\n \r\n // short out if a user clicks on a crash circle \r\n const circleTest = this.map.queryRenderedFeatures(e.point)[0]\r\n if(circleTest.source === 'Crashes') return\r\n \r\n // get source layer and exit if the wrong one is triggered\r\n let sourceLayer = this.map.getZoom() < 8.4 ? 'county' : 'municipality'\r\n const features = e.features[0]\r\n if(sourceLayer[0] !== features.sourceLayer[0]) return\r\n \r\n // get feature properties\r\n const props = features.properties\r\n const name = props.name\r\n const featureID = features.id\r\n let geoID = features.properties.geoid\r\n\r\n // get KSI and range state from store\r\n const range = this.props.range || defaultRange\r\n const newFilterType = this.props.crashType || 'KSI'\r\n let isKSI = newFilterType === 'KSI' ? 'yes' : 'no'\r\n\r\n // set layer-dependent variables\r\n let tileType;\r\n let countyName;\r\n if(sourceLayer === 'county'){\r\n tileType = 'c'\r\n countyName = `${name} County`\r\n }else {\r\n tileType = 'm'\r\n }\r\n\r\n // handle philly edge case\r\n const phillyTest = name.substring(0, 5)\r\n if(phillyTest === 'Phila') {\r\n geoID = 42101\r\n tileType = 'c'\r\n sourceLayer = 'county'\r\n }\r\n \r\n // create data, filter and boundary objects\r\n const dataObj = { geoID, isKSI }\r\n const boundaryObj = { type: sourceLayer, id: geoID }\r\n const filterObj = {filterType: newFilterType, tileType, id: geoID, range, boundary: true}\r\n\r\n // dispatch actions to: set sidebar header, fetch the data and create a bounding box for the selected area\r\n this.props.setSidebarHeaderContext(countyName || name)\r\n this.props.getData(dataObj)\r\n this.props.setMapBounding(boundaryObj)\r\n this.props.getBoundingBox(geoID)\r\n this.props.setMapFilter(filterObj)\r\n\r\n // use featureID to remove the muni fill that hovering created\r\n this.removeGeographyFill(featureID)\r\n\r\n // hide the hover boundary\r\n this.hoveredArea.style.visibility = 'hidden'\r\n\r\n // update boundary state to prevent hover effects when boundaries are present & so the ksi/all toggle can stay within the set bounds\r\n this.setState({boundary: filterObj})\r\n\r\n // set URL state\r\n this.state.route.searchParams.set('filter', newFilterType)\r\n this.state.route.searchParams.set('geom', `${geoID},${sourceLayer},${encodeURI(name)}`)\r\n\r\n window.history.replaceState(null, null, `?geom=${geoID},${sourceLayer},${encodeURI(name)}&filter=${newFilterType}`)\r\n }\r\n\r\n // create bbox object from polygon & hit endpoints w/it\r\n handleBbox = bbox => {\r\n const bboxFormatted = encodeURIComponent(JSON.stringify(\r\n {\r\n \"type\":\"Polygon\",\r\n \"coordinates\": [bbox],\r\n \"crs\": {\r\n \"type\": \"name\",\r\n \"properties\": {\r\n \"name\": \"EPSG:4326\"\r\n }\r\n }\r\n }\r\n ))\r\n \r\n let typeCheck = this.props.crashType || 'KSI'\r\n let isKSI = typeCheck === 'KSI' ? 'yes' : 'no'\r\n\r\n // create data object for API call\r\n const dataObj = {\r\n geojson: bboxFormatted,\r\n isKSI\r\n }\r\n\r\n // update store w/bbox info\r\n this.props.getPolygonCrashes(bboxFormatted)\r\n this.props.getData(dataObj)\r\n this.props.setPolygonBbox(bboxFormatted)\r\n }\r\n\r\n // handle popup creation and pagination\r\n handlePopup = async (crnArray, index, popup) => {\r\n const length = crnArray.length\r\n const popupInfo = popups.getPopupInfo(crnArray[index])\r\n\r\n const html = await popupInfo.then(result => {\r\n const current = index + 1\r\n\r\n // create popup content (success or fail)\r\n if(result.fail){\r\n // remove the state code from the CRN for printing\r\n const crnOutput = result.crn.substring(2)\r\n return popups.catchPopupFail(crnOutput)\r\n }else{\r\n return popups.setPopup(result, current, length)\r\n }\r\n })\r\n\r\n // set popup\r\n popup.setHTML(html).addTo(this.map)\r\n\r\n // handle pagination if necessary\r\n if (length > 1) {\r\n let nextPopup, previousPopup\r\n\r\n // get a handle on the buttons\r\n const node = ReactDOM.findDOMNode(this)\r\n if (node instanceof HTMLElement) {\r\n const wrapper = node.querySelector('.mapboxgl-popup')\r\n nextPopup = wrapper.querySelector('#crash-next-popup')\r\n previousPopup = wrapper.querySelector('#crash-previous-popup')\r\n } else{\r\n console.log('pagination function failed to find map node')\r\n return\r\n }\r\n\r\n // add next click handler\r\n nextPopup.onclick = () => {\r\n index + 1 >= length ? index = 0 : index += 1\r\n this.handlePopup(crnArray, index, popup)\r\n }\r\n\r\n // add previous click handler\r\n previousPopup.onclick = () => {\r\n index - 1 < 0 ? index = length - 1 : index -= 1\r\n this.handlePopup(crnArray, index, popup)\r\n }\r\n }\r\n }\r\n\r\n updateLegend = () => {\r\n const zoom = this.map.getZoom()\r\n\r\n if(zoom >= 11) {\r\n this.legendTitle.textContent = 'Crash Severity'\r\n\r\n if(!this.props.crashType || this.props.crashType === 'KSI') {\r\n this.legendGradient.style.background = 'linear-gradient(to right, #e67e88, #de5260, #c12433)'\r\n this.legendLabel.innerHTML = 'Severe InjuryFatal'\r\n\r\n }else {\r\n this.legendGradient.style.background = 'linear-gradient(to right, #f7f7f7, #93c7db, #6eb5cf, #4ba3c3, #e67e88, #de5260, #c12433)'\r\n this.legendLabel.innerHTML = 'No InjuryFatal'\r\n }\r\n\r\n } else {\r\n let crashType = this.props.crashType || 'KSI'\r\n this.legendTitle.textContent = `Number of Crashes (${crashType})`\r\n this.legendGradient.style.background = 'linear-gradient(to right, #feebe2, #fcc5c0, #c51b8a, #7a0177)'\r\n this.legendLabel.innerHTML = '148+'\r\n }\r\n }\r\n\r\n handleRoute = params => {\r\n /* @params:\r\n {\r\n geoParams: geoid,sourceLayer,name,\r\n filterParams: filter\r\n }\r\n */\r\n const geo = params.geoParams.split(',')\r\n \r\n // get feature properties\r\n let tileType;\r\n let countyName;\r\n let geoID = geo[0]\r\n let sourceLayer = geo[1]\r\n\r\n const name = decodeURIComponent(geo[2])\r\n const newFilterType = params.filterParams\r\n const range = defaultRange\r\n let isKSI = newFilterType === 'KSI' ? 'yes' : 'no'\r\n\r\n if(sourceLayer === 'county'){\r\n tileType = 'c'\r\n countyName = `${name} County`\r\n }else {\r\n tileType = 'm'\r\n }\r\n\r\n // handle philly edge case\r\n const phillyTest = name.substring(0, 5)\r\n if(phillyTest === 'Phila') {\r\n geoID = 42101\r\n tileType = 'c'\r\n sourceLayer = 'county'\r\n }\r\n \r\n // create data, filter and boundary objects\r\n const dataObj = { geoID, isKSI }\r\n const boundaryObj = { type: sourceLayer, id: geoID }\r\n const filterObj = {filterType: newFilterType, tileType, id: geoID, range, boundary: true}\r\n\r\n // dispatch actions to: set sidebar header, fetch the data and create a bounding box for the selected area\r\n this.props.setSidebarHeaderContext(countyName || name)\r\n this.props.getData(dataObj)\r\n this.props.setMapBounding(boundaryObj)\r\n this.props.getBoundingBox(geoID)\r\n this.props.setMapFilter(filterObj)\r\n\r\n // update boundary state to prevent hover effects when boundaries are present & so the ksi/all toggle can stay within the set bounds\r\n this.setState({boundary: filterObj})\r\n }\r\n\r\n render() {\r\n let crashType = this.props.crashType || 'KSI'\r\n \r\n return (\r\n
this.crashMap = el}>\r\n
\r\n

this.legendTitle = el}>Number of Crashes ({crashType})

\r\n this.legendGradient = el}>\r\n
this.legendLabel = el}>\r\n 1\r\n 4\r\n 8+\r\n
\r\n
\r\n\r\n
this.hoveredArea = el}>\r\n

default

\r\n
\r\n\r\n
\r\n DVRPC logo\r\n
\r\n\r\n \r\n
\r\n );\r\n }\r\n}\r\n\r\nconst mapStateToProps = state => {\r\n return {\r\n center: state.center,\r\n crashType: state.crashType,\r\n range: state.range,\r\n bounding: state.bounding,\r\n bbox: state.bbox,\r\n filter: state.filter,\r\n polyCRNS: state.polyCRNS\r\n }\r\n}\r\n\r\nconst mapDispatchToProps = dispatch => {\r\n return {\r\n getData: dataObj => dispatch(getDataFromKeyword(dataObj)),\r\n setMapBounding: boundingObj => dispatch(setMapBounding(boundingObj)),\r\n setSidebarHeaderContext: area => dispatch(setSidebarHeaderContext(area)),\r\n getBoundingBox: id => dispatch(getBoundingBox(id)),\r\n setDefaultState: region => dispatch(getDataFromKeyword(region)),\r\n setMapFilter: filter => dispatch(setMapFilter(filter)),\r\n getPolygonCrashes: bbox => dispatch(getPolygonCrashes(bbox)),\r\n setPolygonBbox: formattedBbox => dispatch(setPolygonBbox(formattedBbox)),\r\n removePolyCRNS: () => dispatch(removePolyCRNS()),\r\n }\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Map);\r\n","import React, { Component } from 'react';\r\nimport { connect } from 'react-redux'\r\nimport PrintTemplate from 'react-print';\r\n\r\nimport { setSrc, getDefaultRange } from '../../redux/reducers/mapReducer.js'\r\nimport * as charts from '../sidebar/charts.js';\r\nimport './printPage.css';\r\n\r\nclass PrintPage extends Component {\r\n componentDidUpdate() {\r\n if(this.props.src) {\r\n // print and then clear src from store\r\n this.mapImg.setAttribute('src', this.props.src)\r\n window.print()\r\n this.props.setSrc(null)\r\n }\r\n }\r\n\r\n render() {\r\n const defaultRange = this.props.getDefaultRange()\r\n \r\n // set dynamic text\r\n let area = this.props.area || 'the DVRPC Region'\r\n let crashType = this.props.crashType || 'KSI'\r\n let from, to;\r\n\r\n const defaultFrom = defaultRange.range.from\r\n const defaultTo = defaultRange.range.to\r\n\r\n if(this.props.range) {\r\n from = this.props.range.from\r\n to = this.props.range.to\r\n } else {\r\n from = defaultFrom\r\n to = defaultTo\r\n }\r\n \r\n let chartsRange = {from, to}\r\n\r\n // get and organize data\r\n const data = charts.makeCharts(this.props.data, chartsRange)\r\n\r\n const trend = data.trendChart\r\n const trendData = trend.datasets[0].data\r\n const trendLabels = trend.labels\r\n\r\n const severity = data.severityChart\r\n const severityData = severity.datasets[0].data\r\n const severityLabels = severity.labels\r\n\r\n const mode = data.modeChart\r\n const modeData = mode.datasets[0].data\r\n const modeLabels = mode.labels\r\n\r\n const collisionType = data.collisionTypeChart\r\n const collisionTypeData = collisionType.datasets[0].data\r\n const collissionTypeLabels = collisionType.labels\r\n\r\n return(\r\n \r\n
\r\n
\r\n \"DVRPC\r\n \"map this.mapImg = el} className=\"print-map\" />\r\n
\r\n\r\n

Crash Statistics for {area}

\r\n\r\n

This tool's default setting is limited to five years of killed and severe injury crashes (abbreviated as \"KSI\") for {defaultFrom} to {defaultTo}. Five years of data is typically used by local, state, and federal partners in safety analyses.

\r\n

The following tables are showing results for {crashType} crash types from {from} to {to}.

\r\n

Raw crash data tables for this tool were downloaded from the PennDOT Crash Download Map and the NJDOT Crash Tables webpage, for Pennsylvania and New Jersey data, respectively.

\r\n \r\n
\r\n\r\n

Crashes over Time

\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {trendData.map((data, index) => {\r\n return(\r\n \r\n \r\n \r\n \r\n )\r\n })}\r\n \r\n
YearNumber of Crashes
{trendLabels[index]}{data.toLocaleString()}
\r\n

This table shows {crashType} crashes in {area} by crash severity from {from} to {to}. Crash trends can be useful for identifying if the frequency of crashes is increasing or decreasing over time, but it is important not to infer patterns from single-year spikes or drops in crashes or in datasets with limited data points.

\r\n\r\n

Crash Severity

\r\n \r\n \r\n \r\n {severityLabels.map((data => ))}\r\n \r\n \r\n \r\n \r\n {severityData.map(((data, index) => ))}\r\n \r\n \r\n
{data}
{data.toLocaleString()}
\r\n

This table shows people involved in {crashType} crashes in {area} by crash severity from {from} to {to}. Injury severity is divided into seven possible categories, as defined in the \"About\" section of the information modal.

\r\n\r\n

Mode

\r\n \r\n \r\n \r\n {modeLabels.map((data => ))}\r\n \r\n \r\n \r\n \r\n {modeData.map(((data, index) => ))}\r\n \r\n \r\n
{data}
{data.toLocaleString()}
\r\n

This table shows people involved in {crashType} crashes in the {area} by mode from {from} to {to}. Pedestrians and bicyclists are often a focus of transportation safety planning efforts because they are the road users most vulnerable to sever injuries in the event of a crash. This is reflected in data that consistently shows pedestrians account for a disproportionate number of the injuries sustained on the road.

\r\n \r\n

Collision Type

\r\n \r\n \r\n \r\n {collissionTypeLabels.map((data => ))}\r\n \r\n \r\n \r\n \r\n {collisionTypeData.map(((data, index) => ))}\r\n \r\n \r\n
{data}
{data.toLocaleString()}
\r\n

This table shows {crashType} crashes in {area} by collision type from {from} to {to}. Collision type data can be especially useful for identifying trends at specific locations or along specific routes.

\r\n
\r\n
\r\n )\r\n }\r\n}\r\n\r\nconst mapStateToProps = state => {\r\n return {\r\n data: state.data,\r\n area: state.area,\r\n range: state.range,\r\n crashType: state.crashType,\r\n src: state.src\r\n } \r\n}\r\n\r\nconst mapDispatchToProps = dispatch => {\r\n return {\r\n setSrc: src => dispatch(setSrc(src)),\r\n getDefaultRange: () => dispatch(getDefaultRange())\r\n }\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(PrintPage);","import React, { Component } from 'react';\r\n\r\nimport Navbar from '../navbar/navbar.js'\r\nimport Sidebar from '../sidebar/sidebar.js'\r\nimport Map from '../map/map.js'\r\nimport PrintPage from '../printPage/printPage.js'\r\n\r\nimport './crashMapContainer.css';\r\n\r\nclass CrashMapContainer extends Component {\r\n render() {\r\n return (\r\n
\r\n \r\n\r\n
\r\n \r\n \r\n
\r\n \r\n \r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default CrashMapContainer;\r\n","import React, { Component } from 'react';\r\n\r\nimport './App.css';\r\nimport CrashMapContainer from './components/crashMapContainer/crashMapContainer.js'\r\n\r\nclass App extends Component {\r\n render() {\r\n return (\r\n \r\n );\r\n }\r\n}\r\n\r\nexport default App;","import { createStore, applyMiddleware } from \"redux\";\r\nimport ReduxThunk from \"redux-thunk\";\r\n\r\nimport mapReducer from './reducers/mapReducer.js'\r\n\r\nexport default createStore(\r\n mapReducer,\r\n applyMiddleware(ReduxThunk)\r\n)","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport { Provider } from 'react-redux'\r\n\r\nimport './index.css';\r\nimport App from './App';\r\nimport store from './redux/store.js'\r\n\r\nReactDOM.render(\r\n \r\n \r\n ,\r\n document.getElementById('root')\r\n);\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: http://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n","module.exports = \"data:image/png;base64,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\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAATCAYAAAB7u5a2AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAASdAAAEnQB3mYfeAAAAcNJREFUOE+1lD2KAkEQhd/4b6CgiYgogomZBzDwFB5AU69gYiiIkZmBdzDwBIIKBoLiJVQ08hfs7Vdry65jDyysH9R0T3fPq67q6nFOp5PCh/DxodRn9H2fEiY+x3E+t3N5+KT5dzxVGdFPM9jGX7GK8yO/349IJIJgMPgcozGVHKd5pfWtOBcHAgFpJ5MJNpsNotHo0yg6n8+xXq+lb8Na5/yo2Wyi0+mgWCyiXq9Dr5VoDocDer0e7vc7lsslcrkczuezRPELir+aXqg3rVQmk6FjTxsMBrL2eDy6dKxpIY1GQ9pEIoHxeIzZbIbFYoF2uy3jpFqtSgRvefVG4y7IarVS4XBYtVoteTcwMu1QaWF5f6dB86yW2+0mfZNL7RTX61VyzwO37viBVZyCFCA8RKKjQCgUEiNm3oZVnOi04HK5YDQaYbvdSknu93vJP/vT6VR2T+eM1MVrnmimWkql0rMqstmsyufzqlAoqFgs9hwfDoey9s/VkkqlpCXpdBrxeBxaWOrakEwmHz03by8RxZnf3W6Hfr+PcrmMSqXymP2m2+1KidZqNTlg1wXSWG+ocWD+mBQw8CDN/4Y3k2vd4sAXUZySoSwW9McAAAAASUVORK5CYII=\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAlCAYAAADvLtGsAAAACXBIWXMAABYlAAAWJQFJUiTwAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACvklEQVR42mL8//8/Azp4//59ApBSYBjEQFBQsAFdDCCAWHCovQDEE4CYf5D6JRGbIEAAMQFjQQCE0XwN8owDEH8cjB4Bum8BltSkABBATFBHH8DhoYRB5pGJODwCEisACCCQZwKAWB+IF2BJlxtwRekAgIVA9xRg8Qgo78SDIgUggJiQMro/1IfoHgKJFQ6wRzYC3ZGAo6Cqh3L1AQKICU0+HoeHQIXBwgHyyEVsyR3qkfnIYgABxIRFczxUIbqHEgbAQyCPOADt/oDmEQNoaYsCAAKICYch8/F46CKdPAIqSQNweOQAtmoDIICY8BgG8pADFnEHOnjoIzRGHqB5RACXR0AAIICYCBi6ARoSyLHzAeqhhzT2yAVSPAICAAFEyDP80DoIm4cCaFSpFuDxiD4+jQABxESE4SAPLaBTKwFr7Q7N7PqENAMEEBORlujToZXQiKd2jyfGAIAAYiLBMpCHNtColbAQWysYqXYnCgAEEBOJltrjaSUkUuARQrU7UQAggJjIsDwej4dIrVRBRXwBMbU7MQAggJjIDE1qtBJIqt2JAQABxERBOsfXSjhIZF1CdO1ODAAIICYKMy6uVkIAnlYCLo8oUOIREAAIIEo9Q6iVcJGE2n0Dpd10gACihmfwtRJAHpoITXYLCTRT9Cl1CEAAMb579w5kkD2tmuuEANAzoBjxp0atCxBA1IgZvK0EAh5ZQC2PgABAAFHTMyR5iJRmCrEAIICo7RmYhy4AHRuAwxMOQHyA2h4BAYAAYqFRn0QeiNcDHf0QmrlBnSwBaIGgTyM7GQACiFaeQfZUPAOdAEAAMTEMIwAQQMPKMwABNKw8AxBAw8ozAAE0rDwDEEBM2LrCQxRsBAggUNtMAFoP8A9xzzgCBBATUuv24xD2CGiI6gBAADHC5jSh7akEaE09lMAC2DAuQIABAPz9FV9oUJx6AAAAAElFTkSuQmCC\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAApCAYAAABDV7v1AAAACXBIWXMAABYlAAAWJQFJUiTwAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAB+klEQVR42mL8//8/Awi8f/9eAEhNAOIAIOZnGHhwEYgbBAUFN4A4AAHECHIo0JEGQPaBQeJAdDAR6NgCgACCORTkSHuGwQscAQKI8d27d6DQPM8wuMFGgABiAhICDIMfCAAEEBPDEAEAATRkHAoQQCwDYOdHIL4AxR+QxB2AWAGI5bFpAgggejoUpVzEBoClTwOQqscmBxBA9HLoQqADEygxACCA6JFGL1LqSBAACCB6OLSAGoYABBCto/4hMDQP4EmTBmjluAIutQABRGuHXsDhQAFo20KfWIMAAohpIBwKBAmkOBIEAAJooAr8AFI1AATQkKmZAAJoyDgUIICGjEMBAoiauf4hED9AE3tAYibD2XgHCCBqOnQCsMycgFwEAfkfsCkEdS1wFFv/cRkOEEDUjPoLaI75QIpmoCMV8MkDBNBgSqN4HQoQQNR0KKVdGgN8kgABxESvEKHUowABRM3MFACtw5HBAWyNEqC6BCwew9sUBAggajrUHkfxcgBHXU/SOAJAAA2ZAh8ggIaMQwECaMg4FCCAhoxDAQJoyDgUIICGjEMBAmjIOBQggIaMQwECaMg4FCCAhoxDAQII5NAPQ8CdHwACiAnYaAA1eC8OcodOAAggJqRGwsdB6kjQSOABgABignYbLkAbrgsHkYNBsZwIGwkECDAAOEBeUhV3hmgAAAAASUVORK5CYII=\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAArCAYAAADhXXHAAAAACXBIWXMAABYlAAAWJQFJUiTwAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAECklEQVR42mL8//8/AyHw/v17ByAFwgJAbMBAPXABiD9A6QOCgoIf8CkGCCBGXI4FOlABSDUAcQAQ8zPQBywE4glAR1/AJgkQQFgdC3QoyJH1DAMHJoICCj2kAQIIxbFAR4KieQMQ2zMMPLgISnrIDgYIIBY0BQvwOPQgUvqiFlCAYmx26oPSMXIeAQggeMjiiPqPoDQETUcfaBWE0BgNgNqFnj8agXaD3MYAEEBgx0IVP0BT+BEaDRfoFe9QdxyAhioyUAS64wFAADFBOQVYfERzh4JKHCAuAGJQqDJAY88BGlDIAByyAAEEc2wCehFCB4c6QNN/PxCvB/IvIDl4AppysGcAAogJWp7Ko0lOoEOsN6DFpj7QLQk47OcHeQ4ggFiguRElU5ETqtD0ZgCNRhgApb8LODIntppQABa6QPMuoqVdA4AAYsGi6QIZ0QlK8/5YpOuhag5CS5QNaMVkPpp6ZHl0DwoABBALzDdkhuQCHI5EB6By1B7q6ABoSDfAMjIsk4NyPD5DAAKIhcpFDDGOfgCKDWhSKyDQyEGpLAACiInKDv0IrekmQumPWNSAMtUBqDn4AEY6BwggFjJzsT4WR4KicQEWzyVA9cijOXgDWmYkBBwAAoiJxFBVwJIpQLnWAJtDoTl7ATQTX0RPEtDMSSx4ABBATGSEKnqIBhDKGEg100M0qQJSHAsQQKQ6NgDd8YQciuZgdM/6E5F24QAggJhISAIGWNoPC0jxKTRJPCSicsAKAAKIlJBFD4GDZDYbD6BnHGI1AgQQEwP9wQNyNQIE0EA4VoFcjQABRIpjP2Apesipqh0IJAucACCAmEjIHBew1EgBZDR65MlsOAkABBCpyWADeruX2NBFaviQm0kNAAKIVMcuIKeeR2pPUNTIBwggkhwLDIUD0FET9C7zA6RWPq7uiz6WUN1Aiv0AAUROQ6YAWpDro4XwfGh3/gIUG0CxPI7WWQKpFgMEEMmOhXY5HHA0E+WhGF+DHNbFJ7W8vQAQQGSVs0gNk40kaj0IbaFdIKOI+wAQQGRXCiAHAzGo6HKEOoLQuFUiUD05IQoHAAHEAo3OenIaFkiZzgGa4x3Q9F+A9m7JcSB6CfMAIIAY3717B6r+7qNJGNJz2AhHUfce3U0AAcQE9TUljWJagABsYxkAAcSEo7CPh7ZfBypUJ2CrOQECiAmpJkGv9zfQ28FINR0/tu4UQAAx4RkMk4dWpQ1ktq5IdWgCjppuIiyDAgQQ+jD9AQb8I98XsPXnKQSwEoQfR5EHH6oHCCBscwrkjLTQAmDMKQAEEBOWgt4AOqIykGAiukNBACCAiJkHi6eTAz9CS6UJuCoRgABiJDTDiFYzKVDSh8LR0wWF3gFiKiGAAAMAFa59vgPQWaUAAAAASUVORK5CYII=\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAAApCAYAAACoYAD2AAAACXBIWXMAABYlAAAWJQFJUiTwAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACU0lEQVR42mL8//8/Awi8f/9eAUglALEDw8CDC0A8QVBQ8AGIAxBAjCBHAh1oAGQfAGJ+hsEFEoEOXQAQQIzv3r1TgLp8sDkQBhwBAogJGsWD1YEgUAAQQEyDJA3iAwYAAcTEMPiBPEAAEePIj0DcCEoboIQMxBfp7UqAAGIhwoEOwBx2ASYALAk2QEsCfXo5EiCACIXkAmQHggCQ/wFINdAzJAECiJAjP5AoThMAEECEHKlAojhNAEAAEXJkPDANJiALQKvPCfR0JEAAsRChZj7QYaCyFFSPCgxE4Q8QQCxEqosfyIISIIDoXZg/BOKDpGoCCCBiQtIRi1gCWugWQhsp2NQ8hBZZG6DFFyxtg1peBcTEEkAAEXQk0OAD6GLQNIrS/kNXB1WzEOQQZMchmQvyVAJQ3QKQB/Clc4AAomV0X8DlQCyBgLe0AAggmjkSaPkGQg5EAhOgVTBWABBANM84wOgUAOIAIC6AlrHYPPQB2h7ACgACiInGDkyAlq/rgbgfiO+jVw5oyQMrAAggWofkBCwZooFURwIEEBMNQ9EBR46VxxHtONMvQAANVMucpAYKQADR0pEG1DIIIIBo6UiqtTkBAoiWjnxALYMAAmgo9BYZAAJoSDgSIICGhCMBAmhIOBIggIaEIwECaEg4EiCACDZ6gVUYtroWvdGbgKUhjK9WIUk9QACBxidBTST7wRySAAE0JKIbIICGgiM/AgQQE7523CABBwACaEiMmQMEEBN0GqIAX0doAAFo9uEAQAAxos3jFFCzHUhhdxg+jwMQYACfi5rgrcecEAAAAABJRU5ErkJggg==\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAlCAYAAADWSWD3AAAACXBIWXMAABYlAAAWJQFJUiTwAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAADDElEQVR42mL8//8/A73A+/fvFYBUABA7ALEAVPgDEB8A4g2CgoIPiDEHIIAY6eFooGNBDpwAxPEElC4E4gZ0x0M92wDyIFCuACCA4I4GSjhADXYASnygooMNoCHJT6SWj9CYeACNFRD2h8opgjwEEEAsSIoTgFgfZAHIA9RwOBkOZoCqPY9FfCIsBgACCDmkPyAZfpEaIQ408wI0ICgFB4FucYAmMweAAGJC8yEMwEJcgAIHJ1DJwaAA3AA0bwM0ySgABBA4pKHpeT+O9BUA9OWBAQxllIwKdEsCQADBQvoCnvS1H+iACWSEOk0cDGIABBDY0USk3XxQ1AAdXkBkKDvQysEgABBAyGl6IxG5uh+UYYG4AVp20gM0IjsYBAACCNnRG0gokuqB+D4o3YJCH1q0IYMHVHQ0Rn4CCCCUGpEKmecgtFq+APUYNYAjekEAEEAsaAoSyKgMkIE9lPanZXoBCCAmWMYBYpBjDaDV5keGQQwAAghWToMy1f1B6kZB9NINIIBwVeODBXwEOhijfgAIIHJKD3oCrDUxQAAhO3rBUHE0QAAxISWcA9BG+GACWGMfIICY0PgF0FbVYAAXcXW/AAKICS2bfoD2Gg4OAkfjTK4AAcSEpXwB9cNADk8E4ocDVWrgczRAADHhaKVtgFY0FwaoopmAr+UJEEAsOMQ/QJujAxXKE/ApAAggJhziDQNYlTcQat8DBBDOcQ9oH2/+AJQYBoQUAQQQE54KfwE0M9IzWQQQoxAggJgItFRADnekUylSQOywGEAAET0sBkwusNEeBWjJQs3GVSHQwROIVQwQQCSN5UF75A1ULlkWovcBCQGAAGIhcfBlApVDOBGaBEkCAAHEQsChBtAuWAKVHQvKdAlAB5PVHAYIIBboWAZyQ1sAmmapnW6RO78JxGY6bAAggBjfvXtHi3SKDTyEVhwUt9sBAgi5u6UAbZpSOylQzbEwABBAGKUHtISAFW8OZHrgIbQBvwDo2AvUjjKAACJY5EEzowM0rTvgUPYAikEOvEBJeiUGAAQYACjlIZIO1a+gAAAAAElFTkSuQmCC\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAAACXBIWXMAABYlAAAWJQFJUiTwAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAACOElEQVR42mL8//8/A63A+/fvHdCELggKCn6ghV0AAcSIzSNABxgAKZAjBKA0MgCJ6TPQFlwEYnQPH4CKHQAGxgV0DQABhOIRaAguAGJ5hsENDgJxAbKHAAII7hGgJxKA1HyGoQUCgZ7ZAGIABBDYI0BPKIDSLxDzDzGPfARiBVC+AwggJqhAwRD0BAPUzSC3MwAEEMwjCQxDF4DdDhBAjO/evQOVUOcZhjZQBAggJmhxOtSBAkAAMWGpJ4YiEAAIICaG4QEMAAKIFh75OBA+AQggkEcMqJ1egbiR3h4CCCCqZ3ZQ5QTEDXT2kAFAANEsj6B5aCKtMztAANE8s0M9BKp9FYF4Ia3sAQggupVaQM88AOIEWnkIIIDoXvyieeggtcwFCKABq0dAHoK2ky5SwzyAAGIZCE8Auw2gkhJUEORTy0yAAGIZAA8U0KLbABBALHT0RAI0FmjSjQYIIBY6eIAu4wAAAcRCYw+AYsCeDhH+ASCAQB75QGUPKEA9EE/H7HcBIIBYoIMO/lQ09P5AlIQAATRc+iMMAAE0XDxyASCAQB45MAw88gEggJiondkHCDwACCDYSOMHhqE5QAcCD4HtNgWAAILlkQVDODbAbgcIIJhHJgzUoAEVBjpAbmcACCAmpCZ1wRD0SAJs4ggggJiQ+gegKAoEpbmhkC+A2BE2pQACAAGEb8YqgAEywoI+XGRPJ8ei9x4vQEvYDdhmrAACiJHac4jQPgey53mA+Au6o6g9lwgQYAAeVY5WhEl1xAAAAABJRU5ErkJggg==\"","module.exports = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAcCAYAAAAAwr0iAAAACXBIWXMAABcRAAAXEQHKJvM/AAABaklEQVRIie1XwVHDMBDcePIHOqAD6CB+oH86IFRA/kJDMkJ/d4DpAN76OB2EDtIBpgIzR+QZjXNGRjb2h31pbEm7d16dzrOqqsBBKLMEsAJwzk7ojhJAbrV85VawAoQyGwCPPYmb2FotN0EBQhmK+GNg8hoXVsvSfzBnJl174zer5TKWzQVTALjy9i78OUlgj30sOcFFy377rgL+HN8ecI6vU38J4NaNd82URSAFsHDLXgAc3HhPJ2N28/BER+15ogTcJe6sT4XV5B7gBNB3ep9SQEalcywBXCEi15+NJYDLwGjkbQJGxeQCOA/AnYL1wFyZdykFBaTNa7MvhDIpd82zAnxyoUzWuKJ/A6r363pPoczJ0rYM+OT3PYJfEGktgkPIhLGRd94jGbPqMcjnVstcKFMOFG0IW+/9sR9oa8tx9EDhNROx2Fkt07a1/5UwJKCvQT9DFfVHDxCEMmTO2N+zg9WybkJPAeALZENrY+QVPXMAAAAASUVORK5CYII=\""],"sourceRoot":""}