PageSourceSearch

https://soledadvillamil.com/wp-content/themes/villamil/library/js/init.js?ver=1170316485

js soledadvillamil.com collected 2026-09-25 00:45:46 UTC 107,969 bytes, 3,086 lines download raw bytes

1/**
2 * Load utils - BEGIN
3 */
4/*
5 CSS Browser Selector 1.0
6 Originally written by Rafael Lima (http://rafael.adm.br)
7 http://rafael.adm.br/css_browser_selector
8 License: http://creativecommons.org/licenses/by/2.5/
9
10 Co-maintained by:
11 https://github.com/ridjohansen/css_browser_selector
12 https://github.com/wbruno/css_browser_selector
13 */
14
15"use strict";
16
17var uaInfo = {
18	ua: '',
19	is: function(t) {
20		return RegExp(t, "i").test(uaInfo.ua);
21	},
22	version: function(p, n) {
23		n = n.replace(".", "_");
24		var i = n.indexOf('_'),
25			ver = "";
26		while (i > 0) {
27			ver += " " + p + n.substring(0, i);
28			i = n.indexOf('_', i + 1);
29		}
30		ver += " " + p + n;
31		return ver;
32	},
33	getBrowser: function() {
34		var g = 'gecko',
35			w = 'webkit',
36			c = 'chrome',
37			f = 'firefox',
38			s = 'safari',
39			o = 'opera',
40			a = 'android',
41			bb = 'blackberry',
42			dv = 'device_',
43			ua = uaInfo.ua,
44			is = uaInfo.is;
45		return [
46			(!(/opera|webtv/i.test(ua)) && /msie\s(\d+)/.test(ua)) ? ('ie ie' + (/trident\/4\.0/.test(ua) ? '8' : RegExp.$1))
47			: is('edge\/') ? 'edge ie' + (/edge\/(\d+)\.(\d+)/.test(ua) ? RegExp.$1 + ' ie' + RegExp.$1 + '_' + RegExp.$2 : '') // IE Edge
48			: is('trident\/') ? 'ie ie'+ (/trident\/.+rv:(\d+)/i.test(ua) ? RegExp.$1 : '') //ie11+
49			: is('firefox/') ? g + " " + f + (/firefox\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + f + RegExp.$2 + ' ' + f + RegExp.$2 + "_" + RegExp.$4 : '') 
50			: is('gecko/') ? g
51			: is('opera') ? o + (/version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + o + RegExp.$2 + ' ' + o + RegExp.$2 + "_" + RegExp.$4 : (/opera(\s|\/)(\d+)\.(\d+)/.test(ua) ? ' ' + o + RegExp.$2 + " " + o + RegExp.$2 + "_" + RegExp.$3 : '')) 
52			: is('konqueror') ? 'konqueror'
53			: is('blackberry') ? (bb + (/Version\/(\d+)(\.(\d+)+)/i.test(ua) ? " " + bb + RegExp.$1 + " " + bb + RegExp.$1 + RegExp.$2.replace('.', '_') : (/Blackberry ?(([0-9]+)([a-z]?))[\/|;]/gi.test(ua) ? ' ' + bb + RegExp.$2 + (RegExp.$3 ? ' ' + bb + RegExp.$2 + RegExp.$3 : '') : ''))) // blackberry
54			: is('android') ? (a + (/Version\/(\d+)(\.(\d+))+/i.test(ua) ? " " + a + RegExp.$1 + " " + a + RegExp.$1 + RegExp.$2.replace('.', '_') : '') + (/Android (.+); (.+) Build/i.test(ua) ? ' ' + dv + ((RegExp.$2).replace(/ /g, "_")).replace(/-/g, "_") : '')) //android
55			: is('chrome') ? w + ' ' + c + (/chrome\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + c + RegExp.$2 + ((RegExp.$4 > 0) ? ' ' + c + RegExp.$2 + "_" + RegExp.$4 : '') : '') 
56			: is('iron') ? w + ' iron'
57			: is('applewebkit/') ? (w + ' ' + s + (/version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua) ? ' ' + s + RegExp.$2 + " " + s + RegExp.$2 + RegExp.$3.replace('.', '_') : (/ Safari\/(\d+)/i.test(ua) ? ((RegExp.$1 == "419" || RegExp.$1 == "417" || RegExp.$1 == "416" || RegExp.$1 == "412") ? ' ' + s + '2_0' : RegExp.$1 == "312" ? ' ' + s + '1_3' : RegExp.$1 == "125" ? ' ' + s + '1_2' : RegExp.$1 == "85" ? ' ' + s + '1_0' : '') : ''))) //applewebkit
58			: is('mozilla/') ? g : ''
59		];
60	},
61	getPlatform : function() {
62		var wp = 'winphone',
63			a  = 'android',
64			bb = 'blackberry',
65			dv = 'device_',
66
67			ua = uaInfo.ua,
68			version = uaInfo.version,
69			is = uaInfo.is;
70
71		return [
72			is('j2me') ? 'j2me'
73			:is('windows phone') ? (wp + (/Windows Phone (\d+)(\.(\d+))+/i.test(ua) ? " " + wp + RegExp.$1 + " " + wp + RegExp.$1 + RegExp.$2.replace('.', '_') : (/Windows Phone OS (\d+)(\.(\d+))+/i.test(ua) ? " " + wp + RegExp.$1 + " " + wp + RegExp.$1 + RegExp.$2.replace('.', '_') : ''))) // Windows Phone
74			:is('blackberry') ? (bb + (/Version\/(\d+)(\.(\d+)+)/i.test(ua) ? " " + bb + RegExp.$1 + " " + bb + RegExp.$1 + RegExp.$2.replace('.', '_') : (/Blackberry ?(([0-9]+)([a-z]?))[\/|;]/gi.test(ua) ? ' ' + bb + RegExp.$2 + (RegExp.$3 ? ' ' + bb + RegExp.$2 + RegExp.$3 : '') : ''))) // blackberry
75			:is('android') ? (a + (/Version\/(\d+)(\.(\d+))+/i.test(ua) ? " " + a + RegExp.$1 + " " + a + RegExp.$1 + RegExp.$2.replace('.', '_') : '') + (/Android (.+); (.+) Build/i.test(ua) ? ' ' + dv + ((RegExp.$2).replace(/ /g, "_")).replace(/-/g, "_") : '')) //android
76			:is('ipad|ipod|iphone') ? (
77			(/CPU( iPhone)? OS (\d+[_|\.]\d+([_|\.]\d+)*)/i.test(ua) ? 'ios' + version('ios', RegExp.$2) : '') + ' ' + (/(ip(ad|od|hone))/gi.test(ua) ? RegExp.$1 : "")) //'iphone'
78			//:is('ipod')?'ipod'
79			//:is('ipad')?'ipad'
80			:is('playbook') ? 'playbook'
81			:is('kindle|silk') ? 'kindle'
82			:is('playbook') ? 'playbook'
83			:is('mac') ? 'mac' + (/mac os x ((\d+)[.|_](\d+))/.test(ua) ? (' mac' 
83+ (RegExp.$2) + ' mac' + (RegExp.$1).replace('.', "_")) : '')
84			:is('win') ? 'win' + (is('windows nt 10.0') ? ' win10'
85			:is('windows nt 6.3') ? ' win8_1'
86			:is('windows nt 6.2') ? ' win8'
87			:is('windows nt 6.1') ? ' win7'
88			:is('windows nt 6.0') ? ' vista'
89			:is('windows nt 5.2') || is('windows nt 5.1') ? ' win_xp'
90			:is('windows nt 5.0') ? ' win_2k'
91			:is('windows nt 4.0') || is('WinNT4.0') ? ' win_nt' : '')
92			:is('freebsd') ? 'freebsd'
93			:is('x11|linux') ? 'linux' : ''
94		];
95	},
96	getMobile: function() {
97		var is = uaInfo.is;
98		return [
99			is("android|mobi|mobile|j2me|iphone|ipod|ipad|blackberry|playbook|kindle|silk") ? 'mobile' : ''
100		];
101	},
102	getIpadApp: function() {
103		var is = uaInfo.is;
104		return [
105			(is('ipad|iphone|ipod') && !is('safari')) ? 'ipad_app' : ''
106		];
107	},
108	getLang: function() {
109		var ua = uaInfo.ua;
110		return [/[; |\[](([a-z]{2})(\-[a-z]{2})?)[)|;|\]]/i.test(ua) ? ('lang_' + RegExp.$2).replace("-", "_") + (RegExp.$3 != '' ? (' ' + 'lang_' + RegExp.$1).replace("-", "_") : '') : ''];
111	}
112}
113var screenInfo = {
114	width: (window.outerWidth || document.documentElement.clientWidth) - 15,
115	height: window.outerHeight || document.documentElement.clientHeight,
116	screens: [0, 768, 980, 1200],
117	screenSize: function() {
118		screenInfo.width = (window.outerWidth || document.documentElement.clientWidth) - 15;
119		screenInfo.height = window.outerHeight || document.documentElement.clientHeight;
120		var screens = screenInfo.screens,
121			i = screens.length,
122			arr = [],
123			maxw,
124			minw;
125		while (i--) {
126			if (screenInfo.width >= screens[i]) {
127				if (i) {
128					arr.push("minw_" + screens[(i)]);
129				}
130				if (i <= 2) {
131					arr.push("maxw_" + (screens[(i) + 1] - 1));
132				}
133				break;
134			}
135		}
136		return arr;
137	},
138	getOrientation: function() {
139		return screenInfo.width < screenInfo.height ? ["orientation_portrait"] : ["orientation_landscape"];
140	},
141	getInfo: function() {
142		var arr = [];
143		arr = arr.concat(screenInfo.screenSize());
144		arr = arr.concat(screenInfo.getOrientation());
145		return arr;
146	},
147	getPixelRatio: function() {
148		var arr = [],
149			pixelRatio = window.devicePixelRatio ? window.devicePixelRatio : 1;
150		if (pixelRatio > 1) {
151			arr.push('retina_' + parseInt(pixelRatio) + 'x');
152			arr.push('hidpi');
153		} else {
154			arr.push('no-hidpi');
155		}
156		return arr;
157	}
158}
159var dataUriInfo = {
160	data: new Image(),
161	div: document.createElement("div"),
162	isIeLessThan9: false,
163	getImg: function() {
164		dataUriInfo.data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
165		dataUriInfo.div.innerHTML = "<!--[if lt IE 9]><i></i><![endif]-->";
166		dataUriInfo.isIeLessThan9 = dataUriInfo.div.getElementsByTagName("i").length == 1;
167		return dataUriInfo.data;
168	},
169	checkSupport: function() {
170		if (dataUriInfo.data.width != 1 || dataUriInfo.data.height != 1 || dataUriInfo.isIeLessThan9) {
171			return ["no-datauri"];
172		} else {
173			return ["datauri"];
174		}
175	}
176}
177
178function css_browser_selector(u, ns) {
179		var html = document.documentElement,
180			b = []
181		ns = ns ? ns : "";
182		/* ua */
183		uaInfo.ua = u.toLowerCase();
184		var browser = uaInfo.getBrowser();
185		if (browser == 'gecko') browser = (!(window.ActiveXObject) && "ActiveXObject" in window) ? 'ie ie11' : browser;
186		var pattTouch = /no-touch/g;
187		if (pattTouch.test(html.className)) b = b.concat('no-touch');
188		else b = b.concat('touch');
189		var pattAdmin = /admin-mode/g;
190		if (pattAdmin.test(html.className)) b = b.concat('admin-mode');
191		b = b.concat(browser);
192		b = b.concat(uaInfo.getPlatform());
193		b = b.concat(uaInfo.getMobile());
194		b = b.concat(uaInfo.getIpadApp());
195		b = b.concat(uaInfo.getLang());
196		/* js */
197		b = b.concat(['js']);
198		/* pixel ratio */
199		b = b.concat(screenInfo.getPixelRatio());
200		/* screen */
201		b = b.concat(screenInfo.getInfo());
202		var updateScreen = function() {
203			html.className = html.className.replace(/ ?orientation_\w+/g, "").replace(/ [min|max|cl]+[w|h]_\d+/g, "");
204			html.className = html.className + ' ' + screenInfo.getInfo().join(' ');
205		}
206		window.addEventListener('resize', updateScreen);
207		window.addEventListener('orientationchange', updateScreen);
208		/* dataURI */
209		var data = dataUriInfo.getImg();
210		data.onload = data.onerror = function() {
211				html.className += ' ' + dataUriInfo.checkSupport().join(' ');
212			}
213			/* removendo itens invalidos do array */
214		b = b.filter(function(e) {
215			return e;
216		});
217		/* prefixo do namespace */
218		b[0] = ns ? ns + b[0] : b[0];
219		html.className = b.join(' ' + ns);
220		return html.className;
221	}
222	// define css_browser_selector_ns before loading this script to assign a namespace
223var css_browser_selector_ns = css_browser_selector_ns || "";
224// init
225css_browser_selector(navigator.userAgent, css_browser_selector_ns);
226/**
227 * skip-link-focus-fix.js
228 *
229 * Helps with accessibility for keyboard only users.
230 *
231 * Learn more: https://github.com/Automattic/_s/pull/136
232 */
233(function() {
234	var is_webkit = navigator.userAgent.toLowerCase().indexOf('webkit') > -1,
235		is_opera = navigator.userAgent.toLowerCase().indexOf('opera') > -1,
236		is_ie = navigator.userAgent.toLowerCase().indexOf('msie') > -1;
237	if ((is_webkit || is_opera || is_ie) && document.getElementById && window.addEventListener) {
238		window.addEventListener('hashchange', function() {
239			var id = location.hash.substring(1),
240				element;
241			if (!(/^[A-z0-9_-]+$/.test(id))) {
242				return;
243			}
244			element = document.getElementById(id);
245			if (element) {
246				if (!(/^(?:a|select|input|button|textarea)$/i.test(element.tagName))) {
247					element.tabIndex = -1;
248				}
249				element.focus();
250			}
251		}, false);
252	}
253})();
254// Polyfill for creating CustomEvents on IE9/10/11
255// code pulled from:
256// https://github.com/d4tocchini/customevent-polyfill
257// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill
258try {
259	new CustomEvent("test");
260} catch (e) {
261	var CustomEvent = function(event, params) {
262		var evt;
263		params = params || {
264			bubbles: false,
265			cancelable: false,
266			detail: undefined
267		};
268		evt = document.createEvent("CustomEvent");
269		evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
270		return evt;
271	};
272	CustomEvent.prototype = window.Event.prototype;
273	window.CustomEvent = CustomEvent; // expose definition to window
274}
275// Evento - v1.0.0
276// by Erik Royall <[email protected]> (http://erikroyall.github.io)
277// Dual licensed under MIT and GPL
278// Array.prototype.indexOf shim
279// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
280Array.prototype.indexOf || (Array.prototype.indexOf = function(n) {
281	"use strict";
282	if (null == this) throw new TypeError;
283	var t, e, o = Object(this),
284		r = o.length >>> 0;
285	if (0 === r) return -1;
286	if (t = 0, arguments.length > 1 && (t = Number(arguments[1]), t != t ? t = 0 : 0 != t && 1 / 0 != t && t != -1 / 0 && (t = (t > 0 || -1) * Math.floor(Math.abs(t)))), t >= r) return -1;
287	for (e = t >= 0 ? t : Math.max(r - Math.abs(t), 0); r > e; e++)
288		if (e in o && o[e] === n) return e;
289	return -1
290});
291var evento = function(n) {
292	var t, e, o, r = n,
293		i = r.document,
294		f = {};
295	return t = function() {
296		return "function" == typeof i.addEventListener ? function(n, t, e) {
297			n.addEventListener(t, e, !1), f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t].push(e)
298		} : "function" == typeof i.attachEvent ? function(n, t, e) {
299			n.attachEvent(t, e), f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t].push(e)
300		} : function(n, t, e) {
301			n["on" + t] = e, f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t].push(e)
302		}
303	}(), e = function() {
304		return "function" == typeof i.removeEventListener ? function(n, t, e) {
305			n.removeEventListener(t, e, !1), Helio.each(f[n][t], function(o) {
306				o === e && (f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t][f[n][t].indexOf(o)] = void 0)
307			})
308		} : "function" == typeof i.detachEvent ? function(n, t, e) {
309			n.detachEvent(t, e), Helio.each(f[n][t], function(o) {
310				o === e && (f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t][f[n][t].indexOf(o)] = void 0)
311			})
312		} : function(n, t, e) {
313			n["on" + t] = void 0, Helio.each(f[n][t], function(o) {
314				o === e && (f[n] = f[n] || {}, f[n][t] = f[n][t] || [], f[n][t][f[n][t].indexOf(o)] = void 0)
315			})
316		}
317	}(), o = function(n, t) {
318		f[n] = f[n] || {}, f[n][t] = f[n][t] || [];
319		for (var e = 0, o = f[n][t].length; o > e; e += 1) f[n][t][e]()
320	}, {
321		add: t,
322		remove: e,
323		trigger: o,
324		_handlers: f
325	}
326}(this);
327/*
328 * OKVideo by OKFocus v2.3.2
329 * http://okfoc.us
330 *
331 * Copyright 2014, OKFocus
332 * Licensed under the MIT license.
333 *
334 */
335var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array();
336// youtube player ready
337function onYouTubeIframeAPIReady() {
338	YTplayers = new Array();
339	jQuery('.no-touch .uncode-video-container.video').each(function() {
340		var playerY;
341		if (jQuery(this).attr('data-provider') == 'youtube') {
342			var id = jQuery(this).attr('data-id');
343			options = jQuery(window).data('okoptions-' + id);
344			options.time = jQuery(this).attr('data-t');
345			playerY = new YT.Player('okplayer-' + id, {
346				videoId: options.video ? options.video.id : null,
347				playerVars: {
348					'autohide': 1,
349					'autoplay': 0, //options.autoplay,
350					'disablekb': options.keyControls,
351					'cc_load_policy': options.captions,
352					'controls': options.controls,
353					'enablejsapi': 1,
354					'fs': 0,
355					'modestbranding': 1,
356					'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname),
357					'iv_load_policy': options.annotations,
358					'loop': options.loop,
359					'showinfo': 0,
360					'rel': 0,
361					'wmode': 'opaque',
362					'hd': options.hd
363				},
364				events: {
365					'onReady': OKEvents.yt.ready,
366					'onStateChange': OKEvents.yt.onStateChange,
367					'onError': OKEvents.yt.error
368				}
369			});
370			YTplayers[id] = playerY;
371			playerY.videoId = id;
372		}
373	});
374}
375// vimeo player ready
376function vimeoPlayerReady(id) {
377	options = jQuery(window).data('okoptions-' + id);
378	var jIframe = options.jobject,
379	iframe = jIframe[0];
380	jIframe.attr('src', jIframe.data('src'));
381	var playerV = $f(iframe);
382	// hide player until Vimeo hides controls...
383	playerV.addEvent('ready', function(e) {
384		OKEvents.v.onReady(iframe);
385		var carouselContainer = jQuery(iframe).closest('.owl-carousel');
386		if (carouselContainer.length) {
387			UNCODE.owlPlayVideo(carouselContainer);
388		}
389		// "Do not try to add listeners or call functions before receiving this event."
390		if (OKEvents.utils.isMobile()) {
391			// mobile devices cannot listen for play event
392			OKEvents.v.onPlay(playerV);
393		} else {
394			playerV.addEvent('play', OKEvents.v.onPlay(playerV));
395			playerV.addEvent('pause', OKEvents.v.onPause);
396			playerV.addEvent('finish', OKEvents.v.onFinish);
397		}
398		if (options.time != null) {
399			playerV.api('seekTo', (options.time).replace('t=', ''));
400		}
401
402		playerV.api('play');
403		jQuery(iframe).css({
404			visibility: 'visible',
405			opacity: 1
406		});
407
408	});
409}
410OKEvents = {
411	yt: {
412		ready: function(event) {
413			var id = event.target.videoId;
414			youtubePlayers[id] = event.target;
415			event.target.setVolume(options.volume);
416			if (options.autoplay === 1) {
417				if (options.playlist.list) {
418					player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality);
419				} else {
420					var inCarousel = jQuery('#okplayer-' + id).closest('.owl-item');
421					if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) {
422						if (options.time != null) {
423							event.target.seekTo(parseInt(options.time));
424						}
425						event.target.playVideo();
426					} else {
427						event.target.pauseVideo();
428					}
429				}
430			}
431			OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target);
432		},
433		onStateChange: function(event) {
434			var id = event.target.videoId;
435			switch (event.data) {
436				case -1:
437					OKEvents.utils.isFunction(options.unstarted) && options.unstarted();
438					break;
439				case 0:
440					OKEvents.utils.isFunction(options.onFinished) && options.onFinished();
441					options.loop && event.target.playVideo();
442					break;
443				case 1:
444					OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
445					setTimeout(function() {
446						UNCODE.initVideoComponent(document.body, '.uncode-video-container.video, .uncode-video-container.self-video');
447						jQuery('#okplayer-' + id).closest('.uncode-video-container').css('opacity', '1');
448					}, 300);
449					break;
450				case 2:
451					OKEvents.utils.isFunction(options.onPause) && options.onPause();
452					break;
453				case 3:
454					OKEvents.utils.isFunction(options.buffering) && options.buffering();
455					break;
456				case 5:
457					OKEvents.utils.isFunction(options.cued) && options.cued();
458					break;
459				default:
460					throw "OKVideo: received invalid data from YT player.";
461			}
462		},
463		error: function(event) {
464			throw event;
465		}
466	},
467	v: {
468		onReady: function(target) {
469			OKEvents.utils.isFunction(options.onReady) && options.onReady(target);
470		},
471		onPlay: function(player) {
472			if (!OKEvents.utils.isMobile()) player.api('setVolume', options.volume);
473			OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
474			jQuery(player.element).closest('.uncode-video-container').css('opacity', '1');
475		},
476		onPause: function() {
477			OKEvents.utils.isFunction(options.onPause) && options.onPause();
478		},
479		onFinish: function() {
480			OKEvents.utils.isFunction(options.onFinish) && options.onFinish();
481		}
482	},
483	utils: {
484		isFunction: function(func) {
485			if (typeof func === 'function') {
486				return true;
487			} else {
488				return false;
489			}
490		},
491		isMobile: function() {
492			if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
493				return true;
494			} else {
495				return false;
496			}
497		}
498	}
499};
500// DOM class helper
501(function(window) {
502	'use strict';
503	// class helper functions from bonzo https://github.com/ded/bonzo
504	function classReg(className) {
505			return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
506		}
507		// classList support for class management
508		// altho to be fair, the api sucks because it won't accept multiple classes at once
509	var hasClass, addClass, removeClass;
510	if ('classList' in document.documentElement) {
511		hasClass = function(elem, c) {
512			if (elem !== null) return elem.classList.contains(c);
513		};
514		addClass = function(elem, c) {
515			if (elem !== null) elem.classList.add(c);
516		};
517		removeClass = function(elem, c) {
518			if (elem !== null) elem.classList.remove(c);
519		};
520	} else {
521		hasClass = function(elem, c) {
522			if (elem !== null) return classReg(c).test(elem.className);
523		};
524		addClass = function(elem, c) {
525			if (!hasClass(elem, c)) {
526				if (elem !== null) elem.className = elem.className + ' ' + c;
527			}
528		};
529		removeClass = function(elem, c) {
530			if (elem !== null) elem.className = elem.className.replace(classReg(c), ' ');
531		};
532	}
533
534	function toggleClass(elem, c) {
535		var fn = hasClass(elem, c) ? removeClass : addClass;
536		fn(elem, c);
537	}
538	var classie = {
539		// full names
540		hasClass: hasClass,
541		addClass: addClass,
542		removeClass: removeClass,
543		toggleClass: toggleClass,
544		// short names
545		has: hasClass,
546		add: addClass,
547		remove: removeClass,
548		toggle: toggleClass
549	};
550	// transport
551	if (typeof define === 'function' && define.amd) {
552		// AMD
553		define(classie);
554	} else {
555		// browser global
556		window.classie = classie;
557	}
558})(window);
559/* From Modernizr */
560function whichTransitionEvent() {
561		var t;
562		var el = document.createElement('fakeelement');
563		var transitions = {
564			'transition': 'transitionend',
565			'OTransition': 'oTransitionEnd',
566			'MozTransition': 'transitionend',
567			'WebkitTransition': 'webkitTransitionEnd'
568		}
569		for (t in transitions) {
570			if (el.style[t] !== undefined) {
571				return transitions[t];
572			}
573		}
574	}
575/**
576 * Load utils - END
577 */
578
579/**
580 * Start main js
581 */
582(function(window, undefined) {
583	'use strict';
584	// Init variables
585	var bodyTop,
586		scrollbarWidth = false,
587		noScroll = false,
588		boxEvent = new CustomEvent('boxResized'),
589		bodyBorder = 0,
590		adminBarHeight = 0,
591		boxWidth = 0,
592		boxLeft = 0,
593		parallaxRows,
594		parallaxCols,
595		parallaxHeaders,
596		headerWithOpacity,
597		speedDivider = SiteParameters.parallax_factor,
598		adminBar,
599		pageHeader,
600		masthead,
601		mastheadMobile,
602		mastheadMobilePaddingTop = 0,
603		menuwrapper,
604		menuhide,
605		menusticky,
606		menuHeight = 0,
607		menuMobileHeight = 0,
608		mainmenu = new Array(),
609		secmenu = new Array(),
610		secmenuHeight = 0,
611		transmenuHeight = 0,
612		header,
613		transmenuel,
614		logo,
615		logoel,
616		logolink,
617		logoMinScale,
618		lastScrollValue = 0,
619		wwidth = window.innerWidth || document.documentElement.clientWidth,
620		wheight = window.innerHeight || document.documentElement.clientHeight,
621		boxWrapper,
622		docheight = 0,
623		isMobile = classie.hasClass(document.documentElement, 'touch') ? true : false,
624		isIE = classie.hasClass(document.documentElement, 'ie') || classie.hasClass(document.documentElement, 'opera12') ? true : false,
625		isFF = classie.hasClass(document.documentElement, 'firefox') ? true : false,
626		transitionEvent = whichTransitionEvent(),
627		footerScroller = false,
628		mediaQuery = 959,
629		mediaQueryMobile = 569,
630		menuOpened = false,
631		overlayOpened = false,
632		menuMobileTriggerEvent = new CustomEvent('menuMobileTrigged'),
633		resizeTimer,
634		hidingTimer,
635		isSplitMenu = false,
636		mainNavMenu,
637		mainNavWrapper,
638		isMobileTransparent = false,
639	initBox = function() {
640			var bodyBorderDiv = document.querySelectorAll('.body-borders .top-border');
641			if (bodyBorderDiv.length) {
642				bodyBorder = outerHeight(bodyBorderDiv[0]);
643			} else bodyBorder = 0;
644			UNCODE.bodyBorder = bodyBorder;
645			if (bodyBorder != 0) {
646				document.documentElement.style.marginTop = bodyBorder + 'px';
647				wheight = (window.innerHeight || document.documentElement.clientHeight) - (bodyBorder * 2);
648			}
649			if (!isMobile && !scrollbarWidth) {
650				// Create the measurement node
651				var scrollDiv = document.createElement("div");
652				scrollDiv.className = "scrollbar-measure";
653				var dombody = document.body;
654				if (dombody != null) {
655					dombody.appendChild(scrollDiv);
656					// Get the scrollbar width
657					scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
658					// Delete the DIV
659					dombody.removeChild(scrollDiv);
660				}
661			}
662			if (!isMobile) {
663				forEachElement('.box-container', function(el, i) {
664					if (!classie.hasClass(el, 'limit-width')) {
665						var elWidth = outerWidth(el),
666							newWidth = 12 * Math.ceil((wwidth - scrollbarWidth) / 12);
667						boxWidth = newWidth - (bodyBorder * 2);
668						boxLeft = (wwidth - boxWidth - scrollbarWidth) / 2;
669						el.style.width = boxWidth + 'px';
670						el.style.marginLeft = boxLeft + 'px';
671						if (mainmenu != undefined && mainmenu[0] != undefined) {
672							mainmenu[0].style.width = boxWidth + 'px';
673						}
674					}
675				});
676			}
677
678			if (classie.hasClass(document.body, 'menu-mobile-transparent')) isMobileTransparent = true;
679
680			if (!isMobileTransparent) {
681				if (wwidth > mediaQuery && classie.hasClass(document.body, 'menu-force-opacity')) classie.removeClass(document.body, 'menu-force-opacity');
682				if (wwidth < mediaQuery && !classie.hasClass(document.body, 'menu-force-opacity')) classie.addClass(document.body, 'menu-force-opacity');
683			}
684			
685		},
686		fixMenuHeight = function() {
687			if (!classie.hasClass(document.body, 'vmenu')) noScroll = true;
688			
689			menuwrapper = document.querySelectorAll(".menu-wrapper");
690			masthead = document.getElementById("masthead");
691			if (classie.hasClass(document.body, 'hmenu-center-split')) {
692				mastheadMobile = new Array(document.getElementById("logo-container-mobile"), document.getElementById("main-logo").parentNode);
693			} else mastheadMobile = document.getElementById("logo-container-mobile");
694			menuhide = document.querySelector('#masthead .menu-hide, .main-header .menu-hide, #masthead .menu-hide-vertical');
695			menusticky = document.querySelectorAll('.menu-sticky, .menu-sticky-vertical');
696			transmenuel = document.querySelectorAll('.menu-transparent:not(.vmenu-container)');
697			var menuItemsButton = document.querySelectorAll('.menu-item-button .menu-btn-table');
698			logo = document.querySelector('#main-logo');
699			if (logo != undefined) logolink = (logo.firstElementChild || logo.firstChild);
700			if (logolink != undefined) logoMinScale = logolink.getAttribute("data-minheight");
701			logoel = document.querySelectorAll('.menu-shrink .logo-container');
702			mainmenu = document.querySelectorAll('.vmenu .vmenu-container, .menu-primary .menu-container');
703			if (classie.hasClass(document.body, 'hmenu-center')) {
704				var mainmenucenter = document.querySelectorAll('.hmenu-center .menu-container-mobile');
705				var first_array = Array.prototype.slice.call(mainmenu);
706				var second_array = Array.prototype.slice.call(mainmenucenter);
707				mainmenu = first_array.concat(second_array);
708			}
709			secmenu = document.querySelectorAll('.menu-secondary');
710			calculateMenuHeight(true);
711			for (var k = 0; k < menuItemsButton.length; k++) {
712				var a_item = menuItemsButton[k].parentNode,
713					buttonHeight = outerHeight(menuItemsButton[k]);
714				a_item.style.height = buttonHeight + 'px';
715			}
716			if (classie.hasClass(document.body, 'hmenu-center-split')) {
717				mainNavMenu = document.querySelector('#masthead .navbar-main .menu-primary-inner');
718				mainNavWrapper = document.querySelector('#masthead > .menu-container');
719				isSplitMenu = true;
720			}
721		},
722		calculateMenuHeight = function(first) {
723			menuHeight = transmenuHeight = secmenuHeight = 0;
724
725			if (mastheadMobile != null) {
726				if (mastheadMobile.length === 2) {
727					if (wwidth > mediaQuery) {
728						UNCODE.menuMobileHeight = outerHeight(mastheadMobile[1]);
729						mastheadMobilePaddingTop = parseFloat(getComputedStyle(mastheadMobile[1]).paddingTop);
730					} else {
731						UNCODE.menuMobileHeight = outerHeight(mastheadMobile[0]);
732						mastheadMobilePaddingTop = parseFloat(getComputedStyle(mastheadMobile[0]).paddingTop);
733					}
734				} else {
735					UNCODE.menuMobileHeight = outerHeight(mastheadMobile);
736					mastheadMobilePaddingTop = parseFloat(getComputedStyle(mastheadMobile).paddingTop);
737				}
738			}
739
740			if (wwidth > mediaQuery) {
741				for (var i = 0; i < mainmenu.length; i++) {
742					if (classie.hasClass(document.body, 'hmenu-center') && i === 1) continue;
743					if (!classie.hasClass(masthead, 'masthead-vertical')) {
744						menuHeight = menuHeight + outerHeight(mainmenu[i]);
745					} else menuHeight = 0;
746
747					if (isIE && first) {
748						getDivChildren(mainmenu[i], '.menu-horizontal-inner', function(innerMenu, i) {
749							innerMenu.style.height = menuHeight + 'px';
750						});
751					}
752
753					if (classie.hasClass(mainmenu[i].parentNode, 'menu-transparent')) {
754						transmenuHeight += menuHeight;
755					}
756				}
757
758				for (var j = 0; j < secmenu.length; j++) {
759					secmenuHeight += outerHeight(secmenu[j]);
760				}
761				menuHeight += secmenuHeight;
762			} else {
763				menuHeight = UNCODE.menuMobileHeight;
764				if (isMobileTransparent) {
765					for (var i = 0; i < mainmenu.length; i++) {
766						if (classie.hasClass(mainmenu[i].parentNode, 'menu-transparent')) {
767							transmenuHeight += menuHeight;
768						}
769					}
770				}
771				var search_box = document.querySelectorAll('.search-icon .drop-menu');
772				for (var i = 0; i < search_box.length; i++) {
773					search_box[i].removeAttribute('style');
774				}
775			}
776
777
778			if (classie.hasClass(document.documentElement, 'admin-mode')) {
779				adminBar = document.getElementById("wpadminbar");
780				if (wwidth > 600) {
781					if (adminBar != null) adminBarHeight = outerHeight(adminBar);
782					else {
783						if (wwidth > 782) adminBarHeight = 32;
784						else adminBarHeight = 46;
785					}
786				} else adminBarHeight = 0;
787			}
788			UNCODE.adminBarHeight = adminBarHeight;
789			UNCODE.menuHeight = menuHeight;
790
791			if (masthead != undefined) {
792				//masthead.parentNode.style.height = menuHeight + 'px';
793				if (classie.hasClass(masthead, 'menu-transparent')) {
794					if (wwidth > mediaQuery) masthead.parentNode.style.height = '0px';
795				}
796			}
797
798			if (typeof menuhide == 'object' && menuhide != null && mainmenu[0] != undefined) {
799				var sticky_element = (typeof mainmenu.item === 'undefined' ? ((wwidth > mediaQuery) ? mainmenu[0] : mainmenu[1]) : mainmenu[0]);
800				if (sticky_element.style.top != '') {
801					sticky_element.style.top = UNCODE.bodyBorder + 'px'
802				}
803			}
804
805		},
806		centerSplitMenu = function() {
807			if (wwidth > mediaQuery && mainNavMenu) {
808				if (mainNavMenu.style.left == '') {
809					mainNavMenu.style.left = '0px';
810					var logoPos = logo.parentNode.getBoundingClientRect();
811					mainNavMenu.style.left = (wwidth / 2) - (logoPos.left + (logoPos.width / 2) ) + 'px';
812					mainNavWrapper.style.opacity = '1';
813				}
814			}
815		},
816		initHeader = function() {
817			UNCODE.adaptive();
818			headerHeight('.header-wrapper');
819			parallaxHeaders = document.querySelectorAll('.header-parallax > .header-bg-wrapper > .header-bg');
820			header = document.querySelectorAll('.header-wrapper.header-uncode-block, .header-wrapper.header-revslider, .header-basic .header-wrapper, .header-uncode-block > .row-container:first-child > .row > .row-inner > .col-lg-12 > .uncol, .header-uncode-block .uncode-slider .owl-carousel > .row-container:first-child .col-lg-12 .uncoltable');
821			headerWithOpacity = document.querySelectorAll('.header-scroll-opacity');
822			pageHeader = document.getElementById("page-header");
823			if (pageHeader != undefined) {
824				var backs = pageHeader.querySelectorAll('.header-bg'),
825					backsCarousel = pageHeader.querySelectorAll('.header-uncode-block .background-inner'),
826					uri_pattern = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig;
827				if (backs.length == 0 && backsCarousel.length == 0) {
828					pageHeader.setAttribute('data-imgready', 'true');
829				} else {
830					if (backsCarousel.length) {
831						for (var j = 0; j < backsCarousel.length; j++) {
832							if (j == 0) {
833								if (!!backsCarousel[j].style.backgroundImage && backsCarousel[j].style.backgroundImage !== void 0) {
834									var url = (backsCarousel[j].style.backgroundImage).match(uri_pattern),
835										image = new Image();
836									image.onload = function() {
837										pageHeader.setAttribute('data-imgready', 'true');
838									};
839									image.src = url[0];
840								} else {
841									pageHeader.setAttribute('data-imgready', 'true');
842								}
843							}
844						}
845					} else {
846						for (var i = 0; i < backs.length; i++) {
847							if (i == 0) {
848								if (!!backs[i].style.backgroundImage && backs[i].style.backgroundImage !== void 0) {
849									var url = (backs[i].style.backgroundImage).match(uri_pattern),
850										image = new Image();
851									image.onload = function() {
852										pageHeader.setAttribute('data-imgready', 'true');
853									};
854									image.src = url[0];
855								} else {
856									pageHeader.setAttribute('data-imgready', 'true');
857								}
858							}
859						}
860					}
861				}
862			}
863
864			if (masthead != undefined && !classie.hasClass(masthead, 'masthead-vert
864ical')) {
865				if (header.length) {
866					masthead.parentNode.style.height = menuHeight + 'px';
867					if (menuwrapper[0] != undefined) classie.addClass(menuwrapper[0], 'with-header');
868					for (var j = 0; j < header.length; j++) {
869						var headerel = header[j],
870							closestStyle = getClosest(headerel, 'style-light');
871						if (closestStyle != null && classie.hasClass(closestStyle, 'style-light')) switchColorsMenu(0, 'light');
872						else if (getClosest(headerel, 'style-dark') != null) switchColorsMenu(0, 'dark');
873						else {
874							if (masthead.style.opacity !== 1) masthead.style.opacity = 1;
875						}
876						if (classie.hasClass(masthead, 'menu-transparent')) {
877							if (isMobileTransparent || wwidth > mediaQuery) {
878								masthead.parentNode.style.height = '0px'; 	
879								if (classie.hasClass(masthead, 'menu-add-padding')) {
880									var headerBlock = getClosest(headerel, 'header-uncode-block');
881									if (headerBlock != null) {
882										var innerRows = headerel.querySelectorAll('.column_parent > .uncol > .uncoltable > .uncell > .uncont, .uncode-slider .column_child > .uncol > .uncoltable > .uncell > .uncont');
883										for (var k = 0; k < innerRows.length; k++) {
884											if (innerRows[k] != undefined) {
885												if (wwidth > mediaQuery) innerRows[k].style.paddingTop = transmenuHeight + 'px';
886												else innerRows[k].style.paddingTop = (transmenuHeight - mastheadMobilePaddingTop) + 'px';
887											}
888										}
889									} else {
890										getDivChildren(headerel, '.header-content', function(headerContent, i) {
891											if (wwidth > mediaQuery) headerContent.style.paddingTop = transmenuHeight + 'px';
892											else headerContent.style.paddingTop = (transmenuHeight - mastheadMobilePaddingTop) + 'px';
893										});
894									}
895								}
896							}
897						}
898					}
899				} else {
900					if (menuwrapper[0] != undefined) classie.addClass(menuwrapper[0], 'no-header');
901					classie.removeClass(masthead, 'menu-transparent');
902					transmenuHeight = 0;
903					isMobileTransparent = false;
904				}
905			} else {
906				isMobileTransparent = false;
907			}
908			if (!transmenuel.length) isMobileTransparent = false;
909			bodyTop = document.documentElement['scrollTop'] || document.body['scrollTop'];
910			UNCODE.bodyTop = bodyTop;
911			scrollFunction();
912			showHideScrollup(bodyTop);
913		},
914		initRow = function(currentRow) {
915			UNCODE.adaptive();
916			var el = currentRow.parentNode.parentNode.getAttribute("data-parent") == 'true' ? currentRow.parentNode : currentRow.parentNode.parentNode,
917				rowParent = el.parentNode,
918				rowInner = currentRow.parentNode,
919				percentHeight = el.getAttribute("data-height-ratio"),
920				minHeight = el.getAttribute("data-minheight"),
921				calculateHeight,
922				calculatePadding = 0,
923				isHeader = false,
924				isFirst = false,
925				uri_pattern = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig;
926
927			/** Add class to the row when contains responsive column size */
928			getDivChildren(el.parentNode, '.column_parent, .column_child', function(obj, i, total) {
929				if ((obj.className).indexOf("col-md-") > - 1) classie.addClass(obj.parentNode, 'cols-md-responsive');
930				if ((obj.className).indexOf("col-sm-") > - 1) classie.addClass(obj.parentNode, 'cols-sm-responsive');
931			});
932
933			setRowHeight(el);
934
935			var elements = 0;
936			getDivChildren(el, '.row-internal .background-inner', function(obj, i, total) {
937				elements++;
938				if (i == 0) {
939					if (!!obj.style.backgroundImage && obj.style.backgroundImage !== void 0) {
940						var url = (obj.style.backgroundImage).match(uri_pattern),
941							image = new Image();
942						image.onload = function() {
943							el.setAttribute('data-imgready', 'true');
944							el.dispatchEvent(new CustomEvent('imgLoaded'));
945						};
946						image.src = url[0];
947					} else {
948						el.setAttribute('data-imgready', 'true');
949						el.dispatchEvent(new CustomEvent('imgLoaded'));
950					}
951				}
952			});
953			if (elements == 0) {
954				el.setAttribute('data-imgready', 'true');
955			}
956
957			/** init parallax is not mobile */
958			if (!UNCODE.isMobile) {
959				parallaxRows = el.parentNode.parentNode.querySelectorAll('.with-parallax > .row-background > .background-wrapper');
960				parallaxCols = el.querySelectorAll('.with-parallax > .column-background > .background-wrapper');
961				bodyTop = document.documentElement['scrollTop'] || document.body['scrollTop'];
962				UNCODE.bodyTop = bodyTop;
963				parallaxRowCol(bodyTop);
964			}
965		},
966		setRowHeight = function(container, forced, resized) {
967			var currentTallest = 0,
968				percentHeight = 0,
969				minHeight = 0,
970				el,
971				child,
972				hasSubCols = false;
973			if (container.length == undefined) {
974				container = [container];
975			}
976			// Loop for each container element to match their heights
977			for (var i = 0; i < container.length; i++) {
978				var el = container[i],
979					$row = el,
980					totalHeight = 0,
981					colsArray = new Array(),
982					calculatePadding = 0,
983					$rowParent = $row.parentNode,
984					isHeader = false,
985					isFirst = false;
986				$row.oversized = false;
987				percentHeight = el.getAttribute("data-height-ratio");
988				minHeight = el.getAttribute("data-minheight");
989				child = (el.firstElementChild || el.firstChild);
990				var childHeight = outerHeight(child);
991				/** window height without header **/
992				if (!!percentHeight || !!minHeight || forced || (isIE && classie.hasClass(el, 'unequal'))) {
993					child.style.height = '';
994					if (!!percentHeight) {
995						if (percentHeight == 'full') {
996							currentTallest = parseInt(wheight);
997						} else {
998							currentTallest = parseInt((wheight * percentHeight) / 100);
999						}
1000					} else {
1001						currentTallest = el.clientHeight;
1002					}
1003
1004					if (!!minHeight) {
1005						if (currentTallest < minHeight || currentTallest == undefined) currentTallest = parseInt(minHeight);
1006					}
1007
1008					var computedStyleRow = getComputedStyle(el),
1009						computedStyleRowParent = getComputedStyle($rowParent);
1010					calculatePadding -= (parseFloat(computedStyleRow.paddingTop) + parseFloat(computedStyleRowParent.paddingTop));
1011					calculatePadding -= (parseFloat(computedStyleRow.paddingBottom) + parseFloat(computedStyleRowParent.paddingBottom));
1012					if (getClosest(el, 'header-uncode-block') != null) {
1013						el.setAttribute('data-row-header', 'true');
1014						isHeader = true;
1015					} else {
1016						if (pageHeader == null) {
1017							var prevRow = $rowParent.previousSibling;
1018							if (prevRow != null && prevRow.innerText == 'UNCODE.initHeader();') {
1019								isFirst = true;
1020							}
1021						}
1022					}
1023
1024					if (classie.hasClass(el, 'row-slider')) {
1025						percentHeight = el.getAttribute("data-height-ratio");
1026						minHeight = el.getAttribute("data-minheight");
1027						if (percentHeight == 'full') {
1028							currentTallest = parseInt(wheight);
1029						} else {
1030							currentTallest = parseInt((wheight * percentHeight) / 100);
1031						}
1032
1033						if (isHeader || isFirst) {
1034							if (isMobileTransparent || wwidth > mediaQuery) currentTallest -= menuHeight - transmenuHeight;
1035							else currentTallest -= menuHeight - secmenuHeight;
1036							currentTallest += calculatePadding;
1037						} else {
1038							if (isMobileTransparent || wwidth > mediaQuery) currentTallest += calculatePadding;
1039							else currentTallest = 'auto';
1040						}
1041
1042						getDivChildren(el, '.owl-carousel', function(owl, i) {
1043							owl.style.height = (currentTallest == 'auto' ? 'auto' : currentTallest + 'px');
1044							if (isIE) {
1045								getDivChildren(owl, '.owl-stage', function(owlIn, i) {
1046									owlIn.style.height = (currentTallest == 'auto' ? '100%' : currentTallest + 'px');
1047								});
1048							}
1049						});
1050						continue;
1051					} else {
1052						if (isHeader || isFirst) {
1053							if (isMobileTransparent || wwidth > mediaQuery) currentTallest -= menuHeight - transmenuHeight;
1054							else currentTallest -= menuHeight - secmenuHeight;
1055							currentTallest += calculatePadding;
1056						} else {
1057							if (isMobileTransparent || wwidth > mediaQuery) currentTallest += calculatePadding;
1058							else currentTallest = 'auto';
1059						}
1060					}
1061					if (!!minHeight) {
1062						if (currentTallest < minHeight || currentTallest == 'auto') currentTallest = parseInt(minHeight);
1063					}
1064
1065					child.style.height = (currentTallest == 'auto' ? 'auto' : currentTallest + 'px');
1066				} else {
1067					currentTallest = 0;
1068				}
1069
1070				if (wwidth > mediaQuery) {
1071
1072					getDivChildren(el, '.column_parent', function(col, i, total) {
1073						var $col = col,
1074							$colHeight = 0,
1075							$colDiff = 0,
1076							$colPercDiff = 100;
1077						$col.oversized = false;
1078						$col.forceHeight = currentTallest;
1079						currentTallest = child.clientHeight;
1080						if ((isHeader || isFirst) && currentTallest != 'auto') currentTallest -= transmenuHeight;
1081						var getFirstCol = null, 
1082						getMargin = 0,
1083						getSubMargin = 0;
1084						getDivChildren(col, '.row-child', function(obj, i, total) {
1085							var $colChild = obj,
1086								$colParent = $colChild.parentNode,
1087								computedStyleCol = getComputedStyle($colParent);
1088							parseFloat(computedStyleCol.marginTop);
1089							getSubMargin += parseFloat(computedStyleCol.marginTop);
1090						});
1091						currentTallest += getSubMargin;
1092						getDivChildren(col, '.row-child', function(obj, i, total) {
1093							var $colChild = obj,
1094								$colInner = $colChild.children[0],
1095								$colParent = $colChild.parentNode,
1096								$uncont = $colParent.parentNode;
1097							if (i == 0 && total > 1) getFirstCol = $colInner;
1098							$colChild.oversized = false;
1099							percentHeight = $colChild.getAttribute("data-height");
1100							minHeight = $colChild.getAttribute("data-minheight");
1101							if (percentHeight != null || minHeight != null) {
1102								$colInner.style.height = '';
1103								$colParent.style.height = 'auto';
1104								$uncont.style.height = '100%';
1105								$colChild.removeAttribute("style");
1106								var newHeight = (percentHeight != null) ? Math.ceil((currentTallest) * (percentHeight / 100)) : parseInt(minHeight);
1107								var computedStyleCol = getComputedStyle($colParent);
1108								parseFloat(computedStyleCol.marginTop);
1109								getMargin = parseFloat(computedStyleCol.marginTop);
1110								newHeight -= (getMargin);
1111								$colPercDiff -= (percentHeight != null) ? percentHeight : 0;
1112								if (currentTallest > newHeight) {
1113									var getColHeight = outerHeight($colChild);
1114									if (getColHeight > newHeight) {
1115										$colHeight += getColHeight;
1116										$colDiff += getColHeight;
1117										$colChild.oversized = true;
1118										$col.oversized = true;
1119										$row.oversized = true;
1120									} else {
1121										$colHeight += newHeight;
1122										$colInner.style.height = newHeight + 'px';
1123									}
1124								}
1125							} else {
1126								$colHeight += outerHeight($colChild);
1127							}
1128						});
1129						if (getFirstCol != null) {
1130							getFirstCol.style.height = (parseFloat(getFirstCol.style.height) - getMargin) + 'px';
1131						}
1132						colsArray.push({
1133							colHeight: $colHeight,
1134							colDiv: $col
1135						});
1136						$col.colDiff = $colDiff;
1137						$col.colPercDiff = $colPercDiff;
1138					});
1139
1140					if ($row.oversized) {
1141						child.style.height = '';
1142						colsArray.sort(function(a, b) {
1143							if (a.colHeight < b.colHeight) return 1;
1144							if (a.colHeight > b.colHeight) return -1;
1145							return 0;
1146						});
1147						var $totalHeight = 0;
1148						colsArray.forEach(function(col) {
1149							var $col = col.colDiv,
1150								$colHeight = col.colHeight;
1151							getDivChildren($col, '.row-child', function(obj, i, total) {
1152								var $colChild = obj,
1153									$colInner = $colChild.children[0],
1154									percentHeight = $colChild.getAttribute("data-height"),
1155									$colParent = $colChild.parentNode,
1156									$uncont = $colParent.parentNode,
1157									newHeight;
1158								//console.log(percentHeight);
1159								$colHeight = $col.forceHeight - $col.colDiff;
1160								if (percentHeight != null) {
1161									if ($colHeight > 0) {
1162										if ($col.oversized) {
1163											if (!$colChild.oversized) {
1164												newHeight = Math.ceil(($colHeight) * (percentHeight / $col.colPercDiff));
1165												if (i == total - 1 && total > 1) {
1166													$uncont.style.height = 'auto';
1167													$colChild.style.display = 'none';
1168													newHeight = outerHeight($col.parentNode) - outerHeight($uncont);
1169													$uncont.style.height = '100%';
1170													$colChild.style.display = 'table';
1171												}
1172												if (newHeight == 0) newHeight = Math.ceil(($col.forceHeight) * (percentHeight / 100));
1173												$colInner.style.height = newHeight + 'px';
1174											}
1175										} else {
1176											if ($totalHeight == 0) newHeight = Math.ceil(($colHeight) * (percentHeight / $col.colPercDiff));
1177											else {
1178												newHeight = Math.ceil(($totalHeight) * (percentHeight / $col.colPercDiff));
1179											}
1180											if (i == total - 1 && total > 1) {
1181												$uncont.style.height = 'auto';
1182												$colChild.style.display = 'none';
1183												newHeight = outerHeight($col.parentNode) - outerHeight($uncont);
1184												$uncont.style.height = '100%';
1185												$colChild.style.display = 'table';
1186											}
1187											$colInner.style.height = newHeight + 'px';
1188										}
1189									} else {
1190										if ($colChild.oversized) {
1191											if ($totalHeight == 0) newHeight = Math.ceil(($colHeight) * (percentHeight / $col.colPercDiff));
1192											else {
1193												if ($col.colPercDiff == 0) $col.colPercDiff = 100;
1194												newHeight = Math.ceil(($totalHeight) * (percentHeight / $col.colPercDiff));
1195											}
1196											if (i == total - 1 && total > 1) {
1197												$uncont.style.height = 'auto';
1198												$colChild.style.display = 'none';
1199												newHeight = outerHeight($col.parentNode) - outerHeight($uncont);
1200												$uncont.style.height = '100%';
1201												$colChild.style.display = 'table';
1202											}
1203											$colInner.style.height = newHeight + 'px';
1204										}
1205									}
1206								}
1207							});
1208							var uncell = $col.getElementsByClassName('uncell');
1209							if (uncell[0] != undefined && $totalHeight == 0) $totalHeight = outerHeight(uncell[0]);
1210						});
1211					}
1212					if (isFF) {
1213						getDivChildren(el, '.uncoltable', function(col, i, total) {
1214							if (col.style.minHeight != '') {
1215								col.style.height = '';
1216							}
1217						});
1218					}
1219					if (resized) {
1220						getDivChildren(el, '.row-child > .row-inner', function(obj, k, total) {
1221							if (obj.style.height == '') {
1222								if (wwidth > mediaQueryMobile) {
1223									var getStyle = (window.getComputedStyle((obj.parentNode), null)),
1224									getInnerHeight = (parseInt(obj.parentNode.clientHeight) - parseInt(getStyle.paddingTop) - parseInt(getStyle.paddingBottom));
1225									obj.style.height = getInnerHeight + 1 + 'px';
1226									obj.style.marginBottom = '-1px';
1227								}
1228							}
1229						});
1230						getDivChildren(el, '.row-parent > .row-inner', function(obj, k, total) {
1231							if (obj.style.height != '') {
1232								var getStyle = (window.getComputedStyle((obj.parentNode), null)),
1233								getInnerHeight = (parseInt(obj.parentNode.clientHeight) - parseInt(getStyle.paddingTop) - parseInt(getStyle.paddingBottom)),
1234								getTempHeight = parseInt(obj.style.height);
1235								if (getInnerHeight > getTempHeight) {
1236									obj.style.height = getInnerHeight + 1 + 'px';
1237									obj.style.marginBottom = '-1px';
1238								}
1239							}
1240						});
1241					}
1242				} else {
1243					if (isFF) {
1244						getDivChildren(el, '.uncoltable', function(col, i, total) {
1245							if (col.style.minHeight != '') {
1246								col.style.height = '';
1247								col.style.height = outerHeight(col.parentNode) + 'px';
1248							}
1249						});
1250					}
1251					if (isIE && (wwidth > mediaQueryMobile)) {
1252						if (child.style.height == 'auto') {
1253							child.style.height = outerHeight(child) + 'px';
1254						}
1255					}
1256				}
1257				if (isFF) {
1258					var sliderColumnFix = document.querySelector('.uncode-slider .row-inner > .column_child:only-child');
1259					if (sliderColumnFix != null) {
1260						if (wwidth > mediaQuery) {
1261							sliderColumnFix.style.setProperty("height", "");
1262						} else {
1263							sliderColumnFix.style.setProperty("height", "");
1264							sliderColumnFix.style.setProperty("height", outerHeight(sliderColumnFix.parentNode) + "px", "important");
1265						}
1266					}
1267				}
1268			};
1269		},
1270		headerHeight = function(container) {
1271			forEachElement(container, function(el, i) {
1272				var getHeight = el.getAttribute("data-height"),
1273					newHeight = ((wheight * getHeight) / 100);
1274				if (getHeight != 'fixed' && newHeight != 0) {
1275					if (isMobileTransparent || wwidth > mediaQuery) newHeight -= menuHeight - transmenuHeight;
1276					else newHeight -= menuHeight - secmenuHeight;
1277					el.style.height = newHeight + 'px';
1278				}
1279			});
1280			if (masthead != undefined) {
1281				masthead.parentNode.style.height = menuHeight + 'px';
1282				if (header != undefined && header.length) {
1283					if (classie.hasClass(masthead, 'menu-transparent')) {
1284						if (isMobileTransparent || wwidth > mediaQuery) {
1285							masthead.parentNode.style.height = '0px'; 
1286							if (classie.hasClass(masthead, 'menu-add-padding')) {
1287								for (var j = 0; j < header.length; j++) {
1288									var headerel = header[j];
1289									var headerBlock = getClosest(headerel, 'header-uncode-block');
1290									if (headerBlock != null) {
1291										var innerRows = headerel.querySelectorAll('.column_parent > .uncol > .uncoltable > .uncell > .uncont, .uncode-slider .column_child > .uncol > .uncoltable > .uncell > .uncont');
1292										for (var k = 0; k < innerRows.length; k++) {
1293											if (innerRows[k] != undefined) {
1294												if (wwidth > mediaQuery) innerRows[k].style.paddingTop = transmenuHeight + 'px';
1295												else innerRows[k].style.paddingTop = (transmenuHeight - mastheadMobilePaddingTop) + 'px';
1296											}
1297										}
1298									} else {
1299										getDivChildren(headerel, '.header-content', function(headerContent, i) {
1300											if (wwidth > mediaQuery) headerContent.style.paddingTop = transmenuHeight + 'px';
1301											else headerContent.style.paddingTop = (transmenuHeight - mastheadMobilePaddingTop) + 'px';
1302										});
1303									}
1304								}
1305							}
1306						}
1307					}
1308				}
1309			}
1310		},
1311		initVideoComponent = function(container, classTarget) {
1312			getDivChildren(container, classTarget, function(el, i) {
1313				var width = outerWidth(el),
1314					pWidth, // player width, to be defined
1315					height = outerHeight(el),
1316					pHeight, // player height, tbd
1317					$tubularPlayer = (el.getElementsByTagName('iframe').length == 1) ? el.getElementsByTagName('iframe') : el.getElementsByTagName('video'),
1318					ratio = (el.getAttribute("data-ratio") != null) ? Number(el.getAttribute("data-ratio")) : null,
1319					heightOffset = 80,
1320					widthOffset = heightOffset * ratio;
1321				// when screen aspect ratio differs from video, video must center and underlay one dimension
1322				if ($tubularPlayer[0] != undefined) {
1323					if (width / ratio < height) { // if new video height < window height (gap underneath)
1324						pWidth = Math.ceil((height + heightOffset) * ratio); // get new player width
1325						$tubularPlayer[0].style.width = pWidth + widthOffset + 'px';
1326						$tubularPlayer[0].style.height = height + heightOffset + 'px';
1327						$tubularPlayer[0].style.left = ((width - pWidth) / 2) - (widthOffset / 2) + 'px';
1328						$tubularPlayer[0].style.top = '-' + (heightOffset / 2) + 'px';
1329						$tubularPlayer[0].style.position = 'absolute';
1330					} else { // new video width < window width (gap to right)
1331						pHeight = Math.ceil(width / ratio); // get new player height
1332						$tubularPlayer[0].style.width = width + widthOffset + 'px';
1333						$tubularPlayer[0].style.height = pHeight + heightOffset + 'px';
1334						$tubularPlayer[0].style.left = '-' + (widthOffset / 2) + 'px';
1335						$tubularPlayer[0].style.top = ((height - pHeight) / 2) - (heightOffset / 2) + 'px';
1336						$tubularPlayer[0].style.position = 'absolute';
1337					}
1338				}
1339			});
1340		},
1341		init_overlay = function() {
1342			var triggerButton,
1343			closeButtons = new Array();
1344			function toggleOverlay(btn) {
1345				Array.prototype.forEach.call(document.querySelectorAll('div.overlay'), function(overlay) {
1346					if (btn.getAttribute('data-area') == overlay.getAttribute('data-area')) {
1347						var container = document.querySelector('div.' + btn.getAttribute('data-container')),
1348							inputField = overlay.querySelector('.search-field');
1349						if (classie.has(overlay, 'open')) {
1350							overlayOpened = false;
1351							classie.remove(overlay, 'open');
1352							classie.remove(container, 'overlay-open');
1353							classie.add(overlay, 'close');
1354							classie.remove(overlay, 'open-items');
1355							var onEndTransitionFn = function(ev) {
1356								if (transitionEvent) {
1357									if (ev.propertyName !== 'visibility') return;
1358									this.removeEventListener(transitionEvent, onEndTransitionFn);
1359								}
1360								classie.remove(overlay, 'close');
1361							};
1362							if (transitionEvent) {
1363								overlay.addEventListener(transitionEvent, onEndTransitionFn);
1364							} else {
1365								onEndTransitionFn();
1366							}
1367						} else if (!classie.has(overlay, 'close')) {
1368							overlayOpened = true;
1369							classie.add(overlay, 'open');
1370							classie.add(container, 'overlay-open');
1371							if (jQuery('body.menu-overlay').length == 0) {
1372								setTimeout(function() {
1373									inputField.focus();
1374								}, 1000);
1375							}
1376							setTimeout(function() {
1377								if (classie.has(overlay, 'overlay-sequential')) classie.add(overlay, 'open-items');
1378							}, 800);
1379						}
1380					}
1381				});
1382
1383				if (classie.hasClass(btn, 'search-icon') || classie.hasClass(btn, 'menu-close-search')) return;
1384
1385				if (classie.hasClass(triggerButton, 'close')) {
1386					UNCODE.menuOpened = false;
1387					classie.removeClass(triggerButton, 'close');
1388					classie.addClass(triggerButton, 'closing');
1389					Array.prototype.forEach.call(closeButtons, function(closeButton) {
1390						if (!classie.hasClass(closeButton, 'menu-close-search')) {
1391							classie.removeClass(closeButton, 'close');
1392							classie.addClass(closeButton, 'closing');
1393						}
1394					});
1395					setTimeout(function() {
1396						classie.removeClass(triggerButton, 'closing');
1397						triggerButton.style.opacity = 1;
1398						Array.prototype.forEach.call(closeButtons, function(closeButton) {
1399							if (!classie.hasClass(closeButton, 'menu-close-search')) {
1400								classie.removeClass(closeButton, 'closing');
1401								closeButton.style.opacity = 0;
1402							}
1403						});
1404					}, 800);
1405				} else {
1406					UNCODE.menuOpened = true;
1407					triggerButton.style.opacity = 0;
1408					var getBtnRect = !classie.hasClass(triggerButton, 'search-icon') ? triggerButton.getBoundingClientRect() : null;
1409					Array.prototype.forEach.call(closeButtons, function(closeButton) {
1410						if (!classie.hasClass(closeButton, 'menu-close-search')) {
1411							classie.addClass(triggerButton, 'close');
1412							if (getBtnRect != null) closeButton.setAttribute('style', 'top:' + getBtnRect.top + 'px; left:'+ getBtnRect.left + 'px !important');
1413							classie.addClass(closeButton, 'close');
1414							closeButton.style.opacity = 1;
1415						}
1416					});
1417					window.addEventListener("resize", function() {
1418						positionCloseBtn(triggerButton, closeButtons);
1419					});
1420				}
1421			}
1422			function positionCloseBtn(triggerButton, closeButtons){
1423				var getBtnRect = !classie.hasClass(triggerButton, 'search-icon') ? triggerButton.getBoundingClientRect() : null;
1424				Array.prototype.forEach.call(closeButtons, function(closeButton) {
1425					if (!classie.hasClass(closeButton, 'menu-close-search')) {
1426						if (getBtnRect != null) closeButton.setAttribute('style', 'top:' + getBtnRect.top + 'px; left:'+ getBtnRect.left + 'px !important');
1427						closeButton.style.opacity = 1;
1428					}
1429				});
1430			}
1431			(function bindEscape() {
1432				document.onkeydown = function(evt) {
1433			    evt = evt || window.event;
1434			    var isEscape = false;
1435			    if ("key" in evt) {
1436			       isEscape = (evt.key == "Escape" || evt.key == "Esc");
1437			    } else {
1438			      isEscape = (evt.keyCode == 27);
1439			    }
1440			    if (isEscape && overlayOpened) {
1441			      Array.prototype.forEach.call(closeButtons, function(closeButton) {
1442			      	if (classie.hasClass(closeButton, 'overlay-close') && classie.hasClass(closeButton, 'menu-button-overlay')) {
1443			      		closeButton.click();
1444			      	}
1445			      });
1446			    }
1447				};
1448			})();
1449			Array.prototype.forEach.call(document.querySelectorAll('.trigger-overlay'), function(triggerBttn) {
1450				if (UNCODE.menuOpened) return;
1451				triggerBttn.addEventListener('click', function(e) {
1452					triggerButton = e.currentTarget;
1453					if (wwidth < mediaQuery && classie.hasClass(triggerButton, 'search-icon')) {
1454						return true;
1455					} else {
1456						e.stopPropagation();
1457						if (wwidth > mediaQuery) toggleOverlay(triggerButton);
1458						else {
1459							if (classie.addClass(triggerButton, 'search-icon')) return true;
1460						}
1461						e.preventDefault();
1462						return false;
1463					}
1464				}, false);
1465			});
1466			Array.prototype.forEach.call(document.querySelectorAll('.overlay-close'), function(closeBttn) {
1467				closeButtons.push(closeBttn);
1468				closeBttn.addEventListener('click', function(e) {
1469					if (wwidth > mediaQuery) toggleOverlay(closeBttn);
1470					e.preventDefault();
1471					return false;
1472				}, false);
1473			});
1474		},
1475		/** All scrolling functions - Begin */
1476		/** Shrink menu **/
1477		shrinkMenu = function(bodyTop) {
1478			var logoShrink,
1479				offset = 100;
1480			for (var i = 0; i < logoel.length; i++) {
1481				if (((secmenuHeight == 0) ? bodyTop > menuHeight : bodyTop > secmenuHeight + offset) && !classie.hasClass(logoel[i], 'shrinked') && (wwidth > mediaQuery)) {
1482					classie.addClass(logoel[i], 'shrinked');
1483					if (logoMinScale != undefined) {
1484						logoShrink = logolink.children;
1485						Array.prototype.forEach.call(logoShrink, function(singleLogo) {
1486							singleLogo.style.height = logoMinScale + 'px';
1487							singleLogo.style.lineHeight = logoMinScale + 'px';
1488							if (classie.hasClass(singleLogo, 'text-logo')) singleLogo.style.fontSize = logoMinScale + 'px';
1489						});
1490					}
1491					setTimeout(function() {
1492						calculateMenuHeight(false);
1493						//window.dispatchEvent(new Event('resize'));
1494					}, 300);
1495				} else if ((((secmenuHeight == 0) ? bodyTop == 0 : bodyTop <= secmenuHeight + offset) || (wwidth < mediaQuery)) && classie.hasClass(logoel[i], 'shrinked')) {
1496					classie.removeClass(logoel[i], 'shrinked');
1497					if (logoMinScale != undefined) {
1498						logoShrink = logolink.children;
1499						Array.prototype.forEach.call(logoShrink, function(singleLogo) {
1500							singleLogo.style.height = singleLogo.getAttribute('data-maxheight') + 'px';
1501							singleLogo.style.lineHeight = singleLogo.getAttribute('data-maxheight') + 'px';
1502							if (classie.hasClass(singleLogo, 'text-logo')) singleLogo.style.fontSize = singleLogo.getAttribute('data-maxheight') + 'px';
1503						});
1504					}
1505					setTimeout(function() {
1506						calculateMenuHeight(false);
1507						//window.dispatchEvent(new Event('resize'));
1508					}, 300);
1509				}
1510			}
1511		},
1512		/** Switch colors menu **/
1513		switchColorsMenu = function(bodyTop, style) {
1514			for (var i = 0; i < transmenuel.length; i++) {
1515				if (masthead.style.opacity !== 1) masthead.style.opacity = 1;
1516				if ((secmenuHeight == 0) ? bodyTop > menuHeight / 2 : bodyTop > secmenuHeight) {
1517					if (classie.hasClass(masthead, 'style-dark-original')) {
1518						logo.className = logo.className.replace("style-light", "style-dark");
1519					}
1520					if (classie.hasClass(masthead, 'style-light-original')) {
1521						logo.className = logo.className.replace("style-dark", "style-light");
1522					}
1523					if (style != undefined) {
1524						if (style == 'dark') {
1525							classie.removeClass(transmenuel[i], 'style-light-override');
1526						}
1527						if (style == 'light') {
1528							classie.removeClass(transmenuel[i], 'style-dark-override');
1529						}
1530						classie.addClass(transmenuel[i], 'style-' + style + '-override');
1531					}
1532				} else {
1533					if (style != undefined) {
1534						if (style == 'dark') {
1535							classie.removeClass(transmenuel[i], 'style-light-override');
1536						}
1537						if (style == 'light') {
1538							classie.removeClass(transmenuel[i], 'style-dark-override');
1539						}
1540						classie.addClass(transmenuel[i], 'style-' + style + '-override');
1541					}
1542				}
1543			}
1544			if (pageHeader != undefined) {
1545				if (style != undefined) {
1546					if (classie.hasClass(pageHeader, 'header-style-dark')) {
1547						classie.removeClass(pageHeader, 'header-style-dark');
1548					}
1549					if (classie.hasClass(pageHeader, 'header-style-light')) {
1550						classie.removeClass(pageHeader, 'header-style-light');
1551					}
1552					classie.addClass(pageHeader, 'header-style-' + style);
1553				}
1554			}
1555		},
1556		/** Parallax Rows **/
1557		parallaxRowCol = function(bodyTop) {
1558			var value;
1559			if (typeof parallaxRows == 'object') {
1560				for (var i = 0; i < parallaxRows.length; i++) {
1561					var section = parallaxRows[i].parentNode,
1562						thisHeight = outerHeight(parallaxRows[i]),
1563						sectionHeight = outerHeight(section),
1564						offSetTop = bodyTop + (section != null ? (classie.hasClass(section.parentNode.parentNode, 'owl-carousel') ? section.parentNode.parentNode.getBoundingClientRect().top : section.getBoundingClientRect().top) : 0),
1565						offSetPosition = wheight + bodyTop - offSetTop;
1566					if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
1567						value = ((offSetPosition - wheight) * speedDivider);
1568						if (Math.abs(value) < (thisHeight - sectionHeight)) {
1569							translateElement(parallaxRows[i], value);
1570						} else {
1571							translateElement(parallaxRows[i], thisHeight - sectionHeight);
1572						}
1573					}
1574				}
1575			}
1576			if (typeof parallaxCols == 'object') {
1577				for (var j = 0; j < parallaxCols.length; j++) {
1578					var section = parallaxCols[j].parentNode,
1579						thisHeight = outerHeight(parallaxCols[j]),
1580						sectionHeight = outerHeight(section),
1581						offSetTop = bodyTop + (section != null ? section.getBoundingClientRect().top : 0),
1582						offSetPosition = wheight + bodyTop - offSetTop;
1583					if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
1584						value = ((offSetPosition - wheight) * speedDivider);
1585						value *= .8;
1586						if (Math.abs(value) < (thisHeight - sectionHeight)) {
1587							translateElement(parallaxCols[j], value);
1588						} else {
1589							translateElement(parallaxCols[j], thisHeight - sectionHeight);
1590						}
1591					}
1592				}
1593			}
1594		},
1595		/** Parallax Headers **/
1596		parallaxHeader = function(bodyTop) {
1597			var value;
1598			if (typeof parallaxHeaders == 'object') {
1599				for (var i = 0; i < parallaxHeaders.length; i++) {
1600					var section = parallaxHeaders[i].parentNode,
1601						thisSibling = section.nextSibling,
1602						thisHeight,
1603						sectionHeight,
1604						offSetTop,
1605						offSetPosition;
1606					if (classie.hasClass(parallaxHeaders[i], 'header-carousel-wrapper')) {
1607						getDivChildren(parallaxHeaders[i], '.t-background-cover', function(item, l, total) {
1608							thisHeight = outerHeight(item);
1609							sectionHeight = outerHeight(section);
1610							offSetTop = bodyTop + section.getBoundingClientRect().top;
1611							offSetPosition = wheight + bodyTop - offSetTop;
1612							if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
1613								value = ((offSetPosition - wheight) * speedDivider);
1614								if (Math.abs(value) < (thisHeight - sectionHeight)) {
1615									translateElement(item, value);
1616								}
1617							}
1618						});
1619					} else {
1620						thisHeight = outerHeight(parallaxHeaders[i]);
1621						sectionHeight = outerHeight(section);
1622						offSetTop = bodyTop + section.getBoundingClientRect().top;
1623						offSetPosition = wheight + bodyTop - offSetTop;
1624						if (offSetPosition > 0 && offSetPosition < (sectionHeight + wheight)) {
1625							value = ((offSetPosition - wheight) * speedDivider);
1626							if (Math.abs(value) < (thisHeight - sectionHeight)) {
1627								translateElement(parallaxHeaders[i], value);
1628							}
1629						}
1630					}
1631				}
1632			}
1633		},
1634		/** Header opacity **/
1635		headerOpacity = function(bodyTop) {
1636			if (headerWithOpacity && headerWithOpacity.length) {
1637				var thisHeight = outerHeight(headerWithOpacity[0]);
1638				if (bodyTop > thisHeight / 8) {
1639					if (pageHeader != undefined) classie.addClass(pageHeader, 'header-scrolled');
1640				} else {
1641					if (pageHeader != undefined) classie.removeClass(pageHeader, 'header-scrolled');
1642				}
1643			}
1644		},
1645		/** Show hide scroll top arrow **/
1646		showHideScrollup = function(bodyTop) {
1647			if (bodyTop != 0) {
1648				if (bodyTop > wheight || ((bodyTop + wheight) >= docheight) && docheight > 0) {
1649					classie.addClass(document.body, 'window-scrolled');
1650					classie.removeClass(document.body, 'hide-scrollup');
1651					if (footerScroller && footerScroller[0] != undefined) {
1652						footerScroller[0].style.display = '';
1653					}
1654				} else {
1655					if (classie.hasClass(document.body, 'window-scrolled')) classie.addClass(document.body, 'hide-scrollup');
1656					classie.removeClass(document.body, 'window-scrolled');
1657				}
1658			}
1659		},
1660		/** Hide Menu **/
1661		hideMenu = function(bodyTop) {
1662			if (UNCODE.menuOpened || bodyTop < 0) return;
1663			if (classie.hasClass(document.body, 'vmenu')) {
1664				if (wwidth < mediaQuery) menuhide = document.querySelector('#masthead .menu-hide-vertical');
1665				else menuhide = null;
1666			}
1667			if (classie.hasClass(document.body, 'hmenu-center')) {
1668				if (wwidth > mediaQuery) menuhide = document.querySelector('#masthead .menu-hide');
1669				else menuhide = document.querySelector('.menu-container-mobile.menu-hide');
1670			}
1671			if (typeof menuhide == 'object' && menuhide != null && mainmenu[0] != undefined) {
1672				var translate,
1673				scrollingDown = true;
1674				/** fix for hmenu-center **/
1675				var sticky_element = (typeof mainmenu.item === 'undefined' ? ((wwidth > mediaQuery) ? mainmenu[0] : mainmenu[1]) : mainmenu[0]);
1676				if (lastScrollValue == bodyTop) return;
1677
1678				if (lastScrollValue > bodyTop) scrollingDown = false;
1679				else scrollingDown = true;
1680				lastScrollValue = bodyTop;
1681
1682				if (!scrollingDown) {
1683					if (!UNCODE.scrolling) {
1684						if ((secmenuHeight == 0) ? bodyTop == 0 : bodyTop < secmenuHeight) {
1685							classie.removeClass(sticky_element.parentNode, 'is_stuck');
1686							if (classie.hasClass(masthead, 'menu-transparent')) {
1687								if ((isMobileTransparent || wwidth > mediaQuery) && !classie.hasClass(masthead.parentNode, 'no-header')) masthead.parentNode.style.height = '0px'; 
1688							}
1689							if (wwidth < mediaQuery) sticky_element.style.position = 'fixed';
1690							hideMenuReset(sticky_element);
1691							clearTimeout(hidingTimer);
1692						}
1693
1694						if (classie.hasClass(menuhide, 'menu-hided')) {
1695							classie.removeClass(menuhide, 'menu-hided');
1696							hidingTimer = setTimeout(function() {
1697								classie.addClass(sticky_element.parentNode, 'is_stuck');
1698								hideMenuReset(sticky_element);
1699							}, 400);
1700						}
1701					}
1702				} else {
1703					if (menusticky.length == 0 && bodyTop < wheight / 3) {
1704						if (sticky_element.style.position == 'fixed') sticky_element.style.position = '';
1705					}
1706					if (bodyTop > wheight / 2) {
1707						clearTimeout(hidingTimer);
1708						if (!classie.hasClass(menuhide, 'menu-hided')) {
1709							classie.addClass(menuhide, 'menu-hided');
1710							classie.addClass(sticky_element.parentNode, 'is_stuck');
1711							if (sticky_element.style.position != 'fixed') {
1712								sticky_element.style.visibility = 'hidden';
1713								sticky_element.style.position = 'fixed';
1714								sticky_element.style.top = '0px';
1715							}
1716							translateElement(menuhide, -UNCODE.menuMobileHeight - 1);
1717						}
1718					}
1719				}
1720			}
1721		},
1722		hideMenuReset = function(sticky_element) {
1723			var topOffset = 0;
1724			if (sticky_element.style.visibility == 'hidden') sticky_element.style.visibility = '';
1725			if (bodyBorder > 0) topOffset += bodyBorder;
1726			if (adminBar != null && window.getComputedStyle(adminBar,null).getPropertyValue("position") != 'fixed') adminBarHeight = 0;
1727			if (adminBarHeight > 0) topOffset += adminBarHeight;
1728			//sticky_element.style.top = topOffset + 'px';
1729			if (!classie.hasClass(document.body, 'boxed-width') && boxWidth > 0) sticky_element.style.width = boxWidth + 'px';
1730			translateElement(menuhide, 0);
1731		},
1732		/** Stick Menu **/
1733		stickMenu = function(bodyTop) {
1734			if (header && mainmenu[0] != undefined) {
1735				if (classie.hasClass(mainmenu[0], 'vmenu-container') && wwidth > mediaQuery) return;
1736				/** fix for hmenu-center **/
1737				var sticky_element = (typeof mainmenu.item === 'undefined' ? ((isMobileTransparent || wwidth > mediaQuery) ? mainmenu[0] : mainmenu[1]) : mainmenu[0]);
1738				if ((secmenuHeight == 0 && (isMobileTransparent || wwidth > mediaQuery)) ? bodyTop > (0 + adminBarHeight)  : bodyTop > (secmenuHeight + adminBarHeight)) {
1739					if (!classie.hasClass(sticky_element.parentNode, 'is_stuck')) {
1740						classie.addClass(sticky_element.parentNode, 'is_stuck');
1741						sticky_element.style.position = 'fixed';
1742						var getAnchorTop = bodyBorder;
1743						if (adminBar != null && window.getComputedStyle(adminBar,null).getPropertyValue("position") != 'fixed') adminBarHeight = 0;
1744						if (adminBarHeight > 0) getAnchorTop += adminBarHeight;
1745						sticky_element.style.top = getAnchorTop + 'px';
1746						if (!classie.hasClass(document.body, 'boxed-width') && boxWidth > 0) sticky_element.style.width = boxWidth + 'px';
1747					}
1748				} else {
1749					clearTimeout(hidingTimer);
1750					classie.removeClass(sticky_element.parentNode, 'is_stuck');
1751					if (isMobileTransparent || wwidth > mediaQuery) sticky_element.style.position = '';
1752					if (wwidth < mediaQuery) sticky_element.style.position = 'fixed';
1753					sticky_element.style.top = '';
1754				}
1755			}
1756		},
1757		translateElement = function(element, valueY) {
1758			var translate = 'translate3d(0, ' + valueY + 'px' + ', 0)';
1759			element.style['-webkit-transform'] = translate;
1760			element.style['-moz-transform'] = translate;
1761			element.style['-ms-transform'] = translate;
1762			element.style['-o-transform'] = translate;
1763			element.style['transform'] = translate;
1764		},
1765		scrollFunction = function() {
1766			if (logoel != undefined && logoel.length && !isMobile) shrinkMenu(bodyTop);
1767			if (menusticky != undefined && menusticky.length) stickMenu(bodyTop);
1768			hideMenu(bodyTop);
1769			if (!isMobile) {
1770				if (header && menusticky != undefined && menusticky.length) switchColorsMenu(bodyTop);
1771				parallaxRowCol(bodyTop);
1772				parallaxHeader(bodyTop);
1773				headerOpacity(bodyTop);
1774			}
1775		};
1776	if (!noScroll) {
1777		window.addEventListener('scroll', function(e) {
1778			bodyTop = document.documentElement.scrollTop || document.body.scrollTop;
1779			scrollFunction();
1780			showHideScrollup(bodyTop);
1781		}, false);
1782	}
1783	/** All scrolling functions - End */
1784	/** help functions */
1785	function getClosest(el, tag) {
1786		do {
1787			if (el.className != undefined && el.className.indexOf(tag) > -1) return el;
1788		} while (el = el.parentNode);
1789		// not found :(
1790		return null;
1791	}
1792
1793	function outerHeight(el, includeMargin) {
1794		if (el != null) {
1795			var height = el.offsetHeight;
1796			if (includeMargin) {
1797				var style = el.currentStyle || getComputedStyle(el);
1798				height += parseInt(style.marginTop) + parseInt(style.marginBottom);
1799			}
1800			return height;
1801		}
1802	}
1803
1804	function outerWidth(el, includeMargin) {
1805			var width = el.offsetWidth;
1806			if (includeMargin) {
1807				var style = el.currentStyle || getComputedStyle(el);
1808				width += parseInt(style.marginLeft) + parseInt(style.marginRight);
1809			}
1810			return width;
1811		}
1812		// Replicate jQuery .each method
1813	function forEachElement(selector, fn) {
1814		var elements = document.querySelectorAll(selector);
1815		for (var i = 0; i < elements.length; i++) fn(elements[i], i);
1816	}
1817
1818	function getDivChildren(containerId, selector, fn) {
1819		if (containerId !== null) {
1820			var elements = containerId.querySelectorAll(selector);
1821			for (var i = 0; i < elements.length; i++) fn(elements[i], i, elements.length);
1822		}
1823	}
1824
1825	function hideFooterScroll() {
1826		if (classie.hasClass(document.body, 'hide-scrollup')) footerScroller[0].style.display = "none";
1827	}
1828	document.addEventListener("DOMContentLoaded", function(event) {
1829		UNCODE.adaptive();
1830		boxWrapper = document.querySelectorAll('.box-wrapper');
1831		docheight = boxWrapper[0] != undefined ? boxWrapper[0].offsetHeight : 0;
1832		if (!classie.hasClass(document.body, 'vmenu') && !classie.hasClass(document.body, 'menu-offcanvas')) init_overlay();
1833		if (!UNCODE.isMobile) {
1834			parallaxRows = document.querySelectorAll('.with-parallax > .row-background > .background-wrapper');
1835			parallaxCols = document.querySelectorAll('.with-parallax > .column-background > .background-wrapper');
1836		}
1837		footerScroller = document.querySelectorAll('.footer-scroll-top');
1838		if (footerScroller && footerScroller[0] != undefined) {
1839			if (transitionEvent) {
1840				footerScroller[0].addEventListener(transitionEvent, hideFooterScroll);
1841			}
1842		}
1843		Array.prototype.forEach.call(document.querySelectorAll('.row-inner'), function(el) {
1844			el.style.height = '';
1845			el.style.marginBottom = '';
1846		});
1847		setRowHeight(document.querySelectorAll('.page-wrapper .row-parent, footer .row-parent'));
1848	});
1849	/** On resize events **/
1850	window.addEventListener("resize", function() {
1851		docheight = (boxWrapper != undefined && boxWrapper[0] != undefined) ? boxWrapper[0].offsetHeight : 0;
1852		var oldWidth = wwidth;
1853		UNCODE.wwidth = wwidth = window.innerWidth || document.documentElement.clientWidth;
1854		UNCODE.wheight = wheight = (window.innerHeight || document.documentElement.clientHeight) - (bodyBorder * 2);
1855		if (isSplitMenu) centerSplitMenu();
1856		if (isMobile && (oldWidth == wwidth)) return false;
1857		calculateMenuHeight(false);
1858		initBox();
1859		headerHeight('.header-wrapper');
1860		window.dispatchEvent(boxEvent);
1861		if (!isMobile) {
1862			setTimeout(function() {
1863				initVideoComponent(document.body, '.uncode-video-container.video, .uncode-video-container.self-video');
1864			}, 100);
1865		}
1866		scrollFunction();
1867		showHideScrollup(bodyTop);
1868		clearTimeout(resizeTimer);
1869		resizeTimer = setTimeout(function() {
1870			UNCODE.wheight = wheight = (window.innerHeight || document.documentElement.clientHeight) - (bodyBorder * 2);
1871			Array.prototype.forEach.call(document.querySelectorAll('.row-inner'), function(el) {
1872				el.style.height = '';
1873				el.style.marginBottom = '';
1874			});
1875			setRowHeight(document.querySelectorAll('.page-wrapper .row-parent, footer .row-parent'), false, true);
1876		}, 500);
1877	});
1878
1879	/**
1880	 * On DOM ready
1881	 */
1882	window.addEventListener("load", function(){
1883		if (!UNCODE.isMobile) {
1884			setTimeout(function() {
1885				window.dispatchEvent(UNCODE.boxEvent);
1886				Waypoint.refreshAll();
1887			}, 2000);
1888		}
1889		showHideScrollup(bodyTop);
1890		if (document.createEvent) { // W3C
1891	    var ev = document.createEvent('Event');
1892	    ev.initEvent('resize', true, true);
1893	    window.dispatchEvent(ev);
1894		} else { // IE
1895    	document.fireEvent('onresize');
1896		}
1897	}, false);
1898
1899	var UNCODE = {
1900		bodyTop: bodyTop,
1901		boxEvent: boxEvent,
1902		bodyBorder: bodyBorder,
1903		initBox: initBox,
1904		adminBarHeight: 0,
1905		menuHeight: 0,
1906		menuMobileHeight: 0,
1907		fixMenuHeight: fixMenuHeight,
1908		initHeader: initHeader,
1909		initRow: initRow,
1910		setRowHeight: setRowHeight,
1911		switchColorsMenu: switchColorsMenu,
1912		isMobile: isMobile,
1913		scrolling: false,
1914		menuHiding: false,
1915		menuOpened: false,
1916		menuMobileTriggerEvent: menuMobileTriggerEvent,
1917		mediaQuery: mediaQuery,
1918		initVideoComponent: initVideoComponent,
1919		hideMenu: hideMenu,
1920		wwidth: wwidth,
1921		wheight: wheight,
1922	};
1923	// transport
1924	if (typeof define === 'function' && define.amd) {
1925		// AMD
1926		define(UNCODE);
1927	} else {
1928		// browser global
1929		window.UNCODE = UNCODE;
1930	}
1931
1932	UNCODE.adaptive = function() {
1933		var images = new Array(),
1934			getImages = document.querySelectorAll('.adaptive-async:not(.adaptive-fetching)');
1935		for (var i = 0; i < getImages.length; i++) {
1936			var imageObj = {},
1937				el = getImages[i];
1938			classie.addClass(el, 'adaptive-fetching');
1939			imageObj.unique = el.getAttribute('data-uniqueid');
1940			imageObj.url = el.getAttribute('data-guid');
1941			imageObj.path = el.getAttribute('data-path');
1942			imageObj.singlew = el.getAttribute('data-singlew');
1943			imageObj.singleh = el.getAttribute('data-singleh');
1944			imageObj.origwidth = el.getAttribute('data-width');
1945			imageObj.origheight = el.getAttribute('data-height');
1946			imageObj.crop = el.getAttribute('data-crop');
1947			imageObj.fixed = el.getAttribute('data-fixed') == undefined ? null : el.getAttribute('data-fixed');
1948			imageObj.screen = window.uncodeScreen;
1949			imageObj.images = window.uncodeImages;
1950			images.push(imageObj);
1951		}
1952		var jsonString = JSON.stringify(images);
1953		var data = new Array();
1954		data['action'] = 'get_adaptive_async';
1955		data['images'] = jsonString;
1956		data['cache'] = 'false';
1957
1958		if (images.length > 0) {
1959			var xmlhttp;
1960			if (window.XMLHttpRequest) {
1961				// code for IE7+, Firefox, Chrome, Opera, Safari
1962				xmlhttp = new XMLHttpRequest();
1963			} else {
1964				// code for IE6, IE5
1965				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
1966			}
1967			xmlhttp.onreadystatechange = function() {
1968				if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
1969					if(xmlhttp.status == 200){
1970						var images = JSON.parse(xmlhttp.responseText);
1971						for (var i = 0; i < images.length; i++) {
1972							var val = images[i],
1973								getImage = document.querySelectorAll('[data-uniqueid="'+val.unique+'"]');
1974							for (var j = 0; j < getImage.length; j++) {
1975								var attrScr = getImage[j].getAttribute('src'),
1976								replaceImg = new Image();
1977								replaceImg.source = attrScr;
1978								replaceImg.el = getImage[j];
1979
1980								classie.removeClass(getImage[j], 'adaptive-async');
1981								classie.removeClass(getImage[j], 'adaptive-fetching');
1982
1983								replaceImg.onload = function () {
1984									if (this.source !== null) {
1985										(this.el).src = this.src;
1986									} else {
1987										(this.el).style.backgroundImage = 'url("'+this.src+'")';
1988									}
1989									classie.addClass(this.el, 'async-done');
1990								}
1991								replaceImg.src = val.url;
1992							}
1993						}
1994					}
1995					else if(xmlhttp.status == 400) {
1996						console.log('There was an error 400')
1997					}
1998					else {
1999						console.log('something else other than 200 was returned')
2000					}
2001				}
2002			}
2003			//Serialize the data
2004	    var queryString = "",
2005	    	arrayLength = Object.keys(data).length,
2006	    	arrayCounter = 0;
2007
2008	    for (var key in data) {
2009				queryString += key + "=" + data[key];
2010				if(arrayCounter < arrayLength - 1) {
2011					queryString += "&";
2012				}
2013				arrayCounter++;
2014			}
2015
2016			xmlhttp.open("POST", SiteParameters.theme_directory + '/core/inc/uncode-ajax.php', true);
2017			xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
2018	    xmlhttp.send(queryString);
2019
2020		}
2021	};
2022
2023})(window);
2024
2025/**
2026 * vivus - JavaScript library to make drawing animation on SVG
2027 * @version v0.4.0 
2028 * @link https://github.com/maxwellito/vivus
2029 * @license MIT
2030 */
2031
2032'use strict';
2033
2034(function (window, document) {
2035
2036  'use strict';
2037
2038/**
2039 * Pathformer
2040 * Beta version
2041 *
2042 * Take any SVG version 1.1 and transform
2043 * child elements to 'path' elements
2044 *
2045 * This code is purely forked from
2046 * https://github.com/Waest/SVGPathConverter
2047 */
2048
2049/**
2050 * Class constructor
2051 *
2052 * @param {DOM|String} element Dom element of the SVG or id of it
2053 */
2054function Pathformer(element) {
2055  // Test params
2056  if (typeof element === 'undefined') {
2057    throw new Error('Pathformer [constructor]: "element" parameter is required');
2058  }
2059
2060  // Set the element
2061  if (element.constructor === String) {
2062    element = document.getElementById(element);
2063    if (!element) {
2064      throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID');
2065    }
2066  }
2067  if (element.constructor instanceof window.SVGElement || /^svg$/i.test(element.nodeName)) {
2068    this.el = element;
2069  } else {
2070    throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement');
2071  }
2072
2073  // Start
2074  this.scan(element);
2075}
2076
2077/**
2078 * List of tags which can be transformed
2079 * to path elements
2080 *
2081 * @type {Array}
2082 */
2083Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect'];
2084
2085/**
2086 * List of attribute names which contain
2087 * data. This array list them to check if
2088 * they contain bad values, like percentage.
2089 *
2090 * @type {Array}
2091 */
2092Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
2092y1', 'y2'];
2093
2094/**
2095 * Finds the elements compatible for transform
2096 * and apply the liked method
2097 *
2098 * @param  {object} options Object from the constructor
2099 */
2100Pathformer.prototype.scan = function (svg) {
2101  var fn, element, pathData, pathDom,
2102      elements = svg.querySelectorAll(this.TYPES.join(','));
2103
2104  for (var i = 0; i < elements.length; i++) {
2105    element = elements[i];
2106    fn = this[element.tagName.toLowerCase() + 'ToPath'];
2107    pathData = fn(this.parseAttr(element.attributes));
2108    pathDom = this.pathMaker(element, pathData);
2109    element.parentNode.replaceChild(pathDom, element);
2110  }
2111};
2112
2113
2114/**
2115 * Read `line` element to extract and transform
2116 * data, to make it ready for a `path` object.
2117 *
2118 * @param  {DOMelement} element Line element to transform
2119 * @return {object}             Data for a `path` element
2120 */
2121Pathformer.prototype.lineToPath = function (element) {
2122  var newElement = {},
2123      x1 = element.x1 || 0,
2124      y1 = element.y1 || 0,
2125      x2 = element.x2 || 0,
2126      y2 = element.y2 || 0;
2127
2128  newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2;
2129  return newElement;
2130};
2131
2132/**
2133 * Read `rect` element to extract and transform
2134 * data, to make it ready for a `path` object.
2135 * The radius-border is not taken in charge yet.
2136 * (your help is more than welcomed)
2137 *
2138 * @param  {DOMelement} element Rect element to transform
2139 * @return {object}             Data for a `path` element
2140 */
2141Pathformer.prototype.rectToPath = function (element) {
2142  var newElement = {},
2143      x      = parseFloat(element.x)      || 0,
2144      y      = parseFloat(element.y)      || 0,
2145      width  = parseFloat(element.width)  || 0,
2146      height = parseFloat(element.height) || 0;
2147
2148  newElement.d  = 'M' + x + ' ' + y + ' ';
2149  newElement.d += 'L' + (x + width) + ' ' + y + ' ';
2150  newElement.d += 'L' + (x + width) + ' ' + (y + height) + ' ';
2151  newElement.d += 'L' + x + ' ' + (y + height) + ' Z';
2152  return newElement;
2153};
2154
2155/**
2156 * Read `polyline` element to extract and transform
2157 * data, to make it ready for a `path` object.
2158 *
2159 * @param  {DOMelement} element Polyline element to transform
2160 * @return {object}             Data for a `path` element
2161 */
2162Pathformer.prototype.polylineToPath = function (element) {
2163  var newElement = {},
2164      points = element.points.trim().split(' '),
2165      i, path;
2166
2167  // Reformatting if points are defined without commas
2168  if (element.points.indexOf(',') === -1) {
2169    var formattedPoints = [];
2170    for (i = 0; i < points.length; i+=2) {
2171      formattedPoints.push(points[i] + ',' + points[i+1]);
2172    }
2173    points = formattedPoints;
2174  }
2175
2176  // Generate the path.d value
2177  path = 'M' + points[0];
2178  for(i = 1; i < points.length; i++) {
2179    if (points[i].indexOf(',') !== -1) {
2180      path += 'L' + points[i];
2181    }
2182  }
2183  newElement.d = path;
2184  return newElement;
2185};
2186
2187/**
2188 * Read `polygon` element to extract and transform
2189 * data, to make it ready for a `path` object.
2190 * This method rely on polylineToPath, because the
2191 * logic is similar. The path created is just closed,
2192 * so it needs an 'Z' at the end.
2193 *
2194 * @param  {DOMelement} element Polygon element to transform
2195 * @return {object}             Data for a `path` element
2196 */
2197Pathformer.prototype.polygonToPath = function (element) {
2198  var newElement = Pathformer.prototype.polylineToPath(element);
2199
2200  newElement.d += 'Z';
2201  return newElement;
2202};
2203
2204/**
2205 * Read `ellipse` element to extract and transform
2206 * data, to make it ready for a `path` object.
2207 *
2208 * @param  {DOMelement} element ellipse element to transform
2209 * @return {object}             Data for a `path` element
2210 */
2211Pathformer.prototype.ellipseToPath = function (element) {
2212  var newElement = {},
2213      rx = parseFloat(element.rx) || 0,
2214      ry = parseFloat(element.ry) || 0,
2215      cx = parseFloat(element.cx) || 0,
2216      cy = parseFloat(element.cy) || 0,
2217      startX = cx - rx,
2218      startY = cy,
2219      endX = parseFloat(cx) + parseFloat(rx),
2220      endY = cy;
2221
2222  newElement.d = 'M' + startX + ',' + startY +
2223                 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY +
2224                 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY;
2225  return newElement;
2226};
2227
2228/**
2229 * Read `circle` element to extract and transform
2230 * data, to make it ready for a `path` object.
2231 *
2232 * @param  {DOMelement} element Circle element to transform
2233 * @return {object}             Data for a `path` element
2234 */
2235Pathformer.prototype.circleToPath = function (element) {
2236  var newElement = {},
2237      r  = parseFloat(element.r)  || 0,
2238      cx = parseFloat(element.cx) || 0,
2239      cy = parseFloat(element.cy) || 0,
2240      startX = cx - r,
2241      startY = cy,
2242      endX = parseFloat(cx) + parseFloat(r),
2243      endY = cy;
2244      
2245  newElement.d =  'M' + startX + ',' + startY +
2246                  'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY +
2247                  'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY;
2248  return newElement;
2249};
2250
2251/**
2252 * Create `path` elements form original element
2253 * and prepared objects
2254 *
2255 * @param  {DOMelement} element  Original element to transform
2256 * @param  {object} pathData     Path data (from `toPath` methods)
2257 * @return {DOMelement}          Path element
2258 */
2259Pathformer.prototype.pathMaker = function (element, pathData) {
2260  var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path');
2261  for(i = 0; i < element.attributes.length; i++) {
2262    attr = element.attributes[i];
vendor: 6,056 bytes, lines 2263-2455
2263    if (this.ATTR_WATCH.indexOf(attr.name) === -1) {
2264      pathTag.setAttribute(attr.name, attr.value);
2265    }
2266  }
2267  for(i in pathData) {
2268    pathTag.setAttribute(i, pathData[i]);
2269  }
2270  return pathTag;
2271};
2272
2273/**
2274 * Parse attributes of a DOM element to
2275 * get an object of attribute => value
2276 *
2277 * @param  {NamedNodeMap} attributes Attributes object from DOM element to parse
2278 * @return {object}                  Object of attributes
2279 */
2280Pathformer.prototype.parseAttr = function (element) {
2281  var attr, output = {};
2282  for (var i = 0; i < element.length; i++) {
2283    attr = element[i];
2284    // Check if no data attribute contains '%', or the transformation is impossible
2285    if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) {
2286      throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.');
2287    }
2288    output[attr.name] = attr.value;
2289  }
2290  return output;
2291};
2292
2293  'use strict';
2294
2295var requestAnimFrame, cancelAnimFrame, parsePositiveInt;
2296
2297/**
2298 * Vivus
2299 * Beta version
2300 *
2301 * Take any SVG and make the animation
2302 * to give give the impression of live drawing
2303 *
2304 * This in more than just inspired from codrops
2305 * At that point, it's a pure fork.
2306 */
2307
2308/**
2309 * Class constructor
2310 * option structure
2311 *   type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed)
2312 *   duration: <int> (in frames)
2313 *   start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport)
2314 *   delay: <int> (delay between the drawing of first and last path)
2315 *   dashGap <integer> whitespace extra margin between dashes
2316 *   pathTimingFunction <function> timing animation function for each path element of the SVG
2317 *   animTimingFunction <function> timing animation function for the complete SVG
2318 *   forceRender <boolean> force the browser to re-render all updated path items
2319 *   selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original
2320 *
2321 * The attribute 'type' is by default on 'delayed'.
2322 *  - 'delayed'
2323 *    all paths are draw at the same time but with a
2324 *    little delay between them before start
2325 *  - 'sync'
2326 *    all path are start and finish at the same time
2327 *  - 'oneByOne'
2328 *    only one path is draw at the time
2329 *    the end of the first one will trigger the draw
2330 *    of the next one
2331 *
2332 * All these values can be overwritten individually
2333 * for each path item in the SVG
2334 * The value of frames will always take the advantage of
2335 * the duration value.
2336 * If you fail somewhere, an error will be thrown.
2337 * Good luck.
2338 *
2339 * @constructor
2340 * @this {Vivus}
2341 * @param {DOM|String}   element  Dom element of the SVG or id of it
2342 * @param {Object}       options  Options about the animation
2343 * @param {Function}     callback Callback for the end of the animation
2344 */
2345function Vivus (element, options, callback) {
2346
2347  // Setup
2348  this.isReady = false;
2349  this.setElement(element, options);
2350  this.setOptions(options);
2351  this.setCallback(callback);
2352
2353  if (this.isReady) {
2354    this.init();
2355  }
2356}
2357
2358/**
2359 * Timing functions
2360 **************************************
2361 *
2362 * Default functions to help developers.
2363 * It always take a number as parameter (between 0 to 1) then
2364 * return a number (between 0 and 1)
2365 */
2366Vivus.LINEAR          = function (x) {return x;};
2367Vivus.EASE            = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;};
2368Vivus.EASE_OUT        = function (x) {return 1 - Math.pow(1-x, 3);};
2369Vivus.EASE_IN         = function (x) {return Math.pow(x, 3);};
2370Vivus.EASE_OUT_BOUNCE = function (x) {
2371  var base = -Math.cos(x * (0.5 * Math.PI)) + 1,
2372    rate = Math.pow(base,1.5),
2373    rateR = Math.pow(1 - x, 2),
2374    progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1;
2375  return (1- rateR) + (progress * rateR);
2376};
2377
2378
2379/**
2380 * Setters
2381 **************************************
2382 */
2383
2384/**
2385 * Check and set the element in the instance
2386 * The method will not return anything, but will throw an
2387 * error if the parameter is invalid
2388 *
2389 * @param {DOM|String}   element  SVG Dom element or id of it
2390 */
2391Vivus.prototype.setElement = function (element, options) {
2392  // Basic check
2393  if (typeof element === 'undefined') {
2394    throw new Error('Vivus [constructor]: "element" parameter is required');
2395  }
2396
2397  // Set the element
2398  if (element.constructor === String) {
2399    element = document.getElementById(element);
2400    if (!element) {
2401      throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');
2402    }
2403  }
2404  this.parentEl = element;
2405
2406  // Create the object element if the property `file` exists in the options object
2407  if (options && options.file) {
2408    var objElm = document.createElement('object');
2409    objElm.setAttribute('type', 'image/svg+xml');
2410    objElm.setAttribute('data', options.file);
2411    objElm.setAttribute('built-by-vivus', 'true');
2412    element.appendChild(objElm);
2413    element = objElm;
2414  }
2415
2416  switch (element.constructor) {
2417  case window.SVGSVGElement:
2418  case window.SVGElement:
2419    this.el = element;
2420    this.isReady = true;
2421    break;
2422
2423  case window.HTMLObjectElement:
2424    // If we have to wait for it
2425    var onLoad, self;
2426
2427    self = this;
2428    onLoad = function (e) {
2429      if (self.isReady) {
2430        return;
2431      }
2432      self.el = element.contentDocument && element.contentDocument.querySelector('svg');
2433      if (!self.el && e) {
2434        throw new Error('Vivus [constructor]: object loaded does not contain any SVG');
2435      }
2436      else if (self.el) {
2437        if (element.getAttribute('built-by-vivus')) {
2438          self.parentEl.insertBefore(self.el, element);
2439          self.parentEl.removeChild(element);
2440          self.el.setAttribute('width', '100%');
2441          self.el.setAttribute('height', '100%');
2442        }
2443        self.isReady = true;
2444        self.init();
2445        return true;
2446      }
2447    };
2448
2449    if (!onLoad()) {
2450      element.addEventListener('load', onLoad);
2451    }
2452    break;
2453
2454  default:
2455    throw new Error('Vivus [constructor]: "element" parameter is not val
2455id (or miss the "file" attribute)');
2456  }
2457};
2458
2459/**
2460 * Set up user option to the instance
2461 * The method will not return anything, but will throw an
2462 * error if the parameter is invalid
2463 *
2464 * @param  {object} options Object from the constructor
2465 */
2466Vivus.prototype.setOptions = function (options) {
2467  var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync'];
2468  var allowedStarts =  ['inViewport', 'manual', 'autostart'];
2469
2470  // Basic check
2471  if (options !== undefined && options.constructor !== Object) {
2472    throw new Error('Vivus [constructor]: "options" parameter must be an object');
2473  }
2474  else {
2475    options = options || {};
2476  }
2477
2478  // Set the animation type
2479  if (options.type && allowedTypes.indexOf(options.type) === -1) {
2480    throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`');
2481  }
2482  else {
2483    this.type = options.type || allowedTypes[0];
2484  }
2485
2486  // Set the start type
2487  if (options.start && allowedStarts.indexOf(options.start) === -1) {
2488    throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option');
2489  }
2490  else {
2491    this.start = options.start || allowedStarts[0];
2492  }
2493
2494  this.isIE         = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 );
2495  this.duration     = parsePositiveInt(options.duration, 120);
2496  this.delay        = parsePositiveInt(options.delay, null);
2497  this.delayStart   = parsePositiveInt(options.delayStart, null);
2498  this.dashGap      = parsePositiveInt(options.dashGap, 1);
2499  this.forceRender  = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE;
2500  this.reverseStack = !!options.reverseStack;
2501  this.selfDestroy  = !!options.selfDestroy;
2502  this.onReady      = options.onReady;
2503  this.map          = [];
2504  this.frameLength  = this.currentFrame = this.delayUnit = this.speed = this.handle = null;
2505
2506  this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false;
2507
2508  this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
2509  this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR;
2510
2511  if (this.delay >= this.duration) {
2512    throw new Error('Vivus [constructor]: delay must be shorter than duration');
2513  }
2514};
2515
2516/**
2517 * Set up callback to the instance
2518 * The method will not return enything, but will throw an
2519 * error if the parameter is invalid
2520 *
2521 * @param  {Function} callback Callback for the animation end
2522 */
2523Vivus.prototype.setCallback = function (callback) {
2524  // Basic check
2525  if (!!callback && callback.constructor !== Function) {
2526    throw new Error('Vivus [constructor]: "callback" parameter must be a function');
2527  }
2528  this.callback = callback || function () {};
2529};
2530
2531
2532/**
2533 * Core
2534 **************************************
2535 */
2536
2537/**
2538 * Map the svg, path by path.
2539 * The method return nothing, it just fill the
2540 * `map` array. Each item in this array represent
2541 * a path element from the SVG, with informations for
2542 * the animation.
2543 *
2544 * ```
2545 * [
2546 *   {
2547 *     el: <DOMobj> the path element
2548 *     length: <number> length of the path line
2549 *     startAt: <number> time start of the path animation (in frames)
2550 *     duration: <number> path animation duration (in frames)
2551 *   },
2552 *   ...
2553 * ]
2554 * ```
2555 *
2556 */
2557Vivus.prototype.mapping = function () {
2558  var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint;
2559  timePoint = totalLength = lengthMeter = 0;
2560  paths = this.el.querySelectorAll('path');
2561
2562  for (i = 0; i < paths.length; i++) {
2563    path = paths[i];
2564    if (this.isInvisible(path)) {
2565      continue;
2566    }
2567    pathObj = {
2568      el: path,
2569      length: Math.ceil(path.getTotalLength())
2570    };
2571    // Test if the path length is correct
2572    if (isNaN(pathObj.length)) {
2573      if (window.console && console.warn) {
2574        console.warn('Vivus [mapping]: cannot retrieve a path element length', path);
2575      }
2576      continue;
2577    }
2578    this.map.push(pathObj);
2579    path.style.strokeDasharray  = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2);
2580    path.style.strokeDashoffset = pathObj.length + this.dashGap;
2581    pathObj.length += this.dashGap;
2582    totalLength += pathObj.length;
2583
2584    this.renderPath(i);
2585  }
2586
2587  totalLength = totalLength === 0 ? 1 : totalLength;
2588  this.delay = this.delay === null ? this.duration / 3 : this.delay;
2589  this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1);
2590
2591  // Reverse stack if asked
2592  if (this.reverseStack) {
2593    this.map.reverse();
2594  }
2595
2596  for (i = 0; i < this.map.length; i++) {
2597    pathObj = this.map[i];
2598
2599    switch (this.type) {
2600    case 'delayed':
2601      pathObj.startAt = this.delayUnit * i;
2602      pathObj.duration = this.duration - this.delay;
2603      break;
2604
2605    case 'oneByOne':
2606      pathObj.startAt = lengthMeter / totalLength * this.duration;
2607      pathObj.duration = pathObj.length / totalLength * this.duration;
2608      break;
2609
2610    case 'sync':
2611    case 'async':
2612    case 'nsync':
2613      pathObj.startAt = 0;
2614      pathObj.duration = this.duration;
2615      break;
2616
2617    case 'scenario-sync':
2618      path = pathObj.el;
2619      pAttrs = this.parseAttr(path);
2620      pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0);
2621      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
2622      timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration;
2623      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
2624      break;
2625
2626    case 'scenario':
2627      path = pathObj.el;
2628      pAttrs = this.parseAttr(path);
2629      pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0;
2630      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
2631      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
2632      break;
2633    }
2634    lengthMeter += pathObj.length;
2635    this.frameLength = this.frameLength || this.duration;
2636  }
2637};
2638
2639/**
2640 * Interval method to draw the SVG from current
2641 * position of the animation. It update the value of
2642 * `currentFrame` and re-trace the SVG.
2643 *
2644 * It use this.handle to store the requestAnimationFrame
2645 * and clear it one the animation is stopped. So this
2646 * attribute can be used to know if the animation is
2647 * playing.
2648 *
2649 * Once the animation at the end, this method will
2650 * trigger the Vivus callback.
2651 *
2652 */
2653Vivus.prototype.drawer = function () {
2654  var self = this;
2655  this.currentFrame += this.speed;
2656
2657  if (this.currentFrame <= 0) {
2658    this.stop();
2659    this.reset();
2660  } else if (this.currentFrame >= this.frameLength) {
2661    this.stop();
2662    this.currentFrame = this.frameLength;
2663    this.trace();
vendor: 4,770 bytes, lines 2664-2842
2664    if (this.selfDestroy) {
2665      this.destroy();
2666    }
2667  } else {
2668    this.trace();
2669    this.handle = requestAnimFrame(function () {
2670      self.drawer();
2671    });
2672    return;
2673  }
2674
2675  this.callback(this);
2676  if (this.instanceCallback) {
2677    this.instanceCallback(this);
2678    this.instanceCallback = null;
2679  }
2680};
2681
2682/**
2683 * Draw the SVG at the current instant from the
2684 * `currentFrame` value. Here is where most of the magic is.
2685 * The trick is to use the `strokeDashoffset` style property.
2686 *
2687 * For optimisation reasons, a new property called `progress`
2688 * is added in each item of `map`. This one contain the current
2689 * progress of the path element. Only if the new value is different
2690 * the new value will be applied to the DOM element. This
2691 * method save a lot of resources to re-render the SVG. And could
2692 * be improved if the animation couldn't be played forward.
2693 *
2694 */
2695Vivus.prototype.trace = function () {
2696  var i, progress, path, currentFrame;
2697  currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength;
2698  for (i = 0; i < this.map.length; i++) {
2699    path = this.map[i];
2700    progress = (currentFrame - path.startAt) / path.duration;
2701    progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress)));
2702    if (path.progress !== progress) {
2703      path.progress = progress;
2704      path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress));
2705      this.renderPath(i);
2706    }
2707  }
2708};
2709
2710/**
2711 * Method forcing the browser to re-render a path element
2712 * from it's index in the map. Depending on the `forceRender`
2713 * value.
2714 * The trick is to replace the path element by it's clone.
2715 * This practice is not recommended because it's asking more
2716 * ressources, too much DOM manupulation..
2717 * but it's the only way to let the magic happen on IE.
2718 * By default, this fallback is only applied on IE.
2719 *
2720 * @param  {Number} index Path index
2721 */
2722Vivus.prototype.renderPath = function (index) {
2723  if (this.forceRender && this.map && this.map[index]) {
2724    var pathObj = this.map[index],
2725        newPath = pathObj.el.cloneNode(true);
2726    pathObj.el.parentNode.replaceChild(newPath, pathObj.el);
2727    pathObj.el = newPath;
2728  }
2729};
2730
2731/**
2732 * When the SVG object is loaded and ready,
2733 * this method will continue the initialisation.
2734 *
2735 * This this mainly due to the case of passing an
2736 * object tag in the constructor. It will wait
2737 * the end of the loading to initialise.
2738 *
2739 */
2740Vivus.prototype.init = function () {
2741  // Set object variables
2742  this.frameLength = 0;
2743  this.currentFrame = 0;
2744  this.map = [];
2745
2746  // Start
2747  new Pathformer(this.el);
2748  this.mapping();
2749  this.starter();
2750
2751  if (this.onReady) {
2752    this.onReady(this);
2753  }
2754};
2755
2756/**
2757 * Trigger to start of the animation.
2758 * Depending on the `start` value, a different script
2759 * will be applied.
2760 *
2761 * If the `start` value is not valid, an error will be thrown.
2762 * Even if technically, this is impossible.
2763 *
2764 */
2765Vivus.prototype.starter = function () {
2766  switch (this.start) {
2767  case 'manual':
2768    return;
2769
2770  case 'autostart':
2771    this.play();
2772    break;
2773
2774  case 'inViewport':
2775    var self = this,
2776    listener = function () {
2777      if (self.isInViewport(self.parentEl, 1)) {
2778        self.play();
2779        window.removeEventListener('scroll', listener);
2780      }
2781    };
2782    window.addEventListener('scroll', listener);
2783    listener();
2784    break;
2785  }
2786};
2787
2788
2789/**
2790 * Controls
2791 **************************************
2792 */
2793
2794/**
2795 * Get the current status of the animation between
2796 * three different states: 'start', 'progress', 'end'.
2797 * @return {string} Instance status
2798 */
2799Vivus.prototype.getStatus = function () {
2800  return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress';
2801};
2802
2803/**
2804 * Reset the instance to the initial state : undraw
2805 * Be careful, it just reset the animation, if you're
2806 * playing the animation, this won't stop it. But just
2807 * make it start from start.
2808 *
2809 */
2810Vivus.prototype.reset = function () {
2811  return this.setFrameProgress(0);
2812};
2813
2814/**
2815 * Set the instance to the final state : drawn
2816 * Be careful, it just set the animation, if you're
2817 * playing the animation on rewind, this won't stop it.
2818 * But just make it start from the end.
2819 *
2820 */
2821Vivus.prototype.finish = function () {
2822  return this.setFrameProgress(1);
2823};
2824
2825/**
2826 * Set the level of progress of the drawing.
2827 *
2828 * @param {number} progress Level of progress to set
2829 */
2830Vivus.prototype.setFrameProgress = function (progress) {
2831  progress = Math.min(1, Math.max(0, progress));
2832  this.currentFrame = Math.round(this.frameLength * progress);
2833  this.trace();
2834  return this;
2835};
2836
2837/**
2838 * Play the animation at the desired speed.
2839 * Speed must be a valid number (no zero).
2840 * By default, the speed value is 1.
2841 * But a negative value is accepted to go forward.
2842 *
2843 * And works with float too.
2844 * But don't forget we are in JavaScript, se be nice
2845 * with him and give him a 1/2^x value.
2846 *
2847 * @param  {number} speed Animation speed [optional]
2848 */
2849Vivus.prototype.play = function (speed, callback) {
2850  this.instanceCallback = null;
2851
2852  if (speed && typeof speed === 'function') {
2853    this.instanceCallback = speed; // first parameter is actually the callback function
2854    speed = null;
2855  }
2856  else if (speed && typeof speed !== 'number') {
2857    throw new Error('Vivus [play]: invalid speed');
2858  }
2859  // if the first parameter wasn't the callback, check if the seconds was
2860  if (callback && typeof(callback) === 'function' && !this.instanceCallback) {
2861    this.instanceCallback = callback;
2862  }
2863
2864
2865  this.speed = speed || 1;
2866  if (!this.handle) {
2867  	var $this = this,
2868  	delay = (this.delayStart != null) ? this.delayStart : 0;
2869  	setTimeout(function() {
2870  		$this.drawer();
2871  	}, delay);
2872  }
2873  return this;
2874};
2875
2876/**
2877 * Stop the current animation, if on progress.
2878 * Should not trigger any error.
2879 *
2880 */
2881Vivus.prototype.stop = function () {
2882  if (this.handle) {
2883    cancelAnimFrame(this.handle);
2884    this.handle = null;
2885  }
2886  return this;
2887};
2888
2889/**
2890 * Destroy the instance.
2891 * Remove all bad styling attributes on all
2892 * path tags
2893 *
2894 */
2895Vivus.prototype.destroy = function () {
2896  this.stop();
2897  var i, path;
2898  for (i = 0; i < this.map.length; i++) {
2899    path = this.map[i];
2900    path.el.style.strokeDashoffset = null;
2901    path.el.style.strokeDasharray = null;
2902    this.renderPath(i);
2903  }
2904};
2905
2906
2907/**
2908 * Utils methods
2909 * include methods from Codrops
2910 **************************************
2911 */
2912
2913/**
2914 * Method to best guess if a path should added into
2915 * the animation or not.
2916 *
2917 * 1. Use the `data-vivus-ignore` attribute if set
2918 * 2. Check if the instance must ignore invisible paths
2919 * 3. Check if the path is visible
2920 *
2921 * For now the visibility checking is unstable.
2922 * It will be used for a beta phase.
2923 *
2924 * Other improvments are planned. Like detecting
2925 * is the path got a stroke or a valid opacity.
2926 */
2927Vivus.prototype.isInvisible = function (el) {
2928  var rect,
2929    ignoreAttr = el.getAttribute('data-ignore');
2930
2931  if (ignoreAttr !== null) {
2932    return ignoreAttr !== 'false';
2933  }
2934
2935  if (this.ignoreInvisible) {
2936    rect = el.getBoundingClientRect();
2937    return !rect.width && !rect.height;
2938  }
2939  else {
2940    return false;
2941  }
2942};
2943
2944/**
2945 * Parse attributes of a DOM element to
2946 * get an object of {attributeName => attributeValue}
2947 *
2948 * @param  {object} element DOM element to parse
2949 * @return {object}         Object of attributes
2950 */
2951Vivus.prototype.parseAttr = function (element) {
2952  var attr, output = {};
2953  if (element && element.attributes) {
2954    for (var i = 0; i < element.attributes.length; i++) {
2955      attr = element.attributes[i];
2956      output[attr.name] = attr.value;
2957    }
2958  }
2959  return output;
2960};
2961
2962/**
2963 * Reply if an element is in the page viewport
2964 *
2965 * @param  {object} el Element to observe
2966 * @param  {number} h  Percentage of height
2967 * @return {boolean}
2968 */
2969Vivus.prototype.isInViewport = function (el, h) {
2970  var scrolled   = this.scrollY(),
2971    viewed       = scrolled + this.getViewportH(),
2972    elBCR        = el.getBoundingClientRect(),
2973    elHeight     = elBCR.height,
2974    elTop        = scrolled + elBCR.top,
2975    elBottom     = elTop + elHeight;
2976
2977  // if 0, the element is considered in the viewport as soon as it enters.
2978  // if 1, the element is considered in the viewport only when it's fully inside
2979  // value in percentage (1 >= h >= 0)
2980  h = h || 0;
2981
2982  return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled;
2983};
2984
2985/**
2986 * Alias for document element
2987 *
2988 * @type {DOMelement}
2989 */
2990Vivus.prototype.docElem = window.document.documentElement;
2991
2992/**
2993 * Get the viewport height in pixels
2994 *
2995 * @return {integer} Viewport height
2996 */
2997Vivus.prototype.getViewportH = function () {
2998  var client = this.docElem.clientHeight,
2999    inner = window.innerHeight;
3000
3001  if (client < inner) {
3002    return inner;
3003  }
3004  else {
3005    return client;
3006  }
3007};
3008
3009/**
3010 * Get the page Y offset
3011 *
3012 * @return {integer} Page Y offset
3013 */
3014Vivus.prototype.scrollY = function () {
3015  return window.pageYOffset || this.docElem.scrollTop;
3016};
3017
3018/**
3019 * Alias for `requestAnimationFrame` or
3020 * `setTimeout` function for deprecated browsers.
3021 *
3022 */
3023requestAnimFrame = (function () {
3024  return (
3025    window.requestAnimationFrame       ||
3026    window.webkitRequestAnimationFrame ||
3027    window.mozRequestAnimationFrame    ||
3028    window.oRequestAnimationFrame      ||
3029    window.msRequestAnimationFrame     ||
3030    function(/* function */ callback){
3031      return window.setTimeout(callback, 1000 / 60);
3032    }
3033  );
3034})();
3035
3036/**
3037 * Alias for `cancelAnimationFrame` or
3038 * `cancelTimeout` function for deprecated browsers.
3039 *
3040 */
3041cancelAnimFrame = (function () {
3042  return (
3043    window.cancelAnimationFrame       ||
3044    window.webkitCancelAnimationFrame ||
3045    window.mozCancelAnimationFrame    ||
3046    window.oCancelAnimationFrame      ||
3047    window.msCancelAnimationFrame     ||
3048    function(id){
3049      return window.clearTimeout(id);
3050    }
3051  );
3052})();
3053
3054/**
3055 * Parse string to integer.
3056 * If the number is not positive or null
3057 * the method will return the default value
3058 * or 0 if undefined
3059 *
3060 * @param {string} value String to parse
3061 * @param {*}
3061 defaultValue Value to return if the result parsed is invalid
3062 * @return {number}
3063 *
3064 */
3065parsePositiveInt = function (value, defaultValue) {
3066  var output = parseInt(value, 10);
3067  return (output >= 0) ? output : defaultValue;
3068};
3069
3070
3071  if (typeof define === 'function' && define.amd) {
3072    // AMD. Register as an anonymous module.
3073    define([], function() {
3074      return Vivus;
3075    });
3076  } else if (typeof exports === 'object') {
3077    // Node. Does not work with strict CommonJS, but
3078    // only CommonJS-like environments that support module.exports,
3079    // like Node.
3080    module.exports = Vivus;
3081  } else {
3082    // Browser globals
3083    window.Vivus = Vivus;
3084  }
3085
3086}(window, document));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.