PageSourceSearch

https://tartanink.com/assets/js/jquery.tg.js?v=1791437181

js tartanink.com collected 2026-10-08 05:26:25 UTC 61,909 bytes, 1,970 lines download raw bytes

1/*
2	TaskGenius Plugin
3    File : jquery.tg.js
4	Author : Andrew Eldridge
5  	Version : 1.2
6	Date Created : 09/10/2017
7  	Last Updated : 23/07/2018
8*/
9
10(function($, window, document, undefined){
11	"use strict";
12    
13	var prod = true;
14    var version = "1.2";
15    
16    var timeoutWarning = 570000;
17    var timeoutNow = timeoutWarning + 30000;
18    
19    var warningTimer;
20    var timeoutTimer;
21    
22	var path = "/assets/includes/ajax/";
23	var defaults = {
24		form : $('#searchForm')
25	};
26	
27    var methods = {
28        init	:	function(options) {
29			options = $.extend({}, defaults, options );
30        },
31		load 	: 	function(type, options) {
32			options = $.extend({}, defaults, options );
33			type = typeof type !== 'undefined' ? type : 'tasks';
34			options.page = typeof options.page !== 'undefined' ? options.page : "1";
35			options.orderby = typeof options.orderby !== 'undefined' ? options.orderby : "";
36            var filters='';
37            var f='';
38            var url='';
39            var dataType = 'html';
40            filters = objectifyForm(options.form.serializeArray());
41			$.each(filters, function( index, value ) {
42			  f += '&'+index+'='+value;
43			});	
44			$.each(options, function( index, value ) {
45			  f += '&'+index+'='+value;
46			});
47			switch (type) {
48                case 'errors':
49                    options.siteid = typeof options.siteid !== 'undefined' ? options.siteid : "0";
50				    url = path+'ajax_requests.php?view=geterrors&accountid='+options.siteid;
51                    break;
52                case 'settings':
53                    options.tab = typeof options.tab !== 'undefined' ? options.tab : "locations";
54				    url = path+'ajax_'+options.tab+'.php?view=get'+options.tab+'&display='+options.tab+'_main';
55                    break;
56                case 'calendar':
57                    url = path+'ajax_tasks.php?view=gettasks&display=tasks_calendar_main';
58                    break;
59                default:
60                    url = path+'ajax_'+type+'.php?view=get'+type+f;
61                    break;
62            }
63            if(type==='reports') { dataType = 'json'; }
64            load(url, type, options, filters, dataType);
65		},
66		view 	: 	function(type, options) {
67            options.tab = typeof options.tab !== 'undefined' ? options.tab : "taskoverview";
68            var filters='';
69            var f='';
70            var url='';
71            var dataType = 'html';
72			$.each(options, function( index, value ) {
73			  f += '&'+index+'='+value;
74			});
75            if(type==='errors') {
76                url = path+'ajax_requests.php?view=view'+type+f;    
77            } else {
78                url = path+'ajax_'+type+'.php?view=view'+type+f;
79            }
80            view(url, type, options, filters, dataType);
81		},
82		add  	: 	function(type, options) {
83			options = $.extend({}, defaults, options );
84			options.task = typeof options.task !== 'undefined' ? options.task : "";
85            var url='';
86			url = path+'ajax_'+type+'.php?view=add'+type;
87			if(type==="tasks") {
88				switch(options.task){
89					case "reactive":
90						send(url+"&tasktype=reactive", fadeIn);
91						break;
92					
93					case "planned":
94						send(url+"&tasktype=planned", fadeIn);
95						break;
96						
97					default:
98						var buttons  = {
99							reactive: {
100							  text: "Reactive",
101							  value: "reactive",
102							},
103							planned: {
104							  text: "Planned",
105							  value: "planned",
106							}
107						};
108						alertBox(
109							"Choose a task type", 
110							"", 
111							buttons, 
112							function(value) {
113								switch (value) {
114									case "reactive":
115									  send(url+"&tasktype=reactive", fadeIn);
116									  break;
117
118									case "planned":
119									  send(url+"&tasktype=planned", fadeIn);
120									  break;
121								}
122							}
123						);	
124						break;
125				}
126			} else {
127				send(url, fadeIn);
128			}
129		},
130		edit 	: 	function(type, options) {
131            var f='';
132            var url='';
133			$.each(options, function( index, value ) {
134			  f += '&'+index+'='+value;
135			});
136			if(type === 'tasks') {
137				url = path+'ajax_'+type+'.php?view=edit'+type+f;
138			} else {
139				url = path+'ajax_'+type+'.php?view=view'+type+f;
140			}
141            switch(options.type) {
142                case 'onoff':
143                    send(url, function(result){
144                        fadeIn(result);
145                        setTimeout(function(){
146                            $('#editOption').val("oneoff");
147                            $('#recurring_line').hide();
148                            $('#oneoff_line').show();
149                        }, 400);
150                    });
151                    break;
152                case 'recurring':
153					alertBox(
154						"What do you want to edit?", 
155						"", 
156						["Just this occurrence", "All occurrences"], 
157						function(value) {
158							if (value) {
159								alertBox(
160									"Are you sure?",
161									"This will edit ALL occurances of this task",
162									["Go Back", "Continue"],
163									function(value){
164										if (value) {
165											send(url, function(result) {
166												fadeIn(result);
167												setTimeout(function() {
168													$('#editOption').val("all");
169													$('#recurring_line').show();
170													$('#oneoff_line').hide();
171													$('#publicLink').hide();
172												}, 400);
173											});
174										} 
175									}
176								)
177							} else {
178								send(url, function(result) {
179									fadeIn(result);
180									setTimeout(function() {
181										$('#editOption').val("single");
182										$('#recurring_line').hide();
183										$('#oneoff_line').hide();
184									}, 400);
185								});
186							}
187						}
188					);
189                    break;
190                default :
191                    send(url, fadeIn);
192                    break;
193            }
194		},
195        print 	: 	function(type, options) {
196			options = $.extend({}, defaults, options );
197			type = typeof type !== 'undefined' ? type : 'tasks';
198            
199            var filters='';
200            var f='';
201			var o='';
202            var url='';
203
204			filters = objectifyForm(options.form.serializeArray());
205			$.each(filters, function( index, value ) {
206			  f += '&'+index+'='+value;
207			});	
208			$.each(options, function( index, value ) {
209				if(index != 'form'){
210			         o += '&'+index+'='+value;
211				}
212            });
213			url = path+'ajax_print.php?view=print'+type;
214			
215			switch(type){
216				case 'now':
217					var limit = $('#print_limit').val();
218					url += '&print_format=full&print_limit='+limit+f;
219					printFrame(url);
220					break;
221				case 'single':
222					url += '&print_format=full'+f+o;
223					printFrame(url);
224					break;
225				case 'reports':
226					url += f+o;
227					if(options.report_type==='print'){
228						printFrame(url);
229					} else {
230						window.location = url;
231					}
232					break;
233				default :
234					url += f+o;
235					send(url, fadeIn);
236					break;
237			}
238			
239				
240			
241		},
242		delete 	: 	function(type, options) {
243            var f='';
244            var url='';
245            $.each(options, function( index, value ) {
246			  f += '&'+index+'='+value;
247			});
248            if(type==='subtasks') {
249                url = path+'ajax_requests.php?update=subtasks&type=deletesubtask'+f;			
250            } else if(type==="timesheets") {
251                if(options.tid > 0){
252					url = path+'ajax_requests.php?id='+options.id+'&tid='+options.tid+'&update='+type+'&type=delete'+type;
253				}
254            } else {
255                url = path+'ajax_'+type+'.php?view=update'+type+'&method=update&task=delete'+type+f;			
256            }
257			if(options.type==="recurring"){
258				alertBox(
259					"What do you want to delete?",
260					"Please select what you wish to delete.",
261					["Just this occurrence", "All occurrences"], 
262					function(value) {
263						if (value) {
264							alertBox(
265								"Are you sure?",
266								"This will delete ALL occurances of this task",
267								["Go Back", "Continue"],
268								function(value){
269									if (value) {
270										send(url+"&deleteall=Y", function(result) {
271											$.tg('load');
272										});
273									} 
274								}
275							)
276						} else {
277							alertBox(
278								"Are you sure?",
279								"Deleting this task will result in all related content being deleted as well",
280								["No, do not delete", "Yes, delete this task"],
281								function(value){
282									if (value) {
283										send(url, function(result) {
284											$.tg('load');
285										});
286									} 
287								}
288							)
289						}
290					}
291				);
292			} else {
293				alertBox(
294					"Are you sure?",
295					"You won't be able to revert this!",
296					true,
297					function(value) {
298						if (value) {
299							send(url, function(result){
300								if(type!=='tasks') {
301									if(type==='links') {
302										window.location.href = "/";
303									} else if (type==='subtasks') {
304										$.tg('view', 'tasks', {id : result.id, tab: 'taskdetails' });
305									} else if(type==='accounts') {
306                                        window.location.href = '/?siteid=0';
307                                    } else if(type==='timesheets') {
308                                        $.tg('view', 'tasks', {id : result.id, tab : 'tasktimesheet' }); 
309									} else {
310										$.tg('load', 'settings', { tab : type });
311									}
312								} else {
313									$.tg('load');	
314								}			
315							}, 'json');
316						}
317					}
318				);
319			}
320		},
321		recover : 	function(type, options) {
322            var f='';
323            var url='';
324            $.each(options, function( index, value ) {
325			  f += '&'+index+'='+value;
326			});
327			url = path+'ajax_'+type+'.php?view=update'+type+'&method=update&task=recover'+type+f;
328			send(url, function(){
329				$.tg('load');			
330			}, 'json');
331		},
332        reopen : 	function(type, options) {
333            var f='';
334            var url='';
335            $.each(options, function( index, value ) {
336			  f += '&'+index+'='+value;
337			});
338			url = path+'ajax_'+type+'.php?view=update'+type+'&method=update&task=reopen'+type+f;
339			send(url, function(){
340				$.tg('load');			
341			}, 'json');
342		},
343        notify : 	function(type, options) {
344            var f='';
345            var url='';
346            $.each(options, function( index, value ) {
347			  f += '&'+index+'='+value;
348			});
349			url = path+'ajax_'+type+'.php?view=update'+type+'&method=notify&task=notify'+type+f;
350            alertBox(
351                'Notify Users Of This Task?',
352                'Please Enter a custom message',
353                ['Cancel', 'Send Notification'],
354                function(value) {
355                    if (value) {
356                        url += "&customtext="+value;
357                        send(url, function(){
358                            swal("Notification Sent!", "", "success");
359                        }, 'json');
360                    }
361                },
362                'input'
363            )
364		},
365		update 	: 	function(type, options) {
366            var f='';
367            var url='';
368            var data='';
369            if(type==='status') {
370                $.each(options, function( index, value ) {
371                  f += '&'+index+'='+value;
372                }); 
373                if(options.tasktype==='errors') {
374                    url = path+'ajax_requests.php?view=updateerrors&method=update'+f;
375                } else {
376                    url = path+'ajax_tasks.php?view=updatetasks&method=update'+f;   
377                }
378                var displayText;
379                switch(options.task) {
380                    case 'markstarted':
381                        displayText = 'Started';
382                        break;
383                    case 'markcompleted':
384                        displayText = 'Completed';
385                        break;
386                    case 'marksignedoff':
387                        displayText = 'Signed Off';
388                        break;
389                    case 'markpublish':
390                        displayText = 'Published';
391                        break;
392                    case 'markresolved':
393                        displayText = 'Resolved';
394                        break;
395                }
396                if(options.task==="markhold") {
397                    alertBox(
398						"Put task on hold?",
399                        "Reason for putting task on hold:",
400                        true,
401						function(value){
402							if (value === null) {
403								return false;  
404							} else if (value === "") {
405								return false;
406							} else {
407								data = { reason : value };
408								send(url, function(result){
409									if(!result.error) {
410										$.tg('view', 'tasks', {id : result.id });
411									}
412								}, 'json', data);
413							}
414						},
415						{
416							element: "input",
417							attributes: {
418								placeholder: "e.g. Awaiting Parts",
419							},
420						}
421                	);
422                } else if(options.task==="removehold") {
423                    alertBox(
424						"Remove \"On Hold\" status?",
425                        "Are you sure you want to remove the \"On Hold\" status?",
426                        true,
427						function(value){
428							if (value) {
429								send(url, function(result){
430									if(!result.error) {
431										$.tg('view', 'tasks', {id : result.id });
432									}
433								}, 'json', data);
434							}
435						}
436                    );
437                } else if(options.task==="markresolved") {
438                    alertBox(
439						"Mark as "+displayText+"?",
440                        "Are you sure you want to mark this error as resolved?",
441                        true,
442						function(value) {
443							if (value) {
444								send(url, function(result){
445									if(!result.error) {
446										$.tg('load', 'errors');
447									}
448								}, 'json', data);
449							}
450						}
451                    );
452                } else if(options.task !== "markstarted") {
453                    alertBox(
454						"Mark as "+displayText+"?",
455                        "Are you sure you want to mark this task as "+displayText+"?",
456                        ["Cancel", "Yes"],
457						function(value){
458							if (value) {
459								send(url, function(result){
460									if(!result.error) {
461										$.tg('load');
462									}
463								}, 'json', data);
464							}
465						}
466                    );
467                } else {
468                    send(url, function(result){
469                        if(!result.error) {
470                            $.tg('view', 'tasks', {id : result.id });
471                        }
472                    }, 'json', data);
473                }
474            } else if(type==="timesheets") {
475				if(options.tid > 0){
476					var timefrom = $('#editTimeSheet'+options.tid+' #ts_timefrom').val();
477					var timeto = $('#editTimeSheet'+options.tid+' #ts_timeto').val();
478					var timenote = $('#editTimeSheet'+options.tid+' #ts_note').val().replace(/\n/g, "<br />");
479					
480					url = path+'ajax_requests.php';
481					var d = {
482						id : options.id,
483						tid : options.tid,
484						update : type, 
485						type : 'edit'+type,
486						tfrom : timefrom,
487						tto : timeto,
488						timenote : timenote
489					};
490					send(url, function(result){
491						$.tg('view', 'tasks', {id : result.id, tab : 'tasktimesheet' }); 
492					}, 'json', d, 'POST');
493					
494				} else {
495					var timefrom = $('#addtimesheet #ts_timefrom').val();
496					var timeto = $('#addtimesheet #ts_timeto').val();
497					var timenote = $('#addtimesheet #ts_note').val().replace(/\n/g, "<br />");
498                    url = path+'ajax_requests.php';
499					var d = {
500						id : options.id,
501						update : type, 
502						type : 'add'+type,
503						tfrom : timefrom,
504						tto : timeto,
505						timenote : timenote
506					};
507					send(url, function(result){
508						$.tg('view', 'tasks', {id : result.id, tab : 'tasktimesheet' }); 
509					}, 'json', d, 'POST');
510				}
511                
512            } else {
513                if(type==="errors") {
514                    url = path+'ajax_requests.php';
515                } else {
516                    url = path+'ajax_'+type+'.php';    
517                }
518                var form;
519                if($('#'+options.form).is(":visible")){
520                    form = options.form;
521                } else {
522                    form = options.form+'p';
523                }
524                var desc;
525                var sdesc;
526                var note;
527                if(type==='tasks') {
528                    desc = $('#'+form+' #taskdesc > .ql-editor').html();
529                    sdesc = $('#'+form+' #taskshortdesc > .ql-editor').html();
530                    note = $('#'+form+' #notecontent > .ql-editor').html();
531                    $('#'+form+' #task_desc').val(desc);
532                    $('#'+form+' #task_short_desc').val(sdesc);
533                    $('#'+form+' #note_content').val(note);
534                }
535                if(type==='errors') {
536                    desc = $('#'+options.form+' .ql-editor').html();
537                    $('#error_desc').val(desc);
538                }
539                if(options.draft) {
540                    $('#'+form+' #task_draft').val('Y');
541                } else {
542                    $('#'+form+' #task_draft').val('N');
543                }
544				if(type==="accounts") {
545					var d = $('#'+form).get(0);
546					data = new FormData(d);
547					send(url, function(result){
548						if(!result.error) {
549							window.location.href= '/accounts/';
550						} else {
551							$('#erroralert').html(result.message);
552							$('#erroralert').slideDown();
553							setTimeout(function() { $('#erroralert').slideUp(); }, 2000);
554						}
555					}, 'html', data, 'POST', false);
556				} else {
557                    var d = $('#'+form).get(0);
558					data = new FormData(d);
559					if(debugData($('#'+form).serializeArray())){
560                        $('.loading').fadeIn();
561						send(url, function(result){
562                            result = JSON.parse(result);
563							$('.loading').fadeOut();
564                            if(!result.error) {
565								if(type!=='tasks') {
566									if(type==='links') {
567										window.location.reload();
568									} else if(type==='errors') {
569										$('#error_title').val('');
570										$('#error_desc').val('');
571										$('#errordesc .ql-editor').html('');
572										$('#erroralert').slideDown();
573										setTimeout(function() { $('#erroralert').slideUp(); }, 2000);
574									} else {
575										$.tg('load', 'settings', { tab : type });
576									}
577								} else {
578									if(result.task==="addtasknote"){
579										$.tg('view', type, {id : result.id, tab : 'tasknotes' });
580									} else {
581										$.tg('view', type, {id : result.id });
582									}
583								}
584							} else {
585								$('#erroralert').html(result.message);
586								$('#erroralert').slideDown();
587								setTimeout(function() { $('#erroralert').slideUp(); }, 2000);
588							}
589						}, 'html', data, 'POST', false);  
590					}
591				}
592            }
593		},
594		star 	: 	function(type, options) {
595			options = $.extend({}, defaults, options );
596			type = typeof type !== 'undefined' ? type : 'tasks';
597            var url = path+'ajax_'+type+'.php?view=updatetasks&method=update&tasktype=notify&id='+options.id;
598			send(url, function(result){
599				if (result.id !== null){
600					$.tg('load', 'tasks');
601				} 
602			}, 'json');
603		},
604		next 	: 	function(type, options) {
605			options = $.extend({}, defaults, options );
606			type = typeof type !== 'undefined' ? type : 'tasks';
607			var filters = objectifyForm(options.form.serializeArray());
608			var f = '';
609			$.each(filters, function( index, value ) {
610			  f += '&'+index+'='+value;
611			});	
612			var url = path+'ajax_'+type+'.php?view=get'+type+f+'&direction=next&row='+options.row;
613			send(url, function(result){
614				if (result.id !== null){
615					$.tg('view', 'tasks', { id : result.id, row : result.row });
616				} 
617			}, 'json');
618		},
619		prev 	: 	function(type, options) {
620			options = $.extend({}, defaults, options );
621			type = typeof type !== 'undefined' ? type : 'tasks';
622			var filters = objectifyForm(options.form.serializeArray());
623			var f = '';
624			$.each(filters, function( index, value ) {
625			  f += '&'+index+'='+value;
626			});	
627			var url = path+'ajax_'+type+'.php?view=get'+type+f+'&direction=prev&row='+options.row;
628			send(url, function(result){
629				if (result.id !== null){
630					$.tg('view', 'tasks', { id : result.id, row : result.row });
631				} 
632			}, 'json');
633		},
634        close   :   function() {
635            fadeOut();
636        },
637        render  :   function(type, options) {
638            options = $.extend({}, defaults, options );
639			type = typeof type !== 'undefined' ? type : 'tasks';
640            options.method = typeof options.method !== 'undefined' ? options.method : "renderAdd";
641            options.method = options.method+type;
642            var fn = window[options.method];
643            if (typeof fn === "function") { fn(); }
644        },
645		alert   :	function(type, options) {
646			type = typeof type !== 'undefined' ? type : 'permission';
647			switch(type){
648				case "permission" :
649					alertBox(
650						"Access Restricted", 
651						"You Do Not Have The Permissions To View This Area!", 
652						false, 
653						false
654					);
655					break;
656				case "timesheets" :
657					alertBox(
658						"No Timesheets Submitted",
659                        "Are you sure you want to mark the task as complete?",
660                        true,
661						function(value){
662							if (value) {
663								/*
664								var url = path+'ajax_tasks.php?view=updatetasks&method=update&id='+options.id+'&taskype='+options.tasktype+'&task=markcompleted';
665								send(url, function(result){
666									if(!result.error) {
667										$.tg('load');
668									}
669								}, 'json', '');
670								*/
671								$.tg('update', 'status', { task : 'markcompleted', tasktype : options.task_type, id : options.id })
672							}
673						}
674					);
675					break;
676			}
677		},
678		backup  :   function(type, options) {
679			options.id = typeof options.id !== 'undefined' ? options.id : 0;
680			if(options.id > 0) {
681				window.location.href = "/assets/includes/scripts/backup.php?method=backup&type="+type+"&account="+options.id;
682			}
683		}
684    };
685	
686    $.tg = function(method) {
687        if ( methods[method] ) {
688            debug(method, arguments);
689            //resetTimers();
690            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
691        } else if ( typeof method === 'object' || ! method ) {
692            debug('init', arguments);
693            return methods.init.apply( this, arguments );
694        } else {
695            debug(method, arguments, false);
696        }    
697    };
698    
699    function load(url, type, options, filters, dataType){
700        $('[data-display="viewTask"]').modal('hide');
701		$('[data-display="editTask"]').modal('hide');
702		if(options.page > 1) {
703            $('.ajax-load').fadeIn();
704        }
705        send(url, function(result){
706            if(type!=='reports') {
707                if(options.page > 1) {
708                    //$('#load-more').remove();
709                    setTimeout(function(){
710                        var loaded = $(result).hide().fadeIn();
711                        $('[data-list="'+filters.taskpage+'"]').append(loaded); 
712                        $('.ajax-load').fadeOut();
713                    }, 500);                   
714                } else {
715                    if(type==='errors') {
716                        $('#errors').html(result); 
717                    } else if(type==='settings'){
718                        $('#'+options.tab+'_content').html(result);
719                    } else if(type==='calendar' || filters.taskpage == 'calendar'){
720                        loadCalendar(result);
721                    } else if(type==='accounts') {
722                        $('[data-list="'+type+'"]').html(result); 
723					} else {
724                        $('[data-list="'+filters.taskpage+'"]').html(result); 
725                    }
726                }
727                if(options.orderby!=="") {
728                    $( "#orderoptions a" ).each(function() {
729                      $(this).removeClass('active');
730                    });
731                    $('a[data-order="'+options.orderby+'"]').addClass('active');
732                }
733                $('#details').fadeOut();
734                $('#options').fadeOut();
735                setTimeout(function(){ $('#overview').fadeIn(); }, 800);
736                $('[data-toggle="tooltip"]').tooltip();
737            } else {
738				$('[data-list="'+filters.taskpage+'"]').html(result.html);
739				if(options.type === 'overview'){
740                	createChart(result.data);
741				}
742            }
743        }, dataType);
744    }
745    
746    function view(url, type, options, filters, dataType){
747        $('[data-display="editTask"]').modal('hide');
748		$('[data-display="viewTask"]').modal('hide');
749		var f='';
750        $.each(options, function( index, value ) {
751          f += '&'+index+'='+value;
752        });
753        if(type === 'tasks') {
754            send(url, function(result){
755				var modal = $('[data-display="viewTask"]');
756				var modalContent = $('[data-display="viewTask"] .modal-content');
757				modalContent.html(result);
758				var tab = options.tab;
759				$('a[href="#'+tab+'"]').tab('show');
760				$('[data-toggle="tooltip"]').tooltip();
761				var toolbarOptions = [
762					['bold', 'italic']
763				];
764				var quill = new Quill('.noteeditor',{
765					theme: 'snow',
766					modules: {
767						toolbar: toolbarOptions
768					}
769				});
770				$('#sub_task_add').click(function(e){
771					e.preventDefault();
772					if($('#sub_title').val()!=="") {
773						var u = path+"ajax_requests.php?update=subtasks&type=addsubtask&title="+encodeURIComponent($('#sub_title').val())+f;
774						send(u, function(result){ 
775							$.tg('view', 'tasks', {id : result.id, tab: 'taskdetails' });
776						}, 'json');
777					}
778				});
779				$('.todo-list > li input + label').click(function(e){
780					e.preventDefault();
781					var input = $(e.currentTarget.previousElementSibling);
782					var li = $(e.currentTarget.parentElement).parent();
783					var checked = input.attr('checked');        
784					var id = li.attr('data-id');
785					if (typeof checked !== typeof undefined && checked !== false) {
786						input.removeAttr('checked');
787						li.removeClass('complete');
788						input.val('N');
789					} else {
790						input.attr('checked', 'checked');
791						li.addClass('complete');
792						input.val('Y');
793					} 
794					var u = path+"ajax_requests.php?update=subtasks&type=updatesubtask&id="+id+"&is_complete="+input.val();
795					send(u, returnBlank);
796				});
797				
798				$(".ts").flatpickr({
799					enableTime: true,
800					dateFormat: "d-m-Y H:i",
801					static:true
802				});
803				modal.unbind();
804				modal.on('shown.bs.modal', function() {
805					$(document).off('focusin.modal');
806					$( ".main-panel" ).scrollTop( 0 );
807				});
808				modal.on('hidden.bs.modal', function () {
809					$('[data-toggle="tooltip"]').tooltip('hide');
810					modalContent.html('');
811					
812					if(options.displayType === "calendar"){
813						$('[data-list=calendar]').fullCalendar('destroy');
814						$.tg('load', 'calendar');
815					} else {
816						$.tg('load');
817					}
818				});
819				modal.modal('show');
820            }, dataType);
821        } else {
822          send(url, fadeIn, dataType);
823        }        
824    }
825    
826    function send(url, callback, datatype, data, method, proccess) {
827		datatype = typeof datatype !== 'undefined' ? datatype : 'html';
828		data = typeof data !== 'undefined' ? data : '';
829        method = typeof method !== 'undefined' ? method : 'GET';
830		proccess = typeof proccess !== 'undefined' ? proccess : true;
831		var contentType;
832		if(proccess){
833			contentType = 'application/x-www-form-urlencoded; charset=UTF-8';
834		} else {
835			contentType = proccess;
836		}
837        $.ajax({
838            url: url,
839            method : method,
840			processData: proccess,
841			contentType: contentType,
842            dataType:datatype,
843            data: data,			
844            success:function(result){ 
845                callback(result);
846				contextMenuInit();
847            }
848        });	
849	}
850	
851    // CALLBACKS
852    
853    function fadeIn(result){
854		var modal = $('[data-display="editTask"]');
855		var modalContent = $('[data-display="editTask"] .modal-content');
856		modalContent.html(result);
857		
858		modal.on('hidden.bs.modal', function () {
859			modalContent.html('');
860		});
861		modal.on('shown.bs.modal', function() {
862			$(document).off('focusin.modal');
863			$( ".main-panel" ).scrollTop( 0 );
864		});
865		modal.modal('show');
866	}
867	
868    function fadeOut(){
869        if($('#details').hasClass("return")){
870            $('#details').removeClass('return');
871            $('#options').fadeOut();
872            setTimeout(function(){ $('#details').fadeIn(); }, 800);
873        } else {
874            $('#overview').removeClass('return');
875            $('#options').fadeOut();
876            setTimeout(function(){ $('#overview').fadeIn(); }, 800);		
877        }
878        setTimeout(function() { $('#options').html(''); }, 800);
879    }
880    
881	function returnBlank(){
882        return true;
883    }
884
885    // FUNCTIONS
886    
887	function alertBox(title, text, buttons, callback, content){
888		swal({
889			title : title,
890			text : text,
891			buttons: buttons,
892			content : content,
893			//html : true
894		})
895		.then(function(value){
896		  if(callback){ callback(value) };
897		});
898	}
899	
900    function objectifyForm(formArray) {
901  		var returnArray = {};
902  		for (var i = 0; i < formArray.length; i++){
903    		returnArray[formArray[i].name] = formArray[i].value;
904  		}
905  		return returnArray;
906	}
907    
908    function contextMenuInit() {
909		
910		var swidth = $('#sidebar').width();
911		var nheight = $('.navbar.default-layout-navbar').height();
912		
913        /*
914		$('body').contextmenu(function(){
915            return false;
916        });
917		*/
918		
919        /* Locations */
920		$("#locations_content .nav-tabs.tabs-left li").contextmenu(function(e) {
921            var id = $(e.target).attr('data-id');
922            $('#contextMenu').html('<div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;"><a class="dropdown-item" href="#" onClick="$.tg(\'view\', \'locations\', { id : '+id+' }); return false;">Edit</a></div>');
923            $("#contextMenu").css({
924                display: "block",
925                left: e.pageX - swidth,
926                top: e.pageY - nheight
927            });
928            return false;
929        });
930		
931        /* Quick Links */
932		
933        $(".qlink").contextmenu(function(e) {
934            var id = $(e.currentTarget).attr('data-id');
935            $('#contextMenu').html('<div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;"><a href="#" class="dropdown-item" onClick="$.tg(\'view\', \'links\', { id : '+id+' }); return false;">Edit</a><a href="#" class="dropdown-item" onClick="$.tg(\'delete\', \'links\', { tasktype : \'link\', id : '+id+' }); return false;">Delete</a></div>');
936            $("#contextMenu").css({
937                display: "block",
938                left: e.pageX - swidth,
939                top: e.pageY - nheight
940            });
941            return false;
942        });
943		
944		
945        /* Sub Tasks */
946        $(".todo-list > li").contextmenu(function(e) {
947           var id = $(e.currentTarget).attr('data-id');
948            $('#contextMenu').html('<div class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;"><a href="#" class="dropdown-item" onClick="$.tg(\'delete\', \'subtasks\', { id : '+id+' }); return false;">Delete</a></div>');
949			
950            $("#contextMenu").css({
951                display: "block",
952                left: e.pageX - swidth,
953                top: e.pageY - nheight
954            });
955        });
956
957    }
958	
959    function loadCalendar(tasks){
960        if ( $('[data-list=calendar]').children().length > 0 ) {
961            $('[data-list=calendar]').fullCalendar('destroy');
962        }
963        $('[data-list=calendar]').fullCalendar({
964			themeSystem: 'bootstrap4',
965            defaultView: 'list',
966            firstDay : 1,
967            contentHeight: ($(window).height() - 346),
968            displayEventTime : false,
969            events: JSON.parse(tasks),
970            eventOrder : 'start',
971            eventClick : function(task) {
972                $.tg('view', 'tasks', { id : task.taskid, displayType : 'calendar' });
973            },
974            eventRender: function(event, element) {
975                var extra;
976                if(event.overdue) {
977                    extra = "<td class=\"fc-list-item-title fc-widget-content text-right\" style=\"color:#e74c3c;vertical-align:middle !important;font-size:12px;font-weight:bold;\">OVERDUE</td>";
978                } else {
979                    extra = "<td class=\"fc-list-item-title fc-widget-content text-right\" style=\"color:red;vertical-align:middle !important;\"></td>";
980                }
981                element.html("<td class=\"fc-list-item-marker fc-widget-content\"><span class=\"fc-event-dot\" style=\"background-color : "+event.color+"\"></span></td><td class=\"fc-list-item-title fc-widget-content\"><a style=\"font-size : 16px; font-weight:bold;\">"+event.title+"<br/><span style=\"font-size:12px; font-weight:normal;\">"+event.tasktype+"</span></a></td>"+extra);
982            }
983        });
984    }
985    
986    function printIt() {
987       
988		var pdf = new jsPDF('p', 'pt', 'a4');
989		pdf.html(document.getElementById('printFrame').contentWindow.document.getElementById('printBox'), {
990			html2canvas : {
991				scale : 0.72,
992			},
993			callback: function (pdf) {	
994				pdf.save( moment().format('DMY')+".pdf");
995				$('#printFrame').remove();
996			},
997			
998		});
999		
1000    }
1001	
1002	function printFrame(url) {
1003		if($('#printFrame').length) {
1004			$('#printFrame').load(url);
1005		} else {
1006			$('<iframe>', {
1007			   src: url,
1008			   id:  'printFrame',
1009			   frameborder: 0,
1010			   scrolling: 'no',
1011				height:0,
1012				width:0
1013			   }).css(
1014				{
1015					"position" : 'absolute',
1016					'top' : 0,
1017					'left' : 0,
1018					'width':'100%',
1019					'height' : '100vh',
1020					'z-index' : '-1'
1021				}
1022			).on('load', function(){
1023				printIt();
1024			}).appendTo('body');
1025		}
1026	}
1027    
1028    function createChart(data) {
1029        Chart.helpers.each(Chart.instances, function(instance){
1030            instance.chart.destroy();
1031        });
1032        var chart = document.getElementById("breakdown");
1033        var myChart = new Chart(chart, {
1034            type: 'doughnut', 
1035            data: { 
1036                datasets: [{ 
1037                    data: [ data.open, data.started, data.hold, data.completed, data.signedoff ], 
1038                    backgroundColor: [                    
1039                        "#a1a1a1",
1040                        "#03a9f4",
1041                        "#E74C3C",
1042                        "#29c75f",
1043                        "#7962b3",
1044                    ]
1045                }],
1046                labels: [ 
1047                    "Open Tasks", 
1048                    "Started Tasks", 
1049                    "On Hold Tasks", 
1050                    "Completed Tasks", 
1051                    "Signed Off Tasks"
1052                ] 
1053            }, 
1054            options: { 
1055                title: { 
1056                    display: true, 
1057                    text: 'Breakdown of '+data.total+' Tasks',
1058                    fontSize: '16'
1059                }, 
1060                legend: {
1061                    position:'right'
1062                },
1063                rotation: 1 * Math.PI, circumference: 1 * Math.PI 
1064            } 
1065        });
1066    }
1067    
1068    // LOGOUT TIMERS
1069
1070    function resetTimers() {
1071        if($('#logoutdialogue').length){
1072            clearTimeout(warningTimer);
1073            clearTimeout(timeoutTimer);
1074            warningTimer = setTimeout(function(){
1075                idleWarning();
1076            }, timeoutWarning);
1077            timeoutTimer = setTimeout(function(){
1078                idleTimeout();
1079            }, timeoutNow);
1080        }
1081    }
1082    
1083    function idleWarning() {
1084		var timeleft = 30;
1085		var el = document.createElement("div");
1086		var text = document.createTextNode("You will be automatically logged out in ");
1087		var counter = document.createElement("span");
1088		var timecount = document.createTextNode(timeleft+" seconds");
1089		counter.setAttribute("id", "timeleft");
1090		el.appendChild(text);
1091		counter.appendChild(timecount);
1092		el.appendChild(counter);
1093		alertBox(
1094			"Session About To Timeout",
1095			"",
1096			{
1097				cancel: "Continue Working",
1098				confirm: "Logout Now"
1099			},
1100			function(value){
1101				if(value){
1102					window.location.href="/logout/";
1103				} else {
1104					window.location.href="";
1105				}
1106			},
1107			el
1108		);
1109		setInterval(function(){
1110            timeleft = timeleft - 1;
1111            $('#timeleft').html(timeleft+ " seconds");
1112        }, 1000);
1113	}
1114	
1115    function idleTimeout() {
1116        window.location.href = '/logout/';
1117    }
1118    
1119    // DEBUG
1120    
1121    function debug(method, args, valid) {
1122        valid = typeof valid !== 'undefined' ? valid : true;
1123        if(!valid) {
1124            $.error( 'Call to undefined method ' +  method );
1125        } else {
1126            switch(method){
1127                case 'init' :
1128                    console.log("TG PLUGIN V."+version+" INITIALIZED");
1129                break;
1130                default :
1131                    if(!prod){
1132                        var a = [];
1133                        $.each(args, function( index, value ) {
1134                            if(typeof value === 'object') {
1135                                var s = [];
1136                                $.each(value, function( i, v ) {
1137                                    s.push(i+" : "+v);
1138                                });
1139                                var st = "{"+s.toString()+"}";
1140                                a.push(st);
1141                            } else {
1142                                a.push(value);
1143                            }
1144                        });
1145                        console.log("$.tg() method \""+method+"\" was called with arguments \""+a.toString()+"\"");
1146                    }
1147                break;
1148            }
1149        }
1150	}
1151    function debugData(data) {
1152       if(!prod){
1153            console.log(data);
1154            return false;
1155        } else {
1156            return true;
1157        }
1158    }
1159    
1160	$.tg();
1161
1162})(jQuery, window, document);
1163
1164/*
1165	TaskGenius Included Functions
1166	Date Created : 09/10/2017
1167  	Last Updated : 23/07/2018
1168*/
1169
1170var timeout;
1171
1172function changeTab(tab) {	
1173	"use strict";
1174	var name = $(tab).data('tab');
1175	$('.tab_content').removeClass('active');
1176	$('.tab').removeClass('active');
1177    $('*[data-tab="'+name+'"]').addClass('active');
1178    $('#tab_'+name).addClass('active');
1179	if($(tab).data('tab') !== 'settings' && $(tab).data('tab') !== 'faqs' && $(tab).data('tab') !== 'errors' && $(tab).data('tab') !== 'whatsnew') {
1180		$.tg('load', 'settings', { tab : $(tab).data('tab') });
1181	}
1182}
1183function displayDaterange(type) {
1184    "use strict";
1185	if($('#'+type+'_sel').is(':checked')) { 
1186		$('#'+type+'selector').show();
1187	} else {
1188		$('#'+type+'selector').hide();	
1189	}
1190}
1191function modelMatcher (params, data) {
1192	"use strict";
1193    data.parentText = data.parentText || "";
1194    if ($.trim(params.term) === '') {
1195        return data;
1196    }
1197    if (data.children && data.children.length > 0) {
1198        var match = $.extend(true, {}, data);
1199        for (var c = data.children.length - 1; c >= 0; c--) {
1200            var child = data.children[c];
1201            child.parentText += data.parentText + " " + data.text;
1202            var matches = modelMatcher(params, child);
1203            if (matches === null) {
1204                match.children.splice(c, 1);
1205            }
1206        }
1207        if (match.children.length > 0) {
1208            return match;
1209        }
1210        return modelMatcher(params, match);
1211    }
1212    var original = (data.parentText + ' ' + data.text).toUpperCase();
1213    var term = params.term.toUpperCase();
1214    if (original.indexOf(term) > -1) {
1215        return data;
1216    }
1217    return null;
1218}
1219function formatResult(item) {
1220	"use strict";
1221    if(!item.id) {
1222        if(item.text==="Teams"){
1223            return $('<i class="fa fa-users"></i> <strong>' + item.text + '</strong>');
1224        } else if(item.text==="Users"){
1225            return $('<i class="fa fa-user"></i> <strong>' + item.text + '</strong>');
1226        } else {
1227            return $('<strong>' + item.text + '</strong>');
1228        }
1229    } else {
1230        var level = 0;
1231        if(item.element !== undefined){
1232            level = (item.element.className);
1233            if(level.trim() !== ''){
1234                level = (parseInt(level.match(/\d+/)[0]));
1235            }
1236        }
1237		var $icon = '';
1238        if(level > 0) {
1239            $icon = '<strong>-</strong>';
1240        } 
1241        var $result = $($icon+'<span style="padding-left:' + (20 * level) + 'px;">' + item.text + '</span>');
1242        return $result;	
1243    }
1244}
1245function changetasktype($type) {
1246	"use strict";
1247    if($type==='r') { $('#rtoptions').show(); $('#otoptions').hide();$(".select").select2({
1248        //dropdownParent: $("#options"),
1249        minimumResultsForSearch: -1,
1250        matcher: modelMatcher,
1251        templateResult: formatResult
1252    }); }
1253    if($type==='o') { $('#otoptions').show(); $('#rtoptions').hide();$(".select").select2({
1254        //dropdownParent: $("#options"),
1255        minimumResultsForSearch: -1,
1256        matcher: modelMatcher,
1257        templateResult: formatResult
1258    }); }
1259}
1260function changetaskduration($type) {
1261	"use strict";
1262    if($type==='forever') { $('#recursetdate').hide(); }
1263    if($type==='date') { $('#recursetdate').show();  }
1264}
1265function showpasswordbox($set) {
1266	"use strict";
1267    if($set === 'set') {
1268        $('#password_box').show(); 
1269    } else {
1270        $('#password_box').hide(); 	
1271    }
1272}
1273function checkPType() {
1274	"use strict";
1275    if($('#accesslevel3').is(':checked')||$('#accesslevel4').is(':checked')||$('#accesslevel0').is(':checked')) {
1276        $('#custom_access_row').hide();
1277    } else {
1278        $('#custom_access_row').show();
1279    }
1280    setTimeout(checkPType,500);
1281}
1282function changenotifytype($type) {
1283	"use strict";
1284    if($type==='u') { $('#notify_email_options').hide(); }
1285    if($type==='e') { $('#notify_email_options').show(); }
1286    if($type==='n') { $('#notify_email_options').hide(); }
1287}
1288function addTimeSheet(){
1289    "use strict";
1290    $('#timesheetbutton').toggle();
1291    $('#addtimesheet').toggle();
1292}
1293function editTimeSheet(tid){
1294    "use strict";
1295    $('#timeSheet'+tid).toggle();
1296	$('#editTimeSheet'+tid).toggle();
1297    
1298}
1299
1300function renderAddtasks(){
1301    "use strict";
1302    
1303    $(".dateentry").flatpickr({
1304        mode : "single",
1305        minDate : "today",
1306        dateFormat: "d-m-Y",
1307        defaultDate: "today"
1308    });
1309    
1310    /* CUSTOM PRIORITY TIMES */
1311    var time = $('#task_priority').find(':selected').attr('data-time');
1312    var tValue = $('#task_priority').find(':selected').attr('data-value');
1313    $('#task_due_date').val(moment().add(tValue, time).format("DD-MM-YYYY"));
1314    $('#task_priority').change(function(){
1315        time = $(this).find(':selected').attr('data-time');
1316        tValue = $(this).find(':selected').attr('data-value');
1317        var sdate = $('#task_date').val();
1318        var datearray = sdate.split("-");
1319        var newdate = datearray[2] + '-/' + datearray[1] + '-/' + datearray[0];
1320        $('#task_due_date').val(moment(newdate).add(tValue, time).format("DD-MM-YYYY"));
1321    });
1322    $('#task_date').change(function(){
1323        time = $('#task_priority').find(':selected').attr('data-time');
1324        tValue = $('#task_priority').find(':selected').attr('data-value');
1325        var sdate = $(this).val();
1326        var datearray = sdate.split("-");
1327        var newdate = datearray[2] + '-/' + datearray[1] + '-/' + datearray[0];
1328        $('#task_due_date').val(moment(newdate).add(tValue, time).format("DD-MM-YYYY"));
1329    });
1330    /* END */
1331    
1332    $(".select").select2({
1333        //dropdownParent: $("#options"),
1334        minimumResultsForSearch: -1,
1335        matcher: modelMatcher,
1336        templateResult: formatResult
1337    });
1338    $('a[data-toggle="pill"]').on('shown.bs.tab', function () {
1339        $(".select").select2({
1340            //dropdownParent: $("#options"),
1341            minimumResultsForSearch: -1,
1342            matcher: modelMatcher,
1343            templateResult: formatResult
1344        });
1345    });
1346    $('.desceditor').each(function(index) {
1347        var toolbarOptions = [
1348            ['bold', 'italic', 'underline', 'strike'],
1349            [{ 'list': 'ordered'}, { 'list': 'bullet' }],
1350            ['link'],
1351            ['code-block'],
1352            ['clean']
1353        ];
1354        var container = $('.desceditor').get(index);
1355        var quill = new Quill(container,{
1356            theme: 'snow',
1357            modules: {
1358                toolbar: toolbarOptions
1359            }
1360        });
1361    });    
1362}
1363function renderEdittasks(){
1364    "use strict";
1365    $(".dateentry").flatpickr({
1366        mode : "single",
1367        dateFormat: "d-m-Y",
1368    });
1369    var toolbarOptions = [
1370        ['bold', 'italic', 'underline', 'strike'],
1371        [{ 'list': 'ordered'}, { 'list': 'bullet' }],
1372        ['link'],
1373        ['code-block'],
1374        ['clean']
1375    ];
1376    var quill = new Quill('.desceditor',{
1377        theme: 'snow',
1378        modules: {
1379            toolbar: toolbarOptions
1380        }
1381    });
1382    
1383    $(".select").select2({
1384        //dropdownParent: $("#options"),
1385        minimumResultsForSearch: -1,
1386        matcher: modelMatcher,
1387        templateResult: formatResult
1388    });
1389}
1390function renderAddlocations() {
1391    "use strict";
1392    $(".select").select2({
1393        //dropdownParent: $("#options"),
1394        minimumResultsForSearch: -1,
1395		templateResult: formatResult
1396    });
1397	$('a[data-toggle="pill"]').on('shown.bs.tab', function () {
1398        $(".select").select2({
1399            //dropdownParent: $("#options"),
1400			minimumResultsForSearch: -1,
1401			matcher: modelMatcher,
1402			templateResult: formatResult
1403        });
1404    });
1405}
1406function renderEditlocations() {
1407    "use strict";
1408    $(".select").select2({
1409        //dropdownParent: $("#options"),
1410        minimumResultsForSearch: -1,
1411		templateResult: formatResult
1412    });
1413}
1414function renderAddpriorities() {
1415    "use strict";
1416    $(".select").select2({
1417        //dropdownParent: $("#options"),
1418        minimumResultsForSearch: -1,
1419    });
1420}
1421function renderEditpriorities() {
1422    "use strict";
1423    $(".select").select2({
1424        //dropdownParent: $("#options"),
1425        minimumResultsForSearch: -1,
1426    });
1427}
1428function renderAddteams() {
1429    "use strict";
1430    $(".select").select2({
1431        //dropdownParent: $("#options"),
1432        minimumResultsForSearch: -1,
1433    });
1434}
1435function renderEditteams() {
1436    "use strict";
1437    $(".select").select2({
1438        //dropdownParent: $("#options"),
1439        minimumResultsForSearch: -1,
1440    });
1441}
1442function renderAddlinks(){
1443    "use strict";    
1444    $(".select").select2({
1445        //dropdownParent: $("#options"),
1446        minimumResultsForSearch: -1,
1447        matcher: modelMatcher,
1448        templateResult: formatResult
1449    });    
1450}
1451function renderEditlinks(){
1452    "use strict";    
1453    $(".select").select2({
1454        //dropdownParent: $("#options"),
1455        minimumResultsForSearch: -1,
1456        matcher: modelMatcher,
1457        templateResult: formatResult
1458    });    
1459}
1460function renderAdderrors(){
1461    "use strict";    
1462    var toolbarOptions = [
1463        ['bold', 'italic']
1464    ];
1465	var quill = new Quill('.erroreditor',{
1466        theme: 'snow',
1467        modules: {
1468            toolbar: toolbarOptions
1469        }
1470    });
1471}
1472function renderprint(){
1473    "use strict";   
1474    
1475    $(".select").select2({
1476        //dropdownParent: $("#options"),
1477        minimumResultsForSearch: -1,
1478    });
1479}
1480function renderprofile(){
1481    "use strict";   
1482	$("#profilePassword").submit(function(e) {
1483		var form = $(this);
1484		var url = '/assets/includes/ajax/ajax_requests.php';
1485		$.ajax({
1486			type: "POST",
1487			url: url,
1488			data: form.serialize(),
1489			dataType : "JSON",
1490			success: function(result)
1491			{
1492				if(result.status){
1493					swal({
1494						title : 'Password changed',
1495						icon : 'success'
1496					});
1497				} else { 
1498					swal({
1499						title : 'Something went wrong',
1500						text : result.error,
1501						icon : 'error'
1502					});
1503				}
1504			}
1505		});
1506		e.preventDefault(); // avoid to execute the actual submit of the form.
1507	});
1508	
1509	$("#userPreferences").submit(function(e) {
1510		var form = $(this);
1511		var url = '/assets/includes/ajax/ajax_requests.php';
1512		$.ajax({
1513			type: "POST",
1514			url: url,
1515			data: form.serialize(),
1516			dataType : "JSON",
1517			success: function(result)
1518			{
1519				if(result.status){
1520					swal({
1521						title : 'Preferences Saved',
1522						icon : 'success'
1523					});
1524				}
1525			}
1526		});
1527		e.preventDefault(); // avoid to execute the actual submit of the form.
1528	});
1529	
1530}
1531
1532$(document).ready(function(){
1533	"use strict";
1534	// Keep Alive
1535	setInterval(function(){
1536		//console.log("KEEP ALIVE");
1537		$.post('/assets/includes/ajax/ajax_keepalive.php', { keepalive : true });
1538	}, 60000);
1539	
1540	$('[data-toggle="tooltip"]').tooltip();
1541    $('#tg_login_form').submit( function(event) {
1542        var form = this;
1543
1544        $(".loading").fadeIn();
1545
1546        event.preventDefault();
1547
1548        setTimeout( function () { 
1549            form.submit();
1550        }, 1500);
1551    });
1552    $('#search').autocomplete({
1553        paramName : 'keywords',
1554        serviceUrl: '/assets/includes/ajax/ajax_quicksearch.php',
1555        formatResult: function (suggestion, currentValue) {
1556            var reg = new RegExp(currentValue, 'gi');
1557            var final_str = suggestion.value.replace(reg, function(str) { return '<strong>'+str+'</strong>'; });		
1558            return final_str+"<br/><small><b>"+suggestion.data.typealt+"</b> | "+suggestion.data.date+"<span style='float:right;text-transform:capitalize;'>"+suggestion.data.status+"</span></small>";
1559        },
1560        minChars : 4,
1561        showNoSuggestionNotice : true,
1562        onSelect: function (suggestion) {
1563            $.tg('view', 'tasks', { id : suggestion.data.id });
1564            $('#search').val('');
1565        } 
1566    });
1567    $('.autocomplete-suggestions').scrollbar();
1568    $(".select2").select2({
1569        minimumResultsForSearch: -1
1570    });
1571    $(".input-daterange").flatpickr({
1572        mode: "range",
1573        dateFormat: "d-m-Y",
1574        defaultDate: [moment().startOf('month').format('DD-MM-YYYY'), "today"],
1575        onChange: function(selectedDates, dateStr, instance) {
1576            var input = $(instance._input).attr('data-range');
1577            $('#'+input+'from').val(moment(selectedDates[0]).format('DD-MM-YYYY'));
1578            $('#'+input+'to').val(moment(selectedDates[1]).format('DD-MM-YYYY'));
1579        }
1580    });
1581    $(".report-daterange").flatpickr({
1582        mode: "range",
1583        dateFormat: "d-m-Y",
1584        defaultDate: [moment().startOf('month').format('DD-MM-YYYY'), moment().endOf('month').format('DD-MM-YYYY')],
1585        onChange: function(selectedDates, dateStr, instance) {
1586            var input = $(instance._input).attr('data-range');
1587            $('#'+input+'from').val(moment(selectedDates[0]).format('DD-MM-YYYY'));
1588            $('#'+input+'to').val(moment(selectedDates[1]).format('DD-MM-YYYY'));
1589        }
1590    });
1591    $("#togglefilter").click( function(e){
1592        e.preventDefault();
1593        if ($('#filterbtn').hasClass("active") ) {
1594			$('#togglefilter').removeClass("active");
1595            $('#togglefilter').html('<i class="mdi mdi-filter d-block mb-1"></i>Filter');
1596            $('#filterbtn').slideUp();       
1597            $('#filterbtn').removeClass("active");
1598        } else {
1599            $('#filterbtn').slideDown();
1600            $('#togglefilter').html('<i class="mdi mdi-filter-remove d-block mb-1"></i>Close');
1601			$('#togglefilter').addClass("active");
1602            $('#filterbtn').addClass("active");
1603        }
1604        return false;
1605    });
1606    $('#searchForm').on('submit',function(e) {
1607        e.preventDefault();
1608		$('#togglefilter').removeClass("active");
1609		$('#togglefilter').html('<i class="mdi mdi-filter d-block mb-1"></i>Filter');
1610		$('#filterbtn').slideUp();       
1611		$('#filterbtn').removeClass("active");
1612        $.tg('load');
1613    });
1614    new CropAvatar($('#crop-avatar'));
1615    checkPType();
1616});
1617
1618/*
1619$('.main-content').on('scroll', function() {
1620    "use strict";
1621	var currPage = 1;
1622   	if($('#load-more').length) {
1623		if(parseInt($('#load-more').attr("data-page")) <= Math.ceil(parseInt($('#load-more').attr('data-total')) / 12)) {
1624			var sh = Math.ceil($('.main-content').scrollTop() + $('.main-content').height());
1625			var h = Math.ceil($('.main-content').prop('scrollHeight')-35);
1626			if(sh >= h) {
1627			   var pagenum = parseInt($('#load-more').attr("data-page"));
1628				var nextPage = pagenum + 1;
1629				if(currPage < nextPage){
1630					$.tg('load', 'tasks', { page: nextPage });
1631				}				
1632		   	}			
1633		}
1634	}
1635});	
1636*/
1637
1638$(document).click(function(){
1639	"use strict";
1640    $("#contextMenu").html('');
1641});
1642
1643function CropAvatar($element) {
1644	"use strict";
1645    this.$container = $element;
1646
1647    this.$avatarView = this.$container.find('.avatar-view');
1648    this.$avatar = this.$avatarView.find('img');
1649    this.$avatarModal = this.$container.find('#avatar-modal');
1650    this.$loading = this.$container.find('.loading');
1651
1652    this.$avatarForm = this.$avatarModal.find('.avatar-form');
1653    this.$avatarUpload = this.$avatarForm.find('.avatar-upload');
1654    this.$avatarSrc = this.$avatarForm.find('.avatar-src');
1655    this.$avatarData = this.$avatarForm.find('.avatar-data');
1656    this.$avatarInput = this.$avatarForm.find('.avatar-input');
1657    this.$avatarSave = this.$avatarForm.find('.avatar-save');
1658    this.$avatarBtns = this.$avatarForm.find('.avatar-btns');
1659
1660    this.$avatarWrapper = this.$avatarModal.find('.avatar-wrapper');
1661    this.$avatarPreview = this.$avatarModal.find('.avatar-preview');
1662
1663    this.init();
1664}
1665
1666CropAvatar.prototype = {
1667    constructor: CropAvatar,
1668
1669    support: {
1670      fileList: !!$('<input type="file">').prop('files'),
1671      blobURLs: !!window.URL && URL.createObjectURL,
1672      formData: !!window.FormData
1673    },
1674
1675    init: function () {
1676		"use strict";
1677      this.support.datauri = this.support.fileList && this.support.blobURLs;
1678
1679      if (!this.support.formData) {
1680        this.initIframe();
1681      }
1682
1683      this.initTooltip();
1684      this.initModal();
1685      this.addListener();
1686    },
1687
1688    addListener: function () {
1689		"use strict";
1690      this.$avatarView.on('click', $.proxy(this.click, this));
1691      this.$avatarInput.on('change', $.proxy(this.change, this));
1692      this.$avatarForm.on('submit', $.proxy(this.submit, this));
1693      this.$avatarBtns.on('click', $.proxy(this.rotate, this));
1694    },
1695
1696    initTooltip: function () {
1697		"use strict";
1698      this.$avatarView.tooltip({
1699        placement: 'bottom'
1700      });
1701    },
1702
1703    initModal: function () {
1704		"use strict";
1705      this.$avatarModal.modal({
1706        show: false
1707      });
1708    },
1709
1710    initPreview: function () {
1711		"use strict";
1712      var url = this.$avatar.attr('src');
1713
1714      this.$avatarPreview.html('<img src="' + url + '">');
1715    },
1716
1717    initIframe: function () {
1718		"use strict";
1719      var target = 'upload-iframe-' + (new Date()).getTime();
1720      var $iframe = $('<iframe>').attr({
1721            name: target,
1722            src: ''
1723          });
1724      var _this = this;
1725
1726      // Ready ifrmae
1727      $iframe.one('load', function () {
1728
1729        // respond response
1730        $iframe.on('load', function () {
1731          var data;
1732
1733          try {
1734            data = $(this).contents().find('body').text();
1735          } catch (e) {
1736            console.log(e.message);
1737          }
1738
1739          if (data) {
1740            try {
1741              data = $.parseJSON(data);
1742            } catch (e) {
1743              console.log(e.message);
1744            }
1745
1746            _this.submitDone(data);
1747          } else {
1748            _this.submitFail('Image upload failed!');
1749          }
1750
1751          _this.submitEnd();
1752
1753        });
1754      });
1755
1756      this.$iframe = $iframe;
1757      this.$avatarForm.attr('target', target).after($iframe.hide());
1758    },
1759
1760    click: function () {
1761		"use strict";
1762      this.$avatarModal.modal('show');
1763      this.initPreview();
1764    },
1765
1766    change: function () {
1767		"use strict";
1768      var files;
1769      var file;
1770
1771      if (this.support.datauri) {
1772        files = this.$avatarInput.prop('files');
1773
1774        if (files.length > 0) {
1775          file = files[0];
1776
1777          if (this.isImageFile(file)) {
1778            if (this.url) {
1779              URL.revokeObjectURL(this.url); // Revoke the old one
1780            }
1781
1782            this.url = URL.createObjectURL(file);
1783            this.startCropper();
1784          }
1785        }
1786      } else {
1787        file = this.$avatarInput.val();
1788
1789        if (this.isImageFile(file)) {
1790          this.syncUpload();
1791        }
1792      }
1793    },
1794
1795    submit: function () {
1796		"use strict";
1797      if (!this.$avatarSrc.val() && !this.$avatarInput.val()) {
1798        return false;
1799      }
1800
1801      if (this.support.formData) {
1802        this.ajaxUpload();
1803        return false;
1804      }
1805    },
1806
1807    rotate: function (e) {
1808		"use strict";
1809      var data;
1810
1811      if (this.active) {
1812        data = $(e.target).data();
1813
1814        if (data.method) {
1815          this.$img.cropper(data.method, data.option);
1816        }
1817      }
1818    },
1819
1820    isImageFile: function (file) {
1821		"use strict";
1822      if (file.type) {
1823        return /^image\/\w+$/.test(file.type);
1824      } else {
1825        return /\.(jpg|jpeg|png|gif)$/.test(file);
1826      }
1827    },
1828
1829    startCropper: function () {
1830		"use strict";
1831      var _this = this;
1832
1833      if (this.active) {
1834        this.$img.cropper('replace', this.url);
1835      } else {
1836        this.$img = $('<img src="' + this.url + '">');
1837        this.$avatarWrapper.empty().html(this.$img);
1838        this.$img.cropper({
1839          aspectRatio: 1,
1840          viewMode : 1,
1841          preview: this.$avatarPreview,
1842          crop: function (e) {
1843            var json = [
1844                  '{"x":' + e.x,
1845                  '"y":' + e.y,
1846                  '"height":' + e.height,
1847                  '"width":' + e.width,
1848                  '"rotate":' + e.rotate + '}'
1849                ].join();
1850
1851            _this.$avatarData.val(json);
1852          }
1853        });
1854
1855        this.active = true;
1856      }
1857
1858      this.$avatarModal.one('hidden.bs.modal', function () {
1859        _this.$avatarPreview.empty();
1860        _this.stopCropper();
1861      });
1862    },
1863
1864    stopCropper: function () {
1865		"use strict";
1866      if (this.active) {
1867        this.$img.cropper('destroy');
1868        this.$img.remove();
1869        this.active = false;
1870      }
1871    },
1872
1873    ajaxUpload: function () {
1874		"use strict";
1875      var url = this.$avatarForm.attr('action');
1876      var data = new FormData(this.$avatarForm[0]);
1877      var _this = this;
1878
1879      $.ajax(url, {
1880        type: 'post',
1881        data: data,
1882        dataType: 'json',
1883        processData: false,
1884        contentType: false,
1885
1886        beforeSend: function () {
1887          _this.submitStart();
1888        },
1889
1890        success: function (data) {
1891          _this.submitDone(data);
1892        },
1893
1894        error: function (XMLHttpRequest, textStatus, errorThrown) {
1895          _this.submitFail(textStatus || errorThrown);
1896        },
1897
1898        complete: function () {
1899          _this.submitEnd();
1900        }
1901      });
1902    },
1903
1904    syncUpload: function () {
1905		"use strict";
1906      this.$avatarSave.click();
1907    },
1908
1909    submitStart: function () {
1910		"use strict";
1911      this.$loading.fadeIn();
1912    },
1913
1914    submitDone: function (data) {
1915		"use strict";
1916      console.log(data);
1917
1918      if ($.isPlainObject(data) && data.state === 200) {
1919        if (data.result) {
1920          this.url = data.result;
1921
1922          if (this.support.datauri || this.uploaded) {
1923            this.uploaded = false;
1924            this.cropDone();
1925          } else {
1926            this.uploaded = true;
1927            this.$avatarSrc.val(this.url);
1928            this.startCropper();
1929          }
1930
1931          this.$avatarInput.val('');
1932        } else if (data.message) {
1933          this.alert(data.message);
1934        }
1935      } else {
1936        this.alert('Failed to response');
1937      }
1938    },
1939
1940    submitFail: function (msg) {
1941		"use strict";
1942      this.alert(msg);
1943    },
1944
1945    submitEnd: function () {
1946		"use strict";
1947      this.$loading.fadeOut();
1948    },
1949
1950    cropDone: function () {
1951		"use strict";
1952      this.$avatarForm.get(0).reset();
1953      this.$avatar.attr('src', this.url);
1954      this.stopCropper();
1955      this.$avatarModal.modal('hide');
1956        window.location.href="";
1957    },
1958
1959    alert: function (msg) {
1960		"use strict";
1961      var $alert = [
1962            '<div class="alert alert-danger avatar-alert alert-dismissable">',
1963              '<button type="button" class="close" data-dismiss="alert">&times;</button>',
1964              msg,
1965            '</div>'
1966          ].join('');
1967
1968      this.$avatarUpload.after($alert);
1969    }
1970};

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.