PageSourceSearch

https://www.montesanto.net/plugins/comments/comments.js?v=3

js montesanto.net collected 2026-10-02 13:25:42 UTC 29,614 bytes, 761 lines download raw bytes

1
2/**
3 * Comments Module System
4 *
5 * @version 1.0.0
6 * @author William Carneiro <[email protected]>
7 * @copyright 2022 HITMO Marketing Digital
8*/
9
10class Comments {
11
12    /**
13     * Target element
14     *
15     * @var {HTMLElement}
16     */
17    target;
18
19    /**
20     * System settings
21     *
22     * @var {object}
23     */
24    settings = {};
25
26    /**
27     * Comments loaded
28     *
29     * @var {array}
30     */
31    comments_loaded = [];
32
33    /**
34     * Comments built
35     *
36     * @var {object}
37     */
38    comments_built = [];
39
40    /**
41     * Comments showing
42     *
43     * @var {object}
44     */
45    comments_showing = {};
46
47    /**
48     * Comments load attempts
49     *
50     * @var {int}
51     */
52    comments_load_attempts = 0;
53
54    /**
55     * Comments load maximum attempts
56     *
57     * @var {int}
58     */
59    comments_load_attempts_max = 3;
60
61    /**
62     * Initialize system
63     *
64     * @param {HTMLElement} target
65     * @param {object} settings
66     * @returns {object}
67     */
68    constructor(target, settings = {}) {
69        const self = this;
70
71        if (!$(target)[0]) {
72            throw new Error('O elemento especificado não existe.');
73        }
74
75        this.target = target;
76        this.settings = settings;
77
78        this.loadComments();
79
80        $(target).find('.comments_load_more').on('click', function() {
81            self.commentsBuild();
82
83            return false;
84        });
85
86        $(target).find('.post_form').on('submit', function() {
87            var form = this;
88            var form_data = Object.assign(Object.fromEntries(new FormData(form)), {
89                page: settings.page,
90                referrer_type: settings.referrer.type,
91                referrer_id: settings.referrer.id
92            });
93
94            $(this).find('textarea, button').prop('disabled', true);
95
96            $.ajax({
97                dataType: 'json',
98                method: 'POST',
99                url: setting.site_url + '/system/lib/post_comment.php',
100                context: self,
101                data: form_data,
102                success: function(data) {
103                    if (data.status == 'success') {
104                        this.comments_loaded.unshift(data.comment);
105
106                        this.commentsBuild(data.comment.id);
107
108                        $(form)[0].reset();
109                    } else {
110                        alert(data.error);
111                    }
112                },
113                error: function(e) {
114                    alert('(' + e.status + ') Algo deu errado ao tentar publicar seu comentário. Por favor, tente novamente.');
115                },
116                complete: function() {
117                    $(form).find('textarea, button').prop('disabled', false);
118                }
119            });
120
121            return false;
122        });
123
124        return this;
125    }
126
127    /**
128     * Load comments
129     */
130    loadComments() {
131        const self = this;
132
133        $(this.target).addClass('loading');
134
135        $.ajax({
136            dataType: 'json',
137            method: 'POST',
138            url: setting.site_url + '/system/lib/get_comments.php',
139            context: this,
140            data: {
141                page: this.settings.page,
142                referrer_type: this.settings.referrer.type,
143                referrer_id: this.settings.referrer.id,
144            },
145            success: function(data) {
146                this.comments_loaded = data.comments;
147                this.comments_load_attempts = 0;
148
149                if (this.settings.onLoad) {
150                    this.settings.onLoad(this);
151                }
152
153                this.commentsBuild();
154            },
155            error: function(e) {
156                if (this.comments_load_attempts < this.comments_load_attempts_max) {
157                    setTimeout(function() {
158                        self.loadComments();
159                    }, 500);
160
161                    this.comments_load_attempts++;
162                } else {
163                    console.error('Ocorreu um erro inesperado ao tentar carregar os comentários!', e);
164                }
165            },
166            complete: function() {
167                $(this.target).removeClass('loading');
168            }
169        });
170    }
171
172    /**
173     * Build comments
174     *
175     * @param {boolean} new_comment_id
176     */
177    commentsBuild(new_comment_id = false) {
178        const self = this;
179
180        var build_count = 0;
181
182        if (!(self.target.id in this.comments_showing)) {
183            this.comments_showing[self.target.id] = [];
184        }
185
186        $.each(this.comments_loaded, function(k, comment) {
187            if (!self.comments_showing[self.target.id].includes(comment.id) && build_count < self.settings.max_results && (new_comment_id == false || new_comment_id && new_comment_id == comment.id)) {
188                var _comment = self.commentFactory();
189
190                _comment.setId(comment.id);
191                _comment.setPage(self.settings.page);
192                _comment.setReferrerType(self.settings.referrer.type);
193                _comment.setReferrerId(self.settings.referrer.id);
194                _comment.setParentElement(self.target);
195                _comment.setAnswerStatus(comment.answer_status);
196                _comment.setDeleteStatus(comment.delete_status);
197                _comment.setPostDate(comment.date.elapsed_short);
198                _comment.setAuthor(comment.customer.shortname, (comment.customer.file_01 && comment.customer.file_01.length > 0 ? setting.site_url + '/midia/customers/' + comment.customer.file_01 : setting.site_url + '/images/i/user.svg'));
199                _comment.setMessage(comment.message);
200
201                self.comments_built.push(_comment);
202
203                $.each(comment.replies, function(rk, reply) {
204                    var _reply = self.commentFactory();
205
206                    _reply.setId(reply.id);
207                    _reply.setPage(self.settings.page);
208                    _reply.setReferrerType(self.settings.referrer.type);
209                    _reply.setReferrerId(self.settings.referrer.id);
210                    _reply.setParentElement(self.target);
211                    _reply.setDeleteStatus(reply.delete_status);
212                    _reply.setAnswerStatus(reply.answer_status);
213                    _reply.setMainComment(_comment);
214                    _reply.setReplyFrom(self.getCommentById(reply.reply_from_id));
215                    _reply.setPostDate(reply.date.elapsed_short);
216                    _reply.setAuthor(reply.customer.shortname, (reply.customer.file_01 && reply.customer.file_01.length > 0 ? setting.site_url + '/midia/customers/' + reply.customer.file_01 : setting.site_url + '/images/i/user.svg'));
217                    _reply.setMessage(reply.message);
218
219                    _comment.addReply(_reply);
220
221                    self.comments_built.push(_reply);
222                });
223
224                if (new_comment_id && comment.id == new_comment_id) {
225                    $(self.target).find('.comments_list').prepend(_comment.getElement());
226
227                    setTimeout(function() {
228                        self.highlightComment(_comment.getId());
229                    }, 500);
230                } else {
231                    $(self.target).find('.comments_list').append(_comment.getElement());
232                }
233
234                self.comments_showing[self.target.id].push(comment.id);
235                build_count++;
236            }
237        });
238
239        if (this.comments_loaded.length == 0) {
240            $(self.target).addClass('no_comments_yet');
241        } else {
242            $(self.target).removeClass('no_comments_yet');
243        }
244
245        if (this.comments_showing[this.target.id].length < this.comments_loaded.length) {
246            $(self.target).addClass('load_more');
247        } else {
248            $(self.target).removeClass('load_more');
249        }
250    }
251
252    /**
253     * Get comment by ID
254     *
255     * @param {int} id
256     * @returns {object}
257     */
258    getCommentById(id) {
259        var found_comment = null;
260
261        for (var k = 0; k < this.comments_built.length; k++) {
262            var comment = this.comments_built[k];
263
264            if (comment.getId() == id) {
265                found_comment = comment;
266                break;
267            }
268        }
269
270        return found_comment;
271    }
272
273    /**
274     * Clear comments
275     */
276    clearComments() {
277        $.each(this.comments_built, function(k, comment) {
278            $(comment.e).remove();
279        });
280
281        this.comments_built = [];
282        this.comments_loaded = [];
283        this.comments_showing = {};
284    }
285
286    /**
287     * Highlight a comment
288     *
289     * @param {int} comment_id
290     * @param {boolean} scroll
291     */
292    highlightComment(comment_id, scroll = false) {
293        $("[data-comment-id = '" + comment_id + "'] > .comment_container").css('background-color', 'rgb(245 182 66 / 10%)');
294
295        setTimeout(function() {
296            $("[data-comment-id = '" + comment_id + "'] > .comment_container").css('background-color', 'transparent');
297        }, 1000);
298
299        if (scroll) {
300            $("html, body").animate({
301                scrollTop: $("[data-comment-id = '" + comment_id + "']").offset().top - 160
302            }, 500);
303        }
304    }
305
306    /**
307     * Show loading
308     */
309    showLoading() {
310        $(this.target).addClass('loading');
311    }
312
313    /**
314     * Dismiss loading
315     */
316    dismissLoading() {
317        $(this.target).removeClass('loading');
318    }
319
320    /**
321     * Comment Factory
322     *
323     * @returns {object}
324     */
325    commentFactory() {
326        const self = this;
327
328        var comment = {
329            e: null,
330            parent_e: null,
331            id: null,
332            post_date: null,
333            message: null,
334            author: {
335                fullname: null,
336                picture: null
337            },
338            page: null,
339            referrer: {
340                type: null,
341                id: null
342            },
343            main_comment: null,
344            reply_from: null,
345            answer_status: false,
346            delete_status: false,
347            replies: []
348        };
349
350        comment.setId = function(id) {
351            comment.id = id;
352        };
353
354        comment.setParentElement = function(parent_e) {
355            comment.parent_e = parent_e;
356        };
357
358        comment.setPostDate = function(post_date) {
359            comment.post_date = post_date;
360        };
361
362        comment.setMessage = function(message) {
363            comment.message = message;
364        };
365
366        comment.setReplyFrom = function(reply_from) {
367            comment.reply_from = reply_from;
368        };
369
370        comment.setMainComment = function(main_comment) {
371            comment.main_comment = main_comment;
372        };
373
374        comment.setAnswerStatus = function(answer_status) {
375            comment.answer_status = answer_status;
376        };
377
378        comment.setDeleteStatus = function(delete_status) {
379            comment.delete_status = delete_status;
380        };
381
382        comment.setPage = function(page) {
383            comment.page = page;
384        };
385
386        comment.setReferrerType = function(referrer_type) {
387            comment.referrer.type = referrer_type;
388        };
389
390        comment.setReferrerId = function(referrer_id) {
391            comment.referrer.id = referrer_id;
392        };
393
394        comment.addReply = function(reply) {
395            comment.replies.push(reply);
396        };
397
398        comment.setAuthor = function(fullname, picture) {
399            comment.author.fullname = fullname;
400            comment.author.picture = picture;
401        };
402
403        comment.getId = function() {
404            return comment.id;
405        };
406
407        comment.getPostDate = function() {
408            return comment.post_date;
409        };
410
411        comment.getMessage = function() {
412            return comment.message;
413        };
414
415        comment.getDeleteStatus = function() {
416            return comment.delete_status;
417        };
418
419        comment.getAnswerStatus = function() {
420            return comment.answer_status;
421        };
422
423        comment.getReplies = function() {
424            return comment.replies;
425        };
426
427        comment.getReplyFrom = function() {
428            return comment.reply_from;
429        };
430
431        comment.getAuthorFullname = function() {
432            return comment.author.fullname;
433        };
434
435        comment.getMainComment = function() {
436            return comment.main_comment ?? comment;
437        };
438
439        comment.getPage = function() {
440            return comment.page;
441        };
442
443        comment.getParentElement = function() {
444            return comment.parent_e;
445        };
446
447        comment.getReferrerType = function() {
448            return comment.referrer.type;
449        };
450
451        comment.getReferrerId = function() {
452            return comment.referrer.id;
453        };
454
455        comment.rebuildElement = function() {
456            $(comment.e).replaceWith(comment.getElement());
457        }
458
459        comment.getElement = function() {
460            let element = document.createElement('div');
461            let element_container = document.createElement('div');
462            let author_picture = document.createElement('div');
463            let author_picture_picture = document.createElement('div');
464            let comment_data = document.createElement('div');
465            let comment_data_header = document.createElement('div');
466            let comment_data_header_info_user_name = document.createElement('div');
467            let comment_data_header_info_post_date = document.createElement('div');
468            let comment_data_body = document.createElement('div');
469            let comment_data_footer = document.createElement('div');
470            let comment_data_footer_actions = document.createElement('div');
471            let comment_data_footer_actions_reply_from = document.createElement('div');
472            let comment_data_footer_actions_reply_from_a = document.createElement('a');
473            let comment_data_footer_actions_answer = document.createElement('a');
474            let comment_data_footer_actions_answer_icon = document.createElement('i');
475            let comment_data_footer_actions_report = document.createElement('a');
476            let comment_data_footer_actions_report_icon = document.createElement('i');
477            let comment_data_footer_actions_delete = document.createElement('a');
478            let comment_data_footer_actions_delete_icon = document.createElement('i');
479            let comment_data_footer_replies = document.createElement('div');
480            let comment_data_footer_replies_post_reply = document.createElement('div');
481            let comment_data_footer_replies_post_reply_reply_to = document.createElement('div');
482            let comment_data_footer_replies_post_reply_reply_to_label = document.createElement('label');
483            let comment_data_footer_replies_post_reply_reply_form = document.createElement('form');
484            let comment_data_footer_replies_post_reply_reply_form_textarea = document.createElement('textarea');
485            let comment_data_footer_replies_post_reply_reply_form_main_id = document.createElement('input');
486            let comment_data_footer_replies_post_reply_reply_form_from_id = document.createElement('input');
487            let comment_data_footer_replies_post_reply_reply_form_button = document.createElement('button');
488            let comment_data_footer_replies_post_reply_reply_form_button_i = document.createElement('i');
489            let comment_data_footer_replies_list = document.createElement('div');
490
491            $(author_picture).addClass('author_picture');
492            $(author_picture_picture).addClass('picture');
493            $(author_picture_picture).css('background-image', 'url(' + (comment.author.picture ? comment.author.picture : '') + ')');
494            $(author_picture).append(author_picture_picture);
495
496            $(comment_data_header).addClass('data_header');
497            $(comment_data_header_info_user_name).addClass('info user_name');
498            $(comment_data_header_info_user_name).text(comment.author.fullname);
499            $(comment_data_header_info_post_date).addClass('info post_date');
500            $(comment_data_header_info_post_date).text(comment.getPostDate());
501            $(comment_data_body).addClass('data_body');
502            $(comment_data_body).text(comment.getMessage());
503            $(comment_data_footer).addClass('data_footer');
504            $(comment_data_footer_actions).addClass('actions');
505            $(comment_data_footer_actions_reply_from).addClass('reply_from');
506            $(comment_data_footer_replies).addClass('replies');
507            $(comment_data_footer_replies_post_reply).addClass('post_reply');
508            $(comment_data_footer_replies_post_reply_reply_to).addClass('reply_to');
509            $(comment_data_footer_replies_post_reply_reply_form).addClass('reply_form');
510            $(comment_data_footer_replies_post_reply_reply_form).attr('method', 'POST');
511            $(comment_data_footer_replies_post_reply_reply_form_textarea).addClass('form-control');
512            $(comment_data_footer_replies_post_reply_reply_form_button).addClass('btn btn-primary');
513            $(comment_data_footer_replies_post_reply_reply_form_button_i).addClass('fa fa-reply');
514            $(comment_data_footer_replies_list).addClass('replies_list');
515
516            $(comment_data_footer_replies_post_reply_reply_form_textarea).attr({
517                name: 'message',
518                minlength: 3,
519                maxlength: 1000,
520                required: true,
521                placeholder: 'Digite sua resposta...'
522            });
523
524            $(comment_data_footer_replies_post_reply_reply_form_main_id).attr({
525                type: 'hidden',
526                name: 'main_comment_id'
527            });
528
529            $(comment_data_footer_replies_post_reply_reply_form_from_id).attr({
530                type: 'hidden',
531                name: 'reply_from_id'
532            });
533
534            $(comment_data_header).append(comment_data_header_info_user_name);
535            $(comment_data_header).append(comment_data_header_info_post_date);
536
537            if (comment.reply_from) {
538                $(comment_data_footer_actions_reply_from_a).text(comment.reply_from.getAuthorFullname());
539                $(comment_data_footer_actions_reply_from_a).attr('href', '#')
540
541                $(comment_data_footer_actions_reply_from_a).on('click', function() {
542                    self.highlightComment(comment.reply_from.getId(), true);
543
544                    return false;
545                });
546
547                $(comment_data_footer_actions_reply_from).append('Em resposta a ');
548                $(comment_data_footer_actions_reply_from).append(comment_data_footer_actions_reply_from_a);
549
550                $(comment_data_footer_actions).append(comment_data_footer_actions_reply_from);
551            }
552
553            $(comment_data_footer_actions_answer_icon).addClass('fa fa-reply me-2');
554            $(comment_data_footer_actions_report_icon).addClass('fa fa-flag me-2');
555            $(comment_data_footer_actions_delete_icon).addClass('fa fa-tras
555h-alt me-2');
556
557            $(comment_data_footer_actions_answer).attr('href', '#');
558            $(comment_data_footer_actions_report).attr('href', '#');
559            $(comment_data_footer_actions_delete).attr('href', '#');
560
561            $(comment_data_footer_actions_answer).append(comment_data_footer_actions_answer_icon).append('Responder');
562            $(comment_data_footer_actions_report).append(comment_data_footer_actions_report_icon).append('Denunciar');
563            $(comment_data_footer_actions_delete).append(comment_data_footer_actions_delete_icon).append('Apagar');
564
565            $(comment_data_footer_actions_answer).on('click', function() {
566                if (!comment.getAnswerStatus()) {
567                    if (confirm('Este recurso está disponível apenas para Assinantes!\nAssine agora para responder este comentário com benefícios exclusivos!\n\nDesejar ver nossos planos agora?')) {
568                        location.href = setting.site_url + '/assine/';
569                    }
570
571                    return false;
572                }
573
574                let main_comment = comment.getMainComment();
575
576                if ($(main_comment.e).find(".post_reply .reply_form [name = 'reply_from_id']").val() != comment.getId()) {
577                    if ($(main_comment.e).find('.post_reply .reply_form textarea').val().length > 0) {
578                        if (!confirm('Você começou a escrever uma resposta para outro comentário desta conversa. Se prosseguir, seu texto será perdido.\n\nDeseja continuar?')) {
579                            return false;
580                        }
581                    }
582                } else {
583                    $(main_comment.e).find('.post_reply .reply_form textarea')[0].focus();
584
585                    return false;
586                }
587
588                $(main_comment.e).find(".post_reply .reply_form [name = 'reply_from_id']").val(comment.getId());
589                $(main_comment.e).find(".post_reply .reply_form [name = 'main_comment_id']").val(comment.getMainComment().getId());
590
591                $(main_comment.e).addClass('reply');
592                $(main_comment.e).find('.post_reply .reply_to').empty();
593
594                if (comment.getId() != main_comment.getId()) {
595                    var answer_to_a = document.createElement('a');
596
597                    $(answer_to_a).attr('href', '#');
598
599                    $(answer_to_a).on('click', function() {
600                        self.highlightComment(comment.getId(), true);
601
602                        return false;
603                    });
604
605                    $(answer_to_a).text(comment.author.fullname);
606
607                    $(main_comment.e).find('.post_reply .reply_to').append('Em resposta a ').append(answer_to_a);
608                }
609
610                $(main_comment.e).find('.post_reply .reply_form textarea').val('');
611                $(main_comment.e).find('.post_reply .reply_form textarea')[0].focus();
612
613                return false;
614            });
615
616            $(comment_data_footer_actions_delete).on('click', function() {
617                if (confirm('Tem certeza que desejar apagar o seu comentário?')) {
618                    self.clearComments();
619                    self.showLoading();
620
621                    $.ajax({
622                        dataType: 'json',
623                        method: 'POST',
624                        url: setting.site_url + '/system/lib/delete_comment.php',
625                        data: {
626                            id: comment.getId()
627                        },
628                        context: self,
629                        success: function(data) {
630                            if (data.status == 'success') {
631                                alert('Seu comentário foi deletado!');
632                            } else {
633                                alert(data.error);
634                            }
635                        },
636                        error: function(e) {
637                            alert('(' + e.status + ') Algo deu errado ao tentar deletar seu comentário. Por favor, tente novamente.');
638                        },
639                        complete: function() {
640                            self.loadComments();
641                        }
642                    });
643                }
644
645                return false;
646            });
647
648            $(comment_data_footer_actions).append(comment_data_footer_actions_answer);
649            // $(comment_data_footer_actions).append(comment_data_footer_actions_report);
650
651            if (comment.getDeleteStatus()) {
652                $(comment_data_footer_actions).append(comment_data_footer_actions_delete);
653            }
654
655            $.each(comment.getReplies(), function(k, reply) {
656                $(comment_data_footer_replies_list).append(reply.getElement());
657            });
658
659            $(comment_data_footer_replies_post_reply_reply_to).append(comment_data_footer_replies_post_reply_reply_to_label);
660
661            $(comment_data_footer_replies_post_reply_reply_form_button).append(comment_data_footer_replies_post_reply_reply_form_button_i);
662
663            $(comment_data_footer_replies_post_reply_reply_form).append(comment_data_footer_replies_post_reply_reply_form_textarea);
664            $(comment_data_footer_replies_post_reply_reply_form).append(comment_data_footer_replies_post_reply_reply_form_button);
665            $(comment_data_footer_replies_post_reply_reply_form).append(comment_data_footer_replies_post_reply_reply_form_from_id);
666            $(comment_data_footer_replies_post_reply_reply_form).append(comment_data_footer_replies_post_reply_reply_form_main_id);
667
668            $(comment_data_footer_replies_post_reply_reply_form).on('submit', function() {
669                let main_comment = comment.getMainComment();
670
671                var form = this;
672                var form_data = Object.assign(Object.fromEntries(new FormData(form)), {
673                    page: main_comment.getPage(),
674                    referrer_type: main_comment.getReferrerType(),
675                    referrer_id: main_comment.getReferrerId()
676                });
677
678                $(this).find('textarea, button').prop('disabled', true);
679
680                $.ajax({
681                    dataType: 'json',
682                    method: 'POST',
683                    url: setting.site_url + '/system/lib/post_comment.php',
684                    data: form_data,
685                    context: self,
686                    success: function(data) {
687                        if (data.status == 'success') {
688                            var reply = this.commentFactory();
689
690                            reply.setId(data.comment.id);
691                            reply.setPage(comment.getPage());
692                            reply.setReferrerType(comment.getReferrerType());
693                            reply.setReferrerId(comment.getReferrerId());
694                            reply.setParentElement(comment.getParentElement());
695                            reply.setAnswerStatus(data.comment.answer_status);
696                            reply.setDeleteStatus(data.comment.delete_status);
697                            reply.setMainComment(comment.getMainComment());
698                            reply.setReplyFrom(this.getCommentById(data.comment.reply_from_id));
699                            reply.setPostDate(data.comment.date.elapsed_short);
700                            reply.setAuthor(data.comment.customer.shortname, (data.comment.customer.file_01 && data.comment.customer.file_01.length > 0 ? setting.site_url + '/midia/customers/' + data.comment.customer.file_01 : setting.site_url + '/images/i/user.svg'));
701                            reply.setMessage(data.comment.message);
702
703                            comment.addReply(reply);
704                            comment.rebuildElement();
705
706                            setTimeout(function() {
707                                self.highlightComment(reply.getId());
708                            }, 500);
709
710                            this.comments_built.push(reply);
711
712                            $(form)[0].reset();
713                        } else {
714                            alert(data.error);
715                        }
716                    },
717                    error: function(e) {
718                        alert('(' + e.status + ') Algo deu errado ao tentar publicar seu comentário. Por favor, tente novamente.');
719                    },
720                    complete: function() {
721                        $(form).find('textarea, button').prop('disabled', false);
722                    }
723                });
724
725                return false;
726            });
727
728            $(comment_data_footer_replies_post_reply).append(comment_data_footer_replies_post_reply_reply_to);
729            $(comment_data_footer_replies_post_reply).append(comment_data_footer_replies_post_reply_reply_form);
730
731            $(comment_data_footer_replies).append(comment_data_footer_replies_list);
732            $(comment_data_footer_replies).append(comment_data_footer_replies_post_reply);
733
734            $(comment_data_footer).append(comment_data_footer_actions);
735
736            if (comment.getId() == comment.getMainComment().getId()) {
737                $(comment_data_footer).append(comment_data_footer_replies);
738            }
739
740            $(comment_data).addClass('comment_data');
741            $(comment_data).append(comment_data_header);
742            $(comment_data).append(comment_data_body);
743            $(comment_data).append(comment_data_footer);
744
745            $(element_container).addClass('comment_container');
746            $(element_container).append(author_picture);
747            $(element_container).append(comment_data);
748
749            $(element).attr('data-comment-id', comment.getId());
750            $(element).addClass('comment');
751            $(element).append(element_container);
752
753            comment.e = element;
754
755            return comment.e;
756        }
757
758        return comment;
759    }
760
761}

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.