PageSourceSearch

https://chil.org/Scripts/App/listsManager.js

js chil.org collected 2026-10-03 17:35:26 UTC 25,148 bytes, 846 lines download raw bytes

1chil.LisstManager = function(){
2	var lang = chil.localization.getLang();
3	var dialogs = chil.dialogs;
4
5	var sections = {
6    	FOLLOWERS: 1,
7    	FOLLOWING: 2,
8    	LIST: 3,
9        EMAILFOLLOWERS: 4
10	}
11
12	var actorId = 0;
13
14	var $ulActorsContainer = $(".actors-list");
15	var $following = $(".following");
16	var $followers = $(".followers"); 
17	var $emailfollowers = $(".mail-followers");
18	var $listsContainer = $(".lists");
19	var currentSection = sections.FOLLOWERS;
20	var currentList = 0;
21	var $buttonSearch = $(".action-search");
22	var $textSearch = $(".search-text-box");
23	var $contentdownloadCSV = $(".address-options");
24	var $downloadCSV = $(".download-list");
25
26	var pageIndex = 0;
27	var loading = false;
28	var loadMore = true;
29
30	function onFollowersClick(ev) {
31	    $contentdownloadCSV.hide();
32	    $following.removeClass("selected");
33	    $emailfollowers.removeClass("selected");
34		$(".list-item").removeClass("selected");
35		$followers.addClass("selected");
36		$textSearch.val("");
37
38		pageIndex = 0;
39		loading = false;
40		loadMore = true;
41
42		currentSection = sections.FOLLOWERS;
43
44		chil.ui.showToast(lang.loadingPleaseWait);
45
46		$.ajax({
47			url: "/manage-followers-list/{0}".format(actorId),
48			success: function(response){
49				chil.ui.hideToast();
50
51				if (typeof(response) == 'string'){
52					$ulActorsContainer.html(response);
53				}
54			}
55		});
56
57		ev.preventDefault();
58	}
59
60	function onFollwingClick(ev) {
61	    $contentdownloadCSV.hide();
62	    $followers.removeClass("selected");
63	    $emailfollowers.removeClass("selected");
64		$(".list-item").removeClass("selected");
65		$following.addClass("selected");
66		$textSearch.val("");
67
68		pageIndex = 0;
69		loading = false;
70		loadMore = true;
71
72		currentSection = sections.FOLLOWING;
73		
74		chil.ui.showToast(lang.loadingPleaseWait);
75
76		$.ajax({
77			url: "/manage-following-list/{0}".format(actorId),
78			success: function(response){
79				chil.ui.hideToast();
80
81				if (typeof(response) == 'string'){
82					$ulActorsContainer.html(response);
83					setupMembersRows();
84				}
85			}
86		});
87		ev.preventDefault();
88	}
89
90	function onEmailFollowersClick(ev) {
91	    $contentdownloadCSV.show();
92	    $following.removeClass("selected");
93	    $followers.removeClass("selected");
94	    $(".list-item").removeClass("selected");
95	    $emailfollowers.addClass("selected");
96	    $textSearch.val("");
97
98	    pageIndex = 0;
99	    loading = false;
100	    loadMore = true;
101
102	    currentSection = sections.EMAILFOLLOWERS;
103
104	    chil.ui.showToast(lang.loadingPleaseWait);
105
106	    $.ajax({
107	        url: "/manage-email-followers/{0}".format(actorId),
108	        success: function (response) {
109	            chil.ui.hideToast();
110
111	            if (typeof (response) == 'string') {
112	                $ulActorsContainer.html(response);
113	            }
114	        }
115	    });
116
117	    ev.preventDefault();
118	}
119
120	function onDownloadCSVClick(ev) {
121	    //alert(actorId);
122	    var $href = "/export-csv/" + actorId;
123	    $downloadCSV.attr("href", $href);          
124	}
125
126	function onListClick(ev){
127		pageIndex = 0;
128		loading = false;
129		loadMore = true;
130
131		var $this = $(this);
132
133		var listId = $this.attr("data-id");
134
135		currentSection = sections.LIST;
136		currentList = listId;
137
138		$contentdownloadCSV.hide();
139		$emailfollowers.removeClass("selected");
140		$followers.removeClass("selected");
141		$following.removeClass("selected");
142		$(".list-item").removeClass("selected");
143		$this.addClass("selected");
144		$textSearch.val("");
145
146		chil.ui.showToast(lang.loadingPleaseWait);
147
148		$.ajax({
149			url: "/manage-list-members/{0}".format(listId),
150			success: function(response){
151				chil.ui.hideToast();
152
153				if (typeof(response) == 'string'){
154					$ulActorsContainer.html(response);
155					setupMembersRows();
156				}
157			}
158		});
159
160		ev.preventDefault();
161	}
162
163	function onAddListClick(ev){
164		var dialog = dialogs.ajaxFormDialog({
165			title: lang.newList,
166			popupClass: "namedesc-popup",
167			url: "/add-list/{0}".format(actorId),
168			ajaxForm: {
169				success: function(response){
170					dialog.success(response);
171					if (!response.error) {
172						var $li = $("<li></li>")
173							.addClass("list-item selected")
174							.attr("data-id", response.id)
175							.appendTo($listsContainer)
176							.on('click', onListClick);
177
178						var $a = $("<a></a>")
179							.attr("title", response.name)
180							.addClass('set-icon ch-contacts-icon ellipsis')
181							.html(response.name)
182							.appendTo($li);
183
184						$("<div></div>").addClass("img-option-file-off").appendTo($li).on("click", onListMenuClick);
185						var $menu = $("<ul>").addClass("list-optins-menu options-menu")
186							.appendTo($li)
187							.hover(function(){}, function(){
188								$(".list-optins-menu").hide();
189							});
190
191						$("<li></li>").addClass("edit-list").html(lang.edit).appendTo($menu).on("click", onEditListClick);
192						$("<li></li>").addClass("remove-list").html(lang.remove).appendTo($menu).on("click", onRemoveListClick);
193						$("<li></li>").addClass("invite-to-list").html(lang.sendInvitation).appendTo($menu).on("click", onInviteToListClick);
194						$("<li></li>").addClass("view-list-invitations").html(lang.viewInvitations).appendTo($menu).on("click", onViewInvitationsClick);
195						$("<li></li>").addClass("add-member-to-list").html(lang.addNewMember).appendTo($menu).on("click", onAddMemberToListClick);
196						$("<li></li>").addClass("add-email-to-list").html(lang.addEmail).appendTo($menu).on("click", onAddEmailToListClick);
197						$("<li></li>").addClass("send-email-to-list").html(lang.SendMail).appendTo($menu).on("click", onSendEmailToListClick);
198						$li.trigger("click");
199					}
200				}
201			},
202			error: function(e){
203				if (e.code == "list_exists")
204					$("label[for=name]", dialog.$form).html(lang.listExists).show();
205				dialog.showSubmit();
206			},
207			afterLoad: function(d){
208				setupListEditor(d.$form);
209			},
210		});
211	}
212
213	function setupMembersRows() {
214		chil.widgets.lists.setupMembersManagementView({
215			minMembers: 0,
216			addMember: function(memberId, callback){
217				if (currentSection == sections.FOLLOWING){
218					$.ajax({
219						type: "POST",
220						url: "/follow/actor/{0}".format(memberId),
221						data: {
222							actorId: actorId,
223							renderer: "actor"
224						},
225						success: function(response){
226							callback(response);
227						}
228					});
229				} else {
230					$.ajax({
231						type: "POST",
232						url: "/add-list-member/{0}/{1}".format(currentList, memberId),
233						data: {
234							renderer: "item"
235						},
236						success: function(response){
237							callback(response);
238						}
239					});
240				}
241			},
242			removeMember: function (memberId, callback) {
243				if (currentSection == sections.FOLLOWING){
244					$.ajax({
245						type: "POST",
246						url: "/unfollow/actor/{0}".format(memberId),
247						data: {
248							actorId: actorId
249						},
250						success: function(response){
251							callback(response);
252						}
253					});
254				} else if (currentSection == sections.LIST) {
255				    var typeMember = $(".ico-remove[data-id=" + memberId + "]").attr("data-type-member");
256				    var url = "";
257				    if (typeMember == "email")
258				        var url = "/remove-email-member-by-id/{0}".format(memberId);
259				    else
260				        //var url: "/set-manager-flag/{0}/{1}/{2}".format(currentList, memberId,1),
261                        var url = "/remove-list-member/{0}/{1}".format(currentList, memberId);
262
263					$.ajax({
264						type: "POST",
265						url: url,
266						success: function(response){
267							callback(response);
268						}
269					});
270				}
271			}
272		});
273
274		$(".role-list-selector").on("change", function(){
275			chil.ui.showToast("Changing Role...");
276			var id = $(this).attr("data-id");
277			var val = $(this).val();
278			$.ajax({
279				type: "POST",
280				url: "/update-member-role",
281				data: {
282					memberId: id,
283					role: val
284				},
285				success: function(){
286					chil.ui.hideToast();
287				}
288			})
289		})
290	}
291
292	function onListMenuClick(ev){
293		var $this = $(this);
294		var $menu = $(".list-optins-menu", $this.closest(".list-item")).toggle();
295		$(".list-optins-menu").not($menu).hide();
296		ev.stopPropagation();
297	}
298
299	function onEditListClick(ev){
300		$(".list-optins-menu").hide();
301
302		var $this = $(this);
303		var $list = $this.closest(".list-item");
304		var listId = $list.attr("data-id");
305
306		var dialog = dialogs.ajaxFormDialog({
307			title: lang.editList,
308			popupClass: "namedesc-popup",
309			url: "/edit-list/{0}".format(listId),
310			afterLoad: function(d){
311				setupListEditor(d.$form);
312			},
313			ajaxForm: {
314				success: function(response){
315					console.log(response);
316					dialog.success(response);
317					if (!response.error) {
318						$(".list-name", $list).html(response.name).attr("title", response.name);
319					}
320				}
321			},
322			error: function(e){
323				if (e.code == "list_exists")
324					$("label[for=name]", dialog.$form).html(lang.listExists).show();
325				dialog.showSubmit();
326			}
327		});
328
329		ev.stopPropagation();
330	}
331
332	function onRemoveListClick(ev){
333		$(".list-optins-menu").hide();
334		var $this = $(this);
335		var $list = $this.closest(".list-item");
336		var listId = $list.attr("data-id");
337
338		dialogs.confirmDialog({
339			message: lang.removeRoleWarning,
340			ok: function(){
341				$list.remove();
342
343				$.ajax({
344					type: "POST",
345					url: "/remove-list/{0}".format(listId)
346				});
347
348				$followers.trigger("click");
349			}
350		});
351
352		ev.stopPropagation();
353	}
354
355	function onInviteToListClick(ev){
356		var $this = $(this);
357		var id = $this.closest(".list-item").attr("data-id");
358		var $popup = null;
359
360		chil.ui.showVeil();
361		chil.ui.showLoading();
362
363		function updateInputValues(){
364			var tags = "";
365			$(".tags-list li", $popup).each(function(){
366	        	tags += $(this).attr("data-id") + ",";
367	        });
368	        $("input[name=actorsIds]", $popup).val(tags);
369		}
370
371		$.ajax({
372			url: "/list-invitation-popup/" + id,
373			success: function(response){
374				chil.ui.hideLoading();
375				$popup = $(response).popupDialog();
376
377				$(".actor-picker", $popup).actorsAutocomplete({
378					select: function(event, ui){
379						console.log(ui.item);
380
381						var $li = $("<li data-id={0}><span>{1}</span><a class='as-close'></a></li>".format(ui.item.id, ui.item.displayName))
382		        			.appendTo($(".tags-list", $popup));
383
384			        	$(".as-close", $li).bind("click", function(){
385			        		$(this).parent().remove();
386			        		updateInputValues();
387			        	});
388
389			        	updateInputValues();
390
391			        	this.value = "";
392			        	return false;
393					}
394				});
395
396				var $form = $("form", $popup);
397				$form.ajaxForm({
398					success: function(){
399						$popup.remove();
400						chil.ui.hideVeil();
401					}
402				});
403			}
404		});
405
406		ev.stopPropagation();
407	}
408
409	function setupListEditor($form){
410		$visibility = $("select[name=visibility]", $form).on("change", function(){
411			var val = $(this).val();
412			if (val == 2)
413				$("select[name=membershipType]", $form)
414					.attr("disabled", "disabled")
415					.val(2);
416			else
417				$("select[name=membershipType]", $form).removeAttr("disabled");
418		});
419	}
420
421	function onSearchClick(ev){
422		chil.ui.showToast(lang.searching);
423		switch(currentSection){
424			case sections.FOLLOWING:
425				alert("FOLLOWING NOT YET");
426				chil.ui.hideToast();
427				break;
428			case sections.FOLLOWERS:
429				alert("FOLLOWERS NOT YET");
430				chil.ui.hideToast();
431				break;
432			case sections.LIST:
433				$.ajax({
434					url: "/manage-list-members/{0}/search?query={1}".format(currentList, $textSearch.val()),
435					success: function(response){
436						chil.ui.hideToast();
437						if (typeof(response) == 'string'){
438							$ulActorsContainer.html(response);
439							setupMembersRows();
440						}
441					}
442				});
443
444				break;
445		}
446	}
447
448	function loadMoreListMembers(){
449		$.ajax({
450        	url: "/manage-list-members/{0}/page-{1}".format(currentList, ++pageIndex),
451        	success: function(response) {
452            	if (response){
453            		var $response = $(response);
454            		$ulActorsContainer.append($response);
455
456	            	chil.widgets.lists.setupNewItems($response, {
457	            		removeMember: function(memberId, callback){
458							$.ajax({
459							    type: "POST",
460							    //url: "/set-manager-flag/{0}/{1}/{2}".format(currentList, memberId,1),
461								url: "/remove-list-member/{0}/{1}".format(currentList, memberId),
462								success: function(response){
463									callback(response);
464								}
465							});
466						}
467	            	});
468            	}
469            	else
470            		loadMore = false;
471
472            	chil.ui.hideToast();
473            	loading = false;
474        	}
475    	});
476	}
477
478	function loadMoreEmailFollowers() {
479	    $.ajax({
480	        url: "/manage-email-followers/{0}/page-{1}".format(actorId, ++pageIndex),
481	        success: function (response) {
482	            if (response) {
483	                var $response = $(response);
484	                $ulActorsContainer.append($response);
485	                
486	            }
487	            else
488	                loadMore = false;
489
490	            chil.ui.hideToast();
491	            loading = false;
492	        }
493	    });
494	    chil.ui.hideToast();
495	}
496
497	function loadMoreFollowers(){
498		$.ajax({
499        	url: "/manage-followers-list/{0}/page-{1}".format(actorId, ++pageIndex),
500        	success: function(response) {
501            	if (response){
502            		var $response = $(response);
503            		$ulActorsContainer.append($response);
504
505	            	chil.widgets.lists.setupNewItems($response, {
506	            		removeMember: function(memberId, callback){
507							/*$.ajax({
508								type: "POST",
509								url: "/remove-list-member/{0}/{1}".format(currentList, memberId),
510								success: function(response){
511									callback(response);
512								}
513							});*/
514						}
515	            	});
516            	}
517            	else
518            		loadMore = false;
519
520            	chil.ui.hideToast();
521            	loading = false;
522        	}
523    	});
524	}
525
526	function loadMoreFollowing(){
527		$.ajax({
528        	url: "/manage-following-list/{0}/page-{1}".format(actorId, ++pageIndex),
529        	success: function(response) {
530            	if (response){
531            		var $response = $(response);
532            		$ulActorsContainer.append($response);
533
534	            	chil.widgets.lists.setupNewItems($response, {
535	            		removeMember: function(memberId, callback){
536							/*$.ajax({
537								type: "POST",
538								url: "/remove-list-member/{0}/{1}".format(currentList, memberId),
539								data: {
540									actorId: actorId
541								}
542								success: function(response){
543									callback(response);
544								}
545							});*/
546						}
547	            	});
548            	}
549            	else
550            		loadMore = false;
551
552            	chil.ui.hideToast();
553            	loading = false;
554        	}
555    	});
556	}
557
558	function setup(actor){
559		actorId = actor;
560
561		$followers.on('click', onFollowersClick);
562		$following.on('click', onFollwingClick);
563		$emailfollowers.on('click', onEmailFollowersClick);
564		$downloadCSV.on('click', onDownloadCSVClick);
565		$(".add-list").on('click', onAddListClick);
566		$(".img-option-file-off").on("click", onListMenuClick);
567		$(".list-optins-menu .edit-list").on("click", onEditListClick);
568		$(".list-optins-menu .remove-list").on("click", onRemoveListClick);
569		$(".list-optins-menu .invite-to-list").on("click", onInviteToListClick);
570		$(".list-optins-menu .view-list-invitations").on("click", onViewInvitationsClick);
571		$(".list-optins-menu .add-email-to-list").on("click", onAddEmailToListClick);
572		$(".list-optins-menu .add-member-to-list").on("click", onAddMemberToListClick);
573		$(".list-optins-menu .send-email-to-list").on("click", onSendEmailToListClick);
574
575		$buttonSearch.on("click", onSearchClick);
576
577		$textSearch.on("keypress", function(e){
578			var code = e.keyCode || e.which;
579			if (code == 13) {
580				$buttonSearch.trigger("click");
581			}
582		});
583
584		$(".list-item").on('click', onListClick);
585
586		if ($followers.hasClass("selected"))
587			currentSection = sections.FOLLOWERS;
588		else if ($following.hasClass("selected"))
589		    currentSection = sections.FOLLOWING;
590		else if ($emailfollowers.hasClass("selected"))
591		    currentSection = sections.EMAILFOLLOWERS;
592		else
593			currentSection = sections.LIST;
594
595		if (currentSection == sections.LIST){
596			currentList = $(".list-item.selected").attr("data-id");
597		}
598
599		//setup infinite scroll
600		$(".file-list").scroll(function(ev){
601			if (loading || !loadMore)
602		    	return;
603
604		    if ( $(".file-list").scrollTop() + $(".file-list").height() + 25 >= $ulActorsContainer.height() ) {
605		    	loading = true;
606		      	chil.ui.showToast(lang.loadingPleaseWait);
607
608		      	if (currentSection == sections.LIST)
609		      		loadMoreListMembers();
610		      	else if (currentSection == sections.FOLLOWERS)
611		      	    loadMoreFollowers();
612		      	else if (currentSection == sections.EMAILFOLLOWERS)
613		      	    loadMoreEmailFollowers();
614		      	else
615		      		loadMoreFollowing();
616		    }
617		});
618
619
620		$(".action-files-add").click(function(ev) {
621	    	$(".add-new-element-list").toggle();
622	    	ev.stopPropagation();
623		});
624
625		$(".add-new-element-list").hover(function(){}, function(){
626			$(this).hide();
627		});
628
629		$(document).on("click", function(ev){
630			$(".add-new-element-list").hide();
631			$(".list-optins-menu").hide();
632		});
633
634		$(".list-optins-menu").hover(function(){}, function(){
635			$(this).hide();
636		});
637
638		$(".list-item").hover(function(){}, function(){
639			$(".list-optins-menu").hide();
640		});
641
642		setupMembersRows();
643	}
644
645	function setupInvitationRows($rows){
646		$.each($rows, function(index, obj){
647			var $this = $(this);
648			$(".remove-invitation", $this).on("click", onRemoveInvitationClick)
649		})
650	}
651
652	function onRemoveInvitationClick(ev){
653		var $this = $(this);
654		var id = $this.attr("data-id");
655		$.ajax({
656			type: "POST",
657			url: "/remove-list-invitation/" + id
658		})
659		return false;
660	}
661
662	function onViewInvitationsClick(ev){
663		chil.ui.showVeil();
664		chil.ui.showLoading();
665
666		var $this = $(this);
667		var $list = $this.closest(".list-item");
668		var listId = $list.attr("data-id");
669
670		$.ajax({
671			url: "/list-invitations/" + listId,
672			success: function(response){
673				chil.ui.hideLoading();
674				var $popup = $(response).popupDialog();
675
676				setupInvitationRows($(".invitation-row", $popup))
677			}
678		})
679
680		return false;
681	}
682
683	function onSendEmailToListClick(ev) {
684
685	    //alert("aqui");
686	    var $this = $(this);
687	    var id = $this.closest(".list-item").attr("data-id");
688	    var $popup = null;
689
690	    chil.ui.showVeil();
691	    chil.ui.showLoading();           
692
693	    $.ajax({
694	        url: "/send-mail-popup/" + id,
695	        success: function (response) {
696	            chil.ui.hideLoading();
697	            $popup = $(response).popupDialog();
698	            var $editorHeight = 450;
699                
700	            var $form = $("form", $popup);	            
701	            $('textarea[name=body]', $popup).tinymce({
702	                script_url: "/scripts/libs/tinymce/tinymce.min.js",
703	                theme: "modern",
704	                relative_urls: false,
705	                plugins: "link,paste,images,videos,docs,textcolor,colorpicker,preview,pagebreak,tweet,image,table,code",
706	                image_advtab: true,
707	                menu: " ",
708	                toolbar1: "bold italic underline fontsizeselect | mybutton forecolor backcolor | bullist numlist | alignleft aligncenter alignright alignjustify | link unlink | pagebreak",
709	                toolbar2: "images videos docs tweet code table preview",
710	                statusbar: true,
711	                height: $(window).height() - $editorHeight,
712	                convert_urls: false,
713	                content_css: "/content/profile-custom-info-editor.css",
714	                actor_id: chil.identity.id,
715	                formats: {
716	                    underline: { inline: 'span', 'classes': 'underline' },
717	                    bold: { inline: 'span', 'classes': 'bold' },
718	                    italic: { inline: 'span', 'classes': 'italic' },
719	                    custom_format: { inline: 'span', 'classes': 'remarkable' }
720	                }	                
721	            });
722	            
723	            $form.ajaxForm({
724	                beforeSubmit: function () {
725	                    $(".button-submit", $form).hide();
726	                    $(".saving", $form).show();
727	                },
728	                success: function () {
729	                    $popup.remove();
730	                    chil.ui.hideVeil();
731	                }
732	            });
733	        }
734	    });
735
736	    ev.stopPropagation();
737	}
738
739	function onAddEmailToListClick(ev) {
740	    var $this = $(this);
741	    var $list = $this.closest(".list-item");
742	    var listId = $list.attr("data-id");
743
744	    $.ajax({
745	        url: "/popup-add-email/" + listId,
746	        success: function (response) {
747	            chil.ui.hideLoading();
748
749	            var $popup = chil.dialogs.popup({
750	                title: lang.addEmail,
751	                body: response
752	            });
753
754	            var $form = $("form", $popup);
755	            $form.ajaxForm({
756	                success: function (result) {
757	                    if (result.ok) {
758	                        var id = result.data.Id;
759	                        var name = result.data.Name;
760	                        var email = result.data.Email;
761
762	                        var $listEmails = $(".list-emails", $popup);
763	                        $("<li></li>").html(email).appendTo($listEmails);
764	                        $("input[name=email]", $popup).val("");
765	                        $("input[name=name]", $popup).val("");
766
767	                        //este html se corresponde con el partialView Views/ListManager/_EmailItem. Si se modifica ese partialView, hay que modificar este html tambien
768	                        var html = "<li><div>";
769	                        html += "<img class=\"thumb candidate-thumb\" src=\"/images/anonymous.jpg\" />";
770	                        html += "<div class=\"profile-info\">";
771	                        html += "<a href=\"#\" class=\"name-profile ellipsis\">" + name + "</a>";
772	                        html += "<p class=\"bio-profile ellipsis\">" + email + "</p>";
773	                        html += "</div>";
774	                        html += "<a class=\"ico-remove\" title=\"" + lang.remove + "\" data-id=\"" + id + "\" data-type-member=\"email\"></a>";
775	                        html += "</div></li>";
776
777	                        $ulActorsContainer.append($(html));
778	                        setupMembersRows();
779	                        chil.ui.toast(lang.yourEmailAddedToList);
780	                    }
781	                    else
782	                        chil.ui.toast(result.error.msg);
783	                }
784	            });
785	        }
786	    });
787	}
788
789	function onAddMemberToListClick(ev) {
790	    var $this = $(this);
791	    var $list = $this.closest(".list-item");
792	    var listId = $list.attr("data-id");
793
794	    $.ajax({
795	        url: "/popup-add-member/" + listId,
796	        success: function (response) {
797	            chil.ui.hideLoading();
798
799	            var $popup = chil.dialogs.popup({
800	                title: lang.addMember,
801	                body: response
802	            });
803
804	            var $listEmails = $(".list-emails", $popup);
805	            var $candidate = $("input[name=name]", $popup);
806
807	            $candidate.actorsAutocomplete({
808	                select: function (ev, ui) {
809	                    var name = ui.item.displayName;
810	                    var actorId = ui.item.id;
811	                    $candidate.val(name);
812	                    var $loading = $("<li></li>").addClass('loading-txt').css("float", "right").html(lang.loadingPleaseWait).appendTo($listEmails);
813
814	                    $.ajax({
815	                        type: "POST",
816	                        url: "/add-list-member/{0}/{1}".format(listId, actorId),
817	                        data: {
818	                            renderer: "item"
819	                        },
820	                        success: function (response) {
821	                            $loading.remove();
822
823	                            if (typeof (response) == "string") {
824	                                var $response = $(response);
825	                                $("<li></li>").html(name).appendTo($listEmails);
826	                                $ulActorsContainer.append($response);
827	                                setupMembersRows();
828
829	                            } else {
830	                                if (typeof (response) == "object" && response.error && response.error.msg)
831	                                    chil.ui.toast(response.error.msg);
832	                            }
833	                        }
834	                    });
835
836	                    return false;
837	                }
838	            });
839	        }
840	    });
841	}
842
843	return {
844		setup: setup
845	}
846}();

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.