PageSourceSearch

https://www.kommunicate.io/blog/wp-content/themes/cheerup/js/theme.js?ver=7.7.0

js kommunicate.io collected 2026-09-24 15:20:05 UTC 56,530 bytes, 2,436 lines download raw bytes

1/**
2 * CheerUp Theme Frontend JS.
3 * 
4 * Copyright (c) 2021 ThemeSphere.
5 */
6var Bunyad_Tests = (function() {
7	"use strict";
8
9	var _supportsFn  = (window.CSS && window.CSS.supports && window.CSS.supports.bind(window.CSS)) || (window.supportsCSS);
10	var _agent = window.navigator.userAgent;
11	return {
12		vars: !!_supportsFn && (_supportsFn('--f:0') || _supportsFn('--f', 0)),
13		ie: /MSIE|Trident/.test(_agent),
14		srcset: 'srcset' in document.createElement('img')
15	};
16})();
17
18var Bunyad_Theme = (function($) {
19	"use strict";
20	
21	var has_touch  = false,
22	    mega_menus_init = false,
23		responsive_menu = false,
24		search_active = false,
25		sticky_bar_active = false;
26	
27	// module
28	var self = {
29		has_sticky_nav: false,
30
31		init: function() 
32		{	
33			// Don't take over pinterest buttons.
34			$('.tsi-pinterest, .tsi-pinterest-p').attr('data-pin-custom', '1');
35
36			/**
37			 * Woocommerce
38			 */ 
39			$('.woocommerce-ordering .drop li a').on('click', function(e) {
40				var form = $(this).closest('form');
41				
42				form.find('[name=orderby]').val($(this).parent().data('value'));
43				form.submit();
44				
45				e.preventDefault();
46			});	
47			
48			$('.woocommerce .related > h2, .woocommerce .upsells > h2')
49				.addClass('block-head-legacy').wrapInner('<span class="title" />');
50			
51			
52			// Fit videos to container
53			$('.featured-vid, .post-content').fitVids();
54			
55			// Back to top handler
56			$('.back-to-top').on('click', function() {
57				
58				// Using both html, body until scrollingElement has more support
59				$('html, body').animate({scrollTop: 0}, 800);
60				return false;
61			});
62			
63			// Go back handler
64			$('.go-back').on('click', function() { 
65				window.history.back();
66				return false;
67			});
68			
69			// Post ticker
70			$('.posts-ticker ul').each(function() {
71				
72				if (!$(this).find('li.active').length) {
73					$(this).find('li:first').addClass('active');
74				}
75				
76				var ticker = $(this);
77				
78				window.setInterval(function() {
79					
80					var active = ticker.find('li.active');
81					active.fadeOut(function() {
82						
83						var next = active.next();
84						if (!next.length) {
85							next = ticker.find('li:first');
86						}
87						
88						next.addClass('active').fadeIn();
89						active.removeClass('active');
90					});
91					
92				}, 8000);
93			});
94			
95			if (navigator.platform.toLowerCase().indexOf('win') !== -1) {
96				$('html').addClass('is-win');
97			}
98			
99			// Fix Firefox Bug #1149357
100			if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
101				
102				var logo = $('.logo-image');
103				if ($('.logo-image').length) {
104					
105					// order maters - attach event first
106					$('<img />').on('load', function() {
107						
108						// picked 2x logo? set 1x dimension to prevent firefox overflowing
109						if (logo.prop('currentSrc') !== logo.prop('src')) {
110							logo.prop('width', $(this)[0].naturalWidth).prop('height', $(this)[0].naturalHeight);
111						}
112						
113					}).attr('src', logo.attr('src'));
114				}
115			}
116			
117			/**
118			 * Header Parallax - for style 7
119			 */
120			var header = $('.main-head.top-below .inner'),
121				bg = header.css('background-image');
122			
123			if ($(window).width() > 940 && (bg && bg != 'none')) {
124				var parallax = $('<div class="parallax" />').css('background-image', bg);
125				header.append(parallax);
126				header.css('background-image', 'none');
127				
128				var bottom = parallax.offset().top + parallax.outerHeight(),
129					top = parallax.offset().top;
130				
131				$(window).on('scroll', function() {
132					
133					var scroll = $(window).scrollTop();
134					
135					// Already scrolled enough
136					if (scroll > bottom) {
137						return;
138					}
139					
140					var distance = scroll * 0.4;
141					
142					requestAnimationFrame(function() {
143						parallax.css('transform', 'translate3d(0,' + distance + 'px, 0)');
144					});
145				});
146			}
147			
148			// VC Blocks fix
149			// $('.blocks .block, .blocks .wpb_content_element').last().addClass('last-block');
150
151			// Twitter widget.js take-over fix.
152			$('.service.twitter, .post-share .twitter, .social-share .tsi-twitter').on('click', function(e) {
153				e.stopPropagation();
154			});
155
156			// Masonry layouts setup
157			this.masonry();
158			
159			// Lazyload setup
160			this.lazy_load();
161
162			// Setup search
163			this.search();
164			
165			// Setup all sliders
166			this.sliders();
167
168			// Setup mobile & touch navigation
169			this.responsive_nav();
170			
171			// Setup mega menus
172			this.mega_menus();
173			
174			// Setup sticky top-bar
175			this.sticky_bar();
176			
177			// Sticky sidebar
178			this.sticky_sidebar();
179						
180			// Lightbox for images
181			this.lightbox();
182			
183			// Likes system
184			this.likes();
185			
186			// Single post functionality
187			this.single();
188	
189			// Pin buttons
190			this.pin_it();
191		},
192
193		/**
194		 * Setup responsive and touch
195		 */
196		responsive_nav: function()
197		{
198			// detect touch capability dynamically
199			$(window).on('touchstart', function() {
200				has_touch = true;
201				$('body').addClass('touch');
202			});
203			
204			this.init_responsive_nav();
205			this.touch_nav();
206			var that = this;
207
208			$(window).on('resize orientationchange', function() {
209				that.init_responsive_nav();
210			});
211		},
212		
213		/**
214		 * Setup the responsive nav events and markup
215		 */
216		init_responsive_nav: function() {
217			
218			if ($(window).width() > 940 || responsive_menu) {
219				return;
220			}
221			
222			// Set responsive initialized
223			responsive_menu = true;
224			
225			// Create off-canvas container
226			var menu_contain = $('.mobile-menu-container');
227			
228			// No items for mobile menu? Grab from others
229			if (!menu_contain.find('.mobile-menu').children().length) {
230				
231				// Merge existing menus
232				var mobile_menu = menu_contain.find('.mobile-menu'),
233				    main_menu = $('.navigation .menu');
234				
235				var menu = main_menu.children().clone();
236				
237				if (!main_menu.length) {
238					return;
239				}
240				
241				// add category mega menu links
242				menu.find('.mega-menu .sub-cats').each(function() {
243					var container = $(this).closest('.menu-item');
244					
245					container.append($(this).find('.sub-nav'));
246					container.find('.sub-nav').replaceWith(function() {
247						return $('<ul />', {html: $(this).html()});
248					});
249					
250					$(this).remove();
251					
252				});
253				
254				mobile_menu.append(menu);
255			}
256			
257			$('body').addClass('nav-off-canvas');
258			
259			// Setup mobile menu click handlers
260			$('.mobile-menu li > a').each(function() {
261				
262				if ($(this).parent().children('ul').length) {
263					$('<span class="chevron"><i class="tsi tsi-chevron-down"></i></span>').appendTo($(this));
264				}
265			});
266			
267			$('.mobile-menu li .chevron').click(function() {
268					$(this).closest('li').find('ul').first().parent().toggleClass('active item-active');
269					return false;
270			});
271			
272			// Menu open handler
273			$('.top-bar .mobile-nav, .main-head .mobile-nav').on('click', function() {
274				$('.mobile-menu').addClass('active');
275            	$('body').toggleClass('off-canvas-active');
276            	$('html').toggleClass('hide-scroll');
277			});
278			
279			// Off-canvas close
280			$('.off-canvas .close').click(function() {
281				$('body').toggleClass('off-canvas-active');
282			});
283		},
284
285		/**
286		 * Setup touch for touch devices
287		 */
288		touch_nav: function() {
289			
290			var targets = $('.menu:not(.mobile-menu) a'),
291				open_class = 'item-active',
292				child_tag = 'ul, .mega-menu';
293			
294			targets.each(function() {
295				
296				var $this = $(this),
297					$parent = $this.parent('li'),
298					$siblings = $parent.siblings().find('a');
299				
300				$this.click(function(e) {
301					
302					if (!has_touch) {
303						return;
304					}
305					
306					var $this = $(this);
307					e.stopPropagation();
308					
309					$siblings.parent('li').removeClass(open_class);
310					
311					// has a child? open the menu on tap
312					if (!$this.parent().hasClass(open_class) && $this.next(child_tag).length > 0 && !$this.parents('.mega-menu.links').length) {
313						e.preventDefault();
314						$this.parent().addClass(open_class);
315					}
316				});
317			});
318			
319			// close all menus
320			$(document).click(function(e) {
321				if (!$(e.target).is('.menu') && !$(e.target).parents('.menu').length) {
322					targets.parent('li').removeClass(open_class);
323				}
324			});
325		},
326		
327		/**
328		 * Search setup
329		 */
330		search: function() 
331		{
332			// Nav search overlay
333			$('.main-head.has-search-overlay .search-link').on('click', function() {
334				
335				var overlay = $(this).parent().find('.search-box-overlay');
336				
337				search_active = true;
338				if (overlay.hasClass('active')) {
339					search_active = false;
340				}
341				
342				overlay.toggleClass('active');
343				
344				return false;
345			});
346			
347			// Search bar for alt header
348			var search_active_alt = false;
349			$('.search-alt .top-bar .search-submit').on('click', function() {
350				if (!search_active_alt) {
351					$(this).closest('form').find('.search-field').addClass('active').focus();
352					search_active_alt = true;
353					
354					return false;
355				} 
356			});
357			
358			// Hide search on outside clicks
359			$(document).on('click', function(e) {
360				if (search_active && !$(e.target).parents('.search-box-overlay').length) {
361					$('.main-head.has-search-overlay .search-link').click();
362				}
363				
364				// Hide alt header search
365				if (search_active_alt && !$(e.target).parents('.top-bar').length) {
366					search_active_alt = false;
367					
368					$('.main-head.search-alt .search-submit')
369						.closest('form').find('.search-field').removeClass('active');
370				}
371			});
372
373			// Search modal
374			$('.main-head.has-search-modal .search-link').magnificPopup({
375				items: {
376					src: '.search-modal-wrap',
377					type: 'inline'
378				},
379				removalDelay: 400,
380				focus: 'input',
381				closeBtnInside: false,
382				closeOnBgClick: false,
383				mainClass: 'search-modal',
384				midClick: true,
385				fixedContentPos: true,
386				autoFocusLast: false
387			}); 
388		},
389		
390		/**
391		 * Mega Menus
392		 */
393		mega_menus: function()
394		{
395			this.init_mega_menus();
396
397			$(window).on('resize orientationchange', function() {
398				self.init_mega_menus();
399			});
400		},
401
402		init_mega_menus: function()
403		{
404			if ($(window).width() < 940 || mega_menus_init) {
405				return;
406			}
407
408			mega_menus_init = true;
409
410			// Bind events for mega menus
411			$('.navigation .mega-menu').each(function() {
412				
413				var menu = $(this),
414				    number = 4;
415				
416				if (menu.find('.one-fifth').length) {
417					number = 5;
418				}
419				
420				var slick_vars = {
421					draggable: false,
422					infinite: true,
423					slidesToShow: number,
424					slidesToScroll: number,
425					arrows: false
426				};
427				
428				// Helper to re-init
429				var slick_init = function(posts) {
430					if (!posts.hasClass('slick-initialized')) {
431						posts.slick(slick_vars);
432					}
433					// Race condition? Might have calculated while hiding - recalc pos
434					else if (posts.find('.slick-track').width() == 0) {
435						posts.slick('setPosition');
436					}
437				};
438				
439				// Init mega menus
440				var default_mega_menu = function f() {
441					slick_init( menu.find('.posts').last().addClass('active') );
442					return f;
443				}();
444
445				// Mega-menu sub-cats handling
446				menu.find('.menu-item').on('mouseenter', function() {
447
448					var id = parseInt( $(this).attr('class').match(/menu-cat-(\d+)/)[1] || 0 ),
449					    menu = $(this).parents('.mega-menu'),
450					    view_all = $(this).hasClass('view-all');
451				
452					if (!view_all && !id) {
453						return;
454					}
455					
456					// remove other actives
457					menu.find('.active, .current-menu-item').removeClass('active current-menu-item');
458
459					// activate current
460					$(this).addClass('current-menu-item');
461					var posts = menu.find('[data-id=' + id + ']').addClass('active');
462				
463					slick_init(posts);
464					
465					if (posts.find('.post').length < 5) {
466						posts.parent().find('.navigate').hide();
467					}
468					else {
469						posts.parent().find('.navigate').show();
470					}
471					
472					return false;
473				});
474				
475				// Reset mega menu state on fresh hover
476				menu.parent().on('mouseenter', function() {
477					
478					var menu = $(this).find('.mega-menu');
479					
480					// reset at beginning
481					menu.find('.active, .current-menu-item')
482						.removeClass('active current-menu-item');
483
484					$(this)[0].offsetWidth; // reflow
485					default_mega_menu();
486				});
487				
488			});
489			
490			// Mega menu pagination
491			$('.mega-menu .show-next, .mega-menu .show-prev').on('click', function() {
492				
493				var current = $(this).parents('.mega-menu').find('.posts.active'),
494				    action  = $(this).hasClass('show-prev') ? 'slickPrev' : 'slickNext';
495				
496				current.slick(action);
497				
498				return false;
499			});	
500		},
501
502		/**
503		 * Setup sticky bar if enabled
504		 */
505		sticky_bar: function()
506		{
507			var nav,
508			    top_bar = $('.top-bar-content'),
509			    is_smart = false,
510			    is_sticky = false,
511			    is_static = false,
512			    prev_scroll = 0,
513			    cur_scroll = 0,
514			    extra_top = 0,
515			    nav_top,
516			    hide_at,
517				head = $('.main-head'),
518				head_height;
519			
520
521			// Set height for container
522			var calc_head_size = writeRaf(function() {
523
524				// Don't reset if it's stuck
525				if (sticky_bar_active) {
526					return;
527				}
528
529				var new_height = head.css('min-height', 0).height();
530				head.css('min-height', new_height);
531				head_height = new_height;
532			});
533
534			var set_size = function(skip_calc) {
535
536				// Skip calculation if asked to and head height has been prev set
537				if (skip_calc && head_height) {
538					return;
539				}
540
541				calc_head_size();
542			};
543			
544			$(window).on('load resize', calc_head_size);
545			
546			var init = function() {
547				
548				// Reset vars - might be a re-init
549				is_static = false;
550
551				// Is smart?
552				var check_smart = function() {
553
554					// Enable smart at responsive
555					if ($(window).width() < 940) {
556						is_smart = true;
557					}
558					else {
559						is_smart = false;
560					}
561
562					if (nav && nav.data('sticky-bar') == 'smart') {
563						is_smart = true;
564					}
565				};
566				
567				if ($('.admin-bar').length) {
568					extra_top = $('#wpadminbar').height();
569				}
570				
571				// Target sticky based on header layout
572				if (head.is('.nav-below, .top-below')) {
573					
574					// Top bar below or nav-below-logo types
575					nav = head.hasClass('nav-below') ? $('.navigation.below') : top_bar;
576					
577					if (nav.length) {
578						nav_top = nav.offset().top - extra_top;
579						hide_at = nav_top + 1;
580					}
581				}
582				// Compact has a sticky topbar configured below
583				else if (head.is('.simple') || (head.is('.compact') && $(window).width() >= 940)) {
584					
585					// Top bar below or nav below logo types
586					nav = head.find('.inner').first();
587					check_smart();
588					
589					nav_top = head.offset().top + (head.height()/2) - extra_top;
590					hide_at = nav_top + 200;
591
592					if (is_smart) {
593
594						// For performance
595						var parallax = $('.single-creative .featured');
596						if (parallax.length) {
597							hide_at  = nav_top;
598							nav_top += parallax.height();
599						}
600					}
601
602				}
603				else if (top_bar.length) {
604				
605					nav = top_bar;
606					check_smart();
607
608					// static sticky via CSS unless it's smart sticky
609					if (!is_smart && top_bar.data('sticky-bar')) {
610						top_bar.addClass('sticky-bar');
611						is_static = true;
612					}
613					
614					// default 
615					var pos_ele  = $('.top-bar');
616					
617					nav_top  = pos_ele.offset().top - extra_top,
618					hide_at  = nav_top + 1;
619				}
620
621				check_smart();
622
623				// Android fix on addr bar hide
624				if (is_smart && !sticky_bar_active) {
625					prev_scroll = 0;
626				}
627			};
628			
629			// Init and calculate defaults
630			init();
631			
632			if (!nav) {
633				return;
634			}
635			
636			// not enabled?
637			if (!nav.data('sticky-bar')) {
638				return;
639			}
640		
641			self.has_sticky_nav = true;
642			
643			if (nav.find('.sticky-logo').length) {
644				nav.addClass('has-logo');
645			}
646			
647			// disable the sticky nav
648			var remove_sticky = function() {
649				
650				// check before dom modification 
651				if (is_sticky) {
652					
653					sticky_bar_active = 0;
654					nav.removeClass('sticky-bar');
655					set_size(true);
656					
657					$(document).trigger('sticky-bar-hide');
658				}
659			};
660			
661			// Check and apply sticky - separated writes
662			var sticky_writes = writeRaf(function() {
663				
664				// make it sticky when viewport is scrolled beyond the navigation
665				if (cur_scroll > nav_top) {
666					
667					// for smart sticky, test for scroll change
668					if (is_smart && (!prev_scroll || cur_scroll > prev_scroll)) {
669						remove_sticky();
670					}
671					else {
672						sticky_bar_active = 1;
673						
674						if (!is_smart || cur_scroll < prev_scroll-4) {
675
676							if (!nav.hasClass('sticky-bar')) {
677								nav.addClass('sticky-bar no-transition');
678							
679								setTimeout(function() { 
680									nav.removeClass('no-transition'); 
681								}, 100);
682								
683								$(document).trigger('sticky-bar-show');
684							}
685						}
686					}
687					
688					prev_scroll = cur_scroll;
689					
690				} else {
691					
692					// hide at a certain point
693					if (cur_scroll <= hide_at) {
694						prev_scroll = 0;
695						remove_sticky();
696					}
697				}
698			});
699			
700			// Make the nav sticky
701			var sticky = function() {
702
703				if (!nav.data('sticky-bar') || is_static) {
704					return;
705				}
706
707				cur_scroll = $(window).scrollTop();
708				is_sticky  = nav.hasClass('sticky-bar');
709				
710				sticky_writes();
711			};
712
713			sticky();
714
715			$(window).on('scroll', function() {
716				sticky();
717			});
718			
719			// Re-initialize on resize
720			$(window).on('resize orientationchange', function() {
721				init();
722				sticky();
723			});
724		},
725		
726		/**
727		 * Setup sticky sidebar
728		 */
729		sticky_sidebar: function() 
730		{
731			
732			// Sidebar class on the widget element? Move it up
733			$('.main .sidebar').each(function() {
734				if ($(this).hasClass('wpb_content_element')) {
735					var parent = $(this).closest('.wpb_column'),
736						classes = 'sidebar';
737					
738					if ($(this).hasClass('sticky-col')) {
739						classes += ' sticky-col';
740					}
741					
742					parent.addClass(classes);
743					$(this).removeClass(classes);
744				}
745			});
746			
747			var sticky = $('.main .sticky-col, .main .sidebar[data-sticky=1]');
748			
749			if (!sticky.length) {
750				return;
751			}
752			
753			var add = 20;
754			if ($('.admin-bar').length) {
755				add += 32;
756			}
757			
758			if (self.has_sticky_nav) {
759				add += 50;
760			}
761			
762			sticky.each(function() {
763			
764				var parent_col = $(this);
765				
766				// Add wrapper class if missing
767				if (!parent_col.find('.theiaStickySidebar').length) {
768					parent_col.find('.wpb_wrapper').first().addClass('theiaStickySidebar');
769				}
770				
771				parent_col.theiaStickySidebar({
772					minWidth: 940, 
773					updateSidebarHeight: false,
774					additionalMarginTop: add
775				});
776			});
777			
778			// for iframe loads in sidebar
779			$(window).on('load', function() {
780				setTimeout(function() {
781					$(window).trigger('resize.TSS');
782				}, 2500);
783			});
784		},
785		
786		/**
787		 * Single post functionality
788		 */
789		single: function()
790		{
791			if (!$('body').hasClass('single-post')) {
792				return;
793			}
794
795			/**
796			 * Social sharing
797			 */
798			// Single top social sharing view all buttons
799			$('.post-share-b .show-more').on('click', function() {
800				$(this).parent().addClass('all');
801				return false;
802			});
803
804			// Setup floating share
805			Bunyad_Share_Float.init();
806			
807			// Paralax for creative
808			var creative = $('.single-creative .featured');
809			if (creative.length && creative.data('parallax')) {
810
811				if ($(window).width() < 940) {
812					creative.removeClass('parallax');
813					return;
814				}
815				
816				creative.addClass('parallax');
817				self._parallax.call(creative);
818			}
819
820			$(window).on('resize', this.post_navigation);
821			this.post_navigation();
822			
823		},
824		
825		/**
826		 * Post Naviation
827		 */
828		post_navigation: function() 
829		{
830			var initialized = false,
831			    post_nav = $('.post-nav');
832			
833			if (!post_nav.length || $(window).width() < 1300) {
834				post_nav.removeClass('post-nav-float').addClass('post-nav-inline');
835				return;
836			}
837			
838			// Already setup or shouldn't be init?
839			if (initialized) {
840				return;
841			}
842			
843			initialized = true;
844			post_nav.addClass('post-nav-float');
845			post_nav = post_nav.find('.post');
846
847			if ($('.has-share-float').length) {
848				post_nav.addClass('ss-overlap');
849			}
850			
851			// Show when post-content is in viewport and hide when footer 
852			// becomes visible in view. 
853			var ele = $('.the-post .post-content'), 
854				scroll, offset, win_height, show_at, hide_at;
855				
856			var calc = function() {
857			    offset     = ele.offset();
858				win_height = $(window).height();
859
860			    show_at = offset.top + (win_height / 2) + 56;
861			    hide_at = $('.main-footer').offset().top + (win_height / 3);
862			};
863
864			calc();
865			self._wait_load(calc, {'ready': true});
866
867			// Lazyload fires this
868			$(window).on('resize.TSS', calc);
869			
870			// Show at certain scroll
871			$(window).on('scroll', function() {
872				
873				if ($(window).width() < 940) {
874					return;
875				}
876				
877				// Add viewport height to scrollTop
878				scroll = $(window).scrollTop() + win_height;
879				
880				requestAnimationFrame(function() {
881					if (scroll > show_at && scroll < hide_at) {
882						
883						if (!post_nav.hasClass('active')) {
884							post_nav.addClass('active');
885						}
886					}
887					else {
888						post_nav.removeClass('active');
889					}
890				});
891			});
892		},
893		
894		/**
895		 * Util to wait for until async CSS has been applied - waits for async font load
896		 * too by default.
897		 */
898		_wait_load: function(cb, options) {
899
900			options = $.extend({
901				'fonts': true,
902				'ready': false
903			}, options);
904
905			var sel = options.fonts ? '.wf-loading, .ld' : '.ld';
906
907			if ($('html').is(sel) || (options.ready && document.readyState !== 'complete')) {
908				setTimeout(
909					self._wait_load.bind(null, cb, options), 
910					30
911				);
912			}
913			else {
914				cb();
915			}
916		},
917
918		_parallax: function(opts) {
919
920			var container = $(this).find('.wp-post-image');
921			var options   = {
922				speed: 0.4,
923				noIos: false
924			};
925
926			$.extend(options, opts);
927			
928			var render = function() {
929				var target = container;
930
931				// img tag instead of bg image.
932				if (container.is('img')) {
933
934					var img = container,
935						src = img.prop('src');
936					
937					if (img.prop('currentSrc')) {
938						src = img.prop('currentSrc');
939					}
940
941					options.imgSrc = src;
942					target = container.parent().parent();
943				}
944
945				target.jarallax(options);
946			};
947
948			// Class can be lazyload, lazyloading or lazyloaded.
949			if (container.is('img') && !container.is('[class*=lazyload]')) {
950				render();
951			}
952			
953			container.on('lazyloaded', render);
954		},
955		
956		/**
957		 * Setup sliders and carousels
958		 */
959		sliders: function()
960		{
961			/**
962			 * Parallax extend 
963			 */
964			if (window.jarallax) {
965				var Jarallax = window.jarallax.constructor;
966				var orig = Jarallax.prototype.onScroll;
967				Jarallax.prototype.onScroll = function(force) {
968					
969					if (!force) {
970						var ele = $(this.options.elementInViewport);
971						if (ele && ele.data('active-only') && !ele.is('.slick-active, .active')) {
972							return;
973						}
974					}
975					
976					orig.apply(this, arguments);
977				};
978			}
979			
980			// Enable parallax
981			var add_parallax = function(slider, parallax_one) {
982				
983				var do_parallax = function() {
984					
985					if ($(window).width() < 940) {
986						slider.removeClass('parallax');
987						return;
988					}
989				
990					slider.addClass('parallax');
991					var slides = slider.find('.slick-slide');
992
993					slides.each(function() {
994
995						if (parallax_one) {
996							$(this).data('active-only', true);
997						}
998
999						var opts = { 
1000							elementInViewport: parallax_one ? $(this) : $(this).closest('.slick-slider')
1001						};
1002
1003						self._parallax.call(this, opts);
1004					});
1005				};
1006				
1007				$(window).on('resize', do_parallax);
1008				do_parallax();
1009			};
1010
1011			// Basic featured grids parallax.
1012			$('.feat-grid.static .slides[data-parallax=1]')
1013				.addClass('parallax')
1014				.find('.item')
1015				.each(self._parallax);
1016
1017			
1018			/**
1019			 * Slider setup object
1020			 */
1021			var setup = {};
1022
1023			/**
1024			 * Main featured post slider
1025			 */
1026			setup.main_slider = function(slider) {
1027				
1028				slider.slick({
1029					centerMode: true,
1030					variableWidth: true,
1031					slidesToShow: 1,
1032	            	slidesToScroll: 1,
1033					autoplay: slider.data('autoplay') ? true : false,
1034					autoplaySpeed: slider.data('speed'),
1035					arrows: true,
1036					prevArrow: '<a href="#" class="prev-arrow"><i class="tsi tsi-angle-left"></i></a>',
1037					nextArrow: '<a href="#" class="next-arrow"><i class="tsi tsi-angle-right"></i></a>',
1038					touchThreshold: 50,
1039					dots: false,
1040					infinite: true,
1041					responsive: [{
1042						breakpoint: 940,
1043						settings: {
1044							slidesToShow: 1,
1045							centerMode: false,
1046							variableWidth: false
1047						}
1048					}]
1049				});
1050				
1051				// Arrow positions
1052				slider.on('setPosition', function() {
1053					
1054					// not for responsive
1055					if ($(window).width() < 940) {
1056						return;
1057					}
1058					
1059					var center = $(this).find('.slick-active.slick-center'),
1060						pos   = center.offset(),
1061						right = pos.left + center.width();
1062					
1063					$(this).find('.prev-arrow').css('left', pos.left + 'px');
1064					$(this).find('.next-arrow').css('left', right + 'px');
1065				});
1066				
1067				slider.find('[data-slick-index=0]').addClass('active');
1068				
1069				// Force our active class by first removing it from clones
1070				slider.on('beforeChange', function(e, slick, prev, current) {
1071					
1072					$(this).find('.active').removeClass('active');
1073					var ele = $(this);
1074					
1075					requestAnimationFrame(function() {
1076						ele.find('[data-slick-index=' + current + ']').addClass('active');
1077					}, 1);
1078				});
1079				
1080			};
1080 // main slider
1081
1082			/**
1083			 * Beauty Slider
1084			 */
1085			setup.beauty_slider = function(slider, vars) {
1086
1087				slider.slick($.extend(vars, {
1088					arrows: true,
1089					dots: true,
1090					infinite: true,
1091					cssEase: 'ease-in'
1092				}));
1093			};
1094
1095			/**
1096			 * Fashion Slider
1097			 */
1098			setup.fashion_slider = function(slider, vars) {
1099
1100				slider.on('init', function(e, slick) {
1101					self._wait_load(function() {
1102						$(slick.$slides[0]).addClass('active');
1103					});
1104				});
1105
1106				slider.slick($.extend(vars, {
1107					arrows: true,
1108					infinite: true,
1109					cssEase: 'cubic-bezier(0.4, 0.03, 0, 0.83)',
1110					speed: 700
1111				}));
1112
1113				slider.on('beforeChange', function(e, slick, prev, current) {
1114					var ele = $(this);
1115
1116					requestAnimationFrame(function() {
1117
1118						ele.find('.active').removeClass('active');
1119						ele.find('[data-slick-index=' + current + ']').addClass('active');
1120						
1121					});
1122					
1123				});
1124			};
1125			
1126			/**
1127			 * Trendy Slider
1128			 */
1129			setup.trendy_slider = function(slider, vars) {
1130				
1131				slider.slick($.extend(vars, {
1132					arrows: true,
1133					slidesToShow: 2,
1134					infinite: true,
1135					cssEase: 'ease',
1136					speed: 300,
1137					autoplay: slider.data('autoplay') ? true : false,
1138					autoplaySpeed: slider.data('speed'),
1139					responsive: [{
1140						breakpoint: 940,
1141						settings: {
1142							slidesToShow: 1
1143						}
1144					}]
1145				}));
1146			};
1147			
1148			/**
1149			 * Large Slider
1150			 */
1151			setup.large_slider = function(slider, vars) {
1152				slider.slick($.extend(vars, {
1153					arrows: true,
1154					infinite: true,
1155					cssEase: 'ease',
1156					speed: 350
1157				}));
1158			};
1159			
1160			/**
1161			 * Grid Slider
1162			 */
1163			setup.grid_slider = function(slider, vars) {
1164				slider.slick($.extend(vars, {
1165					arrows: true,
1166					infinite: true,
1167					cssEase: 'ease',
1168					speed: 300
1169				}));
1170			};
1171			
1172			/**
1173			 * Carousel Slider
1174			 */
1175			setup.carousel_slider = function(slider, vars) {
1176				
1177				slider.slick($.extend(vars, {
1178					arrows: true,
1179					slidesToShow: 3,
1180					slidesToScroll: 3,
1181					infinite: true,
1182					cssEase: 'ease-out',
1183					speed: 500,
1184					responsive: [
1185						{
1186							breakpoint: 940,
1187							settings: {slidesToShow: 2, slidesToScroll: 2}
1188						},
1189						{
1190							breakpoint: 600,
1191							settings: {slidesToShow: 1, slidesToScroll: 1}
1192						}
1193					]
1194				}));
1195			};
1196			
1197			// Bold slider
1198			setup.bold_slider = function(slider, vars) {
1199				
1200				slider.on('init', function(e, slick) {
1201					self._wait_load(function() {
1202						$(slick.$slides[0]).addClass('active');
1203					});
1204				});
1205				
1206				//var slick = instance.get(0).slick;
1207				slider.slick($.extend(vars, {
1208					arrows: true,
1209					infinite: true,
1210					cssEase: 'ease-in-out',
1211					speed: 500
1212				}));
1213
1214				var nav = slider.parent().find('.post-thumb');
1215				
1216				slider.on('beforeChange', function(e, slick, prev, current) {
1217					
1218					// Current nav thumb to activate
1219					nav.eq(current).click();
1220					
1221					var ele = $(this);
1222					ele.find('.active').removeClass('active');
1223					
1224					requestAnimationFrame(function() {
1225						ele.find('[data-slick-index=' + current + ']').addClass('active');
1226					});
1227					
1228				});
1229				
1230				// Sync slider with navigation
1231				nav.first().addClass('active');
1232				nav.on('click', function() {
1233					var index = $(this).index();
1234					
1235					$(this)
1236						.addClass('active')
1237						.siblings().removeClass('active');
1238					
1239					slider.slick('slickGoTo', index);
1240					
1241					return false;
1242				});
1243			};
1244
1245			/**
1246			 * Featured Grid Sliders
1247			 */
1248			setup.feat_grid = function(slider, vars) {
1249				var scroll_num = slider.data('scroll-num') || 1,
1250					scroll_num_md = slider.data('scroll-num-md');
1251					
1252				if (!scroll_num_md) {
1253					scroll_num_md = Math.min(2, Math.max(1, scroll_num - 1));
1254				}
1255
1256				slider.slick($.extend(vars, {
1257					arrows: true,
1258					infinite: true,
1259					cssEase: 'ease-out',
1260					speed: 500,
1261					slidesToShow: scroll_num,
1262					slidesToScroll: scroll_num_md, 
1263					responsive: [
1264						{
1265							breakpoint: 940,
1266							settings: {slidesToShow: scroll_num_md, slidesToScroll: scroll_num_md}
1267						},
1268						{
1269							breakpoint: 540,
1270							settings: {slidesToShow: 1, slidesToScroll: 1}
1271						}
1272					]
1273				}));
1274			};
1275			
1276			
1277			/* Initialize home sliders and featured grids */
1278			$('.common-slider .slides').each(function() {
1279			
1280				var slider = $(this);
1281				slider.one('init', function() {
1282					$(this).addClass('loaded');
1283				});
1284			
1285				// Common setting
1286				var vars = {
1287					prevArrow: '<a href="#" class="prev-arrow"><i class="tsi tsi-angle-left"></i></a>',
1288					nextArrow: '<a href="#" class="next-arrow"><i class="tsi tsi-angle-right"></i></a>',
1289					autoplay: slider.data('autoplay') ? true : false,
1290					autoplaySpeed: slider.data('speed'),
1291					fade: slider.data('animation') == 'fade' ? true : false
1292				};
1293				
1294				var parallax = slider.data('parallax') || 0,
1295					parallax_one,
1296					slider_type = slider.data('slider');
1297
1298				// First image load.
1299				if (vars.autoplay) {
1300
1301					slider.on('init afterChange', function(e, slick) {				
1302						var ele = $(this),
1303						    current = ele.find('[data-slick-index="' + slick.currentSlide + '"]');
1304
1305						var img = current.find('.wp-post-image').first();
1306						if (!img.length) {
1307							return;
1308						}					
1309
1310						var loaded = img.hasClass('lazyloaded') || (img.is('img:not(.lazyload)') && img.prop('complete'));
1311
1312						if (!loaded) {
1313							img.on('lazyloaded load', function(e) {
1314								slick.slickPlay();
1315							});
1316							
1317							slick.slickPause();
1318						}
1319					});
1320				}
1321				
1322				switch (slider_type) {
1323					case 'trendy':
1324						setup.trendy_slider(slider, vars);
1325						break;
1326					
1327					case 'beauty':
1328						setup.beauty_slider(slider, vars);
1329						break;
1330						
1331					case 'large':
1332						setup.large_slider(slider, vars);
1333						// parallax_one = 1;
1334						break;
1335						
1336					case 'grid':
1337						setup.grid_slider(slider, vars);
1338						break;
1339						
1340					case 'carousel':
1341						setup.carousel_slider(slider, vars);
1342						break;
1343						
1344					case 'bold':
1345						setup.bold_slider(slider, vars);
1346						// parallax_one = 1;
1347						break;
1348
1349					case 'feat-grid':
1350						setup.feat_grid(slider, vars);
1351						break;
1352						
1353					default:
1354
1355						var fn = setup[slider_type + '_slider'];
1356						if (typeof fn === 'function') {
1357							fn(slider, vars);
1358						}
1359						else {
1360							setup.main_slider(slider);
1361						}
1362
1363						break;
1364				}
1365				
1366				// Has Parallax effect?
1367				if (parallax) {
1368					
1369					// One active slide only to parallax
1370					if (parallax_one) {
1371						slider.on('beforeChange', function(e, slick, prev, current) {
1372							$(this).find('.active').removeClass('active');
1373							var slide = $(this).find('[data-slick-index=' + current + ']');
1374							
1375							slide.addClass('active');
1376							slide.jarallax('onScroll');
1377						});
1378					}
1379					
1380					add_parallax(slider, parallax_one);
1381				}
1382
1383			});
1384
1385			this.post_gallery_slider();
1386			$(document).on('ajax-pagination', this.post_gallery_slider);
1387
1388			/**
1389			 * Homepage carousel
1390			 */
1391			var carousel_init = false;
1392
1393			var setup_carousel = function(check_visible) {	
1394				
1395				var carousel = $('.posts-carousel .posts, .posts-carousel-b .posts')
1396					.one('init', function() {
1397						$(this).addClass('loaded');
1398						
1399						// Calculate arrow position based on image heights
1400						var posts = $(this),
1401							image = posts.find('.wp-post-image').first();
1402
1403						var compute = function() {
1404							if (image && image.height() > 0) {
1405								posts.parent().find('.slick-arrow').css('top', image.height()/2 + 'px');
1406							}
1407						};
1408
1409						posts.imagesLoaded(compute);
1410						posts.on('lazyloaded', compute);
1411					});
1412
1413
1414				if (check_visible === true && carousel.length && !isInViewport($(carousel).get(0))) {
1415					return;
1416				}
1417
1418				carousel_init = true;
1419				
1420				carousel.each(function() {
1421					
1422					$(this).slick({
1423						infinite: true,
1424						slidesToShow: $(this).data('slides') || 4,
1425						prevArrow: '<a class="prev-post"><i class="tsi tsi-angle-left"></i></a>',
1426						nextArrow: '<a class="next-post"><i class="tsi tsi-angle-right"></i></a>',
1427						appendArrows: $(this).parent().find('.navigate'),
1428						slidesToScroll: $(this).data('slides') || 4,
1429						
1430						responsive: [{
1431							breakpoint: 940,
1432							settings: {slidesToShow: 3, slidesToScroll: 3}
1433						},
1434						{
1435							breakpoint: 767,
1436							settings: {slidesToShow: 2, slidesToScroll: 2}
1437						},
1438						{
1439							breakpoint: 480,
1440							settings: {slidesToShow: 1, slidesToScroll: 1}
1441						}]
1442					});
1443				});
1444			};
1445
1446			var delay_setup = function(cb) {
1447				if (!carousel_init) {
1448					requestAnimationFrame((cb || setup_carousel));
1449				}
1450			};
1451
1452			$(window)
1453				.on('load', function() {
1454					// If in viewport.
1455					delay_setup(setup_carousel.bind(this, true));
1456				})
1457				.on('touchstart.ts-cs scroll.ts-cs', function() {
1458					$(this).off('.ts-cs');
1459					delay_setup();
1460				});
1461
1462			setTimeout(delay_setup, 15000);
1463			
1464			/**
1465			 * Widget: Posts slider
1466			 */
1467			$('.widget-slider .slides').each(function() {
1468				$(this).slick({
1469					prevArrow: '<a href="#" class="prev-arrow"><i class="tsi tsi-angle-left"></i></a>',
1470					nextArrow: '<a href="#" class="next-arrow"><i class="tsi tsi-angle-right"></i></a>',
1471					autoplay: $(this).data('autoplay') ? true : false,
1472					autoplaySpeed: 6000,
1473					infinite: true
1474				});
1475			});
1476			
1477			// Disable anchor jump on arrows
1478			$('.common-slider, .widget-slider').on('click', '.slick-arrow', function(e) {
1479				e.preventDefault();
1480			});
1481			
1482			// Polyfill check for outdated browsers
1483			objectFitImages($('img:not([data-src]), img.lazyloaded'));
1484			$(document).on('lazyloaded', function(e) {
1485				if ($(e.target).is('img')) {
1486					objectFitImages(e.target);
1487				}
1488			});
1489		},
1490
1491		/**
1492		 * Posts featured gallery slider
1493		 */
1494		post_gallery_slider: function(e) {
1495
1496			$('.gallery-slider:not(.slick-initialized)').each(function() {
1497
1498				var slider = $(this);
1499
1500				var init = function() {
1501					
1502					var vars = {
1503						infinite: true,
1504						slidesToShow: 1,
1505						prevArrow: '<a href="#" class="prev-arrow"><i class="tsi tsi-angle-left"></i></a>',
1506						nextArrow: '<a href="#" class="next-arrow"><i class="tsi tsi-angle-right"></i></a>',
1507						slidesToScroll: 1,
1508						adaptiveHeight: true
1509					};
1510					
1511					var parent = slider.closest('.single-creative .featured'),
1512						parallax;
1513					
1514					if (parent.length) {
1515						
1516						parent.addClass('has-gallery');
1517						slider.addClass('gallery-slider-lg');
1518						
1519						vars = $.extend(vars, {
1520							variableWidth: true,
1521							centerMode: true,
1522							adaptiveHeight: false,
1523							responsive: [{
1524								breakpoint: 940,
1525								settings: {centerMode: false, variableWidth: false}
1526							}]
1527						});
1528						
1529					}
1530					
1531					slider.slick(vars);
1532					!parallax || add_parallax(slider);
1533				};
1534
1535				if (e) {
1536					slider.imagesLoaded(init);
1537				}
1538				else {
1539					init();
1540				}
1541
1542			});
1543		},
1544		
1545		/**
1546		 * Setup Likes system
1547		 */
1548		likes: function()
1549		{
1550			if (typeof Sphere_Plugin == 'undefined') {
1551				return;
1552			}
1553			
1554			$('.likes-count').on('click', function() {
1555				
1556				var like = $(this);
1557				
1558				if (like.hasClass('voted')) {
1559					return false;
1560				}
1561				
1562				// Register the vote!
1563				$.post(Sphere_Plugin.ajaxurl, {action: 'sphere_likes', id: $(this).data('id')}, function(data) {
1564					
1565					if (data === Object(data)) {
1566						like.addClass('voted animate').find('.number').html(data.count);
1567					}
1568					
1569				}, 'json');
1570				
1571				return false;
1572				
1573			});
1574		},
1575		
1576		/**
1577		 * Setup Lightbox
1578		 */
1579		lightbox: function() 
1580		{
1581			// Can be disabled overall, or on mobile.
1582			if (
1583				!$.fn.magnificPopup 
1584				|| !$('body').hasClass('has-lb') 
1585				|| (!$('body').hasClass('has-lb-s') && $(window).width() < 768)
1586			) {
1587				return;
1588			}
1589
1590			// filter to handle valid images only
1591			var filter_images = function() {
1592				
1593				if (!$(this).attr('href')) {
1594					return false;
1595				}
1596				
1597				return $(this).attr('href').match(/\.(jpe?g|webp|png|bmp|gif)($|\?.+?)/); 
1598			};	
1599			
1600			var mfp_init = {
1601				type: 'image',
1602				tLoading: '',
1603				mainClass: 'mfp-fade mfp-img-mobile',
1604				removalDelay: 300,
1605				callbacks: {
1606					afterClose: function() {
1607						if (this._lastFocusedEl) {
1608							$(this._lastFocusedEl).addClass('blur');
1609						}
1610					}
1611				}
1612			};
1613			
1614			/**
1615			 * Handle Galleries in post
1616			 */
1617			
1618			var gal_selectors = '.gallery-slider, .post-content .gallery, .post-content .blocks-gallery-item, .post-content .tiled-gallery';
1619			
1620			// filter to only tie valid images
1621			$(gal_selectors).find('a').has('img').filter(filter_images).addClass('lightbox-gallery-img');
1622			
1623			// Add WooCommerce support
1624			$('.woocommerce a[data-rel^="prettyPhoto"], a.zoom').addClass('lightbox-gallery-img');
1625			gal_selectors += ', .woocommerce .images';
1626			
1627			// attach the lightbox as gallery
1628			$(gal_selectors).magnificPopup($.extend({}, mfp_init, {
1629				delegate: '.lightbox-gallery-img',
1630				gallery: {enabled: true},
1631				image: {
1632					titleSrc: function(item) {
1633						var image = item.el.find('img'), 
1634						    caption = item.el.find('.caption').html();
1635						
1636						return (caption || image.attr('title') || ' ');
1637					}
1638				}
1639			}));
1640			
1641			// Non-gallery images in posts
1642			var selector = $('.post-content, .main .featured, .single-creative .featured')
1643				.find('a:not(.lightbox-gallery-img)').has('img, .img');
1644			
1645			selector.add('.post-content, .main .featured, .lightbox-img')
1646				.filter(filter_images)
1647				.magnificPopup(mfp_init);
1648			
1649			
1650			// WooCommerce lightbox
1651			//$('a[data-rel^="prettyPhoto"], a.zoom').magnificPopup({hook: 'data-rel'});
1652		},
1653		
1654		/**
1655		 * Pinterest Pin It
1656		 */
1657		pin_it: function()
1658		{	
1659			var button = $('body .pinit-btn'),
1660				the_button = button.prop('outerHTML'),
1661			    index = 1;
1662			
1663			// Only proceed if non-touch device and button exists
1664			if (has_touch || !the_button) {
1665				return;
1666			}
1667			
1668			var show_on = button.data('show-on').split(',');
1669			
1670			var get_image = function(ele) {
1671				if (!ele.is('img')) {
1672					ele = ele.find('img').first();
1673				}
1674				
1675				return ele;
1676			};
1677			
1678			var setup = function() {
1679				
1680				var selectors = [];
1681				if (show_on.indexOf('single') !== -1) {
1682					selectors.push('.post-content img, .single-cover .featured, .single:not(.layout-creative) .featured .image-link');
1683				}
1684				
1685				if (show_on.indexOf('listing') !== -1) {
1686					selectors.push('.posts-container .post-header .image-link, .posts-container .post-thumb .image-link');
1687				}
1688				
1689				selectors = selectors.join(', ');
1690				
1691				$(selectors)
1692					.on('mouseenter', function() {
1693						
1694						var img = get_image($(this)),
1695						    wrap = img.parent();
1696						
1697						if (img.hasClass('nopin') || img.width() < 200 || img.height < 200) {
1698							return;
1699						}
1700						
1701						var pos = img.position(),
1702						    media  = img.prop('src'),
1703						    url, desc, button;
1704						
1705						// URL
1706						if ($('body').hasClass('single')) {
1707							url = window.location.href;
1708						}
1709						else {
1710							
1711							if (wrap.hasClass('image-link')) {
1712								url = wrap.prop('href');
1713							}
1714							else {
1715								url = img.closest('.post').find('.post-title-alt a, .post-title a').prop('href');
1716							}
1717
1718							// featured img has post title
1719							desc = img.prop('title');
1720						}
1721
1722						// desc = img.prop('alt') || img.prop('title');
1723						
1724						if (!url) {
1725							return;
1726						}
1727						
1728						// Create if not already done
1729						if (!img.data('pinit-id')) {
1730							button = $(the_button).appendTo(wrap);
1731
1732							if (!desc) {
1733								desc = button.data('heading');
1734							}
1735
1736							var url_format = button.prop('href')
1737								.replace('%media%', encodeURIComponent(media))
1738								.replace('%url%', encodeURIComponent(url))
1739								.replace('%desc%', encodeURIComponent(desc));
1740							
1741							button.prop('href', url_format);
1742							
1743							button.on('click', function(e) {
1744								e.preventDefault();
1745								e.stopPropagation();
1746								
1747								window.open($(this).prop('href'), '_blank');
1748							});
1749							
1750							index++;
1751							img.attr('data-pinit-id', index);
1752							button.attr('data-pinit-id', index);
1753						}
1754						else {
1755							// Existing button
1756							button = wrap.find('a[data-pinit-id=' + img.data('pinit-id') +']');
1757						}
1758						
1759						button.addClass('show').css({
1760							top: pos.top + parseInt(img.css('marginTop')) + parseInt(img.css('paddingTop')),
1761							left: pos.left + parseInt(img.css('marginLeft')) + parseInt(img.css('paddingLeft'))
1762						});
1763				})	
1764				.on('mouseleave', function(e) {
1765						 
1766						var ele = get_image($(this)).parent();
1767						
1768						if ($(e.relatedTarget).hasClass('pinit-btn')) {
1769							return;
1770						}
1771						
1772						ele.find('.pinit-btn').removeClass('show');
1773				});
1774			};
1775			
1776			setup();
1777			$(document).on('ajax-pagination', setup);
1778			
1779		},
1780		
1781		lazy_load: function()
1782		{
1783			var setRatio = function(target) {
1784
1785				target    = $(target);
1786				var ratio = target.data('ratio');
1787
1788				// Ratio info for a bg image.
1789				if (ratio > 0) {
1790					var container = target.parent(),
1791						style = container.prop('style');
1792						
1793					if (
1794						container.hasClass('media-ratio') && 
1795						(!Bunyad_Tests.vars || !style.getPropertyValue('--a-ratio'))
1796					) {
1797						container.css('padding-bottom', (100 / ratio) + '%');
1798					}
1799				}
1800			};
1801
1802			// Background Image load with callback.
1803			var bgLoad = function(target, cb) {
1804
1805				target    = $(target);
1806				var attrs = {};
1807
1808				if (Bunyad_Tests.srcset && target.data('bgset') && target.data('sizes')) {
1809					attrs.sizes  = target.data('sizes');
1810					attrs.srcset = target.data('bgset');
1811				}
1812				else {
1813					// Set src at last.
1814					attrs.src = target.data('bgsrc');
1815				}
1816
1817				// Just in-case it wasn't set via css var.
1818				setRatio(target);
1819
1820				var img = document.createElement('img');
1821				img.onload = function() {
1822					var bg = "url('" + (img.currentSrc || img.src) + "')";
1823					var ele = target[0].style;
1824
1825					if (ele.backgroundImage !== bg) {
1826						ele.backgroundImage = bg;
1827					}
1828					
1829					!cb || cb();
1830
1831					img.onload = null;
1832					img.onerror = null;
1833					img = null;
1834				};
1835
1836				img.onerror = img.onload;
1837
1838				for (var i in attrs) {
1839					img.setAttribute(i, attrs[i]);
1840				}
1841	
1842				// For odd cases / old browsers. naturalWidth check for old Firefox where if src omitted, complete is true.
1843				if (img && img.complete && img.naturalWidth > 0 && img.onload) {
1844					img.onload();
1845				}
1846			};
1847
1848			/**
1849			 * Is lazyload enabled?
1850			 */
1851			var type = $('body').prop('className').match(/lazy-([^\s]+)/);
1852			var loadBgImages = function() {
1853				var target = this;
1854				bgLoad(this, function() {
1855					$(target).trigger('lazyloaded');
1856				});
1857			};
1858
1859			// Load bg images with lazyload selectively disabled.
1860			$('.img.bg-cover:not(.lazyload)').each(loadBgImages);
1861
1862			if (!type || !window.lazySizes) {
1863				// Process all bg images at once if not lazyloading.
1864				$('.img.bg-cover').each(loadBgImages);
1865				return;
1866			}
1867			
1868			type = type[1];
1869
1870			// For bg images. Inspired from unveilhooks plugin.
1871			addEventListener('lazybeforeunveil', function(e) {
1872
1873				var target = e.target;
1874				if (!target.getAttribute('data-bgsrc')) {
1875					return;
1876				}
1877
1878				e.detail.firesLoad = true;
1879
1880				bgLoad(target, function() {
1881					e.detail.firesLoad = false;
1882					window.lazySizes.fire(target, '_lazyloaded', {}, true, true);
1883				});
1884			});
1885			
1886			// Debounced resize trigger on lazyload
1887			var timer;
1888			var loaded = function() {
1889				clearTimeout(timer);
1890				timer = setTimeout(function() {
1891					$(window).trigger('resize.TSS');
1892				}, 50);
1893			};
1894			
1895			$(document).on('lazyloaded', '.main', function(e) {
1896				loaded();
1897			});
1898
1899			window.lazySizes.init();
1900
1901			// Only for "smart" type and large desktops
1902			if (type != 'smart' || $(window).width() < 1380) {
1903				return;
1904			}
1905			
1906			// Deferred preload
1907			var is_loaded = false;
1908			var defer_load = function() {
1909
1910				if (is_loaded) {
1911					return;
1912				}
1913
1914				$('.lazyload').each(function() {
1915					lazySizes.loader.unveil($(this).get(0));
1916				});
1917
1918				is_loaded = true;
1919			};
1920			
1921			// With delay or immediate on scroll (touch, mousemove other candidates)
1922			var events = 'scroll.ll';
1923			$(window).on(events, function() {
1924				defer_load();
1925				$(this).off(events);
1926			});
1927
1928			self._wait_load(defer_load, {ready: true});
1929		},
1930		
1931		/**
1932		 * Setup masonry on archives
1933		 */
1934		masonry: function(reload, posts, grid) 
1935		{
1936			if ($.fn.masonry && $('.posts-dynamic').hasClass('masonry')) {
1937				var grid = grid || $('.posts-dynamic.masonry .posts-wrap'); 
1938				
1939				if (!grid.length) {
1940					return;
1941				}
1942
1943				grid.on('layoutComplete', function() {
1944					requestAnimationFrame(function() {
1945						$(window).trigger('resize.TSS');
1946					});
1947				});
1948				
1949				// Reload masonry?
1950				if (reload && posts) {
1951		
1952					var posts = grid.find(posts).css({ opacity: 0 });
1953					
1954					grid.each(function() {
1955
1956						var block = $(this);
1957						block.imagesLoaded(function() {
1958							posts.css({ opacity: 1 });
1959							block.masonry('appended', posts, true);
1960						});
1961					});
1962				}
1963				else {
1964					// debounce.
1965					var reinit = writeRaf(function() {
1966						$(this).masonry('layout');
1967					});
1968
1969					grid.each(function() {
1970						$(this).masonry();
1971
1972						$(this).on('lazyloaded', reinit.bind(this));
1973						$(this).imagesLoaded(reinit.bind(this));
1974					});
1975				}
1976			}
1977		}
1978		
1979	}; // end module
1980	
1981	// Utils
1982	function writeRaf(fn, options) {
1983		var running, 
1984		    args, 
1985		    that;
1986
1987		var run = function() {
1988			running = false;
1989			fn.apply(that, args);
1990		};
1991
1992		if (!options) {
1993			options = {};
1994		}
1995
1996		return function() {
1997			args = arguments;
1998			that = options.that || this;
1999
2000			if (!running) {
2001				running = true;
2002				requestAnimationFrame(run);
2003			}
2004		};
2005	}
2006
2007	function isInViewport(element) {
2008		var rect = element.getBoundingClientRect();
2009		const windowHeight = (window.innerHeight || document.documentElement.clientHeight);
2010		const windowWidth = (window.innerWidth || document.documentElement.clientWidth);
2011
2012		const vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
2013		const horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);
2014		
2015		return (vertInView && horInView);
2016	}
2017	
2018	return self;
2019	
2020})(jQuery);
2021
2022/**
2023 * Social Sharing float behavior
2024 */
2025var Bunyad_Share_Float = (function($) {
2026	"use strict";
2027
2028	/**
2029	 * Check if element intersects
2030	 */
2031	var intersects = function(el1, el2) {
2032		var rect1 = el1.getBoundingClientRect();
2033		var rect2 = el2.getBoundingClientRect();
2034	
2035		return !(
2036			rect1.top    > rect2.bottom ||
2037			rect1.right  < rect2.left ||
2038			rect1.bottom < rect2.top ||
2039			rect1.left   > rect2.right
2040		);
2041	}
2042
2043	var start_at = 0;
2044
2045	return {
2046		init: function() {
2047
2048			if (!$('.post-share-float').length) {
2049				return;
2050			}
2051
2052			$(window).on('resize load resize.TSS', function() {
2053				this.init_calc();
2054				this.sticky();
2055				this.visibility();
2056			}.bind(this));
2057		},
2058
2059		/**
2060		 * Pre-calc for performance
2061		 */
2062		init_calc: function() {
2063
2064			if (!$('body').hasClass('no-sidebar') && !$('.the-post-modern').length) {
2065				var featured = $('.the-post-header .featured, .single-creative .featured, .single-cover .featured, .single-magazine .featured');
2066				if (featured.length) {
2067					start_at = 	featured.position().top;
2068				}
2069				else {
2070					var post_header = $('.the-post-header');
2071					start_at = post_header.length ? post_header.position().top : 0;
2072				}
2073			}
2074		},
2075		
2076		/**
2077		 * Setup sticky float
2078		 */
2079		sticky: function() {
2080			// Floating social sharing
2081			var add = 20;
2082			add += $('.admin-bar').length ? 32 : 0;
2083			add += Bunyad_Theme.has_sticky_nav ? 50 : 0;
2084			var width = $(window).width();
2085			
2086			$('.post-share-float').each(function() {
2087
2088				var post_foot = $('.the-post-foot').outerHeight(true) + 50;
2089				$(this).css('height', $('.the-post .post-content').height() + (width > 1500 ? post_foot : 0) + 'px');
2090				
2091				$(this).theiaStickySidebar({
2092					minWidth: 768, 
2093					updateSidebarHeight: false,
2094					defaultPosition: 'absolute',
2095					additionalMarginTop: add
2096				});
2097			});
2098		},
2099
2100		/**
2101		 * Determine when to show and hide
2102		 */
2103		visibility: function() {
2104
2105			if ($(window).width() < 768) {
2106				return false;
2107			}
2108
2109			var intersect_sels = [
2110				'.the-post-modern .alignfull',
2111				'.the-post-modern .alignwide', 
2112				'.the-post-modern .gallery:not(.aligncenter)',
2113				'.the-post-modern .wp-block-gallery:not(.aligncenter)',
2114				'.the-post-modern figure.alignnone', 
2115				'.the-post-modern img.alignnone',
2116			];
2117
2118			var observe = [],
2119			    share_ele = $('.post-share-float');
2120
2121			$(intersect_sels.join(',')).each(function() { 
2122				observe.push(this);
2123			});
2124		
2125			$(window).on('scroll', function() {
2126				var is_hidden = false,
2127					ele = share_ele.find('.theiaStickySidebar').get(0);
2128
2129				if ($(window).scrollTop() < start_at) {
2130					is_hidden = true;
2131				}
2132				else {
2133
2134					// Check if any of the observed elements intersect
2135					for (var i in observe) {
2136						if (intersects(ele, observe[i])) {
2137							is_hidden = true;
2138							break;
2139						}
2140					}
2141				}
2142		
2143				(is_hidden
2144						? share_ele.addClass('is-hidden') 
2145						: share_ele.removeClass('is-hidden')
2146				);
2147			});
2148		}
2149	}
2150})(jQuery);
2151
2152
2153// If lazysizes init earlier than our ready method, this causes race conditions with
2154// hooks not executing.
2155window.lazySizesConfig = {init: false};
2156
2157/**
2158 * Pagination handlers
2159 */
2160var Bunyad_Pagination = (function($) {
2161	"use strict";
2162
2163	// Blocks load more
2164	var processing = false,
2165	    cache = [];
2166	
2167	var self = {
2168			
2169		init: function() {
2170			// AJAX pagination handlers
2171			$('.main').on('click', '.main-pagination .load-button, .block .main-pagination.number a', this.ajax_pagination);
2172		},
2173		
2174		/**
2175		 * Initiate handling of AJAX pagination
2176		 */
2177		ajax_pagination: function(e) 
2178		{
2179			if (processing) {
2180				return false;
2181			}
2182			
2183			// Type of pagination
2184			var type = 'more';
2185			if ($(this).closest('.main-pagination').hasClass('number')) {
2186				type = 'number';
2187			}
2188			
2189			var ele = $(this),
2190		    	block = ele.closest('.block'),
2191		    	post_id = ele.closest('.page-content, .post-content').data('id'),
2192		    	page = ele.data('page') + 1,
2193		    	is_block = true;
2194		
2195			// Not a block, archives
2196			if (!block.length) {
2197				is_block = false;
2198				block = ele.closest('.main-content');
2199			}
2200			
2201			// AJAX params
2202			var params =  {
2203				'_bunyad_act': 'block',
2204				'page_id': post_id,
2205				'paged': page, 
2206				'block_id': block.data('id')
2207			};
2208
2209			switch(type) {
2210			
2211				// Type: Load More
2212				case 'more':
2213					ele.addClass('loading').find('.tsi').addClass('tsi-spin');
2214					
2215					// Processing method for load more
2216					var process = self.process_load_more;
2217					
2218					break;
2219				
2220				// Type: Numbered
2221				case 'number':
2222					block.find('.block-content').addClass('loading');
2223					
2224					// Change page number
2225					var permalink = ele.attr('href').match(/\/page\/(\d+)\//);
2226					if (permalink !== null) {
2227						params.paged = permalink[1];
2228					}
2229					else {
2230						// Plain links
2231						var src = ele.attr('href').match(/(\?|&)paged?=(\d+)/);
2232						params.paged = src ? src[2] : 1;
2233					}
2234					
2235					// Set height
2236					block.css('height', block.height());
2237					
2238					var process = function(data) {
2239						cache[params.paged] = data;
2240						var content = $(data),
2241						    block_content = block.find('.block-content');
2242						
2243						block_content.removeClass('fade-in-down-lg')
2244							.html($(data).find('.block-content').html());
2245						
2246						block.css('height', 'auto');
2247						block_content.addClass('fade-in-down-lg').removeClass('loading');
2248						
2249						// position correctly
2250						$('html, body').animate({scrollTop: block.offset().top - 50}, 200);
2251						
2252						$(document).trigger('ajax-pagination');
2253					};
2254					
2255					// In cache?
2256					if (cache[params.paged]) {
2257						processing = false;
2258						process(cache[params.paged]);
2259						
2260						return false;
2261					}
2262
2263					break;
2264			}
2265
2266			// Process block
2267			if (is_block) {
2268				
2269				// Home blocks AJAX
2270				var ajax_url = Bunyad.custom_ajax_url;
2271				ajax_url += (ajax_url.indexOf('?') !== -1 ? '&' : '?');
2272				
2273				processing = $.get(ajax_url + $.param(params), function(data) {
2274						process(data, block, ele);
2275					})
2276					.always(function() {
2277						// All done
2278						processing = false;
2279					});	
2280			}
2281			else {
2282				
2283				// Archives AJAX
2284				var ajax_url = $(this).attr('href');
2285				processing = $.get(ajax_url, function(data) {
2286					data = $(data).find('.main-content').get(0);
2287					process(data, block, ele);
2288				})
2289				.always(function() {
2290					// All done
2291					processing = false;
2292				});
2293			}
2294
2295			return false;
2296		},
2297		
2298		/**
2299		 * Load More Ajax callback method
2300		 */
2301		process_load_more: function(data, block, ele) 
2302		{
2303			var content = $(data),
2304				wrap = block.find('.posts-container'),
2305				posts;
2306			
2307			if (content.find('.posts-container').hasClass('mixed')) {
2308				posts = content.find('.posts-dynamic').children().addClass('fade-in-up-lg');
2309				wrap.append(posts);
2310			}
2311			else {
2312				// Directly below or in a .posts-wrap wrapper?
2313				// WARNING: Always have .posts-wrap to prevent unexpected bugs
2314				var container = block.find('.posts-wrap').length ? '.posts-wrap' : '.posts-container';
2315				
2316		        posts = content.find(container).children().addClass('fade-in-up-lg');
2317		        block.find(container).append(posts);
2318			}
2319			
2320			// Masonry reload
2321			if (wrap.hasClass('masonry')) {
2322				//posts.removeClass('fade-in-up-lg');
2323				Bunyad_Theme.masonry(true, posts, wrap.find('.posts-wrap'));
2324			}
2325			
2326			$(document).trigger('ajax-pagination');
2327
2328			block.find('.main-pagination')
2329				.replaceWith(content.find('.main-pagination'));
2330			
2331			ele.removeClass('loading')
2332				.find('.tsi').removeClass('tsi-spin');
2333		}
2334	};
2335	
2336	return self;
2337	
2338})(jQuery);
2339
2340// Load when ready.
2341jQuery(function($) {
2342	"use strict";
2343	
2344	// Init
2345	var init = function() {
2346		Bunyad_Theme.init();
2347		Bunyad_Pagination.init();
2348	};
2349
2350	var rp_support = function() {
2351		var relList = document.createElement('link').relList;
2352		return !!(relList && relList.supports && relList.supports('preload'));
2353	};
2354	
2355	if (window.ts_ld && !rp_support() && !window.ld_skip && window.loadCSS) {
2356		
2357		var link = $('link[as=style]');
2358		if (link.length) {
2359			link = link[0];
2360			
2361			var css_load = function(target) {
2362				if (target.prop('media') == 'all') {
2363					init();
2364					
2365					setTimeout(function() {
2366						$('html').removeClass('ld');
2367					}, 50);
2368					
2369					return;
2370				}
2371
2372				setTimeout(css_load.bind(null, target), 20);
2373			};
2374			
2375			css_load($(link));
2376		}
2377	}
2378	else {
2379		init();
2380	}
2381});
2382
2383 // Required plugins and 3rd Party Libraries
2384
2385/**
2386 * Plus/minus polyfill for numbers - used in WooCommerce
2387 * 
2388 * Author Bryce Adams
2389 */
2390jQuery( function( $ ) {
2391
2392	// Quantity buttons
2393	$( 'div.quantity:not(.buttons_added), td.quantity:not(.buttons_added)' )
2394		.addClass( 'buttons_added' )
2395		.append( '<div class="vertical-buttons"><input type="button" value="+" class="plus" /><input type="button" value="-" class="minus" /></div>' );
2396
2397	$( document ).on( 'click', '.plus, .minus', function() {
2398
2399		// Get values
2400		var $qty		= $( this ).closest( '.quantity' ).find( '.qty' ),
2401			currentVal	= parseFloat( $qty.val() ),
2402			max			= parseFloat( $qty.attr( 'max' ) ),
2403			min			= parseFloat( $qty.attr( 'min' ) ),
2404			step		= $qty.attr( 'step' );
2405
2406		// Format values
2407		if ( ! currentVal || currentVal === '' || currentVal === 'NaN' ) currentVal = 0;
2408		if ( max === '' || max === 'NaN' ) max = '';
2409		if ( min === '' || min === 'NaN' ) min = 0;
2410		if ( step === 'any' || step === '' || step === undefined || parseFloat( step ) === 'NaN' ) step = 1;
2411
2412		// Change the value
2413		if ( $( this ).is( '.plus' ) ) {
2414
2415			if ( max && ( max == currentVal || currentVal > max ) ) {
2416				$qty.val( max );
2417			} else {
2418				$qty.val( currentVal + parseFloat( step ) );
2419			}
2420
2421		} else {
2422
2423			if ( min && ( min == currentVal || currentVal < min ) ) {
2424				$qty.val( min );
2425			} else if ( currentVal > 0 ) {
2426				$qty.val( currentVal - parseFloat( step ) );
2427			}
2428
2429		}
2430
2431		// Trigger change event
2432		$qty.trigger( 'change' );
2433
2434	});
2435
2436});

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