PageSourceSearch

https://redacademy.it/wp-content/plugins/tlp-team/assets/js/tlpteam.js?ver=1790948596

js redacademy.it collected 2026-10-02 13:44:20 UTC 58,451 bytes, 1,697 lines download raw bytes

1(function ($) {
2	'use strict';
3	var mdModalWrap = $("#tlp-modal");
4	var elementThumbInstances = [];
5	window.initTlpTeam = function () {
6		$(".rt-team-container").each(function (index) {
7			// The Elementor editor re-renders a widget on every edit, so this can run
8			// many times over containers that are already wired up. Bind each one once,
9			// otherwise every re-render stacks another set of handlers (and another
10			// Swiper) on the same markup. On the frontend this runs once anyway.
11			if ($(this).data("tlpTeamInit")) {
12				return;
13			}
14			$(this).data("tlpTeamInit", true);
15
16			var container = $(this),
17				str = container.attr("data-layout"),
18				popupBg = container.attr("data-popup-bg"),
19				id = $.trim(container.attr('id')),
20				randId = id.replace("rt-team-container-", ""),
21				scID = $.trim(container.attr("data-sc-id")),
22				mdPopup = $('.ttp-single-md-popup', container),
23				multiPopup = $('.ttp-multi-popup', document),
24				$default_order_by = $('.rt-order-by-action .order-by-default', container),
25				$default_order = $('.rt-sort-order-action .rt-sort-order-action-arrow', container),
26				$taxonomy_filter = $('.rt-filter-item-wrap.rt-tax-filter', container),
27				$pagination_wrap = $('.rt-pagination-wrap', container),
28				$loadmore = $('.rt-loadmore-action', container),
29				$infinite = $('.rt-infinite-action', container),
30				$page_prev_next = $('.rt-cb-page-prev-next', container),
31				$page_numbers = $('.rt-page-numbers', container),
32				html_loading = '<div class="rt-loading-overlay"></div><div class="rt-loading rt-ball-clip-rotate"><div></div></div>',
33				preLoader = container.find('.ttp-pre-loader'),
34				loader = container.find(".rt-content-loader"),
35				contentLoader = container.children(".rt-row.rt-content-loader"),
36				search_wrap = container.find(".rt-search-filter-wrap"),
37				ttp_order = '',
38				ttp_order_by = '',
39				ttp_taxonomy = '',
40				ttp_term = '',
41				ttp_search = '',
42				ttp_paged = 1,
43				temp_total_pages = parseInt($pagination_wrap.attr('data-total-pages'), 10),
44				ttp_total_pages = typeof (temp_total_pages) != 'undefined' && temp_total_pages != '' ? temp_total_pages : 1,
45				temp_posts_per_page = parseInt($pagination_wrap.attr('data-posts-per-page'), 10),
46				ttp_posta_per_page = typeof (temp_posts_per_page) != 'undefined' && temp_posts_per_page != '' ? temp_posts_per_page : 3,
47				infinite_status = 0,
48				paramsRequest = {},
49				mIsotopeWrap = '',
50				IsotopeWrap = '',
51				// `ttp-masonry`, not `tpg-masonry` (that is The Post Grid's prefix, and no
52				// markup here ever carries it). While this looked for the wrong class it
53				// was always empty, so every `isMasonry.length` branch below was dead:
54				// AJAX-loaded items were appended without ever being handed to Isotope,
55				// so they kept `position: relative` and stacked on top of the absolutely
56				// positioned cards already on the page.
57				isMasonry = $('.rt-row.rt-content-loader.ttp-masonry', container),
58				isIsotope = $(".tlp-team-isotope", container),
59				IsoButton = $(".ttp-isotope-buttons", container),
60				IsoDropDownFilter = $("select.isotope-dropdown-filter", container),
61				isCarousel = $('.rt-carousel-holder', container),
62				caroThumb = $('.rttm-carousel-main', container),
63				isSpecial = $('.rt-special-wrapper', container),
64				placeholder_loading = function () {
65					if (loader.find('.rt-loading-overlay').length == 0) {
66						loader.addClass('ttp-pre-loader');
67						loader.append(html_loading);
68					}
69				},
70				remove_placeholder_loading = function () {
71					loader.find('.rt-loading').fadeOut(300);
72					loader.removeClass('ttp-pre-loader');
73					$loadmore.removeClass('rt-lm-loading');
74					$page_numbers.removeClass('rt-lm-loading');
75					$infinite.removeClass('rt-active-elm');
76					search_wrap.find('input').prop("disabled", false);
77				},
78				check_query = function () {
79					if ($taxonomy_filter.length > 0) {
80						ttp_taxonomy = $taxonomy_filter.attr('data-taxonomy');
81						var term;
82						if ($taxonomy_filter.hasClass('rt-filter-button-wrap')) {
83							term = $taxonomy_filter.find('.rt-filter-button-item.selected').attr('data-term');
84						} else {
85							term = $taxonomy_filter.find('.term-default').attr('data-term');
86						}
87						if (typeof (term) != 'undefined' && term != '') {
88							ttp_term = term;
89						}
90					}
91					if ($default_order_by.length > 0) {
92						var order_by_param = $default_order_by.attr('data-order-by');
93						if (typeof (order_by_param) != 'undefined' && order_by_param != '' && (order_by_param.toLowerCase())) {
94							ttp_order_by = order_by_param;
95						}
96					}
97					if ($default_order_by.length > 0) {
98						var order_param = $default_order.attr('data-sort-order');
99						if (typeof (order_param) != 'undefined' && order_param != '' && (order_param == 'DESC' || order_param == 'ASC')) {
100							ttp_order = order_param;
101						}
102					}
103					if (search_wrap.length > 0) {
104						ttp_search = $.trim(search_wrap.find('input').val());
105					}
106					paramsRequest = {
107						'ttp_post__not_in': [20],
108						'scID': scID,
109						'order': ttp_order,
110						'order_by': ttp_order_by,
111						'taxonomy': ttp_taxonomy,
112						'term': ttp_term,
113						'paged': ttp_paged,
114						'action': 'ttp_Layout_Ajax_Action',
115						'search': ttp_search,
116						'tlp_nonce': ttp.nonce
117					};
118				},
119				infinite_scroll = function () {
120					if (infinite_status == 1 || $infinite.hasClass('rt-hidden-elm') || $pagination_wrap.length == 0) {
121						return;
122					}
123					var ajaxVisible = $pagination_wrap.offset().top,
124						ajaxScrollTop = $(window).scrollTop() + $(window).height();
125
126					if (ajaxVisible <= (ajaxScrollTop) && (ajaxVisible + $(window).height()) > ajaxScrollTop) {
127						infinite_status = 1; //stop inifite scroll
128						ttp_paged = ttp_paged + 1;
129						$infinite.addClass('rt-active-elm');
130						ajax_action(true, true);
131					}
132				},
133				generateData = function (number) {
134					var result = [];
135					for (var i = 1; i < number + 1; i++) {
136						result.push(i);
137					}
138					return result;
139				},
140				createPagination = function () {
141					if ($page_numbers.length > 0) {
142						$page_numbers.pagination({
143							dataSource: generateData(ttp_total_pages * parseFloat(ttp_posta_per_page)),
144							pageSize: parseFloat(ttp_posta_per_page),
145							autoHidePrevious: true,
146							autoHideNext: true,
147							prevText: '<i class="fa fa-angle-double-left" aria-hidden="true"></i>',
148							nextText: '<i class="fa fa-angle-double-right" aria-hidden="true"></i>'
149						});
150						$page_numbers.addHook('beforePaging', function (pagination) {
151							infinite_status = 1;
152							ttp_paged = pagination;
153							$page_numbers.addClass('rt-lm-loading');
154							$page_numbers.pagination('disable');
155							ajax_action(true, false);
156						});
157						if (ttp_total_pages <= 1) {
158							$page_numbers.addClass('rt-hidden-elm');
159						} else {
160							$page_numbers.removeClass('rt-hidden-elm');
161						}
162					}
163				},
164				getItemsArray = function (contentLoader) {
165					return contentLoader.find('.rt-grid-item').map(function () {
166						var _self = $(this);
167						if (_self.is(":visible")) {
168							return _self.attr("data-id");
169						}
170					}).get();
171				},
172				animateAction = function () {
173					var $postItem = $('.rt-grid-item:not(.rt-ready-animation, .isotope-item)', container);
174					$postItem.addClass('rt-ready-animation animated fadeIn');
175				},
176				ajax_action = function (page_request, append) {
177					page_request = page_request || false;
178					append = append || false;
179					if (!page_request) {
180						ttp_paged = 1;
181					}
182					check_query();
183					if (page_request == true && ttp_total_pages > 1 && paramsRequest.paged > ttp_total_pages) {
184						remove_placeholder_loading();
185						return;
186					}
187					$.ajax({
188						url: ttp.ajaxurl,
189						type: 'POST',
190						data: paramsRequest,
191						cache: false,
192						beforeSend: function () {
193							placeholder_loading();
194						},
195						success: function (data) {
196							if (!data.error) {
197								ttp_paged = data.paged;
198								ttp_total_pages = data.total_pages;
199								if (data.paged >= ttp_total_pages) {
200									if ($loadmore.length) {
201										$loadmore.addClass('rt-hidden-elm');
202									}
203									if ($infinite.length) {
204										infinite_status = 1;
205										$infinite.addClass('rt-hidden-elm');
206									}
207									if ($page_prev_next.length) {
208										if (!page_request) {
209											$page_prev_next.addClass('rt-hidden-elm');
210										} else {
211											$page_prev_next.find('.rt-cb-prev-btn').removeClass('rt-disabled');
212											$page_prev_next.find('.rt-cb-next-btn').addClass('rt-disabled');
213										}
214									}
215								} else {
216									if ($loadmore.length) {
217										$loadmore.removeClass('rt-hidden-elm');
218									}
219									if ($infinite.length) {
220										infinite_status = 0;
221										$infinite.removeClass('rt-hidden-elm');
222									}
223									if ($page_prev_next.length) {
224										if (!page_request) {
225											$page_prev_next.removeClass('rt-hidden-elm');
226										} else {
227											if (data.paged == 1) {
228												$page_prev_next.find('.rt-cb-prev-btn').addClass('rt-disabled');
229												$page_prev_next.find('.rt-cb-next-btn').removeClass('rt-disabled');
230											} else {
231												$page_prev_next.find('.rt-cb-prev-btn').removeClass('rt-disabled');
232												$page_prev_next.find('.rt-cb-next-btn').removeClass('rt-disabled');
233											}
234										}
235									}
236								}
237								if (append) {
238									if (isIsotope.length) {
239										// Parse ONCE — append(html) and isotope('appended', html)
240										// each parse the string separately, so Isotope was
241										// registering a detached copy of the new cards.
242										var $isoAppended = $(data.data);
243
244										// No reloadItems()/updateSortData(): they rebuild every Item
245										// and discard the positions `appended` just assigned, so the
246										// arrange that followed animated each new card in from the
247										// grid's origin. They are only for sort/filter data.
248										//
249										// Put the markup in the DOM but hand it to Isotope only once
250										// the images are in — registering earlier measures cards
251										// that have not finished loading, so they land at the wrong
252										// y and then visibly slide when the arrange corrects them.
253										// transitionDuration 0 keeps that correction from animating.
254										IsotopeWrap.append($isoAppended);
255										IsotopeWrap.imagesLoaded(function () {
256											preFunction();
257											IsotopeWrap.isotope({ transitionDuration: 0 });
258											IsotopeWrap.isotope('appended', $isoAppended);
259											IsotopeWrap.isotope();
260											IsotopeWrap.isotope({ transitionDuration: '0.4s' });
261
262											// preFunction() -> HeightResize() pins every
263											// .even-grid-item to the tallest card, from its OWN
264											// async imagesLoaded pass on the row. That lands after
265											// the arrange above, so if the cards just loaded are
266											// taller than the ones already there, the rows stay
267											// spaced by the old height and the new row overlaps the
268											// one above it. Registering on the same row queues this
269											// settle behind HeightResize's write.
270											contentLoader.imagesLoaded(function () {
271												IsotopeWrap.isotope({ transitionDuration: 0 });
272												IsotopeWrap.isotope();
273												IsotopeWrap.isotope({ transitionDuration: '0.4s' });
274											});
275										});
276									} else if (isMasonry.length) {
277										// Parse the markup ONCE. `append(html)` and
278										// `isotope('appended', html)` each parse the string
279										// separately, so Isotope would end up tracking a second,
280										// detached copy instead of the cards actually on screen.
281										var $appended = $(data.data);
282
283										// No reloadItems()/updateSortData() here. `appended`
284										// already places the new cards instantly, in their slot;
285										// reloadItems() rebuilds every Item and throws those
286										// positions away, so the relayout below animated each new
287										// card in from the grid's top-left corner. Those two are
288										// only needed when sort/filter data changes.
289										mIsotopeWrap.append($appended).isotope('appended', $appended);
290										mIsotopeWrap.imagesLoaded(function () {
291											mIsotopeWrap.isotope('layout');
292										});
293									} else if (isSpecial.length) {
294										// Special paginates the thumbnail grid only - the stage
295										// and the feature panel have to survive the swap.
296										container.find('.special-items-wrapper').append(data.data);
297										syncSpecialActive();
298									} else {
299										contentLoader.append(data.data);
300									}
301								} else {
302									if (isMasonry.length) {
303										// Filter / sort / search / AJAX pagination replace the
304										// whole row. reloadItems() is REQUIRED here (the exact
305										// opposite of the append case above): Isotope still holds
306										// Item objects for the elements html() just destroyed, so
307										// laying out without it positions detached nodes, sets the
308										// container to height 0 and leaves the new cards in normal
309										// flow spilling over whatever follows on the page.
310										// `.isotope()` with no args re-runs arrange, which is what
311										// actually measures and places items — `isotope('layout')`
312										// alone leaves item.size undefined and collapses the row.
313										mIsotopeWrap.html(data.data);
314										mIsotopeWrap.imagesLoaded(function () {
315											mIsotopeWrap.isotope('reloadItems').isotope();
316										});
317									} else if (isSpecial.length) {
318										container.find('.special-items-wrapper').html(data.data);
319										syncSpecialActive();
320									} else {
321										contentLoader.html(data.data);
322									}
323								}
324								contentLoader.imagesLoaded(function () {
325									preFunction();
326									remove_placeholder_loading();
327								});
328								if (!page_request) {
329									createPagination();
330								}
331								animateAction();
332							} else {
333								remove_placeholder_loading();
334							}
335						},
336						error: function () {
337							remove_placeholder_loading();
338						}
339					});
340					if ($('.paginationjs-pages .paginationjs-page', $page_numbers).length > 0) {
341						$page_numbers.pagination('enable');
342					}
343				},
344				syncSpecialActive = function () {
345					var activeId = container.find('#special-selected-wrapper').attr('data-id'),
346						cells = container.find('.special-items-wrapper .rt-grid-item');
347					cells.removeClass('selected');
348					if (activeId) {
349						cells.filter('[data-id="' + activeId + '"]').addClass('selected');
350					}
351				},
352				scrollToTopMember = function () {
353										// below 992 the stage stacks with the details BELOW the thumbnails,
354					// so bring the freshly loaded profile into view after a tap
355					if ($(window).width() < 992) {
356						$('html, body').animate({
357							scrollTop: $('#special-selected-wrapper').offset().top - 35
358						}, 200);
359					}
360				};
361
362			switch ($pagination_wrap.attr('data-type')) {
363				case 'load_more':
364					$loadmore.on('click', function () {
365						$(this).addClass('rt-lm-loading');
366						ttp_paged = ttp_paged + 1;
367						ajax_action(true, true);
368					});
369					break;
370				case 'pagination_ajax':
371					createPagination();
372					break;
373				case 'pagination':
374					break;
375				case 'load_on_scroll':
376					$(window).on('scroll load', function () {
377						infinite_scroll();
378					});
379					break;
380				case 'page_prev_next':
381					if (ttp_paged == 1) {
382						$page_prev_next.find('.rt-cb-prev-btn').addClass('rt-disabled');
383					}
384					if (ttp_paged == ttp_total_pages) {
385						$page_prev_next.find('.rt-cb-next-btn').addClass('rt-disabled');
386					}
387					if (ttp_total_pages == 1) {
388						$page_prev_next.addClass('rt-hidden-elm');
389					}
390					break;
391			}
392
393			if (str) {
394				var qsRegex, buttonFilter;
395				if (preLoader.find('.rt-loading-overlay').length == 0) {
396					preLoader.append(html_loading);
397				}
398
399				if (isCarousel.length) {
400					isCarousel.imagesLoaded(function () {
401						if (str === "carousel10") {
402							var carouselOptions = caroThumb.data('options');
403
404							RTElementThumbCarousel(container, carouselOptions, elementThumbInstances, index);
405							remove_placeholder_loading();
406						} else {
407							rtSliderInit($);
408						}
409
410						$(document).on('rttm_slider_loaded', function () {
411							remove_placeholder_loading();
412						});
413					});
414				} else if (isIsotope.length) {
415					if (!buttonFilter) {
416						buttonFilter = IsoButton.find('button.selected').data('filter');
417					}
418					IsotopeWrap = isIsotope.imagesLoaded(function () {
419						preFunction();
420						// Grid Style. Isotope defaults to masonry AND passing a `masonry`
421						// option pins it there, so the hardcoded option below used to make
422						// "Even" render as masonry on every isotope layout. `ttp-even` is
423						// written on the row by the renderer; its absence means masonry
424						// (the shortcode path adds no class at all in that case).
425						IsotopeWrap.isotope($.extend({
426							itemSelector: '.isotope-item',
427							filter: function () {
428								return buttonFilter ? $(this).is(buttonFilter) : true;
429							}
430						}, isIsotope.closest('.rt-row').hasClass('ttp-even')
431							? { layoutMode: 'fitRows' }
432							: { layoutMode: 'masonry', masonry: { columnWidth: '.isotope-item' } }));
433						setTimeout(function () {
434							IsotopeWrap.isotope();
435							remove_placeholder_loading();
436						}, 100);
437					});
438
439					IsoButton.on('click touchstart', 'button', function (e) {
440						e.preventDefault();
441						buttonFilter = $(this).attr('data-filter');
442						IsotopeWrap.isotope();
443						$(this).parent().find('.selected').removeClass('selected');
444						$(this).addClass('selected');
445					});
446
447				} else if (isSpecial.length) {
448					// Every member stays in the grid;
448 clicking one promotes it to the
449					// active thumbnail and loads that profile into the feature panel.
450					target = container.find('#special-selected-wrapper');
451
452					var loadSpecialMember = function (id) {
453						if (!id) {
454							remove_placeholder_loading();
455							return;
456						}
457						$.ajax({
458							url: ttp.ajaxurl,
459							type: 'POST',
460							data: { memberId: id, scID: scID, action: 'rtGetSpecialLayoutData', tlp_nonce: ttp.nonce },
461							cache: false,
462							beforeSend: function () {
463								placeholder_loading();
464							},
465							success: function (data) {
466								if (!data.error) {
467									target.attr('data-id', id);
468									target.html(data.data);
469								}
470								remove_placeholder_loading();
471							},
472							error: function () {
473								remove_placeholder_loading();
474							}
475						});
476					};
477
478					var activeCell = container.find('.special-items-wrapper .rt-grid-item.selected').first();
479					if (!activeCell.length) {
480						activeCell = container.find('.special-items-wrapper .rt-grid-item').first().addClass('selected');
481					}
482					loadSpecialMember(activeCell.attr('data-id'));
483
484					container.on('click', '.special-items-wrapper .single-team-item.image-wrapper', function (e) {
485						e.preventDefault();
486						var self = $(this),
487							cell = self.closest('.rt-grid-item'),
488							id = self.attr('data-id');
489
490						if (!id || cell.hasClass('selected')) {
491							return;
492						}
493
494						container.find('.special-items-wrapper .rt-grid-item.selected').removeClass('selected');
495						cell.addClass('selected');
496						loadSpecialMember(id);
497						scrollToTopMember();
498					});
499
500				} else if (container.find('.rt-row.rt-content-loader.ttp-masonry').length) {
501					var masonryTarget = $('.rt-row.rt-content-loader.ttp-masonry', container);
502					mIsotopeWrap = masonryTarget.imagesLoaded(function () {
503						preFunction();
504						mIsotopeWrap.isotope({
505							itemSelector: '.masonry-grid-item',
506							masonry: { columnWidth: '.masonry-grid-item' },
507							// Fade only. Isotope reveals appended items from
508							// `scale(0.001)` by default, which makes a card loaded by
509							// "Load more" balloon out of the centre of its slot on top of
510							// the fadeIn the cards already do for themselves. Overriding
511							// both styles drops the scale and leaves the card to simply
512							// appear where it belongs.
513							hiddenStyle: { opacity: 0 },
514							visibleStyle: { opacity: 1 }
515						});
516						remove_placeholder_loading();
517					});
518				} else {
519					var target = $('.rt-row.rt-content-loader.ttp-masonry', container);
520					target.imagesLoaded(function () {
521						preFunction();
522						remove_placeholder_loading();
523					});
524				}
525			}
526
527			$('#' + id).on('click', '.rt-search-filter-wrap .rt-action', function (e) {
528				search_wrap.find('input').prop("disabled", true);
529				ajax_action();
530			});
531			$('#' + id).on('keypress', '.rt-search-filter-wrap .rt-search-input', function (e) {
532				if (e.which == 13) {
533					search_wrap.find('input').prop("disabled", true);
534					ajax_action();
535				}
536			});
537			$('#' + id).on('click', '.rt-filter-dropdown-wrap', function (event) {
538				var self = $(this);
539				self.toggleClass('active-dropdown');
540			});// Dropdown click
541			$('#' + id).on('click', '.term-dropdown-item', function (event) {
542				$loadmore.addClass('rt-lm-loading');
543				var $this_item = $(this),
544					default_target = $taxonomy_filter.find('.rt-filter-dropdown-default'),
545					old_param = default_target.attr('data-term'),
546					old_text = default_target.find('.rt-text').html();
547				$this_item.parents('.rt-filter-dropdown-wrap').removeClass('active-dropdown');
548				$this_item.parents('.rt-filter-dropdown-wrap').toggleClass('active-dropdown');
549				default_target.attr('data-term', $this_item.attr('data-term'));
550				default_target.find('.rt-text').html($this_item.html());
551				$this_item.attr('data-term', old_param);
552				$this_item.html(old_text);
553				ajax_action();
554			});//term
555			$('#' + id).on('click', '.order-by-dropdown-item', function (event) {
556				$loadmore.addClass('rt-lm-loading');
557				var $this_item = $(this),
558					old_param = $default_order_by.attr('data-order-by'),
559					old_text = $default_order_by.find('.rt-text-order-by').html();
560
561				$this_item.parents('.rt-order-by-action').removeClass('active-dropdown');
562				$this_item.parents('.rt-order-by-action').toggleClass('active-dropdown');
563				$default_order_by.attr('data-order-by', $this_item.attr('data-order-by'));
564				$default_order_by.find('.rt-text-order-by').html($this_item.html());
565				$this_item.attr('data-order-by', old_param);
566				$this_item.html(old_text);
567				ajax_action();
568			});//Order By
569
570			//Sort Order
571			$('#' + id).on('click', '.rt-sort-order-action', function (event) {
572				$loadmore.addClass('rt-lm-loading');
573				var $this_item = $(this),
574					$sort_order_elm = $('.rt-sort-order-action-arrow', $this_item),
575					sort_order_param = $sort_order_elm.attr('data-sort-order');
576				if (typeof (sort_order_param) != 'undefined' && sort_order_param.toLowerCase() == 'desc') {
577					$default_order.attr('data-sort-order', 'ASC');
578				} else {
579					$default_order.attr('data-sort-order', 'DESC');
580				}
581				ajax_action();
582			});//Sort Order
583
584			$taxonomy_filter.on('click touchstart', '.rt-filter-button-item', function () {
585				var self = $(this);
586				self.parents('.rt-filter-button-wrap').find('.rt-filter-button-item').removeClass('selected');
587				self.addClass('selected');
588				ajax_action();
589			});
590
591			$page_prev_next.on('click', '.rt-cb-prev-btn', function (event) {
592				if (ttp_paged <= 1) {
593					return;
594				}
595				ttp_paged = ttp_paged - 1;
596				ajax_action(true, false);
597			});
598			$page_prev_next.on('click', '.rt-cb-next-btn', function (event) {
599				if (ttp_paged >= ttp_total_pages) {
600					return;
601				}
602				ttp_paged = ttp_paged + 1;
603				ajax_action(true, false);
604			});
605
606			// md Popup
607			// The redesigned single popup can page between MEMBERS, so the open call is
608			// a named function and the member order is read from the triggers already in
609			// this container (deduped — a card usually has several triggers: the photo,
610			// the name and the Read More link).
611			var singleMemberIds = [];
612
613			function ttpCollectSingleMembers() {
614				singleMemberIds = [];
615				container.find('.ttp-single-md-popup[data-id]').each(function () {
616					var mid = String($(this).attr('data-id'));
617					if (mid && singleMemberIds.indexOf(mid) === -1) {
618						singleMemberIds.push(mid);
619					}
620				});
621			}
622
623			function ttpOpenSinglePopup(id, isStep) {
624				id = String(id);
625				var data = "action=tlp_md_popup_single&id=" + id + "&tlp_nonce=" + ttp.nonce;
626
627				$.ajax({
628					type: "post",
629					url: ttp.ajaxurl,
630					data: data,
631					beforeSend: function () {
632						mdModalWrap.addClass("tlp-modal-" + scID);
633						mdModalWrap.addClass('md-show');
634						// Paging between members must NOT tear the card out: `.tlp-md-loading` is
635					// absolutely positioned, so replacing the holder with it leaves the shell
636					// with no in-flow content and the modal collapses to height 0 (measured:
637					// 583 -> 0 -> 538 across one click). Keep the outgoing card, drop
638					// `is-ready` so the existing CSS fades it to the spinner, and pin the
639					// height so it cannot collapse while the next member loads.
640					var $pop = mdModalWrap.find('.rttm-pop');
641					if (isStep && $pop.length) {
642						ttpPopLockHeight();
643						$pop.removeClass('is-ready');
644					} else {
645						mdModalWrap.find('.tlp-md-content-holder').html('<div class="tlp-md-loading">Loading...</div>');
646					}
647						// The visible card is `.rttm-pop` INSIDE .md-content, so painting the
648						// holder put the colour behind an opaque surface and the control
649						// appeared to do nothing. Set the surface token on the shell instead
650						// — every surface the popup owns reads it.
651						if (popupBg) {
652							mdModalWrap[0].style.setProperty('--rttm-pop-surface', popupBg);
653						}
654						// Carry the opening container's Primary Color onto the shared modal so
655						// the popup's pills, icon chips, skill bars and buttons use the same
656						// accent as the cards instead of the design's fallback blue.
657						var rttmPrim = (getComputedStyle(container[0]).getPropertyValue('--l1-primary') || '').trim();
658						if (rttmPrim) {
659							mdModalWrap[0].style.setProperty('--rttm-pop-primary', rttmPrim);
660						} else {
661							mdModalWrap[0].style.removeProperty('--rttm-pop-primary');
662						}
663
664					},
665					success: function (data) {
666						mdModalWrap.find('.tlp-md-content-holder').html(data.data);
667						// The modal is shared by every shortcode on the page, so the member
668						// list travels ON it rather than in a per-container closure.
669						mdModalWrap.data('rttmMember', id);
670						mdModalWrap.data('rttmMembers', singleMemberIds);
671						ttpSyncPager();
672						ttpRefreshGallery();
673						ttpPopReady(ttpPopReleaseHeight);
674					},
675					error: function (e) {
676						console.log(e);
677					}
678				});
679			}
680
681			// Hide the pager when there is nothing to page to; otherwise it is a wrap-around
682			// so neither button is ever disabled.
683			// Reveal the card as ONE piece, only once its photos have decoded. The AJAX
684			// lands ~60ms after the open animation starts, so without this the modal
685			// scales in empty and the content then the image snap in mid-flight.
686			// The 8s guard means a blocked image can never leave the card hidden.
687			function ttpPopShell() {
688				return mdModalWrap.find('.md-content').first();
689			}
690
691			// Pin the shell to its current height so the swap cannot collapse the modal.
692			function ttpPopLockHeight() {
693				var $el = ttpPopShell();
694				if ($el.length) {
695					$el.css('height', $el.outerHeight() + 'px');
696				}
697			}
698
699			// Ease from the pinned height to whatever the new member needs, then hand the
700			// box back to auto so nothing is left inline-styled.
701			function ttpPopReleaseHeight() {
702				var $el = ttpPopShell();
703				if (!$el.length || !$el[0].style.height) {
704					return;
705				}
706				var from = $el[0].style.height;
707				$el.css('height', '');
708				var to = $el.outerHeight();
709				$el.css('height', from);
710				void $el[0].offsetWidth;
711				$el.css({ transition: 'height .35s cubic-bezier(.4, 0, .2, 1)', height: to + 'px' });
712				setTimeout(function () {
713					$el.css({ transition: '', height: '' });
714				}, 400);
715			}
716
717			function ttpPopReady(onReady) {
718				var pop = mdModalWrap.find('.rttm-pop');
719				if (!pop.length) {
720					return;
721				}
722				pop.removeClass('is-ready');
723
724				var imgs = pop.find('.rttm-pop-gallery img').get(),
725					pending = imgs.length,
726					reveal = function () {
727						// Force a style flush, then flip on the next frame. Adding the class
728						// in the same frame as the insert lets the browser collapse the
729						// before/after states into one, so the cross-fade never runs and the
730						// card just appears — which is what made the open look snappy/janky.
731						void pop[0].offsetWidth;
732						window.requestAnimationFrame(function () {
733							pop.addClass('is-ready');
734							if (typeof onReady === 'function') {
735								onReady();
736							}
737						});
738					};
739
740				if (!pending) {
741					reveal();
742					return;
743				}
744
745				var settle = function () {
746					pending -= 1;
747					if (pending <= 0) {
748						reveal();
749					}
750				};
751
752				$.each(imgs, function (i, img) {
753					if (img.complete && img.naturalWidth) {
754						settle();
755					} else {
756						$(img).one('load error', settle);
757					}
758				});
759
760				setTimeout(reveal, 8000);
761			}
762
763			// Swiper measures the gallery while the modal is still mid open-transition
764			// (scaled down), so slide widths come out wrong and two part-slides show.
765			// Re-measure once the transition has settled.
766			function ttpRefreshGallery() {
767				setTimeout(function () {
768					mdModalWrap.find('.rttm-pop-gallery .swiper').each(function () {
769						if (this.swiper) {
770							this.swiper.update();
771						}
772					});
773				}, 450);
774			}
775
776			function ttpSyncPager() {
777				var pager = mdModalWrap.find('.rttm-pop-pager');
778				if (!pager.length) {
779					return;
780				}
781				if (singleMemberIds.length < 2) {
782					pager.hide();
783				} else {
784					pager.show();
785				}
786			}
787
788			function ttpStepMember(step) {
789				var ids = mdModalWrap.data('rttmMembers') || [];
790				var open = mdModalWrap.data('rttmOpen');
791				if (ids.length < 2 || typeof open !== 'function') {
792					return;
793				}
794				var cur = String(mdModalWrap.data('rttmMember') || '');
795				var i = ids.indexOf(cur);
796				if (i === -1) {
797					i = 0;
798				}
799				open(ids[(i + step + ids.length) % ids.length], true);
800			}
801
802			$(document).on('click', '.ttp-single-md-popup', function (e) {
803				// This handler is bound once PER CONTAINER, so on a page with more than
804				// one shortcode every copy fires. Only the container that actually owns
805				// the clicked trigger may respond — otherwise the last copy to run wins
806				// and overwrites the member list with its own (often empty) one.
807				if (!container.has(this).length) {
808					return;
809				}
810				e.preventDefault();
811				ttpCollectSingleMembers();
812				// Hand the pager THIS container's opener, so paging keeps using the
813				// scID / popup background of the shortcode that was actually clicked.
814				mdModalWrap.data('rttmOpen', ttpOpenSinglePopup);
815				ttpOpenSinglePopup($(this).attr("data-id"));
816				return false;
817			});
818
819			// Bind the pager ONCE. `#tlp-modal` is a single shared element, so binding
820			// inside this per-container loop would fire the handler once per shortcode
821			// on the page and race between their member lists.
822			if (!mdModalWrap.data('rttmPagerBound')) {
823				mdModalWrap.data('rttmPagerBound', true);
824				mdModalWrap.on('click', '.rttm-pop-prev', function (e) {
825					e.preventDefault();
826					ttpStepMember(-1);
827				});
828				mdModalWrap.on('click', '.rttm-pop-next', function (e) {
829					e.preventDefault();
830					ttpStepMember(1);
831				});
832			}
833
834			// ---------- smart popup ----------
835			// A right-hand drawer over a blurred backdrop. The shell is built once per
836			// open and survives every member step; only `.rt-smart-modal-main-content` is
837			// swapped. The state the stepper needs travels ON the shell via .data(), so
838			// the delegated handlers bound at build time keep working after each swap.
839			$(document).on('click', '.ttp-smart-popup', function (e) {
840				e.preventDefault();
841
842				var self = $(this);
843
844				// Bound inside the per-container .each(), so on a page with two widgets
845				// both copies run; without this the last one wins and opens the drawer
846				// with the wrong member list.
847				if (!container.has(this).length) {
848					return false;
849				}
850
851				var current = String(self.attr('data-id')),
852					contentLoader = $('.rt-row.rt-content-loader', container),
853					itemArray = $.map(getItemsArray(contentLoader), function (v) { return String(v); }),
854					$wrap = ttpSpBuild(scID);
855
856				$wrap.data('rttmList', itemArray);
857
858				// The drawer paints every surface it owns from --rttm-pop-surface, so the
859				// token covers the panel and the scrolling body together. The gradient bar
860				// is deliberately left alone — it follows Primary Color, exactly as the
861				// Elementor path keeps PopUp Header Background separate from PopUp
862				// Background.
863				if (popupBg) {
864					$wrap[0].style.setProperty('--rttm-pop-surface', popupBg);
865				}
866
867				// Carry the opening container's Primary Color onto the drawer — the shell
868				// lives outside the widget wrapper, so no per-widget selector reaches it.
869				var rttmPrim = (getComputedStyle(container[0]).getPropertyValue('--l1-primary') || '').trim();
870				if (rttmPrim) {
871					$wrap[0].style.setProperty('--rttm-pop-primary', rttmPrim);
872				} else {
873					$wrap[0].style.removeProperty('--rttm-pop-primary');
874				}
875
876				ttpSpLoad($wrap, current, false);
877
878				return false;
879			});
880
881			// ---------- multiple popup ----------
882			// One shared viewer element; the state it needs to step between members
883			// travels ON it via .data(), so the delegated handlers built with the shell
884			// keep working after every panel swap.
885			$(document).on('click', '.ttp-multi-popup', function () {
886				var self = $(this);
887
888				// `.ttp-multi-popup` is bound inside the per-container .each(), so on a
889				// page with two widgets both copies run; without this the last one wins
890				// and opens the viewer with the wrong member list.
891				if (!container.has(this).length) {
892					return;
893				}
894
895				var current = String(self.attr('data-id')),
896					contentLoader = self.parents('.rt-team-container').children('.rt-row.rt-content-loader'),
897					itemArray = $.map(getItemsArray(contentLoader), function (v) { return String(v); }),
898					$wrap = ttpMpopBuild();
899
900				$wrap.addClass('tlp-popup-wrap-' + scID);
901				$wrap.data('rttmList', itemArray);
902				$wrap.data('rttmContainer', container);
903
904				// This used to paint only the top BAR, so the viewer's stage — the surface
905				// the control is named for — stayed white. The token covers the stage and
906				// the thumbnail strip; the bar follows Primary Color.
907				if (popupBg) {
908					$wrap[0].style.setProperty('--rttm-pop-surface', popupBg);
909				}
910
911				// Carry the opening container's Primary Color onto the viewer, exactly as
912				// the single popup does — the shell lives outside the widget wrapper, so
913				// no per-widget selector can reach it.
914				var rttmPrim = (getComputedStyle(container[0]).getPropertyValue('--l1-primary') || '').trim();
915				if (rttmPrim) {
916					$wrap[0].style.setProperty('--rttm-pop-primary', rttmPrim);
917				} else {
918					$wrap[0].style.removeProperty('--rttm-pop-primary');
919				}
920
921				ttpMpopLoad($wrap, current, 0);
922
923				return false;
924			});
925
926
927		});
928	};
929	initTlpTeam();
930	function preFunction() {
931		HeightResize();
932	}
933
934	function equalHeight4Layout4() {
935		var $maxH = $(".rt-row.rt-content-loader.layout4 .layout4item").height();
936		$(".rt-row.rt-content-loader.layout4 .layout4item .layoutInner .rt-img-holder img,.rt-row.rt-content-loader.layout4 .layout4item .layoutInner.layoutInner-content").height($maxH + "px");
937	}
938
939    function HeightResize() {
940        if($(".rt-team-container[data-layout*='layout']").length > 0) {
941            return;
942        }
943
944        var wWidth = $(window).width();
945        $(".rt-team-container").each(function () {
946            var self = $(this),
947                dCol = self.data('desktop-col'),
948                tCol = self.data('tab-col'),
949                mCol = self.data('mobile-col'),
950                target = $(this).find('.rt-row.rt-content-loader.ttp-even');
951            if ((wWidth >= 992 && dCol > 1) || (wWidth >= 768 && tCol > 1) || (wWidth < 768 && mCol > 1)) {
952                target.imagesLoaded(function () {
953                    var tlpMaxH = 0;
954                    target.find('.even-grid-item').height('auto');
955                    target.find('.even-grid-item').each(function () {
956                        var $thisH = $(this).outerHeight();
957                        if ($thisH > tlpMaxH) {
958                            tlpMaxH = $thisH;
959                        }
960                    });
961                    target.find('.even-grid-item').height(tlpMaxH + "px");
962                });
963            } else {
964                target.find('.even-grid-item').height('auto');
965            }
966
967        });
968        if ($(".rt-row.rt-content-loader.layout4").length) {
969            equalHeight4Layout4();
970        }
971    }
972
973	/* ---------- smart popup: the right-hand drawer ----------
974	   The shell keeps every legacy hook class (.rt-smart-modal-main,
975	   .rt-smart-modal-header, .rt-smart-modal-nav, .rt-smart-nav-item,
976	   .rt-smart-modal-close, .rt-smart-modal, .rt-smart-modal-main-content-wrapper)
977	   because user Style controls are wired to them — see
978	   ElementorFilters::colorControls() "PopUp Colors" and the smart-modal arms in
979	   Fns::layoutStyleGenerator() and templates/sc-css.php. */
980
981	function ttpSpClose() {
982		var $wrap = $('#rt-smart-modal-container');
983		if (!$wrap.length) {
984			return;
985		}
986		$('html').removeClass('rt-smart-modal-on');
987		$wrap.removeClass('open');
988		setTimeout(function () {
989			$wrap.remove();
990		}, 450);
991	}
992
993	function ttpSpBuild(scID) {
994		$('#rt-smart-modal-container').remove();
995
996		var html =
997			'<div id="rt-smart-modal-container" class="rt-modal-' + scID + ' rttm-sp">' +
998			'<div class="rt-smart-modal-main">' +
999			'<div class="rt-smart-modal-header">' +
1000			'<span class="rt-smart-modal-nav">' +
1001			'<a href="#" class="rt-smart-nav-left rt-smart-nav-item" aria-label="Previous member"><i class="fa fa-chevron-left" aria-hidden="true"></i></a>' +
1002			'<a href="#" class="rt-smart-nav-right rt-smart-nav-item" aria-label="Next member"><i class="fa fa-chevron-right" aria-hidden="true"></i></a>' +
1003			'</span>' +
1004			'<a href="#" class="rt-smart-modal-close" aria-label="Close"><i class="fa fa-times" aria-hidden="true"></i></a>' +
1005			'</div>' +
1006			'<div class="rt-smart-modal"><div class="rt-smart-modal-main-content-wrapper"></div></div>' +
1007			'</div>' +
1008			'</div>';
1009
1010		$('body').append(html);
1011		$('html').addClass('rt-smart-modal-on');
1012
1013		var $wrap = $('#rt-smart-modal-container');
1014
1015		// Adding the reveal class in the same frame as the insert collapses both states
1016		// and the drawer just appears; force a style flush first.
1017		void $wrap[0].offsetWidth;
1018		requestAnimationFrame(function () {
1019			$wrap.addClass('open');
1020		});
1021
1022		$wrap.on('click', '.rt-smart-modal-close', function (e) {
1023			e.preventDefault();
1024			ttpSpClose();
1025			return false;
1026		});
1027		$wrap.on('click', '.rt-smart-nav-right', function (e) {
1028			e.preventDefault();
1029			ttpSpStep($wrap, 1);
1030			return false;
1031		});
1032		$wrap.on('click', '.rt-smart-nav-left', function (e) {
1033			e.preventDefault();
1034			ttpSpStep($wrap, -1);
1035			return false;
1036		});
1037		$wrap.on('click', '.rttm-sp-garrow', function () {
1038			ttpSpShot($wrap, $(this).hasClass('next') ? 1 : -1, false);
1039			return false;
1040		});
1041		$wrap.on('click', '.rttm-sp-dot', function () {
1042			ttpSpShot($wrap, parseInt($(this).attr('data-i'), 10), true);
1043			return false;
1044		});
1045		// clicking the dimmed backdrop closes; clicks inside the drawer must not
1046		$wrap.on('click', function (e) {
1047			if (e.target === this) {
1048				ttpSpClose();
1049			}
1050		});
1051
1052		return $wrap;
1053	}
1054
1055	/* hero slider — a plain cross-fade, so nothing has to measure a drawer that is
1056	   still sliding in */
1057	function ttpSpShot($wrap, value, absolute) {
1058		var $slides = $wrap.find('.rttm-sp-slide'),
1059			$dots = $wrap.find('.rttm-sp-dot');
1060
1061		if (!$slides.length) {
1062			return;
1063		}
1064
1065		var cur = $slides.index($slides.filter('.is-active'));
1066		if (cur < 0) {
1067			cur = 0;
1068		}
1069
1070		var i = absolute ? value : cur + value;
1071		i = ((i % $slides.length) + $slides.length) % $slides.length;
1072
1073		$slides.removeClass('is-active').eq(i).addClass('is-active');
1074		$dots.removeClass('is-active').eq(i).addClass('is-active');
1075	}
1076
1077	function ttpSpStep($wrap, delta) {
1078		var list = $wrap.data('rttmList') || [],
1079			cur = String($wrap.data('rttmCurrent'));
1080
1081		if (list.length < 2) {
1082			return;
1083		}
1084
1085		var i = $.inArray(cur, list);
1086		if (i < 0) {
1087			i = 0;
1088		}
1089		i = (i + delta + list.length) % list.length;
1090
1091		ttpSpLoad($wrap, list[i], true);
1092	}
1093
1094	/* Loads one member. `swap` is false on first open (spinner) and true when stepping,
1095	   which fades the outgoing panel out and the new one back in. */
1096	function ttpSpLoad($wrap, id, swap) {
1097		var $body = $wrap.find('.rt-smart-modal'),
1098			$holder = $wrap.find('.rt-smart-modal-main-content-wrapper'),
1099			$old = $holder.find('.rttm-sp-panel'),
1100			list = $wrap.data('rttmList') || [];
1101
1102		$wrap.data('rttmCurrent', String(id));
1103		// hide the stepper when there is only one member to step to
1104		$wrap.find('.rt-smart-modal-nav').css('display', list.length > 1 ? '' : 'none');
1105
1106		var data = {
1107			action: 'tlp_team_smart_popup',
1108			id: id
1109		};
1110		data[ttp.nonceID] = ttp.nonce;
1111
1112		var fire = function () {
1113			$.ajax({
1114				type: 'post',
1115				url: ttp.ajaxurl,
1116				data: data,
1117				beforeSend: function () {
1118					if (!swap) {
1119						$wrap.addClass('loading');
1120						$holder.html('<span class="rt-spinner"></span>');
1121					}
1122				},
1123				success: function (response) {
1124					$wrap.removeClass('loading').addClass('ready');
1125					$holder.html(response.data);
1126					$body.scrollTop(0);
1127
1128					var $panel = $holder.find('.rttm-sp-panel');
1129					if (swap && $panel.length) {
1130						$panel.addClass('is-swapping');
1131						void $panel[0].offsetWidth;
1132						requestAnimationFrame(function () {
1133							$panel.removeClass('is-swapping');
1134						});
1135					}
1136
1137					ttpSpSkills($wrap);
1138				},
1139				error: function (e) {
1140					console.log(e);
1141					$wrap.removeClass('loading');
1142					$holder.html('<p>Loading error!!!</p>');
1143				}
1144			});
1145		};
1146
1147		if (swap && $old.length) {
1148			$old.addClass('is-swapping');
1149			setTimeout(fire, 200);
1150		} else {
1151			fire();
1152		}
1153	}
1154
1155	/* the skill bars animate from 0 to their data-progress-animation width */
1156	function ttpSpSkills($wrap) {
1157		$('.tlp-tooltip', $wrap).rtTooltip();
1158		$('.tlp-team-skill', $wrap).find('.fill').css('width', '0%');
1159		$('.tlp-team-skill .fill', $wrap).each(function () {
1160			var k = 0,
1161				f = $(this),
1162				p = f.attr('data-progress-animation'),
1163				w = f.width();
1164			if (w == 0 && p) {
1165				p = p.substring(0, p.length - 1);
1166				var go = function () {
1167					return k >= p || k >= 100 ? false : ((k += 1), f.css('width', k + '%'), setTimeout(go, 20));
1168				};
1169				go();
1170			}
1171		});
1172	}
1173
1174	/* Bound ONCE — the old code re-bound its close/nav handlers on every card click. */
1175	$(document).on('keydown.rttmSp', function (event) {
1176		var $wrap = $('#rt-smart-modal-container.open');
1177
1178		if (!$wrap.length) {
1179			return;
1180		}
1181
1182		if (event.keyCode === 27) {
1183			ttpSpClose();
1184		} else if (event.keyCode === 37) {
1185			ttpSpStep($wrap, -1);
1186		} else if (event.keyCode === 39) {
1187			ttpSpStep($wrap, 1);
1188		}
1189	});
1190
1191	/* ---------- multiple popup: the fullscreen viewer ----------
1192	   The shell is built once per open and survives every member step; only the panel
1193	   inside `.tlp-popup-content` is swapped. Every legacy hook class is kept on it
1194	   (.tlp-popup-navigation-wrap, .tlp-popup-navigation, .tlp-popup-prev/-close/-next,
1195	   .tlp-popup-content and the counter) because user Style controls are wired to
1196	   them — see ElementorFilters::colorControls() "PopUp Colors" and the popup
1197	   background block in Fns::layoutStyleGenerator(). */
1198
1199	function ttpMpopClose() {
1200		var $wrap = $('#tlp-popup-wrap');
1201		if (!$wrap.length) {
1202			return;
1203		}
1204		$wrap.removeClass('is-open');
1205		setTimeout(function () {
1206			$wrap.remove();
1207		}, 350);
1208	}
1209
1210	function ttpMpopBuild() {
1211		$('#tlp-popup-wrap').remove();
1212
1213		var html =
1214			'<div id="tlp-popup-wrap" class="tlp-popup-wrap rttm-mpop">' +
1215			'<div class="tlp-popup-navigation-wrap rttm-mpop-bar">' +
1216			'<div class="tlp-popup-singlePage-counter rttm-mpop-counter"><b class="ccurrent"></b> <span class="rttm-mpop-of">' + ttp.lan.of + '</span> <span class="ctotal"></span></div>' +
1217			'<div class="tlp-popup-navigation rttm-mpop-controls">' +
1218			'<button type="button" class="tlp-popup-prev rttm-mpop-ctrl" title="Previous (Left arrow key)" data-action="prev" aria-label="Previous member"><i class="fas fa-chevron-left"></i></button>' +
1219			'<button type="button" class="tlp-popup-close rttm-mpop-ctrl is-close" title="Close (Esc key)" data-action="close" aria-label="Close"><i class="fas fa-times"></i></button>' +
1220			'<button type="button" class="tlp-popup-next rttm-mpop-ctrl" title="Next (Right arrow key)" data-action="next" aria-label="Next member"><i class="fas fa-chevron-right"></i></button>' +
1221			'</div>' +
1222			'<div class="rttm-mpop-spacer"></div>' +
1223			'<div class="rttm-mpop-progress"></div>' +
1224			'</div>' +
1225			'<div class="tlp-popup-content rttm-mpop-stage"><div class="rttm-mpop-loading"></div></div>' +
1226			'<div class="rttm-mpop-strip"></div>' +
1227			'</div>';
1228
1229		$('body').append(html);
1230
1231		var $wrap = $('#tlp-popup-wrap');
1232
1233		// Adding the reveal class in the same frame as the insert collapses both states
1234		// and the viewer just appears; force a style flush first.
1235		void $wrap[0].offsetWidth;
1236		requestAnimationFrame(function () {
1237			$wrap.addClass('is-open');
1238		});
1239
1240		$wrap.on('click', '.tlp-popup-close', function () {
1241			ttpMpopClose();
1242			return false;
1243		});
1244		$wrap.on('click', '.tlp-popup-prev', function () {
1245			ttpMpopStep($wrap, -1);
1246			return false;
1247		});
1248		$wrap.on('click', '.tlp-popup-next', function () {
1249			ttpMpopStep($wrap, 1);
1250			return false;
1251		});
1252		$wrap.on('click', '.rttm-mpop-thumb', function () {
1253			var id = String($(this).attr('data-id')),
1254				list = $wrap.data('rttmList') || [],
1255				cur = String($wrap.data('rttmCurrent'));
1256			if (id === cur) {
1257				return false;
1258			}
1259			ttpMpopLoad($wrap, id, $.inArray(id, list) > $.inArray(cur, list) ? 1 : -1);
1260			return false;
1261		});
1262		$wrap.on('click', '.rttm-mpop-garrow', function () {
1263			ttpMpopShot($wrap, $(this).hasClass('next') ? 1 : -1, false);
1264			return false;
1265		});
1266		$wrap.on('click', '.rttm-mpop-dot', function () {
1267			ttpMpopShot($wrap, parseInt($(this).attr('data-i'), 10), true);
1268			return false;
1269		});
1270
1271		return $wrap;
1272	}
1273
1274	/* counter, progress bar, and hiding the stepper when there is only one member */
1275	function ttpMpopLevel($wrap, current, list) {
1276		var index = $.inArray(String(current), list) + 1,
1277			count = list.length;
1278
1279		$wrap.find('.ccurrent').text(index || 1);
1280		$wrap.find('.ctotal').text(count);
1281		$wrap.find('.rttm-mpop-progress').css('width', count ? ((index || 1) / count) * 100 + '%' : 0);
1282		$wrap.find('.tlp-popup-prev, .tlp-popup-next').css('display', count > 1 ? '' : 'none');
1283	}
1284
1285	/* The strip mirrors exactly the members the viewer can step through — the visible
1286	   cards getItemsArray() counts — so the thumbnails come from the opening
1287	   container's own cards rather than a second query. */
1288	function ttpMpopStrip($wrap, container, list, current) {
1289		var $strip = $wrap.find('.rttm-mpop-strip');
1290
1291		if (!$strip.length) {
1292			return;
1293		}
1294
1295		if (!container || list.length < 2) {
1296			$strip.empty();
1297			return;
1298		}
1299
1300		if ($strip.data('rttmFor') !== list.join(',')) {
1301			var html = '';
1302			$.each(list, function (i, id) {
1303				var $img = container.find('.rt-grid-item[data-id="' + id + '"]').first().find('img').first(),
1304					src = $img.attr('src') || '',
1305					alt = ($img.attr('alt') || '').replace(/"/g, '');
1306				html +=
1307					'<button type="button" class="rttm-mpop-thumb" data-id="' + id + '" aria-label="' + alt + '">' +
1308					(src ? '<img src="' + src + '" alt="' + alt + '" />' : '') +
1309					'</button>';
1310			});
1311			$strip.html(html).data('rttmFor', list.join(','));
1312		}
1313
1314		$strip.find('.rttm-mpop-thumb').each(function () {
1315			$(this).toggleClass('is-active', String($(this).attr('data-id')) === String(current));
1316		});
1317	}
1318
1319	/* photo slider inside the panel — a plain cross-fade, so nothing has to measure a
1320	   container that is still fading in */
1321	function ttpMpopShot($wrap, value, absolute) {
1322		var $slides = $wrap.find('.rttm-mpop-slide'),
1323			$dots = $wrap.find('.rttm-mpop-dot');
1324
1325		if (!$slides.length) {
1326			return;
1327		}
1328
1329		var cur = $slides.index($slides.filter('.is-active'));
1330		if (cur < 0) {
1331			cur = 0;
1332		}
1333
1334		var i = absolute ? value : cur + value;
1335		i = ((i % $slides.length) + $slides.length) % $slides.length;
1336
1337		$slides.removeClass('is-active').eq(i).addClass('is-active');
1338		$dots.removeClass('is-active').eq(i).addClass('is-active');
1339	}
1340
1341	function ttpMpopStep($wrap, delta) {
1342		var list = $wrap.data('rttmList') || [],
1343			cur = String($wrap.data('rttmCurrent'));
1344
1345		if (list.length < 2) {
1346			return;
1347		}
1348
1349		var i = $.inArray(cur, list);
1350		if (i < 0) {
1351			i = 0;
1352		}
1353		i = (i + delta + list.length) % list.length;
1354
1355		ttpMpopLoad($wrap, list[i], delta);
1356	}
1357
1358	/* Loads one member. `dir` is 0 on first open and ±1 when stepping, which drives the
1359	   slide-out / slide-back-in: the outgoing panel leaves in the direction of travel
1360	   and the incoming one arrives from the opposite side. */
1361	function ttpMpopLoad($wrap, id, dir) {
1362		var $stage = $wrap.find('.rttm-mpop-stage'),
1363			$old = $stage.find('.rttm-mpop-card'),
1364			list = $wrap.data('rttmList') || [];
1365
1366		$wrap.data('rttmCurrent', String(id));
1367		ttpMpopLevel($wrap, id, list);
1368		ttpMpopStrip($wrap, $wrap.data('rttmContainer'), list, id);
1369
1370		var fire = function () {
1371			$.ajax({
1372				type: 'post',
1373				url: ttp.ajaxurl,
1374				data: ttp.nonceID + '=' + ttp.nonce + '&action=tlp_multi_popup_single&id=' + id,
1375				success: function (data) {
1376					$stage.html(data.data);
1377
1378					var $card = $stage.find('.rttm-mpop-card');
1379					if (dir && $card.length) {
1380						$card[0].style.setProperty('--rttm-mpop-swap', dir > 0 ? '24px' : '-24px');
1381						$card.addClass('is-swapping');
1382						void $card[0].offsetWidth;
1383						requestAnimationFrame(function () {
1384							$card.removeClass('is-swapping');
1385						});
1386					}
1387
1388					tlpSingleTeamScript();
1389				},
1390				error: function (e) {
1391					console.log(e);
1392					$stage.html('<p>Loading error!!!</p>');
1393				}
1394			});
1395		};
1396
1397		if (dir && $old.length) {
1398			$old[0].style.setProperty('--rttm-mpop-swap', dir > 0 ? '-24px' : '24px');
1399			$old.addClass('is-swapping');
1400			setTimeout(fire, 220);
1401		} else {
1402			$stage.html('<div class="rttm-mpop-loading"></div>');
1403			fire();
1404		}
1405	}
1406
1407	/* Bound ONCE. The old code bound this inside the card click handler, so every card
1408	   ever clicked added another listener and a single arrow press stepped several
1409	   times. */
1410	$(document).on('keydown.rttmMpop', function (event) {
1411		var $wrap = $('#tlp-popup-wrap.is-open');
1412
1413		if (!$wrap.length) {
1414			return;
1415		}
1416
1417		if (event.keyCode === 27) {
1418			ttpMpopClose();
1419		} else if (event.keyCode === 37) {
1420			ttpMpopStep($wrap, -1);
1421		} else if (event.keyCode === 39) {
1422			ttpMpopStep($wrap, 1);
1423		}
1424	});
1425
1426	/* the viewer sizes itself from the viewport; the old slide-in panel needed a
1427	   display:block nudge on resize, this one must never be forced visible. */
1428	function navResize() {}
1429
1430	$(window).on('load resize', function () {
1431		navResize();
1432		HeightResize();
1433		if ($(".tlp-md-content").length) {
1434			$(".tlp-md-content").mCustomScrollbar({
1435				scrollbarPosition: "outside"
1436			});
1437		}
1438	});
1439	$.fn.alterClass = function (removals, additions) {
1440		var self = this;
1441		if (removals.indexOf('*') === -1) {
1442			// Use native jQuery methods if there is no wildcard matching
1443			self.removeClass(removals);
1444			return !additions ? self : self.addClass(additions);
1445		}
1446		var patt = new RegExp('\\s' +
1447			removals.replace(/\*/g, '[A-Za-z0-9-_]+').split(' ').join('\\s|\\s') +
1448			'\\s', 'g');
1449		self.each(function (i, it) {
1450			var cn = ' ' + it.className + ' ';
1451			while (patt.test(cn)) {
1452				cn = cn.replace(patt, ' ');
1453			}
1454			it.className = $.trim(cn);
1455		});
1456		return !additions ? self : self.addClass(additions);
1457	};
1458
1459	$('.md-close').on('click', function (e) {
1460		e.preventDefault();
1461		mdModalWrap.removeClass('md-show');
1462		mdModalWrap.alterClass('tlp-modal-*');
1463		mdModalWrap.find('.tlp-md-content-holder').html('');
1464	});
1465
1466	skillAnimation();
1467
1468	if( $('.tlp-tooltip').length > 0 ) {
1469		$('.tlp-tooltip').rtTooltip();
1470	}
1471
1472	var RttmSlider = function ($slider) {
1473		this.$slider = $slider;
1474		this.slider = this.$slider.get(0);
1475		this.swiperSlider = this.slider.swiper || null;
1476		this.defaultOptions = {
1477			breakpointsInverse: true,
1478			observer: true,
1479			navigation: {
1480				nextEl: this.$slider.find('.swiper-button-next').get(0),
1481				prevEl: this.$slider.find('.swiper-button-prev').get(0),
1482			},
1483			pagination: {
1484				el: this.$slider.find('.swiper-pagination').get(0),
1485				type: 'bullets',
1486				clickable: true
1487			}
1488		};
1489
1490		this.slider_enabled = 'function' === typeof Swiper;
1491		this.options = Object.assign({}, this.defaultOptions, this.$slider.data('options') || {});
1492		this.initSlider = function () {
1493			if (!this.slider_enabled) {
1494				return;
1495			}
1496			if (this.options.rtl) {
1497				this.$slider.attr('dir', 'rtl');
1498			}
1499			if (this.swiperSlider) {
1500				this.swiperSlider.parents = this.options;
1501				this.swiperSlider.update();
1502			} else {
1503				this.swiperSlider = new Swiper(this.$slider.get(0), this.options);
1504			}
1505		};
1506		this.imagesLoaded = function () {
1507			if(this.$slider.data('options').lazy) {
1508				this.$slider.trigger('rttm_slider_loaded', this);
1509				return;
1510			}
1511
1512			var that = this;
1513
1514			if (!$.isFunction($.fn.imagesLoaded) || $.fn.imagesLoaded.done) {
1515				this.$slider.trigger('rttm_slider_loading', this);
1516				this.$slider.trigger('rttm_slider_loaded', this);
1517				return;
1518			}
1519
1520			this.$slider.imagesLoaded().progress(function (instance, image) {
1521				that.$slider.trigger('rttm_slider_loading', [that]);
1522			}).done(function (instance) {
1523				that.$slider.trigger('rttm_slider_loaded', [that]);
1524			});
1525		};
1526		this.start = function () {
1527			var that = this;
1528			this.$slider.on('rttm_slider_loaded', this.init.bind(this));
1529			setTimeout(function () {
1530				that.imagesLoaded();
1531			}, 1);
1532		};
1533		this.init = function () {
1534			this.initSlider();
1535		};
1536		this.rtSwiper = function () {
1537			return new Swiper(this.$slider.get(0), this.options);
1538		};
1539
1540		this.start();
1541	};
1542
1543	$.fn.rttm_slider = function () {
1544		new RttmSlider(this);
1545		return this;
1546	};
1547	window.rttmpBuilderInit = {
1548		initSlider: function () {
1549			var $ = jQuery;
1550			rtSliderInit($);
1551		},
1552		initLoader: function () {
1553			$(".rttmp-team-builder").each(function (index) {
1554				var container = $(this),
1555					loader = container.find(".rt-content-loader");
1556
1557				loader.find('.rt-loading').fadeOut(300);
1558				loader.removeClass('ttp-pre-loader');
1559			});
1560
1561		}
1562	};
1563	rttmpBuilderInit.initLoader();
1564	rttmpBuilderInit.initSlider()
1565
1566
1567})(jQuery);
1568
1569function rtSliderInit($) {
1570	$('.rttm-carousel-slider').each(function () {
1571		$(this).rttm_slider();
1572	});
1573}
1574
1575function skillAnimation() {
1576	jQuery('.tlp-team-skill').find('.fill').css('width', '0%');
1577	jQuery(window).bind('load', function () {
1578		jQuery('.tlp-team-skill').each(function () {
1579			jQuery(this).find('.fill').each(function () {
1580				var k = 0, f = jQuery(this), p = f.attr('data-progress-animation'), w = f.width();
1581				if (w == 0) {
1582					p = p.substring(0, p.length - 1);
1583					var go = function () {
1584						return k >= p || k >= 100 ? (false) : (k += 1, f.css('width', k + '%'), setTimeout(go, 20))
1585					};
1586					go();
1587				}
1588			});
1589		});
1590	});
1591}
1592
1593function mdPopUpSkillAnimation() {
1594	rtSliderInit(jQuery);
1595	jQuery('#tlp-modal .tlp-md-content').mCustomScrollbar({
1596		scrollbarPosition: 'outside'
1597	});
1598	jQuery('#tlp-modal .tlp-tooltip').rtTooltip();
1599	jQuery('#tlp-modal .tlp-team-skill').find('.fill').css('width', '0%');
1600
1601	jQuery('#tlp-modal .tlp-team-skill').each(function () {
1602		jQuery(this).find('.fill').each(function () {
1603			var k = 0, f = jQuery(this), p = f.attr('data-progress-animation'), w = f.width();
1604			if (w == 0) {
1605				p = p.substring(0, p.length - 1);
1606				var go = function () {
1607					return k >= p || k >= 100 ? (false) : (k += 1, f.css('width', k + '%'), setTimeout(go, 20))
1608				};
1609				go();
1610			}
1611		});
1612	});
1613}
1614
1615function tlpSingleTeamScript() {
1616	jQuery('#tlp-popup-wrap .tlp-tooltip').rtTooltip();
1617	jQuery('#tlp-popup-wrap .tlp-team-skill').find('.fill').css('width', '0%');
1618	jQuery('#tlp-popup-wrap .tlp-team-skill .fill').each(function () {
1619		var k = 0, f = jQuery(this), p = f.attr('data-progress-animation'), w = f.width();
1620		if (w == 0) {
1621			p = p.substring(0, p.length - 1);
1622			var go = function () {
1623				return k >= p || k >= 100 ? (false) : (k += 1, f.css('width', k + '%'), setTimeout(go, 20))
1624			};
1625			go();
1626		}
1627	});
1628	rtSliderInit(jQuery);
1629}
1630
1631function RTElementThumbCarousel(container, options, instance, index) {
1632	// Params
1633	var mainSlider = container.find('.rttm-carousel-main').addClass('instance-' + index),
1634		navSlider = container.find('.ttp-carousel-thumb').addClass('instance-' + index),
1635		navPrev = '.swiper-button-prev',
1636		navNext = '.swiper-button-next',
1637		dotsEl = '.swiper-pagination';
1638
1639	container.find(navPrev).addClass('prev-' + index);
1640	container.find(navNext).addClass('next-' + index);
1641
1642	// Main Slider
1643	var mainSliderOptions = {
1644		loop: true,
1645		speed: options.speed ? options.speed : 1000,
1646		loopedSlides: 5,
1647		autoHeight: options.autoHeight ? options.autoHeight : false,
1648		navigation: {
1649			nextEl: navNext,
1650			prevEl: navPrev
1651		},
1652		pagination: {
1653			el: dotsEl,
1654			type: 'bullets',
1655			clickable: true
1656		}
1657	};
1658
1659	var main = new Swiper(mainSlider[0], mainSliderOptions);
1660
1661	// Navigation Slider
1662	var navSliderOptions = {
1663		loop: true,
1664		speed: options.speed ? options.speed : 1000,
1665		observer: true,
1666		observerParents: true,
1667		slidesPerView: options.slidesPerView ? options.slidesPerView : 5,
1668		centeredSlides: true,
1669		spaceBetween: 0,
1670		touchRatio: 0.2,
1671		slideToClickedSlide: true,
1672		loopedSlides: 5,
1673		watchSlidesProgress: true,
1674		breakpoints: options.breakpoints
1675	};
1676
1677	if (options.autoplay) {
1678		navSliderOptions.autoplay = {
1679			delay: options.autoplay.delay,
1680			pauseOnMouseEnter: options.autoplay.pauseOnMouseEnter,
1681			disableOnInteraction: false
1682		};
1683	}
1684
1685	if (options.lazy) {
1686		navSliderOptions.preloadImages = false;
1687		navSliderOptions.lazy = true;
1688	}
1689
1690	var thumb = new Swiper(navSlider[0], navSliderOptions);
1691
1692	// Syncing the sliders
1693	main.controller.control = thumb;
1694	thumb.controller.control = main;
1695
1696	instance[index] = [main, thumb];
1697}

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.