PageSourceSearch

https://www.coloneldelivery.com/assets/templates/default/js/common.js?v=126

js coloneldelivery.com collected 2026-10-02 15:22:12 UTC 29,346 bytes, 852 lines download raw bytes

1$(document).ready(function(){
2
3	$.ajaxSetup({ cache: false });
4
5	var user_address = jQuery.parseJSON(localStorage.getItem('cached_customer_address'));
6	if(user_address){
7		var address = user_address['full_address'];
8		var zip_code = user_address['zip_code'];
9		var address_type = user_address['address_type'];
10		$("#address_form #address").val(address);
11		$('#address_form input[name="zip_code"]').val(zip_code);
12		$('#address_form select[name="ADDRESS[TYPE]"]').val(address_type);
13	}
14
15
16	// Field Formats
17	if(($('.phone').length > 0) && (phone_mask != '')) $(".phone").mask(phone_mask, { placeholder: phone_placeholder, clearIfNotMatch: true });
18	if(($('.mphone').length > 0) && (mobile_mask != '')) $(".mphone").mask(mobile_mask, { placeholder: mobile_placeholder, clearIfNotMatch: true });
19	if(($('.mask-date').length > 0) && (date_mask != '')) $('.mask-date').mask(date_mask, { placeholder: date_placeholder, clearIfNotMatch: true });
20
21	var clipboard = new ClipboardJS('.clipboard');
22	clipboard.on('success', function(e) {
23		setTimeout("$('.clipboard').tooltip('hide');", 2000);
24		e.clearSelection();
25	});
26
27	$("#address_form").on("submit", function(){
28		add_page_loader();
29		
30		var address  = $('#address_form input[name="address"]').val();
31		var zip_code = $('#address_form input[name="zip_code"]').val();
32		var address_type = $('#address_form select[name="ADDRESS[TYPE]"]').val();
33		
34		var cached_address = {};
35		cached_address.full_address = address;
36		cached_address.zip_code = zip_code;
37		cached_address.address_type = address_type;
38		try{
39			if(cached_address.zip_code != '')
40				localStorage.setItem('cached_customer_address', JSON.stringify(cached_address));
41			else
42				localStorage.setItem('cached_customer_address', JSON.stringify(''));
43		}
44		catch(e){}
45	});
46
47	$(".clipboard").on('click', function(e){
48		$(this).tooltip({title: "Link copied to clipboard!", placement: "bottom", trigger: "manual"});
49		$(this).tooltip('show');
50	});
51
52	$('.selectpicker').selectpicker();
53
54	$('a.menu-heading-toggle').on('click', function(e) {
55		e.preventDefault();
56
57		toggle_menu_heading(this);
58	});
59
60	$('a.filters-toggle').on('click', function(e) {
61		e.preventDefault();
62
63		$(this).next('div.filter-items-toggle').slideToggle('fast');
64		$(this).find('.filters-toggle-indicator').toggleClass('fa-plus-square-o fa-minus-square-o');
65	});
66	
67	$('body').on('click', '.show-cart-modal', function(e) {
68		e.preventDefault();
69		var pathname = window.location.pathname.toLowerCase(); //Current page path
70		var checkout_method = 'CASH';
71		if (window.location.href.indexOf("group_order") > -1) {
72			group_order_show_cart_modal();
73		} else {
74			if (pathname.indexOf('/order/checkout') > -1) {
75				if($("#CHECKOUTMETHOD").val().length > 0){ 
76					checkout_method = $("#CHECKOUTMETHOD").val();
77				}
78				$('#cart-modal').modal('show');
79				$.post(base_url + "order/cart/true/" + checkout_method + "/0/1/1", function(data){
80					$('#cart-modal .modal-body-content').html(data);
81					$('#cart-modal .modal-body-content').show();
82					$('[data-toggle="tooltip"]').tooltip();
83					$('#cart_content [data-toggle="popover"]').popover();
84					//update_checkout_total_order();
85				});
86			} else {
87				$('#cart-modal').modal('show');
88				$.get(base_url + "order/cart/0/0/0/1/1", function(data){
89					$('#cart-modal .modal-body-content').html(data);
90					$('#cart-modal .modal-body-content').show();
91					$('[data-toggle="tooltip"]').tooltip();
92					$('#cart_content [data-toggle="popover"]').popover();
93		/*			$('#cart-modal .modal-footer').empty();
94					$('#cart-modal').find('.cart-actions-wrapper').appendTo('#cart-modal .modal-footer');*/
95				});
96			}
97		}
98	});
99
100	$('#cart-modal').on('hidden.bs.modal', function (e) {
101		$('#cart-modal .progress').show();
102		$('#cart-modal .modal-body-content').html('');
103	})
104
105	$('#cart-modal').on('shown.bs.modal', function (e) {
106/*		$('#cart-modal .modal-body').css('height', $(window).height()*0.8);
107		$('#cart-modal .modal-body').css('max-height', $(window).height()*0.8 - 100);*/
108		$('#cart-modal .modal-body').show();
109		$('#cart-modal .progress').hide();
110	})
111
112	$('.store-link img.media-object').error(function() { $(this).hide() });
113
114/*
115	// Disabled these hashes on the URL 8/8/17.
116	$(".modal").on("shown.bs.modal", function()  { // any time a modal is shown
117		if (window.location.href.indexOf('mobile.php') < 0) {
118			var urlReplace = "#" + $(this).attr('id'); // make the hash the id of the modal shown
119			history.pushState(null, null, urlReplace); // push state that hash into the url
120		}
121	});
122*/
123	// Hide DLC breadcrumbs if on single embed page.
124	if (window.location.href.indexOf('single.php') > 0) {
125		$('#page_subheader').addClass('hidden');
126	}
127	
128	// If a pushstate has previously happened and the back button is clicked, hide any modals.
129	$(window).on('popstate', function() { 
130		$(".modal").modal('hide');
131	});
132	
133	// Remove the hash when modal is closed and user did not click back button.
134	$(".modal").on("hide.bs.modal", function()  { 
135		if(window.location.hash) {
136			//history.pushState('', document.title, window.location.pathname);
137			//history.back(1);
138		}
139	});
140	
141	if (session_user) {
142		var logged_in_user = getCookie('logged_in_user');
143		$('.not-logged-in').addClass('hidden');
144		$('.logged-in').removeClass('hidden');
145		$('.account-name').html(logged_in_user.replace('+', ' '));
146	} else {
147		$('.not-logged-in').removeClass('hidden');
148		$('.logged-in').addClass('hidden');
149	}
150
151});
152
153$(document).on("click", "button[data-loading-text]", function(event){
154	$(this).button('loading');
155});
156
157var print_window;
158function print(URL, title){
159
160	print_window = window.open(URL, title, 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=0,width=600,height=600,left = 390,top = 212');      
161	setTimeout('print_window.print();', 1000);
162}
163
164function getCookie(key) {
165
166	var keyValue = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)');
167	return keyValue ? keyValue[2] : null;
168}
169
170function toggle_menu_heading(heading) {
171
172	$(heading).find('.menu-heading-toggle-indicator i').toggleClass('fa-plus-square-o fa-minus-square-o');
173	if($(heading).parent().find('div.menu-items-toggle').is(':visible')) {
174		$(heading).parent().find('div.menu-items-toggle').slideToggle('fast');
175	}
176	else {
177		// scrollTo plugin causes mobile app to scroll to top on each menu heading click, swapped to jquery native function
178		$('html, body').animate({
179			scrollTop: $(heading).parent().offset().top - 70
180		}, 250);
181
182		//$(heading).parent().ScrollTo({
183		//	onlyIfOutside: true,
184		//	offsetTop: 60
185		//});
186
187		$(heading).parent().find('div.menu-items-toggle').slideToggle('fast');
188	}
189}
190
191function toggle_restaurant_filters() {
192
193		if($('#restaurant_filters').is(':visible')) {
194
195				$('#restaurant_filters').addClass('hidden-xs hidden-sm');
196				$('#restaurant_filter_show').show();
197				$('#restaurant_filter_hide').hide();
198		}
199		else {
200
201				$('#restaurant_filters').removeClass('hidden-xs hidden-sm');
202				$('#restaurant_filter_show').hide();
203				$('#restaurant_filter_hide').show();
204		}
205}
206
207// array shuffle
208Array.prototype.shuffle = function() {
209	var input = this;
210	 
211	for (var i = input.length-1; i >=0; i--) {
212	 
213		var randomIndex = Math.floor(Math.random()*(i+1)); 
214		var itemAtIndex = input[randomIndex]; 
215		 
216		input[randomIndex] = input[i]; 
217		input[i] = itemAtIndex;
218	}
219	return input;
220}
221
222(function ($) {
223	// function to quickly add bootstrap dropdown menus to navigation bar
224	$.fn.add_dropdown = function(menu) {
225		this.addClass('dropdown');
226		this.find('a').addClass('dropdown-toggle').attr('data-toggle', 'dropdown').append(' <span class="caret"></span>');
227		this.append('<ul class="dropdown-menu">');
228		for(var link in menu) {
229			this.find('ul.dropdown-menu').append('<li><a href="' + link + '">' + menu[link] + '</a><li>');
230		}
231		this.append('</ul>');
232
233		return this;
234	}
235
236	$.fn.address_autocomplete = function(options, callback) {
237
238		var use_country_code = 'us';
239		if(country_code) use_country_code = country_code;
240
241		// Disable use under certain criteria.
242		if(use_country_code == 'mm') return;
243		if(use_country_code == 'pa') return;
244		if(use_country_code == 'bm') return;
245
246		var settings = $.extend({
247			autocomplete_type: 'address',			// set type of autocomplete
248			country: use_country_code,			// set the country restriction
249			use_prediction: true,				// use the google prediction service?
250			auto_submit: true,				// auto submit form on address selection?
251			container_div: 'div.autocomplete_container',	// name of container
252			bounds_circle: null,				// bounding circle
253			cache_address: true				// cache address to local storage
254		}, options);
255
256		$(this).each(function() {
257
258			var el = $(this);
259
260			var address_form  = el.is('form') ? el : el.closest('form');
261			var address_div   = el.closest(settings.container_div);
262
263			var hnd = (address_div.length > 0) ? address_div : address_form;
264
265			// find the elements in the address form
266			var address_field = hnd.find('input[name="address"], input#address, input.address');
267			var city_field    = hnd.find('input[name="city"], input#city, input.city');
268			var state_field   = hnd.find('input[name="state"], input#state, select#state, input.state, select.state');
269			var zipcode_field = hnd.find('input[name="zip_code"], input#zip_code, input.zip_code');
270			var address_type_field = hnd.find('select[name="ADDRESS[TYPE]"], select#address_type');
271
272			$(address_field).attr('autocomplete', 'off');
273
274			$(address_field).typeahead({
275
276				fitToElement: true,
277				items: 10,
278				//minLength: 5,
279				delay: 350,
280				changeInputOnSelect: false,
281				autoSelect: true,
282				selectOnBlur: false,
283
284				source: function(query, typeahead) {
285
286//console.log(query);
287					// Don't query if not enough.
288					if((query.length < 5) && !query.includes(' ')) return;
289
290					return $.getJSON(base_url + 'order/autocomplete/address/' + encodeURIComponent(query), function(data) {
291
292						var src = null;
293						var locations = [];
294						$.each(data, function(index, address) {
295
296							src = address.src;
297							locations.push({ id: address.reference, name: address.autocomplete_display1 + '<br/>' + address.autocomplete_display2, contains_details: address.contains_details, full_address: address.full_address, city: address.city, state: address.state, zipcode: address.zipcode, query: address.query, src: src });
298						});
299
300//console.log(locations);
301						typeahead(locations);
302						if(src == 'google') $('.typeahead').append('<img style="float: right; height: 15px; margin-right: 10px; margin-top: 10px;
302" src="https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3_hdpi.png" />');
303					});
304				},
305
306				matcher: function(item) {
307
308					return true;
309				},
310
311				displayText: function(obj, text_only) {
312
313					if(text_only) return obj.full_address;
314					return '<span class="address_autocomplete_entry"><i class="fa fa-map-marker"></i>' + obj.name + '</span>';
315				},
316
317				afterSelect: function(obj) {
318
319//console.log('selected');console.log(obj);
320
321					// Some sources do not require an additional lookup.
322					if(obj.contains_details) {
323
324						if(obj.zipcode != '') zipcode_field.val(obj.zipcode);
325						if(obj.full_address != '') address_field.val(obj.full_address);
326						if(obj.city != '' && city_field.length) city_field.val(obj.city);
327						if(obj.state != '' && state_field.length) state_field.val(obj.state);
328						if(obj.type != '') address_type_field.val(obj.type);
329						if(obj.full_address != '' && obj.zipcode != '' && settings.auto_submit) address_form.submit();
330						return;
331					}
332
333					$.getJSON(base_url + 'order/autocomplete/details/' + encodeURIComponent(obj.id) + '/' + encodeURIComponent(obj.src), function(data) {
334
335//console.log('details');console.log(data);
336
337						// TODO: need all of that intl logic - move into helper?
338						var zipcode = data.zip;
339						var full_address = data.address1;
340						var city = data.city;
341						var address_type = data.type;
342						var state = data.state;
343
344						if(zipcode != '') zipcode_field.val(zipcode);
345						if(full_address != '') address_field.val(full_address);
346						if(city != '' && city_field.length) city_field.val(city);
347						if(state != '' && state_field.length) { if(state_field.attr('name') == undefined) state_field.attr('name', 'state'); state_field.val(state); }
348						// Auto-select address type if detected and field exists
349						if(address_type && address_type_field.length) {
350							address_type_field.val(address_type).trigger('change');
351							// Trigger selecttype() function if it exists (enables save button)
352							if(typeof selecttype === 'function') {
353								selecttype();
354							}
355						}
356
357						if(full_address != '' && zipcode != '' && settings.auto_submit) {
358
359							address_form.append('<input type="hidden" name="update_order_params" value="true"/>');
360							address_form.submit();
361						}
362					});
363				}
364			});
365		});
366
367return;
368///// GOOGLE WIDGET VERSION BELOW
369
370		// default settings
371		var settings = $.extend({
372			autocomplete_type: 'address',			// set type of autocomplete
373			country: use_country_code,			// set the country restriction
374			use_prediction: true,				// use the google prediction service?
375			auto_submit: false,				// auto submit form on address selection?
376			container_div: 'div.autocomplete_container',	// name of container
377			bounds_circle: null,				// bounding circle
378			cache_address: true				// cache address to local storage
379		}, options);
380
381		if((places_location != '') && (places_radius != '')) {
382
383			var pieces = places_location.split(',');
384			settings.bounds_circle = new google.maps.Circle({ center: new google.maps.LatLng(pieces[0], pieces[1]), radius: parseInt(places_radius) });
385		}
386
387		// loop through each object and apply autocomplete function
388		this.each(function() {
389			// variables for address autocomplete
390			var address_autocomplete;
391			var address_autocomplete_options = { componentRestrictions: { country: settings.country } };
392			var address_autocomplete_service;
393
394			// get element and it's container (if any)
395			var el = $(this);
396
397			var address_form  = el.is('form') ? el : el.closest('form');
398			var address_div   = el.closest(settings.container_div);
399
400			// if more than one autocomplete field in a form, we need to get a handle to the container
401			var hnd = (address_div.length > 0) ? address_div : address_form;
402
403			// find the elements in the address form
404			var address_field = hnd.find('input[name="address"], input#address, input.address');
405			var city_field    = hnd.find('input[name="city"], input#city, input.city');
406			var state_field   = hnd.find('input[name="state"], input#state, select#state, input.state, select.state');
407			var zipcode_field = hnd.find('input[name="zip_code"], input#zip_code, input.zip_code');
408			var address_type_field = hnd.find('select[name="ADDRESS[TYPE]"], select#address_type');
409
410			// address prediction programmatically gets first result from autocomplete widget
411			var address_prediction = function(predictions, status) {
412				if (status == 'OK') {
413console.log(predictions);
414					var place_id = predictions[0].place_id;
415					var places = new google.maps.places.PlacesService(address_field[0]);
416					places.getDetails({ placeId: place_id },
417						function result(address_detail, places_service_status) {
418							populate_address_fields(address_detail);
419						}
420					);
421				}
422			}
423
424			// populate the address/zip fields
425			var populate_address_fields = function(place_detail) {
426				// see if we're passing in a place object or if we need to get it from the autocomplete widget
427				var place = (typeof place_detail === 'undefined') ? address_autocomplete.getPlace() : place_detail;
428				var place_type = (place.types) ? place.types[0] : '';
429				var address_components;
430				var full_address = '';
431				var city = '';
432				var state = '';
433				var zipcode = '';
434
435				// determine what type of place this address is
436				switch(place_type) {
437					case 'route':
438						address_components = { street_number: 'long_name', route: 'long_name', locality: 'short_name', postal_code: 'short_name', political: 'short_name', administrative_area_level_1: 'short_name', administrative_area_level_2: 'short_name', neighborhood: 'short_name', sublocality_level_1: 'short_name', postal_code_prefix: 'long_name' };
439						break;
440
441					default:
442						address_components = { street_number: 'long_name', route: 'long_name', postal_code: 'short_name', political: 'short_name', administrative_area_level_1: 'short_name', administrative_area_level_2: 'short_name', locality: 'short_name', neighborhood: 'short_name', sublocality_level_1: 'short_name', postal_code_prefix: 'long_name' };
443						break;
444				}
445
446				// get each component of the address from the place details and update the corresponding field on the form.
447				if (place.address_components) {
448
449					var has_street_number = false;
450
451					for(var i = 0; i < place.address_components.length; i++) {
452
453						var address_type = place.address_components[i].types[0];
454
455						if (address_components[address_type]) {
456							var val = place.address_components[i][address_components[address_type]];
457
458							if(address_type == "street_number") {
459								has_street_number = true;
460								if (full_address == '')
461									full_address = val;
462								else
463									full_address = val + " " + full_address;
464							}
465							else if(address_type == "route") {
466
467								if(use_country_code == 'es')
468									full_address = val + ', ' + full_address;
469								else
470									full_address += " " + val;
471							}
472							else if(address_type == "locality") {
473
474								if(use_country_code == 'ie') {
475
476									if(full_address == '') full_address = val;
477								}
478								else city = val;
479							}
480							else if((address_type == "political") || (address_type == "administrative_area_level_1")) {
481
482								if(use_country_code != 'ie')
483									state = val;
484							}
485							else if(address_type == "postal_code") {
486								zipcode = val;
487							}
488							else if(address_type == "postal_code_prefix") {
489								zipcode = val;
490							}
491							else if(address_type == "postal_town") {
492								zipcode = val;
493							}
494							else if(address_type == "sublocality_level_1") {
495								if(use_country_code == 'mm') zipcode = val;
496							}
497							else if(address_type == "neighborhood") {
498
499								if(use_country_code == 'ie') {
500
501									if(full_address == '') full_address = val;
502								}
503								else if(zipcode == '') zipcode = val;
504							}
505							else if(address_type == "administrative_area_level_2") {
506
507								if(use_country_code == 'ie')
508									zipcode = val;
509								else if(use_country_code == 'mm')
510									zipcode = val.replace(' Township', '');
511							}
512						}
513					}
514				}
515
516				// Non-US: If no street number was received, parse it from the input.
517				if((use_country_code != 'us') && !has_street_number) {
518
519					var user_input = address_field.val().toUpperCase();
520					var sa_pos = user_input.indexOf(full_address.toUpperCase());
521					if(sa_pos != -1) {
522
523						var sa_data = user_input.substr(0, sa_pos);
524						full_address = sa_data + ' ' + full_address.trim();
525					}
526				}
527
528				if(use_country_code == 'ph') zipcode = '';
529
530				// populate the address form
531				if (zipcode != '') zipcode_field.val(zipcode);
532				if (full_address != '') address_field.val(full_address);
533				if (city != '' && city_field.length) city_field.val(city);
534				if (state != '' && state_field.length) state_field.val(state);
535				if (type != '') address_type_field.val(type);
536
537				if (settings.cache_address) {
538					var cached_address = {};
539					cached_address.full_address = full_address;
540					cached_address.zip_code = zipcode;
541					cached_address.address_type = type;
542
543					localStorage.setItem('cached_customer_address', JSON.stringify(cached_address));
544				}
545
546				// check if we are autosubmitting the form
547				if (full_address != '' && zipcode != '' && settings.auto_submit) address_form.submit();
548				if (typeof callback === 'function') callback();
549
550				return false;
551			}
552
553			// check to make sure the element we are bound to is actually present
554			var input_field = el.is('form') ? address_field : el;
555			if (input_field && (input_field.length > 0)) {
556				if (settings.autocomplete_type == 'address') {
557					// get the autocomplete widget
558					address_autocomplete = new google.maps.places.Autocomplete(input_field[0], address_autocomplete_options);
559					if(settings.bounds_circle) address_autocomplete.setBounds(settings.bounds_circle.getBounds());
560				}
561
562
563				if (settings.autocomplete_type == 'establishment') {
564					// get the autocomplete widget
565					address_autocomplete = new google.maps.places.Autocomplete(input_field[0], { types: ['establishment'] });
566					var input_val = input_field.val().split(',');
567					input_field.val(input_val[0]);
568				}
569
570				// listen for enter key
571				google.maps.event.addDomListener(input_field[0], 'keyup', function(e) {
572					if (e.keyCode === 13) {
573						e.preventDefault();
574						e.stopPropagation();
575						e.stopImmediatePropagation();
576
577						if (settings.use_prediction) {
578							// if user hits enter key, we get the first result from the autocomplete widget programmatically
579							address_autocomplete_service = new google.maps.places.AutocompleteService();
580							address_autocomplete_service.getPlacePredictions({ input: input_field.val() }, address_prediction);
581						}
582
583						return false;
584					}
585				});
586
587				// listen for an address change
588				address_autocomplete.addListener('place_changed', function() {
589					populate_address_fields();
590				});
591			}
592		});
593
594		return this;
595	}
596
597	//pass in just the context as a $(obj) or a settings JS object
598	$.fn.autogrow = function(opts) {
599		var that = $(this).css({overflow: 'hidden', resize: 'none'}), //prevent scrollies
600			   selector = that.selector,
601			   defaults = {
602				context: $(document),		//what to wire events to
603				animate: true,			//if you want the size change to animate
604				speed: 200,			//speed of animation
605				fixMinHeight: true,		//if you don't want the box to shrink below its initial size
606				cloneClass: 'autogrowclone',	//helper CSS class for clone if you need to add special rules
607				onInitialize: false		//resizes the textareas when the plugin is initialized
608			   };
609
610		opts = $.isPlainObject(opts) ? opts : {context: opts ? opts : $(document)};
611		opts = $.extend({}, defaults, opts);
612		that.each(function(i, elem){
613			var min, clone;
614			elem = $(elem);
615			//if the element is "invisible", we get an incorrect height value
616			//to get correct value, clone and append to the body.
617			if (elem.is(':visible') || parseInt(elem.css('height'), 10) > 0) {
618				min = parseInt(elem.css('height'), 10) || elem.innerHeight();
619			} else {
620				clone = elem.clone()
621					.addClass(opts.cloneClass)
622					.val(elem.val())
623					.css({
624						position: 'absolute',
625						visibility: 'hidden',
626						display: 'block'
627					});
628				$('body').append(clone);
629				min = clone.innerHeight();
630				clone.remove();
631			}
632			if (opts.fixMinHeight) {
633				elem.data('autogrow-start-height', min); //set min height
634			}
635			elem.css('height', min);
636
637			if (opts.onInitialize && elem.length) {
638				resize.call(elem[0]);
639			}
640		});
641		opts.context.on('keyup paste', selector, resize);
642
643		function resize (e){
644			var box = $(this),
645				  oldHeight = box.innerHeight(),
646				  newHeight = this.scrollHeight,
647				  minHeight = box.data('autogrow-start-height') || 0,
648				  clone;
649
650			if (oldHeight < newHeight) { //user is typing
651				this.scrollTop = 0; //try to reduce the top of the content hiding for a second
652				opts.animate ? box.stop().animate({height: newHeight}, opts.speed) : box.innerHeight(newHeight);
653			} else if (!e || e.which == 8 || e.which == 46 || (e.ctrlKey && e.which == 88)) { //user is deleting, backspacing, or cutting
654				if (oldHeight > minHeight) { //shrink!
655					//this cloning part is not particularly necessary. however, it helps with animation
656					//since the only way to cleanly calculate where to shrink the box to is to incrementally
657					//reduce the height of the box until the $.innerHeight() and the scrollHeight differ.
658					//doing this on an exact clone to figure out the height first and then applying it to the
659					//actual box makes it look cleaner to the user
660					clone = box.clone()
661						//add clone class for extra css rules
662						.addClass(opts.cloneClass)
663						//make "invisible", remove height restriction potentially imposed by existing CSS
664						.css({position: 'absolute', zIndex:-10, height: ''})
665						//populate with content for consistent measuring
666						.val(box.val());
667					box.after(clone); //append as close to the box as possible for best CSS matching for clone
668					do { //reduce height until they don't match
669						newHeight = clone[0].scrollHeight - 1;
670						clone.innerHeight(newHeight);
671					} while (newHeight === clone[0].scrollHeight);
672					newHeight++; //adding one back eliminates a wiggle on deletion
673					clone.remove();
674					box.focus(); // Fix issue with Chrome losing focus from the textarea.
675
676					//if user selects all and deletes or holds down delete til beginning
677					//user could get here and shrink whole box
678					newHeight < minHeight && (newHeight = minHeight);
679					oldHeight > newHeight && opts.animate ? box.stop().animate({height: newHeight}, opts.speed) : box.innerHeight(newHeight);
680				} else { //just set to the minHeight
681					box.innerHeight(minHeight);
682				}
683			}
684		}
685		return that;
686	}
687}(jQuery));
688
689function seconds_to_HMS(secs, word_format) {
690
691	var num_hours = Math.floor(secs / 3600);
692	var num_minutes = Math.floor((secs - (num_hours * 3600)) / 60);
693	var secs_remain = Math.round(secs - ((num_hours * 3600) + (num_minutes * 60)));
694	var rv = '';
695
696	if(word_format) {
697
698
699		if(num_hours > 0) rv = num_hours + ' ' + pluralize_word('hour', num_hours);
700		if(num_minutes > 0) {
701
702			if(rv != '') rv += ' ';
703			rv += num_minutes + ' ' + pluralize_word('minute', num_minutes);
704		}
705		if(secs_remain > 0) {
706
707			if(rv != '') rv += ' ';
708			rv += secs_remain + ' ' + pluralize_word('second', secs_remain);
709		}
710	}
711	else {
712
713		if(num_minutes < 10) num_minutes = "0" + num_minutes;
714		if(secs_remain < 10) secs_remain = "0" + secs_remain;
715
716		if(num_hours > 0) rv = num_hours + ':' + num_minutes + ':' + secs_remain;
717		else if(parseInt(num_minutes) > 0) rv = '00:' + num_minutes + ':' + secs_remain;
718		else rv = '00:00:' + secs_remain;
719	}
720
721	return rv;
722}
723
724function pluralize_word(base, num) {
725
726	if(num == 1) return base;
727	return base + 's';
728}
729
730var loader_enabled = false;
731function add_page_loader() {
732
733	if(!loader_enabled) {
734
735		loader_enabled = true;
736		return;
737	}
738
739	var is_safari = false;
740	try {
741
742		is_safari = ((navigator.userAgent.indexOf("Safari") > -1) && (navigator.userAgent.indexOf("Chrome") == -1));
743	}
744	catch(ex) {
745	}
746
747	// Don't use the loader if Safari.
748	if(is_safari) return;
749	$('#page-loader').show();
750}
751
752function remove_page_loader() {
753	$('#page-loader').fadeOut("slow");
754}
755
756function format_money(amount) {
757
758	var decimals = 2;
759	if(country_code == 'mm') decimals = 0;
760
761	return currency_symbol + amount.toFixed(decimals);
762}
763
764function levenshtein_ratio(s1, s2) {
765	let max_len = (s1.length > s2.length) ? s1.length : s2.length;
766	return Math.round((1 - levenshteinDistance(s1, s2) / max_len) * 100);
767}
768
769function levenshteinDistance(str1 = '', str2 = '') {
770	const track = Array(str2.length + 1).fill(null).map(() => Array(str1.length + 1).fill(null));
771	
772	for (let i = 0; i <= str1.length; i += 1) {
773		track[0][i] = i;
774	}
775
776	for (let j = 0; j <= str2.length; j += 1) {
777		track[j][0] = j;
778	}
779
780	for (let j = 1; j <= str2.length; j += 1) {
781		for (let i = 1; i <= str1.length; i += 1) {
782			const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;
783			track[j][i] = Math.min(
784				track[j][i - 1] + 1, //deletion
785				track[j - 1][i] + 1, //insertion
786				track[j - 1][i - 1] + indicator, //substitution
787			);
788		}
789	}
790
791	return track[str2.length][str1.length];
792}
793
794function stringSimilarity(str1, str2, gramSize = 2) {
795	function getNGrams(s, len) {
796		s = ' '.repeat(len - 1) + s.toLowerCase() + ' '.repeat(len - 1);
797		let v = new Array(s.length - len + 1);
798		for (let i = 0; i < v.length; i++) {
799			v[i] = s.slice(i, i + len);
800		}
801		return v;
802	}
803  
804	if (!str1?.length || !str2?.length) { return 0.0; }
805  
806	let s1 = str1.length < str2.length ? str1 : str2;
807	let s2 = str1.length < str2.length ? str2 : str1;
808  
809	let pairs1 = getNGrams(s1, gramSize);
810	let pairs2 = getNGrams(s2, gramSize);
811	let set = new Set(pairs1);
812  
813	let total = pairs2.length;
814	let hits = 0;
815	for (let item of pairs2) {
816		if (set.delete(item)) {
817			hits++;
818		}
819	}
820	
821	return (hits / total) * 100;
822}
823
824function show_deal_item(deal_id) {
825	// Find the item container div using the deal_id
826	var $item = $("#order_restaurant--menu_item_" + deal_id);
827	var debug = false
828	
829	if ($item.length > 0) {
830		if(debug) console.log("Found deal item:", $item);
831		
832		// Find the closest parent container that has an onclick event (assumed to be the clickable container)
833		var $clickableContainer = $item.closest(".order_restaurant--menu_item_container");
834		
835		if ($clickableContainer.length > 0) {
836			if(debug) console.log("Triggering click on:", $clickableContainer);
837			$clickableContainer.click();
838		} else {
839			if(debug) console.warn("No clickable container found for deal_id:", deal_id);
840		}
841	} else {
842		if(debug) console.warn("Deal item not found for deal_id:", deal_id);
843	}
844}
845
846// Globally-UI-Hamburger-menu-position-changes
847jQuery(document).ready(function($){
848$('#page-loader').on('click', function() {
849  $('body').removeClass('block-scroll sidemenu-active');
850  $('.header-menu-mobile').removeClass('active');
851});
852});

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.