PageSourceSearch

https://magdanza.com/wp-content/plugins/quick-timetable/assets/js/quick-timetable.js?ver=1.0

js magdanza.com collected 2026-09-27 05:58:19 UTC 39,678 bytes, 934 lines download raw bytes

1(function ($) {
2    'use strict';
3
4    // Url
5    var quick_timetable_home_url 	= $('.quick-timetable-home-url').html();
6	var quick_timetable_plugin_url 	= $('.quick-timetable-plugin-url').html();
7
8	// Global timetables variables
9	var quick_timetables 		= [];
10	var timetable_cats 			= [];
11	var multi_timetables 		= [];
12	var multi_timetables_arrs 	= [];
13	var sort_timetables			= [];
14
15	// Global time variables
16	var today 			= new Date();
17	var today_date_g 	= today.getDate();
18	var today_month_g 	= today.getMonth() + 1;
19	var today_year_g 	= today.getFullYear();
20
21	// Calculate time
22	function calculateTime(time) {
23		// return time;
24		var t = time.split(':');
25		return parseInt(t[0], 10) + (t[1] / 60);
26	}
27
28	// Sort timetables by time and id
29	function sortTimetables(a,b) {
30		if (a.start_time < b.start_time) {
31			return -1;
32		} else if (a.start_time > b.start_time) {
33			return 1;
34		} else {
35			if (a.id < b.id) {
36				return -1;
37			} else if (a.id > b.id) {
38				return 1;
39			} else {
40				return 0;
41			}
42		}
43	}
44
45	// Process timetables source
46	function processTimetablesSource() {
47		// Sort timetables by time
48		quick_timetables.sort(sortTimetables);
49
50		// Add id for timetable
51		for (var j = 0; j < quick_timetables.length; j++) {
52			quick_timetables[j].id = j + 1;
53		}
54
55		// Get timetable categories
56		for (var i = 0; i < quick_timetables.length; i++) {
57			var check = true;
58			for (var j = 0; j < timetable_cats.length; j++) {
59				if (timetable_cats[j] == quick_timetables[i].category) {
60					check = false;
61				}
62			}
63			if (check) {
64				if (quick_timetables[i].category) {
65					timetable_cats.push(quick_timetables[i].category);
66				}
67			}
68		}
69	} 
70
71	// Get axis time
72	function getAxisTime() {
73		var axis = [];
74
75		// Min time
76		for (var i = 0; i < quick_timetables.length; i++) {
77			if (quick_timetables[i].start_time) {
78				axis['min'] = parseInt(quick_timetables[i].start_time, 10);
79				break;
80			}
81		}
82		axis['min'] = (axis['min'] < 9) ? axis['min'] : 9; 
83
84		// Max time
85		for (var i = 0; i < sort_timetables.length; i++) {
86			for (var j = i + 1; j < sort_timetables.length; j++) {
87				if (sort_timetables[i].end_time < sort_timetables[j].end_time) {	
88					// Swap items
89					var tmp 			= sort_timetables[j];
90					sort_timetables[j] 	= sort_timetables[i];
91					sort_timetables[i] 	= tmp;
92				}
93			}
94		}
95
96		for (var i = sort_timetables.length-1; i >= 0; i--) {
97			if (sort_timetables[i].end_time) {
98				var time = sort_timetables[i].end_time.split(':');
99				if (time[1] == '00') {
100					axis['max'] = time[0] - 1;
101				} else {
102					axis['max'] = parseInt(time[0], 10);
103				}
104			}
105		}
106		axis['max'] = (axis['max'] > 24) ? axis['max'] : 24;
107
108		return axis;
109	}
110
111	// Get timetables
112	function getTimetables(timetables, mode, day, date, month, year) {
113		var _timetables = [];
114
115		for (var i = 0; i < timetables.length; i++) {
116			if (mode == 'day') {
117				if (timetables[i].day == day) {
118					_timetables.push(timetables[i]);
119				}
120			} else {
121				if ((timetables[i].date == date) && (timetables[i].month == month) && (timetables[i].year == year)) {
122					_timetables.push(timetables[i]);
123				}
124			}
125		}
126		
127		return _timetables;
128	}
129
130	function getTimetablesByCategory(category) {
131		var timetables = [];
132
133		for (var i = 0; i < quick_timetables.length; i++) {
134			if (quick_timetables[i].category) {
135				if ((quick_timetables[i].category.toLowerCase().replace(' ', '-') == category) || (category == 'all-category')) {
136					timetables.push(quick_timetables[i]);
137				}
138			} else {
139				if (category == 'all-category') {
140					timetables.push(quick_timetables[i]);
141				}
142			}
143		}
144
145		return timetables;
146	}
147
148	// Get day
149	function getDay(day, time, num) {
150		var date = new Date();
151		if (time == 'before') {
152			return new Date(date.setTime(day.getTime() - (num * 24 * 60 * 60 * 1000)));
153		} else {
154			return new Date(date.setTime(day.getTime() + (num * 24 * 60 * 60 * 1000)));
155		}
156	}
157
158	// Get postion of timetable on axis
159	function getTimetablePosition(min_time, start_time) {
160		return parseInt((calculateTime(start_time) - min_time) * 60, 10);
161	}
162
163	// Get height of timetable
164	function getTimetableHeight(start_time, end_time) {
165		return parseInt((calculateTime(end_time) - calculateTime(start_time)) * 60, 10);
166	}
167
168	// Group multi timetables on column
169	function groupMultiTimetables(timetable, timetables) {
170		var check_exist_group_multi = false;
171		var multi_key;
172		
173		for (var key in multi_timetables_arrs) {
174			if (multi_timetables_arrs[key].includes(timetable.id)) {
175				multi_key = key;
176				check_exist_group_multi = true;
177			}
178		}
179		
180		if (check_exist_group_multi) { // Already exist on group multi
181			multi_timetables_arrs[timetable.id] = multi_timetables_arrs[multi_key];
182		} else {
183			multi_timetables.push(timetable);
184			
185			for (var i = 0; i < timetables.length; i++) {
186				for (var j = 0; j < multi_timetables.length; j++) {
187					if 	(multi_timetables[j].id != timetables[i].id) {
188						if (((calculateTime(multi_timetables[j].start_time) >= calculateTime(timetables[i].start_time)) && (calculateTime(multi_timetables[j].start_time) < calculateTime(timetables[i].end_time)))
189							|| ((calculateTime(timetables[i].start_time) >= calculateTime(multi_timetables[j].start_time)) && (calculateTime(timetables[i].start_time) < calculateTime(multi_timetables[j].end_time)))) {
190							var check_exist = false;
191							for (var k = 0; k < multi_timetables.length; k++) {
192								if (multi_timetables[k].id == timetables[i].id) {
193									check_exist = true;
194								}
195							}
196							if (!check_exist) {
197								multi_timetables.push(timetables[i]);
198							}
199						}
200					}
201				}
202			}
203
204			multi_timetables.sort(sortTimetables);
205
206			multi_timetables_arrs[timetable.id] = [];
207			for (var t = 0; t < multi_timetables.length; t++) {
208				multi_timetables_arrs[timetable.id].push(multi_timetables[t].id);
209			}
210		}
211	}
212
213	// Get order of timetable on column
214	function getTimetableOrder(timetable, timetables) {
215		var order = 0;
216		
217		for (var i = 0; i < timetables.length; i++) {
218			if 	(timetable.id == timetables[i]) {
219				order = i;
220			}
221		}
222		
223		return order;
224	}
225
226	// Timetable detail
227	function timetableDetail(timetable) {
228		var timetable_string = '';
229
230		var timetable_image = (timetable.image) ? '<img src="' + quick_timetable_plugin_url + '/images/' + timetable.image + '" alt="' + timetable.title + '" />' : '';
231
232		timetable_string += '<div class="timetable-item">'
233							+ '<div class="timetable-image">' + timetable_image + '</div>'
234							+ '<div class="timetable-info">'
235								+ '<div class="timetable-title">' + timetable.title + '</div>'
236								+ '<div class="timetable-meta">'
237									+ '<div class="timetable-category"><i class="icon-folder"></i>' + timetable.category + '</i></div>'
238									+ '<div class="timetable-time"><i class="icon-clock"></i>' + timetable.start_time + ' - ' + timetable.end_time + '</i></div>'
239									+ '<div class="timetable-trainer"><i class="icon-user"></i>' + timetable.trainer + '</i></div>'
240								+ '</div>'
241								+ '<div class="timetable-content">' + timetable.content + '</div>'
242							+ '</div>'
243						+ '</div>';
244		
245		return timetable_string;
246	}
247
248	// Check day has timetable or not
249	function dayHasTimetable(day, month, year) {
250		var num_timetables = 0;
251		var date_check = new Date(year, Number(month) - 1, day);
252		for (var i = 0; i < quick_timetables.length; i++) { 
253			var start_date = new Date(quick_timetables[i].year, Number(quick_timetables[i].month) - 1, quick_timetables[i].day); 
254			var end_date = new Date(quick_timetables[i].year, Number(quick_timetables[i].month) - 1, Number(quick_timetables[i].day) + Number(quick_timetables[i].duration) - 1);
255			if ((start_date.getTime() <= date_check.getTime()) && (date_check.getTime() <= end_date.getTime())) {
256				num_timetables++;
257			}
258		}
259		
260		if (num_timetables == 0) {
261			return false;
262		} else {
263			return true;
264		}
265	}
266
267	// Week Timetable
268	function weekTimetable(el, _timetables, category, week, nav_time) {
269		var show_category 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-category').html();
270		var show_nav 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-nav').html();
271		var show_time 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-header-time').html();
272		var mode 			= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-mode').html();
273		var day_start 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-start').html();
274
275		var all_category	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-all-category').html();
276
277		var word_day_mon 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-mon').html();
278		var word_day_tue 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-tue').html();
279		var word_day_wed 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-wed').html();
280		var word_day_thu 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-thu').html();
281		var word_day_fri 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-fri').html();
282		var word_day_sat 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-sat').html();
283		var word_day_sun 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-sun').html();
284
285		var word_month_1 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-1').html();
286		var word_month_2 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-2').html();
287		var word_month_3 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-3').html();
288		var word_month_4 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-4').html();
289		var word_month_5 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-5').html();
290		var word_month_6 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-6').html();
291		var word_month_7 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-7').html();
292		var word_month_8 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-8').html();
293		var word_month_9 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-9').html();
294		var word_month_10 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-10').html();
295		var word_month_11 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-11').html();
296		var word_month_12 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-12').html();
297		
298		if (day_start == 'friday') { // Start with sunday
299			var word_day = new Array(word_day_sun, word_day_mon, word_day_tue, word_day_wed, word_day_thu, word_day_fri, word_day_sat);
300			var week_days = new Array('friday', 'saturday','sunday');
301		} else { // Start with monday
302			var word_day = new Array(word_day_mon, word_day_tue, word_day_wed, word_day_thu, word_day_fri, word_day_sat, word_day_sun);
303			var week_days = new Array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
304		}
305		var word_month = new Array(word_month_1, word_month_2, word_month_3, word_month_4, word_month_5, word_month_6, word_month_7, word_month_8, word_month_9, word_month_10, word_month_11, word_month_12);
306
307		var week_time = new Date(week);
308		if (nav_time == 'prev-week') {
309			week = getDay(week_time, 'before', 7);
310		} else if (nav_time == 'next-week') {
311			week = getDay(week_time, 'after', 7);
312		}
313
314		var week_first 			= new Date(week);
315		var week_first_date 	= week_first.getDate();
316		var week_first_month 	= week_first.getMonth() + 1;
317		var week_first_year 	= week_first.getFullYear();
318		
319		var week_last 			= getDay(week_first, 'after', 6);
320		var week_last_date 		= week_last.getDate();
321		var week_last_month 	= week_last.getMonth() + 1;
322		var week_last_year 		= week_last.getFullYear();
323			
324		var week_nav;
325		if ((week_first_month != week_last_month) && (week_first_year != week_last_year)) {
326			week_nav = word_month[week_first_month - 1].substring(0, 3) + ' ' + week_first_date + ', ' + week_first_year + ' - ' + word_month[week_last_month - 1].substring(0, 3) + ' ' + week_last_date + ', ' + week_last_year;
327		} else if (week_first_month != week_last_month) {
328			week_nav = word_month[week_first_month - 1].substring(0, 3) + ' ' + week_first_date + ' - ' + word_month[week_last_month - 1].substring(0, 3) + ' ' + week_last_date + ', ' + week_first_year;
329		} else {
330			week_nav = word_month[week_first_month - 1].substring(0, 3) + ' ' + week_first_date + ' - ' + week_last_date + ', ' + week_first_year;
331		}
332		
333		// Get axis time
334		var axis_time = getAxisTime();
335		var min_time = axis_time['min'];
336		var max_time = axis_time['max'];
337		
338		var timetable_string = '';
339
340		// Categories
341		if (!(show_category == 'hide')) {
342			var active = (category == 'all-category') ? 'active' : '';
343			
344			timetable_string += '<div class="timetable-category">';
345			timetable_string += 	'<ul>';
346			timetable_string += 		'<li id="all-category" class="category-item ' + active + '">' + all_category + '</li>';
347			for (var i = 0; i < timetable_cats.length; i++) {
348				var active = (category == timetable_cats[i].toLowerCase().replace(' ', '-')) ? 'active' : '';
349				timetable_string += 	'<li id="' + timetable_cats[i].toLowerCase().replace(' ', '-') + '" class="category-item ' + active + '">'
350											+ timetable_cats[i]
351										+ '</li>';
352			}	
353			timetable_string += 	'</ul>';
354			timetable_string += '</div>';
355		}
356
357		// Time navigation
358		if (!(show_nav == 'hide') && !(mode == 'day')) {
359			timetable_string += '<div class="timetable-navigation">'
360									+ '<span id="prev-week" class="nav nav-prev">‹</span>'	
361									+ '<span>' + week_nav + '</span>'
362									+ '<span id="next-week" class="nav nav-next">›</span>'
363								+ '</div>';
364		}
365
366		timetable_string += 	'<div class="timetable-week ' + show_time + '-header-time">';
367
368		// Axis column
369		timetable_string += 		'<div class="timetable-column">';
370		timetable_string += 			'<div class="column-header"></div>';
371		timetable_string += 			'<div class="column-content">';
372		for (var n = min_time; n <= max_time; n++) {
373			var hour = (n < 10) ? '0' + n : n;
374			timetable_string += 			'<div class="axis-item">' + hour + ':00</div>';
375		}
376		timetable_string += 			'</div>';
377		timetable_string += 			'<div class="column-grid">';
378		for (var n = min_time; n <= max_time; n++) {
379			timetable_string += 			'<div class="grid-item"></div>';
380		}
381		timetable_string += 			'</div>';
382		timetable_string += 		'</div>';
383
384		// Timetables column
385		for (var m = 0; m < word_day.length; m++) {
386			// Caculate date of column
387			var time 	= getDay(week_first, 'after', m);
388			var date 	= time.getDate();
389			var month 	= time.getMonth() + 1;
390			var year 	= time.getFullYear();			
391			
392			var last_column = (m == word_day.length - 1) ? 'last-column' : '';
393			timetable_string += 	'<div class="timetable-column ' + last_column + '">';
394			
395			// Header
396			var header_time = (show_time == 'hide') ? '' : '<div class="week-time">' + word_month[month - 1].substring(0, 3) + ' ' + date + ', ' + year + '</div>';
397			if (screen.width > 991) {
398				timetable_string += 	'<div class="column-header"><div class="header-container"><div class="week-day">' + word_day[m] + '</div>' + header_time + '</div></div>';
399			} else {
400				timetable_string += 	'<div class="column-header"><div class="header-container"><div class="week-day">' + word_day[m].substring(0, 3) + '</div>' + header_time + '</div></div>';
401			}
402			
403			// Content
404			timetable_string += 		'<div class="column-content">';
405			
406			// Get timetables on column
407			var timetables = getTimetables(_timetables, mode, week_days[m], date, month, year);
408			
409			for (var t = 0; t < timetables.length; t++) {
410				// Group multi timetables on column
411				multi_timetables = [];
412				groupMultiTimetables(timetables[t], timetables);
413				
414				if (timetables[t].start_time && timetables[t].end_time) {	
415					// Position
416					var position 	= getTimetablePosition(min_time, timetables[t].start_time);
417					var height 		= getTimetableHeight(timetables[t].start_time, timetables[t].end_time);
418					
419					// Width of timetable
420					var count_multi = multi_timetables_arrs[timetables[t].id].length;
421					var item_width 	= (count_multi > 1) ? 'width:' + (100 / count_multi) + '%;' : '';
422					var item_left 	= (count_multi > 1) ? 'left:' + (getTimetableOrder(timetables[t], multi_timetables_arrs[timetables[t].id]) * (100 / count_multi)) + '%' : '';
423
424					timetable_string += 	'<div class="timetable-container">'
425												+ '<a class="timetable-title-wrap color-' + timetables[t].color + '" style="top:' 
425+ position + 'px; height:' + height + 'px; ' + item_width + item_left + '" href="#' + el.attr('id') + '-popup-' + timetables[t].id + '">'
426													+ '<div class="timetable-title">'
427														+ '<h4>' + timetables[t].title + '</h4>'
428														+ '<div class="timetable-time">' + timetables[t].start_time + ' - ' + timetables[t].end_time + '</div>'
429													+ '</div>'
430												+ '</a>'
431												+ '<div id="' + el.attr('id') + '-popup-' + timetables[t].id + '" class="timetable-popup zoom-anim-dialog mfp-hide">'
432													+ '<div class="popup-body">'
433														+ timetableDetail(timetables[t])
434													+ '</div>'
435												+ '</div>'
436											+ '</div>';
437				}
438			}
439			timetable_string += 		'</div>';
440			
441			// Grid
442			timetable_string += 		'<div class="column-grid">';
443			for (var n = min_time; n <= max_time; n++) {
444				timetable_string += 		'<div class="grid-item"></div>';
445			}
446			timetable_string += 		'</div>'
447									+ '</div>';
448		}
449		timetable_string += 		'<div id="category" style="display:none">' + category + '</div>';
450		timetable_string += 		'<div id="week" style="display:none">' + week + '</div>';
451		timetable_string += 	'</div>';
452
453		el.html(timetable_string);
454		
455		// Popup
456		el.find('.timetable-title-wrap').magnificPopup({
457			type: 'inline',
458			removalDelay: 800,
459			mainClass: 'my-mfp-zoom-in'
460		});
461	}
462
463	// Month Timetable
464	function monthTimetable(el, _timetables, category, month_num, year_num, nav_time) {
465		var show_category 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-category').html();
466		var show_nav 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-nav').html();
467		var mode 			= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-mode').html();
468		var day_start 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-start').html();
469
470		var all_category	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-all-category').html();
471
472		var word_day_mon 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-mon').html();
473		var word_day_tue 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-tue').html();
474		var word_day_wed 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-wed').html();
475		var word_day_thu 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-thu').html();
476		var word_day_fri 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-fri').html();
477		var word_day_sat 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-sat').html();
478		var word_day_sun 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-sun').html();
479
480		var word_month_1 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-1').html();
481		var word_month_2 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-2').html();
482		var word_month_3 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-3').html();
483		var word_month_4 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-4').html();
484		var word_month_5 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-5').html();
485		var word_month_6 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-6').html();
486		var word_month_7 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-7').html();
487		var word_month_8 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-8').html();
488		var word_month_9 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-9').html();
489		var word_month_10 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-10').html();
490		var word_month_11 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-11').html();
491		var word_month_12 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-12').html();
492
493		if (day_start == 'sunday') { // Start with sunday
494			var word_day = new Array(word_day_sun, word_day_mon, word_day_tue, word_day_wed, word_day_thu, word_day_fri, word_day_sat);
495			var week_days = new Array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
496		} else { // Start with monday
497			var word_day = new Array(word_day_mon, word_day_tue, word_day_wed, word_day_thu, word_day_fri, word_day_sat, word_day_sun);
498			var week_days = new Array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
499		}
500		var word_month = new Array(word_month_1, word_month_2, word_month_3, word_month_4, word_month_5, word_month_6, word_month_7, word_month_8, word_month_9, word_month_10, word_month_11, word_month_12);
501
502		if (nav_time == 'prev-year') {
503			year_num--;
504		} else if (nav_time == 'next-year') {
505			year_num++;
506		} else if (nav_time == 'prev-month') {
507			month_num--;
508		} else if (nav_time == 'next-month') {
509			month_num++;
510		} else if (nav_time == 'current') {
511			month_num = today_month_g;
512			year_num = today_year_g;
513		}
514
515		if (month_num == 0) {
516			month_num = 12;
517			year_num--;
518		} else if (month_num == 13) {
519			month_num = 1;
520			year_num++;
521		}
522		
523		// Get first day and number days of month
524		var first_date_g = new Date(year_num, month_num - 1, 1);
525		if (day_start == 'sunday') {
526			var first_day_g = first_date_g.getDay() + 1;
527		} else {
528			var first_day_g = (first_date_g.getDay() == 0) ? 7 : first_date_g.getDay();
529		}
530		
531		var last_date_g = new Date(year_num, month_num, 0);
532		var num_days = last_date_g.getDate();
533		
534		// Create calendar
535		var timetable_string = '';
536		var date_num = 0;
537
538		// Categories
539		if (!(show_category == 'hide')) {
540			var active = (category == 'all-category') ? 'active' : '';
541			
542			timetable_string += '<div class="timetable-category">';
543			timetable_string += 	'<ul>';
544			timetable_string += 		'<li id="all-category" class="category-item ' + active + '">' + all_category + '</li>';
545			for (var i = 0;
545 i < timetable_cats.length; i++) {
546				var active = (category == timetable_cats[i].toLowerCase().replace(' ', '-')) ? 'active' : '';
547				timetable_string += 	'<li id="' + timetable_cats[i].toLowerCase().replace(' ', '-') + '" class="category-item ' + active + '">'
548											+ timetable_cats[i]
549										+ '</li>';
550			}	
551			timetable_string += 	'</ul>';
552			timetable_string += '</div>';
553		}
554
555		// Time navigation
556		if (!(show_nav == 'hide') && !(mode == 'day')) {
557			timetable_string += '<div class="timetable-navigation">'
558									+ '<span id="prev-year" class="nav nav-prev">«</span>'
559									+ '<span id="prev-month" class="nav nav-prev">‹</span>'
560									+ '<span>' + word_month[month_num - 1] + ' ' + year_num + '</span>'
561									+ '<span id="next-month" class="nav nav-next">›</span>'
562									+ '<span id="next-year" class="nav nav-next">»</span>'
563								+ '</div>';
564		}
565		
566		timetable_string += 	'<div class="timetable-month">';
567		timetable_string += 		'<div class="timetables-calendar">';
568		timetable_string += 			'<table class="calendar-table">';
569		timetable_string += 				'<tbody>';
570				
571		timetable_string += 					'<tr>';
572		for (var m = 0; m < word_day.length; m++) {
573			timetable_string += 					'<th>' + word_day[m] + '</th>';
574		}
575		timetable_string += 					'</tr>';
576
577		var this_date = 1;
578		
579		for (var i = 1; i <= 6; i++) {
580			var k = (i - 1) * 7 + 1;
581			if (k < (first_day_g + num_days)) {
582				timetable_string += 			'<tr>';
583				for (var x = 1; x <= 7; x++) {
584					date_num = (this_date - first_day_g) + 1;
585					this_date++;
586					if ((date_num > num_days) || (date_num < 1)) {
587						timetable_string += 		'<td class="calendar-day blank"></td>';
588					} else {			
589						// Weekend
590						var weekend_class = '';
591						if (day_start == 'sunday') {
592							if ((x == 1) || (x == 7)) {
593								weekend_class = ' weekend';
594							}
595						} else {
596							if ((x == 6) || (x == 7)) {
597								weekend_class = ' weekend';
598							}
599						}
600
601						// Today
602						var today_class = '';
603						if ((today_date_g == date_num) && (today_month_g == month_num) && (today_year_g == year_num)) {
604							today_class = ' today';
605						}
606
607						timetable_string += 	'<td class="calendar-day' + weekend_class + today_class + '">';
608						timetable_string += 		'<span class="day-num">' + date_num + '</span>';
609							
610						// Get timetables
611						var day = new Date(year_num, month_num - 1, date_num);
612						if (day_start == 'sunday') {
613							var day_num = day.getDay();
614						} else {
615							var day_num = (day.getDay() == 0) ? 6 : day.getDay() - 1;
616						}
617						var timetables = getTimetables(_timetables, mode, week_days[day_num], date_num, month_num, year_num);
618
619						for (var t = 0; t < timetables.length; t++) {
620							var color = timetables[t].color ? timetables[t].color : 1;
621																	
622							timetable_string += 	'<div class="timetable-title color-' + color + '" href="#' + el.attr('id') + '-popup-' + timetables[t].id + '">'
623														+ '<div class="timetable-time">' + timetables[t].start_time + ' - ' + timetables[t].end_time + '</div>'
624														+ '<div>' + timetables[t].title + '</div>'
625													+ '</div>';
626							
627							// ==== Timetable detail popup ====
628							timetable_string += 	'<div id="' + el.attr('id') + '-popup-' + timetables[t].id + '" class="timetable-popup zoom-anim-dialog mfp-hide">'
629														+ '<div class="popup-body">'
630							 								+ timetableDetail(timetables[t])
631							 							+ '</div>'
632							 						+ '</div>';
633						}
634						
635						timetable_string += 	'</td>';
636					}
637				}
638				timetable_string += 		'</tr>';
639			}
640		}
641		timetable_string += 			'</tbody>';
642		timetable_string += 		'</table>';
643		timetable_string += 		'<div id="category" style="display:none">' + category + '</div>';
644		timetable_string += 		'<div id="month" style="display:none">' + month_num + '</div>';
645		timetable_string += 		'<div id="year" style="display:none">' + year_num + '</div>';
646		timetable_string += 	'</div>';
647		
648		// Create calendar
649		el.html(timetable_string);
650
651		// Popup
652		el.find('.timetable-title').magnificPopup({
653			type: 'inline',
654			removalDelay: 800,
655			mainClass: 'my-mfp-zoom-in'
656		});
657		el.find('.timetable-mark').magnificPopup({
658			type: 'inline',
659			removalDelay: 800,
660			mainClass: 'my-mfp-zoom-in'
661		});
662	}
663
664	// List Timetable
665	function listTimetable(el, _timetables, category, week, nav_time) {
666		var show_category 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-category').html();
667		var show_nav 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-nav').html();
668		var show_time 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-header-time').html();
669		var mode 			= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-mode').html();
670		var day_start 		= el.parents('.quick-timetable-wrapper').find('.quick-timetable-option-start').html();
671
672		var all_category	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-all-category').html();
673
674		var word_day_mon 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-mon').html();
675		var word_day_tue 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-tue').html();
676		var word_day_wed 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-wed').html();
677		var word_day_thu 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-thu').html();
678		var word_day_fri 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-fri').html();
679		var word_day_sat 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-sat').html();
680		var word_day_sun 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-day-sun').html();
681
682		var word_month_1 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-1').html();
683		var word_month_2 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-2').html();
684		var word_month_3 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-3').html();
685		var word_month_4 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-4').html();
686		var word_month_5 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-5').html();
687		var word_month_6 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-6').html();
688		var word_month_7 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-7').html();
689		var word_month_8 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-8').html();
690		var word_month_9 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-9').html();
691		var word_month_10 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-10').html();
692		var word_month_11 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-11').html();
693		var word_month_12 	= el.parents('.quick-timetable-wrapper').find('.quick-timetable-word-month-12').html();
694		
695		if (day_start == 'sunday') { // Start with sunday
696			var word_day = new Array(word_day_sun, word_day_mon, word_day_tue, word_day_wed, word_day_thu, word_day_fri, word_day_sat);
697			var week_days = new Array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
698		} else { // Start with monday
699			var word_day = new Array(word_day_mon, word_day_tue, word_day_wed, word_day_thu, word_day_fri, word_day_sat, word_day_sun);
700			var week_days = new Array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
701		}
702		var word_month = new Array(word_month_1, word_month_2, word_month_3, word_month_4, word_month_5, word_month_6, word_month_7, word_month_8, word_month_9, word_month_10, word_month_11, word_month_12);
703
704		var week_time = new Date(week);
705		if (nav_time == 'prev-week') {
706			week = getDay(week_time, 'before', 7);
707		} else if (nav_time == 'next-week') {
708			week = getDay(week_time, 'after', 7);
709		}
710
711		var week_first 			= new Date(week);
712		var week_first_date 	= week_first.getDate();
713		var week_first_month 	= week_first.getMonth() + 1;
714		var week_first_year 	= week_first.getFullYear();
715		
716		var week_last 			= getDay(week_first, 'after', 6);
717		var week_last_date 		= week_last.getDate();
718		var week_last_month 	= week_last.getMonth() + 1;
719		var week_last_year 		= week_last.getFullYear();
720			
721		var week_nav;
722		if ((week_first_month != week_last_month) && (week_first_year != week_last_year)) {
723			week_nav = word_month[week_first_month - 1].substring(0, 3) + ' ' + week_first_date + ', ' + week_first_year + ' - ' + word_month[week_last_month - 1].substring(0, 3) + ' ' + week_last_date + ', ' + week_last_year;
724		} else if (week_first_month != week_last_month) {
725			week_nav = word_month[week_first_month - 1].substring(0, 3) + ' ' + week_first_date + ' - ' + word_month[week_last_month - 1].substring(0, 3) + ' ' + week_last_date + ', ' + week_first_year;
726		} else {
727			week_nav = word_month[week_first_month - 1].substring(0, 3) + ' ' + week_first_date + ' - ' + week_last_date + ', ' + week_first_year;
728		}
729		
730		var timetable_string = '';
731
732		// Categories
733		if (!(show_category == 'hide')) {
734			var active = (category == 'all-category') ? 'active' : '';
735			
736			timetable_string += '<div class="timetable-category">';
737			timetable_string += 	'<ul>';
738			timetable_string += 		'<li id="all-category" class="category-item ' + active + '">' + all_category + '</li>';
739			for (var i = 0; i < timetable_cats.length; i++) {
740				var active = (category == timetable_cats[i].toLowerCase().replace(' ', '-')) ? 'active' : '';
741				timetable_string += 	'<li id="' + timetable_cats[i].toLowerCase().replace(' ', '-') + '" class="category-item ' + active + '">'
742											+ timetable_cats[i]
743										+ '</li>';
744			}	
745			timetable_string += 	'</ul>';
746			timetable_string += '</div>';
747		}
748
749		// Time navigation
750		if (!(show_nav == 'hide') && !(mode == 'day')) {
751			timetable_string += '<div class="timetable-navigation">'
752									+ '<span id="prev-week" class="nav nav-prev">‹</span>'	
753									+ '<span>' + week_nav + '</span>'
754									+ '<span id="next-week" class="nav nav-next">›</span>'
755								+ '</div>';
756		}
757
758		timetable_string += 	'<div class="timetable-list ' + show_time + '-header-time">';
759
760		// Timetables row
761		for (var m = 0; m < word_day.length; m++) {
762			// Caculate date of row
763			var time 	= getDay(week_first, 'after', m);
764			var date 	= time.getDate();
765			var month 	= time.getMonth() + 1;
766			var year 	= time.getFullYear();
767
768			// Get timetables on row
769			var timetables = getTimetables(_timetables, mode, week_days[m], date, month, year);
770
771			if (timetables.length) {		
772				timetable_string += '<div class="timetable-row">';
773				
774				// Header
775				var header_time = (show_time == 'hide') ? '' : '<div class="week-time">' + word_month[month - 1].substring(0, 3) + ' ' + date + ', ' + year + '</div>';
776				timetable_string += 	'<div class="row-header"><div class="week-day">' + word_day[m] + '</div>' + header_time + '</div>';
777				
778				// Content
779				timetable_string += 	'<div class="row-content">';
780				
781				for (var t = 0; t < timetables.length; t++) {
782					var color = timetables[t].color ? timetables[t].color : 1;
783					timetable_string += '<div class="timetable-item">'
784											+ '<div class="timetable-title" href="#' + el.attr('id') + '-popup-' + timetables[t].id + '">'
785												+ '<span class="timetable-color color-' + color + '"></span>'
786												+ '<span class="timetable-time">' + timetables[t].start_time + ' - ' + timetables[t].end_time + '</span>'
787												+ timetables[t].title
788											+ '</div>'
789											+ '<div id="' + el.attr('id') + '-popup-' + timetables[t].id + '" class="timetable-popup zoom-anim-dialog mfp-hide">'
790												+ '<div class="popup-body">'
791													+ timetableDetail(timetables[t])
792												+ '</div>'
793											+ '</div>'
794										+ '</div>';
795				}
796				timetable_string += 	'</div>'
797									+ '</div>';
798			}
799		}
800		timetable_string += 		'<div id="category" style="display:none">' + category + '</div>';
801		timetable_string += 		'<div id="week" style="display:none">' + week + '</div>';
802		timetable_string += 	'</div>';
803
804		el.html(timetable_string);
805		
806		// Popup
807		el.find('.timetable-title').magnificPopup({
808			type: 'inline',
809			removalDelay: 800,
810			mainClass: 'my-mfp-zoom-in'
811		});
812	}
813
814
815	$(document).ready(function(){
816		$('.quick-timetable').each(function(index) {
817			// Set id for timetable
818			$(this).attr('id', 'timetable-' + (index + 1));
819
820			// Get variables
821			var view 		= $(this).parents('.quick-timetable-wrapper').find('.quick-timetable-option-view').html();
822			var day_start 	= $(this).parents('.quick-timetable-wrapper').find('.quick-timetable-option-start').html();
823			var list 		= $(this).parents('.quick-timetable-wrapper').find('.quick-timetable-option-list').html();
824
825			// Automatic switch to list view on small sreen
826			if (screen.width < 768) {
827				view = 'list';
828			}
829
830			var timetable_contain = $(this);
831
832			$.ajax({
833				type: 'POST',
834				url: quick_timetable_home_url + 'wp-admin/admin-ajax.php',
835				dataType: 'json',
836				data : {action: 'get_timetables', list: list},
837				success: function(data) { 
838					// Init
839					quick_timetables = [];
840					sort_timetables = [];
841
842					// Get data
843					for (var i = 0; i < data.length; i++) {
844						quick_timetables.push(data[i]);
845						sort_timetables.push(data[i]);
846					}
847
848					// Process data
849					processTimetablesSource();
850					
851					// Show Timetables
852					if (view == 'month') { // Month
853						monthTimetable(timetable_contain, quick_timetables, 'all-category', today_month_g, today_year_g, 'current');
854					} else if (view == 'list') { // List
855						var today_date = new Date();
856						if (day_start == 'sunday') { // Start with sunday
857							var week = new Date(today_date.setDate(today.getDate() - today_date.getDay()));
858						} else { // Start with monday
859							var today_day = (today_date.getDay() == 0) ? 7 : today_date.getDay();
860							var week = new Date(today_date.setDate(today.getDate() - today_day + 1));
861						}
862						listTimetable(timetable_contain, quick_timetables, 'all-category', week, 'current');
863					} else { // Week
864						var today_date = new Date();
865						if (day_start == 'sunday') { // Start with sunday
866							var week = new Date(today_date.setDate(today.getDate() - today_date.getDay()));
867						} else { // Start with monday
868							var today_day = (today_date.getDay() == 0) ? 7 : today_date.getDay();
869							var week = new Date(today_date.setDate(today.getDate() - today_day + 1));
870						}
871						weekTimetable(timetable_contain, quick_timetables, 'all-category', week, 'current');
872					}
873				}
874			});
875		});
876
877		// Filter category
878		$('.quick-timetable').on('click', '.timetable-category ul li', function() {
879			var timetable_contain = $(this).closest('.quick-timetable');
880			
881			// Get timetables by category
882			var category = $(this).attr('id');
883			var timetables = getTimetablesByCategory(category);
884
885			var view = $(this).closest('.quick-timetable-wrapper').find('.quick-timetable-option-view').html();
886
887			// Automatic switch to list view on small sreen
888			if (screen.width < 768) {
889				view = 'list';
890			}
891
892            if (view == 'month') { // Month
893				var month = timetable_contain.find('#month').text();
894				var year = timetable_contain.find('#year').text();
895	            monthTimetable(timetable_contain, timetables, category, month, year, 'current');
896			} else if (view == 'list') { // List
897				var week = timetable_contain.find('#week').text();
898            	listTimetable(timetable_contain, timetables, category, week, 'current');
899			} else { // Week
900				var week = timetable_contain.find('#week').text();
901            	weekTimetable(timetable_contain, timetables, category, week, 'current');
902			}
903        });
904
905        // Navigation
906		$('.quick-timetable').on('click', '.timetable-navigation .nav', function() {
907			var timetable_contain = $(this).closest('.quick-timetable');
908			var nav_time = $(this).attr('id');
909
910			// Get timetables by category
911			var category = timetable_contain.find('#category').text();
912			var timetables = getTimetablesByCategory(category);
913
914			var view = $(this).closest('.quick-timetable-wrapper').find('.quick-timetable-option-view').html();
915
916			// Automatic switch to list view on small sreen
917			if (screen.width < 768) {
918				view = 'list';
919			}
920			
921			if (view == 'month') { // Month
922				var month = timetable_contain.find('#month').text();
923				var year = timetable_contain.find('#year').text();
924	            monthTimetable(timetable_contain, timetables, category, month, year, nav_time);
925			} else if (view == 'list') { // List
926				var week = timetable_contain.find('#week').text();
927	            listTimetable(timetable_contain, timetables, category, week, nav_time);
928			} else { // Week
929				var week = timetable_contain.find('#week').text();
930	            weekTimetable(timetable_contain, timetables, category, week, nav_time);
931			}
932        });
933	});
934})(jQuery);

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.