# Source: wp-google-maps.combined.js

    // js/v8/core.js

    /**

     * @module WPGMZA

     * @summary This is the core Javascript module. Some code exists in ../core.js, the functionality there will slowly be handed over to this module.

     */

    (function($) {

    	var core = {

    		maps: [],

    		events: null,

    		settings: null,

    		loadingHTML: '<div class="wpgmza-preloader"><div class="wpgmza-loader">...</div></div>',

    		/**

    		 * @function guid

    		 * @summary Utility function returns a GUID

    		 * @static

    		 * @return {string} The GUID

    		 */

    		guid: function() { // Public Domain/MIT

    		  var d = new Date().getTime();

    			if (typeof performance !== 'undefined' && typeof performance.now === 'function'){

    				d += performance.now(); //use high-precision timer if available

    			}

    			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {

    				var r = (d + Math.random() * 16) % 16 | 0;

    				d = Math.floor(d / 16);

    				return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);

    			});

    		},

    		/**

    		 * @function hexOpacityToRGBA

    		 * @summary Takes a hex string and opacity value and converts it to Openlayers RGBA format

    		 * @param {string} colour The hex color string

    		 * @param {number} opacity The opacity from 0.0 - 1.0

    		 * @static

    		 * @return {array} RGBA where color components are 0 - 255 and opacity is 0.0 - 1.0

    		 */

    		hexOpacityToRGBA: function(colour, opacity)

    		{

    			hex = parseInt(colour.replace(/^#/, ""), 16);

    			return [

    				(hex & 0xFF0000) >> 16,

    				(hex & 0xFF00) >> 8,

    				hex & 0xFF,

    				parseFloat(opacity)

    			];

    		},

    		latLngRegexp: /^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/,

    		/**

    		 * @function isLatLngString

    		 * @summary Utility function returns true is string is a latitude and longitude

    		 * @param str {string} The string to attempt to parse as coordinates

    		 * @static

    		 * @return {array} the matched latitude and longitude or null if no match

    		 */

    		isLatLngString: function(str)

    		{

    			if(typeof str != "string")

    				return null;

    			// Remove outer brackets

    			if(str.match(/^\(.+\)$/))

    				str = str.replace(/^\(|\)$/, "");

    			var m = str.match(WPGMZA.latLngRegexp);

    			if(!m)

    				return null;

    			return {

    				lat: parseFloat(m[1]),

    				lng: parseFloat(m[3])

    			};

    		},

    		/**

    		 * @function stringToLatLng

    		 * @summary Utility function returns a latLng literal given a valid latLng string

    		 * @param str {string} The string to attempt to parse as coordinates

    		 * @static

    		 * @return {object} LatLng literal

    		 */

    		stringToLatLng: function(str)

    		{

    			var result = WPGMZA.isLatLngString(str);

    			if(!result)

    				throw new Error("Not a valid latLng");

    			return result;

    		},

    		/**

    		 * @function getImageDimensions

    		 * @summary Utility function to get the dimensions of an image, caches results for best performance

    		 * @param src {string} Image source URL

    		 * @param callback {function} Callback to recieve image dimensions

    		 * @static

    		 * @return {void}

    		 */

    		imageDimensionsCache: {},

    		getImageDimensions: function(src, callback)

    		{

    			if(WPGMZA.imageDimensionsCache[src])

    			{

    				callback(WPGMZA.imageDimensionsCache[src]);

    				return;

    			}

    			var img = document.createElement("img");

    			img.onload = function(event) {

    				var result = {

    					width: image.width,

    					height: image.height

    				};

    				WPGMZA.imageDimensionsCache[src] = result;

    				callback(result);

    			};

    			img.src = src;

    		},

    		/**

    		 * @function isDeveloperMode

    		 * @summary Returns true if developer mode is set

    		 * @static

    		 * @return {boolean} True if developer mode is on

    		 */

    		isDeveloperMode: function()

    		{

    			return this.developer_mode || (window.Cookies && window.Cookies.get("wpgmza-developer-mode"));

    		},

    		/**

    		 * @function isProVersion

    		 * @summary Returns true if the Pro add-on is active

    		 * @static

    		 * @return {boolean} True if the Pro add-on is active

    		 */

    		isProVersion: function()

    		{

    			return (this._isProVersion == "1");

    		},

    		/**

    		 * @function openMediaDialog

    		 * @summary Opens the WP media dialog and returns the result to a callback

    		 * @param {function} callback Callback to recieve the attachment ID as the first parameter and URL as the second

    		 * @static

    		 * @return {void}

    		 */

    		openMediaDialog: function(callback) {

    			// Media upload

    			var file_frame;

    			// If the media frame already exists, reopen it.

    			if ( file_frame ) {

    				// Set the post ID to what we want

    				file_frame.uploader.uploader.param( 'post_id', set_to_post_id );

    				// Open frame

    				file_frame.open();

    				return;

    			}

    			// Create the media frame.

    			file_frame = wp.media.frames.file_frame = wp.media({

    				title: 'Select a image to upload',

    				button: {

    					text: 'Use this image',

    				},

    				multiple: false	// Set to true to allow multiple files to be selected

    			});

    			// When an image is selected, run a callback.

    			file_frame.on( 'select', function() {

    				// We set multiple to false so only get one image from the uploader

    				attachment = file_frame.state().get('selection').first().toJSON();

    				callback(attachment.id, attachment.url);

    			});

    			// Finally, open the modal

    			file_frame.open();

    		},

    		/**

    		 * @function getCurrentPosition

    		 * @summary This function will get the users position, it first attempts to get

    		 * high accuracy position (mobile with GPS sensors etc.), if that fails

    		 * (desktops will time out) then it tries again without high accuracy

    		 * enabled

    		 * @static

    		 * @return {object} The users position as a LatLng literal

    		 */

    		getCurrentPosition: function(callback)

    		{

    			if(!navigator.geolocation)

    			{

    				console.warn("No geolocation available on this device");

    				return;

    			}

    			var options = {

    				enableHighAccuracy: true

    			};

    			navigator.geolocation.getCurrentPosition(function(position) {

    				callback(position);

    			},

    			function(error) {

    				options.enableHighAccuracy = false;

    				navigator.geolocation.getCurrentPosition(function(position) {

    					callback(position);

    				},

    				function(error) {

    					console.warn(error.code, error.message);

    				},

    				options);

    			},

    			options);

    		},

    		/**

    		 * @function runCatchableTask

    		 * @summary Runs a catchable task and displays a friendly error if the function throws an error

    		 * @param {function} callback The function to run

    		 * @param {HTMLElement} friendlyErrorContainer The container element to hold the error

    		 * @static

    		 * @return {void}

    		 */

    		runCatchableTask: function(callback, friendlyErrorContainer) {

    			if(WPGMZA.isDeveloperMode())

    				callback();

    			else

    				try{

    					callback();

    				}catch(e) {

    					var friendlyError = new WPGMZA.FriendlyError(e);

    					$(friendlyErrorContainer).html("");

    					$(friendlyErrorContainer).append(friendlyError.element);

    					$(friendlyErrorContainer).show();

    				}

    		},

    		/**

    		 * @function assertInstanceOf

    		 * @summary

    		 * This function is for checking inheritence has been setup correctly.

    		 * For objects that have engine and Pro specific classes, it will automatically

    		 * add the engine and pro prefix to the supplied string and if such an object

    		 * exists it will test against that name rather than the un-prefix argument

    		 * supplied.

    		 *

    		 * For example, if we are running the Pro addon with Google maps as the engine,

    		 * if you supply Marker as the instance name the function will check to see

    		 * if instance is an instance of GoogleProMarker

    		 * @param {object} instance The object to check

    		 * @param {string} instanceName The class name as a string which this object should be an instance of

    		 * @static

    		 * @return {void}

    		 */

    		assertInstanceOf: function(instance, instanceName) {

    			var engine, fullInstanceName, assert;

    			var pro = WPGMZA.isProVersion() ? "Pro" : "";

    			switch(WPGMZA.settings.engine)

    			{

    				case "google-maps":

    					engine = "Google";

    					break;

    				default:

    					engine = "OL";

    					break;

    			}

    			if(WPGMZA[engine + pro + instanceName])

    				fullInstanceName = engine + pro + instanceName;

    			else if(WPGMZA[pro + instanceName])

    				fullInstanceName = pro + instanceName;

    			else if(WPGMZA[engine + instanceName])

    				fullInstanceName = engine + instanceName;

    			else

    				fullInstanceName = instanceName;

    			assert = instance instanceof WPGMZA[fullInstanceName];

    			if(!assert)

    				throw new Error("Object must be an instance of " + fullInstanceName + " (did you call a constructor directly, rather than createInstance?)");

    		},

    		/**

    		 * @function getMapByID

    		 * @param {mixed} id The ID of the map to retrieve

    		 * @static

    		 * @return {object} The map object, or null if no such map exists

    		 */

    		getMapByID: function(id) {

    			for(var i = 0; i < WPGMZA.maps.length; i++) {

    				if(WPGMZA.maps[i].id == id)

    					return WPGMZA.maps[i];

    			}

    			return null;

    		},

    		/**

    		 * @function isGoogleAutocompleteSupported

    		 * @summary Shorthand function to determine if the Places Autocomplete is available

    		 * @static

    		 * @return {boolean}

    		 */

    		isGoogleAutocompleteSupported: function() {

    			return typeof google === 'object' && typeof google.maps === 'object' && typeof google.maps.places === 'object' && typeof google.maps.places.Autocomplete === 'function';

    		}

    	};

    	if(window.WPGMZA)

    		window.WPGMZA = $.extend(window.WPGMZA, core);

    	else

    		window.WPGMZA = core;

    	for(var key in WPGMZA_localized_data)

    	{

    		var value = WPGMZA_localized_data[key];

    		WPGMZA[key] = value;

    	}

    	/*for(var key in WPGMZA_localized_data)

    		WPGMZA[key] = WPGMZA_localized_data[key];

    	$(document).ready(function(event) {

    		// Datatables to throw errors

    		if($.fn.dataTable)

    			$.fn.dataTable.ext.errMode = 'throw';

    		// Combined script warning

    		if($("script[src*='wp-google-maps.combined.js'], script[src*='wp-google-maps-pro.combined.js']").length)

    			console.warn("Minified script is out of date, using combined script instead.");

    		// Check for multiple jQuery versions

    		var elements = $("script").filter(function() {

    			return this.src.match(/(^|\/)jquery\.(min\.)?js(\?|$)/i);

    		});

    		if(elements.length > 1)

    			console.warn("Multiple jQuery versions detected: ", elements);

    		// Disable map edit page preloader in developer more

    		if(WPGMZA.isDeveloperMode())

    			$("#wpgmza-map-edit-page form.wpgmza").show();

    		// Shortcode boxes

    		$(".wpgmza_copy_shortcode").on("click", function() {

    			var temp = $("<input>");

    			var temp2 = $('<div id="wpgmza_tmp" style="display: none;" width:100%; text-align:center;"/>');

    			$(document.body).append(temp);

    			temp.val($(this).val()).select();

    			document.execCommand("copy");

    			temp.remove();

    			$(this).after(temp2);

    			$(temp2).html(

    				$("[data-shortcode-copy-string]").attr("data-shortcode-copy-string")

    			);

    			$(temp2).fadeIn();

    			setTimeout(function() {

    				$(temp2).fadeOut();

    			}, 1000);

    			setTimeout(function() {

    				$(temp2).remove();

    			}, 1500);

    		});

    		// Fancy switches

    		// $("form.wpgmza .cmn-toggle").each(function(index, el) {

    		//

    		// 	$(el).wrap("<div class='switch'/>");

    		// 	$(el).after("<label for=""/>")

    		//

    		// });

    		$("form.wpgmza").on("click", ".switch label", function(event) {

    			var input = $(this).prev(".cmn-toggle");

    			if(input.prop("disabled"))

    				return;

    			var val = !input.prop("checked");

    			input.prop("checked", val);

    			if(val)

    				input.attr("checked", "checked");

    			else

    				input.removeAttr("checked");

    			input.trigger("change");

    		});

    		// Geolocation warnings

    		if(window.location.protocol != 'https:')

    		{

    			var warning = '<span class="notice notice-warning">' + WPGMZA.localized_strings.unsecure_geolocation + "</span>";

    			$(".wpgmza-geolocation-setting").after(

    				$(warning)

    			);

    		}

    		// Switch off thanks for feedback message

    		document.cookie = "wpgmza_feedback_thanks=false; expires=Thu, 01 Jan 1970 00:00:01 GMT;";

    	});*/

    })(jQuery);

    // js/v8/distance.js

    /**

     * @namespace WPGMZA

     * @module Distance

     * @requires WPGMZA

     */

    (function($) {

    	WPGMZA.Distance = {

    		MILES:					true,

    		KILOMETERS:				false,

    		MILES_PER_KILOMETER:	0.621371,

    		KILOMETERS_PER_MILE:	1.60934,

    		// TODO: Implement WPGMZA.settings.distance_units

    		/**

    		 * Converts a UI distance (eg from a form control) to meters,

    		 * accounting for the global units setting

    		 */

    		uiToMeters: function(uiDistance)

    		{

    			return parseFloat(uiDistance) / (WPGMZA.settings.distance_units == WPGMZA.Distance.MILES ? WPGMZA.Distance.MILES_PER_KILOMETER : 1) * 1000;

    		},

    		/**

    		 * Converts a UI distance (eg from a form control) to kilometers,

    		 * accounting for the global units setting

    		 */

    		uiToKilometers: function(uiDistance)

    		{

    			return WPGMZA.Distance.uiToMeters(uiDistance) * 0.001;

    		},

    		/**

    		 * Converts a UI distance (eg from a form control) to miles,

    		 * accounting for the global units setting

    		 */

    		uiToMiles: function(uiDistance)

    		{

    			return WPGMZA.Distance.uiToKilometers(uiDistance) * WPGMZA.Distance.MILES_PER_KILOMETER;

    		},

    		kilometersToUI: function(km)

    		{

    			if(WPGMZA.settings.distance_units == WPGMZA.Distance.MILES)

    				return km * WPGMZA.Distance.MILES_PER_KILOMETER;

    			return km;

    		}

    	};

    })(jQuery);

    // js/v8/event-dispatcher.js

    /**

     * @namespace WPGMZA

     * @module EventDispatcher

     * @requires WPGMZA

     */

    (function($) {

    	WPGMZA.EventDispatcher = function()

    	{

    		WPGMZA.assertInstanceOf(this, "EventDispatcher");

    		this._listenersByType = [];

    	}

    	WPGMZA.EventDispatcher.prototype.addEventListener = function(type, listener, thisObject, useCapture)

    	{

    		var arr;

    		var types = type.split(/\s+/);

    		if(types.length > 1)

    		{

    			for(var i = 0; i < types.length; i++)

    				this.addEventListener(types[i], listener, thisObject, useCapture);

    			return;

    		}

    		if(!(listener instanceof Function))

    			throw new Error("Listener must be a function");

    		if(!(arr = this._listenersByType[type]))

    			arr = this._listenersByType[type] = [];

    		var obj = {

    			listener: listener,

    			thisObject: (thisObject ? thisObject : this),

    			useCapture: (useCapture ? true : false)

    			};

    		arr.push(obj);

    	}

    	WPGMZA.EventDispatcher.prototype.on = WPGMZA.EventDispatcher.prototype.addEventListener;

    	WPGMZA.EventDispatcher.prototype.removeEventListener = function(type, listener, thisObject, useCapture)

    	{

    		var arr, index, obj;

    		if(!(arr = this._listenersByType[type]))

    			return;

    		if(!thisObject)

    			thisObject = this;

    		useCapture = (useCapture ? true : false);

    		for(var i = 0; i < arr.length; i++)

    		{

    			obj = arr[i];

    			if(obj.listener == listener && obj.thisObject == thisObject && obj.useCapture == useCapture)

    			{

    				arr.splice(i, 1);

    				return;

    			}

    		}

    	}

    	WPGMZA.EventDispatcher.prototype.off = WPGMZA.EventDispatcher.prototype.removeEventListener;

    	WPGMZA.EventDispatcher.prototype.hasEventListener = function(type)

    	{

    		return (_listenersByType[type] ? true : false);

    	}

    	WPGMZA.EventDispatcher.prototype.dispatchEvent = function(event)

    	{

    		if(!(event instanceof WPGMZA.Event))

    		{

    			if(typeof event == "string")

    				event = new WPGMZA.Event(event);

    			else

    			{

    				var src = event;

    				event = new WPGMZA.Event();

    				for(var name in src)

    					event[name] = src[name];

    			}

    		}

    		event.target = this;

    		var path = [];

    		for(var obj = this.parent; obj != null; obj = obj.parent)

    			path.unshift(obj);

    		event.phase = WPGMZA.Event.CAPTURING_PHASE;

    		for(var i = 0; i < path.length && !event._cancelled; i++)

    			path[i]._triggerListeners(event);

    		if(event._cancelled)

    			return;

    		event.phase = WPGMZA.Event.AT_TARGET;

    		this._triggerListeners(event);

    		event.phase = WPGMZA.Event.BUBBLING_PHASE;

    		for(i = path.length - 1; i >= 0 && !event._cancelled; i--)

    			path[i]._triggerListeners(event);

    	}

    	WPGMZA.EventDispatcher.prototype.trigger = WPGMZA.EventDispatcher.prototype.dispatchEvent;

    	WPGMZA.EventDispatcher.prototype._triggerListeners = function(event)

    	{

    		var arr, obj;

    		if(!(arr = this._listenersByType[event.type]))

    			return;

    		for(var i = 0; i < arr.length; i++)

    		{

    			obj = arr[i];

    			if(event.phase == WPGMZA.Event.CAPTURING_PHASE && !obj.useCapture)

    				continue;

    			obj.listener.call(arr[i].thisObject, event);

    		}

    	}

    	WPGMZA.events = new WPGMZA.EventDispatcher();

    })(jQuery);

    // js/v8/event.js

    /**

     * @namespace WPGMZA

     * @module Event

     * @requires WPGMZA

     */

    (function($) {

    	WPGMZA.Event = function(options)

    	{

    		if(typeof options == "string")

    			this.type = options;

    		this.bubbles		= true;

    		this.cancelable		= true;

    		this.phase			= WPGMZA.Event.PHASE_CAPTURE;

    		this.target			= null;

    		this._cancelled = false;

    		if(typeof options == "object")

    			for(var name in options)

    				this[name] = options[name];

    	}

    	WPGMZA.Event.CAPTURING_PHASE		= 0;

    	WPGMZA.Event.AT_TARGET				= 1;

    	WPGMZA.Event.BUBBLING_PHASE			= 2;

    	WPGMZA.Event.prototype.stopPropagation = function()

    	{

    		this._cancelled = true;

    	}

    })(jQuery);

    // js/v8/friendly-error.js

    /**

     * @namespace WPGMZA

     * @module FriendlyError

     * @requires WPGMZA

     */

    (function($) {

    	/*var template = '\

    		<div class="notice notice-error"> \

    			<p> \

    			' + WPGMZA.localized_strings.friendly_error + ' \

    			</p> \

    			<pre style="white-space: pre-line;"></pre> \

    		<div> \

    		';

    	WPGMZA.FriendlyError = function(nativeError)

    	{

    		if(!WPGMZA.is_admin)

    		{

    			this.element = $(WPGMZA.preloaderHTML);

    			$(this.element).removeClass("animated");

    			return;

    		}

    		$("#wpgmza-map-edit-page>.wpgmza-preloader").remove();

    		this.element = $(template);

    		this.element.find("pre").html(nativeError.message + "\r\n" + nativeError.stack + "\r\n\r\n on " + window.location.href);

    	}*/

    })(jQuery);

    // js/v8/geocoder.js

    /**

     * @namespace WPGMZA

     * @module Geocoder

     * @requires WPGMZA

     */

    (function($) {

    	WPGMZA.Geocoder = function()

    	{

    		WPGMZA.assertInstanceOf(this, "Geocoder");

    	}

    	WPGMZA.Geocoder.SUCCESS			= "success";

    	WPGMZA.Geocoder.ZERO_RESULTS	= "zero-results";

    	WPGMZA.Geocoder.FAIL			= "fail";

    	WPGMZA.Geocoder.getConstructor = function()

    	{

    		switch(WPGMZA.settings.engine)

    		{

    			case "google-maps":

    				return WPGMZA.GoogleGeocoder;

    				break;

    			default:

    				return WPGMZA.OLGeocoder;

    				break;

    		}

    	}

    	WPGMZA.Geocoder.createInstance = function()

    	{

    		var constructor = WPGMZA.Geocoder.getConstructor();

    		return new constructor();

    	}

    	WPGMZA.Geocoder.prototype.getLatLngFromAddress = function(options, callback)

    	{

    		if(WPGMZA.isLatLngString(options.address))

    		{

    			var parts = options.address.split(/,\s*/);

    			var latLng = {

    				lat: parseFloat(parts[0]),

    				lng: parseFloat(parts[1])

    			}

    			callback(latLng);

    		}

    	}

    	WPGMZA.Geocoder.prototype.geocode = function(options, callback)

    	{

    		return this.getLatLngFromAddress(options, callback);

    	}

    })(jQuery);

    // js/v8/info-window.js

    /**

     * @namespace WPGMZA

     * @module InfoWindow

     * @requires WPGMZA.EventDispatcher

     */

    (function($) {

    	WPGMZA.InfoWindow = function(mapObject)

    	{

    		var self = this;

    		WPGMZA.EventDispatcher.call(this);

    		WPGMZA.assertInstanceOf(this, "InfoWindow");

    		if(!mapObject)

    			return;

    		this.mapObject = mapObject;

    		if(mapObject.map)

    		{

    			// This has to be slightly delayed so the map initialization won't overwrite the infowindow element

    			setTimeout(function() {

    				self.onMapObjectAdded(event);

    			}, 100);

    		}

    		else

    			mapObject.addEventListener("added", function(event) {

    				self.onMapObjectAdded(event);

    			});

    	}

    	WPGMZA.InfoWindow.prototype = Object.create(WPGMZA.EventDispatcher.prototype);

    	WPGMZA.InfoWindow.prototype.constructor = WPGMZA.InfoWindow;

    	WPGMZA.InfoWindow.OPEN_BY_CLICK = 1;

    	WPGMZA.InfoWindow.OPEN_BY_HOVER = 2;

    	WPGMZA.InfoWindow.getConstructor = function()

    	{

    		switch(WPGMZA.settings.engine)

    		{

    			case "google-maps":

    				if(WPGMZA.isProVersion())

    					return WPGMZA.GoogleProInfoWindow;

    				return WPGMZA.GoogleInfoWindow;

    				break;

    			default:

    				if(WPGMZA.isProVersion())

    					return WPGMZA.OLProInfoWindow;

    				return WPGMZA.OLInfoWindow;

    				break;

    		}

    	}

    	WPGMZA.InfoWindow.createInstance = function(mapObject)

    	{

    		var constructor = this.getConstructor();

    		return new constructor(mapObject);

    	}

    	/**

    	 * Gets the content for the info window and passes it to the specified callback - this allows for delayed loading (eg AJAX) as well as instant content

    	 * @return void

    	 */

    	WPGMZA.InfoWindow.prototype.getContent = function(callback)

    	{

    		var html = "";

    		if(this.mapObject instanceof WPGMZA.Marker)

    			html = this.mapObject.address;

    		callback(html);

    	}

    	/**

    	 * Opens the info window

    	 * @return boolean FALSE if the info window should not & will not open, TRUE if it will

    	 */

    	WPGMZA.InfoWindow.prototype.open = function(map, mapObject)

    	{

    		var self = this;

    		this.mapObject = mapObject;

    		if(WPGMZA.settings.disable_infowindows)

    			return false;

    		return true;

    	}

    	WPGMZA.InfoWindow.prototype.close = function()

    	{

    	}

    	/**

    	 * Event listener for when the map object is added. This will cause the info window to open if the map object has infoopen set

    	 * @return void

    	 */

    	WPGMZA.InfoWindow.prototype.onMapObjectAdded = function()

    	{

    		if(this.mapObject.settings.infoopen == 1)

    			this.open();

    	}

    })(jQuery);

    // js/v8/latlng.js

    /**

     * @namespace WPGMZA

     * @module LatLng

     * @requires WPGMZA

     */

    (function($) {

    	/**

    	 * Constructor

    	 * @param mixed A latLng literal, or latitude

    	 * @param mixed The latitude, where arg is a longitude

    	 */

    	WPGMZA.LatLng = function(arg, lng)

    	{

    		this._lat = 0;

    		this._lng = 0;

    		if(arguments.length == 0)

    			return;

    		if(arguments.length == 1)

    		{

    			if(typeof arg != "object" || !("lat" in arg && "lng" in arg))

    				throw new Error("Argument must be a LatLng literal");

    			this.lat = arg.lat;

    			this.lng = arg.lng;

    		}

    		else

    		{

    			this.lat = arg;

    			this.lng = lng;

    		}

    	}

    	WPGMZA.LatLng.isValid = function(obj)

    	{

    		if(typeof obj != "object")

    			return false;

    		if(!("lat" in obj && "lng" in obj))

    			return false;

    		return true;

    	}

    	Object.defineProperty(WPGMZA.LatLng.prototype, "lat", {

    		get: function() {

    			return this._lat;

    		},

    		set: function(val) {

    			if(!$.isNumeric(val))

    				throw new Error("Latitude must be numeric");

    			this._lat = parseFloat( val );

    		}

    	});

    	Object.defineProperty(WPGMZA.LatLng.prototype, "lng", {

    		get: function() {

    			return this._lng;

    		},

    		set: function(val) {

    			if(!$.isNumeric(val))

    				throw new Error("Longitude must be numeric");

    			this._lng = parseFloat( val );

    		}

    	});

    	WPGMZA.LatLng.prototype.toString = function()

    	{

    		return this._lat + ", " + this._lng;

    	}

    	WPGMZA.LatLng.prototype.toGoogleLatLng = function()

    	{

    		return new google.maps.LatLng({

    			lat: this.lat,

    			lng: this.lng

    		});

    	}

    	/**

    	 * @function moveByDistance

    	 * @summary Moves this latLng by the specified kilometers along the given heading

    	 * @return void

    	 * With many thanks to Hu Kenneth - https://gis.stackexchange.com/questions/234473/get-a-lonlat-point-by-distance-or-between-2-lonlat-points

    	 */

    	WPGMZA.LatLng.prototype.moveByDistance = function(kilometers, heading)

    	{

    		var radius 		= 6371;

    		var delta 		= parseFloat(kilometers) / radius;

    		var theta 		= parseFloat(heading) / 180 * Math.PI;

    		var phi1 		= this.lat / 180 * Math.PI;

    		var lambda1 	= this.lng / 180 * Math.PI;

    		var sinPhi1 	= Math.sin(phi1), cosPhi1 = Math.cos(phi1);

    		var sinDelta	= Math.sin(delta), cosDelta = Math.cos(delta);

    		var sinTheta	= Math.sin(theta), cosTheta = Math.cos(theta);

    		var sinPhi2		= sinPhi1 * cosDelta + cosPhi1 * sinDelta * cosTheta;

    		var phi2		= Math.asin(sinPhi2);

    		var y			= sinTheta * sinDelta * cosPhi1;

    		var x			= cosDelta - sinPhi1 * sinPhi2;

    		var lambda2		= lambda1 + Math.atan2(y, x);

    		this.lat		= phi2 * 180 / Math.PI;

    		this.lng		= lambda2 * 180 / Math.PI;

    	}

    })(jQuery);

    // js/v8/latlngbounds.js

    /**

     * @namespace WPGMZA

     * @module LatLngBounds

     * @requires WPGMZA

     */

    (function($) {

    	WPGMZA.LatLngBounds = function(southWest, northEast)

    	{

    	}

    	WPGMZA.LatLngBounds.prototype.isInInitialState = function()

    	{

    		return (this.north == undefined && this.south == undefined && this.west == undefined && this.east == undefined);

    	}

    	WPGMZA.LatLngBounds.prototype.extend = function(latLng)

    	{

    		if(this.isInInitialState())

    		{

    			this.north = this.south = this.west = this.east = new WPGMZA.LatLng(latLng);

    			return;

    		}

    		if(!(latLng instanceof WPGMZA.LatLng))

    			latLng = new WPGMZA.LatLng(latLng);

    		if(latLng.lat < this.north)

    			this.north = latLng.lat;

    		if(latLng.lat > this.south)

    			this.south = latLng.lat;

    		if(latLng.lng < this.west)

    			this.west = latLng.lng;

    		if(latLng.lng > this.east)

    			this.east = latLng.lng;

    	}

    })(jQuery);

    // js/v8/map-object.js

    /**

     * @namespace WPGMZA

     * @module MapObject

     * @requires WPGMZA.EventDispatcher

     */

    (function($) {

    	WPGMZA.MapObject = function(row)

    	{

    		var self = this;

    		WPGMZA.assertInstanceOf(this, "MapObject");

    		WPGMZA.EventDispatcher.call(this);

    		this.id = -1;

    		this.guid = WPGMZA.guid();

    		this.modified = true;

    		this.settings = {};

    		if(row)

    		{

    			for(var name in row)

    			{

    				if(name == "settings")

    				{

    					if(row["settings"] == null)

    						this["settings"] = {};

    					else switch(typeof row["settings"]) {

    						case "string":

    							this["settings"] = JSON.parse(row[name]);

    							break;

    						case "object":

    							this["settings"] = row[name];

    							break;

    						default:

    							throw new Error("Don't know how to interpret settings")

    							break;

    					}

    					for(var name in this.settings)

    					{

    						var value = this.settings[name];

    						if(String(value).match(/^-?\d+$/))

    							this.settings[name] = parseInt(value);

    					}

    				}

    				else

    					this[name] = row[name];

    			}

    		}

    	}

    	WPGMZA.MapObject.prototype = Object.create(WPGMZA.EventDispatcher.prototype);

    	WPGMZA.MapObject.prototype.constructor = WPGMZA.MapObject;

    	WPGMZA.MapObject.prototype.parseGeometry = function(string)

    	{

    		var stripped, pairs, coords, results = [];

    		stripped = string.replace(/[^ ,\d\.\-+e]/g, "");

    		pairs = stripped.split(",");

    		for(var i = 0; i < pairs.length; i++)

    		{

    			coords = pairs[i].split(" ");

    			results.push({

    				lat: parseFloat(coords[1]),

    				lng: parseFloat(coords[0])

    			});

    		}

    		return results;

    	}

    	WPGMZA.MapObject.prototype.toJSON = function()

    	{

    		return {

    			id: this.id,

    			guid: this.guid,

    			settings: this.settings

    		};

    	}

    })(jQuery);

    // js/v8/circle.js

    /**

     * @namespace WPGMZA

     * @module Circle

     * @requires WPGMZA.MapObject

     */

    (function($) {

    	var Parent = WPGMZA.MapObject;

    	/**

    	 * @class Circle

    	 * @summary Represents a generic circle. <b>Please do not instantiate this object directly, use createInstance</b>

    	 * @return {WPGMZA.Circle}

    	 */

    	WPGMZA.Circle = function(options, engineCircle)

    	{

    		var self = this;

    		WPGMZA.assertInstanceOf(this, "Circle");

    		this.center = new WPGMZA.LatLng();

    		this.radius = 100;

    		Parent.apply(this, arguments);

    	}

    	WPGMZA.Circle.prototype = Object.create(Parent.prototype);

    	WPGMZA.Circle.prototype.constructor = WPGMZA.Circle;

    	/**

    	 * @function createInstance

    	 * @summary Creates an instance of a circle, <b>please always use this function rather than calling the constructor directly</b>

    	 * @param {object} options Options for the object (optional)

    	 */

    	WPGMZA.Circle.createInstance = function(options)

    	{

    		var constructor;

    		if(WPGMZA.settings.engine == "google-maps")

    			constructor = WPGMZA.GoogleCircle;

    		else

    			constructor = WPGMZA.OLCircle;

    		return new constructor(options);

    	}

    	/**

    	 * @function getCenter

    	 * @returns {WPGMZA.LatLng}

    	 */

    	WPGMZA.Circle.prototype.getCenter = function()

    	{

    		return this.center.clone();

    	}

    	/**

    	 * @function setCenter

    	 * @param {object|WPGMZA.LatLng} latLng either a literal or as a WPGMZA.LatLng

    	 * @returns {void}

    	 */

    	WPGMZA.Circle.prototype.setCenter = function(latLng)

    	{

    		this.center.lat = latLng.lat;

    		this.center.lng = latLng.lng;

    	}

    	/**

    	 * @function getRadius

    	 * @summary Returns the circles radius in kilometers

    	 * @returns {WPGMZA.LatLng}

    	 */

    	WPGMZA.Circle.prototype.getRadius = function()

    	{

    		return this.radius;

    	}

    	/**

    	 * @function setRadius

    	 * @param {number} The radius

    	 * @returns {void}

    	 */

    	WPGMZA.Circle.prototype.setRadius = function(radius)

    	{

    		this.radius = radius;

    	}

    	/**

    	 * @function getMap

    	 * @summary Returns the map that this circle is being displayed on

    	 * @return {WPGMZA.Map}

    	 */

    	WPGMZA.Circle.prototype.getMap = function()

    	{

    		return this.map;

    	}

    	/**

    	 * @function setMap

    	 * @param {WPGMZA.Map} The target map

    	 * @summary Puts this circle on a map

    	 * @return {void}

    	 */

    	WPGMZA.Circle.prototype.setMap = function(map)

    	{

    		if(this.map)

    			this.map.removeCircle(this);

    		if(map)

    			map.addCircle(this);

    	}

    })(jQuery);

    // js/v8/map-settings.js

    /**

     * @namespace WPGMZA

     * @module MapSettings

     * @requires WPGMZA

     */

    (function($) {

    	WPGMZA.MapSettings = function(element)

    	{

    		var str = element.getAttribute("data-settings");

    		var json = JSON.parse(str);

    		//var id = $(element).attr("data-map-id");

    		//var json = JSON.parse(window["wpgmza_map_settings_" + id]);

    		WPGMZA.assertInstanceOf(this, "MapSettings");

    		for(var key in json)

    		{

    			var value = json[key];

    			if(String(value).match(/^-?\d+$/))

    				value = parseInt(value);

    			this[key] = value;

    		}

    	}

    	WPGMZA.MapSettings.prototype.toOLViewOptions = function()

    	{

    		var options = {

    			center: ol.proj.fromLonLat([-119.4179, 36.7783]),

    			zoom: 4

    		};

    		function empty(name)

    		{

    			if(typeof self[name] == "object")

    				return false;

    			return !self[name] || !self[name].length;

    		}

    		// Start location

    		if(typeof this.start_location == "string")

    		{

    			var coords = this.start_location.replace(/^\(|\)$/g, "").split(",");

    			if(WPGMZA.isLatLngString(this.start_location))

    				options.center = ol.proj.fromLonLat([

    					parseFloat(coords[1]),

    					parseFloat(coords[0])

    				]);

    			else

    				console.warn("Invalid start location");

    		}

    		if(this.center)

    		{

    			options.center = ol.proj.fromLonLat([

    				parseFloat(this.center.lng),

    				parseFloat(this.center.lat)

    			]);

    		}

    		// Start zoom

    		if(this.zoom)

    			options.zoom = parseInt(this.zoom);

    		if(this.start_zoom)

    			options.zoom = parseInt(this.start_zoom);

    		// Zoom limits

    		// TODO: This matches the Google code, so some of these could be potentially put on a parent class

    		if(!empty("min_zoom"))

    			options.minZoom = parseInt(this.min_zoom);

    		if(!empty("max_zoom"))

    			options.maxZoom = parseInt(this.max_zoom);

    		return options;

    	}

    	WPGMZA.MapSettings.prototype.toGoogleMapsOptions = function()

    	{

    		var self = this;

    		var latLngCoords = (this.start_location && this.start_location.length ? this.start_location.split(",") : [36.7783, -119.4179]);

    		function empty(name)

    		{

    			if(typeof self[name] == "object")

    				return false;

    			return !self[name] || !self[name].length;

    		}

    		function formatCoord(coord)

    		{

    			if($.isNumeric(coord))

    				return coord;

    			return parseFloat( String(coord).replace(/[\(\)\s]/, "") );

    		}

    		var latLng = new google.maps.LatLng(

    			formatCoord(latLngCoords[0]),

    			formatCoord(latLngCoords[1])

    		);

    		var zoom = (this.start_zoom ? parseInt(this.start_zoom) : 4);

    		if(!this.start_zoom && this.zoom)

    			zoom = parseInt( this.zoom );

    		var options = {

    			zoom:			zoom,

    			center:			latLng

    		};

    		if(!empty("center"))

    			options.center = new google.maps.LatLng({

    				lat: parseFloat(this.center.lat),

    				lng: parseFloat(this.center.lng)

    			});

    		if(!empty("min_zoom"))

    			options.minZoom = parseInt(this.min_zoom);

    		if(!empty("max_zoom"))

    			options.maxZoom = parseInt(this.max_zoom);

    		// These settings are all inverted because the checkbox being set means "disabled"

    		options.zoomControl 			= !(this.map_zoom == true);

    		options.panControl 				= !(this.map_pan == true);

    		options.mapTypeControl			= !(this.disable_map_type_controls == true);

    		options.streetViewControl		= !(this.map_streetview == true);

    		options.fullscreenControl		= !(this.map_full_screen_control == true);

    		options.draggable				= !(this.map_draggable == true);

    		options.disableDoubleClickZoom	= !(this.map_clickzoom == true);

    		options.scrollwheel				= !(this.map_scroll == true);

    		if(this.force_greedy_gestures)

    			options.gestureHandling = "greedy";

    		switch(parseInt(this.map_type))

    		{

    			case 2:

    				options.mapTypeId = google.maps.MapTypeId.SATELLITE;

    				break;

    			case 3:

    				options.mapTypeId = google.maps.MapTypeId.HYBRID;

    				break;

    			case 4:

    				options.mapTypeId = google.maps.MapTypeId.TERRAIN;

    				break;

    			default:

    				options.mapTypeId = google.maps.MapTypeId.ROADMAP;

    				break;

    		}

    		if(this.theme_data && this.theme_data.length > 0)

    		{

    			try{

    				options.styles = JSON.parse(this.theme_data);

    			}catch(e) {

    				alert("Your theme data is not valid JSON and has been ignored");

    			}

    		}

    		return options;

    	}

    })(jQuery);

    // js/v8/map.js

    /**

     * @namespace WPGMZA

     * @module Map

     * @requires WPGMZA.EventDispatcher

     */

    (function($) {

    	/**

    	 * Constructor

    	 * @param element to contain map

    	 */

    	WPGMZA.Map = function(element, options)

    	{

    		var self = this;

    		WPGMZA.assertInstanceOf(this, "Map");

    		WPGMZA.EventDispatcher.call(this);

    		if(!(element instanceof HTMLElement))

    			throw new Error("Argument must be a HTMLElement");

    		this.id = element.getAttribute("data-map-id");

    		if(!/\d+/.test(this.id))

    			throw new Error("Map ID must be an integer");

    		WPGMZA.maps.push(this);

    		this.element = element;

    		this.element.wpgmzaMap = this;

    		this.engineElement = element;

    		this.markers = [];

    		this.polygons = [];

    		this.polylines = [];

    		this.circles = [];

    		this.loadSettings();

    	}

    	WPGMZA.Map.prototype = Object.create(WPGMZA.EventDispatcher.prototype);

    	WPGMZA.Map.prototype.constructor = WPGMZA.Map;

    	WPGMZA.Map.getConstructor = function()

    	{

    		switch(WPGMZA.settings.engine)

    		{

    			case "google-maps":

    				if(WPGMZA.isProVersion())

    					return WPGMZA.GoogleProMap;

    				return WPGMZA.GoogleMap;

    				break;

    			default:

    				if(WPGMZA.isProVersion())

    					return WPGMZA.OLProMap;

    				return WPGMZA.OLMap;

    				break;

    		}

    	}

    	WPGMZA.Map.createInstance = function(element, options)

    	{

    		var constructor = WPGMZA.Map.getConstructor();

    		return new constructor(element, options);

    	}

    	/**

    	 * Loads the maps settings and sets some defaults

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.loadSettings = function()

    	{

    		var settings = new WPGMZA.MapSettings(this.element);

    		this.settings = $.extend({}, WPGMZA.settings, settings);

    	}

    	/**

    	 * Sets options in bulk on map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.setOptions = function(options)

    	{

    		for(var name in options)

    			this.settings[name] = options[name];

    	}

    	/**

    	 * Gets the distance between two latLngs in kilometers

    	 * NB: Static function

    	 * @return number

    	 */

    	var earthRadiusMeters = 6371;

    	var piTimes360 = Math.PI / 360;

    	function deg2rad(deg) {

    	  return deg * (Math.PI/180)

    	};

    	/**

    	 * This gets the distance in kilometers between two latitude / longitude points

    	 * TODO: Move this to the distance class, or the LatLng class

    	 * @return void

    	 */

    	WPGMZA.Map.getGeographicDistance = function(lat1, lon1, lat2, lon2)

    	{

    		var dLat = deg2rad(lat2-lat1);

    		var dLon = deg2rad(lon2-lon1);

    		var a =

    			Math.sin(dLat/2) * Math.sin(dLat/2) +

    			Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *

    			Math.sin(dLon/2) * Math.sin(dLon/2);

    		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

    		var d = earthRadiusMeters * c; // Distance in km

    		return d;

    	}

    	WPGMZA.Map.prototype.setCenter = function(latLng)

    	{

    		if(!("lat" in latLng && "lng" in latLng))

    			throw new Error("Argument is not an object with lat and lng");

    	}

    	/**

    	 * Sets the dimensions of the map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.setDimensions = function(width, height)

    	{

    		$(this.element).css({

    			width: width

    		});

    		$(this.engineElement).css({

    			width: "100%",

    			height: height

    		});

    	}

    	/**

    	 * Adds the specified marker to this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.addMarker = function(marker)

    	{

    		if(!(marker instanceof WPGMZA.Marker))

    			throw new Error("Argument must be an instance of WPGMZA.Marker");

    		marker.map = this;

    		marker.parent = this;

    		this.markers.push(marker);

    		this.dispatchEvent({type: "markeradded", marker: marker});

    		marker.dispatchEvent({type: "added"});

    	}

    	/**

    	 * Removes the specified marker from this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.removeMarker = function(marker)

    	{

    		if(!(marker instanceof WPGMZA.Marker))

    			throw new Error("Argument must be an instance of WPGMZA.Marker");

    		if(marker.map !== this)

    			throw new Error("Wrong map error");

    		marker.map = null;

    		marker.parent = null;

    		this.markers.splice(this.markers.indexOf(marker), 1);

    		this.dispatchEvent({type: "markerremoved", marker: marker});

    		marker.dispatchEvent({type: "removed"});

    	}

    	WPGMZA.Map.prototype.getMarkerByID = function(id)

    	{

    		for(var i = 0; i < this.markers.length; i++)

    		{

    			if(this.markers[i].id == id)

    				return this.markers[i];

    		}

    		return null;

    	}

    	WPGMZA.Map.prototype.removeMarkerByID = function(id)

    	{

    		var marker = this.getMarkerByID(id);

    		if(!marker)

    			return;

    		this.removeMarker(marker);

    	}

    	/**

    	 * Adds the specified polygon to this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.addPolygon = function(polygon)

    	{

    		if(!(polygon instanceof WPGMZA.Polygon))

    			throw new Error("Argument must be an instance of WPGMZA.Polygon");

    		polygon.map = this;

    		this.polygons.push(polygon);

    		this.dispatchEvent({type: "polygonadded", polygon: polygon});

    	}

    	/**

    	 * Removes the specified polygon from this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.deletePolygon = function(polygon)

    	{

    		if(!(polygon instanceof WPGMZA.Polygon))

    			throw new Error("Argument must be an instance of WPGMZA.Polygon");

    		if(polygon.map !== this)

    			throw new Error("Wrong map error");

    		polygon.map = null;

    		this.polygons.splice(this.polygons.indexOf(polygon), 1);

    		this.dispatchEvent({type: "polygonremoved", polygon: polygon});

    	}

    	WPGMZA.Map.prototype.getPolygonByID = function(id)

    	{

    		for(var i = 0; i < this.polygons.length; i++)

    		{

    			if(this.polygons[i].id == id)

    				return this.polygons[i];

    		}

    		return null;

    	}

    	WPGMZA.Map.prototype.deletePolygonByID = function(id)

    	{

    		var polygon = this.getPolygonByID(id);

    		if(!polygon)

    			return;

    		this.deletePolygon(polygon);

    	}

    	/**

    	 * Gets a polyline by ID

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.getPolylineByID = function(id)

    	{

    		for(var i = 0; i < this.polylines.length; i++)

    		{

    			if(this.polylines[i].id == id)

    				return this.polylines[i];

    		}

    		return null;

    	}

    	/**

    	 * Adds the specified polyline to this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.addPolyline = function(polyline)

    	{

    		if(!(polyline instanceof WPGMZA.Polyline))

    			throw new Error("Argument must be an instance of WPGMZA.Polyline");

    		polyline.map = this;

    		this.polylines.push(polyline);

    		this.dispatchEvent({type: "polylineadded", polyline: polyline});

    	}

    	/**

    	 * Removes the specified polyline from this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.deletePolyline = function(polyline)

    	{

    		if(!(polyline instanceof WPGMZA.Polyline))

    			throw new Error("Argument must be an instance of WPGMZA.Polyline");

    		if(polyline.map !== this)

    			throw new Error("Wrong map error");

    		polyline.map = null;

    		this.polylines.splice(this.polylines.indexOf(polyline), 1);

    		this.dispatchEvent({type: "polylineremoved", polyline: polyline});

    	}

    	WPGMZA.Map.prototype.getPolylineByID = function(id)

    	{

    		for(var i = 0; i < this.polylines.length; i++)

    		{

    			if(this.polylines[i].id == id)

    				return this.polylines[i];

    		}

    		return null;

    	}

    	WPGMZA.Map.prototype.deletePolylineByID = function(id)

    	{

    		var polyline = this.getPolylineByID(id);

    		if(!polyline)

    			return;

    		this.deletePolyline(polyline);

    	}

    	/**

    	 * Adds the specified circle to this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.addCircle = function(circle)

    	{

    		if(!(circle instanceof WPGMZA.Circle))

    			throw new Error("Argument must be an instance of WPGMZA.Circle");

    		circle.map = this;

    		this.circles.push(circle);

    		this.dispatchEvent({type: "circleadded", circle: circle});

    	}

    	/**

    	 * Removes the specified circle from this map

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.removeCircle = function(circle)

    	{

    		if(!(circle instanceof WPGMZA.Circle))

    			throw new Error("Argument must be an instance of WPGMZA.Circle");

    		if(circle.map !== this)

    			throw new Error("Wrong map error");

    		circle.map = null;

    		this.circles.splice(this.circles.indexOf(circle), 1);

    		this.dispatchEvent({type: "circleremoved", circle: circle});

    	}

    	WPGMZA.Map.prototype.getCircleByID = function(id)

    	{

    		for(var i = 0; i < this.circles.length; i++)

    		{

    			if(this.circles[i].id == id)

    				return this.circles[i];

    		}

    		return null;

    	}

    	WPGMZA.Map.prototype.deleteCircleByID = function(id)

    	{

    		var circle = this.getCircleByID(id);

    		if(!circle)

    			return;

    		this.deleteCircle(circle);

    	}

    	/**

    	 * Nudges the map viewport by the given pixel coordinates

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.nudge = function(x, y)

    	{

    		var pixels = this.latLngToPixels(this.getCenter());

    		pixels.x += parseFloat(x);

    		pixels.y += parseFloat(y);

    		if(isNaN(pixels.x) || isNaN(pixels.y))

    			throw new Error("Invalid coordinates supplied");

    		var latLng = this.pixelsToLatLng(pixels);

    		this.setCenter(latLng);

    	}

    	/**

    	 * Triggered when the window resizes

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.onWindowResize = function(event)

    	{

    	}

    	/**

    	 * Listener for when the engine map div is resized

    	 * @return void

    	 */

    	WPGMZA.Map.prototype.onElementResized = function(event)

    	{

    	}

    	WPGMZA.Map.prototype.onBoundsChanged = function(event)

    	{

    		// Native events

    		this.trigger("boundschanged");

    		$(this.element).trigger("boundschanged.wpgmza");

    		// Google / legacy compatibility events

    		this.trigger("bounds_changed");

    		$(this.element).trigger("bounds_changed");

    	}

    	WPGMZA.Map.prototype.onIdle = function(event)

    	{

    		$(this.element).trigger("idle");

    		$(this.element).trigger("idle.wpgmza");

    	}

    	/*$(document).ready(function() {

    		function createMaps()

    		{

    			// TODO: Test that this works for maps off screen (which borks google)

    			$(".wpgmza-map").each(function(index, el) {

    				if(!el.wpgmzaMap)

    				{

    					WPGMZA.runCatchableTask(function() {

    						WPGMZA.Map.createInstance(el);

    					}, el);

    				}

    			});

    		}

    		createMaps();

    		// Call again each second to load AJAX maps

    		setInterval(createMaps, 1000);

    	});*/

    })(jQuery);

    // js/v8/maps-engine-dialog.js

    /**

     * @namespace WPGMZA

     * @module MapsEngineDialog

     * @requires WPGMZA

     */

    (function($) {

    	WPGMZA.MapsEngineDialog = function(element)

    	{

    		var self = this;

    		this.element = element;

    		$(element).show();

    		$(element).remodal().open();

    		$("[data-maps-engine]").on("click", function(event) {

    			self.onButtonClicked(event);

    		});

    	}

    	WPGMZA.MapsEngineDialog.prototype.onButtonClicked = function(event)

    	{

    		$(event.target).prop("disabled", true);

    		$.ajax(WPGMZA.ajaxurl, {

    			method: "POST",

    			data: {

    				action: "wpgmza_maps_engine_dialog_set_engine",

    				engine: $(event.target).attr("data-maps-engine")

    			},

    			success: function(response, status, xhr) {

    				window.location.reload();

    			}

    		});

    	}

    	$(window).on("load", function(event) {

    		var element = $("#wpgmza-maps-engine-dialog");

    		if(!element.length)

    			return;

    		if(WPGMZA.settings.wpgmza_maps_engine_dialog_done)

    			return;

    		WPGMZA.mapsEngineDialog = new WPGMZA.MapsEngineDialog(element);

    	});

    })(jQuery);

    // js/v8/marker.js

    /**

     * @namespace WPGMZA

     * @module Marker

     * @requires WPGMZA

     */

    (function($) {

    	/**

    	 * Constructor

    	 * @param json to load (optional)

    	 */

    	WPGMZA.Marker = function(row)

    	{

    		var self = this;

    		WPGMZA.assertInstanceOf(this, "Marker");

    		this.lat = "36.778261";

    		this.lng = "-119.4179323999";

    		this.address = "California";

    		this.title = null;

    		this.description = "";

    		this.link = "";

    		this.icon = "";

    		this.approved = 1;

    		this.pic = null;

    		WPGMZA.MapObject.apply(this, arguments);

    		if(row && row.heatmap)

    			return; // Don't listen for these events on heatmap markers.

    		this.on("init", function(event) {

    			if(row.position)

    				this.setPosition(row.position);

    			if(row.map)

    				row.map.addMarker(this);

    		});

    		this.addEventListener("added", function(event) {

    			self.onAdded(event);

    		});

    	}

    	WPGMZA.Marker.prototype = Object.create(WPGMZA.MapObject.prototype);

    	WPGMZA.Marker.prototype.constructor = WPGMZA.Marker;

    	/**

    	 * Gets the constructor. You can use this instead of hard coding the parent class when inheriting,

    	 * which is helpful for making subclasses that work with Basic only, Pro, Google, OL or a

    	 * combination of the four.

    	 * @return function

    	 */

    	WPGMZA.Marker.getConstructor = function()

    	{

    		switch(WPGMZA.settings.engine)

    		{

    			case "google-maps":

    				if(WPGMZA.isProVersion())

    					return WPGMZA.GoogleProMarker;

    				return WPGMZA.GoogleMarker;

    				break;

    			default:

    				if(WPGMZA.isProVersion())

    					return WPGMZA.OLProMarker;

    				return WPGMZA.OLMarker;

    				break;

    		}

    	}

    	WPGMZA.Marker.createInstance = function(row)

    	{

    		var constructor = WPGMZA.Marker.getConstructor();

    		return new constructor(row);

    	}

    	WPGMZA.Marker.ANIMATION_NONE			= "0";

    	WPGMZA.Marker.ANIMATION_BOUNCE			= "1";

    	WPGMZA.Marker.ANIMATION_DROP			= "2";

    	WPGMZA.Marker.prototype.onAdded = function(event)

    	{

    		var self = this;

    		this.infoWindow = WPGMZA.InfoWindow.createInstance(this);

    		this.addEventListener("click", function(event) {

    			self.onClick(event);

    		});

    		this.addEventListener("mouseover", function(event) {

    			self.onMouseOver(event);

    		});

    		this.addEventListener("select", function(event) {

    			self.onSelect(event);

    		});

    		if(this.map.settings.marker == this.id)

    			self.trigger("select");

    	}

    	/**

    	 * This function will hide the last info the user interacted with

    	 * @return void

    	 */

    	WPGMZA.Marker.prototype.hidePreviousInteractedInfoWindow = function()

    	{

    		if(!this.map.lastInteractedMarker)

    			return;

    		this.map.lastInteractedMarker.infoWindow.close();

    	}

    	WPGMZA.Marker.prototype.openInfoWindow = function()

    	{

    		this.hidePreviousInteractedInfoWindow();

    		this.infoWindow.open(this.map, this);

    		this.map.lastInteractedMarker = this;

    	}

    	WPGMZA.Marker.prototype.onClick = function(event)

    	{

    	}

    	WPGMZA.Marker.prototype.onSelect = function(event)

    	{

    		this.openInfoWindow();

    	}

    	WPGMZA.Marker.prototype.onMouseOver = function(event)

    	{

    		if(this.map.settings.info_window_open_by == WPGMZA.InfoWindow.OPEN_BY_HOVER)

    			this.openInfoWindow();

    	}

    	WPGMZA.Marker.prototype.getIcon = function()

    	{

    		return WPGMZA.settings.default_marker_icon;

    	}

    	/**

    	 * Gets the position of the marker

    	 * @return object

    	 */

    	WPGMZA.Marker.prototype.getPosition = function()

    	{

    		return {

    			lat: parseFloat(this.lat),

    			lng: parseFloat(this.lng)

    		};

    	}

    	/**

    	 * Sets the position of the marker

    	 * @return void

    	 */

    	WPGMZA.Marker.prototype.setPosition = function(latLng)

    	{

    		if(latLng instanceof WPGMZA.LatLng)

    		{

    			this.lat = latLng.lat;

    			this.lng = latLng.lng;

    		}

    		else

    		{

    			this.lat = parseFloat(latLng.lat);

    			this.lng = parseFloat(latLng.lng);

    		}

    	}

    	/**

    	 * Set the marker animation

    	 * @return void

    	 */

    	WPGMZA.Marker.prototype.getAnimation = function(animation)

    	{

    		return this.settings.animation;

    	}

    	/**

    	 * Set the marker animation

    	 * @return void

    	 */

    	WPGMZA.Marker.prototype.setAnimation = function(animation)

    	{

    		this.settings.animation = animation;

    	}

    	/**

    	 * Get the marker visibility

    	 * @return void

    	 */

    	WPGMZA.Marker.prototype.getVisible = function(visible)

    	{

    	}

    	/**

    	 * Set the marker visibility. This is used by the store locator etc. and is not a setting

    	 * @return void

    	 */

    	WPGMZA.Marker.prototype.setVisible = function(visible)

    	{

    		if(!visible && this.infoWindow)

    			this.infoWindow.close();

    	}

    	WPGMZA.Marker.prototype.setMap = function(map)

    	{

    		if(!map)

    		{

    			if(this.map)

    				this.map.removeMarker(this);

    			return;

    		}

    		map.addMarker(this);

    	}

    	WPGMZA.Marker.prototype.getDraggable = function()

    	{

    	}

    	WPGMZA.Marker.prototype.setDraggable = function(draggable)

    	{

    	}

    	WPGMZA.Marker.prototype.panIntoView = function()

    	{

    		if(!this.map)

    			throw new Error("Marker hasn't been added to a map");

    		this.map.setCenter(this.getPosition());

    	}

    	/**

    	 * Returns the marker as a JSON object

    	 * @return object

    	 */

    	WPGMZA.Marker.prototype.toJSON = function()

    	{

    		var result = WPGMZA.MapObject.prototype.toJSON.call(this);

    		var position = this.getPosition();

    		$.extend(result, {

    			lat: position.lat,

    			lng: position.lng,

    			address: this.address,

    			title: this.title,

    			description: this.description,

    			link: this.link,

    			icon: this.icon,

    			pic: this.pic,

    			approved: this.approved

    		});

    		return result;

    	}

    })(jQuery);

    // js/v8/modern-store-locator-circle.js

    /**

     * @namespace WPGMZA

     * @module ModernStoreLocatorCircle

     * @requires WPGMZA

     */

    (function($) {

    	/**

    	 * This module is the modern store locator circle

    	 * @constructor

    	 */

    	WPGMZA.ModernStoreLocatorCircle = function(map_id, settings) {

    		var self = this;

    		var map;

    		if(WPGMZA.isProVersion())

    			map = this.map = MYMAP[map_id].map;

    		else

    			map = this.map = MYMAP.map;

    		this.map_id = map_id;

    		this.mapElement = map.element;

    		this.mapSize = {

    			width:  $(this.mapElement).width(),

    			height: $(this.mapElement).height()

    		};

    		this.initCanvasLayer();

    		this.settings = {

    			center: new WPGMZA.LatLng(0, 0),

    			radius: 1,

    			color: "#63AFF2",

    			shadowColor: "white",

    			shadowBlur: 4,

    			centerRingRadius: 10,

    			centerRingLineWidth: 3,

    			numInnerRings: 9,

    			innerRingLineWidth: 1,

    			innerRingFade: true,

    			numOuterRings: 7,

    			ringLineWidth: 1,

    			mainRingLineWidth: 2,

    			numSpokes: 6,

    			spokesStartAngle: Math.PI / 2,

    			numRadiusLabels: 6,

    			radiusLabelsStartAngle: Math.PI / 2,

    			radiusLabelFont: "13px sans-serif",

    			visible: false

    		};

    		if(settings)

    			this.setOptions(settings);

    	};

    	WPGMZA.ModernStoreLocatorCircle.createInstance = function(map, settings) {

    		if(WPGMZA.settings.engine == "google-maps")

    			return new WPGMZA.GoogleModernStoreLocatorCircle(map, settings);

    		else

    			return new WPGMZA.OLModernStoreLocatorCircle(map, settings);

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.initCanvasLayer = function() {

    	}

    	WPGMZA.ModernStoreLocatorCircle.prototype.onResize = function(event) {

    		this.draw();

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.onUpdate = function(event) {

    		this.draw();

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.setOptions = function(options) {

    		for(var name in options)

    		{

    			var functionName = "set" + name.substr(0, 1).toUpperCase() + name.substr(1);

    			if(typeof this[functionName] == "function")

    				this[functionName](options[name]);

    			else

    				this.settings[name] = options[name];

    		}

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.getResolutionScale = function() {

    		return window.devicePixelRatio || 1;

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.getCenter = function() {

    		return this.getPosition();

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.setCenter = function(value) {

    		this.setPosition(value);

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.getPosition = function() {

    		return this.settings.center;

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.setPosition = function(position) {

    		this.settings.center = position;

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.getRadius = function() {

    		return this.settings.radius;

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.setRadius = function(radius) {

    		if(isNaN(radius))

    			throw new Error("Invalid radius");

    		this.settings.radius = radius;

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.getVisible = function(visible) {

    		return this.settings.visible;

    	};

    	WPGMZA.ModernStoreLocatorCircle.prototype.setVisible = function(visible) {

    		this.settings.visible = visible;

    	};

    	/**

    	 * This function transforms a km radius into canvas space

    	 * @return number

    	 */

    	WPGMZA.ModernStoreLocatorCircle.prototype.getTransformedRadius = function(km)

    	{

    		throw new Error("Abstract function called");

    	}

    	WPGMZA.ModernStoreLocatorCircle.prototype.getContext = function(type)

    	{

    		throw new Error("Abstract function called");

    	}

    	WPGMZA.ModernStoreLocatorCircle.prototype.getCanvasDimensions = function()

    	{

    		throw new Error("Abstract function called");

    	}

    	WPGMZA.ModernStoreLocatorCircle.prototype.draw = function() {

    		var settings = this.settings;

    		var canvasDimensions = this.getCanvasDimensions();

            var canvasWidth = canvasDimensions.width;

            var canvasHeight = canvasDimensions.height;

    		var map = this.map;

    		var resolutionScale = this.getResolutionScale();

    		context = this.getContext("2d");

            context.clearRect(0, 0, canvasWidth, canvasHeight);

    		if(!settings.visible)

    			return;

    		context.shadowColor = settings.shadowColor;

    		context.shadowBlur = settings.shadowBlur;

    		// NB: 2018/02/13 - Left this here in case it needs to be calibrated more accurately

    		/*if(!this.testCircle)

    		{

    			this.testCircle = new google.maps.Circle({

    				strokeColor: "#ff0000",

    				strokeOpacity: 0.5,

    				strokeWeight: 3,

    				map: this.map,

    				center: this.settings.center

    			});

    		}

    		this.testCircle.setCenter(settings.center);

    		this.testCircle.setRadius(settings.radius * 1000);*/

            // Reset transform

            context.setTransform(1, 0, 0, 1, 0, 0);

            var scale = Math.pow(2, map.getZoom()) * resolutionScale;

            context.scale(scale, scale);

    		// Translate by world origin

    		var offset = this.getWorldOriginOffset();

    		context.translate(offset.x, offset.y);

            // Get center and project to pixel space

    		var center = new WPGMZA.LatLng(this.settings.center);

    		var worldPoint = this.getCenterPixels();

    		var rgba = WPGMZA.hexToRgba(settings.color);

    		var ringSpacing = this.getTransformedRadius(settings.radius) / (settings.numInnerRings + 1);

    		// TODO: Implement gradients for color and opacity

    		// Inside circle (fixed?)

            context.strokeStyle = settings.color;

    		context.lineWidth = (1 / scale) * settings.centerRingLineWidth;

    		context.beginPath();

    		context.arc(

    			worldPoint.x,

    			worldPoint.y,

    			this.getTransformedRadius(settings.centerRingRadius) / scale, 0, 2 * Math.PI

    		);

    		context.stroke();

    		context.closePath();

    		// Spokes

    		var radius = this.getTransformedRadius(settings.radius) + (ringSpacing * settings.numOuterRings) + 1;

    		var grad = context.createRadialGradient(0, 0, 0, 0, 0, radius);

    		var rgba = WPGMZA.hexToRgba(settings.color);

    		var start = WPGMZA.rgbaToString(rgba), end;

    		var spokeAngle;

    		rgba.a = 0;

    		end = WPGMZA.rgbaToString(rgba);

    		grad.addColorStop(0, start);

    		grad.addColorStop(1, end);

    		context.save();

    		context.translate(worldPoint.x, worldPoint.y);

    		context.strokeStyle = grad;

    		context.lineWidth = 2 / scale;

    		for(var i = 0; i < settings.numSpokes; i++)

    		{

    			spokeAngle = settings.spokesStartAngle + (Math.PI * 2) * (i / settings.numSpokes);

    			x = Math.cos(spokeAngle) * radius;

    			y = Math.sin(spokeAngle) * radius;

    			context.setLineDash([2 / scale, 15 / scale]);

    			context.beginPath();

    			context.moveTo(0, 0);

    			context.lineTo(x, y);

    			context.stroke();

    		}

    		context.setLineDash([]);

    		context.restore();

    		// Inner ringlets

    		context.lineWidth = (1 / scale) * settings.innerRingLineWidth;

    		for(var i = 1; i <= settings.numInnerRings; i++)

    		{

    			var radius = i * ringSpacing;

    			if(settings.innerRingFade)

    				rgba.a = 1 - (i - 1) / settings.numInnerRings;

    			context.strokeStyle = WPGMZA.rgbaToString(rgba);

    			context.beginPath();

    			context.arc(worldPoint.x, worldPoint.y, radius, 0, 2 * Math.PI);

    			context.stroke();

    			context.closePath();

    		}

    		// Main circle

    		context.strokeStyle = settings.color;

    		context.lineWidth = (1 / scale) * settings.centerRingLineWidth;

    		context.beginPath();

    		context.arc(worldPoint.x, worldPoint.y, this.getTransformedRadius(settings.radius), 0, 2 * Math.PI);

    		context.stroke();

    		context.closePath();

    		// Outer ringlets

    		var radius = radius + ringSpacing;

    		for(var i = 0; i < settings.numOuterRings; i++)

    		{

    			if(settings.innerRingFade)

    				rgba.a = 1 - i / settings.numOuterRings;

    			context.strokeStyle = WPGMZA.rgbaToString(rgba);

    			context.beginPath();

    			context.arc(worldPoint.x, worldPoint.y, radius, 0, 2 * Math.PI);

    			context.stroke();

    			context.closePath();

    			radius += ringSpacing;

    		}

    		// Text

    		if(settings.numRadiusLabels > 0)

    		{

    			var m;

    			var radius = this.getTransformedRadius(settings.radius);

    			var clipRadius = (12 * 1.1) / scale;

    			var x, y;

    			if(m = settings.radiusLabelFont.match(/(\d+)px/))

    				clipRadius = (parseInt(m[1]) / 2 * 1.1) / scale;

    			context.font = settings.radiusLabelFont;

    			context.textAlign = "center";

    			context.textBaseline = "middle";

    			context.fillStyle = settings.color;

    			context.save();

    			context.translate(worldPoint.x, worldPoint.y)

    			for(var i = 0; i < settings.numRadiusLabels; i++)

    			{

    				var spokeAngle = settings.radiusLabelsStartAngle + (Math.PI * 2) * (i / settings.numRadiusLabels);

    				var textAngle = spokeAngle + Math.PI / 2;

    				var text = settings.radiusString;

    				var width;

    				if(Math.sin(spokeAngle) > 0)

    					textAngle -= Math.PI;

    				x = Math.cos(spokeAngle) * radius;

    				y = Math.sin(spokeAngle) * radius;

    				context.save();

    				context.translate(x, y);

    				context.rotate(textAngle);

    				context.scale(1 / scale, 1 / scale);

    				width = context.measureText(text).width;

    				height = width / 2;

    				context.clearRect(-width, -height, 2 * width, 2 * height);

    				context.fillText(settings.radiusString, 0, 0);

    				context.restore();

    			}

    			context.restore();

    		}

    	}

    })(jQuery);

    // js/v8/modern-store-locator.js

    /**

     * @namespace WPGMZA

     * @module ModernStoreLocator

     * @requires WPGMZA

     */

    (function($) {

    	/**

    	 * The new modern look store locator. It takes the elements

    	 * from the default look and moves them into the map, wrapping

    	 * in a new element so we can apply new styles.

    	 * @return Object

    	 */

    	WPGMZA.ModernStoreLocator = function(map_id)

    	{

    		var self = this;

    		var original;

    		WPGMZA.assertInstanceOf(this, "ModernStoreLocator");

    		if(WPGMZA.isProVersion())

    			 original = $(".wpgmza_sl_search_button[mid='" + map_id + "']").closest(".wpgmza_sl_main_div");

    		else

    			original = $(".wpgmza_sl_search_button").closest(".wpgmza_sl_main_div");

    		if(!original.length)

    			return;

    		// Build / re-arrange elements

    		this.element = $("<div class='wpgmza-modern-store-locator'><div class='wpgmza-inner wpgmza-modern-hover-opaque'/></div>")[0];

    		var inner = $(this.element).find(".wpgmza-inner");

    		var titleSearch = $(original).find("[id='nameInput_" + map_id + "']");

    		if(titleSearch.length)

    		{

    			var placeholder = wpgmaps_localize[map_id].other_settings.store_locator_name_string;

    			if(placeholder && placeholder.length)

    				titleSearch.attr("placeholder", placeholder);

    			inner.append(titleSearch);

    		}

    		var addressInput;

    		if(WPGMZA.isProVersion())

    			addressInput = $(original).find(".addressInput");

    		else

    			addressInput = $(original).find("#addressInput");

    		if(wpgmaps_localize[map_id].other_settings.store_locator_query_string && wpgmaps_localize[map_id].other_settings.store_locator_query_string.length)

    			addressInput.attr("placeholder", wpgmaps_localize[map_id].other_settings.store_locator_query_string);

    		inner.append(addressInput);

    		inner.append($(original).find("select.wpgmza_sl_radius_select"));

    		// inner.append($(original).find(".wpgmza_filter_select_" + map_id));

    		// Buttons

    		this.searchButton = $(original).find( ".wpgmza_sl_search_button" );

    		inner.append(this.searchButton);

    		this.resetButton = $(original).find( ".wpgmza_sl_reset_button_div" );

    		inner.append(this.resetButton);

    		this.resetButton.hide();

    		if(WPGMZA.isProVersion())

    		{

    			this.searchButton.on("click", function(event) {

    				if($("addressInput_" + map_id).val() == 0)

    					return;

    				self.searchButton.hide();

    				self.resetButton.show();

    			});

    			this.resetButton.on("click", function(event) {

    				self.resetButton.hide();

    				self.searchButton.show();

    			});

    		}

    		// Distance type

    		inner.append($("#wpgmza_distance_type_" + map_id));

    		// Categories

    		var container = $(original).find(".wpgmza_cat_checkbox_holder");

    		var ul = $(container).children("ul");

    		var items = $(container).find("li");

    		var numCategories = 0;

    		//$(items).find("ul").remove();

    		//$(ul).append(items);

    		var icons = [];

    		items.each(function(index, el) {

    			var id = $(el).attr("class").match(/\d+/);

    			for(var category_id in wpgmza_category_data) {

    				if(id == category_id) {

    					var src = wpgmza_category_data[category_id].image;

    					var icon = $('<div class="wpgmza-chip-icon"/>');

    					icon.css({

    						"background-image": "url('" + src + "')",

    						"width": $("#wpgmza_cat_checkbox_" + category_id + " + label").height() + "px"

    					});

    					icons.push(icon);

                        if(src != null && src != ""){

    					   //$(el).find("label").prepend(icon);

                           $("#wpgmza_cat_checkbox_" + category_id + " + label").prepend(icon);

                        }

    					numCategories++;

    					break;

    				}

    			}

    		});

            $(this.element).append(container);

    		if(numCategories) {

    			this.optionsButton = $('<span class="wpgmza_store_locator_options_button"><i class="fas fa-list"></i></span>');

    			$(this.searchButton).before(this.optionsButton);

    		}

    		setInterval(function() {

    			icons.forEach(function(icon) {

    				var height = $(icon).height();

    				$(icon).css({"width": height + "px"});

    				$(icon).closest("label").css({"padding-left": height + 8 + "px"});

    			});

    			$(container).css("width", $(self.element).find(".wpgmza-inner").outerWidth() + "px");

    		}, 1000);

    		$(this.element).find(".wpgmza_store_locator_options_button").on("click", function(event) {

    			if(container.hasClass("wpgmza-open"))

    				container.removeClass("wpgmza-open");

    			else

    				container.addClass("wpgmza-open");

    		});

    		// Remove original element

    		$(original).remove();

    		// Event listeners

    		$(this.element).find("input, select").on("focus", function() {

    			$(inner).addClass("active");

    		});

    		$(this.element).find("input, select").on("blur", function() {

    			$(inner).removeClass("active");

    		});

    	}

    	WPGMZA.ModernStoreLocator.createInstance = function(map_id)

    	{

    		if(WPGMZA.settings.engine == "google-maps")

    			return new WPGMZA.GoogleModernStoreLocator(map_id);

    		else

    			return new WPGMZA.OLModernStoreLocator(map_id);

    	}

    })(jQuery);

    // js/v8/polygon.js

    /**

     * @namespace WPGMZA

     * @module Polygon

     * @requires WPGMZA.MapObject

     */

    (function($) {

    	WPGMZA.Polygon = function(row, enginePolygon)

    	{

    		var self = this;

    		WPGMZA.assertInstanceOf(this, "Polygon");

    		this.paths = null;

    		this.title = null;

    		this.name = null;

    		this.link = null;

    		WPGMZA.MapObject.apply(this, arguments);

    	}

    	WPGMZA.Polygon.prototype = Object.create(WPGMZA.MapObject.prototype);

    	WPGMZA.Polygon.prototype.constructor = WPGMZA.Polygon;

    	WPGMZA.Polygon.getConstructor = function()

    	{

    		switch(WPGMZA.settings.engine)

    		{

    			case "google-maps":

    				if(WPGMZA.isProVersion())

    					return WPGMZA.GoogleProPolygon;

    				return WPGMZA.GooglePolygon;

    				break;

    			default:

    				if(WPGMZA.isProVersion())

    					return WPGMZA.OLProPolygon;

    				return WPGMZA.OLPolygon;

    				break;

    		}

    	}

    	WPGMZA.Polygon.createInstance = function(row, engineObject)

    	{

    		var constructor = WPGMZA.Polygon.getConstructor();

    		return new constructor(row, engineObject);

    	}

    	WPGMZA.Polygon.prototype.toJSON = function()

    	{

    		var result = WPGMZA.MapObject.prototype.toJSON.call(this);

    		$.extend(result, {

    			name:		this.name,

    			title:		this.title,

    			link:		this.link,

    		});

    		return result;

    	}

    })(jQuery);

    // js/v8/polyline.js

    /**

     * @namespace WPGMZA

     * @module Polyline

     * @requires WPGMZA.MapObject

     */

    (function($) {

    	WPGMZA.Polyline = function(row, googlePolyline)

    	{

    		var self = this;

    		WPGMZA.assertInstanceOf(this, "Polyline");

    		this.title = null;

    		WPGMZA.MapObject.apply(this, arguments);

    	}

    	WPGMZA.Polyline.prototype = Object.create(WPGMZA.MapObject.prototype);

    	WPGMZA.Polyline.prototype.constructor = WPGMZA.Polyline;

    	WPGMZA.Polyline.getConstructor = function()

    	{

    		switch(WPGMZA.settings.engine)

    		{

    			case "google-maps":

    				return WPGMZA.GooglePolyline;

    				break;

    			default:

    				return WPGMZA.OLPolyline;

    				break;

    		}

    	}

    	WPGMZA.Polyline.createInstance = function(row, engineObject)

    	{

    		var constructor = WPGMZA.Polyline.getConstructor();

    		return new constructor(row, engineObject);

    	}

    	WPGMZA.Polyline.prototype.getPoints = function()

    	{

    		return this.toJSON().points;

    	}

    	WPGMZA.Polyline.prototype.toJSON = function()

    	{

    		var result = WPGMZA.MapObject.prototype.toJSON.call(this);

    		result.title = this.title;

    		return result;

    	}

    })(jQuery);

    // js/v8/google-maps/google-circle.js

    /**

     * @namespace WPGMZA

     * @module GoogleCircle

     * @requires WPGMZA.Circle

     */

    (function($) {

    	WPGMZA.GoogleCircle = function(options, googleCircle)

    	{

    		var self = this;

    		WPGMZA.Circle.call(this, options, googleCircle);

    		if(googleCircle)

    		{

    			this.googleCircle = googleCircle;

    		}

    		else

    		{

    			this.googleCircle = new google.maps.Circle();

    			this.googleCircle.wpgmzaCircle = this;

    		}

    		google.maps.event.addListener(this.googleCircle, "click", function() {

    			self.dispatchEvent({type: "click"});

    		});

    		if(options)

    		{

    			var googleOptions = {};

    			googleOptions = $.extend({}, options);

    			delete googleOptions.map;

    			delete googleOptions.center;

    			if(options.center)

    				googleOptions.center = new google.maps.LatLng({

    					lat: options.center.lat,

    					lng: options.center.lng

    				});

    			this.googleCircle.setOptions(googleOptions);

    			if(options.map)

    				options.map.addCircle(this);

    		}

    	}

    	WPGMZA.GoogleCircle.prototype = Object.create(WPGMZA.Circle.prototype);

    	WPGMZA.GoogleCircle.prototype.constructor = WPGMZA.GoogleCircle;

    })(jQuery);

    // js/v8/google-maps/google-geocoder.js

    /**

     * @namespace WPGMZA

     * @module GoogleGeocoder

     * @requires WPGMZA.Geocoder

     */

    (function($) {

    	WPGMZA.GoogleGeocoder = function()

    	{

    	}

    	WPGMZA.GoogleGeocoder.prototype = Object.create(WPGMZA.Geocoder.prototype);

    	WPGMZA.GoogleGeocoder.prototype.constructor = WPGMZA.GoogleGeocoder;

    	WPGMZA.GoogleGeocoder.prototype.getLatLngFromAddress = function(options, callback)

    	{

    		if(!options || !options.address)

    			throw new Error("No address specified");

    		if(WPGMZA.isLatLngString(options.address))

    			return WPGMZA.Geocoder.prototype.getLatLngFromAddress.call(this, options, callback);

    		if(options.country)

    			options.componentRestrictions = {

    				country: options.country

    			};

    		var geocoder = new google.maps.Geocoder();

    		geocoder.geocode(options, function(results, status) {

    			if(status == google.maps.GeocoderStatus.OK)

    			{

    				var location = results[0].geometry.location;

    				latLng = {

    					lat: location.lat(),

    					lng: location.lng()

    				};

    				var results = [

    					{

    						geometry: {

    							location: latLng

    						},

    						latLng: latLng

    					}

    				];

    				callback(results, WPGMZA.Geocoder.SUCCESS);

    			}

    			else

    			{

    				var nativeStatus = WPGMZA.Geocoder.FAIL;

    				if(status == google.maps.GeocoderStatus.ZERO_RESULTS)

    					nativeStatus = WPGMZA.Geocoder.ZERO_RESULTS;

    				callback(null, nativeStatus);

    			}

    		});

    	}

    })(jQuery);

    // js/v8/google-maps/google-info-window.js

    /**

     * @namespace WPGMZA

     * @module GoogleInfoWindow

     * @requires WPGMZA.InfoWindow

     * @pro-requires WPGMZA.ProInfoWindow

     */

    (function($) {

    	var Parent;

    	WPGMZA.GoogleInfoWindow = function(mapObject)

    	{

    		Parent.call(this, mapObject);

    		this.setMapObject(mapObject);

    	}

    	if(WPGMZA.isProVersion())

    		Parent = WPGMZA.ProInfoWindow;

    	else

    		Parent = WPGMZA.InfoWindow;

    	WPGMZA.GoogleInfoWindow.prototype = Object.create(Parent.prototype);

    	WPGMZA.GoogleInfoWindow.prototype.constructor = WPGMZA.GoogleInfoWindow;

    	WPGMZA.GoogleInfoWindow.prototype.setMapObject = function(mapObject)

    	{

    		if(mapObject instanceof WPGMZA.Marker)

    			this.googleObject = mapObject.googleMarker;

    		else if(mapObject instanceof WPGMZA.Polygon)

    			this.googleObject = mapObject.googlePolygon;

    		else if(mapObject instanceof WPGMZA.Polyline)

    			this.googleObject = mapObject.googlePolyline;

    	}

    	WPGMZA.GoogleInfoWindow.prototype.createGoogleInfoWindow = function()

    	{

    		if(this.googleInfoWindow)

    			return;

    		this.googleInfoWindow = new google.maps.InfoWindow();

    	}

    	/**

    	 * Opens the info window

    	 * @return boolean FALSE if the info window should not & will not open, TRUE if it will

    	 */

    	WPGMZA.GoogleInfoWindow.prototype.open = function(map, mapObject)

    	{

    		var self = this;

    		if(!Parent.prototype.open.call(this, map, mapObject))

    			return false;

    		this.createGoogleInfoWindow();

    		this.setMapObject(mapObject);

    		this.googleInfoWindow.open(

    			this.mapObject.map.googleMap,

    			this.googleObject

    		);

    		if(this.content)

    			this.googleInfoWindow.setContent(this.content);

    		//this.

    		/*this.getContent(function(html) {

    			// Wrap HTML with unique ID

    			var guid = WPGMZA.guid();

    			var html = "<div id='" + guid + "'>" + html + "</div>";

    			var div, intervalID;

    			self.googleInfoWindow.setContent(html);

    			self.googleInfoWindow.open(

    				self.mapObject.map.googleMap,

    				self.googleObject

    			);

    			intervalID = setInterval(function(event) {

    				div = $("#" + guid);

    				if(div.find(".gm-style-iw").length)

    				{

    					div[0].wpgmzaMapObject = self.mapObject;

    					self.dispatchEvent("infowindowopen");

    					div.trigger("infowindowopen");

    					clearInterval(intervalID);

    				}

    			}, 50);

    		});*/

    		return true;

    	}

    	WPGMZA.GoogleInfoWindow.prototype.close = function()

    	{

    		if(!this.googleInfoWindow)

    			return;

    		WPGMZA.InfoWindow.prototype.close.call(this);

    		this.googleInfoWindow.close();

    	}

    	WPGMZA.GoogleInfoWindow.prototype.setContent = function(html)

    	{

    		this.content = html;

    		this.createGoogleInfoWindow();

    		this.googleInfoWindow.setContent(html);

    	}

    })(jQuery);

    // js/v8/google-maps/google-map.js

    /**

     * @namespace WPGMZA

     * @module GoogleMap

     * @requires WPGMZA.Map

     * @pro-requires WPGMZA.ProMap

     */

    (function($) {

    	var Parent;

    	/**

    	 * Constructor

    	 * @param element to contain the map

    	 */

    	WPGMZA.GoogleMap = function(element, options)

    	{

    		var self = this;

    		if(!window.google)

    			throw new Error("Google API not loaded - " + wpgmza_api_not_enqueued_reason);

    		Parent.call(this, element, options);

    		this.loadGoogleMap();

    		if(options)

    			this.setOptions(options);

    		google.maps.event.addListener(this.googleMap, "click", function(event) {

    			self.dispatchEvent("click");

    		});

    		google.maps.event.addListener(this.googleMap, "rightclick", function(event) {

    			var wpgmzaEvent = new WPGMZA.Event("rightclick");

    			wpgmzaEvent.latLng = {

    				lat: event.latLng.lat(),

    				lng: event.latLng.lng()

    			};

    			self.dispatchEvent(wpgmzaEvent);

    		});

    		google.maps.event.addListener(this.googleMap, "dragend", function(event) {

    			self.dispatchEvent("dragend");

    		});

    		google.maps.event.addListener(this.googleMap, "zoom_changed", function(event) {

    			self.dispatchEvent("zoom_changed");

    			self.dispatchEvent("zoomchanged");

    		});

    		// Idle event

    		google.maps.event.addListener(this.googleMap, "idle", function(event) {

    			self.onIdle(event);

    		});

    		// Dispatch event

    		if(!WPGMZA.isProVersion())

    		{

    			this.dispatchEvent("created");

    			WPGMZA.events.dispatchEvent({type: "mapcreated", map: this});

    		}

    	}

    	// If we're running the Pro version, inherit from ProMap, otherwise, inherit from Map

    	if(WPGMZA.isProVersion())

    	{

    		Parent = WPGMZA.ProMap;

    		WPGMZA.GoogleMap.prototype = Object.create(WPGMZA.ProMap.prototype);

    	}

    	else

    	{

    		Parent = WPGMZA.Map;

    		WPGMZA.GoogleMap.prototype = Object.create(WPGMZA.Map.prototype);

    	}

    	WPGMZA.GoogleMap.prototype.constructor = WPGMZA.GoogleMap;

    	/**

    	 * Creates the Google Maps map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.loadGoogleMap = function()

    	{

    		var self = this;

    		var options = this.settings.toGoogleMapsOptions();

    		this.googleMap = new google.maps.Map(this.engineElement, options);

    		google.maps.event.addListener(this.googleMap, "bounds_changed", function() {

    			self.onBoundsChanged();

    		});

    		if(this.settings.bicycle)

    			this.enableBicycleLayer(true);

    		if(this.settings.traffic)

    			this.enableTrafficLayer(true);

    		if(this.settings.transport)

    			this.enablePublicTransportLayer(true);

    		this.showPointsOfInterest(this.settings.show_points_of_interest);

    		// Move the loading wheel into the map element (it has to live outside in the HTML file because it'll be overwritten by Google otherwise)

    		$(this.engineElement).append($(this.element).find(".wpgmza-loader"));

    	}

    	WPGMZA.GoogleMap.prototype.setOptions = function(options)

    	{

    		Parent.prototype.setOptions.call(this, options);

    		this.googleMap.setOptions(this.settings.toGoogleMapsOptions());

    		var clone = $.extend({}, options);

    		if(clone.center instanceof WPGMZA.LatLng || typeof clone.center == "object")

    			clone.center = {

    				lat: parseFloat(clone.center.lat),

    				lng: parseFloat(clone.center.lng)

    			};

    		this.googleMap.setOptions(clone);

    	}

    	/**

    	 * Adds the specified marker to this map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.addMarker = function(marker)

    	{

    		marker.googleMarker.setMap(this.googleMap);

    		Parent.prototype.addMarker.call(this, marker);

    	}

    	/**

    	 * Removes the specified marker from this map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.removeMarker = function(marker)

    	{

    		marker.googleMarker.setMap(null);

    		Parent.prototype.removeMarker.call(this, marker);

    	}

    	/**

    	 * Adds the specified polygon to this map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.addPolygon = function(polygon)

    	{

    		polygon.googlePolygon.setMap(this.googleMap);

    		Parent.prototype.addPolygon.call(this, polygon);

    	}

    	/**

    	 * Removes the specified polygon from this map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.removePolygon = function(polygon)

    	{

    		polygon.googlePolygon.setMap(null);

    		Parent.prototype.removePolygon.call(this, polygon);

    	}

    	/**

    	 * Adds the specified polyline to this map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.addPolyline = function(polyline)

    	{

    		polyline.googlePolyline.setMap(this.googleMap);

    		Parent.prototype.addPolyline.call(this, polyline);

    	}

    	/**

    	 * Removes the specified polygon from this map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.removePolyline = function(polyline)

    	{

    		polyline.googlePolyline.setMap(null);

    		Parent.prototype.removePolyline.call(this, polyline);

    	}

    	WPGMZA.GoogleMap.prototype.addCircle = function(circle)

    	{

    		circle.googleCircle.setMap(this.googleMap);

    		Parent.prototype.addCircle.call(this, circle);

    	}

    	WPGMZA.GoogleMap.prototype.removeCircle = function(circle)

    	{

    		circle.googleCircle.setMap(null);

    		Parent.prototype.removeCircle.call(this, circle);

    	}

    	/**

    	 * Delegate for google maps getCenter

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.getCenter = function()

    	{

    		var latLng = this.googleMap.getCenter();

    		return {

    			lat: latLng.lat(),

    			lng: latLng.lng()

    		};

    	}

    	/**

    	 * Delegate for google maps setCenter

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.setCenter = function(latLng)

    	{

    		WPGMZA.Map.prototype.setCenter.call(this, latLng);

    		if(latLng instanceof WPGMZA.LatLng)

    			this.googleMap.setCenter({

    				lat: latLng.lat,

    				lng: latLng.lng

    			});

    		else

    			this.googleMap.setCenter(latLng);

    	}

    	/**

    	 * Delegate for google maps setPan

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.panTo = function(latLng)

    	{

    		if(latLng instanceof WPGMZA.LatLng)

    			this.googleMap.panTo({

    				lat: latLng.lat,

    				lng: latLng.lng

    			});

    		else

    			this.googleMap.panTo(latLng);

    	}

    	/**

    	 * Delegate for google maps getCenter

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.getZoom = function()

    	{

    		return this.googleMap.getZoom();

    	}

    	/**

    	 * Delegate for google maps getZoom

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.setZoom = function(value)

    	{

    		return this.googleMap.setZoom(value);

    	}

    	/**

    	 * Gets the bounds

    	 * @return object

    	 */

    	WPGMZA.GoogleMap.prototype.getBounds = function()

    	{

    		var bounds = this.googleMap.getBounds();

    		var northEast = bounds.getNorthEast();

    		var southWest = bounds.getSouthWest();

    		return {

    			topLeft: {

    				lat: northEast.lat(),

    				lng: southWest.lng()

    			},

    			bottomRight: {

    				lat: southWest.lat(),

    				lng: northEast.lng()

    			}

    		};

    	}

    	/**

    	 * Fit to given boundaries

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.fitBounds = function(southWest, northEast)

    	{

    		if(southWest instanceof WPGMZA.LatLng)

    			southWest = {lat: southWest.lat, lng: southWest.lng};

    		if(northEast instanceof WPGMZA.LatLng)

    			northEast = {lat: northEast.lat, lng: northEast.lng};

    		this.googleMap.fitBounds(southWest, northEast);

    	}

    	/**

    	 * Fit the map boundaries to visible markers

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.fitBoundsToVisibleMarkers = function()

    	{

    		var bounds = new google.maps.LatLngBounds();

    		for(var i = 0; i < this.markers.length; i++)

    		{

    			if(markers[i].getVisible())

    				bounds.extend(markers[i].getPosition());

    		}

    		this.googleMap.fitBounds(bounds);

    	}

    	/**

    	 * Enables / disables the bicycle layer

    	 * @param enable boolean, enable or not

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.enableBicycleLayer = function(enable)

    	{

    		if(!this.bicycleLayer)

    			this.bicycleLayer = new google.maps.BicyclingLayer();

    		this.bicycleLayer.setMap(

    			enable ? this.googleMap : null

    		);

    	}

    	/**

    	 * Enables / disables the bicycle layer

    	 * @param enable boolean, enable or not

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.enableTrafficLayer = function(enable)

    	{

    		if(!this.trafficLayer)

    			this.trafficLayer = new google.maps.TrafficLayer();

    		this.trafficLayer.setMap(

    			enable ? this.googleMap : null

    		);

    	}

    	/**

    	 * Enables / disables the bicycle layer

    	 * @param enable boolean, enable or not

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.enablePublicTransportLayer = function(enable)

    	{

    		if(!this.publicTransportLayer)

    			this.publicTransportLayer = new google.maps.TransitLayer();

    		this.publicTransportLayer.setMap(

    			enable ? this.googleMap : null

    		);

    	}

    	/**

    	 * Shows / hides points of interest

    	 * @param show boolean, enable or not

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.showPointsOfInterest = function(show)

    	{

    		// TODO: This will bug the front end because there is textarea with theme data

    		var text = $("textarea[name='theme_data']").val();

    		if(!text)

    			return;

    		var styles = JSON.parse(text);

    		styles.push({

    			featureType: "poi",

    			stylers: [

    				{

    					visibility: (show ? "on" : "off")

    				}

    			]

    		});

    		this.googleMap.setOptions({styles: styles});

    	}

    	/**

    	 * Gets the min zoom of the map

    	 * @return int

    	 */

    	WPGMZA.GoogleMap.prototype.getMinZoom = function()

    	{

    		return parseInt(this.settings.min_zoom);

    	}

    	/**

    	 * Sets the min zoom of the map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.setMinZoom = function(value)

    	{

    		this.googleMap.setOptions({

    			minZoom: value,

    			maxZoom: this.getMaxZoom()

    		});

    	}

    	/**

    	 * Gets the min zoom of the map

    	 * @return int

    	 */

    	WPGMZA.GoogleMap.prototype.getMaxZoom = function()

    	{

    		return parseInt(this.settings.max_zoom);

    	}

    	/**

    	 * Sets the min zoom of the map

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.setMaxZoom = function(value)

    	{

    		this.googleMap.setOptions({

    			minZoom: this.getMinZoom(),

    			maxZoom: value

    		});

    	}

    	WPGMZA.GoogleMap.prototype.latLngToPixels = function(latLng)

    	{

    		var map = this.googleMap;

    		var nativeLatLng = new google.maps.LatLng({

    			lat: parseFloat(latLng.lat),

    			lng: parseFloat(latLng.lng)

    		});

    		var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());

    		var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());

    		var scale = Math.pow(2, map.getZoom());

    		var worldPoint = map.getProjection().fromLatLngToPoint(nativeLatLng);

    		return {

    			x: (worldPoint.x - bottomLeft.x) * scale,

    			y: (worldPoint.y - topRight.y) * scale

    		};

    	}

    	WPGMZA.GoogleMap.prototype.pixelsToLatLng = function(x, y)

    	{

    		if(y == undefined)

    		{

    			if("x" in x && "y" in x)

    			{

    				y = x.y;

    				x = x.x;

    			}

    			else

    				console.warn("Y coordinate undefined in pixelsToLatLng (did you mean to pass 2 arguments?)");

    		}

    		var map = this.googleMap;

    		var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());

    		var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());

    		var scale = Math.pow(2, map.getZoom());

    		var worldPoint = new google.maps.Point(x / scale + bottomLeft.x, y / scale + topRight.y);

    		var latLng = map.getProjection().fromPointToLatLng(worldPoint);

    		return {

    			lat: latLng.lat(),

    			lng: latLng.lng()

    		};

    	}

    	/**

    	 * Handle the map element resizing

    	 * @return void

    	 */

    	WPGMZA.GoogleMap.prototype.onElementResized = function(event)

    	{

    		if(!this.googleMap)

    			return;

    		google.maps.event.trigger(this.googleMap, "resize");

    	}

    })(jQuery);

    // js/v8/google-maps/google-marker.js

    /**

     * @namespace WPGMZA

     * @module GoogleMarker

     * @requires WPGMZA.Marker

     * @pro-requires WPGMZA.ProMarker

     */

    (function($) {

    	var Parent;

    	WPGMZA.GoogleMarker = function(row)

    	{

    		var self = this;

    		Parent.call(this, row);

    		this.googleMarker = new google.maps.Marker(/*this.settings*/);

    		this.googleMarker.wpgmzaMarker = this;

    		this.googleMarker.setPosition(new google.maps.LatLng({

    			lat: parseFloat(this.lat),

    			lng: parseFloat(this.lng)

    		}));

    		this.googleMarker.setLabel(this.settings.label);

    		if(this.animation)

    			this.googleMarker.setAnimation(this.animation);

    		google.maps.event.addListener(this.googleMarker, "click", function() {

    			self.dispatchEvent("click");

    			self.dispatchEvent("select");

    		});

    		google.maps.event.addListener(this.googleMarker, "mouseover", function() {

    			self.dispatchEvent("mouseover");

    		});

    		google.maps.event.addListener(this.googleMarker, "dragend", function() {

    			var googleMarkerPosition = self.googleMarker.getPosition();

    			self.setPosition({

    				lat: googleMarkerPosition.lat(),

    				lng: googleMarkerPosition.lng()

    			});

    			self.dispatchEvent("dragend");

    		});

    		this.trigger("init");

    	}

    	if(WPGMZA.isProVersion())

    		Parent = WPGMZA.ProMarker;

    	else

    		Parent = WPGMZA.Marker;

    	WPGMZA.GoogleMarker.prototype = Object.create(Parent.prototype);

    	WPGMZA.GoogleMarker.prototype.constructor = WPGMZA.GoogleMarker;

    	WPGMZA.GoogleMarker.prototype.setLabel = function(label)

    	{

    		if(!label)

    		{

    			this.googleMarker.setLabel(null);

    			return;

    		}

    		this.googleMarker.setLabel({

    			text: label

    		});

    		if(!this.googleMarker.getIcon())

    			this.googleMarker.setIcon(WPGMZA.settings.default_marker_icon);

    	}

    	/**

    	 * Sets the position of the marker

    	 * @return void

    	 */

    	WPGMZA.GoogleMarker.prototype.setPosition = function(latLng)

    	{

    		Parent.prototype.setPosition.call(this, latLng);

    		this.googleMarker.setPosition({

    			lat: this.lat,

    			lng: this.lng

    		});

    	}

    	/**

    	 * Sets the position offset of a marker

    	 * @return void

    	 */

    	WPGMZA.GoogleMarker.prototype.setOffset = function(x, y)

    	{

    		var self = this;

    		var icon = this.googleMarker.getIcon();

    		var img = new Image();

    		var params;

    		if(typeof icon == "string")

    			params = {

    				url: icon

    			};

    		else

    			params = icon;

    		img.onload = function()

    		{

    			var defaultAnchor = {

    				x: img.width / 2,

    				y: img.height

    			};

    			params.anchor = new google.maps.Point(defaultAnchor.x - x, defaultAnchor.y - y);

    			self.googleMarker.setIcon(params);

    		}

    		img.src = params.url;

    	}

    	/**

    	 * Set the marker animation

    	 * @return void

    	 */

    	WPGMZA.GoogleMarker.prototype.setAnimation = function(animation)

    	{

    		Parent.prototype.setAnimation.call(this, animation);

    		this.googleMarker.setAnimation(animation);

    	}

    	/**

    	 * Sets the visibility of the marker

    	 * @return void

    	 */

    	WPGMZA.GoogleMarker.prototype.setVisible = function(visible)

    	{

    		Parent.prototype.setVisible.call(this, visible);

    		this.googleMarker.setVisible(visible);

    	}

    	WPGMZA.GoogleMarker.prototype.setDraggable = function(draggable)

    	{

    		this.googleMarker.setDraggable(draggable);

    	}

    })(jQuery);

    // js/v8/google-maps/google-modern-store-locator-circle.js

    /**

     * @namespace WPGMZA

     * @module GoogleModernStoreLocatorCircle

     * @requires WPGMZA.ModernStoreLocatorCircle

     */

    (function($) {

    	WPGMZA.GoogleModernStoreLocatorCircle = function(map, settings)

    	{

    		var self = this;

    		WPGMZA.ModernStoreLocatorCircle.call(this, map, settings);

    		this.intervalID = setInterval(function() {

    			var mapSize = {

    				width: $(self.mapElement).width(),

    				height: $(self.mapElement).height()

    			};

    			if(mapSize.width == self.mapSize.width && mapSize.height == self.mapSize.height)

    				return;

    			self.canvasLayer.resize_();

    			self.canvasLayer.draw();

    			self.mapSize = mapSize;

    		}, 1000);

    		$(document).bind('webkitfullscreenchange mozfullscreenchange fullscreenchange', function() {

    			self.canvasLayer.resize_();

    			self.canvasLayer.draw();

    		});

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype = Object.create(WPGMZA.ModernStoreLocatorCircle.prototype);

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.constructor = WPGMZA.GoogleModernStoreLocatorCircle;

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.initCanvasLayer = function()

    	{

    		var self = this;

    		if(this.canvasLayer)

    		{

    			this.canvasLayer.setMap(null);

    			this.canvasLayer.setAnimate(false);

    		}

    		this.canvasLayer = new CanvasLayer({

    			map: this.map.googleMap,

    			resizeHandler: function(event) {

    				self.onResize(event);

    			},

    			updateHandler: function(event) {

    				self.onUpdate(event);

    			},

    			animate: true,

    			resolutionScale: this.getResolutionScale()

            });

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.setOptions = function(options)

    	{

    		WPGMZA.ModernStoreLocatorCircle.prototype.setOptions.call(this, options);

    		this.canvasLayer.scheduleUpdate();

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.setPosition = function(position)

    	{

    		WPGMZA.ModernStoreLocatorCircle.prototype.setPosition.call(this, position);

    		this.canvasLayer.scheduleUpdate();

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.setRadius = function(radius)

    	{

    		WPGMZA.ModernStoreLocatorCircle.prototype.setRadius.call(this, radius);

    		this.canvasLayer.scheduleUpdate();

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.getTransformedRadius = function(km)

    	{

    		var multiplierAtEquator = 0.006395;

    		var spherical = google.maps.geometry.spherical;

    		var center = this.settings.center;

    		var equator = new WPGMZA.LatLng({

    			lat: 0.0,

    			lng: 0.0

    		});

    		var latitude = new WPGMZA.LatLng({

    			lat: center.lat,

    			lng: 0.0

    		});

    		var offsetAtEquator = spherical.computeOffset(equator.toGoogleLatLng(), km * 1000, 90);

    		var offsetAtLatitude = spherical.computeOffset(latitude.toGoogleLatLng(), km * 1000, 90);

    		var factor = offsetAtLatitude.lng() / offsetAtEquator.lng();

    		var result = km * multiplierAtEquator * factor;

    		if(isNaN(result))

    			throw new Error("here");

    		return result;

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.getCanvasDimensions = function()

    	{

    		return {

    			width: this.canvasLayer.canvas.width,

    			height: this.canvasLayer.canvas.height

    		};

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.getWorldOriginOffset = function()

    	{

    		var projection = this.map.googleMap.getProjection();

    		var position = projection.fromLatLngToPoint(this.canvasLayer.getTopLeft());

    		return {

    			x: -position.x,

    			y: -position.y

    		};

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.getCenterPixels = function()

    	{

    		var center = new WPGMZA.LatLng(this.settings.center);

    		var projection = this.map.googleMap.getProjection();

    		return projection.fromLatLngToPoint(center.toGoogleLatLng());

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.getContext = function(type)

    	{

    		return this.canvasLayer.canvas.getContext("2d");

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.getScale = function()

    	{

    		return Math.pow(2, this.map.getZoom()) * this.getResolutionScale();

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.setVisible = function(visible)

    	{

    		WPGMZA.ModernStoreLocatorCircle.prototype.setVisible.call(this, visible);

    		this.canvasLayer.scheduleUpdate();

    	}

    	WPGMZA.GoogleModernStoreLocatorCircle.prototype.destroy = function()

    	{

    		this.canvasLayer.setMap(null);

    		this.canvasLayer = null;

    		clearInterval(this.intervalID);

    	}

    })(jQuery);

    // js/v8/google-maps/google-modern-store-locator.js

    /**

     * @namespace WPGMZA

     * @module GoogleModernStoreLocator

     * @requires WPGMZA.ModernStoreLocator

     */

    (function($) {

    	WPGMZA.GoogleModernStoreLocator = function(map_id)

    	{

    		WPGMZA.ModernStoreLocator.call(this, map_id);

    		var googleMap;

    		if(WPGMZA.isProVersion())

    			googleMap = MYMAP[map_id].map.googleMap;

    		else

    			googleMap = MYMAP.map.googleMap;

    		googleMap.controls[google.maps.ControlPosition.TOP_CENTER].push(this.element);

    	}

    	WPGMZA.GoogleModernStoreLocator.prototype = Object.create(WPGMZA.ModernStoreLocator.prototype);

    	WPGMZA.GoogleModernStoreLocator.prototype.constructor = WPGMZA.GoogleModernStoreLocator;

    })(jQuery);

    // js/v8/google-maps/google-polygon.js

    /**

     * @namespace WPGMZA

     * @module GooglePolygon

     * @requires WPGMZA.Polygon

     * @pro-requires WPGMZA.ProPolygon

     */

    (function($) {

    	var Parent;

    	WPGMZA.GooglePolygon = function(row, googlePolygon)

    	{

    		var self = this;

    		Parent.call(this, row, googlePolygon);

    		if(googlePolygon)

    		{

    			this.googlePolygon = googlePolygon;

    		}

    		else

    		{

    			this.googlePolygon = new google.maps.Polygon(this.settings);

    			if(row && row.points)

    			{

    				var paths = this.parseGeometry(row.points);

    				this.googlePolygon.setOptions({paths: paths});

    			}

    		}

    		this.googlePolygon.wpgmzaPolygon = this;

    		google.maps.event.addListener(this.googlePolygon, "click", function() {

    			self.dispatchEvent({type: "click"});

    		});

    	}

    	if(WPGMZA.isProVersion())

    		Parent = WPGMZA.ProPolygon;

    	else

    		Parent = WPGMZA.Polygon;

    	WPGMZA.GooglePolygon.prototype = Object.create(Parent.prototype);

    	WPGMZA.GooglePolygon.prototype.constructor = WPGMZA.GooglePolygon;

    	/**

    	 * Returns true if the polygon is editable

    	 * @return void

    	 */

    	WPGMZA.GooglePolygon.prototype.getEditable = function()

    	{

    		return this.googlePolygon.getOptions().editable;

    	}

    	/**

    	 * Sets the editable state of the polygon

    	 * @return void

    	 */

    	WPGMZA.GooglePolygon.prototype.setEditable = function(value)

    	{

    		this.googlePolygon.setOptions({editable: value});

    	}

    	/**

    	 * Returns the polygon represented by a JSON object

    	 * @return object

    	 */

    	WPGMZA.GooglePolygon.prototype.toJSON = function()

    	{

    		var result = WPGMZA.Polygon.prototype.toJSON.call(this);

    		result.points = [];

    		// TODO: Support holes using multiple paths

    		var path = this.googlePolygon.getPath();

    		for(var i = 0; i < path.getLength(); i++)

    		{

    			var latLng = path.getAt(i);

    			result.points.push({

    				lat: latLng.lat(),

    				lng: latLng.lng()

    			});

    		}

    		return result;

    	}

    })(jQuery);

    // js/v8/google-maps/google-polyline.js

    /**

     * @namespace WPGMZA

     * @module GooglePolyline

     * @requires WPGMZA.Polyline

     */

    (function($) {

    	WPGMZA.GooglePolyline = function(row, googlePolyline)

    	{

    		var self = this;

    		WPGMZA.Polyline.call(this, row, googlePolyline);

    		if(googlePolyline)

    		{

    			this.googlePolyline = googlePolyline;

    		}

    		else

    		{

    			this.googlePolyline = new google.maps.Polyline(this.settings);

    			this.googlePolyline.wpgmzaPolyline = this;

    			if(row && row.points)

    			{

    				var path = this.parseGeometry(row.points);

    				this.setPoints(path);

    			}

    		}

    		google.maps.event.addListener(this.googlePolyline, "click", function() {

    			self.dispatchEvent({type: "click"});

    		});

    	}

    	WPGMZA.GooglePolyline.prototype = Object.create(WPGMZA.Polyline.prototype);

    	WPGMZA.GooglePolyline.prototype.constructor = WPGMZA.GooglePolyline;

    	WPGMZA.GooglePolyline.prototype.setEditable = function(value)

    	{

    		this.googlePolyline.setOptions({editable: value});

    	}

    	WPGMZA.GooglePolyline.prototype.setPoints = function(points)

    	{

    		this.googlePolyline.setOptions({path: points});

    	}

    	WPGMZA.GooglePolyline.prototype.toJSON = function()

    	{

    		var result = WPGMZA.Polyline.prototype.toJSON.call(this);

    		result.points = [];

    		var path = this.googlePolyline.getPath();

    		for(var i = 0; i < path.getLength(); i++)

    		{

    			var latLng = path.getAt(i);

    			result.points.push({

    				lat: latLng.lat(),

    				lng: latLng.lng()

    			});

    		}

    		return result;

    	}

    })(jQuery);

    // js/v8/google-maps/google-vertex-context-menu.js

    /**

     * @namespace WPGMZA

     * @module GoogleVertexContextMenu

     * @requires wpgmza_api_call

     */

    (function($) {

    	if(WPGMZA.settings.engine != "google-maps")

    		return;

    	WPGMZA.GoogleVertexContextMenu = function(mapEditPage)

    	{

    		var self = this;

    		this.mapEditPage = mapEditPage;

    		this.element = document.createElement("div");

    		this.element.className = "wpgmza-vertex-context-menu";

    		this.element.innerHTML = "Delete";

    		google.maps.event.addDomListener(this.element, "click", function(event) {

    			self.removeVertex();

    			event.preventDefault();

    			event.stopPropagation();

    			return false;

    		});

    	}

    	WPGMZA.GoogleVertexContextMenu.prototype = new google.maps.OverlayView();

    	WPGMZA.GoogleVertexContextMenu.prototype.onAdd = function()

    	{

    		var self = this;

    		var map = this.getMap();

    		this.getPanes().floatPane.appendChild(this.element);

    		this.divListener = google.maps.event.addDomListener(map.getDiv(), "mousedown", function(e) {

    			if(e.target != self.element)

    				self.close();

    		}, true);

    	}

    	WPGMZA.GoogleVertexContextMenu.prototype.onRemove = function()

    	{

    		google.maps.event.removeListener(this.divListener);

    		this.element.parentNode.removeChild(this.element);

    		this.set("position");

    		this.set("path");

    		this.set("vertex");

    	}

    	WPGMZA.GoogleVertexContextMenu.prototype.open = function(map, path, vertex)

    	{

    		this.set('position', path.getAt(vertex));

    		this.set('path', path);

    		this.set('vertex', vertex);

    		this.setMap(map);

    		this.draw();

    	}

    	WPGMZA.GoogleVertexContextMenu.prototype.close = function()

    	{

    		this.setMap(null);

    	}

    	WPGMZA.GoogleVertexContextMenu.prototype.draw = function()

    	{

    		var position = this.get('position');

    		var projection = this.getProjection();

    		if (!position || !projection)

    		  return;

    		var point = projection.fromLatLngToDivPixel(position);

    		this.element.style.top = point.y + 'px';

    		this.element.style.left = point.x + 'px';

    	}

    	WPGMZA.GoogleVertexContextMenu.prototype.removeVertex = function()

    	{

    		var path = this.get('path');

    		var vertex = this.get('vertex');

    		if (!path || vertex == undefined) {

    		  this.close();

    		  return;

    		}

    		path.removeAt(vertex);

    		this.close();

    	}

    })(jQuery);

    // js/v8/open-layers/ol-circle.js

    /**

     * @namespace WPGMZA

     * @module OLCircle

     * @requires WPGMZA.Circle

     */

    (function($) {

    	var Parent = WPGMZA.Circle;

    	WPGMZA.OLCircle = function(options, olFeature)

    	{

    		var self = this;

    		this.center = {lat: 0, lng: 0};

    		this.radius = 0;

    		Parent.call(this, options, olFeature);

    		if(!this.settings.fillColor)

    		{

    			this.settings.fillColor = "#ff0000";

    			this.settings.fillOpacity = 0.6;

    		}

    		this.olStyle = new ol.style.Style(this.getStyleFromSettings());

    		// IMPORTANT: Please note that due to what appears to be a bug in OpenLayers, the following code MUST be exected specifically in this order, or the circle won't appear

    		var vectorLayer3857 = new ol.layer.Vector({

    			source: new ol.source.Vector(),

    			style: this.olStyle

    		});

    		if(olFeature)

    		{

    			this.olFeature = olFeature;

    		}

    		else

    		{

    			var wgs84Sphere = new ol.Sphere(6378137);

    			var radius = this.radius;

    			var x, y;

    			x = this.center.lng;

    			y = this.center.lat;

    			var circle4326 = ol.geom.Polygon.circular(wgs84Sphere, [x, y], radius, 64);

    			var circle3857 = circle4326.clone().transform('EPSG:4326', 'EPSG:3857');

    			vectorLayer3857.getSource().addFeature(new ol.Feature(circle3857));

    		}

    		this.layer = vectorLayer3857;

    		options.map.olMap.addLayer(vectorLayer3857);

    	}

    	WPGMZA.OLCircle.prototype = Object.create(Parent.prototype);

    	WPGMZA.OLCircle.prototype.constructor = WPGMZA.OLCircle;

    	WPGMZA.OLCircle.prototype.getStyleFromSettings = function()

    	{

    		var params = {};

    		if(this.settings.strokeOpacity)

    			params.stroke = new ol.style.Stroke({

    				color: WPGMZA.hexOpacityToRGBA(this.settings.strokeColor, this.settings.strokeOpacity)

    			});

    		if(this.settings.fillOpacity)

    			params.fill = new ol.style.Fill({

    				color: WPGMZA.hexOpacityToRGBA(this.settings.fillColor, this.settings.fillOpacity)

    			});

    		return params;

    	}

    	WPGMZA.OLCircle.prototype.updateStyleFromSettings = function()

    	{

    		// Re-create the style - working on it directly doesn't cause a re-render

    		var params = this.getStyleFromSettings();

    		this.olStyle = new ol.style.Style(params);

    		this.layer.setStyle(this.olStyle);

    	}

    })(jQuery);

    // js/v8/open-layers/ol-geocoder.js

    /**

     * @namespace WPGMZA

     * @module OLGeocoder

     * @requires WPGMZA.Geocoder

     */

    (function($) {

    	/**

    	 * @class OLGeocoder

    	 * @extends Geocoder

    	 * @summary OpenLayers geocoder - uses Nominatim by default

    	 */

    	WPGMZA.OLGeocoder = function()

    	{

    	}

    	WPGMZA.OLGeocoder.prototype = Object.create(WPGMZA.Geocoder.prototype);

    	WPGMZA.OLGeocoder.prototype.constructor = WPGMZA.OLGeocoder;

    	/**

    	 * @function getResponseFromCache

    	 * @access protected

    	 * @summary Tries to retrieve cached coordinates from server cache

    	 * @param {string} address The street address to geocode

    	 * @param {function} callback Where to send the results, as an array

    	 * @return {void}

    	 */

    	WPGMZA.OLGeocoder.prototype.getResponseFromCache = function(address, callback)

    	{

    		$.ajax(WPGMZA.ajaxurl, {

    			data: {

    				action: "wpgmza_query_nominatim_cache",

    				query: address

    			},

    			success: function(response, xhr, status) {

    				callback(response);

    			}

    		});

    	}

    	/**

    	 * @function getResponseFromNominatim

    	 * @access protected

    	 * @summary Queries Nominatim on the specified address

    	 * @param {object} options An object containing the options for geocoding, address is a mandatory field

    	 * @param {function} callback The function to send the results to, as an array

    	 */

    	WPGMZA.OLGeocoder.prototype.getResponseFromNominatim = function(options, callback)

    	{

    		var data = {

    			q: options.address,

    			format: "json"

    		};

    		if(options.country)

    			data.countrycodes = options.country;

    		$.ajax("https://nominatim.openstreetmap.org/search/", {

    			data: data,

    			success: function(response, xhr, status) {

    				callback(response);

    			},

    			error: function(response, xhr, status) {

    				callback(null, WPGMZA.Geocoder.FAIL)

    			}

    		});

    	}

    	/**

    	 * @function cacheResponse

    	 * @access protected

    	 * @summary Caches a response on the server, usually after it's been returned from Nominatim

    	 * @param {string} address The street address

    	 * @param {object|array} response The response to cache

    	 * @returns {void}

    	 */

    	WPGMZA.OLGeocoder.prototype.cacheResponse = function(address, response)

    	{

    		$.ajax(WPGMZA.ajaxurl, {

    			data: {

    				action: "wpgmza_store_nominatim_cache",

    				query: address,

    				response: JSON.stringify(response)

    			},

    			method: "POST"

    		});

    	}

    	/**

    	 * @function getLatLngFromAddress

    	 * @access public

    	 * @summary Attempts to geocode an address, firstly by checking the cache for previous

    	 * results, if this fails the Nominatim server will be queried, cached and sent to the

    	 * specified callback

    	 * @param {object} options An object containing the options for geocoding, address is a mandatory field

    	 * @param {function} callback The function to send the results to, as an array

    	 * @returns {void}

    	 */

    	WPGMZA.OLGeocoder.prototype.getLatLngFromAddress = function(options, callback)

    	{

    		var self = this;

    		var address = options.address;

    		var latLng;

    		if(latLng = WPGMZA.isLatLngString(address))

    			return WPGMZA.Geocoder.prototype.getLatLngFromAddress.call(this, options, callback);

    		function finish(response, status)

    		{

    			for(var i = 0; i < response.length; i++)

    			{

    				response[i].geometry = {

    					location: new WPGMZA.LatLng({

    						lat: parseFloat(response[i].lat),

    						lng: parseFloat(response[i].lon)

    					})

    				};

    				response[i].lat = parseFloat(response[i].lat);

    				response[i].lng = parseFloat(response[i].lon);

    			}

    			callback(response, status);

    		}

    		this.getResponseFromCache(address, function(response) {

    			if(response.length)

    			{

    				finish(response, WPGMZA.Geocoder.SUCCESS);

    				return;

    			}

    			self.getResponseFromNominatim(options, function(response, status) {

    				if(status == WPGMZA.Geocoder.FAIL)

    				{

    					callback(null, WPGMZA.Geocoder.FAIL);

    					return;

    				}

    				if(response.length == 0)

    				{

    					callback(response, WPGMZA.Geocoder.ZERO_RESULTS);

    					return;

    				}

    				finish(response, WPGMZA.Geocoder.SUCCESS);

    				self.cacheResponse(address, response);

    			});

    		});

    	}

    })(jQuery);

    // js/v8/open-layers/ol-info-window.js

    /**

     * @namespace WPGMZA

     * @module OLInfoWindow

     * @requires WPGMZA.InfoWindow

     * @pro-requires WPGMZA.ProInfoWindow

     */

    (function($) {

    	var Parent;

    	WPGMZA.OLInfoWindow = function(mapObject)

    	{

    		var self = this;

    		Parent.call(this, mapObject);

    		this.element = $("<div class='ol-info-window-container ol-info-window-plain'></div>")[0];

    		$(this.element).on("click", ".ol-info-window-close", function(event) {

    			self.close();

    		});

    	}

    	if(WPGMZA.isProVersion())

    		Parent = WPGMZA.ProInfoWindow;

    	else

    		Parent = WPGMZA.InfoWindow;

    	WPGMZA.OLInfoWindow.prototype = Object.create(Parent.prototype);

    	WPGMZA.OLInfoWindow.prototype.constructor = WPGMZA.OLInfoWindow;

    	/**

    	 * Opens the info window

    	 * TODO: This should take a mapObject, not an event

    	 * @return boolean FALSE if the info window should not & will not open, TRUE if it will

    	 */

    	WPGMZA.OLInfoWindow.prototype.open = function(map, mapObject)

    	{

    		var self = this;

    		var latLng = mapObject.getPosition();

    		if(!WPGMZA.InfoWindow.prototype.open.call(this, map, mapObject))

    			return false;

    		if(this.overlay)

    			this.mapObject.map.olMap.removeOverlay(this.overlay);

    		this.overlay = new ol.Overlay({

    			element: this.element

    		});

    		this.overlay.setPosition(ol.proj.fromLonLat([

    			latLng.lng,

    			latLng.lat

    		]));

    		self.mapObject.map.olMap.addOverlay(this.overlay);

    		$(this.element).show();

    		this.dispatchEvent("infowindowopen");

    		$(this.element).trigger("infowindowopen.wpgmza");

    	}

    	WPGMZA.OLInfoWindow.prototype.close = function(event)

    	{

    		// TODO: Why? This shouldn't have to be here. Removing the overlay should hide the element (it doesn't)

    		$(this.element).hide();

    		if(!this.overlay)

    			return;

    		WPGMZA.InfoWindow.prototype.close.call(this);

    		this.mapObject.map.olMap.removeOverlay(this.overlay);

    		this.overlay = null;

    	}

    	WPGMZA.OLInfoWindow.prototype.setContent = function(html)

    	{

    		$(this.element).html("<i class='fa fa-times ol-info-window-close' aria-hidden='true'></i>" + html);

    	}

    })(jQuery);

    // js/v8/open-layers/ol-map.js

    /**

     * @namespace WPGMZA

     * @module OLMap

     * @requires WPGMZA.Map

     * @pro-requires WPGMZA.ProMap

     */

    (function($) {

    	var Parent;

    	WPGMZA.OLMap = function(element, options)

    	{

    		var self = this;

    		Parent.call(this, element);

    		this.setOptions(options);

    		var viewOptions = this.settings.toOLViewOptions();

    		$(this.element).html("");

    		this.olMap = new ol.Map({

    			target: $(element)[0],

    			layers: [

    				new ol.layer.Tile({

    					source: new ol.source.OSM()

    				})

    			],

    			view: new ol.View(viewOptions)

    		});

    		// TODO: Re-implement using correct setting names

    		// Interactions

    		this.olMap.getInteractions().forEach(function(interaction) {

    			// NB: The true and false values are flipped because these settings represent the "disabled" state when true

    			if(interaction instanceof ol.interaction.DragPan)

    				interaction.setActive( (this.settings.map_draggable ? false : true) );

    			else if(interaction instanceof ol.interaction.DoubleClickZoom)

    				interaction.setActive( (this.settings.map_clickzoom ? false : true) );

    			else if(interaction instanceof ol.interaction.MouseWheelZoom)

    				interaction.setActive( (this.settings.map_scroll ? false : true) );

    		}, this);

    		// Controls

    		this.olMap.getControls().forEach(function(control) {

    			// NB: The true and false values are flipped because these settings represent the "disabled" state when true

    			if(control instanceof ol.control.Zoom && this.settings.map_zoom)

    				this.olMap.removeControl(control);

    		}, this);

    		if(!this.settings.map_full_screen_control)

    			this.olMap.addControl(new ol.control.FullScreen());

    		// Marker layer

    		this.markerLayer = new ol.layer.Vector({

    			source: new ol.source.Vector({

    				features: []

    			})

    		});

    		this.olMap.addLayer(this.markerLayer);

    		// Listen for end of pan so we can wrap longitude if needs be

    		this.olMap.on("moveend", function(event) {

    			self.wrapLongitude();

    			self.dispatchEvent("dragend");

    			self.onIdle();

    		});

    		// Listen for zoom

    		this.olMap.getView().on("change:resolution", function(event) {

    			self.dispatchEvent("zoom_changed");

    			self.dispatchEvent("zoomchanged");

    			self.onIdle();

    			$(self.element).trigger("zoomchanged.wpgmza");

    		});

    		// Listen for bounds changing

    		this.olMap.getView().on("change", function() {

    			// Wrap longitude

    			self.onBoundsChanged();

    		});

    		self.onBoundsChanged();

    		// Store locator center

    		var marker;

    		if(this.storeLocator && (marker = this.storeLocator.centerPointMarker))

    		{

    			this.olMap.addOverlay(marker.overlay);

    			marker.setVisible(false);

    		}

    		// Cycling layer

    		console.log(this.settings);

    		// Right click listener

    		$(this.element).on("click contextmenu", function(event) {

    			var isRight;

    			event = event || window.event;

    			if("which" in event)

    				isRight = event.which == 3;

    			else if("button" in event)

    				isRight = event.button == 2;

    			if(!isRight)

    				return;

    			return self.onRightClick(event);

    		});

    		// Dispatch event

    		if(!WPGMZA.isProVersion())

    		{

    			this.dispatchEvent("created");

    			WPGMZA.events.dispatchEvent({type: "mapcreated", map: this});

    		}

    	}

    	if(WPGMZA.isProVersion())

    		Parent = WPGMZA.ProMap;

    	else

    		Parent = WPGMZA.Map;

    	WPGMZA.OLMap.prototype = Object.create(Parent.prototype);

    	WPGMZA.OLMap.prototype.constructor = WPGMZA.OLMap;

    	WPGMZA.OLMap.prototype.wrapLongitude = function()

    	{

    		var center = this.getCenter();

    		if(center.lng >= -180 && center.lng <= 180)

    			return;

    		center.lng = center.lng - 360 * Math.floor(center.lng / 360);

    		if(center.lng > 180)

    			center.lng -= 360;

    		this.setCenter(center);

    	}

    	WPGMZA.OLMap.prototype.getCenter = function()

    	{

    		var lonLat = ol.proj.toLonLat(

    			this.olMap.getView().getCenter()

    		);

    		return {

    			lat: lonLat[1],

    			lng: lonLat[0]

    		};

    	}

    	WPGMZA.OLMap.prototype.setCenter = function(latLng)

    	{

    		var view = this.olMap.getView();

    		WPGMZA.Map.prototype.setCenter.call(this, latLng);

    		view.setCenter(ol.proj.fromLonLat([

    			latLng.lng,

    			latLng.lat

    		]));

    		this.wrapLongitude();

    		this.onBoundsChanged();

    	}

    	WPGMZA.OLMap.prototype.getBounds = function()

    	{

    		var bounds = this.olMap.getView().calculateExtent(this.olMap.getSize());

    		var topLeft = ol.proj.toLonLat([bounds[0], bounds[1]]);

    		var bottomRight = ol.proj.toLonLat([bounds[2], bounds[3]]);

    		return {

    			topLeft: {

    				lat: topLeft[1],

    				lng: topLeft[0]

    			},

    			bottomRight: {

    				lat: bottomRight[1],

    				lng: bottomRight[0]

    			}

    		};

    	}

    	/**

    	 * Fit to given boundaries

    	 * @return void

    	 */

    	WPGMZA.OLMap.prototype.fitBounds = function(southWest, northEast)

    	{

    		this.olMap.getView().fitExtent(

    			[southWest.lng, southWest.lat, northEast.lng, northEast.lat],

    			this.olMap.getSize()

    		);

    	}

    	WPGMZA.OLMap.prototype.panTo = function(latLng)

    	{

    		var view = this.olMap.getView();

    		view.animate({

    			center: ol.proj.fromLonLat([

    				parseFloat(latLng.lng),

    				parseFloat(latLng.lat),

    			]),

    			duration: 500

    		});

    	}

    	WPGMZA.OLMap.prototype.getZoom = function()

    	{

    		return Math.round( this.olMap.getView().getZoom() ) + 1;

    	}

    	WPGMZA.OLMap.prototype.setZoom = function(value)

    	{

    		this.olMap.getView().setZoom(value);

    	}

    	WPGMZA.OLMap.prototype.getMinZoom = function()

    	{

    		return this.olMap.getView().getMinZoom();

    	}

    	WPGMZA.OLMap.prototype.setMinZoom = function(value)

    	{

    		this.olMap.getView().setMinZoom(value);

    	}

    	WPGMZA.OLMap.prototype.getMaxZoom = function()

    	{

    		return this.olMap.getView().getMaxZoom();

    	}

    	WPGMZA.OLMap.prototype.setMaxZoom = function(value)

    	{

    		this.olMap.getView().setMaxZoom(value);

    	}

    	WPGMZA.OLMap.prototype.setOptions = function(options)

    	{

    		Parent.prototype.setOptions.call(this, options);

    		if(!this.olMap)

    			return;

    		this.olMap.getView().setProperties( this.settings.toOLViewOptions() );

    	}

    	/**

    	 * TODO: Consider moving all these functions to their respective classes, same on google map (DO IT!!! It's very misleading having them here)

    	 */

    	WPGMZA.OLMap.prototype.addMarker = function(marker)

    	{

    		this.olMap.addOverlay(marker.overlay);

    		Parent.prototype.addMarker.call(this, marker);

    	}

    	WPGMZA.OLMap.prototype.removeMarker = function(marker)

    	{

    		this.olMap.removeOverlay(marker.overlay);

    		Parent.prototype.removeMarker.call(this, marker);

    	}

    	WPGMZA.OLMap.prototype.addPolygon = function(polygon)

    	{

    		this.olMap.addLayer(polygon.layer);

    		Parent.prototype.addPolygon.call(this, polygon);

    	}

    	WPGMZA.OLMap.prototype.removePolygon = function(polygon)

    	{

    		this.olMap.removeLayer(polygon.layer);

    		Parent.prototype.removePolygon.call(this, polygon);

    	}

    	WPGMZA.OLMap.prototype.addPolyline = function(polyline)

    	{

    		this.olMap.addLayer(polyline.layer);

    		Parent.prototype.addPolyline.call(this, polyline);

    	}

    	WPGMZA.OLMap.prototype.removePolyline = function(polyline)

    	{

    		this.olMap.removeLayer(polyline.layer);

    		Parent.prototype.removePolyline.call(this, polyline);

    	}

    	WPGMZA.OLMap.prototype.addCircle = function(circle)

    	{

    		this.olMap.addLayer(circle.layer);

    		Parent.prototype.addCircle.call(this, circle);

    	}

    	WPGMZA.OLMap.prototype.removeCircle = function(circle)

    	{

    		this.olMap.removeLayer(circle.layer);

    		Parent.prototype.removeCircle.call(this, circle);

    	}

    	WPGMZA.OLMap.prototype.pixelsToLatLng = function(x, y)

    	{

    		if(y == undefined)

    		{

    			if("x" in x && "y" in x)

    			{

    				y = x.y;

    				x = x.x;

    			}

    			else

    				console.warn("Y coordinate undefined in pixelsToLatLng (did you mean to pass 2 arguments?)");

    		}

    		var coord = this.olMap.getCoordinateFromPixel([x, y]);

    		if(!coord)

    			return {

    				x: null,

    				y: null

    			};

    		var lonLat = ol.proj.toLonLat(coord);

    		return {

    			lat: lonLat[1],

    			lng: lonLat[0]

    		};

    	}

    	WPGMZA.OLMap.prototype.latLngToPixels = function(latLng)

    	{

    		var coord = ol.proj.fromLonLat([latLng.lng, latLng.lat]);

    		var pixel = this.olMap.getPixelFromCoordinate(coord);

    		if(!pixel)

    			return {

    				x: null,

    				y: null

    			};

    		return {

    			x: pixel[0],

    			y: pixel[1]

    		};

    	}

    	WPGMZA.OLMap.prototype.enableBicycleLayer = function(value)

    	{

    		if(value)

    		{

    			if(!this.bicycleLayer)

    				this.bicycleLayer = new ol.layer.Tile({

    					source: new ol.source.OSM({

    						url: "http://{a-c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png"

    					})

    				});

    			this.olMap.addLayer(this.bicycleLayer);

    		}

    		else

    		{

    			if(!this.bicycleLayer)

    				return;

    			this.olMap.removeLayer(this.bicycleLayer);

    		}

    	}

    	WPGMZA.OLMap.prototype.onElementResized = function(event)

    	{

    		this.olMap.updateSize();

    	}

    	WPGMZA.OLMap.prototype.onRightClick = function(event)

    	{

    		if($(event.target).closest(".ol-marker, .wpgmza_modern_infowindow, .wpgmza-modern-store-locator").length)

    			return true;

    		var parentOffset = $(this.element).offset();

    		var relX = event.pageX - parentOffset.left;

    		var relY = event.pageY - parentOffset.top;

    		var latLng = this.pixelsToLatLng(relX, relY);

    		this.trigger({type: "rightclick", latLng: latLng});

    		$(this.element).trigger("rightclick.wpgmza");

    		event.preventDefault();

    		return false;

    	}

    })(jQuery);

    // js/v8/open-layers/ol-marker.js

    /**

     * @namespace WPGMZA

     * @module OLMarker

     * @requires WPGMZA.Marker

     * @pro-requires WPGMZA.ProMarker

     */

    (function($) {

    	var Parent;

    	WPGMZA.OLMarker = function(row)

    	{

    		var self = this;

    		Parent.call(this, row);

    		var origin = ol.proj.fromLonLat([

    			parseFloat(this.lng),

    			parseFloat(this.lat)

    		]);

    		this.element = $("<div class='ol-marker'><img src='" + WPGMZA.settings.default_marker_icon + "'/></div>")[0];

    		$(this.element).on("click", function(event) {

    			self.dispatchEvent("click");

    			self.dispatchEvent("select");

    		});

    		$(this.element).on("mouseover", function(event) {

    			self.dispatchEvent("mouseover");

    		});

    		this.overlay = new ol.Overlay({

    			element: this.element

    		});

    		this.overlay.setPosition(origin);

    		if(this.animation)

    			this.setAnimation(this.animation);

    		this.setLabel(this.settings.label);

    		if(row.draggable)

    			this.setDraggable(true);

    		this.trigger("init");

    	}

    	if(WPGMZA.isProVersion())

    		Parent = WPGMZA.ProMarker;

    	else

    		Parent = WPGMZA.Marker;

    	WPGMZA.OLMarker.prototype = Object.create(Parent.prototype);

    	WPGMZA.OLMarker.prototype.constructor = WPGMZA.OLMarker;

    	WPGMZA.OLMarker.prototype.addLabel = function()

    	{

    		this.setLabel(this.getLabelText());

    	}

    	WPGMZA.OLMarker.prototype.setLabel = function(label)

    	{

    		if(!label)

    		{

    			if(this.label)

    				$(this.element).find(".ol-marker-label").remove();

    			return;

    		}

    		if(!this.label)

    		{

    			this.label = $("<div class='ol-marker-label'/>");

    			$(this.element).append(this.label);

    		}

    		this.label.html(label);

    	}

    	WPGMZA.OLMarker.prototype.setVisible = function(visible)

    	{

    		Parent.prototype.setVisible(visible);

    		this.overlay.getElement().style.display = (visible ? "block" : "none");

    	}

    	WPGMZA.OLMarker.prototype.setPosition = function(latLng)

    	{

    		Parent.prototype.setPosition.call(this, latLng);

    		var origin = ol.proj.fromLonLat([

    			parseFloat(this.lng),

    			parseFloat(this.lat)

    		]);

    		this.overlay.setPosition(origin);

    	}

    	WPGMZA.OLMarker.prototype.setOffset = function(x, y)

    	{

    		this.element.style.position = "relative";

    		this.element.style.left = x + "px";

    		this.element.style.top = y + "px";

    	}

    	WPGMZA.OLMarker.prototype.setAnimation = function(anim)

    	{

    		Parent.prototype.setAnimation.call(this, anim);

    		switch(anim)

    		{

    			case WPGMZA.Marker.ANIMATION_NONE:

    				$(this.element).removeAttr("data-anim");

    				break;

    			case WPGMZA.Marker.ANIMATION_BOUNCE:

    				$(this.element).attr("data-anim", "bounce");

    				break;

    			case WPGMZA.Marker.ANIMATION_DROP:

    				$(this.element).attr("data-anim", "drop");

    				break;

    		}

    	}

    	WPGMZA.OLMarker.prototype.setDraggable = function(draggable)

    	{

    		var self = this;

    		if(draggable)

    		{

    			var options = {

    				disabled: false

    			};

    			if(!this.jQueryDraggableInitialized)

    			{

    				options.stop = function(event) {

    					self.onDragEnd(event);

    				}

    			}

    			$(this.element).draggable(options);

    		}

    		else

    			$(this.element).draggable({disabled: true});

    	}

    	WPGMZA.OLMarker.prototype.onDragEnd = function(event)

    	{

    		var offset = {

    			top:	parseFloat( $(this.element).css("top").match(/-?\d+/)[0] ),

    			left:	parseFloat( $(this.element).css("left").match(/-?\d+/)[0] )

    		};

    		$(this.element).css({

    			top: 	"0px",

    			left: 	"0px"

    		});

    		console.log(offset);

    		var currentLatLng 		= this.getPosition();

    		var pixelsBeforeDrag 	= this.map.latLngToPixels(currentLatLng);

    		var pixelsAfterDrag		= {

    			x: pixelsBeforeDrag.x + offset.left,

    			y: pixelsBeforeDrag.y + offset.top

    		};

    		var latLngAfterDrag		= this.map.pixelsToLatLng(pixelsAfterDrag);

    		this.setPosition(latLngAfterDrag);

    		this.trigger({type: "dragend", latLng: latLngAfterDrag})

    		$(this.element).trigger("dragend.wpgmza");

    	}

    })(jQuery);

    // js/v8/open-layers/ol-modern-store-locator-circle.js

    /**

     * @namespace WPGMZA

     * @module OLModernStoreLocatorCircle

     * @requires WPGMZA.ModernStoreLocatorCircle

     */

    (function($) {

    	WPGMZA.OLModernStoreLocatorCircle = function(map, settings)

    	{

    		WPGMZA.ModernStoreLocatorCircle.call(this, map, settings);

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype = Object.create(WPGMZA.ModernStoreLocatorCircle.prototype);

    	WPGMZA.OLModernStoreLocatorCircle.prototype.constructor = WPGMZA.OLModernStoreLocatorCircle;

    	WPGMZA.OLModernStoreLocatorCircle.prototype.initCanvasLayer = function()

    	{

    		var self = this;

    		var mapElement = $(this.map.element);

    		var olViewportElement = mapElement.children(".ol-viewport");

    		this.canvas = document.createElement("canvas");

    		this.canvas.className = "wpgmza-ol-canvas-overlay";

    		mapElement.append(this.canvas);

    		this.renderFunction = function(event) {

    			if(self.canvas.width != olViewportElement.width() || self.canvas.height != olViewportElement.height())

    			{

    				self.canvas.width = olViewportElement.width();

    				self.canvas.height = olViewportElement.height();

    				$(this.canvas).css({

    					width: olViewportElement.width() + "px",

    					height: olViewportElement.height() + "px"

    				});

    			}

    			self.draw();

    		};

    		this.map.olMap.on("postrender", this.renderFunction);

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype.getContext = function(type)

    	{

    		return this.canvas.getContext(type);

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype.getCanvasDimensions = function()

    	{

    		return {

    			width: this.canvas.width,

    			height: this.canvas.height

    		};

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype.getCenterPixels = function()

    	{

    		var center = this.map.latLngToPixels(this.settings.center);

    		return center;

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype.getWorldOriginOffset = function()

    	{

    		return {

    			x: 0,

    			y: 0

    		};

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype.getTransformedRadius = function(km)

    	{

    		var center = new WPGMZA.LatLng(this.settings.center);

    		var outer = new WPGMZA.LatLng(center);

    		outer.moveByDistance(km, 90);

    		var centerPixels = this.map.latLngToPixels(center);

    		var outerPixels = this.map.latLngToPixels(outer);

    		return Math.abs(outerPixels.x - centerPixels.x);

    		if(!window.testMarker){

    			window.testMarker = WPGMZA.Marker.createInstance({

    				position: outer

    			});

    			WPGMZA.maps[0].addMarker(window.testMarker);

    		}

    		return 100;

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype.getScale = function()

    	{

    		return 1;

    	}

    	WPGMZA.OLModernStoreLocatorCircle.prototype.destroy = function()

    	{

    		$(this.canvas).remove();

    		this.map.olMap.un("postrender", this.renderFunction);

    		this.map = null;

    		this.canvas = null;

    	}

    })(jQuery);

    // js/v8/open-layers/ol-modern-store-locator.js

    /**

     * @namespace WPGMZA

     * @module OLModernStoreLocator

     * @requires WPGMZA.ModernStoreLocator

     */

    (function($) {

    	WPGMZA.OLModernStoreLocator = function(map_id)

    	{

    		var element;

    		WPGMZA.ModernStoreLocator.call(this, map_id);

    		if(WPGMZA.isProVersion())

    			element = $(".wpgmza_map[data-map-id='" + map_id + "']");

    		else

    			element = $("#wpgmza_map");

    		element.append(this.element);

    	}

    	WPGMZA.OLModernStoreLocator.prototype = Object.create(WPGMZA.ModernStoreLocator);

    	WPGMZA.OLModernStoreLocator.prototype.constructor = WPGMZA.OLModernStoreLocator;

    })(jQuery);

    // js/v8/open-layers/ol-polygon.js

    /**

     * @namespace WPGMZA

     * @module OLPolygon

     * @requires WPGMZA.Polygon

     * @pro-requires WPGMZA.ProPolygon

     */

    (function($) {

    	var Parent;

    	WPGMZA.OLPolygon = function(row, olFeature)

    	{

    		var self = this;

    		Parent.call(this, row, olFeature);

    		this.olStyle = new ol.style.Style();

    		if(olFeature)

    		{

    			this.olFeature = olFeature;

    		}

    		else

    		{

    			var coordinates = [[]];

    			if(row && row.points)

    			{

    				var paths = this.parseGeometry(row.points);

    				for(var i = 0; i < paths.length; i++)

    					coordinates[0].push(ol.proj.fromLonLat([

    						parseFloat(paths[i].lng),

    						parseFloat(paths[i].lat)

    					]));

    				this.olStyle = new ol.style.Style(this.getStyleFromSettings());

    			}

    			this.olFeature = new ol.Feature({

    				geometry: new ol.geom.Polygon(coordinates)

    			});

    		}

    		this.layer = new ol.layer.Vector({

    			source: new ol.source.Vector({

    				features: [this.olFeature]

    			}),

    			style: this.olStyle

    		});

    		this.layer.getSource().getFeatures()[0].setProperties({

    			wpgmzaPolygon: this

    		});

    	}

    	if(WPGMZA.isProVersion())

    		Parent = WPGMZA.ProPolygon;

    	else

    		Parent = WPGMZA.Polygon;

    	WPGMZA.OLPolygon.prototype = Object.create(Parent.prototype);

    	WPGMZA.OLPolygon.prototype.constructor = WPGMZA.OLPolygon;

    	WPGMZA.OLPolygon.prototype.getStyleFromSettings = function()

    	{

    		var params = {};

    		if(this.settings.strokeOpacity)

    			params.stroke = new ol.style.Stroke({

    				color: WPGMZA.hexOpacityToRGBA(this.settings.strokeColor, this.settings.strokeOpacity)

    			});

    		if(this.settings.fillOpacity)

    			params.fill = new ol.style.Fill({

    				color: WPGMZA.hexOpacityToRGBA(this.settings.fillColor, this.settings.fillOpacity)

    			});

    		return params;

    	}

    	WPGMZA.OLPolygon.prototype.updateStyleFromSettings = function()

    	{

    		// Re-create the style - working on it directly doesn't cause a re-render

    		var params = this.getStyleFromSettings();

    		this.olStyle = new ol.style.Style(params);

    		this.layer.setStyle(this.olStyle);

    	}

    	WPGMZA.OLPolygon.prototype.setEditable = function(editable)

    	{

    	}

    	WPGMZA.OLPolygon.prototype.toJSON = function()

    	{

    		var result = Parent.prototype.toJSON.call(this);

    		var coordinates = this.olFeature.getGeometry().getCoordinates()[0];

    		result.points = [];

    		for(var i = 0; i < coordinates.length; i++)

    		{

    			var lonLat = ol.proj.toLonLat(coordinates[i]);

    			var latLng = {

    				lat: lonLat[1],

    				lng: lonLat[0]

    			};

    			result.points.push(latLng);

    		}

    		return result;

    	}

    })(jQuery);

    // js/v8/open-layers/ol-polyline.js

    /**

     * @namespace WPGMZA

     * @module OLPolyline

     * @requires WPGMZA.Polyline

     */

    (function($) {

    	var Parent;

    	WPGMZA.OLPolyline = function(row, olFeature)

    	{

    		var self = this;

    		WPGMZA.Polyline.call(this, row);

    		this.olStyle = new ol.style.Style();

    		if(olFeature)

    		{

    			this.olFeature = olFeature;

    		}

    		else

    		{

    			var coordinates = [];

    			if(row && row.points)

    			{

    				var path = this.parseGeometry(row.points);

    				for(var i = 0; i < path.length; i++)

    					coordinates.push(ol.proj.fromLonLat([

    						parseFloat(path[i].lng),

    						parseFloat(path[i].lat)

    					]));

    			}

    			var params = this.getStyleFromSettings();

    			this.olStyle = new ol.style.Style(params);

    			this.olFeature = new ol.Feature({

    				geometry: new ol.geom.LineString(coordinates)

    			});

    		}

    		this.layer = new ol.layer.Vector({

    			source: new ol.source.Vector({

    				features: [this.olFeature]

    			}),

    			style: this.olStyle

    		});

    		this.layer.getSource().getFeatures()[0].setProperties({

    			wpgmzaPolyling: this

    		});

    	}

    	Parent = WPGMZA.Polyline;

    	WPGMZA.OLPolyline.prototype = Object.create(Parent.prototype);

    	WPGMZA.OLPolyline.prototype.constructor = WPGMZA.OLPolyline;

    	WPGMZA.OLPolyline.prototype.getStyleFromSettings = function()

    	{

    		var params = {};

    		if(this.settings.strokeOpacity)

    			params.stroke = new ol.style.Stroke({

    				color: WPGMZA.hexOpacityToRGBA(this.settings.strokeColor, this.settings.strokeOpacity),

    				width: parseInt(this.settings.strokeWeight)

    			});

    		return params;

    	}

    	WPGMZA.OLPolyline.prototype.updateStyleFromSettings = function()

    	{

    		// Re-create the style - working on it directly doesn't cause a re-render

    		var params = this.getStyleFromSettings();

    		this.olStyle = new ol.style.Style(params);

    		this.layer.setStyle(this.olStyle);

    	}

    	WPGMZA.OLPolyline.prototype.setEditable = function(editable)

    	{

    	}

    	WPGMZA.OLPolyline.prototype.setPoints = function(points)

    	{

    		if(this.olFeature)

    			this.layer.getSource().removeFeature(this.olFeature);

    		var coordinates = [];

    		for(var i = 0; i < points.length; i++)

    			coordinates.push(ol.proj.fromLonLat([

    				parseFloat(points[i].lng),

    				parseFloat(points[i].lat)

    			]));

    		this.olFeature = new ol.Feature({

    			geometry: new ol.geom.LineString(coordinates)

    		});

    		this.layer.getSource().addFeature(this.olFeature);

    	}

    	WPGMZA.OLPolyline.prototype.toJSON = function()

    	{

    		var result = Parent.prototype.toJSON.call(this);

    		var coordinates = this.olFeature.getGeometry().getCoordinates();

    		result.points = [];

    		for(var i = 0; i < coordinates.length; i++)

    		{

    			var lonLat = ol.proj.toLonLat(coordinates[i]);

    			var latLng = {

    				lat: lonLat[1],

    				lng: lonLat[0]

    			};

    			result.points.push(latLng);

    		}

    		return result;

    	}

    })(jQuery);