(function ($) {

'use strict';

/*!==========================================================================
 * ==========================================================================
 * ==========================================================================
 *
 * Cassio – Architect Portfolio AJAX HTML5 Template
 *
 * [Table of Contents]
 *
 * 1. PJAX Animate Clonned Heading
 * 2. PJAX Animate Curtain
 * 3. PJAX Clone Heading
 * 4. PJAX Finish Loading
 * 5. PJAX Get Flying Direction
 * 6. PJAX Init New Page
 * 7. PJAX Prepare Transition
 * 8. PJAX Transition Flying Heading
 * 9. PJAX Transition General
 * 10. PJAX Transition Overlay Menu
 * 11. PJAX Update Admin Bar
 * 12. PJAX Update Audio Background
 * 13. PJAX Update Body
 * 14. PJAX Update Cloud Flare Email Protection
 * 15. PJAX Update Head
 * 16. PJAX Update Language Switcher
 * 17. PJAX Update Nodes
 * 18. PJAX Update Scripts
 * 19. PJAX Update Styles
 * 20. PJAX Update Trackers
 * 21. PJAX Wait Container Images
 * 22. PJAX
 * 23. Assets Manager
 * 24. Audio Background
 * 25. Audio Control
 * 26. Button Circle
 * 27. Button Circles
 * 28. Cursor
 * 29. Effect Distortion
 * 30. Counter
 * 31. Figure Award
 * 32. Figure Portfolio Animation
 * 33. Figure Portfolio Hover
 * 34. Filter
 * 35. Form
 * 36. Grid
 * 37. Gmap
 * 38. Header
 * 39. Lazy Load
 * 40. Menu
 * 41. Menu Overlay
 * 42. Preloader
 * 43. Smooth Scroll
 * 44. Create OS Scene
 * 45. Get Scroll Top
 * 46. Lock Scroll
 * 47. Restore Scroll Top
 * 48. Scroll To Very Top
 * 49. Scroll Down
 * 50. Section About
 * 51. Section Awards
 * 52. Section Content
 * 53. Section Fullscreen Slider
 * 54. Section Grid
 * 55. Section Masthead
 * 56. Section Nav Projects
 * 57. Section Portfolio
 * 58. Section Properties
 * 59. Section Services
 * 60. Section Testimonials
 * 61. Slider Fullscreen
 * 62. Slider Images
 * 63. Render Slider Counter
 * 64. Render Slider Dots
 * 65. Set Slider Distortion Effect
 * 66. Set Slider Overlap Effect
 * 67. Set Slider Testimonials Transitions
 * 68. Set Slider Text Transitions
 * 69. Slider Letters
 * 70. Slider Testimonials
 * 71. Slider Projects
 * 72. Animate Chars
 * 73. Animate Headline
 * 74. Animate Lines
 * 75. Distribute By Position
 * 76. Do Split Text
 * 77. Hide Chars
 * 78. Hide Lines
 * 79. Hide Words
 * 80. Hide Words Vertical
 * 81. Set Chars
 * 82. Set Lines
 * 83. Debounce
 * 84. Fix Mobile Bar Height
 * 85. Fix Scroll Bar
 * 86. Is Anchor
 * 87. Load Swiper
 * 88. Run On High Performance GPU
 * 89. Sanitize Selector
 * 90. Sync Attributes
 * 91. Elementor
 *
 * ==========================================================================
 * ==========================================================================
 * ==========================================================================
 */

/**
 * Try to use high performance GPU on dual-GPU systems
 */
runOnHighPerformanceGPU();

window.$document = $(document);
window.$window = $(window);
window.$body = $('body');
window.$html = $('html');
window.$pageContent = $('.page-wrapper__content');
window.$pageHeader = $('.header');
window.$overlay = $('.header__wrapper-overlay-menu');
window.$barbaWrapper = $('[data-barba="wrapper"]');
window.PagePreloader = new Preloader();
window.$curtain = $('.transition-curtain');
window.triggerTextAlign = 'left';
window.$spinner = $('.js-spinner');

/**
 * Begin Page Load
 */
window.PagePreloader.start();

/**
 * Default Theme Options
 * Used to prevent errors if there is
 * no data provided from backend
 */
if (typeof window.theme === 'undefined') {
	window.theme = {
		ajax: {
			enabled: true,
			preventRules: '',
			evalInlineContainerScripts: false,
			loadMissingScripts: false,
			loadMissingStyles: false
		},
		animations: {
			triggerHook: 0.85,
			timeScale: {
				onScrollReveal: 1,
				overlayMenuOpen: 1,
				overlayMenuClose: 1.5,
			},
			flyingHeadingsStagger: 0.15,
			cursorAttractionDelay: 0.04
		},
		smoothScroll: {
			damping: 0.06,
			renderByPixels: true,
			continuousScrolling: false,
			plugins: {
				edgeEasing: true
			}
		},
		audio: {
			playing: {
				label: 'Sound on',
				icon: 'pause'
			},
			paused: {
				label: 'Sound off',
				icon: 'play'
			}
		},
		mobileBarFix: {
			enabled: true,
			update: true
		},
		assets: {
			promises: []
		}
	}
}

/**
 * ScrollMagic Setup
 */
window.SMController = new ScrollMagic.Controller();
window.SMController.enabled(false);
window.SMSceneTriggerHook = window.theme.animations.triggerHook;
window.SMSceneReverse = false;

/**
 * Don't save scroll position
 * after AJAX transition
 */
if ('scrollRestoration' in history) {
	history.scrollRestoration = 'manual';
}

/**
 * Page Load Strategy
 */
window.$document.ready(function () {

	Promise.all([,
		loadSwiper(),
		document.fonts.ready
	])
		.then(function () {
			return doSplitText();
		})
		.then(function () {
			return setLines();
		})
		.then(function () {
			return setChars();
		})
		.then(function () {
			lazyLoad(window.$document);
			initComponents(window.$document);
			return window.PagePreloader.finish();
		})
		.then(function () {
			window.SMController.enabled(true);
			window.SMController.update(true);
			window.$body.removeClass('cursor-progress');
		});

	new PJAX();

	if ($('#js-audio-background').length) {
		window.AudioBackground = new AudioBackground(window.$document);
		window.AudioBackground.run();
	}

	window.InteractiveCursor = new Cursor();

});

/**
 * Init Template Components
 */
function initComponents($scope = window.$document) {

	new SmoothScroll();

	window.PageHeader = new Header();

	if (typeof window.PageMenu === 'undefined') {
		window.PageMenu = new MenuOverlay();
	}

	new Grid();
	new SectionGrid($scope);
	new SectionMasthead($scope);
	new SectionPortfolio($scope);
	new SectionNavProjects($scope);
	new SectionFullscreenSlider($scope);
	new SectionContent($scope);
	new SectionAbout($scope);
	new SectionServices($scope);
	new SectionTestimonials($scope);
	new SectionAwards($scope);
	new SectionProperties($scope);
	new SliderImages($scope);
	new SliderProjects($scope);
	new SliderLetters($scope);
	$('.js-video').magnificPopup();
	new ScrollDown();
	new Form();
	new GMap($scope);
	new ButtonCircle($scope);
	if (window.theme.mobileBarFix.enabled) {
		fixMobileBarHeight();
	}
	lazyLoad($scope);
	objectFitVideos(document.querySelectorAll('video.of-cover'));

	$('[data-art-parallax]').artParallax({
		ScrollMagicController: window.SMController,
		SmoothScrollController: window.SB
	});

	// refresh animation triggers
	// for Waypoints library
	if (typeof Waypoint !== 'undefined') {
		Waypoint.refreshAll();
	}

	// custom JS code
	if (window.theme.customJSInit) {
		try {
			window.eval(window.theme.customJSInit);
		} catch (error) {
			console.warn(error);
		}
	}

	// anchors AJAX smooth scrolling
	if (window.location.hash && !window.location.hash.startsWith('#elementor-action')) {
		var
			$scrollElement = $(window.location.hash),
			$preloader = $('.js-preloader'),
			time = 800,
			timeout = $preloader.length ? 1500 : 300;

		if ($scrollElement.length) {
				var offsetY = $scrollElement.offset().top;

			setTimeout(() => {
				if (typeof window.SB !== 'undefined') {
					window.SB.scrollTo(0, offsetY, time);
				} else {
					$('html, body').animate({
						scrollTop: offsetY
					}, time);
				}
	
			}, timeout);
	
		}
	}	

}

/*!========================================================================
	1. PJAX Animate Clonned Heading
	======================================================================!*/
function PJAXAnimateClonnedHeading(data, $customPositionElement) {

	return new Promise(function (resolve, reject) {

		var
			tl = new TimelineMax(),
			$nextContainer = $(data.next.container),
			$trigger = $(data.trigger),
			$nextContent = $nextContainer.find('.page-wrapper__content'),
			$clonnedHeading = $('.js-text-to-fly.clone'),
			$clonnedHeadingChars = $clonnedHeading.find('.split-text__char.clone'),
			$mastheadHeading = $nextContainer.find('.section-masthead .js-text-to-fly'),
			staggerAmount = 0.15,
			$mastheadHeadingChars,
			$mastheadHeadingWords,
			$mastheadHeadingLines,
			coordinates = [],
			CSSProperties,
			from,
			resolveTiming = $('.section-masthead_big-heading[data-os-animation]').length ? 0.6 : 0.9;

		if (!$mastheadHeading.length) {

			tl.set($nextContent, {
				y: '10vh',
			})
				.to($clonnedHeading, 0.6, {
					autoAlpha: 0,
					display: 'none',
					y: '-100%'
				})
				.to(window.$curtain, 1.2, {
					y: '-100%',
					ease: Expo.easeInOut
				}, '0.6')
				.to($nextContent, 2.4, {
					y: '0vh',
					ease: Expo.easeInOut,
				}, '0')
				.set(window.$curtain, {
					y: '100%',
					display: 'none'
				})
				.set($trigger, {
					autoAlpha: 1
				})
				.add(function () {
					$clonnedHeading.remove();
				})
				.add(function () {
					resolve(true);
				}, '0.8');

			return;

		}

		if (window.theme !== 'undefined') {

			staggerAmount = window.theme.animations.flyingHeadingsStagger || 0.15;

		}

		$mastheadHeadingChars = $mastheadHeading.find('.split-text__char');
		$mastheadHeadingWords = $mastheadHeading.find('.split-text__word');
		$mastheadHeadingLines = $mastheadHeading.find('.split-text__line');
		CSSProperties = $mastheadHeadingChars.css(['text-align', 'font-size', 'line-height', 'color', 'opacity']);
		from = PJAXGetFlyingDirection($clonnedHeading, $mastheadHeading);

		// clear any transforms for the correct
		// position calculation
		TweenMax.set([$mastheadHeadingChars, $mastheadHeadingWords, $mastheadHeadingLines], {
			x: 0,
			y: 0,
			clearProps: 'transform'
		});

		// clear transforms on page content wrapper
		// in case it may be shifted
		TweenMax.set($nextContent, {
			clearProps: 'all'
		});

		$mastheadHeadingChars.each(function (index) {

			var current = $(this).get(0).getBoundingClientRect();

			coordinates[index] = {
				top: current.top,
				left: current.left
			};

		});

		tl
			.add(function () {
				scrollToVeryTop();
			})
			.set($nextContent, {
				y: '10vh',
			})
			.delay(0.2)
			.staggerTo($clonnedHeadingChars, 1.2, {
				position: 'absolute',
				fontSize: CSSProperties['font-size'],
				lineHeight: CSSProperties['line-height'],
				transform: 'none',
				autoAlpha: 1,
				cycle: {
					left: function (index) {

						if (coordinates[index]) {
							return coordinates[index].left + 'px';
						} else {
							$clonnedHeadingChars[index].remove();
							return '0px';
						}

					},
					top: function (index) {

						if (coordinates[index]) {
							return coordinates[index].top + 'px';
						} else {
							$clonnedHeadingChars[index].remove();
							return '0px';
						}

					}
				},
				stagger: distributeByPosition({
					amount: staggerAmount,
					from: from
				}),
				ease: Power3.easeInOut,
			})
			.set([$mastheadHeadingChars, $mastheadHeadingWords, $mastheadHeadingLines], {
				autoAlpha: 1,
				clearProps: 'transform'
			}, '+=0.6')
			.add(function () {
				$clonnedHeading.remove();
			})
			.add(function () {
				if ($mastheadHeading.hasClass('section-masthead__heading-big')) {
					tl.to($clonnedHeadingChars, 1.2, {
						opacity: .3
					}, '0.6');
				}
			}, '0.6')
			.to($clonnedHeadingChars, 1.2, {
				color: CSSProperties['color'],
			}, '0.6')
			.to(window.$curtain, 1.2, {
				y: '-100%',
				ease: Expo.easeInOut
			}, '0.6')
			.to($nextContent, 2.4, {
				y: '0vh',
				onComplete: function () {
					TweenMax.set($nextContent, {
						clearProps: 'all'
					});
				},
				ease: Expo.easeInOut,
			}, '0')
			.set(window.$curtain, {
				y: '100%',
				display: 'none'
			})
			.set($trigger, {
				autoAlpha: 1
			})
			.add(function () {
				resolve(true);
			}, resolveTiming);

	});

}

/*!========================================================================
	2. PJAX Animate Curtain
	======================================================================!*/
function PJAXAnimateCurtain(direction = 'in') {

	return new Promise(function (resolve, reject) {

		var
			tl = new TimelineMax(),
			$pageContent = $('.page-wrapper__content');

		if (!window.$curtain.length) {
			resolve(true);
			return;
		}

		tl.timeScale(1.5);

		if (direction == 'in') {

			tl
				.to(window.$curtain, 1.2, {
					y: '0%',
					ease: Expo.easeInOut
				}, '0')
				.to($pageContent, 1.2, {
					y: '-5vh',
					ease: Expo.easeInOut,
					onComplete: function () {
						TweenMax.set($pageContent, {
							clearProps: 'all'
						});
					}
				}, '-=1.0')
				.add(function () {
					resolve(true);
				});

		} else if (direction == 'out') {

			tl
				.fromTo($pageContent, 2.4, {
					y: '10vh',
				}, {
					y: '0vh',
					ease: Expo.easeInOut,
					onComplete: function () {
						TweenMax.set($pageContent, {
							clearProps: 'all'
						});
					}
				}, '0')
				.to(window.$curtain, 1.2, {
					y: '-100%',
					ease: Expo.easeInOut
				}, '0.6')
				.add(function () {
					resolve(true);
				}, '-=1.2');

		}

	});

}

/*!========================================================================
	3. PJAX Clone Heading
	======================================================================!*/
function PJAXCloneHeading(data, $customPositionElement) {

	return new Promise(function (resolve, reject) {
		var
			tl = new TimelineMax(),
			$trigger = $(data.trigger),
			$pageContent = $('.page-wrapper__content'),
			$heading = $trigger.find('.js-text-to-fly'),
			$headingChars,
			CSSProperties = [],
			coordinates,
			$clone;

		window.cloneCoordinates = [];

		if (!$heading.length) {
			$heading = $trigger.parent().parent().find('.js-text-to-fly');
		}

		if (!$heading.length) {
			resolve(true);
		}

		CSSProperties = $heading.css([
			'font-size',
			'font-style',
			'font-weight',
			'line-height',
			'letter-spacing',
			'color',
			'text-align'
		]);

		$headingChars = $heading.find('.split-text__char');
		$clone = $heading.clone();
		$clone.css(CSSProperties);
		coordinates = $heading.get(0).getBoundingClientRect();

		tl
			.set($heading, {
				autoAlpha: 0
			})
			.add(function () {

				return new Promise(function (resolve, reject) {

					$clone.attr({
						'data-origin-top': coordinates['top'],
						'data-origin-left': coordinates['left'],
						'data-origin-right': coordinates['right'],
						'data-origin-bottom': coordinates['bottom'],
					});

					$headingChars.each(function (index) {

						var
							$current = $(this),
							current = $current.get(0).getBoundingClientRect(),
							$cloneChar = $clone.find('.split-text__char')[index];

						window.cloneCoordinates[index] = {
							top: current.top,
							left: current.left
						};

						TweenMax.set($cloneChar, {
							position: 'fixed',
							top: window.cloneCoordinates[index].top,
							left: window.cloneCoordinates[index].left,
							className: '+=clone',
							clearProps: 'transform',
							zIndex: 600
						});

					});

					resolve(true);

				});

			})
			.set($clone, {
				display: 'flex',
				className: '+=clone',
				position: 'fixed',
				top: 0,
				left: 0,
				width: 0,
				height: 0,
				margin: 0,
				padding: 0,
				zIndex: 600
			})
			.add(function () {
				$clone.appendTo(window.$barbaWrapper);
			})
			.add([
				window.PageHeader.hideOverlayMenu(1.5, false),
				TweenMax.to(window.$curtain, 1.2, {
					y: '0%',
					ease: Expo.easeInOut
				}),
				TweenMax.to($pageContent, 1.6, {
					y: '-10vh',
					ease: Expo.easeInOut,
					onUpdate: function () {
						// update scrollbar geometry
						if (typeof window.SB !== 'undefined') {
							window.SB.update();
						}
					},
					onComplete: function () {
						TweenMax.set($pageContent, {
							clearProps: 'all'
						});

						// update scrollbar geometry
						if (typeof window.SB !== 'undefined') {
							window.SB.update();
						}
					}
				})
			])
			.set($heading, {
				clearProps: 'opacity,visibility'
			})
			.add(function () {
				resolve(true);
			}, '-=0.6');

	});

}

/*!========================================================================
	4. PJAX Finish Loading
	======================================================================!*/
function PJAXFinishLoading(data) {

	return new Promise(function (resolve, reject) {

		var
			tl = new TimelineMax();

		TweenMax.to(window.$spinner, 1.2, {
			autoAlpha: 0
		});

		tl
			.add(function () {

				// audio backgrounds
				if (typeof window.AudioBackground !== 'undefined') {

					if (window.AudioBackground.isAudioSrc()) {
						window.AudioBackground.controller.reveal(true);
					} else {
						window.AudioBackground.controller.reveal(false);
					}
				}

				window.SMController.enabled(true);
				window.SMController.update(true);
				window.$pageHeader.attr('data-header-animation', '');
			})
			.add(function () {
				if (!$('.section-masthead_big-heading[data-os-animation]').length) {
					lockScroll(false);
				}
			}, '1.2')
			.add(function () {
				window.$body.removeClass('cursor-progress');
				window.InteractiveCursor.finishLoading();

				// Transition ended event
				window.dispatchEvent(new CustomEvent('arts/barba/transition/end'));
			})
			.add(function () {
				resolve(true);
			});

	});

}

/*!========================================================================
	5. PJAX Get Flying Direction
	======================================================================!*/
function PJAXGetFlyingDirection($clone, $target) {

	if (!$clone.length || !$target.length) {
		return 'start';
	}

	var coordinatesTarget = $target.get(0).getBoundingClientRect();

	if (
		$clone.attr('data-origin-left') > coordinatesTarget['left'] &&
		$clone.attr('data-origin-right') < coordinatesTarget['right'] &&
		$clone.css('text-align') == 'center' &&
		$target.css('text-align') == 'center'
	) {
		return 'center';
	}

	if ($clone.attr('data-origin-left') > coordinatesTarget['left']) {
		return 'start';
	} else {
		return 'end';
	}

}

/*!========================================================================
	6. PJAX Init New Page
	======================================================================!*/
function PJAXInitNewPage(data) {

	return new Promise(function (resolve, reject) {

		var
			promises = [
				PJAXUpdateBody(data),
				PJAXUpdateNodes(data),
				PJAXUpdateHead(data),
				PJAXUpdateAdminBar(data),
				PJAXUpdateLanguageSwitcher(data)
			],
			$currentContainer = $(data.current.container),
			$nextContainer = $(data.next.container),
			$elementorSections = $nextContainer.find('.elementor-section'),
			$cf7Forms = $nextContainer.find('.wpcf7-form'),
			event = document.createEvent('MutationEvents');

		$currentContainer.remove();

		if (window.theme.ajax.loadMissingScripts || window.theme.updateScriptNodes) {
			promises.push(PJAXUpdateScripts(data));
		}

		if (window.theme.ajax.loadMissingStyles) {
			promises.push(PJAXUpdateStyles(data));
		}

		// Prepare ready event
		event.initMutationEvent('DOMContentLoaded', true, true, document, '', '', '', 0);

		PJAXUpdateAudioBackground(data).then(function () {

			return Promise
				.all(promises)
				.then(() => document.fonts.ready)
				.then(function () {
					return doSplitText($nextContainer);
				})
				.then(function () {
					return setLines($nextContainer);
				})
				.then(function () {
					return setChars($nextContainer);
				})
				.then(function () {

					// Elementor Pro sticky effects handling
					TweenMax.set($elementorSections, {
						clearProps: 'all',
						className: '-=elementor-sticky--active'
					});
					$nextContainer.find('.elementor-sticky__spacer').remove();

					// Elementor Animated Headline reset
					$nextContainer.find('.elementor-headline-animation-type-typing .elementor-headline-dynamic-wrapper').empty();

					// Elementor Pro Lottie animations reset
					$nextContainer.find('.e-lottie__animation').empty();

					// re-init Contact Form 7 Conditional Fields plugin
					if ($cf7Forms.length && typeof wpcf7cf === 'object' && typeof wpcf7cf.initForm === 'function') {
						wpcf7cf.initForm($cf7Forms);
					}

					// re-init WPForms plugin
					if (typeof wpforms !== 'undefined' && typeof wpforms.init === 'function') {
						wpforms.init();
					}

					// clear & re-init ScrollMagic
					window.SMController.destroy(true);
					window.SMController = new ScrollMagic.Controller();

					// Transition init new page event (before components init)
					window.dispatchEvent(new CustomEvent('arts/barba/transition/init/before'));

					// re-init components
					initComponents($nextContainer);

					// don't start animations immediately
					window.SMController.enabled(false);

					// scroll at the page beginning
					scrollToVeryTop();

					// fire ready event
					document.dispatchEvent(event);

					if (window.theme.ajax.evalInlineContainerScripts) {

						// eval inline scripts in the main container
						$nextContainer.find('script').each(function () {
							try {
								window.eval(this.text);
							} catch (error) {
								console.warn(error);
							}
						});

					}

					// ensure that scroll is still locked
					lockScroll(true);

					// Transition init new page event (after components init)
					window.dispatchEvent(new CustomEvent('arts/barba/transition/init/after'));

					// init Elementor frontend
					if (typeof window.elementorFrontend !== 'undefined') {
						elementorFrontend.init();
					}

					// update ad trackers
					PJAXUpdateTrackers();

					// Update "Email Protection" by CloudFlare
					PJAXUpdateCloudFlareEmailProtection();

					resolve(true);

				})
				.catch((e) => {
					barba.force(data.next.url.href);
					console.warn(e);
				});

		});

	});

}

/*!========================================================================
	7. PJAX Prepare Transition
	======================================================================!*/
function PJAXPrepareTransition(data) {

	return new Promise(function (resolve, reject) {

		var
			tl = new TimelineMax(),
			$trigger = $(data.trigger),
			$heading = $trigger.find('.js-text-to-fly');

		// Transition started event
		window.dispatchEvent(new CustomEvent('arts/barba/transition/start'));

		if (!$heading.length) {
			$heading = $trigger.parent().parent().find('.js-text-to-fly');
		}

		if (!$heading.length) {
			$heading = $trigger;
		}

		TweenMax.to(window.$spinner, 0.6, {
			autoAlpha: 1
		});

		tl
			.add(function () {
				window.InteractiveCursor.startLoading();
				window.$body.addClass('cursor-progress');
			})
			.set(window.$curtain, {
				display: 'block',
				y: '100%',
				zIndex: 550
			})
			.set($trigger, {
				className: '+=selected'
			})
			.add(function () {
				lockScroll(true);
				window.triggerTextAlign = $heading.css('text-align');
				window.$document.off('click');
				resolve(true);
			});

	});

}

/*!========================================================================
	8. PJAX Transition Flying Heading
	======================================================================!*/
var PJAXTransitionFlyingHeading = {
	name: 'flyingHeading',
	custom: ({
		current,
		next,
		trigger
	}) => {
		return $(trigger).data('pjax-link') == 'flyingHeading';
	},

	before: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXPrepareTransition(data).then(function () {
				resolve(true);
			});

		});

	},

	beforeLeave: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXCloneHeading(data).then(function () {
				resolve(true);
			});

		});

	},

	beforeEnter: (data) => {

		return new Promise(function (resolve, reject) {

			var
				$nextContainer = $(data.next.container),
				$mastheadHeading = $nextContainer.find('.section-masthead .js-text-to-fly');

			// don't trigger reveal animation on heading
			$mastheadHeading.addClass('js-split-text_cancel-animation');
			resolve(true);

		});
	},

	enter: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXInitNewPage(data).then(function () {
				resolve(true);
			});

		});
	},

	afterEnter: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXAnimateClonnedHeading(data).then(function () {
				resolve(true);
			});

		});

	},

	after: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXFinishLoading(data).then(function () {
				resolve(true);
			});

		});

	}

}

