google-map-react
Version:
Isomorphic component that allows rendering react components on a google map
1,720 lines (1,392 loc) • 71 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import EventEmitter from 'eventemitter3';
import Point from '@mapbox/point-geometry';
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var style = {
width: '100%',
height: '100%',
left: 0,
top: 0,
margin: 0,
padding: 0,
position: 'absolute'
};
var GoogleMapMap = /*#__PURE__*/function (_Component) {
_inheritsLoose(GoogleMapMap, _Component);
function GoogleMapMap() {
return _Component.apply(this, arguments) || this;
}
var _proto = GoogleMapMap.prototype;
_proto.shouldComponentUpdate = function shouldComponentUpdate() {
return false;
};
_proto.render = function render() {
var registerChild = this.props.registerChild;
return /*#__PURE__*/React.createElement("div", {
ref: registerChild,
style: style
});
};
return GoogleMapMap;
}(Component);
var MarkerDispatcher = /*#__PURE__*/function (_EventEmitter) {
_inheritsLoose(MarkerDispatcher, _EventEmitter);
function MarkerDispatcher(gmapInstance) {
var _this;
_this = _EventEmitter.call(this) || this;
_this.gmapInstance = gmapInstance;
return _this;
}
var _proto = MarkerDispatcher.prototype;
_proto.getChildren = function getChildren() {
return this.gmapInstance.props.children;
};
_proto.getMousePosition = function getMousePosition() {
return this.gmapInstance.mouse_;
};
_proto.getUpdateCounter = function getUpdateCounter() {
return this.gmapInstance.updateCounter_;
};
_proto.dispose = function dispose() {
this.gmapInstance = null;
this.removeAllListeners();
};
return MarkerDispatcher;
}(EventEmitter);
var omit = function omit(obj, keys) {
var rest = _extends({}, obj);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (key in rest) {
delete rest[key];
}
}
return rest;
};
var hasOwnProperty = Object.prototype.hasOwnProperty;
function is(x, y) {
if (x === y) {
return x !== 0 || y !== 0 || 1 / x === 1 / y;
}
return x !== x && y !== y;
}
function shallowEqual(objA, objB) {
if (is(objA, objB)) {
return true;
}
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
return false;
}
var keysA = Object.keys(objA);
var keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
for (var i = 0; i < keysA.length; i++) {
if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
}
return true;
}
var mainStyle = {
width: '100%',
height: '100%',
left: 0,
top: 0,
margin: 0,
padding: 0,
position: 'absolute'
};
var style$1 = {
width: 0,
height: 0,
left: 0,
top: 0,
backgroundColor: 'transparent',
position: 'absolute'
};
var GoogleMapMarkers = /*#__PURE__*/function (_Component) {
_inheritsLoose(GoogleMapMarkers, _Component);
function GoogleMapMarkers(props) {
var _this;
_this = _Component.call(this, props) || this;
_this._getState = function () {
return {
children: _this.props.dispatcher.getChildren(),
updateCounter: _this.props.dispatcher.getUpdateCounter()
};
};
_this._onChangeHandler = function () {
if (!_this.dimensionsCache_) {
return;
}
var prevChildCount = (_this.state.children || []).length;
var state = _this._getState();
_this.setState(state, function () {
return (state.children || []).length !== prevChildCount && _this._onMouseChangeHandler();
});
};
_this._onChildClick = function () {
if (_this.props.onChildClick) {
if (_this.hoverChildProps_) {
var hoverKey = _this.hoverKey_;
var childProps = _this.hoverChildProps_;
_this.props.onChildClick(hoverKey, childProps);
}
}
};
_this._onChildMouseDown = function () {
if (_this.props.onChildMouseDown) {
if (_this.hoverChildProps_) {
var hoverKey = _this.hoverKey_;
var childProps = _this.hoverChildProps_;
_this.props.onChildMouseDown(hoverKey, childProps);
}
}
};
_this._onChildMouseEnter = function (hoverKey, childProps) {
if (!_this.dimensionsCache_) {
return;
}
if (_this.props.onChildMouseEnter) {
_this.props.onChildMouseEnter(hoverKey, childProps);
}
_this.hoverChildProps_ = childProps;
_this.hoverKey_ = hoverKey;
_this.setState({
hoverKey: hoverKey
});
};
_this._onChildMouseLeave = function () {
if (!_this.dimensionsCache_) {
return;
}
var hoverKey = _this.hoverKey_;
var childProps = _this.hoverChildProps_;
if (hoverKey !== undefined && hoverKey !== null) {
if (_this.props.onChildMouseLeave) {
_this.props.onChildMouseLeave(hoverKey, childProps);
}
_this.hoverKey_ = null;
_this.hoverChildProps_ = null;
_this.setState({
hoverKey: null
});
}
};
_this._onMouseAllow = function (value) {
if (!value) {
_this._onChildMouseLeave();
}
_this.allowMouse_ = value;
};
_this._onMouseChangeHandler = function () {
if (_this.allowMouse_) {
_this._onMouseChangeHandlerRaf();
}
};
_this._onMouseChangeHandlerRaf = function () {
if (!_this.dimensionsCache_) {
return;
}
var mp = _this.props.dispatcher.getMousePosition();
if (mp) {
var distances = [];
var hoverDistance = _this.props.getHoverDistance();
React.Children.forEach(_this.state.children, function (child, childIndex) {
if (!child) return;
if (child.props.latLng === undefined && child.props.lat === undefined && child.props.lng === undefined) {
return;
}
var childKey = child.key !== undefined && child.key !== null ? child.key : childIndex;
var dist = _this.props.distanceToMouse(_this.dimensionsCache_[childKey], mp, child.props);
if (dist < hoverDistance) {
distances.push({
key: childKey,
dist: dist,
props: child.props
});
}
});
if (distances.length) {
distances.sort(function (a, b) {
return a.dist - b.dist;
});
var hoverKey = distances[0].key;
var childProps = distances[0].props;
if (_this.hoverKey_ !== hoverKey) {
_this._onChildMouseLeave();
_this._onChildMouseEnter(hoverKey, childProps);
}
} else {
_this._onChildMouseLeave();
}
} else {
_this._onChildMouseLeave();
}
};
_this._getDimensions = function (key) {
var childKey = key;
return _this.dimensionsCache_[childKey];
};
_this.dimensionsCache_ = {};
_this.hoverKey_ = null;
_this.hoverChildProps_ = null;
_this.allowMouse_ = true;
_this.state = _extends({}, _this._getState(), {
hoverKey: null
});
return _this;
}
var _proto = GoogleMapMarkers.prototype;
_proto.componentDidMount = function componentDidMount() {
this.props.dispatcher.on('kON_CHANGE', this._onChangeHandler);
this.props.dispatcher.on('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler);
this.props.dispatcher.on('kON_CLICK', this._onChildClick);
this.props.dispatcher.on('kON_MDOWN', this._onChildMouseDown);
};
_proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
if (this.props.experimental === true) {
return !shallowEqual(this.props, nextProps) || !shallowEqual(omit(this.state, ['hoverKey']), omit(nextState, ['hoverKey']));
}
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
};
_proto.componentWillUnmount = function componentWillUnmount() {
this.props.dispatcher.removeListener('kON_CHANGE', this._onChangeHandler);
this.props.dispatcher.removeListener('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler);
this.props.dispatcher.removeListener('kON_CLICK', this._onChildClick);
this.props.dispatcher.removeListener('kON_MDOWN', this._onChildMouseDown);
this.dimensionsCache_ = null;
};
_proto.render = function render() {
var _this2 = this;
var mainElementStyle = this.props.style || mainStyle;
this.dimensionsCache_ = {};
var markers = React.Children.map(this.state.children, function (child, childIndex) {
if (!child) return undefined;
if (child.props.latLng === undefined && child.props.lat === undefined && child.props.lng === undefined) {
return React.cloneElement(child, {
$geoService: _this2.props.geoService,
$onMouseAllow: _this2._onMouseAllow,
$prerender: _this2.props.prerender
});
}
var latLng = child.props.latLng !== undefined ? child.props.latLng : {
lat: child.props.lat,
lng: child.props.lng
};
var pt = _this2.props.insideMapPanes ? _this2.props.geoService.fromLatLngToDivPixel(latLng) : _this2.props.geoService.fromLatLngToCenterPixel(latLng);
var stylePtPos = {
left: pt.x,
top: pt.y
};
if (child.props.seLatLng !== undefined || child.props.seLat !== undefined && child.props.seLng !== undefined) {
var seLatLng = child.props.seLatLng !== undefined ? child.props.seLatLng : {
lat: child.props.seLat,
lng: child.props.seLng
};
var sePt = _this2.props.insideMapPanes ? _this2.props.geoService.fromLatLngToDivPixel(seLatLng) : _this2.props.geoService.fromLatLngToCenterPixel(seLatLng);
stylePtPos.width = sePt.x - pt.x;
stylePtPos.height = sePt.y - pt.y;
}
var containerPt = _this2.props.geoService.fromLatLngToContainerPixel(latLng);
var childKey = child.key !== undefined && child.key !== null ? child.key : childIndex;
_this2.dimensionsCache_[childKey] = _extends({
x: containerPt.x,
y: containerPt.y
}, latLng);
return /*#__PURE__*/React.createElement("div", {
key: childKey,
style: _extends({}, style$1, stylePtPos),
className: child.props.$markerHolderClassName
}, React.cloneElement(child, {
$hover: childKey === _this2.state.hoverKey,
$getDimensions: _this2._getDimensions,
$dimensionKey: childKey,
$geoService: _this2.props.geoService,
$onMouseAllow: _this2._onMouseAllow,
$prerender: _this2.props.prerender
}));
});
return /*#__PURE__*/React.createElement("div", {
style: mainElementStyle
}, markers);
};
return GoogleMapMarkers;
}(Component);
GoogleMapMarkers.propTypes = {
geoService: PropTypes.any,
style: PropTypes.any,
distanceToMouse: PropTypes.func,
dispatcher: PropTypes.any,
onChildClick: PropTypes.func,
onChildMouseDown: PropTypes.func,
onChildMouseLeave: PropTypes.func,
onChildMouseEnter: PropTypes.func,
getHoverDistance: PropTypes.func,
insideMapPanes: PropTypes.bool,
prerender: PropTypes.bool
};
GoogleMapMarkers.defaultProps = {
insideMapPanes: false,
prerender: false
};
var style$2 = {
width: '50%',
height: '50%',
left: '50%',
top: '50%',
margin: 0,
padding: 0,
position: 'absolute'
};
function GoogleMapMarkersPrerender (props) {
return /*#__PURE__*/React.createElement("div", {
style: style$2
}, /*#__PURE__*/React.createElement(GoogleMapMarkers, _extends({}, props, {
prerender: true
})));
}
var generateHeatmap = function generateHeatmap(instance, _ref) {
var positions = _ref.positions;
return new instance.visualization.HeatmapLayer({
data: positions.reduce(function (acc, _ref2) {
var lat = _ref2.lat,
lng = _ref2.lng,
_ref2$weight = _ref2.weight,
weight = _ref2$weight === void 0 ? 1 : _ref2$weight;
acc.push({
location: new instance.LatLng(lat, lng),
weight: weight
});
return acc;
}, [])
});
};
var optionsHeatmap = function optionsHeatmap(instance, _ref3) {
var _ref3$options = _ref3.options,
options = _ref3$options === void 0 ? {} : _ref3$options;
return Object.keys(options).map(function (option) {
return instance.set(option, options[option]);
});
};
var BASE_URL = 'https://maps';
var DEFAULT_URL = BASE_URL + ".googleapis.com";
var API_PATH = '/maps/api/js?callback=_$_google_map_initialize_$_';
var $script_ = null;
var loadPromise_;
var resolveCustomPromise_;
var _customPromise = new Promise(function (resolve) {
resolveCustomPromise_ = resolve;
});
var googleMapLoader = (function (bootstrapURLKeys, heatmapLibrary) {
if (!$script_) {
$script_ = require('scriptjs');
}
if (!bootstrapURLKeys) {
return _customPromise;
}
if (loadPromise_) {
return loadPromise_;
}
loadPromise_ = new Promise(function (resolve, reject) {
if (typeof window === 'undefined') {
reject(new Error('google map cannot be loaded outside browser env'));
return;
}
if (window.google && window.google.maps) {
resolve(window.google.maps);
return;
}
if (typeof window._$_google_map_initialize_$_ !== 'undefined') {
reject(new Error('google map initialization error'));
}
window._$_google_map_initialize_$_ = function () {
delete window._$_google_map_initialize_$_;
resolve(window.google.maps);
};
if (process.env.NODE_ENV !== 'production') {
if (Object.keys(bootstrapURLKeys).indexOf('callback') > -1) {
var message = "\"callback\" key in bootstrapURLKeys is not allowed,\n use onGoogleApiLoaded property instead";
console.error(message);
throw new Error(message);
}
}
var params = Object.keys(bootstrapURLKeys).reduce(function (r, key) {
return r + "&" + key + "=" + bootstrapURLKeys[key];
}, '');
var libraries = heatmapLibrary ? '&libraries=visualization' : '';
$script_("" + DEFAULT_URL + API_PATH + params + libraries, function () {
return typeof window.google === 'undefined' && reject(new Error('google map initialization error (not loaded)'));
});
});
resolveCustomPromise_(loadPromise_);
return loadPromise_;
});
function wrap(n, min, max) {
var d = max - min;
return n === max ? n : ((n - min) % d + d) % d + min;
}
var LatLng = /*#__PURE__*/function () {
function LatLng(lat, lng) {
if (isNaN(lat) || isNaN(lng)) {
throw new Error("Invalid LatLng object: (" + lat + ", " + lng + ")");
}
this.lat = +lat;
this.lng = +lng;
}
var _proto = LatLng.prototype;
_proto.wrap = function wrap$1() {
return new LatLng(this.lat, wrap(this.lng, -180, 180));
};
return LatLng;
}();
LatLng.convert = function (a) {
if (a instanceof LatLng) {
return a;
}
if (Array.isArray(a)) {
return new LatLng(a[0], a[1]);
}
if ('lng' in a && 'lat' in a) {
return new LatLng(a.lat, a.lng);
}
return a;
};
var Transform = /*#__PURE__*/function () {
function Transform(tileSize, minZoom, maxZoom) {
this.tileSize = tileSize || 512;
this._minZoom = minZoom || 0;
this._maxZoom = maxZoom || 52;
this.latRange = [-85.05113, 85.05113];
this.width = 0;
this.height = 0;
this.zoom = 0;
this.center = new LatLng(0, 0);
this.angle = 0;
}
var _proto = Transform.prototype;
_proto.zoomScale = function zoomScale(zoom) {
return Math.pow(2, zoom);
};
_proto.scaleZoom = function scaleZoom(scale) {
return Math.log(scale) / Math.LN2;
};
_proto.project = function project(latlng, worldSize) {
return new Point(this.lngX(latlng.lng, worldSize), this.latY(latlng.lat, worldSize));
};
_proto.unproject = function unproject(point, worldSize) {
return new LatLng(this.yLat(point.y, worldSize), this.xLng(point.x, worldSize));
};
_proto.lngX = function lngX(lon, worldSize) {
return (180 + lon) * (worldSize || this.worldSize) / 360;
};
_proto.latY = function latY(lat, worldSize) {
var y = 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360));
return (180 - y) * (worldSize || this.worldSize) / 360;
};
_proto.xLng = function xLng(x, worldSize) {
return x * 360 / (worldSize || this.worldSize) - 180;
};
_proto.yLat = function yLat(y, worldSize) {
var y2 = 180 - y * 360 / (worldSize || this.worldSize);
return 360 / Math.PI * Math.atan(Math.exp(y2 * Math.PI / 180)) - 90;
};
_proto.locationPoint = function locationPoint(latlng) {
var p = this.project(latlng);
return this.centerPoint._sub(this.point._sub(p)._rotate(this.angle));
};
_proto.pointLocation = function pointLocation(p) {
var p2 = this.centerPoint._sub(p)._rotate(-this.angle);
return this.unproject(this.point.sub(p2));
};
_createClass(Transform, [{
key: "minZoom",
get: function get() {
return this._minZoom;
},
set: function set(zoom) {
this._minZoom = zoom;
this.zoom = Math.max(this.zoom, zoom);
}
}, {
key: "maxZoom",
get: function get() {
return this._maxZoom;
},
set: function set(zoom) {
this._maxZoom = zoom;
this.zoom = Math.min(this.zoom, zoom);
}
}, {
key: "worldSize",
get: function get() {
return this.tileSize * this.scale;
}
}, {
key: "centerPoint",
get: function get() {
return new Point(0, 0);
}
}, {
key: "size",
get: function get() {
return new Point(this.width, this.height);
}
}, {
key: "bearing",
get: function get() {
return -this.angle / Math.PI * 180;
},
set: function set(bearing) {
this.angle = -wrap(bearing, -180, 180) * Math.PI / 180;
}
}, {
key: "zoom",
get: function get() {
return this._zoom;
},
set: function set(zoom) {
var zoomV = Math.min(Math.max(zoom, this.minZoom), this.maxZoom);
this._zoom = zoomV;
this.scale = this.zoomScale(zoomV);
this.tileZoom = Math.floor(zoomV);
this.zoomFraction = zoomV - this.tileZoom;
}
}, {
key: "x",
get: function get() {
return this.lngX(this.center.lng);
}
}, {
key: "y",
get: function get() {
return this.latY(this.center.lat);
}
}, {
key: "point",
get: function get() {
return new Point(this.x, this.y);
}
}]);
return Transform;
}();
var Geo = /*#__PURE__*/function () {
function Geo(tileSize) {
this.hasSize_ = false;
this.hasView_ = false;
this.transform_ = new Transform(tileSize || 512);
}
var _proto = Geo.prototype;
_proto.setView = function setView(center, zoom, bearing) {
this.transform_.center = LatLng.convert(center);
this.transform_.zoom = +zoom;
this.transform_.bearing = +bearing;
this.hasView_ = true;
};
_proto.setViewSize = function setViewSize(width, height) {
this.transform_.width = width;
this.transform_.height = height;
this.hasSize_ = true;
};
_proto.setMapCanvasProjection = function setMapCanvasProjection(maps, mapCanvasProjection) {
this.maps_ = maps;
this.mapCanvasProjection_ = mapCanvasProjection;
};
_proto.canProject = function canProject() {
return this.hasSize_ && this.hasView_;
};
_proto.hasSize = function hasSize() {
return this.hasSize_;
};
_proto.fromLatLngToCenterPixel = function fromLatLngToCenterPixel(ptLatLng) {
return this.transform_.locationPoint(LatLng.convert(ptLatLng));
};
_proto.fromLatLngToDivPixel = function fromLatLngToDivPixel(ptLatLng) {
if (this.mapCanvasProjection_) {
var latLng = new this.maps_.LatLng(ptLatLng.lat, ptLatLng.lng);
return this.mapCanvasProjection_.fromLatLngToDivPixel(latLng);
}
return this.fromLatLngToCenterPixel(ptLatLng);
};
_proto.fromLatLngToContainerPixel = function fromLatLngToContainerPixel(ptLatLng) {
if (this.mapCanvasProjection_) {
var latLng = new this.maps_.LatLng(ptLatLng.lat, ptLatLng.lng);
return this.mapCanvasProjection_.fromLatLngToContainerPixel(latLng);
}
var pt = this.fromLatLngToCenterPixel(ptLatLng);
pt.x -= this.transform_.worldSize * Math.round(pt.x / this.transform_.worldSize);
pt.x += this.transform_.width / 2;
pt.y += this.transform_.height / 2;
return pt;
};
_proto.fromContainerPixelToLatLng = function fromContainerPixelToLatLng(ptXY) {
if (this.mapCanvasProjection_) {
var latLng = this.mapCanvasProjection_.fromContainerPixelToLatLng(ptXY);
return {
lat: latLng.lat(),
lng: latLng.lng()
};
}
var ptxy = _extends({}, ptXY);
ptxy.x -= this.transform_.width / 2;
ptxy.y -= this.transform_.height / 2;
var ptRes = this.transform_.pointLocation(Point.convert(ptxy));
ptRes.lng -= 360 * Math.round(ptRes.lng / 360);
return ptRes;
};
_proto.getWidth = function getWidth() {
return this.transform_.width;
};
_proto.getHeight = function getHeight() {
return this.transform_.height;
};
_proto.getZoom = function getZoom() {
return this.transform_.zoom;
};
_proto.getCenter = function getCenter() {
var ptRes = this.transform_.pointLocation({
x: 0,
y: 0
});
return ptRes;
};
_proto.getBounds = function getBounds(margins, roundFactor) {
var bndT = margins && margins[0] || 0;
var bndR = margins && margins[1] || 0;
var bndB = margins && margins[2] || 0;
var bndL = margins && margins[3] || 0;
if (this.getWidth() - bndR - bndL > 0 && this.getHeight() - bndT - bndB > 0) {
var topLeftCorner = this.transform_.pointLocation(Point.convert({
x: bndL - this.getWidth() / 2,
y: bndT - this.getHeight() / 2
}));
var bottomRightCorner = this.transform_.pointLocation(Point.convert({
x: this.getWidth() / 2 - bndR,
y: this.getHeight() / 2 - bndB
}));
var res = [topLeftCorner.lat, topLeftCorner.lng, bottomRightCorner.lat, bottomRightCorner.lng, bottomRightCorner.lat, topLeftCorner.lng, topLeftCorner.lat, bottomRightCorner.lng];
if (roundFactor) {
res = res.map(function (r) {
return Math.round(r * roundFactor) / roundFactor;
});
}
return res;
}
return [0, 0, 0, 0];
};
return Geo;
}();
function raf(callback) {
if (window.requestAnimationFrame) {
return window.requestAnimationFrame(callback);
}
var nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
return nativeRaf ? nativeRaf(callback) : window.setTimeout(callback, 1e3 / 60);
}
var log2 = Math.log2 ? Math.log2 : function (x) {
return Math.log(x) / Math.LN2;
};
function pick(obj, fn) {
return Object.keys(obj).reduce(function (result, key) {
if (fn(obj[key])) {
result[key] = obj[key];
}
return result;
}, {});
}
var isEmpty = function isEmpty(val) {
if (val !== null && typeof val === 'object') {
if (Object.keys(val).length === 0) {
return true;
}
} else if (val === null || val === undefined || val === '') {
return true;
}
return false;
};
function isObjectLike(value) {
return !!value && typeof value === 'object';
}
var objectToString = Object.prototype.toString;
function isNumber(value) {
var numberTag = '[object Number]';
return typeof value === 'number' || isObjectLike(value) && objectToString.call(value) === numberTag;
}
var detectBrowserResult_ = null;
function detectBrowser() {
if (detectBrowserResult_) {
return detectBrowserResult_;
}
if (typeof navigator !== 'undefined') {
var isExplorer = navigator.userAgent.indexOf('MSIE') > -1;
var isFirefox = navigator.userAgent.indexOf('Firefox') > -1;
var isOpera = navigator.userAgent.toLowerCase().indexOf('op') > -1;
var isChrome = navigator.userAgent.indexOf('Chrome') > -1;
var isSafari = navigator.userAgent.indexOf('Safari') > -1;
if (isChrome && isSafari) {
isSafari = false;
}
if (isChrome && isOpera) {
isChrome = false;
}
detectBrowserResult_ = {
isExplorer: isExplorer,
isFirefox: isFirefox,
isOpera: isOpera,
isChrome: isChrome,
isSafari: isSafari
};
return detectBrowserResult_;
}
detectBrowserResult_ = {
isChrome: true,
isExplorer: false,
isFirefox: false,
isOpera: false,
isSafari: false
};
return detectBrowserResult_;
}
var fnToString = function fnToString(fn) {
return Function.prototype.toString.call(fn);
};
function isPlainObject(obj) {
if (!obj || typeof obj !== 'object') {
return false;
}
var proto = typeof obj.constructor === 'function' ? Object.getPrototypeOf(obj) : Object.prototype;
if (proto === null) {
return true;
}
var constructor = proto.constructor;
return typeof constructor === 'function' && constructor instanceof constructor && fnToString(constructor) === fnToString(Object);
}
function isArraysEqualEps(arrayA, arrayB, eps) {
if (arrayA && arrayB) {
for (var i = 0; i !== arrayA.length; ++i) {
if (Math.abs(arrayA[i] - arrayB[i]) > eps) {
return false;
}
}
return true;
}
return false;
}
function hasPassiveSupport() {
var passiveSupported = false;
try {
var options = Object.defineProperty({}, 'passive', {
get: function get() {
passiveSupported = true;
}
});
window.addEventListener('test', options, options);
window.removeEventListener('test', options, options);
} catch (err) {
passiveSupported = false;
}
return passiveSupported;
}
function addPassiveEventListener(element, eventName, func, capture) {
element.addEventListener(eventName, func, hasPassiveSupport() ? {
capture: capture,
passive: true
} : capture);
}
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
var _window;
if (canUseDOM) {
_window = window;
} else if (typeof self !== 'undefined') {
_window = self;
} else {
_window = undefined;
}
var attachEvent = typeof document !== 'undefined' && document.attachEvent;
var stylesCreated = false;
if (canUseDOM && !attachEvent) {
var requestFrame = function () {
var raf = _window.requestAnimationFrame || _window.mozRequestAnimationFrame || _window.webkitRequestAnimationFrame || function (fn) {
return _window.setTimeout(fn, 20);
};
return function (fn) {
return raf(fn);
};
}();
var cancelFrame = function () {
var cancel = _window.cancelAnimationFrame || _window.mozCancelAnimationFrame || _window.webkitCancelAnimationFrame || _window.clearTimeout;
return function (id) {
return cancel(id);
};
}();
var resetTriggers = function resetTriggers(element) {
var triggers = element.__resizeTriggers__,
expand = triggers.firstElementChild,
contract = triggers.lastElementChild,
expandChild = expand.firstElementChild;
contract.scrollLeft = contract.scrollWidth;
contract.scrollTop = contract.scrollHeight;
expandChild.style.width = expand.offsetWidth + 1 + 'px';
expandChild.style.height = expand.offsetHeight + 1 + 'px';
expand.scrollLeft = expand.scrollWidth;
expand.scrollTop = expand.scrollHeight;
};
var checkTriggers = function checkTriggers(element) {
return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height;
};
var scrollListener = function scrollListener(e) {
var element = this;
resetTriggers(this);
if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
this.__resizeRAF__ = requestFrame(function () {
if (checkTriggers(element)) {
element.__resizeLast__.width = element.offsetWidth;
element.__resizeLast__.height = element.offsetHeight;
element.__resizeListeners__.forEach(function (fn) {
fn.call(element, e);
});
}
});
};
var animation = false,
keyframeprefix = '',
animationstartevent = 'animationstart',
domPrefixes = 'Webkit Moz O ms'.split(' '),
startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
pfx = '';
if (canUseDOM) {
var elm = document.createElement('fakeelement');
if (elm.style.animationName !== undefined) {
animation = true;
}
if (animation === false) {
for (var i = 0; i < domPrefixes.length; i++) {
if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) {
pfx = domPrefixes[i];
keyframeprefix = '-' + pfx.toLowerCase() + '-';
animationstartevent = startEvents[i];
animation = true;
break;
}
}
}
}
var animationName = 'resizeanim';
var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
}
var createStyles = function createStyles() {
if (!stylesCreated) {
var css = (animationKeyframes ? animationKeyframes : '') + '.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' + '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: " "; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
stylesCreated = true;
}
};
var addResizeListener = function addResizeListener(element, fn) {
if (element.parentNode === undefined) {
var tempParentDiv = document.createElement('div');
element.parentNode = tempParentDiv;
}
element = element.parentNode;
if (attachEvent) element.attachEvent('onresize', fn);else {
if (!element.__resizeTriggers__) {
if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
createStyles();
element.__resizeLast__ = {};
element.__resizeListeners__ = [];
(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' + '<div class="contract-trigger"></div>';
element.appendChild(element.__resizeTriggers__);
resetTriggers(element);
addPassiveEventListener(element, 'scroll', scrollListener, true);
animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function (e) {
if (e.animationName == animationName) resetTriggers(element);
});
}
element.__resizeListeners__.push(fn);
}
};
var removeResizeListener = function removeResizeListener(element, fn) {
element = element.parentNode;
if (attachEvent) element.detachEvent('onresize', fn);else {
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
if (!element.__resizeListeners__.length) {
element.removeEventListener('scroll', scrollListener);
element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
}
}
};
var kEPS = 0.00001;
var K_GOOGLE_TILE_SIZE = 256;
var K_IDLE_TIMEOUT = 100;
var K_IDLE_CLICK_TIMEOUT = 300;
var DEFAULT_MIN_ZOOM = 3;
var DRAW_CALLED_DURING_ANIMATION_VERSION = 32;
var IS_REACT_16 = ReactDOM.createPortal !== undefined;
var createPortal = IS_REACT_16 ? ReactDOM.createPortal : ReactDOM.unstable_renderSubtreeIntoContainer;
function defaultOptions_() {
return {
overviewMapControl: false,
streetViewControl: false,
rotateControl: true,
mapTypeControl: false,
styles: [{
featureType: 'poi',
elementType: 'labels',
stylers: [{
visibility: 'off'
}]
}],
minZoom: DEFAULT_MIN_ZOOM
};
}
var latLng2Obj = function latLng2Obj(latLng) {
return isPlainObject(latLng) ? latLng : {
lat: latLng[0],
lng: latLng[1]
};
};
var _checkMinZoom = function _checkMinZoom(zoom, minZoom) {
if (process.env.NODE_ENV !== 'production') {
if (zoom < minZoom) {
console.warn('GoogleMap: ' + 'minZoom option is less than recommended ' + 'minZoom option for your map sizes.\n' + 'overrided to value ' + minZoom);
}
}
if (minZoom < zoom) {
return zoom;
}
return minZoom;
};
var isFullScreen = function isFullScreen() {
return document.fullscreen || document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement;
};
var GoogleMap = /*#__PURE__*/function (_Component) {
_inheritsLoose(GoogleMap, _Component);
function GoogleMap(props) {
var _this;
_this = _Component.call(this, props) || this;
_this._getMinZoom = function () {
if (_this.geoService_.getWidth() > 0 || _this.geoService_.getHeight() > 0) {
var tilesPerWidth = Math.ceil(_this.geoService_.getWidth() / K_GOOGLE_TILE_SIZE) + 2;
var tilesPerHeight = Math.ceil(_this.geoService_.getHeight() / K_GOOGLE_TILE_SIZE) + 2;
var maxTilesPerDim = Math.max(tilesPerWidth, tilesPerHeight);
return Math.ceil(log2(maxTilesPerDim));
}
return DEFAULT_MIN_ZOOM;
};
_this._computeMinZoom = function (minZoom) {
if (!isEmpty(minZoom)) {
return minZoom;
}
return _this._getMinZoom();
};
_this._mapDomResizeCallback = function () {
_this.resetSizeOnIdle_ = true;
if (_this.maps_) {
var originalCenter = _this.props.center || _this.props.defaultCenter;
var currentCenter = _this.map_.getCenter();
_this.maps_.event.trigger(_this.map_, 'resize');
_this.map_.setCenter(_this.props.resetBoundsOnResize ? originalCenter : currentCenter);
}
};
_this._setLayers = function (layerTypes) {
layerTypes.forEach(function (layerType) {
_this.layers_[layerType] = new _this.maps_[layerType]();
_this.layers_[layerType].setMap(_this.map_);
});
};
_this._renderPortal = function () {
return /*#__PURE__*/React.createElement(GoogleMapMarkers, {
experimental: _this.props.experimental,
onChildClick: _this._onChildClick,
onChildMouseDown: _this._onChildMouseDown,
onChildMouseEnter: _this._onChildMouseEnter,
onChildMouseLeave: _this._onChildMouseLeave,
geoService: _this.geoService_,
insideMapPanes: true,
distanceToMouse: _this.props.distanceToMouse,
getHoverDistance: _this._getHoverDistance,
dispatcher: _this.markersDispatcher_
});
};
_this._initMap = function () {
if (_this.initialized_) {
return;
}
_this.initialized_ = true;
var propsCenter = latLng2Obj(_this.props.center || _this.props.defaultCenter);
_this.geoService_.setView(propsCenter, _this.props.zoom || _this.props.defaultZoom, 0);
_this._onBoundsChanged();
var bootstrapURLKeys = _extends({}, _this.props.apiKey && {
key: _this.props.apiKey
}, _this.props.bootstrapURLKeys);
_this.props.googleMapLoader(bootstrapURLKeys, _this.props.heatmapLibrary).then(function (maps) {
if (!_this.mounted_) {
return;
}
var centerLatLng = _this.geoService_.getCenter();
var propsOptions = {
zoom: _this.props.zoom || _this.props.defaultZoom,
center: new maps.LatLng(centerLatLng.lat, centerLatLng.lng)
};
if (_this.props.heatmap.positions) {
Object.assign(_assertThisInitialized(_this), {
heatmap: generateHeatmap(maps, _this.props.heatmap)
});
optionsHeatmap(_this.heatmap, _this.props.heatmap);
}
var mapPlainObjects = pick(maps, isPlainObject);
var options = typeof _this.props.options === 'function' ? _this.props.options(mapPlainObjects) : _this.props.options;
var defaultOptions = defaultOptions_();
var draggableOptions = !isEmpty(_this.props.draggable) && {
draggable: _this.props.draggable
};
var minZoom = _this._computeMinZoom(options.minZoom);
_this.minZoom_ = minZoom;
var preMapOptions = _extends({}, defaultOptions, {
minZoom: minZoom
}, options, propsOptions);
_this.defaultDraggableOption_ = !isEmpty(preMapOptions.draggable) ? preMapOptions.draggable : _this.defaultDraggableOption_;
var mapOptions = _extends({}, preMapOptions, draggableOptions);
mapOptions.minZoom = _checkMinZoom(mapOptions.minZoom, minZoom);
var map = new maps.Map(ReactDOM.findDOMNode(_this.googleMapDom_), mapOptions);
_this.map_ = map;
_this.maps_ = maps;
_this._setLayers(_this.props.layerTypes);
var versionMatch = maps.version.match(/^3\.(\d+)\./);
var mapsVersion = versionMatch && Number(versionMatch[1]);
var this_ = _assertThisInitialized(_this);
var overlay = Object.assign(new maps.OverlayView(), {
onAdd: function onAdd() {
var K_MAX_WIDTH = typeof screen !== 'undefined' ? screen.width + "px" : '2000px';
var K_MAX_HEIGHT = typeof screen !== 'undefined' ? screen.height + "px" : '2000px';
var div = document.createElement('div');
div.style.backgroundColor = 'transparent';
div.style.position = 'absolute';
div.style.left = '0px';
div.style.top = '0px';
div.style.width = K_MAX_WIDTH;
div.style.height = K_MAX_HEIGHT;
if (this_.props.overlayViewDivStyle) {
var overlayViewDivStyle = this_.props.overlayViewDivStyle;
if (typeof overlayViewDivStyle === 'object') {
Object.keys(overlayViewDivStyle).forEach(function (property) {
div.style[property] = overlayViewDivStyle[property];
});
}
}
var panes = this.getPanes();
panes.overlayMouseTarget.appendChild(div);
this_.geoService_.setMapCanvasProjection(maps, overlay.getProjection());
if (!IS_REACT_16) {
createPortal(this_, this_._renderPortal(), div, function () {
return this_.setState({
overlay: div
});
});
} else {
this_.setState({
overlay: div
});
}
},
onRemove: function onRemove() {
var renderedOverlay = this_.state.overlay;
if (renderedOverlay && !IS_REACT_16) {
ReactDOM.unmountComponentAtNode(renderedOverlay);
}
this_.setState({
overlay: null
});
},
draw: function draw() {
this_.updateCounter_++;
this_._onBoundsChanged(map, maps, !this_.props.debounced);
if (!this_.googleApiLoadedCalled_) {
this_._onGoogleApiLoaded({
map: map,
maps: maps,
ref: this_.googleMapDom_
});
this_.googleApiLoadedCalled_ = true;
}
if (this_.mouse_) {
var latLng = this_.geoService_.fromContainerPixelToLatLng(this_.mouse_);
this_.mouse_.lat = latLng.lat;
this_.mouse_.lng = latLng.lng;
}
this_._onChildMouseMove();
if (this_.markersDispatcher_) {
this_.markersDispatcher_.emit('kON_CHANGE');
if (this_.fireMouseEventOnIdle_) {
this_.markersDispatcher_.emit('kON_MOUSE_POSITION_CHANGE');
}
}
}
});
_this.overlay_ = overlay;
overlay.setMap(map);
if (_this.props.heatmap.positions) {
_this.heatmap.setMap(map);
}
if (_this.props.onTilesLoaded) {
maps.event.addListener(map, 'tilesloaded', function () {
this_._onTilesLoaded();
});
}
maps.event.addListener(map, 'zoom_changed', function () {
if (this_.geoService_.getZoom() !== map.getZoom()) {
if (!this_.zoomAnimationInProgress_) {
this_.zoomAnimationInProgress_ = true;
this_._onZoomAnimationStart(map.zoom);
}
if (mapsVersion < DRAW_CALLED_DURING_ANIMATION_VERSION) {
var TIMEOUT_ZOOM = 300;
if (new Date().getTime() - _this.zoomControlClickTime_ < TIMEOUT_ZOOM) {
raf(function () {
return raf(function () {
this_.updateCounter_++;
this_._onBoundsChanged(map, maps);
});
});
} else {
this_.updateCounter_++;
this_._onBoundsChanged(map, maps);
}
}
}
});
maps.event.addListener(map, 'idle', function () {
if (_this.resetSizeOnIdle_) {
_this._setViewSize();
var currMinZoom = _this._computeMinZoom(options.minZoom);
if (currMinZoom !== _this.minZoom_) {
_this.minZoom_ = currMinZoom;
map.setOptions({
minZoom: currMinZoom
});
}
_this.resetSizeOnIdle_ = false;
}
if (this_.zoomAnimationInProgress_) {
this_.zoomAnimationInProgress_ = false;
this_._onZoomAnimationEnd(map.zoom);
}
this_.updateCounter_++;
this_._onBoundsChanged(map, maps);
this_.dragTime_ = 0;
if (this_.markersDispatcher_) {
this_.markersDispatcher_.emit('kON_CHANGE');
}
});
maps.event.addListener(map, 'mouseover', function () {
this_.mouseInMap_ = true;
});
maps.event.addListener(map, 'click', function () {
this_.mouseInMap_ = true;
});
maps.event.addListener(map, 'mouseout', function () {
this_.mouseInMap_ = false;
this_.mouse_ = null;
this_.markersDispatcher_.emit('kON_MOUSE_POSITION_CHANGE');
});
maps.event.addListener(map, 'drag', function () {
this_.dragTime_ = new Date().getTime();
this_._onDrag(map);
});
maps.event.addListener(map, 'dragend', function () {
var idleListener = maps.event.addListener(map, 'idle', function () {
maps.event.removeListener(idleListener);
this_._onDragEnd(map);
});
});
maps.event.addListener(map, 'maptypeid_changed', function () {
this_._onMapTypeIdChange(map.getMapTypeId());
});
})["catch"](function (e) {
_this._onGoogleApiLoaded({
map: null,
maps: null,
ref: _this.googleMapDom_
});
console.error(e);
throw e;
});
};
_this._onGoogleApiLoaded = function () {
if (_this.props.onGoogleApiLoaded) {
var _this$props;
if (process.env.NODE_ENV !== 'production' && _this.props.yesIWantToUseGoogleMapApiInternals !== true) {
console.warn('GoogleMap: ' + 'Usage of internal api objects is dangerous ' + 'and can cause a lot of issues.\n' + 'To hide this warning add yesIWantToUseGoogleMapApiInternals={true} ' + 'to <GoogleMap instance');
}
(_this$props = _this.props).onGoogleApiLoaded.apply(_this$props, arguments);
}
};
_this._getHoverDistance = function () {
return _this.props.hoverDistance;
};
_this._onDrag = function () {
var _this$props2;
return _this.props.onDrag && (_this$props2 = _this.props).onDrag.apply(_this$props2, arguments);
};
_this._onDragEnd = function () {
var _this$props3;
return _this.props.onDragEnd && (_this$props3 = _this.props).onDragEnd.apply(_this$props3, arguments);
};
_this._onMapTypeIdChange = function () {
var _this$props4;
return _this.props.onMapTypeIdChange && (_this$props4 = _this.props).onMapTypeIdChange.apply(_this$props4, arguments);
};
_this._onZoomAnimationStart = function () {
var _this$props5;
return _this.props.onZoomAnimationStart && (_this$props5 = _this.props).onZoomAnimationStart.apply(_this$props5, arguments);
};
_this._onZoomAnimationEnd = function () {
var _this$props6;
return _this.props.onZoomAnimationEnd && (_this$props6 = _this.props).onZoomAnimationEnd.apply(_this$props6, arguments);
};
_this._onTilesLoaded = function () {
return _this.props.onTilesLoaded && _this.props.onTilesLoaded();
};
_this._onChildClick = function () {
if (_this.props.onChildClick) {
var _this$props7;
return (_this$props7 = _this.props).onChildClick.apply(_this$props7, arguments);
}
return undefined;
};
_this._onChildMouseDown = function (hoverKey, childProps) {
_this.childMouseDownArgs_ = [hoverKey, childProps];
if (_this.props.onChildMouseDown) {
_this.props.onChildMouseDown(hoverKey, childProps, _extends({}, _this.mouse_));
}
};
_this._onChildMouseUp = function () {
if (_this.childMouseDownArgs_) {
if (_this.props.onChildMouseUp) {
var _this$props8;
(_this$props8 = _this.props).onChildMouseUp.apply(_this$props8, _this.childMouseDownArgs_.concat([_extends({}, _this.mouse_)]));
}
_this.childMouseDownArgs_ = null;
_this.childMouseUpTime_ = new Date().getTime();
}
};
_this._onChildMouseMove = function () {
if (_this.childMouseDownArgs_) {
if (_this.props.onChildMouseMove) {
var _this$props9;
(_this$props9 = _this.props).onChildMouseMove.apply(_this$props9, _this.childMouseDownArgs_.concat([_extends({}, _this.mouse_)]));
}
}
};
_this._onChildMouseEnter = function () {
if (_this.props.onChildMouseEnter) {
var _this$props10;
return (_this$props10 = _this.props).onChildMouseEnter.apply(_this$props10, arguments);
}
return undefined;
};
_this._onChildMouseLeave = function () {
if (_this.props.onChildMouseLeave) {
var _this$props11;
return (_this$props11 = _this.props).onChildMouseLeave.apply(_this$props11, arguments);
}
return undefined;
};
_this._setViewSize = function () {
if (!_this.mounted_) return;
if (isFullScreen()) {
_this.geoService_.setViewSize(window.innerWidth, window.innerHeight);
} else {
var mapDom = ReactDOM.findDOMNode(_this.googleMapDom_);
_this.geoService_.setViewSize(mapDom.clientWidth, mapDom.clientHeight);
}
_this._onBoundsChanged();
};
_this._onWindowResize = function () {
_this.resetSizeOnIdle_ = true;
};
_this._onMapMouseMove = function (e) {
if (!_this.mouseInMap_) return;
var currTime = new Date().getTime();
var K_RECALC_CLIENT_RECT_MS = 50;
if (currTime - _this.mouseMoveTime_ > K_RECALC_CLIENT_RECT_MS) {
_this.boundingRect_ = e.currentTarget.getBoundingClientRect();
}
_this.mouseMoveTime_ = currTime;
var mousePosX = e.clientX - _this.boundingRect_.left;
var mousePosY = e.clientY - _this.boundingRect_.top;
if (!_this.mouse_) {
_this.mouse_ = {
x: 0,
y: 0,
lat: 0,
lng: 0
};
}
_this.mouse_.x = mousePosX;
_this.mouse_.y = mousePosY;
var latLng = _this.geoService_.fromContainerPixelToLatLng(_this.mouse_);
_this.mouse_.lat = latLng.lat;
_this.mouse_.lng = latLng.lng;
_this._onChildMouseMove();
if (currTime - _this.dragTime_ < K_IDLE_TIMEOUT) {
_this.fireMouseEventOnIdle_ = true;
} else {
_this.markersDispatcher_.emit('kON_MOUSE_POSITION_CHANGE');
_this.fireMouseEventOnIdle_ = false;
}
};
_this._onClick = function () {
var _this$props12;
return _this.props.onClick && !_this.childMouseDownArgs_ && new