\n
\n {showZoom && renderButton('zoom-in', zoomInLabel, onZoomIn)}\n {showZoom && renderButton('zoom-out', zoomOutLabel, onZoomOut)}\n {showCompass && renderButton('compass', compassLabel, onResetNorth, renderCompass(context))}\n
\n
\n );\n}\n\nNavigationControl.propTypes = propTypes;\nNavigationControl.defaultProps = defaultProps;\n\nexport default React.memo(NavigationControl);\n","// Helper function for version comparison\n// A version is a string in the format of \"{major}.{minor}.{patch}\"\n// Empty/missing version is treated as \"0.0.0\"\n// If version1 is smaller than version2, return -1\n// If version1 is larger than version2, return 1\n// If equal, return 0\nexport function compareVersions(version1, version2) {\n const v1 = (version1 || '').split('.').map(Number);\n const v2 = (version2 || '').split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const part1 = v1[i] || 0;\n const part2 = v2[i] || 0;\n if (part1 < part2) {\n return -1;\n }\n if (part1 > part2) {\n return 1;\n }\n }\n\n return 0;\n}\n","// Copyright (c) 2015 Uber Technologies, Inc.\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\nimport * as React from 'react';\nimport {useEffect, useState, useMemo} from 'react';\nimport * as PropTypes from 'prop-types';\nimport mapboxgl from '../utils/mapboxgl';\nimport useMapControl, {mapControlDefaultProps, mapControlPropTypes} from './use-map-control';\n\nconst propTypes = Object.assign({}, mapControlPropTypes, {\n className: PropTypes.string,\n style: PropTypes.object,\n maxWidth: PropTypes.number,\n unit: PropTypes.oneOf(['imperial', 'metric', 'nautical'])\n});\n\nconst defaultProps = Object.assign({}, mapControlDefaultProps, {\n className: '',\n maxWidth: 100,\n unit: 'metric'\n});\n\nfunction ScaleControl(props) {\n const {context, containerRef} = useMapControl(props);\n const [mapboxScaleControl, createMapboxScaleControl] = useState(null);\n\n useEffect(() => {\n if (context.map) {\n const control = new mapboxgl.ScaleControl();\n control._map = context.map;\n control._container = containerRef.current;\n createMapboxScaleControl(control);\n }\n }, [context.map]);\n\n if (mapboxScaleControl) {\n mapboxScaleControl.options = props;\n mapboxScaleControl._onMove();\n }\n\n const style = useMemo(() => ({position: 'absolute', ...props.style}), [props.style]);\n\n return (\n \n {props.redraw({\n width: viewport.width,\n height: viewport.height,\n isDragging,\n project: viewport.project,\n unproject: viewport.unproject\n })}\n
\n );\n}\n\nHTMLOverlay.propTypes = propTypes;\nHTMLOverlay.defaultProps = defaultProps;\n\nexport default HTMLOverlay;\n","// Copyright (c) 2015 Uber Technologies, Inc.\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport * as React from 'react';\nimport * as PropTypes from 'prop-types';\nimport useMapControl, {mapControlPropTypes} from '../components/use-map-control';\n\nconst propTypes = Object.assign({}, mapControlPropTypes, {\n redraw: PropTypes.func.isRequired,\n style: PropTypes.object\n});\n\nconst defaultProps = {\n captureScroll: false,\n captureDrag: false,\n captureClick: false,\n captureDoubleClick: false,\n capturePointerMove: false\n};\n\nfunction SVGOverlay(props) {\n const {context, containerRef} = useMapControl(props);\n const {viewport, isDragging} = context;\n const style = {\n position: 'absolute',\n left: 0,\n top: 0,\n ...props.style\n };\n\n return (\n