/*!========================================================================
	9. PJAX Transition General
	======================================================================!*/
var PJAXTransitionGeneral = {

	before: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXPrepareTransition(data).then(function () {
				resolve(true);
			});

		});

	},

	beforeLeave: (data) => {

		return new Promise(function (resolve, reject) {

			if (window.PageHeader) {
				window.PageHeader.hideOverlayMenu(1.5, false);
			}

			PJAXAnimateCurtain('in').then(function () {
				resolve(true);
			});

		});

	},

	enter: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXInitNewPage(data).then(function () {
				resolve(true);
			});

		});
	},

	afterEnter: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXAnimateCurtain('out').then(function () {
				resolve(true);
			});

		});

	},


	after: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXFinishLoading(data).then(function () {
				resolve(true);
			});

		});

	}

}

/*!========================================================================
	10. PJAX Transition Overlay Menu
	======================================================================!*/
var PJAXTransitionOverlayMenu = {
	name: 'overlayMenu',
	custom: ({
		current,
		next,
		trigger
	}) => {
		return $(trigger).data('pjax-link') == 'overlayMenu';
	},

	before: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXPrepareTransition(data).then(function () {
				resolve(true);
			});

		});

	},

	beforeLeave: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXCloneHeading(data).then(function () {
				resolve(true);
			});

		});

	},

	beforeEnter: (data) => {

		return new Promise(function (resolve, reject) {

			var
				$nextContainer = $(data.next.container),
				$mastheadHeading = $nextContainer.find('.section-masthead .js-text-to-fly');

			// don't trigger reveal animation on heading
			if ($mastheadHeading.length) {
				$mastheadHeading.addClass('js-split-text_cancel-animation');
			}

			resolve(true);

		});
	},

	enter: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXInitNewPage(data).then(function () {
				resolve(true);
			});

		});
	},

	afterEnter: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXAnimateClonnedHeading(data).then(function () {
				resolve(true);
			});

		});

	},

	after: (data) => {

		return new Promise(function (resolve, reject) {

			PJAXFinishLoading(data).then(function () {
				resolve(true);
			});

		});

	}

}

/*!========================================================================
	11. PJAX Update Admin Bar
	======================================================================!*/
function PJAXUpdateAdminBar(data) {
	return new Promise(function (resolve, reject) {
		const
			$elementorAdminBarConfigScript = $('#elementor-admin-bar-js-before'),
			$currentBar = $('#wpadminbar');

		if (!$currentBar.length) {
			resolve(true);
			return;
		}

		const
			$rawHTML = $($.parseHTML(data.next.html, undefined, true)),
			$newBar = $rawHTML.filter('#wpadminbar');

		if ($newBar.length) {
			$newBar.find('.hide-if-no-customize').removeClass('hide-if-no-customize');
			$currentBar.html($newBar.html());
		}

		// re-init Elementor admin bar buttons
		if (document.body.classList.contains('elementor-page') && $elementorAdminBarConfigScript.length) {
			try {
				const $nextElementorAdminBarConfigScript = $rawHTML.filter('#elementor-admin-bar-js-before');

				if ($nextElementorAdminBarConfigScript.length) {
					// update the script contents
					$elementorAdminBarConfigScript.html($nextElementorAdminBarConfigScript.text());

					// eval new script params
					window.eval($elementorAdminBarConfigScript.text());
				}

			} catch (err) {
				console.warn(err);
			}
		}

		resolve(true);
	});
}

/*!========================================================================
	12. PJAX Update Audio Background
	======================================================================!*/
function PJAXUpdateAudioBackground(data) {

  return new Promise(function (resolve, reject) {

    var
      $nextContainer = $($.parseHTML(data.next.html)),
      $audioBackground = $('#js-audio-background'),
      $audioBackgroundOptions = $nextContainer.find('#js-audio-background__options');

    if (typeof window.AudioBackground !== 'undefined') {

      switch ($audioBackgroundOptions.data('options')) {
        case 'music_off':
          window.AudioBackground.fadeOut().then(function () {
            // the next page audio source is different
            // just update audio src but don't start playback
            if ($nextContainer.find('#js-audio-background').attr('src') !== $audioBackground.attr('src')) {
              syncAttributes($nextContainer.find('#js-audio-background'), $audioBackground);
            }

            window.AudioBackground.el.currentTime = 0;
            window.AudioBackground.el.pause();
            window.AudioBackground.controller.pause();
          });
          break;
        case 'play':
          // audio autoplay is enabled
          if (window.AudioBackground.el.autoplay === true) {

            // the next page audio source is different
            // fade out current volume, update src, start playback
            if ($nextContainer.find('#js-audio-background').attr('src') !== $audioBackground.attr('src')) {
              window.AudioBackground.fadeOut().then(function () {
                syncAttributes($nextContainer.find('#js-audio-background'), $audioBackground);
                window.AudioBackground.fadeIn();
              });
            }

            // the next page audio source is the same as current
            // reset position and start playback if it's paused
            if (window.AudioBackground.el.paused) {
              window.AudioBackground.el.currentTime = 0;
              window.AudioBackground.fadeIn();
            }

          } else { // audio autoplay is disabled

            if (window.AudioBackground.el.paused) { // playback is paused

              // the next page audio source is different
              // just update audio src but don't start playback
              if ($nextContainer.find('#js-audio-background').attr('src') !== $audioBackground.attr('src')) {
                syncAttributes($nextContainer.find('#js-audio-background'), $audioBackground);
              }

            } else { // playback is running

              // the next page audio source is different
              // fade out current volume, update src, start playback
              if ($nextContainer.find('#js-audio-background').attr('src') !== $audioBackground.attr('src')) {
                window.AudioBackground.fadeOut().then(function () {
                  syncAttributes($nextContainer.find('#js-audio-background'), $audioBackground);
                  window.AudioBackground.fadeIn();
                });
              }

            }

          }
          break;
        default:
          window.AudioBackground.el.currentTime = 0;
          window.AudioBackground.fadeIn();
          break;
      }
    }

    resolve(true);

  });
}

/*!========================================================================
	13. PJAX Update Body
	======================================================================!*/
