
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.api = {

	isTokenRefresh: false,
	ajaxRequestStack: new Array(),
	
	setAccessToken: function(accessToken) {
		if(typeof(localStorage) !== "undefined") {	
			window.localStorage.setItem("_n_a_at", accessToken);
		}
	},
		
	getAccessToken: function() {
		if(typeof(localStorage) !== "undefined") {	
			var accessToken = window.localStorage.getItem("_n_a_at");
			if(accessToken != "undefined" && accessToken != null) {
				return accessToken;
			}
		}
		return null;
	},
		
	removeAccessToken: function() {
		if(typeof(localStorage) !== "undefined") {	
			window.localStorage.removeItem("_n_a_at");
		}
	},
		
	setRefreshToken: function(refreshToken) {
		if(typeof(localStorage) !== "undefined") {	
			window.localStorage.setItem("_n_a_rt", refreshToken);
		}
	},
		
	getRefreshToken: function() {
		if(typeof(localStorage) !== "undefined") {	
			var refreshToken = window.localStorage.getItem("_n_a_rt");
			if(refreshToken != "undefined" && refreshToken != null) {
				return refreshToken;
			}
		}
		return null;
	},
		
	removeRefreshToken: function() {
		if(typeof(localStorage) !== "undefined") {	
			window.localStorage.removeItem("_n_a_rt");
		}
	},
	
	request: function(options) {
		var parentBeforeSend = null;
		if (options.beforeSend != undefined && typeof options.beforeSend === "function") {
			parentBeforeSend = options.beforeSend;
		}
		options.beforeSend = function(xhr) {
			if (parentBeforeSend != null && typeof parentBeforeSend === "function") {
	        	parentBeforeSend();
	        }
			if (naviki.util.api.getAccessToken() != null) {
				xhr.setRequestHeader('Authorization', 'Bearer ' + naviki.util.api.getAccessToken());
			}
			if (typeof(naviki.CONSTANTS.LANGUAGE) !== "undefined") {	
				xhr.setRequestHeader('Accept-Language', naviki.CONSTANTS.LANGUAGE);
			}
	    }
		
		var parentError = null;
		if (options.error != undefined && typeof options.error === "function") {
			parentError = options.error;
		}
		options.error = function(jqXHR, textStatus, errorThrown) {
			if (jqXHR != null && jqXHR.status != null && jqXHR.status == 401) {
				naviki.util.api.ajaxRequestStack.push(options);
				if (!naviki.util.api.isTokenRefresh) {
					naviki.util.api.isTokenRefresh = true;
					naviki.util.api.refreshToken();
				}
				return;
			}
			if (parentError != null && typeof parentError === "function") {
				parentError(jqXHR);
	        }
		}
		
		return $.ajax(options);
	},
	
	refreshToken: function() {
		
		var _this = this;
		var params = "?eID=controllerDispatcher&request[format]=json&request[controller]=FeUser&request[action]=refreshToken";	
		params += "&request[arguments][refreshToken]=" + naviki.util.api.getRefreshToken();

		$.ajax({
			url: window.location.pathname + encodeURI(params),
			type: "GET",
			cache: false,
			dataType : "json",
			contentType: 'application/json; charset=utf-8',
		    processData: false,
			success : function(data) {					
				if (data.status && data.accessToken && data.refreshToken) {
					naviki.util.api.setAccessToken(data.accessToken);
					naviki.util.api.setRefreshToken(data.refreshToken);
					naviki.util.user.setUserId(data.feUserId); // could be missing, if last login long ago
					while(naviki.util.api.ajaxRequestStack.length > 0) {
						$.ajax(naviki.util.api.ajaxRequestStack.pop());
					}
					naviki.util.api.ajaxRequestStack = new Array();
					naviki.util.api.isTokenRefresh = false;
				} else {
					naviki.util.api.logoutFeUser();
				}
			},
			error: function(err) {
				naviki.util.api.logoutFeUser();
			}
		});
	},
	
	logoutFeUser: function() {
		naviki.util.api.removeAccessToken();
		naviki.util.api.removeRefreshToken();

		naviki.util.user.removeLoggedIn();
		naviki.util.user.removeUsername();
		naviki.util.user.removeUserId();
		naviki.util.user.setActivated(false);
		naviki.util.user.setUserAverageSpeed(null);
		naviki.util.user.setUserEnergyUnit(null);
		naviki.util.user.setUserWayFilters(null);
		naviki.util.user.setUserWaySort(null);
	}
}
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.binary = {

	prepare : function(binary, length) {
		if (binary.length < length) {
			do {
				binary = "0" + binary;
			} while (binary.length < length);
		}
		return "" + binary;
	},

	getBit : function(binary, pos) {
		binary = naviki.util.prepareBinary("" + binary, pos + 1);
		tmp = binary.split("");
		return tmp[tmp.length - (pos + 1)];
	},

	setBit : function(binary, pos, value) {
		binary = naviki.util.prepareBinary("" + binary, pos + 1);
		tmp = binary.split("");
		tmp[tmp.length - (pos + 1)] = value;
		binary = "";
		for (var i = 0; i < tmp.length; i++) {
			binary += tmp[i];
		}
		return binary;
	}
}
if(typeof naviki == "undefined"){
	var naviki = {}
}

if(typeof naviki.util == "undefined"){
	naviki.util = {}
}

naviki.util.compression = {
		
		// Encodes one-dimensional and two-dimensional arrays.
		//
		// @param array decodedObject
		//
		// e.g. decodedObject = array: ((1,2,3,4),(5,6,7,8),(9,10,11,12),(13,14,15,16))
		//		result = "ACEGGGGGGGGGGGGG"
		//
		//		decodedObject = array: (1,2,3,4)
		//		result = "AAAA"
		//
		encode: function(decodedObject)
		{
		    var encodedString = "";
		    var prevRow;
		    var row;
		    
		    var delta, prevVal = 0;
		    
		    for(var i = 0; i < decodedObject.length; i++)
		    {
		        if($.isArray(decodedObject[i]))
		        {
		            row = decodedObject[i];
		            
		            // If is the first row, than
		            // generate a previous row with 0 values​​.
		            if(i == 0)
		            {
		                prevRow = new Array();
		                for(var k = 0; k < row.length; k++)
		                {
		                    prevRow.push(0);
		                }
		            }
		            
		            for(var j = 0; j < row.length; j++)
		            {
		                // Calculate the delta from the previous value.
		                delta = parseInt(row[j]) - parseInt(prevRow[j]);
		                
		                // Encode the delta value.
		                encodedString = naviki.util.compression.encodeValue(encodedString,delta);
		            }
		            // Hold the current row.
		            prevRow = row;
		        }
		        else
		        {
		            // Calculate the delta from the previous value.
		            delta = parseInt(decodedObject[i]) - parseInt(prevVal);
		            // Hold the current value.
		            prevVal = parseInt(decodedObject[i]);
		            // Encode the delta value.
		            encodedString = naviki.util.compression.encodeValue(encodedString,delta);
		        }
		    }
		    
		    return encodedString;
		},

		encodeValue: function(encodedString,delta)
		{
		    // Left-shift the value one bit.
		    // If the original decimal value is negative, invert this encoding.
		    delta = (delta < 0) ? ~(delta << 1) : (delta << 1);

		    // OR each value with 0x20 if another 5-bit chunk follows.
		    // Add 63 to each value.
		    // Convert each value to its ASCII equivalent.
		    while (delta >= 0x20) {
		    	var val = (0x20 | (delta & 0x1f)) + 63;
		        encodedString += String.fromCharCode(val);
		        delta >>= 5;
		    }
		    encodedString += String.fromCharCode(delta + 63);
		    return encodedString;
		},
		
		// Decodes an encoded string.
		//
		// @param string encodedString The encoded string.
		// @param int columnCount Number of values ​​per row.
		//
		// e.g. encodedString = "ACEGGGGGGGGGGGGG"
		//		columnCount = 4
		//		result = array: ((1,2,3,4),(5,6,7,8),(9,10,11,12),(13,14,15,16))
		//
		//		encodedString = "AAAA"
		//		columnCount = 1
		//		result = array: (1,2,3,4)
		//
		decode: function(encodedString,columnCount)
		{
		    var length = encodedString.length;
		    var idx = 0;
		    
		    var byte;
		    var shift;
		    var delta;
		    var value;
		    var res;
		    
		    var result = new Array();
		    var prevRow;
		    var row;
		    
		    while (idx < length)
		    {
		        // If is the first row, than
		        // generate a previous row with 0 values​​.
		        if(result.length == 0)
		        {
		            prevRow = new Array();
		            for(var i = 0; i < columnCount; i++)
		            {
		                prevRow.push(0);
		            }
		        }
		  
		        row = new Array();
		        for(var i = 0; i < columnCount; i++)
		        {
		            byte  = 0;
		            res   = 0;
		            shift = 0;

		            do {
		                // The statement returns the ASCII code for the character at index.
		                // Subtract 63 to get the original value.
		                // (63 was added to ensure proper ASCII characters are displayed
		                // in the encoded polyline string, which is `human` readable)
		                byte = encodedString.charCodeAt(idx++) - 63;
		                // AND the bits of the byte with 0x1f to get the original 5-bit `chunk.
		                // Then left shift the bits by the required amount, which increases
		                // by 5 bits each time.
		                // OR the value into results, which sums up the individual 5-bit chunks
		                // into the original value.  Since the 5-bit chunks were reversed in
		                // order during encoding, reading them in this way ensures proper
		                // summation.
		                res |= (byte & 0x1F) << shift;
		                shift += 5;
		                // Continue while the read byte is >= 0x20 since the last `chunk`
		                // was not OR'd with 0x20 during the conversion process. (Signals the end)
		            } while (byte >= 0x20);
		     
		            // Check if negative, and convert. (All negative values have the last bit set)
		            delta = (res & 1) ? ~(res >> 1) : (res >> 1);
		            
		            // Summing the delta to the previous value.
		            value = parseInt(prevRow[i]);
		            value += delta;
		            
		            row.push(value);
		        }
		        result.push(row);
		        // Hold the current row.
		        prevRow = row;
		    }

		    // if the column count 1, than return a one-dimensional array.
		    if(columnCount == 1)
		    {
		        var change = new Array();
		        for(var i = 0; i < result.length; i++)
		        {
		            change.push(result[i][0]);
		        }
		        result = change;
		    }

		    return result;
		}
};
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.cookie = {

	read : function(key) {
		var c_value = document.cookie;
		var c_start = c_value.indexOf(" " + key + "=");
		if (c_start == -1) {
			c_start = c_value.indexOf(key + "=");
		}
		if (c_start == -1) {
			c_value = null;
		} else {
			c_start = c_value.indexOf("=", c_start) + 1;
			var c_end = c_value.indexOf(";", c_start);
			if (c_end == -1) {
				c_end = c_value.length;
			}
			c_value = unescape(c_value.substring(c_start, c_end));
		}
		return c_value;
	},

	write : function(key, value) {
		var e = 1000 * 60 * 60 * 24 * 365;
		var a = new Date();
		a = new Date(a.getTime() + e);
		document.cookie = key + '=' + value + ';expires=' + a.toGMTString()
				+ ';path=/';
	},

	remove : function(key) {
		document.cookie = key + '=;expires=Thu, 01-Jan-70 00:00:01 GMT;path=/';
	}
}
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.geo = {

	/**
	 * Calculates the distance between two points.
	 * 
	 * @param p1 Object that contains the geo-coordinates.
	 * @param p2 Object that contains the geo-coordinates.
	 * @return integer The distance in km.
	 */
	calculateDistance : function(p1, p2) {
		var radlat1 = Math.PI * p1.lat / 180;
		var radlat2 = Math.PI * p2.lat / 180;
		var radlon1 = Math.PI * p1.lng / 180;
		var radlon2 = Math.PI * p2.lng / 180;
		var theta = p1.lng - p2.lng;
		var radtheta = Math.PI * theta / 180;
		var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1)
				* Math.cos(radlat2) * Math.cos(radtheta);
		dist = Math.acos(dist);
		dist = dist * 180 / Math.PI;
		dist = dist * 60 * 1.1515;
		dist = dist * 1.609344;

		if (!isNaN(dist)) {
			return dist;
		}

		return 0;
	},

	/**
	 * Calculate the bearing between two positions as a value from 0-360
	 *
	 * @param lat1 - The latitude of the first position
	 * @param lng1 - The longitude of the first position
	 * @param lat2 - The latitude of the second position
	 * @param lng2 - The longitude of the second position
	 *
	 * @return int - The bearing between 0 and 360
	 */
	calculateBearing : function(lat1, lng1, lat2, lng2) {
		var dLon = (lng2 - lng1);
		var y = Math.sin(dLon) * Math.cos(lat2);
		var x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
				* Math.cos(lat2) * Math.cos(dLon);
		var brng = Math.atan2(y, x) * 180 / Math.PI;
		return 360 - ((brng + 360) % 360);
	}
}
if(typeof naviki == "undefined"){
	var naviki = {}
}

if(typeof naviki.util == "undefined"){
	naviki.util = {}
}

