PageSourceSearch

https://tjc.com.vn/wp-content/plugins/customer-reviews-woocommerce/js/frontend.js?ver=5.76.2

js tjc.com.vn collected 2026-10-05 01:03:03 UTC 92,469 bytes, 1,910 lines download raw bytes

1(function() {
2	jQuery(document).ready(function($) {
3		// initial resize of [cusrev_reviews_grid] and Trust Badges
4		crResizeAllGridItems();
5		crResizeTrustBadges();
6		//enable attachment of images to comments
7		jQuery("form#commentform").attr( "enctype", "multipart/form-data" ).attr( "encoding", "multipart/form-data" );
8		//prevent review submission if captcha is not solved
9		jQuery("#commentform").on( "submit", function(event) {
10			if( cr_ajax_object.ivole_recaptcha === '1' ) {
11				var recaptcha = jQuery("#g-recaptcha-response").val();
12				if (recaptcha === "") {
13					event.preventDefault();
14					alert("Please confirm that you are not a robot");
15				}
16			}
17		} );
18		//show lightbox when click on images attached to reviews
19		jQuery("ol.commentlist").on("click", ".cr-comment-a", function(t) {
20			if(cr_ajax_object.disable_lightbox === '0') {
21				//only if lightbox is not disabled in settings of the plugin
22				t.preventDefault();
23				const oo = jQuery(".pswp");
24				if ( 0 < oo.length ) {
25					const o = oo[0];
26					var pics = jQuery(this).parent().parent().find(".cr-comment-a img");
27					var this_pic = jQuery(this).find("img");
28					var inx = 0;
29					if (pics.length > 0 && this_pic.length > 0) {
30						var a = [];
31						for (i = 0; i < pics.length; i++) {
32							a.push({
33								src: pics[i].src,
34								w: pics[i].naturalWidth,
35								h: pics[i].naturalHeight,
36								title: pics[i].alt
37							});
38							if (this_pic[0].src == pics[i].src) {
39								inx = i;
40							}
41						}
42						var r = {
43							index: inx
44						};
45						new PhotoSwipe(o, PhotoSwipeUI_Default, a, r).init();
46					}
47				}
48			}
49		});
50		// play a video when a user clicks on it in the reviews grid
51		jQuery(".cr-reviews-grid").on("click", ".image-row-vid, .cr-comment-videoicon", function(t) {
52			if( ! jQuery(this).closest(".image-row").hasClass( "cr-vid-playing" ) ) {
53				jQuery(this).closest(".image-row").addClass( "cr-vid-playing" );
54				jQuery(this).closest(".image-row").find(".image-row-vid").prop( "controls", true );
55				jQuery(this).closest(".image-row").find(".image-row-vid").get(0).play();
56			} else {
57				jQuery(this).closest(".image-row").find(".image-row-vid").get(0).pause();
58				jQuery(this).closest(".image-row").find(".image-row-vid").prop( "controls", false );
59				jQuery(this).closest(".image-row").removeClass( "cr-vid-playing" );
60			}
61			return false;
62		} );
63		// play a video when a user clicks on it in the media pop-up window
64		jQuery(".cr-ajax-reviews-cus-images-modal").on("click", ".cr-ajax-reviews-video, .cr-ajax-reviews-video .cr-comment-videoicon", function(t) {
65			if( ! jQuery(this).closest(".cr-ajax-reviews-video").hasClass( "cr-vid-playing" ) ) {
66				jQuery(this).closest(".cr-ajax-reviews-video").addClass( "cr-vid-playing" );
67				jQuery(this).closest(".cr-ajax-reviews-video").find("video").prop( "controls", true );
68				jQuery(this).closest(".cr-ajax-reviews-video").find("video").get(0).play();
69			} else {
70				jQuery(this).closest(".cr-ajax-reviews-video").find("video").get(0).pause();
71				jQuery(this).closest(".cr-ajax-reviews-video").find("video").prop( "controls", false );
72				jQuery(this).closest(".cr-ajax-reviews-video").removeClass( "cr-vid-playing" );
73			}
74			return false;
75		} );
76		// open a gallery with media files in the reviews grid
77		jQuery(".cr-reviews-grid").on("click", ".media-row-count", function(t) {
78			if ( cr_ajax_object.disable_lightbox === '0' ) {
79				// only if lightbox is not disabled in settings of the plugin
80				t.preventDefault();
81				const oo = jQuery(".pswp");
82				let media = jQuery(this).parent().find(".image-row-vid,.image-row-img"),
83					this_media = jQuery(this),
84					inx = 0;
85				if (media.length > 0 && this_media.length > 0) {
86					const o = oo[0];
87					var a = [];
88					for (i = 0; i < media.length; i++) {
89						if ( "vid" === media[i].dataset.crmedia ) {
90							a.push({
91								html: '<div class="cr-video-wrapper"><video class="cr-media-video" src="' + media[i].src + '" controls></video></div>',
92								title: media[i].dataset.crtitle
93							});
94						} else {
95							a.push({
96								src: media[i].src,
97								w: media[i].naturalWidth,
98								h: media[i].naturalHeight,
99								title: media[i].alt
100							});
101						}
102						if (this_media[0].src == media[i].src) {
103							inx = i;
104						}
105					}
106					var r = {
107						index: inx
108					};
109					new PhotoSwipe(o, PhotoSwipeUI_Default, a, r).init();
110				}
111			}
112		} );
113		// play or pause a video in the gallery
114		jQuery(document).on("click", ".cr-video-wrapper .cr-media-video", function(t) {
115			const vid = jQuery(this).get(0);
116			if ( vid ) {
117				const isVideoPlaying = !!( vid.currentTime > 0 && !vid.paused && !vid.ended && vid.readyState > 2 );
118				if ( isVideoPlaying ) {
119					vid.pause();
120				} else {
121					vid.play();
122				}
123			}
124			return false;
125		} );
126		// show a lightbox when a user clicks on images in the reviews grid
127		jQuery(".cr-reviews-grid").on("click", ".image-row-img, .image-row-count", function(t) {
128			if(cr_ajax_object.disable_lightbox === '0') {
129				// only if lightbox is not disabled in settings of the plugin
130				t.preventDefault();
131				const oo = jQuery(".pswp");
132				if ( 0 < oo.length ) {
133					const o = oo[0];
134					var pics = jQuery(this).parent().find("img.image-row-img");
135					var this_pic = jQuery(this);
136					var inx = 0;
137					if (pics.length > 0 && this_pic.length > 0) {
138						var a = [];
139						for (i = 0; i < pics.length; i++) {
140							a.push({
141								src: pics[i].src,
142								w: pics[i].naturalWidth,
143								h: pics[i].naturalHeight,
144								title: pics[i].alt
145							});
146							if (this_pic[0].src == pics[i].src) {
147								inx = i;
148							}
149						}
150						var r = {
151							index: inx
152						};
153						new PhotoSwipe(o, PhotoSwipeUI_Default, a, r).init();
154					}
155				}
156			}
157		});
158		//register a listener for votes on for reviews
159		initVoteClick("ol.commentlist", ".cr-voting-a", "cr_vote_review");
160		//register a listener for the voting buttons on modal
161		initVoteClick(".cr-ajax-reviews-cus-images-modal", ".cr-voting-a", "cr_vote_review");
162		//register a listener for the voting buttons on Q & A
163		initVoteClick(".cr-qna-block .cr-qna-list-block", ".cr-voting-a", "cr_vote_question");
164
165		//show a lightbox when click on videos attached to reviews
166		jQuery("ol.commentlist").on("click", ".cr-video-a, .cr-comment-videoicon", function(t) {
167			if( ! jQuery(this).closest(".cr-comment-videos").hasClass( "cr-comment-videos-modal" ) ) {
168				let tt = jQuery(this).closest("[class*='cr-comment-video-']");
169				jQuery(this).closest(".cr-comment-videos").addClass( "cr-comment-videos-modal" );
170				tt.addClass( "cr-comment-video-modal" );
171				tt.find( "video" ).prop( "controls", true );
172				tt.find( ".cr-comment-videoicon" ).hide();
173				tt.find( "video" ).get(0).play();
174				return false;
175			}
176			return false;
177		} );
178		//close a video lightbox
179		jQuery("ol.commentlist").on( "click", ".cr-comment-videos", function(t) {
180			if( jQuery(this).hasClass( "cr-comment-videos-modal" ) ) {
181				jQuery(this).removeClass( "cr-comment-videos-modal" );
182				jQuery(this).find("[class*='cr-comment-video-']").each(function(index, element){
183					if( jQuery(element).hasClass( "cr-comment-video-modal" ) ) {
184						jQuery(element).removeClass( "cr-comment-video-modal" );
185						jQuery(element).find( "video").get(0).pause();
186						jQuery(element).find( "video" ).prop( "controls", false );
187						jQuery(element).find( ".cr-comment-videoicon" ).show();
188						jQuery(element).removeAttr("style");
189					}
190				});
191				return false;
192			}
193		} );
194		//show more ajax reviews
195		jQuery(".cr-show-more-reviews-prd").on( "click", function(t) {
196			t.preventDefault();
197			crShowMoreReviewsPrd( jQuery(this) );
198		} );
199
200		// ajax sorting of reviews
201		jQuery(".cr-ajax-reviews-sort").on( "change", function(t) {
202			t.preventDefault();
203
204			if ( jQuery(this).parents(".cr-all-reviews-shortcode").length ) {
205				// sorting in the all reviews block
206				cr_filter_all_reviews( jQuery(this) );
207			} else {
208				// sorting on a product page
209				var cr_product_id = jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").attr("data-product");
210				var cr_sort = jQuery(this).children("option:selected").val();
211				var cr_rating = jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax tr.ivole-histogramRow.ivole-histogramRow-s .ivole-histogram-a").attr("data-rating");
212				if(!cr_rating){
213					cr_rating = 0;
214				}
215				var cr_data = {
216					"action": "cr_sort_reviews",
217					"productID": cr_product_id,
218					"sort": cr_sort,
219					"rating": cr_rating
220				};
221				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-search-no-reviews").hide();
222				jQuery(this).parents(".cr-reviews-ajax-comments").find('.cr-ajax-search input').val("").trigger("change");
223				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").hide();
224				jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").hide();
225				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").show();
226				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").addClass("cr-summaryBar-updating");
227				jQuery(this).addClass("cr-sort-updating");
228				jQuery.post( {
229					url: cr_ajax_object.ajax_url,
230					data: cr_data,
231					context: this,
232					success: function(response) {
233						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").hide();
234						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").removeClass("cr-summaryBar-updating");
235						jQuery(this).removeClass("cr-sort-updating");
236						if(response.page > 0){
237							jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").empty();
238							jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").append(response.html);
239							jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").show();
240							jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page",response.page);
241							if( response.show_more_label ) {
242								jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").text( response.show_more_label );
243							}
244							if ( response.count_row ) {
245								jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-count-row .cr-count-row-count").html( response.count_row );
246							}
247							if(!response.last_page){
248								jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").show();
249							}
250						}
251					},
252					dataType: "json"
253				} );
254			}
255		} );
256		// non-ajax filtering of reviews
257		jQuery(".cr-noAjax").on( "click", ".ivole-histogram-a", function (t) {
258			t.preventDefault();
259			const parser = new URL(window.location);
260			parser.searchParams.set(cr_ajax_object.rating_filter, jQuery(this).data("rating"));
261			parser.hash = cr_ajax_object.reviews_tab;
262			window.location = parser.href;
263		} );
264		// ajax filtering of reviews
265		jQuery(".cr-reviews-ajax-comments").on("click", ".ivole-histogram-a, .cr-seeAllReviews", function(t){
266			t.preventDefault();
267			let tmpParent = jQuery(this).parents(".cr-reviews-ajax-comments");
268			let cr_product_id = tmpParent.find(".commentlist.cr-ajax-reviews-list").attr("data-product");
269			let cr_nonce = tmpParent.find(".cr-summaryBox-ajax").attr("data-nonce");
270			let cr_rating = jQuery(this).attr("data-rating");
271			let cr_sort = tmpParent.find(".cr-ajax-reviews-sort").children("option:selected").val();
272			let cr_data = {
273				"action": "cr_filter_reviews",
274				"productID": cr_product_id,
275				"rating": cr_rating,
276				"sort": cr_sort,
277				"security": cr_nonce
278			};
279			tmpParent.find(".cr-summaryBox-ajax tr.ivole-histogramRow.ivole-histogramRow-s").removeClass("ivole-histogramRow-s");
280			if( cr_rating > 0 ) {
281				jQuery(this).closest("tr.ivole-histogramRow").addClass("ivole-histogramRow-s");
282			}
283			tmpParent.find(".cr-search-no-reviews").hide();
284			tmpParent.find('.cr-ajax-search input').val("").trigger("change");
285			tmpParent.find(".cr-show-more-reviews-prd").hide();
286			tmpParent.find(".commentlist.cr-ajax-reviews-list").hide();
287			tmpParent.find(".cr-show-more-review-spinner").show();
288			tmpParent.find(".cr-summaryBox-ajax").addClass("cr-summaryBar-updating");
289			tmpParent.find(".cr-ajax-reviews-sort").addClass("cr-sort-updating");
290			jQuery.post( {
291				url: cr_ajax_object.ajax_url,
292				data: cr_data,
293				context: tmpParent,
294				success: function(response) {
295					this.find(".cr-show-more-review-spinner").hide();
296					this.find(".cr-summaryBox-ajax").removeClass("cr-summaryBar-updating");
297					this.find(".cr-ajax-reviews-sort").removeClass("cr-sort-updating");
298					if(response.page > 0) {
299						this.find(".commentlist.cr-ajax-reviews-list").empty();
300						this.find(".commentlist.cr-ajax-reviews-list").append(response.html);
301						this.find(".commentlist.cr-ajax-reviews-list").show();
302						this.attr("data-page",response.page);
303						if( response.show_more_label ) {
304							this.find( ".cr-show-more-reviews-prd" ).text( response.show_more_label );
305						}
306						if ( response.count_row ) {
307							this.find(".cr-count-row .cr-count-row-count").html( response.count_row );
308						}
309						if(!response.last_page){
310							this.find(".cr-show-more-reviews-prd").show();
311						}
312					}
313				},
314				dataType: "json"
315			} );
316		} );
317		// ajax search typing
318		jQuery('.cr-ajax-search input').on("keyup", function(e){
319			if(e.keyCode == 13){
320				jQuery(this).parents(".cr-ajax-search").find("button").trigger("click");
321			}
322			// show clear icon
323			if(jQuery(this).val() !== "") {
324				jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").css("display", "inline-block");
325			} else {
326				jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").css("display", "none");
327			}
328		}).on("change", function(){
329			if(jQuery(this).val() === "") jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").hide();
330		});
331		//
332		jQuery('.cr-reviews-ajax-reviews .cr-ajax-search input').on( 'keyup', crDebounce(
333			( ref ) => {
334				jQuery(ref.target).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
335				jQuery(ref.target).parents(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-list").empty();
336				crShowMoreReviewsPrd( jQuery(ref.target) );
337			},
338			1000
339		) );
340		// clear search field
341		jQuery(".cr-ajax-search .cr-clear-input").on("click", function () {
342			jQuery(this).prev("input").val("");
343			jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").hide();
344			jQuery(this).parents(".cr-ajax-search").find("button").trigger("click");
345			//
346			if( jQuery(this).parents(".cr-reviews-ajax-reviews").length ) {
347				// clear search in the case of product pages
348				jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
349				jQuery(this).parents(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-list").empty();
350				crShowMoreReviewsPrd( jQuery(this) );
351			}
352		});
353		// ajax search of reviews
354		jQuery(".cr-ajax-search button").on("click", function (e) {
355			e.preventDefault();
356
357			//search in the all reviews block
358			if( jQuery(this).parents(".cr-all-reviews-shortcode").length ){
359				// search in ajax version of the All Reviews block / shortcode
360				cr_filter_all_reviews( jQuery(this) );
361			} else {
362				jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
363				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-list").empty();
364				crShowMoreReviewsPrd( jQuery(this) );
365			}
366		});
367		jQuery(".cr-ajax-reviews-add-review, .cr-nosummary-add").on( "click", function(t) {
368			t.preventDefault();
369			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-reviews-ajax-comments").hide();
370			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-review-form").show();
371		} );
372		// click to filter reviews by tags
373		jQuery(".cr-review-tags-filter span.cr-tags-filter").on( "click", function (e) {
374			e.preventDefault();
375			if(jQuery(this).hasClass("cr-tag-selected")) {
376				jQuery(this).removeClass("cr-tag-selected");
377			} else {
378				jQuery(this).addClass("cr-tag-selected");
379			}
380			if ( jQuery(this).parents(".cr-all-reviews-shortcode").length ) {
381				// tags filtering in the all reviews shortcode
382				cr_filter_all_reviews( jQuery(this) );
383			} else {
384				// tags filtering on a product page
385				jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
386				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-list").empty();
387				crShowMoreReviewsPrd( jQuery(this) );
388			}
389		} );
390		//open popup window with pictures
391		jQuery(".cr-comment-image-top .cr-comment-image-top-item").on( "click", function(t) {
392			t.preventDefault();
393			jQuery("body").addClass("cr-noscroll");
394			let slide_no = jQuery(this).data("slide");
395			let imgParent = jQuery(this).closest(".cr-ajax-reviews-cus-images-div").parent();
396			imgParent.find(".cr-ajax-reviews-cus-images-modal-cont").addClass("cr-mask-active");
397			imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-main").slickk('setPosition');
398			imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-nav").slickk('setPosition');
399			if ( typeof slide_no !== 'undefined' ) {
400				imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-main").slickk('slickGoTo', slide_no, true);
401				imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-nav").slickk('slickGoTo', slide_no, true);
402			}
403		} );
404		jQuery(".cr-comment-image-top .cr-comment-videoicon").on( "click", function(t) {
405			jQuery(this).closest( ".cr-comment-image-top" ).find( ".cr-comment-image-top-item" ).trigger( "click" );
406		} );
407		//close popup window with pictures
408		jQuery(".cr-ajax-reviews-cus-images-modal-cont, .cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-close").on( "click", function(t) {
409			t.preventDefault();
410			let closeParent = jQuery(this).closest(".cr-ajax-reviews-cus-images-modal-cont.cr-mask-active");
411			closeParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-main").slickk('slickGoTo',0,true);
412			closeParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-nav").slickk('slickGoTo',0,true);
413			closeParent.removeClass("cr-mask-active");
414			jQuery("body").removeClass("cr-noscroll");
415		} );
416		jQuery(".cr-ajax-reviews-cus-images-modal-cont .cr-ajax-reviews-cus-images-modal").on( "click", function(t) {
417			t.stopPropagation();
418		} );
419		//Product variations
420		jQuery(".single_variation_wrap").on( "show_variation", function ( event, variation ) {
421			if(jQuery(".cr_gtin").length){
422				jQuery(".cr_gtin_val").text(variation._cr_gtin);
423			}
424			if(jQuery(".cr_mpn").length){
425				jQuery(".cr_mpn_val").text(variation._cr_mpn);
426			}
427			if(jQuery(".cr_brand").length){
428				jQuery(".cr_brand_val").text(variation._cr_brand);
429			}
430		});
431		//Reset Product variations
432		jQuery(document).on('reset_data', function () {
433			var cr_gtin = jQuery(".cr_gtin"),
434			cr_mpn = jQuery(".cr_mpn"),
435			cr_brand = jQuery(".cr_brand");
436
437			if(cr_gtin.length){
438				jQuery(".cr_gtin_val").text(cr_gtin.data("o_content"));
439			}
440			if(cr_mpn.length){
441				jQuery(".cr_mpn_val").text(cr_mpn.data("o_content"));
442			}
443			if(cr_brand.length){
444				jQuery(".cr_brand_val").text(cr_brand.data("o_content"));
445			}
446		});
447		// show more ajax reviews in the all reviews block
448		jQuery('.cr-all-reviews-shortcode .cr-show-more-button').on("click", function (e) {
449			e.preventDefault();
450			cr_filter_all_reviews( jQuery(this), true );
451		});
452		jQuery('.cr-all-reviews-shortcode').on("click", ".cr-page-numbers-a", function (e) {
453			e.preventDefault();
454			cr_filter_all_reviews( jQuery(this), true );
455		});
456		// filter ajax reviews in the all reviews block
457		jQuery(".cr-all-reviews-shortcode").on("click", ".cr-histogram-a, .cr-seeAllReviews", function(t){
458			t.preventDefault();
459			let cr_rating = jQuery(this).data("rating");
460			jQuery("div.ivole-summaryBox tr.ivole-histogramRow.ivole-histogramRow-s").removeClass("ivole-histogramRow-s");
461			if ( cr_rating > 0 ) {
462				jQuery(this).closest("tr.ivole-histogramRow").addClass("ivole-histogramRow-s");
463			}
464			jQuery(this).parents(".cr-all-reviews-shortcode").find(".cr-review-tags-filter .cr-tag-selected").removeClass("cr-tag-selected");
465			cr_filter_all_reviews( jQuery(this) );
466		});
467
468		// show more ajax reviews in the grid
469		jQuery( ".cr-reviews-grid .cr-show-more-button" ).on( "click", function (e) {
470			e.preventDefault();
471
472			let $this = jQuery(this),
473			$spinner =  $this.next(".cr-show-more-spinner"),
474			cr_rating = $this.parents(".cr-reviews-grid").find(".ivole-summaryBox.cr-grid-reviews-ajax tr.ivole-histogramRow.ivole-histogramRow-s .cr-histogram-a").attr("data-rating"),
475			attributes = $this.parents(".cr-reviews-grid").data("attributes");
476
477			attributes.comment__not_in = $this.parents(".cr-reviews-grid").find(".cr-review-card.cr-card-product").map( function() {
478				return jQuery(this).data("reviewid");
479			} ).get();
480			attributes.comment__not_in = attributes.comment__not_in.concat(
481				$this.parents(".cr-reviews-grid").find(".cr-review-card.cr-card-shop").map(function(){
482					return jQuery(this).data("reviewid");
483				}).get() );
484
485			var grid_data = {
486				'action': "ivole_show_more_grid_reviews",
487				'rating': cr_rating,
488				'attributes': attributes
489			};
490
491			$this.hide();
492			$spinner.show();
493
494			jQuery.post(cr_ajax_object.ajax_url, grid_data, function(response) {
495				$spinner.hide();
496				$reviews = jQuery(response.html).find(".cr-review-card");
497				let showMoreBtn = jQuery(response.html).find(".cr-show-more-button");
498				if ( $reviews.length ) {
499					$this.parents(".cr-reviews-grid").find(".cr-reviews-grid-inner").colcade("append", $reviews);
500					if ( showMoreBtn.length ) {
501						$this.text( showMoreBtn.text() );
502						$this.show();
503					} else {
504						$this.hide();
505					}
506				} else {
507					$this.hide();
508				}
509			}).fail(function(response) {
510				$spinner.hide();
511				$this.show();
512				$this.parent().append('<div style="color:#cd2653;text-align:center;display:block;">'+response.responseText+'</div>');
513			});
514		});
515
516		jQuery(".cr-reviews-grid .cr-summaryBox-wrap").on("click", ".cr-histogram-a, .cr-seeAllReviews", function(e){
517			e.preventDefault();
518
519			let $this = jQuery(this),
520			$grid =  $this.parents(".cr-reviews-grid"),
521			$spinner =  $grid.find(".cr-show-more-spinner"),
522			cr_rating = $this.attr("data-rating"),
523			attributes = $grid.data("attributes");
524
525			attributes.show_more = attributes.count + attributes.count_shop_reviews;
526			attributes.comment__not_in = [];
527
528			if(!cr_rating) cr_rating = 0;
529
530			var grid_data = {
531				'action': "ivole_show_more_grid_reviews",
532				'rating': cr_rating,
533				'attributes': attributes
534			};
535
536			$grid.find("div.ivole-summaryBox tr.ivole-histogramRow.ivole-histogramRow-s").removeClass("ivole-histogramRow-s");
537			if( cr_rating > 0 ) {
538				$this.closest("tr.ivole-histogramRow").addClass("ivole-histogramRow-s");
539			}
540			$grid.find(".cr-reviews-grid-inner").hide();
541			$grid.find(".cr-show-more-button").hide();
542			$spinner.show();
543			$grid.find("div.ivole-summaryBox").addClass("cr-summaryBar-updating");
544
545			jQuery.post(cr_ajax_object.ajax_url, grid_data, function(response) {
546				$spinner.hide();
547				$grid.find(".cr-show-more-button").show();
548				$grid.find(".cr-summaryBox-wrap .cr-count-filtered-reviews").empty();
549				$reviews = jQuery(response.html).find(".cr-review-card");
550				if($reviews.length){
551					$grid.find(".cr-reviews-grid-inner").colcade("empty");
552					$grid.find(".cr-reviews-grid-inner").show();
553					$grid.find(".cr-reviews-grid-inner").colcade("append", $reviews);
554					$grid.find("div.ivole-summaryBox").removeClass("cr-summaryBar-updating");
555					$grid.find(".cr-summaryBox-wrap .cr-count-filtered-reviews").append(jQuery(response.html).find(".cr-count-filtered-reviews").html());
556				}
557			}).fail(function(response) {
558				$spinner.hide();
559				$this.parent().append('<div style="color: #cd2653;text-align: center;display: block;">'+response.responseText+'</div>');
560			});
561
562		});
563		jQuery('#cr_floatingtrustbadge').on( "click", function() {
564			if( !jQuery(this).hasClass( 'cr-floatingbadge-big' ) ) {
565				jQuery(this).find('div.cr-badge.badge_size_compact').hide();
566				jQuery(this).find('div.cr-badge.badge--wide-mobile').css( 'display', 'block' );
567				jQuery(this).find('div.cr-floatingbadge-close').css( 'display', 'block' );
568				jQuery(this).addClass( 'cr-floatingbadge-big' );
569				//update colors
570				var crcolors = jQuery(this).data('crcolors');
571				if (typeof crcolors !== 'undefined') {
572					jQuery(this).css( 'border-color', crcolors['big']['border'] );
573					jQuery(this).find('div.cr-floatingbadge-background-top').css( 'background-color', crcolors['big']['top'] );
574					jQuery(this).find('div.cr-floatingbadge-background-middle').
574css( 'background-color', crcolors['big']['middle'] );
575					jQuery(this).find('div.cr-floatingbadge-background-bottom').css( 'background-color', crcolors['big']['bottom'] );
576					jQuery(this).find('div.cr-floatingbadge-background-bottom').css( 'border-color', crcolors['big']['border'] );
577				}
578			}
579		} );
580		jQuery('#cr_floatingtrustbadge .cr-floatingbadge-close').on( "click", function(event) {
581			if( jQuery('#cr_floatingtrustbadge').hasClass( 'cr-floatingbadge-big' ) ) {
582				jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-badge.badge--wide-mobile').hide();
583				jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-badge.badge_size_compact').css( 'display', 'block' );
584				jQuery(this).closest('#cr_floatingtrustbadge').removeClass( 'cr-floatingbadge-big' );
585				//update colors
586				var crcolors = jQuery(this).closest('#cr_floatingtrustbadge').data('crcolors');
587				if (typeof crcolors !== 'undefined') {
588					jQuery(this).closest('#cr_floatingtrustbadge').css( 'border-color', crcolors['small']['border'] );
589					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-top').css( 'background-color', crcolors['small']['top'] );
590					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-middle').css( 'background-color', crcolors['small']['middle'] );
591					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-bottom').css( 'background-color', crcolors['small']['bottom'] );
592					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-bottom').css( 'border-color', crcolors['small']['border'] );
593				}
594			} else {
595				jQuery('#cr_floatingtrustbadge').hide();
596				document.cookie = 'cr_hide_trustbadge=true; path=/; max-age='+60*60*24+';';
597			}
598			event.stopPropagation();
599		} );
600		jQuery( '.cr-reviews-slider' ).on( 'click', '.cr-slider-read-more a', function (e) {
601			e.preventDefault();
602			let parent = jQuery(this).parents(".review-text");
603			parent.find(".cr-slider-read-more").hide();
604			parent.find(".cr-slider-details").css("display", "inline");
605			jQuery(this).parents(".cr-reviews-slider").slickk('setPosition');
606		} );
607		jQuery( '.cr-reviews-slider' ).on( 'click', '.cr-slider-read-less a', function (e) {
608			e.preventDefault();
609			let parent = jQuery(this).parents(".review-text");
610			parent.find(".cr-slider-details").hide();
611			parent.find(".cr-slider-read-more").css("display", "inline");
612			jQuery(this).parents(".cr-reviews-slider").slickk('setPosition');
613		} );
614		jQuery('.cr-qna-block .cr-qna-search-block .cr-qna-ask-button').on( 'click', function (e) {
615			e.preventDefault();
616			jQuery( this ).closest( '.cr-qna-block' ).addClass( 'cr-qna-new-q-form-open' );
617		} );
618		jQuery(".cr-qna-block .cr-qna-list-block").on( "click", ".cr-qna-ans-button", function (e) {
619			e.preventDefault();
620
621			let nameField = jQuery( this ).closest( '.cr-qna-block' ).find( ".cr-qna-new-q-form .cr-review-form-name" );
622			let nameValue = nameField.find( ".cr-review-form-txt" ).data("defval");
623			jQuery( this ).closest( '.cr-qna-list-q-b' ).find( ".cr-qna-list-inl-answ .cr-review-form-name .cr-review-form-txt" ).val( nameValue );
624
625			let emailField = jQuery( this ).closest( '.cr-qna-block' ).find( ".cr-qna-new-q-form .cr-review-form-email" );
626			let emailValue = emailField.find( ".cr-review-form-txt" ).data("defval");
627			jQuery( this ).closest( '.cr-qna-list-q-b' ).find( ".cr-qna-list-inl-answ .cr-review-form-email .cr-review-form-txt" ).val( emailValue );
628
629			jQuery( this ).closest( '.cr-qna-list-q-b' ).addClass( 'cr-qna-ans-form-open' );
630		} );
631		//show more questions and answers
632		jQuery(".cr-qna-block").on( "click", ".cr-show-more-que", function(t) {
633			t.preventDefault();
634			let qna_block = jQuery(this).parents(".cr-qna-block").eq(0);
635			let cr_product_id = jQuery(this).attr("data-product");
636			let cr_page = jQuery(this).attr("data-page");
637			let cr_attributes = qna_block.data("attributes");
638			let cr_search = qna_block.find(".cr-ajax-qna-search input").val();
639			let cr_permalink = jQuery(this).attr("data-permalink");
640			let cr_data = {
641				"action": "cr_show_more_qna",
642				"productID": cr_product_id,
643				"page": cr_page,
644				"permalink": cr_permalink,
645				"search": cr_search,
646				"cr_attributes": cr_attributes
647			};
648			qna_block.find(".cr-search-no-qna").hide();
649			jQuery(this).hide();
650			qna_block.find("#cr-show-more-q-spinner").show();
651			jQuery.post(cr_ajax_object.ajax_url, cr_data, function(response) {
652				jQuery(".cr-qna-block #cr-show-more-q-spinner").hide();
653				if(response.page >= 0){
654					jQuery(".cr-qna-block .cr-qna-list-block .cr-qna-list-block-inner").append(response.html);
655					jQuery(".cr-qna-block #cr-show-more-q-id").attr("data-page",response.page);
656					if(!response.last_page){
657						jQuery(".cr-qna-block #cr-show-more-q-id").show();
658					}
659				}
660				if(response.html === "" && response.page === 0){
661					jQuery(".cr-qna-block .cr-search-no-qna").show();
662				}
663			}, "json");
664		} );
665		//search questions and answers
666		jQuery(".cr-qna-block .cr-ajax-qna-search input").on("keyup", cr_keyup_delay(function(e) {
667			// do nothing if it's an arrow key
668			var code = (e.keyCode || e.which);
669			if(code == 37 || code == 38 || code == 39 || code == 40) {
670				return;
671			}
672			jQuery(".cr-qna-block #cr-show-more-q-id").attr("data-page", -1);
673			jQuery(".cr-qna-block .cr-qna-list-block .cr-qna-list-block-inner").empty();
674			jQuery(".cr-qna-block #cr-show-more-q-id").trigger("click");
675		}, 500));
676		jQuery(".cr-qna-block .cr-ajax-qna-search input").on("keyup", function(e){
677			//show clear icon
678			if(jQuery(this).val() !== "") {
679				jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").css("display", "inline-block");
680			} else {
681				if(jQuery(this).val() === "") jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").hide();
682			}
683		}).on("change", function(){
684			if(jQuery(this).val() === "") jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").hide();
685		});
686		jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").on("click", function () {
687			jQuery(this).prev("input").val("");
688			jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").hide();
689			jQuery(".cr-qna-block #cr-show-more-q-id").attr("data-page", -1);
690			jQuery(".cr-qna-block .cr-qna-list-block .cr-qna-list-block-inner").empty();
691			jQuery(".cr-qna-block #cr-show-more-q-id").trigger("click");
692		});
693		//show QnA tab
694		jQuery("body").on("click", "a.cr-qna-link", function () {
695			const cr_qna_tab = jQuery( '.cr_qna_tab a' );
696			if( cr_qna_tab.length ) {
697				cr_qna_tab.trigger( "click" );
698			} else {
699				jQuery( '.cr-qna-block' ).parents( ':hidden' ).show();
700			}
701			return true;
702		});
703		// show Reviews tab
704		jQuery("body").on("click", ".cr-review-link", function () {
705			const wc_reviews_tab = jQuery( '.reviews_tab a' );
706			if( wc_reviews_tab.length ) {
707				wc_reviews_tab.trigger( "click" );
708				return true;
709			}
710		});
711
712		// upload images with a review
713		jQuery("#cr_review_image").on("change", function () {
714			jQuery(".cr-upload-images-status").removeClass("cr-upload-images-status-error");
715			jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_initial);
716			let allowedTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif', 'video/mp4', 'video/mpeg', 'video/ogg', 'video/webm', 'video/quicktime', 'video/x-msvideo'];
717			let uploadFiles = jQuery("#cr_review_image");
718			let countFiles = uploadFiles[0].files.length;
719			let countUploaded = jQuery(".cr-upload-images-preview .cr-upload-images-containers").length;
720			let lastIndex = 1;
721			let cr_captcha = "";
722			if(jQuery(this).attr("data-lastindex")) {
723				lastIndex = parseInt(jQuery(this).attr("data-lastindex"));
724			}
725			if( countFiles + countUploaded > cr_ajax_object.cr_images_upload_limit ) {
726				jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
727				jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_error_too_many);
728				jQuery(".cr-upload-images-preview .cr-upload-images-containers").not(".cr-upload-ok").remove();
729				uploadFiles.val("");
730				return;
731			}
732			for(let i = 0; i < countFiles; i++) {
733				if(!allowedTypes.includes(uploadFiles[0].files[i].type) ) {
734					jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
735					jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_error_file_type);
736					jQuery(".cr-upload-images-preview .cr-upload-images-containers").not(".cr-upload-ok").remove();
737					uploadFiles.val("");
738					return;
739				} else if(uploadFiles[0].files[i].size && uploadFiles[0].files[i].size > cr_ajax_object.cr_images_upload_max_size) {
740					jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
741					jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_error_file_size);
742					jQuery(".cr-upload-images-preview .cr-upload-images-containers").not(".cr-upload-ok").remove();
743					uploadFiles.val("");
744					return;
745				} else {
746					let container = jQuery("<div/>", {class:"cr-upload-images-containers cr-upload-images-container-" + (lastIndex + i)});
747					let progressBar = jQuery("<div/>", {class:"cr-upload-images-pbar"});
748					progressBar.append(
749						jQuery("<div/>", {class:"cr-upload-images-pbarin"})
750					);
751					if( -1 === uploadFiles[0].files[i].type.indexOf( 'image' ) ) {
752						container.append(
753							jQuery( "<svg class='cr-upload-video-thumbnail' viewBox='0 0 576 512'>
753<path d='M336.2 64H47.8C21.4 64 0 85.4 0 111.8v288.4C0 426.6 21.4 448 47.8 448h288.4c26.4 0 47.8-21.4 47.8-47.8V111.8c0-26.4-21.4-47.8-47.8-47.8zm189.4 37.7L416 177.3v157.4l109.6 75.5c21.2 14.6 50.4-.3 50.4-25.8V127.5c0-25.4-29.1-40.4-50.4-25.8z'></path></svg>" )
754						);
755					} else{
756						container.append(
757							jQuery("<img>", {class:"cr-upload-images-thumbnail",src:URL.createObjectURL(uploadFiles[0].files[i])})
758						);
759					}
760					container.append(
761						progressBar
762					);
763					let removeButton = jQuery("<button/>", {class:"cr-upload-images-delete"});
764					removeButton.append(
765						'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path class="cr-no-icon" d="M12.12 10l3.53 3.53-2.12 2.12L10 12.12l-3.54 3.54-2.12-2.12L7.88 10 4.34 6.46l2.12-2.12L10 7.88l3.54-3.53 2.12 2.12z"/></g></svg>'
766					);
767					container.append(
768						removeButton
769					);
770					container.append(
771						jQuery("<input>", {name:"cr-upload-images-ids[]",type:"hidden",value:""})
772					);
773					container.append(
774						jQuery("<span/>", {class:"cr-upload-images-delete-spinner"})
775					);
776					jQuery(".cr-upload-images-preview").append(container);
777				}
778			}
779			for(let i = 0; i < countFiles; i++) {
780				let formData = new FormData();
781				formData.append("action", "cr_upload_local_images_frontend");
782				formData.append("cr_nonce", jQuery(this).attr("data-nonce"));
783				formData.append("cr_postid", jQuery(this).attr("data-postid"));
784				formData.append("cr_file", uploadFiles[0].files[i]);
785				if(typeof grecaptcha !== "undefined" && cr_ajax_object.ivole_recaptcha === '1') {
786					cr_captcha = grecaptcha.getResponse();
787					grecaptcha.reset();
788				}
789				formData.append("cr_captcha", cr_captcha);
790				jQuery.ajax({
791					url: cr_ajax_object.ajax_url,
792					data: formData,
793					processData: false,
794					contentType: false,
795					dataType: "json",
796					type: "POST",
797					beforeSend: function() {
798					},
799					xhr: function() {
800						var myXhr = jQuery.ajaxSettings.xhr();
801						if ( myXhr.upload ) {
802							myXhr.upload.addEventListener( 'progress', function(e) {
803								if ( e.lengthComputable ) {
804									let perc = ( e.loaded / e.total ) * 100;
805									perc = perc.toFixed(0);
806									jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " .cr-upload-images-pbar .cr-upload-images-pbarin").width(perc + "%");
807								}
808							}, false );
809						}
810						return myXhr;
811					},
812					success: function(response) {
813						if(200 === response["code"]) {
814							let idkey = JSON.stringify({ id: response["attachment"]["id"], key: response["attachment"]["key"] });
815							jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " input").val(idkey);
816							jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).addClass("cr-upload-ok");
817							jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " button").attr("data-delnonce",response["attachment"]["nonce"]);
818						} else if(500 <= response["code"]) {
819							jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).remove();
820							jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
821							jQuery(".cr-upload-images-status").text(response["message"]);
822						}
823					}
824				});
825			}
826			jQuery(this).attr("data-lastindex", lastIndex + countFiles);
827			uploadFiles.val("");
828		});
829
830		// delete uploaded image
831		jQuery(".cr-upload-images-preview").on("click", ".cr-upload-images-delete", function (e) {
832			e.preventDefault();
833			jQuery(".cr-upload-images-status").removeClass("cr-upload-images-status-error");
834			jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_initial);
835			let classList = jQuery(this).parent().eq(0).attr("class").split(/\s+/);
836			let classes = "";
837			jQuery.each(classList, function(index, item) {
838				classes += "." + item;
839			});
840			let ajaxData = {
841				"action": "cr_delete_local_images_frontend",
842				"cr_nonce": jQuery(this).attr("data-delnonce"),
843				"image": jQuery(this).parent().children("input").eq(0).val(),
844				"class": classes
845			}
846			jQuery(this).parent().addClass("cr-upload-delete-pending");
847			jQuery.post(cr_ajax_object.ajax_url, ajaxData, function(response) {
848				if(200 === response["code"] && response["class"]) {
849					jQuery(".cr-upload-images-preview " + response["class"]).remove();
850				}
851				jQuery(".cr-upload-images-preview " + response["class"]).removeClass("cr-upload-delete-pending");
852			}, "json");
853		});
854
855		// update star rating on an add-a-review form hover
856		jQuery( ".cr-review-form-rating .cr-review-form-rating-inner" ).on(
857			"mouseenter",
858			function() {
859				let rating = parseInt( jQuery( this ).data( "rating" ) );
860				let ratingActv = parseInt( jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-actv" ).data( "rating" ) );
861				if( isNaN( ratingActv ) ) {
862					ratingActv = 0;
863				}
864				for( r = 1; r < 6; r++ ) {
865					if( r > rating && r > ratingActv ) {
866						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).hide();
867						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).show();
868					} else {
869						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).hide();
870						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).show();
871					}
872				}
873				jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-nbr" ).text( rating + "/5" );
874			}
875		).on(
876			"mouseleave",
877			function() {
878				let ratingActv = parseInt( jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-actv" ).data( "rating" ) );
879				if( isNaN( ratingActv ) ) {
880					ratingActv = 0;
881				}
882				for( r = 1; r < 6; r++ ) {
883					if( r > ratingActv ) {
884						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).hide();
885						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).show();
886					} else {
887						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).hide();
888						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).show();
889					}
890				}
891				jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-nbr" ).text( ratingActv + "/5" );
892			}
893		);
894
895		// update star rating on an add-a-review form click
896		jQuery( ".cr-review-form-rating .cr-review-form-rating-inner" ).on( "click", function( e ) {
897			e.preventDefault();
898			let rating = parseInt( jQuery( this ).data( "rating" ) );
899			jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner" ).removeClass( "cr-review-form-rating-actv" );
900			jQuery( this ).addClass( "cr-review-form-rating-actv" );
901			for( r = 1; r < 6; r++ ) {
902				if( r > rating ) {
903					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).hide();
904					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).show();
905				} else {
906					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).hide();
907					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).show();
908				}
909			}
910			jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-nbr" ).text( rating + "/5" );
911			jQuery( this ).closest( ".cr-review-form-rating" ).find( ".cr-review-form-rating-inp" ).val( rating );
912			jQuery( this ).closest( ".cr-review-form-rating" ).removeClass( "cr-review-form-error" );
913		} );
914
915		// close the review form
916		jQuery( ".cr-all-reviews-shortcode .cr-nav-left svg, .cr-all-reviews-shortcode .cr-nav-right svg, .cr-all-reviews-shortcode .cr-review-form-cancel" ).on( "click", function( e ) {
917			jQuery( this ).closest( ".cr-all-reviews-shortcode" ).removeClass( "cr-all-reviews-new-review" );
918			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
919			cr_reset_review_form( jQuery( this ) );
920		} );
921		jQuery( ".cr-all-reviews-shortcode .cr-review-form-wrap" ).on( "click", ".cr-review-form-success", function( e ) {
922			jQuery( this ).closest( ".cr-all-reviews-shortcode" ).removeClass( "cr-all-reviews-new-review" );
923			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
924			cr_reset_review_form( jQuery( this ) );
925		} );
926		jQuery( ".cr-review-form-wrap" ).on( "click", ".cr-review-form-error", function( e ) {
927			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
928		} );
929		jQuery( ".cr-ajax-reviews-review-form .cr-nav-left svg, .cr-ajax-reviews-review-form .cr-nav-right svg, .cr-ajax-reviews-review-form .cr-review-form-cancel" ).on( "click", function( e ) {
930			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-reviews-ajax-comments").show();
931			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-review-form").hide();
932			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
933			cr_reset_review_form( jQuery( this ) );
934		} );
935		jQuery( ".cr-ajax-reviews-review-form .cr-review-form-wrap" ).on( "click", ".cr-review-form-success", function( e ) {
936			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-reviews-ajax-comments").show();
937			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-review-form").hide();
938			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
939			cr_reset_review_form( jQuery( this ) );
940		} );
941		jQuery( ".cr-reviews-grid .cr-nav-left svg, .cr-reviews-grid .cr-nav-right svg, .cr-reviews-grid .cr-review-form-cancel" ).on( "click", function( e ) {
942			jQuery( this ).closest( ".cr-reviews-grid" ).removeClass( "cr-reviews-grid-new-review" );
943			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
944			cr_reset_review_form( jQuery( this ) );
945		} );
946		jQuery( ".cr-reviews-grid .cr-review-form-wrap" ).on( "click", ".cr-review-form-success", function( e ) {
947			jQuery( this ).closest( ".cr-reviews-grid" ).removeClass( "cr-reviews-grid-new-review" );
948			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
949			cr_reset_review_form( jQuery( this ) );
950		} );
951		// close the qna form
952		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-new-q-form .cr-nav-left svg, .cr-qna-new-q-form .cr-nav-right svg, .cr-qna-new-q-form .cr-review-form-cancel", function( e ) {
953			jQuery( this ).closest( ".cr-qna-block" ).removeClass( "cr-qna-new-q-form-open" );
954			jQuery( this ).closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-res" );
955			cr_reset_qna_form( jQuery( this ) );
956		} );
957		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-new-q-form .cr-review-form-success", function( e ) {
958			jQuery( this ).closest( ".cr-qna-block" ).removeClass( "cr-qna-new-q-form-open" );
959			jQuery( this ).closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-res" );
960			cr_reset_qna_form( jQuery( this ) );
961		} );
962		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-new-q-form .cr-review-form-error", function( e ) {
963			jQuery( this ).closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-res" );
964		} );
965		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-nav-left svg, .cr-qna-list-inl-answ .cr-nav-right svg, .cr-qna-list-inl-answ .cr-review-form-cancel", function( e ) {
966			jQuery( this ).closest( ".cr-qna-list-q-b" ).removeClass( "cr-qna-ans-form-open" );
967			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-res" );
968			cr_reset_ans_form( jQuery( this ) );
969		} );
970		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-review-form-success", function( e ) {
971			jQuery( this ).closest( ".cr-qna-list-q-b" ).removeClass( "cr-qna-ans-form-open" );
972			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-res" );
973			cr_reset_ans_form( jQuery( this ) );
974		} );
975		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-review-form-error", function( e ) {
976			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-res" );
977		} );
978
979		// submit the review form
980		jQuery( ".cr-review-form-wrap .cr-review-form-submit" ).on( "click", function( e ) {
981			// check if media upload is in progress
982			if ( 0 < jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media-preview .cr-upload-images-containers:not(.cr-upload-ok)" ).length ) {
983				return false;
984			}
985			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating" ).removeClass( "cr-review-form-error" );
986			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
987			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
988			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
989			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
990			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media" ).removeClass( "cr-review-form-error" );
991			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-captcha" ).removeClass( "cr-review-form-error" );
992			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
993			if( cr_validate_review_form( jQuery( this ) ) ) {
994				// add custom onsite questions and ratings to the ajax call
995				let onsiteQuestions = {};
996				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating input[type='hidden']" ).each(
997					function() {
998						onsiteQuestions[jQuery( this ).attr( 'name' )] = jQuery( this ).val();
999					}
1000				)
1001				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-onsite-question input" ).each(
1002					function() {
1003						onsiteQuestions[jQuery( this ).attr( 'name' )] = jQuery( this ).val();
1004					}
1005				)
1006				// if available, add captcha to the ajax call
1007				let captchaResponse = '';
1008				if ( 0 < jQuery( this ).closest( ".cr-review-form-wrap" ).find( '.cr-review-form-captcha .cr-recaptcha' ).length ) {
1009					if ( grecaptcha ) {
1010						captchaResponse = grecaptcha.getResponse();
1011					}
1012				}
1013				// submit the form if the validation is successful
1014				let cr_data = {
1015					"action": "cr_submit_review",
1016					"rating": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-overall .cr-review-form-rating-inp" ).val(),
1017					"review": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment-txt" ).val().trim(),
1018					"name": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim(),
1019					"id": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-item-id" ).val(),
1020					"email": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim(),
1021					"onsiteQuestions": onsiteQuestions,
1022					"cr-upload-images-ids": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-upload-images-containers input" ).map( function() {
1023						return jQuery( this ).val();
1024					} ).get(),
1025					'g-recaptcha-response': captchaResponse
1026				};
1027				jQuery( this ).closest( ".cr-review-form-wrap" ).addClass( "cr-review-form-submitting" );
1028				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-success" );
1029				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-error" );
1030				jQuery.post(
1031					{
1032						url: cr_ajax_object.ajax_url,
1033						data: cr_data,
1034						context: jQuery( this ),
1035						success: function( response ) {
1036							this.closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-submitting" );
1037							this.closest( ".cr-review-form-wrap" ).addClass( "cr-review-form-res" );
1038							this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-result span" ).html( response.description );
1039							this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).html( response.button );
1040							if( 0 === response.code ) {
1041								this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-success" );
1042							} else {
1043								this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-error" );
1044							}
1045						},
1046						dataType: "json"
1047					}
1048				);
1049			};
1050		} );
1051
1052		// submit a new question
1053		jQuery( ".cr-qna-block .cr-qna-new-q-form" ).on( "click", ".cr-review-form-submit", function( e ) {
1054			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1055			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
1056			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
1057			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1058			if( cr_validate_qna( jQuery( this ) ) ) {
1059				// submit the form if the validation is successful
1060				let cr_data = {
1061					"action": "cr_new_qna",
1062					"crNonce": jQuery( this ).closest( ".cr-qna-block" ).data( "nonce" ),
1063					"currentPostID": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-item-id" ).val(),
1064					"text": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment-txt" ).val().trim(),
1065					"name": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim(),
1066					"email": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim()
1067				};
1068				jQuery( this ).closest( ".cr-qna-new-q-form" ).addClass( "cr-review-form-submitting" );
1069				jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-success" );
1070				jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-error" );
1071				//
1072				const postQuestion = ( token, data, ref ) => {
1073					data.cptcha = token;
1074					jQuery.post(
1075						{
1076							url: cr_ajax_object.ajax_url,
1077							data: data,
1078							context: jQuery( ref ),
1079							success: function( response ) {
1080								this.closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-submitting" );
1081								this.closest( ".cr-qna-new-q-form" ).addClass( "cr-review-form-res" );
1082								this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-result span" ).html( response.description );
1083								this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).html( response.button );
1084								if( 0 === response.code ) {
1085									this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-success" );
1086								} else {
1087									this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-error" );
1088								}
1089							},
1090							dataType: "json"
1091						}
1092					);
1093				};
1094				//
1095				let cr_cptcha = jQuery(this).attr("data-crcptcha");
1096				var rf = this;
1097				if ( cr_cptcha && cr_cptcha.length > 0 ) {
1098					grecaptcha.ready(function() {
1099						grecaptcha.execute( cr_cptcha, {action: 'submit'} ).then( function(token) {
1100							postQuestion( token, cr_data, rf )
1101						} );
1102					} );
1103				} else {
1104					postQuestion( '', cr_data, rf );
1105				}
1106			};
1107		} );
1108
1109		// submit a new answer
1110		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-review-form-submit", function( e ) {
1111			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1112			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
1113			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
1114			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1115			if( cr_validate_ans( jQuery( this ) ) ) {
1116				// submit the form if the validation is successful
1117				let cr_data = {
1118					"action": "cr_new_qna",
1119					"crNonce": jQuery( this ).closest( ".cr-qna-block" ).data( "nonce" ),
1120					"currentPostID": jQuery( this ).closest( ".cr-qna-block" ).find( ".cr-review-form-item-id" ).val(),
1121					"questionID": jQuery( this ).closest( ".cr-qna-list-q-b" ).data( "question" ),
1122					"productID": jQuery( this ).closest( ".cr-qna-list-q-b" ).data( "post" ),
1123					"text": jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment-txt" ).val().trim(),
1124					"name": jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim(),
1125					"email": jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim()
1126				};
1127				jQuery( this ).closest( ".cr-qna-list-inl-answ" ).addClass( "cr-review-form-submitting" );
1128				jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-success" );
1129				jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-error" );
1130				//
1131				const postQuestion = ( token, data, ref ) => {
1132					data.cptcha = token;
1133					jQuery.post(
1134						{
1135							url: cr_ajax_object.ajax_url,
1136							data: data,
1137							context: jQuery( ref ),
1138							success: function( response ) {
1139								this.closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-submitting" );
1140								this.closest( ".cr-qna-list-inl-answ" ).addClass( "cr-review-form-res" );
1141								this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-result span" ).html( response.description );
1142								this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).html( response.button );
1143								if( 0 === response.code ) {
1144									this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-success" );
1145								} else {
1146									this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-error" );
1147								}
1148							},
1149							dataType: "json"
1150						}
1151					);
1152				};
1153				//
1154				let cr_cptcha = jQuery(this).attr("data-crcptcha");
1155				var rf = this;
1156				if ( cr_cptcha && cr_cptcha.length > 0 && grecaptcha ) {
1157					grecaptcha.ready(function() {
1158						grecaptcha.execute( cr_cptcha, {action: 'submit'} ).then( function(token) {
1159							postQuestion( token, cr_data, rf )
1160						} );
1161					} );
1162				} else {
1163					postQuestion( '', cr_data, rf );
1164				}
1165			};
1166		} );
1167
1168		// validate custom questions and ratings on submission of a review form on a product page
1169		jQuery( ".cr-single-product-review" ).on( "click", ".cr-single-product-rev-submit", function(t) {
1170			let validationResult = true;
1171			let reviewForm = jQuery( this ).closest( ".cr-single-product-review" );
1172
1173			// validate ratings
1174			reviewForm.find( ".cr-review-form-rating-cont.cr-review-form-rating-req" ).each( function( index ) {
1175				if( 1 > jQuery( this ).find( ".cr-review-form-rating-actv" ).length ) {
1176					jQuery( this ).closest( ".cr-review-form-rating" ).addClass( "cr-review-form-error" );
1177					validationResult = false;
1178				}
1179			} );
1180
1181			// validate custom questions
1182			reviewForm.find( ".cr-onsite-question.cr-review-form-que-req" ).each( function( index ) {
1183				if( 1 > jQuery( this ).find( "input[type=text]" ).val().trim().length ) {
1184					jQuery( this ).closest( ".cr-onsite-question" ).addClass( "cr-review-form-error" );
1185					validationResult = false;
1186				} else {
1187					jQuery( this ).closest( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
1188				}
1189			} );
1190
1191			// validate the comment field
1192			reviewForm.find( ".cr-review-form-textbox" ).each( function( index ) {
1193				if( 1 > jQuery( this ).val().trim().length ) {
1194					jQuery( this ).addClass( "cr-review-form-error" );
1195					validationResult = false;
1196				} else {
1197					jQuery( this ).removeClass( "cr-review-form-error" );
1198				}
1199			} );
1200
1201			// validate the terms checkbox
1202			if ( 0 < reviewForm.find( '.cr-review-form-terms' ).length ) {
1203				if ( ! reviewForm.find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1204					alert( 'Please tick the checkbox to proceed' );
1205					validationResult = false;
1206				}
1207			}
1208
1209			if( ! validationResult ) {
1210				t.preventDefault();
1211			}
1212		} );
1213
1214		// open the review form
1215		jQuery( ".cr-all-reviews-add-review" ).on( "click", function(t) {
1216			t.preventDefault();
1217			if ( 0 < jQuery( this ).closest( ".cr-all-reviews-shortcode" ).length ) {
1218				jQuery( this ).closest( ".cr-all-reviews-shortcode" ).addClass( "cr-all-reviews-new-review" );
1219			}
1220			if ( 0 < jQuery( this ).closest( ".cr-reviews-grid" ).length ) {
1221				jQuery( this ).closest( ".cr-reviews-grid" ).addClass( "cr-reviews-grid-new-review" );
1222			}
1223		} );
1224
1225		// upload media trigger
1226		jQuery( ".cr-review-form-wrap .cr-form-item-media-none" ).on( "click", function( t ) {
1227			jQuery( this ).parent().find( "input.cr-form-item-media-file" ).trigger( "click" );
1228		} );
1229
1230		// upload media trigger
1231		jQuery( ".cr-review-form-wrap .cr-form-item-media-preview" ).on( "click", ".cr-form-item-media-add", function( t ) {
1232			jQuery( this ).parents( ".cr-form-item-media" ).find( "input.cr-form-item-media-file" ).trigger( "click" );
1233		} );
1234
1235		// upload media
1236		jQuery( ".cr-review-form-wrap .cr-form-item-media .cr-form-item-media-file" ).on( "change", function () {
1237			let allowedTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif', 'video/mp4', 'video/mpeg', 'video/ogg', 'video/webm', 'video/quicktime', 'video/x-msvideo'],
1238			uploadFiles = jQuery( this ),
1239			countFiles = uploadFiles[0].files.length,
1240			lastIndex = 1,
1241			mediaPreview = jQuery( this ).parent().find( ".cr-form-item-media-preview" ),
1242			countUploaded = mediaPreview.children( ".cr-upload-images-containers" ).length;
1243			jQuery(this).closest(".cr-form-item-media").removeClass("cr-review-form-error");
1244			if( jQuery(this).attr("data-lastindex") ) {
1245				lastIndex = parseInt( jQuery( this ).attr( "data-lastindex" ) );
1246			}
1247			if( countFiles + countUploaded > cr_ajax_object.cr_images_upload_limit ) {
1248				jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1249				jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(cr_ajax_object.cr_upload_error_too_many);
1250				uploadFiles.val("");
1251				return;
1252			}
1253			for(let i = 0; i < countFiles; i++) {
1254				if(!allowedTypes.includes(uploadFiles[0].files[i].type) ) {
1255					jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1256					jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(cr_ajax_object.cr_upload_error_file_type);
1257					uploadFiles.val("");
1258					return;
1259				} else if( uploadFiles[0].files[i].size && uploadFiles[0].files[i].size > cr_ajax_object.cr_images_upload_max_size * 100 ) {
1260					jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1261					jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(cr_ajax_object.cr_upload_error_file_size);
1262					uploadFiles.val("");
1263					return;
1264				} else {
1265					let container = jQuery( "<div/>", {class:"cr-upload-images-containers cr-upload-images-container-" + (lastIndex + i)} );
1266					let progressBar = jQuery( "<div/>", {class:"cr-upload-images-pbar"} );
1267					progressBar.append(
1268						jQuery( "<div/>", {class:"cr-upload-images-pbarin"} )
1269					);
1270					if( -1 === uploadFiles[0].files[i].type.indexOf( 'image' ) ) {
1271						container.append(
1272							jQuery( "<svg class='cr-upload-video-thumbnail' viewBox='0 0 576 512'>
1272<path d='M336.2 64H47.8C21.4 64 0 85.4 0 111.8v288.4C0 426.6 21.4 448 47.8 448h288.4c26.4 0 47.8-21.4 47.8-47.8V111.8c0-26.4-21.4-47.8-47.8-47.8zm189.4 37.7L416 177.3v157.4l109.6 75.5c21.2 14.6 50.4-.3 50.4-25.8V127.5c0-25.4-29.1-40.4-50.4-25.8z'></path></svg>" )
1273						);
1274					} else {
1275						container.append(
1276							jQuery( "<img>", {class:"cr-upload-images-thumbnail", src:URL.createObjectURL(uploadFiles[0].files[i])} )
1277						);
1278					}
1279					container.append(
1280						progressBar
1281					);
1282					let removeButton = jQuery( "<button/>", {class:"cr-upload-images-delete"} );
1283					removeButton.append(
1284						'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path class="cr-no-icon" d="M12.12 10l3.53 3.53-2.12 2.12L10 12.12l-3.54 3.54-2.12-2.12L7.88 10 4.34 6.46l2.12-2.12L10 7.88l3.54-3.53 2.12 2.12z"/></g></svg>'
1285					);
1286					container.append(
1287						removeButton
1288					);
1289					container.append(
1290						jQuery( "<input>", {name:"cr-upload-images-ids[]",type:"hidden",value:""} )
1291					);
1292					container.append(
1293						jQuery( "<span/>", {class:"cr-upload-images-delete-spinner"} )
1294					);
1295					mediaPreview.find( ".cr-form-item-media-add" ).remove();
1296					mediaPreview.append( container );
1297					if( countFiles + countUploaded < cr_ajax_object.cr_images_upload_limit ) {
1298						mediaPreview.append(
1299							jQuery( "<div class='cr-form-item-media-add'>+</div>" )
1300						);
1301					}
1302				}
1303			}
1304			if( 0 < mediaPreview.children( ".cr-upload-images-containers" ).length && ! mediaPreview.hasClass( "cr-form-visible" ) ) {
1305				mediaPreview.parents( ".cr-form-item-subcontainer" ).addClass( "cr-form-visible" );
1306			}
1307			for(let i = 0; i < countFiles; i++) {
1308				let formData = new FormData();
1309				formData.append( "action", "cr_upload_media" );
1310				formData.append( "cr_file", uploadFiles[0].files[i] );
1311				formData.append( "cr_item", jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-item-id" ).val() );
1312				var currentFileInput = jQuery( this );
1313				jQuery.ajax({
1314					url: cr_ajax_object.ajax_url,
1315					data: formData,
1316					processData: false,
1317					contentType: false,
1318					dataType: "json",
1319					type: "POST",
1320					context: this,
1321					beforeSend: function() {
1322					},
1323					xhr: function() {
1324						var myXhr = jQuery.ajaxSettings.xhr();
1325						if ( myXhr.upload ) {
1326							myXhr.upload.addEventListener( 'progress', function(e) {
1327								if ( e.lengthComputable ) {
1328									let perc = ( e.loaded / e.total ) * 100;
1329									perc = perc.toFixed(0);
1330									currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " .cr-upload-images-pbar .cr-upload-images-pbarin" ).width(perc + "%");
1331								}
1332							}, false );
1333						}
1334						return myXhr;
1335					},
1336					success: function(response) {
1337						if(200 === response["code"]) {
1338							let idkey = JSON.stringify( { "id": response["attachment"]["id"], "key": response["attachment"]["key"] } );
1339							currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " input").val(idkey);
1340							currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).addClass("cr-upload-ok");
1341						} else if(500 <= response["code"]) {
1342							currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).remove();
1343							let mediaPreview = jQuery(this).closest(".cr-form-item-media").find(".cr-form-item-media-preview");
1344							let countUploaded = mediaPreview.find( ".cr-upload-images-containers" ).length;
1345							if( 0 < countUploaded ) {
1346								if( 0 === mediaPreview.children( ".cr-form-item-media-add" ).length ) {
1347									mediaPreview.append(
1348										jQuery( "<div class='cr-form-item-media-add'>+</div>" )
1349									);
1350								}
1351							} else {
1352								mediaPreview.removeClass( "cr-form-visible" );
1353								mediaPreview.parents( ".cr-form-item-subcontainer" ).removeClass( "cr-form-visible" );
1354							}
1355							jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1356							jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(response["message"]);
1357						}
1358					}
1359				});
1360			}
1361			jQuery(this).attr("data-lastindex", lastIndex + countFiles);
1362			uploadFiles.val("");
1363		} );
1364
1365		// delete uploaded image
1366		jQuery(".cr-review-form-wrap .cr-form-item-media-preview").on("click", ".cr-upload-images-delete", function (e) {
1367			e.preventDefault();
1368			let imgContainer = jQuery(this).parent(),
1369			mediaPreview = imgContainer.parent();
1370			let ajaxData = {
1371				"action": "cr_delete_media",
1372				"image": jQuery( this ).parent().children( "input" ).eq( 0 ).val()
1373			}
1374			imgContainer.addClass( "cr-upload-delete-pending" );
1375			jQuery.post( cr_ajax_object.ajax_url, ajaxData, function(response) {
1376				imgContainer.removeClass( "cr-upload-delete-pending" );
1377				if( 200 === response["code"] ) {
1378					imgContainer.remove();
1379					let countUploaded = mediaPreview.children( ".cr-upload-images-containers" ).length;
1380					if( 0 < countUploaded ) {
1381						if( 0 === mediaPreview.children( ".cr-form-item-media-add" ).length ) {
1382							mediaPreview.append(
1383								jQuery( "<div class='cr-form-item-media-add'>+</div>" )
1384							);
1385						}
1386					} else {
1387						mediaPreview.removeClass( "cr-form-visible" );
1388						mediaPreview.parents( ".cr-form-item-subcontainer" ).removeClass( "cr-form-visible" );
1389					}
1390				}
1391			}, "json" );
1392		} );
1393
1394		cr_maybe_download_media_frontend();
1395
1396		if( "object" === typeof elementorFrontend && "hooks" in elementorFrontend ) {
1397			elementorFrontend.hooks.addAction( "frontend/element_ready/widget", function( $scope ) {
1398				if( -1 !== $scope.data( "widget_type" ).indexOf( "shortcode" ) ) {
1399					if( 0 < $scope.find( ".cr-reviews-grid-inner" ).length ) {
1400						crResizeAllGridItems();
1401					}
1402				}
1403			} );
1404		}
1405
1406	} );
1407
1408	const crValidateEmail = (email) => {
1409		return email.match(
1410			/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
1411		);
1412	};
1413
1414	function initVoteClick(sel1, sel2, action) {
1415		jQuery(sel1).on("click", sel2, function(e) {
1416			e.preventDefault();
1417
1418			let reviewIDhtml = jQuery(this).data("vote");
1419			let parent = jQuery(this).parents(".cr-voting-cont-uni");
1420
1421			if(reviewIDhtml != null) {
1422				let reviewID = reviewIDhtml;
1423				let data = {
1424					"action": action,
1425					"reviewID": reviewID,
1426					"upvote": jQuery(this).data("upvote")
1427				};
1428
1429				parent.find(".cr-voting-a").removeClass("cr-voting-active");
1430				parent.find(".cr-voting-a").addClass("cr-voting-update");
1431				jQuery.post(cr_ajax_object.ajax_url, data, function(response) {
1432					parent.find(".cr-voting-a").removeClass("cr-voting-update");
1433					if( response.code === 0 ) {
1434						if( response.votes ) {
1435							parent.find(".cr-voting-upvote-count").text("(" +  response.votes.upvotes + ")");
1436							parent.find(".cr-voting-downvote-count").text("(" +  response.votes.downvotes + ")");
1437						}
1438						if( 0 !== response.votes.current ) {
1439							if( 0 < response.votes.current ) {
1440								parent.find(".cr-voting-upvote").addClass("cr-voting-active");
1441							} else {
1442								parent.find(".cr-voting-downvote").addClass("cr-voting-active");
1443							}
1444						}
1445					}
1446				}, "json");
1447			}
1448		});
1449	}
1450
1451	function cr_keyup_delay(fn, ms) {
1452		let timer = 0;
1453		return function(...args) {
1454			clearTimeout(timer);
1455			timer = setTimeout(fn.bind(this, ...args), ms || 0);
1456		};
1457	}
1458
1459	function cr_filter_all_reviews( refElement, show_more = false ) {
1460		let attributes = refElement.parents(".cr-all-reviews-shortcode").data("attributes"),
1461		cr_rating = refElement.parents(".cr-all-reviews-shortcode").find(".ivole-summaryBox .ivole-histogramRow.ivole-histogramRow-s .cr-histogram-a").attr("data-rating"),
1462		cr_search = refElement.parents(".cr-all-reviews-shortcode").find(".cr-ajax-search input").val(),
1463		cr_sort = refElement.parents(".cr-all-reviews-shortcode").find(".cr-ajax-reviews-sort").children("option:selected").val();
1464		let cr_tags = [];
1465		refElement.parents(".cr-all-reviews-shortcode").find(".cr-review-tags-filter .cr-tags-filter.cr-tag-selected").each(
1466			function() {
1467				cr_tags.push( jQuery(this).attr("data-crtagid") );
1468			}
1469		);
1470		let cr_data = {
1471			"action": "cr_show_more_all_reviews",
1472			"attributes": attributes,
1473			"rating": cr_rating,
1474			"page": 0,
1475			"search": cr_search,
1476			"sort": cr_sort,
1477			"tags": cr_tags
1478		};
1479		//
1480		if( show_more ) {
1481			cr_data.page = refElement.data( "page" );
1482			// click on 'show more' button
1483			jQuery(".cr-search-no-reviews").hide();
1484			jQuery('.cr-show-more-button').hide();
1485
1486			// dim the list of comments when dealing with the pagination
1487			if ( refElement.hasClass( "cr-page-numbers-a" ) ) {
1488				refElement.closest( ".cr-all-reviews-shortcode" ).find( ".commentlist" ).addClass( "cr-pagination-load" );
1489				refElement.closest( ".cr-all-reviews-shortcode" ).find( ".cr-all-reviews-pagination" ).addClass( "cr-pagination-load" );
1490			} else {
1491				refElement.closest( ".cr-all-reviews-shortcode" ).find( ".cr-show-more-review-spinner" ).show();
1492			}
1493
1494			jQuery.post(
1495				{
1496					url: cr_ajax_object.ajax_url,
1497					data: cr_data,
1498					context: refElement,
1499					success: function(response) {
1500						let shcode = jQuery(this).closest( ".cr-all-reviews-shortcode" );
1501						shcode.find( ".cr-show-more-review-spinner" ).hide();
1502						if( response.html !== "" ) {
1503							if ( jQuery(this).hasClass( "cr-page-numbers-a" ) ) {
1504								shcode.find(".commentlist").find("*").not(".cr-pagination-review-spinner").remove();
1505								shcode.find(".commentlist").prepend(response.html);
1506							} else {
1507								shcode.find(".commentlist").append(response.html);
1508							}
1509							if( ! response.last_page ) {
1510								shcode.find(".cr-show-more-button").text( response.show_more_label );
1511								shcode.find(".cr-show-more-button").show();
1512							}
1513							shcode.find(".cr-show-more-button").data( "page", response.page );
1514							shcode.find(".cr-count-row .cr-count-row-count").html( response.count_row );
1515							if ( response.pagination !== "" ) {
1516								shcode.find(".cr-all-reviews-pagination").html(response.pagination);
1517							}
1518						} else {
1519							shcode.find(".cr-show-more-button").hide();
1520						}
1521						if( response.html == "" && response.page === 1 ){
1522							shcode.find( ".cr-search-no-reviews" ).show();
1523						}
1524						shcode.find( ".commentlist" ).removeClass( "cr-pagination-load" );
1525						shcode.find( ".cr-all-reviews-pagination" ).removeClass( "cr-pagination-load" );
1526					},
1527					dataType: "json"
1528				}
1529			);
1530		} else {
1531			// click on 'search' button
1532			refElement.closest(".cr-all-reviews-shortcode").find(".cr-search-no-reviews").hide();
1533			refElement.closest(".cr-all-reviews-shortcode").find(".cr-show-more-button").hide();
1534			refElement.closest(".cr-all-reviews-shortcode").find(".commentlist").hide();
1535			refElement.closest(".cr-all-reviews-shortcode").find(".cr-show-more-review-spinner").show();
1536			refElement.closest(".cr-all-reviews-shortcode").find(".ivole-summaryBox").addClass("cr-summaryBar-updating");
1537			refElement.closest(".cr-all-reviews-shortcode").find(".cr-seeAllReviews").addClass("cr-seeAll-updating");
1538			refElement.closest(".cr-all-reviews-shortcode").find(".cr-ajax-reviews-sort").addClass("cr-sort-updating");
1539			refElement.closest(".cr-all-reviews-shortcode").find(".cr-review-tags-filter").addClass("cr-tags-updating");
1540			refElement.closest(".cr-all-reviews-shortcode").find(".cr-all-reviews-pagination").hide();
1541			jQuery.post(
1542				{
1543					url: cr_ajax_object.ajax_url,
1544					data: cr_data,
1545					context: refElement,
1546					success: function(response) {
1547						let shcode = jQuery(this).closest( ".cr-all-reviews-shortcode" );
1548						shcode.find( ".cr-show-more-review-spinner" ).hide();
1549						shcode.find(".ivole-summaryBox").removeClass("cr-summaryBar-updating");
1550						shcode.find(".cr-seeAllReviews").removeClass("cr-seeAll-updating");
1551						shcode.find(".cr-ajax-reviews-sort").removeClass("cr-sort-updating");
1552						shcode.find(".cr-review-tags-filter").removeClass("cr-tags-updating");
1553						if(response.html !== ""){
1554							shcode.find(".commentlist").empty();
1555							shcode.find(".commentlist").append(response.html);
1556							shcode.find(".commentlist").show();
1557							shcode.find(".cr-show-more-button").data("page",response.page);
1558							if( !response.last_page ){
1559								shcode.find(".cr-show-more-button").text( response.show_more_label );
1560								shcode.find(".cr-show-more-button").show();
1561							}
1562						} else {
1563							shcode.find(".cr-search-no-reviews").show();
1564						}
1565						shcode.find(".cr-count-row .cr-count-row-count").html( response.count_row );
1566						shcode.find(".cr-all-reviews-pagination").html(response.pagination);
1567						shcode.find(".cr-all-reviews-pagination").show();
1568					},
1569					dataType: "json"
1570				}
1571			);
1572		}
1573	}
1574
1575	function cr_maybe_download_media_frontend() {
1576		jQuery(".cr-comment-image-ext,.cr-comment-video-ext").each(function() {
1577			let ajaxData = {
1578				"action": "cr_auto_download_media_frontend",
1579				"reviewID": jQuery(this).data("reviewid")
1580			}
1581			jQuery.post(cr_ajax_object.ajax_url, ajaxData, function(response) {
1582				// do nothing
1583			}, "json");
1584			return false;
1585		});
1586	}
1587
1588	function cr_validate_review_form( submitBtn ) {
1589		let validationResult = true;
1590
1591		submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont.cr-review-form-rating-req" ).each( function( index ) {
1592			if( 1 > jQuery( this ).find( ".cr-review-form-rating-actv" ).length ) {
1593				jQuery( this ).closest( ".cr-review-form-rating" ).addClass( "cr-review-form-error" );
1594				validationResult = false;
1595			}
1596		} );
1597		if( 1 > submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment-txt" ).val().trim().length ) {
1598			submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment" ).addClass( "cr-review-form-error" );
1599			validationResult = false;
1600		}
1601		if( 1 > submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim().length ) {
1602			submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name" ).addClass( "cr-review-form-error" );
1603			validationResult = false;
1604		}
1605		if( ! crValidateEmail( submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim() ) ) {
1606			submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email" ).addClass( "cr-review-form-error" );
1607			validationResult = false;
1608		}
1609		// validate custom questions
1610		submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-question.cr-review-form-que-req" ).each( function( index ) {
1611			if ( 0 < jQuery( this ).find( "input[type=text]" ).length ) {
1612				if( 1 > jQuery( this ).find( "input[type=text]" ).val().trim().length ) {
1613					jQuery( this ).closest( ".cr-onsite-question" ).addClass( "cr-review-form-error" );
1614					validationResult = false;
1615				} else {
1616					jQuery( this ).closest( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
1617				}
1618			}
1619			if ( 0 < jQuery( this ).find( "input[type=number]" ).length ) {
1620				if( 1 > jQuery( this ).find( "input[type=number]" ).val().trim().length ) {
1621					jQuery( this ).closest( ".cr-onsite-question" ).addClass( "cr-review-form-error" );
1622					validationResult = false;
1623				} else {
1624					jQuery( this ).closest( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
1625				}
1626			}
1627		} );
1628		// validate terms and conditions if available
1629		if ( 0 < submitBtn.closest( ".cr-review-form-wrap" ).find( '.cr-review-form-terms' ).length ) {
1630			if ( ! submitBtn.closest( ".cr-review-form-wrap" ).find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1631				submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms" ).addClass( "cr-review-form-error" );
1632				validationResult = false;
1633			}
1634		}
1635		// validate captcha if available
1636		if ( 0 < submitBtn.closest( ".cr-review-form-wrap" ).find( '.cr-review-form-captcha .cr-recaptcha' ).length ) {
1637			if ( grecaptcha ) {
1638				let widgetId = 0;
1639				// check if there are multiple captchas on a page
1640				if ( 0 < jQuery( ".cr-review-form-captcha .cr-recaptcha" ).length ) {
1641					jQuery( ".cr-review-form-captcha .cr-recaptcha" ).each(
1642						function( index ) {
1643							if (
1644								submitBtn.closest( '.cr-review-form-wrap' ).find( '.cr-review-form-captcha .cr-recaptcha' ).data( 'crcaptchaid' ) === jQuery(this).data( 'crcaptchaid' )
1645							) {
1646								widgetId = index;
1647							}
1648						}
1649					);
1650				}
1651				//
1652				let captchaCheck = "";
1653				if ( 0 < widgetId ) {
1654					captchaCheck = grecaptcha.getResponse( widgetId );
1655				} else {
1656					captchaCheck = grecaptcha.getResponse();
1657				}
1658				if ( ! captchaCheck.length > 0 ) {
1659					submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-captcha" ).addClass( "cr-review-form-error" );
1660					validationResult = false;
1661				}
1662			}
1663		}
1664
1665		return validationResult;
1666	}
1667
1668	function cr_validate_qna( submitBtn ) {
1669		let validationResult = true;
1670		if( 1 > submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment-txt" ).val().trim().length ) {
1671			submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment" ).addClass( "cr-review-form-error" );
1672			validationResult = false;
1673		}
1674		if( 1 > submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim().length ) {
1675			submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name" ).addClass( "cr-review-form-error" );
1676			validationResult = false;
1677		}
1678		if( ! crValidateEmail( submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim() ) ) {
1679			submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email" ).addClass( "cr-review-form-error" );
1680			validationResult = false;
1681		}
1682		if ( 0 < submitBtn.closest( ".cr-qna-new-q-form" ).find( '.cr-review-form-terms' ).length ) {
1683			if ( ! submitBtn.closest( ".cr-qna-new-q-form" ).find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1684				submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms" ).addClass( "cr-review-form-error" );
1685				validationResult = false;
1686			}
1687		}
1688		return validationResult;
1689	}
1690
1691	function cr_validate_ans( submitBtn ) {
1692		let validationResult = true;
1693		if( 1 > submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment-txt" ).val().trim().length ) {
1694			submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment" ).addClass( "cr-review-form-error" );
1695			validationResult = false;
1696		}
1697		if( 1 > submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim().length ) {
1698			submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name" ).addClass( "cr-review-form-error" );
1699			validationResult = false;
1700		}
1701		if( ! crValidateEmail( submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim() ) ) {
1702			submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email" ).addClass( "cr-review-form-error" );
1703			validationResult = false;
1704		}
1705		if ( 0 < submitBtn.closest( ".cr-qna-list-inl-answ" ).find( '.cr-review-form-terms' ).length ) {
1706			if ( ! submitBtn.closest( ".cr-qna-list-inl-answ" ).find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1707				submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms" ).addClass( "cr-review-form-error" );
1708				validationResult = false;
1709			}
1710		}
1711		return validationResult;
1712	}
1713
1714	function cr_reset_review_form( refElement ) {
1715		// reset the rating bar
1716		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-inner" ).removeClass( "cr-review-form-rating-actv" );
1717		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-inner .cr-rating-act" ).hide();
1718		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-inner .cr-rating-deact" ).show();
1719		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-nbr" ).text( "0/5" );
1720		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating" ).removeClass( "cr-review-form-error" );
1721
1722		// reset the comment field
1723		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment-txt" ).val('');
1724		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1725
1726		// reset the name field
1727		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name .cr-review-form-txt" ).val('');
1728		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
1729
1730		// reset the email field
1731		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email .cr-review-form-txt" ).val('');
1732		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
1733
1734		// reset the custom questions
1735		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-questions .cr-onsite-question" ).removeClass( "cr-review-form-error" );
1736		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-questions .cr-onsite-question input[type = 'text']" ).val('');
1737		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-questions .cr-onsite-question input[type = 'number']" ).val('');
1738
1739		// reset the media files
1740		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-upload-images-containers" ).remove();
1741		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-form-item-media-preview" ).removeClass( "cr-form-visible" );
1742		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-form-item-media-preview" ).parents( ".cr-form-item-subcontainer" ).removeClass( "cr-form-visible" );
1743
1744		// reset the terms and conditions checkbox
1745		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms .cr-review-form-checkbox" ).prop( 'checked', false );
1746		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1747
1748		// reset recaptcha
1749		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-captcha" ).removeClass( "cr-review-form-error" );
1750	}
1751
1752	function cr_reset_qna_form( refElement ) {
1753		// reset the comment field
1754		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment-txt" ).val('');
1755		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1756
1757		// reset the name field
1758		const nameField = refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name" );
1759		nameField.find( ".cr-review-form-txt" ).val(nameField.find( ".cr-review-form-txt" ).data('defval'));
1760		nameField.removeClass( "cr-review-form-error" );
1761
1762		// reset the email field
1763		const emailField = refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email" );
1764		emailField.find( ".cr-review-form-txt" ).val(emailField.find( ".cr-review-form-txt" ).data('defval'));
1765		emailField.removeClass( "cr-review-form-error" );
1766
1767		// reset the terms and conditions checkbox
1768		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms .cr-review-form-checkbox" ).prop( 'checked', false );
1769		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1770	}
1771
1772	function cr_reset_ans_form( refElement ) {
1773		// reset the comment field
1774		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment-txt" ).val("");
1775		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1776
1777		// reset the name field
1778		const nameField = refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name" );
1779		nameField.find( ".cr-review-form-txt" ).val("");
1780		nameField.removeClass( "cr-review-form-error" );
1781
1782		// reset the email field
1783		const emailField = refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email" );
1784		emailField.find( ".cr-review-form-txt" ).val("");
1785		emailField.removeClass( "cr-review-form-error" );
1786
1787		// reset the terms and conditions checkbox
1788		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms .cr-review-form-checkbox" ).prop( 'checked', false );
1789		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1790	}
1791
1792	function crDebounce(callback, wait) {
1793		let timeout;
1794		return (...args) => {
1795			clearTimeout(timeout);
1796			if ( 0 < args.length && 13 === args[0].keyCode ) {
1797				wait = 0;
1798			} else {
1799				wait = 1000;
1800			}
1801			timeout = setTimeout(function () { callback.apply(this, args); }, wait);
1802		};
1803	}
1804
1805	function crShowMoreReviewsPrd( refElement ) {
1806		let cr_product_id = refElement.parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").attr("data-product");
1807		let cr_nonce = refElement.parents(".cr-reviews-ajax-comments").attr("data-nonce");
1808		let cr_page = refElement.parents(".cr-reviews-ajax-comments").attr("data-page");
1809		let cr_sort = refElement.parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-sort").children("option:selected").val();
1810		let cr_rating = refElement.parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax tr.ivole-histogramRow.ivole-histogramRow-s a.ivole-histogram-a").attr("data-rating");
1811		let cr_search = refElement.parents(".cr-reviews-ajax-comments").find(".cr-ajax-search input").val();
1812		let cr_tags = [];
1813		refElement.parents(".cr-reviews-ajax-comments").find(".cr-review-tags-filter .cr-tags-filter.cr-tag-selected").each(
1814			function() {
1815				cr_tags.push( jQuery(this).attr("data-crtagid") );
1816			}
1817		);
1818		if ( ! cr_rating ){
1819			cr_rating = 0;
1820		}
1821		let cr_data = {
1822			"action": "cr_show_more_reviews",
1823			"productID": cr_product_id,
1824			"page": cr_page,
1825			"sort": cr_sort,
1826			"rating": cr_rating,
1827			"search": cr_search,
1828			"tags": cr_tags,
1829			"security": cr_nonce
1830		};
1831		refElement.parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").addClass("cr-summaryBar-updating");
1832		refElement.parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-sort").addClass("cr-sort-updating");
1833		refElement.parents(".cr-reviews-ajax-comments").find(".cr-review-tags-filter").addClass("cr-review-tags-filter-disabled");
1834		refElement.parents(".cr-reviews-ajax-comments").find(".cr-search-no-reviews").hide();
1835		refElement.parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").hide();
1836		refElement.parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").show();
1837		jQuery.post( {
1838			url: cr_ajax_object.ajax_url,
1839			data: cr_data,
1840			context: refElement,
1841			success: function(response) {
1842				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").hide();
1843				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").removeClass("cr-summaryBar-updating");
1844				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-sort").removeClass("cr-sort-updating");
1845				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-review-tags-filter").removeClass("cr-review-tags-filter-disabled");
1846				if( response.page > 0 ) {
1847					jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").append( response.html );
1848					jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page",response.page);
1849					if ( response.show_more_label ) {
1850						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").text( response.show_more_label );
1851					}
1852					if ( response.count_row ) {
1853						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-count-row .cr-count-row-count").html( response.count_row );
1854					}
1855					if ( ! response.last_page ) {
1856						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").show();
1857					}
1858					cr_maybe_download_media_frontend();
1859				}
1860				if ( response.html == null && response.page === 1 ) {
1861					jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-search-no-reviews").show();
1862				}
1863			},
1864			dataType: "json"
1865		} );
1866	}
1867
1868})();
1869
1870function crResizeAllGridItemsUtil(grids) {
1871	jQuery(grids).each( function() {
1872		if(800 > jQuery(this).width()) {
1873			jQuery(this).find(".cr-reviews-grid-col3").addClass("cr-reviews-grid-col-none");
1874		}
1875		if(550 > jQuery(this).width()) {
1876			jQuery(this).find(".cr-reviews-grid-col2").addClass("cr-reviews-grid-col-none");
1877		}
1878		jQuery(this).colcade( {
1879			columns: ".cr-reviews-grid-col",
1880			items: ".cr-review-card"
1881		} );
1882	} );
1883}
1884
1885function crResizeAllGridItems() {
1886	if (
1887		typeof Colcade !== "undefined" &&
1888		typeof Colcade.makeJQueryPlugin !== "undefined" &&
1889		typeof Colcade.makeJQueryPlugin === "function"
1890	) {
1891		if (
1892			! typeof jQuery.fn.colcade === "function" ||
1893			typeof jQuery.fn.colcade === "undefined"
1894		) {
1895			Colcade.makeJQueryPlugin();
1896		}
1897	}
1898	crResizeAllGridItemsUtil( jQuery(".cr-reviews-grid-inner") );
1899}
1900
1901function crResizeTrustBadges() {
1902	jQuery(".cr-trustbadgef").each(function() {
1903		let badge = jQuery(this).find(".cr-badge").eq(0);
1904		let scale = jQuery(this).width() / badge.outerWidth();
1905		if( 1 > scale ) {
1906			badge.css("transform", "scale(" + scale + ")");
1907		}
1908		badge.css("visibility", "visible");
1909	});
1910}

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.