function PJAXUpdateBody(data) {

	return new Promise(function (resolve, reject) {

		var
			regexp = /\<body.*\sclass=["'](.+?)["'].*\>/gi,
			match = regexp.exec(data.next.html);

		if (!match || !match[1]) {
			resolve(true);
		}

		// Interrupt the transition
		// Current page prevents all the inner links from transition
		if (document.body.classList.contains('no-ajax')) {
			reject('Transition has been interrupted: Origin page prevents all the inner links from transition.');
			return;
		}

		// Sync new container body classes
		document.body.setAttribute('class', match[1]);

		// Interrupt the transition
		// Destination page doesn't allow to perform AJAX transition
		if (document.body.classList.contains('page-no-ajax')) {
			reject('Transition has been interrupted: Destination page requested a hard refresh.');
			return;
		}

		// Hide theme header on Elementor Canvas page
		if (document.body.classList.contains('elementor-template-canvas')) {
			window.$pageHeader.addClass('hidden');
		}

		// Clear window overflow rule in case Elementor Canvas page
		// doesn't have smooth scrolling container
		if (!$(data.next.container).find('.js-smooth-scroll').length) {
			TweenMax.set(window.$html, {
				clearProps: 'overflow'
			});
		}

		resolve(true);

	});

}

/*!========================================================================
	14. PJAX Update Cloud Flare Email Protection
	======================================================================!*/
function PJAXUpdateCloudFlareEmailProtection() {
	var HEADER = "/cdn-cgi/l/email-protection#",
		SPECIAL_SELECTOR = ".__cf_email__",
		SPECIAL_ATTRIBUTE = "data-cfemail",
		DIV = document.createElement("div");

	function error(e) {
		try {
			if ("undefined" == typeof console) return;
			"error" in console ? console.error(e) : console.log(e)
		} catch (e) { }
	}

	function sanitize(e) {
		DIV.innerHTML = '<a href="' + e.replace(/"/g, "&quot;") + '"></a>';
		return DIV.childNodes[0].getAttribute("href") || ""
	}

	function nextHex(hexstr, skip) {
		return parseInt(hexstr.substr(skip, 2), 16)
	}

	function decrypt(ciphertext, skip) {
		for (var out = "", magic = nextHex(ciphertext, skip), i = skip + 2; i < ciphertext.length; i += 2) {
			var hex = nextHex(ciphertext, i) ^ magic;
			out += String.fromCharCode(hex)
		}
		try {
			out = decodeURIComponent(escape(out))
		} catch (err) {
			error(err)
		}
		return sanitize(out)
	}

	function decryptLinks(doc) {
		for (var links = doc.querySelectorAll("a"), c = 0; c < links.length; c++) try {
			var currentLink = links[c];
			var a = currentLink.href.indexOf(HEADER);
			a > -1 && (currentLink.href = "mailto:" + decrypt(currentLink.href, a + HEADER.length))
		} catch (err) {
			error(err)
		}
	}

	function decryptOthers(doc) {
		for (var specials = doc.querySelectorAll(SPECIAL_SELECTOR), c = 0; c < specials.length; c++) try {
			var current = specials[c],
				parent = current.parentNode,
				ciphertext = current.getAttribute(SPECIAL_ATTRIBUTE);
			if (ciphertext) {
				var email = decrypt(ciphertext, 0),
					tmpDOM = document.createTextNode(email);
				parent.replaceChild(tmpDOM, current)
			}
		} catch (err) {
			error(err)
		}
	}

	function decryptTemplates(doc) {
		for (var templates = doc.querySelectorAll("template"), n = 0; n < templates.length; n++) try {
			init(templates[n].content)
		} catch (err) {
			error(err)
		}
	}

	function init(doc) {
		try {
			decryptLinks(doc);
			decryptOthers(doc);
			decryptTemplates(doc);
		} catch (err) {
			error(err)
		}
	}

	init(document);
}

/*!========================================================================
	15. PJAX Update Head
	======================================================================!*/
function PJAXUpdateHead(data) {

	return new Promise(function(resolve, reject) {

		var
			head = document.head,
			newPageRawHead = data.next.html.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0],
			newPageHead = document.createElement('head'),
			customNodes = sanitizeSelector(window.theme.updateHeadNodes),
			oldHeadTags,
			newHeadTags,
			newStylesLoaded,
			pageStyles,
			headTags = [
				'meta[name="keywords"]',
				'meta[name="description"]',
				'meta[property^="og"]',
				'meta[name^="twitter"]',
				'meta[itemprop]',
				'link[itemprop]',
				'link[rel="prev"]',
				'link[rel="next"]',
				'link[rel="canonical"]',
				'link[rel="alternate"]',
				'link[rel="shortlink"]',
				'link[id*="elementor"]',
				'link[id*="eael"]', // Essential Addons plugin post CSS
				'link[id*="theplus-"]', // ThePlus Elementor addon
				'style[id*="elementor"]',
				'style[id*="eael"]', // Essential Addons plugin inline CSS
				'style[id*="theplus-"]', // ThePlus Elementor addon
				'link[id*="google-fonts"]' // Elementor inline fonts
			];

		// Custom head nodes to update
		if (customNodes) {
			headTags = [...headTags, ...customNodes.split(',')]

			// Make the node names unique
			headTags = [... new Set(headTags)];
		}

		// Prepare the selector
		headTags = headTags.join(',');

		newPageHead.innerHTML = newPageRawHead;

		try {
			oldHeadTags = head.querySelectorAll(headTags),
			newHeadTags = newPageHead.querySelectorAll(headTags),
			newStylesLoaded = [];
			pageStyles = document.querySelectorAll('link[rel="stylesheet"]');

		} catch (error) {
			reject(`Transition has been interrupted: Invalid selector given "${customNodes}"`);
		}

		// flag all current page styles as loaded
		for (var i = 0; i < pageStyles.length; i++) {
			pageStyles[i].isLoaded = true;
		}
		// append new and remove old tags
		for (var i = 0; i < newHeadTags.length; i++) {
			if (typeof oldHeadTags[i] !== 'undefined') {
				head.insertBefore(newHeadTags[i], oldHeadTags[i].nextElementSibling);
				head.removeChild(oldHeadTags[i]);
			} else {
				head.insertBefore(newHeadTags[i], newHeadTags[i - 1]);
			}
		}

		// page now has new styles
		pageStyles = document.querySelectorAll('link[rel="stylesheet"]');

		// listen for 'load' only on elements which are not loaded yet
		for (var i = 0; i < pageStyles.length; i++) {
			if (!pageStyles[i].isLoaded) {
				const promise = new Promise((resolve) => {
					pageStyles[i].addEventListener('load', () => {
						resolve(true);
					});
				});

				newStylesLoaded.push(promise);
			}
		}

		// load all new page styles
		Promise.all(newStylesLoaded).then(() => {
			resolve(true);
		});

	});
}

/*!========================================================================
	16. PJAX Update Language Switcher
	======================================================================!*/
function PJAXUpdateLanguageSwitcher(data) {

	return new Promise(function (resolve, reject) {

		var $currentSwitcher = $('.lang-switcher');

		if (!$currentSwitcher.length) {
			resolve(true);
			return;
		}

		var
			rawHTML = $.parseHTML(data.next.html, document, true), // make sure to parse <script> tags as well
			$newSwitcher = $(rawHTML).find('.lang-switcher'),
			$trpSwitcher = $newSwitcher.find('.trp-language-switcher'); // TranslatePress language switcher

		$currentSwitcher.replaceWith($newSwitcher);

		// eval language switcher inline scripts
		$newSwitcher.find('script').each(function () {
			try {
				window.eval(this.text);
			} catch (error) {
				console.warn(error);
			}
		});

		// reset width of TranslatePress language switcher
		if ($trpSwitcher.length) {
			TweenMax.set($newSwitcher.find('.trp-ls-shortcode-language, .trp-ls-shortcode-current-language'), {
				clearProps: 'width'
			});
		}

		resolve(true);

	});

}

/*!========================================================================
	17. PJAX Update Nodes
	======================================================================!*/
function PJAXUpdateNodes(data) {

	return new Promise(function (resolve, reject) {

		var
			$nextContainer = $($.parseHTML(data.next.html)),
			nodesToUpdate = [
				'#page-header',
				'#page-footer',
				'.header__wrapper-overlay-menu',
				'.transition-curtain',
				'#js-audio-background__options',
				'#page-header .menu li',
				'#page-header .menu-overlay li'
			]; // selectors of elements that needed to update

		$.each(nodesToUpdate, function () {

			var
				$item = $(this),
				$nextItem = $nextContainer.find(this);

			// different type of menu (overlay) found on the next page
			if (this === '#page-header .menu li' && !$nextItem.length) {
				$nextItem = $nextContainer.find('#page-header .menu-overlay li');
			}

			// different type of menu (classic) found on the next page
			if (this === '#page-header .menu-overlay li' && !$nextItem.length) {
				$nextItem = $nextContainer.find('#page-header .menu li');
			}

			// sync attributes if element exist in the new container
			if ($nextItem.length) {
				syncAttributes($nextItem, $item);
			}

		});

		resolve(true);

	});

}

/*!========================================================================
	18. PJAX Update Scripts
	======================================================================!*/
function PJAXUpdateScripts(data) {
  return new Promise((resolve) => {
    const
      nextDocument = jQuery.parseHTML(data.next.html, document, true),
      scriptsToLoad = [],
      customNodes = sanitizeSelector(window.theme.updateScriptNodes) || [],
      $nextScripts = $(nextDocument).filter('script[src][id]');

    $nextScripts.each(function () {
      const
        queryString = `script[id="${this.id}"]`,
        element = document.querySelector(queryString);

      // load script that's not present on the current page
      if (typeof element === 'undefined' || element === null) {
        scriptsToLoad.push(AssetsManager.load({
          type: 'script',
          id: this.id,
          src: this.src
        }));
      } else if (customNodes.includes(queryString)) { // force update existing script

        // remove current script
        element.remove();

        // re-load script
        scriptsToLoad.push(AssetsManager.load({
          type: 'script',
          id: this.id,
          src: this.src,
          update: true
        }));
      }
    });

    Promise
      .all(scriptsToLoad)
      .then(() => resolve(true), () => resolve(true));
  });
}

/*!========================================================================
	19. PJAX Update Styles
	======================================================================!*/
function PJAXUpdateStyles(data) {
  return new Promise((resolve) => {
    const
      nextDocument = jQuery.parseHTML(data.next.html, document, true),
      stylesToLoad = [],
      $nextStyles = $(nextDocument).filter('link[rel="stylesheet"][id]');

    $nextStyles.each(function (index) {
      const element = document.querySelector(`link[id="${this.id}"]`);

      // load stylesheet that's not present on the current page
      if (typeof element === 'undefined' || element === null) {
        stylesToLoad.push(AssetsManager.load({
          type: 'style',
          id: this.id ? this.id : `pjax-asset-${index}-css`,
          src: this.href
        }));
      }
    });

    Promise
      .all(stylesToLoad)
      .then(() => resolve(true), () => resolve(true));
  });
}

/*!========================================================================
	20. PJAX Update Trackers
	======================================================================!*/
function PJAXUpdateTrackers() {

	updateGA();
	updateFBPixel();
	updateYaMetrika();

	/**
	 * Google Analytics
	 */
	function updateGA() {

		if (typeof gtag === 'function' && typeof window.gaData !== 'undefined' && Object.keys(window.gaData)[0] !== 'undefined') {

			var
				trackingID = Object.keys(window.gaData)[0],
				pageRelativePath = (window.location.href).replace(window.location.origin, '');

			gtag('js', new Date());
			gtag('config', trackingID, {
				'page_title': document.title,
				'page_path': pageRelativePath
			});

		}

	}

	/**
	 * Facebook Pixel
	 */
	function updateFBPixel() {

		if (typeof fbq === 'function') {
			fbq('track', 'PageView');
		}

	}

	/**
	 * Yandex Metrika
	 */
	function updateYaMetrika() {

		if (typeof ym === 'function') {

			var trackingID = getYmTrackingNumber();

			ym(trackingID, 'hit', window.location.href, {
				title: document.title
			});

		}

		function getYmTrackingNumber() {

			if (typeof window.Ya !== 'undefined' && typeof window.Ya.Metrika2) {
				return window.Ya.Metrika2.counters()[0].id || null;
			}

			if (typeof window.Ya !== 'undefined' && typeof window.Ya.Metrika) {
				return window.Ya.Metrika.counters()[0].id || null;
			}

			return null;

		}

	}

}

/*!========================================================================
	21. PJAX Wait Container Images
	======================================================================!*/
function PJAXWaitContainerImages(data) {

	return new Promise(function (resolve, reject) {

		var
			$nextContainer = $(data.next.container),
			$nextMasthead = $nextContainer.find('.section-masthead');

		/**
		 * We can't wait infinitely for the images
		 * so let's proceed further anyway
		 */
		setTimeout(function () {
			resolve(true);
		}, 3000);

		$nextMasthead.imagesLoaded().always({
			background: true
		}, function () {

			/**
			 * small delay to avoid any problems
			 * with masthead image size calculation
			 */
			setTimeout(function () {
				resolve(true);
			}, 150);

		});

	});

}

/*!========================================================================
	22. PJAX
	======================================================================!*/
var PJAX = function () {

	var $barbaWrapper = $('[data-barba="wrapper"]');

	if (!$barbaWrapper.length) {
		return;
	}

	barba.init({

		timeout: 10000,

		// don't trigger barba for links outside wrapper 
		prevent: ({
			el
		}) => {

			var
				$el = $(el),
				url = $el.attr('href'),
				customRules = sanitizeSelector(window.theme.ajax.preventRules),
				exludeRules = [
					'.no-ajax',
					'.no-ajax a',
					'[data-elementor-open-lightbox]', // Elementor lightbox gallery
					'[data-elementor-lightbox-slideshow]', // Elementor Pro Gallery
					'.lang-switcher a' // Polylang & WPML language switcher
				];

			if (
				url === '#' || // dummy link
				url.indexOf('wp-admin') > -1 || // WordPress admin link
				url.indexOf('wp-login') > -1 || // WordPress login link
				url.indexOf('/feed/') > -1 // WordPress feed
			) {
				return true;
			}

			// page anchor
			if ($el.is('[href*="#"]') && window.location.href === url.substring(0, url.indexOf('#'))) {
				return true;
			}

			// elementor preview
			if (window.theme.isElementorEditorActive) {
				return true;
			}

			// clicked on elementor ouside barba wrapper
			if ($el.closest($barbaWrapper).length < 1) {
				return true;
			}

			// custom rules from WordPress Customizer
			if (customRules) {
				exludeRules = [...exludeRules, ...customRules.split(',')];
				exludeRules = [...new Set(exludeRules)];
			}

			// check against array of rules to prevent
			return $el.is(exludeRules.join(','));

		},
		// custom transitions
		transitions: [
			PJAXTransitionGeneral,
			PJAXTransitionFlyingHeading,
			PJAXTransitionOverlayMenu,
		],
		customHeaders: () => {
			if (Modernizr.webp) {
				return {
					'name': 'Accept',
					'value': 'image/webp'
				};
			}
		}
	});
}

/*!========================================================================
	23. Assets Manager
	======================================================================!*/
class AssetsManager {
  static load({
    type = undefined, // script | stylesheet
    src = null,
    id = null, // id attribute in DOM
    refElement,
    version = null,
    timeout = 15000,
    cache = false
  }) {
    return new Promise((resolve, reject) => {
      // Don't load asset that is pending to load
      if (cache && id in window.theme.assets.promises) {
        // return existing loading promise
        window.theme.assets.promises[id].then(resolve, reject);
        return;
      }

      // CSS
      if (type === 'style') {
        const stylePromise = AssetsManager.loadStyle({ src, id, refElement, timeout, version });

        window.theme.assets.promises[id] = stylePromise;
        return stylePromise.then(resolve, reject);

      } else if (type === 'script') { // JS
        const scriptPromise = AssetsManager.loadScript({ src, id, refElement, timeout, version });

        window.theme.assets.promises[id] = scriptPromise;

        return scriptPromise.then(resolve, reject);

      } else { // Unknown type
        reject(new TypeError('Resource type "style" or "script" is missing.'));
      }
    });
  }

  static loadScript({
    src = null,
    id = null,
    refElement = document.body,
    version = null,
    timeout = 15000
  }) {
    return new Promise((resolve, reject) => {
      const
        element = document.querySelector(`script[id="${id}"]`),
        head = document.getElementsByTagName('head')[0];

      let script, timer, preload;

      if (!src) {
        reject(new TypeError('Resource URL is missing.'));
        return;
      }

      if (!id) {
        reject(new TypeError('Resource ID attribute is missing.'));
        return;
      }

      if (typeof element === 'undefined' || element === null) {

        if (version) {
          src += `?ver=${version}`;
        }

        if (window.theme.isFirstLoad) {
          preload = document.createElement('link');
          preload.setAttribute('rel', 'preload');
          preload.setAttribute('href', src);
          preload.setAttribute('as', 'script');
          preload.setAttribute('type', 'text/javascript');
          head.prepend(preload);
        }

        script = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('async', 'async');
        script.setAttribute('src', src);
        script.setAttribute('id', id);
        refElement.append(script);

        script.onerror = (error) => {
          cleanup();
          refElement.removeChild(script);
          script = null;
          reject(new Error(`A network error occured while trying to load resouce ${src}`));
        }

        if (script.onreadystatechange === undefined) {
          script.onload = onload;
        } else {
          script.onreadystatechange = onload;
        }

        timer = setTimeout(script.onerror, timeout);

      } else {
        resolve(element);
      }

      function cleanup() {
        clearTimeout(timer);
        timer = null;
        script.onerror = script.onreadystatechange = script.onload = null;
      }

      function onload() {
        cleanup();
        if (!script.onreadystatechange || (script.readyState && script.readyState == 'complete')) {
          resolve(script);
          return;
        }
      }
    });
  }

  static loadStyle({
    src = null,
    id = null,
    refElement = document.head.querySelector('link[type="text/css"]'),
    version = null,
    timeout = 15000
  }) {
    return new Promise((resolve, reject) => {
      const
        element = document.querySelector(`link[id="${id}"]`),
        head = document.getElementsByTagName('head')[0];

      // don't load resouce that already exists
      if (typeof element !== 'undefined' && element !== null) {
        resolve(element);
      }

      if (!src) {
        reject(new TypeError('Resource URL is missing.'));
      }

      if (!id) {
        reject(new TypeError('Resource ID attribute is missing.'))
      }

      let
        link = document.createElement('link'),
        timer,
        sheet,
        cssRules,
        preload,
        c = (timeout || 10) * 100;

      if (version) {
        src += `?ver=${version}`;
      }

      if (window.theme.isFirstLoad) {
        preload = document.createElement('link');
        preload.setAttribute('rel', 'preload');
        preload.setAttribute('href', src);
        preload.setAttribute('as', 'style');
        preload.setAttribute('type', 'text/css');
        head.prepend(preload);
      }

      link.setAttribute('rel', 'stylesheet');
      link.setAttribute('type', 'text/css');
      link.setAttribute('href', src);

      if (typeof refElement !== 'undefined' && refElement !== null) {
        head.insertBefore(link, refElement);
      } else {
        head.append(link);
      }

      link.onerror = function (error) {
        if (timer) {
          clearInterval(timer);
        }
        timer = null;

        reject(new Error(`A network error occured while trying to load resouce ${src}`));
      };

      if ('sheet' in link) {
        sheet = 'sheet';
        cssRules = 'cssRules';
      } else {
        sheet = 'styleSheet';
        cssRules = 'rules';
      }

      timer = setInterval(function () {
        try {
          if (link[sheet] && link[sheet][cssRules].length) {
            clearInterval(timer);
            timer = null;
            resolve(link);
            return;
          }
        } catch (e) {}

        if (c-- < 0) {
          clearInterval(timer);
          timer = null;
          reject(new Error(`A network error occured while trying to load resouce ${src}`));
        }
      }, 10);


    });
  }

}

/*!========================================================================
	24. Audio Background
	======================================================================!*/
class AudioBackground {

  constructor($scope) {
    this.$target = $scope.find('#js-audio-background');
    this.$options = $scope.find('#js-audio-background__options');
    this.controller = new AudioControl();
    this.el = this.$target.get(0);
    this.targetVolume = this.$target.data('volume') || 100;
    this.tl = new TimelineMax();
    this.el.volume = 0;
    this.el.muted = false;
    this.bindEvents();
  }

  run() {

    if (this.isAudioSrc() && !this.isAudioOff()) {

      this.controller.reveal(true);

      if (this.el.autoplay === true) {
        this.controller.play();
        this.fadeIn();
      } else {
        this.controller.pause();
      }

    }

  }

  isAudioOff() {
    return this.$options.attr('data-options') === 'music_off';
  }

  isAudioSrc() {
    return this.$target.attr('src').length > 0;
  }

  bindEvents() {
    this.controller.$control.on('click', () => {
      if (!this.isAudioSrc()) {
        return false;
      }

      if (this.el.paused === true) {
        this.el.volume = 0;
        this.el.play();
        this.fadeIn();
        this.controller.play();
      } else {
        this.fadeOut().then(() => {
          this.el.pause();
        });
        this.controller.pause();
      }
    });

    this.el.addEventListener('play', () => {
      this.controller.play();
    });
    this.el.addEventListener('pause', () => {
      this.controller.pause();
    });
  }

  fadeIn() {

    return new Promise((resolve) => {

      const volume = {
        val: 0
      };

      if (this.el.play !== 'undefined') {
        this.el.play().then(() => {
          this.tl
            .clear()
            .to(volume, 3, {
              val: this.targetVolume,
              ease: Power3.easeInOut,
              onUpdate: () => {
                let value = parseFloat((volume.val) / 100);
                if (value >= 0 && value <= this.targetVolume / 100) {
                  this.el.volume = value;
                }
              },
              onComplete: () => {
                resolve(true);
              }
            });
        }).catch(() => {
          resolve(true);
        });
      }

    });
  }

  fadeOut() {

    return new Promise((resolve) => {

      const volume = {
        val: 0
      };

      this.tl
        .clear()
        .to(volume, 1, {
          val: this.targetVolume,
          ease: Power3.easeInOut,
          onUpdate: () => {
            let value = parseFloat((this.targetVolume - volume.val) / 100);
            if (value >= 0 && value <= this.targetVolume / 100) {
              this.el.volume = value;
            }
          },
          onComplete: () => {
            this.el.pause();
            resolve(true);
          }
        });

    });

  }

}

/*!========================================================================
	25. Audio Control
	======================================================================!*/
class AudioControl {

  constructor() {

    this.$control = $('.js-audio-background__control')
    this.$icon = this.$control.find('.js-audio-background__icon');
    this.$label = this.$control.find('.js-audio-background__label');

    this.hiddenClass = 'hidden';
  }

  reveal(yes) {
    if (yes === true) {
      this.$control.removeClass(this.hiddenClass)
    } else {
      this.$control.addClass(this.hiddenClass);
    }
  }

  play() {
    this.$icon.html(window.theme.audio.playing.icon.toString());
    this.$label.html(window.theme.audio.playing.label.toString());
  }

  pause() {
    this.$icon.html(window.theme.audio.paused.icon.toString());
    this.$label.html(window.theme.audio.paused.label.toString());
  }

}

/*!========================================================================
	26. Button Circle
	======================================================================!*/
var ButtonCircle = function ($scope) {

	var $target = $scope.find('.js-button-circle');

	if (!$target.length) {
		return;
	}

	$target.each(function () {

		var
			$current = $(this),
			$currentCircle = $current.find('.circle'),
			tl = new TimelineMax();

		tl.set($currentCircle, {
			drawSVG: '100% 100%'
		});

		$current.on('mouseenter touchstart', function () {

			tl
				.clear()
				.fromTo($currentCircle, 0.6, {
					drawSVG: '100% 100%'
				}, {
					drawSVG: '0% 100%',
					ease: Power3.easeInOut,
				});

		}).on('mouseleave touchend', function () {

			tl
				.clear()
				.to($currentCircle, 0.6, {
					drawSVG: '0% 0%',
					ease: Power3.easeInOut
				});

		});

	});

}

/*!========================================================================
	27. Button Circles
	======================================================================!*/
var ButtonCircles = function ($target) {

	if (!$target.length) {
		return;
	}

	var
		$circles = $target.find('.circle'),
		tl = new TimelineMax();

	tl.set($circles, {
		drawSVG: '0% 0%',
	});

	$target
		.on('mouseenter touchstart', function () {

			tl
				.clear()
				.staggerTo($circles, 0.6, {
					drawSVG: '0% 100%',
					ease: Power4.easeOut,
				}, 0.05);

		})
		.on('mouseleave touchend', function () {

			tl
				.clear()
				.staggerTo($circles, 0.6, {
					drawSVG: '0% 0%',
					ease: Power4.easeOut
				}, 0.05);

		});

}

/*!========================================================================
	28. Cursor
	======================================================================!*/
var Cursor = function () {

	var
		$cursor = $('#js-cursor'),
		self = this,
		tl = new TimelineMax();

	this.startLoading = function () {
		window.$document.off('mouseenter mouseleave');
		if ($cursor.length) {
			revealCursor();
		}
	};

	this.finishLoading = function () {
		finishLoading();
		if ($cursor.length) {
			registerEventListeners();
			clearCursor();
		}
	};

	this.mouseX = 0;
	this.mouseY = 0;

	this.update = function () {
		self.mouseX = self.mouseX + pageXOffset;
		self.mouseY = self.mouseY + pageYOffset;
	}

	// don't launch on mobiles
	if (!$cursor.length || Modernizr.touchevents) {
		return;
	}

	var
		tl = new TimelineMax(),
		$follower = $('.cursor__follower'),
		$labelText = $('.cursor__label-text'),
		offset = parseInt(window.$html.css('marginTop'), 10),
		posX = 0,
		posY = 0,
		cursorNoneClass = 'cursor-none',
		trailingDelay = parseFloat(window.theme.animations.cursorAttractionDelay) || 0;

	start();

	function start() {

		var moveEvt = new MouseEvent('mousemove');

		if (!$cursor.length || Modernizr.touchevents) {
			return;
		}

		TweenMax.to($cursor, 1.2, {
			display: 'block',
			autoAlpha: 1,
			y: '-50%',
			x: '-50%',
			ease: Elastic.easeOut.config(1, 0.6),
		});

		TweenMax.to({}, 0.01, {
			repeat: -1,
			onRepeat: function () {

				posX += (self.mouseX - posX);
				posY += (self.mouseY - posY - offset);

				TweenMax.to($cursor, trailingDelay, {
					x: posX,
					y: posY + offset,
				});

			}
		});

		registerEventListeners();
		document.dispatchEvent(moveEvt);

	}

	function startLoading() {

		if (!$cursor.length || Modernizr.touchevents) {
			return;
		}

		tl
			.stop()
			.clear()
			.play()
			.add(function () {
				revealHelper(window.theme.cursorFollower.labels.loading);
			});

	}

	function finishLoading() {

		if (!$cursor.length || Modernizr.touchevents) {
			return;
		}

		tl
			.stop()
			.clear()
			.play()
			.add(function () {
				hideHelper();
			});

	}

	function registerEventListeners() {

		window.$document
			.on('mousemove', function (e) {
				self.mouseX = e.clientX;
				self.mouseY = e.clientY;
			});

		registerEventListener('a, .slider__dot, .slider__arrow, #js-submenu-back, #js-burger, .js-scroll-down, .button, .audio-control', function () {
			revealCursor();
		}, function () {
			clearCursor();
		});

		if (window.theme.cursorFollower.labels.slider !== '') {
			registerEventListener('.slider_draggable, .dialog-lightbox-widget .swiper-container .elementor-lightbox-prevent-close', function () {
				revealHelper(window.theme.cursorFollower.labels.slider);
			}, function () {
				hideHelper();
			});
		}

	}

	function registerEventListener(elements, fEnter, fLeave) {

		window.$document
			.on('mouseenter', elements, function () {
				fEnter();
			})
			.on('mouseleave', elements, function () {
				fLeave();
			});

	}

	function revealHelper(label) {

		tl
			.clear()
			.add(function () {
				$labelText.html(label);
				window.$body.addClass(cursorNoneClass);
			})
			.set($cursor, {
				mixBlendMode: 'normal'
			})
			.to($follower, 0.6, {
				autoAlpha: 1,
				scale: 1,
				ease: Elastic.easeOut.config(1, 0.6),
			})
			.to($labelText, 0.3, {
				y: '0%',
				autoAlpha: 1,
				ease: Power3.easeInOut,
			}, '-=0.6');

	}

	function hideHelper() {

		tl
			.clear()
			.add(function () {
				window.$body.removeClass(cursorNoneClass);
			})
			.to($labelText, 0.3, {
				y: '100%',
				autoAlpha: 0,
				ease: Power3.easeInOut,
			})
			.set($cursor, {
				clearProps: 'mixBlendMode'
			})
			.to($follower, 0.6, {
				autoAlpha: 0.5,
				scale: 0.2,
				ease: Elastic.easeOut.config(1, 0.6),
			}, '-=0.1')
			.add(function () {
				$labelText.html('');
			});
	}

	function revealCursor() {
		tl
			.clear()
			.set($cursor, {
				clearProps: 'mixBlendMode'
			})
			.add([
				TweenMax.to($labelText, 0.3, {
					y: '100%',
					autoAlpha: 0,
					ease: Power3.easeInOut,
				}),
				TweenMax.to($follower, 0.6, {
					autoAlpha: 0.5,
					scale: 0.8,
					ease: Elastic.easeOut.config(1, 0.6),
				})
			]);
	}

	function clearCursor() {
		tl
			.clear()
			.set($cursor, {
				clearProps: 'mixBlendMode'
			})
			.add([
				TweenMax.to($labelText, 0.3, {
					y: '100%',
					autoAlpha: 0,
					ease: Power3.easeInOut,
				}),
				TweenMax.to($follower, 0.6, {
					autoAlpha: 0.5,
					scale: 0.2,
					ease: Elastic.easeOut.config(1, 0.6),
				})
			]);
	}

}

/*!========================================================================
	29. Effect Distortion
	======================================================================!*/
var EffectDistortion = function (opts) {

	var vertex = `
			varying vec2 vUv;
			void main() {
				vUv = uv;
				gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
			}
	`;
	var fragmentHorizontal = `
			varying vec2 vUv;

			uniform sampler2D texture;
			uniform sampler2D texture2;
			uniform sampler2D disp;

			uniform float dispFactor;
			uniform float effectFactor;

			void main() {

					vec2 uv = vUv;

					vec4 disp = texture2D(disp, uv);

					vec2 distortedPosition = vec2(uv.x + dispFactor * (disp.r*effectFactor), uv.y);
					vec2 distortedPosition2 = vec2(uv.x - (1.0 - dispFactor) * (disp.r*effectFactor), uv.y);

					vec4 _texture = texture2D(texture, distortedPosition);
					vec4 _texture2 = texture2D(texture2, distortedPosition2);

					vec4 finalTexture = mix(_texture, _texture2, dispFactor);

					gl_FragColor = finalTexture;

			}
	`;
	var fragmentVertical = `
			varying vec2 vUv;

			uniform sampler2D texture;
			uniform sampler2D texture2;
			uniform sampler2D disp;

			uniform float dispFactor;
			uniform float effectFactor;

			void main() {

					vec2 uv = vUv;

					vec4 disp = texture2D(disp, uv);

					vec2 distortedPosition = vec2(uv.x, uv.y - dispFactor * (disp.r*effectFactor));
					vec2 distortedPosition2 = vec2(uv.x, uv.y + (1.0 - dispFactor) * (disp.r*effectFactor));

					vec4 _texture = texture2D(texture, distortedPosition);
					vec4 _texture2 = texture2D(texture2, distortedPosition2);

					vec4 finalTexture = mix(_texture, _texture2, dispFactor);

					gl_FragColor = finalTexture;

			}
	`;
	var aspect = opts.aspectRatio || 1.6;
	var canvas = opts.canvas;
	var dispImage = opts.displacementImage;
	var images = opts.images;
	var scene = new THREE.Scene();
	var camera;
	var scrollScene;
	var textures = [];
	var renderer = new THREE.WebGLRenderer({
		canvas: canvas,
		powerPreference: 'high-performance'
	});
	var loader = new THREE.TextureLoader();
	var disp = loader.load(dispImage);
	var mat = new THREE.ShaderMaterial({
		uniforms: {
			effectFactor: {
				type: "f",
			},
			dispFactor: {
				type: "f",
				value: 0.0
			},
			texture: {
				type: "t",
				value: textures[0]
			},
			texture2: {
				type: "t",
				value: textures[1]
			},
			disp: {
				type: "t",
				value: disp
			}
		},
		vertexShader: vertex,
		fragmentShader: opts.slider.params.direction == 'horizontal' ? fragmentHorizontal : fragmentVertical,
		opacity: 1
	});
	var position = calculatePosition();
	var render;

	camera = new THREE.OrthographicCamera(
		position[0] / -2,
		position[0] / 2,
		position[1] / 2,
		position[1] / -2,
		1,
		1000
	);

	createScene();

	render = function () {
		if (renderer) {
			renderer.render(scene, camera);
		}
	};

	function createScene() {

		if (!scene || !renderer || !camera) {
			return;
		}

		var geometry = new THREE.PlaneBufferGeometry(
			position[0],
			position[1],
		);

		var object = new THREE.Mesh(geometry, mat);

		renderer.setPixelRatio(1); // window.devicePixelRatio
		renderer.setClearColor(0xffffff, 0.0);
		renderer.setSize(position[0], position[1]);

		scene.add(object);

		camera.aspect = aspect;
		camera.position.z = 1;
		camera.updateProjectionMatrix();

		$window.on('resize', debounce(function () {
			position = calculatePosition();
			renderer.setSize(position[0], position[1]);
			camera.updateProjectionMatrix();
		}, 250));

		disp.wrapS = disp.wrapT = THREE.RepeatWrapping;

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

			var texture = loader.load(images[i]);

			texture.magFilter = THREE.LinearFilter;
			texture.minFilter = THREE.LinearFilter;
			texture.anisotropy = renderer.capabilities.getMaxAnisotropy();

			textures[i] = texture;

		};

		scrollScene = new $.ScrollMagic.Scene({
			duration: () => window.innerHeight + canvas.height,
			triggerElement: canvas,
			triggerHook: 1,
			reverse: true
		})
		.addTo(SMController);

		scrollScene
			.on('enter', () => {
				if (renderer && typeof renderer.setAnimationLoop === 'function') {
					renderer.setAnimationLoop(render);
				}
			})
			.on('leave', () => {
				if (renderer && typeof renderer.setAnimationLoop === 'function') {
					renderer.setAnimationLoop(null);
				}
			});

	}

	function calculatePosition() {

		var
			height = parseFloat(window.outerHeight),
			width = parseFloat(height * aspect),
			multiplier = 1,
			result = [];

		if (aspect > 1) {
			multiplier = window.innerWidth > width ? window.innerWidth / width : 1;
		} else {
			multiplier = canvas.clientWidth / width;
		}

		if (multiplier < 1) {
			multiplier = 1;
		}

		result[0] = width * multiplier;
		result[1] = height * multiplier;

		return result;

	}

	this.change = function (opts) {

		if (!mat) {
			return;
		}

		var
			indexFrom = opts.indexFrom || '0',
			indexTo = opts.indexTo || '0',
			speedIn = opts.speedIn || 1.2,
			intensity = opts.intensity || 0.25,
			easing = opts.easing || Power3.easeOut;

		mat.uniforms.texture.value = textures[indexFrom];
		mat.uniforms.texture2.value = textures[indexTo];
		mat.uniforms.effectFactor.value = intensity;

		TweenMax.fromTo(mat.uniforms.dispFactor, speedIn, {
			value: 0
		}, {
			value: 1,
			ease: easing
		});
	};

	this.animate = function () {
		if (renderer && typeof renderer.setAnimationLoop === 'function') {
			renderer.setAnimationLoop(render);
		}
	};

	this.destroy = function () {
		if (renderer && typeof renderer.setAnimationLoop === 'function') {
			renderer.setAnimationLoop(null);
		}

		renderer = undefined;
		camera = undefined;
		scene = undefined;
		loader = undefined;
		mat = undefined;
		$window.off('resize');
		opts.slider.off('slideChange');
	};

};

/*!========================================================================
	30. Counter
	======================================================================!*/
var Counter = function ($target) {

	var $num = $target.find('.js-counter__number');

	if (!$target.length || !$num.length) {
		return;
	}

	var
		numberStart = $target.data('counter-start') || 0,
		numberTarget = $target.data('counter-target') || 100,
		animDuration = $target.data('counter-duration') || 4,
		counter = {
			val: numberStart
		};

	setCounterUp();
	animateCounterUp();

	function setCounterUp() {

		$num.text(numberStart.toFixed(0));

	}

	function animateCounterUp() {

		var tl = new TimelineMax();

		tl.to(counter, animDuration, {
			val: numberTarget.toFixed(0),
			ease: Power4.easeOut,
			onUpdate: function () {
				$num.text(counter.val.toFixed(0));
			}
		});

		createOSScene($target, tl);

	}

}

/*!========================================================================
	31. Figure Award
	======================================================================!*/
var FigureAward = function ($target) {

	if (!$target.length) {
		return;
	}

	var
		tl = new TimelineMax();

	tl
		.add(animateLines($target, 1.2, 0.1), '0')
		.add(animateChars($target, 1.2, 0.3, Power3.easeOut), '0');

	createOSScene($target, tl);

}

/*!========================================================================
	32. Figure Portfolio Animation
	======================================================================!*/
var FigurePortfolioAnimation = function ($target, animDelay = 0) {

	var
		$heading,
		$category,
		$letter,
		$imgWrapper,
		tl;

	$heading = $target.find('.figure-portfolio-big__heading');
	$category = $target.find('.figure-portfolio-big__category');
	$letter = $target.find('.figure-portfolio-big__wrapper-letter');
	$imgWrapper = $target.find('.figure-portfolio-big__wrapper-img, .figure-portfolio__wrapper-img');
	tl = new TimelineMax();

	prepare();
	animate();

	function prepare() {

		setChars($heading, 0, -20);
		setChars($category, 0, -20);

		TweenMax.set($imgWrapper, {
			y: '25%',
			autoAlpha: 0,
			force3D: true,
		});

		TweenMax.set($letter, {
			autoAlpha: 0,
			y: '200px'
		});

	}

	function animate() {

		tl
			.to($letter, 1.2, {
				y: 0,
				yPercent: 0,
				autoAlpha: 1,
				ease: Power3.easeOut,
			})
			.add([
				TweenMax.to($imgWrapper, 0.9, {
					autoAlpha: 1,
					yPercent: 0,
					force3D: true,
					y: 0,
					ease: Power3.easeOut,
				}),
			], '-=0.8')
			.add(animateChars($heading, 1.2, 0.3, Power3.easeOut), '-=0.8')
			.add(animateChars($category, 1.2, 0.3, Power3.easeOut), '-=1.2');

		createOSScene($target, tl, null, false, animDelay);

	}

}

/*!========================================================================
	33. Figure Portfolio Hover
	======================================================================!*/
var FigurePortfolioHover = function ($target) {

	var
		tl,
		$curtain,
		$category,
		$heading,
		$icon,
		$imgWrapper;

	if (!$target.length) {
		return;
	}

	tl = new TimelineMax();
	$curtain = $target.find('.figure-portfolio__curtain');
	$category = $target.find('.figure-portfolio__category');
	$heading = $target.find('.figure-portfolio__heading');
	$imgWrapper = $target.find('.figure-portfolio__wrapper-img-zoom');
	$icon = $target.find('.figure-portfolio__icon');

	hideChars($heading, 0, 0, Power3.easeOut, 50, 0, 'end');

	TweenMax.set($category, {
		autoAlpha: 0,
		y: '-40px'
	});

	TweenMax.set($icon, {
		autoAlpha: 0,
		x: '40px'
	});

	$target
		.on('mouseenter touchstart', function () {

			tl
				.clear()
				.to($curtain, 0.6, {
					y: '0%',
					skewY: '-5deg',
					ease: Power3.easeInOut
				})
				.to($imgWrapper, 0.6, {
					y: '-40px',
					ease: Power3.easeInOut,
					transition: 'none'
				}, '0')
				.add(animateChars($heading, 0.6, 0.2, Power3.easeOut), '0.2')
				.to($category, 0.6, {
					autoAlpha: 1,
					y: '0px',
					ease: Power3.easeOut
				}, '0.2')
				.to($icon, 0.6, {
					autoAlpha: 1,
					x: '0px',
					ease: Power3.easeOut
				}, '0.4');

		})
		.on('mouseleave touchend', function () {

			tl
				.clear()
				.add(hideChars($heading, 0.6, 0.2, Power3.easeOut, 50, 0, 'end'), '0')
				.to($category, 0.6, {
					autoAlpha: 0,
					y: '-40px',
					ease: Power3.easeOut
				}, '0')
				.to($icon, 0.6, {
					autoAlpha: 0,
					x: '40px',
					ease: Power3.easeOut
				}, '0.2')
				.to($curtain, 0.6, {
					y: '100%',
					skewY: '0deg',
					ease: Power3.easeOut,
				}, '0.3')
				.to($imgWrapper, 0.6, {
					y: '0px',
					ease: Power3.easeOut,
					transition: 'none'
				}, '0.3');


		});

}