naviki.util.googlepolyline = {
		
		/**
		 * Decodes a polyline that was encoded using the Google Maps method.
		 *
		 * The encoding algorithm is detailed here:
		 * http://code.google.com/apis/maps/documentation/polylinealgorithm.html
		 *
		 * This function is based off of Mark McClure's JavaScript polyline decoder
		 * (http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/decode.js)
		 * which was in turn based off Google's own implementation.
		 *
		 * This function assumes a validly encoded polyline.  The behaviour of this
		 * function is not specified when an invalid expression is supplied.
		 *
		 * @param String encoded the encoded polyline.
		 * 
		 * @return Array an Nx2 array with the first element of each entry containing
		 *  the latitude and the second containing the longitude of the
		 *  corresponding point.
		 */
		decode : function(encoded, precision) {

			if (typeof precision == "undefined" || precision == null) {
				precision = 5;
			}
			
			var precisionMultiplier = Math.pow(10, -precision);
			var index = 0, lat = 0, lng = 0, array = [];
			var b, shift, result;
			var dlat,dlng;
			
			while (index < encoded.length) {
				// The encoded polyline consists of a latitude value followed by a
				// longitude value.  They should always come in pairs.  Read the
				// latitude value first.
				shift  = 0;
				result = 0;
				do {
					// The statement returns the ASCII code for the character at index.  
					// Subtract 63 to get the original value.
					// (63 was added to ensure proper ASCII characters are displayed
					// in the encoded polyline string, which is `human` readable)
					b = encoded.charCodeAt(index++) - 63;
					// AND the bits of the byte with 0x1f to get the original 5-bit `chunk.
					// Then left shift the bits by the required amount, which increases
					// by 5 bits each time.
					// OR the value into results, which sums up the individual 5-bit chunks
					// into the original value.  Since the 5-bit chunks were reversed in
					// order during encoding, reading them in this way ensures proper
					// summation.
					result |= (b & 0x1f) << shift;
					shift += 5;
					// Continue while the read byte is >= 0x20 since the last `chunk`
					// was not OR'd with 0x20 during the conversion process. (Signals the end)
				} while (b >= 0x20);
				// Check if negative, and convert. (All negative values have the last bit set)	
				dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
				// Compute actual latitude since value is offset from previous value.
				lat += dlat;
				
				// The next values will correspond to the longitude for this point.
				shift  = 0;
				result = 0;
				do {
					b = encoded.charCodeAt(index++) - 63;
					result |= (b & 0x1f) << shift;
					shift += 5;
				} while (b >= 0x20);
				dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
				lng += dlng;
				
				var latVal = (lat * precisionMultiplier).toFixed(precision);
				var lngVal = (lng * precisionMultiplier).toFixed(precision);
				array.push([latVal, lngVal]);
			}
			
			return array;
		},

		/**
		 * Encodes a polyline that was decoded using the Google Maps method.
		 * (https://developers.google.com/maps/documentation/utilities/polylinealgorithm?hl=de&csw=1)
		 */
		encode : function(points, precision){
			
			precision = Math.pow(10, precision);
			
			var dlat, dlng;
			var latE5,lngE5;
			var nextValue;
			var plat = 0, plng = 0;
			var encodedPoints = "";
			
			for(var i = 0; i < points.length; i++){	
				// Take the decimal value and multiply it by 1e5.
				latE5 =  parseInt(points[i][0] * precision);    
			    // Calculate the delta from the previous value.
			    dlat = latE5 - plat;	    
			    // Hold the current value.
			    plat = latE5;    
			    // Left-shift the value one bit.
			    dlat = dlat << 1;    
			    // If the original decimal value is negative, invert this encoding.
			    if (dlat < 0) {
			    	dlat = ~(dlat);
			    }    
			    // OR each value with 0x20 if another 5-bit chunk follows.
			    // Add 63 to each value.
			    // Convert each value to its ASCII equivalent.
				while (dlat >= 0x20) {
					nextValue = (0x20 | (dlat & 0x1f)) + 63;
					encodedPoints += String.fromCharCode(nextValue);
					dlat >>= 5;
				}
				encodedPoints += String.fromCharCode(dlat + 63);
				
				// The next values will correspond to the longitude for this point.
			    lngE5 = parseInt(points[i][1] * precision);
			    dlng = lngE5 - plng;
			    plng = lngE5;
			    dlng = dlng << 1;
			    
			    if (dlng < 0) {
			    	dlng = ~(dlng);
			    }
			    
			    while (dlng >= 0x20) {
					nextValue = (0x20 | (dlng & 0x1f)) + 63;
					encodedPoints += String.fromCharCode(nextValue);
					dlng >>= 5;
				}
				encodedPoints += String.fromCharCode(dlng + 63);
			}
			return encodedPoints;
		},
		
		mergeTracks : function(geom) {
			if(geom == null) {
				console.log("geom was null!");
				return [];
			}
			
			var points = new Array();
			for (var i = 0; i < geom.length; i++) {
				const pointList = naviki.util.googlepolyline.decode(geom[i], 5);
				for (var counter = 0; counter < pointList.length; counter++) {
					points.push([parseFloat(pointList[counter][0]), parseFloat(pointList[counter][1])]);
				}
			}
			return points;
		},
		
		reverseTrack: function(geom) {
			if(geom == null) {
				console.log("geom was null!");
				return;
			}
			const mergedTracks = naviki.util.googlepolyline.mergeTracks(geom);	
			return mergedTracks.reverse();
		},
		
		/**
		 * 
		 * @param encoded
		 * @param max
		 * @returns string encoded the encoded polyline
		 */
		reduceToMaxPoints : function(encoded, max){		
			var points = naviki.util.googlepolyline.decode(encoded, 5);
			if(points.length > max){
				var newArray = new Array();
				var m = parseInt((points.length / max) + 1);
				
				for(var i = 0; i < points.length; i++){
					if(parseInt((i % m)) == 0){
						newArray.push(points[i]);
					}
				}
				return naviki.util.googlepolyline.encode(newArray, 5);
			}
			return encoded;
		},
		
		
		turnDirection: function(encoded){
			var points = naviki.util.googlepolyline.decode(encoded, 5);
			var newArray = new Array();
			for(var i = (points.length - 1); i >= 0; i--){
				newArray.push(points[i]);
			}
			return naviki.util.googlepolyline.encode(newArray, 5);
		}
};
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.html = {

	/**
	 * The normal bring to top function does not work correctly 
	 * because of the nui- classes. So i must implement ower own.
	 * @returns {Number}
	 */
	bringToTop : function() {
		var aDivs = new Array();
		// get all div elements.
		aDivs = document.getElementsByTagName("div");
		if (aDivs.length == 0) {
			return 10;
		}
		var maxIndex = -9999;
		var count = aDivs.length;
		for (var i = 1; i < count; i++) {
			var div = aDivs[i];
			var sZIndex = Ext.get(div).getStyle("zIndex");
			var nZIndex = (!sZIndex || isNaN(sZIndex)) ? 0 : parseInt(sZIndex,
					10);
			if (nZIndex > maxIndex) {
				maxIndex = nZIndex;
			}
		}
		return maxIndex;
	},

	/**
	 * Strip HTML and PHP tags from a string.
	 * @param str
	 * @returns
	 */
	stripTags : function(str) {
		str = str.toString();
		return str.replace(/<\/?[^>]+>/gi, '');
	},

	/**
	 * Rreplace P tag with Br tag.
	 * @param str
	 * @returns
	 */
	replaceParagraphWithBreak : function(str) {
		str = str.toString();
		str = str.replace(/<p[^>]*?>/gi, "");
		return str.replace("</p>", "<br />");
	},

	/**
	 * Substring not in HTLM tags.
	 * @param str
	 * @param len
	 * @returns
	 */
	substr : function(str, len) {
		var temp = str.substr(0, len);
		if (temp.lastIndexOf('<') > temp.lastIndexOf('>')) {
			temp = str.substr(0, 1 + str.indexOf('>', temp.lastIndexOf('<')));
		}
		return temp;
	}
}
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.number = {

	/**
	 * Formats a number into a string, also the "." to a ",".
	 */
	formatNumber: function(number) {
		return number.toString().replace(/\./, ","); 
	},

	/**
	 * Rounds a value with <digits> of numbers after the point ,
	 * attention: Safari doesn't support "Number.toLocaleString".
	 */
	round: function(number, digits) {
		var factor = Math.pow(10, digits);
		number = (Math.round(number*factor)) / factor;
		try {
			var roundedNumber = Number(number).toLocaleString(naviki.CONSTANTS.LOCALE_ALL.replace("_","-"), { maximumFractionDigits: digits });
			if (!isNaN(roundedNumber)) {
				return roundedNumber;
			}
		} catch (e) {
			console.log("Can not format number: " + number);
		}
		return number;
	}
};
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.second = {

	toDate : function(timevalue) {
		var mydate = new Date();
		mydate.setTime(timevalue * 1000);
		var month = mydate.getMonth() + 1;
		if (month < 10) {
			month = "0" + month;
		}
		var day = mydate.getDate();
		if (day < 10) {
			day = "0" + day;
		}
		return day + "." + month + "." + mydate.getFullYear();
	},

	toDateAndTime : function(timevalue) {
		var mydate = new Date();
		mydate.setTime(timevalue * 1000);
		var month = mydate.getMonth() + 1;
		if (month < 10) {
			month = "0" + month;
		}
		var day = mydate.getDate();
		if (day < 10) {
			day = "0" + day;
		}
		var minutes = mydate.getMinutes();
		if (minutes < 10) {
			minutes = "0" + minutes;
		}
		var hours = mydate.getHours();
		if (hours < 10) {
			hours = "0" + hours;
		}
		return day + "." + month + "." + mydate.getFullYear() + ", " + hours
				+ ":" + minutes;
	},

	toTime : function(seconds) {
		var hours = Math.floor(seconds / (60 * 60));
		seconds -= hours * (60 * 60);
		var minutes = Math.floor(seconds / 60);
		if (minutes < 10) {
			minutes = "0" + minutes;
		}
		return hours + ":" + minutes;
	}
}
if(typeof naviki == "undefined"){
	var naviki = {}
}

if(typeof naviki.util == "undefined"){
	naviki.util = {}
}

naviki.util.solr = function(config) {
	this.config = config;
	this.initialize();
};

naviki.util.solr.prototype.initialize = function(){
	this.url = this.config.url;
	this.mainCore = this.config.mainCore;
	this.sharedCore = null;
	if(typeof this.config.sharedCore != "undefined" && this.config.sharedCore != null && this.config.sharedCore.length > 0){
		this.sharedCore = this.config.sharedCore;
	}
};

naviki.util.solr.prototype.getSearchURL = function(){
	this.config.url = naviki.util.url.replaceProtocol(this.config.url);
	return this.config.url + "/solr/" + this.mainCore + "/select";
};

naviki.util.solr.prototype.getReverseSearchURL = function(){
	this.config.url = naviki.util.url.replaceProtocol(this.config.url);
	return this.config.url + "/solr/" + this.mainCore + "/reverse";
};

naviki.util.solr.prototype.getJsonCallback = function(){
	return "json.wrf";
};

naviki.util.solr.prototype.getSearchRequestData = function(query,language,point){
	var result = {
			"q" : query,
			"qt" : "default",
			"language" : language
	};
	if (point != null) {
		result.pt = point.lat + "," + point.lng;
	}
	if(this.sharedCore != null){
		result.collection = this.sharedCore + "," + this.mainCore;
	}
	return result;
};

naviki.util.solr.prototype.getReverseSearchRequestData = function(latitude,longitude,language){
	var pt = latitude + "," + longitude;
	var result = {
			"q": "*:*",
			"fq": "{!geofilt}",
			"pt": pt,
			"d": "5",
			"format" : "json",
			"language" : language,
			"onlyAddress" : true,
			"rows": 1
		};
	if(this.sharedCore != null){
		result.collection = this.mainCore + "," + this.sharedCore;
	}
	return result;
};

naviki.util.solr.prototype.formatSearchResponse = function(response){
	var _self = this;
	var docs = response.response;
	if(response.response.docs){
		docs = response.response.docs;
	}
	var jsonResult = $.map(docs, function(jsonItem) {
		var item = _self.formatResponseItem(jsonItem);
		if(item != null){
			return item;	
		}
	});
	return jsonResult;
};

naviki.util.solr.prototype.formatReverseSearchResponse = function(response){
	var docs = response.response;
	if(response.response.docs){
		docs = response.response.docs;
	}
	if(docs.length == 0){
		return null;
	};
	return this.formatResponseItem(docs[0]);
};

naviki.util.solr.prototype.formatResponseItem = function(item){
		
	var coordinate = item.coordinate.split(",");
	
	var point = {
		lat : coordinate[0],
		lon : coordinate[1],
		icon : null,
		label: item.label,
		subLabel : item.subLabel
	};

	return point;
};

if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.url = {

	/**
	 * This method converts a query string to a object.
	 * e.g. 
	 * source -> ?id=10&type=20
	 * target -> {id: 10,type: 20}
	 * 
	 * @param query
	 * @returns {Object}
	 */
	decodeParams : function(query) {

		if (query.indexOf("?") == 0) {
			query = query.substr(1);
		}

		if (query.indexOf("#") == 0) {
			query = query.substr(1);
		}

		var params = {};
		var pairs = query.split('&');
		for (var i = 0; i < pairs.length; i++) {

			var pair = pairs[i].split('=');

			var accessors = [];
			var name = decodeURIComponent(pair[0]), value = decodeURIComponent(pair[1]);

			if (name.length == 0) {
				continue;
			}

			var name = name.replace(/\[([^\]]*)\]/g, function(k, acc) {
				accessors.push(acc);
				return "";
			});
			accessors.unshift(name);

			var obj = null;
			for (var j = accessors.length - 1; j >= 0; j--) {
				var acc = accessors[j];
				if (obj == null) {
					obj = {};
					obj[acc] = value;
				} else {
					var tmp = {};
					tmp[acc] = obj;
					obj = $.extend({}, tmp);
				}
			}
			params = (jQuery).extend(true, {}, params, obj);
		}

		return params;
	},

	/**
	 * This method converts a object to a query string.
	 * e.g.
	 * source -> {id: 10,type: 20}
	 * target -> ?id=10&type=20
	 * 
	 * @param params
	 * @returns
	 */
	encodeParams : function(params) {

		function encodeItem(params, key) {

			var query = "";

			if (typeof params == "object") {

				for (k in params) {

					if (query.length > 0) {
						query += "&";
					}

					query += encodeItem(params[k], key + "[" + k + "]");
				}
			} else {

				query += key + "=" + params;
			}

			return query;
		}
		;

		var query = "";
		var isFirst = true;

		for (key in params) {

			if (query.length > 0) {
				query += "&";
			}

			query += encodeItem(params[key], key);
		}

		return query;
	},

	/**
	 * This method replaces the protocol from a URL.
	 * 
	 * @param url
	 * @returns {String}
	 */
	replaceProtocol : function(url) {

		var result;
		var protocol = window.location.protocol;

		if (url.search(protocol) == -1) {

			var parts = url.split("//");
			var path = parts[parts.length - 1];

			// If the protocol is http, then cut out the port.
			if (protocol == "http:" && path.search(/:/) > 0) {
				parts = path.split(":");
				result = protocol + "//" + parts[0];
				parts = path.split("/");
				for (var i = 1; i < parts.length; i++) {
					result += "/" + parts[i];
				}
			} else {
				result = protocol + "//" + path;
			}
		} else {
			result = url;
		}

		return result;
	},

	/**
	 * This method replaces a value in the url query.
	 * @param keyToReplace
	 * @param value
	 * @returns {String}
	 */
	replaceParam : function(keyToReplace, value) {

		var url = window.location.protocol + "//" + window.location.host
				+ window.location.pathname;
		var params = naviki.util.url.decodeParams(window.location.search);

		params[keyToReplace] = value;

		var query = naviki.util.url.encodeParams(params);
		if (query.length > 0) {
			url += "?" + query + window.location.hash;
		} else {
			url += window.location.hash;
		}

		return url;
	},

	/**
	 * This method removes a key from the url query.
	 * @param keyToRemove
	 * @returns {String}
	 */
	removeParam : function(keyToRemove) {

		var url = window.location.protocol + "//" + window.location.host
				+ window.location.pathname;
		var params = naviki.util.url.decodeParams(window.location.search);

		if (keyToRemove in params) {
			delete params[keyToRemove];
		}

		var query = naviki.util.url.encodeParams(params);
		if (query.length > 0) {
			url += "?" + query + window.location.hash;
		} else {
			url += window.location.hash;
		}

		return url;
	},
	
	/**
	 * This method removes keys from the url query.
	 * @param keyToRemove
	 * @returns {String}
	 */
	removeParams : function(keysToRemove) {

		var url = window.location.protocol + "//" + window.location.host
				+ window.location.pathname;
		var params = naviki.util.url.decodeParams(window.location.search);

		for (var key in params) {
			if(keysToRemove.indexOf(key) != -1) {  
				delete params[key];
			}		
		}

		var query = naviki.util.url.encodeParams(params);
		if (query.length > 0) {
			url += "?" + query + window.location.hash;
		} else {
			url += window.location.hash;
		}

		return url;
	},	

	/**
	 * This method gives back a value from the url query.
	 * @param key
	 * @returns
	 */
	extractValue : function(key) {
		var params = window.location.search, value = "";

		if (params.indexOf(key) < 0) {
			return null;
		}

		value = params.substring(params.indexOf(key), params.length);
		value = value.substring(key.length + 1,
				(value.indexOf("&") > -1) ? value.indexOf("&") : value.length);
		return value;
	},

	/**
	 * This method adds a slash to the end when it is missing.
	 * @param url
	 * @returns the formated url
	 */
	addSlash : function(url) {
		var pos = url.indexOf("/");
		if (pos != 0) {
			url = "/" + url;
		}
		return url;
	},
	
	/**
	 * This method gives back the domain from the url.
	 * @param url
	 * @returns
	 */
	extractDomain: function(url) {
	    var domain = url.replace(/(https?:\/\/)?(www.)?/i, '');
	    domain = domain.split('.');
	    domain = domain.slice(domain.length - 2).join('.');
	    if (domain.indexOf('/') !== -1) {
	        return domain.split('/')[0];
	    }
	    return domain;
	}
}
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.localeformatter = {

	FACTOR_KCAL_KJ: 4.1868,

	ENERGY_UNIT_KCAL: 10,
	ENERGY_UNIT_KJ: 20,

	getConvertedEnergy: function(energyInKilocalories) {
		var userEnergyUnit = naviki.util.user.getUserEnergyUnit();
		if (userEnergyUnit && userEnergyUnit == this.ENERGY_UNIT_KJ) {
			return "" + Math.round(energyInKilocalories * this.FACTOR_KCAL_KJ) + " " + naviki.Lang.getLL("pi_userprofile.energy.kilojoule");
		}
		return "" + Math.round(energyInKilocalories) + " " + naviki.Lang.getLL("pi_userprofile.energy.kilocalories");
	},

}
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.user = {
		
	isLoggedIn: function() {
		if(typeof(localStorage) !== "undefined") {	
			var userState = window.localStorage.getItem("_n_u_s");
			if(userState != "undefined" && userState != null) {
				return userState == "in" ? true : false;
			}
		}
		return false;
	},
	
	setLoggedIn: function(status) {
		if(typeof(localStorage) !== "undefined") {	
			// saving of booleans causes problems
			window.localStorage.setItem("_n_u_s", status ? "in" : "out");
		}
	},
	
	removeLoggedIn: function() {
		if(typeof(localStorage) !== "undefined") {	
			window.localStorage.removeItem("_n_u_s");
		}
	},
	
	setUsername: function(username) {
		if(typeof(localStorage) !== "undefined") {	
			window.localStorage.setItem("_n_u_n", username);
		}
	},
	
	getUsername: function() {
		if(typeof(localStorage) !== "undefined") {	
			var username = window.localStorage.getItem("_n_u_n");
			if(username != "undefined" && username != null) {
				return username;
			}
		}
		return null;
	},
	
	removeUsername: function() {
		if(typeof(localStorage) !== "undefined") {	
			window.localStorage.removeItem("_n_u_n");
		}
	},

	setUserId: function(userId) {
		if(typeof(localStorage) !== "undefined") {
			window.localStorage.setItem("_n_u_id", userId);
		}
	},

	getUserId: function() {
		if(typeof(localStorage) !== "undefined") {
			var userId = window.localStorage.getItem("_n_u_id");
			if(userId != "undefined" && userId != null) {
				return userId;
			}
		}
		return null;
	},

	removeUserId: function() {
		if(typeof(localStorage) !== "undefined") {
			window.localStorage.removeItem("_n_u_id");
		}
	},
	
	isActivated: function() {
		if(typeof(localStorage) !== "undefined") {	
			var userState = window.localStorage.getItem("_n_u_act");
			if(userState != "undefined" && userState != null) {
				return userState == "y" ? true : false;
			}
		}
		return false;
	},
	
	setActivated: function(status) {
		if(typeof(localStorage) !== "undefined") {	
			// saving of booleans causes problems
			window.localStorage.setItem("_n_u_act", status ? "y" : "n");
		}
	},
	
	getUserAverageSpeed: function() {
		if (typeof(localStorage) !== "undefined") {	
			var avgSpeed = window.localStorage.getItem("_n_u_asp");
			if (avgSpeed != "undefined" && avgSpeed != null) {
				return avgSpeed;
			}
		}
		return 15;
	},
	
	setUserAverageSpeed: function(avgSpeed) {
		if (typeof(localStorage) !== "undefined") {
			window.localStorage.setItem("_n_u_asp", avgSpeed);
		}
	},

	getUserEnergyUnit: function() {
		if (typeof(localStorage) !== "undefined") {
			var energyUnit = window.localStorage.getItem("_n_u_ueu");
			if (energyUnit != "undefined" && energyUnit != null) {
				return energyUnit;
			}
		}
		return null;
	},

	setUserEnergyUnit: function(energyUnit) {
		if (typeof(localStorage) !== "undefined") {
			window.localStorage.setItem("_n_u_ueu", energyUnit);
		}
	},

	getUserWayFilters: function() {
		if (typeof(localStorage) !== "undefined") {
			var wayFilters = window.localStorage.getItem("_n_u_way_filters");
			if (wayFilters != "undefined" && wayFilters != null) {
				return JSON.parse(wayFilters);
			}
		}
		return null;
	},

	setUserWayFilters: function(wayFilters) {
		if (typeof(localStorage) !== "undefined") {
			window.localStorage.setItem("_n_u_way_filters", wayFilters != null ? JSON.stringify(wayFilters) : null);
		}
	},

	getUserWaySort: function() {
		if (typeof(localStorage) !== "undefined") {
			var waySort = window.localStorage.getItem("_n_u_way_sort");
			if (waySort != "undefined" && waySort != null) {
				return waySort;
			}
		}
		return null;
	},

	setUserWaySort: function(waySort) {
		if (typeof(localStorage) !== "undefined") {
			window.localStorage.setItem("_n_u_way_sort", waySort);
		}
	},
}
if (typeof naviki == "undefined") {
	var naviki = {}
}

