PageSourceSearch

https://www.pinglighting.com/modules/ets_reviews/views/js/function.js

js pinglighting.com collected 2026-10-06 18:27:39 UTC 135,229 bytes, 2,562 lines download raw bytes

1/**
2 * Copyright ETS Software Technology Co., Ltd
3 *
4 * NOTICE OF LICENSE
5 *
6 * This file is not open source! Each license that you purchased is only available for 1 website only.
7 * If you want to use this file on more websites (or projects), you need to purchase additional licenses.
8 * You are not allowed to redistribute, resell, lease, license, sub-license or offer our resources to any third party.
9 *
10 * DISCLAIMER
11 *
12 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
13 * versions in the future.
14 *
15 * @author ETS Software Technology Co., Ltd
16 * @copyright  ETS Software Technology Co., Ltd
17 * @license    Valid for 1 website (or project) for each purchase of license
18 */
19try {
20    var ETS_RV_DATETIME_PICKER = typeof ets_rv_datetime_picker !== "undefined" ? JSON.parse(ets_rv_datetime_picker) : [];
21    ETS_RV_DATETIME_PICKER.currentText = ets_rv_datetime_picker_currentText ?? 'Now';
22    ETS_RV_DATETIME_PICKER.closeText = ets_rv_datetime_picker_closeText ?? 'Done';
23    ETS_RV_DATETIME_PICKER.timeOnlyTitle = ets_rv_datetime_picker_timeOnlyTitle ?? 'Choose time';
24    ETS_RV_DATETIME_PICKER.timeText = ets_rv_datetime_picker_timeText ?? 'Time';
25    ETS_RV_DATETIME_PICKER.hourText = ets_rv_datetime_picker_hourText ?? 'Hour';
26    ETS_RV_DATETIME_PICKER.minuteText = ets_rv_datetime_picker_minuteText ?? 'Minute';
27} catch (error) {
28    console.error(error);
29}
30var ETS_RV_DISPLAY_RATE_AND_QUESTION = typeof ETS_RV_DISPLAY_RATE_AND_QUESTION !== typeof undefined ? ETS_RV_DISPLAY_RATE_AND_QUESTION : 'button';
31var ETS_RV_SCROLL_ITEM = null;
32var ETS_RV_CONFIRM_DELETE_ITEM = typeof ets_rv_confirm_delete_item !== "undefined" && ets_rv_confirm_delete_item ? ets_rv_confirm_delete_item : 'Do you want to delete selected item?';
33// reCAPTCHA google.
34var reCaptchaETS = {
35    recaptchaWidgets: [],
36    onLoad: function (forms) {
37        if (ETS_RV_CUSTOMER_IS_LOGGED && ETS_RV_RECAPTCHA_USER_REGISTERED)
38            return;
39        if (ETS_RV_RECAPTCHA_TYPE !== 'recaptcha_v2')
40            reCaptchaETS.v3(forms);
41        else
42            reCaptchaETS.v2(forms);
43    },
44    reset: function (form) {
45        if (ETS_RV_CUSTOMER_IS_LOGGED && ETS_RV_RECAPTCHA_USER_REGISTERED)
46            return;
47        if (ETS_RV_RECAPTCHA_TYPE !== 'recaptcha_v2') {
48            form.removeClass('g-loaded');
49            reCaptchaETS.v3(form);
50        } else {
51            reCaptchaETS.v2Reset(form.attr('id'));
52        }
53    },
54    v2: function (forms) {
55        if (!ETS_RV_RECAPTCHA_ENABLED || !ETS_RV_RECAPTCHA_SITE_KEY || typeof forms === "undefined" || !forms)
56            return false;
57        const pattern = /(^|\s)g-recaptcha(\s|$)/;
58        for (let i = 0; i < forms.length; i++) {
59            if (forms[i].classList.contains('g-loaded'))
60                continue;
61            var items = forms[i].getElementsByTagName('div');
62            for (let k = 0; k < items.length; k++) {
63                if (items[k].className && items[k].className.match(pattern)) {
64                    this.recaptchaWidgets[forms[i].id] = grecaptcha.render(items[k], {
65                        'sitekey': ETS_RV_RECAPTCHA_SITE_KEY,
66                    });
67                    forms[i].classList.add('g-loaded');
68                    break;
69                }
70            }
71        }
72    },
73    v3: function (forms) {
74        if (!ETS_RV_RECAPTCHA_ENABLED || !ETS_RV_RECAPTCHA_SITE_KEY || typeof forms === "undefined" || !forms)
75            return false;
76        const pattern = /(^|\s)g-recaptcha-response(\s|$)/;
77        let body = document.getElementsByTagName('body'),
78            action = body[0].id ? body[0].id.replace(/(?=[^A-Za-z\_])([^A-Za-z\_])/g, '_') : 'submit'
79        ;
80        for (let i = 0; i < forms.length; i++) {
81            if (forms[i].classList.contains('g-loaded'))
82                continue;
83            let items = forms[i].getElementsByTagName('input');
84            for (let k = 0; k < items.length; k++) {
85                if (items[k].className && items[k].className.match(pattern)) {
86                    grecaptcha.ready(function () {
87                        grecaptcha.execute(ETS_RV_RECAPTCHA_SITE_KEY, {action: action}).then(function (token) {
88                            if (token) {
89                                items[k].value = token;
90                                forms[i].classList.add('g-loaded');
91                            }
92                        });
93                    });
94                    break;
95                }
96            }
97        }
98    },
99    v2Reset: function (id) {
100        if (!ETS_RV_RECAPTCHA_ENABLED || !ETS_RV_RECAPTCHA_SITE_KEY || !id)
101            return false;
102        if (this.recaptchaWidgets && grecaptcha) {
103            ETS_RV_RECAPTCHA_VALID = 0;
104            if (id) {
105                grecaptcha.reset(this.recaptchaWidgets[id]);
106                reCaptchaETS.removeClassError(id);
107            } else {
108                Object.keys(this.recaptchaWidgets).forEach(function (key) {
109                    grecaptcha.reset(this.recaptchaWidgets[key]);
110                    reCaptchaETS.removeClassError(key);
111                });
112            }
113        }
114    },
115    removeClassError: function (id) {
116        var form = document.getElementById(id);
117        if (form.classList.contains('g-loaded')) {
118            var ele = form.getElementsByClassName('g-recaptcha');
119            if (ele[0].classList.contains('error')) {
120                ele[0].classList.remove('error');
121            }
122        }
123    },
124};
125// End reCAPTCHA google.
126var funcPCETS = {
127    n2br: function (str) {
128        return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br />');
129    },
130    br2n: function (str) {
131        return (str + '').replace(/<br\s*[\/]?>/gi, '\r\n');
132    },
133    colorHex: function (str) {
134        var hash = 0;
135        if (str && str.length === 0) return hash;
136        for (var i = 0; i < str.length; i++) {
137            hash = str.charCodeAt(i) + ((hash << 5) - hash);
138            hash = hash & hash;
139        }
140        var color = '#';
141        for (var ik = 0; ik < 3; ik++) {
142            var value = (hash >> (ik * 8)) & 255;
143            color += ('00' + value.toString(16)).substr(-2);
144        }
145        return color;
146    },
147    readURL: function (input) {
148        if (input.files && input.files[0]) {
149            var reader = new FileReader();
150            reader.onload = function (e) {
151                if ($(input).hasClass('video')) {
152                    $(input).parents('.ets_rv_upload_video_item').addClass('cms_has_video').find('.ets_rv_video').html('<video controls><source src="' + e.target.result + '" type="video/mp4"></video>');
153                } else {
154                    $(input).parents('.ets_rv_upload_photo_item').addClass('cms_has_video').find('.ets_rv_upload_photo_wrap')
155                        .css('background-image', 'url(' + e.target.result + ')')
156                        .attr('title', input.files[0].name)
157                        .addClass('selected')
158                    ;
159                }
160
161            };
162            reader.readAsDataURL(input.files[0]);
163        }
164    },
165    decodeHTMLEntities: function (text) {
166        var textArea = document.createElement('textarea');
167        textArea.innerHTML = text;
168        return textArea.value;
169    },
170    //display a success/error/notice message
171    showSuccessMessage: function (msg) {
172        if ($.growl)
173            $.growl.notice({title: "", message: msg});
174    },
175    showErrorMessage: function (msg) {
176        if ($.growl)
177            $.growl.error({title: "", message: msg});
178    },
179    isSafari: function () {
180        var e = navigator, c = e.userAgent, g = e.vendor;
181        return (!(/(Chrome|CriOS)\s*\/\s*(\d[\d\.]*)/i).test(c) && ((/Apple/i).test(g) || !g) && (/Safari\s*\/\s*(\d[\d\.]*)/i).test(c));
182    },
183    hide: function (dom) {
184        if (dom.hasClass('bo')) {
185            dom.hide();
186        } else {
187            dom.remove();
188        }
189    },
190    show: function (dom) {
191        if (dom.hasClass('bo')) {
192            dom.show();
193        } else {
194            dom.remove();
195        }
196    },
197    isGuestLogin: function ($this, _prop) {
198        var prop = _prop || 'comment',
199            bindingEl = $this || $('body')
200        ;
201        if (!bindingEl.hasClass('loading')) {
202            bindingEl.addClass('loading');
203            $.ajax({
204                url: $('#ets-rv-product-' + prop + 's-list').data('comments-url'),
205                type: 'POST',
206                data: {
207                    __ac: 'is_guest_login'
208                },
209                dataType: 'json',
210                success: function (json) {
211                    bindingEl.removeClass('loading');
212                    if (json) {
213                        const decodedErrorMessage = $("<div/>").html(json.error).html();
214                        productCommentsETS.showUpdateErrorModal(decodedErrorMessage);
215                    }
216                },
217                error: function () {
218                    bindingEl.removeClass('loading');
219                }
220            });
221        }
222    },
223    stats: function (jsonData, prop) {
224        if (jsonData.length < 1 || prop === '')
225            return false;
226        const $stats = $('#ets-rv-product-comments-list-header');
227        var results = jsonData;
228
229        $('.ets_rv_average_rating .ets_rv_average_grade', $stats).html(results.average_grade.toFixed(1));
230        $('.ets_rv_average_rating .ets_rv_grade_stars', $stats).attr('data-grade', results.average_grade.toFixed(1));
231        $('.ets_rv_average_rating .ets_rv_nb_comments, .ets_rv_li_dropdown.ets_rv_all_review, .ets_rv_tab_reviews .ets_rv_selection', $stats).html(function () {
232            if ($(this).hasClass('ets_rv_selection')) {
233                var total = $(this).attr('data-default').replace(/\d+/, parseInt(results.nb_reviews));
234                $(this).attr('data-default', total);
235                return total;
236            } else if ($(this).hasClass('ets_rv_nb_comments')) {
237                return (parseInt(results.nb_reviews) > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%s/g, parseInt(results.nb_reviews));
238            } else
239                return $(this).html().replace(/\d+/, parseInt(results.nb_reviews));
240        });
241        $('.ets_rv_tab_questions .ets_rv_question_selection', $stats).html(function () {
242            return $(this).html().replace(/\d+/, parseInt(results.nb_questions))
243        });
244        if (prop !== 'question') {
245            var ets_rv_image_review = $('.ets_rv_li_dropdown.ets_rv_image_review');
246            if (ets_rv_image_review.length > 0) {
247                if (results.nb_reviewHasImageVideo) {
248                    ets_rv_image_review.html(ets_rv_image_review.html().replace(/\d+/, parseInt(results.nb_reviewHasImageVideo)));
249                    ets_rv_image_review.removeClass('empty');
250                } else
251                    ets_rv_image_review.addClass('empty');
252            }
253            if (results.grade_stats) {
254                $.each(results.grade_stats, function (i, stat) {
255                    $('.ets_rv_grade_stars_' + stat.id + ' .ets_rv_grade_stars_percent', $stats).css('width', stat.grade_percent.toFixed(1) + '%');
256                    $('.ets_rv_grade_stars_' + stat.id + ' .ets_rv_grade_stars_total', $stats).html(stat.grade_total);
257                    $('.ets_rv_' + stat.id + '', $stats).html(function () {
258                        if (stat.grade_total > 0) {
259                            $(this).removeClass('empty');
260                        } else {
261                            $(this).addClass('empty');
262                        }
263                        return $(this).html().replace(/\d+/, stat.grade_total);
264                    });
265                });
266            }
267            $('.ets_rv_header_wrap:hidden').show();
268        }
269    }
270};
271
272var productCommentsETS = {
273    init: function () {
274    },
275    getReviewPhotosSlickOptions: function () {
276        return {
277            arrows: true,
278            autoplay: true,
279            slidesToShow: 6,
280            slidesToScroll: 1,
281            speed: 300,
282            adaptiveHeight: false,
283            responsive: [
284                {
285                    breakpoint: 1199,
286                    settings: {
287                        slidesToShow: 6,
288                        slidesToScroll: 6,
289                        infinite: true,
290                        dots: true
291                    }
292                },
293                {
294                    breakpoint: 992,
295                    settings: {
296                        slidesToShow: 5,
297                        slidesToScroll: 5,
298                        infinite: true,
299                        dots: true
300                    }
301                },
302                {
303                    breakpoint: 768,
304                    settings: {
305                        slidesToShow: 4,
306                        slidesToScroll: 4
307                    }
308                },
309                {
310                    breakpoint: 480,
311                    settings: {
312                        slidesToShow: 3,
313                        slidesToScroll: 3
314                    }
315                }
316            ]
317        };
318    },
319    refreshReviewPhotosBlock: function () {
320        var $photosWrap = $('.ets_rv_review_photos_wrap').first();
321        if ($photosWrap.length < 1) {
322            return;
323        }
324        var $photos = $photosWrap.find('.ets_rv_review_photos').first();
325        var $items = $photos.find('.ets_rv_image_item');
326        if ($items.length < 1) {
327            $photosWrap.remove();
328            return;
329        }
330        $photosWrap.addClass('active');
331        if (typeof $.fn.slick === typeof undefined || $photos.length < 1) {
332            return;
333        }
334        if (!$photos.hasClass('slick-initialized')) {
335            $photos.slick(productCommentsETS.getReviewPhotosSlickOptions());
336            return;
337        }
338        $photos.slick('setPosition');
339    },
340    hasValidPhotosMarkup: function (photos) {
341        return typeof photos === 'string'
342            && photos.indexOf('ets_rv_review_photos_wrap') !== -1
343            && photos.indexOf('ets_rv_image_item') !== -1;
344    },
345    initSlider: function (photos) {
346        if (!productCommentsETS.hasValidPhotosMarkup(photos)) {
347            return;
348        }
349        var decodedPhotos = $.trim(funcPCETS.decodeHTMLEntities(photos));
350        if (!decodedPhotos) {
351            return;
352        }
353
354        var $currentWrap = $('.ets_rv_review_photos_wrap').first();
355        if ($currentWrap.length > 0) {
356            $currentWrap.replaceWith(decodedPhotos);
357        } else {
358            $('.ets_rv_statistics').after(decodedPhotos);
359        }
360
361        productCommentsETS.refreshReviewPhotosBlock();
362    },
363    showErrorModal: function (errorMessage) {
364        $('#ets-rv-product-comment-post-error-message').html(errorMessage);
365        $('#ets-rv-product-comment-post-error').ETSModal('show');
366        $('.post-question-buttons button').removeClass('active');
367        if (typeof id_language !== "undefined") {
368            showErrorMessage(errorMessage);
369        }
370    },
371    rawActions: function ($productComment, data, prop) {
372        // like.
373        $('.useful-' + data.type + ':not(.disable)', $productComment).click(function () {
374            data.options.usefulness = 1;
375            data.options.__ac = 'useful_' + data.type.replace('-', '_');
376            productCommentsETS.updateUsefulness($productComment, data, prop);
377        });
378
379        if (data.usefulness > 0 && data.current) {
380            $('.useful-' + data.type, $productComment).addClass('current');
381        }
382
383        // dislike.
384        $('.ets-rv-not-useful-' + data.type + ':not(.disable)', $productComment).click(function () {
385            data.options.usefulness = 0;
386            data.options.__ac = 'useful_' + data.type.replace('-', '_');
387            productCommentsETS.updateUsefulness($productComment, data, prop
387);
388        });
389
390        if (data.usefulness < 1 && data.current) {
391            $('.ets-rv-not-useful-' + data.type, $productComment).addClass('current');
392        }
393
394        if (prop !== 'comment') {
395            $('.useful-answer.bo', $productComment).click(function () {
396                data.options.usefulness = $(this).hasClass('checked') ? 0 : 1;
397                data.options.__ac = 'useful_answer';
398                productCommentsETS.usefulnessAnswer($productComment, data, prop);
399            });
400        }
401    },
402    add: function (comment, isPosted) {
403        const qa = comment.question && parseInt(comment.question) > 0 ? 1 : 0;
404        const prop = qa ? 'question' : 'comment';
405        const commentsList = $('#ets-rv-product-' + prop + 's-list');
406        var commentTemplate = productCommentsETS.htmlTemplate($('#ets-rv-product-' + prop + '-item-prototype').html(), comment),
407            initialComments = commentsList.data('comments-initial') ? parseInt(commentsList.data('comments-initial')) : 1,
408            commentsNbForward = typeof comment.comments_nb_forward !== "undefined" ? parseInt(comment.comments_nb_forward) : 0,
409            commentsNb = parseInt(comment.comments_nb),
410            nbComments = commentsNb + commentsNbForward,
411            answersNbForward = typeof comment.answers_nb_forward !== "undefined" ? parseInt(comment.answers_nb_forward) : 0,
412            answersNb = typeof comment.answers_nb !== "undefined" ? parseInt(comment.answers_nb) : 0,
413            nbAnswers = answersNb + answersNbForward
414        ;
415        commentTemplate = commentTemplate.replace(/@COMMENT_ID@/g, comment.id_ets_rv_comment);
416        if (typeof comment.title === "object") {
417            var languages = Object.keys(comment.title);
418            languages.forEach(function (id_lang) {
419                var regEx = new RegExp('@COMMENT_TITLE_' + id_lang + '@', 'g');
420                commentTemplate = commentTemplate.replace(regEx, comment.title[id_lang] ? comment.title[id_lang] : '');
421            });
422        } else
423            commentTemplate = commentTemplate.replace(/@COMMENT_TITLE@/g, comment.title ? comment.title : '');
424        commentTemplate = commentTemplate.replace(/@COMMENT_GRADE@/g, parseFloat(comment.grade).toFixed(1));
425        commentTemplate = commentTemplate.replace(/@COMMENT_IMAGES@/g, comment.images);
426        commentTemplate = commentTemplate.replace(/@COMMENT_VIDEOS@/g, comment.videos);
427        commentTemplate = commentTemplate.replace(/@COMMENTS_PER_PAGE@/g, commentsList.data('comments-per-page') ? parseInt(commentsList.data('comments-per-page')) : 5);
428        commentTemplate = commentTemplate.replace(/@COMMENTS_NB@/g, nbComments);
429        // Comment's.
430        if (comment.comments) {
431            if (commentsNbForward > 0) {
432                var initialCommentsReal = initialComments + commentsNb;
433                commentTemplate = commentTemplate.replace(/@COMMENTS_BEGIN@/g, initialCommentsReal);
434                commentTemplate = commentTemplate.replace(/@COMMENTS_LOADMORE@/g, nbComments > initialCommentsReal ? nbComments - initialCommentsReal : 0);
435                commentTemplate = commentTemplate.replace(/@COMMENTS_BEGIN_FORWARD@/g, commentsNb > initialComments ? commentsNb - initialComments : 0);
436                commentTemplate = commentTemplate.replace(/@COMMENTS_LOADMORE_FORWARD@/g, commentsNb);
437                commentTemplate = commentTemplate.replace(/@COMMENTS_PER_PAGE_FORWARD@/g, commentsNb > commentsList.data('comments-per-page') ? parseInt(commentsList.data('comments-per-page')) : commentsNb);
438            } else {
439                commentTemplate = commentTemplate.replace(/@COMMENTS_BEGIN@/g, initialComments);
440                commentTemplate = commentTemplate.replace(/@COMMENTS_LOADMORE@/g, commentsNb > initialComments ? commentsNb - initialComments : 0);
441            }
442        }
443
444        // Answer's
445        if (prop !== 'comment')
446            commentTemplate = commentTemplate.replace(/@ANSWERS_NB@/g, nbAnswers);
447        if (comment.answers) {
448            if (answersNbForward > 0) {
449                var initialAnswersReal = initialComments + answersNb;
450                commentTemplate = commentTemplate.replace(/@ANSWERS_BEGIN@/g, initialAnswersReal);
451                commentTemplate = commentTemplate.replace(/@ANSWERS_LOADMORE@/g, nbAnswers > initialAnswersReal ? nbAnswers - initialAnswersReal : 0);
452                commentTemplate = commentTemplate.replace(/@ANSWERS_BEGIN_FORWARD@/g, answersNb > initialComments ? answersNb - initialComments : 0);
453                commentTemplate = commentTemplate.replace(/@ANSWERS_LOADMORE_FORWARD@/g, answersNb);
454                commentTemplate = commentTemplate.replace(/@ANSWERS_PER_PAGE_FORWARD@/g, answersNb > commentsList.data('comments-per-page') ? parseInt(commentsList.data('comments-per-page')) : answersNb);
455            } else {
456                commentTemplate = commentTemplate.replace(/@ANSWERS_BEGIN@/g, initialComments);
457                commentTemplate = commentTemplate.replace(/@ANSWERS_LOADMORE@/g, answersNb > initialComments ? answersNb - initialComments : 0);
458            }
459        }
460
461        const $productComment = $(commentTemplate);
462        const $action = $('.comment_dropdown_action', $productComment);
463        const $comment_title = $('.ets-rv-product-comment-title-html', $productComment);
464
465        // Load more comments.
466        if (comment.comments && (commentsNbForward > 0 && nbComments > initialCommentsReal || commentsNbForward <= 0 && commentsNb > initialComments)) {
467            var btn = $('.ets_rv_comment_load_more:not(.answer):not(.forward-comments)', $productComment),
468                rest = parseInt(btn.attr('data-rest')),
469                per_page = parseInt(btn.attr('data-comments-per-page'))
470            ;
471            btn.show();
472            if (rest > per_page) {
473                btn.html(function () {
474                    return (rest > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, per_page).replace(/%2s/g, rest);
475                });
476            } else {
477                btn.html(function () {
478                    return (rest > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, rest);
479                });
480            }
481        }
482        // Load more comments forward.
483        if (comment.comments && commentsNbForward > 0) {
484            var btn_forward = $('.ets_rv_comment_load_more.forward-comments.bo:not(.answer)', $productC
484omment),
485                rest_forward = parseInt(btn_forward.attr('data-rest')),
486                per_page_forward = parseInt(btn_forward.attr('data-comments-per-page'))
487            ;
488            if (rest_forward <= 0 || commentsNb <= 0) {
489                btn_forward.hide();
490            } else {
491                btn_forward.show();
492                if (rest_forward > per_page_forward) {
493                    btn_forward.html(function () {
494                        return (rest_forward > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, per_page_forward).replace(/%2s/g, rest_forward);
495                    });
496                } else {
497                    btn_forward.html(function () {
498                        return (rest_forward > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, rest_forward);
499                    });
500                }
501            }
502        }
503
504        if (!comment.title)
505            $comment_title.hide();
506        else
507            $comment_title.show();
508
509        if (!comment.edit_profile)
510            $('.product-comment-author-profile-link', $productComment).remove();
511
512        if (!qa) {
513            if (parseInt(comment.grade) > 0) {
514                $('.ets-rv-grade-stars', $productComment).etsRating({
515                    grade: comment.grade
516                });
517            } else {
518                $('.ets-rv-grade-stars, .ets_rv_grade_stars', $productComment).hide();
519            }
520            if (comment.criterion.length > 1) {
521                var popover = new String(), rateInvalidCount = 0;
522                comment.criterion.forEach(function (item) {
523                    if (parseInt(item.grade) > 0) {
524                        popover += '<li class="criterion-item"><span class="criterion-name">' + item.name + ':</span><span class="ets_rv_grade_stars' + (ETS_RV_DESIGN_COLOR1 ? ' color1' : '') + '" data-grade="' + item.grade + '" data-rate-empty="☆☆☆☆☆" data-rate-full="★★★★★"></span> <span class="criterion-grade">(' + item.grade + ')</span></li>';
525                        rateInvalidCount++;
526                    }
527                });
528                if (popover && rateInvalidCount > 1)
529                    $('.ets_rv_grade_stars', $productComment).append('<ul class="popover_wrap">' + popover + '</ul>');
530            }
531        } else
532            $('.ets_rv_grade_stars', $productComment).remove();
533
534        if (comment.answers) {
535            $('.ets_rv_answers_nb .ets_rv_answers_text, .comment_actions_right .ets_rv_answers_text', $productComment).html(function () {
536                return (parseInt(comment.answers_nb) > 1 ? $(this).data('multi-text') : $(this).data('text'));
537            });
538        } else {
539            $('.comment_actions_right .nb-comment-text', $productComment).html(function () {
540                return (parseInt(comment.comments_nb) > 1 ? $(this).data('multi-text') : $(this).data('text'));
541            });
542        }
543        if (!comment.action_allowed) {
544            $('.comment_dropdown_action:not(.bo), .comment_clock:not(.bo), .review-date-upd:not(.bo)', $productComment).remove();
545        } else {
546            $('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.ets_rv_btn_private.product-comment', $productComment).remove();
547        }
548        if (!comment.edit) {
549            $('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.ets_rv_btn_edit.product-comment', $productComment).remove();
550        }
551        if (!comment.delete) {
552            $('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.ets_rv_btn_delete.product-comment', $productComment).remove();
553        }
554        if ($('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.product-comment', $productComment).length <= 0) {
555            $('.comment_dropdown_action:not(.bo)', $productComment).remove();
556        }
557        const date_upd = $('.review-date-upd', $productComment);
558        if (date_upd.length > 0 && date_upd.attr('data-upd-date')) {
559            date_upd.show().addClass('show_il');
560        }
561        if (!comment.comment_allowed) {
562            if (prop !== 'comment') {
563                $('.ets_rv_btn_add_answer,.ets_rv_btn_add_comment', $productC
563omment).remove();
564            } else {
565                $('.write-a-comment', $productComment).remove();
566                $('.ets_rv_form_comment', $productComment).empty();
567            }
568        }
569        productCommentsETS.rawActions($productComment, {
570            type: 'product-comment',
571            options: {
572                id_ets_rv_product_comment: comment.id_ets_rv_product_comment,
573                __ac: 'useful_product_comment'
574            },
575            bo: ':not(.bo)',
576            current: comment.current,
577            usefulness: comment.usefulness,
578        }, prop);
579
580        $('.write-a-comment, .ets_rv_btn_add_comment' + (prop !== 'comment' ? ', .ets_rv_btn_add_answer' : ''), $productComment).click(function () {
581            const _wrap = $((prop !== 'comment' && !$(this).hasClass('ets_rv_btn_add_comment') ? '.ets_rv_answer_list' : '.ets_rv_comment_list') + '[data-product-comment-id=' + comment.id_ets_rv_product_comment + '] .ets_rv_form_comment');
582            var $this = $(this);
583            if ($this.hasClass('guest')) {
584                funcPCETS.isGuestLogin($this, prop);
585
586                return false;
587            }
588            _wrap
589                .addClass('active')
590                .find('textarea.ets_rv_comment')
591                .focus();
592
593            var btnCancel = _wrap.find('.ets_rv_cancel_comment');
594            if (!btnCancel.hasClass('show_answer_box') && !btnCancel.hasClass('show_comment_box'))
595                btnCancel.show();
596        });
597
598        if (isPosted) {
599            commentsList.prepend($productComment);
600        } else {
601            commentsList.find('#product-comments-list-footer').before($productComment);
602        }
603
604        // Comment's.
605        if (comment.comments && comment.comments.length > 0)
606            comment.comments.forEach(function (ele) {
607                commentsETS.add(ele, false);
608            });
609
610        // Load more answer.
611        if (comment.answers && (answersNbForward > 0 && nbAnswers > initialAnswersReal || answersNbForward <= 0 && answersNb > initialComments)) {
612            var answer_btn = $('.ets_rv_comment_load_more.answer:not(.forward-answers)', $productComment),
613                answer_rest = parseInt(answer_btn.attr('data-rest')),
614                answer_per_page = parseInt(answer_btn.attr('data-comments-per-page'))
615            ;
616            answer_btn.show();
617            if (answer_rest > answer_per_page) {
618                answer_btn.html(function () {
619                    return (answer_rest > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, answer_per_page).replace(/%2s/g, answer_rest);
620                });
621            } else {
622                answer_btn.html(function () {
623                    return (answer_rest > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, answer_rest);
624                });
625            }
626        }
627        // Load more answer forward.
628        if (comment.answers && answersNbForward > 0) {
629            var answer_btn_forward = $('.ets_rv_comment_load_more.answer.forward-answers.bo', $productComment),
630                answer_rest_forward = parseInt(answer_btn_forward.attr('data-rest')),
631                answer_per_page_forward = parseInt(answer_btn_forward.attr('data-comments-per-page'))
632            ;
633            if (answer_rest_forward <= 0 || answersNb <= 0) {
634                answer_btn_forward.hide();
635            } else {
636                answer_btn_forward.show();
637                if (answer_rest_forward > answer_per_page_forward) {
638                    answer_btn_forward.html(function () {
639                        return (answer_rest_forward > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, answer_per_page_forward).replace(/%2s/g, answer_rest_forward);
640                    });
641                } else {
642                    answer_btn_forward.html(function () {
643                        return (answer_rest_forward > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, answer_rest_forward);
644                    });
645                }
646            }
647        }
648
649        // Answer's.
650        if (comment.answers && comment.answers.length > 0)
651            comment.answers.forEach(function (ele) {
652                commentsETS.add(ele, false);
653            });
654
655        if (!qa) {
656        }
657
658        if (($('body#product').length <= 0 || ETS_RV_ADDED_PRODUCT_COMMENT) && !ETS_RV_SCROLL_ITEM && (comment.answers && answersNbForward <= 0 || !comment.answers && commentsNbForward <= 0)) {
659            var footerList = $productComment.find('.ets_rv_answer_list .ets_rv_comment_footer').length > 0 ? $productComment.find('.ets_rv_answer_list .ets_rv_comment_footer') : $productComment.find('.ets_rv_comment_list .ets_rv_comment_footer'),
660                footerForm = footerList.find('.ets_rv_form_comment')
661            ;
662            footerForm.addClass('active');
663            setTimeout(function () {
664                $('.ets_rv_overload.active').animate({scrollTop: footerForm.position().top}, 750);
665                if (typeof id_language !== "undefined" && id_language > 0) {
666                    footerForm.find('form textarea[name=comment_content_' + id_language + ']').focus();
667                } else {
668                    footerForm.find('form textarea[name^=comment_content]').focus();
669                }
670            }, 750);
671        }
672
673        reCaptchaETS.onLoad($('form.form-control-comment:not(.g-loaded)', $productComment));
674    },
675    updateUsefulness: function ($comment, data, prop) {
676        var usefulness = $('.useful-' + data.type + '-value', $comment),
677            not_usefulness = $('.ets-rv-not-useful-' + data.type + '-value', $comment),
678            total_usefulness = $('.total-usefulness-' + data.type, $comment)
679        ;
680        var hasError = false, msgError = null;
681
682        var countUseful = parseInt(usefulness.attr('data-count')),
683            parentUseful = usefulness.parents('.useful-' + data.type),
684            currentUseful = parentUseful.hasClass('current'),
685            countNotUseful = parseInt(not_usefulness.attr('data-count')),
686            parentNotUseful = not_usefulness.parents('.ets-rv-not-useful-' + data.type),
687            currentNotUseful = parentNotUseful.hasClass('current')
688        ;
689
690        if (data.options.usefulness > 0) {
691            if (currentUseful) {
692                countUseful--
693                parentUseful.removeClass('current');
694            } else {
695                countUseful++
696                if (currentNotUseful) {
697                    parentNotUseful.removeClass('current');
698                }
699                parentUseful.addClass('current');
700            }
701        }
702        if (data.options.usefulness < 1) {
703            if (currentNotUseful) {
704                countNotUseful--;
705                parentNotUseful.removeClass('current');
706            } else {
707                countNotUseful++
708                if (currentUseful) {
709                    parentUseful.removeClass('current');
710                }
711                parentNotUseful.addClass('current');
712            }
713        }
714
715        $.post($('#ets-rv-product-' + prop + 's-list').data('comments-url'), data.options, function (jsonResponse) {
716            var jsonData = false;
717            try {
718                jsonData = JSON.parse(jsonResponse);
719            } catch (e) {
720                hasError = true;
721            }
722            if (jsonData) {
723                if (jsonData.success) {
724                    usefulness.html(jsonData.usefulness).attr('data-count', jsonData.usefulness);
725
726                    const notUseful = jsonData.total_usefulness - jsonData.usefulness;
727                    not_usefulness.html(notUseful).attr('data-count', notUseful);
728
729                    const totalUseful = jsonData.usefulness - (jsonData.total_usefulness - jsonData.usefulness);
730                    total_usefulness.html(totalUseful).attr('data-count', totalUseful);
731                    // admin:
732                    if (typeof ets_rv !== "undefined") ets_rv.refreshList(jsonData);
733                } else {
734                    msgError = $("<div/>").html(jsonData.error).html();
735                    hasError = true;
736                }
737            } else
738                hasError = true;
739
740            if (hasError) {
741                productCommentsETS.showUpdateErrorModal(msgError !== null ? msgError : productCommentUpdatePostErrorMessage);
742                if (data.options.usefulness > 0) {
743                    if (currentUseful) {
744                        countUseful++;
745                        parentUseful.addClass('current');
746                    } else {
747                        countUseful--
748                        if (currentNotUseful) {
749                            parentNotUseful.addClass('current');
750                        }
751                        parentUseful.removeClass('current');
752                    }
753                }
754                if (data.options.usefulness < 1) {
755                    if (currentNotUseful) {
756                        countNotUseful++;
757                        parentNotUseful.addClass('current');
758                    } else {
759                        countNotUseful--
760                        if (currentUseful) {
761                            parentUseful.addClass('current');
762                        }
763                        parentNotUseful.removeClass('current');
764                    }
765                }
766            }
767
768        }).fail(function () {
769            hasError = true;
770        });
771
772        if (hasError) {
773            productCommentsETS.showUpdateErrorModal(msgError !== null ? msgError : productCommentUpdatePostErrorMessage);
774        }
775    },
776    usefulnessAnswer: function ($comment, data, prop) {
777        var useful_answer = $('.useful-answer', $comment),
778            answerList = useful_answer.parents('.ets_rv_answer_list')
779        ;
780        answerList
781            .find('.useful-answer.checked')
782            .addClass('old-checked')
783            .removeClass('checked')
784        ;
785        if (data.options.usefulness) {
786            useful_answer.addClass('checked');
787        } else {
788            useful_answer.removeClass('checked');
789        }
790        $.post($('#ets-rv-product-' + prop + 's-list').data('comments-url'), data.options, function (jsonResponse) {
791            var jsonData = false;
792            try {
793                jsonData = JSON.parse(jsonResponse);
794            } catch (e) {
795            }
796            if (jsonData) {
797                if (jsonData.success) {
798                    answerList
799                        .find('.useful-answer.old-checked')
800                        .removeClass('.old-checked')
801                    // backoffice:
802                    if (typeof ets_rv !== "undefined") {
803                        ets_rv.refreshList(jsonData);
804                    }
805                } else {
806                    if (data.options.usefulness) {
807                        useful_answer.removeClass('checked');
808                    } else {
809                        useful_answer.addClass('checked');
810                    }
811                    answerList
812                        .find('.useful-answer.old-checked')
813                        .removeClass('.old-checked')
814                        .addClass('checked');
815                    const decodedErrorMessage = $("<div/>").html(jsonData.error).html();
816                    productCommentsETS.showUpdateErrorModal(decodedErrorMessage);
817                }
818            } else {
819                if (data.options.usefulness) {
820                    useful_answer.removeClass('checked');
821                } else {
822                    useful_answer.addClass('checked');
823                }
824                answerList
825                    .find('.useful-answer.old-checked')
826                    .removeClass('.old-checked')
827                    .addClass('checked');
828                productCommentsETS.showUpdateErrorModal(productCommentUpdatePostErrorMessage);
829            }
830        }).fail(function () {
831            if (data.options.usefulness) {
832                useful_answer.removeClass('checked');
833            } else {
834                useful_answer.addClass('checked');
835            }
836            answerList
837                .find('.useful-answer.old-checked')
838                .removeClass('.old-checked')
839                .addClass('checked');
840            productCommentsETS.showUpdateErrorModal(productCommentUpdatePostErrorMessage);
841        });
842    },
843    populate: function (comments, prop) {
844        var prop = prop || 'comment';
845        $('#ets-rv-product-' + prop + 's-list').find('.ets-rv-product-comment-list-item').remove();
846        comments.forEach(function (ele) {
847            productCommentsETS.add(ele, false);
848        });
849    },
850    maskCustomerName: function (name) {
851        var value = (name || '').toString().trim();
852        if (!value) {
853            return '';
854        }
855        var chars = value.split('');
856        if (chars.length <= 1) {
857            return value;
858        }
859        if (chars.length === 2) {
860            return chars[0] + '*';
861        }
862        return chars[0] + '***' + chars[chars.length - 1];
863    },
864    paginate: function (config, $prop, $bindingEL) {
865        var prop = $prop || 'comment',
866            commentsList = $('#ets-rv-product-' + prop + 's-list'),
867            urlPost = commentsList.data('comments-url'),
868            bindingEL = $bindingEL || false
869        ;
870        if (!config) {
871            config = {};
872        }
873        var default_config = {
874            __ac: 'list_product_comment',
875            qa: prop !== 'question' ? 0 : 1,
876        };
877        $.each(default_config, function (index, el) {
878            if (config[index] === undefined)
879                config[index] = el;
880        });
881
882        if ($('.form-group-review-wrap').length > 0) {
883            $('.form-group-review-wrap:not(.loading)').addClass('loading');
884        }
885        if (urlPost) {
886            $.ajax({
887                type: 'GET',
888                url: urlPost,
889                data: config,
890                dataType: 'json',
891                success: function (jsonResponse) {
892                    if (jsonResponse) {
893                        if ($('.form-group-review-wrap').length > 0)
894                            $('.form-group-review-wrap.loading').removeClass('loading');
895                        if (jsonResponse.comments && jsonResponse.comments.length > 0) {
896                            productCommentsETS.populate(jsonResponse.comments, prop);
897                            if (config.back_office) {
898                                ets_rv_op.multiOptions();
899                                $('.ets_rv_overload:not(.active)').addClass('active');
900                            }
901                        } else
902                            commentsList.find('.ets-rv-product-comment-list-item').remove();
903                        var btn_load_more = $('.ets_rv_product_comment_load_more', commentsList);
904                        if (jsonResponse.id)
905                            btn_load_more.remove();
906                        else if (jsonResponse.reviews_nb > jsonResponse.reviews_initial) {
907                            btn_load_more.show();
908                        }
909                        if (bindingEL && typeof ets_rv !== "undefined") {
910                            ets_rv.processFinish(bindingEL);
911                            bindingEL.parents('.btn-group-action').find('.btn-group > a.btn').removeClass('active')
912                        }
913                        if (productCommentsETS.hasValidPhotosMarkup(jsonResponse.photos)) {
914                            productCommentsETS.initSlider(jsonResponse.photos);
915                        }
916                    }
917                },
918                error: function () {
919                    if (bindingEL && typeof ets_rv !== "undefined") {
920                        ets_rv.processFinish(bindingEL);
921                        bindingEL.parents('.btn-group-action').find('.btn-group > a.btn').removeClass('active')
922                    }
923                }
924            });
925        }
926    },
927    htmlTemplate: function (prototype, comment) {
928        var commentTemplate = prototype,
929            customerName = comment.customer_name,
930            customerNameDisplay = '',
931            groupTabs = $('#ets_rv_group_tabs')
932        ;
933        if (!customerName)
934            customerName = comment.firstname + ' ' + comment.lastname;
935        customerNameDisplay = productCommentsETS.maskCustomerName(customerName);
936        commentTemplate = commentTemplate.replace(/@PRODUCT_COMMENT_ID@/g, comment.id_ets_rv_product_comment);
937        commentTemplate = commentTemplate.replace(/@PRODUCT_ID@/g, comment.id_product);
938        commentTemplate = commentTemplate.replace(/@CUSTOMER_NAME@/g, customerNameDisplay);
939        commentTemplate = commentTemplate.replace(/@COMMENT_DATE@/g, '<span title="' + comment.date_add + '">' + comment.time_elapsed + '</span>');
940        commentTemplate = commentTemplate.replace(/@COMMENT_UPD_DATE@/g, comment.upd_date);
941        if (typeof comment.content === "object") {
942            var languages = Object.keys(comment.content);
943            languages.forEach(function (id_lang) {
944                var regEx = new RegExp('@COMMENT_COMMENT_' + id_lang + '@', 'g');
945                commentTemplate = commentTemplate.replace(regEx, funcPCETS.n2br(comment.content[id_lang]));
946            });
947        } else
948            commentTemplate = commentTemplate.replace(/@COMMENT_COMMENT@/g, funcPCETS.n2br(comment.content));
949        commentTemplate = commentTemplate.replace(/@COMMENT_USEFUL_ADVICES@/g, comment.usefulness);
950        commentTemplate = commentTemplate.replace(/@COMMENT_NOT_USEFUL_ADVICES@/g, (comment.total_usefulness - comment.usefulness));
951        commentTemplate = commentTemplate.replace(/@COMMENT_TOTAL_ADVICES@/g, comment.total_usefulness);
952        commentTemplate = commentTemplate.replace(/@VERIFY_PURCHASE@/g, comment.verify_purchase);
953        commentTemplate = commentTemplate.replace(/@COMMENT_ISO_COUNTRY@/g, comment.iso_code ? '<img src="' + comment.iso_code + '" title="' + comment.country_name + '" alt="" />' : '');
954        commentTemplate = commentTemplate.replace(/@COMMENT_AVATAR@/g, comment.avatar ? '<span class="ets_rv_avatar_photo" style="background-image:url(' + comment.avatar + ')"></span>' : (customerName ? '<span class="ets_rv_avatar_caption" style="background-color: ' + funcPCETS.colorHex(customerName) + '">' + customerName.substr(0, 1).toUpperCase() + '</span>' : ''));
955        commentTemplate = commentTemplate.replace(/@CURRENT_AVATAR@/g, groupTabs.data('profile-photo') ? '<span class="ets_rv_avatar_photo" style="background-image:url(' + groupTabs.data('profile-photo') + ')"></span>' : (groupTabs.data('profile-name') ? '<span class="ets_rv_avatar_caption" style="background-color: ' + funcPCETS.colorHex(groupTabs.data('profile-name')) + '">' + (groupTabs.data('profile-name')).substr(0, 1).toUpperCase() + '</span>' : ''));
956        commentTemplate = commentTemplate.replace(/@CURRENT_NAME@/g, groupTabs.data('profile-name') ? groupTabs.data('profile-name') : '');
957
958        commentTemplate = commentTemplate.replace(/@FORM_ID@/g, Math.floor((Math.random() * Math.pow(10, 8)) + 1));
959
960        commentTemplate = commentTemplate.replace(/@AUTHOR_PROFILE@/g, comment.author_profile ? comment.author_profile : '');
961        commentTemplate = commentTemplate.replace(/data-href\s*=\s*\"@MY_ACCOUNT@\"/g, 'href="' + (comment.my_account ? comment.my_account : '') + '"');
962        commentTemplate = commentTemplate.replace(/data-href\s*=\s*\"@CURRENT_MY_ACCOUNT@\"/g, 'href="' + (groupTabs.data('my-account-link') ? groupTabs.data('my-account-link') : 'javascript::void(0);') + '"');
963        commentTemplate = commentTemplate.replace(/data-href\s*=\s*\"@ACTIVITY_LINK@\"/g, 'href="' + (comment.activity_link ? comment.activity_link : 'javascript::void(0);') + '"');
964        commentTemplate = commentTemplate.replace(/@NO_LINK@/g, comment.activity_link ? '' : ' no-link');
965        commentTemplate = commentTemplate.replace(/@DATE_ADD@/g, comment.date_add);
966        commentTemplate = commentTemplate.replace(/@VALIDATE@/g, comment.validate);
967        if (parseInt(comment.validate) === 3) {
968            commentTemplate = commentTemplate.replace(/@COMMENT_NO_APPROVE@/g, '<span class="rejected">' + comment.comment_refuse + '</span>');
969        } else
970            commentTemplate = commentTemplate.replace(/@COMMENT_NO_APPROVE@/g, comment.comment_no_approve);
971        commentTemplate = commentTemplate.replace(/@CURRENT_STATE@/g, parseInt(comment.validate) === 1 ? 'approved' : (parseInt(comment.validate) === 0 ? 'pending' : 'private'));
972
973        return commentTemplate;
974    },
975    showUpdateErrorModal: function (errorMessage) {
976        $('#ets-rv-update-comment-usefulness-post-error-message').html(errorMessage);
977        $('#ets-rv-update-comment-usefulness-post-error').ETSModal('show');
978    },
979    updateCriterion: function (action, numberOfRating) {
980        const criterionList = $('#criterions_list');
981        var submit = action || '';
982
983        if (parseInt(criterionList.attr('data-maximum-rating')) !== 0) {
984            var maximum_rating = parseInt(criterionList.attr('data-maximum-rating'));
985            switch (submit) {
986                case "add":
987                case 'delete':
988                    criterionList.attr('data-number-of-rating', numberOfRating);
989                    break;
990                case "edit":
991                    criterionList.parents('.ets-pc-criterion:not(.active)').addClass('active');
992                    break;
993            }
994            if (maximum_rating <= parseInt(criterionList.attr('data-number-of-rating'))) {
995                criterionList.parents('.ets-pc-criterion').removeClass('active').removeAttr('style');
996            } else {
997                criterionList.parents('.ets-pc-criterion').addClass('active').removeAttr('style');
998            }
999        }
1000    },
1001};
1002
1003var repliesETS = {
1004    post: function (form, button) {
1005        var id_lang_default = form.data('lang-default'),
1006            ele = form.find('textarea[name=comment_content]').eq(0).length > 0 ? form.find('textarea[name=comment_content]').eq(0) : form.find('textarea[name=comment_content_' + id_lang_default + ']').eq(0)
1007        ;
1008        if (ele.val() && !button.hasClass('active')) {
1009            button.addClass('active');
1010            var replyCommentList = form.parents('.ets_rv_reply_comment_list').eq(0),
1011                replyComment = replyCommentList.find('.reply-comment-list-item.active').eq(0),
1012                onUpdate = button.hasClass('update-reply-comment')
1013            ;
1014            var formData = new FormData(form.get(0));
1015
1016            formData.append('id_product', replyCommentList.data('product-id'));
1017            formData.append('id_comment', replyCommentList.data('comment-id'));
1018            if (onUpdate)
1019                formData.append('id_reply_comment', replyComment.data('reply-comment-id'));
1020
1021            $.ajax({
1022                url: form.attr('action'),
1023                type: 'POST',
1024                data: formData,
1025                processData: false,
1026                contentType: false,
1027                dataType: 'json',
1028                success: function (json) {
1029                    button.removeClass('active');
1030                    reCaptchaETS.reset(form);
1031                    if (json) {
1032                        if (!json.success) {
1033                            productCommentsETS.showErrorModal(json.error);
1034                        } else if (json.comment) {
1035                            if (onUpdate) {
1036                                if (typeof json.comment.content === "object") {
1037                                    var languages = Object.keys(json.comment.content);
1038                                    languages.forEach(function (id_lang) {
1039                                        replyComment.find('p.reply-comment-content-html .translatable-field.lang-' + id_lang).html(funcPCETS.n2br(json.comment.content[id_lang]));
1040                                    });
1041                                } else
1042                                    replyComment.find('p.reply-comment-content-html').html(funcPCETS.n2br(json.comment.content));
1043                                if (json.comment.upd_date)
1044                                    replyComment.find('.reply-comment-date-upd').show().find('.reply-comment-upd-date').html(json.comment.upd_date);
1045                                if (json.comment.time_elapsed)
1046                                    replyComment.find('.reply-comment-date .reply-comment-date-add span').attr('title', json.comment.date_add).html(json.comment.time_elapsed);
1047                            } else {
1048                                repliesETS.add(json.comment, true);
1049                                replyCommentList.prev().find('.nb-reply-comment-value').text(function () {
1050                                    var data_count = parseInt($(this).text()) + 1;
1051                                    $(this).parent('.nb-reply-comment').attr('data-count', data_count);
1052                                    return parseInt($(this).text()) + 1;
1053
1054                                });
1055                            }
1056                            form.find('textarea[name^=comment_content]').val('');
1057                            if (replyCommentList.find('button.ets_rv_post_reply_comment.update-reply-comment').length > 0) {
1058                                replyCommentList.find('button.ets_rv_cancel_reply_comment:visible').trigger('click');
1059                            }
1060                            // admin:
1061                            if (typeof ets_rv !== "undefined")
1062                                ets_rv.refreshList(json);
1063                        }
1064                    }
1065                },
1066                error: function () {
1067                    button.removeClass('active');
1068                    reCaptchaETS.reset(form);
1069                }
1070            });
1071        } else
1072            ele.focus();
1073    },
1074    add: function (replyComment, isPosted) {
1075        var qa = parseInt(replyComment.question) > 0 ? 1 : 0,
1076            option = qa > 0 ? 'answer' : 'reply',
1077            prop = qa ? 'question' : 'comment'
1078        ;
1079        var commentTemplate = productCommentsETS.htmlTemplate($('#' + option + '-comment-item-prototype').html(), replyComment);
1080
1081        commentTemplate = commentTemplate.replace(/@COMMENT_ID@/g, replyComment.id_ets_rv_comment);
1082        commentTemplate = commentTemplate.replace(/@REPLY_COMMENT_ID@/g, replyComment.id_ets_rv_reply_comment);
1083        commentTemplate = commentTemplate.replace(/@REPLIES_NB@/g, parseInt(replyComment.replies_nb));
1084
1085        const $replyComment = $(commentTemplate);
1086        const $action = $('.comment_dropdown_action', $replyComment);
1087
1088        if (!replyComment.edit_profile)
1089            $('.reply-comment-author-profile-link', $replyComment).remove();
1090
1091        if (!replyComment.action_allowed) {
1092            $('.comment_dropdown_action:not(.bo), .reply-comment-date-upd:not(.bo)', $replyComment).remove();
1093        } else {
1094            $('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.ets_rv_btn_private.reply-comment', $replyComment).remove();
1095        }
1096        if (!replyComment.edit) {
1097            $('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.ets_rv_btn_edit.reply-comment', $replyComment).remove();
1098        }
1099        if (!replyComment.delete) {
1100            $('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.ets_rv_btn_delete.reply-comment', $replyComment).remove();
1101        }
1102        if ($('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.reply-comment', $replyComment).length <= 0) {
1103            $('.comment_dropdown_action:not(.bo)', $replyComment).remove();
1104        }
1105        const date_upd = $('.reply-comment-date-upd', $replyComment);
1106        if (date_upd.length > 0 && date_upd.attr('data-upd-date')) {
1107            date_upd.show();
1108        }
1109        if (!replyComment.comment_allowed) {
1110            if (prop !== 'question') {
1111                $('.ets_rv_button_reply', $replyComment).remove();
1112                $('.ets_rv_form_reply_comment', $replyComment).empty();
1113            }
1114        }
1115        productCommentsETS.rawActions($replyComment, {
1116            type: 'reply-comment',
1117            options: {
1118                id_ets_rv_reply_comment: replyComment.id_ets_rv_reply_comment,
1119                __ac: 'useful_reply_comment'
1120            },
1121            bo: '',
1122            current: replyComment.current,
1123            usefulness: replyComment.usefulness,
1124        }, prop);
1125
1126        $('.ets_rv_button_reply', $replyComment).click(function () {
1127            const _wrap = $('.ets_rv_reply_comment_list[data-comment-id=' + replyComment.id_ets_rv_comment + '] .ets_rv_form_reply_comment');
1128            _wrap
1129                .addClass('active')
1130                .find('textarea.ets_rv_reply_comment')
1131                .focus();
1132
1133            var btnCancel = _wrap.find('.ets_rv_cancel_reply_comment');
1134            if (!btnCancel.hasClass('show_reply_box'))
1135                btnCancel.show();
1136        });
1137
1138        var position = $('.ets_rv_reply_comment_list[data-comment-id=' + replyComment.id_ets_rv_comment + '] .ets_rv_reply_comment_' + (isPosted ? 'footer' : 'header'));
1139        if (isPosted) {
1140            position.before($replyComment);
1141        } else {
1142            position.after($replyComment);
1143        }
1144        if (replyComment.scroll) {
1145            if (ETS_RV_SCROLL_ITEM) {
1146                ETS_RV_SCROLL_ITEM.removeClass('ets_rv_highlight');
1147            }
1148            ETS_RV_SCROLL_ITEM = $('.reply-comment-list-item[data-reply-comment-id=' + replyComment.id_ets_rv_reply_comment + ']').addClass('ets_rv_highlight');
1149        }
1150    },
1151    pagination: function (button, prop, begin, perPage) {
1152        var ele = button || $('.ets_rv_reply_comment_load_more' + (prop ? '.question' : '')).eq(0);
1153        if (ele.length <= 0)
1154            return;
1155        var grade = $('.ets_rv_tab_reviews').length > 0 ? $('.ets_rv_tab_reviews .ets_rv_li_dropdown.active') : 0,
1156            commentList = $('#ets-rv-product-' + prop + 's-list'),
1157            rest = ele.hasClass('forward-replies') ? parseInt(ele.attr('data-rest')) : 0
1158        ;
1159        if (!ele.hasClass('active') && commentList.data('comments-url')) {
1160            ele.addClass('active');
1161            $.ajax({
1162                url: commentList.data('comments-url'),
1163                data: '__ac=list_reply_comment&id_comment=' + ele.parents('.ets_rv_reply_comment_list').attr('data-comment-id') + '&begin=' + (begin ? begin : ele.attr('data-begin')) + '&replies_per_page=' + (perPage ? perPage : ele.attr('data-replies-per-page')) + '&sort_by=date_add.desc' + (grade && prop !== 'question' ? '&grade=' + grade.data('grade') : '') + (prop !== 'comment' ? '&qa=1' : '') + (rest ? '&rest=' + rest : ''),
1164                type: 'POST',
1165                dataType: 'json',
1166                success: function (json) {
1167                    if (json) {
1168                        ele.removeClass('active');
1169                        if (json.replies) {
1170                            json.replies.forEach(function (ele) {
1171                                repliesETS.add(ele, rest > 0);
1172                            });
1173                        }
1174                        var rest2 = parseInt(json.nb) - parseInt(json.begin);
1175                        ele.attr({
1176                            'data-begin': json.begin,
1177                            'data-replies-per-page': json.replies_per_page,
1178                            'data-rest': rest2
1179                        });
1180                        if (json.begin >= json.nb || json.replies_per_page <= 0) {
1181                            ele.hide();
1182                        } else if (json.success) {
1183                            if (rest > parseInt(json.replies_per_page)) {
1184                                ele.html(function () {
1185                                    return (rest2 > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, json.replies_per_page).replace(/%2s/g, rest2);
1186                                });
1187                            } else {
1188                                ele.html(function () {
1189                                    return (parseInt(json.replies_per_page) > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, json.replies_per_page);
1190                                });
1191                            }
1192                        }
1193                    }
1194                },
1195                error: function () {
1196                    ele.removeClass('active');
1197                }
1198            });
1199        }
1200        return false;
1201    },
1202};
1203
1204var commentsETS = {
1205    add: function (comment, isPosted) {
1206        var qa = parseInt(comment.question) > 0 ? 1 : 0;
1207        var prop = qa > 0 ? 'question' : 'comment';
1208        const commentsList = $('#ets-rv-product-' + prop + 's-list'),
1209            initialReplies = commentsList.data('replies-initial') ? parseInt(commentsList.data('replies-initial')) : 1,
1210            repliesNbForward = typeof comment.replies_nb_forward !== "undefined" ? parseInt(comment.replies_nb_forward) : 0,
1211            repliesNb = parseInt(comment.replies_nb),
1212            nbReplies = repliesNb + repliesNbForward
1213        ;
1214
1215        var commentTemplate = productCommentsETS.htmlTemplate($('#' + (qa ? prop + '-' : '') + 'comment-item-prototype').html(), comment);
1216        commentTemplate = commentTemplate.replace(/@COMMENT_ID@/g, comment.id_ets_rv_comment);
1217        commentTemplate = commentTemplate.replace(/@PRODUCT_COMMENT_ID@/g, parseInt(comment.id_ets_rv_product_comment));
1218        commentTemplate = commentTemplate.replace(/@REPLIES_NB@/g, nbReplies);//repliesNb
1219        commentTemplate = commentTemplate.replace(/@REPLIES_PER_PAGE@/g, commentsList.data('replies-per-page'));
1220        if (comment.replies) {
1221            if (repliesNbForward > 0) {
1222                var initialRepliesReal = initialReplies + repliesNb;
1223                commentTemplate = commentTemplate.replace(/@REPLIES_BEGIN@/g, initialRepliesReal);
1224                commentTemplate = commentTemplate.replace(/@REPLIES_LOADMORE@/g, nbReplies > initialRepliesReal ? nbReplies - initialRepliesReal : 0);
1225                commentTemplate = commentTemplate.replace(/@REPLIES_BEGIN_FORWARD@/g, repliesNb > initialReplies ? repliesNb - initialReplies : 0);
1226                commentTemplate = commentTemplate.replace(/@REPLIES_LOADMORE_FORWARD@/g, repliesNb);
1227                commentTemplate = commentTemplate.replace(/@REPLIES_PER_PAGE_FORWARD@/g, repliesNb > commentsList.data('replies-per-page') ? parseInt(commentsList.data('replies-per-page')) : repliesNb);
1228            } else {
1229                commentTemplate = commentTemplate.replace(/@REPLIES_BEGIN@/g, initialReplies);
1230                commentTemplate = commentTemplate.replace(/@REPLIES_LOADMORE@/g, repliesNb > initialReplies ? repliesNb - initialReplies : 0);
1231            }
1232        }
1233        if (parseInt(comment.answer)) {
1234            commentTemplate = commentTemplate.replace(/@USEFUL_ANSWER@/g, parseInt(comment.useful_answer) > 0 ? 'checked' : '');
1235            commentTemplate = commentTemplate.replace(/@TOTAL_USEFULNESS@/g, parseInt(comment.usefulness) - (parseInt(comment.total_usefulness) - parseInt(comment.usefulness)));
1236        } else {
1237            commentTemplate = commentTemplate.replace(/@USEFUL_ANSWER@/g, '');
1238            commentTemplate = commentTemplate.replace(/@TOTAL_USEFULNESS@/g, '');
1239        }
1240
1241        const $comment = $(commentTemplate);
1242        const $action = $('.comment_dropdown_action', $comment);
1243
1244        // Load more replies:
1245        if ((qa && parseInt(comment.answer) || !qa) && comment.replies && (repliesNbForward > 0 && nbReplies > initialRepliesReal || repliesNbForward <= 0 && repliesNb > initialReplies)) {
1246            var btn = $('.ets_rv_reply_comment_load_more:not(.forward-replies)', $comment),
1247                rest = parseInt(btn.attr('data-rest')),
1248                per_page = parseInt(btn.attr('data-replies-per-page'))
1249            ;
1250            btn.show();
1251            if (rest > per_page) {
1252                btn.html(function () {
1253                    return (rest > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, per_page).replace(/%2s/g, rest);
1254                });
1255            } else {
1256                btn.html(function () {
1257                    return (rest > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, rest);
1258                });
1259            }
1260        }
1261        // Load more comments forward.
1262        if ((qa && parseInt(comment.answer) || !qa) && comment.replies && repliesNbForward > 0) {
1263            var btn_forward = $('.ets_rv_reply_comment_load_more.forward-replies.bo', $comment),
1264                rest_forward = parseInt(btn_forward.attr('data-rest')),
1265                per_page_forward = parseInt(btn_forward.attr('data-replies-per-page'))
1266            ;
1267            if (rest_forward <= 0 || repliesNb <= 0) {
1268                btn_forward.hide();
1269            } else {
1270                btn_forward.show();
1271                if (rest_forward > per_page_forward) {
1272                    btn_forward.html(function () {
1273                        return (rest_forward > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, per_page_forward).replace(/%2s/g, rest_forward);
1274                    });
1275                } else {
1276                    btn_forward.html(function () {
1277                        return (rest_forward > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, rest_forward);
1278                    });
1279                }
1280            }
1281        }
1282
1283        if (!comment.edit_profile)
1284            $('.comment-author-profile-link', $comment).remove();
1285
1286        if (!comment.action_allowed) {
1287            $('.comment_dropdown_action:not(.bo), .comment-date-upd:not(.bo)', $comment).remove();
1288        } else {
1289            $('.comment_dropdown_action:not(.bo) .ets_rv_btn_private.comment', $comment).remove();
1290        }
1291        if (!comment.edit) {
1292            $('.comment_dropdown_action:not(.bo) .ets_rv_btn_edit.comment', $comment).remove();
1293        }
1294        if (!comment.delete) {
1295            $('.comment_dropdown_action:not(.bo) .ets_rv_btn_delete.comment', $comment).remove();
1296        }
1297        if ($('.comment_dropdown_action:not(.bo) .ets_rv_li_dropdown.comment', $comment).length <= 0) {
1298            $('.comment_dropdown_action:not(.bo)', $comment).remove();
1299        }
1300        const date_upd = $('.comment-date-upd', $comment);
1301        if (date_upd.length > 0 && date_upd.attr('data-upd-date')) {
1302            date_upd.show().addClass('show_il');
1303        }
1304        if (!comment.comment_allowed) {
1305            if (prop !== 'comment') {
1306                $('.ets_rv_btn_add_reply', $comment).remove();
1307            } else {
1308                $('.ets_rv_button_reply', $comment).remove();
1309                $('.ets_rv_form_reply_comment', $comment).empty();
1310            }
1311        }
1312        productCommentsETS.rawActions($comment, {
1313            type: 'comment',
1314            options: {
1315                id_ets_rv_comment: comment.id_ets_rv_comment,
1316                __ac: 'useful_comment'
1317            },
1318            bo: '',
1319            current: comment.current,
1320            usefulness: comment.usefulness,
1321        }, prop);
1322        $(prop !== 'question' ? '.ets_rv_button_reply' : '.ets_rv_btn_add_reply', $comment).click(function () {
1323            const _wrap = $('.ets_rv_reply_comment_list[data-comment-id=' + comment.id_ets_rv_comment + '] .ets_rv_form_reply_comment');
1324            _wrap
1325                .addClass('active')
1326                .find('textarea.ets_rv_reply_comment')
1327                .focus();
1328
1329            var btnCancel = _wrap.find('.ets_rv_cancel_reply_comment');
1330            if (!btnCancel.hasClass('show_reply_box'))
1331                btnCancel.show();
1332        });
1333
1334        const option = parseInt(comment.answer) > 0 ? 'answer' : 'comment';
1335        const raw = $('.ets_rv_' + option + '_list[data-product-comment-id=' + comment.id_ets_rv_product_comment + ']');
1336        if (isPosted) {
1337            raw.find('.ets_rv_comment_footer').before($comment);
1338        } else {
1339            if (prop !== 'comment' && option !== 'comment' && raw.find('.comment-list-item[data-useful-answer*=checked]').length > 0) {
1340                raw.find('.comment-list-item[data-useful-answer*=checked]').after($comment);
1341            } else {
1342                raw.find('.ets_rv_comment_header').after($comment);
1343            }
1344        }
1345        raw.find('.ets_rv_answers_nb:hidden').show();
1346        if (qa && !parseInt(comment.answer)) {
1347            $('.ets_rv_reply_comment_list, .nb-reply-comment, .ets_rv_button_reply, .ets_rv_btn_add_reply, .comment_arrow_total_ans.answer', $comment).remove();
1348        } else if (parseInt(comment.answer)) {
1349            $('.ets-rv-comment-buttons .useful-comment, .ets-rv-comment-buttons .ets-rv-not-useful-comment', $comment).remove();
1350        }
1351        //Scroll item:
1352        if (comment.scroll) {
1353            if (qa && parseInt(comment.answer) <= 0) {
1354                var commentBox = $comment.parents('.ets_rv_comment_list').eq(0).find('.ets_rv_comment_footer .ets_rv_form_comment').eq(0);
1355                commentBox.addClass('active');
1356                setTimeout(function () {
1357                    $('.ets_rv_overload.active').animate({scrollTop: commentBox.position().top}, 750);
1358                    if (typeof id_language !== "undefined" && id_language > 0) {
1359                        commentBox.find('form textarea[name=comment_content_' + id_language + ']').focus();
1360                    } else {
1361                        commentBox.find('form textarea[name^=comment_content]').focus();
1362                    }
1363                }, 750);
1364            } else {
1365                var replyBox = $('.ets_rv_form_reply_comment', $comment);
1366                replyBox.addClass('active');
1367                setTimeout(function () {
1368                    $('.ets_rv_overload.active').animate({scrollTop: replyBox.offset().top}, 750);
1369                    if (typeof id_language !== "undefined" && id_language > 0) {
1370                        replyBox.find('form textarea[name=comment_content_' + id_language + ']').focus();
1371                    } else {
1372                        replyBox.find('form textarea[name^=comment_content]').focus();
1373                    }
1374
1375                }, 750);
1376            }
1377            if (ETS_RV_SCROLL_ITEM !== null) {
1378                ETS_RV_SCROLL_ITEM.removeClass('ets_rv_highlight');
1379            }
1380            ETS_RV_SCROLL_ITEM = $('.comment-list-item[data-comment-id=' + comment.id_ets_rv_comment + ']').addClass('ets_rv_highlight');
1381        }
1382        if (comment.replies && comment.replies.length > 0) {
1383            comment.replies.forEach(function (ele) {
1384                repliesETS.add(ele, false);
1385            });
1386        }
1387        reCaptchaETS.onLoad($('form.form-control-reply-comment:not(.g-loaded)', $comment));
1388    },
1389    pagination: function (button, prop, begin, perPage) {
1390        var ele = button || $('.ets_rv_comment_load_more' + (prop ? '.question' : '')).eq(0);
1391        if (ele.length <= 0)
1392            return;
1393        var grade = $('.ets_rv_tab_reviews').length > 0 ? $('.ets_rv_tab_reviews .ets_rv_li_dropdown.active') : 0,
1394            commentList = $('#ets-rv-product-' + prop + 's-list'),
1395            option = ele.hasClass('answer') ? 'answer' : 'comment',
1396            rest = ele.hasClass('forward-comments') || ele.hasClass('forward-answers') ? parseInt(ele.attr('data-rest')) : 0
1397        ;
1398        if (!ele.hasClass('active') && commentList.data('comments-url')) {
1399            ele.addClass('active');
1400            $.ajax({
1401                url: commentList.data('comments-url'),
1402                data: '__ac=list_comment&id_product_comment=' + ele.parents('.ets_rv_' + option + '_list').attr('data-product-comment-id') + '&begin=' + (begin ? begin : ele.attr('data-begin')) + '&comments_per_page=' + (perPage ? perPage : ele.attr('data-comments-per-page')) + '&sort_by=date_add.desc' + (grade && prop !== 'question' ? '&grade=' + grade.data('grade') : '') + (prop !== 'comment' ? '&qa=1' : '') + (option !== 'comment' ? '&answer=1' : '') + (rest ? '&rest=' + rest : ''),
1403                type: 'POST',
1404                dataType: 'json',
1405                success: function (json) {
1406                    if (json) {
1407                        ele.removeClass('active');
1408                        if (json.comments) {
1409                            json.comments.forEach(function (ele) {
1410                                commentsETS.add(ele, rest > 0);
1411                            });
1412                        }
1413                        if (json.begin >= json.nb || json.comments_per_page <= 0) {
1414                            ele.remove();
1415                        } else if (json.success) {
1416                            var rest2 = parseInt(json.nb) - parseInt(json.begin);
1417                            ele.attr({
1418                                'data-begin': json.begin,
1419                                'data-comments-per-page': json.comments_per_page,
1420                                'data-rest': rest2
1421                            });
1422                            if (rest2 > parseInt(json.comments_per_page)) {
1423                                ele.html(function () {
1424                                    return (rest2 > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, json.comments_per_page).replace(/%2s/g, rest2);
1425                                });
1426                            } else {
1427                                ele.html(function () {
1428                                    return (parseInt(json.comments_per_page) > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, json.comments_per_page);
1429                                });
1430                            }
1431                        }
1432                    }
1433                },
1434                error: function () {
1435                    ele.removeClass('active');
1436                }
1437            });
1438        }
1439        return false;
1440    },
1441    post: function (form, button) {
1442        var id_lang_default = form.data('lang-default'),
1443            ele = form.find('textarea[name=comment_content]').eq(0).length > 0 ? form.find('textarea[name=comment_content]').eq(0) : form.find('textarea[name=comment_content_' + id_lang_default + ']').eq(0)
1444        ;
1445        if (ele.val() && !button.hasClass('active')) {
1446            button.addClass('active');
1447            var option = form.hasClass('answer') ? 'answer' : 'comment',
1448                commentList = form.parents('.ets_rv_' + option + '_list').eq(0),
1449                commentBlock = form.parents('.ets-rv-product-comment-list-item');
1450            var comment = commentList.find('.comment-list-item.active').eq(0),
1451                onUpdate = button.hasClass('update-comment')
1452            ;
1453            var formData = new FormData(form.get(0));
1454            formData.append('id_product', commentList.data('product-id'));
1455            formData.append('id_product_comment', commentList.data('product-comment-id'));
1456            if (option !== 'comment')
1457                formData.append('answer', 1);
1458            if (onUpdate)
1459                formData.append('id_comment', comment.data('comment-id'));
1460            $.ajax({
1461                url: form.attr('action'),
1462                type: 'POST',
1463                data: formData,
1464                processData: false,
1465                contentType: false,
1466                dataType: 'json',
1467                success: function (json) {
1468                    button.removeClass('active');
1469                    reCaptchaETS.reset(form);
1470                    if (json) {
1471                        if (!json.success) {
1472                            productCommentsETS.showErrorModal(json.error);
1473                        } else if (json.comment) {
1474                            if (onUpdate) {
1475                                if (typeof json.comment.content === "object") {
1476                                    var languages = Object.keys(json.comment.content);
1477                                    languages.forEach(function (id_lang) {
1478                                        comment.find('.ets-rv-comment-content-html > span .translatable-field.lang-' + id_lang).html(funcPCETS.n2br(json.comment.content[id_lang]));
1479                                    });
1480                                } else
1481                                    comment.find('.ets-rv-comment-content-html > span').html(funcPCETS.n2br(json.comment.content));
1482                                if (json.comment.upd_date)
1483                                    comment.find('.comment-date-upd').show().find('.comment-upd-date').html(json.comment.upd_date);
1484                                if (json.comment.time_elapsed)
1485                                    comment.find('.comment-date-add.ets_rv_date_add > span').attr('title', json.comment.date_add).html(json.comment.time_elapsed);
1486                            } else {
1487                                commentsETS.add(json.comment, true);
1488                                if (option !== 'answer') {
1489                                    var nb_comments = 0;
1490                                    commentBlock.find('.nb-comment-value').text(function () {
1491                                        nb_comments = parseInt($(this).text()) + 1;
1492                                        return nb_comments;
1493                                    });
1494                                    commentBlock.find('.nb-comment-text').text(function () {
1495                                        return nb_comments > 1 ? $(this).data('multi-text') : $(this).data('text');
1496                                    });
1497                                    commentBlock.find('.nb-comment-text').parents('.nb-comment:not(.active)').trigger('click');
1498                                } else if (commentList.hasClass('answer')) {
1499                                    var nb_answers = 0;
1500                                    commentBlock.find('.ets_rv_nb_answers').text(function () {
1501                                        nb_answers = parseInt($(this).text()) + 1;
1502                                        return nb_answers;
1503                                    });
1504                                    commentBlock.find('.ets_rv_answers_text').html(function () {
1505                                        return nb_answers > 1 ? $(this).data('multi-text') : $(this).data('text');
1506                                    });
1507                                    commentBlock.find('.ets_rv_answers_text').parents('.ets_rv_btn_show_answer:not(.active)').trigger('click');
1508                                }
1509                            }
1510                            form.find('textarea[name^=comment_content]').val('');
1511                            if (commentList.find('button.ets_rv_post_comment.update-comment').length > 0) {
1512                                commentList.find('button.ets_rv_cancel_comment:visible').trigger('click');
1513                            }
1514                            // admin:
1515                            if (typeof ets_rv !== "undefined")
1516                                ets_rv.refreshList(json);
1517                            commentList.addClass('show_content');
1518                        }
1519                    }
1520                },
1521                error: function () {
1522                    button.removeClass('active');
1523                    reCaptchaETS.reset(form);
1524                }
1525            });
1526        } else {
1527            ele.focus();
1528            if (typeof hideOtherLanguage !== typeof undefined)
1529                hideOtherLanguage(id_lang_default);
1530            if (typeof ETS_RV_DEFAULT_LANGUAGE_MSG !== typeof undefined)
1531                showErrorMessage(ETS_RV_DEFAULT_LANGUAGE_MSG);
1532        }
1533    },
1534};
1535
1536var ETS_RV_ADDED_PRODUCT_COMMENT = false;
1537
1538$(document).ready(function () {
1539    // Init function.
1540    productCommentsETS.init();
1541    $(document).on('hooksLoaded', function () {
1542        productCommentsETS.init();
1543    });
1544    $(document).on('keyup', '.error', function () {
1545        if (typeof $(this)[0] === typeof undefined || typeof $(this)[0].name === typeof undefined || !$(this)[0].name) return;
1546        if ($(this)[0].name !== 'email' && $(this).val() !== '' || $(this)[0].name === 'email' && /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test($(this).val()))
1547            $(this).removeClass('error');
1548    });
1549    $(document).on('click', '.ets_rv_product_id.ets-rv-post-product-comment', function (e) {
1550        e.preventDefault();
1551        var ele = $(this);
1552        if (!ele.hasClass('active')) {
1553            ele.addClass('active');
1554            var orderId = ele.data('id-order') ?? 0;
1555            $.ajax({
1556                type: 'GET',
1557                data: 'qa=0&ajax=1&action=formPostComment&product_id=' + ele.data('id-product') + (parseInt(orderId) > 0 ? '&id_order=' + ele.data('id-order') : ''),
1558                dataType: 'json',
1559                success: function (json) {
1560                    ele.removeClass('active');
1561                    if (json) {
1562                        if (json.errors) {
1563                            funcPCETS.showErrorMessage(json.errors);
1564                        } else {
1565                            if (json.form) {
1566                                $('.ets_rv_form').html(json.form);
1567                                commonPCETS.initForm('comment');
1568                                commonPCETS.showPostModal('comment', 'add');
1569                            }
1570                        }
1571                    }
1572                },
1573                error: function () {
1574                    ele.removeClass('active');
1575                }
1576            });
1577        }
1578    });
1579    productCommentsETS.refreshReviewPhotosBlock();
1580    $(document).on('ets-rv:review-tab-activated', function () {
1581        setTimeout(function () {
1582            productCommentsETS.refreshReviewPhotosBlock();
1583        }, 20);
1584        setTimeout(function () {
1585            productCommentsETS.refreshReviewPhotosBlock();
1586        }, 180);
1587    });
1588    $(document).on('click', '.ets_rv_review_photos_wrap.display_type_slider .ets_rv_image_item .ets_rv_fancy', function (e) {
1589        e.preventDefault();
1590        $(this).closest('.ets_rv_review_photos_wrap').find('.ets_image_list_popup').addClass('active').addClass('blur_content');
1591        let current_slide_active = $(this).attr('data-value');
1592
1593        if (!$('.ets_image_list_popup.active .ets_rv_review_photos_ul').hasClass('slick-initialized')) {
1594            $('.ets_image_list_popup.active .ets_rv_review_photos_ul').slick({
1595                slidesToShow: 1,
1596                slidesToScroll: 1,
1597                arrows: true,
1598            });
1599        }
1600        $('.ets_image_list_popup.active .ets_rv_review_photos_ul').slick('slickGoTo', current_slide_active, true);
1601        $('.ets_image_list_popup.active.blur_content').removeClass('blur_content');
1602
1603    });
1604    $(document).on('click', '.product-comment-content_images_videos .ets_rv_image_item > .ets_rv_fancy', function (e) {
1605        if ($(this).parents('.slick-slide').length <= 0) {
1606            e.preventDefault();
1607            var content_slider = $(this).parents('.ets_rv_images').clone(),
1608                value_active = $(this).attr('data-value') - 1
1609            ;
1610            $(this).parents('.product-comment-image-html').find('.ets_popup_content').append(content_slider);
1611            $('.ets_popup_content .ets_rv_fancy').each(function () {
1612                $(this).css('background-image', 'url(' + $(this).attr('href') + ')');
1613            });
1614            $(this).parents('.product-comment-image-html').find('.ets_image_list_popup').addClass('active').addClass('blur_content');
1615            setTimeout(function () {
1616                $('.ets_image_list_popup.active .ets_rv_images').slick({
1617                    slidesToShow: 1,
1618                    slidesToScroll: 1,
1619                    arrows: true,
1620                });
1621                $('.ets_image_list_popup.active .ets_rv_images').slick('slickGoTo', value_active, true);
1622                $('.ets_image_list_popup.active.blur_content').removeClass('blur_content');
1623            }, 500);
1624        }
1625    });
1626
1627    $(document).keyup(function (e) {
1628        if (e.keyCode === 27) {
1629            $('.ets_image_list_popup.active').removeClass('blur_content').removeClass('active');
1630            $('.ets_image_list_popup').find('.ets_rv_images').remove();
1631        }
1632    });
1633
1634    $(document).on('click', '.close_img_list', function () {
1635        $('.ets_image_list_popup.active').removeClass('blur_content').removeClass('active');
1636        $('.ets_image_list_popup').find('.ets_rv_images').remove();
1637    });
1638    $(document).on('click', '.ets_rv_form_comment.guest textarea.ets_rv_comment', function (e) {
1639        e.preventDefault();
1640        funcPCETS.isGuestLogin($(this));
1641
1642        return false;
1643    });
1644    $(document).on('keypress', '.form-control-comment textarea.ets_rv_comment', function (event) {
1645        if (parseInt(event.keyCode) === 13 && ETS_RV_PRESS_ENTER_ENABLED) {
1646            var ele = $(this),
1647                form = ele.parents('form').eq(0)
1648            ;
1649            commentsETS.post(form, form.find('button.ets_rv_post_comment'));
1650            event.preventDefault();
1651        }
1652    });
1653
1654    $(document).on('click', '.ets-rv-post-product-question', function () {
1655        $('.ets-rv-btn-question-big').removeClass('active');
1656        $('.ets-rv-product-comment-modal .ets_rv_error, .ets-rv-product-comment-modal .ets_rv_error').remove();
1657    });
1658
1659    $(document).on('click', '.form-control-comment button.ets_rv_post_comment', function (ev) {
1660        ev.preventDefault();
1661        var ele = $(this),
1662            form = $(this).parents('form')
1663        ;
1664        if (form.parent('.ets_rv_form_comment.guest').length > 0) {
1665            funcPCETS.isGuestLogin($(this));
1666
1667            return false;
1668        }
1669        commentsETS.post(form, ele);
1670    });
1671
1672    $(document).on('keypress', '.form-control-reply-comment .ets_rv_reply_comment', function (event) {
1673        if (parseInt(event.keyCode) === 13 && typeof ETS_RV_PRESS_ENTER_ENABLED !== "undefined" && ETS_RV_PRESS_ENTER_ENABLED) {
1674            var ele = $(this),
1675                form = ele.parents('form').eq(0)
1676            ;
1677            repliesETS.post(form, form.find('button.ets_rv_post_reply_comment'));
1678            return false;
1679        }
1680    });
1681
1682    $(document).on('click', '.form-control-reply-comment .ets_rv_post_reply_comment', function (ev) {
1683        ev.preventDefault();
1684        var ele = $(this),
1685            form = $(this).parents('form')
1686        ;
1687        repliesETS.post(form, ele);
1688    });
1689
1690    // load more.
1691    $(document).on('click', '.ets_rv_reply_comment_load_more', function (ev) {
1692        ev.preventDefault();
1693        repliesETS.pagination($(this), ($(this).hasClass('question') ? 'question' : 'comment'));
1694    });
1695
1696    $(document).on('click', '.ets_rv_comment_load_more', function (ev) {
1697        ev.preventDefault();
1698        commentsETS.pagination($(this), ($(this).hasClass('question') ? 'question' : 'comment'));
1699
1700    });
1701
1702    $(document).on('click', '.ets_rv_product_comment_load_more', function (ev) {
1703        ev.preventDefault();
1704        var ele = $(this),
1705            sort_by = $('.ets_rv_sort_by').length > 0 ? $('.ets_rv_sort_by .ets_rv_li_dropdown.active') : false,
1706            grade = $('.ets_rv_tab_reviews').length > 0 ? $('.ets_rv_tab_reviews .ets_rv_li_dropdown.active') : false,
1707            commentList = ele.parents('.ets_rv_tab_content').eq(0)
1708        ;
1709        if (!ele.hasClass('active') && commentList.data('comments-url')) {
1710            ele.addClass('active');
1711            $.ajax({
1712                url: commentList.data('comments-url'),
1713                data: '__ac=list_product_comment&begin=' + ele.attr('data-begin') + '&reviews_per_page=' + ele.attr('data-reviews-per-page') + (sort_by ? '&sort_by=' + sort_by.data('sort') : '') + (grade ? '&grade=' + grade.data('grade') : ''),
1714                type: 'POST',
1715                dataType: 'json',
1716                success: function (json) {
1717                    if (json) {
1718                        ele.removeClass('active');
1719                        if (json.comments) {
1720                            json.comments.forEach(function (ele) {
1721                                productCommentsETS.add(ele, false);
1722                            });
1723                        }
1724                        var rest = parseInt(json.reviews_nb) - parseInt(json.begin);
1725                        if (parseInt(json.begin) >= parseInt(json.reviews_nb) || parseInt(json.reviews_per_page) <= 0)
1726                            ele.hide();
1727                        else if (json.success) {
1728                            ele.attr({
1729                                'data-begin': json.begin,
1730                                'data-reviews-per-page': json.reviews_per_page,
1731                                'data-rest': rest,
1732                            });
1733                            if (parseInt(ele.attr('data-rest')) > parseInt(ele.attr('data-reviews-per-page'))) {
1734                                ele.html(function () {
1735                                    return (rest > 1 ? $(this).data('multi-text-rest') : $(this).data('text-rest')).replace(/%1s/g, json.reviews_per_page).replace(/%2s/g, rest);
1736                                });
1737                            } else {
1738                                ele.html(function () {
1739                                    return (parseInt(json.reviews_per_page) > 1 ? $(this).data('multi-text') : $(this).data('text')).replace(/%1s/g, json.reviews_per_page);
1740                                });
1741                            }
1742                        }
1743                    }
1744                },
1745                error: function () {
1746                    ele.removeClass('active');
1747                }
1748            });
1749        }
1750        return false;
1751    });
1752
1753    // Delete.
1754    $(document).on('click', '.ets_rv_btn_delete.product-comment', function (ev) {
1755        ev.preventDefault();
1756        if (!$(this).hasClass('employee')) {
1757            var ele = $(this),
1758                productComment = ele.parents('.ets-rv-product-comment-list-item'),
1759                prop = productComment.hasClass('question') ? 'question' : 'comment',
1760                commentList = $('#ets-rv-product-' + prop + 's-list')
1761            ;
1762            if (!ele.hasClass('active') && confirm(ETS_RV_CONFIRM_DELETE_ITEM)) {
1763                $('.ets-rv-product-comment-list-item').removeClass('active');
1764                ele.addClass('active');
1765                $.ajax({
1766                    type: 'POST',
1767                    url: commentList.data('comments-url'),
1768                    data: '__ac=delete_product_comment&id_product_comment=' + productComment.data('product-comment-id'),
1769                    dataType: 'json',
1770                    success: function (json) {
1771                        ele.removeClass('active');
1772                        if (json) {
1773                            if (!json.success)
1774                                productCommentsETS.showErrorModal(json.error);
1775                            else {
1776                                if (json.msg)
1777                                    funcPCETS.showSuccessMessage(json.msg);
1778                                if ((parseInt(json.review_enabled) > 0 || parseInt(json.question_enabled) > 0) && (parseInt(json.nb_reviews) < 1 && parseInt(json.nb_questions) < 1 || parseInt(json.nb_reviews) < 1 && parseInt(json.nb_questions) > 0 && parseInt(json.question_enabled) < 1 || parseInt(json.nb_reviews) > 0 && parseInt(json.review_enabled) < 1 && parseInt(json.nb_questions) < 1)) {
1779                                    //$('.ets-rv-product-comments-additional-info').show();
1780                                    if (ETS_RV_DISPLAY_RATE_AND_QUESTION === 'button')
1781                                        $('.ets_rv_wrap').hide();
1782                                    if (parseInt(json.nb_reviews) < 1) {
1783                                        if (ETS_RV_DISPLAY_RATE_AND_QUESTION === 'button')
1784                                            $('.ets-rv-product-comments-additional-info .ets-rv-btn-read-user').addClass('ets-rv-hidden');
1785                                        if (typeof json.stats !== typeof undefined) {
1786                                            $('.ets-rv-product-comments-additional-info .ets-rv-btn-read-user .ets_rv_grade_stars').attr('data-grade', json.stats.average_grade.toFixed(1));
1787                                            $('.ets-rv-product-comments-additional-info .ets-rv-btn-read-user .ets_rv_grade_stars .ets-rv-comments-nb').text('(' + json.stats.nb_reviews + ')');
1788                                        }
1789                                    }
1790                                    if (ETS_RV_DISPLAY_RATE_AND_QUESTION === 'button')
1791                                        $('.ets-rv-product-comments-additional-info .link-comment, .ets-rv-product-comments-additional-info .ets-rv-btn-comment').removeClass('ets-rv-hidden');
1792                                } else {
1793                                    //$('.ets-rv-product-comments-additional-info').hide();
1794                                    if (ETS_RV_DISPLAY_RATE_AND_QUESTION === 'button')
1795                                        $('.ets_rv_wrap').show();
1796                                    if (parseInt(json.nb_reviews) > 0) {
1797                                        if (typeof json.stats !== typeof undefined) {
1798                                            $('.ets-rv-product-comments-additional-info .ets-rv-btn-read-user .ets_rv_grade_stars').attr('data-grade', json.stats.average_grade.toFixed(1));
1799                                            $('.ets-rv-product-comments-additional-info .ets-rv-btn-read-user .ets_rv_grade_stars .ets-rv-comments-nb').text('(' + json.stats.nb_reviews + ')');
1800                                        }
1801                                        if (ETS_RV_DISPLAY_RATE_AND_QUESTION === 'button')
1802                                            $('.ets-rv-product-comments-additional-info .ets-rv-btn-read-user').removeClass('ets-rv-hidden');
1803                                    }
1804                                    if (ETS_RV_DISPLAY_RATE_AND_QUESTION === 'button')
1805                                        $('.ets-rv-product-comments-additional-info .link-comment, .ets-rv-product-comments-additional-info .ets-rv-btn-comment').addClass('ets-rv-hidden');
1806                                }
1807                                productComment.remove();
1808                                productCommentsETS.updateCriterion('delete', json.nb_rate);
1809                                if ($('#ets-rv-product-' + prop + 's-list .ets-rv-product-comment-list-item').length < 1) $('#ets-rv-product-' + prop + 's-list #product-comments-list-footer .ets-rv-' + prop + '.empty').show();
1810                                if (prop !== 'question') {
1811                                    if (json.review_allowed) {
1812                                        $('#ets-rv-post-product-comment-form').removeClass('hide');
1813                                        $('.ets_rv_review_error').addClass('hide');
1814                                    } else {
1815                                        $('#ets-rv-post-product-comment-form').addClass('hide');
1816                                        $('.ets_rv_review_error').removeClass('hide');
1817                                    }
1818                                }
1819                                if ($('body[id*=comment]').length > 0) {
1820                                    window.location.reload();
1821                                }
1822                                // front:
1823                                if (json.stats) {
1824                                    funcPCETS.stats(json.stats, prop);
1825                                } else if (typeof json.nb_questions !== "undefined") {
1826                                    $('#ets-rv-product-comments-list-header .ets_rv_tab_questions .ets_rv_question_selection').html(function () {
1827                                        return $(this).html().replace(/\d+/, parseInt(json.nb_questions))
1828                                    });
1829                                }
1830                                if (productCommentsETS.hasValidPhotosMarkup(json.photos)) {
1831                                    productCommentsETS.initSlider(json.photos);
1832                                }
1833                                // backoffice:
1834                                if (typeof ets_rv !== "undefined")
1835                                    ets_rv.refreshList(json);
1836                            }
1837                        }
1838                    },
1839                    error: function () {
1840                        ele.removeClass('active');
1841                    }
1842                });
1843            }
1844        } else
1845            $('#product-comment-render-form a.delete').trigger('click');
1846    });
1847    $(document).on('click', '.ets_rv_btn_delete.comment', function (ev) {
1848        ev.preventDefault();
1849        var ele = $(this),
1850            prop = ele.parents('.comment-list-item.question') ? 'question' : 'comment',
1851            commentList = $('#ets-rv-product-' + prop + 's-list'),
1852            comment = ele.parents('.comment-list-item'),
1853            listComment = comment.parents('.ets_rv_comment_list').eq(0).length > 0 ? comment.parents('.ets_rv_comment_list').eq(0) : comment.parents('.ets_rv_answer_list').eq(0),
1854            productCommentActions = ele.parents('.ets-rv-product-comment-list-item').eq(0).find('.comment_actions_right').eq(0)
1855        ;
1856        if (!ele.hasClass('active') && confirm(ETS_RV_CONFIRM_DELETE_ITEM)) {
1857            $('.comment-list-item').removeClass('active');
1858            ele.addClass('active');
1859            $.ajax({
1860                type: 'POST',
1861                url: commentList.data('comments-url'),
1862                data: '__ac=delete_comment&id_comment=' + comment.data('comment-id') + (prop === 'question' ? '&qa=1' : ''),
1863                dataType: 'json',
1864                success: function (json) {
1865                    ele.removeClass('active');
1866                    if (json) {
1867                        if (!json.success)
1868                            productCommentsETS.showErrorModal(json.error);
1869                        else {
1870                            if (json.msg)
1871                                funcPCETS.showSuccessMessage(json.msg);
1872                            comment.remove();
1873                            listComment.find('.ets_rv_comment_load_more').attr('data-begin', function () {
1874                                return parseInt($(this).attr('data-begin')) > 0 ? parseInt($(this).attr('data-begin')) - 1 : 0;
1875                            });
1876                            listComment.prev().find('.nb-comment-value').text(function () {
1877                                return parseInt($(this).text()) > 0 ? parseInt($(this).text()) - 1 : 0;
1878                            });
1879                            if (listComment.hasClass('answer')) {
1880                                var nb_reviews = 0;
1881                                listComment.find('.ets_rv_nb_answers').text(function () {
1882                                    nb_reviews = (parseInt($(this).text()) > 0 ? parseInt($(this).text()) - 1 : 0);
1883                                    return nb_reviews;
1884                                });
1885                                listComment.find('.ets_rv_answers_text').html(function () {
1886                                    return (nb_reviews > 1 ? $(this).data('multi-text') : $(this).data('text'));
1887                                });
1888                            }
1889
1890                            //new code:
1891                            if (productCommentActions.length > 0) {
1892                                if (listComment.hasClass('answer')) {
1893                                    var nb_questions = 0;
1894                                    productCommentActions.find('.ets_rv_nb_answers').text(function () {
1895                                        nb_questions = (parseInt($(this).text()) > 0 ? parseInt($(this).text()) - 1 : 0);
1896                                        return nb_questions;
1897                                    });
1898                                    productCommentActions.find('.ets_rv_answers_text').html(function () {
1899                                        return (nb_questions > 1 ? $(this).data('multi-text') : $(this).data('text'));
1900                                    });
1901                                } else {
1902                                    productCommentActions.find('.nb-comment-value').html(function () {
1903                                        nb_questions = (parseInt($(this).text()) > 0 ? parseInt($(this).text()) - 1 : 0);
1904                                        return nb_questions;
1905                                    });
1906                                    productCommentActions.find('.nb-comment-text').html(function () {
1907                                        return (nb_questions > 1 ? $(this).data('multi-text') : $(this).data('text'));
1908                                    });
1909                                }
1910                            }
1911                        }
1912                        // admin:
1913                        if (typeof ets_rv !== "undefined")
1914                            ets_rv.refreshList(json);
1915                    }
1916                },
1917                error: function () {
1918                    ele.removeClass('active');
1919                }
1920            });
1921        }
1922    });
1923    $(document).on('click', '.ets_rv_btn_delete.reply-comment', function (ev) {
1924        ev.preventDefault();
1925        var ele = $(this),
1926            commentList = $('#ets-rv-product-comments-list'),
1927            replyComment = ele.parents('.reply-comment-list-item').eq(0),
1928            listReplyComment = replyComment.parents('.ets_rv_reply_comment_list').eq(0)
1929        ;
1930        if (!ele.hasClass('active') && confirm(ETS_RV_CONFIRM_DELETE_ITEM)) {
1931            if (listReplyComment.find('button.ets_rv_post_reply_comment.update-reply-comment').length > 0) {
1932                listReplyComment.find('button.ets_rv_cancel_reply_comment:visible').trigger('click');
1933            }
1934            $('.reply-comment-list-item').removeClass('active');
1935            ele.addClass('active');
1936            $.ajax({
1937                type: 'POST',
1938                url: commentList.data('comments-url'),
1939                data: '__ac=delete_reply_comment&id_reply_comment=' + replyComment.data('reply-comment-id'),
1940                dataType: 'json',
1941                success: function (json) {
1942                    ele.removeClass('active');
1943                    if (json) {
1944                        if (!json.success)
1945                            productCommentsETS.showErrorModal(json.error);
1946                        else {
1947                            if (json.msg)
1948                                funcPCETS.showSuccessMessage(json.msg);
1949                            replyComment.remove();
1950                            listReplyComment.find('.ets_rv_reply_comment_load_more').attr('data-begin', function () {
1951                                return parseInt($(this).attr('data-begin')) > 0 ? parseInt($(this).attr('data-begin')) - 1 : 0;
1952                            });
1953                            listReplyComment.prev().find('.nb-reply-comment-value').text(function () {
1954                                var data_count = parseInt($(this).text()) > 0 ? parseInt($(this).text()) - 1 : 0;
1955                                $(this).parent('.nb-reply-comment').attr('data-count', data_count);
1956                                return parseInt($(this).text()) > 0 ? parseInt($(this).text()) - 1 : 0;
1957
1958                            });
1959                            // admin:
1960                            if (typeof ets_rv !== "undefined")
1961                                ets_rv.refreshList(json);
1962                        }
1963                    }
1964                },
1965                error: function () {
1966                    ele.removeClass('active');
1967                }
1968            });
1969        }
1970    });
1971
1972    // Approve
1973    $(document).on('click', '.ets_rv_btn_approve.product-comment, .ets_rv_btn_private.product-comment', function (ev) {
1974        ev.preventDefault();
1975        if ($(this).hasClass('bo')) {
1976            var ele = $(this),
1977                productComment = ele.parents('.ets-rv-product-comment-list-item'),
1978                prop = productComment.hasClass('question') ? 'question' : 'comment',
1979                commentList = $('#ets-rv-product-' + prop + 's-list'),
1980                _ac = ele.hasClass('ets_rv_btn_private') ? 'private' : 'approve'
1981            ;
1982            if (!ele.hasClass('active')) {
1983                $('.ets-rv-product-comment-list-item').removeClass('active');
1984                ele.addClass('active');
1985                $.ajax({
1986                    type: 'POST',
1987                    url: commentList.data('comments-url'),
1988                    data: '__ac=' + _ac + '_product_comment&id_product_comment=' + productComment.data('product-comment-id'),
1989                    dataType: 'json',
1990                    success: function (json) {
1991                        ele.removeClass('active');
1992                        if (json) {
1993                            if (!json.success)
1994                                productCommentsETS.showErrorModal(json.error);
1995                            else {
1996                                if (json.msg)
1997                                    funcPCETS.showSuccessMessage(json.msg);
1998                                if (_ac !== 'private') {
1999                                    ele.parents('.ets-rv-product-comment-list-item').attr('data-status', 'approved');
2000                                } else {
2001                                    ele.parents('.ets-rv-product-comment-list-item').attr('data-status', 'private');
2002                                }
2003                                // admin:
2004                                if (typeof ets_rv !== "undefined")
2005                                    ets_rv.refreshList(json);
2006
2007                                if (ele.hasClass('ets_rv_btn_approve'))
2008                                    $('#product-comment-render-form .panel-footer a.ets_rv_approve').hide();
2009                                else
2010                                    $('#product-comment-render-form .panel-footer a.ets_rv_approve').show();
2011                            }
2012                        }
2013                    },
2014                    error: function () {
2015                        ele.removeClass('active');
2016                    }
2017                });
2018            }
2019        }
2020    });
2021    $(document).on('click', '.ets_rv_btn_approve.comment, .ets_rv_btn_private.comment', function (ev) {
2022        ev.preventDefault();
2023        var ele = $(this),
2024            prop = ele.parents('.comment-list-item').hasClass('question') ? 'question' : 'comment',
2025            commentList = $('#ets-rv-product-' + prop + 's-list'),
2026            comment = ele.parents('.comment-list-item'),
2027            _ac = ele.hasClass('ets_rv_btn_private') ? 'private' : 'approve'
2028        ;
2029        if (!ele.hasClass('active')) {
2030            $('.comment-list-item').removeClass('active');
2031            ele.addClass('active');
2032            $.ajax({
2033                type: 'POST',
2034                url: commentList.data('comments-url'),
2035                data: '__ac=' + _ac + '_comment&id_comment=' + comment.data('comment-id'),
2036                dataType: 'json',
2037                success: function (json) {
2038                    ele.removeClass('active');
2039                    if (json) {
2040                        if (!json.success)
2041                            productCommentsETS.showErrorModal(json.error);
2042                        else {
2043                            if (json.msg)
2044                                funcPCETS.showSuccessMessage(json.msg);
2045
2046                            if (_ac !== 'private') {
2047                                ele.parents('.comment-list-item').attr('data-status', 'approved');
2048                            } else {
2049                                ele.parents('.comment-list-item').attr('data-status', 'private');
2050                            }
2051
2052                            // admin:
2053                            if (typeof ets_rv !== "undefined")
2054                                ets_rv.refreshList(json);
2055                        }
2056                    }
2057                },
2058                error: function () {
2059                    ele.removeClass('active');
2060                }
2061            });
2062        }
2063    });
2064    $(document).on('click', '.ets_rv_btn_approve.reply-comment, .ets_rv_btn_private.reply-comment', function (ev) {
2065        ev.preventDefault();
2066        var ele = $(this),
2067            prop = ele.parents('.reply-comment-list-item').hasClass('question') ? 'question' : 'comment',
2068            commentList = $('#ets-rv-product-' + prop + 's-list'),
2069            replyComment = ele.parents('.reply-comment-list-item').eq(0),
2070            _ac = ele.hasClass('ets_rv_btn_private') ? 'private' : 'approve'
2071        ;
2072        if (!ele.hasClass('active')) {
2073            $('.reply-comment-list-item').removeClass('active');
2074            ele.addClass('active');
2075            $.ajax({
2076                type: 'POST',
2077                url: commentList.data('comments-url'),
2078                data: '__ac=' + _ac + '_reply_comment&id_reply_comment=' + replyComment.data('reply-comment-id'),
2079                dataType: 'json',
2080                success: function (json) {
2081                    ele.removeClass('active');
2082                    if (json) {
2083                        if (!json.success)
2084                            productCommentsETS.showErrorModal(json.error);
2085                        else {
2086                            if (json.msg)
2087                                funcPCETS.showSuccessMessage(json.msg);
2088
2089                            if (_ac !== 'private') {
2090                                ele.parents('.reply-comment-list-item').attr('data-status', 'approved');
2091                            } else {
2092                                ele.parents('.reply-comment-list-item').attr('data-status', 'private');
2093                            }
2094                            // Backoffice:
2095                            if (typeof ets_rv !== "undefined")
2096                                ets_rv.refreshList(json);
2097                        }
2098                    }
2099                },
2100                error: function () {
2101                    ele.removeClass('active');
2102                }
2103            });
2104        }
2105    });
2106
2107    // Edit
2108    $(document).on('click', '.ets_rv_btn_edit.reply-comment', function (ev) {
2109        ev.preventDefault();
2110        var ele = $(this),
2111            replyComment = ele.parents('.reply-comment-list-item').eq(0),
2112            listReplyComment = replyComment.parents('.ets_rv_reply_comment_list').eq(0),
2113            dropdown = ele.parents('.comment_dropdown_action').eq(0),
2114            prop = replyComment.hasClass('question') ? 'question' : 'comment'
2115        ;
2116
2117        if (!ele.hasClass('active') && !replyComment.hasClass('active')) {
2118
2119            reCaptchaETS.reset(listReplyComment.find('.form-control-reply-comment'));
2120
2121            if (listReplyComment.find('button.ets_rv_post_reply_comment.update-reply-comment').length > 0) {
2122                listReplyComment.find('button.ets_rv_cancel_reply_comment:visible').trigger('click');
2123            }
2124            $('.reply-comment-list-item').removeClass('active');
2125            replyComment.addClass('active');
2126            ele.addClass('active');
2127            if (!ele.hasClass('json-loading')) {
2128                ele.addClass('json-loading');
2129                var commentList = $('#ets-rv-product-' + prop + 's-list');
2130                $.ajax({
2131                    url: commentList.data('comments-url'),
2132                    data: '__ac=reply_comment&id_reply_comment=' + replyComment.data('reply-comment-id'),
2133                    type: 'get',
2134                    dataType: 'json',
2135                    success: function (json) {
2136                        ele.removeClass('json-loading');
2137                        if (json) {
2138                            listReplyComment.find('.form-control-reply-comment textarea[name^=comment_content]').val(function () {
2139                                var matches = $(this).attr('name').match(/comment_content_(\d+)/i);
2140                                if (matches && typeof matches[1] !== "undefined") {
2141                                    var prop = matches[1];
2142                                    if (json.content.hasOwnProperty(prop)) {
2143                                        return funcPCETS.br2n(json.content[prop] ? json.content[prop] : json.origin_content);
2144                                    }
2145                                } else
2146                                    return funcPCETS.br2n(json.origin_content);
2147                            });
2148                            if (dropdown.hasClass('bo')) {
2149                                if (listReplyComment.find('.form-control-reply-comment input.datetimepicker').length < 1)
2150                                    listReplyComment.find('.form-control-reply-comment .form-group.date_add').find('.input-group').append('<input id="date_add_' + Math.random().toString(36).slice(-8) + '" type="text" data-hex="true" class="datetimepicker" name="date_add" />');
2151                                listReplyComment.find('.form-control-reply-comment .form-group.date_add').removeClass('hide');
2152                                if (json.date_add !== '0000-00-00 00:00:00')
2153                                    listReplyComment.find('.form-control-reply-comment input.datetimepicker').val(json.date_add);
2154                                listReplyComment.find('.form-control-reply-comment input.datetimepicker:not(.hasDatepicker)').datetimepicker(ETS_RV_DATETIME_PICKER);
2155                            }
2156
2157                            listReplyComment.find('button.ets_rv_cancel_reply_comment:hidden').show();
2158                            listReplyComment.find('button.ets_rv_post_reply_comment')
2159                                .addClass('update-reply-comment')
2160                                .html(function () {
2161                                    return $(this).data('upd');
2162                                });
2163                            listReplyComment.find('.ets_rv_form_reply_comment:not(.active)').addClass('active');
2164                            listReplyComment.find('textarea.ets_rv_reply_comment').focus();
2165                        }
2166                    },
2167                    error: function () {
2168                        ele.removeClass('json-loading');
2169                        ele.removeClass('active');
2170                    }
2171                });
2172            }
2173        }
2174    });
2175    $(document).on('click', '.ets_rv_btn_edit.comment', function (ev) {
2176        ev.preventDefault();
2177        var ele = $(this),
2178            comment = ele.parents('.comment-list-item').eq(0),
2179            listComment = comment.parents('.ets_rv_answer_list').eq(0).length > 0 ? comment.parents('.ets_rv_answer_list').eq(0) : comment.parents('.ets_rv_comment_list').eq(0),
2180            dropdown = ele.parents('.comment_dropdown_action').eq(0),
2181            prop = comment.hasClass('question') ? 'question' : 'comment'
2182        ;
2183        if (!ele.hasClass('active') && !comment.hasClass('active')) {
2184            if (listComment.find('button.ets_rv_post_comment.update-comment').length > 0) {
2185                listComment.find('button.ets_rv_cancel_comment:visible').trigger('click');
2186            }
2187            $('.comment-list-item').removeClass('active');
2188            comment.addClass('active');
2189            ele.addClass('active');
2190            if (!ele.hasClass('json-loading')) {
2191                ele.addClass('json-loading');
2192                var commentList = $('#ets-rv-product-' + prop + 's-list');
2193                $.ajax({
2194                    url: commentList.data('comments-url'),
2195                    data: '__ac=comment&id_comment=' + comment.data('comment-id'),
2196                    type: 'get',
2197                    dataType: 'json',
2198                    success: function (json) {
2199                        ele.removeClass('json-loading');
2200                        if (json) {
2201                            listComment.find('.form-control-comment textarea[name^=comment_content]').val(function () {
2202                                var matches = $(this).attr('name').match(/comment_content_(\d+)/i);
2203                                if (matches && typeof matches[1] !== "undefined") {
2204                                    var idLang = matches[1];
2205                                    if (json.content.hasOwnProperty(idLang)) {
2206                                        return funcPCETS.br2n(json.content[idLang] ? json.content[idLang] : json.origin_content);
2207                                    }
2208                                } else {
2209                                    var idDefaultLang = parseInt($(this).parents('form').data('lang-default'));
2210                                    return funcPCETS.br2n(json.origin_content ? json.origin_content : (json.content && json.content[idDefaultLang] ? json.content[idDefaultLang] : ''));
2211                                }
2212                            });
2213                            if (dropdown.hasClass('employee')) {
2214                                if (listComment.find('.form-control-comment input.datetimepicker').length < 1)
2215                                    listComment.find('.form-control-comment .form-group.date_add').find('.input-group').append('<input id="date_add_' + Math.random().toString(36).slice(-8) + '" type="text" data-hex="true" class="datetimepicker" name="date_add" />');
2216                                listComment.find('.form-control-comment .form-group.date_add').removeClass('hide');
2217                                if (json.date_add !== '0000-00-00 00:00:00')
2218                                    listComment.find('.form-control-comment input.datetimepicker').val(json.date_add);
2219                                listComment.find('.form-control-comment input.datetimepicker:not(.hasDatepicker)').datetimepicker(ETS_RV_DATETIME_PICKER);
2220                            }
2221
2222                            listComment.find('button.ets_rv_cancel_comment:hidden').show();
2223                            listComment.find('button.ets_rv_post_comment')
2224                                .addClass('update-comment')
2225                                .html(function () {
2226                                    return $(this).data('upd');
2227                                });
2228                            reCaptchaETS.reset(listComment.find('.form-control-comment'));
2229                            listComment.find('.ets_rv_form_comment:not(.active)').addClass('active');
2230                            listComment.find('textarea.ets_rv_comment').focus();
2231
2232                        }
2233                    },
2234                    error: function () {
2235                        ele.removeClass('json-loading');
2236                        ele.removeClass('active');
2237                    }
2238                });
2239            }
2240        }
2241    });
2242
2243    // Cancel.
2244    $(document).on('click', '.ets_rv_cancel_comment', function (ev) {
2245        ev.preventDefault();
2246        var ele = $(this),
2247            listComment = ele.parents('.ets_rv_comment_list').eq(0).length > 0 ? ele.parents('.ets_rv_comment_list').eq(0) : ele.parents('.ets_rv_answer_list').eq(0),
2248            comment = listComment.find('.comment-list-item.active').eq(0),
2249            option = comment.hasClass('question') ? 'question' : 'comment'
2250        ;
2251        comment.removeClass('active');
2252        comment.find('.ets_rv_btn_edit.comment').removeClass('active');
2253        listComment.find('button.ets_rv_cancel_comment:visible').hide();
2254        listComment.find('button.ets_rv_post_comment')
2255            .removeClass('update-comment')
2256            .html(function () {
2257                return $(this).data('name');
2258            });
2259        listComment.find('textarea.ets_rv_comment').val('').focus();
2260        listComment.find('.form-group.date_add').addClass('hide');
2261        if (!ele.hasClass('show_answer_box') && !ele.hasClass('show_comment_box')) {
2262            ele.parents('.ets_rv_form_comment').removeClass('active');
2263        }
2264    });
2265    $(document).on('click', '.ets_rv_cancel_reply_comment', function (ev) {
2266        ev.preventDefault();
2267        var ele = $(this),
2268            listReplyComment = ele.parents('.ets_rv_reply_comment_list').eq(0),
2269            replyComment = listReplyComment.find('.reply-comment-list-item.active').eq(0),
2270            option = replyComment.hasClass('question') ? 'question' : 'comment'
2271        ;
2272        replyComment.removeClass('active');
2273        replyComment.find('.ets_rv_btn_edit.reply-comment').removeClass('active');
2274
2275        listReplyComment.find('button.ets_rv_cancel_reply_comment:visible').hide();
2276        listReplyComment.find('button.ets_rv_post_reply_comment')
2277            .removeClass('update-reply-comment')
2278            .html(function () {
2279                return $(this).data('name');
2280            });
2281        listReplyComment.find('textarea.ets_rv_reply_comment').val('').focus();
2282        listReplyComment.find('.form-group.date_add').addClass('hide');
2283        if (!ele.hasClass('show_reply_box')) {
2284            ele.parents('.ets_rv_form_reply_comment').removeClass('active');
2285        }
2286    });
2287
2288    $(document).on('click', '#ets-rv-post-product-comment-form .ets_rv_btn_upload, form[id^=ets_rv_product_comment_form] .ets_rv_btn_upload, .ets_rv_form_upload_image .ets_rv_btn_upload', function () {
2289        $(this).parents('.ets_rv_upload_photo_item').find('input[type=file]').trigger('click');
2290    });
2291
2292    $(document).on('change', '#ets-rv-post-product-comment-form input[type=file][name*=image],#ets-rv-post-product-comment-form input[type=file][name*=video], form[id^=ets_rv_product_comment_form] input[type=file][name*=image], form[id^=ets_rv_product_comment_form] input[type=file][name*=video],.ets_rv_form_upload_image input[type=file][name*=image],.ets_rv_form_upload_image input[type=file][name*=video]', function (event) {
2293        event.preventDefault();
2294        var ele = $(this),
2295            max_file_size = PS_ATTACHMENT_MAXIMUM_SIZE,
2296            ext_file = ele.val().split('.').pop().toLowerCase()
2297        ;
2298        var fileExtension = ['jpeg', 'jpg', 'png', 'gif'];
2299        if (ele.hasClass('video')) {
2300            fileExtension = ['mp4', 'webm', 'mov'];
2301        }
2302        if (fileExtension.indexOf(ext_file) === -1) {
2303            ele.val('');
2304            alert(file_not_valid_text);
2305        } else if (this.files && this.files[0] && this.files[0].size > max_file_size) {
2306            $(this).val('');
2307            alert(file_is_to_large_text.replace('%s', PS_ATTACHMENT_MAXIMUM_SIZE_TEXT));
2308        } else {
2309            var photos_wrap = ele.parents('.ets_rv_upload_photos'),
2310                maximum_of_photo = parseInt(photos_wrap.data('photos')),
2311                current_photo_wrap = ele.parents('.ets_rv_upload_photo_item').eq(0),
2312                count_photo = photos_wrap.find('.ets_rv_upload_photo_item').length,
2313                randomSize = Math.random().toString(36).slice(-8)
2314            ;
2315            if (maximum_of_photo > count_photo) {
2316                var addPhoto = current_photo_wrap.clone(true, true);
2317                addPhoto
2318                    .find('input[type=file]')
2319                    .val('')
2320                    .attr({
2321                        id: 'image_' + randomSize,
2322                        name: 'image[' + randomSize + ']'
2323                    });
2324                photos_wrap.append(addPhoto);
2325            }
2326            funcPCETS.readURL(this);
2327
2328            // Upload image.
2329            if ($(this).parents('form').eq(0).hasClass('ets_rv_form_upload_image')) {
2330                var btn = $(this),
2331                    form = btn.parents('form'),
2332                    formFiles = form.find('input[type="file"]');
2333                if (!btn.hasClass('active')) {
2334                    btn.addClass('active');
2335                    var formData = new FormData(form.get(0));
2336                    // Safari fixed.
2337                    if (formFiles.length > 0) {
2338                        formFiles.each(function () {
2339                            if ($($(this).attr('id')).files.length == 0) {
2340                                formData.delete($(this).attr('id'));
2341                            }
2342                        });
2343                    }
2344                    $.ajax({
2345                        type: 'POST',
2346                        url: form.attr('action'),
2347                        data: formData,
2348                        processData: false,
2349                        contentType: false,
2350                        dataType: 'json',
2351                        success: function (json) {
2352                            btn.removeClass('active');
2353                            if (json) {
2354                                if (json.error)
2355                                    productCommentsETS.showErrorModal(json.error);
2356                                else if (json.errors) {
2357                                    productCommentsETS.showErrorModal(json.errors);
2358                                } else {
2359                                    btn.val('');
2360                                    if (json.msg)
2361                                        funcPCETS.showSuccessMessage(json.msg);
2362                                    if (json.images) {
2363                                        btn.parents('.ets_rv_upload_photo_item')
2364                                            .find('.ets_rv_btn_delete_photo')
2365                                            .attr({
2366                                                'data-product-comment-image-id': json.images.id,
2367                                                'data-product-comment-id': json.images.id_ets_rv_product_comment,
2368                                            });
2369                                    }
2370                                }
2371                            }
2372                        },
2373                        error: function () {
2374                            btn.removeClass('active');
2375                        }
2376                    });
2377                }
2378            }
2379        }
2380
2381    });
2382
2383    $(document).on('click', '#ets-rv-post-product-comment-form .ets_rv_btn_delete_photo, form[id^=ets_rv_product_comment_form] .ets_rv_btn_delete_photo, .ets_rv_form_upload_image .ets_rv_btn_delete_photo', function (ev) {
2384        ev.preventDefault();
2385        var ele = $(this),
2386            formPost = $('#ets-rv-post-product-comment-form').length > 0 ? $('#ets-rv-post-product-comment-form') : $('form[id^=ets_rv_product_comment_form]'),
2387            url = formPost.attr('action');
2388        if (!ele.hasClass('active') && ele.data('product-comment-image-id') && url) {
2389            if (url.match(/(__ac=)/ig)) {
2390                url = url.replace(/(__ac=)([^\&\?]+)(&)?/ig, '$1delete_product_comment_image$3')
2391            } else {
2392                url += '&__ac=delete_product_comment_image'
2393            }
2394            ele.addClass('active');
2395            $.ajax({
2396                url: url,
2397                type: 'post',
2398                data: 'id_product_comment_image=' + ele.data('product-comment-image-id') + '&id_product_comment=' + ele.data('product-comment-id'),
2399                dataType: 'json',
2400                success: function (json) {
2401                    ele.removeClass('active');
2402                    if (json) {
2403                        if (json.error)
2404                            productCommentsETS.showErrorModal(json.error);
2405                        else {
2406                            if (json.msg)
2407                                funcPCETS.showSuccessMessage(json.msg);
2408                        }
2409                    }
2410                },
2411                error: function () {
2412                    ele.removeClass('active');
2413                }
2414            });
2415        }
2416        var photos_wrap = ele.parents('.ets_rv_upload_photos').eq(0),
2417            maximum_of_photo = parseInt(photos_wrap.data('photos')),
2418            photo_items = photos_wrap.find('.ets_rv_upload_photo_item'),
2419            selected_photo = ele.parents('.ets_rv_upload_photo_item').eq(0)
2420        ;
2421        if (photos_wrap.find('.ets_rv_upload_photo_item .ets_rv_upload_photo_wrap:not(.selected)').length <= 0) {
2422            var addPhoto = selected_photo.clone(true, true),
2423                randomSize = Math.random().toString(36).slice(-8)
2424            ;
2425            addPhoto
2426                .find('input[type=file]').val('')
2427                .attr({
2428                    id: 'image_' + randomSize,
2429                    name: 'image[' + randomSize + ']'
2430                })
2431            ;
2432            addPhoto
2433                .find('.ets_rv_upload_photo_wrap')
2434                .removeClass('selected')
2435                .css('background-image', '')
2436                .attr('title', '')
2437            ;
2438            photos_wrap.append(addPhoto);
2439        }
2440        selected_photo.remove();
2441    });
2442    $(document).on('click', '#ets-rv-post-product-comment-form .ets_rv_btn_delete_video, form[id^=ets_rv_product_comment_form] .ets_rv_btn_delete_video, .ets_rv_form_upload_video .ets_rv_btn_delete_video', function (ev) {
2443        ev.preventDefault();
2444        var ele = $(this),
2445            formPost = $('#ets-rv-post-product-comment-form').length > 0 ? $('#ets-rv-post-product-comment-form') : $('form[id^=ets_rv_product_comment_form]'),
2446            url = formPost.attr('action')
2447        ;
2448        selected_video = ele.parents('.ets_rv_upload_video_item').eq(0);
2449
2450        if (!ele.hasClass('active') && ele.data('product-comment-video-id') && url) {
2451            if (url.match(/(__ac=)/ig)) {
2452                url = url.replace(/(__ac=)([^\&\?]+)(&)?/ig, '$1delete_product_comment_video$3')
2453            } else {
2454                url += '&__ac=delete_product_comment_video'
2455            }
2456            ele.addClass('active');
2457            $.ajax({
2458                url: url,
2459                type: 'post',
2460                data: 'id_product_comment_video=' + ele.data('product-comment-video-id') + '&id_product_comment=' + ele.data('product-comment-id'),
2461                dataType: 'json',
2462                success: function (json) {
2463                    ele.removeClass('active');
2464                    if (json) {
2465                        if (json.error)
2466                            productCommentsETS.showErrorModal(json.error);
2467                        else {
2468                            if (json.msg)
2469                                funcPCETS.showSuccessMessage(json.msg);
2470                        }
2471                    }
2472                },
2473                error: function () {
2474                    ele.removeClass('active');
2475                }
2476            });
2477        }
2478        ele.parents('.ets_rv_upload_video_item').find('input[type=file]').val('');
2479        ele.parents('.ets_rv_upload_video_wrap').attr('title', '').removeClass('selected').parents('.ets_rv_upload_video_item').removeClass('cms_has_video');
2480        ele.parents('.ets_rv_upload_video_wrap').find('.ets_rv_video').html('');
2481        var copy_selected = selected_video.clone();
2482        selected_video.remove();
2483        $('.ets_rv_upload_videos').append(copy_selected);
2484
2485    });
2486    $(document).on('click', '.ets_rv_edit_date', function (ev) {
2487        var btn = $(this),
2488            form = btn.prev('.comment-form');
2489        if (form.find('.datepicker').length > 0) {
2490            form.find('.datepicker').datepicker({
2491                prevText: '',
2492                nextText: '',
2493                dateFormat: 'yy-mm-dd',
2494            });
2495        }
2496        form.addClass('active');
2497        $('#ui-datepicker-div').css('z-index', '10000');
2498    });
2499
2500    $(document).on('click', '.ets_rv_btn_edit_date', function (ev) {
2501        ev.preventDefault();
2502        var btn = $(this), urlPost = btn.attr('href');
2503        if (!btn.hasClass('active') && urlPost !== '') {
2504            btn.addClass('active');
2505            var requestData = {};
2506            if (btn.hasClass('product-comment')) {
2507                requestData.id_product_comment = btn.parents('.ets-rv-product-comment-list-item').data('product-comment-id');
2508            } else if (btn.hasClass('comment')) {
2509                requestData.id_comment = btn.parents('.comment-list-item').data('comment-id');
2510            } else {
2511                requestData.id_reply_comment = btn.parents('.reply-comment-list-item').data('reply-comment-id');
2512            }
2513            requestData.date_add = btn.parents('.comment-form').find('input[name=date_add]').val();
2514            $.ajax({
2515                url: urlPost,
2516                type: 'POST',
2517                data: requestData,
2518                dataType: 'json',
2519                success: function (json) {
2520                    btn.removeClass('active');
2521                    if (json) {
2522                        if (json.errors) {
2523                            showErrorMessage(json.errors);
2524                        } else {
2525                            if (json.msg)
2526                                funcPCETS.showSuccessMessage(json.msg);
2527                            if (json.date_add) {
2528                                btn.parents('.comment-form').removeClass('active');
2529                                btn.parents('.ets_rv_form_date_add').find('.ets_rv_date_add').eq(0).text(json.date_add);
2530                            }
2531                        }
2532                    }
2533                },
2534                error: function () {
2535                    btn.removeClass('active');
2536                }
2537            });
2538        }
2539
2540    });
2541
2542    $(document).keyup(function (e) {
2543        if (e.keyCode === 27) {
2544            $('.comment-form.active').removeClass('active');
2545        }
2546    });
2547
2548    $(document).mouseup(function (e) {
2549        var commentForm = $('.comment-form.active'),
2550            datePicker = $('#ui-datepicker-div');
2551
2552        if (!commentForm.is(e.target) && commentForm.has(e.target).length === 0 && (!datePicker.length || !datePicker.is(e.target) && datePicker.has(e.target).length === 0 && datePicker.css('display') === 'none')) {
2553            commentForm.removeClass('active');
2554        }
2555    });
2556    $(document).on('click', '.ets_rv_btn_show_answer', function () {
2557        $(this).toggleClass('active').parents('.ets-rv-product-comment-list-item.question').find('.ets_rv_answer_list.answer').stop().toggleClass('show_content');
2558    });
2559    $(document).on('click', '.nb-comment.question', function () {
2560        $(this).stop().toggleClass('active').parents('.ets-rv-product-comment-list-item.question').find('.ets_rv_comment_list').stop().toggleClass('show_content');
2561    });
2562});

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.