/*!========================================================================
	34. Filter
	======================================================================!*/
var Filter = function ($scope, $filter) {

	if (!$filter.length) {
		return;
	}

	var
		self = this,
		itemClass = '.js-filter__item',
		$items = $scope.find(itemClass),
		activeItemClass = 'filter__item_active';

	this.$filter = $scope.find($filter);
	this.$items = $scope.find($items);

	bindEvents();
	updateLinePosition();

	function bindEvents() {

		$($scope)
			.on('mouseenter', itemClass, function () {

				updateLinePosition($(this));

			})
			.on('mouseleave', itemClass, function () {

				updateLinePosition($items.filter('.' + activeItemClass));

			})
			.on('click', itemClass, function () {

				var $el = $(this);

				$items.removeClass(activeItemClass);
				$el.addClass(activeItemClass);
				updateLinePosition($el);

			});

	}

	function updateLinePosition($target) {

		var
			$line = self.$filter.find('.js-filter__underline');

		if (!$line.length) {
			return;
		}

		if (!$target || !$target.length) {

			TweenMax.to($line, 0.6, {
				width: 0,
				ease: Expo.easeOut,
			});

		} else {

			var
				$heading = $target.find('div'),
				headingWidth = $heading.innerWidth(),
				headingPos = $heading.position(),
				colPos = $target.position();

			TweenMax.to($line, 0.6, {
				ease: Expo.easeInOut,
				width: headingWidth,
				x: headingPos.left + colPos.left,
			});

		}

	}

	function setActiveItem(index) {

		var $target = $items.eq(index);
		if (!$target) {
			return;
		}

		$items.removeClass(activeItemClass);
		$target.addClass(activeItemClass);
		updateLinePosition($target, self.$filter);


	}

	this.setActiveItem = function (index) {
		setActiveItem(index);
	}

}

/*!========================================================================
	35. Form
	======================================================================!*/
var Form = function () {

	var
		INPUT_CLASS = '.input-float__input',
		INPUT_NOT_EMPTY = 'input-float__input_not-empty',
		INPUT_FOCUSED = 'input-float__input_focused';

	floatLabels();
	ajaxForm();

	if (typeof window.theme !== 'undefined' && window.theme.contactForm7.customModals) {
		attachModalsEvents();
	}

	function floatLabels() {

		if (!$(INPUT_CLASS).length) {
			return;
		}

		$(INPUT_CLASS).each(function () {

			var
				$currentField = $(this),
				$currentControlWrap = $currentField.parent('.wpcf7-form-control-wrap');

			// not empty value
			if ($currentField.val()) {
				$currentField.addClass(INPUT_NOT_EMPTY);
				$currentControlWrap.addClass(INPUT_NOT_EMPTY);
				// empty value
			} else {
				$currentField.removeClass([INPUT_FOCUSED, INPUT_NOT_EMPTY]);
				$currentControlWrap.removeClass([INPUT_FOCUSED, INPUT_NOT_EMPTY]);
			}

			// has placeholder & empty value
			if ($currentField.attr('placeholder') && !$currentField.val()) {
				$currentField.addClass(INPUT_NOT_EMPTY);
				$currentControlWrap.addClass(INPUT_NOT_EMPTY);
			}

		});

		window.$document.off('focusin').on('focusin', INPUT_CLASS, function () {

			var
				$currentField = $(this),
				$currentControlWrap = $currentField.parent('.wpcf7-form-control-wrap');

			$currentField.addClass(INPUT_FOCUSED).removeClass(INPUT_NOT_EMPTY);
			$currentControlWrap.addClass(INPUT_FOCUSED).removeClass(INPUT_NOT_EMPTY);

		}).off('focusout').on('focusout', INPUT_CLASS, function () {

			var
				$currentField = $(this),
				$currentControlWrap = $currentField.parent('.wpcf7-form-control-wrap');

			// not empty value
			if ($currentField.val()) {
				$currentField.removeClass(INPUT_FOCUSED).addClass(INPUT_NOT_EMPTY);
				$currentControlWrap.removeClass(INPUT_FOCUSED).addClass(INPUT_NOT_EMPTY);
			} else {
				// has placeholder & empty value
				if ($currentField.attr('placeholder')) {
					$currentField.addClass(INPUT_NOT_EMPTY);
					$currentControlWrap.addClass(INPUT_NOT_EMPTY);
				}
				$currentField.removeClass(INPUT_FOCUSED);
				$currentControlWrap.removeClass(INPUT_FOCUSED);

			}

		});

	}

	function ajaxForm() {

		var $form = $('.js-ajax-form');

		if (!$form.length) {
			return;
		}

		$form.validate({
			errorElement: 'span',
			errorPlacement: function (error, element) {
				error.appendTo(element.parent()).addClass('form__error');
			},
			submitHandler: function (form) {
				ajaxSubmit(form);
			}
		});

		function ajaxSubmit(form) {

			$.ajax({
				type: $form.attr('method'),
				url: $form.attr('action'),
				data: $form.serialize()
			}).done(function () {
				alert($form.attr('data-message-success'));
				$form.trigger('reset');
				floatLabels();
			}).fail(function () {
				alert($form.attr('data-message-error'));
			});
		}

	}

	function attachModalsEvents() {
		window.$document.off('wpcf7submit').on('wpcf7submit', function (e) {

			var $modal = $('#modalContactForm7');

			$modal.modal('dispose').remove();

			if (e.detail.apiResponse.status === 'mail_sent') {

				createModalTemplate({
					icon: 'icon-success.svg',
					message: e.detail.apiResponse.message,
					onHide: function () {
						$(e.srcElement).find(INPUT_CLASS).parent().val('').removeClass(INPUT_FOCUSED).removeClass(INPUT_NOT_EMPTY);
					}
				});
			}

			if (e.detail.apiResponse.status === 'mail_failed') {
				createModalTemplate({
					icon: 'icon-error.svg',
					message: e.detail.apiResponse.message
				});
			}

		});
	}

	function createModalTemplate({
		icon,
		message,
		onHide
	}) {

		window.$body.append(`
			<div class="modal fade" id="modalContactForm7">
				<div class="modal-dialog modal-dialog-centered">
					<div class="modal-content radius-img">
						<div class="modal__close" data-dismiss="modal"><img src="${window.theme.themeURL}/img/general/icon-close.svg"/></div>
							<header class="text-center mb-3">
								<img src="${window.theme.themeURL}/img/general/${icon}" width="80px" height="80px" alt=""/>
								<p class="modal__message h4"><strong>${message}</strong></p>
							</header>
							<button type="button" class="button button_solid button_accent-secondary-2 button_fullwidth" data-dismiss="modal">OK</button>
					</div>
				</div>
			</div>
		`);
		var $modal = $('#modalContactForm7');

		$modal.modal('show');
		$modal.on('hidden.bs.modal', function () {
			$modal.modal('dispose').remove();
			if (typeof onHide === 'function') {
				onHide();
			}
		});

	}

}

/*!========================================================================
	36. Grid
	======================================================================!*/
var Grid = function ($target = $('.js-grid')) {

	if (!$target.length) {
		return;
	}

	$target.each(function () {

		var
			$current = $(this),
			$currentLazyImages = $current.find('img[data-src]'),
			currentInstance;

		currentInstance = $current.isotope({
			itemSelector: '.js-grid__item',
			columnWidth: '.js-grid__sizer',
			percentPosition: true
		});

		loadLazyImages($currentLazyImages, false, function () {
			$current.imagesLoaded().always(function () {
				currentInstance.isotope('layout').one('arrangeComplete', function () {
					if (typeof Waypoint === 'function') {
						Waypoint.refreshAll();
					}
				});
			});
		});

		// update non-lazy images
		$current.imagesLoaded().always(function () {
			currentInstance.isotope('layout').one('arrangeComplete', function () {
				if (typeof Waypoint === 'function') {
					Waypoint.refreshAll();
				}
			});
		});

	});

	return $target;

}

/*!========================================================================
	37. Gmap
	======================================================================!*/
var GMap = function ($scope) {

	var
		$wrapper = $scope.find('.gmap'),
		prevInfoWindow = false;

	if (typeof google === 'undefined' || typeof google.maps === 'undefined') {
		return;
	}

	createMap($wrapper);

	/**
	 * 
	 * @param {Map jQuery Object} $wrapper 
	 */
	function createMap($wrapper) {

		var $mapContainer = $wrapper.find('.gmap__container');

		if (!$mapContainer.length) {
			return;
		}

		var
			$markers = $wrapper.find('.gmap__marker'),
			ZOOM = parseInt($wrapper.attr('data-gmap-zoom')),
			SNAZZY_STYLES = $wrapper.attr('data-gmap-snazzy-styles');

		var argsMap = {
			center: new google.maps.LatLng(0, 0),
			zoom: ZOOM,
			scrollwheel: false
		};

		if (SNAZZY_STYLES) {

			try {
				SNAZZY_STYLES = JSON.parse(SNAZZY_STYLES);
				$.extend(argsMap, {
					styles: SNAZZY_STYLES
				});
			} catch (err) {
				console.error('Google Map: Invalid Snazzy Styles');
			}

		};

		var map = new google.maps.Map($mapContainer[0], argsMap);

		map.markers = [];

		$markers.each(function () {
			createMarker($(this), map);
		});

		centerMap(ZOOM, map);

	}

	/**
	 * 
	 * @param {Marker jQuery object} $marker 
	 * @param {Google Map Instance} map
	 */
	function createMarker($marker, map) {

		if (!$marker.length) {
			return;
		}

		var
			MARKER_LAT = parseFloat($marker.attr('data-marker-lat')),
			MARKER_LON = parseFloat($marker.attr('data-marker-lon')),
			MARKER_IMG = $marker.attr('data-marker-img'),
			MARKER_WIDTH = $marker.attr('data-marker-width'),
			MARKER_HEIGHT = $marker.attr('data-marker-height'),
			MARKER_CONTENT = $marker.attr('data-marker-content');

		/**
		 * Marker
		 */
		var argsMarker = {
			position: new google.maps.LatLng(MARKER_LAT, MARKER_LON),
			map: map
		};

		if (MARKER_IMG) {

			$.extend(argsMarker, {
				icon: {
					url: MARKER_IMG
				}
			});

		}

		if (MARKER_IMG && MARKER_WIDTH && MARKER_HEIGHT) {

			$.extend(argsMarker.icon, {
				scaledSize: new google.maps.Size(MARKER_WIDTH, MARKER_HEIGHT),
				origin: new google.maps.Point(0,0), // origin
				anchor: new google.maps.Point(0, 0) // anchor
			});

		}

		var marker = new google.maps.Marker(argsMarker)

		map.markers.push(marker);

		/**
		 * Info Window (Content)
		 */
		if (MARKER_CONTENT) {

			var infoWindow = new google.maps.InfoWindow({
				content: MARKER_CONTENT
			});

			marker.addListener('click', function () {

				if (prevInfoWindow) {
					prevInfoWindow.close();
				}

				prevInfoWindow = infoWindow;

				infoWindow.open(map, marker);

			});

		}

	}

	/**
	 * 
	 * @param {Map Zoom} zoom 
	 * @param {Google Map Instance} map
	 */
	function centerMap(zoom, map) {

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

		$.each(map.markers, function () {

			var item = this;

			if (typeof item.position === 'undefined') {
				return;
			}

			newZoom = new google.maps.LatLng(item.position.lat(), item.position.lng());
			bounds.extend(newZoom);

		});

		if (map.markers.length == 1) {

			map.setCenter(bounds.getCenter());
			map.setZoom(zoom);

		} else {

			map.fitBounds(bounds);

		}
	}

}

/*!========================================================================
	38. Header
	======================================================================!*/
var Header = function () {

	var $overlay = $('.header__wrapper-overlay-menu');

	this.hideOverlayMenu = function (speed, setMenu) {

		return closeOverlayMenu(speed, setMenu);

	};

	if (!$overlay.length) {
		return;
	}

	var
		tl = new TimelineMax(),
		$stickyHeader = $('.js-sticky-header'),
		$burger = $('#js-burger'),
		$menuLinks = $overlay.find('.menu-overlay > li > a'),
		$allLinks = $overlay.find('a'),
		$submenu = $overlay.find('.menu-overlay .sub-menu'),
		$submenuButton = $('#js-submenu-back'),
		$submenuLinks = $submenu.find('> li > a'),
		$overlayWidgets = $overlay.find('.header__wrapper-overlay-widgets'),
		$social = $overlayWidgets.find('.social'),
		$audio = $overlayWidgets.find('.audio-control-wrapper'),
		$headerLeft = $('.header__col-left'),
		$headerRight = $('.header__col-right'),
		$langSwitcher = $('.lang-switcher'),
		$curtain = $('.header__curtain'),
		$circleLetters = $('.header__circle-letters'),
		$letters = $circleLetters.find('.vector-letter'),
		$circle = $circleLetters.find('.circle'),
		$widgetListElements = $('.header__wrapper-overlay-widgets ul li, .audio-control-wrapper'),
		OPEN_CLASS = 'header__burger_opened',
		STICKY_CLASS = 'header_sticky',
		STICKY_THEME = $stickyHeader.attr('data-header-sticky-theme'),
		$adminBar = $('#wpadminbar');

	clickBurger();
	setOverlayMenu();
	stickHeader();
	offsetHeaderPosition();
	correctAbsoluteHeader();
	handleAnchors();

	function offsetHeaderPosition() {

		if ($adminBar.length) {
			correctHeaderTop();
			$(window).on('resize', debounce(correctHeaderTop, 250));
		}

	}

	function correctHeaderTop() {

		var barHeight = $adminBar.height() || 0;

		TweenMax.to(window.$pageHeader, 0.3, {
			top: barHeight
		});

	}

	function stickHeader() {

		if (!$stickyHeader.length) {
			return;
		}

		if (typeof window.SB !== 'undefined') {

			window.SB.addListener(changeHeaderClass);

		} else {

			window.stickyScene = new $.ScrollMagic.Scene({
					offset: '1px',
				})
				.setClassToggle($stickyHeader, [STICKY_CLASS, STICKY_THEME].join(' '))
				.addTo(SMController);

		}

	}

	function unstickHeader() {

		if (!$stickyHeader.length) {
			return;
		}

		if (typeof window.SB !== 'undefined') {

			window.SB.removeListener(changeHeaderClass);
			$stickyHeader.removeClass(STICKY_CLASS);

		} else {

			if (window.stickyScene) {

				window.stickyScene.destroy(true);
				$stickyHeader.removeClass(STICKY_CLASS);

			}

		}

	}

	function changeHeaderClass() {

		if (window.SB.offset.y >= 1) {
			$stickyHeader.addClass(STICKY_CLASS).addClass(STICKY_THEME);
		} else {
			$stickyHeader.removeClass(STICKY_CLASS).removeClass(STICKY_THEME);
		}

	}

	function correctAbsoluteHeader() {

		var barHeight = $adminBar.height() || 0;

		if (typeof window.SB !== 'undefined' && window.$pageHeader.hasClass('header_absolute')) {
			window.SB.addListener(function (scrollbar) {
				TweenMax.set(window.$pageHeader, {
					top: -scrollbar.offset.y + barHeight + 'px'
				});
			});
		}

	}

	function setOverlayMenu() {

		getScrollTop();

		TweenMax.set($overlay, {
			autoAlpha: 0,
			className: '-=opened',
		});

		TweenMax.set([$submenu, $submenuButton], {
			autoAlpha: 0
		});

		TweenMax.set($submenu, {
			className: '-=opened'
		});

		TweenMax.set($curtain, {
			y: '-100%',
		});

		TweenMax.set($circleLetters, {
			autoAlpha: 0,
			rotation: 0
		});

		TweenMax.set($menuLinks.find('.split-text__line'), {
			y: '100%',
			autoAlpha: 0
		});

		TweenMax.set($menuLinks.find('.split-text__char'), {
			clearProps: 'transform',
			autoAlpha: 1
		});

		setLines($overlayWidgets);

		TweenMax.set([$social, $audio], {
			autoAlpha: 0,
			y: '100%'
		});

		TweenMax.set($submenuLinks.find('.split-text__line'), {
			clearProps: 'transform',
			autoAlpha: 1
		});

		if (window.theme.animations.hasMenuSplitCharsAnimation) {
			TweenMax.set($submenuLinks.find('.split-text__char'), {
				x: '50px',
				autoAlpha: 0
			});
		} else {
			TweenMax.set($submenuLinks.find('.split-text__line'), {
				y: '50px',
				autoAlpha: 0
			});
		}

		TweenMax.set($widgetListElements, {
			autoAlpha: 0,
			y: '50px'
		});

		$allLinks.removeClass('selected');

		TweenMax.set($circle, {
			drawSVG: '100% 100%'
		});

	};

	function openOverlayMenu() {

		var
			// tl = new TimelineMax(),
			$pageContent = $('.page-wrapper__content');

		// adjust animation menu master speed
		if (window.theme !== 'undefined') {

			var scale = window.theme.animations.timeScale.overlayMenuOpen || 1;
			tl.timeScale(scale);

		}

		tl
			.clear()
			.set($overlay, {
				autoAlpha: 1,
				zIndex: 500,
				className: '+=opened'
			}, '0')
			.add([function () {
				window.$pageHeader.attr('data-header-animation', 'intransition');
				getScrollTop();

			}, TweenMax.set($adminBar, {
				position: 'fixed',
			})])
			.to($curtain, 1.2, {
				y: '0%',
				ease: Expo.easeInOut,
			})
			.to($pageContent, 1.3, {
				y: '10vh',
				ease: Expo.easeInOut,
				onComplete: function () {
					TweenMax.set($pageContent, {
						clearProps: 'all'
					});
				}
			}, '-=1.2')
			.add(animateLines($menuLinks, 1.2, 0.05), '-=0.6')
			.staggerTo($widgetListElements, 0.6, {
				autoAlpha: 1,
				y: '0px'
			}, 0.03, '-=1.2')
			.add(animateLines($overlayWidgets, 1.2, 0.05), '-=1.2')
			.to([$social, $audio], 0.6, {
				autoAlpha: 1,
				y: '0%'
			}, '-=1.2')
			.add([
				TweenMax.to($circleLetters, 1.2, {
					autoAlpha: 1,
				}),
				TweenMax.fromTo($circle, 1.2, {
					drawSVG: '100% 100%',
					rotation: 0,
				}, {
					drawSVG: '0% 100%',
					rotation: 90,
					transformOrigin: 'center center',
					ease: Power3.easeInOut,
				})
			], '-=1.2')
			.to([$headerLeft, $langSwitcher, $headerRight], 1.2, {
				x: '30px',
				autoAlpha: 0,
				ease: Expo.easeInOut
			}, '0')
			.to($pageContent, 0.3, {
				autoAlpha: 0
			})
			.add(function () {
				unstickHeader();
			}, '0.6')
			.add(function () {
				window.$pageHeader.attr('data-header-animation', '');
			}, '0.9');

	};

	function closeOverlayMenu(speed, setMenu = true, restoreScroll = true) {

		var
			// tl = new TimelineMax(),
			$pageContent,
			$submenuLinksCurrent;

		if (!$overlay.hasClass('opened')) {
			return tl;
		}

		$pageContent = $('.page-wrapper__content');
		$submenuLinksCurrent = $submenu.filter('.opened').find($submenuLinks);

		// adjust animation menu master speed
		if (window.theme !== 'undefined' && !speed) {

			var scale = window.theme.animations.timeScale.overlayMenuClose || 1;
			tl.timeScale(scale);

		} else {

			tl.timeScale(speed);

		}

		tl
			.clear()
			.set($overlay, {
				zIndex: 500
			})
			.add([function () {
				window.$pageHeader.attr('data-header-animation', 'intransition');
			}, TweenMax.set($adminBar, {
				clearProps: 'position'
			})])
			.add(function () {

				if (restoreScroll === true) {
					restoreScrollTop();
				}
				stickHeader();

				if (typeof window.SB !== 'undefined' && window.SB.offset.y >= 1) {
					$stickyHeader.addClass(STICKY_CLASS);
				}

				if (setMenu === true) {
					lockScroll(false);
				}

			}, '0.6')
			.set($burger, {
				className: '-=header__burger_opened'
			}, '0')
			.set($pageContent, {
				y: '5vh',
			}, '0')
			.add(hideLines($menuLinks, 1.2, 0.05, '-100%', true), '0')
			.add(hideLines($submenuLinksCurrent, 1.2, 0.05, '-100%', Power3.easeInOut, true), '0')
			.add(hideLines($overlayWidgets, 0.6), '0')
			.to([$social, $audio], 0.6, {
				autoAlpha: 0,
				y: '-100%'
			}, '0')
			.staggerTo($widgetListElements, 0.6, {
				autoAlpha: 0,
				y: '-30px'
			}, 0.03, '0')
			.add([
				TweenMax.to($circleLetters, 1.2, {
					autoAlpha: 0,
				}),
				TweenMax.to($circle, 0.6, {
					drawSVG: '0% 0%',
					ease: Power3.easeInOut,
					rotation: 180,
					transformOrigin: 'center center',
				})
			], '0')
			.to($curtain, 1.3, {
				y: '-100%',
				ease: Expo.easeInOut
			}, '0.6')
			.to($pageContent, 2.4, {
				y: '0vh',
				autoAlpha: 1,
				ease: Expo.easeInOut,
				display: 'block',
				onComplete: function () {
					TweenMax.set($pageContent, {
						clearProps: 'all'
					});
				}
			}, '0')
			.to($submenuButton, 0.6, {
				x: '-10px',
				autoAlpha: 0
			}, '0')
			.staggerFromTo([$headerLeft, $langSwitcher, $headerRight], 2.4, {
				x: '-50px',
			}, {
				x: '0px',
				autoAlpha: 1,
				ease: Expo.easeInOut
			}, 0.05, '0.4')
			.set($overlay, {
				className: '-=opened'
			}, '1')
			.add(function () {
				window.$pageHeader.attr('data-header-animation', '');
				if (setMenu === true) {
					setOverlayMenu();
				}
			});

		return tl;

	};

	function clickBurger() {

		$burger.off().on('click', function (e) {

			e.preventDefault();

			if (window.$pageHeader.attr('data-header-animation') !== 'intransition') {

				if ($burger.hasClass(OPEN_CLASS)) {
					closeOverlayMenu();
					$burger.removeClass(OPEN_CLASS);
				} else {
					openOverlayMenu();
					$burger.addClass(OPEN_CLASS);
				}

			}

		});

	};

	function handleAnchors() {

		$('.menu a, .menu-overlay a').filter('a[href*="#"]:not([href="#"]):not([href*="#elementor-action"])').off('click').each(function () {
			var
				$current = $(this),
				url = $current.attr('href'),
				filteredUrl = url.substring(url.indexOf('#'));
			
			try {
				if (filteredUrl.length) {
					var $el = $(filteredUrl);

					if ($el.length) {

						$current.on('click', function (e) {
							if ($burger.hasClass(OPEN_CLASS)) {
								closeOverlayMenu(1, true, false);
								$burger.removeClass(OPEN_CLASS);

								if (typeof window.SB !== 'undefined') {
									setTimeout(() => {
										window.SB.scrollIntoView($el.get(0));
									}, 1200);
								}
							} else {

								if (typeof window.SB !== 'undefined') {
									window.SB.scrollIntoView($el.get(0));
								}

							}
						});
					
					}
				}
			} catch(error) {
				console.error('Error when handling menu anchor links: ' + error);
			}
		});

	}



}

/*!========================================================================
	39. Lazy Load
	======================================================================!*/