if (typeof naviki.util == "undefined") {
	naviki.util = {}
}

naviki.util.pixel = {
	
		// distance from a point to a segment between two points
		pointToSegmentDistance:  function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
			return Math.sqrt(this._sqClosestPointOnSegment(p, p1, p2, true));
		},
		
		closestPointOnSegment: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
			return this._sqClosestPointOnSegment(p, p1, p2);
		},
		
		// return closest point on segment or distance to that point
		_sqClosestPointOnSegment: function (p, p1, p2, sqDist) {
			var x = p1.x,
				y = p1.y,
				dx = p2.x - x,
				dy = p2.y - y,
				dot = dx * dx + dy * dy,
				t;

			if (dot > 0) {
				t = ((p.x - x) * dx + (p.y - y) * dy) / dot;

				if (t > 1) {
					x = p2.x;
					y = p2.y;
				} else if (t > 0) {
					x += dx * t;
					y += dy * t;
				}
			}

			dx = p.x - x;
			dy = p.y - y;

			return sqDist ? dx * dx + dy * dy : {x:x, y:y};
		},
		
		// square distance (to avoid unnecessary Math.sqrt calls)
		dist: function (p1, p2) {
			var xs = p2.x - p1.x,
				ys = p2.y - p1.y;		
		
			xs *= xs;
			ys *= ys;
		 
			return Math.sqrt( xs + ys );
		},
}
/*
 *  jQuery Boilerplate - v3.3.1
 *  A jump-start for jQuery plugins development.
 *  http://jqueryboilerplate.com
 *
 *  Made by Zeno Rocha
 *  Under MIT License
 */
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function($, window, document, undefined) {

	var pluginName = "History";
	
	function Plugin(settings){
		
		var defaults = {
			popstate: null
		};
		
		if (settings){
			$.extend(this, defaults, settings);
		} else {
			$.extend(this, defaults);
		}
		
		this.enable = false;
		this.init();
	}
	
	Plugin.prototype = {
		
		init : function(){
			
			var _self = this;
			
			/*
	         * Note, this is the only difference when using this library,
	         * because the object window.location cannot be overriden,
	         * so library the returns generated "location" object within
	         * an object window.history, so get it out of "history.location".
	         * For browsers supporting "history.pushState" get generated
	         * object "location" with the usual "window.location".
	         */
	        var location = window.history.location || window.location;
	        
	        $(window).on('popstate', function(e) {
	        	try {
		        	if (typeof _self.popstate == "function") {
	        			_self.popstate(history.state);
	        		}
	        	} catch (e) {
	        		console.log(e);
	        	}
	       });
		},
	
		replaceState: function(state, title, url) {
			try {
				if (typeof history != "undefined") {
					if (state == null) {
						state = this.getState();
					}
					history.replaceState(state, title, url);
				}
			} catch (e) {
				console.log(e);
			}
		},
		
		pushState: function(state, title, url) {
			try {
				if (typeof history != "undefined") {
					history.pushState(state, title, url);
				}
			} catch (e) {
				console.log(e);
			}
		},
		
		updateURL: function(url) {
			try {
				if (typeof history != "undefined") {
					history.replaceState(this.getState(), "", url);
				}
			} catch (e) {
				console.log(e);
			}
		},
		
		getState: function() {
			try {
				if(typeof history != "undefined") {
					return history.state;
				}
			} catch (e) {
				console.log(e);
			}
			return null;
			
		},
		
		back: function() {
			try {
				if(typeof history != "undefined") {
					history.back();
				}
			} catch (e) {
				console.log(e);
			}
		}
	}
		
	$.fn[pluginName] = function(options) {
		return new Plugin(options);
	}

})(jQuery, window, document);
/**
 * Call function if user clicked on naviki logo.
 * Changes the window location to the start of the landingpage.
 * 
 */
