{"version":3,"sources":["AqiApi.js","ActionsList.js","NoData.js","Working.js","Actions.js","Footer.js","Gauge.js","Legend.js","Summary.js","GaugePanel.js","Refresh.js","Header.js","LineChart.js","Map.js","ActionTableCell.js","UCCharacteristics.js","UCRevisionHistory.js","Matrix.js","Texture.js","WeatherCurrent.js","WeatherForecast.js","WeatherPanel.js","App.js","serviceWorker.js","index.js","UCLA_logo_wht.svg","aq_logo.svg","UCI_logo.svg","UCSB_logo.svg","UCSD_logo.svg","UCSF_logo.svg"],"names":["AqiApi","level","range","lowerLimit","upperLimit","colors","bg","cssHex","rgb","text","whoAffected","actions","outdoorWorkersVolunteers","classes","campusOperations","healthSystemOperations","athleticsOutdoorRec","outdoorCampsEvents","preK12","everyone","campus","devices","code","dataSource","deviceId","locationName","id","url","codeArr","period","codeStr","join","dTRange","this","getTimeRange","timeSpan","qs","baseUrl","Promise","resolve","reject","controller","AbortController","signal","timeoutId","setTimeout","abort","Error","fetch","method","then","response","clearTimeout","ok","json","catch","error","campusId","campuses","filter","c","deviceIds","forEach","obj","push","g","reduce","r","a","latestData","prop","pop","characteristics","pm2_5ConcMass","campusDevice","d","aqi","pm25ToAqi","value","aqiProps","getAqiLevel","location","device","pm25ConcMass","time","array","aqis","map","campusAqiAvg","Math","round","b","length","campusAqiAverage","data","cVal","date","Date","getFullYear","getMonth","toString","chartData","initVals","avg","n","averageAqi","row","i","sort","objects","onClick","L","popup","autoPanPadding","closeOnClick","keepInView","maxWidth","minWidth","maxHeight","offset","setLatLng","coordinates","slice","reverse","setContent","html","toFixed","formatDate","getPopUpHtml","openOn","markers","marker","coord","bgColor","circleMarker","fillColor","fillOpacity","radius","stroke","on","featureGroup","div","setView","tileLayer","attribution","addTo","zoomControl","setPosition","aqiMatrix","color","AQIhigh","AQIlow","Conchigh","Conclow","Concentration","parseFloat","Linear","dv","arr","l","u","getGaugeDivisor","dt","setHours","getHours","start","setDate","getDate","setMonth","setYear","getYear","toISOString","format","string","toLocaleTimeString","hour","replace","toLocaleDateString","weekday","toUpperCase","month","year","day","minute","rangeA","opt","strA","field","str","matches","match","groupId","title","urls","forecast","forecast_","forecastHourly","latest","weatherUrls","type","cache","getCampusWeatherUrls","getPeriod","periods","now","p","startTime","endTime","getWeatherData","properties","deg","floor","pa","km","m","locHref","vars","key","useStyles","makeStyles","action","display","paddingLeft","groupTitle","fontWeight","li","backgroundColor","marginBottom","ul","listStyle","marginTop","ActionsList","props","Typography","root","component","gutterBottom","variant","getGroupTitle","className","clsx","required","indexOf","container","alignItems","borderRadius","boxShadow","boxSizing","left","marginLeft","padding","position","top","width","zIndex","heading","fontSize","icon","marginRight","NoData","circularProgress","Working","show","CircularProgress","size","thickness","theme","background","flexDirection","height","overflow","breakpoints","down","minHeight","content","flex","overflowY","paddingBottom","paddingRight","paddingTop","header","requiredContainer","Actions","hasRequired","Object","keys","useState","elevate","_setElevate","Box","style","onScroll","e","target","scrollTop","group","working","fail","margin","copy","textAlign","link","textTransform","linksContainer","logo","Footer","alt","src","UCLALogo","Link","href","getColors","Gauge","animDelay","arcPadding","arcWidth","cornerRadius","formatTextValue","marginInPercent","needleBaseColor","needleColor","nrOfLevels","percent","getGaugePercent","iconContainer","cursor","visibility","infoIcon","listItem","listItemTextRoot","primaryText","secondaryText","swatchContainer","toolTip","right","Legend","items","List","dense","disablePadding","Fragment","ListItem","ListItemIcon","ListItemText","primary","secondary","Summary","_setLevel","useEffect","paragraph","description","updated","GaugePanel","Grid","item","lg","md","sm","xs","button","Refresh","handleRefresh","useTheme","small","useMediaQuery","Button","startIcon","aqLogo","up","refreshContainer","flexGrow","justifyContent","Header","_setLogo","UCILogo","UCSBLogo","UCSDLogo","UCSFLogo","document","window","open","checked","progress","radio","radioContainer","radioGroup","timeRange","radios","label","shortLabel","LineChart","_setPeriod","_setChartData","_setHeading","_setTimeRange","_setFontSize","lineWidth","_setLineWidth","slantedText","_setSlantedText","_setTitle","_setFail","_setWorking","showRadios","_setShowRadios","getOpenMapAqiChartData","codes","data_","processChartData","trA","trStr","formatTimeRange","colVals","formatChartDataTime","unshift","console","finally","refresh","chartType","options","axisTitlesPosition","chartArea","fontName","hAxis","slantedTextAngle","textStyle","legend","vAxis","minorGridlines","interval","animation","duration","easing","startup","rootProps","FormControl","RadioGroup","aria-label","name","FormControlLabel","control","Radio","handleChange","mapHeading","textShadow","aqiLayer","Map","_setMap","getMap","locations","hasLayer","removeLayer","getDeviceMarkers","fitBounds","getBounds","tableCell","verticalAlign","ActionTableCell","TableCell","colSpan","j","UCCharacteristics","revs","version","RevisionHistory","Table","table","TableHead","TableRow","TableBody","rev","desc","lineHeight","tableWrapper","overflowX","Matrix","stickyHeader","align","category","whiteSpace","backgroundSize","opacity","container_1","container_2","earth","jupiter","bottom","mars","pluto_1","pluto_2","sun","venus","Texture","aria-hidden","condition","letterSpacing","containerAtmos","containerTemp","backgroundPosition","backgroundRepeat","borderTopLeftRadius","borderTopRightRadius","temp","WeatherCurrent","_setDesc","_setError","humidity","_setHumidity","imgUrl","_setImgUrl","pressure","_setPressure","_setTemp","_setVisibility","wind","_setWind","getTempWind","tempWind","temperature","shortForecast","wA","windDirection","windSpeed","getPressHumid","pressHumid","barometricPressure","paToInHg","mToMi","relativeHumidity","backgroundImage","tempContainer","Boolean","message","arrowHi","arrowLo","list","WeatherForecast","_setPeriods","getWeatherForecast","componenent","primaryTypographyProps","isDaytime","detailedForecast","WeatherPanel","gridContainer","urlParams","getUrlParams","otherCampus","toLowerCase","alert","App","_setAqi","_setLocations","_setRefresh","_setUpdated","getOpenMapAqiData","spacing","hostname","ReactDOM","render","StrictMode","getElementById","navigator","serviceWorker","ready","registration","unregister","module","exports"],"mappings":"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","file":"static/js/main.61a02fec.chunk.js","sourcesContent":["import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'\r\nimport L from 'leaflet'\r\n\r\nclass AqiApi {\r\n static get aqiMatrix () {\r\n return [\r\n {\r\n level: 'Good',\r\n range: '0‐50',\r\n lowerLimit: 0,\r\n upperLimit: 50,\r\n colors: {\r\n bg: {\r\n cssHex: 'limegreen',\r\n rgb: '50, 205, 50'\r\n },\r\n text: 'black'\r\n },\r\n whoAffected: 'No individuals expected to be affected.',\r\n actions: {\r\n outdoorWorkersVolunteers: [\r\n 'No Action Anticipated'\r\n ],\r\n classes: [\r\n 'No Action Anticipated'\r\n ],\r\n campusOperations: [\r\n 'No Action Anticipated'\r\n ],\r\n healthSystemOperations: [\r\n 'No Action Anticipated'\r\n ],\r\n athleticsOutdoorRec: [\r\n 'No Action Anticipated'\r\n ],\r\n outdoorCampsEvents: [\r\n 'No Action Anticipated'\r\n ],\r\n preK12: [\r\n 'No Action Anticipated'\r\n ]\r\n }\r\n },\r\n {\r\n level: 'Moderate',\r\n range: '51‐100',\r\n lowerLimit: 51,\r\n upperLimit: 100,\r\n colors: {\r\n bg: {\r\n cssHex: 'yellow',\r\n rgb: '255, 255, 0'\r\n },\r\n text: 'black'\r\n },\r\n whoAffected: 'Unusually sensitive individuals (people with lung and heart disease) may be affected.',\r\n actions: {\r\n outdoorWorkersVolunteers: [\r\n 'Unusually sensitive people may require work accommodations.'\r\n ],\r\n classes: [\r\n 'No Action Anticipated'\r\n ],\r\n campusOperations: [\r\n 'No Action Anticipated'\r\n ],\r\n healthSystemOperations: [\r\n 'In patient care areas, consider modifying filtered mechanical ventilation systems and/or implementing other controls to reduce outdoor air intake.'\r\n ],\r\n athleticsOutdoorRec: [\r\n 'No Action Anticipated'\r\n ],\r\n outdoorCampsEvents: [\r\n 'No Action Anticipated'\r\n ],\r\n preK12: [\r\n 'No Action Anticipated'\r\n ]\r\n }\r\n },\r\n {\r\n level: 'Unhealthy for Sensitive Groups',\r\n range: '101‐150',\r\n lowerLimit: 101,\r\n upperLimit: 150,\r\n colors: {\r\n bg: {\r\n cssHex: 'orange',\r\n rgb: '255, 165, 0'\r\n },\r\n text: 'black'\r\n },\r\n whoAffected: 'Sensitive groups including people with heart or lung disease, older adults, pregnant women, and children affected.',\r\n actions: {\r\n outdoorWorkersVolunteers: [\r\n 'Workers in sensitive groups may require work accommodations.'\r\n ],\r\n classes: [\r\n 'No Action Anticipated'\r\n ],\r\n campusOperations: [\r\n 'Consider closing building doors and windows to reduce outdoor air intake'\r\n ],\r\n healthSystemOperations: [\r\n 'As feasible, modify filtered mechanical ventilation systems to reduce outdoor air intake in patient care areas.'\r\n ],\r\n athleticsOutdoorRec: [\r\n 'Medical/athletic staff/outdoor recreation staff should consult with individuals who fall into the sensitive groups about participation in practice, competition, and/or outdoor events.'\r\n ],\r\n outdoorCampsEvents: [\r\n 'At higher end of range, consider moving activities indoors.'\r\n ],\r\n preK12: [\r\n 'For longer activities such as athletic practice, take more breaks and do less intense activities.'\r\n ]\r\n }\r\n },\r\n {\r\n level: 'Unhealthy',\r\n range: '151‐200',\r\n lowerLimit: 151,\r\n upperLimit: 200,\r\n colors: {\r\n bg: {\r\n cssHex: 'red',\r\n rgb: '255, 0, 0'\r\n },\r\n text: 'white'\r\n },\r\n whoAffected: 'Everyone affected.',\r\n actions: {\r\n outdoorWorkersVolunteers: [\r\n 'Limit outdoor work and prolonged or heavy exertion if practicable.',\r\n 'Reassign employees who work outdoors for more than one hour or provide N95 respirators for voluntary use.'\r\n ],\r\n classes: [\r\n 'Consider academic accommodations for students and faculty with pre‐existing health conditions.',\r\n 'Consider cancelling or moving outdoor classes indoors.'\r\n ],\r\n campusOperations: [\r\n 'Consider making N95 respirators and use/care guidance available for voluntary use.',\r\n 'Consider increasing campus-managed shuttle/bus service.',\r\n 'As feasible, modify filtered mechanical ventilation systems to reduce outdoor air intake.' \r\n ],\r\n healthSystemOperations: [\r\n 'Consider making N95 respirators and use/care guidance available for voluntary use.',\r\n 'In patient care areas, consider monitoring indoor air quality and implement mitigation actions if indoor AQI is within this range.' \r\n ],\r\n athleticsOutdoorRec: [\r\n 'Medical/athletic training staff should closely monitor the health of all athletes in practice and competition. Modifications to athletic activities should be considered and implemented as necessary.',\r\n 'Shorten/modify outdoor recreational activity to limit prolonged or heavy exertion.' \r\n ],\r\n outdoorCampsEvents: [\r\n 'Consider cancellation of more intense outdoor events or move events indoors.'\r\n ],\r\n preK12: [\r\n 'For all outdoor activities, take more breaks and do less intense activities.',\r\n 'Consider moving longer or more intense activities indoors or rescheduling them to another day or time.'\r\n ]\r\n }\r\n },\r\n {\r\n level: 'Very Unhealthy',\r\n range: '201‐300 ',\r\n lowerLimit: 201,\r\n upperLimit: 300,\r\n colors: {\r\n bg: {\r\n cssHex: '#8f3f97',\r\n rgb: '143, 63, 151'\r\n },\r\n text: 'white'\r\n },\r\n whoAffected: 'Everyone affected.',\r\n actions: {\r\n outdoorWorkersVolunteers: [\r\n 'Suspend outdoor work. If work is absolutely necessary, provide N‐95 respirators for voluntary use.'\r\n ],\r\n classes: [\r\n 'Per local procedures and in consultation with the divisional Academic Senate Chair or designee, cancel or restructure classes if current AQI levels have maintained in this range and are expected to continue (academic activities that support clinical operations or research may be excluded from cancellation).'\r\n ],\r\n campusOperations: [\r\n 'To the extent possible, curtail campus operations.',\r\n 'Consider monitoring indoor air quality and implement mitigation actions if indoor AQI is within this range.'\r\n ],\r\n healthSystemOperations: [\r\n 'To the extent possible, curtail health system operations.',\r\n 'Consider monitoring indoor air quality and implement mitigation actions if indoor AQI is within this range.'\r\n ],\r\n athleticsOutdoorRec: [\r\n 'Outdoor athletic activities should be moved indoors or delayed, postponed, or relocated.',\r\n 'Cancel or move indoors outdoor recreational activities.'\r\n ],\r\n outdoorCampsEvents: [\r\n 'Cancel outdoor events involving activity (e.g., sports).',\r\n 'Consider cancellation of outdoor events that do not involve activity (e.g., concerts).'\r\n ],\r\n preK12: [\r\n 'Close school if current AQI levels have maintained in this range and are expected to continue.'\r\n ]\r\n }\r\n },\r\n {\r\n level: 'Very Hazardous',\r\n range: '301‐500',\r\n lowerLimit: 301,\r\n upperLimit: 500,\r\n colors: {\r\n bg: {\r\n cssHex: '#7e0023',\r\n rgb: '126, 0, 35'\r\n },\r\n text: 'white'\r\n },\r\n whoAffected: 'Everyone affected.',\r\n actions: {\r\n outdoorWorkersVolunteers: [\r\n 'Suspend outdoor work. If work is absolutely necessary, provide N‐95 respirators for voluntary use.'\r\n ],\r\n classes: [\r\n 'Per local procedures and in consultation with the divisional Academic Senate Chair or designee, cancel or restructure classes if current AQI levels have maintained in this range and are expected to continue (academic activities that support clinical operations or research may be excluded from cancellation).'\r\n ],\r\n campusOperations: [\r\n 'To the extent possible, curtail campus operations.',\r\n 'Consider monitoring indoor air quality and implement mitigation actions if indoor AQI is within this range.'\r\n ],\r\n healthSystemOperations: [\r\n 'To the extent possible, curtail health system operations.',\r\n 'Consider monitoring indoor air quality and implement mitigation actions if indoor AQI is within this range.'\r\n ],\r\n athleticsOutdoorRec: [\r\n 'Cancel or move indoors all outdoor athletic and recreation events/activities.',\r\n 'Consider cancellation of indoor events/activities based on indoor air quality measurements.'\r\n ],\r\n outdoorCampsEvents: [\r\n 'Cancel all outdoor events and camp activities.',\r\n 'Consider cancellation of indoor camps that require participants or families to travel to and from campus.'\r\n ],\r\n preK12: [\r\n 'Close school if current AQI levels have maintained in this range and are expected to continue.'\r\n ]\r\n }\r\n },\r\n {\r\n level: 'Beyond the AQI',\r\n range: '>500',\r\n lowerLimit: 501,\r\n upperLimit: null,\r\n colors: {\r\n bg: {\r\n cssHex: 'Black',\r\n rgb: '0, 0, 0'\r\n },\r\n text: 'white'\r\n },\r\n whoAffected: 'Everyone affected.',\r\n actions: {\r\n everyone: [\r\n 'Follow recommendations for the Hazardous Category.',\r\n 'Suspend outdoor work and activities. If outdoor work is absolutely necessary, N95 respirators are mandatory and require training and fit testing.'\r\n ]\r\n }\r\n }\r\n ]\r\n }\r\n\r\n static get campuses () {\r\n return [\r\n {\r\n campus: 'Los Angeles',\r\n devices: [\r\n {\r\n code: 'DZDZD2653',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DZDZD2653',\r\n locationName: 'Anderson'\r\n },\r\n {\r\n code: 'DKDJZ8833',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DKDJZ8833',\r\n locationName: 'Sycamore Court Apartments'\r\n },\r\n {\r\n code: 'DJKJK2078',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DJKJK2078',\r\n locationName: 'Sproul Hall'\r\n },\r\n {\r\n code: 'DKUCV1988',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DKUCV1988',\r\n locationName: 'Terasaki Life Sciences'\r\n },\r\n {\r\n code: 'DYSEV5920',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DYSEV5920',\r\n locationName: 'UCLA Ronald Reagan Hospital'\r\n }\r\n ],\r\n id: 'ucla',\r\n url: 'https://www.ucla.edu/'\r\n },\r\n {\r\n campus: 'San Diego',\r\n devices: [\r\n {\r\n code: 'DKILC3507',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DKILC3507',\r\n locationName: 'RIMAC Arena'\r\n },\r\n {\r\n code: 'DBWVN5705',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DBWVN5705',\r\n locationName: 'Price Center'\r\n },\r\n {\r\n code: 'DTTCR6730',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DTTCR6730',\r\n locationName: 'CRSF (EHS Bldg)'\r\n },\r\n {\r\n code: 'DZQII2860',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DZQII2860',\r\n locationName: 'Nierenberg Hall'\r\n }\r\n ],\r\n id: 'ucsd',\r\n url: 'https://ucsd.edu/'\r\n },\r\n {\r\n campus: 'San Francisco',\r\n devices: [\r\n {\r\n code: 'DNQLI9651',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DNQLI9651',\r\n locationName: 'UCSF Parnassus'\r\n },\r\n {\r\n code: 'DSSIJ1361',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DSSIJ1361',\r\n locationName: 'UCSF Mission Bay'\r\n },\r\n {\r\n code: 'DUFGE0229',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DUFGE0229',\r\n locationName: 'UCSF Mount Zion'\r\n },\r\n {\r\n code: 'DKYUH8186',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DKYUH8186',\r\n locationName: 'UCSF Hunter\\'s Point'\r\n }\r\n ],\r\n id: 'ucsf',\r\n url: 'https://ucsf.edu/'\r\n },\r\n {\r\n campus: 'Santa Barbara',\r\n devices: [\r\n {\r\n code: 'DVCBA7399',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DVCBA7399',\r\n locationName: 'CNSI Roof Top'\r\n },\r\n {\r\n code: 'DNRYQ4646',\r\n dataSource: 'Clarity Node',\r\n deviceId: 'DNRYQ4646',\r\n locationName: 'SRB Roof Top'\r\n }\r\n ],\r\n id: 'ucsb',\r\n url: 'https://ucsb.edu/'\r\n }\r\n ]\r\n }\r\n\r\n static getOpenMapAqiChartData (codeArr, period) {\r\n const baseUrl = 'https://openmap.clarity.io/api/measurements'\r\n const codeStr = period === 'year' ? codeArr[0] : codeArr.join()\r\n const dTRange = this.getTimeRange(period)\r\n let timeSpan = '×pan='\r\n if (period === 'hour') {\r\n timeSpan = ''\r\n } else if (period === 'day') {\r\n timeSpan += 'hour'\r\n } else {\r\n timeSpan += 'day'\r\n }\r\n let qs = 'startTime=' + dTRange[0] + '&endTime=' + dTRange[1] + '&deviceId=' + codeStr + '&aqi=pm2_5ConcMass'\r\n qs += timeSpan !== '' ? timeSpan : ''\r\n const url = baseUrl + '?' + qs\r\n return new Promise((resolve, reject) => {\r\n const controller = new AbortController()\r\n const signal = controller.signal\r\n const timeoutId = setTimeout(() => {\r\n controller.abort()\r\n reject(new Error('getAqiData request timed out'))\r\n }, 30000)\r\n const opt = {\r\n method: 'GET'\r\n }\r\n fetch(url, { ...opt, ...signal })\r\n .then(response => {\r\n clearTimeout(timeoutId)\r\n if (response.ok) {\r\n response.json()\r\n .then(json => {\r\n return resolve(json)\r\n })\r\n .catch(error => {\r\n return reject(error)\r\n })\r\n } else {\r\n reject(new Error('getAqiData response not ok'))\r\n }\r\n })\r\n .catch(error => {\r\n clearTimeout(timeoutId)\r\n return reject(error)\r\n })\r\n })\r\n }\r\n\r\n static getOpenMapAqiData (campusId) {\r\n const baseUrl = 'https://openmap.clarity.io/api/measurements'\r\n const campus = AqiApi.campuses.filter(c => c.id === campusId)[0]\r\n const deviceIds = []\r\n campus.devices.forEach(obj => {\r\n deviceIds.push(obj.deviceId)\r\n })\r\n let qs = '?deviceId=' + deviceIds.join()\r\n const dTRange = this.getTimeRange('hour')\r\n qs += '&startTime=' + dTRange[0]\r\n qs += '×pan=hour&aqi=pm2_5ConcMass'\r\n const url = baseUrl + qs\r\n return new Promise((resolve, reject) => {\r\n const controller = new AbortController()\r\n const signal = controller.signal\r\n const timeoutId = setTimeout(() => {\r\n controller.abort()\r\n reject(new Error('getOpenMapAqiData request timed out'))\r\n }, 15000)\r\n const opt = {\r\n method: 'GET'\r\n }\r\n fetch(url, { ...opt, ...signal })\r\n .then(response => {\r\n clearTimeout(timeoutId)\r\n if (response.ok) {\r\n response.json()\r\n .then(json => {\r\n const g = json.reduce((r, a) => {\r\n r[a.deviceId] = [...r[a.deviceId] || [], a]\r\n return r\r\n }, {})\r\n const latestData = []\r\n for (const prop in g) {\r\n latestData.push(g[prop].pop())\r\n }\r\n const devices = []\r\n latestData.forEach(obj => {\r\n if (obj.characteristics.pm2_5ConcMass) {\r\n const campusDevice = campus.devices.filter(d => d.deviceId === obj.deviceId)[0]\r\n const aqi = this.pm25ToAqi(obj.characteristics.pm2_5ConcMass.value)\r\n const aqiProps = this.getAqiLevel(aqi)\r\n const deviceId = campusDevice.deviceId\r\n const location = obj.device.location\r\n const locationName = campusDevice.locationName\r\n const pm25ConcMass = obj.characteristics.pm2_5ConcMass.value\r\n const time = obj.time\r\n devices.push({\r\n aqi: aqi,\r\n aqiProps: aqiProps,\r\n deviceId: deviceId,\r\n location: location,\r\n locationName: locationName,\r\n pm25ConcMass: pm25ConcMass,\r\n time: time\r\n })\r\n }\r\n })\r\n const aqis = devices.map(obj => obj.aqi)\r\n const getAverage = (array) => array.reduce((a, b) => a + b) / array.length\r\n const campusAqiAvg = Math.round(getAverage(aqis))\r\n return resolve({\r\n campusAqiAverage: campusAqiAvg,\r\n devices: devices\r\n })\r\n })\r\n .catch(error => {\r\n return reject(error)\r\n })\r\n } else {\r\n reject(new Error('getOpenMapAqiData response not ok'))\r\n }\r\n })\r\n .catch(error => {\r\n clearTimeout(timeoutId)\r\n return reject(error)\r\n })\r\n })\r\n }\r\n\r\n static processChartData (data, period) {\r\n const data_ = data.filter(obj => typeof (obj.characteristics.pm2_5ConcMass) !== 'undefined')\r\n const g = data_.reduce((r, a) => {\r\n let cVal\r\n if (period === 'year') {\r\n let date = new Date(a.time)\r\n date = new Date(date.getFullYear(), date.getMonth(), 1, 0, 0)\r\n cVal = date.toString()\r\n } else {\r\n cVal = a.time\r\n }\r\n r[cVal] = [...r[cVal] || [], a]\r\n return r\r\n }, {})\r\n let chartData = []\r\n const initVals = { avg: 0, n: 0 }\r\n for (const prop in g) {\r\n const avg = g[prop].reduce(AqiApi.averageAqi, initVals).avg\r\n chartData.push([prop, Math.round(avg)])\r\n }\r\n chartData.forEach((row, i) => {\r\n chartData[i][0] = new Date(row[0])\r\n })\r\n chartData = chartData.sort((a, b) => a[0] - b[0])\r\n return chartData\r\n }\r\n\r\n static getDeviceMarkers (objects, map) {\r\n const getMarker = (coord, bgColor) => {\r\n return L.circleMarker(coord, {\r\n fillColor: bgColor,\r\n fillOpacity: 0.7,\r\n radius: 80,\r\n stroke: false\r\n })\r\n }\r\n const getPopUpHtml = (obj) => {\r\n let html = '
'\r\n html += '

' + obj.locationName + '

'\r\n html += '
AQI: ' + Math.round(obj.aqi) + ' - ' + obj.aqiProps.level + '
'\r\n html += ''\r\n html += ''\r\n html += ''\r\n const formattedDate = this.formatDate(new Date(obj.time))\r\n html += ''\r\n html += '
Device ID' + obj.deviceId + '
PM2.5' + obj.pm25ConcMass.toFixed(1) + ' µg/m3
Updated' + formattedDate + '
'\r\n html += '
'\r\n html += ''\r\n html += '
'\r\n html += '
'\r\n return html\r\n }\r\n const onClick = (obj, map) => {\r\n L.popup({\r\n autoPanPadding: [64, 64],\r\n closeOnClick: true,\r\n keepInView: true,\r\n maxWidth: 256,\r\n minWidth: 240,\r\n maxHeight: 288,\r\n offset: [0, 0]\r\n })\r\n .setLatLng(obj.location.coordinates.slice().reverse())\r\n .setContent(getPopUpHtml(obj))\r\n .openOn(map)\r\n }\r\n const markers = []\r\n objects.forEach(obj => {\r\n if (obj.aqiProps) {\r\n const marker = getMarker(obj.location.coordinates.slice().reverse(), obj.aqiProps.colors.bg.cssHex)\r\n marker.on('click', () => {\r\n onClick(obj, map)\r\n })\r\n markers.push(marker)\r\n }\r\n })\r\n const featureGroup = L.featureGroup(markers)\r\n return (featureGroup)\r\n }\r\n\r\n static getMap (div) {\r\n const map = L.map(div)\r\n .setView([34.0700461, -118.4470284], 15)\r\n\r\n L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\r\n attribution: '© OpenStreetMap'\r\n }).addTo(map)\r\n\r\n map.zoomControl.setPosition('topright')\r\n\r\n return map\r\n }\r\n\r\n static getAqiLevel (aqi) {\r\n let level = null\r\n if (aqi) {\r\n if (aqi > 500) {\r\n level = this.aqiMatrix.filter(obj => obj.upperLimit === null)[0]\r\n } else {\r\n level = this.aqiMatrix.filter(obj => aqi >= obj.lowerLimit && aqi <= obj.upperLimit)[0]\r\n }\r\n }\r\n return level\r\n }\r\n\r\n static getAqiProps (aqi) {\r\n const level = this.aqiMatrix.filter(obj => aqi >= obj.lowerLimit && aqi <= obj.upperLimit)[0]\r\n return {\r\n aqi: aqi,\r\n bgColor: level.bgColor,\r\n color: level.color,\r\n level: level.level\r\n }\r\n }\r\n\r\n static averageAqi ({ avg, n }, obj) {\r\n return {\r\n avg: (AqiApi.pm25ToAqi(obj.characteristics.pm2_5ConcMass.value) + n * avg) / (n + 1),\r\n n: n + 1\r\n }\r\n }\r\n\r\n static averagePm25ConcMass ({ avg, n }, obj) {\r\n return {\r\n avg: (obj.characteristics.pm2_5ConcMass.value + n * avg) / (n + 1),\r\n n: n + 1\r\n }\r\n }\r\n\r\n static Linear (AQIhigh, AQIlow, Conchigh, Conclow, Concentration) {\r\n var linear\r\n var Conc = parseFloat(Concentration)\r\n var a\r\n a = ((Conc - Conclow) / (Conchigh - Conclow)) * (AQIhigh - AQIlow) + AQIlow\r\n linear = Math.round(a)\r\n return linear\r\n }\r\n\r\n static pm25ToAqi (c) {\r\n let index\r\n if (c >= 0 && c < 12.1) {\r\n index = this.Linear(50, 0, 12, 0, c)\r\n } else if (c >= 12.1 && c < 35.5) {\r\n index = this.Linear(100, 51, 35.4, 12.1, c)\r\n } else if (c >= 35.5 && c < 55.5) {\r\n index = this.Linear(150, 101, 55.4, 35.5, c)\r\n } else if (c >= 55.5 && c < 150.5) {\r\n index = this.Linear(200, 151, 150.4, 55.5, c)\r\n } else if (c >= 150.5 && c < 250.5) {\r\n index = this.Linear(300, 201, 250.4, 150.5, c)\r\n } else if (c >= 250.5 && c < 350.5) {\r\n index = this.Linear(400, 301, 350.4, 250.5, c)\r\n } else if (c >= 350.5 && c < 500.5) {\r\n index = this.Linear(500, 401, 500.4, 350.5, c)\r\n } else {\r\n index = null\r\n }\r\n return index\r\n }\r\n\r\n static getGaugeDivisor (aqi) {\r\n let dv\r\n if (aqi === 0) {\r\n dv = 1\r\n } else if (aqi >= 0 && aqi < 210) {\r\n dv = 311\r\n } else if (aqi >= 500) {\r\n dv = 500\r\n } else if (aqi >= 210 && aqi < 500) {\r\n const arr = [\r\n [210, 307],\r\n [220, 314],\r\n [230, 321],\r\n [240, 327],\r\n [250, 333],\r\n [260, 339],\r\n [270, 345],\r\n [280, 350],\r\n [290, 355],\r\n [300, 360],\r\n [310, 368],\r\n [320, 376],\r\n [330, 384],\r\n [340, 392],\r\n [350, 400],\r\n [360, 407],\r\n [370, 415],\r\n [380, 422],\r\n [390, 429],\r\n [400, 436],\r\n [410, 443],\r\n [420, 450],\r\n [430, 457],\r\n [440, 463],\r\n [450, 470],\r\n [460, 476],\r\n [470, 482],\r\n [480, 488],\r\n [490, 494],\r\n [500, 500]\r\n ]\r\n for (let i = 0; i < arr.length; i++) {\r\n const l = arr[i][0]\r\n const u = arr[i + 1][0]\r\n if (aqi === l) {\r\n dv = arr[i][1]\r\n break\r\n } else if (aqi >= l && aqi < u) {\r\n dv = arr[i + 1][1]\r\n break\r\n }\r\n }\r\n }\r\n return dv\r\n }\r\n\r\n static getGaugePercent (aqi) {\r\n let prct\r\n if (aqi === 0) {\r\n prct = 0\r\n } else if (aqi >= 500) {\r\n prct = 1.01\r\n } else {\r\n prct = aqi / this.getGaugeDivisor(aqi)\r\n }\r\n return prct\r\n }\r\n\r\n static getTimeRange (period) {\r\n let dt = new Date()\r\n dt.setHours(dt.getHours() - 1)\r\n let start = new Date()\r\n if (period === 'hour') {\r\n start.setHours(dt.getHours() - 1)\r\n } else if (period === 'day') {\r\n start.setHours(dt.getHours() -25)\r\n } else if (period === 'week') {\r\n start.setDate(dt.getDate() - 8)\r\n } else if (period === 'month') {\r\n start.setMonth(dt.getMonth() - 1)\r\n } else if (period === 'year') {\r\n start.setYear(dt.getYear() - 1)\r\n }\r\n start = start.toISOString()\r\n const end = dt.toISOString()\r\n return [start, end]\r\n }\r\n\r\n static formatChartDataTime (time, format) {\r\n const d = new Date(time)\r\n let string\r\n if (format === 'hour') {\r\n string = d.toLocaleTimeString('en-US', {\r\n hour: '2-digit'\r\n }).replace(/^0+|\\s+|M/g, '')\r\n } else if (format === 'day') {\r\n string = d.toLocaleDateString('en-US', {\r\n weekday: 'short'\r\n }).toUpperCase()\r\n } else if (format === 'date') {\r\n string = d.toLocaleDateString('en-US', {\r\n date: 'short'\r\n }).replace(/\\/(\\d{4})/, '')\r\n } else if (format === 'month') {\r\n string = d.toLocaleDateString('en-US', {\r\n month: 'short'\r\n }).toUpperCase()\r\n }\r\n return string\r\n }\r\n\r\n static formatDate (date) {\r\n var opt = {\r\n weekday: 'short',\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n hour: '2-digit',\r\n minute: '2-digit'\r\n }\r\n return date.toLocaleTimeString('en-us', opt)\r\n }\r\n\r\n static formatTimeRange (rangeA, period) {\r\n let opt\r\n if (period === 'day') {\r\n opt = {\r\n day: 'numeric',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n month: 'numeric',\r\n weekday: 'short',\r\n year: '2-digit'\r\n }\r\n } else if (period === 'week') {\r\n opt = {\r\n day: 'numeric',\r\n month: 'numeric',\r\n weekday: 'short',\r\n year: 'numeric'\r\n }\r\n } else if (period === 'month') {\r\n opt = {\r\n day: 'numeric',\r\n month: 'numeric',\r\n weekday: 'short',\r\n year: 'numeric'\r\n }\r\n } else if (period === 'year') {\r\n opt = {\r\n day: 'numeric',\r\n month: 'short',\r\n year: 'numeric'\r\n }\r\n }\r\n rangeA.forEach((dt, i) => {\r\n rangeA[i] = dt.toLocaleDateString('en-us', opt)\r\n })\r\n const rangeStr = rangeA.join(' to ')\r\n return rangeStr\r\n }\r\n\r\n static formatAddress (obj) {\r\n const strA = []\r\n for (const prop in obj) {\r\n ['ADD1', 'ADD2', 'CTYSTZP'].forEach(field => {\r\n if (prop === field && obj[prop] !== null) {\r\n strA.push(obj[prop])\r\n }\r\n })\r\n }\r\n if (strA.length) {\r\n return strA.join('
')\r\n } else {\r\n return null\r\n }\r\n }\r\n\r\n static formatTelephone (str) {\r\n const regEx = /(?:(?:\\+?([1-9]|[0-9][0-9]|[0-9][0-9][0-9])\\s*(?:[.-]\\s*)?)?(?:\\(\\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\\s*\\)|([0-9][1-9]|[0-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\\s*(?:[.-]\\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\\s*(?:[.-]\\s*)?([0-9]{4})(?:\\s*(?:#|x\\.?|ext\\.?|extension)\\s*(\\d+))?/g;\r\n if (str && str.length) {\r\n var matches = str.match(regEx)\r\n if (matches && matches.length) {\r\n matches.forEach(match => {\r\n str = str.replace(match, '' + match + '')\r\n })\r\n return str\r\n } else {\r\n return str\r\n }\r\n } else {\r\n return null\r\n }\r\n }\r\n\r\n static getGroupTitle (groupId) {\r\n let title\r\n switch (groupId) {\r\n case 'outdoorWorkersVolunteers':\r\n title = 'Outdoor Workers/Volunteers'\r\n break\r\n case 'classes':\r\n title = 'Classes'\r\n break\r\n case 'campusOperations':\r\n title = 'Campus Operations'\r\n break\r\n case 'healthSystemOperations':\r\n title = 'Health System Operations'\r\n break\r\n case 'athleticsOutdoorRec':\r\n title = 'Athletics & Outdoor Rec'\r\n break\r\n case 'outdoorCampsEvents':\r\n title = 'Outdoor Camps/Events'\r\n break\r\n case 'preK12':\r\n title = 'Pre‐K‐12'\r\n break\r\n default:\r\n title = ''\r\n }\r\n return title\r\n }\r\n\r\n static get weatherUrls () {\r\n return [\r\n {\r\n campus: 'Irvine',\r\n id: 'uci',\r\n urls: {\r\n forecast: 'https://api.weather.gov/gridpoints/SGX/38,57/forecast',\r\n forecast_: 'https://api.weather.gov/gridpoints/SGX/38,58/forecast',\r\n forecastHourly: 'https://api.weather.gov/gridpoints/SGX/38,58/forecast/hourly',\r\n latest: 'https://api.weather.gov/stations/KSNA/observations/latest'\r\n }\r\n },\r\n {\r\n campus: 'Los Angeles',\r\n id: 'ucla',\r\n urls: {\r\n forecast: 'https://api.weather.gov/gridpoints/LOX/147,46/forecast',\r\n forecast_: 'https://api.weather.gov/gridpoints/LOX/147,46/forecast',\r\n forecastHourly: 'https://api.weather.gov/gridpoints/LOX/147,46/forecast/hourly',\r\n latest: 'https://api.weather.gov/stations/KLAX/observations/latest'\r\n }\r\n },\r\n {\r\n campus: 'San Diego',\r\n id: 'ucsd',\r\n urls: {\r\n forecast: 'https://api.weather.gov/gridpoints/SGX/54,21/forecast',\r\n forecast_: 'https://api.weather.gov/gridpoints/SGX/54,20/forecast',\r\n forecastHourly: 'https://api.weather.gov/gridpoints/SGX/54,20/forecast/hourly',\r\n latest: 'https://api.weather.gov/stations/E3170/observations/latest'\r\n }\r\n },\r\n {\r\n campus: 'San Francisco',\r\n id: 'ucsf',\r\n urls: {\r\n forecast: 'https://api.weather.gov/gridpoints/MTR/86,126/forecast',\r\n forecast_: 'https://api.weather.gov/gridpoints/MTR/82,104/forecast',\r\n forecastHourly: 'https://api.weather.gov/gridpoints/MTR/82,104/forecast/hourly',\r\n latest: 'https://api.weather.gov/stations/SFOC1/observations/latest'\r\n }\r\n },\r\n {\r\n campus: 'Santa Barbara',\r\n id: 'ucsb',\r\n urls: {\r\n forecast: 'https://api.weather.gov/gridpoints/LOX/100,71/forecast',\r\n forecast_: 'https://api.weather.gov/gridpoints/LOX/100,71/forecast',\r\n forecastHourly: 'https://api.weather.gov/gridpoints/LOX/100,71/forecast/hourly',\r\n latest: 'https://api.weather.gov/stations/KSBA/observations/latest'\r\n }\r\n }\r\n ]\r\n }\r\n\r\n static getCampusWeatherUrls (campusId) {\r\n const campus = this.weatherUrls.filter(u => u.id === campusId)\r\n return campus[0] || null\r\n }\r\n\r\n static getWeatherData (campusId, type) {\r\n const opt = {\r\n cache: 'no-cache'\r\n }\r\n const controller = new AbortController()\r\n const signal = controller.signal\r\n const campus = this.getCampusWeatherUrls(campusId)\r\n const url = type === 'forecast'\r\n ? campus.urls.forecast_ : type === 'latest'\r\n ? campus.urls.latest : type === 'hourly'\r\n ? campus.urls.forecastHourly\r\n : campus.urls.forecast_\r\n return new Promise((resolve, reject) => {\r\n const timeoutId = setTimeout(() => {\r\n controller.abort()\r\n reject(new Error('getWeatherData request timed out'))\r\n }, 10000)\r\n fetch(url, { ...opt, ...signal })\r\n .then(response => {\r\n clearTimeout(timeoutId)\r\n response.json()\r\n .then(json => {\r\n resolve(json)\r\n })\r\n .catch(error => {\r\n reject(error)\r\n })\r\n })\r\n .catch(error => {\r\n clearTimeout(timeoutId)\r\n reject(error)\r\n })\r\n })\r\n }\r\n\r\n static getTempWind (campusId) {\r\n const getPeriod = (periods) => {\r\n const now = new Date()\r\n const p = periods.filter(p => now >= new Date(p.startTime) && now < new Date(p.endTime))\r\n return p[0]\r\n }\r\n return new Promise((resolve, reject) => {\r\n this.getWeatherData(campusId, 'hourly')\r\n .then(data => {\r\n if (data.properties) {\r\n resolve(getPeriod(data.properties.periods))\r\n } else {\r\n this.getWeatherData(campusId, 'forecast')\r\n .then(data => {\r\n if (data.properties) {\r\n resolve(getPeriod(data.properties.period))\r\n } else {\r\n reject(new Error('GetTempWind using forecastHourly service returned no data'))\r\n }\r\n })\r\n .catch(() => {\r\n reject(new Error('GetTempWind using forecast service error'))\r\n })\r\n }\r\n })\r\n .catch(() => {\r\n reject(new Error('GetTempWind forecastHourly error'))\r\n })\r\n })\r\n }\r\n\r\n static getPressHumid (campusId) {\r\n return new Promise((resolve, reject) => {\r\n this.getWeatherData(campusId, 'latest')\r\n .then(data => {\r\n if (data.properties) {\r\n resolve(data.properties)\r\n } else {\r\n reject(new Error('GetPressHumid returned no data'))\r\n }\r\n })\r\n .catch(() => {\r\n reject(new Error('GetPressHumid error'))\r\n })\r\n })\r\n }\r\n\r\n static getWeatherForecast (campusId) {\r\n return new Promise((resolve, reject) => {\r\n this.getWeatherData(campusId, 'forecast')\r\n .then(data => {\r\n if (data.properties) {\r\n resolve(data.properties)\r\n } else {\r\n reject(new Error('GetWeatherForecast returned no data'))\r\n }\r\n })\r\n .catch(() => {\r\n reject(new Error('GetWeatherForecast error'))\r\n })\r\n })\r\n }\r\n\r\n static degreesToCompass (deg) {\r\n const cardA = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N']\r\n return cardA[Math.floor((deg + 11.25) / 22.5)]\r\n }\r\n\r\n static cToF (c) {\r\n return Math.round(c * 1.8 + 32)\r\n }\r\n\r\n static paToInHg (pa) {\r\n return (pa * 0.0002953).toFixed(2)\r\n }\r\n\r\n static kmToMi (km) {\r\n return Math.round(km * 0.62)\r\n }\r\n\r\n static mToMi (m) {\r\n return Math.round(m * 0.00062137)\r\n }\r\n\r\n static getUrlParams (locHref) {\r\n const vars = {}\r\n locHref.replace(/[?&]+([^=&]+)=([^&]*)/gi, (m, key, value) => {\r\n vars[key] = value\r\n })\r\n return vars\r\n }\r\n}\r\n\r\nexport default AqiApi\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport clsx from 'clsx'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n action: {\r\n display: 'block',\r\n paddingLeft: 4\r\n },\r\n groupTitle: {\r\n color: 'White',\r\n fontWeight: 'normal'\r\n },\r\n li: {\r\n color: 'White',\r\n '&>.required': {\r\n backgroundColor: 'rgba(255, 0, 0, 0.8)'\r\n },\r\n '&:not(:last-child)>.required': {\r\n marginBottom: 4\r\n }\r\n },\r\n ul: {\r\n listStyle: 'square',\r\n paddingLeft: 24,\r\n marginTop: 0\r\n }\r\n}))\r\n\r\nexport default function ActionsList (props) {\r\n const classes = useStyles()\r\n\r\n return (\r\n <>\r\n \r\n {AqiApi.getGroupTitle(props.groupId)}\r\n \r\n \r\n \r\n )\r\n}\r\nActionsList.propTypes = {\r\n actions: PropTypes.array,\r\n groupId: PropTypes.string\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport ErrorOutlineIcon from '@material-ui/icons/ErrorOutline'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n container: {\r\n alignItems: 'flex-start',\r\n backgroundColor: 'rgba(220, 20, 60, 0.7)',\r\n borderRadius: 4,\r\n boxShadow: '2px 2px 4px rgba(51, 51, 51, 0.9)',\r\n boxSizing: 'border-box',\r\n display: 'flex',\r\n left: '50%',\r\n marginLeft: -64,\r\n padding: 8,\r\n position: 'absolute',\r\n top: 108,\r\n width: 128,\r\n zIndex: 502\r\n },\r\n heading: {\r\n color: 'White',\r\n fontSize: '0.8rem'\r\n },\r\n icon: {\r\n color: 'White',\r\n marginRight: 8\r\n }\r\n}))\r\n\r\nexport default function NoData ({ text }) {\r\n const classes = useStyles()\r\n\r\n return (\r\n
\r\n \r\n \r\n {text || 'Air quality data unavailable'}\r\n \r\n
\r\n )\r\n}\r\n\r\nNoData.propTypes = {\r\n text: PropTypes.string\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport CircularProgress from '@material-ui/core/CircularProgress'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n circularProgress: {\r\n color: 'White',\r\n position: 'absolute',\r\n left: '50%',\r\n marginLeft: -20,\r\n marginTop: -20,\r\n top: '50%',\r\n zIndex: 1001\r\n }\r\n}))\r\n\r\nexport default function Working ({ show }) {\r\n const classes = useStyles()\r\n\r\n return (\r\n <>\r\n {show && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nWorking.propTypes = {\r\n show: PropTypes.bool\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport ActionsList from './ActionsList'\r\nimport AqiApi from './AqiApi'\r\nimport Box from '@material-ui/core/Box'\r\nimport NoData from './NoData'\r\nimport PropTypes from 'prop-types'\r\nimport React, { useState } from 'react'\r\nimport StopIcon from '@material-ui/icons/Stop'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport Working from './Working'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n container: {\r\n background: 'linear-gradient( #2B4886 100px, #4480BB 400px)',\r\n borderRadius: '10px',\r\n boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n height: 432,\r\n overflow: 'hidden',\r\n position: 'relative',\r\n width: '100%',\r\n [theme.breakpoints.down('sm')]: {\r\n height: 'auto',\r\n minHeight: 432\r\n }\r\n },\r\n content: {\r\n display: 'flex',\r\n flex: '1 1 auto',\r\n flexDirection: 'column',\r\n overflowY: 'auto',\r\n paddingBottom: 0,\r\n paddingLeft: 16,\r\n paddingRight: 16,\r\n paddingTop: 0\r\n },\r\n header: {\r\n paddingBottom: 8,\r\n paddingLeft: 16,\r\n paddingRight: 16,\r\n paddingTop: 8,\r\n zIndex: 2\r\n },\r\n heading: {\r\n color: 'White'\r\n },\r\n required: {\r\n color: 'White'\r\n },\r\n requiredContainer: {\r\n alignItems: 'center',\r\n display: 'flex'\r\n }\r\n}))\r\n\r\nexport default function Actions (props) {\r\n const classes = useStyles()\r\n const level = props.aqi ? AqiApi.getAqiLevel(props.aqi) : null\r\n let hasRequired = false\r\n\r\n if (level) {\r\n Object.keys(level.actions).forEach(key => {\r\n level.actions[key].forEach(action => {\r\n if (action.indexOf('') > -1) {\r\n hasRequired = true\r\n }\r\n })\r\n })\r\n }\r\n\r\n const [elevate, _setElevate] = useState(false)\r\n\r\n const onScroll = (e) => {\r\n _setElevate(e.target.scrollTop > 0)\r\n }\r\n\r\n return (\r\n
\r\n \r\n \r\n Actions to Take at This Level\r\n \r\n {hasRequired === true && (\r\n
\r\n \r\n \r\n Required\r\n \r\n
\r\n )}\r\n \r\n \r\n {level && (\r\n Object.keys(level.actions).map((group, i) => {\r\n return (\r\n \r\n )\r\n })\r\n )}\r\n
\r\n \r\n {props.fail && (\r\n \r\n )}\r\n \r\n )\r\n}\r\nActions.propTypes = {\r\n aqi: PropTypes.number,\r\n fail: PropTypes.bool,\r\n working: PropTypes.bool\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport Link from '@material-ui/core/Link'\r\nimport UCLALogo from './UCLA_logo_wht.svg'\r\nimport React from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n container: {\r\n alignItems: 'center',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n margin: '0 auto 0 auto',\r\n maxWidth: '1400px',\r\n paddingBottom: 48,\r\n paddingLeft: 16,\r\n paddingRight: 16,\r\n paddingTop: 48,\r\n width: '90%'\r\n },\r\n copy: {\r\n color: '#fff',\r\n textAlign: 'center'\r\n },\r\n link: {\r\n color: '#ffe800',\r\n fontSize: '.8rem',\r\n fontWeight: 700,\r\n textTransform: 'uppercase'\r\n },\r\n linksContainer: {\r\n color: '#ffe800',\r\n marginBottom: 16,\r\n zIndex: 4\r\n },\r\n logo: {\r\n display: 'flex',\r\n height: 32,\r\n marginBottom: 16\r\n }\r\n}))\r\n\r\nexport default function Footer (props) {\r\n const classes = useStyles()\r\n\r\n return (\r\n
\r\n \r\n
\r\n \r\n UCLA.EDU\r\n \r\n  | \r\n \r\n Terms of Use\r\n \r\n
\r\n \r\n ©2020 Regents of the University of California • All Rights Reserved\r\n \r\n
\r\n )\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport GaugeChart from 'react-gauge-chart'\r\nimport NoData from './NoData'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport Working from './Working'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n container: {\r\n display: 'flex',\r\n marginBottom: 24,\r\n position: 'relative',\r\n width: '100%'\r\n }\r\n}))\r\n\r\nconst getColors = () => {\r\n const colors = []\r\n AqiApi.aqiMatrix.forEach((obj, i) => {\r\n if (i < AqiApi.aqiMatrix.length - 1) {\r\n colors.push(obj.colors.bg.cssHex)\r\n }\r\n })\r\n return colors\r\n}\r\n\r\nconst colors = getColors()\r\n\r\nexport default function Gauge (props) {\r\n const classes = useStyles()\r\n\r\n return (\r\n
\r\n props.aqi >= 500 ? props.aqi : Math.round(value * AqiApi.getGaugeDivisor(props.aqi) * 0.01)}\r\n marginInPercent={0.01}\r\n needleBaseColor={'#333333'}\r\n needleColor={'#333333'}\r\n nrOfLevels={colors.length}\r\n percent={AqiApi.getGaugePercent(props.aqi)}\r\n />\r\n \r\n {props.fail && (\r\n \r\n )}\r\n
\r\n )\r\n}\r\nGauge.propTypes = {\r\n aqi: PropTypes.number,\r\n fail: PropTypes.bool,\r\n working: PropTypes.bool\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport FiberManualRecordIcon from '@material-ui/icons/FiberManualRecord'\r\nimport InfoIcon from '@material-ui/icons/Info'\r\nimport List from '@material-ui/core/List'\r\nimport ListItem from '@material-ui/core/ListItem'\r\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\r\nimport ListItemText from '@material-ui/core/ListItemText'\r\nimport React from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n heading: {\r\n color: 'White',\r\n textAlign: 'center'\r\n },\r\n iconContainer: {\r\n cursor: 'pointer',\r\n minWidth: 28,\r\n overflow: 'visible',\r\n position: 'relative',\r\n '&:hover .hidden': {\r\n visibility: 'visible'\r\n }\r\n },\r\n infoIcon: {\r\n color: 'LightGray',\r\n marginTop: 4\r\n },\r\n listItem: {\r\n alignItems: 'flex-start',\r\n width: '100%'\r\n },\r\n listItemTextRoot: {\r\n marginBottom: 0,\r\n marginRight: 8,\r\n marginTop: 0\r\n },\r\n primaryText: {\r\n color: 'White'\r\n },\r\n secondaryText: {\r\n color: 'LightGray'\r\n },\r\n swatchContainer: {\r\n minWidth: 40\r\n },\r\n toolTip: {\r\n alignItems: 'center',\r\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\r\n borderRadius: 4,\r\n boxShadow: '2px 2px 4px rgba(51, 51, 51, 0.9)',\r\n boxSizing: 'border-box',\r\n color: 'White',\r\n display: 'flex',\r\n fontSize: '0.8rem',\r\n maxWidth: 128,\r\n minWidth: 128,\r\n padding: 8,\r\n position: 'absolute',\r\n right: 36,\r\n top: 0,\r\n visibility: 'hidden',\r\n zIndex: 100\r\n }\r\n}))\r\n\r\nexport default function Legend () {\r\n const classes = useStyles()\r\n const items = AqiApi.aqiMatrix\r\n\r\n // remove comment to suppress 'beyond aqi' category\r\n // items.pop()\r\n\r\n return (\r\n <>\r\n \r\n Air Quality Index\r\n \r\n \r\n {items.map((l, i) => (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {l.whoAffected}\r\n \r\n \r\n \r\n \r\n ))\r\n }\r\n \r\n \r\n )\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport PropTypes from 'prop-types'\r\nimport React, { useEffect, useState } from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n level: {\r\n color: 'White',\r\n marginTop: '1rem',\r\n textAlign: 'center'\r\n },\r\n whoAffected: {\r\n color: 'White',\r\n marginLeft: 16,\r\n marginRight: 16,\r\n textAlign: 'center'\r\n }\r\n}))\r\n\r\nexport default function Summary ({ aqi }) {\r\n const classes = useStyles()\r\n\r\n const [level, _setLevel] = useState(null)\r\n\r\n useEffect(() => {\r\n _setLevel(aqi !== null ? AqiApi.getAqiLevel(aqi) : null)\r\n }, [aqi])\r\n\r\n return (\r\n <>\r\n {level && (\r\n <>\r\n \r\n {level.level}\r\n \r\n \r\n {level.whoAffected}\r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\nSummary.propTypes = {\r\n aqi: PropTypes.number\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport Gauge from './Gauge'\r\nimport Grid from '@material-ui/core/Grid'\r\nimport Legend from './Legend'\r\nimport Link from '@material-ui/core/Link'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport Summary from './Summary'\r\nimport Typography from '@material-ui/core/Typography'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n container: {\r\n background: 'linear-gradient( #2B4886 100px, #4480BB 400px)',\r\n borderRadius: '10px',\r\n boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)',\r\n height: 496,\r\n overflow: 'hidden',\r\n paddingBottom: 24,\r\n paddingLeft: 16,\r\n paddingRight: 16,\r\n padding: 8,\r\n position: 'relative',\r\n [theme.breakpoints.down('md')]: {\r\n height: 'auto',\r\n minHeight: 448\r\n }\r\n },\r\n description: {\r\n color: 'White'\r\n },\r\n heading: {\r\n color: 'White'\r\n },\r\n link: {\r\n color: 'White'\r\n },\r\n updated: {\r\n color: 'White'\r\n }\r\n}))\r\n\r\nexport default function GaugePanel (props) {\r\n const classes = useStyles()\r\n\r\n return (\r\n
\r\n <>\r\n \r\n Campus Air Quality\r\n \r\n \r\n Real-time US EPA Air Quality Index for particulate (PM2.5) air matter.\r\n \r\n \r\n \r\n \r\n \r\n {props.updated}\r\n \r\n {props.aqi !== null && (\r\n \r\n )}\r\n {props.aqi === null && (\r\n \r\n )}\r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n )\r\n}\r\nGaugePanel.propTypes = {\r\n aqi: PropTypes.number,\r\n fail: PropTypes.bool,\r\n updated: PropTypes.string,\r\n working: PropTypes.bool\r\n}\r\n","import { makeStyles, useTheme } from '@material-ui/core/styles'\r\nimport Button from '@material-ui/core/Button'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport RefreshIcon from '@material-ui/icons/Refresh'\r\nimport useMediaQuery from '@material-ui/core/useMediaQuery'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n button: {\r\n backgroundColor: '#C3D7EE'\r\n },\r\n container: {\r\n display: 'flex',\r\n flexDirection: 'column'\r\n }\r\n}))\r\n\r\nexport default function Refresh ({ handleRefresh }) {\r\n const classes = useStyles()\r\n const theme = useTheme()\r\n const small = useMediaQuery(theme.breakpoints.down('sm'))\r\n\r\n return (\r\n
\r\n }\r\n variant=\"contained\"\r\n >\r\n Refresh\r\n \r\n
\r\n )\r\n}\r\n\r\nRefresh.propTypes = {\r\n handleRefresh: PropTypes.func\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport aqLogo from './aq_logo.svg'\r\nimport PropTypes from 'prop-types'\r\nimport React, { useEffect, useState } from 'react'\r\nimport Refresh from './Refresh'\r\nimport UCILogo from './UCI_logo.svg'\r\nimport UCLALogo from './UCLA_logo_wht.svg'\r\nimport UCSBLogo from './UCSB_logo.svg'\r\nimport UCSDLogo from './UCSD_logo.svg'\r\nimport UCSFLogo from './UCSF_logo.svg'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n aqLogo: {\r\n height: 40\r\n },\r\n container: {\r\n alignItems: 'center',\r\n display: 'flex',\r\n marginLeft: 'auto',\r\n marginRight: 'auto',\r\n maxWidth: 1600,\r\n paddingBottom: 16,\r\n paddingLeft: 16,\r\n paddingRight: 16,\r\n paddingTop: 16\r\n },\r\n logo: {\r\n cursor: 'pointer',\r\n marginLeft: 16,\r\n zIndex: 2,\r\n [theme.breakpoints.down('md')]: {\r\n height: 36\r\n },\r\n [theme.breakpoints.up('md')]: {\r\n height: 40\r\n }\r\n },\r\n refreshContainer: {\r\n display: 'flex',\r\n flexGrow: 2,\r\n justifyContent: 'flex-end'\r\n }\r\n}))\r\n\r\nexport default function Header (props) {\r\n const classes = useStyles()\r\n const [logo, _setLogo] = useState(UCLALogo)\r\n\r\n useEffect(() => {\r\n if (props.campus.id === 'uci') {\r\n _setLogo(UCILogo)\r\n } else if (props.campus.id === 'ucsb') {\r\n _setLogo(UCSBLogo)\r\n } else if (props.campus.id === 'ucsd') {\r\n _setLogo(UCSDLogo)\r\n } else if (props.campus.id === 'ucsf') {\r\n _setLogo(UCSFLogo)\r\n }\r\n document.title = props.campus.id.toUpperCase() + ' AirQual'\r\n }, [props.campus.id])\r\n\r\n const handleHome = (url) => {\r\n window.open(url)\r\n }\r\n\r\n return (\r\n
\r\n \r\n handleHome(props.campus.url)}\r\n src={logo}\r\n />\r\n
\r\n \r\n
\r\n
\r\n )\r\n}\r\n\r\nHeader.propTypes = {\r\n campus: PropTypes.object,\r\n handleRefresh: PropTypes.func\r\n}\r\n","import { makeStyles, useTheme } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport Chart from 'react-google-charts'\r\nimport FormControl from '@material-ui/core/FormControl'\r\nimport FormControlLabel from '@material-ui/core/FormControlLabel'\r\nimport NoData from './NoData'\r\nimport PropTypes from 'prop-types'\r\nimport Radio from '@material-ui/core/Radio'\r\nimport RadioGroup from '@material-ui/core/RadioGroup'\r\nimport React, { useEffect, useState } from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport useMediaQuery from '@material-ui/core/useMediaQuery'\r\nimport Working from './Working'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n checked: {},\r\n container: {\r\n background: 'linear-gradient( #2B4886 100px, #4480BB 400px)',\r\n borderRadius: '10px',\r\n boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)',\r\n height: 496,\r\n overflow: 'hidden',\r\n paddingBottom: 24,\r\n paddingLeft: 16,\r\n paddingRight: 16,\r\n padding: 8,\r\n position: 'relative',\r\n [theme.breakpoints.down('md')]: {\r\n height: 448\r\n }\r\n },\r\n heading: {\r\n color: 'White'\r\n },\r\n progress: {\r\n color: 'White',\r\n position: 'absolute',\r\n left: '50%',\r\n marginLeft: -22,\r\n marginTop: -22,\r\n top: '50%'\r\n },\r\n radio: {\r\n '&$checked': {\r\n color: 'Aqua'\r\n }\r\n },\r\n radioContainer: {\r\n display: 'flex',\r\n justifyContent: 'center',\r\n paddingLeft: 32\r\n },\r\n radioGroup: {\r\n color: 'White'\r\n },\r\n timeRange: {\r\n color: 'White'\r\n }\r\n}))\r\n\r\nconst radios = [\r\n {\r\n label: 'Day',\r\n shortLabel: 'DY',\r\n value: 'day'\r\n },\r\n {\r\n label: 'Week',\r\n shortLabel: 'WK',\r\n value: 'week'\r\n },\r\n {\r\n label: 'Month',\r\n shortLabel: 'MO',\r\n value: 'month'\r\n },\r\n {\r\n label: 'Year',\r\n shortLabel: 'YR',\r\n value: 'year'\r\n }\r\n]\r\n\r\nexport default function LineChart (props) {\r\n const classes = useStyles()\r\n const theme = useTheme()\r\n const small = useMediaQuery(theme.breakpoints.down('sm'))\r\n const [period, _setPeriod] = useState('day')\r\n const [chartData, _setChartData] = useState(null)\r\n const [heading, _setHeading] = useState('Historical Values')\r\n const [timeRange, _setTimeRange] = useState('')\r\n const [fontSize, _setFontSize] = useState(11)\r\n const [lineWidth, _setLineWidth] = useState(8)\r\n const [slantedText, _setSlantedText] = useState(true)\r\n const [title, _setTitle] = useState('Hour')\r\n const [fail, _setFail] = useState(false)\r\n const [working, _setWorking] = useState(false)\r\n const [showRadios, _setShowRadios] = useState(false)\r\n\r\n useEffect(() => {\r\n _setWorking(true)\r\n _setFail(false)\r\n _setChartData(null)\r\n _setShowRadios(false)\r\n switch (period) {\r\n case 'day':\r\n _setHeading('Past 24 Hours')\r\n break\r\n case 'week':\r\n _setHeading('Past Week')\r\n break\r\n case 'month':\r\n _setHeading('Past Month')\r\n break\r\n case 'year':\r\n _setHeading('Past Year')\r\n break\r\n default:\r\n }\r\n AqiApi.getOpenMapAqiChartData(props.codes, period)\r\n .then(data => {\r\n _setWorking(false)\r\n const data_ = AqiApi.processChartData(data, period)\r\n const trA = [data_[0][0], data_[data_.length - 1][0]]\r\n const trStr = AqiApi.formatTimeRange(trA, period)\r\n _setTimeRange(trStr)\r\n let format\r\n const colVals = ['', 'AQI']\r\n switch (period) {\r\n case 'day':\r\n colVals[0] = 'Hour'\r\n format = 'hour'\r\n _setFontSize(11)\r\n _setHeading('Past 24 Hours')\r\n _setLineWidth(6)\r\n _setSlantedText(true)\r\n break\r\n case 'week':\r\n colVals[0] = 'Weekday'\r\n format = 'day'\r\n _setFontSize(13)\r\n _setLineWidth(6)\r\n _setSlantedText(false)\r\n _setTitle('Day of Week')\r\n break\r\n case 'month':\r\n colVals[0] = 'Date'\r\n format = 'date'\r\n _setFontSize(11)\r\n _setLineWidth(4)\r\n _setSlantedText(true)\r\n _setTitle('Date')\r\n break\r\n case 'year':\r\n colVals[0] = 'Month'\r\n format = 'month'\r\n _setFontSize(12)\r\n _setLineWidth(6)\r\n _setSlantedText(false)\r\n _setTitle('Month')\r\n break\r\n default:\r\n }\r\n data_.forEach((dt, i) => {\r\n data_[i][0] = AqiApi.formatChartDataTime(dt[0], format)\r\n })\r\n data_.unshift(colVals)\r\n _setChartData(data_)\r\n })\r\n .catch(error => {\r\n _setWorking(false)\r\n _setFail(true)\r\n console.error(error)\r\n })\r\n .finally(() => {\r\n setTimeout(() => {\r\n _setShowRadios(true)\r\n }, 2000)\r\n })\r\n }, [period, props.codes, props.refresh])\r\n\r\n const handleChange = (period) => {\r\n _setPeriod(period)\r\n }\r\n\r\n return (\r\n \r\n \r\n {heading}\r\n \r\n {chartData && (\r\n <>\r\n \r\n {timeRange}\r\n \r\n \r\n \r\n )}\r\n {showRadios && (\r\n
\r\n \r\n \r\n {radios.map((radio, i) => (\r\n \r\n }\r\n key={i}\r\n label={small ? radio.shortLabel : radio.label}\r\n onClick={() => handleChange(radio.value)}\r\n value={radio.value}\r\n />\r\n ))}\r\n \r\n \r\n
\r\n )}\r\n \r\n {fail && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nLineChart.propTypes = {\r\n codes: PropTypes.array,\r\n refresh: PropTypes.bool\r\n}\r\n","import { makeStyles, useTheme } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport clsx from 'clsx'\r\nimport NoData from './NoData'\r\nimport PropTypes from 'prop-types'\r\nimport React, { useEffect, useState } from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport useMediaQuery from '@material-ui/core/useMediaQuery'\r\nimport Working from './Working'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n container: {\r\n borderRadius: '10px',\r\n boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)',\r\n height: 432,\r\n overflow: 'hidden',\r\n position: 'relative',\r\n width: '100%',\r\n '&.small': {\r\n height: 432\r\n }\r\n },\r\n map: {\r\n borderRadius: '10px',\r\n height: '100%',\r\n left: 0,\r\n overflow: 'hidden',\r\n position: 'absolute',\r\n top: 0,\r\n width: '100%',\r\n zIndex: 500\r\n },\r\n mapHeading: {\r\n left: 16,\r\n position: 'absolute',\r\n top: 8,\r\n textShadow: '1px 1px 2px #fff',\r\n zIndex: 1500\r\n }\r\n}))\r\n\r\nlet aqiLayer = null\r\n\r\nexport default function Map (props) {\r\n const classes = useStyles()\r\n const theme = useTheme()\r\n const small = useMediaQuery(theme.breakpoints.down('sm'))\r\n const [map, _setMap] = useState(null)\r\n\r\n useEffect(() => {\r\n _setMap(AqiApi.getMap('map'))\r\n }, [])\r\n\r\n useEffect(() => {\r\n if (props.locations.length && map) {\r\n if (aqiLayer && map.hasLayer(aqiLayer)) {\r\n map.removeLayer(aqiLayer)\r\n aqiLayer = null\r\n }\r\n aqiLayer = AqiApi.getDeviceMarkers(props.locations, map)\r\n setTimeout(() => {\r\n aqiLayer.addTo(map)\r\n map.fitBounds(aqiLayer.getBounds(), { padding: [40, 40] })\r\n }, 500)\r\n }\r\n }, [props.locations, map])\r\n\r\n return (\r\n \r\n \r\n Monitoring Locations\r\n \r\n \r\n \r\n {props.fail && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nMap.propTypes = {\r\n fail: PropTypes.bool,\r\n locations: PropTypes.array,\r\n working: PropTypes.bool\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport TableCell from '@material-ui/core/TableCell'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n li: {\r\n marginBottom: '0.5rem'\r\n },\r\n required: {\r\n color: 'Red',\r\n fontWeight: 'bold'\r\n },\r\n tableCell: {\r\n fontSize: '.9rem',\r\n verticalAlign: 'top',\r\n width: '10%',\r\n '&:last-child': {\r\n paddingRight: 48\r\n }\r\n },\r\n ul: {\r\n margin: 0,\r\n padding: 0\r\n }\r\n}))\r\n\r\nexport default function ActionTableCell (props) {\r\n const classes = useStyles()\r\n\r\n return (\r\n \r\n
    \r\n {props.actions.map((action, j) => {\r\n if (action.indexOf('') > -1) {\r\n return (\r\n \r\n {action.replace('', '')}\r\n \r\n )\r\n } else {\r\n return (\r\n \r\n {action}\r\n \r\n )\r\n }\r\n })}\r\n
\r\n \r\n )\r\n}\r\nActionTableCell.propTypes = {\r\n actions: PropTypes.array,\r\n colSpan: PropTypes.number\r\n}\r\n","import { makeStyles, useTheme } from '@material-ui/core/styles'\r\nimport React from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport useMediaQuery from '@material-ui/core/useMediaQuery'\r\n\r\nconst items = [\r\n 'The matrix is designed for use when wildfire smoke conditions result in worsening and unhealthy air quality. It does not apply if there is a direct threat of wildfire and/or other significant hazard to the location, or for smog‐related air quality conditions.',\r\n 'Required actions are in bolded red text. These are definitive actions that must take place when ‐ but not before ‐ the corresponding AQI threshold is met.',\r\n 'Non‐bolded actions are recommended for consideration and should be implemented at the location’s discretion.',\r\n 'The matrix is not a stand‐alone document. It should be used in conjunction with existing local response plans, protocols, and procedures including the Emergency Operations Plan, Crisis Management Plan, and Continuity of Operations Plans.',\r\n 'If building indoor air quality is measured at a level consistent with the AQI thresholds, applicable mitigation measures should be implemented if feasible, and required actions listed in the matrix should be taken.',\r\n 'Contractors working at UC locations should follow the advice of their own employers.',\r\n 'The Pre‐K‐12 actions apply to UC‐managed facilities only.',\r\n 'The matrix incorporates actions required by Cal/OSHA Section 5141.1.',\r\n 'University sponsored outdoor events held at off‐campus locations are subject to actions associated with that location’s AQI levels.',\r\n 'Actions for athletic practice and competition were based on current National Collegiate Athletic Association (NCAA) guidance. Decisions regarding the cancellation and/or rescheduling of athletic competitions should be made in accordance with the NCAA. Rescheduling of athletic and recreation competitions may take place when the AQI lowers to an acceptable level.',\r\n 'Locations should ensure timely communication of AQI‐based decisions and expected actions via multiple and redundant communication methods.',\r\n 'Higher AQI thresholds automatically incorporate all guidance and actions associated with lower AQI levels.'\r\n]\r\n\r\nconst useStyles = makeStyles(() => ({\r\n container: {\r\n marginRight: 24\r\n }\r\n}))\r\n\r\nexport default function UCCharacteristics (props) {\r\n const classes = useStyles()\r\n const theme = useTheme()\r\n const small = useMediaQuery(theme.breakpoints.down('sm'))\r\n\r\n return (\r\n
\r\n \r\n Key characteristics:\r\n \r\n
    \r\n {items.map((item, i) => {\r\n return (\r\n \r\n {item}\r\n \r\n )\r\n })}\r\n
\r\n
\r\n )\r\n}\r\n","import { makeStyles, useTheme } from '@material-ui/core/styles'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport Table from '@material-ui/core/Table'\r\nimport TableBody from '@material-ui/core/TableBody'\r\nimport TableCell from '@material-ui/core/TableCell'\r\nimport TableHead from '@material-ui/core/TableHead'\r\nimport TableRow from '@material-ui/core/TableRow'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport useMediaQuery from '@material-ui/core/useMediaQuery'\r\n\r\nconst revs = [\r\n {\r\n date: '10/30/2019',\r\n description: [\r\n 'Removed \"PM2.5 (24hr avg; μg/m3)\" column',\r\n 'Renamed \"Current AQI Value\" column to \"Current PM2.5 AQI Value\"'\r\n ],\r\n version: '1.1'\r\n }\r\n]\r\n\r\nconst useStyles = makeStyles(() => ({\r\n container: {\r\n marginRight: 24,\r\n maxWidth: '640px'\r\n },\r\n ul: {\r\n margin: 0,\r\n padding: 0\r\n }\r\n}))\r\n\r\nexport default function RevisionHistory (props) {\r\n const classes = useStyles()\r\n const theme = useTheme()\r\n const small = useMediaQuery(theme.breakpoints.down('sm'))\r\n\r\n return (\r\n <>\r\n \r\n Revision History\r\n \r\n
\r\n \r\n \r\n \r\n Version\r\n Revision Date\r\n Change Made\r\n \r\n \r\n \r\n {revs.map((rev, i) => {\r\n return (\r\n \r\n \r\n \r\n {rev.version}\r\n \r\n \r\n \r\n \r\n {rev.date}\r\n \r\n \r\n \r\n
    \r\n {rev.description.map((desc, j) => {\r\n return (\r\n
  • \r\n \r\n {desc}\r\n \r\n
  • \r\n )\r\n })}\r\n
\r\n {rev.whoAffected}\r\n
\r\n \r\n )\r\n })}\r\n
\r\n \r\n
\r\n \r\n )\r\n}\r\nRevisionHistory.propTypes = {\r\n refresh: PropTypes.bool\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport ActionTableCell from './ActionTableCell'\r\nimport AqiApi from './AqiApi'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport Table from '@material-ui/core/Table'\r\nimport TableBody from '@material-ui/core/TableBody'\r\nimport TableCell from '@material-ui/core/TableCell'\r\nimport TableHead from '@material-ui/core/TableHead'\r\nimport TableRow from '@material-ui/core/TableRow'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport UCCharacteristics from './UCCharacteristics'\r\nimport UCRevisionHistory from './UCRevisionHistory'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n container: {\r\n background: 'White',\r\n borderRadius: '10px',\r\n boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)',\r\n marginTop: 24,\r\n paddingBottom: 24,\r\n paddingLeft: 16,\r\n paddingRight: 0,\r\n paddingTop: 8\r\n },\r\n heading: {\r\n paddingRight: 16\r\n },\r\n required: {\r\n color: 'red',\r\n fontWeight: 'bold'\r\n },\r\n table: {\r\n '& td': {\r\n fontSize: '0.9rem'\r\n },\r\n '& th': {\r\n fontSize: '0.9rem',\r\n fontWeight: 'bold',\r\n lineHeight: 1.5,\r\n verticalAlign: 'bottom'\r\n },\r\n [theme.breakpoints.down('md')]: {\r\n '& th': {\r\n color: 'red',\r\n fontSize: '0.8rem'\r\n },\r\n '& td': {\r\n fontSize: '0.8rem'\r\n }\r\n }\r\n },\r\n tableWrapper: {\r\n marginBottom: 32,\r\n maxHeight: 'auto',\r\n overflowX: 'auto',\r\n overflowY: 'hidden'\r\n }\r\n}))\r\n\r\nexport default function Matrix (props) {\r\n const classes = useStyles()\r\n\r\n return (\r\n
\r\n \r\n University of California AQI‐Based Decision‐Making Matrix for Wildfire Smoke Events (Version 1.1)\r\n \r\n \r\n Required action in bolded red text\r\n \r\n
\r\n \r\n \r\n \r\n Levels of Health Concern\r\n Current PM2.5 AQI Value\r\n Who is Affected?\r\n Actions\r\n \r\n \r\n \r\n Outdoor Workers/
Volunteers
\r\n Classes\r\n Campus Operations\r\n Health System Operations\r\n Athletics & Outdoor Rec\r\n Outdoor Camps/
Events
\r\n Pre‐K‐12\r\n
\r\n
\r\n \r\n {AqiApi.aqiMatrix.map((category, i) =>\r\n = category.lowerLimit && props.aqi <= category.upperLimit) || (category.upperLimit === null && props.aqi >= category.lowerLimit)\r\n ? { backgroundColor: 'rgba(' + category.colors.bg.rgb + ', 0.2' }\r\n : null\r\n }\r\n >\r\n \r\n {category.level}\r\n \r\n \r\n {category.range}\r\n \r\n \r\n {category.whoAffected}\r\n \r\n {category.upperLimit !== null &&\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n }\r\n {category.upperLimit === null &&\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\nMatrix.propTypes = {\r\n aqi: PropTypes.number\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport React from 'react'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n container: {\r\n '& div': {\r\n background: 'transparent url(svg/bgd_octagon.svg) no-repeat left top',\r\n backgroundSize: 'cover',\r\n opacity: 0.05,\r\n position: 'absolute'\r\n },\r\n position: 'fixed',\r\n zIndex: -1\r\n },\r\n container_1: {\r\n height: 320,\r\n left: 0,\r\n top: 240,\r\n width: 320\r\n },\r\n container_2: {\r\n height: 200,\r\n right: 0,\r\n top: 48,\r\n width: 200\r\n },\r\n earth: {\r\n height: 72,\r\n left: 48,\r\n top: 176,\r\n width: 72\r\n },\r\n jupiter: {\r\n bottom: 0,\r\n height: 184,\r\n left: 0,\r\n width: 184\r\n },\r\n mars: {\r\n height: 56,\r\n left: 16,\r\n top: 216,\r\n width: 56\r\n },\r\n pluto_1: {\r\n height: 32,\r\n left: 72,\r\n opacity: 0.05,\r\n top: 160,\r\n width: 32\r\n },\r\n pluto_2: {\r\n height: 32,\r\n right: 0,\r\n top: 0,\r\n width: 32\r\n },\r\n sun: {\r\n height: 320,\r\n left: 0,\r\n top: 0,\r\n width: 320\r\n },\r\n venus: {\r\n height: 63,\r\n right: 16,\r\n top: 8,\r\n width: 64\r\n }\r\n}))\r\n\r\nexport default function Texture (props) {\r\n const classes = useStyles()\r\n\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\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport List from '@material-ui/core/List'\r\nimport ListItem from '@material-ui/core/ListItem'\r\nimport ListItemText from '@material-ui/core/ListItemText'\r\nimport NoData from './NoData'\r\nimport PropTypes from 'prop-types'\r\nimport React, { useEffect, useState } from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport Working from './Working'\r\n\r\nconst useStyles = makeStyles(() => ({\r\n condition: {\r\n '& .type': {\r\n color: 'White',\r\n fontSize: '0.7rem',\r\n fontWeight: 300,\r\n letterSpacing: '0.08333em',\r\n lineHeight: 1,\r\n textTransform: 'uppercase'\r\n },\r\n '&.first': {\r\n minWidth: '60%'\r\n },\r\n '& .value': {\r\n color: 'White',\r\n fontSize: '1.3rem',\r\n fontWeight: 400,\r\n letterSpacing: '0em',\r\n lineHeight: 1.334\r\n }\r\n },\r\n container: {\r\n height: 'auto',\r\n position: 'relative'\r\n },\r\n containerAtmos: {\r\n position: 'relative'\r\n },\r\n containerTemp: {\r\n alignItems: 'center',\r\n backgroundPosition: 'center center',\r\n backgroundRepeat: 'no-repeat',\r\n backgroundSize: '100% auto',\r\n borderTopLeftRadius: '10px',\r\n borderTopRightRadius: '10px',\r\n color: 'White',\r\n display: 'flex',\r\n justifyContent: 'center',\r\n position: 'relative',\r\n width: '100%',\r\n '&::after': {\r\n content: '\"\"',\r\n display: 'block',\r\n paddingBottom: '50%'\r\n }\r\n },\r\n description: {\r\n textAlign: 'center',\r\n textShadow: '3px 3px 3px #000000'\r\n },\r\n temp: {\r\n fontSize: '4rem',\r\n lineHeight: 1,\r\n marginLeft: '1rem',\r\n textAlign: 'center',\r\n textShadow: '3px 3px 3px #000000'\r\n }\r\n}))\r\n\r\nexport default function WeatherCurrent ({ campusId }) {\r\n const classes = useStyles()\r\n const [desc, _setDesc] = useState(null)\r\n const [error, _setError] = useState(null)\r\n const [humidity, _setHumidity] = useState('N/A')\r\n const [imgUrl, _setImgUrl] = useState(null)\r\n const [pressure, _setPressure] = useState('N/A')\r\n const [temp, _setTemp] = useState(null)\r\n const [visibility, _setVisibility] = useState('N/A')\r\n const [wind, _setWind] = useState('N/A')\r\n const [working, _setWorking] = useState(false)\r\n\r\n useEffect(() => {\r\n if (campusId) {\r\n _setWorking(true)\r\n AqiApi.getTempWind(campusId)\r\n .then(tempWind => {\r\n return tempWind\r\n })\r\n .then(tempWind => {\r\n _setTemp(tempWind.temperature)\r\n _setDesc(tempWind.shortForecast)\r\n _setImgUrl(tempWind.icon.replace('size=medium', 'size=large'))\r\n _setImgUrl(tempWind.icon.replace(',0', ''))\r\n const wA = []\r\n if (tempWind.windDirection) {\r\n wA.push(tempWind.windDirection)\r\n }\r\n if (tempWind.windSpeed) {\r\n wA.push(tempWind.windSpeed)\r\n }\r\n if (wA.length) {\r\n _setWind(wA.join(' '))\r\n } else {\r\n _setWind('N/A')\r\n }\r\n AqiApi.getPressHumid(campusId)\r\n .then(pressHumid => {\r\n _setWorking(false)\r\n if (pressHumid.barometricPressure.value) {\r\n _setPressure(AqiApi.paToInHg(pressHumid.barometricPressure.value) + ' inHg')\r\n }\r\n if (pressHumid.visibility.value) {\r\n _setVisibility(AqiApi.mToMi(pressHumid.visibility.value) + ' mi')\r\n }\r\n if (pressHumid.relativeHumidity.value) {\r\n _setHumidity(Math.round(pressHumid.relativeHumidity.value) + '%')\r\n }\r\n })\r\n .catch(error => {\r\n console.error(error)\r\n _setWorking(false)\r\n })\r\n })\r\n .catch(error => {\r\n _setWorking(false)\r\n _setError(new Error('Current weather unavailable'))\r\n console.error(error)\r\n })\r\n }\r\n }, [campusId])\r\n\r\n return (\r\n
\r\n {temp &&\r\n <>\r\n \r\n
\r\n \r\n {temp}°\r\n \r\n \r\n {desc}\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 \r\n }\r\n \r\n {Boolean(error) &&\r\n \r\n }\r\n \r\n )\r\n}\r\n\r\nWeatherCurrent.propTypes = {\r\n campusId: PropTypes.string\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport AqiApi from './AqiApi'\r\nimport Box from '@material-ui/core/Box'\r\nimport clsx from 'clsx'\r\nimport List from '@material-ui/core/List'\r\nimport ListItem from '@material-ui/core/ListItem'\r\nimport ListItemIcon from '@material-ui/core/ListItemIcon'\r\nimport ListItemText from '@material-ui/core/ListItemText'\r\nimport NoData from './NoData'\r\nimport PropTypes from 'prop-types'\r\nimport React, { useEffect, useState } from 'react'\r\nimport Typography from '@material-ui/core/Typography'\r\nimport Working from './Working'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n arrowHi: {\r\n color: 'FireBrick !important',\r\n fontSize: '1rem',\r\n marginRight: '.5rem',\r\n '&::before': {\r\n content: '\"▲\"'\r\n }\r\n },\r\n arrowLo: {\r\n color: 'Blue !important',\r\n fontSize: '1rem',\r\n marginRight: '.5rem',\r\n '&::before': {\r\n content: '\"▼\"'\r\n }\r\n },\r\n container: {\r\n color: 'White',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n height: 'auto',\r\n overflow: 'hidden',\r\n width: '100%'\r\n },\r\n content: {\r\n display: 'flex',\r\n flex: '1 1 auto',\r\n flexDirection: 'column',\r\n [theme.breakpoints.up('md')]: {\r\n overflowY: 'auto'\r\n }\r\n },\r\n day: {\r\n minWidth: '60%'\r\n },\r\n header: {\r\n zIndex: 2\r\n },\r\n heading: {\r\n color: 'White',\r\n fontSize: '0.7rem',\r\n fontWeight: 300,\r\n letterSpacing: '0.08333em',\r\n lineHeight: 1,\r\n paddingBottom: 4,\r\n paddingLeft: 16,\r\n textTransform: 'uppercase'\r\n },\r\n icon: {\r\n backgroundSize: 'cover',\r\n borderRadius: 4,\r\n display: 'block',\r\n height: 32,\r\n width: 32\r\n },\r\n iconContainer: {\r\n cursor: 'pointer',\r\n height: 32,\r\n minWidth: 32,\r\n overflow: 'visible',\r\n position: 'relative',\r\n '&:hover .hidden': {\r\n visibility: 'visible'\r\n }\r\n },\r\n list: {\r\n marginBottom: 16\r\n },\r\n row: {\r\n paddingBottom: 2,\r\n paddingTop: 2\r\n },\r\n toolTip: {\r\n alignItems: 'center',\r\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\r\n borderRadius: 4,\r\n boxShadow: '2px 2px 4px rgba(51, 51, 51, 0.9)',\r\n boxSizing: 'border-box',\r\n color: 'White',\r\n display: 'flex',\r\n fontSize: '0.8rem',\r\n lineHeight: 1.3,\r\n maxWidth: 160,\r\n minWidth: 160,\r\n padding: 8,\r\n position: 'absolute',\r\n right: 36,\r\n top: 0,\r\n visibility: 'hidden',\r\n zIndex: 100\r\n }\r\n}))\r\n\r\nexport default function WeatherForecast ({ campusId }) {\r\n const classes = useStyles()\r\n const now = new Date()\r\n const [elevate, _setElevate] = useState(false)\r\n const [error, _setError] = useState(null)\r\n const [periods, _setPeriods] = useState(null)\r\n const [working, _setWorking] = useState(false)\r\n\r\n const onScroll = (e) => {\r\n _setElevate(e.target.scrollTop > 0)\r\n }\r\n\r\n useEffect(() => {\r\n if (campusId) {\r\n _setWorking(true)\r\n AqiApi.getWeatherForecast(campusId)\r\n .then(data => {\r\n _setWorking(false)\r\n _setPeriods(data.periods)\r\n })\r\n .catch(error => {\r\n _setWorking(false)\r\n _setError(new Error('Weather forecast unavailable'))\r\n console.error(error)\r\n })\r\n }\r\n }, [campusId])\r\n\r\n return (\r\n
\r\n {periods &&\r\n <>\r\n \r\n \r\n Extended Forecast\r\n \r\n \r\n \r\n \r\n {periods.map((p, i) => {\r\n if (new Date(p.endTime) > now) {\r\n return (\r\n \r\n \r\n \r\n \r\n {p.temperature}°\r\n \r\n \r\n \r\n {p.detailedForecast}\r\n
\r\n \r\n \r\n \r\n )\r\n } else {\r\n return null\r\n }\r\n })}\r\n \r\n \r\n \r\n }\r\n \r\n {Boolean(error) && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nWeatherForecast.propTypes = {\r\n campusId: PropTypes.string\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\r\nimport PropTypes from 'prop-types'\r\nimport React from 'react'\r\nimport WeatherCurrent from './WeatherCurrent'\r\nimport WeatherForecast from './WeatherForecast'\r\n\r\nconst useStyles = makeStyles(theme => ({\r\n container: {\r\n background: 'linear-gradient( #2B4886 100px, #4480BB 400px)',\r\n borderRadius: '10px',\r\n boxShadow: '0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n height: 432,\r\n overflow: 'hidden',\r\n position: 'relative',\r\n width: '100%',\r\n [theme.breakpoints.down('sm')]: {\r\n height: 'auto'\r\n }\r\n },\r\n content: {\r\n display: 'flex',\r\n flex: '1 1 auto',\r\n flexDirection: 'column',\r\n overflowY: 'auto'\r\n },\r\n heading: {\r\n color: 'White',\r\n fontSize: '0.7rem',\r\n fontWeight: 300,\r\n letterSpacing: '0.08333em',\r\n lineHeight: 1,\r\n paddingLeft: 16,\r\n textTransform: 'uppercase'\r\n }\r\n}))\r\n\r\nexport default function WeatherPanel (props) {\r\n const classes = useStyles()\r\n\r\n return (\r\n
\r\n \r\n \r\n
\r\n )\r\n}\r\n\r\nWeatherPanel.propTypes = {\r\n campusId: PropTypes.string,\r\n refresh: PropTypes.bool\r\n}\r\n","import { makeStyles } from '@material-ui/core/styles'\nimport './App.css'\nimport Actions from './Actions'\nimport AqiApi from './AqiApi'\nimport Footer from './Footer'\nimport GaugePanel from './GaugePanel'\nimport Grid from '@material-ui/core/Grid'\nimport Header from './Header'\nimport LineChart from './LineChart'\nimport Map from './Map'\nimport Matrix from './Matrix'\nimport React, { useState, useEffect } from 'react'\nimport Texture from './Texture'\nimport WeatherPanel from './WeatherPanel'\n\nconst useStyles = makeStyles(() => ({\n container: {\n marginLeft: 'auto',\n marginRight: 'auto',\n maxWidth: 1600,\n paddingLeft: 16,\n paddingRight: 16\n },\n gridContainer: {\n marginBottom: 16\n }\n}))\n\nconst urlParams = AqiApi.getUrlParams(window.location.href)\n\nlet campus = AqiApi.campuses.filter(c => c.id === 'ucla')[0]\n\nif (urlParams.campus) {\n const otherCampus = AqiApi.campuses.filter(c => c.id === urlParams.campus.toLowerCase())\n if (otherCampus.length) {\n campus = otherCampus[0]\n } else {\n alert('No dashboard configuration for ' + urlParams.campus + '.')\n }\n}\n\nconst codes = []\n\ncampus.devices.forEach(obj => {\n codes.push(obj.deviceId)\n})\n\nfunction App () {\n const classes = useStyles()\n\n const [aqi, _setAqi] = useState(null)\n\n const [locations, _setLocations] = useState([])\n\n const [refresh, _setRefresh] = useState(false)\n\n const [updated, _setUpdated] = useState(AqiApi.formatDate(new Date()))\n\n const [fail, _setFail] = useState(false)\n\n const [working, _setWorking] = useState(false)\n\n useEffect(() => {\n _setWorking(true)\n AqiApi.getOpenMapAqiData(campus.id)\n .then(data => {\n _setWorking(false)\n _setAqi(data.campusAqiAverage)\n _setLocations(data.devices)\n })\n .catch(error => {\n _setWorking(false)\n _setFail(true)\n console.error(error)\n })\n _setUpdated(AqiApi.formatDate(new Date()))\n }, [refresh])\n\n const handleRefresh = () => {\n if (aqi) {\n _setAqi(null)\n }\n _setRefresh(!refresh)\n }\n\n return (\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n