function lazyLoad($scope = $window.document) {

	var
		$elements = $scope.find('.lazy'),
		$images = $elements.find('img[data-src]'),
		$backgrounds = $scope.find('.lazy-bg[data-src]');

	prepareLazyImages($images, $backgrounds);
	loadLazyImages($images, $backgrounds);

}

function prepareLazyImages($images, $backgrounds) {

	$images.each(function () {

		var
			$el = $(this),
			$elParent = $el.parent(),
			elPB,
			elWidth = $el.attr('width') || false,
			elHeight = $el.attr('height') || false;

		// we need both width and height of element
		// to calculate proper value for "padding-bottom" hack
		if (!elWidth || !elHeight) {
			return;
		}

		elPB = (elHeight / elWidth) * 100 + '%';

		TweenMax.set($el, {
			position: 'absolute',
			top: 0,
			left: 0,
			width: '100%',
			height: '100%'
		});

		TweenMax.set($elParent, {
			width: '100%',
			position: 'relative',
			overflow: 'hidden',
			paddingBottom: elPB
		});

	});

};

function loadLazyImages($images, $backgrounds, lazyCallback) {

	var
		lazyInstance,
		lazyInstanceBackgrounds;

	if ($images && $images.length) {

		lazyInstance = $images.Lazy({
			threshold: 1000,
			chainable: false,
			afterLoad: function (el) {

				var
					$el = $(el),
					$elParent = $el.parent();

				$el.imagesLoaded({
					background: true
				}).always(function () {

					TweenMax.set($elParent, {
						className: '+=lazy_loaded'
					});

				});

				// update scrollbar geometry
				if (window.SB !== undefined) {
					window.SB.update();
				}

				if (lazyCallback !== undefined) {
					lazyCallback();
				}

			}

		});

	}

	if ($backgrounds && $backgrounds.length) {

		lazyInstanceBackgrounds = $backgrounds.Lazy({
			threshold: 1000,
			chainable: false,
			afterLoad: function (el) {
				$(el).addClass('lazy-bg_loaded');
			}
		});

	}

};

/*!========================================================================
	40. Menu
	======================================================================!*/
var Menu = function () {

	var $menu = $('.js-overlay-menu');

	if (!$menu.length) {
		return;
	}

	var
		$overlay = $('.header__wrapper-overlay-menu'),
		$links = $menu.find('.menu-item-has-children > a'),
		$submenus = $menu.find('.overlay-sub-menu'),
		$submenuButton = $('.js-submenu-back'),
		OPEN_CLASS = 'opened',
		tl = new TimelineMax();

	function openSubmenu($submenu, $currentMenu) {

		var
			$currentLinks = $currentMenu.find('> li > a .overlay-menu__item-wrapper'),
			$submenuLinks = $submenu.find('> li > a .overlay-menu__item-wrapper');

		tl
			.clear()
			.set($submenu, {
				autoAlpha: 1,
				zIndex: 100,
				y: '0px'
			})
			.to($currentLinks, 0.6, {
				y: '-100%',
				ease: Power4.easeIn
			}, '-=0.3')
			.staggerTo($submenuLinks, 0.6, {
				y: '0%',
				ease: Power4.easeOut
			}, 0.05);

		$submenus.removeClass(OPEN_CLASS);
		$submenu.not($menu).addClass(OPEN_CLASS);

		if ($submenus.hasClass(OPEN_CLASS)) {
			tl.to($submenuButton, 0.3, {
				autoAlpha: 1,
				y: '0px'
			}, '-=0.6');
		} else {
			tl.to($submenuButton, 0.3, {
				autoAlpha: 0,
				y: '10px'
			}, '-=0.6');
		}

	}

	function closeSubmenu($submenu, $currentMenu) {

		var
			$currentLinks = $currentMenu.find('> li > a .overlay-menu__item-wrapper'),
			$submenuLinks = $submenu.find('> li > a .overlay-menu__item-wrapper');

		tl
			.clear()
			.set($submenu, {
				zIndex: -1
			})
			.to($submenuLinks, 0.6, {
				y: '100%',
				ease: Power4.easeIn
			}, '-=0.3')
			.staggerTo($currentLinks, 0.6, {
				y: '0%',
				ease: Power4.easeOut
			}, 0.05)
			.set($submenu, {
				autoAlpha: 0,
				y: '10px'
			});

		$submenus.removeClass(OPEN_CLASS);
		$currentMenu.not($menu).addClass(OPEN_CLASS);

		if ($submenus.hasClass(OPEN_CLASS)) {
			TweenMax.to($submenuButton, 0.3, {
				autoAlpha: 1,
				y: '0px'
			}, '-=0.6');
		} else {
			TweenMax.to($submenuButton, 0.3, {
				autoAlpha: 0,
				y: '10px'
			}, '-=0.6');
		}

	}

	$links.on('click', function (e) {

		e.preventDefault();

		if (!$overlay.hasClass('in-transition')) {
			var
				$el = $(this),
				$currentMenu = $el.parents('ul'),
				$submenu = $el.next('.overlay-sub-menu');

			openSubmenu($submenu, $currentMenu);
		}

	});

	$submenuButton.on('click', function (e) {

		e.preventDefault();

		if (!$overlay.hasClass('in-transition')) {
			var
				$el = $(this),
				$openedMenu = $submenus.filter('.' + OPEN_CLASS),
				$prevMenu = $openedMenu.parent('li').parent('ul');

			closeSubmenu($openedMenu, $prevMenu);
		}

	});

}

/*!========================================================================
	41. Menu Overlay
	======================================================================!*/
var MenuOverlay = function () {

	var $menu = $('.js-menu-overlay');

	if (!$menu.length) {
		return;
	}

	var
		$overlay = $('.header__wrapper-overlay-menu'),
		$overlayWidgets = $overlay.find('.header__wrapper-overlay-widgets'),
		$social = $overlayWidgets.find('.social'),
		$links = $menu.find('.menu-item-has-children > a'),
		$allLinks = $menu.find('a'),
		$submenus = $menu.find('.sub-menu'),
		$submenuButton = $('#js-submenu-back'),
		OPEN_CLASS = 'opened',
		SELECTED_CLASS = 'selected',
		tl = new TimelineMax();

	function openSubmenu($submenu, $currentMenu) {

		var
			$currentLinks = $currentMenu.find('> li > a .menu-overlay__item-wrapper'),
			$submenuLinks = $submenu.find('> li > a .menu-overlay__item-wrapper');

		tl
			.clear()
			.add(function () {

				window.$pageHeader.attr('data-header-animation', 'intransition');

				$submenus.removeClass(OPEN_CLASS);
				$submenu.not($menu).addClass(OPEN_CLASS);

				if ($submenus.hasClass(OPEN_CLASS)) {

					tl
						.to($submenuButton, 0.3, {
							autoAlpha: 1,
							x: '0px'
						}, '-=1.2');

					if (isMediumScreen()) {
						tl
							.to($social, 0.6, {
								autoAlpha: 0,
								y: '100%'
							}, '0.2')
							.add(hideLines($overlayWidgets, 0.6, 0.07, '100%', Power3.easeOut, true), '0');
					}

				} else {

					tl
						.to($submenuButton, 0.3, {
							autoAlpha: 0,
							x: '-10px'
						}, '-=1.2');

					tl
						.to($social, 0.6, {
							autoAlpha: 1,
							y: '0%'
						}, '0.2')
						.add(animateLines($overlayWidgets, 0.6, 0.07), '-=1.2');

				}

			})
			.set($submenu, {
				autoAlpha: 1,
				zIndex: 100,
			}, '0');

			if (window.theme.animations.hasMenuSplitCharsAnimation) {
				tl
					.add(hideChars($currentLinks, 0.6, 0.4, Power3.easeOut, -50, 0, 'start'))
					.add(animateChars($submenuLinks, 0.6, 0.4, Power3.easeOut, 'start'), '-=0.6');
			} else {
				tl.add(hideLines($currentLinks, 0.6, 0.06, -50, Power3.easeOut, false))
					.add(animateLines($submenuLinks, 0.6, 0.06, Power3.easeOut), '-=0.6');
			}

			tl.add(function () {
				$allLinks.removeClass(SELECTED_CLASS);
				window.$pageHeader.attr('data-header-animation', '');
			});

	}

	function closeSubmenu($submenu, $currentMenu) {

		var
			$currentLinks = $currentMenu.find('> li > a .menu-overlay__item-wrapper'),
			$submenuLinks = $submenu.find('> li > a .menu-overlay__item-wrapper');

		tl
			.clear()
			.add(function () {

				window.$pageHeader.attr('data-header-animation', 'intransition');

				$submenus.removeClass(OPEN_CLASS);
				$currentMenu.not($menu).addClass(OPEN_CLASS);

				if ($submenus.hasClass(OPEN_CLASS)) {

					TweenMax.to($submenuButton, 0.3, {
						autoAlpha: 1,
						x: '0px'
					});

					if (isMediumScreen()) {
						tl
							.to($social, 0.6, {
								autoAlpha: 0,
								y: '-100%'
							}, '0.2')
							.add(hideLines($overlayWidgets, 0.6, 0.07, '100%', Power3.easeOut, true), '0');
					}

				} else {

					TweenMax.to($submenuButton, 0.3, {
						autoAlpha: 0,
						x: '-10px'
					});

					tl.to($social, 0.6, {
						autoAlpha: 1,
						y: '0%'
					}, '0.2')
						.add(animateLines($overlayWidgets, 0.6, 0.07), '0');

				}

			});

			if (window.theme.animations.hasMenuSplitCharsAnimation) {
				tl.add(hideChars($submenuLinks, 0.6, 0.4, Power3.easeOut, 50, 0, 'end'))
					.add(animateChars($currentLinks, 0.6, 0.4, Power3.easeOut, 'end'), '-=0.6');
			} else {
				tl.add(hideLines($submenuLinks, 0.6, 0.06, 50, Power3.easeOut, true))
					.add(animateLines($currentLinks, 0.6, 0.06, Power3.easeOut, true), '-=0.6');
			}

			tl.set($submenu, {
				autoAlpha: 0,
				zIndex: -1,
			})
			.add(function () {
				window.$pageHeader.attr('data-header-animation', '');
			});

	}

	$links.on('click', function (e) {

		e.preventDefault();

		if (window.$pageHeader.attr('data-header-animation') !== 'intransition') {
			var
				$el = $(this),
				$currentMenu = $el.parents('ul'),
				$submenu = $el.next('.sub-menu');

			$el.addClass(SELECTED_CLASS);

			openSubmenu($submenu, $currentMenu);
		}

	});

	$submenuButton.on('click', function (e) {

		e.preventDefault();

		if (window.$pageHeader.attr('data-header-animation') !== 'intransition') {
			var
				$openedMenu = $submenus.filter('.' + OPEN_CLASS),
				$prevMenu = $openedMenu.parent('li').parent('ul');

			closeSubmenu($openedMenu, $prevMenu);
		}

	});

	function isMediumScreen() {
		return Modernizr.mq('(max-width: 991px)');
	}

}

/*!========================================================================
	42. Preloader
	======================================================================!*/
function Preloader() {

	var
		tl = new TimelineMax(),
		$preloader = $('.js-preloader'),
		$curtainInner = $preloader.find('.preloader__curtain_inner'),
		$curtainOuter = $preloader.find('.preloader__curtain_outer'),
		$circle = $preloader.find('.circle'),
		$logo = $preloader.find('.preloader__content'),
		$pageContent = $('.page-wrapper__content'),
		$counter = $preloader.find('.js-counter'),
		$num = $counter.find('.js-counter__number'),
		numberStart = 1,
		numberTarget = 100,
		animDuration = 25,
		counter = {
			val: numberStart
		};


	if (window.theme !== 'undefined') {

		var scale = window.theme.animations.timeScale.preloader || 0.9;
		tl.timeScale(scale);

	}

	this.start = function () {

		if (!$preloader.length) {
			return;
		}

		TweenMax.fromTo($circle, animDuration, {
			rotation: 0,
			drawSVG: '100% 100%'
		}, {
			drawSVG: '0% 100%',
			rotation: 90,
			transformOrigin: 'center center',
			ease: Power4.easeOut,
		});

		TweenMax.set($pageContent, {
			y: '20vh'
		});

		TweenMax.to(counter, animDuration, {
			val: numberTarget.toFixed(0),
			ease: Power4.easeOut,
			onUpdate: function () {
				var value = counter.val.toFixed(0);
				if (value < 10) {
					value = '0' + value;
				}
				$num.text(value);
			}
		})

	}

	this.finish = function () {
		return new Promise(function (resolve, reject) {

			if (!$preloader.length) {
				resolve(true);
				return;
			}

			tl
				.clear()
				.to($circle, 1.2, {
					drawSVG: '0% 100%',
					rotation: 90,
					transformOrigin: 'center center',
					ease: Expo.easeInOut,
				})
				.to(counter, 1.2, {
					val: numberTarget.toFixed(0),
					ease: Expo.easeInOut,
					onUpdate: function () {
						var value = counter.val.toFixed(0);
						if (value < 10) {
							value = '0' + value;
						}
						$num.text(value);
					}
				}, '-=1.2')
				.add([
					TweenMax.to($curtainInner, 1.2, {
						y: '-100%',
						ease: Expo.easeInOut,
					}),
					TweenMax.to($curtainOuter, 1.2, {
						y: '-100%',
						ease: Expo.easeInOut
					}),
					TweenMax.to($logo, 0.6, {
						y: '-25%',
						ease: Power3.easeOut,
						autoAlpha: 0
					}),
					TweenMax.to($pageContent, 1.4, {
						y: '0vh',
						ease: Expo.easeInOut,
						onUpdate: function () {
							// update scrollbar geometry
							if (typeof window.SB !== 'undefined') {
								window.SB.update();
							}
						},
						onComplete: function () {
							TweenMax.set($pageContent, {
								clearProps: 'all'
							});

							// update scrollbar geometry
							if (typeof window.SB !== 'undefined') {
								window.SB.update();
							}
						}
					})
				])
				.add(function () {
					resolve(true);
				}, '-=1.0')
				.set($preloader, {
					display: 'none'
				});

		});
	}

}

/*!========================================================================
	43. Smooth Scroll
	======================================================================!*/
var SmoothScroll = function () {

	var
		$smoothScroll = $('.js-smooth-scroll'),
		$WPadminBar = $('#wpadminbar');

	if (!$smoothScroll.length || !window.theme.smoothScroll.enabled) {
		return;
	}

	// don't launch in Elementor edit mode
	if (window.theme.isElementorEditorActive) {
		return;
	}

	// don't launch on mobiles
	if (Modernizr.touchevents && !$smoothScroll.hasClass('js-smooth-scroll_enable-mobile')) {
		return;
	}

	$smoothScroll.addClass('smooth-scroll');

	if (window.theme.smoothScroll.plugins.edgeEasing) {
		Scrollbar.use(window.EdgeEasingPlugin);
	}

	Scrollbar.destroyAll();

	window.SB = Scrollbar.init($smoothScroll[0], window.theme.smoothScroll);

	// Immediately focus SB container so it become accessible for keyboard navigation
	window.SB.containerEl.focus();

	// Emit native scroll event to window
	if (typeof window.SB !== 'undefined') {

		var scrollEvt = new CustomEvent('scroll');

		window.SB.addListener(function (e) {
			window.pageYOffset = e.offset.y;
			window.pageXOffset = e.offset.x;
			window.dispatchEvent(scrollEvt);
		});

	}

	// prevent double scroll because of the offset created
	// by WordPress admin bar
	if (typeof window.SB !== 'undefined' && $WPadminBar.length) {

		window.$html.css({
			overflow: 'hidden'
		});

	}

	// handle smooth anchor scrolling
	$smoothScroll.find('a[href*="#"]:not([href="#"]):not(.post__comments a):not([href*="#elementor-action"])').each(function () {
		var
			$current = $(this),
			url = $current.attr('href'),
			filteredUrl = url.substring(url.indexOf('#'));

		try {
			if (filteredUrl.length) {
				var $el = $(filteredUrl);
				if ($el.length) {
					$current.on('click', function () {
						window.SB.scrollIntoView($el.get(0));
					});
				}
			}
		} catch (error) {
			console.error('Error when handling anchor links: ' + error);
		}
	});

}

/*!========================================================================
	44. Create OS Scene
	======================================================================!*/
function createOSScene($el, tl, $customTrigger, noReveal = false, animDelay = 0) {

	var
		$trigger = $el,
		scale,
		masterTL = new TimelineMax();

	if ($customTrigger && $customTrigger.length) {
		$trigger = $customTrigger;
	}

	if (!noReveal) {
		// reveal hidden element first
		$el.attr('data-os-animation', 'animated');
	}

	if (animDelay) {
		masterTL.delay(animDelay);
	}

	masterTL
		.add([tl, function () {

			// update scrollbar geometry
			if (window.SB !== undefined) {
				window.SB.update();
			}

		}], '0');

	// set animation reveal master speed
	if (window.theme !== undefined) {

		scale = window.theme.animations.timeScale.onScrollReveal || 1;
		masterTL.timeScale(scale);

	}

	new $.ScrollMagic.Scene({
		triggerElement: $trigger,
		triggerHook: window.SMSceneTriggerHook,
		reverse: window.SMSceneReverse
	})
		.setTween(masterTL)
		.addTo(window.SMController);

}

/*!========================================================================
	45. Get Scroll Top
	======================================================================!*/
function getScrollTop() {

	if (typeof window.SB !== 'undefined') {
		window.lastTop = window.SB.scrollTop;
	} else {
		window.lastTop = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
	}

	return window.lastTop;
}

/*!========================================================================
	46. Lock Scroll
	======================================================================!*/
function lockScroll(lock) {

	var LOCK_CLASS = 'body_lock-scroll';

	if (lock) {

		if (typeof window.SB !== 'undefined') {

			window.SB.updatePluginOptions('lockscroll', {
				lock: true
			});

		}

		window.$body.addClass(LOCK_CLASS);

	}

	if (!lock) {

		window.$body.removeClass(LOCK_CLASS);

		if (typeof window.SB !== 'undefined') {

			window.SB.updatePluginOptions('lockscroll', {
				lock: false
			});

		}

	}

}

/*!========================================================================
	47. Restore Scroll Top
	======================================================================!*/
function restoreScrollTop() {

	if (window.SB !== undefined) {

		setTimeout(function () {
			window.SB.scrollTop = window.lastTop;
		}, 100);

	} else {

		$('html, body').animate({
			scrollTop: window.lastTop
		}, 100);

	}

}

/*!========================================================================
	48. Scroll To Very Top
	======================================================================!*/
function scrollToVeryTop() {

	window.scrollTo(0, 0);

	// safari fix
	try {
		window.top.scrollTo(0, 0);
	} catch (error) {

	}

	if (window.SB !== undefined) {
		window.SB.scrollTop = 0;
	}

}

/*!========================================================================
	49. Scroll Down
	======================================================================!*/
