{"version":3,"sources":["components/LayerToggle/style.module.css","components/Sidebar/style.module.css","components/ToolTip/style.module.css","components/FeatureInfo/style.module.css","components/LayerToggleGroup/style.module.css","components/SidebarControl/style.module.css","config/map.js","config/sources.js","config/layers.js","components/FeatureInfo/index.js","images/logo.png","util/window.js","contexts/GlobalContext/actions.js","contexts/GlobalContext/reducer.js","contexts/GlobalContext/index.js","contexts/LayerVisibilityContext/actions.js","contexts/LayerVisibilityContext/reducer.js","contexts/LayerVisibilityContext/index.js","components/ToolTip/index.js","components/LayerToggle/index.js","components/LayerToggleGroup/index.js","components/Sidebar/index.js","util/layers.js","config/breakpoints.js","contexts/ViewPortContext/index.js","components/SidebarControl/index.js","App.js","reportWebVitals.js","index.js"],"names":["module","exports","MAP_DEFAULTS","latitude","longitude","zoom","SOURCES","get","id","type","url","SOURCE_LAYERS","LAYER_WEIGHTS","calculateLineWidth","width","makeLayerGenerator","sourceId","sourceLayerId","layout","baseLayout","paint","basePaint","filter","layerName","source","makeLineLayerGenerator","buildIconLayer","makeSymbolLayerGenerator","buildRouteLayer","buildConnectorLayer","buildPcbLayer","ICONS","layers","map","details","name","icon","color","ROUTES","description","CONNECTORS","PCB","iconIdMap","FeatureInfo","info","typeProperty","useMemo","link","target","href","Website","rel","body","Location","Bikes_Allo","className","styles","Name","getViewPort","innerWidth","innerHeight","height","window","setFocusedLayer","layer","value","clearFocusedLayer","showSidebar","hideSidebar","toggleSidebar","state","focusedLayer","undefined","initialState","GlobalContext","createContext","GlobalProvider","children","globalState","dispatch","useReducer","reducer","Provider","useGlobals","useContext","toggleVisibility","ClassI","ClassII","ClassIII","Trail","LayerVisibilityContext","LayerVisibilityContextProvider","visibilityState","useLayerVisibility","setOffset","offset","document","documentElement","style","setProperty","removeProperty","ToolTip","text","direction","tooltipRef","useRef","onMouseEnter","current","rect","getBoundingClientRect","deltaX","Math","floor","min","right","onMouseLeave","ref","LayerToggle","layerId","dispatchGlobals","layerVisibility","dispatchVisibility","focus","unfocus","onClick","onTouchEnd","onTouchStart","onTouchCancel","defaultChecked","htmlFor","LayerToggleGroup","header","Sidebar","show","layerToggleGroups","toggleType","src","logo","alt","i","Object","entries","LAYER_FOCUS_WEIGHTS","symbol","line","filterVisibleLayers","focusedLayerId","baseLayerId","visibleLayers","layersOrderedByFocus","sort","ai","a","bi","b","Array","from","before","ViewPortContext","ViewPortProvider","viewPort","setViewPort","useState","useEffect","onResize","addEventListener","removeEventListener","SidebarControl","MapContext","showControl","Breakpoints","resize","App","globals","cursorStyle","setCursorStyle","viewport","setViewport","selectedFeature","setSelectedFeature","clearSelectedFeature","onFeatureClick","useCallback","features","lngLat","properties","onRouteFeatureClick","onConnectorFeatureClick","onIconFeatureClick","onPCBFeatureClick","resetCursor","setPointerCursor","mapLayerSources","slice","onLayerClick","accessToken","process","mapStyle","onViewportChange","attributionControl","filteredLayers","applyFocusStyleToLayer","onHover","onLeave","length","key","lat","lng","closeButton","closeOnClick","onClose","showZoom","position","customAttribution","compact","reportWebVitals","onPerfEntry","Function","then","getCLS","getFID","getFCP","getLCP","getTTFB","library","add","faInfoCircle","faExternalLinkAlt","faChevronRight","faChevronLeft","faDollarSign","faBicycle","faWrench","faStoreAlt","ReactDOM","render","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.6a19c5a1.chunk.js","sourcesContent":["// extracted by mini-css-extract-plugin\nmodule.exports = {\"layer-toggle\":\"style_layer-toggle__1Ve87\",\"layer-checkbox\":\"style_layer-checkbox__2k3sd\",\"line\":\"style_line__WqDAE\",\"ClassI\":\"style_ClassI__30Qrr\",\"ClassII\":\"style_ClassII__2hfiF\",\"ClassIII\":\"style_ClassIII__1lxDv\",\"Trail\":\"style_Trail__2Cez4\",\"Advanced\":\"style_Advanced__2zHBE\",\"Intermediate\":\"style_Intermediate__1kIf6\",\"Family-Friendly\":\"style_Family-Friendly__agi-i\",\"Official\":\"style_Official__3OyHu\",\"Alternative\":\"style_Alternative__1o_PS\",\"icon\":\"style_icon__nJFy-\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"sidebar\":\"style_sidebar__20YO8\",\"hidden\":\"style_hidden__1XlB_\",\"logo\":\"style_logo__1e-ND\",\"summary\":\"style_summary__3lUAu\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"tooltip-wrapper\":\"style_tooltip-wrapper__3fm7M\",\"tooltip-text\":\"style_tooltip-text__2NP0t\",\"visible\":\"style_visible__1BmWb\",\"tooltip-top\":\"style_tooltip-top__1aRl1\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"popup-row\":\"style_popup-row__3NELi\",\"popup\":\"style_popup__1Z3vc\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"layer-group-header\":\"style_layer-group-header__2VGaN\",\"layer-group-header-text\":\"style_layer-group-header-text__1YfM9\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"sidebar-toggle\":\"style_sidebar-toggle__30Ict\"};","export const MAP_DEFAULTS = {\r\n viewport: {\r\n latitude: 40.7450,\r\n longitude: -123.8695,\r\n zoom: 8,\r\n }\r\n};","export const SOURCES = {\r\n get: (id) => ({ ...SOURCES[id], id}),\r\n 'bike-points': {\r\n id: 'bike-points',\r\n type: 'vector',\r\n url: 'mapbox://hcaog.4f94k5tj',\r\n },\r\n 'bike-routes': {\r\n id: 'bike-routes',\r\n type: 'vector',\r\n url: 'mapbox://hcaog.1nksq7lv',\r\n },\r\n 'connectors': {\r\n id: 'connectors',\r\n type: 'vector',\r\n url: 'mapbox://hcaog.digdwntd'\r\n },\r\n 'pcb': {\r\n id: 'pcb',\r\n type: 'vector',\r\n url: 'mapbox://hcaog.6vx5ufzz'\r\n }\r\n};\r\n\r\nexport const SOURCE_LAYERS = {\r\n 'bike-points': 'bike_points-0g9ncs',\r\n 'bike-routes': 'bike_routes-4e3370',\r\n 'connectors': 'connectors-7o42gn',\r\n 'pcb': 'PCB_full-4s2gb0'\r\n};\r\n","import { MAP_DEFAULTS } from './map';\r\nimport { SOURCES, SOURCE_LAYERS } from './sources';\r\n\r\n// Set default symbol and line size\r\nexport const LAYER_WEIGHTS = {\r\n symbol: 1,\r\n line: 2,\r\n};\r\n\r\nexport const calculateLineWidth = (width) => [\r\n 'interpolate', \r\n ['linear'], \r\n ['zoom'],\r\n MAP_DEFAULTS.viewport.zoom, width, \r\n MAP_DEFAULTS.viewport.zoom + 8, width*2, \r\n MAP_DEFAULTS.viewport.zoom + 16, width * 4\r\n];\r\n\r\nconst makeLayerGenerator = ({\r\n type,\r\n sourceId,\r\n sourceLayerId,\r\n layout: baseLayout,\r\n paint: basePaint,\r\n filter\r\n}) => {\r\n return ({ id, layerName, layout, paint }) => ({\r\n id,\r\n type,\r\n source: sourceId,\r\n 'source-layer': SOURCE_LAYERS[sourceLayerId],\r\n layout: {\r\n ...baseLayout,\r\n ...layout\r\n },\r\n paint: {\r\n ...basePaint,\r\n ...paint\r\n },\r\n filter: filter(layerName),\r\n }\r\n );\r\n};\r\n\r\nconst makeSymbolLayerGenerator = ({\r\n sourceId,\r\n sourceLayerId,\r\n filter\r\n}) => makeLayerGenerator({\r\n type: 'symbol',\r\n sourceId,\r\n sourceLayerId,\r\n layout: {\r\n 'icon-size': LAYER_WEIGHTS.symbol,\r\n 'icon-allow-overlap': false,\r\n 'visibility': 'visible',\r\n },\r\n paint: {\r\n // 'icon-opacity': 1,\r\n },\r\n filter\r\n});\r\n\r\nconst makeLineLayerGenerator = ({\r\n sourceId,\r\n sourceLayerId,\r\n filter\r\n}) => makeLayerGenerator({\r\n type: 'line',\r\n sourceId,\r\n sourceLayerId,\r\n layout: {\r\n 'line-cap': 'round',\r\n 'line-join': 'round',\r\n 'visibility': 'visible'\r\n },\r\n paint: {\r\n 'line-width': calculateLineWidth(LAYER_WEIGHTS.line),\r\n },\r\n filter\r\n});\r\n\r\n// create bike points ICON layer\r\nconst buildIconLayer = makeSymbolLayerGenerator({\r\n sourceId: 'bike-points',\r\n sourceLayerId: 'bike-points',\r\n filter: (layerName) => ['==', 'Type', layerName]\r\n});\r\n\r\n// create bike routes layer\r\nconst buildRouteLayer = makeLineLayerGenerator({\r\n sourceId: 'bike-routes',\r\n sourceLayerId: 'bike-routes',\r\n filter: (layerName) => ['==', 'type_2021', layerName]\r\n});\r\n\r\n// create connector routes layer\r\nconst buildConnectorLayer = makeLineLayerGenerator({\r\n sourceId: 'connectors',\r\n sourceLayerId: 'connectors',\r\n filter: (layerName) => ['==', 'Type', layerName]\r\n});\r\n\r\n// create pacific coast bike route layer\r\nconst buildPcbLayer = makeLineLayerGenerator({\r\n sourceId: 'pcb',\r\n sourceLayerId: 'pcb',\r\n filter: (layerName) => ['==', 'Status', layerName]\r\n});\r\n\r\n// ICON layer for bike points\r\nexport const ICONS = {\r\n source: SOURCES.get('bike-points'),\r\n layers: [\r\n {\r\n id: 'bike-shops',\r\n layout:{\r\n 'icon-image': 'hcaog-bicycle-shop'\r\n },\r\n paint: {\r\n 'icon-color': 'black',\r\n },\r\n layerName: 'Bicycle Shop'\r\n },\r\n {\r\n id: 'rental',\r\n layout:{\r\n 'icon-image': 'hcaog-bicycle-rental-17'\r\n },\r\n paint: {\r\n 'icon-color': 'black',\r\n },\r\n layerName: 'Rental'\r\n },\r\n {\r\n id: 'tool-station',\r\n layout:{\r\n // 'icon-image': 'hardware-15'\r\n 'icon-image': 'hcaog-hardware-new'\r\n },\r\n layerName: 'Tool Station'\r\n },\r\n ].map(buildIconLayer),\r\n details: {\r\n 'bike-shops': {\r\n name: 'Bike Shop',\r\n icon: 'store-alt',\r\n color: 'white'\r\n },\r\n 'rental': {\r\n name: 'Bike Rental',\r\n icon: 'bicycle',\r\n color: 'white'\r\n },\r\n 'tool-station': {\r\n name: 'Tool Station',\r\n icon: 'wrench',\r\n color: 'white'\r\n },\r\n }\r\n};\r\n\r\n// ROUTES layer for Class I,II,III routes\r\nexport const ROUTES = {\r\n source: SOURCES.get('bike-routes'),\r\n layers: [\r\n {\r\n id: 'ClassI', \r\n paint: {\r\n 'line-color': '#2fa021',\r\n },\r\n layerName: 'Existing Class I',\r\n },\r\n {\r\n id: 'ClassII', \r\n paint: {\r\n 'line-color': '#103ca1',\r\n },\r\n layerName: 'Existing Class II',\r\n },\r\n {\r\n id: 'ClassIII', \r\n paint: {\r\n 'line-color': '#fa8807',\r\n },\r\n layerName: 'Existing Class III',\r\n },\r\n {\r\n id: 'Trail', \r\n paint: {\r\n 'line-color': '#baa77c',\r\n 'line-dasharray': [1,2],\r\n //\"line-opacity\": 1,\r\n },\r\n layerName: 'Existing Trail',\r\n },\r\n ].map(buildRouteLayer),\r\n // What shows up in legend\r\n details: {\r\n 'ClassI': {\r\n name: 'Multi-use Path',\r\n description: 'A separated paved path for bicycles and pedestrians.'\r\n },\r\n 'ClassII': {\r\n name: 'Bike Lane',\r\n description: 'A restricted right-of-way for bicycles along the side of a street (typically 5 feet wide). A thick white line separates the auto and bike lanes. Motor vehicles may merge into these lanes to make turns.'\r\n },\r\n 'ClassIII': {\r\n name: 'Shared Road',\r\n description: 'A travel lane shared by bicycles and motor vehicles designated only by signs or pavement markings. This type of facility mainly informs motorists of preferred cycling routes.'\r\n },\r\n 'Trail': {\r\n name: 'Natural Surface',\r\n description: 'A dirt or gravel path that is often bicycle compatible'\r\n },\r\n }\r\n};\r\n\r\n// CONNECTORS layer for city/rural connections\r\nexport const CONNECTORS = {\r\n source: SOURCES.get('connectors'),\r\n layers: [\r\n {\r\n id: 'Family-Friendly', \r\n paint: {\r\n 'line-color': 'green',\r\n 'line-dasharray': [1,2],\r\n },\r\n layerName: 'Family Friendly',\r\n },\r\n {\r\n id: 'Intermediate', \r\n paint: {\r\n 'line-color': '#2b47a1',\r\n 'line-dasharray': [1,2],\r\n },\r\n layerName: 'Intermediate',\r\n },\r\n {\r\n id: 'Advanced', \r\n paint: {\r\n 'line-color': '#871f1f',\r\n 'line-dasharray': [1,2],\r\n },\r\n layerName: 'Advanced',\r\n },\r\n ].map(buildConnectorLayer),\r\n // What shows up in legend\r\n details: {\r\n 'Family-Friendly': {\r\n name: 'Mellow',\r\n description:'Lower traffic/speed streets; generally appropriate for children and for relaxed everyday use'\r\n },\r\n 'Intermediate': {\r\n name: 'Confident',\r\n description:'Moderate traffic/speed with medium shoulder width streets; suitable for a range of bicyclists'\r\n },\r\n 'Advanced': {\r\n name: 'Brave',\r\n description:'High traffic volume/speed; narrow or non-existent shoulder, and/or extreme topography (hills)'\r\n },\r\n }\r\n};\r\n\r\n// PCB layer for official and alt routes\r\nexport const PCB = {\r\n source: SOURCES.get('pcb'),\r\n layers: [\r\n {\r\n id: 'Official', \r\n paint: {\r\n 'line-color': 'black',\r\n },\r\n layerName: 'Official',\r\n },\r\n {\r\n id: 'Alternative', \r\n paint: {\r\n 'line-color': 'gray',\r\n },\r\n layerName: 'Alternative',\r\n },\r\n ].map(buildPcbLayer),\r\n details: {\r\n 'Official': {\r\n name: 'Official',\r\n description:'Official Pacific Coast Bike Route.'\r\n },\r\n 'Alternative': {\r\n name: 'Alternative',\r\n description:'Alternative Pacific Coast Bike Route segments.'\r\n },\r\n }\r\n};\r\n\r\nexport default { icons:ICONS, routes:ROUTES, connectors:CONNECTORS, pcb:PCB };\r\n","import PropTypes from 'prop-types';\r\nimport { useMemo } from 'react';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport styles from './style.module.css';\r\nimport { ICONS } from '../../config/layers';\r\n\r\nconst iconIdMap = {\r\n 'Bicycle Shop': 'bike-shops',\r\n 'Rental': 'rental',\r\n 'Tool Station': 'tool-station'\r\n};\r\n\r\nexport const FeatureInfo = ({ type, info }) => {\r\n const typeProperty = useMemo(\r\n () => type === 'route' ? 'type_2021' : 'Type',\r\n [type]\r\n );\r\n const icon = useMemo(() => {\r\n if (type !== 'icon')\r\n return;\r\n // const { icon, color } = ICONS.details[iconIdMap[info[typeProperty]]];\r\n const { icon } = ICONS.details[iconIdMap[info[typeProperty]]];\r\n return ;\r\n }, [type, typeProperty]);\r\n const link = useMemo(\r\n () => {\r\n if (type === 'icon')\r\n return (\r\n \r\n \r\n \r\n );\r\n },\r\n [type, info]\r\n );\r\n const body = useMemo(\r\n () => {\r\n if (type === 'icon')\r\n return (\r\n

{info.Location}

\r\n );\r\n if (type === 'route' && info[typeProperty] === 'Existing Trail')\r\n return (\r\n

Bikes Allowed: {info.Bikes_Allo}

\r\n );\r\n },\r\n [type, info]\r\n );\r\n return (\r\n
\r\n

{icon}{info[typeProperty]}

\r\n {\r\n info.Name &&\r\n
\r\n

{info.Name}

\r\n {link}\r\n
\r\n }\r\n {body}\r\n
\r\n );\r\n};\r\n\r\nFeatureInfo.propTypes = {\r\n type: PropTypes.string.isRequired,\r\n info: PropTypes.shape({\r\n Name: PropTypes.string,\r\n Location: PropTypes.string,\r\n Website: PropTypes.string,\r\n Bikes_Allo: PropTypes.string,\r\n type_2021: PropTypes.string,\r\n }).isRequired,\r\n};\r\n\r\nexport default FeatureInfo;","export default __webpack_public_path__ + \"static/media/logo.3d93fbe4.png\";","export const getViewPort = () => {\r\n const { innerWidth: width, innerHeight: height } = window;\r\n return { width, height };\r\n};","/**\r\n * @param {string} layer - layer to focus\r\n */\r\nexport const setFocusedLayer = (layer) => {\r\n return {\r\n type: setFocusedLayer,\r\n value: layer\r\n };\r\n};\r\n/**\r\n */\r\nexport const clearFocusedLayer = () => {\r\n return {\r\n type: clearFocusedLayer\r\n };\r\n};\r\n/**\r\n */\r\nexport const showSidebar = () => {\r\n return {\r\n type: showSidebar\r\n };\r\n};\r\n\r\n/**\r\n */\r\nexport const hideSidebar = () => {\r\n return {\r\n type: hideSidebar\r\n };\r\n};\r\n\r\n/**\r\n */\r\nexport const toggleSidebar = () => {\r\n return {\r\n type: toggleSidebar\r\n };\r\n};","import { setFocusedLayer, clearFocusedLayer, showSidebar, hideSidebar, toggleSidebar } from './actions';\r\n\r\nexport default (state, {type, value}) => {\r\n switch (type) {\r\n case setFocusedLayer:\r\n return { ...state, focusedLayer: value };\r\n case clearFocusedLayer:\r\n return { ...state, focusedLayer: undefined };\r\n case showSidebar:\r\n return {...state, showSidebar: true};\r\n case hideSidebar:\r\n return {...state, showSidebar: false};\r\n case toggleSidebar:\r\n return {...state, showSidebar: !state.showSidebar};\r\n }\r\n};\r\n","import PropTypes from 'prop-types';\r\nimport { createContext, useContext, useReducer } from 'react';\r\nimport { getViewPort } from '../../util/window';\r\nimport reducer from './reducer';\r\n\r\nconst { width } = getViewPort();\r\n\r\nconst initialState = {\r\n showSidebar: width > 600,\r\n focusedLayer: 'class1',\r\n};\r\n\r\nconst GlobalContext = createContext(initialState);\r\n\r\nexport * from './actions';\r\n\r\nexport const GlobalProvider = ({children}) => {\r\n const [globalState, dispatch] = useReducer(reducer, initialState);\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\nGlobalProvider.propTypes = {\r\n children: PropTypes.element.isRequired\r\n};\r\n\r\nexport const useGlobals = () => useContext(GlobalContext);\r\n\r\nexport default GlobalProvider;\r\n","/**\r\n * @param {string} layer - the layer to toggle visibility for\r\n */\r\nexport const toggleVisibility = (layer) => {\r\n return {\r\n type: toggleVisibility,\r\n value: layer\r\n };\r\n};\r\n","import { toggleVisibility } from './actions';\r\n\r\nexport default (state, {type, value}) => {\r\n switch (type) {\r\n case toggleVisibility:\r\n\r\n return { ...state, [value]: !state[value] };\r\n }\r\n};\r\n","import PropTypes from 'prop-types';\r\nimport { createContext, useContext, useReducer } from 'react';\r\nimport reducer from './reducer';\r\n\r\nconst initialState = {\r\n ClassI: true,\r\n ClassII: true,\r\n ClassIII: true,\r\n Trail: true,\r\n 'rental': true,\r\n 'bike-shops': true,\r\n 'tool-station': true,\r\n 'Official': false,\r\n 'Alternative': false\r\n};\r\n\r\nconst LayerVisibilityContext = createContext(initialState);\r\n\r\nexport * from './actions';\r\n\r\nexport const LayerVisibilityContextProvider = ({children}) => {\r\n const [visibilityState, dispatch] = useReducer(reducer, initialState);\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\nLayerVisibilityContextProvider.propTypes = {\r\n children: PropTypes.element.isRequired\r\n};\r\n\r\nexport const useLayerVisibility = () => useContext(LayerVisibilityContext);\r\n\r\nexport default LayerVisibilityContextProvider;\r\n","import PropTypes from 'prop-types';\r\nimport { useRef } from 'react';\r\nimport styles from './style.module.css';\r\n\r\nconst setOffset = (offset) => offset\r\n ? document.documentElement.style.setProperty('--tooltip-offset', `${offset}px`)\r\n : document.documentElement.style.removeProperty('--tooltip-offset');\r\n\r\nconst ToolTip = ({text, direction, children}) => {\r\n const tooltipRef = useRef();\r\n const updateOffset = () => {\r\n if (!tooltipRef.current) return;\r\n const rect = tooltipRef.current.getBoundingClientRect();\r\n const deltaX = Math.floor(Math.min(0, window.innerWidth - rect.right));\r\n setOffset(deltaX);\r\n };\r\n const clearOffset = () => setOffset(0);\r\n return (\r\n \r\n {children}\r\n \r\n {text}\r\n \r\n \r\n );\r\n};\r\n\r\nToolTip.propTypes = {\r\n text: PropTypes.string.isRequired,\r\n direction: PropTypes.oneOf(['top', 'bottom', 'left', 'right']).isRequired,\r\n children: PropTypes.node.isRequired\r\n};\r\n\r\nexport default ToolTip;\r\n","import PropTypes from 'prop-types';\r\nimport { useMemo } from 'react';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport { clearFocusedLayer, setFocusedLayer, useGlobals } from '../../contexts/GlobalContext';\r\nimport { toggleVisibility, useLayerVisibility } from '../../contexts/LayerVisibilityContext';\r\nimport ToolTip from '../ToolTip';\r\nimport styles from './style.module.css';\r\nimport { ICONS } from '../../config/layers';\r\n\r\nconst LayerToggle = ({ layerId, details: { name, description }, type = 'icon' }) => {\r\n const [, dispatchGlobals] = useGlobals();\r\n const [layerVisibility, dispatchVisibility] = useLayerVisibility();\r\n\r\n const toggle = () => dispatchVisibility(toggleVisibility(layerId));\r\n const focus = () => dispatchGlobals(setFocusedLayer(layerId));\r\n const unfocus = () => dispatchGlobals(clearFocusedLayer(layerId));\r\n\r\n const icon = useMemo(() => {\r\n if (type !== 'icon')\r\n return;\r\n const { icon, color } = ICONS.details[layerId];\r\n return ;\r\n }, [type]);\r\n \r\n return (\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n
\r\n {\r\n description && \r\n \r\n \r\n \r\n }\r\n \r\n );\r\n};\r\n\r\nLayerToggle.propTypes = {\r\n layerId: PropTypes.string.isRequired,\r\n details: PropTypes.shape({\r\n name: PropTypes.string.isRequired,\r\n description: PropTypes.string,\r\n }).isRequired,\r\n type: PropTypes.string,\r\n};\r\n\r\nexport default LayerToggle;\r\n","import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport PropTypes from 'prop-types';\r\nimport ToolTip from '../ToolTip';\r\nimport styles from './style.module.css';\r\n\r\nconst LayerToggleGroup = ({header, description, children}) => (\r\n <>\r\n {\r\n header &&\r\n

\r\n {header}\r\n {\r\n description &&\r\n \r\n \r\n \r\n }\r\n

\r\n }\r\n {children}\r\n \r\n);\r\n\r\nLayerToggleGroup.propTypes = {\r\n header: PropTypes.string,\r\n description: PropTypes.string,\r\n children: PropTypes.any,\r\n};\r\n\r\nexport default LayerToggleGroup;","import PropTypes from 'prop-types';\r\nimport { CONNECTORS, ICONS, ROUTES, PCB } from '../../config/layers';\r\nimport logo from '../../images/logo.png';\r\nimport LayerToggle from '../LayerToggle';\r\nimport LayerToggleGroup from '../LayerToggleGroup';\r\nimport styles from './style.module.css';\r\n\r\nconst Sidebar = ({show}) => {\r\n const layerToggleGroups = [\r\n {\r\n details:ROUTES.details,\r\n header: 'Existing Bike Routes',\r\n toggleType: 'line'\r\n },\r\n {\r\n details:ICONS.details,\r\n },\r\n {\r\n details:CONNECTORS.details,\r\n header: 'Connector Routes',\r\n description: 'These dashed lines are streets that bicyclists often use, but do not yet have dedicated bicycle infrastructure.',\r\n toggleType: 'line'\r\n },\r\n {\r\n details:PCB.details,\r\n header: 'Pacific Coast Bike Route',\r\n toggleType: 'line'\r\n },\r\n ];\r\n\r\n return (\r\n <>\r\n
\r\n
\r\n \"HCAGO\r\n
\r\n
\r\n

\r\n Humboldt County offers incredible biking opportunities \r\n for visitors and residents alike. \r\n Find a new way to commute to work, explore the countryside, \r\n take an adventurous mountain bike ride, and more!\r\n

\r\n

\r\n To learn more about Humboldt County Bike Routes click\r\n here.\r\n

\r\n
\r\n {\r\n layerToggleGroups.map(({\r\n header,\r\n description,\r\n details,\r\n toggleType\r\n }, i) => (\r\n \r\n {\r\n Object.entries(details)\r\n .map(([layerId, details]) => (\r\n \r\n ))\r\n }\r\n \r\n ))\r\n }\r\n \r\n
\r\n

Public Transit Routes

\r\n

Note that several bus lines are equipped with bike racks. \r\n Plan your connection here.

\r\n
\r\n
\r\n \r\n );\r\n};\r\n\r\nSidebar.propTypes = {\r\n show: PropTypes.bool\r\n};\r\n\r\nexport default Sidebar;\r\n","import { useMemo } from 'react';\r\nimport { LAYER_WEIGHTS, calculateLineWidth } from '../config/layers';\r\n\r\nconst LAYER_FOCUS_WEIGHTS = {\r\n symbol: LAYER_WEIGHTS.symbol * 1.5,\r\n line: LAYER_WEIGHTS.line * 2,\r\n};\r\n\r\nexport const filterVisibleLayers = (\r\n layers,\r\n layerVisibility,\r\n focusedLayerId,\r\n baseLayerId\r\n) => {\r\n const visibleLayers = useMemo(\r\n () => layers.filter((layer) => layerVisibility[layer.id]),\r\n [layers, layerVisibility]\r\n );\r\n const layersOrderedByFocus = useMemo(\r\n () => visibleLayers.map((layer, i) => [i, layer])\r\n .sort(([ai, a], [bi, b]) => {\r\n if (a.id == focusedLayerId) return -1;\r\n if (b.id == focusedLayerId) return 1;\r\n return ai - bi;\r\n })\r\n .map(([,layer]) => layer),\r\n [visibleLayers, focusedLayerId]\r\n );\r\n return Array.from(\r\n useMemo(\r\n () => layersOrderedByFocus.map((layer, i, layers) => ({\r\n ...layer,\r\n before: layers[i - 1]?.id ?? baseLayerId\r\n })),\r\n [layersOrderedByFocus, baseLayerId]\r\n )\r\n );\r\n};\r\nexport const applyFocusStyleToLayer = (layer) => {\r\n switch (layer.type) {\r\n case 'symbol':\r\n return { \r\n ...layer,\r\n layout:{\r\n ...layer.layout,\r\n 'icon-size': LAYER_FOCUS_WEIGHTS.symbol\r\n },\r\n };\r\n case 'line':\r\n return { \r\n ...layer,\r\n paint: {\r\n ...layer.paint,\r\n 'line-width': calculateLineWidth(LAYER_FOCUS_WEIGHTS.line),\r\n }\r\n };\r\n }\r\n};\r\n","export default {\r\n LARGE: 992\r\n};","import PropTypes from 'prop-types';\r\nimport { createContext, useContext, useEffect, useState } from 'react';\r\nimport { getViewPort } from '../../util/window';\r\n\r\nconst ViewPortContext = createContext(getViewPort());\r\n\r\nexport const ViewPortProvider = ({children}) => {\r\n const [viewPort, setViewPort] = useState(getViewPort());\r\n\r\n useEffect(() => {\r\n const onResize = () => {\r\n setViewPort(getViewPort());\r\n };\r\n window.addEventListener('resize', onResize);\r\n return () => window.removeEventListener('resize', onResize);\r\n }, [viewPort]);\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\nViewPortProvider.propTypes = {\r\n children: PropTypes.element.isRequired\r\n};\r\n\r\nexport const useViewPort = () => useContext(ViewPortContext);\r\n\r\nexport default ViewPortProvider;\r\n","import { useContext, useEffect } from 'react';\r\nimport { MapContext } from '@urbica/react-map-gl';\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\r\nimport Breakpoints from '../../config/breakpoints';\r\nimport { toggleSidebar, useGlobals } from '../../contexts/GlobalContext';\r\nimport { useViewPort } from '../../contexts/ViewPortContext';\r\nimport styles from './style.module.css';\r\n\r\nconst SidebarControl = () => {\r\n const [{showSidebar}, dispatch] = useGlobals();\r\n const {width} = useViewPort();\r\n const map = useContext(MapContext);\r\n\r\n\r\n const onClick = () => dispatch(toggleSidebar());\r\n const showControl = width <= Breakpoints.LARGE;\r\n\r\n useEffect(() => {\r\n if (showControl) return;\r\n if (showSidebar) return;\r\n dispatch(toggleSidebar());\r\n }, [showControl]);\r\n useEffect(() => map.resize(), [showSidebar]);\r\n\r\n if (!showControl) return <>;\r\n\r\n return (\r\n
\r\n
\r\n \r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default SidebarControl;","import React, { useCallback, useState, useEffect } from 'react';\r\nimport MapGL, { GeolocateControl, Layer, NavigationControl, Popup, Source, AttributionControl } from '@urbica/react-map-gl';\r\n\r\nimport FeatureInfo from './components/FeatureInfo';\r\nimport Sidebar from './components/Sidebar';\r\n\r\nimport { MAP_DEFAULTS } from './config/map';\r\nimport { ICONS, ROUTES, CONNECTORS, PCB } from './config/layers.js';\r\n\r\nimport { useGlobals } from './contexts/GlobalContext';\r\nimport { useLayerVisibility } from './contexts/LayerVisibilityContext';\r\n\r\nimport { applyFocusStyleToLayer, filterVisibleLayers } from './util/layers';\r\n\r\nimport './App.css';\r\nimport SidebarControl from './components/SidebarControl';\r\n\r\n// mayStyle choices\r\nconst styles = {\r\n light: 'mapbox://styles/hcaog/ckr3qf0ot95xh17linukv86ts'\r\n};\r\n\r\nconst App = () => {\r\n const [globals] = useGlobals();\r\n const [ layerVisibility ] = useLayerVisibility();\r\n\r\n const [cursorStyle, setCursorStyle] = useState();\r\n const [viewport, setViewport] = useState(MAP_DEFAULTS.viewport);\r\n \r\n const [selectedFeature, setSelectedFeature] = useState();\r\n\r\n const clearSelectedFeature = () => setSelectedFeature(() => null);\r\n\r\n const onFeatureClick = (type) => useCallback(({features, lngLat}) => {\r\n setSelectedFeature(() => ({\r\n type,\r\n ...lngLat,\r\n info: features[0]?.properties,\r\n }));\r\n }, [type]);\r\n\r\n const onRouteFeatureClick = onFeatureClick('route');\r\n const onConnectorFeatureClick = onFeatureClick('connector');\r\n const onIconFeatureClick = onFeatureClick('icon');\r\n const onPCBFeatureClick = onFeatureClick('pcb');\r\n\r\n const resetCursor = () => setCursorStyle(null);\r\n const setPointerCursor = () => setCursorStyle('pointer');\r\n\r\n const mapLayerSources = [\r\n {\r\n ...ROUTES.source,\r\n layers: filterVisibleLayers(\r\n ROUTES.layers,\r\n layerVisibility,\r\n globals.focusedLayer,\r\n ICONS.layers.slice(-1)[0]?.id\r\n ),\r\n onLayerClick: onRouteFeatureClick\r\n },\r\n {\r\n ...CONNECTORS.source,\r\n layers: filterVisibleLayers(\r\n CONNECTORS.layers,\r\n layerVisibility,\r\n globals.focusedLayer\r\n ),\r\n onLayerClick: onConnectorFeatureClick\r\n },\r\n {\r\n ...PCB.source,\r\n layers: filterVisibleLayers(\r\n PCB.layers,\r\n layerVisibility,\r\n globals.focusedLayer\r\n ),\r\n onLayerClick: onPCBFeatureClick\r\n },\r\n {\r\n ...ICONS.source,\r\n layers: filterVisibleLayers(\r\n ICONS.layers,\r\n layerVisibility,\r\n globals.focusedLayer\r\n ),\r\n onLayerClick: onIconFeatureClick\r\n },\r\n ];\r\n\r\n useEffect(clearSelectedFeature, [layerVisibility]);\r\n\r\n return (\r\n
\r\n \r\n {\r\n mapLayerSources.map(({layers, onLayerClick, ...source}) => {\r\n const filteredLayers = layers\r\n .map(layer =>\r\n globals.focusedLayer === layer.id\r\n ? applyFocusStyleToLayer(layer)\r\n : layer\r\n )\r\n .map((layer) => (\r\n \r\n ));\r\n if (!filteredLayers.length) return null;\r\n return (\r\n \r\n { filteredLayers }\r\n \r\n );\r\n }).filter(source => source)\r\n \r\n }\r\n \r\n {\r\n selectedFeature && (\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\nexport default App;\r\n","const reportWebVitals = onPerfEntry => {\r\n if (onPerfEntry && onPerfEntry instanceof Function) {\r\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\r\n getCLS(onPerfEntry);\r\n getFID(onPerfEntry);\r\n getFCP(onPerfEntry);\r\n getLCP(onPerfEntry);\r\n getTTFB(onPerfEntry);\r\n });\r\n }\r\n};\r\n\r\nexport default reportWebVitals;\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\n\r\nimport '@fortawesome/fontawesome-svg-core/attribution';\r\nimport { library } from '@fortawesome/fontawesome-svg-core';\r\nimport {faInfoCircle, faExternalLinkAlt, faChevronRight, faChevronLeft, faDollarSign, faBicycle, faWrench, faStoreAlt} from '@fortawesome/free-solid-svg-icons';\r\n\r\nimport App from './App';\r\n\r\nimport { GlobalProvider } from './contexts/GlobalContext';\r\nimport { LayerVisibilityContextProvider } from './contexts/LayerVisibilityContext';\r\nimport ViewPortProvider from './contexts/ViewPortContext';\r\n\r\nimport reportWebVitals from './reportWebVitals';\r\n\r\nimport './index.css';\r\n\r\nlibrary.add(\r\n faInfoCircle,\r\n faExternalLinkAlt,\r\n faChevronRight,\r\n faChevronLeft,\r\n faDollarSign,\r\n faBicycle,\r\n faWrench,\r\n faStoreAlt\r\n);\r\n\r\nReactDOM.render(\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n ,\r\n document.getElementById('root')\r\n);\r\n// If you want to start measuring performance in your app, pass a function\r\n// to log results (for example: reportWebVitals(console.log))\r\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\r\nreportWebVitals();\r\n"],"sourceRoot":""}