PageSourceSearch

https://satruck.org/scripts/devnext.common-1.0.js?t=134347155896426444

js satruck.org collected 2026-09-24 09:27:24 UTC 32,293 bytes, 1,364 lines download raw bytes

1/*
2	devnext.common-1.0.js
3	depends on jquery & jquery-ui
4	Author: Gordon Patrick
5	Release Date: 3/30/2015
6	Uses: Common JS methods to speed up development and make things more consistent across apps.
7	Contact Gordon Patrick for bug fixes or feature requests, anything added to this file in another project may be overwritten in once a new version is released.
8
9	GJP 3/30/2015: Please use the file verion in your projects or include this header so we can troubleshoot any issues!
10*/
11
12/**
13* converted stringify() to jQuery plugin.
14* serializes a simple object to a JSON formatted string.
15* Note: stringify() is different from jQuery.serialize() which URLEncodes form elements
16 
17* UPDATES:
18* Added a fix to skip over Object.prototype members added by the prototype.js library
19* USAGE:
20* jQuery.ajax({
21* data : {serialized_object : jQuery.stringify (JSON_Object)},
22* success : function (data) {
23*
24* }
25* });
26*
27* CREDITS: http://blogs.sitepointstatic.com/examples/tech/json-serialization/json-serialization.js
28*/
29jQuery.extend(
30{
31	stringify  : function stringify(obj) 
32	{         
33		if ("JSON" in window) 
34		{
35			return JSON.stringify(obj);
36		}
37
38		var t = typeof (obj);
39		if (t != "object" || obj === null) 
40		{
41			// simple data type
42			if (t == "string") obj = '"' + obj + '"';
43
44			return String(obj);
45		} 
46		else 
47		{
48			// recurse array or object
49			var n, v, json = [], arr = (obj && obj.constructor == Array);
50
51			for (n in obj) 
52			{
53				v = obj[n];
54				t = typeof(v);
55				if (obj.hasOwnProperty(n)) 
56					 {
57					if (t == "string") 
58						  {
59						v = '"' + v + '"';
60					} 
61						  else if (t == "object" && v !== null)
62						  {
63						v = jQuery.stringify(v);
64					}
65
66					json.push((arr ? "" : '"' + n + '":') + String(v));
67				}
68			}
69
70			return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
71		}
72	}
73});
74
75jQuery.fn.center = function(parent) 
76{
77	if (parent) 
78	{
79		parent = this.parent();
80	} 
81	else 
82	{
83		parent = window;
84	}
85	this.css
86	({
87		"position": "absolute",
88		"top": ((($(parent).height() - this.outerHeight()) / 2) + $(parent).scrollTop() + "px"),
89		"left": ((($(parent).width() - this.outerWidth()) / 2) + $(parent).scrollLeft() + "px")
90	});
91	return this;
92}
93
94//Prototype additions to primitives
95String.prototype.toDateFromAspDate = function()
96{
97    var re = /-?\d+/; 
98    var m = re.exec(this); 
99    var d = new Date(parseInt(m[0]));
100    
101    return d;
102}
103
104Date.prototype.toShortDateString = function()
105{
106    return (this.getMonth()+1) + 
107		"/" +  this.getDate() +
108		"/" +  this.getFullYear();
109}
110
111if (!Array.prototype.indexOf)
112{
113    Array.prototype.indexOf = function(obj, start)
114    {
115        for (var i = (start || 0), j = this.length; i < j; i++)
116            if (this[i] === obj) { return i; }
117        
118        return -1;
119    }
120}
121
122if (!Array.prototype.findObject)
123{
124	Array.prototype.findObject = function (property, val) 
125	{ 
126		var len = this.length; 
127		for (var i=0; i<len; i++) 
128		{ 
129			if (this[i][property]===val) { return this[i]; } 
130		} 
131		return null; 
132	}
133}
134
135if (!Array.prototype.objectExists)
136{
137	Array.prototype.objectExists = function (property, val) 
138	{ 
139		var len = this.length; 
140		for (var i=0; i<len; i++) 
141		{ 
142			if (this[i][property]===val) { return true; } 
143		} 
144		return false; 
145	}
146}
147
148//Namespace
149DN = {};
150// Site-Wide general utilities
151DN.Utils =
152{
153	//http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
154	GetQueryStringParameterByName: function(name) 
155	{
156		name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
157		var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
158		var results = regex.exec(location.search);
159		return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
160	},
161
162	ScrollToTop: function(speed)
163	{
164		var $body = $('html, body');
165		if(speed) {
166			$body.animate({ scrollTop: 0 }, speed);
167		} else {
168			$body.animate({ scrollTop: 0 }, 500);
169		}
170	},
171
172	CurrentTime: function()
173	{
174		var today = new Date();
175		var UTC_TIMESTAMP = today.toUTCString();
176
177		return UTC_TIMESTAMP;
178	},
179
180	IELessThanEqual: function(version)
181	{
182		var div = document.createElement('div');
183		div.innerHTML = '<!--[if lte IE ' + version + ']><i></i><![endif]-->';
184		
185		return div.getElementsByTagName('i').length > 0;
186	},
187
188	log: function(message)
189	{
190		if (window.console && window.console.log)
191		{
192			console.log(message);
193		}
194	},
195
196	CreateUUID: function()
197	{
198		var id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) 
199		{
200			 var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
201			 return v.toString(16);
202		});
203		return id;
204	},
205
206	LogOut: function(siteroot)
207	{
208		var agt=navigator.userAgent.toLowerCase();
209		if (agt.indexOf("msie") !== -1) 
210		{
211			document.execCommand("ClearAuthenticationCache","false");
212			window.location = siteroot;
213							
214			if (top.location != location) { 
215				top.location.href = "."; 
216			} 
217			window.location = siteroot;
218		}
219		//NOTE: The following doesn't seem to work for FF, but hope for the future
220		//window.crypto is defined in Chrome, but it has no logout function
221//		else if (window.crypto && typeof window.crypto.logout === "function")
222//		{
223//			window.crypto.logout();
224//			window.location = siteroot;
225//		}
226		else
227		{
228			 DN.Utils.ShowMessage("You must close your browser to complete the log out process.", "Log Out", false);
229		}
230	},
231
232	// Site-wide error dialog
233	ShowError: function (msg, title) 
234	{
235		var obj = $('<div/>');
236		if(!title) {
237			title = 'Warning';
238		}
239		obj.html(msg);
240		obj.dialog(
241		{
242			modal: true,
243			title: title,
244			close: function (event, ui) { $(this).dialog("destroy"); },
245			buttons: 
246			[{
247				text:'Ok',
248				click:function () 
249				{
250					$(this).dialog("destroy");
251				},
252				'class' : 'btn btn-default dialog-confirm'
253			}]
254		});
255	},
256
257    // Site-wide error dialog with redirect url
258	ShowErrorRedirect: function (msg, title, redirect) {
259	    var obj = $('<div/>');
260	    if (!title) {
261	        title = 'Warning';
262	    }
263	    obj.html(msg);
264	    obj.dialog(
265		{
266		    modal: true,
267		    title: title,
268		    close: function (event, ui) { $(this).dialog("destroy"); },
269		    buttons:
270			[{
271			    text: 'Ok',
272			    click: function () {
273			        $(this).dialog("destroy");
274			        window.location = redirect;
275			    },
276			    'class': 'btn btn-default dialog-confirm'
277			}]
278		});
279	},
280	
281	// Site-wide general message dialog
282	ShowMessage: function (msg, title, modal) 
283	{
284		var obj = $('<div/>');
285		obj.html(msg);
286		obj.dialog(
287		{
288			modal: (modal === 'undefined' ? true : modal),
289			title: title ? title : 'Message',
290			close: function (event, ui) { $(this).dialog("destroy"); },
291			buttons: 
292			[{
293				text: 'Ok',
294				click: function () 
295				{
296					$(this).dialog("destroy");
297				},
298				'class' : 'btn btn-default dialog-confirm'
299			}]
300		});
301	},
302
303	// Site-wide general confirmation dialog
304	ShowConfirm: function (msg, title, yes, no, skipNoOnClose) 
305	{
306		var obj = $('<div/>');
307		obj.html(msg);
308		obj.dialog({
309			modal: true,
310			title: title ? title : 'Message',
311			close: function (event, ui) 
312			{ 
313				if (no && !skipNoOnClose)
314					no();
315				$(this).dialog("destroy"); 
316			},
317			buttons: 
318			[{
319				text:'Yes', 
320				click:function () 
321				{
322					if (yes)
323						yes();
324					$(this).dialog("destroy");
325				},
326				'class' : 'btn btn-default dialog-confirm'
327			},
328			{
329				text:'No',
330				click: function () 
331				{
332					if (no)
333						no();
334					$(this).dialog("destroy");
335				},
336				'class' : 'btn btn-default dialog-cancel'
337			}]
338		});
339	},
340
341	// Site-wide general confirmation dialog
342	ShowCustomConfirm: function (msg, title, buttons) 
343	{
344		var obj = $('<div/>');
345		obj.html(msg);
346		obj.dialog(
347		{
348			modal: true,
349			title: title ? title : 'Message',
350			close: function (event, ui) 
351			{ 
352				if (no)
353					no();
354				$(this).dialog("destroy"); 
355			},
356			buttons: buttons
357		});
358	},
359
360	ShowWarningDialog: function (msg, title, warnings, yes, no)
361	{
362	    var $obj = $('<div><table style="width: 370px;"><tr><td class="validation-summary-warnings"><span id="warning-message"></span><br /><br /><ul id="warning-list"></ul></td></tr></table></div>');
363
364	    $obj.find("#warning-message").text(msg);
365	    $obj.find('#warning-list li').remove();
366
367	    $.each(warnings, function ()
368	    {
369	        $obj.find('#warning-list').append("<li>" + this + "</li>");
370	    });
371
372	    $obj.dialog(
373		{
374		    modal: true,
375		    title: title ? title : 'Warning',
376		    width: 410,
377		    close: function (event, ui)
378		    {
379		        if (no)
380		            no();
381		        $(this).dialog("destroy");
382		    },
383		    buttons:
384			{
385			    Yes: function (e)
386			    {
387			        if (yes)
388			            yes();
389			        $(this).dialog("destroy");
390			    },
391			    No: function (e)
392			    {
393			        if (no)
394			            no();
395			        $(this).dialog("destroy");
396			    }
397			}
398		});
399	},
400
401	ShowWarningErrorDialog: function (msg, title, warnings)
402	{
403		var $obj = $('<div><table style="width: 370px;"><tr><td class="validation-summary-warnings"><span id="warning-message"></span><br /><br /><ul id="warning-list"></ul></td></tr></table></div>');
404
405		$obj.find("#warning-message").text(msg);
406		$obj.find('#warning-list li').remove();
407
408		$.each(warnings, function ()
409		{
410			$obj.find('#warning-list').append("<li>" + this + "</li>");
411		});
412
413		$obj.dialog(
414		{
415			modal: true,
416			title: title ? title : 'Warning',
417			width: 410,
418			close: function (event, ui)
419			{
420				$(this).dialog("destroy");
421			},
422			buttons:
423			{
424				Ok: function ()
425				{
426					$(this).dialog("destroy");
427				}
428			}
429		});
430	},
431
432	ShowErrorDialog: function (errors)
433	{
434		var $obj = $('<div><table style="width: 370px;"><tr><td class="validation-summary-errors"><span>Save was unsuccessful.<br />Please correct the errors and try again.</span><ul id="error-list"></ul></td></tr></table></div>');
435		$obj.find('#error-list li').remove();
436
437	    $.each(errors, function (index, value)
438		{
439	    	$obj.find('#error-list').append("<li>" + value + "</li>");
440	    	$obj.find('#' + index).addClass('input-validation-error');
441	    });
442
443	    $obj.dialog(
444		{
445			modal: true,
446			title: title ? title : 'Invalid Fields',
447			width: 410,
448			close: function (event, ui)
449			{
450				$(this).dialog("destroy");
451			},
452			buttons:
453			{
454				Ok: function ()
455				{
456					$(this).dialog("destroy");
457				}
458			}
459		});
460	},
461
462	parseTime: function (s)
463	{
464		var part = s.match(/(\d+):(\d+)(?: )?(am|pm)?/i);
465		var hh = parseInt(part[1], 10);
466		var mm = parseInt(part[2], 10);
467		var ap = part[3] ? part[3].toUpperCase() : null;
468		if (ap === "AM")
469		{
470			if (hh == 12)
471			{
472				hh = 0;
473			}
474		}
475		if (ap === "PM")
476		{
477			if (hh != 12)
478			{
479				hh += 12;
480			}
481		}
482		return { hh: hh, mm: mm };
483	},
484	
485	stringToBoolean: function (string) 
486	{
487		switch (string.toLowerCase()) 
488		{
489			case "true": case "yes": case "1": return true;
490			case "false": case "no": case "0": case null: return false;
491			default: return Boolean(string);
492		}
493	},
494
495	toCurrencyString: function(n, decimals, decimal_sep, thousands_sep)
496	{
497		 c = isNaN(decimals) ? 2 : Math.abs(decimals), //if decimal is zero we must take it, it means user does not want to show any decimal
498		 d = decimal_sep || '.', //if no decimal separator is passed we use the dot as default decimal separator (we MUST use a decimal separator)
499		 /*
500		 according to [http://stackoverflow.com/questions/411352/how-best-to-determine-if-an-argument-is-not-sent-to-the-javascript-function]
501		 the fastest way to check for not defined parameter is to use typeof value === 'undefined'
502		 rather than doing value === undefined.
503		 */
504		 t = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, //if you don't want to use a thousands separator you can pass empty string as thousands_sep value
505		 sign = (n < 0) ? '-' : '',
506		 //extracting the absolute value of the integer part of the number and converting to string
507		 i = parseInt(n = Math.abs(n).toFixed(c)) + '',
508		 j = ((j = i.length) > 3) ? j % 3 : 0;
509		 return sign + (j ? i.substr(0, j) + t : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : '');
510	},
511
512	clearEditors: function(css) 
513	{
514		$("." + css).removeClass("has-error has-warning has-feedback has-success");
515		$('input[type=text].' + css).val("");
516		$('input[type=file].' + css).val("");
517		$('textarea.' + css).val("");
518		$('select.' + css).val("");
519		$('.' + css).prop('checked', false);
520	},
521
522	SetupSubmitButton: function (btn, css) 
523	{
524		$('#' + btn).button("option", "disabled", true);
525
526		$('input[type=text].'+ css).keydown(function () 
527		{
528			$('#'+btn).button("option", "disabled", false);
529		});
530
531		$('input[type=checkbox].'+ css).click(function () 
532		{
533			$('#'+btn).button("option", "disabled", false);
534		});
535
536		$('input[type=file].' + css).click(function () 
537		{
538			$('#' + btn).button("option", "disabled", false);
539		});
540
541		$('textarea.'+ css).keydown(function () 
542		{
543			$('#'+btn).button("option", "disabled", false);
544		});
545
546		$("." + css).change(function () 
547		{
548			$('#'+btn).button("option", "disabled", false);
549		});
550	},
551
552	//This one does not set the button to disabled to start
553	//It just wires up the event handlers
554	SetupFormFieldEventsForSubmitButton: function (btn, css) 
555	{
556		$('input[type=text].'+ css).keydown(function () 
557		{
558			$('#'+btn).button("option", "disabled", false);
559		});
560
561		$('input[type=checkbox].'+ css).click(function () 
562		{
563			$('#'+btn).button("option", "disabled", false);
564		});
565
566		$('input[type=file].' + css).click(function () 
567		{
568			$('#' + btn).button("option", "disabled", false);
569		});
570
571		$('textarea.'+ css).keydown(function () 
572		{
573			$('#'+btn).button("option", "disabled", false);
574		});
575
576		$("." + css).change(function () 
577		{
578			$('#'+btn).button("option", "disabled", false);
579		});
580	},
581
582	postJSON: function(uri, data, completed)
583	{
584		 var self = this;
585
586		 // Make the call
587		 $.ajax(
588		 {
589			url: uri,
590			data: data,
591			type: "post",
592			dataType: "json",
593			contentType: "application/json; charset=utf-8",
594			complete: function(jqXHR, textStatus)
595			{
596				if (completed)
597					completed(jqXHR);
598			}
599		}); 
600	},
601
602	formatMoney: function(money, use_sign, use_separator)
603	{
604		if(use_sign === undefined)
605			use_sign = true;
606		if(use_separator === undefined)
607			use_separator = true;
608
609		if(money === undefined || money === null || money === '')
610			return '';
611
612		return (use_sign ? '$' : '') + DN.Utils.toCurrencyString(parseFloat(money), 2, null, (use_separator ? ',' : ''));
613	},
614
615	formatTime: function(param1, param2)
616	{
617		if(param2 !== undefined)
618		{
619			var hours = param1, minutes = param2;
620
621			if (minutes < 10)
622				minutes = "0" + minutes
623
624			var suffix = "am";
625			if (hours >= 12)
626			{
627				suffix = "pm";
628				hours = hours - 12;
629			}
630			if (hours == 0)
631			{
632				hours = 12;
633			}
634
635			return hours + ":" + minutes + " " + suffix; 
636		}
637		else
638		{
639			var total_minutes = param1;
640			var minutes = parseInt(total_minutes % 60, 10)
641			var hours = parseInt(total_minutes / 60 % 24, 10);
642			var ext  = hours < 12 ? "am" : "pm";
643			minutes = "" + minutes;
644			if (hours == 0) hours = 12;
645			if (hours > 12) hours = hours - 12;
646			if (minutes.length == 1) minutes = "0" + minutes;
647
648			return hours + ":" + minutes + " " + ext;
649		}
650    },
651
652    getURLParameter: function(name)
653    {
654        var results = new RegExp('[\?&amp;]' + name + '=([^&amp;#]*)').exec(window.location.href);
655        if(results) {
656            return results[1] || 0;
657        }
658    }
659}; // END UTILS
660
661DN.Validation = 
662{
663	isValidPhone: function (val) 
664	{
665		return (this.unFormatPhone(val).length == 10);
666    },
667
668    isValidZip: function (val) {
669        if (val != null) {
670            var numOnly;
671            numOnly = (new String(val)).replace(/[^0-9]/g, "");
672            return (numOnly.length == 5 || numOnly.length == 9);
673        }
674        else {
675            return false;
676        }
677    },
678
679	isValidEmail: function (val) 
680	{
681		var emailRegex = /^([a-zA-Z0-9_.\-''])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
682		if (!emailRegex.test(val)) 
683		{
684			return false;
685		}
686		return true;
687	},
688
689	isValidInteger: function (val) 
690	{
691		var numericRegex = /^ *[0-9]+ *$/;
692		if (!numericRegex.test(val)) 
693		{
694			return false;
695		}
696		return true;
697	},
698
699	isValidNumber: function (val) 
700	{
701	    var numericRegex = /^([1-9][0-9]*(\.[0-9]+)?|0\.[0-9]+|\.[0-9]+|0)$/;
702		if (!numericRegex.test(val)) 
703		{
704			return false;
705		}
706		return true;
707	},
708
709	isValidCurrency: function (val) 
710	{
711		var currencyRegex = /^\$?[1-9][0-9]{0,2}(,[0-9]{3})*(\.[0-9]{2})?$/;
712		if (!currencyRegex.test(val)) 
713		{
714			return false;
715		}
716		return true;
717	},
718
719	isValidDate: function (val) 
720	{
721		var dateRegex = /^(0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])[\/\-]\d{4}$/;
722		if (!dateRegex.test(val)) 
723		{
724			return false;
725		}
726		return true;
727	},
728
729	isValidTime: function (val)
730	{
731		var timeRegex = /^(0?[1-9]|1[012])(:[0-5]\d) [APap][mM]$/;
732		if (!timeRegex.test(val)) 
733		{
734			return false;
735		}
736		return true;
737	},
738
739	isValidSsn: function (val) 
740	{
741		var ssnRegex = /^\d{3}-?\d\d-?\d{4}$/;
742		if (!ssnRegex.test(val)) 
743		{
744			return false;
745		}
746		return true;
747    },
748
749    //Check for zipcode in database
750    isKnownZip: function (object) {
751        var parent = $(object).parent('div');
752        var zip = $(object).val();
753        var shortZip = zip.slice(0, 5);
754        var helpText = $(object).next('small');
755        var helpTextError = helpText.text().slice(0);
756
757        if (DN.Validation.isValidZip(zip)) {
758            satruck.api.CheckZipExists(shortZip, function (apiResult) {
759                if (apiResult && (apiResult.RetVal.ZipExists != true)) {
760                    //Set help text to an alternative warning
761                    helpText.html('Zip code not found...');
762                    DN.Validation.ShowError(parent, helpText);
763
764                    $(object).focus(function () {
765                        helpText.html(helpTextError);
766                        DN.Validation.HideError(parent);
767                    });
768
769                    isFilled = false;
770                    return false;
771                }
772                else {
773                    return true;
774                }
775            });
776        }
777        else {
778            return false;
779        }
780    },
781
782	isCallAheadAllowed: function (tid, aid) {
783		var allowed = false;
784		satruck.api.CheckCallAheadAllowed(tid, aid, function (apiResult) {
785			if (apiResult.RetVal.CallAheadAllowed == true) {
786				allowed = true
787			}
788			else {
789				allowed = false;
790			}
791		});
792		return allowed;
793	},
794	
795	isDonorExperienceEnabled: function (tid, aid) {
796		var allowed = false;
797		satruck.api.CheckDonorExperienceSetting(tid, aid, function (apiResult) {
798			if (apiResult.RetVal.Active == true) {
799				allowed = true
800			}
801			else {
802				allowed = false;
803			}
804		});
805		return allowed;
806	},
807
808	checkPassword: function(object)
809	{
810		var dialogContainer = $(object).next('#pswd_info');
811		$(object).on('keypress keyup', function() { 
812
813			var pswd = $(this).val();
814
815			if ( pswd.length < 6 ) {
816				dialogContainer.find('#length').removeClass('valid').addClass('invalid');
817			} else {
818				dialogContainer.find('#length').removeClass('invalid').addClass('valid');
819			}
820
821			if ( pswd.match(/[A-Z]/) ) {
822				dialogContainer.find('#capital').removeClass('invalid').addClass('valid');
823			} else {
824				dialogContainer.find('#capital').removeClass('valid').addClass('invalid');
825			}
826
827			if ( pswd.match(/\d/) ) {
828				dialogContainer.find('#number').removeClass('invalid').addClass('valid');
829			} else {
830				dialogContainer.find('#number').removeClass('valid').addClass('invalid');
831			}
832
833			//	Must include validation div, ex:
834			//	<div id="pswd_info">
835			//		<h4>Password must meet the following requirements:</h4>
836			//		<ul>
837			//			<li id="length" class="invalid">Be at least <strong>6 characters</strong></li>
838			//			<li id="capital" class="invalid">At least <strong>one capital letter</strong></li>
839			//			<li id="number" class="invalid">At least <strong>one number</strong></li>	
840			//		</ul>
841			//	</div>
842
843		}).focus(function() {
844			dialogContainer.addClass('shown');
845		}).blur(function() {
846			dialogContainer.removeClass('shown');
847		});
848	},
849	checkNumber: function (object, e) 
850	{
851		var charCode = (e.which || e.which == 0) ? e.which : event.keyCode;
852
853		var numeric = [0, 8, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
854		if (jQuery.inArray(charCode, numeric) == -1) 
855		{
856			return false;
857		}
858	},
859
860	checkInteger: function (object, e) 
861	{
862		var charCode = (e.which || e.which == 0) ? e.which : event.keyCode;
863
864		var numeric = [0, 8, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
865		if (jQuery.inArray(charCode, numeric) == -1) 
866		{
867			return false;
868		}
869	},
870
871	unFormatPhone: function (val) 
872	{
873		if (val != null) 
874		{
875			if (val.length > 0 && val[0] == "1") val = val.substring(1, val.length);
876			return (new String(val)).replace(/[^0-9]/g, "");
877		} 
878		else 
879		{
880			return "";
881		}
882    },
883
884    formatPhone: function (val, ext) {
885        if (this.isValidPhone(val)) {
886            var tmp = this.unFormatPhone(val);
887            tmp = "(" + tmp.substr(0, 3) + ") " + tmp.substr(3, 3) + "-" + tmp.substr(6, 4);
888
889            if (ext && ext != null && ext.length > 0)
890                tmp = tmp + ", ext. " + ext;
891
892            return tmp;
893        }
894        else {
895            return val;
896        }
897    },
898
899	limitCallAheadTimes: function (val, tid) {
900		var validTimes = satruck.controller.pickup.getCallAheadMinutes(tid);
901		var parsedVal = parseInt(val);
902        // Return default call ahead time if an unexpected value was entered
903        return validTimes.includes(parsedVal) ? parsedVal : "30";
904    },
905
906	fieldHasData: function(val, result)
907	{
908		var currentStep = val;
909		var requiredFields = $('.required');
910		var requiredFieldContainer = currentStep.find(requiredFields).length;
911		var qty = 0;
912		var isFilled = true;
913		if(requiredFieldContainer){
914			currentStep.find(requiredFields).each(function(i, e)
915			{
916				if (e.value.trim() == "" || e.value.trim() == "0")
917				{
918					var $parent = $(this).parent('div');
919					var $helpText = $(this).next('small');
920					DN.Validation.ShowError($parent, $helpText);
921					$(this).focus(function()
922					{
923						DN.Validation.HideError($parent);
924					});
925					if (!$('div[aria-describedby="contact-dialog-simple"]:visible').length && !$('div.contactDialog:visible').length && !$('div[aria-describedby="my-pickups-dialog"]:visible').length)
926					{
927						$('html,body').animate({ scrollTop: 0 }, 500);
928					}
929
930					isFilled = false;
931					return false;
932				}
933			});
934			if(isFilled == false) {
935				return false;
936			} else{
937				result();	
938			}
939			
940		}
941	},
942
943	// Site-wide error dialog
944	ShowError: function (item, text) 
945	{
946		var element = item;
947		var error = text;
948
949		if (element != null)
950        {
951		    element.addClass("has-error has-feedback");
952		}
953		if (error != undefined) {
954		    error.addClass('shown');
955		}
956	},
957	
958	ShowErrorEasy: function (id) 
959	{
960		var $parent = $(id).parent('div');
961		var $helpText = $parent.children('small');
962		$(id).focus(function()
963		{
964			DN.Validation.HideError($parent);
965		});
966
967		this.ShowError($parent, $helpText);
968	},
969
970	HideError: function (item) 
971	{
972		var element = item;
973		if(element.parent('div').hasClass('has-error') || element.hasClass('has-error')){
974			element.parent('div').removeClass('has-error has-feedback');
975			element.removeClass('has-error has-feedback');
976		}
977		element.children('small').removeClass('shown');
978	},
979
980	ResetValidation: function (css) 
981	{
982        var $elements = $(css);
983        if ($elements.parent('div').hasClass('has-error') || $elements.hasClass('has-error')) {
984            $elements.parent('div').removeClass('has-error has-feedback');
985            $elements.removeClass('has-error has-feedback');
986        }
987		$elements.children('small').removeClass('shown');
988	}
989};
990
991DN.Mask = 
992{
993	//This script is based on the javascript code of Roman Feldblum ([email protected])
994	//Original script : http://javascript.internet.com/forms/format-phone-number.html
995	//Original script is revised by Eralper Yilmaz (http://www.eralper.com)
996	//Revised script : http://www.kodyaz.com
997
998	zChar: new Array(' ', '(', ')', '-', '.'),
999
1000	maxphonelength: 14,
1001	maxziplength: 5,
1002	value1: null,
1003	value2: null,
1004	cursorposition: null,
1005
1006	PhoneNumberKeyUp: function (object, e) 
1007	{
1008		if (e)
1009			e = e
1010		else
1011			e = window.event
1012
1013		if (e.which)
1014			var keycode = e.which
1015		else
1016			var keycode = e.keyCode
1017
1018		this.value1 = this.ParseChar(object.value, this.zChar);
1019
1020		if (keycode >= 48)
1021			this.ValidatePhone(object)
1022	},
1023
1024	PhoneNumberKeyDown: function (object, e) 
1025	{
1026		if (e)
1027			e = e
1028		else
1029			e = window.event
1030
1031		if (e.which)
1032			var keycode = e.which
1033		else
1034			var keycode = e.keyCode
1035
1036		this.value2 = this.ParseChar(object.value, this.zChar);
1037	},
1038
1039	ZipKeyUp: function (object, e) 
1040	{
1041		if (e)
1042			e = e
1043		else
1044			e = window.event
1045
1046		if (e.which)
1047			var keycode = e.which
1048		else
1049			var keycode = e.keyCode
1050
1051		this.value1 = this.ParseChar(object.value, this.zChar);
1052
1053		if (keycode >= 48)
1054			this.ValidateZip(object)
1055	},
1056
1057	ZipKeyDown: function (object, e) 
1058	{
1059		if (e)
1060			e = e
1061		else
1062			e = window.event
1063
1064		if (e.which)
1065			var keycode = e.which
1066		else
1067			var keycode = e.keyCode
1068
1069		this.value2 = this.ParseChar(object.value, this.zChar);
1070	},
1071
1072	SsnKeyUp: function (object, e) 
1073	{
1074		if (e)
1075			e = e
1076		else
1077			e = window.event
1078
1079		if (e.which)
1080			var keycode = e.which
1081		else
1082			var keycode = e.keyCode
1083
1084		this.value1 = this.ParseChar(object.value, this.zChar);
1085
1086		if (keycode >= 48)
1087			this.ValidateSsn(object)
1088	},
1089	
1090	SsnKeyDown: function (object, e) 
1091	{
1092		if (e)
1093			e = e
1094		else
1095			e = window.event
1096
1097		if (e.which)
1098			var keycode = e.which
1099		else
1100			var keycode = e.keyCode
1101
1102		this.value2 = this.ParseChar(object.value, this.zChar);
1103	},
1104
1105	GetCursorPosition: function () 
1106	{
1107		var t1 = this.value1;
1108		var t2 = this.value2;
1109		var bool = false
1110
1111		for (i = 0; i < t1.length; i++) 
1112		{
1113			if (t1.substring(i, 1) != t2.substring(i, 1)) 
1114			{
1115				if (!bool) 
1116				{
1117					this.cursorposition = i
1118					bool = true
1119				}
1120			}
1121		}
1122	},
1123
1124	ValidatePhone: function (object) 
1125	{
1126		var p = this.value1
1127
1128		p = p.replace(/[^\d]*/gi, "")
1129
1130		if (p.length < 3)
1131			object.value = p
1132		else if (p.length == 3) 
1133		{
1134			pp = p;
1135			d4 = p.indexOf('(')
1136			d5 = p.indexOf(')')
1137
1138			if (d4 == -1)
1139				pp = "(" + pp;
1140
1141			if (d5 == -1)
1142				pp = pp + ")";
1143
1144			object.value = pp;
1145		}
1146		else if (p.length > 3 && p.length < 7) 
1147		{
1148			p = "(" + p;
1149			l30 = p.length;
1150			p30 = p.substring(0, 4);
1151			p30 = p30 + ") "
1152
1153			p31 = p.substring(4, l30);
1154			pp = p30 + p31;
1155
1156			object.value = pp;
1157		}
1158		else if (p.length >= 7) 
1159		{
1160			p = "(" + p;
1161			l30 = p.length;
1162			p30 = p.substring(0, 4);
1163			p30 = p30 + ") "
1164
1165			p31 = p.substring(4, l30);
1166			pp = p30 + p31;
1167
1168			l40 = pp.length;
1169			p40 = pp.substring(0, 9);
1170			p40 = p40 + "-"
1171
1172			p41 = pp.substring(9, l40);
1173			ppp = p40 + p41;
1174
1175			object.value = ppp.substring(0, this.maxphonelength);
1176		}
1177
1178		this.GetCursorPosition()
1179
1180		if (this.cursorposition >= 0) 
1181		{
1182			if (this.cursorposition == 0)
1183				this.cursorposition = 2
1184			else if (this.cursorposition <= 2)
1185				this.cursorposition = this.cursorposition + 1
1186			else if (this.cursorposition <= 6)
1187				this.cursorposition = this.cursorposition + 2
1188			else if (this.cursorposition == 7)
1189				this.cursorposition = this.cursorposition + 2
1190			else if (this.cursorposition == 8) {
1191				this.cursorposition = this.cursorposition + 4
1192				//e1=object.value.indexOf(')')
1193				e1 = object.value.indexOf(' ')
1194				e2 = object.value.indexOf('-')
1195
1196				if (e1 > -1 && e2 > -1) 
1197				{
1198					if (e2 - e1 == 4)
1199						this.cursorposition = this.cursorposition - 1
1200				}
1201			}
1202			else if (this.cursorposition < 12)
1203				this.cursorposition = this.cursorposition + 3
1204			else if (this.cursorposition == 12)
1205				this.cursorposition = this.cursorposition + 1
1206			else if (this.cursorposition >= 13)
1207				this.cursorposition = this.cursorposition
1208
1209			if (document.createRange) {
1210				var txtRange = document.createRange();
1211				var startNode = document.getElementsByTagName("input").item(2);
1212				var startOffset = 0;
1213				txtRange.setStart(startNode,startOffset);
1214			} else {
1215				var txtRange = object.createTextRange();
1216				txtRange.moveStart("character", this.cursorposition);
1217			}
1218			//txtRange.moveEnd("character", this.cursorposition - object.value.length);
1219			//txtRange.select();
1220		}
1221	},
1222
1223	ValidateSsn: function (object) 
1224	{
1225		var p = this.value1
1226
1227		p = p.replace(/[^\d]*/gi, "")
1228
1229		if (p.length < 3)
1230			object.value = p
1231		else if (p.length == 3) 
1232		{
1233			pp = p;
1234			d4 = p.indexOf('-')
1235			
1236			if (d4 == -1)
1237				pp = pp + "-";
1238
1239			object.value = pp;
1240		}
1241		else if (p.length > 3 && p.length < 6) 
1242		{
1243			l30 = p.length;
1244			p30 = p.substring(0, 3);
1245			p30 = p30 + "-"
1246
1247			p31 = p.substring(3, l30);
1248			pp = p30 + p31;
1249
1250			object.value = pp;
1251		}
1252		else if (p.length >= 6) 
1253		{
1254			l30 = p.length;
1255			p30 = p.substring(0, 3);
1256			p30 = p30 + "-"
1257
1258			p31 = p.substring(3, l30);
1259			pp = p30 + p31;
1260
1261			l40 = pp.length;
1262			p40 = pp.substring(0, 6);
1263			p40 = p40 + "-"
1264
1265			p41 = pp.substring(6, l40);
1266			ppp = p40 + p41;
1267
1268			object.value = ppp.substring(0, this.maxphonelength);
1269		}
1270
1271		this.GetCursorPosition()
1272
1273		if (this.cursorposition >= 0) 
1274		{
1275			if (this.cursorposition <= 2)
1276				this.cursorposition = this.cursorposition
1277			else if (this.cursorposition == 3)
1278				this.cursorposition = this.cursorposition + 1
1279			else if (this.cursorposition >= 6)
1280				this.cursorposition = this.cursorposition + 2
1281			
1282			if (document.createRange) {
1283				var txtRange = document.createRange();
1284				var startNode = document.getElementsByTagName("input").item(2);
1285				var startOffset = 0;
1286				txtRange.setStart(startNode, startOffset);
1287			} else {
1288				var txtRange = object.createTextRange();
1289				txtRange.moveStart("character", this.cursorposition);
1290			}
1291
1292		}
1293	},
1294
1295	ValidateZip: function (object) 
1296	{
1297		var z = this.value1
1298
1299		z = z.replace(/[^\d]*/gi, "")
1300
1301		if (z.length <= 5)
1302			object.value = z
1303		else if (z.length >= 6) 
1304		{
1305			l30 = z.length;
1306			p30 = z.substring(0, 5);
1307			p30 = p30 + "-"
1308
1309			p31 = z.substring(5, l30);
1310			pp = p30 + p31;
1311
1312			object.value = pp.substring(0, this.maxziplength);
1313		}
1314
1315		this.GetCursorPosition()
1316
1317		if (this.cursorposition >= 0) 
1318		{
1319			if (this.cursorposition == 4)
1320				this.cursorposition = this.cursorposition + 1
1321			else if (this.cursorposition >= 5)
1322				this.cursorposition = this.cursorposition
1323
1324			if (document.createRange) {
1325				var txtRange = document.createRange();
1326				var startNode = document.getElementsByTagName("input").item(2);
1327				var startOffset = 0;
1328				txtRange.setStart(startNode,startOffset);
1329			} else {
1330				var txtRange = object.createTextRange();
1331				txtRange.moveStart("character", this.cursorposition);
1332			}
1333		}
1334	},
1335
1336	ParseChar: function (sStr, sChar) 
1337	{
1338		if (sChar.length == null)
1339			zChar = new Array(sChar);
1340		else
1341			zChar = sChar;
1342
1343		for (i = 0; i < zChar.length; i++) 
1344		{
1345			sNewStr = "";
1346
1347			var iStart = 0;
1348			var iEnd = sStr.indexOf(sChar[i]);
1349
1350			while (iEnd != -1) 
1351			{
1352				sNewStr += sStr.substring(iStart, iEnd);
1353				iStart = iEnd + 1;
1354				iEnd = sStr.indexOf(sChar[i], iStart);
1355			}
1356
1357			sNewStr += sStr.substring(sStr.lastIndexOf(sChar[i]) + 1, sStr.length);
1358
1359			sStr = sNewStr;
1360		}
1361
1362		return sNewStr;
1363	}
1364};

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.