PageSourceSearch

https://www.we-are-girlz.com/wp-content/themes/cheerup/js/theme.js?ver=8.1.0

js we-are-girlz.com collected 2026-10-02 03:37:13 UTC 54,935 bytes, 2,372 lines download raw bytes

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

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.