;(function($) {
	$.fn.navikiLogo = function(landingpageTitle) {
		var hrefParts = window.location.href.split('/');
		if (hrefParts[3].length == 2) {
			// we have a language parameter
			window.location.href = hrefParts[0]+"//"+hrefParts[2]+"/"+hrefParts[3]+"/"+landingpageTitle+"/";
		} else {
			window.location.href = hrefParts[0]+"//"+hrefParts[2]+"/"+landingpageTitle+"/";
		}
	};
})( jQuery);
/*
 *  jQuery Boilerplate - v3.3.1
 *  A jump-start for jQuery plugins development.
 *  http://jqueryboilerplate.com
 *
 *  Made by Zeno Rocha
 *  Under MIT License
 */
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, document, undefined ) {

		// undefined is used here as the undefined global variable in ECMAScript 3 is
		// mutable (ie. it can be changed by someone else). undefined isn't really being
		// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
		// can no longer be modified.

		// dialog and document are passed through as local variable rather than global
		// as this (slightly) quickens the resolution process and can be more efficiently
		// minified (especially when both are regularly referenced in your plugin).

		// Create the defaults once
		var pluginName = "navikiUiDialog";
		var defaults = {
				id: "naviki-ui-dialog",
				close: true,
				content: "",
				footer: "",
				buttons: null,
				className: null,
				closeCallback: null,
				openCallback: null
		};

		// The actual plugin constructor
		function Plugin (options ) {

				// jQuery has an extend method which merges the contents of two or
				// more objects, storing the result in the first object. The first object
				// is generally empty as we don't want to alter the default options for
				// future instances of the plugin
				this.options = $.extend( {}, defaults, options );
				this._defaults = defaults;
				this._name = pluginName;
				
				this.element = null;
				this.init();
		}

		Plugin.prototype = {
				
				init: function () {
					// Place initialization logic here
					// You already have access to the DOM element and
					// the options via the instance, e.g. this.element
					// and this.options
					// you can add more functions like the one below and
					// call them like so: this.yourOtherFunction(this.element, this.options).		
					var _self = this;
					
					if ($("#" + this.options.id).length == 0) {

						this.element = $("<div/>",{id:this.options.id,"class":"naviki-ui-dialog-wrapper"});
						$('body').append(this.element);
						
						var dialog = $("<div/>",{"class":"naviki-ui-dialog"});
						this.element.append(dialog);
						
						var container = $("<div/>",{"class":"dialog-container"});
						dialog.append(container);
						
						container.append($("<div/>",{"class":"header"}));
						container.append($("<div/>",{"class":"content"}));
						container.append($("<div/>",{"class":"buttons"}));
						container.append($("<div/>",{"class":"footer"}));
						
						$(document).keyup(function (e) {
				            if (e.keyCode == 27) {
				            	_self.close();
				            }
				        });	
						
						if (this.options.className != null) {
							this.element.addClass(this.options.className);
						}
					} else {
						this.element = $("#" + this.options.id);
					}
				
					this.element.find('.header').first().empty();
					this.element.find('.buttons').first().empty();
					this.element.find('.content').first().html(this.options.content);
					this.element.find('.footer').first().html(this.options.footer);			
					
					if (this.options.footer.length == 0) {
						this.element.find('.footer').first().css("display","none");
					} else {
						this.element.find('.footer').first().css("display","");
					}
					
					if (this.options.close) {
						this.element.find('.header').first().append($("<span/>",{"class":"icon-close"}));
						this.element.find('.icon-close').first().click(function(){
							_self.close();
						});
					}
					
					if (this.options.buttons != null && $.isArray(this.options.buttons) && this.options.buttons.length > 0) {

						for (var i = 0; i < this.options.buttons.length; i++) {
							(function(button){
								btn = $("<button/>",{type:"button","class":"btn btn-default"});
								btn.text(button.text);
								btn.click(button.callback);
								_self.element.find('.buttons').first().append(btn);
							})(this.options.buttons[i]);
						}
					}
					
					$( window ).resize(function() {
						_self.resize();
					});
				},
				
				open: function() {
					this.element.addClass('visible');
					this.resize();
					if (typeof this.options.openCallback == "function") {
						this.options.openCallback();
					}
				},
			    
			    close: function() {
					this.element.removeClass('visible');
					if (typeof this.options.closeCallback == "function") {
						this.options.closeCallback();
					}
			    },
			    
			    resize: function() {
			    	var content = this.element.find('.content').first();					
					content.css("height","");
					var height = content.first().outerHeight();
					var windowHeight = $(window).outerHeight() * 0.9;
					if (height > windowHeight) {
						content.css("height",windowHeight);
					}
			    }
		
		};

		$.fn[pluginName] = function(options) {
			return new Plugin(options);
		}

})( jQuery, window, document );
/*
 *  jQuery Boilerplate - v3.3.1
 *  A jump-start for jQuery plugins development.
 *  http://jqueryboilerplate.com
 *
 *  Made by Zeno Rocha
 *  Under MIT License
 */
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, document, undefined ) {

		// undefined is used here as the undefined global variable in ECMAScript 3 is
		// mutable (ie. it can be changed by someone else). undefined isn't really being
		// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
		// can no longer be modified.

		// window and document are passed through as local variable rather than global
		// as this (slightly) quickens the resolution process and can be more efficiently
		// minified (especially when both are regularly referenced in your plugin).

		// Create the defaults once
		var pluginName = "navikiUiLoading";
		var defaults = {
				id : null,
				zindex: null
		};

		// The actual plugin constructor
		function Plugin ( element, options ) {
				
				this.calcualte = function(){				
					$("#loader-overlay-" + this.options.id).css({
						opacity : 0.15,
						top : $(this.element).position().top,
						left: $(this.element).position().left,
						width : $(this.element).outerWidth(),
						height: $(this.element).outerHeight()
					});
					$("#loader-img-" + this.options.id).css({
						top : ($(this.element).height() / 2 - 9),
						left: ($(this.element).width() / 2 - 9)
					});
				};
				
				var uniqID = {
					counter:0,
					get:function(prefix) {
						if(!prefix) {
							prefix = "uniqid";
						}
						var id =  prefix+""+uniqID.counter++;
						if (jQuery("#"+id).length == 0) {
							return id;
						} else {
							return uniqID.get()
						}
					}
				}

				this.element = element;
				// jQuery has an extend method which merges the contents of two or
				// more objects, storing the result in the first object. The first object
				// is generally empty as we don't want to alter the default options for
				// future instances of the plugin
				this.options = $.extend( {}, defaults, options );
				this.options.id = uniqID.get();
				this._defaults = defaults;
				this._name = pluginName;
				this.init();
		}

		Plugin.prototype = {
				init: function () {
					// Place initialization logic here
					// You already have access to the DOM element and
					// the options via the instance, e.g. this.element
					// and this.options
					// you can add more functions like the one below and
					// call them like so: this.yourOtherFunction(this.element, this.options).		
					//this.options.id = $(this.element).uniqueId().attr( "id" );
					var _self = this;
					var node = "<div id='loader-overlay-" + this.options.id + "' class='naviki-ui-loader-overlay'";
					if(this.options.zindex != null) {
						node += " style='z-index:" + this.options.zindex + ";'";
					}
					node += ">" +
					"<img class='naviki-ui-loader-img' src='typo3conf/ext/naviki/Resources/Public/Img/ajax-loader-2.gif' id='loader-img-" + this.options.id + "' />" +
					"</div>";		
					$(this.element).append(node);
					$(window).resize(function() {
						_self.calcualte();
					});
				},
				hide : function(args) {
					$("#loader-overlay-" + this.options.id).fadeOut(0);
				},
				show : function(args) {
					this.calcualte();
					$("#loader-overlay-" + this.options.id).fadeIn(0);
				}
		};

		// A really lightweight plugin wrapper around the constructor, 
		// preventing against multiple instantiations and allowing any
		// public function (ie. a function whose name doesn't start
		// with an underscore) to be called via the jQuery plugin,
		// e.g. $(element).defaultPluginName('functionName', arg1, arg2)
		$.fn[ pluginName ] = function ( options ) {
			var args = arguments;
			if (options === undefined || typeof options === 'object') {
				return this.each(function () {
		            if (!$.data(this, 'plugin_' + pluginName)) {
		                $.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
		            }
		        });
		    } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
		        return this.each(function () {
		            var instance = $.data(this, 'plugin_' + pluginName);
		            if (instance instanceof Plugin && typeof instance[options] === 'function') {
		                instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
		            }
		        });
		    }
		};

})( jQuery, window, document );
/* jQuery Boilerplate - v3.3.1 */
;(function ( $, window, document, undefined ) {

		var pluginName = "navikiUiUserActivationHint";
		var defaults = {
				oauth2MicroServiceHostname: ""
		};

		function Plugin (options) {
				this.options = $.extend( {}, defaults, options );
				this._defaults = defaults;
				this._name = pluginName;
				
				this.element = null;
				this.init();
		}

		Plugin.prototype = {
				init: function () {
					if (naviki.util.user.isLoggedIn() && !naviki.util.user.isActivated()) {
						this._requestActivationStatus();
					}
				},
				
				_showUserActivationHintBar: function(email) {
					var _this = this;

					var hintText = naviki.Lang.getLL('base.deactivatedAccountHint');
					hintText = hintText.replace("{0}", email);

					var linkUrl = this.options.oauth2MicroServiceHostname + "/reactivateUser";
					if (naviki.util.user.getUsername() != null)
						linkUrl += "?emailPlaceholder=" + naviki.util.user.getUsername();

					var content = "<div class='cookie-choice-info warning'><div>";
					content += "<span>" + hintText + "</span>";
					content += "<a href='" + linkUrl + "' id='user-activation-resend-button'>" + naviki.Lang.getLL('base.deactivatedAccountResendButton') + "</a>";
					content += "<a href='" + naviki.CONSTANTS.LANGUAGE + "/naviki/intern/my-naviki-profile-and-settings/'>" + naviki.Lang.getLL('base.deactivatedAccountChangeEmailButton') + "</a>";
					content += "</div></div>";
						
					if ($('#fixedHeader').length > 0) {
						$('#fixedHeader').prepend(content);
					} else {
						$('body').prepend(content);
					}

					$("#user-activation-resend-button").click(function(event) {
						event.preventDefault();
						var url = $(this).attr("href");
						_this._openDialog(url);	
					});	
				},
		 		
		 		_requestActivationStatus: function() {
					var _this = this;
					$.ajax({
						url: this.options.oauth2MicroServiceHostname + "/api/user/activatedAccount",
						type: "POST",
						cache: false,
						dataType : "json",
						contentType: 'application/json; charset=utf-8',
					    processData: false,
					    beforeSend: function(xhr) {
							if (naviki.util.api.getAccessToken() != null) {
								xhr.setRequestHeader('Authorization', 'Bearer ' + naviki.util.api.getAccessToken());
							}
					    },
						success: function(data) {
							if (typeof data.valid !== 'undefined') {
								if (data.valid) {
									naviki.util.user.setActivated(true);
								} else {
									_this._showUserActivationHintBar(data.email);
								}
							}
						},
						error: function (request, status, error) {
							console.log("Error in jquery.naviki.ui.useractivationhint.js: " + error);
		                }
					});
				},
				
				_openDialog: function(url) {	
					this.dialog = $.colorbox({
						width: 320, 
						height: 480, 
						scrolling: false,
						iframe: true, 
						href: url
					});
				}
		};

		$.fn[pluginName] = function(options) {
			return new Plugin(options);
		}
})( jQuery, window, document );
/*
 *  jQuery Boilerplate - v3.3.1
 *  A jump-start for jQuery plugins development.
 *  http://jqueryboilerplate.com
 *
 *  Made by Zeno Rocha
 *  Under MIT License
 */
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, document, undefined ) {

		// undefined is used here as the undefined global variable in ECMAScript 3 is
		// mutable (ie. it can be changed by someone else). undefined isn't really being
		// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
		// can no longer be modified.

		// dialog and document are passed through as local variable rather than global
		// as this (slightly) quickens the resolution process and can be more efficiently
		// minified (especially when both are regularly referenced in your plugin).

		// Create the defaults once
		var pluginName = "navikiUiCookieChoices";
		var defaults = {
				cookieName: "displayCookieConsent",
			    cookieConsentId: "cookieChoiceInfo",
			    dismissLinkId: "cookieChoiceDismiss",
				cookieText: "Please note this website uses cookies enabling us to give you the best user experience.",
				dismissText: "OK",
				linkText: "Learn more",
				linkHref: "http://www.example.net/p/cookies.html"
		};

		// The actual plugin constructor
		function Plugin (options ) {

				// jQuery has an extend method which merges the contents of two or
				// more objects, storing the result in the first object. The first object
				// is generally empty as we don't want to alter the default options for
				// future instances of the plugin
				this.options = $.extend( {}, defaults, options );
				this._defaults = defaults;
				this._name = pluginName;
				
				this.element = null;
				this.init();
		}

		Plugin.prototype = {
				
				init: function () {
					if (this._shouldDisplayConsent()) {
						this._showCookieConsentBar();
					}
				},
				
				_showCookieConsentBar: function() {
					var content = "<div class='cookie-choice-info' id='"+this.options.cookieConsentId+"'>";
					content += "<div>"
					content += "<span>"+this.options.cookieText+"</span>";
					content += "<a id='"+this.options.dismissLinkId+"'>"+this.options.dismissText+"</a>";
					content += "<a href='"+this.options.linkHref+"' target='_blank'>"+this.options.linkText+"</a>";		
					content += "</div></div>";
						
					if ($('#fixedHeader').length > 0) {
						$('#fixedHeader').prepend(content);
					} else {
						$('body').prepend(content);
					}
					
					var _self = this;
					$("#"+this.options.dismissLinkId).click(function(){
						_self._saveUserPreference();
						_self._removeCookieConsent();
					});
				},
				
		 		_removeCookieConsent: function() {
		 			var cookieChoiceElement = document.getElementById(this.options.cookieConsentId);
		 			if (cookieChoiceElement != null) {
		 				cookieChoiceElement.parentNode.removeChild(cookieChoiceElement);
		 				$(document).trigger("cookieChoiceRemoved");
		 			}
		 		},

		 		_saveUserPreference: function() {
		 			localStorage.setItem(this.options.cookieName, 'y');
		 		},

		 		_shouldDisplayConsent: function() {
		 			const cookieValue = Cookies.get(this.options.cookieName);
		 			if (typeof cookieValue !== 'undefined' && cookieValue == 'y') {
		 				// move state from cookie to local storage
		 				this._saveUserPreference();
		 				Cookies.remove(this.options.cookieName, { path: '/' });
		 				return false;
		 			}

		 			const localStorageValue = localStorage.getItem(this.options.cookieName);
		 			return (typeof localStorageValue === null || localStorageValue != 'y');
		 		}
		};

		$.fn[pluginName] = function(options) {
			return new Plugin(options);
		}

})( jQuery, window, document );
/*
 *  jQuery Boilerplate - v3.3.1
 *  A jump-start for jQuery plugins development.
 *  http://jqueryboilerplate.com
 *
 *  Made by Zeno Rocha
 *  Under MIT License
 */
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;
(function($, window, document, undefined) {

	// undefined is used here as the undefined global variable in ECMAScript 3 is
	// mutable (ie. it can be changed by someone else). undefined isn't really being
	// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
	// can no longer be modified.

	// window and document are passed through as local variable rather than global
	// as this (slightly) quickens the resolution process and can be more efficiently
	// minified (especially when both are regularly referenced in your plugin).

	// Create the defaults once
	var pluginName = "navikiUserAuth";
	var defaults = {};

	// The actual plugin constructor
	function Plugin(element, options) {

		this.element = element;
		// jQuery has an extend method which merges the contents of two or
		// more objects, storing the result in the first object. The first object
		// is generally empty as we don't want to alter the default options for
		// future instances of the plugin
		this.options = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName;
		
		this.history = new $.fn.History();
		this.dialog = null;
		this.dialogWidth = 320;
		this.dialogHeight = 480;
		
		this.init();
	}

	Plugin.prototype = {

		init : function() {
			// Place initialization logic here
			// You already have access to the DOM element and
			// the options via the instance, e.g. this.element
			// and this.options
			// you can add more functions like the one below and
			// call them like so: this.yourOtherFunction(this.element, this.options).		
			var _this = this;	
			
			// remove unused item
			if(typeof(localStorage) !== "undefined") {	
				window.localStorage.removeItem("_n_um");
				window.localStorage.removeItem("_n_un");
				window.localStorage.removeItem("_n_us");
			}
			
			if (window.location != window.parent.location) { 
				// THE PAGE IS OPENED INSIDE A IFRAME
				// event listener for cross origin communication,
				window.addEventListener("message", function(event) {
					
					// Do we trust the sender of this message?
				    var domain = naviki.util.url.extractDomain(event.origin);
				    if (domain !== "localhost:18080" &&
				        domain !== "naviki.org") {
				        return;
				    }
					
					if (event.data.get == "search") {
						event.source.postMessage({search:window.location.search},  event.origin);
					}
				}, false);	
			} else {
				// THE PAGE IS OPENED INSIDE A BROWSER TAB
				// event listener for cross origin communication,
				window.addEventListener("message", function(event) {
					
					// Do we trust the sender of this message?
				    var domain = naviki.util.url.extractDomain(event.origin);
				    if (domain !== "localhost:18080" &&
				        domain !== "naviki.org") {
				        return;
				    }	
					
					if (_this.dialog != null) {
						if (event.data.height) {
							//enough height for g-recaptcha
							const newHeight = event.data.height < 522 ? 522 : event.data.height;
							_this.dialog.colorbox.resize({
								innerWidth: _this.dialogWidth,
								innerHeight: newHeight
							});
						}
						if (event.data.search) {
							var query = naviki.util.url.decodeParams(decodeURI(event.data.search.substring(1)));
							_this.initLogin(query);
							setTimeout(function(){
								_this.dialog.colorbox.close();
								_this.dialog.colorbox.remove();
							}, 3000);
						}
					}
				}, false);			

				// open the login/register page inside a iframe
				$("#header-register-container a").first().click(function(event) {
					event.preventDefault();
					var url = $(this).attr("href");
					_this.openLoginDialog(url);	
				});	
				$("#header-login-container a").first().click(function(event) {
					event.preventDefault();
					var url = $(this).attr("href");
					_this.openLoginDialog(url);				
				});	

				// catch url query parameters as object
				var query = naviki.util.url.decodeParams(decodeURI(window.location.search.substring(1)));	
				this.initLogin(query);
			}
		},
		
		initLogin: function(query) {
			if (query.login != undefined) {
				// catch typo3 sociallogin
				this.login(null);
				// remove GET params
				var url = naviki.util.url.removeParam("login");
				this.history.replaceState(null,null,url);
			} else if (query.code) {
				// catch java oauth2
				this.login(query.code);
				// remove GET params
				var url = naviki.util.url.removeParams(new Array("code","state"));
				this.history.replaceState(null,null,url);
			} else if(naviki.util.user.isLoggedIn() && naviki.util.user.getUsername() != null) {
				this.showMenuBtn();
			} else {
				this.showLoginBtn();
			}
		},
		
		login: function(code) {
			var _this = this;
			var params = "?eID=controllerDispatcher&request[format]=json&request[controller]=FeUser&request[action]=feSession";	
			params += "&request[arguments][code]=" + code;

			$.ajax({
				url: window.location.pathname + encodeURI(params),
				type: "GET",
				cache: false,
				dataType : "json",
				contentType: 'application/json; charset=utf-8',
			    processData: false,
				success : function(data) {				
					naviki.util.user.setLoggedIn(data.status);		
					if (data.status) {	
						naviki.util.api.setAccessToken(data.accessToken);
						naviki.util.api.setRefreshToken(data.refreshToken);
						naviki.util.user.setUsername(data.username);
						naviki.util.user.setUserId(data.feUserId);
						_this.showMenuBtn();
					} else {
						_this.showLoginBtn();
					}
					$(window).trigger("naviki_loginSuccess");

					// when user has successfully changed password, it comes to redirect page and this point
					// user is logged in now and tokens are set
					// in this case, wer must manually redirect to naviki start page
					if (window.location.pathname.indexOf("/naviki/single-pages/loading/mobile.html") != -1) {
						document.location.replace(location.origin);
					}
				},
				beforeSend: function() {
					_this.clear();
				},
				complete: function() {
				},
				error: function(err) {
					_this.showLoginBtn();
				}
			});
		},
		
		showLoginBtn: function() {
			this.clear();
			var _this = this;
			$("#header-dropdown-container").fadeOut("slow",function(){
				$("#header-login-container").fadeIn("slow");
				$("#header-register-container").fadeIn("slow");
			});
		},
		
		showMenuBtn: function(loadItems) {
			$("#header-register-container").fadeOut("slow");
			
			$("#header-login-container").fadeOut("slow",function() {
				$("#header-username").text(naviki.util.user.getUsername());
				$("#header-dropdown-container").fadeIn( "slow" );
			});
			
			var _this = this;
			$("#header-dropdown-btn").one("click",function(){
				_this.loadMenu();
			});
		},
		
		loadMenu: function() {
			
			var _this = this;	
			var params = "?eID=controllerDispatcher&request[format]=json&request[controller]=FeUser&request[action]=feMenu";
			
			$.ajax({
				url: window.location.pathname + encodeURI(params),
				type: "GET",
				cache: false,
				dataType : "json",
				contentType: 'application/json; charset=utf-8',
			    processData: false,
				success : function(data) {
					if (data.status) {						
						$("#header-dropdown-menu").html(data.menuItems);
						$("#header-dropdown-container ul li:last-child").one("click", function(){
							// logout was clicked
							_this.clear();
						});
					} else {					
						_this.showLoginBtn();
					}
				},
				beforeSend: function() {
					$("#header-caret").css("visibility", "hidden");
					$("#header-loading").addClass("spinning-wheel");
					$("#header-dropdown-menu").css("border-width","0");
					
				},
				complete: function() {
					$("#header-caret").css("visibility", "");
					$("#header-loading").removeClass("spinning-wheel");
					$("#header-dropdown-menu").css("border-width","1px");
				},
				error: function(jqXHR, textStatus, errorThrown) {
					// do not logout if server was too busy
					if (jqXHR != null && jqXHR.status != null && jqXHR.status == 504)
						return;
					_this.showLoginBtn();
				}
			});
		},
		
		clear: function() {
			naviki.util.api.logoutFeUser();
		},
		
		openLoginDialog: function(url) {	
			this.dialog = $.colorbox({
				width: this.dialogWidth, 
				height: this.dialogHeight, 
				scrolling: false,
				iframe: true, 
				href: url,
				onComplete : function() {
					// avoid opaque title bar
					$('#colorbox').css("background", "#ffffff");
					
					var frame = $('#colorbox iframe').get(0);
					$(frame).load(function(e) {
						frame.contentWindow.postMessage({get:"height"}, "*");
						frame.contentWindow.postMessage({get:"search"}, "*");
					});
				} 
			});
		}
	};
	
	// A really lightweight plugin wrapper around the constructor, 
	// preventing against multiple instantiations and allowing any
	// public function (ie. a function whose name doesn't start
	// with an underscore) to be called via the jQuery plugin,
	// e.g. $(element).defaultPluginName('functionName', arg1, arg2)
	$.fn[pluginName] = function(options) {
		var args = arguments;
		if (options === undefined || typeof options === 'object') {
			return this.each(function() {
				if (!$.data(this, 'plugin_' + pluginName)) {
					$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
				}
			});
		} else if (typeof options === 'string' && options[0] !== '_'
				&& options !== 'init') {
			return this.each(function() {
				var instance = $.data(this, 'plugin_' + pluginName);
				if (instance instanceof Plugin && typeof instance[options] === 'function') {
					instance[options].apply(instance, Array.prototype.slice .call(args, 1));
				}
			});
		}
	};

})(jQuery, window, document);

