/** 
 * Developer's Notice:
 * 
 * Note: JS in this file (and this file itself) is not garunteed backwards compatibility. JS can be added, changed or removed at any time without notice.
 * For more information see the `Backwards Compatibility Guidelines for Developers` section of the README.md file.
 */
/**
 * Handles:
 * - JS Events handling
 *
 * @since 6.0.12
 */
var MonsterInsights = function(){
	// MonsterInsights JS  events tracking works on all major browsers, including IE starting at IE 7, via polyfills for any major JS fucntion used that
	// is not supported by at least  95% of the global and/or US browser marketshare. Currently, IE 7 & 8 which as of 2/14/17 have under 0.25% global marketshare, require
	// us to polyfill Array.prototype.lastIndexOf, and if they continue to drop, we might remove this polyfill at some point. In that case note that events tracking
	// for IE 7/8 will continue to work, with the exception of events tracking of downloads.
	var lastClicked = [];
	
	this.setLastClicked = function(valuesArray,fieldsArray,tracked){ 
		valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
		fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : [];
		tracked     = typeof tracked !== 'undefined' ? tracked : false;

		lastClicked.valuesArray = valuesArray;
		lastClicked.fieldsArray = fieldsArray;
	};

	this.getLastClicked = function () {
		return lastClicked;
	};

	function __gaTrackerIsDebug () {
		if ( monsterinsights_frontend.is_debug_mode === "true" || window.monsterinsights_debug_mode ) {
			 return true;
		} else {
			return false;
		}
	}

	function __gaTrackerSend ( valuesArray, fieldsArray ) {
		valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
		fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : {};

		__gaTracker( 'send', fieldsArray );

		lastClicked.valuesArray = valuesArray;
		lastClicked.fieldsArray = fieldsArray;
		lastClicked.tracked     = true;
		__gaTrackerLog( 'Tracked: ' + valuesArray.type );
		__gaTrackerLog( lastClicked );
	}

	function __gaTrackerNotSend ( valuesArray ) {
		valuesArray             = typeof valuesArray !== 'undefined' ? valuesArray : [];

		lastClicked.valuesArray = valuesArray;
		lastClicked.fieldsArray = [];
		lastClicked.tracked     = false;
		__gaTrackerLog( 'Not Tracked: ' + valuesArray.exit );
		__gaTrackerLog( lastClicked );
	}

	function __gaTrackerLog ( message ) {
		if ( __gaTrackerIsDebug() ) {
			console.dir( message );
		}
	}

	function __gaTrackerStringTrim( x ) {
		return x.replace(/^\s+|\s+$/gm,'');
	}

	function __gaTrackerGetDomain() {
	   var i=0,currentdomain=document.domain,p=currentdomain.split('.'),s='_gd'+(new Date()).getTime();
	   while(i<(p.length-1) && document.cookie.indexOf(s+'='+s)==-1){
		  currentdomain = p.slice(-1-(++i)).join('.');
		  document.cookie = s+"="+s+";domain="+currentdomain+";";
	   }
	   document.cookie = s+"=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain="+currentdomain+";";
	   return currentdomain;
	}

	function __gaTrackerGetExtension( extension ) {
		extension = extension.substring( 0, (extension.indexOf( "#" ) == -1 ) ? extension.length : extension.indexOf( "#" ) ); /* Remove the anchor at the end, if there is one */
		extension = extension.substring( 0, (extension.indexOf( "?" ) == -1 ) ? extension.length : extension.indexOf( "?" ) ); /* Remove the query after the file name, if there is one */
		extension = extension.substring( extension.lastIndexOf( "/" ) + 1, extension.length ); /* Remove everything before the last slash in the path */
		if ( extension.length > 0 && extension.indexOf('.') !== -1 ) { // If there's a period left in the URL, then there's a extension. Else it is not a extension.
			extension = extension.substring( extension.indexOf( "." ) + 1 ); /* Remove everything but what's after the first period */
			return extension;
		} else {
			return "";
		}
	}

	function __gaTrackerLoaded() {
		return __gaTracker.hasOwnProperty( "loaded" ) && __gaTracker.loaded == true; // jshint ignore:line
	}

	function __gaTrackerTrackedClick( event ) {
		return event.which == 1 || event.which == 2 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
	}

	function __gaTrackerGetDownloadExtensions() {
		var download_extensions = [];
		if ( typeof monsterinsights_frontend.download_extensions == 'string' ) {
			download_extensions = monsterinsights_frontend.download_extensions.split(",");
		}
		return download_extensions;
	}

	function __gaTrackerGetInboundPaths() {
		var inbound_paths = [];
		if ( typeof monsterinsights_frontend.inbound_paths == 'string' ) {
			inbound_paths = monsterinsights_frontend.inbound_paths.split(",");
		}
		return inbound_paths;
	}

	function __gaTrackerTrackedClickType( event ) {
		if ( event.which == 1 ) {
			return 'event.which=1';
		} else if ( event.which == 2 ) {
			return 'event.which=2';
		} else if (  event.metaKey ){
			return 'metaKey';
		} else if (  event.ctrlKey ) {
			return 'ctrlKey';
		} else if ( event.shiftKey ) {
			return 'shiftKey';
		} else if (  event.altKey ) {
			return 'altKey';
		} else {
			return '';
		}
	}

	function __gaTrackerLinkType( el ) {
		var download_extensions = __gaTrackerGetDownloadExtensions();
		var inbound_paths       = __gaTrackerGetInboundPaths();
		var type                = 'unknown';
		var link 				= el.href;
		var extension           = __gaTrackerGetExtension( el.href );
		var currentdomain       = __gaTrackerGetDomain();
		var hostname            = el.hostname;
		var protocol            = el.protocol;
		var pathname       		= el.pathname;
		var index, len;

		if ( link.match( /^javascript\:/i ) ) {
			type = 'internal'; // if it's a JS link, it's internal
		} else if ( __gaTrackerStringTrim( protocol ) == 'tel' || __gaTrackerStringTrim( protocol ) == 'tel:' ) { /* If it's a telephone link */
			type = "tel"; 
		} else if ( __gaTrackerStringTrim( protocol ) == 'mailto' ||  __gaTrackerStringTrim( protocol ) == 'mailto:' ) { /* If it's a email */
			type = "mailto"; 
		} else if ( hostname.length > 0 && currentdomain.length > 0 && ! hostname.endsWith( currentdomain ) ) { /* If it's a outbound */
			type = "external"; 
		} else if ( inbound_paths.length > 0 && pathname.length > 0 ) { /* If it's an internal as outbound */
			for ( index = 0, len = inbound_paths.length; index < len; ++index ) {
				if ( inbound_paths[ index ].length > 0 && pathname.startsWith( inbound_paths[ index ] ) ) {
					type = "internal-as-outbound";
					break;
				}
			}
		/* Enable window.monsterinsights_experimental_mode at your own risk. We might eventually remove it. Also you may/can/will burn through GA quota for your property quickly. */
		} else if ( window.monsterinsights_experimental_mode && hostname.length > 0 && document.domain.length > 0 && hostname !== document.domain ) { /* If it's a cross-hostname link */
			type = "cross-hostname";
		} 

		if ( type === 'unknown' && download_extensions.length > 0 && extension.length > 0 ) { /* If it's a download */
			for ( index = 0, len = download_extensions.length; index < len; ++index ) {
				if ( download_extensions[ index ].length > 0 && ( link.endsWith( download_extensions[ index ] ) || download_extensions[ index ]  == extension ) ) {
					type = "download";
					break;
				}
			}
		} 

		if ( type === 'unknown' ) {
			type = 'internal';
		}
		return type;
	}

	function __gaTrackerLinkTarget( el, event ) {
		/* Is actual target set and not _(self|parent|top)? */
		var target = ( el.target && !el.target.match( /^_(self|parent|top)$/i ) ) ? el.target : false;

		/* Assume a target if Ctrl|shift|meta-click */
		if ( event.ctrlKey || event.shiftKey || event.metaKey || event.which == 2 ) {
			target = "_blank";
		}
		return target;
	}

	function __gaTrackerClickEvent( event ) {
		var el            = event.srcElement || event.target;
		var valuesArray   = [];
		var fieldsArray;

		// Start Values Array
		valuesArray.el         = el;
		valuesArray.ga_loaded  = __gaTrackerLoaded();
		valuesArray.click_type = __gaTrackerTrackedClickType( event );

		/* If GA is blocked or not loaded, or not main|middle|touch click then don't track */
		if ( ! __gaTrackerLoaded() || ! __gaTrackerTrackedClick( event ) ) {
			valuesArray.exit = 'loaded';
			__gaTrackerNotSend( valuesArray );
			return;
		}

		/* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */
		while ( el && (typeof el.tagName == 'undefined' || el.tagName.toLowerCase() != 'a' || ! el.href ) ) {
			el = el.parentNode;
		}

		/* if a link with valid href has been clicked */
		if ( el && el.href ) {
			var link                		= el.href;														/* What link are we tracking */
			var extension           		= __gaTrackerGetExtension( el.href );							/* What extension is this link */
			var download_extensions 		= __gaTrackerGetDownloadExtensions(); 							/* Let's get the extensions to track */
			var inbound_paths       		= __gaTrackerGetInboundPaths(); 								/* Let's get the internal paths to track */
			var home_url            		= monsterinsights_frontend.home_url; 							/* Let's get the url to compare for external/internal use */
			var track_download_as   		= monsterinsights_frontend.track_download_as; 					/* should downloads be tracked as events or pageviews */
			var internal_label      		= "outbound-link-" + monsterinsights_frontend.internal_label; 	/* What is the prefix for internal-as-external links */
			var currentdomain       		= __gaTrackerGetDomain();										/* What domain are we on? */
			var type                		= __gaTrackerLinkType( el ); 									/* What type of link is this? */
			var target 						= __gaTrackerLinkTarget( el, event );							/* Is a new tab/window being opened? */

			/* Element */
			valuesArray.el                  = el;					/* el is an a element so we can parse it */
			valuesArray.el_href             = el.href; 				/* "http://example.com:3000/pathname/?search=test#hash" */
			valuesArray.el_protocol         = el.protocol; 			/* "http:" */
			valuesArray.el_hostname         = el.hostname; 			/* "example.com" */
			valuesArray.el_port             = el.port; 				/* "3000" */
			valuesArray.el_pathname         = el.pathname; 			/* "/pathname/" */
			valuesArray.el_search           = el.search; 			/* "?search=test" */
			valuesArray.el_hash             = el.hash;				/* "#hash" */
			valuesArray.el_host             = el.host; 				/* "example.com:3000" */

			/* Settings */
			valuesArray.debug_mode          = __gaTrackerIsDebug(); /* "example.com:3000" */
			valuesArray.download_extensions = download_extensions;  /* Let's get the extensions to track */
			valuesArray.inbound_paths       = inbound_paths; 		/* Let's get the internal paths to track */
			valuesArray.home_url            = home_url;				/* Let's get the url to compare for external/internal use */
			valuesArray.track_download_as   = track_download_as; 	/* should downloads be tracked as events or pageviews */
			valuesArray.internal_label      = internal_label;		/* What is the prefix for internal-as-external links */

			/* Parsed/Logic */
			valuesArray.link                = link; 				/* What link are we tracking */
			valuesArray.extension           = extension; 			/* What extension is this link */
			valuesArray.type                = type; 				/* What type of link is this */
			valuesArray.target              = target;				/* Is a new tab/window being opened? */
			valuesArray.title 				= el.title || el.textContent || el.innerText; /* Try link title, then text content */

			/* Let's track everything but internals (that aren't internal-as-externals) and javascript */
			if ( type !== 'internal' && type !== 'javascript' ) {

				var __gaTrackerHitBackRun = false; /* Tracker has not yet run */

				/* HitCallback to open link in same window after tracker */
				var __gaTrackerHitBack = function() {
					/* Run the hitback only once */
					if ( __gaTrackerHitBackRun ){
						return;
					}
					__gaTrackerHitBackRun = true;
					window.location.href = link;
				};

				var __gaTrackerNoRedirectExternal = function() {
					valuesArray.exit = 'external';
					__gaTrackerNotSend( valuesArray );
				};

				var __gaTrackerNoRedirectInboundAsExternal = function() {
					valuesArray.exit = 'internal-as-outbound';
					__gaTrackerNotSend( valuesArray );
				};
				
				if ( target || type == 'mailto' || type == 'tel' ) { /* If target opens a new window then just track */
					if ( type == 'download' ) {
						if ( track_download_as == 'pageview' ) {
							fieldsArray = { 
								hitType : 'pageview',
								page    : link,
							};
							
							__gaTrackerSend( valuesArray, fieldsArray );
						} else {
							fieldsArray = {
								hitType       : 'event',
								eventCategory : 'download',
								eventAction   : link,
								eventLabel    : valuesArray.title,
							};

							__gaTrackerSend( valuesArray, fieldsArray );
						}
					} else if ( type == 'tel' ) {
						fieldsArray = {
							hitType       : 'event',
							eventCategory : 'tel',
							eventAction   : link,
							eventLabel    : valuesArray.title.replace('tel:', ''),
						};

						__gaTrackerSend( valuesArray, fieldsArray );
					} else if ( type == 'mailto' ) {
						fieldsArray = {
							hitType       : 'event',
							eventCategory : 'mailto',
							eventAction   : link,
							eventLabel    : valuesArray.title.replace('mailto:', ''),
						};

						__gaTrackerSend( valuesArray, fieldsArray );
					} else if ( type == 'internal-as-outbound' ) {
						fieldsArray = {
							hitType       : 'event',
							eventCategory : internal_label,
							eventAction   : link,
							eventLabel    : valuesArray.title,
						};

						__gaTrackerSend( valuesArray, fieldsArray );
					} else if ( type == 'external' ) {
						fieldsArray = {
							hitType: 'event',
							eventCategory:'outbound-link',
							eventAction: link,
							eventLabel: valuesArray.title,
						};

						__gaTrackerSend( valuesArray, fieldsArray );
					} else if ( type == 'cross-hostname' ) {
						fieldsArray = {
							hitType: 'event',
							eventCategory:'cross-hostname',
							eventAction: link,
							eventLabel: valuesArray.title,
						};

						__gaTrackerSend( valuesArray, fieldsArray );
					} else {
						valuesArray.exit = 'type';
						__gaTrackerNotSend( valuesArray );
					}
				} else { 
					/* Prevent standard click, track then open */
					if ( type != 'cross-hostname' && type != 'external' && type != 'internal-as-outbound' ) {
						if (! event.defaultPrevented ) {
							if ( event.preventDefault ) {
								event.preventDefault();
							} else {
								event.returnValue = false;
							}
						}
					}
					
					if ( type == 'download' ) {
						if ( track_download_as == 'pageview' ) {
							fieldsArray = {
								hitType       : 'pageview',
								page 		  : link,
								hitCallback   : __gaTrackerHitBack,
							};

							__gaTrackerSend( valuesArray, fieldsArray );
						} else {
							fieldsArray = {
								hitType       : 'event',
								eventCategory : 'download',
								eventAction   : link,
								eventLabel    : valuesArray.title,
								hitCallback   : __gaTrackerHitBack,
							};

							__gaTrackerSend( valuesArray, fieldsArray );
						}
					} else if ( type == 'internal-as-outbound' ) {
						window.onbeforeunload = function(e) {
							if (! event.defaultPrevented ) {
								if ( event.preventDefault ) {
									event.preventDefault();
								} else {
									event.returnValue = false;
								}
							}

							fieldsArray = {
								hitType       : 'event',
								eventCategory : internal_label,
								eventAction   : link,
								eventLabel    : valuesArray.title,
								hitCallback   : __gaTrackerHitBack,
							};

							if ( navigator.sendBeacon ) {
								fieldsArray.transport = 'beacon';
							}

							__gaTrackerSend( valuesArray, fieldsArray );
							setTimeout( __gaTrackerHitBack, 1000 );
						};
					} else if ( type == 'external' ) {
						window.onbeforeunload = function(e) {
							if (! event.defaultPrevented ) {
								if ( event.preventDefault ) {
									event.preventDefault();
								} else {
									event.returnValue = false;
								}
							}
							
							fieldsArray = {
								hitType       : 'event',
								eventCategory : 'outbound-link',
								eventAction   : link,
								eventLabel    : valuesArray.title,
								hitCallback   : __gaTrackerHitBack,
							};

							if ( navigator.sendBeacon ) {
								fieldsArray.transport = 'beacon';
							}

							__gaTrackerSend( valuesArray, fieldsArray );
							setTimeout( __gaTrackerHitBack, 1000 );
						};						
					} else if ( type == 'cross-hostname' ) {
						window.onbeforeunload = function(e) {
							if (! event.defaultPrevented ) {
								if ( event.preventDefault ) {
									event.preventDefault();
								} else {
									event.returnValue = false;
								}
							}
							
							fieldsArray = {
								hitType       : 'event',
								eventCategory : 'cross-hostname',
								eventAction   : link,
								eventLabel    : valuesArray.title,
								hitCallback   : __gaTrackerHitBack,
							};

							if ( navigator.sendBeacon ) {
								fieldsArray.transport = 'beacon';
							}

							__gaTrackerSend( valuesArray, fieldsArray );
							setTimeout( __gaTrackerHitBack, 1000 );
						};						
					} else {
						valuesArray.exit = 'type';
						__gaTrackerNotSend( valuesArray );
					}

					if ( type != 'external' && type != 'internal-as-outbound' ) {
						/* Run hitCallback again if GA takes longer than 1 second */
						setTimeout( __gaTrackerHitBack, 1000 );
					} else {
						if ( type == 'external' ) {
							setTimeout( __gaTrackerNoRedirectExternal, 1100 );
						} else {
							setTimeout( __gaTrackerNoRedirectInboundAsExternal, 1100 );
						}
					}
				}
			} else {
				valuesArray.exit = 'internal';
				__gaTrackerNotSend( valuesArray );
			}
		} else {
			valuesArray.exit = 'notlink';
			__gaTrackerNotSend( valuesArray );
		}
	}
	var prevHash = window.location.hash;
	function __gaTrackerHashChangeEvent() {
		// Todo: Ready this section for JS unit testing
		if ( monsterinsights_frontend.hash_tracking === "true" && prevHash != window.location.hash ) {
			prevHash = window.location.hash;
			__gaTracker('set', 'page', location.pathname + location.search + location.hash );
			__gaTracker('send', 'pageview' );
			__gaTrackerLog( "Hash change to: " + location.pathname + location.search + location.hash );
		} else {
			__gaTrackerLog( "Hash change to (untracked): " + location.pathname + location.search + location.hash );
		}
	}

	/* Attach the event to all clicks in the document after page has loaded */
	var __gaTrackerWindow    = window;
	if ( __gaTrackerWindow.addEventListener ) {
		__gaTrackerWindow.addEventListener( 
			"load", 
			function() { 
				document.body.addEventListener(
					"click", 
					__gaTrackerClickEvent,
					 false
				);
			}, 
			false
		);
		window.addEventListener("hashchange", __gaTrackerHashChangeEvent, false	);
	} else { 
		if ( __gaTrackerWindow.attachEvent ) {
			__gaTrackerWindow.attachEvent(
				"onload", 
				function() {
					document.body.attachEvent( "onclick", __gaTrackerClickEvent);
				}
			);
			window.attachEvent( "onhashchange", __gaTrackerHashChangeEvent);
		}
	}

	if (typeof String.prototype.endsWith !== 'function') {
		String.prototype.endsWith = function(suffix) {
			return this.indexOf(suffix, this.length - suffix.length) !== -1;
		};
	}
	if (typeof String.prototype.startsWith !== 'function') {
		String.prototype.startsWith = function(prefix) {
			return this.indexOf(prefix) === 0;
		};
	}

	if ( typeof Array.prototype.lastIndexOf !== 'function' ) {
	  Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) {
		'use strict';

		if (this === void 0 || this === null) {
		  throw new TypeError();
		}

		var n, k,
		  t = Object(this),
		  len = t.length >>> 0; // jshint ignore:line
		if (len === 0) {
		  return -1;
		}

		n = len - 1;
		if (arguments.length > 1) {
		  n = Number(arguments[1]);
		  if (n != n) {
			n = 0;
		  }
		  else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) { // jshint ignore:line
			n = (n > 0 || -1) * Math.floor(Math.abs(n));
		  }
		}

		for (k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k >= 0; k--) {
		  if (k in t && t[k] === searchElement) {
			return k;
		  }
		}
		return -1;
	  };
	}
};
var MonsterInsightsObject = new MonsterInsights();