PageSourceSearch

https://appointiv.herokuapp.com/1.9/static4/simplecalendar.js?v=3.0

js appointiv.herokuapp.com collected 2026-10-03 14:46:35 UTC 158,986 bytes, 3,724 lines download raw bytes

1var app = app || {};
2
3'use strict';
4
5app.calendar = {
6	eventsArr : [],
7	selectedDate : '',
8	disablePreviousBtn: false,
9	inputData:{
10		selectLocationfornewapp:"",
11		selectCategoryfornewapp:"",
12		selectatfornewapp:"",
13		selectPractitionerfornewapp:"",
14		isClass:"",
15		Fetch_Method:"",
16		appointmentDate:"",
17		isAnyPractitioner:"",
18		timeZoneKey:"",
19		locationTimeZoneKey:"",
20		slotsTimeZoneKey:"",
21	},
22	sdate : '',
23	edate : '',
24	lday : '',
25	ltime: '',
26	eveTime: '',
27	morTime: '',
28	leadDate: '',
29	viewType: '',
30	lockDate: false,
31	selectedTime: '',
32	lockTime: false,
33	selectedTimeZone: '',
34	defaultWithoutConvertedSlots: {},
35	// Raw availability snapshot from fetchCalendarData (pre-conversion)
36	rawAvailabilityByDate: {},
37
38	dataFromSFAPI: false,
39	varIsSlotsBasedOnLocation: false,
40	varNewDateBasedOnLocation: new Date(),
41
42	dataModel: new app.dataModel(),
43
44	init: function(ajax, appData) {
45
46		var that = this;
47
48		$('.calendar').show();
49		$('.select-date-text').show();
50		$('.change-date-btn').hide();
51		$('.calendar-details').show();
52		$('.changeTimeZoneButton').click(function(e){
53			console.log('getTimeZoneList',that.getTimeZoneList());
54			let timeZonesList = that.getTimeZoneList();
55			const selectorOptions = timeZonesList.map(item=>{
56				return `<option value="${item.timezone}">(GMT ${item.GMTDiff}) ${item.zoneName} (${item.timezone})</option>`;
57			});
58			$('.timeZone_Selector').html('<select class="timeZone_Selector">'+selectorOptions+'</select>');
59			$('#ChangeTimeZoneModal').modal({backdrop: 'static', keyboard: false});
60			if($('#clientTimezoneNotify-2') && $('#clientTimezoneNotify-2').text()){
61				$('.timeZone_Selector').val($('#clientTimezoneNotify-2').text())
62			}
63		});
64
65		$('.chnagedTimeZone').click(function(e){
66			let selectedVal = $('.timeZone_Selector').val();
67			$('#clientTimezoneNow').text(selectedVal);
68			$('.timeZoneInfoBox').css('display','block');
69			if(selectedVal && selectedVal != $('#clientTimezoneNotify-2').text()){
70				$('#clientTimezoneNotify-2').text(selectedVal);
71				that.inputData.locationTimeZoneKey = selectedVal;
72				// Mark as manual selection (not SF business setting)
73				that.varIsSlotsBasedOnLocation = true;
74				
75				// Update timezone indicator if it exists
76				if($('#timezone-indicator').length) {
77					$('#timezone-indicator').text('Booking in: ' + selectedVal + ' timezone');
78				}
79				
80				// Update URL parameter if tz was originally provided
81				if(getUrlParameter('tz')) {
82					var url = new URL(window.location);
83					url.searchParams.set('tz', selectedVal);
84					window.history.replaceState({}, '', url);
85				}
86				$($('tbody.event-calendar tr')).each(function(index) {
87					$(this).empty();
88				});
89				$($('thead.event-days tr')).each(function(index) {
90					$(this).empty();
91				});
92				that.clearMorningEveningTimeSlots();
93				that.updateEvents(that.defaultWithoutConvertedSlots,that,appointmentDetailObj,requiredData);
94			}
95			setTimeout(function(){
96				$('.timeZoneInfoBox').css('display','none');
97			},5000);
98		});
99
100		// Add missing click handler for Change Date button
101
102		$('.change-date-btn').click(function (e) {
103
104			console.log('🔄 Change Date button clicked');
105			// Show calendar and hide timeslots (reverse the mobile view)
106			$('.calendar').show();
107			$('.select-date-text').show();
108			$('.change-date-btn').hide();
109			$('.calendar-details').show();
110			$('.timeslot-main').hide();
111			$('.am-timeslot-section').css('min-height', '50px');
112			$('.smalloverlay-two').hide();
113
114			// Clear any active time slot selection
115			that.clearMorningEveningTimeSlots();
116
117			// Scroll to calendar
118			try {
119				var calendarTop = $('.calendar').position().top;
120				$("body, html").animate({ scrollTop: calendarTop }, 'slow');
121			} catch (e) {
122				console.log('Scroll failed:', e);
123			}
124		});
125
126		if (ajax) {
127
128			that.disablePreviousBtn = true;
129			$('.btn-prev i').addClass('custom-disabled');
130
131			that.inputData.selectLocationfornewapp = appData.locationId;
132			that.inputData.selectCategoryfornewapp = appData.categoryId;
133			that.inputData.selectatfornewapp = appData.appTypeId;
134			that.inputData.selectPractitionerfornewapp = appData.practitionerId;
135			that.inputData.isClass = appData.isClass;
136			that.inputData.appointmentDate = appData.appointmentDate;
137			that.inputData.isAnyPractitioner = appData.isAnyPractitioner;
138			// Store the original prre always in provider timezone
139			const urlTimezone = getUrlParameter('tz');
140			that.originalProviderTimeZone = appData.locationTimeZoneKey; // Store original timezone
141			that.inputData.locationTimeZoneKey = urlTimezone || appData.locationTimeZoneKey;
142			// slotsTimeZoneKey should always be the provider timezone since slots come from provider
143			that.inputData.slotsTimeZoneKey = appData.locationTimeZoneKey;
144			
145			// Note: timezone-based rendering will be determined by priority hierarchy in calendar rendering
146
147		   that.sdate = appData.sdate;
148		   that.edate = appData.edate;
149		   that.lday = appData.lday;
150		   that.ltime = appData.ltime;
151		   that.viewType = appData.viewType || '';
152		   that.lockDate = appData.lockDate === 'true' || appData.lockDate === true;
153		   that.selectedTime = appData.selectedTime;
154		   that.lockTime = appData.lockTime === 'true' || appData.lockTime === true;
155		   that.selectedTimeZone = appData.selectedTimeZone;
156		   
157		   
158		   // Add CSS for locked dates and times
159		   if ((that.lockDate || that.lockTime) && !$('#date-time-lock-styles').length) {
160		   	$('<style id="date-time-lock-styles">' +
161		   	  '.date-locked { ' +
162		   	    'opacity: 0.3 !important; ' +
163		   	    'cursor: not-allowed !important; ' +
164		   	    'pointer-events: none !important; ' +
165		   	    'color: #999 !important; ' +
166		   	  '} ' +
167		   	  '.date-locked:hover { ' +
168		   	    'background-color: transparent !important; ' +
169		   	    'color: #999 !important; ' +
170		   	  '} ' +
171		   	  '.time-locked { ' +
172		   	    'opacity: 0.4 !important; ' +
173		   	    'cursor: not-allowed !important; ' +
174		   	    'pointer-events: none !important; ' +
175		   	  '} ' +
176		   	  '.time-locked h3 { ' +
177		   	    'color: #999 !important; ' +
178		   	  '} ' +
179		   	  '.time-locked:hover { ' +
180		   	    'background-color: transparent !important; ' +
181		   	  '} ' +
182		   	  '.time-preselected { ' +
183		   	    'background-color: var(--brand-color, #007bff) !important; ' +
184		   	    'border-color: var(--brand-color, #007bff) !important; ' +
185		   	  '} ' +
186		   	  '.time-preselected h3 { ' +
187		   	    'color: white !important; ' +
188		   	  '}' +
189		   	'</style>').appendTo('head');
190		   }
191		   
192			var browserCurrentDateTime = new Date();
193			var browserCurrentDate = browserCurrentDateTime.getDate() +","+ (browserCurrentDateTime.getMonth() + 1) +","+ browserCurrentDateTime.getFullYear();
194			var browserCurrentTime = moment(browserCurrentDateTime).format("HH:mm");
195
196			var requiredData = {
197				selectLocationfornewapp:that.inputData.selectLocationfornewapp,
198				selectCategoryfornewapp:that.inputData.selectCategoryfornewapp,
199				selectatfornewapp:that.inputData.selectatfornewapp,
200				selectPractitionerfornewapp:that.inputData.selectPractitionerfornewapp,
201				appointmentDate:that.inputData.appointmentDate,
202				isClass:that.inputData.isClass,
203				fetchMethod:'Fetch_Monthly_Calendar',
204				isAnyPractitioner:that.inputData.isAnyPractitioner,
205				locationTimeZoneKey: that.inputData.locationTimeZoneKey,
206				browserCurrentDate: browserCurrentDate,
207				browserCurrentTime: browserCurrentTime
208			};
209
210			that.clearMorningEveningTimeSlots();
211			$('.smalloverlay').show();
212
213			// ajax call to print json
214			scrollPageToTop();
215			app.calendar.dataModel.getCalendarData(requiredData).done(
216				function(data){
217					that.defaultWithoutConvertedSlots = data;
218					// Cache raw availability for the month for later lookup of original provider times
219					try{
220						if(data && typeof data === 'object'){
221							that.rawAvailabilityByDate = JSON.parse(JSON.stringify(data));
222						}
223					}catch(e){ console.log('[CAL] rawAvailability cache failed', e); }
224					
225					// Check if this is a direct booking request (prefilled link with BOTH date and time)
226					const selectedDate = getUrlParameter('sd');
227					const selectedTime = getUrlParameter('st');
228					const selectedTimeZone = getUrlParameter('tz');
229					
230					// Validate timezone FIRST before any processing (for direct booking links)
231					if (selectedTimeZone && selectedDate && selectedTime) {
232						// Auto-fix common timezone formatting issues
233						var normalizedTimezone = selectedTimeZone
234							.split('/')
235							.map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
236							.join('/');
237						
238						// Validate the normalized timezone for direct booking
239						if (!moment.tz.zone(normalizedTimezone)) {
240							console.error('[DIRECT BOOKING TIMEZONE ERROR] Invalid timezone in URL parameter:', selectedTimeZone, 'normalized to:', normalizedTimezone);
241							
242							// Show timezone error instead of availability error
243							setTimeout(function() {
244								$("#errorHandlerModal .modal-header h2").html("<b>Invalid Timezone</b>");
245								$("#errorHandlerModal .modal-header h2").css('color','red');
246								$("#errorHandlerModal .modal-body h2").html(`The timezone "${selectedTimeZone}" is not valid. Please use a proper timezone format like "Australia/Brisbane".`);
247								$('#errorHandlerModal').modal({backdrop: 'static', keyboard: false});
248								
249								// Hide the loader since direct booking failed
250								if (window.directBookingMode) {
251									app.utility.hideLoader();
252									$('#waitBox').removeClass('direct-booking');
253									window.directBookingMode = false;
254								}
255							}, 500);
256							
257							// Don't proceed with invalid timezone for direct booking
258							return;
259						}
260					}
261					
262					// Always render the calendar first
263					that.updateEvents(data,that,appointmentDetailObj,requiredData);
264					
265					// Then check availability after calendar has processed the data
266					if (selectedDate && selectedTime) {
267						// Both date AND time specified - attempt direct booking
268						console.log('Direct booking check:', {selectedDate, selectedTime, selectedTimeZone});
269						
270						// Check availability after calendar data is processed
271						setTimeout(function() {
272							const isAvailable = that.checkTimeAvailabilityAfterProcessing(selectedDate, selectedTime, selectedTimeZone);
273							console.log('Availability result:', isAvailable);
274							
275							if (isAvailable) {
276								// Time is available - go directly to booking form
277								console.log('Direct booking: Time available, proceeding to booking form');
278								
279								// Set the appointment details (similar to what time slot click handlers do)
280								// Keep user time in user timezone since availability matrix is now converted to user timezone
281								const userTz = selectedTimeZone || moment.tz.guess();
282								const providerTz = that.originalProviderTimeZone || that.inputData.locationTimeZoneKey;
283								const userDateTime = moment.tz(`${selectedDate} ${selectedTime}`, 'YYYY-MM-DD HH:mm', userTz);
284
285								// Keep time in user timezone since availability matrix is converted to user timezone
286								appointmentDetailObj.startTime = userDateTime.format('HH:mm');
287								appointmentDetailObj.endTime = userDateTime.clone().add(parseInt(appointmentDetailObj.appointmentType.timeslotduration)/60,'Hours').format('HH:mm');
288								
289								console.log('Direct booking: Timezone conversion applied:', {
290									originalTime: selectedTime,
291									userTz: userTz,
292									providerTz: providerTz,
293									keptInUserTimeZoneStartTime: appointmentDetailObj.startTime,
294									keptInUserTimeZoneEndTime: appointmentDetailObj.endTime
295								});
296								appointmentDetailObj.date.dateStr = selectedDate;
297								appointmentDetailObj.date.dateText = moment(selectedDate, 'YYYY-MM-DD').format('DD MMMM YYYY');
298
299								// CRITICAL: Set the timezone element that calculateServiceProviders() reads from
300								// This ensures timezone consistency between direct booking and normal booking
301								if (selectedTimeZone) {
302									$("#clientTimezoneNotify-2").text(selectedTimeZone);
303									console.log('Direct booking: Set timezone element to:', selectedTimeZone);
304								}
305								
306								// Calculate service providers before proceeding to booking form
307								console.log('Direct booking: Calling calculateServiceProviders()');
308								calculateServiceProviders().then(function() {
309									console.log('Direct booking: calculateServiceProviders() completed, selectedServiceProviderIds:', selectedServiceProviderIds);
310
311									// Auto-proceed to booking form after calendar is rendered and service providers are calculated
312									setTimeout(function() {
313														// Also update the datetimediv and timezone indicator like the normal flow
314									// For direct booking, the appointment time is already in user timezone, so display it directly
315									var displayTimezone = selectedTimeZone || $('#clientTimezoneNotify-2').text() || appointmentDetailObj.location.timeZoneKey;
316									var providerTimezone = appointmentDetailObj.location.timeZoneKey;
317									// Since appointmentDetailObj.startTime is now in user timezone (not provider timezone),
318									// create the display datetime directly in user timezone
319									var displayDateTime = moment.tz(appointmentDetailObj.date.dateStr + ' ' + appointmentDetailObj.startTime, 'YYYY-MM-DD HH:mm', displayTimezone);
320									var displayText = displayDateTime.format('dddd, MMMM Do YYYY  |  h:mm A');
321										
322										if($("#datetimediv").length){
323											$('#datetimediv').text(displayText);
324										 } else {
325											 $('.appointment-sum-data').append('<div class="tab-bar datetime-summary-cont"><div id="datetimediv">'+displayText+'</div></div>');
326										 }
327
328										 // Add timezone indicator
329										 var selectedTimeZone = getUrlParameter('tz') || $('#clientTimezoneNotify-2').text() || moment.tz.guess();
330										 $("#timezone-indicator").remove();
331										 $('#datetimediv').after('<div id="timezone-indicator" class="location-address">Booking in: ' + selectedTimeZone + ' timezone</div>');
332										 // Apply color styling to timezone indicator
333										 $("#timezone-indicator").css("color", (window.brandingData && window.brandingData.Summary_Text_Color) ? window.brandingData.Summary_Text_Color : '#000');
334
335										// Update appointment summary
336										updateAppointmentSummaryText(appointmentDetailObj);
337
338										// Navigate directly to step 5 (userDetails)
339										// Implement the step switch directly since function may not be available yet
340										$('.stepSection').hide();
341										$('#step5Section').show();
342
343										// Update progress indicator if it exists
344										$('.progressbar li').removeClass('active completed');
345										$('.progressbar li:nth-child(5)').addClass('active');
346										$('.progressbar li:lt(5)').addClass('completed');
347
348										// Update URL hash
349										if (history && history.pushState) {
350											history.pushState({page:"userDetails"}, "page 5", "#userDetails");
351										}
352
353										// Hide the main page loader to reveal the booking form
354										if (window.directBookingMode) {
355											app.utility.hideLoader();
356											$('#waitBox').removeClass('direct-booking'); // Remove direct booking class
357											window.directBookingMode = false; // Reset flag
358										}
359
360										console.log('Direct booking: Successfully navigated to booking form');
361									}, 800); // Longer delay to ensure calendar is fully rendered
362								}).catch(function(error) {
363									console.error('Direct booking: calculateServiceProviders() failed:', error);
364									// If service provider calculation fails, show error instead of proceeding
365									if (window.directBookingMode) {
366										app.utility.hideLoader();
367										$('#waitBox').removeClass('direct-booking');
368										window.directBookingMode = false;
369									}
370									$("#errorHandlerModal .modal-body h2").text('Service Provider is not available');
371									$('#errorHandlerModal').modal({backdrop: 'static', keyboard: false});
372								});
373							} else {
374								// Time is not available - show calendar with error message
375								console.log('Direct booking: Time not available, showing calendar with message');
376								
377								// Clear the main page loader since direct booking failed
378								if (window.directBookingMode) {
379									app.utility.hideLoader();
380									$('#waitBox').removeClass('direct-booking'); // Remove direct booking class
381									window.directBookingMode = false; // Reset flag
382								}
383								
384								// Show error message to user using the app's modal
385								// Use the same timezone logic as the validation
386								let displayTz;
387								if (selectedTimeZone) {
388									displayTz = selectedTimeZone;
389								} else if (appointmentDetailObj.appointmentType && appointmentDetailObj.appointmentType.isSlotsBasedOnLocation) {
390									// No tz param but isSlotsBasedOnLocation=true → show provider timezone
391									displayTz = appointmentDetailObj.location.timeZoneKey;
392								} else {
393									// No tz param and isSlotsBasedOnLocation=false → show browser timezone  
394									displayTz = moment.tz.guess();
395								}
396								
397								const timeDisplay = moment(selectedTime, ['HH:mm', 'HHmm']).format('h:mm A');
398								const dateDisplay = moment(selectedDate).format('MMMM Do, YYYY');
399								
400								setTimeout(function() {
401									// Use the existing error modal instead of browser alert
402									$("#errorHandlerModal .modal-header h2").html("<b>Sorry... we couldn't find any available times</b>");
403									$("#errorHandlerModal .modal-header h2").css('color','red');
404									$("#errorHandlerModal .modal-body h2").html(`The requested time ${timeDisplay} on ${dateDisplay} (${displayTz}) is not available. Please select an alternative time.`);
405									$('#errorHandlerModal').modal({backdrop: 'static', keyboard: false});
406								}, 500);
407							}
408						}, 300); // Wait for calendar processing to complete
409					}
410				}
411			).fail(function(resp){
412				$('.smalloverlay').hide();
413				
414				// Clear the main page loader if direct booking failed
415				if (window.directBookingMode) {
416					app.utility.hideLoader();
417					$('#waitBox').removeClass('direct-booking'); // Remove direct booking class
418					window.directBookingMode = false; // Reset flag
419				}
420				
421				app.utility.handleServerError(resp);
422				console.log(resp);
423				 console.error(resp.responseText);
424				 $('#NoTimeSlotsAvailableModal').modal({backdrop: 'static', keyboard: false});
425				 that.clearMorningEveningTimeSlots();
426				 that.eventsArr = [];
427				 $('#appointmentCalCont').hide();
428			});
429		} else {
430			that.startCalendar("");
431		}
432
433	},
434
435	updateEvents: function(data,that,appointmentDetailObj,requiredData){
436		//console.log('updateEvents 1 >>'+JSON.stringify(data));
437		
438		// Note: Following reschedule appointment approach - use converted times + timezone headers
439		// instead of trying to preserve original times in data attributes
440		
441		$('#appointmentCalCont').show();
442		if(appointmentDetailObj.appointmentType.isFiveMin){
443			appointmentDetailObj.practitioner.timeSlot = '00:00;00:15;00:30;00:45;00:05;00:10;00:20;00:25;00:35;00:40;00:50;00:55';
444		}
445		that.dataFromSFAPI = false
446		var cpDay = new Date().getDate();
447		var cpMonth = new Date().getMonth() +1;
448		// Timezone Priority Hierarchy: URL param > Manual selection > SF location setting > browser timezone
449		var urlTimezone = getUrlParameter('tz');
450		var sfLocationSetting = appointmentDetailObj.appointmentType && 
451			appointmentDetailObj.appointmentType.isSlotsBasedOnLocation == true;
452		var manualSelection = that.varIsSlotsBasedOnLocation && !sfLocationSetting;
453		
454		if(urlTimezone) {
455			// Priority 1: URL timezone parameter (explicit user intent)
456			// Auto-fix common timezone formatting issues
457			var normalizedTimezone = urlTimezone
458				.split('/')
459				.map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
460				.join('/');
461			
462			// Validate the normalized timezone
463			if (!moment.tz.zone(normalizedTimezone)) {
464				console.error('[TIMEZONE ERROR] Invalid timezone in URL parameter:', urlTimezone, 'normalized to:', normalizedTimezone);
465				
466				// Show error modal and prevent booking
467				setTimeout(function() {
468					$("#errorHandlerModal .modal-header h2").html("<b>Invalid Timezone</b>");
469					$("#errorHandlerModal .modal-header h2").css('color','red');
470					$("#errorHandlerModal .modal-body h2").html(`The timezone "${urlTimezone}
470" is not valid. Please use a proper timezone format like "Australia/Brisbane".`);
471					$('#errorHandlerModal').modal({backdrop: 'static', keyboard: false});
472				}, 500);
473				
474				// Don't proceed with invalid timezone
475				return;
476			}
477			
478			// Log if we auto-fixed the timezone
479			if (normalizedTimezone !== urlTimezone) {
480				console.log('[TIMEZONE] Auto-fixed timezone from', urlTimezone, 'to', normalizedTimezone);
481				
482				// Update the URL parameter globally so all parts of the system use the corrected timezone
483				if (window.history && window.history.replaceState) {
484					var currentUrl = new URL(window.location);
485					currentUrl.searchParams.set('tz', normalizedTimezone);
486					window.history.replaceState({}, '', currentUrl.toString());
487					console.log('[TIMEZONE] Updated URL parameter to use normalized timezone');
488				}
489			}
490			
491			that.varIsSlotsBasedOnLocation = true; // Always enable timezone conversion for URL params
492			var userTimezone = normalizedTimezone;
493			that.varNewDateBasedOnLocation = moment(new Date()).tz(userTimezone);
494			cpMonth = moment(new Date()).tz(userTimezone).month() +1;
495			cpDay = moment(new Date()).tz(userTimezone).date();
496			console.log('[TIMEZONE] Using URL parameter timezone:', userTimezone);
497			
498		} else if(manualSelection) {
499			// Priority 2: Manual user timezone selection (dropdown change)
500			that.varIsSlotsBasedOnLocation = true;
501			var selectedTimezone = that.inputData.locationTimeZoneKey;
502			that.varNewDateBasedOnLocation = moment(new Date()).tz(selectedTimezone);
503			cpMonth = moment(new Date()).tz(selectedTimezone).month() +1;
504			cpDay = moment(new Date()).tz(selectedTimezone).date();
505			console.log('[TIMEZONE] Using manually selected timezone:', selectedTimezone);
506			
507		} else if(sfLocationSetting) {
508			// Priority 3: Salesforce location timezone setting (business rule)
509			that.varIsSlotsBasedOnLocation = true;
510			that.varNewDateBasedOnLocation = moment(new Date()).tz(that.inputData.locationTimeZoneKey);
511			cpMonth =  moment(new Date()).tz(that.inputData.locationTimeZoneKey).month() +1;
512			cpDay = moment(new Date()).tz(that.inputData.locationTimeZoneKey).date();
513			
514			// Update display for SF setting
515			if($("#clientTimezoneNotify-2")){
516				$("#clientTimezoneNotify-2").text(that.inputData.locationTimeZoneKey);
517			}
518			console.log('[TIMEZONE] Using Salesforce location timezone:', that.inputData.locationTimeZoneKey);
519			
520		} else {
521			// Priority 4: Browser timezone (fallback)
522			that.varIsSlotsBasedOnLocation = false;
523			that.varNewDateBasedOnLocation = new Date();
524			cpMonth = new Date().getMonth() +1;
525			cpDay = new Date().getDate();
526			console.log('[TIMEZONE] Using browser timezone');
527		}
528
529		cpMonth = cpMonth > 9 ? cpMonth : '0'+cpMonth;
530		cpDay = cpDay > 9 ? cpDay : '0'+cpDay;
531
532	   if(requiredData.selectPractitionerfornewapp == 'Any'){
533		   var newDataTime = {};
534		   if(Array.isArray(data)){
535				data.map(item=>{
536					if(item.availability){
537						for(let key in item.availability){
538							if(newDataTime[key] && newDataTime[key][0].morning && newDataTime[key][0].evening){
539								newDataTime[key][0].morning = [...newDataTime[key][0].morning, ...item.availability[key][0].morning]
540								newDataTime[key][0].evening = [...newDataTime[key][0].evening, ...item.availability[key][0].evening]
541							}else{
542								newDataTime[key] = item.availability[key];
543							}
544							newDataTime[key][0].morning = [...new Set(newDataTime[key][0].morning)];
545							newDataTime[key][0].evening = [...new Set(newDataTime[key][0].evening)];
546						}
547					}
548				})
549		   }
550
551		   if(Object.keys(newDataTime).length > 0){
552			   data = newDataTime;
553		   }
554	   }
555		var convertedDateSlots = {};
556		if(!that.varIsSlotsBasedOnLocation){
557			if(that.ltime){
558				var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
559				that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
560				let hrs = new Date(leadTimeDate).getHours() >= 10 ? new Date(leadTimeDate).getHours() : '0'+new Date(leadTimeDate).getHours();
561				let minutes = new Date(leadTimeDate).getMinutes() >= 10 ? new Date(leadTimeDate).getMinutes() : '0'+new Date(leadTimeDate).getMinutes();
562				var leadTimeCon = hrs +''+ minutes;
563				that.eveTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
564				that.morTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
565
566			}
567			convertedDateSlots = that.convertTimeSlotsBasedOnTimeZone(data);
568
569		}else if(that.varIsSlotsBasedOnLocation){
570			if(that.ltime){
571				var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
572				var convertedDate = moment(new Date(leadTimeDate)).tz(that.inputData.locationTimeZoneKey);
573				that.leadDate = convertedDate.year() +'-'+ (((convertedDate.month()+1) >= 10)? (convertedDate.month()+1) : '0'+(convertedDate.month()+1)) +'-'+ ((convertedDate.date() >= 10)? ((convertedDate.date())) : ('0'+(convertedDate.date())));
574				let hrs = convertedDate.hours() >= 10 ? convertedDate.hours() : '0'+convertedDate.hours();
575				let minutes = convertedDate.minutes() >= 10 ? convertedDate.minutes() : '0'+convertedDate.minutes();
576				var leadTimeCon = hrs +''+ minutes;
577				that.eveTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
578				that.morTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
579
580			}
581
582			convertedDateSlots = that.convertTimeSlotsDefaultTimeZone(data);
583		}
584
585		if(Object.keys(convertedDateSlots).length > 0){
586			if(Array.isArray(convertedDateSlots)){
587				convertedDateSlots.map(item=>{
588					for (const [key, value] of Object.entries(item.availability)) {
589						let newdate = ''+new Date().getFullYear()+'-'+cpMonth +'-'+ cpDay ;
590						 if(that.varIsSlotsBasedOnLocation){
591							 newdate = '' + that.varNewDateBasedOnLocation.year() + '-' + cpMonth + '-' + cpDay ;
592						 }
593						  if(!(key >= newdate)){
594							  delete item.availability[key];
595						  }
596					  }
597					  return item;
598				})
599
600			}else{
601				for (const [key, value] of Object.entries(convertedDateSlots)) {
602					let newdate = ''+new Date().getFullYear()+'-'+cpMonth +'-'+ cpDay ;
603					if(that.varIsSlotsBasedOnLocation){
604						 newdate = '' + that.varNewDateBasedOnLocation.year() + '-' + cpMonth + '-' + cpDay ;
605					 }
606					if(!(key >= newdate)){
607						delete convertedDateSlots[key];
608					}
609				}
610			}
611
612			var data = convertedDateSlots;
613		}
614		var slotsAvailableDate = "";
615		var isSlotsAvailableDateFound = false;
616		var slotsAvailableDateFound = '';
617		//console.log('updateEvents >>'+JSON.stringify(data));
618		$.each(data, function(key, value) {
619			console.log('[CALENDAR DEBUG] Processing date:', key, 'with slots:', value);
620			var currentDatef = new Date();
621			var currentDate = currentDatef.setDate(currentDatef.getDate() - 1);
622			if((data[key] && data[key].morning && data[key].morning.length != undefined && data[key].evening && data[key].evening.length != undefined && (data[key].morning.length > 0 || data[key].evening.length > 0)) && (new Date(key) >= currentDate) ){
623			   if(that.sdate && that.edate){
624				   if(key >= that.sdate && key <= that.edate){
625					   slotsAvailableDate = key;
626				   }
627			   }else if(that.sdate){
628				   // Single date parameter - only show dates from sdate onwards
629				   if(key >= that.sdate){
630					   slotsAvailableDate = key;
631				   }
632			   }else if(that.lday){
633				   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
634				   if(key >= that.leadDate){
635					   slotsAvailableDate = key;
636				   }
637				}else if(that.ltime){
638				   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
639				   that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
640					if(that.varIsSlotsBasedOnLocation){
641						var convertedDate = moment(new Date(leadTimeDate)).tz(that.inputData.locationTimeZoneKey);
642						that.leadDate = convertedDate.year() +'-'+ (((convertedDate.month()+1) >= 10)? (convertedDate.month()+1) : '0'+(convertedDate.month()+1)) +'-'+ ((convertedDate.date() >= 10)? ((convertedDate.date())) : ('0'+(convertedDate.date())));
643					}
644					if(key >= that.leadDate){
645						slotsAvailableDate = key;
646					}
647					if(key >= that.leadDate && isSlotsAvailableDateFound == false){
648						slotsAvailableDateFound = key;
649						isSlotsAvailableDateFound = true;
650					}
651			   }else{
652				   slotsAvailableDate = key;
653			   }
654
655		   }else{ /* new changes for webform */
656			   if((value.morning == true || value.evening == true) && (new Date(key) >= currentDate)){
657				   that.dataFromSFAPI = true;
658				   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
659					   console.log('lead date');
660					   if(key >= that.sdate && key <= that.edate){
661						   slotsAvailableDate = key;
662					   }
663				   }else if(that.sdate !='' && that.sdate != undefined){
664					   // Single date parameter - only show dates from sdate onwards
665					   if(key >= that.sdate){
666						   slotsAvailableDate = key;
667					   }
668				   }else if(that.lday !='' && that.lday != undefined){
669					   // console.log('lead day');
670					   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
671					   if(key >= that.leadDate){
672						   slotsAvailableDate = key;
673					   }
674					}else if(that.ltime !='' && that.ltime != undefined){
675					   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
676					   that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
677					   if(key >= that.leadDate){
678						   slotsAvailableDate = key;
679					   }
680				   }else{
681					   slotsAvailableDate = key;
682				   }
683				   }else if(Array.isArray(value.morning) == false || Array.isArray(value.morning) == false){
684					that.dataFromSFAPI = true;
685				}
686		   }
687		});
688
689		//console.log('slotsAvailableDate >>'+JSON.stringify(slotsAvailableDate));
690
691		if(slotsAvailableDate == ""){
692			requiredData.appointmentDate = '01,'+ (new Date().getMonth() + 2) + ',' + new Date().getFullYear();
693
694			app.calendar.dataModel.getCalendarData(requiredData).done(
695				function(dataFuture1Month){
696					$.each(dataFuture1Month, function(key, value) {
697						var currentDatef = new Date();
698						var currentDate = currentDatef.setDate(currentDatef.getDate() - 1);
699						if((data[key] && data[key].morning && data[key].morning.length != undefined && data[key].evening && data[key].evening.length != undefined && ((dataFuture1Month[key] && dataFuture1Month[key].morning && dataFuture1Month[key].morning.length > 0) || (dataFuture1Month[key] && dataFuture1Month[key].evening && dataFuture1Month[key].evening.length > 0))) && (new Date(key) >= currentDate)){
700						   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
701							   console.log('lead date');
702							   if(key >= that.sdate && key <= that.edate){
703								   slotsAvailableDate = key;
704							   }
705						   }else if(that.sdate !='' && that.sdate != undefined){
706							   // Single date parameter - only show dates from sdate onwards
707							   if(key >= that.sdate){
708								   slotsAvailableDate = key;
709							   }
710						   }else if(that.lday !='' && that.lday != undefined){
711							   // console.log('lead day');
712							   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
713							   if(key >= that.leadDate){
714								   slotsAvailableDate = key;
715							   }
716							}else if(that.ltime !='' && that.ltime != undefined){
717							   // console.log('lead time');
718							   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
719								that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
720							   if(key >= that.leadDate){
721								   slotsAvailableDate = key;
722							   }
723						   }else{
724							   slotsAvailableDate = key;
725						   }
726						}else{
727						   if((value.morning == true || value.evening == true) && (new Date(key) >= currentDate)){
728							   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
729								   console.log('lead date');
730								   if(key >= that.sdate && key <= that.edate){
731									   slotsAvailableDate = key;
732								   }
733							   }else if(that.sdate !='' && that.sdate != undefined){
734								   // Single date parameter - only show dates from sdate onwards
735								   if(key >= that.sdate){
736									   slotsAvailableDate = key;
737								   }
738							   }else if(that.lday !='' && that.lday != undefined){
739								   // console.log('lead day');
740								   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
741								   if(key >= that.leadDate){
742									   slotsAvailableDate = key;
743								   }
744								}else if(that.ltime !='' && that.ltime != undefined){
745								   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
746								   that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
747								   if(key >= that.leadDate){
748									   slotsAvailableDate = key;
749								   }
750							   }else{
751								   slotsAvailableDate = key;
752							   }
753						   }
754						}
755					});
756					if(slotsAvailableDate == ""){
757					requiredData.appointmentDate = '01,'+ (new Date().getMonth() + 3) + ',' + new Date().getFullYear();
758
759					app.calendar.dataModel.getCalendarData(requiredData).done(
760						function(dataFuture2Month){
761							$.each(dataFuture2Month, function(key, value) {
762								var currentDatef = new Date();
763								var currentDate = currentDatef.setDate(currentDatef.getDate() - 1);
764								if((dataFuture2Month[key] && dataFuture2Month[key].morning && dataFuture2Month[key].morning.length != undefined && dataFuture2Month[key] && dataFuture2Month[key].evening && dataFuture2Month[key].evening.length != undefined && (dataFuture2Month[key] && dataFuture2Month[key].morning && dataFuture2Month[key].morning.length > 0 || dataFuture2Month[key] && dataFuture2Month[key].evening && dataFuture2Month[key].evening.length > 0)) && (new Date(key) >= currentDate)){
765								   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
766									   console.log('lead date');
767									   if(key >= that.sdate && key <= that.edate){
768										   slotsAvailableDate = key;
769									   }
770								   }else if(that.sdate !='' && that.sdate != undefined){
771									   // Single date parameter - only show dates from sdate onwards
772									   if(key >= that.sdate){
773										   slotsAvailableDate = key;
774									   }
775								   }else if(that.lday !='' && that.lday != undefined){
776									   // console.log('lead day');
777									   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
778									   if(key >= that.leadDate){
779										   slotsAvailableDate = key;
780									   }
781									}else if(that.ltime !='' && that.ltime != undefined){
782									   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
783									   that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
784									   if(key >= that.leadDate){
785										   slotsAvailableDate = key;
786									   }
787								   }else{
788									   slotsAvailableDate = key;
789								   }
790								}else{
791								   if((value.morning == true || value.evening == true) && (new Date(key) >= currentDate)){
792									   that.dataFromSFAPI = true;
793									   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
794										   console.log('lead date');
795										   if(key >= that.sdate && key <= that.edate){
796											   slotsAvailableDate = key;
797										   }
798									   }else if(that.sdate !='' && that.sdate != undefined){
799										   // Single date parameter - only show dates from sdate onwards
800										   if(key >= that.sdate){
801											   slotsAvailableDate = key;
802										   }
803									   }else if(that.lday !='' && that.lday != undefined){
804										   // console.log('lead day');
805										   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
806										   if(key >= that.leadDate){
807											   slotsAvailableDate = key;
808										   }
809										}else if(that.ltime !='' && that.ltime != undefined){
810										   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
811										that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
812										   if(key >= that.leadDate){
813											   slotsAvailableDate = key;
814										   }
815									   }else{
816										   slotsAvailableDate = key;
817									   }
818								   }
819								}
820							});
821
822							if(slotsAvailableDate == ""){
823								requiredData.appointmentDate = '01,'+ (new Date().getMonth() + 4) + ',' + new Date().getFullYear();
824
825								app.calendar.dataModel.getCalendarData(requiredData).done(
826									function(dataFuture3Month){
827										$.each(dataFuture3Month, function(key, value) {
828											var currentDatef = new Date();
829											var currentDate = currentDatef.setDate(currentDatef.getDate() - 1);
830											if((dataFuture3Month[key] && dataFuture3Month[key].morning && dataFuture3Month[key].morning.length != undefined && dataFuture3Month[key] && dataFuture3Month[key].evening && dataFuture3Month[key].evening.length != undefined && (dataFuture3Month[key] && dataFuture3Month[key].morning && dataFuture3Month[key].morning.length > 0 || dataFuture3Month[key] && dataFuture3Month[key].evening && dataFuture3Month[key].evening.length > 0)) && (new Date(key) >= currentDate)){
831											   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
832												   console.log('lead date');
833												   if(key >= that.sdate && key <= that.edate){
834													   slotsAvailableDate = key;
835												   }
836											   }else if(that.lday !='' && that.lday != undefined){
837												   // console.log('lead day');
838												   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
839												   if(key >= that.leadDate){
840													   slotsAvailableDate = key;
841												   }
842												}else if(that.ltime !='' && that.ltime != undefined){
843												   // console.log('lead time');
844												   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
845												that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
846												   if(key >= that.leadDate){
847													   slotsAvailableDate = key;
848												   }
849											   }else{
850												   slotsAvailableDate = key;
851											   }
852											}else{
853											   if((value.morning == true || value.evening == true) && (new Date(key) >= currentDate)){
854												   that.dataFromSFAPI = true;
855												   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
856													   console.log('lead date');
857													   if(key >= that.sdate && key <= that.edate){
858														   slotsAvailableDate = key;
859													   }
860												   }else if(that.lday !='' && that.lday != undefined){
861													   // console.log('lead day');
862													   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
863													   if(key >= that.leadDate){
864														   slotsAvailableDate = key;
865													   }
866													}else if(that.ltime !='' && that.ltime != undefined){
867													   // console.log('lead time');
868													   var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
869													   //console.log('leadTimeDate '+ new Date(leadTimeDate).getHours() +'-'+ new Date(leadTimeDate).getMinutes() +'--date'+ new Date(leadTimeDate).getUTCDate() +'/'+(new Date(leadTimeDate).getUTCMonth()+1) +'/'+new Date(leadTimeDate).getFullYear());
870													   var leadTimeCon = new Date(leadTimeDate).getHours() +''+ new Date(leadTimeDate).getMinutes();
871													//    that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getUTCMonth()+1) >= 10)? (new Date(leadTimeDate).getUTCMonth()+1) : '0'+(new Date(leadTimeDate).getUTCMonth()+1)) +'-'+ ((new Date(leadTimeDate).getUTCDate() >= 10)? ((new Date(leadTimeDate).getUTCDate())) : ('0'+(new Date(leadTimeDate).getUTCDate())));
872													that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
873													   //console.log('leadDate '+ that.leadDate + ':'+ 'leadTimeCon '+ leadTimeCon);
874													   if(key >= that.leadDate){
875														   slotsAvailableDate = key;
876													   }
877												   }else{
878													   slotsAvailableDate = key;
879												   }
880											   }
881											}
882										});
883
884										if(slotsAvailableDate == ""){
885											// console.log("Slots are not available for next 3rd month");
886
887											// Add popup here - "Sorry... we couldn't find any available times. Please change your selections and try again."
888											//$("#NoTimeSlotsAvailableModal").modal("show");
889											$('#NoTimeSlotsAvailableModal').modal({backdrop: 'static', keyboard: false});
890											that.clearMorningEveningTimeSlots();
891				 							that.eventsArr = [];
892											 $('#appointmentCalCont').hide();
893											$('.smalloverlay').hide();
894										}
895										else{
896											that.updateEventArr(dataFuture3Month);
897											// start calendar
898											that.startCalendar(slotsAvailableDate, data);
899											$('.smalloverlay').hide();
900											that.futureDateAvailableSlots(slotsAvailableDate, data);
901										}
902									}
903								).fail(function(resp){
904									$('.smalloverlay').hide();
905									app.utility.handleServerError(resp);
906									console.log(resp);
907								});
908								// Add 3 months to get next months availibility...END
909
910							}
911							else{
912								// console.log('check for date 1');
913								that.updateEventArr(dataFuture2Month);
914								// start calendar
915								//that.startCalendar();
916								that.startCalendar(slotsAvailableDate, data);
917								$('.smalloverlay').hide();
918								that.futureDateAvailableSlots(slotsAvailableDate, data);
919							}
920						}
921					).fail(function(resp){
922						$('.smalloverlay').hide();
923						app.utility.handleServerError(resp);
924						console.log(resp);
925					});
926					// Add 2 months to get next months availibility...END
927
928					}
929					else{
930						// console.log('check for date');
931						that.updateEventArr(dataFuture1Month);
932						// start calendar
933						//that.startCalendar();
934						that.startCalendar(slotsAvailableDate, data);
935						$('.smalloverlay').hide();
936						that.futureDateAvailableSlots(slotsAvailableDate, data);
937					}
938				}
939			).fail(function(resp){
940				$('.smalloverlay').hide();
941				app.utility.handleServerError(resp);
942				console.log(resp);
943			});
944			// Add 1 month to get next months availibility...END
945
946
947
948		}
949		else{
950			that.updateEventArr(data);
951			// start calendar
952			//that.startCalendar();
953			let prepCurrentDate = '';
954			//console.log('slotsAvailableDateFound'+JSON.stringify(slotsAvailableDateFound));
955			if(that.varIsSlotsBasedOnLocation){
956				var CurrentDate = moment(new Date()).tz(that.inputData.locationTimeZoneKey);
957				let cDate = CurrentDate.date();
958				let cMonth = CurrentDate.month() + 1;
959				let cYear = CurrentDate.year();
960				prepCurrentDate = cYear + '-' + (cMonth < 10 ?  '0'+cMonth : cMonth) + '-' + (cDate < 10 ? '0'+cDate : cDate);
961				var sortedKeys = Object.keys(data).sort((a, b) => new Date(a) - new Date(b));
962				if(prepCurrentDate < sortedKeys[0]){
963					prepCurrentDate = sortedKeys[0];
964				}
965				if(that.leadDate && that.ltime && prepCurrentDate < that.leadDate){
966					if(slotsAvailableDateFound > that.leadDate){
967						prepCurrentDate = slotsAvailableDateFound;
968					}else{
969						prepCurrentDate = that.leadDate;
970					}
971				}
972			}else{
973				let CurrentDate = new Date();
974				let cDate = CurrentDate.getDate();
975				let cMonth = CurrentDate.getMonth() + 1;
976				let cYear = CurrentDate.getFullYear();
977				prepCurrentDate = cYear + '-' + (cMonth < 10 ?  '0'+cMonth : cMonth) + '-' + (cDate < 10 ? '0'+cDate : cDate);
978				if(that.leadDate && that.ltime && prepCurrentDate < that.leadDate){
979					if(slotsAvailableDateFound > that.leadDate){
980						prepCurrentDate = slotsAvailableDateFound;
981					}else{
982						prepCurrentDate = that.leadDate;
983					}
984				}
985			}
986
987			//added by darshan 2.0
988			if(that.dataFromSFAPI && slotsAvailableDate){
989				prepCurrentDate = slotsAvailableDate;
990			}
991
992			//added by darshan if sdate is present in url then select that date
993			if(that.sdate && data[that.sdate]){
994				prepCurrentDate = that.sdate;
995			}
996			//console.log('prepCurrentDate >>'+JSON.stringify(prepCurrentDate));
997			that.startCalendar(prepCurrentDate, data);
998			$('.smalloverlay').hide();
999
1000			if(data[prepCurrentDate]){
1001			   that.futureDateAvailableSlots(prepCurrentDate, data);
1002			}else{
1003			   //Added By darshan to select by default date
1004			   let selectedDate = [];
1005			   for(let i = 0; i < $('#appointmentCalCont tbody.event-calendar td').length; i++){
1006				   if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('calendar-day') && $('#appointmentCalCont tbody.event-calendar td')[i].hasAttribute('date-month') ){
1007					   if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('current-day') || $('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('active')){
1008						   if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('active')){
1009							   $('#appointmentCalCont tbody.event-calendar td')[i].classList.remove('active');
1010						   }
1011						   if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('calendar-day')){
1012							   $('#appointmentCalCont tbody.event-calendar td')[i].classList.remove('current-day');
1013						   }
1014					   }
1015					   if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('event')){
1016						   $('#appointmentCalCont tbody.event-calendar td')[i].classList.add('active');
1017						   $('#appointmentCalCont tbody.event-calendar td')[i].classList.add('current-day');
1018
1019						   let day = $('#appointmentCalCont tbody.event-calendar td')[i].attributes['date-d
1019ay'].value;
1020						   let month = $('#appointmentCalCont tbody.event-calendar td')[i].attributes['date-month'].value;
1021						   let year = $('#appointmentCalCont tbody.event-calendar td')[i].attributes['date-year'].value;
1022						   selectedDate.push(year);
1023						   selectedDate.push(month);
1024						   selectedDate.push(day);
1025						   //added today 03-02-2023
1026						   that.selectedDate = selectedDate.join('-');
1027
1028						  let currentTD = $('#appointmentCalCont tbody.event-calendar td')[i]
1029
1030						   if ($(currentTD).hasClass('event')) {
1031							   $('tbody.event-calendar td').removeClass('active');
1032							   $(currentTD).addClass('active');
1033							   /* new code for mobile version */
1034							   var screensize = $('body').width();
1035							   var actualScreenWidth = window.screen ? window.screen.width : $(window).width();
1036							   if (screensize <= 699 && actualScreenWidth <= 768) {
1037								   $('.calendar').hide();
1038								   $('.select-date-text').hide();
1039								   $('.change-date-btn').show();
1040								   $('.calendar-details').show();
1041								   $('.timeslot-main').hide();
1042								   $('.am-timeslot-section').css('min-height', '50px');
1043								   $('.smalloverlay-two').show();
1044							   }
1045						   /* end code */
1046
1047							  var dayEvent = $(currentTD).text();
1048							  var monthEvent = $(currentTD).attr('date-month');
1049							  var yearEvent = $(currentTD).attr('date-year');
1050							  that.selectedDate = new Date( monthEvent + '/' + dayEvent + '/' + yearEvent );
1051							  if(monthEvent.toString().length == 1){
1052								  monthEvent = '0'+monthEvent;
1053							  }
1054							  if(dayEvent.toString().length == 1){
1055								  dayEvent = '0'+dayEvent;
1056							  }
1057							  if(that.dataFromSFAPI){
1058								  that.updateEventSlots(dayEvent+','+monthEvent+','+yearEvent);
1059							  }else{
1060								  that.updateEventSlots(yearEvent+'-'+monthEvent+'-'+dayEvent, data);
1061							  }
1062							  var date = monthEvent + '/' + dayEvent + '/' + yearEvent;
1063							  $('#dateSelected').text(moment(new Date(date)).format('Do MMMM YYYY'));
1064						  }
1065						  //end added today 03-02-2023
1066						   break;
1067					   }
1068				   }
1069			   }
1070			   console.log(selectedDate)
1071			   // that.selectedDate = selectedDate.join('-');
1072			}
1073			//end 2.0
1074		}
1075
1076	},
1077
1078	convertTimeSlotsBasedOnTimeZone : function(data){
1079		let convertedDateSlots = {}
1080		let practitionerTimeSlots = []
1081		if(appointmentDetailObj.practitioner.timeSlot){
1082			practitionerTimeSlots = appointmentDetailObj.practitioner.timeSlot.split(";");
1083			practitionerTimeSlots = practitionerTimeSlots.map(function(tslot){
1084				return tslot.substr(2);
1085			});
1086		}
1087		that = this;
1088		if(that.leadDate && that.ltime ){
1089			$.each(data, function(key, value) {
1090				if(key && key >= that.leadDate){
1091					$.each(value, function (index, value) {
1092						if((value && value.morning) || (value && value.evening )){
1093							$.each(value.morning, function(keym, valuem) {
1094								if(valuem != undefined){
1095									var a = valuem.toString();
1096									if(a.length == 3){
1097									a = '0'+a;
1098									}else if(a.length == 2){
1099										a = '00'+a;
1100									}
1101									let time = moment(a,'HHmm').format('hh:mm a');
1102									if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time) || practitionerTimeSlots.length == 0){
1103										var b = ":";
1104										var position = 2;
1105										var output = [a.slice(0, position), b, a.slice(position)].join('');
1106										const datem = key+'T'+output+':00';
1107										// console.log('datem ', datem);
1108										const tzone = that.inputData.slotsTimeZoneKey;
1109										const localDatem = moment.tz(datem, tzone).local().format("YYYY-MM-DDTHHmm");
1110										const dateKey = localDatem.split('T')[0];
1111										if(convertedDateSlots[dateKey] == undefined){
1112											convertedDateSlots[dateKey] = {morning: [], evening: []}
1113										}
1114										// console.log('localDatem ', localDatem);
1115										//const utcDatem = moment.tz(datem, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1116										// newtz = 'Asia/Calcutta';
1117										//const utctoDatemtz = moment.tz(utcDatem, newtz).format("YYYY-MM-DDTHHmm");
1118										if(localDatem.split('T').pop() <= 1200){
1119											convertedDateSlots[dateKey].morning.push(localDatem.split('T').pop());
1120										}else{
1121											convertedDateSlots[dateKey].evening.push(localDatem.split('T').pop());
1122										}
1123									}
1124								}
1125							});
1126
1127							$.each(value.evening, function(keye, valuee) {
1128								if(valuee != undefined){
1129									var c = valuee.toString();
1130									if(c.length == 3){
1131										c = '0'+c;
1132									}else if(c.length == 2){
1133										c = '00'+c;
1134									}
1135									let time = moment(c,'HHmm').format('hh:mm a');
1136									if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time) || practitionerTimeSlots.length == 0){
1137										var d = ":";
1138										var position = 2;
1139										var output = [c.slice(0, position), d, c.slice(position)].join('');
1140										const datee = key+'T'+output+':00';
1141										const tzone = that.inputData.slotsTimeZoneKey;
1142										const localDatee = moment.tz(datee, tzone).local().format("YYYY-MM-DDTHHmm");
1143										const dateKey = localDatee.split('T')[0];
1144										if(convertedDateSlots[dateKey] == undefined){
1145											convertedDateSlots[dateKey] = {morning: [], evening: []}
1146										}
1147										// console.log('localDatee ', localDatee);
1148										//const utcDatee = moment.tz(datee, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1149										// newtz = 'Asia/Calcutta';
1150										//const utctoDateetz = moment.tz(utcDatee, newtz).format("YYYY-MM-DDTHHmm");
1151										if(localDatee.split('T').pop() <= 1200){
1152											convertedDateSlots[dateKey].morning.push(localDatee.split('T').pop());
1153										}else{
1154											convertedDateSlots[dateKey].evening.push(localDatee.split('T').pop());
1155										}
1156									}
1157								}
1158							});
1159						}
1160					});
1161				}
1162
1163			});
1164		}else{
1165			$.each(data, function(key, value) {
1166				$.each(value, function (index, value) {
1167					if((value && value.morning) || (value && value.evening )){
1168						$.each(value.morning, function(keym, valuem) {
1169							if(valuem != undefined){
1170								var a = valuem.toString();
1171								if(a.length == 3){
1172								a = '0'+a;
1173								}else if(a.length == 2){
1174									a = '00'+a;
1175								}
1176								let time = moment(a,'HHmm').format('hh:mm a');
1177								if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time) || practitionerTimeSlots.length == 0){
1178									var b = ":";
1179									var position = 2;
1180									var output = [a.slice(0, position), b, a.slice(position)].join('');
1181									const datem = key+'T'+output+':00';
1182									// console.log('datem ', datem);
1183									const tzone = that.inputData.slotsTimeZoneKey;
1184									const localDatem = moment.tz(datem, tzone).local().format("YYYY-MM-DDTHHmm");
1185									const dateKey = localDatem.split('T')[0];
1186									if(convertedDateSlots[dateKey] == undefined){
1187										convertedDateSlots[dateKey] = {morning: [], evening: []}
1188									}
1189									// console.log('localDatem ', localDatem);
1190									//const utcDatem = moment.tz(datem, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1191									// newtz = 'Asia/Calcutta';
1192									//const utctoDatemtz = moment.tz(utcDatem, newtz).format("YYYY-MM-DDTHHmm");
1193									if(localDatem.split('T').pop() <= 1200){
1194										convertedDateSlots[dateKey].morning.push(localDatem.split('T').pop());
1195									}else{
1196										convertedDateSlots[dateKey].evening.push(localDatem.split('T').pop());
1197									}
1198								}
1199							}
1200						});
1201
1202						$.each(value.evening, function(keye, valuee) {
1203							if(valuee != undefined){
1204								var c = valuee.toString();
1205								if(c.length == 3){
1206									c = '0'+c;
1207								}else if(c.length == 2){
1208									c = '00'+c;
1209								}
1210								let time = moment(c,'HHmm').format('hh:mm a');
1211								if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time) || practitionerTimeSlots.length == 0){
1212									var d = ":";
1213									var position = 2;
1214									var output = [c.slice(0, position), d, c.slice(position)].join('');
1215									const datee = key+'T'+output+':00';
1216									const tzone = that.inputData.slotsTimeZoneKey;
1217									const localDatee = moment.tz(datee, tzone).local().format("YYYY-MM-DDTHHmm");
1218									const dateKey = localDatee.split('T')[0];
1219									if(convertedDateSlots[dateKey] == undefined){
1220										convertedDateSlots[dateKey] = {morning: [], evening: []}
1221									}
1222									// console.log('localDatee ', localDatee);
1223									//const utcDatee = moment.tz(datee, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1224									// newtz = 'Asia/Calcutta';
1225									//const utctoDateetz = moment.tz(utcDatee, newtz).format("YYYY-MM-DDTHHmm");
1226									if(localDatee.split('T').pop() <= 1200){
1227										convertedDateSlots[dateKey].morning.push(localDatee.split('T').pop());
1228									}else{
1229										convertedDateSlots[dateKey].evening.push(localDatee.split('T').pop());
1230									}
1231								}
1232							}
1233						});
1234					}
1235				});
1236
1237			});
1238		}
1239
1240		return convertedDateSlots;
1241	 },
1242
1243	changeTimeZone(date, timeZone) {
1244		if (typeof date === 'string') {
1245		  return new Date(
1246			new Date(date).toLocaleString('en-US', {
1247			  timeZone,
1248			}),
1249		  );
1250		}
1251
1252		return new Date(
1253		  date.toLocaleString('en-US', {
1254			timeZone,
1255		  }),
1256		);
1257	  },
1258
1259	 convertTimeSlotsDefaultTimeZone : function(data){
1260		let convertedDateSlots = {}
1261		let practitionerTimeSlots = []
1262		if(appointmentDetailObj.practitioner.timeSlot){
1263			practitionerTimeSlots = appointmentDetailObj.practitioner.timeSlot.split(";");
1264			practitionerTimeSlots = practitionerTimeSlots.map(function(tslot){
1265				return tslot.substr(2);
1266			});
1267		}
1268		that = this;
1269		if(that.leadDate && that.ltime ){
1270			$.each(data, function(key, value) {
1271				if(key && key >= that.leadDate){
1272					$.each(value, function (index, value) {
1273						if((value && value.morning) || (value && value.evening )){
1274							$.each(value.morning, function(keym, valuem) {
1275								if(valuem != undefined){
1276									var a = valuem.toString();
1277									if(a.length == 3){
1278									a = '0'+a;
1279									}else if(a.length == 2){
1280										a = '00'+a;
1281									}
1282									let time = moment(a,'HHmm').format('hh:mm a');
1283									if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
1284										var b = ":";
1285										var position = 2;
1286										var output = [a.slice(0, position), b, a.slice(position)].join('');
1287										const datem = key+'T'+output+':00';
1288										// console.log('datem ', datem);
1289										const tzone = that.inputData.locationTimeZoneKey;
1290										// const localDatem = moment.tz(datem, tzone).format("YYYY-MM-DDTHHmm");
1291										const localDatem = moment.tz(moment.tz(datem, that.inputData.slotsTimeZoneKey), tzone).format("YYYY-MM-DDTHHmm");
1292										const dateKey = localDatem.split('T')[0];
1293										if(convertedDateSlots[dateKey] == undefined){
1294											convertedDateSlots[dateKey] = {morning: [], evening: []}
1295										}
1296										// console.log('localDatem ', localDatem);
1297										//const utcDatem = moment.tz(datem, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1298										// newtz = 'Asia/Calcutta';
1299										//const utctoDatemtz = moment.tz(utcDatem, newtz).format("YYYY-MM-DDTHHmm");
1300										if(localDatem.split('T').pop() <= 1200){
1301											convertedDateSlots[dateKey].morning.push(localDatem.split('T').pop());
1302										}else{
1303											convertedDateSlots[dateKey].evening.push(localDatem.split('T').pop());
1304										}
1305									}
1306								}
1307							});
1308
1309							$.each(value.evening, function(keye, valuee) {
1310								if(valuee != undefined){
1311									var c = valuee.toString();
1312									if(c.length == 3){
1313										c = '0'+c;
1314									}else if(c.length == 2){
1315										c = '00'+c;
1316									}
1317									let time = moment(c,'HHmm').format('hh:mm a');
1318									if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
1319										var d = ":";
1320										var position = 2;
1321										var output = [c.slice(0, position), d, c.slice(position)].join('');
1322										const datee = key+'T'+output+':00';
1323										const tzone = that.inputData.locationTimeZoneKey;
1324										// const localDatee = moment.tz(datee, tzone).format("YYYY-MM-DDTHHmm");
1325										const localDatee = moment.tz(moment.tz(datee, that.inputData.slotsTimeZoneKey), tzone).format("YYYY-MM-DDTHHmm");
1326										const dateKey = localDatee.split('T')[0];
1327										if(convertedDateSlots[dateKey] == undefined){
1328											convertedDateSlots[dateKey] = {morning: [], evening: []}
1329										}
1330										// console.log('localDatee ', localDatee);
1331										//const utcDatee = moment.tz(datee, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1332										// newtz = 'Asia/Calcutta';
1333										//const utctoDateetz = moment.tz(utcDatee, newtz).format("YYYY-MM-DDTHHmm");
1334										if(localDatee.split('T').pop() <= 1200){
1335											convertedDateSlots[dateKey].morning.push(localDatee.split('T').pop());
1336										}else{
1337											convertedDateSlots[dateKey].evening.push(localDatee.split('T').pop());
1338										}
1339									}
1340								}
1341							});
1342						}
1343					});
1344				}
1345
1346			});
1347		}else{
1348			$.each(data, function(key, value) {
1349				$.each(value, function (index, value) {
1350					if((value && value.morning) || (value && value.evening )){
1351						$.each(value.morning, function(keym, valuem) {
1352							if(valuem != undefined){
1353								var a = valuem.toString();
1354								if(a.length == 3){
1355								a = '0'+a;
1356								}else if(a.length == 2){
1357									a = '00'+a;
1358								}
1359								let time = moment(a,'HHmm').format('hh:mm a');
1360								if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
1361									var b = ":";
1362									var position = 2;
1363									var output = [a.slice(0, position), b, a.slice(position)].join('');
1364									const datem = key+'T'+output+':00';
1365									// console.log('datem ', datem);
1366									const tzone = that.inputData.locationTimeZoneKey;
1367									// const localDatem = moment.tz(datem, tzone).format("YYYY-MM-DDTHHmm");
1368									const localDatem = moment.tz(moment.tz(datem, that.inputData.slotsTimeZoneKey), tzone).format("YYYY-MM-DDTHHmm");
1369									const dateKey = localDatem.split('T')[0];
1370									if(convertedDateSlots[dateKey] == undefined){
1371										convertedDateSlots[dateKey] = {morning: [], evening: []}
1372									}
1373									// console.log('localDatem ', localDatem);
1374									//const utcDatem = moment.tz(datem, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1375									// newtz = 'Asia/Calcutta';
1376									//const utctoDatemtz = moment.tz(utcDatem, newtz).format("YYYY-MM-DDTHHmm");
1377									if(localDatem.split('T').pop() <= 1200){
1378										convertedDateSlots[dateKey].morning.push(localDatem.split('T').pop());
1379									}else{
1380										convertedDateSlots[dateKey].evening.push(localDatem.split('T').pop());
1381									}
1382								}
1383							}
1384						});
1385
1386						$.each(value.evening, function(keye, valuee) {
1387							if(valuee != undefined){
1388								var c = valuee.toString();
1389								if(c.length == 3){
1390									c = '0'+c;
1391								}else if(c.length == 2){
1392									c = '00'+c;
1393								}
1394								let time = moment(c,'HHmm').format('hh:mm a');
1395								if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
1396									var d = ":";
1397									var position = 2;
1398									var output = [c.slice(0, position), d, c.slice(position)].join('');
1399									const datee = key+'T'+output+':00';
1400									const tzone = that.inputData.locationTimeZoneKey;
1401									// const localDatee = moment.tz(datee, tzone).format("YYYY-MM-DDTHHmm");
1402									const localDatee = moment.tz(moment.tz(datee, that.inputData.slotsTimeZoneKey), tzone).format("YYYY-MM-DDTHHmm");
1403									const dateKey = localDatee.split('T')[0];
1404									if(convertedDateSlots[dateKey] == undefined){
1405										convertedDateSlots[dateKey] = {morning: [], evening: []}
1406									}
1407									// console.log('localDatee ', localDatee);
1408									//const utcDatee = moment.tz(datee, tzone).utc().format("YYYY-MM-DDTHH:mm:ss");
1409									// newtz = 'Asia/Calcutta';
1410									//const utctoDateetz = moment.tz(utcDatee, newtz).format("YYYY-MM-DDTHHmm");
1411									if(localDatee.split('T').pop() <= 1200){
1412										convertedDateSlots[dateKey].morning.push(localDatee.split('T').pop());
1413									}else{
1414										convertedDateSlots[dateKey].evening.push(localDatee.split('T').pop());
1415									}
1416								}
1417							}
1418						});
1419					}
1420				});
1421
1422			});
1423		}
1424
1425		return convertedDateSlots;
1426	 },
1427
1428	futureDateAvailableSlots: function(slotsDate, data){
1429		var that = this;
1430		var strDate = slotsDate.split("-");
1431
1432		//var strDate123 = appData.appointmentDate.split(",");
1433		// that.updateEventSlots(strDate[0]+','+ strDate[1] +','+ strDate[2]);
1434		// var date = strDate[1] + '/' + strDate[0] + '/' + strDate[2];
1435
1436		// Prafull getting Invalid date issue while booking - resolve it now
1437
1438		that.selectedDate = new Date( strDate[1] + '/' + strDate[2] + '/' + strDate[0] );
1439	   //  console.log('slotsDate ', slotsDate);
1440	   //  console.log('data ', data);
1441		if(that.dataFromSFAPI){
1442		   that.updateEventSlots(strDate[2]+','+ strDate[1] +','+ strDate[0]);
1443		}else{
1444		   that.updateEventSlots(slotsDate, data);
1445		}
1446
1447		var date = strDate[1] + '/' + strDate[2] + '/' + strDate[0];
1448
1449		//commented by darshan
1450		$('#dateSelected').text(moment(new Date(date)).format('Do MMMM YYYY'));
1451
1452		var remLeadingZeroDate = strDate[2].replace(/^0+/, '');
1453
1454		$('#appointmentCalCont tbody.event-calendar td').removeClass('active');
1455		$("#appointmentCalCont tbody.event-calendar td[date-day='" + remLeadingZeroDate + "']").addClass('active');
1456	},
1457
1458	startCalendar: function(slotsAvailableDate, data1) {
1459	   //  console.log(slotsAvailableDate);
1460	   //  console.log(data1);
1461		var that = this;
1462
1463		var mon = 'M';
1464		var tue = 'T';
1465		var wed = 'W';
1466		var thur = 'T';
1467		var fri = 'F';
1468		var sat = 'S';
1469		var sund = 'S';
1470
1471		/**
1472		 * Get current date
1473		 */
1474		var d = new Date(slotsAvailableDate);
1475		var yearNumber = (new Date(d)).getFullYear();
1476		var strDate = yearNumber + "/" + (d.getMonth() + 1) + "/" + d.getDate();
1477		/**
1478		 * Get current month and set as '.current-month' in title
1479		 */
1480		var monthNumber = d.getMonth() + 1;
1481
1482		function GetMonthName(monthNumber) {
1483			var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
1484			return months[monthNumber - 1];
1485		}
1486
1487		setMonth(monthNumber, mon, tue, wed, thur, fri, sat, sund);
1488
1489		function setMonth(monthNumber, mon, tue, wed, thur, fri, sat, sund) {
1490			$('.month').text(GetMonthName(monthNumber) + ' ' + yearNumber);
1491			$('.month').attr('data-month', monthNumber);
1492			printDateNumber(monthNumber, mon, tue, wed, thur, fri, sat, sund);
1493		}
1494
1495		$('.btn-next').unbind('click');
1496		$('.btn-next').on('click', function(e) {
1497
1498			that.disablePreviousBtn = false;
1499			$('.btn-prev i').removeClass('custom-disabled');
1500
1501			that.clearMorningEveningTimeSlots();
1502			var monthNumber = $('.month').attr('data-month');
1503
1504			var browserCurrentDateTime = new Date();
1505			var browserCurrentDate = browserCurrentDateTime.getDate() +","+ (browserCurrentDateTime.getMonth() + 1) +","+ browserCurrentDateTime.getFullYear();
1506			var browserCurrentTime = moment(browserCurrentDateTime).format("HH:mm");
1507
1508			var requiredData = {
1509				selectLocationfornewapp:that.inputData.selectLocationfornewapp,
1510				selectCategoryfornewapp:that.inputData.selectCategoryfornewapp,
1511				selectatfornewapp:that.inputData.selectatfornewapp,
1512				selectPractitionerfornewapp:that.inputData.selectPractitionerfornewapp,
1513				appointmentDate:'',
1514				isClass:that.inputData.isClass,
1515				fetchMethod:'Fetch_Monthly_Calendar',
1516				isAnyPractitioner:that.inputData.isAnyPractitioner,
1517				locationTimeZoneKey: that.inputData.locationTimeZoneKey,
1518				browserCurrentDate: browserCurrentDate,
1519				browserCurrentTime: browserCurrentTime
1520			};
1521
1522			$('.smalloverlay').show();
1523			var startsFromDay = '';
1524
1525
1526			if (monthNumber > 11) {
1527				$('.month').attr('data-month', '0');
1528				var monthNumber = $('.month').attr('data-month');
1529				yearNumber = yearNumber + 1;
1530
1531				startsFromDay = (monthNumber == new Date().getMonth() ? new Date().getDate() : 1);
1532				requiredData.appointmentDate = startsFromDay+','+(parseInt(monthNumber)+1)+','+yearNumber;
1533				if(that.dataFromSFAPI){
1534					app.calendar.dataModel.getCalendarData(requiredData).done(
1535										function(data){
1536									   that.updateEventArr(data);
1537									   //calendar.startCalendar();
1538									   setMonth(parseInt(monthNumber) + 1, mon, tue, wed, thur, fri, sat, sund);
1539									   updateDefaultdate();
1540									   $('.smalloverlay').hide();
1541								}
1542							).fail(function(resp){
1543								console.log(resp);
1544								$('.smalloverlay').hide();
1545								app.utility.handleServerError(resp);
1546							});
1547				}else{
1548				   that.updateEventArr(data1);
1549				   //calendar.startCalendar();
1550				   setMonth(parseInt(monthNumber) + 1, mon, tue, wed, thur, fri, sat, sund);
1551				   updateDefaultdate();
1552				   $('.smalloverlay').hide();
1553				}
1554
1555
1556			} else {
1557
1558				startsFromDay = (monthNumber == new Date().getMonth() ? new Date().getDate() : 1);
1559				requiredData.appointmentDate = startsFromDay+','+(parseInt(monthNumber)+1)+','+yearNumber;
1560				if(that.dataFromSFAPI){
1561					app.calendar.dataModel.getCalendarData(requiredData).done(
1562										function(data){
1563									   that.updateEventArr(data);
1564									   //calendar.startCalendar();
1565									   setMonth(parseInt(monthNumber) + 1, mon, tue, wed, thur, fri, sat, sund);
1566									   updateDefaultdate();
1567									   $('.smalloverlay').hide();
1568								}
1569							).fail(function(resp){
1570								console.log(resp);
1571								$('.smalloverlay').hide();
1572								app.utility.handleServerError(resp);
1573							});
1574				}else{
1575				   that.updateEventArr(data1);
1576				   //calendar.startCalendar();
1577				   setMonth(parseInt(monthNumber) + 1, mon, tue, wed, thur, fri, sat, sund);
1578				   updateDefaultdate();
1579				   $('.smalloverlay').hide();
1580				}
1581			};
1582
1583
1584		});
1585
1586		//Added By darshan to select by default date
1587		function updateDefaultdate(){
1588			$('.smalloverlay').show();
1589			let selectedDate = [];
1590			if($('#appointmentCalCont')[0].style.display != 'none'){
1591				for(let i = 0; i < $('#appointmentCalCont tbody.event-calendar td').length; i++){
1592					if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('calendar-day') && $('#appointmentCalCont tbody.event-calendar td')[i].hasAttribute('date-month') ){
1593					if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('current-day') || $('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('active')){
1594						if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('active')){
1595							$('#appointmentCalCont tbody.event-calendar td')[i].classList.remove('active');
1596						}
1597						if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('calendar-day')){
1598							$('#appointmentCalCont tbody.event-calendar td')[i].classList.remove('current-day');
1599						}
1600					}
1601					if($('#appointmentCalCont tbody.event-calendar td')[i].classList.contains('event')){
1602						$('#appointmentCalCont tbody.event-calendar td')[i].classList.add('active');
1603						$('#appointmentCalCont tbody.event-calendar td')[i].classList.add('current-day');
1604
1605						let day = $('#appointmentCalCont tbody.event-calendar td')[i].attributes['date-d
1605ay'].value;
1606						let month = $('#appointmentCalCont tbody.event-calendar td')[i].attributes['date-month'].value;
1607						let year = $('#appointmentCalCont tbody.event-calendar td')[i].attributes['date-year'].value;
1608						selectedDate.push(year);
1609						selectedDate.push(month);
1610						selectedDate.push(day);
1611						// console.log(selectedDate)
1612						that.selectedDate = selectedDate.join('-');
1613
1614						let currentTD = $('#appointmentCalCont tbody.event-calendar td')[i]
1615						if ($(currentTD).hasClass('event')) {
1616							$('tbody.event-calendar td').removeClass('active');
1617							$(currentTD).addClass('active');
1618
1619							/* new code for mobile version */
1620							var screensize = $('body').width();
1621							var actualScreenWidth = window.screen ? window.screen.width : $(window).width();
1622							if (screensize <= 699 && actualScreenWidth <= 768) {
1623								$('.calendar').hide();
1624								$('.select-date-text').hide();
1625								$('.change-date-btn').show();
1626								$('.calendar-details').show();
1627								$('.timeslot-main').hide();
1628								$('.am-timeslot-section').css('min-height', '50px');
1629								$('.smalloverlay-two').show();
1630							}
1631						/* end code */
1632
1633							var dayEvent = $(currentTD).text();
1634							var monthEvent = $(currentTD).attr('date-month');
1635							var yearEvent = $(currentTD).attr('date-year');
1636							that.selectedDate = new Date( monthEvent + '/' + dayEvent + '/' + yearEvent );
1637							if(monthEvent.toString().length == 1){
1638								monthEvent = '0'+monthEvent;
1639							}
1640							if(dayEvent.toString().length == 1){
1641								dayEvent = '0'+dayEvent;
1642							}
1643							if(that.dataFromSFAPI){
1644								that.updateEventSlots(dayEvent+','+monthEvent+','+yearEvent);
1645							}else{
1646								that.updateEventSlots(yearEvent+'-'+monthEvent+'-'+dayEvent, data1);
1647							}
1648							var date = monthEvent + '/' + dayEvent + '/' + yearEvent;
1649							$('#dateSelected').text(moment(new Date(date)).format('Do MMMM YYYY'));
1650						}
1651						break;
1652					}
1653					}
1654				}
1655				//  console.log(selectedDate)
1656				$('.smalloverlay').hide();
1657				that.selectedDate = selectedDate.join('-');
1658			}
1659		}
1660
1661		$('.btn-prev').unbind('click');
1662		$('.btn-prev').on('click', function(e) {
1663
1664			if(that.disablePreviousBtn){
1665				return false;
1666			}
1667
1668			that.clearMorningEveningTimeSlots();
1669
1670			var browserCurrentDateTime = new Date();
1671			var browserCurrentDate = browserCurrentDateTime.getDate() +","+ (browserCurrentDateTime.getMonth() + 1) +","+ browserCurrentDateTime.getFullYear();
1672			var browserCurrentTime = moment(browserCurrentDateTime).format("HH:mm");
1673
1674			var requiredData = {
1675				selectLocationfornewapp:that.inputData.selectLocationfornewapp,
1676				selectCategoryfornewapp:that.inputData.selectCategoryfornewapp,
1677				selectatfornewapp:that.inputData.selectatfornewapp,
1678				selectPractitionerfornewapp:that.inputData.selectPractitionerfornewapp,
1679				appointmentDate:'',
1680				isClass:that.inputData.isClass,
1681				fetchMethod:'Fetch_Monthly_Calendar',
1682				isAnyPractitioner:that.inputData.isAnyPractitioner,
1683				locationTimeZoneKey: that.inputData.locationTimeZoneKey,
1684				browserCurrentDate: browserCurrentDate,
1685				browserCurrentTime: browserCurrentTime
1686			};
1687
1688			var monthNumber = $('.month').attr('data-month');
1689			var startsFromDay = '';
1690			$('.smalloverlay').show();
1691
1692			if((monthNumber - 2) == new Date().getMonth()){
1693				that.disablePreviousBtn = true;
1694				$('.btn-prev i').addClass('custom-disabled');
1695			}
1696
1697			if (monthNumber < 2) {
1698				$('.month').attr('data-month', '13');
1699				var monthNumber = $('.month').attr('data-month');
1700				yearNumber = yearNumber - 1;
1701
1702				startsFromDay = ((monthNumber-2) == new Date().getMonth() ? new Date().getDate() : 1);
1703				requiredData.appointmentDate = startsFromDay+','+(parseInt(monthNumber)-1)+','+yearNumber;
1704				if(that.dataFromSFAPI){
1705					app.calendar.dataModel.getCalendarData(requiredData).done(
1706										function(data){
1707									   that.updateEventArr(data);
1708									   //calendar.startCalendar();
1709									   setMonth(parseInt(monthNumber) - 1, mon, tue, wed, thur, fri, sat, sund);
1710									   $('.smalloverlay').hide();
1711								}
1712							).fail(function(resp){
1713								console.log(resp);
1714								$('.smalloverlay').hide();
1715								app.utility.handleServerError(resp);
1716							});
1717				}else{
1718					that.updateEventArr(data1);
1719				   //calendar.startCalendar();
1720				   setMonth(parseInt(monthNumber) - 1, mon, tue, wed, thur, fri, sat, sund);
1721				   updateDefaultdate();
1722				   $('.smalloverlay').hide();
1723				}
1724
1725			} else {
1726				startsFromDay = ((monthNumber-2) == new Date().getMonth() ? new Date().getDate() : 1);
1727				requiredData.appointmentDate = startsFromDay+','+(parseInt(monthNumber)-1)+','+yearNumber;
1728
1729				if(that.dataFromSFAPI){
1730				   app.calendar.dataModel.getCalendarData(requiredData).done(
1731									   function(data){
1732									  that.updateEventArr(data1);
1733									  //calendar.startCalendar();
1734									  setMonth(parseInt(monthNumber) - 1, mon, tue, wed, thur, fri, sat, sund);
1735									  updateDefaultdate();
1736									  $('.smalloverlay').hide();
1737							   }
1738						   ).fail(function(resp){
1739							   console.log(resp);
1740							   $('.smalloverlay').hide();
1741							   app.utility.handleServerError(resp);
1742						   });
1743			   }else{
1744				  that.updateEventArr(data1);
1745				  //calendar.startCalendar();
1746				  setMonth(parseInt(monthNumber) - 1, mon, tue, wed, thur, fri, sat, sund);
1747				  updateDefaultdate();
1748				  $('.smalloverlay').hide();
1749			   }
1750
1751			};
1752
1753
1754
1755
1756		});
1757
1758		/**
1759		 * Get all dates for current month
1760		 */
1761
1762		function printDateNumber(monthNumber, mon, tue, wed, thur, fri, sat, sund) {
1763
1764			$($('tbody.event-calendar tr')).each(function(index) {
1765				$(this).empty();
1766			});
1767
1768			$($('thead.event-days tr')).each(function(index) {
1769				$(this).empty();
1770			});
1771
1772			function getDaysInMonth(month, year) {
1773				// Since no month has fewer than 28 days
1774				var date = new Date(year, month, 1);
1775				var days = [];
1776				while (date.getMonth() === month) {
1777					days.push(new Date(date));
1778					date.setDate(date.getDate() + 1);
1779				}
1780				return days;
1781			}
1782
1783			setDaysInOrder(sund, mon, tue, wed, thur, fri, sat);
1784
1785			function setDaysInOrder(sund, mon, tue, wed, thur, fri, sat) {
1786				$('thead.event-days tr').append('<td>' + sund + '</td><td>' + mon + '</td><td>' + tue + '</td><td>' + wed + '</td><td>' + thur + '</td><td>' + fri + '</td><td>' + sat + '</td>');
1787			};
1788
1789
1790			var daysInMonth = getDaysInMonth(monthNumber - 1, yearNumber);
1791
1792			var monthLength = daysInMonth.length;
1793			var startingDay = daysInMonth[0].getDay();
1794
1795			setDayNumbers(monthLength, startingDay);
1796
1797			function setDayNumbers(monthLength, startingDay){
1798				var day = 1;
1799				// this loop is for is weeks (rows)
1800				var tr = '';
1801				for (var i = 0; i < 9; i++) {
1802					var td = '';
1803					// this loop is for weekdays (cells)
1804					for (var j = 0; j <= 6; j++) {
1805						if (day <= monthLength && (i > 0 || j >= startingDay)) {
1806							td += '<td class="calendar-day" date-month="' + monthNumber + '" date-day="' + day + '" date-year="' + yearNumber + '">';
1807							td += day;
1808							td += '</td>';
1809							day++;
1810						}else{
1811							td += '<td class="calendar-day-empty"></td>';
1812						}
1813					}
1814					// stop making rows if we've run out of days
1815					if (day > monthLength) {
1816						tr += '<tr class="row'+(i+1)+'">'+td+'</tr>';
1817						break;
1818					} else {
1819						tr += '<tr class="row'+(i+1)+'">'+td+'</tr>';
1820					}
1821				}
1822				$('tbody.event-calendar').empty().append(tr);
1823			}
1824
1825
1826			var date = new Date();
1827			var month = date.getMonth() + 1;
1828			var thisyear = new Date().getFullYear();
1829			setCurrentDay(month, thisyear);
1830			setEvent();
1831			//displayEvent();
1832		}
1833
1834		/**
1835		 * Get current day and set as '.current-day'
1836		 */
1837		function setCurrentDay(month, year) {
1838			var viewMonth = $('.month').attr('data-month');
1839			if (parseInt(year) === yearNumber) {
1840				if (parseInt(month) === parseInt(viewMonth)) {
1841					$('tbody.event-calendar td[date-day="' + d.getDate() + '"]').addClass('current-day');
1842				}
1843			}
1844		};
1845
1846		/**
1847		 * Add class '.active' on calendar date
1848		 */
1849		$('#appointmentCalCont').off('click','tbody td').on('click','tbody td', function(e) {
1850			// Check if date locking is enabled and this is not the selected date
1851			if (that.lockDate && that.sdate && $(this).hasClass('event')) {
1852				var dayEvent = $(this).text();
1853				var monthEvent = $(this).attr('date-month');
1854				var yearEvent = $(this).attr('date-year');
1855				var clickedDate = yearEvent + '-' + (monthEvent.length === 1 ? '0' + monthEvent : monthEvent) + '-' + (dayEvent.length === 1 ? '0' + dayEvent : dayEvent);
1856				
1857				// Only allow clicks on the preselected date
1858				if (clickedDate !== that.sdate) {
1859					e.preventDefault();
1860					e.stopPropagation();
1861					return false;
1862				}
1863			}
1864			
1865			if ($(this).hasClass('event')) {
1866				$('tbody.event-calendar td').removeClass('active');
1867				$(this).addClass('active');
1868				
1869				 /* new code for mobile version */
1870				 var screensize = $('body').width();
1871				 var actualScreenWidth = window.screen ? window.screen.width : $(window).width();
1872				 if(screensize <= 699 && actualScreenWidth <= 768){
1873						 $('.calendar').hide();
1874						 $('.select-date-text').hide();
1875						 $('.change-date-btn').show();
1876						 $('.calendar-details').show();
1877						 $('.timeslot-main').hide();
1878						 $('.am-timeslot-section').css('min-height', '50px');
1879						 $('.smalloverlay-two').show();
1880				 }
1881				 /* end code */
1882				var dayEvent = $(this).text();
1883				var monthEvent = $(this).attr('date-month');
1884				var yearEvent = $(this).attr('date-year');
1885				
1886				// Fire custom DOM event for date selection tracking
1887				// console.log('Date selected, firing custom event');
1888				const dateSelectionEvent = new CustomEvent('appointmentDateSelected', {
1889					detail: {
1890						date: dayEvent + '/' + monthEvent + '/' + yearEvent,
1891						formId: 1
1892					}
1893				});
1894				document.dispatchEvent(dateSelectionEvent);
1895				that.selectedDate = new Date( monthEvent + '/' + dayEvent + '/' + yearEvent );
1896			   if(monthEvent.toString().length == 1){
1897				   monthEvent = '0'+monthEvent;
1898			   }
1899			   if(dayEvent.toString().length == 1){
1900				   dayEvent = '0'+dayEvent;
1901			   }
1902			   if(that.dataFromSFAPI){
1903				   that.updateEventSlots(dayEvent+','+monthEvent+','+yearEvent);
1904				}else{
1905				   that.updateEventSlots(yearEvent+'-'+monthEvent+'-'+dayEvent, data1);
1906				}
1907				var date = monthEvent + '/' + dayEvent + '/' + yearEvent;
1908				$('#dateSelected').text(moment(new Date(date)).format('Do MMMM YYYY'));
1909			}
1910		});
1911
1912		/**
1913		 * Add '.event' class to all days that has an event
1914		 */
1915		function setEvent() {
1916			that.eventsArr.forEach(function(obj, index){
1917				var eventMonth = obj.month;
1918				var eventDay = obj.day;
1919				var eventYear = obj.year;
1920				var eventClasse = obj.events;
1921				var eventClass = undefined;
1922				if (eventClass === undefined) eventClass = 'event';
1923				else eventClass = 'event ' + eventClass;
1924				if (parseInt(eventYear) === yearNumber) {
1925					$('tbody.event-calendar tr td[date-month="' + eventMonth + '"][date-day="' + eventDay + '"]').addClass(eventClass);
1926					
1927					// Add locked class for date locking feature
1928					if (that.lockDate && that.sdate) {
1929						var currentDate = eventYear + '-' + (eventMonth.length === 1 ? '0' + eventMonth : eventMonth) + '-' + (eventDay.length === 1 ? '0' + eventDay : eventDay);
1930						if (currentDate !== that.sdate) {
1931							$('tbody.event-calendar tr td[date-month="' + eventMonth + '"][date-day="' + eventDay + '"]').addClass('date-locked');
1932						}
1933					}
1934					if(eventClasse.morning){
1935						if( document.location.origin == 'https://baycounty-mi.appointiv.com'){
1936							$('tbody.event-calendar tr td[date-month="' + eventMonth + '"][date-day="' + eventDay + '"]').append('<div class=""></div>');
1937						}else{
1938							$('tbody.event-calendar tr td[date-month="' + eventMonth + '"][date-day="' + eventDay + '"]').append('<div class=""></div>');
1939						}
1940
1941					}
1942					if(eventClasse.evening){
1943						if( document.location.origin == 'https://baycounty-mi.appointiv.com'){
1944							$('tbody.event-calendar tr td[date-month="' + eventMonth + '"][date-day="' + eventDay + '"]').append('<div class=""></div>');
1945						}else{
1946							$('tbody.event-calendar tr td[date-month="' + eventMonth + '"][date-day="' + eventDay + '"]').append('<div class=""></div>');
1947						}
1948
1949					}
1950				}
1951			});
1952		};
1953
1954		$('#dateSelected').text(moment(new Date()).format('Do MMMM YYYY'));
1955	},
1956
1957	updateEventArr: function(data){
1958		var that = this;
1959		that.eventsArr = [];
1960		for(var date in data){
1961			if(that.dataFromSFAPI == false && (!(data[date].morning.length === 0) || !(data[date].evening.length === 0)) && (data[date].morning.length != undefined && data[date].evening.length != undefined)){ // new change for webfrom
1962				// console.log('data coming from DB');
1963				if(!app.utility.isPastDate(date)){
1964					var obj = {};
1965					if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
1966						if(date >
1966= that.sdate && date <= that.edate){
1967							obj['day'] = new Date(date).getUTCDate();
1968							obj['month'] = new Date(date).getUTCMonth()+1;
1969							obj['year'] = new Date(date).getFullYear();
1970							obj['events'] = {
1971								morning:data[date].morning,
1972								evening:data[date].evening
1973							}
1974						}
1975					}else if(that.sdate !='' && that.sdate != undefined){
1976						// Single date parameter - only show dates from sdate onwards
1977						if(date >= that.sdate){
1978							obj['day'] = new Date(date).getUTCDate();
1979							obj['month'] = new Date(date).getUTCMonth()+1;
1980							obj['year'] = new Date(date).getFullYear();
1981							obj['events'] = {
1982								morning:data[date].morning,
1983								evening:data[date].evening
1984							}
1985						}
1986					}else if(that.lday !='' && that.lday != undefined){
1987						that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
1988						if(date >= that.leadDate){
1989							obj['day'] = new Date(date).getUTCDate();
1990							obj['month'] = new Date(date).getUTCMonth()+1;
1991							obj['year'] = new Date(date).getFullYear();
1992							obj['events'] = {
1993								morning:data[date].morning,
1994								evening:data[date].evening
1995							}
1996						}
1997					}else if(that.ltime !='' && that.ltime != undefined){
1998						var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
1999						if(that.varIsSlotsBasedOnLocation){
2000							var convertedDate = moment(new Date(leadTimeDate)).tz(that.inputData.locationTimeZoneKey);
2001							that.leadDate = convertedDate.year() +'-'+ (((convertedDate.month()+1) >= 10)? (convertedDate.month()+1) : '0'+(convertedDate.month()+1)) +'-'+ ((convertedDate.date() >= 10)? ((convertedDate.date())) : ('0'+(convertedDate.date())));
2002							let hrs = convertedDate.hours() >= 10 ? convertedDate.hours() : '0'+convertedDate.hours();
2003							let minutes = convertedDate.minutes() >= 10 ? convertedDate.minutes() : '0'+convertedDate.minutes();
2004							var leadTimeCon = hrs +''+ minutes;
2005							that.eveTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
2006							that.morTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
2007
2008
2009						}else{
2010							that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
2011							let hrs = new Date(leadTimeDate).getHours() >= 10 ? new Date(leadTimeDate).getHours() : '0'+new Date(leadTimeDate).getHours();
2012							let minutes = new Date(leadTimeDate).getMinutes() >= 10 ? new Date(leadTimeDate).getMinutes() : '0'+new Date(leadTimeDate).getMinutes();
2013							var leadTimeCon = hrs +''+ minutes;
2014							that.eveTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
2015							that.morTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
2016						}
2017						if(date >= that.leadDate){
2018							obj['day'] = new Date(date).getUTCDate();
2019							obj['month'] = new Date(date).getUTCMonth()+1;
2020							obj['year'] = new Date(date).getFullYear();
2021							obj['events'] = {
2022								morning:data[date].morning,
2023								evening:data[date].evening
2024							}
2025						}
2026					}else{
2027						obj['day'] = new Date(date).getUTCDate();
2028						obj['month'] = new Date(date).getUTCMonth()+1;
2029						obj['year'] = new Date(date).getFullYear();
2030						obj['events'] = {
2031							morning:data[date].morning,
2032							evening:data[date].evening
2033						}
2034					}/* code end */
2035					that.eventsArr.push(obj);
2036				}
2037			}else{
2038			   if(!(data[date].morning === false && data[date].evening === false)){
2039				   		// console.log('data coming from SF');
2040				   if(!app.utility.isPastDate(date)){
2041					   var obj = {};
2042					   if(that.sdate !='' && that.edate != '' && that.sdate != undefined && that.edate != undefined){
2043						   if(date >
2043= that.sdate && date <= that.edate){
2044							   obj['day'] = new Date(date).getUTCDate();
2045							   obj['month'] = new Date(date).getUTCMonth()+1;
2046							   obj['year'] = new Date(date).getFullYear();
2047							   obj['events'] = {
2048								   morning:data[date].morning,
2049								   evening:data[date].evening
2050							   }
2051						   }
2052					   }else if(that.sdate !='' && that.sdate != undefined){
2053						   // Single date parameter - only show dates from sdate onwards
2054						   if(date >= that.sdate){
2055							   obj['day'] = new Date(date).getUTCDate();
2056							   obj['month'] = new Date(date).getUTCMonth()+1;
2057							   obj['year'] = new Date(date).getFullYear();
2058							   obj['events'] = {
2059								   morning:data[date].morning,
2060								   evening:data[date].evening
2061							   }
2062						   }
2063					   }else if(that.lday !='' && that.lday != undefined){
2064						   that.leadDate = new Date().getFullYear() +'-'+ (((new Date().getUTCMonth()+1) >= 10)? (new Date().getUTCMonth()+1) : '0'+(new Date().getUTCMonth()+1)) +'-'+ (((new Date().getUTCDate() + parseInt(that.lday)) >= 10)? ((new Date().getUTCDate() + parseInt(that.lday))) : ('0'+(new Date().getUTCDate()+parseInt(that.lday))));
2065						   if(date >= that.leadDate){
2066							   		// console.log('leadDate '+that.leadDate);
2067							   obj['day'] = new Date(date).getUTCDate();
2068							   obj['month'] = new Date(date).getUTCMonth()+1;
2069							   obj['year'] = new Date(date).getFullYear();
2070							   obj['events'] = {
2071								   morning:data[date].morning,
2072								   evening:data[date].evening
2073							   }
2074						   }
2075					   }else if(that.ltime !='' && that.ltime != undefined){
2076							var leadTimeDate = new Date().setHours(new Date().getHours() + parseInt(that.ltime));
2077							that.leadDate = new Date(leadTimeDate).getFullYear() +'-'+ (((new Date(leadTimeDate).getMonth()+1) >= 10)? (new Date(leadTimeDate).getMonth()+1) : '0'+(new Date(leadTimeDate).getMonth()+1)) +'-'+ ((new Date(leadTimeDate).getDate() >= 10)? ((new Date(leadTimeDate).getDate())) : ('0'+(new Date(leadTimeDate).getDate())));
2078							let hrs = new Date(leadTimeDate).getHours() >= 10 ? new Date(leadTimeDate).getHours() : '0'+new Date(leadTimeDate).getHours();
2079							let minutes = new Date(leadTimeDate).getMinutes() >= 10 ? new Date(leadTimeDate).getMinutes() : '0'+new Date(leadTimeDate).getMinutes();
2080							var leadTimeCon = hrs +''+ minutes;
2081							that.eveTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
2082							that.morTime = (leadTimeCon.length < 4)? '0'+leadTimeCon : leadTimeCon;
2083
2084							if(date >= that.leadDate){
2085								obj['day'] = new Date(date).getUTCDate();
2086								obj['month'] = new Date(date).getUTCMonth()+1;
2087								obj['year'] = new Date(date).getFullYear();
2088								obj['events'] = {
2089									morning:data[date].morning,
2090									evening:data[date].evening
2091								}
2092							}
2093					   }else{
2094						   obj['day'] = new Date(date).getUTCDate();
2095						   obj['month'] = new Date(date).getUTCMonth()+1;
2096						   obj['year'] = new Date(date).getFullYear();
2097						   obj['events'] = {
2098							   morning:data[date].morning,
2099							   evening:data[date].evening
2100						   }
2101					   }
2102					   that.eventsArr.push(obj);
2103				   }
2104			   }
2105			}
2106		}
2107	},
2108
2109	clearMorningEveningTimeSlots: function(){
2110		$('#morningAppointmentSlots, #eveningAppointmentSlots').html('');
2111	},
2112
2113	getSelectedDate: function(){
2114		var that = this;
2115		return that.selectedDate;
2116	},
2117
2118	isContainsTimeSlot: function(tArr, t){
2119		var flag = false;
2120
2121		if(tArr.length === 0){
2122			flag = true;
2123		}
2124
2125		for(var i=0; i<tArr.length; i++){
2126			if(t.match(tArr[i])){
2127				flag = true;
2128				break;
2129			}
2130		}
2131		return flag;
2132	},
2133
2134	isPastTimeWithTimeZone: function(time, tzone){
2135		var currentTime = moment(new Date()).tz(tzone).format('HHmm');
2136		currentTime = parseInt(currentTime);
2137		var providedTime = parseInt(time);
2138		if(providedTime >= currentTime){
2139			return false;
2140		}else{
2141			return true;
2142		}
2143	},
2144
2145	checkTimeAvailabilityAfterProcessing: function(targetDate, targetTime, userSpecifiedTz) {
2146		const that = this;
2147		console.log('Availability check after processing:', {targetDate, targetTime, userSpecifiedTz});
2148		
2149		// Check if timezone conversion is enabled
2150		const isTimezoneConversionEnabled = appointmentDetailObj.appointmentType && 
2151											appointmentDetailObj.appointmentType.isSlotsBasedOnLocation;
2152		
2153		// Determine the timezone to use for validation
2154		const providerTz = that.originalProviderTimeZone || that.inputData.locationTimeZoneKey;
2155		let validationTz;
2156		
2157		if (userSpecifiedTz) {
2158			// User specified timezone in URL (tz param)
2159			validationTz = userSpecifiedTz;
2160		} else if (isTimezoneConversionEnabled) {
2161			// No tz param but isSlotsBasedOnLocation=true → treat st time as provider timezone
2162			validationTz = providerTz;
2163			console.log('[VALIDATION FIX] No tz param but isSlotsBasedOnLocation=true, treating time as provider timezone:', providerTz);
2164		} else {
2165			// No tz param and isSlotsBasedOnLocation=false → use browser timezone
2166			validationTz = moment.tz.guess();
2167		}
2168		
2169		// Get the raw data that was cached
2170		const rawData = that.defaultWithoutConvertedSlots;
2171		if (!rawData) {
2172			console.log('Availability check: No raw data available');
2173			return false;
2174		}
2175		
2176		// Now validate using the correct timezone
2177		let searchDate, comparisonTime24;
2178		
2179		if (validationTz === providerTz) {
2180			// Validation timezone is same as provider timezone - direct comparison
2181			searchDate = targetDate;
2182			comparisonTime24 = moment(targetTime, 'HH:mm').format('HHmm');
2183			
2184			console.log('Availability check: Direct provider timezone validation', {
2185				searchDate,
2186				comparisonTime24,
2187				validationTz
2188			});
2189			
2190		} else {
2191			// Need to convert validation timezone to provider timezone for comparison
2192			const validationDateTime = moment.tz(`${targetDate} ${targetTime}`, 'YYYY-MM-DD HH:mm', validationTz);
2193			const providerDateTime = validationDateTime.clone().tz(providerTz);
2194			
2195			searchDate = providerDateTime.format('YYYY-MM-DD');
2196			comparisonTime24 = providerDateTime.format('HHmm');
2197			
2198			console.log('Availability check: Converting validation timezone to provider timezone', {
2199				validationInput: `${targetDate} ${targetTime} (${validationTz})`,
2200				providerEquivalent: `${searchDate} ${comparisonTime24} (${providerTz})`
2201			});
2202		}
2203		
2204		// Check against raw data
2205		if (rawData[searchDate]) {
2206			const dayData = rawData[searchDate];
2207			if (Array.isArray(dayData)) {
2208				for (let i = 0; i < dayData.length; i++) {
2209					const timeSlotGroup = dayData[i];
2210					
2211					// Check morning and evening slots
2212					const checkSlots = (slots) => {
2213						if (slots && Array.isArray(slots)) {
2214							for (let j = 0; j < slots.length; j++) {
2215								const slotTime = slots[j].toString().padStart(4, '0');
2216								if (slotTime === comparisonTime24) {
2217									return true;
2218								}
2219							}
2220						}
2221						return false;
2222					};
2223					
2224					if (checkSlots(timeSlotGroup.morning) || checkSlots(timeSlotGroup.evening)) {
2225						console.log('Availability check: Found matching time slot');
2226						return true;
2227					}
2228				}
2229			}
2230		}
2231		
2232		console.log('Availability check: No matching slots found');
2233		return false;
2234	},
2235
2236	checkTimeAvailabilityForDirectBooking: function(data, targetDate, targetTime, userSpecifiedTz) {
2237		const that = this;
2238		// Use the ORIGINAL provider timezone (before URL override), not the URL-overridden timezone
2239		const providerTz = that.originalProviderTimeZone || that.inputData.locationTimeZoneKey;
2240
2241		// The user's specified timezone (from URL) or their local timezone
2242		const userTz = userSpecifiedTz || moment.tz.guess();
2243
2244		// Check if timezone conversion is enabled
2245		const isTimezoneConversionEnabled = appointmentDetailObj.appointmentType && 
2246											appointmentDetailObj.appointmentType.isSlotsBasedOnLocation;
2247
2248		let searchDate, comparisonTime24;
2249		
2250		if (isTimezoneConversionEnabled) {
2251			// When timezone conversion is enabled, we need to convert the user's date/time to provider timezone
2252			// to find the correct date key in the raw server data (which is in provider timezone)
2253			const userDateTime = moment.tz(`${targetDate} ${targetTime}`, 'YYYY-MM-DD HH:mm', userTz);
2254			const providerDateTime = userDateTime.clone().tz(providerTz);
2255			
2256			searchDate = providerDateTime.format('YYYY-MM-DD');
2257			comparisonTime24 = providerDateTime.format('HHmm');
2258			console.log('Availability check: Converting user date/time to provider timezone for raw data lookup');
2259		} else {
2260			// When no timezone conversion, search the user date directly and convert time to provider timezone
2261			const specifiedDateTime = moment.tz(`${targetDate} ${targetTime}`, 'YYYY-MM-DD HH:mm', userTz);
2262			const providerDateTime = specifiedDateTime.clone().tz(providerTz);
2263			
2264			searchDate = targetDate;
2265			comparisonTime24 = providerDateTime.format('HHmm');
2266			console.log('Availability check: Using user date, converting time to provider timezone');
2267		}
2268		
2269		console.log('Availability check debug:', {
2270			targetDate,
2271			targetTime,
2272			userTz,
2273			providerTz,
2274			isTimezoneConversionEnabled,
2275			searchDate,
2276			comparisonTime24,
2277			dataKeys: Object.keys(data)
2278		});
2279
2280		// Check if the search date exists in calendar data
2281		if (!data[searchDate]) {
2282			console.log('Availability check: Date not found in calendar data, searchDate:', searchDate);
2283			return false;
2284		}
2285
2286		const dayData = data[searchDate];
2287		console.log('Availability check: dayData structure:', dayData);
2288
2289		// The data structure is: "2025-09-03": [{ "morning": [...], "evening": [...] }]
2290		// So dayData is an array of objects
2291		if (Array.isArray(dayData)) {
2292			for (let i = 0; i < dayData.length; i++) {
2293				const timeSlotGroup = dayData[i];
2294				console.log('Availability check: timeSlotGroup', i, ':', timeSlotGroup);
2295
2296				// Check morning slots
2297				if (timeSlotGroup.morning && Array.isArray(timeSlotGroup.morning)) {
2298					console.log('Availability check: morning slots:', timeSlotGroup.morning);
2299					for (let j = 0; j < timeSlotGroup.morning.length; j++) {
2300						const slotTime = timeSlotGroup.morning[j].toString().padStart(4, '0');
2301						console.log('Availability check: checking morning slot:', slotTime, 'vs', comparisonTime24);
2302						if (slotTime === comparisonTime24) {
2303							console.log('Availability check: FOUND matching morning slot!');
2304							return true;
2305						}
2306					}
2307				}
2308
2309				// Check evening slots
2310				if (timeSlotGroup.evening && Array.isArray(timeSlotGroup.evening)) {
2311					console.log('Availability check: evening slots:', timeSlotGroup.evening);
2312					for (let j = 0; j < timeSlotGroup.evening.length; j++) {
2313						const slotTime = timeSlotGroup.evening[j].toString().padStart(4, '0');
2314						console.log('Availability check: checking evening slot:', slotTime, 'vs', comparisonTime24);
2315						if (slotTime === comparisonTime24) {
2316							console.log('Availability check: FOUND matching evening slot!');
2317							return true;
2318						}
2319					}
2320				}
2321			}
2322		}
2323
2324		console.log('Availability check: No matching time slots found');
2325		return false;
2326	},
2327
2328	applyDatePreselection: function() {
2329		const selectedDate = getUrlParameter('sd');
2330		
2331		if (selectedDate && this.lockDate) {
2332			// Apply date locking - disable all dates except the selected one
2333			$('.calendar td.calendar-day:not(.calendar-day[data-date="' + selectedDate + '"])').each(function() {
2334				$(this).addClass('date-locked');
2335				$(this).css({
2336					'opacity': '0.3',
2337					'pointer-events': 'none',
2338					'background-color': '#f5f5f5'
2339				});
2340			});
2341		}
2342		
2343		if (selectedDate) {
2344			// Preselect the date (click on it programmatically)
2345			const $targetDate = $('.calendar td.calendar-day[data-date="' + selectedDate + '"]');
2346			if ($targetDate.length > 0) {
2347				// Trigger the date selection
2348				$targetDate.trigger('click');
2349			}
2350		}
2351	},
2352
2353	applyTimeSlotLockingAndPreselection: function(retryCount) {
2354		var that = this;
2355		retryCount = retryCount || 0;
2356		
2357		// Only proceed if we have time slots to process (need selectedTime for preselection OR lockTime for locking)
2358		if (that.selectedTime || that.lockTime) {
2359			var $timeSlots = $('#morningAppointmentSlots .slide-box, #eveningAppointmentSlots .slide-box');
2360			
2361			// If no time slots found and we haven't retried too many times, wait and retry
2362			if ($timeSlots.length === 0 && retryCount < 10) {
2363				setTimeout(function() {
2364					that.applyTimeSlotLockingAndPreselection(retryCount + 1);
2365				}, 200 + (retryCount * 100)); // Increasing delay
2366				return;
2367			}
2368			
2369			if ($timeSlots.length === 0) {
2370				console.warn('Time slots not found after multiple retries');
2371				return;
2372			}
2373			
2374			$timeSlots.each(function() {
2375				var $slot = $(this);
2376				var slotTime = $slot.find('h3').text();
2377				
2378				// Skip empty slots
2379				if (!slotTime.trim()) return;
2380				
2381				var slotTime24 = moment(slotTime, 'hh:mm a').format('HHmm');
2382				var selectedTime24 = null;
2383				
2384				if (that.selectedTime) {
2385					if (that.selectedTimeZone) {
2386						// tz parameter provided - st is in this timezone, convert to local for comparison
2387						var specifiedTime = moment.tz(that.selectedTime, ['HH:mm', 'HHmm', 'hh:mm a'], that.selectedTimeZone);
2388						var localTime = specifiedTime.local();
2389						selectedTime24 = localTime.format('HHmm');
2390					} else {
2391						// No tz parameter - assume st is already in correct timezone for comparison
2392						selectedTime24 = moment(that.selectedTime, ['HH:mm', 'HHmm', 'hh:mm a']).format('HHmm');
2393					}
2394				}
2395				
2396				if (that.selectedTime && slotTime24 === selectedTime24) {
2397					// Preselect the specified time (regardless of locking)
2398					$slot.removeClass('time-locked').addClass('active time-preselected');
2399					// Trigger click to update appointment details
2400					$slot.click();
2401				} else if (that.lockTime && that.selectedTime) {
2402					// Only lock other times if lockTime is explicitly enabled
2403					$slot.addClass('time-locked');
2404				}
2405			});
2406		}
2407	},
2408
2409	updateEventSlots: function(date, data){
2410		var that = this;
2411		var requiredData = {
2412			selectLocationfornewapp:that.inputData.selectLocationfornewapp,
2413			selectCategoryfornewapp:that.inputData.selectCategoryfornewapp,
2414			selectatfornewapp:that.inputData.selectatfornewapp,
2415			selectPractitionerfornewapp:that.inputData.selectPractitionerfornewapp,
2416			isClass:that.inputData.isClass,
2417			appointmentDate:date,
2418			fetchMethod:'Fetch_Daily_Available_TimeSlot',
2419			isAnyPractitioner:that.inputData.isAnyPractitioner,
2420			locationTimeZoneKey: that.inputData.locationTimeZoneKey
2421		};
2422
2423		$('.smalloverlay').show();
2424
2425		if(that.dataFromSFAPI){
2426		   app.calendar.dataModel.getCalendarData(requiredData).done(
2427			   function(data){
2428				   try{
2429					   if($('.slickSlider').hasClass('slick-initialized')){
2430						   $('.slickSlider').slick('unslick');
2431					   }
2432				   } catch(e){
2433					   console.log(e);
2434				   }
2435
2436				   that.clearMorningEveningTimeSlots();
2437
2438				   var _date_arr = date.split(",");
2439				   var _date = _date_arr[2] +"/"+ _date_arr[1] +"/"+ _date_arr[0];
2440
2441				   var practitionerTimeSlots = [];
2442
2443				   if(appointmentDetailObj.practitioner.timeSlot){
2444					   practitionerTimeSlots = appointmentDetailObj.practitioner.timeSlot.split(";");
2445					   practitionerTimeSlots = practitionerTimeSlots.map(function(tslot){
2446						   return tslot.substr(2);
2447					   });
2448				   }
2449				   if(data && data.morning){
2450					   data.morning = data.morning || [];
2451				   }
2452				   if(data && data.evening){
2453					   data.evening = data.evening || [];
2454				   }
2455
2456				   if(!requiredData.isClass){
2457						if(data && data.morning){
2458							data.morning.sort(function(a,b){
2459								return a - b;
2460							});
2461						}
2462						if(data && data.evening){
2463							data.evening.sort(function(a,b){
2464								return a - b;
2465							});
2466						}
2467				   }else{
2468					   if(Object.keys(data.morning).length > 0){
2469						   var new_time_array = [];
2470						   for(var obj in data.morning){
2471							   var new_time_obj = {'appIdKey': obj, 'appTimeValue': data.morning[obj]};
2472							   new_time_array.push(new_time_obj);
2473						   }
2474						   new_time_array.sort(function (x, y) {
2475							   return x.appTimeValue - y.appTimeValue;
2476						   });
2477						   var new_mrng = {};
2478						   for(var i = 0; i < new_time_array.length; i++) {
2479							   new_mrng[new_time_array[i].appIdKey] = new_time_array[i].appTimeValue;
2480						   }
2481						   data.morning = new_mrng;
2482					   }
2483
2484					   if( Object.keys(data.evening).length > 0){
2485						   var new_time_array_e = [];
2486						   for(var obj in data.evening){
2487							   var new_time_obj = {'appIdKey': obj, 'appTimeValue': data.evening[obj]};
2488							   new_time_array_e.push(new_time_obj);
2489						   }
2490						   new_time_array_e.sort(function (x, y) {
2491							   return x.appTimeValue - y.appTimeValue;
2492						   });
2493						   var new_evng = {};
2494						   for(var i = 0; i < new_time_array_e.length; i++) {
2495							   new_evng[new_time_array_e[i].appIdKey] = new_time_array_e[i].appTimeValue;
2496						   }
2497						   data.evening = new_evng;
2498					   }
2499				   }
2500				   for(var obj in data.morning){
2501					   var classAppointmentId = obj;
2502					   var _t = "";
2503					   if(data.morning[obj].toString().length == 3){
2504						   _t = '0'+data.morning[obj];
2505					   }else if(data.morning[obj].toString().length == 2){
2506						   _t = '00'+data.morning[obj];
2507					   }else{
2508						   _t = data.morning[obj];
2509					   }
2510					   
2511					   // Use converted time (like reschedule appointment) - _t contains the timezone-converted time
2512					   var originalServerTime = _t;
2513					   if(app.utility.isTodaysDateWithTimeZone(_date,that.inputData.locationTimeZoneKey)){
2514						   if(!app.utility.isPastTimeWithTimeZone(_t,that.inputData.locationTimeZoneKey)){
2515							  		// console.log('check time '+ _t);
2516							  if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2517								  // console.log('test true');
2518									  _t = null;
2519							  }
2520							   var time = moment(_t,'HHmm').format('hh:mm a');
2521							   console.log(`[SLOT GENERATION] Creating slot with _t: ${_t} → display: ${time} | data-original-time="${_t}"`);
2522							   console.log(`[DISPLAY DEBUG] Rendering time slot: ${_t} (HHmm) → ${time} (display) for date: ${_date}`);
2523							   console.log(`[DISPLAY DEBUG] Slot category check - _t: ${_t}, morTime: ${that.morTime}, condition: ${(_t >= that.morTime)}`);
2524							   console.log(`[DISPLAY DEBUG] Lead date check - _date: ${_date}, leadDate: ${that.leadDate}`);
2525							   if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
2526								   if((_t >= that.morTime) && (that.morTime != '' || that.morTime != undefined) ){
2527									   if(requiredData.isClass){
2528										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2529										   $('#morningAppointmentSlots').append(slot);
2530									   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2531										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2532										   $('#morningAppointmentSlots').append(slot);
2533									   }
2534								   }
2535							   }else{
2536								   if(requiredData.isClass){
2537									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2538									   $('#morningAppointmentSlots').append(slot);
2539								   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2540									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2541									   $('#morningAppointmentSlots').append(slot);
2542								   }
2543							   }
2544
2545						   }
2546					   }else{
2547						  if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2548							  console.log('test true');
2549								  _t = null;
2550						  }
2551						   var time = moment(_t,'HHmm').format('hh:mm a');
2552							   if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
2553								   if((_t >= that.morTime) && (that.morTime != '' || that.morTime != undefined) ){
2554									   if(requiredData.isClass){
2555										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2556										   $('#morningAppointmentSlots').append(slot);
2557									   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2558										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2559										   $('#morningAppointmentSlots').append(slot);
2560									   }
2561								   }
2562							   }else{
2563								   if(requiredData.isClass){
2564									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2565									   $('#morningAppointmentSlots').append(slot);
2566								   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2567									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2568									   $('#morningAppointmentSlots').append(slot);
2569								   }
2570							   }
2571					   }
2572				   }
2573
2574				   for(var obj in data.evening) {
2575					   var classAppointmentId = obj;
2576					   var _t = '';
2577					   if(data.evening[obj].toString().length == 3){
2578						   _t = '0'+data.evening[obj];
2579					   }else if(data.evening[obj].toString().length == 2){
2580						   _t = '00'+data.evening[obj];
2581					   }else{
2582						   _t = data.evening[obj];
2583					   }
2584					   
2585					   // Use converted time (like reschedule appointment) - _t contains the timezone-converted time
2586					   var originalServerTime = _t;
2587
2588					   if(app.utility.isTodaysDateWithTimeZone(_date,that.inputData.locationTimeZoneKey)){
2589						   if(!app.utility.isPastTimeWithTimeZone(_t,that.inputData.locationTimeZoneKey)){
2590							  if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2591								  // console.log('test true');
2592									  _t = null;
2593							  }
2594							   var time = moment(_t,'HHmm').format('hh:mm a');
2595							   if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined) ){
2596								   if((_t >= that.eveTime) && (that.eveTime != '' || that.eveTime != undefined) ){
2597									   if(requiredData.isClass){
2598										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2599										   $('#morningAppointmentSlots').append(slot);
2600									   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2601										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2602										   $('#morningAppointmentSlots').append(slot);
2603									   }
2604								   }
2605							   }else{
2606								   if(requiredData.isClass){
2607									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2608									   $('#morningAppointmentSlots').append(slot);
2609								   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2610									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2611									   $('#morningAppointmentSlots').append(slot);
2612								   }
2613							   }
2614						   }
2615					   }else{
2616						  if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2617							  console.log('test true');
2618								  _t = null;
2619						  }
2620							   var time = moment(_t,'HHmm').format('hh:mm a');
2621							   if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
2622								   if((_t >= that.eveTime) && (that.eveTime != '' || that.eveTime != undefined) ){
2623									   if(requiredData.isClass){
2624										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2625										   $('#morningAppointmentSlots').append(slot);
2626									   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2627										   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2628										   $('#morningAppointmentSlots').append(slot);
2629									   }
2630								   }
2631							   }else{
2632								   if(requiredData.isClass){
2633									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2634									   $('#morningAppointmentSlots').append(slot);
2635								   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2636									   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2637									   $('#morningAppointmentSlots').append(slot);
2638								   }
2639							   }
2640					   }
2641				   }
2642
2643				   try{
2644					   $('.slickSlider').slick({
2645						   accessibility:true,
2646						   arrows:true,
2647						   slidesToShow: 3,
2648						   slidesToScroll: 3,
2649						   vertical:false,
2650						   infinite:false,
2651						   nextArrow:'<button type="button" class="slick-next"><i class="icon icon-angle-right" aria-hidden="true"></i></button>',
2652						   prevArrow:'<button type="button" class="slick-prev"><i class="icon icon-angle-left" aria-hidden="true"></i></button>'
2653					   });
2654				   }catch(e){
2655					   console.log(e);
2656				   }
2657
2658				   $('.smalloverlay').hide();
2659
2660				   // Apply date locking if needed (time preselection is handled by direct booking now)
2661				   const selectedDate = getUrlParameter('sd');
2662				   const selectedTime = getUrlParameter('st');
2663				   
2664				   if (that.lockDate || (selectedDate && !selectedTime)) {
2665				   	// Only apply traditional preselection if: 
2666				   	// 1. Date locking is enabled, OR
2667				   	// 2. Date is specified but time is not (date-only preselection)
2668				   	that.applyDatePreselection();
2669				   }
2670
2671				   var timeSlotsTop = $('.calendar-details').position().top;
2672				   $("body, html").animate({scrollTop:timeSlotsTop}, 'slow');
2673				   $('.timeslot-main').show();
2674				   $('.am-timeslot-section').css('min-height', 'unset');
2675				   		// console.log('time slot retrieved');
2676				   $('.smalloverlay-two').hide();
2677			   }
2678		   ).fail(function(resp){
2679			   console.log(resp);
2680			   $('.smalloverlay').hide();
2681			   app.utility.handleServerError(resp);
2682		   });
2683		}else{
2684						   try{
2685							   if($('.slickSlider').hasClass('slick-initialized')){
2686								   $('.slickSlider').slick('unslick');
2687							   }
2688						   } catch(e){
2689							   console.log(e);
2690						   }
2691
2692						   that.clearMorningEveningTimeSlots();
2693						   var _date_arr = date.split("-");
2694						   var _date = _date_arr[0] +"/"+ _date_arr[1] +"/"+ _date_arr[2];
2695						   var practitionerTimeSlots = [];
2696
2697						   if(appointmentDetailObj.practitioner.timeSlot){
2698							   practitionerTimeSlots = appointmentDetailObj.practitioner.timeSlot.split(";");
2699							   practitionerTimeSlots = practitionerTimeSlots.map(function(tslot){
2700								   return tslot.substr(2);
2701							   });
2702						   }
2703
2704						   data[date].morning = data[date].morning || [];
2705						   data[date].evening = data[date].evening || [];
2706
2707						   if(!requiredData.isClass){
2708							   data[date].morning.sort(function(a,b){
2709									   return a - b;
2710								   });
2711							   data[date].evening.sort(function(a,b){
2712									   return a - b;
2713								   });
2714								   for(var obj in data[date].morning){
2715									   var classAppointmentId = obj;
2716									   var _t = "";
2717									   if(data[date].morning[obj].toString().length == 3){
2718										   _t = '0'+data[date].morning[obj];
2719									   }else if(data[date].morning[obj].toString().length == 2){
2720										   _t = '00'+data[date].morning[obj];
2721									   }else{
2722										   _t = data[date].morning[obj];
2723									   }
2724									   
2725									   // Use converted time (like reschedule appointment) - _t contains the timezone-converted time
2726									   var originalServerTime = _t;
2727
2728									   // compute original provider time for booking by reversing display->
2728provider tz
2729									   var __displayTz = (that.varIsSlotsBasedOnLocation ? that.inputData.locationTimeZoneKey : moment.tz.guess());
2730									   var __originalProviderTime = (function(){
2731										   if(!_t){ return _t; }
2732										   var __colon = _t.slice(0,2)+':'+_t.slice(2);
2733										   var __iso = date+'T'+__colon+':00';
2734										   var __disp = moment.tz(__iso, __displayTz);
2735										   return __disp.clone().tz(that.inputData.slotsTimeZoneKey).format('HHmm');
2736									   })();
2737
2738									   if(app.utility.isTodaysDateWithTimeZone(_date,that.inputData.locationTimeZoneKey)){
2739											let isPastTime = false;
2740											if(that.varIsSlotsBasedOnLocation){
2741												isPastTime = that.isPastTimeWithTimeZone(_t, that.inputData.locationTimeZoneKey);
2742											}else{
2743												isPastTime = app.utility.isPastTimeWithTimeZone(_t,that.inputData.locationTimeZoneKey);
2744											}
2745										   if(!isPastTime){
2746												if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2747														_t = null;
2748												}
2749											   var time = moment(_t,'HHmm').format('hh:mm a');
2750											   if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
2751												   if((_t >= that.morTime) && (that.morTime != '' || that.morTime != undefined) ){
2752													   if(requiredData.isClass){
2753														   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2754														   $('#morningAppointmentSlots').append(slot);
2755													   }else{
2756														   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2757														   $('#morningAppointmentSlots').append(slot);
2758													   }
2759												   }
2760											   }else{
2761												   if(requiredData.isClass){
2762													   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2763													   $('#morningAppointmentSlots').append(slot);
2764												   }else{
2765													   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2766													   $('#morningAppointmentSlots').append(slot);
2767												   }
2768											   }
2769
2770										   }
2771									   }else{
2772											if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2773													_t = null;
2774											}
2775										   var time = moment(_t,'HHmm').format('hh:mm a');
2776											   if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
2777												   if((_t >= that.morTime) && (that.morTime != '' || that.morTime != undefined) ){
2778													   if(requiredData.isClass){
2779														   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2780														   $('#morningAppointmentSlots').append(slot);
2781													   }else{
2782														   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2783														   $('#morningAppointmentSlots').append(slot);
2784													   }
2785												   }
2786											   }else{
2787												   if(requiredData.isClass){
2788													   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2789													   $('#morningAppointmentSlots').append(slot);
2790												   }else{
2791													   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2792													   $('#morningAppointmentSlots').append(slot);
2793												   }
2794											   }
2795									   }
2796								   }
2797
2798								   for(var obj in data[date].evening) {
2799									   var classAppointmentId = obj;
2800									   var _t = '';
2801									   if(data[date].evening[obj].toString().length == 3){
2802										   _t = '0'+data[date].evening[obj];
2803									   }else if(data[date].evening[obj].toString().length == 2){
2804										   _t = '00'+data[date].evening[obj];
2805									   }else{
2806										   _t = data[date].evening[obj];
2807									   }
2808									   
2809									   // Use converted time (like reschedule appointment) - _t contains the timezone-converted time
2810									   var originalServerTime = _t;
2811									   if(false) {
2812										   try {
2813											   var originalValue = that.originalServerData[date].evening[obj];
2814											   if(originalValue) {
2815												   if(originalValue.toString().length == 3) {
2816													   originalServerTime = '0' + originalValue;
2817												   } else if(originalValue.toString().length == 2) {
2818													   originalServerTime = '00' + originalValue;
2819												   } else {
2820													   originalServerTime = originalValue;
2821												   }
2822											   }
2823										   } catch(e) {
2824											   console.warn('[originalServerTime] Error getting evening time:', e);
2825										   }
2826									   }
2827
2828									   if(app.utility.isTodaysDateWithTimeZone(_date,that.inputData.locationTimeZoneKey)){
2829											let isPastTime = false;
2830											if(that.varIsSlotsBasedOnLocation){
2831												isPastTime = that.isPastTimeWithTimeZone(_t, that.inputData.locationTimeZoneKey);
2832											}else{
2833												isPastTime = app.utility.isPastTimeWithTimeZone(_t,that.inputData.locationTimeZoneKey);
2834											}
2835											if(!isPastTime){
2836												if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2837														_t = null;
2838												}
2839												var time = moment(_t,'HHmm').format('hh:mm a');
2840												if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined) ){
2841													if((_t >= that.eveTime) && (that.eveTime != '' || that.eveTime != undefined) ){
2842														if(requiredData.isClass){
2843															var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2844															$('#morningAppointmentSlots').append(slot);
2845														}else{
2846															var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2847															$('#morningAppointmentSlots').append(slot);
2848														}
2849													}
2850												}else{
2851													if(requiredData.isClass){
2852														var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2853														$('#morningAppointmentSlots').append(slot);
2854													}else{
2855														var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2856														$('#morningAppointmentSlots').append(slot);
2857													}
2858												}
2859											}
2860									   }else{
2861											if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
2862													_t = null;
2863											}
2864											   var time = moment(_t,'HHmm').format('hh:mm a');
2865											   if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
2866												   if((_t >= that.eveTime) && (that.eveTime != '' || that.eveTime != undefined) ){
2867													   if(requiredData.isClass){
2868														   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2869														   $('#morningAppointmentSlots').append(slot);
2870													   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2871														   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2872														   $('#morningAppointmentSlots').append(slot);
2873													   }
2874												   }
2875											   }else{
2876												   if(requiredData.isClass){
2877													   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2878													   $('#morningAppointmentSlots').append(slot);
2879												   }else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
2880													   var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
2881													   $('#morningAppointmentSlots').append(slot);
2882												   }
2883											   }
2884									   }
2885								   }
2886
2887								   try{
2888									   $('.slickSlider').slick({
2889										   accessibility:true,
2890										   arrows:true,
2891										   slidesToShow: 3,
2892										   slidesToScroll: 3,
2893										   vertical:false,
2894										   infinite:false,
2895										   nextArrow:'<button type="button" class="slick-next"><i class="icon icon-angle-right" aria-hidden="true"></i></button>',
2896										   prevArrow:'<button type="button" class="slick-prev"><i class="icon icon-angle-left" aria-hidden="true"></i></button>'
2897									   });
2898								   }catch(e){
2899									   console.log(e);
2900								   }
2901
2902								   $('.smalloverlay').hide();
2903
2904								   // Apply date locking if needed (time preselection is handled by direct booking now)
2905								   const selectedDate = getUrlParameter('sd');
2906								   const selectedTime = getUrlParameter('st');
2907								   
2908								   if (that.lockDate || (selectedDate && !selectedTime)) {
2909								   	// Only apply traditional preselection if: 
2910								   	// 1. Date locking is enabled, OR
2911								   	// 2. Date is specified but time is not (date-only preselection)
2912								   	that.applyDatePreselection();
2913								   }
2914
2915								   var timeSlotsTop = $('.calendar-details').position().top;
2916								   $("body, html").animate({scrollTop:timeSlotsTop}, 'slow');
2917								   $('.timeslot-main').show();
2918								   $('.am-timeslot-section').css('min-height', 'unset');
2919								   $('.smalloverlay-two').hide();
2920						   }else{
2921							   app.calendar.dataModel.getCalendarPresetData(requiredData).done(resp=>{
2922								   		// console.log('resp',resp);
2923								   
2924								   // Detect if this is a preset appointment flow
2925								   var isPresetAppointment = Object.keys(resp).length > 0 && 
2926								   	Object.values(resp).some(dateData => 
2927								   		dateData && (dateData.morning || dateData.evening) && 
2928								   		(Object.keys(dateData.morning || {}).length > 0 || Object.keys(dateData.evening || {}).length > 0)
2929								   	);
2930								   
2931								   if(requiredData.selectPractitionerfornewapp != 'Any'){
2932									   if(Object.keys(resp).length > 0){
2933										   var data = resp;
2934									   }else{
2935										   var data = {[date]:{morning:{},evening:{}}};
2936									   }
2937								   }else{
2938									   var data = {[date]:{morning:{},evening:{}}};
2939									   resp.map(item=>{
2940										   if(Object.keys(item.availabilitywithappointmentdetailsids).length > 0){
2941											   if(item.availabilitywithappointmentdetailsids[date] && Object.keys(item.availabilitywithappointmentdetailsids[date]).length > 0){
2942
2943												   if(Object.keys(item.availabilitywithappointmentdetailsids[date].morning).length > 0){
2944													   data[date].morning =  {...data[date].morning,...item.availabilitywithappointmentdetailsids[date].morning}
2945												   }
2946												   if(Object.keys(item.availabilitywithappointmentdetailsids[date].evening).length > 0){
2947														   data[date].evening =  {...data[date].evening,...item.availabilitywithappointmentdetailsids[date].evening}
2948												   }
2949											   }
2950										   }
2951									   })
2952								   }
2953								   let prepChangedTimezoneData = {};
2954									for(let key in data){
2955										if(data[key] && data[key].morning && Object.keys(data[key].morning).length > 0){
2956											for(let time in data[key].morning){
2957												let c = data[key].morning[time].toString();
2958												if(c.length == 3){
2959													c = '0'+c;
2960												}
2961												let d = ":";
2962												let position = 2;
2963												let output = [c.slice(0, position), d, c.slice(position)].join('');
2964												const datee = key+'T'+output+':00';
2965												const tzone = that.inputData.locationTimeZoneKey;
2966												let localDatem ;
2967												if(that.varIsSlotsBasedOnLocation){
2968													localDatem = moment.tz(moment.tz(datee, that.inputData.slotsTimeZoneKey), tzone).format("YYYY-MM-DDTHHmm");
2969												}else{
2970													localDatem = moment.tz(datee, tzone).local().format("YYYY-MM-DDTHHmm");
2971												}
2972												const dateKey = localDatem.split('T')[0];
2973												if(prepChangedTimezoneData[dateKey] == undefined){
2974													prepChangedTimezoneData[dateKey] = {morning: {}, evening: {}}
2975												}
2976
2977												if(localDatem.split('T').pop() < 1200){
2978													prepChangedTimezoneData[dateKey].morning[time] = localDatem.split('T').pop();
2979												}else{
2980													prepChangedTimezoneData[dateKey].evening[time] = localDatem.split('T').pop();
2981												}
2982												prepChangedTimezoneData[dateKey].morning = Object.fromEntries(
2983													Object.entries(prepChangedTimezoneData[dateKey].morning).sort(([,a],[,b]) => a-b)
2984												);
2985												prepChangedTimezoneData[dateKey].evening = Object.fromEntries(
2986													Object.entries(prepChangedTimezoneData[dateKey].evening).sort(([,a],[,b]) => a-b)
2987												);
2988											}
2989										}
2990										if(data[key] && data[key].evening && Object.keys(data[key].evening).length > 0){
2991											for(let time in data[key].evening){
2992												let c = data[key].evening[time].toString();
2993												if(c.length == 3){
2994													c = '0'+c;
2995												}
2996												let d = ":";
2997												let position = 2;
2998												let output = [c.slice(0, position), d, c.slice(position)].join('');
2999												const datee = key+'T'+output+':00';
3000												const tzone = that.inputData.locationTimeZoneKey;
3001												let localDatem ;
3002												if(that.varIsSlotsBasedOnLocation){
3003													localDatem = moment.tz(moment.tz(datee, that.inputData.slotsTimeZoneKey), tzone).format("YYYY-MM-DDTHHmm");
3004												}else{
3005													localDatem = moment.tz(datee, tzone).local().format("YYYY-MM-DDTHHmm");
3006												}
3007												const dateKey = localDatem.split('T')[0];
3008												if(prepChangedTimezoneData[dateKey] == undefined){
3009													prepChangedTimezoneData[dateKey] = {morning: {}, evening: {}}
3010												}
3011
3012												if(localDatem.split('T').pop() < 1200){
3013													prepChangedTimezoneData[dateKey].morning[time] = localDatem.split('T').pop();
3014												}else{
3015													prepChangedTimezoneData[dateKey].evening[time] = localDatem.split('T').pop();
3016												}
3017												prepChangedTimezoneData[dateKey].morning = Object.fromEntries(
3018													Object.entries(prepChangedTimezoneData[dateKey].morning).sort(([,a],[,b]) => a-b)
3019												);
3020												prepChangedTimezoneData[dateKey].evening = Object.fromEntries(
3021													Object.entries(prepChangedTimezoneData[dateKey].evening).sort(([,a],[,b]) => a-b)
3022												);
3023											}
3024										}
3025									}
3026									// console.log('prepChangedTimezoneData ',prepChangedTimezoneData);
3027									if(Object.keys(prepChangedTimezoneData).length > 0){
3028										data = prepChangedTimezoneData;
3029									}
3030
3031									   	if(data[date] && data[date].morning && Object.keys(data[date].morning).length > 0){
3032											for(var obj in data[date].morning){
3033												var classAppointmentId = obj;
3034												var _t = "";
3035												if(data[date].morning[obj].toString().length == 3){
3036													_t = '0'+data[date].morning[obj];
3037												}else if(data[date].morning[obj].toString().length == 2){
3038													_t = '00'+data[date].morning[obj];
3039												}else{
3040													_t = data[date].morning[obj];
3041												}
3042												
3043												// Use converted time (like reschedule appointment) - _t contains the timezone-converted time
3044												var originalServerTime = _t;
3045												if(false) {
3046													try {
3047														var originalValue = that.originalServerData[date].morning[obj];
3048														if(originalValue) {
3049															if(originalValue.toString().length == 3) {
3050																originalServerTime = '0' + originalValue;
3051															} else if(originalValue.toString().length == 2) {
3052																originalServerTime = '00' + originalValue;
3053															} else {
3054																originalServerTime = originalValue;
3055															}
3056														}
3057													} catch(e) {
3058														console.warn('[originalServerTime] Error getting morning time:', e);
3059													}
3060												}
3061												if(app.utility.isTodaysDateWithTimeZone(_date,that.inputData.locationTimeZoneKey)){
3062													if(!app.utility.isPastTimeWithTimeZone(_t,that.inputData.locationTimeZoneKey)){
3063													if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
3064															_t = null;
3065													}
3066														var time = moment(_t,'HHmm').format('hh:mm a');
3067														if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
3068															if((_t >= that.morTime) && (that.morTime != '' || that.morTime != undefined) ){
3069																if(requiredData.isClass || isPresetAppointment){
3070																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3071																	$('#morningAppointmentSlots').append(slot);
3072																}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3073																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3074																	$('#morningAppointmentSlots').append(slot);
3075																}
3076															}
3077														}else{
3078															if(requiredData.isClass || isPresetAppointment){
3079																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3080																$('#morningAppointmentSlots').append(slot);
3081															}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3082																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3083																$('#morningAppointmentSlots').append(slot);
3084															}
3085														}
3086
3087													}
3088												}else{
3089												if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
3090														_t = null;
3091												}
3092													var time = moment(_t,'HHmm').format('hh:mm a');
3093														if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
3094															if((_t >= that.morTime) && (that.morTime != '' || that.morTime != undefined) ){
3095																if(requiredData.isClass || isPresetAppointment){
3096																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3097																	$('#morningAppointmentSlots').append(slot);
3098																}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3099																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3100																	$('#morningAppointmentSlots').append(slot);
3101																}
3102															}
3103														}else{
3104															if(requiredData.isClass || isPresetAppointment){
3105																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3106																$('#morningAppointmentSlots').append(slot);
3107															}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3108																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3109																$('#morningAppointmentSlots').append(slot);
3110															}
3111														}
3112												}
3113											}
3114										}
3115										if(data[date] && data[date].evening && Object.keys(data[date].evening).length > 0){
3116											for(var obj in data[date].evening) {
3117												var classAppointmentId = obj;
3118												var _t = '';
3119												if(data[date].evening[obj].toString().length == 3){
3120													_t = '0'+data[date].evening[obj];
3121												}else if(data[date].evening[obj].toString().length == 2){
3122													_t = '00'+data[date].evening[obj];
3123												}else{
3124													_t = data[date].evening[obj];
3125												}
3126												
3127												// Use converted time (like reschedule appointment) - _t contains the timezone-converted time
3128												var originalServerTime = _t;
3129												if(false) {
3130													try {
3131														var originalValue = that.originalServerData[date].evening[obj];
3132														if(originalValue) {
3133															if(originalValue.toString().length == 3) {
3134																originalServerTime = '0' + originalValue;
3135															} else if(originalValue.toString().length == 2) {
3136																originalServerTime = '00' + originalValue;
3137															} else {
3138																originalServerTime = originalValue;
3139															}
3140														}
3141													} catch(e) {
3142														console.warn('[originalServerTime] Error getting evening time:', e);
3143													}
3144												}
3145
3146												if(app.utility.isTodaysDateWithTimeZone(_date,that.inputData.locationTimeZoneKey)){
3147													if(!app.utility.isPastTimeWithTimeZone(_t,that.inputData.locationTimeZoneKey)){
3148													if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
3149															_t = null;
3150													}
3151														var time = moment(_t,'HHmm').format('hh:mm a');
3152														if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined) ){
3153															if((_t >= that.eveTime) && (that.eveTime != '' || that.eveTime != undefined) ){
3154																if(requiredData.isClass || isPresetAppointment){
3155																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3156																	$('#morningAppointmentSlots').append(slot);
3157																}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3158																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3159																	$('#morningAppointmentSlots').append(slot);
3160																}
3161															}
3162														}else{
3163															if(requiredData.isClass || isPresetAppointment){
3164																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3165																$('#morningAppointmentSlots').append(slot);
3166															}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3167																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3168																$('#morningAppointmentSlots').append(slot);
3169															}
3170														}
3171
3172													}
3173												}else{
3174												if((document.location.origin == 'https://leogempropertyprojectssandbox1.appointiv.com') && (_t.toString().slice(-2) != '00')){
3175														_t = null;
3176												}
3177													var time = moment(_t,'HHmm').format('hh:mm a');
3178														if( (_date == that.leadDate.replaceAll('-0', '/').replaceAll('-', '/') || _date == that.leadDate.replaceAll('-', '/').replaceAll('-', '/')) && (that.leadDate != '' || that.leadDate != undefined)){
3179															if((_t >= that.eveTime) && (that.eveTime != '' || that.eveTime != undefined) ){
3180																if(requiredData.isClass || isPresetAppointment){
3181																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3182																	$('#morningAppointmentSlots').append(slot);
3183																}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3184																	var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3185																	$('#morningAppointmentSlots').append(slot);
3186																}
3187															}
3188														}else{
3189															if(requiredData.isClass || isPresetAppointment){
3190																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3191																$('#morningAppointmentSlots').append(slot);
3192															}else if(app.calendar.isContainsTimeSlot(practitionerTimeSlots, time)){
3193																var slot = '<div><div class="slide-box" data-classappointmentid="'+classAppointmentId+'" data-original-time="'+originalServerTime+'"><h3>'+time+'</h3></div></div>';
3194																$('#morningAppointmentSlots').append(slot);
3195															}
3196														}
3197												}
3198											}
3199										}
3200
3201									   try{
3202										   $('.slickSlider').slick({
3203											   accessibility:true,
3204											   arrows:true,
3205											   slidesToShow: 3,
3206											   slidesToScroll: 3,
3207											   vertical:false,
3208											   infinite:false,
3209											   nextArrow:'<button type="button" class="slick-next"><i class="icon icon-angle-right" aria-hidden="true"></i></button>',
3210											   prevArrow:'<button type="button" class="slick-prev"><i class="icon icon-angle-left" aria-hidden="true"></i></button>'
3211										   });
3212									   }catch(e){
3213										   console.log(e);
3214									   }
3215
3216									   $('.smalloverlay').hide();
3217
3218									   // Apply date locking if needed (time preselection is handled by direct booking now)
3219									   const selectedDate = getUrlParameter('sd');
3220									   const selectedTime = getUrlParameter('st');
3221									   
3222									   if (that.lockDate || (selectedDate && !selectedTime)) {
3223									   	// Only apply traditional preselection if: 
3224									   	// 1. Date locking is enabled, OR
3225									   	// 2. Date is specified but time is not (date-only preselection)
3226									   	that.applyDatePreselection();
3227									   }
3228
3229									   var timeSlotsTop = $('.calendar-details').position().top;
3230									   $("body, html").animate({scrollTop:timeSlotsTop}, 'slow');
3231									   $('.timeslot-main').show();
3232									   $('.am-timeslot-section').css('min-height', 'unset');
3233									   $('.smalloverlay-two').hide();
3234
3235							   });
3236						   }
3237		}
3238	},
3239
3240	getTimeZoneList: function(){
3241		// Get provider ID from URL to filter timezones for specific providers
3242		var providerId = (typeof getIdFromUrl === 'function') ? getIdFromUrl() : null;
3243		
3244		// Return only Australian timezones for Lung Foundation Australia
3245		if(providerId === 'lungfoundationaustralia'){
3246			return [
3247				{
3248					"timezone": "Australia/Perth",
3249					"GMTDiff": "+08:00",
3250					"zoneName": "Australian Western Time"
3251				},
3252				{
3253					"timezone": "Australia/Adelaide",
3254					"GMTDiff": "+09:30",
3255					"zoneName": "Australian Central Time"
3256				},
3257				{
3258					"timezone": "Australia/Darwin",
3259					"GMTDiff": "+09:30",
3260					"zoneName": "Australian Central Time"
3261				},
3262				{
3263					"timezone": "Australia/Brisbane",
3264					"GMTDiff": "+10:00",
3265					"zoneName": "Australian Eastern Time"
3266				},
3267				{
3268					"timezone": "Australia/Sydney",
3269					"GMTDiff": "+10:00",
3270					"zoneName": "Australian Eastern Time"
3271				},
3272				{
3273					"timezone": "Australia/Lord_Howe",
3274					"GMTDiff": "+10:30",
3275					"zoneName": "Lord Howe Time"
3276				}
3277			];
3278		}
3279		
3280		// Return full timezone list for all other providers
3281		return [
3282			{
3283			  "timezone": "Pacific/Kiritimati",
3284			  "GMTDiff": "+14:00",
3285			  "zoneName": "Line Is. Time"
3286			},
3287			{
3288			  "timezone": "Pacific/Tongatapu",
3289			  "GMTDiff": "+13:00",
3290			  "zoneName": "Tonga Time"
3291			},
3292			{
3293			  "timezone": "Pacific/Enderbury",
3294			  "GMTDiff": "+13:00",
3295			  "zoneName": "Phoenix Is. Time"
3296			},
3297			{
3298			  "timezone": "Pacific/Chatham",
3299			  "GMTDiff": "+12:45",
3300			  "zoneName": "Chatham Time"
3301			},
3302			{
3303			  "timezone": "Pacific/Auckland",
3304			  "GMTDiff": "+12:00",
3305			  "zoneName": "New Zealand Time"
3306			},
3307			{
3308			  "timezone": "Pacific/Fiji",
3309			  "GMTDiff": "+12:00",
3310			  "zoneName": "Fiji Time"
3311			},
3312			{
3313			  "timezone": "Asia/Kamchatka",
3314			  "GMTDiff": "+12:00",
3315			  "zoneName": "Petropavlovsk-Kamchatski Time"
3316			},
3317			{
3318			  "timezone": "Pacific/Norfolk",
3319			  "GMTDiff": "+11:00",
3320			  "zoneName": "Norfolk Time"
3321			},
3322			{
3323			  "timezone": "Pacific/Guadalcanal",
3324			  "GMTDiff": "+11:00",
3325			  "zoneName": "Solomon Is. Time"
3326			},
3327			{
3328			  "timezone": "Australia/Lord_Howe",
3329			  "GMTDiff": "+10:30",
3330			  "zoneName": "Lord Howe Time"
3331			},
3332			{
3333			  "timezone": "Australia/Brisbane",
3334			  "GMTDiff": "+10:00",
3335			  "zoneName": "Australian Eastern Time"
3336			},
3337			{
3338			  "timezone": "Australia/Sydney",
3339			  "GMTDiff": "+10:00",
3340			  "zoneName": "Australian Eastern Time"
3341			},
3342			{
3343			  "timezone": "Australia/Adelaide",
3344			  "GMTDiff": "+09:30",
3345			  "zoneName": "Australian Central Time"
3346			},
3347			{
3348			  "timezone": "Australia/Darwin",
3349			  "GMTDiff": "+09:30",
3350			  "zoneName": "Australian Central Time"
3351			},
3352			{
3353			  "timezone": "Asia/Seoul",
3354			  "GMTDiff": "+09:00",
3355			  "zoneName": "Korea Time"
3356			},
3357			{
3358			  "timezone": "Asia/Tokyo",
3359			  "GMTDiff": "+09:00",
3360			  "zoneName": "Japan Time"
3361			},
3362			{
3363			  "timezone": "Asia/Hong_Kong",
3364			  "GMTDiff": "+08:00",
3365			  "zoneName": "Hong Kong Time"
3366			},
3367			{
3368			  "timezone": "Asia/Kuala_Lumpur",
3369			  "GMTDiff": "+08:00",
3370			  "zoneName": "Malaysia Time"
3371			},
3372			{
3373			  "timezone": "Asia/Manila",
3374			  "GMTDiff": "+08:00",
3375			  "zoneName": "Philippines Time"
3376			},
3377			{
3378			  "timezone": "Asia/Shanghai",
3379			  "GMTDiff": "+08:00",
3380			  "zoneName": "China Time"
3381			},
3382			{
3383			  "timezone": "Asia/Singapore",
3384			  "GMTDiff": "+08:00",
3385			  "zoneName": "Singapore Time"
3386			},
3387			{
3388			  "timezone": "Asia/Taipei",
3389			  "GMTDiff": "+08:00",
3390			  "zoneName": "China Time"
3391			},
3392			{
3393			  "timezone": "Australia/Perth",
3394			  "GMTDiff": "+08:00",
3395			  "zoneName": "Australian Western Time"
3396			},
3397			{
3398			  "timezone": "Asia/Bangkok",
3399			  "GMTDiff": "+07:00",
3400			  "zoneName": "Indochina Time"
3401			},
3402			{
3403			  "timezone": "Asia/Ho_Chi_Minh",
3404			  "GMTDiff": "+07:00",
3405			  "zoneName": "Indochina Time"
3406			},
3407			{
3408			  "timezone": "Asia/Jakarta",
3409			  "GMTDiff": "+07:00",
3410			  "zoneName": "West Indonesia Time"
3411			},
3412			{
3413			  "timezone": "Asia/Rangoon",
3414			  "GMTDiff": "+06:30",
3415			  "zoneName": "Myanmar Time"
3416			},
3417			{
3418			  "timezone": "Asia/Dhaka",
3419			  "GMTDiff": "+06:00",
3420			  "zoneName": "Bangladesh Time"
3421			},
3422			{
3423			  "timezone": "Asia/Kathmandu",
3424			  "GMTDiff": "+05:45",
3425			  "zoneName": "Nepal Time"
3426			},
3427			{
3428			  "timezone": "Asia/Colombo",
3429			  "GMTDiff": "+05:30",
3430			  "zoneName": "India Time"
3431			},
3432			{
3433			  "timezone": "Asia/Kolkata",
3434			  "GMTDiff": "+05:30",
3435			  "zoneName": "India Time"
3436			},
3437			{
3438			  "timezone": "Asia/Calcutta",
3439			  "GMTDiff": "+05:30",
3440			  "zoneName": "India Time"
3441			},
3442			{
3443			  "timezone": "Asia/Yekaterinburg",
3444			  "GMTDiff": "+05:00",
3445			  "zoneName": "Yekaterinburg Time"
3446			},
3447			{
3448			  "timezone": "Asia/Karachi",
3449			  "GMTDiff": "+05:00",
3450			  "zoneName": "Pakistan Time"
3451			},
3452			{
3453			  "timezone": "Asia/Tashkent",
3454			  "GMTDiff": "+05:00",
3455			  "zoneName": "Uzbekistan Time"
3456			},
3457			{
3458			  "timezone": "Asia/Kabul",
3459			  "GMTDiff": "+04:30",
3460			  "zoneName": "Afghanistan Time"
3461			},
3462			{
3463			  "timezone": "Asia/Tehran",
3464			  "GMTDiff": "+04:30",
3465			  "zoneName": "Iran Time"
3466			},
3467			{
3468			  "timezone": "Asia/Dubai",
3469			  "GMTDiff": "+04:00",
3470			  "zoneName": "Gulf Time"
3471			},
3472			{
3473			  "timezone": "Asia/Tbilisi",
3474			  "GMTDiff": "+04:00",
3475			  "zoneName": "Georgia Time"
3476			},
3477			{
3478			  "timezone": "Europe/Moscow",
3479			  "GMTDiff": "+03:00",
3480			  "zoneName": "Moscow Time"
3481			},
3482			{
3483			  "timezone": "Africa/Nairobi",
3484			  "GMTDiff": "+03:00",
3485			  "zoneName": "Eastern African Time"
3486			},
3487			{
3488			  "timezone": "Asia/Baghdad",
3489			  "GMTDiff": "+03:00",
3490			  "zoneName": "Arabia Time"
3491			},
3492			{
3493			  "timezone": "Asia/Kuwait",
3494			  "GMTDiff": "+03:00",
3495			  "zoneName": "Arabia Time"
3496			},
3497			{
3498			  "timezone": "Asia/Riyadh",
3499			  "GMTDiff": "+03:00",
3500			  "zoneName": "Arabia Time"
3501			},
3502			{
3503			  "timezone": "Europe/Minsk",
3504			  "GMTDiff": "+03:00",
3505			  "zoneName": "Moscow Time"
3506			},
3507			{
3508			  "timezone": "Asia/Jerusalem",
3509			  "GMTDiff": "+03:00",
3510			  "zoneName": "Israel Time"
3511			},
3512			{
3513			  "timezone": "Europe/Athens",
3514			  "GMTDiff": "+03:00",
3515			  "zoneName": "Eastern European Time"
3516			},
3517			{
3518			  "timezone": "Europe/Bucharest",
3519			  "GMTDiff": "+03:00",
3520			  "zoneName": "Eastern European Time"
3521			},
3522			{
3523			  "timezone": "Europe/Helsinki",
3524			  "GMTDiff": "+03:00",
3525			  "zoneName": "Eastern European Time"
3526			},
3527			{
3528			  "timezone": "Europe/Istanbul",
3529			  "GMTDiff": "+03:00",
3530			  "zoneName": "Eastern European Time"
3531			},
3532			{
3533			  "timezone": "Africa/Cairo",
3534			  "GMTDiff": "+02:00",
3535			  "zoneName": "Eastern European Time"
3536			},
3537			{
3538			  "timezone": "Africa/Johannesburg",
3539			  "GMTDiff": "+02:00",
3540			  "zoneName": "South Africa Time"
3541			},
3542			{
3543			  "timezone": "Europe/Amsterdam",
3544			  "GMTDiff": "+02:00",
3545			  "zoneName": "Central European Time"
3546			},
3547			{
3548			  "timezone": "Europe/Berlin",
3549			  "GMTDiff": "+02:00",
3550			  "zoneName": "Central European Time"
3551			},
3552			{
3553			  "timezone": "Europe/Brussels",
3554			  "GMTDiff": "+02:00",
3555			  "zoneName": "Central European Time"
3556			},
3557			{
3558			  "timezone": "Europe/Paris",
3559			  "GMTDiff": "+02:00",
3560			  "zoneName": "Central European Time"
3561			},
3562			{
3563			  "timezone": "Europe/Prague",
3564			  "GMTDiff": "+02:00",
3565			  "zoneName": "Central European Time"
3566			},
3567			{
3568			  "timezone": "Europe/Rome",
3569			  "GMTDiff": "+02:00",
3570			  "zoneName": "Central European Time"
3571			},
3572			{
3573			  "timezone": "Africa/Algiers",
3574			  "GMTDiff": "+01:00",
3575			  "zoneName": "Central European Time"
3576			},
3577			{
3578			  "timezone": "Europe/Dublin",
3579			  "GMTDiff": "+01:00",
3580			  "zoneName": "Irish Time"
3581			},
3582			{
3583			  "timezone": "Europe/Lisbon",
3584			  "GMTDiff": "+01:00",
3585			  "zoneName": "Western European Time"
3586			},
3587			{
3588			  "timezone": "Europe/London",
3589			  "GMTDiff": "+01:00",
3590			  "zoneName": "British Time"
3591			},
3592			{
3593			  "timezone": "Atlantic/Cape_Verde",
3594			  "GMTDiff": "-01:00",
3595			  "zoneName": "Cape Verde Time"
3596			},
3597			{
3598			  "timezone": "Atlantic/South_Georgia",
3599			  "GMTDiff": "-02:00",
3600			  "zoneName": "South Georgia Time"
3601			},
3602			{
3603			  "timezone": "America/St_Johns",
3604			  "GMTDiff": "-02:30",
3605			  "zoneName": "Newfoundland Time"
3606			},
3607			{
3608			  "timezone": "America/Sao_Paulo",
3609			  "GMTDiff": "-03:00",
3610			  "zoneName": "Brasilia Time"
3611			},
3612			{
3613			  "timezone": "America/Argentina/Buenos_Aires",
3614			  "GMTDiff": "-03:00",
3615			  "zoneName": "Argentine Time"
3616			},
3617			{
3618			  "timezone": "America/Santiago",
3619			  "GMTDiff": "-03:00",
3620			  "zoneName": "Chile Time"
3621			},
3622			{
3623			  "timezone": "America/Halifax",
3624			  "GMTDiff": "-03:00",
3625			  "zoneName": "Atlantic Time"
3626			},
3627			{
3628			  "timezone": "Atlantic/Bermuda",
3629			  "GMTDiff": "-03:00",
3630			  "zoneName": "Atlantic Time"
3631			},
3632			{
3633			  "timezone": "America/Puerto_Rico",
3634			  "GMTDiff": "-04:00",
3635			  "zoneName": "Atlantic Time"
3636			},
3637			{
3638			  "timezone": "America/Caracas",
3639			  "GMTDiff": "-04:00",
3640			  "zoneName": "Venezuela Time"
3641			},
3642			{
3643			  "timezone": "America/Indiana/Indianapolis",
3644			  "GMTDiff": "-04:00",
3645			  "zoneName": "Eastern Time"
3646			},
3647			{
3648			  "timezone": "America/New_York",
3649			  "GMTDiff": "-04:00",
3650			  "zoneName": "Eastern Time"
3651			},
3652			{
3653			  "timezone": "America/Bogota",
3654			  "GMTDiff": "-05:00",
3655			  "zoneName": "Colombia Time"
3656			},
3657			{
3658			  "timezone": "America/Lima",
3659			  "GMTDiff": "-05:00",
3660			  "zoneName": "Peru Time"
3661			},
3662			{
3663			  "timezone": "America/Panama",
3664			  "GMTDiff": "-05:00",
3665			  "zoneName": "Eastern Time"
3666			},
3667			{
3668			  "timezone": "America/Chicago",
3669			  "GMTDiff": "-05:00",
3670			  "zoneName": "Central Time"
3671			},
3672			{
3673			  "timezone": "America/Mexico_City",
3674			  "GMTDiff": "-05:00",
3675			  "zoneName": "Central Time"
3676			},
3677			{
3678			  "timezone": "America/El_Salvador",
3679			  "GMTDiff": "-06:00",
3680			  "zoneName": "Central Time"
3681			},
3682			{
3683			  "timezone": "America/Denver",
3684			  "GMTDiff": "-06:00",
3685			  "zoneName": "Mountain Time"
3686			},
3687			{
3688			  "timezone": "America/Phoenix",
3689			  "GMTDiff": "-07:00",
3690			  "zoneName": "Mountain Time"
3691			},
3692			{
3693			  "timezone": "America/Los_Angeles",
3694			  "GMTDiff": "-07:00",
3695			  "zoneName": "Pacific Time"
3696			},
3697			{
3698			  "timezone": "America/Tijuana",
3699			  "GMTDiff": "-07:00",
3700			  "zoneName": "Pacific Time"
3701			},
3702			{
3703			  "timezone": "America/Anchorage",
3704			  "GMTDiff": "-08:00",
3705			  "zoneName": "Alaska Time"
3706			},
3707			{
3708			  "timezone": "Pacific/Honolulu",
3709			  "GMTDiff": "-10:00",
3710			  "zoneName": "Hawaii-Aleutian Time"
3711			},
3712			{
3713			  "timezone": "Pacific/Niue",
3714			  "GMTDiff": "-11:00",
3715			  "zoneName": "Niue Time"
3716			},
3717			{
3718			  "timezone": "Pacific/Pago_Pago",
3719			  "GMTDiff": "-11:00",
3720			  "zoneName": "Samoa Time"
3721			}
3722		  ];
3723	}
3724};

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.