/*!
	Colorbox 1.6.4
	license: MIT
	http://www.jacklmoore.com/colorbox
*/
(function(t,e,i){function n(i,n,o){var r=e.createElement(i);return n&&(r.id=Z+n),o&&(r.style.cssText=o),t(r)}function o(){return i.innerHeight?i.innerHeight:t(i).height()}function r(e,i){i!==Object(i)&&(i={}),this.cache={},this.el=e,this.value=function(e){var n;return void 0===this.cache[e]&&(n=t(this.el).attr("data-cbox-"+e),void 0!==n?this.cache[e]=n:void 0!==i[e]?this.cache[e]=i[e]:void 0!==X[e]&&(this.cache[e]=X[e])),this.cache[e]},this.get=function(e){var i=this.value(e);return t.isFunction(i)?i.call(this.el,this):i}}function h(t){var e=W.length,i=(A+t)%e;return 0>i?e+i:i}function a(t,e){return Math.round((/%/.test(t)?("x"===e?E.width():o())/100:1)*parseInt(t,10))}function s(t,e){return t.get("photo")||t.get("photoRegex").test(e)}function l(t,e){return t.get("retinaUrl")&&i.devicePixelRatio>1?e.replace(t.get("photoRegex"),t.get("retinaSuffix")):e}function d(t){"contains"in x[0]&&!x[0].contains(t.target)&&t.target!==v[0]&&(t.stopPropagation(),x.focus())}function c(t){c.str!==t&&(x.add(v).removeClass(c.str).addClass(t),c.str=t)}function g(e){A=0,e&&e!==!1&&"nofollow"!==e?(W=t("."+te).filter(function(){var i=t.data(this,Y),n=new r(this,i);return n.get("rel")===e}),A=W.index(_.el),-1===A&&(W=W.add(_.el),A=W.length-1)):W=t(_.el)}function u(i){t(e).trigger(i),ae.triggerHandler(i)}function f(i){var o;if(!G){if(o=t(i).data(Y),_=new r(i,o),g(_.get("rel")),!U){U=$=!0,c(_.get("className")),x.css({visibility:"hidden",display:"block",opacity:""}),I=n(se,"LoadedContent","width:0; height:0; overflow:hidden; visibility:hidden"),b.css({width:"",height:""}).append(I),j=T.height()+k.height()+b.outerHeight(!0)-b.height(),D=C.width()+H.width()+b.outerWidth(!0)-b.width(),N=I.outerHeight(!0),z=I.outerWidth(!0);var h=a(_.get("initialWidth"),"x"),s=a(_.get("initialHeight"),"y"),l=_.get("maxWidth"),f=_.get("maxHeight");_.w=Math.max((l!==!1?Math.min(h,a(l,"x")):h)-z-D,0),_.h=Math.max((f!==!1?Math.min(s,a(f,"y")):s)-N-j,0),I.css({width:"",height:_.h}),J.position(),u(ee),_.get("onOpen"),O.add(F).hide(),x.focus(),_.get("trapFocus")&&e.addEventListener&&(e.addEventListener("focus",d,!0),ae.one(re,function(){e.removeEventListener("focus",d,!0)})),_.get("returnFocus")&&ae.one(re,function(){t(_.el).focus()})}var p=parseFloat(_.get("opacity"));v.css({opacity:p===p?p:"",cursor:_.get("overlayClose")?"pointer":"",visibility:"visible"}).show(),_.get("closeButton")?B.html(_.get("close")).appendTo(b):B.appendTo("<div/>"),w()}}function p(){x||(V=!1,E=t(i),x=n(se).attr({id:Y,"class":t.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),v=n(se,"Overlay").hide(),L=t([n(se,"LoadingOverlay")[0],n(se,"LoadingGraphic")[0]]),y=n(se,"Wrapper"),b=n(se,"Content").append(F=n(se,"Title"),R=n(se,"Current"),P=t('<button type="button"/>').attr({id:Z+"Previous"}),K=t('<button type="button"/>').attr({id:Z+"Next"}),S=t('<button type="button"/>').attr({id:Z+"Slideshow"}),L),B=t('<button type="button"/>').attr({id:Z+"Close"}),y.append(n(se).append(n(se,"TopLeft"),T=n(se,"TopCenter"),n(se,"TopRight")),n(se,!1,"clear:left").append(C=n(se,"MiddleLeft"),b,H=n(se,"MiddleRight")),n(se,!1,"clear:left").append(n(se,"BottomLeft"),k=n(se,"BottomCenter"),n(se,"BottomRight"))).find("div div").css({"float":"left"}),M=n(se,!1,"position:absolute; width:9999px; visibility:hidden; display:none; max-width:none;"),O=K.add(P).add(R).add(S)),e.body&&!x.parent().length&&t(e.body).append(v,x.append(y,M))}function m(){function i(t){t.which>1||t.shiftKey||t.altKey||t.metaKey||t.ctrlKey||(t.preventDefault(),f(this))}return x?(V||(V=!0,K.click(function(){J.next()}),P.click(function(){J.prev()}),B.click(function(){J.close()}),v.click(function(){_.get("overlayClose")&&J.close()}),t(e).bind("keydown."+Z,function(t){var e=t.keyCode;U&&_.get("escKey")&&27===e&&(t.preventDefault(),J.close()),U&&_.get("arrowKey")&&W[1]&&!t.altKey&&(37===e?(t.preventDefault(),P.click()):39===e&&(t.preventDefault(),K.click()))}),t.isFunction(t.fn.on)?t(e).on("click."+Z,"."+te,i):t("."+te).live("click."+Z,i)),!0):!1}function w(){var e,o,r,h=J.prep,d=++le;if($=!0,q=!1,u(he),u(ie),_.get("onLoad"),_.h=_.get("height")?a(_.get("height"),"y")-N-j:_.get("innerHeight")&&a(_.get("innerHeight"),"y"),_.w=_.get("width")?a(_.get("width"),"x")-z-D:_.get("innerWidth")&&a(_.get("innerWidth"),"x"),_.mw=_.w,_.mh=_.h,_.get("maxWidth")&&(_.mw=a(_.get("maxWidth"),"x")-z-D,_.mw=_.w&&_.w<_.mw?_.w:_.mw),_.get("maxHeight")&&(_.mh=a(_.get("maxHeight"),"y")-N-j,_.mh=_.h&&_.h<_.mh?_.h:_.mh),e=_.get("href"),Q=setTimeout(function(){L.show()},100),_.get("inline")){var c=t(e).eq(0);r=t("<div>").hide().insertBefore(c),ae.one(he,function(){r.replaceWith(c)}),h(c)}else _.get("iframe")?h(" "):_.get("html")?h(_.get("html")):s(_,e)?(e=l(_,e),q=_.get("createImg"),t(q).addClass(Z+"Photo").bind("error."+Z,function(){h(n(se,"Error").html(_.get("imgError")))}).one("load",function(){d===le&&setTimeout(function(){var e;_.get("retinaImage")&&i.devicePixelRatio>1&&(q.height=q.height/i.devicePixelRatio,q.width=q.width/i.devicePixelRatio),_.get("scalePhotos")&&(o=function(){q.height-=q.height*e,q.width-=q.width*e},_.mw&&q.width>_.mw&&(e=(q.width-_.mw)/q.width,o()),_.mh&&q.height>_.mh&&(e=(q.height-_.mh)/q.height,o())),_.h&&(q.style.marginTop=Math.max(_.mh-q.height,0)/2+"px"),W[1]&&(_.get("loop")||W[A+1])&&(q.style.cursor="pointer",t(q).bind("click."+Z,function(){J.next()})),q.style.width=q.width+"px",q.style.height=q.height+"px",h(q)},1)}),q.src=e):e&&M.load(e,_.get("data"),function(e,i){d===le&&h("error"===i?n(se,"Error").html(_.get("xhrError")):t(this).contents())})}var v,x,y,b,T,C,H,k,W,E,I,M,L,F,R,S,K,P,B,O,_,j,D,N,z,A,q,U,$,G,Q,J,V,X={html:!1,photo:!1,iframe:!1,inline:!1,transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,opacity:.9,preloading:!0,className:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0,fastIframe:!0,open:!1,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp|jxr|svg)((#|\?).*)?$/i,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",returnFocus:!0,trapFocus:!0,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,rel:function(){return this.rel},href:function(){return t(this).attr("href")},title:function(){return this.title},createImg:function(){var e=new Image,i=t(this).data("cbox-img-attrs");return"object"==typeof i&&t.each(i,function(t,i){e[t]=i}),e},createIframe:function(){var i=e.createElement("iframe"),n=t(this).data("cbox-iframe-attrs");return"object"==typeof n&&t.each(n,function(t,e){i[t]=e}),"frameBorder"in i&&(i.frameBorder=0),"allowTransparency"in i&&(i.allowTransparency="true"),i.name=(new Date).getTime(),i.allowFullscreen=!0,i}},Y="colorbox",Z="cbox",te=Z+"Element",ee=Z+"_open",ie=Z+"_load",ne=Z+"_complete",oe=Z+"_cleanup",re=Z+"_closed",he=Z+"_purge",ae=t("<a/>"),se="div",le=0,de={},ce=function(){function t(){clearTimeout(h)}function e(){(_.get("loop")||W[A+1])&&(t(),h=setTimeout(J.next,_.get("slideshowSpeed")))}function i(){S.html(_.get("slideshowStop")).unbind(s).one(s,n),ae.bind(ne,e).bind(ie,t),x.removeClass(a+"off").addClass(a+"on")}function n(){t(),ae.unbind(ne,e).unbind(ie,t),S.html(_.get("slideshowStart")).unbind(s).one(s,function(){J.next(),i()}),x.removeClass(a+"on").addClass(a+"off")}function o(){r=!1,S.hide(),t(),ae.unbind(ne,e).unbind(ie,t),x.removeClass(a+"off "+a+"on")}var r,h,a=Z+"Slideshow_",s="click."+Z;return function(){r?_.get("slideshow")||(ae.unbind(oe,o),o()):_.get("slideshow")&&W[1]&&(r=!0,ae.one(oe,o),_.get("slideshowAuto")?i():n(),S.show())}}();t[Y]||(t(p),J=t.fn[Y]=t[Y]=function(e,i){var n,o=this;return e=e||{},t.isFunction(o)&&(o=t("<a/>"),e.open=!0),o[0]?(p(),m()&&(i&&(e.onComplete=i),o.each(function(){var i=t.data(this,Y)||{};t.data(this,Y,t.extend(i,e))}).addClass(te),n=new r(o[0],e),n.get("open")&&f(o[0])),o):o},J.position=function(e,i){function n(){T[0].style.width=k[0].style.width=b[0].style.width=parseInt(x[0].style.width,10)-D+"px",b[0].style.height=C[0].style.height=H[0].style.height=parseInt(x[0].style.height,10)-j+"px"}var r,h,s,l=0,d=0,c=x.offset();if(E.unbind("resize."+Z),x.css({top:-9e4,left:-9e4}),h=E.scrollTop(),s=E.scrollLeft(),_.get("fixed")?(c.top-=h,c.left-=s,x.css({position:"fixed"})):(l=h,d=s,x.css({position:"absolute"})),d+=_.get("right")!==!1?Math.max(E.width()-_.w-z-D-a(_.get("right"),"x"),0):_.get("left")!==!1?a(_.get("left"),"x"):Math.round(Math.max(E.width()-_.w-z-D,0)/2),l+=_.get("bottom")!==!1?Math.max(o()-_.h-N-j-a(_.get("bottom"),"y"),0):_.get("top")!==!1?a(_.get("top"),"y"):Math.round(Math.max(o()-_.h-N-j,0)/2),x.css({top:c.top,left:c.left,visibility:"visible"}),y[0].style.width=y[0].style.height="9999px",r={width:_.w+z+D,height:_.h+N+j,top:l,left:d},e){var g=0;t.each(r,function(t){return r[t]!==de[t]?(g=e,void 0):void 0}),e=g}de=r,e||x.css(r),x.dequeue().animate(r,{duration:e||0,complete:function(){n(),$=!1,y[0].style.width=_.w+z+D+"px",y[0].style.height=_.h+N+j+"px",_.get("reposition")&&setTimeout(function(){E.bind("resize."+Z,J.position)},1),t.isFunction(i)&&i()},step:n})},J.resize=function(t){var e;U&&(t=t||{},t.width&&(_.w=a(t.width,"x")-z-D),t.innerWidth&&(_.w=a(t.innerWidth,"x")),I.css({width:_.w}),t.height&&(_.h=a(t.height,"y")-N-j),t.innerHeight&&(_.h=a(t.innerHeight,"y")),t.innerHeight||t.height||(e=I.scrollTop(),I.css({height:"auto"}),_.h=I.height()),I.css({height:_.h}),e&&I.scrollTop(e),J.position("none"===_.get("transition")?0:_.get("speed")))},J.prep=function(i){function o(){return _.w=_.w||I.width(),_.w=_.mw&&_.mw<_.w?_.mw:_.w,_.w}function a(){return _.h=_.h||I.height(),_.h=_.mh&&_.mh<_.h?_.mh:_.h,_.h}if(U){var d,g="none"===_.get("transition")?0:_.get("speed");I.remove(),I=n(se,"LoadedContent").append(i),I.hide().appendTo(M.show()).css({width:o(),overflow:_.get("scrolling")?"auto":"hidden"}).css({height:a()}).prependTo(b),M.hide(),t(q).css({"float":"none"}),c(_.get("className")),d=function(){function i(){t.support.opacity===!1&&x[0].style.removeAttribute("filter")}var n,o,a=W.length;U&&(o=function(){clearTimeout(Q),L.hide(),u(ne),_.get("onComplete")},F.html(_.get("title")).show(),I.show(),a>1?("string"==typeof _.get("current")&&R.html(_.get("current").replace("{current}",A+1).replace("{total}",a)).show(),K[_.get("loop")||a-1>A?"show":"hide"]().html(_.get("next")),P[_.get("loop")||A?"show":"hide"]().html(_.get("previous")),ce(),_.get("preloading")&&t.each([h(-1),h(1)],function(){var i,n=W[this],o=new r(n,t.data(n,Y)),h=o.get("href");h&&s(o,h)&&(h=l(o,h),i=e.createElement("img"),i.src=h)})):O.hide(),_.get("iframe")?(n=_.get("createIframe"),_.get("scrolling")||(n.scrolling="no"),t(n).attr({src:_.get("href"),"class":Z+"Iframe"}).one("load",o).appendTo(I),ae.one(he,function(){n.src="//about:blank"}),_.get("fastIframe")&&t(n).trigger("load")):o(),"fade"===_.get("transition")?x.fadeTo(g,1,i):i())},"fade"===_.get("transition")?x.fadeTo(g,0,function(){J.position(0,d)}):J.position(g,d)}},J.next=function(){!$&&W[1]&&(_.get("loop")||W[A+1])&&(A=h(1),f(W[A]))},J.prev=function(){!$&&W[1]&&(_.get("loop")||A)&&(A=h(-1),f(W[A]))},J.close=function(){U&&!G&&(G=!0,U=!1,u(oe),_.get("onCleanup"),E.unbind("."+Z),v.fadeTo(_.get("fadeOut")||0,0),x.stop().fadeTo(_.get("fadeOut")||0,0,function(){x.hide(),v.hide(),u(he),I.remove(),setTimeout(function(){G=!1,u(re),_.get("onClosed")},1)}))},J.remove=function(){x&&(x.stop(),t[Y].close(),x.stop(!1,!0).remove(),v.remove(),G=!1,x=null,t("."+te).removeData(Y).removeClass(te),t(e).unbind("click."+Z).unbind("keydown."+Z))},J.element=function(){return t(_.el)},J.settings=X)})(jQuery,document,window);
if(typeof naviki == "undefined" || !naviki){	var naviki = {};};naviki.Lang = {	local_lang:{"NavikiException.1000.msg":"Routing server HTTP exception","NavikiException.1001.msg":"Enter a target to submit a routing request","NavikiException.1002.msg":"Routing temporarily not available","NavikiException.3000.msg":"Consider correct spelling. Enter address as follows: Street, Town, Country","NavikiException.5012.msg":"This route is already available on your Naviki app, see 'My routes'","NavikiException.5013.msg":"This route is already available on your Naviki app, see 'My routes'","NavikiException.5017.msg":"Your app version is outdated. Please load update.","NavikiException.5100.msg":"The GPS file {0} is too large. Maximum size is 5 MB.","NavikiException.5101.msg":"Naviki handles GPX, KML, KMZ and TCX files.","NavikiException.5102.msg":"An error occurred processing {0}. Please try again.","NavikiException.5104.msg":"Your file {0} does not contain a route.","NavikiException.5200":"That's impossible. This team doesn't exist.","NavikiException.5201.msg":"This contest is already finished.","NavikiException.5204.msg":"Team modification is not possible any more.","NavikiException.5205.msg":"Sorry, that's impossible","NavikiException.5206.msg":"This is not possible since you haven't joined the contest yet","NavikiException.5207.msg":"The membership is already clarified","NavikiException.5208.msg":"This is not possible since you already joined a team","NavikiException.5209.msg":"Sorry, that's impossible since this team doesn't exist","NavikiException.5210.msg":"This team is already complete","NavikiException.5211.msg":"The coupon code is not available for this contest","NavikiException.5212.msg":"Sorry, that's impossible since this team doesn't exist","NavikiException.5213.msg":"Can not add the route to the contest, because useAllWays is activated","NavikiException.5214.msg":"Sorry, that's impossible since this participant exited the contest","NavikiException.5215.msg":"Sorry, that's impossible since the participant is not connected to the team","NavikiException.5219.msg":"This team name already exists. Insert a different name.","NavikiException.5300.msg":"This coupon code is not valid. Please correct your input.","NavikiException.5301.msg":"This code has been used so often, that it is not valid any longer.","NavikiException.5302.msg":"Sorry, this coupon code is not yet or no longer available.","SelectPointsOfInterestAccommodation":"Accommodation","SelectPointsOfInterestActivitiesAndExperiences":"Activity / Experience","SelectPointsOfInterestAdministration":"Administration","SelectPointsOfInterestAircraft":"Aircraft","SelectPointsOfInterestApartment":"Apartment / B&B","SelectPointsOfInterestBeachesSwimmingAndAnglingLakes":"Beach / Swimming / Angling lake","SelectPointsOfInterestBedAndBike":"Bed + Bike","SelectPointsOfInterestBedAndBreakfast":"Bed & Breakfast","SelectPointsOfInterestBicycleRental":"Bicycle rental","SelectPointsOfInterestBicycleService":"Bicycle service","SelectPointsOfInterestBicycleTube":"Bicycle tube automat","SelectPointsOfInterestBiergarten":"Beer garden","SelectPointsOfInterestBikeFriend":"Bike Friends","SelectPointsOfInterestBooksMagazines":"Books / Magazines","SelectPointsOfInterestBuildingsAndMonuments":"Building / Monument","SelectPointsOfInterestBus":"Bus","SelectPointsOfInterestBusiness":"Business","SelectPointsOfInterestCableCar":"Cable car","SelectPointsOfInterestCafe":"Café","SelectPointsOfInterestCampSite":"Camp site","SelectPointsOfInterestCamping":"Camping","SelectPointsOfInterestCarRental":"Car rental","SelectPointsOfInterestChargingStation":"Charging Station","SelectPointsOfInterestClothing":"Clothes","SelectPointsOfInterestCompressedAir":"Compressed air","SelectPointsOfInterestCraft":"Craft","SelectPointsOfInterestCulture":"Culture","SelectPointsOfInterestCultureHobby":"Culture / Hobby","SelectPointsOfInterestDoItYourself":"Do-it-yourself","SelectPointsOfInterestDrinkingWater":"Drinking water","SelectPointsOfInterestEducation":"Education","SelectPointsOfInterestElectronics":"Electronics","SelectPointsOfInterestEmergency":"Emergency","SelectPointsOfInterestEntertainment":"Entertainment","SelectPointsOfInterestFastFood":"Fast food","SelectPointsOfInterestFerryRoutes":"Ferry route","SelectPointsOfInterestFinance":"Finances","SelectPointsOfInterestFoodDrink":"Food / Drink","SelectPointsOfInterestForChildren":"For children","SelectPointsOfInterestFunGames":"Fun / Games","SelectPointsOfInterestGarageStore":"Garage / Shop","SelectPointsOfInterestGasStation":"Gas station","SelectPointsOfInterestGrocery":"Grocery","SelectPointsOfInterestGuestHouse":"Guest house / B&B","SelectPointsOfInterestHealth":"Health","SelectPointsOfInterestHealthBeauty":"Health / Beauty","SelectPointsOfInterestHolidayHouseAgencies":"Holiday house agency","SelectPointsOfInterestHolidayResort":"Holiday resort","SelectPointsOfInterestHostel":"Hostel","SelectPointsOfInterestHotel":"Hotel","SelectPointsOfInterestHut":"Hut","SelectPointsOfInterestIceCream":"Ice cream parlour","SelectPointsOfInterestInstitution":"Institution","SelectPointsOfInterestInteriorFurniture":"Interior / Furniture","SelectPointsOfInterestLeisureRecreation":"Recreation","SelectPointsOfInterestLocalSpecialities":"Local specialities","SelectPointsOfInterestMallSupermarket":"Supermarket","SelectPointsOfInterestMoreInfos":"Read more ...","SelectPointsOfInterestMuseumsGalleriesAndCrafts":"Museum / Gallery / Craft","SelectPointsOfInterestNaturalAreasParksAndGardens":"Natural area / Park / Garden","SelectPointsOfInterestNatureCamp":"Nature camp","SelectPointsOfInterestNatureLandscape":"Nature / Landscape","SelectPointsOfInterestOrganisation":"Organisation","SelectPointsOfInterestParking":"Parking facility","SelectPointsOfInterestPicnicSite":"Picnic site","SelectPointsOfInterestPlaygroundsAndOutdoorFitness":"Playground / Outdoor fitness","SelectPointsOfInterestPolice":"Police","SelectPointsOfInterestPostalService":"Postal service","SelectPointsOfInterestPubBar":"Pub / Bar","SelectPointsOfInterestRailway":"Railway","SelectPointsOfInterestReligiousSite":"Religious site","SelectPointsOfInterestRenting":"Rental","SelectPointsOfInterestRepairAndChargingStation":"Repair / Shop","SelectPointsOfInterestRestaurant":"Restaurant","SelectPointsOfInterestShelter":"Shelter","SelectPointsOfInterestShip":"Ship","SelectPointsOfInterestShop":"Shop","SelectPointsOfInterestSports":"Sports","SelectPointsOfInterestSportsOutdoorTravel":"Sports / Outdoor / Travel","SelectPointsOfInterestStationeryGifts":"Stationery / Gifts","SelectPointsOfInterestTaxi":"Taxi","SelectPointsOfInterestThemeParksAquaDomesAndZoos":"Theme park / Aqua dome / Zoo","SelectPointsOfInterestTourismInformation":"Tourism information","SelectPointsOfInterestTradeService":"Trade / Services","SelectPointsOfInterestTraffic":"Transport","SelectPointsOfInterestTransportAndInformation":"Transport / Information","SelectPointsOfInterestVendingMachine":"Vending machine","SelectPointsOfInterestWarningTooManyItems":"Select up to five categories at once.","SelectPointsOfInterestWellness":"Wellness","abc.daysToStart":"days until start <br>of the ABC!","abc.daysToStart.teaser":"All ABC leaderboards<br>at a glance ...","abc.header.kilometers":"km cycled so far in ABC %1$s","base.action":"Actions","base.add":"add","base.assume":"accept","base.attention":"Note","base.bookmark":"memorise","base.by":"at","base.cancel":"cancel","base.close":"close","base.cookieChoices":"To provide best user experience we apply cookies.","base.copy":"Copy","base.deactivatedAccountChangeEmailButton":"Change e-mail address","base.deactivatedAccountHint":"Please verify your e-mail address to activate your account. We sent you a confirmation mail to {0}.","base.deactivatedAccountResendButton":"Resend activation mail","base.delete":"delete","base.edit":"edit","base.error":"Fault","base.hour":"h","base.kilometre":"km","base.language":"Language","base.meter":"m","base.more":"Learn more ...","base.move":"move","base.no":"no","base.notsupported":"This function is not supported by your browser.","base.ok":"OK","base.photos":"Photos","base.print":"print","base.send":"Calculate","base.serviceNotAvailable":"Service not available","base.store":"save","base.switchDirection":"Invert direction","base.yes":"yes","contest.chooseArea":"Select a city","contest.chooseTeam":"Select a team","contest.deletedUser":"Deleted user","contest.joinContest":"Participate","contest.joinContestHint":"Join the contest now!","contest.joinTeam":"Join team","contest.joinTeamHint":"Join a team now!","contest.leaveArea":"Leave city","contest.leaveContest":"Leave contest","contest.leaveContestHint":"You are participating in the contest","contest.leaveTeam":"Leave team","contest.leaveTeamHint":"You are a member of this team","contest.linkToRegistration":"See and change your teams or sign up for the ECC now ...","contest.message.confirmJoinningToTeam.message":"The team captain confirmed your request. Your recorded trips now also count for the team.","contest.message.confirmJoinningToTeam.title":"You successfully joined a team!","contest.message.email.regards":"Naviki, www.naviki.org","contest.message.email.salutation":"Hello %s,","contest.message.email.teammessage.hint":"Please don't reply to this message. You may get in touch with your team captain by means of contact data he or she sent you.","contest.message.email.teammessage.subject":"New message from your team captain %s","contest.message.joinToTeam.message":"Someone wants to join your team in the Naviki contest. Open the contest in your Naviki app and go to \"My Team\" to confirm.","contest.message.joinToTeam.title":"Someone wants to join your team!","contest.message.leaveFromTeam.message":"There is at least one free position in your team. Ask cyclists if they want to join your team!","contest.message.leaveFromTeam.title":"Someone left your team","contest.myCity":"My city","contest.myTeam":"My team","contest.nextStep":"Next step","contest.participate.loginHint":"%1$s Log in to Naviki %2$s in order to participate!","contest.participate.welcomeAppMessage":"You are ready for the contest. Now get the Naviki app and record your bicycle trips!","contest.searchArea":"Search your city ...","contest.searchTeam":"Search your team ...","contest.timePeriod.hint":"Active period already completed.","contest.timePeriod.proportional":"Active period already completed. Achieved km appear in the ranking proportionately on a daily basis.","contest.university.employees":"Employees %s","contest.university.founding":"Founding %s","contest.university.students":"Students %s","pi_map.contextMenu_centerOnThisLocation":"Center on this location","pi_map.earthTour":"GoogleEarth","pi_map.enlarge_picture":"Enlarge picture ...","pi_map.fullscreen_max":"Maximise map","pi_map.fullscreen_min":"Minimise map","pi_map.geolocation":"Display own position","pi_map.geolocation.missing_permission":"Authorise Naviki to use your location in browser settings.","pi_map.landingpage_layer.body":"Learn more on Naviki Page","pi_map.landingpage_layer.title":"%s: More info on cycling","pi_map.more":"more...","pi_map.stops_layer_from":"Information on trip from here","pi_map.stops_layer_to":"Information on trip to here","pi_map.type.3d_bicycle":"Muscle Ache","pi_map.type.alternative":"Chain Oil","pi_map.type.alternative_bicycle":"Chain Oil Plus","pi_map.type.default":"Tailwind","pi_map.type.default_bicycle":"Tailwind Plus","pi_map.type.google.satellite":"Satellite","pi_map.type.osm":"OSM","pi_map.type.osm_bike":"OSM Bike","pi_map_open_app.button":"Start Naviki App","pi_portlet.myWays":"My own routes","pi_portlet.myWaysFooter":"This space is for routes you recorded with your Naviki app","pi_portlet.wayBookmarks":"My memorised routes","pi_portlet.wayBookmarksFooter":"This space is for routes you marked as \"memorised\"","pi_routing_request.add_destination":"Route destination","pi_routing_request.add_start":"Route from here","pi_routing_request.add_target":"Add destination","pi_routing_request.attention.address_not_found":"Please consider correct spelling and enter addresses as follows: Street, Town, Country","pi_routing_request.attention.empty_inputfields":"Please fill in all boxes!","pi_routing_request.attention.no_route_between_points":"Naviki cannot calculate any route between these locations. Please try again with alternative locations.","pi_routing_request.attention.routing_not_possible":"Naviki temporarily cannot calculate any route. Please try again later.","pi_routing_request.close_to_roundtrip":"Round trip","pi_routing_request.current_location":"Display own position","pi_routing_request.default":"Street, no., place","pi_routing_request.destination":"Destination","pi_routing_request.imbed":"imbed","pi_routing_request.start":"Start","pi_routing_request.submit":"Calculate","pi_routing_widget.header":"Calculate cycle route","pi_routing_widget.start":"Start","pi_routing_widget.target":"Destination","pi_search":"Search","pi_search.hint":"Location or search term","pi_search.invalid":"Please don't enter special characters (*+:;%$Â§...)!","pi_search.no_result":"No result found for search term","pi_search.to_short":"Please enter a longer search term!","pi_userprofile":"Naviki user profile","pi_userprofile.co2.engineType":"Consumption type","pi_userprofile.co2.gasconsumption":"average consumption per 100 km","pi_userprofile.co2.gasconsumption_not_valid":"Please insert a realistic value ​​between 3 and 20 litres.","pi_userprofile.co2.grams_per_kilometer":"g/km","pi_userprofile.co2.header":"My car","pi_userprofile.co2.individual_co2_per_km":"CO2 emission","pi_userprofile.co2.individual_co2_per_km_not_valid":"Insert a realistic value","pi_userprofile.co2.liter":"litre","pi_userprofile.co2.vehicleClass":"Vehicle","pi_userprofile.delete":"Delete profile ...","pi_userprofile.deleteDialog":"Are you sure, you want to delete your profile including all routes?","pi_userprofile.disable":"Deactivate account","pi_userprofile.disableDialog":"Are you sure, you want to disable your profile? Your data will be deleted after 30 days. Within this time you can reactivate your account via login.","pi_userprofile.email":"E-mail","pi_userprofile.email_already_exists":"This e-mail address is already being used for a Naviki account.","pi_userprofile.email_change_hint":"We have sent you a confirmation email. Click the link in that email. Afterwards your updated email address will appear here.","pi_userprofile.email_not_valid":"This e-mail address is invalid.","pi_userprofile.energy.kilocalories":"kcal","pi_userprofile.energy.kilojoule":"kJ","pi_userprofile.engine.diesel":"diesel","pi_userprofile.engine.gasoline":"gasoline","pi_userprofile.engine.naturalgas":"natural gas","pi_userprofile.general":"General","pi_userprofile.image":"Image","pi_userprofile.mybike.header":"My bicycle","pi_userprofile.mybike.type":"Bicycle type","pi_userprofile.mybike.type.bike_without_drive_support":"Ordinary bicycle","pi_userprofile.mybike.type.e_bike":"E-bike","pi_userprofile.mybike.type.s_pedelec":"S-pedelec","pi_userprofile.name":"Name","pi_userprofile.newsletter":"Naviki newsletter by e-mail","pi_userprofile.notifications.header":"Notifications","pi_userprofile.personal.age":"Age","pi_userprofile.personal.average_speed":"Average speed","pi_userprofile.personal.average_speed.sub":"Enter the average speed at which you cycle without obstacles. When you plan a route, Naviki considers this speed as well as the influence of traffic lights and gradients, to predict the average speed on the planned route.","pi_userprofile.personal.average_speed_not_valid":"Please insert a realistic speed ​​between 4 and 100 km/h.","pi_userprofile.personal.birthday":"Birthday","pi_userprofile.personal.birthday_not_valid":"Please insert a realistic age between 2 and 110 years.","pi_userprofile.personal.gender":"Gender","pi_userprofile.personal.gender.female":"female","pi_userprofile.personal.gender.male":"male","pi_userprofile.personal.header":"Personal","pi_userprofile.personal.size":"Body size","pi_userprofile.personal.size_not_valid":"Please insert a realistic size ​​between 80 and 240 cm.","pi_userprofile.personal.weight":"Body weight","pi_userprofile.personal.weight_not_valid":"Please insert a realistic value ​​between 10 and 180 kg.","pi_userprofile.privacy.header":"Privacy","pi_userprofile.privacy.profile":"I agree that other Naviki users can see information such as my profile picture and my user name.","pi_userprofile.units.energy":"Energy","pi_userprofile.units.energy.kilocalories":"Kilocalories (kcal)","pi_userprofile.units.energy.kilojoules":"Kilojoules (kJ)","pi_userprofile.units.header":"Units","pi_userprofile.units.length":"Distance","pi_userprofile.units.length.kilometers":"Metric (kilometers)","pi_userprofile.units.length.miles":"Imperial (miles)","pi_userprofile.vehicle.costs":"Car costs","pi_userprofile.vehicle.costs.unit":"Cent/km","pi_userprofile.vehicle.individual":"individual input","pi_userprofile.vehicle.middle_class":"Medium class car","pi_userprofile.vehicle.middle_class_diesel":"Medium class (diesel 174 g CO2/km)","pi_userprofile.vehicle.middle_class_gasoline":"Medium class (gasoline 216 g CO2/km)","pi_userprofile.vehicle.not_available":"I don't have a car","pi_userprofile.vehicle.small_car":"Small car","pi_userprofile.vehicle.small_car_diesel":"Small car (diesel 125 g CO2/km)","pi_userprofile.vehicle.small_car_gasoline":"Small car (gasoline 160 g CO2/km)","pi_userprofile.vehicle.sub":"With this information Naviki calculates your individual fuel savings and CO2 avoidance through cycling compared to a car. Be proud of it!","pi_userprofile.vehicle.upper_class":"Upper class car","pi_userprofile.vehicle.upper_class_diesel":"Upper class (diesel 229 g CO2/km)","pi_userprofile.vehicle.upper_class_gasoline":"Upper class (gasoline 271 g CO2/km)","pi_way.crdate":"Trip cycled at","pi_way.delete_path_question":"Do you really want to delete this route?","pi_way.description":"Description","pi_way.env":"Surroundings","pi_way.env_city":"Town/city","pi_way.env_forest":"Woodland","pi_way.env_hills":"Low mountain ranges","pi_way.env_industry":"Industry","pi_way.env_meadow":"Meadows/fields","pi_way.env_mountains":"High mountain ranges","pi_way.env_river":"River/lake","pi_way.env_sea":"Dyke/coast","pi_way.env_village":"Countryside/villages","pi_way.middle_traffic_flow":"Medium traffic volume","pi_way.middle_traffic_flow_very_high":"very high","pi_way.middle_traffic_flow_very_low":"very low","pi_way.private_way":"Status","pi_way.private_way.private":"private","pi_way.private_way.public":"public","pi_way.special_usage":"Suitability","pi_way.special_usage_children":"Children","pi_way.special_usage_m_t_b":"Mountain bike","pi_way.special_usage_racing":"Racing bike","pi_way.special_usage_seniors":"Senior citizens","pi_way.special_usage_sparetime":"Leisure","pi_way.special_usage_tourism":"Tourism","pi_way.title":"Title","pi_way_info.bookmark_path_name":"Name","pi_way_info.calories_burned":"Calories burned","pi_way_info.co2_background_info":"Background information","pi_way_info.co2_savings":"CO2 avoidance","pi_way_info.download_gpx_text":"(e.g. Garmin, Magellan)","pi_way_info.download_header":"GPS files","pi_way_info.download_kml_paths_text":"(as paths, e.g. for editing in Google Earth)","pi_way_info.download_kml_text":"(e.g. Google Earth)","pi_way_info.download_ovl_text":"(e.g. Top50 maps)","pi_way_info.download_tcx_text":"(e.g. Garmin Training Center)","pi_way_info.heightProfileLabelX":"Length in","pi_way_info.heightProfileLabelY":"Height in","pi_way_info.infoheightdiff":"Height in meters upwards","pi_way_info.infoheightmax":"Highest point","pi_way_info.infoheightmin":"Lowest point","pi_way_info.infokm":"Length","pi_way_info.infokmtime":"Ride time at %s km/h","pi_way_info.menu_bookmark":"Memorise","pi_way_info.menu_delete":"Delete","pi_way_info.menu_download":"GPS download","pi_way_info.menu_edit":"Edit","pi_way_info.menu_print":"Print view","pi_way_info.menu_rating":"Rate","pi_way_info.menu_report":"Report","pi_way_info.no_description":"No description available yet.","pi_way_info.no_images":"No image available yet.","pi_way_info.ownerprofile_private":"The user doesn't provide this information publicly.","pi_way_info.price_savings":"Car costs","pi_way_info.print_info":"Naviki is creating your print view. This may take a while, depending on the length of the route.","pi_way_info.rating":"Rating","pi_way_info.rating.1":"very bad","pi_way_info.rating.2":"bad","pi_way_info.rating.3":"medium","pi_way_info.rating.4":"good","pi_way_info.rating.5":"very good","pi_way_info.rating_header":"Route rating","pi_way_info.report_header":"Route report","pi_way_info.starting_points_title":"Starting points","pi_way_info.tab_description":"Info","pi_way_info.tab_energy":"Energy","pi_way_info.tab_images":"Illustrations","pi_way_info.tab_overview":"Overview","pi_way_info.tab_owner":"Owner","pi_way_info.tab_profile":"Heights","pi_way_info.unsuited":"Reports","pi_way_info.unsuitedforbicycles_1":"You have reported this route as impassable","pi_way_info.unsuitedforbicycles_2":"Report this route as impassable","pi_way_info.user_profile":"More routes from %s ...","pi_way_info.widget_more":"More routes on","pi_way_preview.toMapview":"To mapview ...","tx_naviki_domain_model_bicyclemarkingappointment":"Appointment","tx_naviki_domain_model_bicyclemarkingappointment.captcha_response":"Please insert the word shown in the image.","tx_naviki_domain_model_bicyclemarkingappointment.city":"Place of residence","tx_naviki_domain_model_bicyclemarkingappointment.color":"Color","tx_naviki_domain_model_bicyclemarkingappointment.date_of_birth":"Date of birth","tx_naviki_domain_model_bicyclemarkingappointment.email":"E-mail","tx_naviki_domain_model_bicyclemarkingappointment.forename":"Name","tx_naviki_domain_model_bicyclemarkingappointment.framenumber":"Number","tx_naviki_domain_model_bicyclemarkingappointment.gearing":"Gearing","tx_naviki_domain_model_bicyclemarkingappointment.manufacturer":"Type","tx_naviki_domain_model_bicyclemarkingappointment.notes":"Special characteristics","tx_naviki_domain_model_bicyclemarkingappointment.start":"Appointment","tx_naviki_domain_model_bicyclemarkingappointment.steering":"Handlebar","tx_naviki_domain_model_bicyclemarkingappointment.street":"Street / No.","tx_naviki_domain_model_bicyclemarkingappointment.surname":"Name","tx_naviki_domain_model_bicyclemarkingappointment.zip":"Postcode","tx_naviki_domain_model_bicyclemarkingevent":"Bicycle event","tx_naviki_domain_model_bicyclemarkingevent.name":"Name","tx_naviki_domain_model_bicyclemarkingevent.periods":"Periods","tx_naviki_domain_model_bicyclemarkingevent.time_slot_length":"Time slot","tx_naviki_domain_model_bicyclemarkingperiod":"Period","tx_naviki_domain_model_bicyclemarkingperiod.appointments":"Appointments","tx_naviki_domain_model_bicyclemarkingperiod.end":"End","tx_naviki_domain_model_bicyclemarkingperiod.start":"Start","tx_naviki_pibicyclemarkingappointment.calendar.awarded":"occupied","tx_naviki_pibicyclemarkingappointment.calendar.free":"free","tx_naviki_pibicyclemarkingappointment.calendar.weekdays":"Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday","tx_naviki_pibicyclemarkingappointment.choose_date":"Select date","tx_naviki_pibicyclemarkingappointment.dialog":"Would you like to register now for the bicycle coding?","tx_naviki_pibicyclemarkingappointment.dialog.back":"Back to the form","tx_naviki_pibicyclemarkingappointment.dialog.submit":"Sign in","tx_naviki_pibicyclemarkingappointment.dialog.title":"Registration","tx_naviki_pibicyclemarkingappointment.error.1221559976":"This email address is invalid.","tx_naviki_pibicyclemarkingappointment.error.1221560718":"Please fill in the following field","tx_naviki_pibicyclemarkingappointment.error.1221563685":"Only digits (0-9) are allowed.","tx_naviki_pibicyclemarkingappointment.error.1238108067":"Please enter your zip code from five digits.","tx_naviki_pibicyclemarkingappointment.error.1238108069":"Maximum of 256 characters.","tx_naviki_pibicyclemarkingappointment.error.1398857830":"The appointment is already booked.","tx_naviki_pibicyclemarkingappointment.error.1398857831":"You are already registered for this appointment.","tx_naviki_pibicyclemarkingappointment.my_bike":"My bicycle","tx_naviki_pibicyclemarkingappointment.personal_information":"Personal information","tx_naviki_pibicyclemarkingappointment.required_fields":"Fields marked by a star (*) have to be filled","tx_naviki_pibicyclemarkingappointment.submit":"Log in","tx_naviki_pimap.imprint":"Legal notice (Naviki)","tx_naviki_pimapcontrol.bookmark.btn":"Memorise route and use it on App","tx_naviki_pimapcontrol.bookmark.btn.active":"Memorised","tx_naviki_pimapcontrol.bookmark.dlg.success":"This route is now available in your Naviki app, see 'My routes'","tx_naviki_pimapcontrol.bookmark.tip":"Use in Naviki app","tx_naviki_pimapcontrol.download.tip":"Download GPS file","tx_naviki_pimapcontrol.embed.dlg.code":"Embed route in your website","tx_naviki_pimapcontrol.embed.tip":"Embed on website","tx_naviki_pimapcontrol.profile.cadence":"Cadence [1/min]","tx_naviki_pimapcontrol.profile.duration":"Duration [h]","tx_naviki_pimapcontrol.profile.height":"Height [m]","tx_naviki_pimapcontrol.profile.length":"Length [km]","tx_naviki_pimapcontrol.profile.pulse":"Pulse [bpm]","tx_naviki_pimapcontrol.profile.speed":"Speed [km/h]","tx_naviki_pimapcontrol.search.list.header":"Routes of","tx_naviki_pimapcontrol.search.placeholder":"City, landscape, river, ...","tx_naviki_pimapcontrol.search.tip":"Finds routes of other users and official routes","tx_naviki_piwidget.widget.bookmark.btn":"Use route with Naviki"	},	getLL:function(key){		if(key in naviki.Lang.local_lang){			return naviki.Lang.local_lang[key];		}		return key;	}};
/*
 * jQuery Nivo Slider v3.2
 * http://nivo.dev7studios.com
 *
 * Copyright 2012, Dev7studios
 * Free to use and abuse under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */

(function(e){var t=function(t,n){var r=e.extend({},e.fn.nivoSlider.defaults,n);var i={currentSlide:0,currentImage:"",totalSlides:0,running:false,paused:false,stop:false,controlNavEl:false};var s=e(t);s.data("nivo:vars",i).addClass("nivoSlider");var o=s.children();o.each(function(){var t=e(this);var n="";if(!t.is("img")){if(t.is("a")){t.addClass("nivo-imageLink");n=t}t=t.find("img:first")}var r=r===0?t.attr("width"):t.width(),s=s===0?t.attr("height"):t.height();if(n!==""){n.css("display","none")}t.css("display","none");i.totalSlides++});if(r.randomStart){r.startSlide=Math.floor(Math.random()*i.totalSlides)}if(r.startSlide>0){if(r.startSlide>=i.totalSlides){r.startSlide=i.totalSlides-1}i.currentSlide=r.startSlide}if(e(o[i.currentSlide]).is("img")){i.currentImage=e(o[i.currentSlide])}else{i.currentImage=e(o[i.currentSlide]).find("img:first")}if(e(o[i.currentSlide]).is("a")){e(o[i.currentSlide]).css("display","block")}var u=e("<img/>").addClass("nivo-main-image");u.attr("src",i.currentImage.attr("src")).show();s.append(u);e(window).resize(function(){s.children("img").width(s.width());u.attr("src",i.currentImage.attr("src"));u.stop().height("auto");e(".nivo-slice").remove();e(".nivo-box").remove()});s.append(e('<div class="nivo-caption"></div>'));var a=function(t){var n=e(".nivo-caption",s);if(i.currentImage.attr("title")!=""&&i.currentImage.attr("title")!=undefined){var r=i.currentImage.attr("title");if(r.substr(0,1)=="#")r=e(r).html();if(n.css("display")=="block"){setTimeout(function(){n.html(r)},t.animSpeed)}else{n.html(r);n.stop().fadeIn(t.animSpeed)}}else{n.stop().fadeOut(t.animSpeed)}};a(r);var f=0;if(!r.manualAdvance&&o.length>1){f=setInterval(function(){d(s,o,r,false)},r.pauseTime)}if(r.directionNav){s.append('<div class="nivo-directionNav"><a class="nivo-prevNav">'+r.prevText+'</a><a class="nivo-nextNav">'+r.nextText+"</a></div>");e(s).on("click","a.nivo-prevNav",function(){if(i.running){return false}clearInterval(f);f="";i.currentSlide-=2;d(s,o,r,"prev")});e(s).on("click","a.nivo-nextNav",function(){if(i.running){return false}clearInterval(f);f="";d(s,o,r,"next")})}if(r.controlNav){i.controlNavEl=e('<div class="nivo-controlNav"></div>');s.after(i.controlNavEl);for(var l=0;l<o.length;l++){if(r.controlNavThumbs){i.controlNavEl.addClass("nivo-thumbs-enabled");var c=o.eq(l);if(!c.is("img")){c=c.find("img:first")}if(c.attr("data-thumb"))i.controlNavEl.append('<a class="nivo-control" rel="'+l+'"><img src="'+c.attr("data-thumb")+'" alt="" /></a>')}else{i.controlNavEl.append('<a class="nivo-control" rel="'+l+'">'+(l+1)+"</a>")}}e("a:eq("+i.currentSlide+")",i.controlNavEl).addClass("active");e("a",i.controlNavEl).bind("click",function(){if(i.running)return false;if(e(this).hasClass("active"))return false;clearInterval(f);f="";u.attr("src",i.currentImage.attr("src"));i.currentSlide=e(this).attr("rel")-1;d(s,o,r,"control")})}if(r.pauseOnHover){s.hover(function(){i.paused=true;clearInterval(f);f=""},function(){i.paused=false;if(f===""&&!r.manualAdvance){f=setInterval(function(){d(s,o,r,false)},r.pauseTime)}})}s.bind("nivo:animFinished",function(){u.attr("src",i.currentImage.attr("src"));i.running=false;e(o).each(function(){if(e(this).is("a")){e(this).css("display","none")}});if(e(o[i.currentSlide]).is("a")){e(o[i.currentSlide]).css("display","block")}if(f===""&&!i.paused&&!r.manualAdvance){f=setInterval(function(){d(s,o,r,false)},r.pauseTime)}r.afterChange.call(this)});var h=function(t,n,r){if(e(r.currentImage).parent().is("a"))e(r.currentImage).parent().css("display","block");e('img[src="'+r.currentImage.attr("src")+'"]',t).not(".nivo-main-image,.nivo-control img").width(t.width()).css("visibility","hidden").show();var i=e('img[src="'+r.currentImage.attr("src")+'"]',t).not(".nivo-main-image,.nivo-control img").parent().is("a")?e('img[src="'+r.currentImage.attr("src")+'"]',t).not(".nivo-main-image,.nivo-control img").parent().height():e('img[src="'+r.currentImage.attr("src")+'"]',t).not(".nivo-main-image,.nivo-control img").height();for(var s=0;s<n.slices;s++){var o=Math.round(t.width()/n.slices);if(s===n.slices-1){t.append(e('<div class="nivo-slice" name="'+s+'"><img src="'+r.currentImage.attr("src")+'" style="position:absolute; width:'+t.width()+"px; height:auto; display:block !important; top:0; left:-"+(o+s*o-o)+'px;" /></div>').css({left:o*s+"px",width:t.width()-o*s+"px",height:i+"px",opacity:"0",overflow:"hidden"}))}else{t.append(e('<div class="nivo-slice" name="'+s+'"><img src="'+r.currentImage.attr("src")+'" style="position:absolute; width:'+t.width()+"px; height:auto; display:block !important; top:0; left:-"+(o+s*o-o)+'px;" /></div>').css({left:o*s+"px",width:o+"px",height:i+"px",opacity:"0",overflow:"hidden"}))}}e(".nivo-slice",t).height(i);u.stop().animate({height:e(r.currentImage).height()},n.animSpeed)};var p=function(t,n,r){if(e(r.currentImage).parent().is("a"))e(r.currentImage).parent().css("display","block");e('img[src="'+r.currentImage.attr("src")+'"]',t).not(".nivo-main-image,.nivo-control img").width(t.width()).css("visibility","hidden").show();var i=Math.round(t.width()/n.boxCols),s=Math.round(e('img[src="'+r.currentImage.attr("src")+'"]',t).not(".nivo-main-image,.nivo-control img").height()/n.boxRows);for(var o=0;o<n.boxRows;o++){for(var a=0;a<n.boxCols;a++){if(a===n.boxCols-1){t.append(e('<div class="nivo-box" name="'+a+'" rel="'+o+'"><img src="'+r.currentImage.attr("src")+'" style="position:absolute; width:'+t.width()+"px; height:auto; display:block; top:-"+s*o+"px; left:-"+i*a+'px;" /></div>').css({opacity:0,left:i*a+"px",top:s*o+"px",width:t.width()-i*a+"px"}));e('.nivo-box[name="'+a+'"]',t).height(e('.nivo-box[name="'+a+'"] img',t).height()+"px")}else{t.append(e('<div class="nivo-box" name="'+a+'" rel="'+o+'"><img src="'+r.currentImage.attr("src")+'" style="position:absolute; width:'+t.width()+"px; height:auto; display:block; top:-"+s*o+"px; left:-"+i*a+'px;" /></div>').css({opacity:0,left:i*a+"px",top:s*o+"px",width:i+"px"}));e('.nivo-box[name="'+a+'"]',t).height(e('.nivo-box[name="'+a+'"] img',t).height()+"px")}}}u.stop().animate({height:e(r.currentImage).height()},n.animSpeed)};var d=function(t,n,r,i){var s=t.data("nivo:vars");if(s&&s.currentSlide===s.totalSlides-1){r.lastSlide.call(this)}if((!s||s.stop)&&!i){return false}r.beforeChange.call(this);if(!i){u.attr("src",s.currentImage.attr("src"))}else{if(i==="prev"){u.attr("src",s.currentImage.attr("src"))}if(i==="next"){u.attr("src",s.currentImage.attr("src"))}}s.currentSlide++;if(s.currentSlide===s.totalSlides){s.currentSlide=0;r.slideshowEnd.call(this)}if(s.currentSlide<0){s.currentSlide=s.totalSlides-1}if(e(n[s.currentSlide]).is("img")){s.currentImage=e(n[s.currentSlide])}else{s.currentImage=e(n[s.currentSlide]).find("img:first")}if(r.controlNav){e("a",s.controlNavEl).removeClass("active");e("a:eq("+s.currentSlide+")",s.controlNavEl).addClass("active")}a(r);e(".nivo-slice",t).remove();e(".nivo-box",t).remove();var o=r.effect,f="";if(r.effect==="random"){f=new Array("sliceDownRight","sliceDownLeft","sliceUpRight","sliceUpLeft","sliceUpDown","sliceUpDownLeft","fold","fade","boxRandom","boxRain","boxRainReverse","boxRainGrow","boxRainGrowReverse");o=f[Math.floor(Math.random()*(f.length+1))];if(o===undefined){o="fade"}}if(r.effect.indexOf(",")!==-1){f=r.effect.split(",");o=f[Math.floor(Math.random()*f.length)];if(o===undefined){o="fade"}}if(s.currentImage.attr("data-transition")){o=s.currentImage.attr("data-transition")}s.running=true;var l=0,c=0,d="",m="",g="",y="";if(o==="sliceDown"||o==="sliceDownRight"||o==="sliceDownLeft"){h(t,r,s);l=0;c=0;d=e(".nivo-slice",t);if(o==="sliceDownLeft"){d=e(".nivo-slice",t)._reverse()}d.each(function(){var n=e(this);n.css({top:"0px"});if(c===r.slices-1){setTimeout(function(){n.animate({opacity:"1.0"},r.animSpeed,"",function(){t.trigger("nivo:animFinished")})},100+l)}else{setTimeout(function(){n.animate({opacity:"1.0"},r.animSpeed)},100+l)}l+=50;c++})}else if(o==="sliceUp"||o==="sliceUpRight"||o==="sliceUpLeft"){h(t,r,s);l=0;c=0;d=e(".nivo-slice",t);if(o==="sliceUpLeft"){d=e(".nivo-slice",t)._reverse()}d.each(function(){var n=e(this);n.css({bottom:"0px"});if(c===r.slices-1){setTimeout(function(){n.animate({opacity:"1.0"},r.animSpeed,"",function(){t.trigger("nivo:animFinished")})},100+l)}else{setTimeout(function(){n.animate({opacity:"1.0"},r.animSpeed)},100+l)}l+=50;c++})}else if(o==="sliceUpDown"||o==="sliceUpDownRight"||o==="sliceUpDownLeft"){h(t,r,s);l=0;c=0;var b=0;d=e(".nivo-slice",t);if(o==="sliceUpDownLeft"){d=e(".nivo-slice",t)._reverse()}d.each(function(){var n=e(this);if(c===0){n.css("top","0px");c++}else{n.css("bottom","0px");c=0}if(b===r.slices-1){setTimeout(function(){n.animate({opacity:"1.0"},r.animSpeed,"",function(){t.trigger("nivo:animFinished")})},100+l)}else{setTimeout(function(){n.animate({opacity:"1.0"},r.animSpeed)},100+l)}l+=50;b++})}else if(o==="fold"){h(t,r,s);l=0;c=0;e(".nivo-slice",t).each(function(){var n=e(this);var i=n.width();n.css({top:"0px",width:"0px"});if(c===r.slices-1){setTimeout(function(){n.animate({width:i,opacity:"1.0"},r.animSpeed,"",function(){t.trigger("nivo:animFinished")})},100+l)}else{setTimeout(function(){n.animate({width:i,opacity:"1.0"},r.animSpeed)},100+l)}l+=50;c++})}else if(o==="fade"){h(t,r,s);m=e(".nivo-slice:first",t);m.css({width:t.width()+"px"});m.animate({opacity:"1.0"},r.animSpeed*2,"",function(){t.trigger("nivo:animFinished")})}else if(o==="slideInRight"){h(t,r,s);m=e(".nivo-slice:first",t);m.css({width:"0px",opacity:"1"});m.animate({width:t.width()+"px"},r.animSpeed*2,"",function(){t.trigger("nivo:animFinished")})}else if(o==="slideInLeft"){h(t,r,s);m=e(".nivo-slice:first",t);m.css({width:"0px",opacity:"1",left:"",right:"0px"});m.animate({width:t.width()+"px"},r.animSpeed*2,"",function(){m.css({left:"0px",right:""});t.trigger("nivo:animFinished")})}else if(o==="boxRandom"){p(t,r,s);g=r.boxCols*r.boxRows;c=0;l=0;y=v(e(".nivo-box",t));y.each(function(){var n=e(this);if(c===g-1){setTimeout(function(){n.animate({opacity:"1"},r.animSpeed,"",function(){t.trigger("nivo:animFinished")})},100+l)}else{setTimeout(function(){n.animate({opacity:"1"},r.animSpeed)},100+l)}l+=20;c++})}else if(o==="boxRain"||o==="boxRainReverse"||o==="boxRainGrow"||o==="boxRainGrowReverse"){p(t,r,s);g=r.boxCols*r.boxRows;c=0;l=0;var w=0;var E=0;var S=[];S[w]=[];y=e(".nivo-box",t);if(o==="boxRainReverse"||o==="boxRainGrowReverse"){y=e(".nivo-box",t)._reverse()}y.each(function(){S[w][E]=e(this);E++;if(E===r.boxCols){w++;E=0;S[w]=[]}});for(var x=0;x<r.boxCols*2;x++){var T=x;for(var N=0;N<r.boxRows;N++){if(T>=0&&T<r.boxCols){(function(n,i,s,u,a){var f=e(S[n][i]);var l=f.width();var c=f.height();if(o==="boxRainGrow"||o==="boxRainGrowReverse"){f.width(0).height(0)}if(u===a-1){setTimeout(function(){f.animate({opacity:"1",width:l,height:c},r.animSpeed/1.3,"",function(){t.trigger("nivo:animFinished")})},100+s)}else{setTimeout(function(){f.animate({opacity:"1",width:l,height:c},r.animSpeed/1.3)},100+s)}})(N,T,l,c,g);c++}T--}l+=100}}};var v=function(e){for(var t,n,r=e.length;r;t=parseInt(Math.random()*r,10),n=e[--r],e[r]=e[t],e[t]=n);return e};var m=function(e){if(this.console&&typeof console.log!=="undefined"){console.log(e)}};this.stop=function(){if(!e(t).data("nivo:vars").stop){e(t).data("nivo:vars").stop=true;m("Stop Slider")}};this.start=function(){if(e(t).data("nivo:vars").stop){e(t).data("nivo:vars").stop=false;m("Start Slider")}};r.afterLoad.call(this);return this};e.fn.nivoSlider=function(n){return this.each(function(r,i){var s=e(this);if(s.data("nivoslider")){return s.data("nivoslider")}var o=new t(this,n);s.data("nivoslider",o)})};e.fn.nivoSlider.defaults={effect:"random",slices:15,boxCols:8,boxRows:4,animSpeed:500,pauseTime:3e3,startSlide:0,directionNav:true,controlNav:true,controlNavThumbs:false,pauseOnHover:true,manualAdvance:false,prevText:"Prev",nextText:"Next",randomStart:false,beforeChange:function(){},afterChange:function(){},slideshowEnd:function(){},lastSlide:function(){},afterLoad:function(){}};e.fn._reverse=[].reverse})(jQuery);
/**
 * 
 */
;(function($) {
	
	$( document ).ready(function() {
		
		$.fn.navikiStartPage = function() {
			
			$("#teaser").stop();
			
			if($( window ).width() > 991) {
				
				var margin = 20;
				var current = margin - $( document ).scrollTop();
				var lowerLimit = $( window ).height() - ($("#stage").outerHeight() + $("#stage").offset().top) + margin;
				var upperLimit = $( window ).height() - ($(".nivo-caption").first().outerHeight() + $(".nivo-caption").first().offset().top + $("#teaser").outerHeight());
	
				var bottom = current;
				if(current <= lowerLimit){
					bottom = lowerLimit;
				} else if(current >= upperLimit){
					bottom = upperLimit;
				}
				
				$("#teaser").animate({
				    bottom: bottom
				  },1200, function() {
				    // Animation complete.
				});
			
			} else {
				
				if ($("#teaser").css("bottom") != "") {
					$("#teaser").css("bottom","");
				}
				if ($("#teaser").css("position") != "") {
					$("#teaser").css("position","");
				}
			}
		};	
		
		var findCaption = window.setInterval(function(){
			
			if($(".nivo-caption")){
				
				if($(".nivo-caption").first().height() == null) {
					return;
				}
				
				if($(".nivo-caption").first().offset() == null){
					return;
				}

				$( ".nivo-caption" ).wrap( "<div class='container'></div>" );
				$( ".nivo-caption" ).wrap( "<div class='row'></div>" );
				$( ".nivo-caption" ).addClass("col-md-6 col-lg-3");

				$.fn.navikiStartPage();
				window.clearInterval(findCaption);
			
				$( ".nivo-caption" ).animate({
					opacity: 1.0
				  },2000, function() {
				    // Animation complete.
				});
				
				$( window ).resize(function() {
					$.fn.navikiStartPage();
				});
				
				$( window ).scroll(function () {
					$.fn.navikiStartPage();
				});
			}
		}, 1000);
		
		var findControlNav = window.setInterval(function(){
			if($(".nivo-controlNav").length > 0){
				$( ".nivo-controlNav" ).wrap( "<div class='container'></div>" );
				$( ".nivo-controlNav" ).wrap( "<div class='row'></div>" );
				$( ".nivo-controlNav" ).addClass("col-md-6 col-lg-3");
				$( ".nivo-controlNav" ).animate({
					opacity: 1.0
				  },2000, function() {
				    // Animation complete.
				});
				window.clearInterval(findControlNav);
			}
		}, 1000);	
	});
	
})( jQuery);