var ScrollDown = function () {

	var $el = $('.js-scroll-down');

	if (!$el.length) {
		return;
	}

	$el.on('click', function (e) {

		e.preventDefault();

		$('html, body').animate({
			scrollTop: window.innerHeight
		}, 600, 'swing');

		if (window.SB !== undefined) {

			window.SB.scrollTo(0, window.innerHeight, 1200, {
				easing: function (pos) {
					if (pos === 0) return 0;
					if (pos === 1) return 1;
					if ((pos /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (pos - 1));
					return 0.5 * (-Math.pow(2, -10 * --pos) + 2);
				}
			});
		}

	});

};

/*!========================================================================
	50. Section About
	======================================================================!*/
var SectionAbout = function ($scope) {

	var
		$target = $scope.find('.section-about'),
		$counters,
		$animTarget;

	if (!$target.length) {
		return;
	}

	$animTarget = $scope.find('.section-about[data-os-animation]');
	$counters = $target.find('.js-counter');

	$counters.each(function () {

		new Counter($(this));

	});

	$animTarget.each(function () {

		var
			$current = $(this),
			$header = $current.find('.section-about__header'),
			$headline = $current.find('.section__headline'),
			tl = new TimelineMax();

		prepare();
		animate();

		function prepare() {

			TweenMax.set($headline, {
				scaleX: 0
			});

		}

		function animate() {

			tl
				.add(animateHeadline($headline), '0')
				.add(animateChars($current, 1.2, 0.6, Power3.easeOut), '-=1.2')
				.add(animateLines($current, 1.2, 0.07, Power3.easeOut), '-=1.2')

			createOSScene($current, tl, $header);

		}

	});

}

/*!========================================================================
	51. Section Awards
	======================================================================!*/
var SectionAwards = function ($scope) {

	var
		$target = $scope.find('.section-awards'),
		$figureAward = $target.find('.figure-award[data-os-animation]');

	$figureAward.each(function () {
		new FigureAward($(this));
	});

}

/*!========================================================================
	52. Section Content
	======================================================================!*/
var SectionContent = function ($scope) {

	var $target = $scope.find('.section-content[data-os-animation]');

	if (!$target.length) {
		return;
	}

	$target.each(function () {

		var
			tl = new TimelineMax(),
			$current = $(this),
			$header = $current.find('.section-content__header'),
			$wrapperButton = $current.find('.section-content__wrapper-button'),
			$headline = $current.find('.section__headline');

		prepare();
		animate();

		function prepare() {

			TweenMax.set($headline, {
				scaleX: 0,
				transformOrigin: 'left center'
			});

			TweenMax.set($wrapperButton, {
				autoAlpha: 0,
				y: '50%'
			});

		}

		function animate() {

			var $trigger = $current;

			if ($header.length) {
				$trigger = $header
			}

			tl
				.add([
					animateChars($current, 1.2, 0.3, Power3.easeOut),
					animateLines($current, 1.2, 0.07),
					animateHeadline($headline)
				])
				.to($wrapperButton, 1.2, {
					autoAlpha: 1,
					y: '0%'
				}, '-=0.9');

			createOSScene($current, tl, $trigger);

		}

	});

}

/*!========================================================================
	53. Section Fullscreen Slider
	======================================================================!*/
var SectionFullscreenSlider = function ($scope) {

	var $target = $scope.find('.section-fullscreen-slider[data-os-animation]');

	if (!$target.length) {

		return;

	}

	$target.each(function () {

		var
			tl = new TimelineMax(),
			$current = $(this),
			$canvasWrapper = $current.find('.slider__wrapper-canvas'),
			slider,
			$slider = $current.find('.js-slider-fullscreen'),
			$sliderImages = $current.find('.js-slider-fullscreen__images'),
			effectIntensity = $sliderImages.data('transition-effect-intensity') || 0.25,
			speed = $sliderImages.data('speed') / 1000 || 1.2,
			$buttonWrapper = $slider.find('.slider__wrapper-button');

		function prepare() {

			return new Promise(function (resolve, reject) {

				var tl = new TimelineMax();

				tl
					.set($buttonWrapper, {
						autoAlpha: 0,
						y: '20px'
					})
					.set($canvasWrapper, {
						scale: 1.1,
						autoAlpha: 0,
						transformOrigin: 'center center'
					})
					.add(function () {
						slider = new SliderFullScreen($slider);
						if (slider.params.autoplay.enabled) {
							slider.autoplay.stop();
						}
					})
					.add(function () {
						resolve(true);
					});

			});

		}

		function animate() {

			var
				$activeSlide = $target.find('.swiper-slide-active'),
				$activeHeading = $activeSlide.find('.slider__heading'),
				$activeSubheading = $activeSlide.find('.slider__subheading'),
				$activeDescription = $activeSlide.find('.slider__text'),
				$activeButton = $activeSlide.find('.slider__wrapper-button');

			$activeSlide.imagesLoaded({
				background: true,
			}, function () {


				tl
					.add(
						function () {

							if (slider.params.autoplay.enabled) {
								slider.autoplay.start();
							}

							if (typeof slider.distortionEffect !== 'undefined') {
								TweenMax.to($canvasWrapper, speed * 1.5, {
									scale: 1,
									autoAlpha: 1,
									ease: Power3.easeOut
								});

								slider.distortionEffect.animate();
								slider.distortionEffect.change({
									indexFrom: '0',
									indexTo: '0',
									speedIn: speed * 1.5,
									intensity: effectIntensity,
									easing: Power3.easeOut,
									direction: 'vertical'
								});

								window.$window.one('arts/barba/transition/start', () => {
									slider.distortionEffect.destroy();
								});

							}

						}
					)
					.add(animateChars($activeHeading, 1.2, 0.3, Power3.easeOut), '+=0.6')
					.add(animateChars($activeSubheading, 1.2, 0.3, Power3.easeOut), '-=1.2')
					.add(animateLines($activeDescription, 1.2, 0.04), '-=1.2')
					.to($activeButton, 1.2, {
						y: '0px',
						autoAlpha: 1,
						ease: Power3.easeOut
					}, '-=1.2');

				createOSScene($current, tl);

			});

		}

		$sliderImages.imagesLoaded().always(() => {
			prepare().then(() => {
				animate();
			});
		});

	})

}

/*!========================================================================
	54. Section Grid
	======================================================================!*/
var SectionGrid = function ($scope) {

	var
		$target = $scope.find('.section-grid[data-os-animation]'),
		$captions,
		$images,
		$items;

	if (!$target.length) {
		return;
	}

	$captions = $target.find('.figure-image__wrapper-caption');
	$items = $target.find('.figure-image');
	$images = $target.find('.figure-image__wrapper-img');

	prepare();
	animate();

	function prepare() {

		TweenMax.set($images, {
			scaleY: 1.5,
			y: '33%',
			transformOrigin: 'top center',
			autoAlpha: 0.01,
		});

		TweenMax.set($captions, {
			autoAlpha: 0,
		});

		TweenMax.set($target, {
			autoAlpha: 1
		});

	}

	function animate() {

		var
			colsDesktop = parseInt($target.data('grid-columns'), 10),
			colsTablet = parseInt($target.data('grid-columns-tablet'), 10),
			colsMobile = parseInt($target.data('grid-columns-mobile'), 10),
			lg = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.lg - 1 : 1024,
			md = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.md - 1 : 767,
			cols = colsDesktop;

		if (Modernizr.mq('(max-width: ' + lg + 'px)')) {
			cols = colsTablet;
		}

		if (Modernizr.mq('(max-width: ' + md + 'px)')) {
			cols = colsMobile;
		}

		for (var index = 0; index < $items.length; index = index + cols) {

			var
				$array = $items.slice(index, index + cols),
				$currentImages = $array.find($images),
				$currentCaptions = $array.find($captions),
				tl = new TimelineMax();

			tl
				.add([
					TweenMax.staggerTo($currentImages, 0.9, {
						autoAlpha: 1,
						y: '0%',
						force3D: true,
						scaleY: 1,
						ease: Power3.easeOut
					}, 0.15),
					TweenMax.staggerTo($currentCaptions, 0.9, {
						autoAlpha: 1,
						delay: 0.4,
						ease: Power3.easeOut
					}, 0.15),
				]);

			createOSScene($array[0], tl, false, true);

		}

	}

}

/*!========================================================================
	55. Section Masthead
	======================================================================!*/
var SectionMasthead = function ($scope) {

	var $target = $scope.find('.section-masthead[data-os-animation]');

	if (!$target.length) {
		return;
	}

	$target.each(function () {

		var
			$current = $(this),
			$currentBig = $current.filter('.section-masthead_big-heading'),
			tl = new TimelineMax(),
			$background = $current.find('.section-masthead__background .art-parallax__wrapper'),
			$curtain = $current.find('.section-masthead__curtain'),
			$heading = $current.find('.section-masthead__heading'),
			$headingBig = $current.find('.section-masthead__heading-big'),
			$text = $current.find('.section-masthead__text'),
			$subheading = $current.find('.section-masthead__subheading'),
			$button = $current.find('.section-masthead__wrapper-button'),
			$headline = $current.find('.section__headline');

		prepare();
		animate();

		function prepare() {

			TweenMax.set($headline, {
				scaleX: 0,
				transformOrigin: 'left center'
			});

			TweenMax.set($curtain, {
				scaleY: 0,
				transformOrigin: 'bottom center'
			});

			TweenMax.set($background, {
				scale: 1.1,
			});

			TweenMax.set($button, {
				y: '100%',
				autoAlpha: 0
			});

		}

		function animate() {

			tl
				.add(function () {
					if ($currentBig.length) {
						window.SMController.enabled(false);
						lockScroll(true);
					}
				})
				.set($current, {
					autoAlpha: 1
				})
				.add(animateChars($subheading, 1.2, 0.4, Power3.easeInOut))
				.add(animateLines($text, 1.2, 0.08, Power3.easeOut), '0.9')
				.add(animateHeadline($headline), '-=1.2')
				.add(hideChars($headingBig, 0.6, 0.1, Power3.easeInOut, 0, '-200%'), '+=0.4')
				.to($currentBig, 0.6, {
					height: 0,
					ease: Expo.easeOut,
					display: 'none'
				}, '-=0.3')
				.add(function () {
					if ($currentBig.length) {
						lockScroll(false);
						window.SMController.enabled(true);
						window.SMController.update(true);
						new Grid();
					}
				}, '-=0.3')

			if (!$heading.hasClass('js-split-text_cancel-animation')) {
				tl.add(animateChars($heading, 1.2, 0.4, Power3.easeInOut), '0');
			}

			if ($curtain.length) {
				tl.to($curtain, 1.2, {
					scaleY: 1,
					ease: Expo.easeInOut
				}, '0');
			}

			if ($background.length) {
				tl.fromTo($background, 2.4, {
					scale: 1.1
				}, {
					scale: 1
				}, '0');
			}

			if ($button.length) {
				tl.to($button, 1.2, {
					y: '0%',
					autoAlpha: 1,
					ease: Power3.easeOut
				}, '-=1.2');
			}

			createOSScene($current, tl);

		}

	});

}

/*!========================================================================
	56. Section Nav Projects
	======================================================================!*/
var SectionNavProjects = function ($scope) {

	var $target = $scope.find('.section-nav-projects');

	if (!$target.length) {
		return;
	}

	var
		$allButton = $target.find('.section-nav-projects__inner_all'),
		$prevHeading = $target.find('.section-nav-projects__heading_prev'),
		$nextHeading = $target.find('.section-nav-projects__heading_next'),
		$prevArrow = $target.find('.section-nav-projects__arrow_prev'),
		$nextArrow = $target.find('.section-nav-projects__arrow_next'),
		$prevButton = $target.find('.section-nav-projects__inner_prev'),
		$nextButton = $target.find('.section-nav-projects__inner_next'),
		tl = new TimelineMax(),
		duration = 0.6,
		offset = 75,
		stagger = 0.2,
		isRevealEffect = $target.hasClass('section-nav-projects_reveal'),
		isSplitEffect = $target.hasClass('section-nav-projects_none');

	new ButtonCircles($allButton);

	if (isRevealEffect) {

		setChars($prevButton, offset);
		setChars($nextButton, offset);

		if (Modernizr.mq('(min-width: 767px)')) {

			window.$document
				.on('mouseenter touchstart', '.section-nav-projects__inner_prev', function () {
					tl
						.clear()
						.to($nextArrow, duration / 2, {
							autoAlpha: 1,
							x: '0px'
						}, '0.4')
						.to($prevArrow, duration / 2, {
							autoAlpha: 0,
							x: (-1) * offset / 2 + 'px'
						}, '0')
						.add(animateChars($prevHeading, duration, stagger, Power4.easeOut), '0.2')
						.add(hideChars($nextHeading, duration, stagger, Power4.easeOut, (-1) * offset, 0, 'start'), '0.2');
				})
				.on('mouseleave touchend', '.section-nav-projects__inner_prev', function () {
					tl
						.clear()
						.to($prevArrow, duration / 2, {
							autoAlpha: 1,
							x: '0px'
						}, '0.2')
						.to($nextArrow, duration / 2, {
							autoAlpha: 1,
							x: '0px'
						}, '0.4')
						.add(hideChars($prevHeading, duration, stagger, Power4.easeOut, offset, 0, 'end'), '0')
						.add(hideChars($nextHeading, duration, stagger, Power4.easeOut, (-1) * offset, 0, 'start'), '0');
				})
				.on('mouseenter touchstart', '.section-nav-projects__inner_next', function () {
					tl
						.clear()
						.to($prevArrow, duration / 2, {
							autoAlpha: 1,
							x: '0px'
						}, '0.4')
						.to($nextArrow, duration / 2, {
							autoAlpha: 0,
							x: offset / 2 + 'px'
						}, '0')
						.add(animateChars($nextHeading, duration, stagger, Power4.easeOut), '0.2')
						.add(hideChars($prevHeading, duration, stagger, Power4.easeOut, offset, 0, 'end'), '0.2');
				})
				.on('mouseleave touchend', '.section-nav-projects__inner_next', function () {
					tl
						.clear()
						.to($nextArrow, duration / 2, {
							autoAlpha: 1,
							x: '0px'
						}, '0.2')
						.to($prevArrow, duration / 2, {
							autoAlpha: 1,
							x: '0px'
						}, '0.2')
						.add(hideChars($nextHeading, duration, stagger, Power4.easeOut, (-1) * offset, 0, 'start'), '0')
						.add(hideChars($prevHeading, duration, stagger, Power4.easeOut, offset, 0, 'end'), '0');
				})
				.on('click', '.section-nav-projects__inner_prev', function () {
					tl
						.clear()
						.stop();

				})
				.on('click', '.section-nav-projects__inner_next', function () {
					tl
						.clear()
						.stop();

				});

		} else {

			animateChars($prevHeading, 0, 0, Power4.easeOut);
			animateChars($nextHeading, 0, 0, Power4.easeOut);

		}
	}

	if (isSplitEffect) {
		animateChars($prevHeading, 0, 0, Power4.easeOut);
		animateChars($nextHeading, 0, 0, Power4.easeOut);
	}

}

/*!========================================================================
	57. Section Portfolio
	======================================================================!*/
var SectionPortfolio = function ($scope) {

	var
		$target = $scope.find('.section-portfolio'),
		$filter,
		$grid,
		$figurePortfolioHover,
		$figurePortfolio,
		$filterItems,
		$filterLine,
		$animTarget,
		colsDesktop,
		colsTablet,
		colsMobile,
		lg,
		md,
		cols,
		FilterPortfolio,
		GridPortfolio;

	if (!$target.length) {
		return;
	}

	$animTarget = $scope.find('.section-portfolio[data-os-animation]');
	$figurePortfolioHover = $target.find('.figure-portfolio-item_hover');
	$figurePortfolio = $animTarget.find('.figure-portfolio[data-os-animation]');
	$filter = $target.find('.js-filter');
	$filterItems = $animTarget.find('.filter__item > *');
	$filterLine = $animTarget.find('.filter__underline');
	$grid = $target.find('.js-grid');
	colsDesktop = parseInt($grid.data('grid-columns'), 10) || -1;
	colsTablet = parseInt($grid.data('grid-columns-tablet'), 10) || -1;
	colsMobile = parseInt($grid.data('grid-columns-mobile'), 10) || -1;
	lg = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.lg - 1 : 1024;
	md = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.md - 1 : 767;
	cols = colsDesktop;

	if (Modernizr.mq('(max-width: ' + lg + 'px)')) {
		cols = colsTablet;
	}

	if (Modernizr.mq('(max-width: ' + md + 'px)')) {
		cols = colsMobile;
	}

	bindGridFilter();
	animateHover();
	prepare();
	animate();

	function bindGridFilter() {

		if (!$filter.length || !$grid.length) {
			return;
		}

		var scrollEvent = new Event('scroll');

		FilterPortfolio = new Filter($scope, $filter);
		GridPortfolio = new Grid($grid);

		if ($filter.length) {

			FilterPortfolio.setActiveItem(0);

			FilterPortfolio.$items.on('click', function (e) {

				e.preventDefault();

				var filterBy = $(this).data('filter');

				if ($grid.hasClass('grid_fancy')) {
					if (filterBy !== '*') {
						$grid.addClass('grid_fancy-disable');
					} else {
						$grid.removeClass('grid_fancy-disable');
					}
				}

				GridPortfolio.isotope({
					filter: filterBy
				});

				// update scroll to trigger reveal animation & lazy load
				GridPortfolio.on('arrangeComplete', function () {
					window.dispatchEvent(scrollEvent);
				});

			});

		}

		GridPortfolio.isotope({
			filter: '*'
		});

	}

	function animateHover() {

		$figurePortfolioHover.each(function () {

			var $current = $(this);

			new FigurePortfolioHover($current);

		});

	}

	function prepare() {
		TweenMax.set($filterItems, {
			autoAlpha: 0,
			y: '30px'
		});
		TweenMax.set($filterLine, {
			autoAlpha: 0
		});
	}

	function animate() {

		var tl = new TimelineMax();

		tl
			.delay(0.1)
			.add([
				TweenMax.staggerTo($filterItems, 0.9, {
					autoAlpha: 1,
					y: '0px',
					ease: Power3.easeOut
				}, 0.1),
				TweenMax.to($filterLine, 0.9, {
					autoAlpha: 1
				})
			]);

		for (var index = 0; index < $figurePortfolio.length; index = index + cols) {

			var
				$array = $figurePortfolio.slice(index, index + cols),
				currentDelay = 0.1;

			$array.each(function (index) {

				var $current = $(this);

				new FigurePortfolioAnimation($current, currentDelay);

				currentDelay += 0.1;


			});


		}

		createOSScene($animTarget, tl);

	}

}

/*!========================================================================
	58. Section Properties
	======================================================================!*/
var SectionProperties = function ($scope) {

	var
		$target = $scope.find('.section-properties[data-os-animation]');

	if (!$target.length) {
		return;
	}

	$target.attr('data-os-animation', 'animated');

	$target.each(function () {

		var
			$current = $(this),
			$figures = $current.find('.figure-info');

		$figures.each(function () {

			var
				tl = new TimelineMax(),
				$currentFigure = $(this),
				$option = $currentFigure.find('.figure-info__option'),
				$value = $currentFigure.find('.figure-info__value');

			tl
				.add(animateLines($option, 0.6, 0.07))
				.add(animateLines($value, 0.6, 0.07), '-=0.5')

			createOSScene($currentFigure, tl);

		});

	});

}

/*!========================================================================
	59. Section Services
	======================================================================!*/
var SectionServices = function ($scope) {

	var $target = $scope.find('.section-services[data-os-animation]');

	if (!$target.length) {
		return;
	}

	$target.each(function () {

		var
			$current = $(this),
			$serviceItem = $current.find('.section-services__wrapper-item'),
			$lines = $current.find('.section-services__border-line'),
			$bg = $current.find('.section-services__bg'),
			tl = new TimelineMax(),
			tlChild = new TimelineMax();

		prepare();
		animate();

		function prepare() {

			TweenMax.set($bg, {
				x: '-100%',
			});

			TweenMax.set($lines, {
				x: '-200%',
			})

		}

		function animate() {

			tl
				.to([$bg, $lines], 1.2, {
					x: '0%',
					ease: Expo.easeInOut
				});

			$serviceItem.each(function () {

				var
					$currentServiceItem = $(this),
					$counter = $currentServiceItem.find('.section-services__counter'),
					$heading = $currentServiceItem.find('.section-services__heading'),
					$link = $currentServiceItem.find('.section-services__wrapper-button');


				tlChild
					.add([
						animateChars($heading, 1.2, 0.4, Power3.easeOut),
						animateChars($counter, 1.2, 0.1, Power3.easeOut)
					], 'start')
					.fromTo($link, 0.6, {
						y: '100%',
						autoAlpha: 0
					}, {
						y: '0%',
						autoAlpha: 1
					}, 'start')

			});

			tl.add(tlChild, '-=0.2');

			createOSScene($target, tl);

		}

	});

}

/*!========================================================================
	60. Section Testimonials
	======================================================================!*/
var SectionTestimonials = function ($scope) {

	var $target = $scope.find('.section-testimonials');

	if (!$target.length) {
		return;
	}

	$target.each(function () {

		var
			tl = new TimelineMax(),
			$current = $(this),
			$slider = $target;

		prepare().then(function () {
			animate();
		});


		function prepare() {

			return new Promise(function (resolve, reject) {

				var tl = new TimelineMax();

				tl
					.add(function () {
						new SliderTestimonials($current);
					})
					.add(function () {
						resolve(true);
					});

			});

		}

		function animate() {

			var
				$activeSlide = $current.find('.swiper-slide-active'),
				$activeText = $activeSlide.find('.slider-testimonials__text'),
				$activeAuthor = $activeSlide.find('.slider-testimonials__author');


			tl
				.add(animateLines($activeText, 1.2, 0.1, Power3.easeOut))
				.add(animateChars($activeAuthor, 1.2, 0.3, Power3.easeOut), '-=0.6');

		}

	})

}

/*!========================================================================
	61. Slider Fullscreen
	======================================================================!*/
var SliderFullScreen = function ($slider) {

	if (!$slider.length) {
		return;
	}

	var
		$heading = $slider.find('.slider__heading'),
		$subheading = $slider.find('.slider__subheading'),
		$description = $slider.find('.slider__text'),
		$link = $slider.find('.slider-fullscreen__wrapper-button'),
		$sliderImg = $slider.find('.js-slider-fullscreen__images'),
		$sliderContent = $slider.find('.js-slider-fullscreen__content'),
		$inner = $slider.find('.slider__images-slide-inner'),
		sliderSpeed = $sliderImg.data('speed') || 1200,
		effectIntensity = $sliderImg.data('transition-effect-intensity') || 0,
		$dots = $slider.find('.js-slider-dots'),
		$counterCurrent = $slider.find('.js-slider-fullscreen__counter-current'),
		$counterTotal = $slider.find('.js-slider-fullscreen__counter-total'),
		counterZeros = $sliderImg.data('counter-zeros');

	var sliderImg = new Swiper($sliderImg.get(0), {
		direction: $sliderImg.data('direction') || 'vertical',
		preloadImages: true,
		updateOnImagesReady: true,
		slidesPerView: 1,
		slidesPerGroup: 1, // compatibility with Swiper 5.x
		lazy: {
			loadPrevNextAmount: 3,
			loadPrevNext: true,
			loadOnTransitionStart: true
		},
		speed: sliderSpeed,
		allowTouchMove: $sliderImg.data('touch-enabled') || false,
		simulateTouch: false,
		touchRatio: $sliderImg.data('direction') == 'vertical' ? 2.5 : 1.1,
		watchSlidesProgress: true,
		keyboard: {
			enabled: $sliderImg.data('keyboard-enabled') || false
		},
	});

	var sliderContent = new Swiper($sliderContent.get(0), {
		direction: $sliderImg.data('direction') || 'vertical',
		autoHeight: true,
		effect: 'fade',
		virtualTranslate: true,
		slidesPerView: 1,
		slidesPerGroup: 1, // compatibility with Swiper 5.x
		fadeEffect: {
			crossFade: $sliderContent.data('no-transition-text') ? true : false
		},
		autoplay: {
			disableOnInteraction: false,
			enabled: $sliderImg.data('autoplay-enabled') || false,
			delay: $sliderImg.data('autoplay-delay') || 6000,
		},
		mousewheel: $sliderImg.data('mousewheel-enabled') ? {
			eventsTarged: $sliderImg.data('mousewheel-target') || '.page-wrapper',
			releaseOnEdges: true,
		} : false,
		navigation: {
			nextEl: $slider.find('.js-slider-fullscreen__next').get(0),
			prevEl: $slider.find('.js-slider-fullscreen__prev').get(0),
		},
		speed: $sliderImg.data('speed') || 1200,
		allowTouchMove: $sliderImg.data('touch-enabled') || false,
		simulateTouch: false,
		touchRatio: $sliderImg.data('direction') == 'vertical' ? 2.5 : 1.1,
		pagination: {
			el: $slider.find('.js-slider-dots').get(0),
			type: 'bullets',
			bulletElement: 'div',
			clickable: true,
			bulletClass: 'slider__dot',
			bulletActiveClass: 'slider__dot_active'
		},
	});

	TweenMax.set($inner, {
		transitionDelay: sliderSpeed + 'ms' || '1200ms'
	});

	renderSliderDots(sliderContent, $dots);
	renderSliderCounter(
		sliderContent,
		$counterCurrent,
		'',
		$counterTotal,
		sliderImg,
		counterZeros
	);

	sliderImg.on('slideChange', function () {
		sliderContent.slideTo(sliderImg.realIndex);
	});

	setSliderTextTransitions(sliderContent, sliderImg.params.direction, 25, $heading, $subheading, $description, $link);

	if ($sliderImg.data('transition-effect') == 'enter_leave') {
		setSliderOverlapEffect(sliderImg, effectIntensity);
	}

	if ($sliderImg.data('transition-effect') == 'distortion') {

		var aspectRatio = parseFloat($slider.find('[data-aspect-ratio]').data('aspect-ratio')) || 1.7777;

		sliderImg.params.preloadImages = false;
		sliderImg.params.lazy = false;
		sliderContent.distortionEffect = setSliderDistortionEffect(sliderImg, $sliderImg, effectIntensity, aspectRatio);

	}

	return sliderContent;

}

/*!========================================================================
	62. Slider Images
	======================================================================!*/
var SliderImages = function ($scope) {

	var $slider = $scope.find('.js-slider-images');

	if (!$slider.length) {
		return;
	}

	$slider.each(function () {

		var
			$current = $(this),
			$parent = $current.parent(),
			$sliderCaptions = $parent.find('.js-slider-images__captions'),
			sliderCaptions,
			counterZeros = $current.data('counter-zeros'),
			lg = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.lg - 1 : 1024,
			md = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.md - 1 : 767;

		var slider = new Swiper($current.get(0), {
			autoHeight: $current.data('auto-height') || true,
			speed: $current.data('speed') || 1200,
			preloadImages: false,
			lazy: {
				loadPrevNext: true,
				loadPrevNextAmount: 3,
				loadOnTransitionStart: true
			},
			touchRatio: $current.data('touch-ratio') || 3,
			observer: true,
			watchSlidesProgress: true,
			watchSlidesVisibility: true,
			centeredSlides: $current.data('centered-slides') || false,
			slidesPerView: $current.data('slides-per-view') || 1.5,
			slidesPerGroup: 1, // compatibility with Swiper 5.x
			autoplay: {
				disableOnInteraction: false,
				enabled: $current.data('autoplay-enabled') || false,
				delay: $current.data('autoplay-delay') || 6000,
			},
			spaceBetween: $current.data('space-between') || 60,
			pagination: {
				el: $parent.find('.js-slider-images__dots').get(0),
				type: 'bullets',
				bulletElement: 'div',
				clickable: true,
				bulletClass: 'slider__dot',
				bulletActiveClass: 'slider__dot_active'
			},
			navigation: {
				nextEl: $parent.find('.js-slider-images__next').get(0),
				prevEl: $parent.find('.js-slider-images__prev').get(0),
			},
			breakpointsInverse: true // compatibility with both Swiper 4.x and 5.x
		});

		slider.params.breakpoints = {
			0: {
				slidesPerView: $current.data('slides-per-view-mobile') || 1.16,
				spaceBetween: $current.data('space-between-mobile') || 10,
				centeredSlides: $current.data('centered-slides-mobile') || true,
				lazy: {
					loadPrevNext: true,
					loadPrevNextAmount: Math.round($current.data('slides-per-view-mobile')) || 3,
					loadOnTransitionStart: true
				}
			},
			[md]: {
				slidesPerView: $current.data('slides-per-view-tablet') || 1.33,
				spaceBetween: $current.data('space-between-tablet') || 20,
				centeredSlides: $current.data('centered-slides-tablet') || true,
				lazy: {
					loadPrevNext: true,
					loadPrevNextAmount: Math.round($current.data('slides-per-view-tablet')) || 3,
					loadOnTransitionStart: true
				}
			},
			[lg]: {
				centeredSlides: $current.data('centered-slides') || false,
				slidesPerView: $current.data('slides-per-view') || 1.5,
				spaceBetween: $current.data('space-between') || 60,
				lazy: {
					loadPrevNext: true,
					loadPrevNextAmount: Math.round($current.data('slides-per-view')) || 3,
					loadOnTransitionStart: true
				}
			}
		};

		slider.update();

		if ($sliderCaptions.length) {

			sliderCaptions = new Swiper($sliderCaptions.get(0), {
				autoHeight: true,
				direction: 'vertical',
				fadeEffect: {
					crossFade: true
				},
				speed: $current.data('speed') || 1200,
				allowTouchMove: false,
				watchSlidesProgress: true
			});

		}

		slider
			// update height after images are loaded
			.on('lazyImageReady', function () {
				slider.update();
			})
			// zoom images effect
			.on('touchStart', function () {
				$current.addClass('slider-images_touched');
			})
			.on('touchEnd', function () {
				$current.removeClass('slider-images_touched');
			});

		// cursor follower position adjustment
		if (typeof window.InteractiveCursor !== 'undefined') {
			slider.on('touchMove', function (swiper, e) {
				if (swiper instanceof Swiper) {
					window.InteractiveCursor.mouseX = e.clientX;
					window.InteractiveCursor.mouseY = e.clientY;
				} else {
					window.InteractiveCursor.mouseX = swiper.clientX;
					window.InteractiveCursor.mouseY = swiper.clientY;
				}
			});
		}

		$current.imagesLoaded().progress({
			background: true
		}, function (e) {
			setTimeout(function () {
				slider.update();
			}, 300);
		});

		renderSliderDots(slider, $parent.find('.js-slider-images__dots'));
		renderSliderCounter(
			slider,
			$parent.find('.js-slider-images__counter-current'),
			'',
			$parent.find('.js-slider-images__counter-total'),
			sliderCaptions,
			counterZeros
		);

	});

}

/*!========================================================================
	63. Render Slider Counter
	======================================================================!*/
function renderSliderCounter(sliderMain, sliderCounter, slideClass, elTotal, sliderSecondary, addZeros = 2) {

	if ($(sliderMain).length && $(sliderSecondary).length && !$(sliderCounter)) {
		sliderSecondary.controller.control = sliderMain;
		sliderMain.controller.control = sliderSecondary;
	}

	if (!$(sliderMain).length || !$(sliderCounter).length || !$(elTotal).length) {
		return;
	}

	var
		numOfSlides = sliderMain.slides.length,
		startSlides = parseInt(sliderMain.params.slidesPerView, 10),
		prefixTen = '0',
		prefixCurrent = '00',
		prefixTotal = numOfSlides >= 10 ? '0' : '00';

	var counter = new Swiper(sliderCounter.get(0), {
		direction: 'vertical',
		simulateTouch: false,
		allowTouchMove: false
	});

	switch (addZeros) {
		case 0:
			prefixCurrent = '';
			prefixTen = '';
			prefixTotal = '';
			break;
		case 1:
			prefixCurrent = '0';
			prefixTen = '';
			prefixTotal = numOfSlides >= 10 ? '' : '0';
			break;
		case 2:
			prefixCurrent = '00';
			prefixTen = '0';
			prefixTotal = numOfSlides >= 10 ? '0' : '00';
			break;
	}

	counter.removeAllSlides();

	for (var index = startSlides; index <= numOfSlides; index++) {

		if (index >= 10) {
			prefixCurrent = prefixTen;
		}

		counter.appendSlide('<div class="swiper-slide"><div class="' + slideClass + '">' + prefixCurrent + index + '</div></div>');

	}

	$(elTotal).html(prefixTotal + numOfSlides);

	sliderMain.controller.control = counter;
	counter.controller.control = sliderMain;

	if ($(sliderSecondary).length) {
		sliderSecondary.controller.control = counter;
		counter.controller.control = sliderSecondary;
	}

}

/*!========================================================================
	64. Render Slider Dots
	======================================================================!*/
function renderSliderDots(slider, $dotsContainer) {

	var
		$dots = $dotsContainer.find('.slider__dot'),
		tl = new TimelineMax(),
		$circles;

	if (!$dots.length) {
		return false;
	} else {

		// append SVG circle
		$dots.append('<svg viewBox="0 0 152 152" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g fill="none" fill-rule="evenodd"><g transform="translate(-134.000000, -98.000000)"><path class="circle" d="M135,174a75,75 0 1,0 150,0a75,75 0 1,0 -150,0"></path></g></g></svg>');
		$circles = $dots.find('.circle');

	}

	TweenMax.set($circles, {
		drawSVG: false,
	});

	slider
		.on('autoplayStop', function () {
			tl.stop();
		})
		.on('autoplayStart', function () {
			tl.play();
		})
		.on('slideChange', function () {
			// unsetDots();
			setCurrentDot();
		});

	// on init
	setCurrentDot();

	function setCurrentDot() {

		var
			$currentDot = $dots.eq(slider.realIndex),
			$currentCircle = $currentDot.find('.circle'),
			$otherCircles = $circles.not($currentCircle),
			autoPlaydelay = parseFloat(slider.params.speed / 1000) / 2;

		if (slider.params.autoplay.enabled) {
			autoPlaydelay = parseFloat(slider.params.autoplay.delay / 1000);
		}

		tl
			.clear()
			.to($otherCircles, autoPlaydelay / 10, {
				drawSVG: '0% 0%',
				ease: Power4.easeInOut,
			})
			.fromTo($currentCircle, autoPlaydelay, {
				drawSVG: '100% 100%',
				ease: Power4.easeInOut
			}, {
				drawSVG: '0% 100%'
			});

	}

}

/*!========================================================================
	65. Set Slider Distortion Effect
	======================================================================!*/
function setSliderDistortionEffect(slider, $slider, intensity, aspect = 1.6) {

	if (typeof THREE == 'undefined') {
		return;
	}

	var
		canvas = $slider.find('.slider__canvas').get(0),
		$canvasWrapper = $slider.find('.slider__wrapper-canvas'),
		$wrapper = $slider.find('.swiper-wrapper'),
		displacementImg = $slider.data('transition-displacement-img'),
		images = getSliderImages(),
		speed = slider.params.speed / 1000,
		tl = new TimelineMax();

	slider.params.effect = 'fade';
	slider.params.fadeEffect.crossFade = true;
	slider.params.virtualTranslate = true;
	var distortionEffect = new EffectDistortion({
		displacementImage: displacementImg,
		images: images,
		slider: slider,
		aspectRatio: aspect,
		canvas: canvas
	});

	distortionEffect.animate();

	slider.on('slideChange', function (e) {

			tl.clear().to($canvasWrapper, speed, {
					scale: 1.05,
					transformOrigin: 'center center',
					ease: Power3.easeOut
				})
				.to($canvasWrapper, speed * 2, {
					scale: 1,
				});

			distortionEffect.change({
				indexFrom: this.previousIndex,
				indexTo: this.activeIndex,
				speedIn: speed,
				intensity: this.activeIndex < this.previousIndex ? intensity * (-1) : intensity,
				easing: Power3.easeInOut
			});

	});

	if (window.theme.isElementorEditorActive) {
		TweenMax.set($wrapper, {
			display: 'none'
		});
	} else {
		$wrapper.remove();
	}

	function getSliderImages() {

		var
			src = [],
			current;

		$slider.find('.slider__bg').each(function () {
			var $el = $(this);

			current = $el.attr('data-background') || $el[0].currentSrc;

			if (!current) {
				current = $el.attr('poster');
			}

			src.push(current);

		});

		return src;

	}

	return distortionEffect;

}

/*!========================================================================
	66. Set Slider Overlap Effect
	======================================================================!*/
function setSliderOverlapEffect(slider, overlapFactor) {

	var
		i,
		innerOffset,
		innerTranslate,
		background;

	initialSet();

	function initialSet() {

		innerOffset = slider.width * overlapFactor;
		innerTranslate = innerOffset * (-1);
		background = slider.slides[1].querySelector('.slider__bg');

		TweenMax.set(background, {
			y: slider.params.direction === 'vertical' ? innerTranslate : 0,
			x: slider.params.direction === 'horizontal' ? innerTranslate : 0,
			transition: slider.params.speed + 'ms',
			force3D: true,
			backfaceVisibility: 'hidden'
		});
	}

	slider
		.on('progress', function () {
			var swiper = this;

			for (i = 0; i < swiper.slides.length; i++) {
				innerTranslate = swiper.slides[i].progress * innerOffset;

				try {

					TweenMax.set(swiper.slides[i].querySelector('.slider__bg'), {
						y: swiper.params.direction === 'vertical' ? innerTranslate : 0,
						x: swiper.params.direction === 'horizontal' ? innerTranslate : 0,
						transition: swiper.params.speed + 'ms',
						force3D: true,
						backfaceVisibility: 'hidden'
					});

				} catch (error) {

				}

			}

		})
		.on('setTransition', function (instance, speed) {
			var swiper = this;
			var speedParam = typeof instance === 'number' ? instance : speed;

			for (i = 0; i < swiper.slides.length; i++) {

				try {

					TweenMax.set(swiper.slides[i], {
						transition: speedParam + 'ms',
					});

					TweenMax.set(swiper.slides[i].querySelector('.slider__bg'), {
						transition: speedParam + 'ms',
					});

				} catch (error) {

				}

			}

		});

}

/*!========================================================================
	67. Set Slider Testimonials Transitions
	======================================================================!*/
function setSliderTestimonialsTransitions(slider, direction, offset = 40, $text, $author, $line) {

	var
		tl = new TimelineMax(),
		textAlign = $text.css('text-align'),
		offsetXNextIn = 0,
		offsetXNextOut = 0,
		offsetYNextIn = 0,
		offsetYNextOut = 0,
		offsetXPrevIn = 0,
		offsetXPrevOut = 0,
		offsetYPrevIn = 0,
		offsetYPrevOut = 0,

		fromNextIn = 'start',
		fromNextOut = 'start',
		fromPrevIn = 'end',
		fromPrevOut = 'end';


	switch (textAlign) {
		case 'left':
			// text align left & slider horizontal
			if (direction == 'horizontal') {

				offsetXNextIn = offset;
				offsetXNextOut = offset * (-1);
				offsetXPrevIn = offset * (-1);
				offsetXPrevOut = offset;

				fromNextOut = 'start';
				fromNextIn = 'start';
				fromPrevOut = 'end';
				fromPrevIn = 'end';

			}
			// text align left & slider vertical
			if (direction == 'vertical') {

				offsetYNextIn = offset;
				offsetYNextOut = offset * (-1);
				offsetYPrevIn = offset * (-1);
				offsetYPrevOut = offset;

				fromNextOut = 'start';
				fromNextIn = 'end';
				fromPrevOut = 'end';
				fromPrevIn = 'start';
			}
			break;
		case 'center':
			// text align center & slider horizontal
			if (direction == 'horizontal') {

				offsetXNextIn = offset;
				offsetXNextOut = offset * (-1);
				offsetXPrevIn = offset * (-1);
				offsetXPrevOut = offset;

				fromNextOut = 'start';
				fromNextIn = 'start';
				fromPrevOut = 'end';
				fromPrevIn = 'end';

			}
			// text align left & slider vertical
			if (direction == 'vertical') {

				offsetYNextIn = offset / 2;
				offsetYNextOut = offset * (-1) / 2;
				offsetYPrevIn = offset * (-1) / 2;
				offsetYPrevOut = offset / 2;

				fromNextOut = 'center';
				fromNextIn = 'center';
				fromPrevOut = 'center';
				fromPrevIn = 'center';
			}
			break;
		case 'right':
			// text align right & slider horizontal
			if (direction == 'horizontal') {

				offsetXNextIn = offset * (-1);
				offsetXNextOut = offset;
				offsetXPrevIn = offset;
				offsetXPrevOut = offset * (-1);

				fromNextOut = 'end';
				fromNextIn = 'end';
				fromPrevOut = 'start';
				fromPrevIn = 'start';

			}
			// text align right & slider vertical
			if (direction == 'vertical') {

				offsetYNextIn = offset * (-1);
				offsetYNextOut = offset;
				offsetYPrevIn = offset;
				offsetYPrevOut = offset * (-1);

				fromNextOut = 'end';
				fromNextIn = 'start';
				fromPrevOut = 'start';
				fromPrevIn = 'end';
			}
			break;
	}

	slider
		.on('slideNextTransitionStart', function () {

			var
				$activeSlide = $(slider.slides[slider.activeIndex]),
				$activeText = $activeSlide.find($text),
				$activeAuthor = $activeSlide.find($author),
				$activeLine = $activeSlide.find($line);

			tl.clear();

			$text.each(function () {

				tl
					.to($line, 0.6, {
						ease: Power3.easeInOut,
						scaleX: 0,
						transformOrigin: 'right center'
					}, '0')
					.add(hideLines($(this), 0.6, 0.05, offsetYNextOut, Power3.easeOut), '0')
					.add(hideChars($author, 0.6, 0.3, Power3.easeInOut, offsetYNextIn, 0, fromNextIn), '0')
					.add(hideLines($(this), 0, 0, offsetYNextIn, Power3.easeInOut))
					.add(hideChars($author, 0, 0, Power3.easeInOut, offsetYNextOut, 0));

			});

			tl
				.add(animateLines($activeText, 1.2, 0.1, Power3.easeOut, fromNextIn))
				.add(animateChars($activeAuthor, 1.2, 0.3, Power3.easeOut, fromNextIn), '-=1.2')
				.add(animateHeadline($activeLine, 0.6, Power3.easeInOut, 'left center'), '-=1.2');

		})
		.on('slidePrevTransitionStart', function () {

			var
				$activeSlide = $(slider.slides[slider.activeIndex]),
				$activeText = $activeSlide.find($text),
				$activeAuthor = $activeSlide.find($author),
				$activeLine = $activeSlide.find($line);

			tl.clear();

			$text.each(function () {

				tl
					.to($line, 0.6, {
						ease: Power3.easeInOut,
						scaleX: 0,
						transformOrigin: 'left center'
					}, '0')
					.add(hideLines($(this), 0.6, 0.05, offsetYPrevOut, Power3.easeOut, true), '0')
					.add(hideChars($author, 0.6, 0.3, Power3.easeInOut, offsetYNextOut, 0, fromPrevIn), '0')
					.add(hideLines($(this), 0, 0, offsetYPrevIn, Power3.easeInOut))
					.add(hideChars($author, 0, 0, Power3.easeInOut, offsetYPrevOut, 0));

			});

			tl
				.add(animateLines($activeText, 1.2, 0.1, Power3.easeOut, fromPrevIn))
				.add(animateChars($activeAuthor, 1.2, 0.3, Power3.easeOut, fromPrevIn), '-=1.2')
				.add(animateHeadline($activeLine, 0.6, Power3.easeInOut, 'right center'), '-=1.2');

		});


}

/*!========================================================================
	68. Set Slider Text Transitions
	======================================================================!*/
function setSliderTextTransitions(sliderContent, direction, offset = 40, $heading, $subheading, $description, $link) {

	var
		tl = new TimelineMax(),
		textAlign = $heading.css('text-align'),
		sliderSpeed = sliderContent.params.speed / 1000,
		noTextTransition = jQuery(sliderContent.$el).data('no-transition-text'),
		offsetXNextIn = 0,
		offsetXNextOut = 0,
		offsetYNextIn = 0,
		offsetYNextOut = 0,
		offsetXPrevIn = 0,
		offsetXPrevOut = 0,
		offsetYPrevIn = 0,
		offsetYPrevOut = 0,

		fromNextIn = 'start',
		fromNextOut = 'start',
		fromPrevIn = 'end',
		fromPrevOut = 'end';

	switch (textAlign) {
		case 'left':
			// text align left & slider horizontal
			if (direction == 'horizontal') {

				offsetXNextIn = offset;
				offsetXNextOut = offset * (-1);
				offsetXPrevIn = offset * (-1);
				offsetXPrevOut = offset;

				fromNextOut = 'start';
				fromNextIn = 'start';
				fromPrevOut = 'end';
				fromPrevIn = 'end';

			}
			// text align left & slider vertical
			if (direction == 'vertical') {

				offsetYNextIn = offset;
				offsetYNextOut = offset * (-1);
				offsetYPrevIn = offset * (-1);
				offsetYPrevOut = offset;

				fromNextOut = 'start';
				fromNextIn = 'end';
				fromPrevOut = 'end';
				fromPrevIn = 'start';
			}
			break;
		case 'center':
			// text align center & slider horizontal
			if (direction == 'horizontal') {

				offsetXNextIn = offset;
				offsetXNextOut = offset * (-1);
				offsetXPrevIn = offset * (-1);
				offsetXPrevOut = offset;

				fromNextOut = 'start';
				fromNextIn = 'start';
				fromPrevOut = 'end';
				fromPrevIn = 'end';

			}
			// text align left & slider vertical
			if (direction == 'vertical') {

				offsetYNextIn = offset / 2;
				offsetYNextOut = offset * (-1) / 2;
				offsetYPrevIn = offset * (-1) / 2;
				offsetYPrevOut = offset / 2;

				fromNextOut = 'center';
				fromNextIn = 'center';
				fromPrevOut = 'center';
				fromPrevIn = 'center';
			}
			break;
		case 'right':
			// text align right & slider horizontal
			if (direction == 'horizontal') {

				offsetXNextIn = offset * (-1);
				offsetXNextOut = offset;
				offsetXPrevIn = offset;
				offsetXPrevOut = offset * (-1);

				fromNextOut = 'end';
				fromNextIn = 'end';
				fromPrevOut = 'start';
				fromPrevIn = 'start';

			}
			// text align right & slider vertical
			if (direction == 'vertical') {

				offsetYNextIn = offset * (-1);
				offsetYNextOut = offset;
				offsetYPrevIn = offset;
				offsetYPrevOut = offset * (-1);

				fromNextOut = 'end';
				fromNextIn = 'start';
				fromPrevOut = 'start';
				fromPrevIn = 'end';
			}
			break;
	}

	sliderContent.on('slideChange', function () {

		if (sliderContent.realIndex > sliderContent.previousIndex) {
			slideChangeTransition('next');
		}

		if (sliderContent.realIndex < sliderContent.previousIndex) {
			slideChangeTransition('prev');
		}

	});

	function slideChangeTransition(direction = 'next') {

		var
			directionOutX,
			directionOutY,
			directionOutFrom,
			directionInX,
			directionInY,
			directionInFrom,
			$activeSlide = $(sliderContent.slides[sliderContent.realIndex]),
			$activeHeading = $activeSlide.find($heading),
			$activeSubheading = $activeSlide.find($subheading),
			$activeDescription = $activeSlide.find($description),
			$activeLink = $activeSlide.find($link);

		if (direction === 'next') {

			// next out
			directionOutX = offsetXNextOut;
			directionOutY = offsetYNextOut;
			directionOutFrom = fromNextOut;

			// next in
			directionInX = offsetXNextIn;
			directionInY = offsetYNextIn;
			directionInFrom = fromNextIn;

		}

		if (direction === 'prev') {

			// prev out
			directionOutX = offsetXPrevOut;
			directionOutY = offsetYPrevOut;
			directionOutFrom = fromPrevOut;

			// prev in
			directionInX = offsetXPrevIn;
			directionInY = offsetYPrevIn;
			directionInFrom = fromPrevIn;

		}

		tl.clear();

		$heading.each(function () {

			tl
				.add(hideChars($(this), sliderSpeed / 2, 0.3, Power3.easeInOut, directionOutX, directionOutY, directionOutFrom), '0')
				.add(hideChars($subheading, sliderSpeed / 2, 0.3, Power3.easeInOut, directionOutX / 1.5, directionOutY / 1.5, directionOutFrom), '0')
				.add(hideLines($description, sliderSpeed / 2, 0.04, directionOutY || directionOutX, Power3.easeOut), '0')
				.add(hideButton(), noTextTransition ? '0' : '-=' + sliderSpeed / 2)
				.add(hideChars($(this), 0, 0, Power3.easeInOut, directionInX, directionInY))
				.add(hideChars($subheading, 0, 0, Power3.easeInOut, directionInX / 2, directionInY / 2))
				.add(hideLines($activeDescription, 0, 0, directionInY || directionInX))
				.add(setButton());

		});

		tl
			.add(animateChars($activeHeading, sliderSpeed, 0.3, Power3.easeOut, directionInFrom))
			.add(animateLines($activeDescription, sliderSpeed, 0.04, Power3.easeOut, directionInFrom), '-=' + sliderSpeed)
			.add(animateChars($activeSubheading, sliderSpeed, 0.3, Power3.easeOut, directionInFrom), '-=' + sliderSpeed)
			.add(showButton($activeLink), noTextTransition ? 'null' : '-=' + sliderSpeed / 4 * 3);
	}

	function hideButton() {

		var tl = new TimelineMax();

		if (typeof $link != 'undefined' && $link.length) {
			tl.to($link, sliderSpeed / 2, {
				y: (offsetYNextOut || offsetXNextOut) * (-1) / 2 + 'px',
				autoAlpha: 0
			});
		}

		return tl;

	}

	function showButton($activeLink) {

		var tl = new TimelineMax();

		if (typeof $activeLink != 'undefined' && $activeLink.length) {
			tl.to($activeLink, sliderSpeed / 2, {
				y: '0px',
				autoAlpha: 1
			});
		}

		return tl;

	}

	function setButton() {

		var tl = new TimelineMax();

		if (typeof $link != 'undefined' && $link.length) {
			tl.set($link, {
				y: (offsetYNextIn || offsetXNextIn) / 2 + 'px',
				autoAlpha: 0
			});
		}

		return tl;

	}

}

/*!========================================================================
	69. Slider Letters
	======================================================================!*/
var SliderLetters = function ($scope) {

	var
		$SVGLetters = $('.vector-letters'),
		$letters = $SVGLetters.find('.vector-letter'),
		$menuItems = $scope.find('.menu-overlay a'),
		$currentMenuItem = $scope.find('.menu-overlay li.current-menu-item a'),
		currentLetter = $currentMenuItem.attr('data-letter'),
		$targetLetter = $letters.filter('[data-vector-id="' + currentLetter + '"]'),
		tl = new TimelineMax();

	if (!$SVGLetters.length || !$letters.length) {
		return;
	}

	hoverMenuitems();

	if ($currentMenuItem.length && currentLetter) {
		$letters.removeClass('current');
		$targetLetter.addClass('current');
		tl
			.clear()
			.set($letters[0], {
				morphSVG: $targetLetter
			});
	}

	function hoverMenuitems() {

		$menuItems.each(function () {

			var
				$current = $(this),
				currentLetter = $current.data('letter'),
				targetLetter = $letters.filter('[data-vector-id="' + currentLetter + '"]');

			$current
				.on('mouseenter touchstart', function () {
					tl
						.clear()
						.to($letters[0], 0.6, {
							morphSVG: targetLetter,
							ease: Expo.easeInOut
						});
				});

		});

	}

}

/*!========================================================================
	70. Slider Testimonials
	======================================================================!*/
var SliderTestimonials = function ($target) {

	if (!$target.length) {
		return;
	}

	var
		$footer = $target.parent().find('.js-slider-testimonials__footer'),
		$text = $target.find('.slider-testimonials__text'),
		$author = $target.find('.slider-testimonials__author'),
		$line = $target.find('.slider-testimonials__author-line'),
		counterZeros = $target.data('counter-zeros');

	var slider = new Swiper($target.get(0), {
		effect: 'fade',
		fadeEffect: {
			crossFade: true
		},
		allowTouchMove: false,
		direction: 'horizontal',
		autoHeight: true,
		speed: $target.data('speed') || 1200,
		autoplay: {
			disableOnInteraction: false,
			enabled: $target.data('autoplay-enabled') || false,
			delay: $target.data('autoplay-delay') || 6000,
		},
		pagination: {
			el: '.js-slider-testimonials__dots',
			type: 'bullets',
			bulletElement: 'div',
			clickable: true,
			bulletClass: 'slider__dot',
			bulletActiveClass: 'slider__dot_active'
		},
		navigation: {
			nextEl: '.js-slider-testimonials__next',
			prevEl: '.js-slider-testimonials__prev',
		},
	});

	renderSliderDots(slider, $footer.find('.js-slider-testimonials__dots'));
	renderSliderCounter(
		slider,
		$footer.find('.js-slider-testimonials__counter-current'),
		'',
		$footer.find('.js-slider-testimonials__counter-total'),
		'',
		counterZeros
	);
	setSliderTestimonialsTransitions(slider, 'vertical', 20, $text, $author, $line);

}

/*!========================================================================
	71. Slider Projects
	======================================================================!*/
var SliderProjects = function ($scope) {

	var $slider = $scope.find('.js-slider-projects');

	if (!$slider.length) {
		return;
	}

	$slider.each(function () {

		var
			$current = $(this),
			$parent = $current.parent(),
			counterZeros = $current.data('counter-zeros'),
			lg = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.lg - 1 : 1024,
			md = window.elementorFrontend ? window.elementorFrontend.config.breakpoints.md - 1 : 767;

		var slider = new Swiper($current.get(0), {
			autoHeight: $current.data('auto-height') || true,
			speed: $current.data('speed') || 1200,
			preloadImages: false,
			lazy: {
				loadPrevNext: true,
				loadOnTransitionStart: true
			},
			touchRatio: $current.data('touch-ratio') || 3,
			observer: true,
			watchSlidesProgress: true,
			watchSlidesVisibility: true,
			centeredSlides: $current.data('centered-slides') || false,
			slidesPerView: $current.data('slides-per-view') || 4,
			slidesPerGroup: 1, // compatibility with Swiper 5.x
			autoplay: {
				disableOnInteraction: false,
				enabled: $current.data('autoplay-enabled') || false,
				delay: $current.data('autoplay-delay') || 6000,
			},
			spaceBetween: $current.data('space-between') || 0,
			pagination: {
				el: $parent.find('.js-slider-projects__dots').get(0),
				type: 'bullets',
				bulletElement: 'div',
				clickable: true,
				bulletClass: 'slider__dot',
				bulletActiveClass: 'slider__dot_active'
			},
			navigation: {
				nextEl: $parent.find('.js-slider-projects__next').get(0),
				prevEl: $parent.find('.js-slider-projects__prev').get(0),
			},
			breakpointsInverse: true // compatibility with both Swiper 4.x and 5.x
		});

		slider.params.breakpoints = {
			0: {
				slidesPerView: $current.data('slides-per-view-mobile'),
				spaceBetween: $current.data('space-between-mobile'),
				centeredSlides: $current.data('centered-slides-mobile'),
				lazy: {
					loadPrevNext: true,
					loadPrevNextAmount: Math.round($current.data('slides-per-view-mobile')) || 3,
					loadOnTransitionStart: true
				}
			},
			[md]: {
				slidesPerView: $current.data('slides-per-view-tablet'),
				spaceBetween: $current.data('space-between-tablet'),
				centeredSlides: $current.data('centered-slides-tablet'),
				lazy: {
					loadPrevNext: true,
					loadPrevNextAmount: Math.round($current.data('slides-per-view-tablet')) || 3,
					loadOnTransitionStart: true
				}
			},
			[lg]: {
				centeredSlides: $current.data('centered-slides') || false,
				slidesPerView: $current.data('slides-per-view') || 4,
				spaceBetween: $current.data('space-between') || 0,
				lazy: {
					loadPrevNext: true,
					loadPrevNextAmount: Math.round($current.data('slides-per-view')) || 3,
					loadOnTransitionStart: true
				}
			}
		};

		slider.update();

		// update height after images are loaded
		slider.on('lazyImageReady', function () {
			slider.update();
		});

		// cursor follower position adjustment
		if (typeof window.InteractiveCursor !== 'undefined') {
			slider.on('touchMove', function (swiper, e) {
				if (swiper instanceof Swiper) {
					window.InteractiveCursor.mouseX = e.clientX;
					window.InteractiveCursor.mouseY = e.clientY;
				} else {
					window.InteractiveCursor.mouseX = swiper.clientX;
					window.InteractiveCursor.mouseY = swiper.clientY;
				}
			});
		}

		$current.imagesLoaded().progress({
			background: true
		}, function (e) {
			setTimeout(function () {
				slider.update();
			}, 300);
		});

		renderSliderDots(slider, $parent.find('.js-slider-projects__dots'));
		renderSliderCounter(
			slider,
			$parent.find('.js-slider-projects__counter-current'),
			'',
			$parent.find('.js-slider-projects__counter-total'),
			'',
			counterZeros
		);

	});

}

/*!========================================================================
	72. Animate Chars
	======================================================================!*/
function animateChars($target, duration = 1.2, stagger = 0.3, ease = Power3.easeInOut, from) {

	var
		$chars = $target.find('.split-text__char'),
		tl = new TimelineMax();

	if (!$chars.length || $target.hasClass('js-split-text_cancel-animation')) {
		return tl;
	}

	var textAlign = $target.css('text-align');

	if (!from) {

		switch (textAlign) {
			case 'left':
				from = 'start';
				break;
			case 'center':
				from = 'center';
				break;
			case 'right':
				from = 'end';
				break;
		}

	}

	tl.staggerTo($chars, duration, {
		x: '0px',
		y: '0px',
		xPercent: 0,
		yPercent: 0,
		autoAlpha: 1,
		ease: ease,
		stagger: distributeByPosition({
			amount: stagger,
			from: from
		})
	});

	return tl;

}

/*!========================================================================
	73. Animate Headline
	======================================================================!*/
function animateHeadline($target, duration = 1.2, ease = Power3.easeInOut, origin) {

	var
		tl = new TimelineMax();

	if (!$target.length) {
		return tl;
	}

	var textAlign = $target.css('text-align');

	if (!origin) {

		switch (textAlign) {
			case 'left':
				origin = 'left center';
				break;
			case 'center':
				origin = 'center center';
				break;
			case 'right':
				origin = 'right center';
				break;
		}

	}

	tl.to($target, duration, {
		scaleX: 1,
		scaleY: 1,
		transformOrigin: origin,
		ease: ease
	});

	return tl;

}

/*!========================================================================
	74. Animate Lines
	======================================================================!*/
function animateLines($target, duration = 1.2, stagger = 0.02, ease = Power3.easeOut, reverse) {

	var
		tl = new TimelineMax(),
		$lines = $target.find('.split-text__line');
	
	if (!$lines.length || $target.hasClass('js-split-text_cancel-animation')) {
		return tl;
	}

	if (reverse) {
		$lines = $lines.get().reverse();
	}

	tl
		.staggerTo($lines, duration, {
			y: '0px',
			yPercent: 0,
			ease: ease,
			autoAlpha: 1,
		}, stagger);

	return tl;

}

/*!========================================================================
	75. Distribute By Position
	======================================================================!*/
/*
pass in an object with any of the following optional properties (just like the stagger special object):
{
  amount: amount (in seconds) that should be distributed
  from: "center" | "end" | "start" | index value (integer)
  ease: any ease, like Power1.easeOut
  axis: "x" | "y" (or omit, and it'll be based on both the x and y positions)
}
*/
function distributeByPosition(vars) {
	var ease = vars.ease,
		from = vars.from || 0,
		base = vars.base || 0,
		axis = vars.axis,
		ratio = {
			center: 0.5,
			end: 1
		} [from] || 0,
		distances;
	return function (i, target, a) {
		var l = a.length,
			originX, originY, x, y, d, j, minX, maxX, minY, maxY, positions;
		if (!distances) {
			distances = [];
			minX = minY = Infinity;
			maxX = maxY = -minX;
			positions = [];
			for (j = 0; j < l; j++) {
				d = a[j].getBoundingClientRect();
				x = (d.left + d.right) / 2; //based on the center of each element
				y = (d.top + d.bottom) / 2;
				if (x < minX) {
					minX = x;
				}
				if (x > maxX) {
					maxX = x;
				}
				if (y < minY) {
					minY = y;
				}
				if (y > maxY) {
					maxY = y;
				}
				positions[j] = {
					x: x,
					y: y
				};
			}
			originX = isNaN(from) ? minX + (maxX - minX) * ratio : positions[from].x || 0;
			originY = isNaN(from) ? minY + (maxY - minY) * ratio : positions[from].y || 0;
			maxX = 0;
			minX = Infinity;
			for (j = 0; j < l; j++) {
				x = positions[j].x - originX;
				y = originY - positions[j].y;
				distances[j] = d = !axis ? Math.sqrt(x * x + y * y) : Math.abs((axis === "y") ? y : x);
				if (d > maxX) {
					maxX = d;
				}
				if (d < minX) {
					minX = d;
				}
			}
			distances.max = maxX - minX;
			distances.min = minX;
			distances.v = l = vars.amount || (vars.each * l) || 0;
			distances.b = (l < 0) ? base - l : base;
		}
		l = (distances[i] - distances.min) / distances.max;
		return distances.b + (ease ? ease.getRatio(l) : l) * distances.v;
	};
}

/*!========================================================================
	76. Do Split Text
	======================================================================!*/
function doSplitText($target = window.$document) {

	return new Promise(function (resolve, reject) {

		var
			$texts = $target.find('.js-split-text'),
			$content,
			type;

		if (!$texts.length) {
			resolve(true);
			return;
		}

		$texts.each(function () {

			var $current = $(this);

			type = $current.data('split-text-type');
			$content = $current;

			if ($current.children(':not(br)').length > 0) {
				$content = $current.find(' > *');
			}

			try {
				new SplitText($content, {
					type: type,
					linesClass: 'split-text__line',
					wordsClass: 'split-text__word',
					charsClass: 'split-text__char',
					reduceWhiteSpace: false,
				});
			} catch (error) {
				console.error(`SplitText error occurred while parsing the following HTML markup: "${this.innerHTML}"`);
			}

			$current.removeClass('js-split-text');

		});

		resolve(true);

	});

}

/*!========================================================================
	77. Hide Chars
	======================================================================!*/
function hideChars($target, duration = 1.2, stagger = 0.3, ease = Power3.easeInOut, x = 0, y = 100, from) {

	var tl = new TimelineMax();

	if (typeof $target == 'undefined' || !$target.length) {
		return tl;
	}

	var
		$chars = $target.find('.split-text__char'),
		textAlign = $target.css('text-align');

	if (!from) {

		switch (textAlign) {
			case 'left':
				from = 'start';
				break;
			case 'center':
				from = 'center';
				break;
			case 'right':
				from = 'end';
				break;
		}

	}

	tl.staggerTo($chars, duration, {
		x: x,
		y: y,
		autoAlpha: 0,
		ease: ease,
		stagger: distributeByPosition({
			amount: stagger,
			from: from
		})
	});

	return tl;

}

/*!========================================================================
	78. Hide Lines
	======================================================================!*/
function hideLines($target, duration = 0.6, stagger = 0.02, offset = '-100%', ease = Power3.easeInOut, reverse) {

	var
		tl = new TimelineMax(),
		$lines = $target.find('.split-text__line');

	if (reverse) {
		$lines = $lines.get().reverse();
	}

	if ($lines.length) {

		tl.staggerTo($lines, duration, {
			y: offset,
			autoAlpha: 0,
			ease: ease
		}, stagger);

	};

	return tl;

}

/*!========================================================================
	79. Hide Words
	======================================================================!*/
function hideWords($target, duration = 0.6, stagger = 0.02, offset = -30, reverse, masterStagger, direction = 'x') {

	var masterTL = new TimelineMax();

	if ($target.length) {

		$target.each(function () {

			var
				tl = new TimelineMax(),
				$chars = $(this).find('.split-chars__char'),
				options = {};

			if (reverse) {
				$chars = $chars.get().reverse();
			}

			if (!masterStagger) {
				masterStagger = '-=' + duration;
			}

			if (direction == 'x') {
				options = {
					x: offset,
					autoAlpha: 0
				};
			} else {
				options = {
					y: offset,
					autoAlpha: 0
				}
			}

			tl.staggerTo($chars, duration, options, stagger);

			masterTL.add(tl, masterStagger);
		});

	};

	return masterTL;

}

/*!========================================================================
	80. Hide Words Vertical
	======================================================================!*/
function hideWordsVertical($target, duration = 0.6, stagger = 0.02, offset = -30, reverse, masterStagger) {

	var masterTL = new TimelineMax();

	if ($target.length) {

		$target.each(function () {

			var
				tl = new TimelineMax(),
				$chars = $(this).find('.split-chars__char');

			if (reverse) {
				$chars = $chars.get().reverse();
			}

			if (!masterStagger) {
				masterStagger = '-=' + duration;
			}

			tl.staggerTo($chars, duration, {
				y: offset,
				autoAlpha: 0
			}, stagger);

			masterTL.add(tl, masterStagger);
		});

	};

	return masterTL;

}

/*!========================================================================
	81. Set Chars
	======================================================================!*/
function setChars($scope = window.$document, x = '50', y = 0, from) {

	return new Promise(function (resolve, reject) {

		var $target = $scope.find('.split-text[data-split-text-set="chars"]');

		if (!$target.length) {
			resolve(true);
			return;
		}

		TweenMax.set($target, {
			clearProps: 'all'
		});

		$target.each(function () {

			var
				$current = $(this),
				$lines = $current.find('.split-text__line'),
				textAlign = $current.css('text-align');

			if (!from) {

				switch (textAlign) {
					case 'left':
						setFromLeft($lines);
						break;
					case 'center':
						setFromCenter($lines);
						break;
					case 'right':
						setFromRight($lines);
						break;
				}

			}

		});

		function setFromLeft($lines) {

			if (!$lines || !$lines.length) {
				return;
			}

			var $chars = $lines.find('.split-text__char');

			TweenMax.set($chars, {
				x: x + 'px',
				y: y + 'px',
				autoAlpha: 0
			});

			resolve(true);

		}

		function setFromCenter($lines) {

			if (!$lines || !$lines.length) {
				return;
			}

			$lines.each(function () {

				var
					$currentLine = $(this),
					$wordsInCurrentLine = $currentLine.find('.split-text__word');

				// only 1 word in the current line
				if ($wordsInCurrentLine.length === 1) {

					var
						$charsInWord = $wordsInCurrentLine.find('.split-text__char'),
						halfWord = Math.ceil($charsInWord.length / 2),
						$fistHalfWord = $charsInWord.slice(0, halfWord),
						$secondHalfWord = $charsInWord.slice(halfWord, $charsInWord.length);

					TweenMax.set($fistHalfWord, {
						x: x * (-1) + 'px',
						y: y * (-1) + 'px',
						autoAlpha: 0
					});

					TweenMax.set($secondHalfWord, {
						x: x + 'px',
						y: y + 'px',
						autoAlpha: 0
					});

				}

				// odd number of words in line
				if ($wordsInCurrentLine.length !== 1 && $wordsInCurrentLine.length % 2 !== 0) {

					var
						halfLine = Math.ceil($wordsInCurrentLine.length / 2),
						$fistHalf = $wordsInCurrentLine.slice(0, halfLine),
						$secondHalf = $wordsInCurrentLine.slice(halfLine, $wordsInCurrentLine.length),
						$middleWord = $wordsInCurrentLine.eq(halfLine - 1),
						$charsInMiddleWord = $middleWord.find('.split-text__char'),
						halfLineMiddleWord = Math.ceil($charsInMiddleWord.length / 2),
						$fistHalfMiddleWord = $charsInMiddleWord.slice(0, halfLineMiddleWord),
						$secondHalfMiddleWord = $charsInMiddleWord.slice(halfLineMiddleWord, $charsInMiddleWord.length);

					// first half
					$fistHalf.each(function () {

						var $charsInWord = $(this).find('.split-text__char');

						TweenMax.set($charsInWord, {
							x: x * (-1) + 'px',
							y: y * (-1) + 'px',
							autoAlpha: 0
						});

					});

					// second half
					$secondHalf.each(function () {

						var $charsInWord = $(this).find('.split-text__char');

						TweenMax.set($charsInWord, {
							x: x + 'px',
							y: y + 'px',
							autoAlpha: 0
						});

					});

					// middle word first half
					$fistHalfMiddleWord.each(function () {

						var $charsInWord = $(this);
						TweenMax.set($charsInWord, {
							x: x * (-1) + 'px',
							y: y * (-1) + 'px',
							autoAlpha: 0
						});

					});

					// middle word second half
					$secondHalfMiddleWord.each(function () {

						var $charsInWord = $(this);
						TweenMax.set($charsInWord, {
							x: x + 'px',
							y: y + 'px',
							autoAlpha: 0
						});

					});

				}

				// even number of words in line
				if ($wordsInCurrentLine.length !== 1 && $wordsInCurrentLine.length % 2 === 0) {

					var
						halfLine = Math.ceil($wordsInCurrentLine.length / 2),
						$fistHalf = $wordsInCurrentLine.slice(0, halfLine),
						$secondHalf = $wordsInCurrentLine.slice(halfLine, $wordsInCurrentLine.length);

					// first half
					$fistHalf.each(function () {

						var $charsInWord = $(this).find('.split-text__char');

						TweenMax.set($charsInWord, {
							x: x * (-1) + 'px',
							y: y * (-1) + 'px',
							autoAlpha: 0
						});

					});

					// second half
					$secondHalf.each(function () {

						var $charsInWord = $(this).find('.split-text__char');

						TweenMax.set($charsInWord, {
							x: x + 'px',
							y: y + 'px',
							autoAlpha: 0
						});

					});

				}

			});

			resolve(true);

		}

		function setFromRight($lines) {

			if (!$lines || !$lines.length) {
				return;
			}

			var $chars = $lines.find('.split-text__char');

			TweenMax.set($chars, {
				x: x * (-1) + 'px',
				y: y * (-1) + 'px',
				autoAlpha: 0
			});

			resolve(true);

		}

	});

}

/*!========================================================================
	82. Set Lines
	======================================================================!*/
function setLines($target = window.$document, offset = '100%') {

	return new Promise(function (resolve, reject) {

		var
			tl = new TimelineMax(),
			$lines = $target.find('.split-text[data-split-text-set="lines"] .split-text__line');

		if (!$lines.length) {
			resolve(true);
			return;
		}

		tl
			.set($lines, {
				y: offset,
				autoAlpha: 0
			})
			.add(function () {
				resolve(true);
			});

	});

}

/*!========================================================================
	83. Debounce
	======================================================================!*/
function debounce(func, wait, immediate) {

	var timeout;

	return function () {

		var
			context = this,
			args = arguments;

		var later = function () {

			timeout = null;

			if (!immediate) {
				func.apply(context, args)
			};

		};

		var callNow = immediate && !timeout;

		clearTimeout(timeout);

		timeout = setTimeout(later, wait);

		if (callNow) {
			func.apply(context, args)
		};

	};

};

/*!========================================================================
	84. Fix Mobile Bar Height
	======================================================================!*/
function fixMobileBarHeight() {

	var vh;

	/**
	 * Initial set
	 */
	createStyleElement();
	setVh();

	if (window.theme.mobileBarFix.update) {
		/**
		 * Resize handling (with debounce)
		 */
		$(window).on('resize', debounce(function () {
			setVh();
		}, 250));
	}

	/**
	 * 100vh elements height correction
	 */
	function setVh() {

		vh = document.documentElement.clientHeight * 0.01;

		$('#cassio-fix-bar').html(':root { --fix-bar-vh: ' + vh + 'px; }\n');

	}

	function createStyleElement() {

		if (!$('#cassio-fix-bar').length) {
			$('head').append('<style id=\"cassio-fix-bar\"></style>');
		}

	}

}

/*!========================================================================
	85. Fix Scroll Bar
	======================================================================!*/
function fixScrollBar() {

	var
		fixClass = 'body_has-scrollbar';

	/**
	 * Initial set
	 */
	createStyleElement();
	calculateScrollbar();

	/**
	 * Resize handling (with debounce)
	 */
	$window.on('resize', debounce(function () {
		calculateScrollbar();
	}, 250));

	/**
	 * Prevent page from jumping during scroll lock/unlock
	 */
	function calculateScrollbar() {

		if (window.innerWidth > window.$body[0].clientWidth + 5) {
			window.$body.addClass(fixClass);
			$('#cassio-fix-scroll').html(':root { --fix-scroll-bar-px: ' + (window.innerWidth - window.$body[0].clientWidth) + 'px; }');
		} else {
			window.$body.removeClass(fixClass);
		}


	}

	function createStyleElement() {

		if (!$('#cassio-fix-scroll').length) {
			$('head').append('<style id=\"cassio-fix-scroll\"></style>');
		}

	}

}

/*!========================================================================
	86. Is Anchor
	======================================================================!*/
function checkIsAnchor($el) {

	var link = $el.attr('href');

	if ($el.length && link.length && link !== '#') {

		return true;

	}

	return false;

}

/*!========================================================================
	87. Load Swiper
	======================================================================!*/
function loadSwiper() {
	return new Promise((resolve) => {
		let loaded = false;

		if (typeof window.Swiper === 'undefined' && !loaded) {
			elementorFrontend.on('components:init', () => {
				if (!loaded) {
					elementorFrontend.utils.assetsLoader.load('script', 'swiper').then((instance) => {
						loaded = true;
						resolve(true);
					});
				}
			});
		} else {
			resolve(true);
		}
	});
}

/*!========================================================================
	88. Run On High Performance GPU
	======================================================================!*/
function runOnHighPerformanceGPU() {
	const
		$webGLCanvas = $('#js-webgl'),
		$otherCanvas = $('canvas:not(#js-webgl)');

	if (!$otherCanvas.length && !window.Modernizr.touchevents && $webGLCanvas.length) {
		$webGLCanvas[0].getContext('webgl', {
			powerPreference: 'high-performance'
		});
	}

}

/*!========================================================================
	89. Sanitize Selector
	======================================================================!*/
function sanitizeSelector(string) {
	if (!string || !string.length) {
		return false;
	}

	return string
		.replace(/(\r\n|\n|\r)/gm, '') // remove tabs, spaces
		.replace(/(\\n)/g, '') // remove lines breaks
		.replace(/^[,\s]+|[,\s]+$/g, '') // remove redundant commas
		.replace(/\s*,\s*/g, ','); // remove duplicated commas
}

/*!========================================================================
	90. Sync Attributes
	======================================================================!*/
function syncAttributes($sourceElement, $targetElement) {

	// single element
	if ($sourceElement.length === 1 && $targetElement.length === 1) {
		const
			targetEl = $targetElement.get(0),
			targetAttributes = $targetElement.getAllAttributes(),
			sourceAttributes = $sourceElement.getAllAttributes();

		// source element doesn't have any attributes present
		if ($.isEmptyObject(sourceAttributes)) {
			// ... so remove all attributes from the target element
			[...targetEl.attributes].forEach(attr => targetEl.removeAttribute(attr.name));
		} else {
			Object.keys(targetAttributes).forEach((key) => {
				// delete key on target that doesn't exist in source element
				if (key !== 'style' && !(key in sourceAttributes)) {
					$targetElement.removeAttr(key);
				}
			});

			// sync attributes
			$targetElement.attr(sourceAttributes);
		}

	// multiple elements
	} else if ($sourceElement.length > 1 && $targetElement.length > 1 && $sourceElement.length === $targetElement.length) {

		$.each($targetElement, function (index) {
			const
				$current = $(this),
				sourceAttributes = $sourceElement.eq(index).getAllAttributes();

			// source element doesn't have any attributes present
			if ($.isEmptyObject(sourceAttributes)) {
				// ... so remove all attributes from the target element
				[...this.attributes].forEach(attr => this.removeAttribute(attr.name));
			} else {

				// sync attributes
				$current.attr(sourceAttributes);
			}
		});

	}

}

/*!========================================================================
	91. Elementor
	======================================================================!*/
/**
 * Elementor Preview
 */
window.$window.on('elementor/frontend/init', function () {

	if (typeof elementor !== 'undefined') {

		elementorFrontend.hooks.addAction('frontend/element_ready/global', function ($scope) {
			loadSwiper().then(() => {
				doSplitText($scope);
				setLines();
				setChars();
				window.PagePreloader.finish();
				window.$body.removeClass('cursor-progress');
				new SectionMasthead(window.$document);
				initComponents($scope);
				window.SMController.update(true);
				window.SMController.enabled(true);
			});
		});

	}

});


})(jQuery);
