PageSourceSearch

https://www.boll.ch/ajax/mybic.js

js boll.ch collected 2026-10-02 17:15:52 UTC 31,670 bytes, 902 lines download raw bytes

1// using version of bind from prototype for scoping purposes
2Function.prototype.mybicBind = function(object) {  
3  var __method = this;
4  return function() {
5    return __method.apply(object, arguments);
6  }
7};
8
9/**
10* Constructor for MyBIC's ajax object
11* This only needs to be instantiated once in your script and you'll be able to re-use the same object for all your requests
12*@constructor
13*@author Jim Plush [email protected]
14*@param {string} server_url The URL of the page you're going to connect to on the server, by default mybic_server.php
15*@param {string} readyStateFunction (OPTIONAL)The function that will be called when ajax responses come back from the server, by default mybic handles this for you
16*/
17function XMLHTTP(server_url, readyStateFunction)
18{
19	/** 
20	* the SERVER page URL to connect to IE ajax_server.php 
21	*@type String
22	*/
23	this.server_url = server_url;
24	 
25	/**
26	*  whether we're in syncronous mode or async (default), syncronous means the UI will lock up until the response is received - you rarely would want this.
27	*@type String
28	*/	
29	this.async = true;	
30	
31	/** 
32	* debug turned off by default, to see your request/response do ajaxObj.debug=1, useful for seeing what's going on with your ajax requests
33	*@type int
34	*/			
35	this.debug=0;
36					
37	/**
38	* this enables throttling by default so all your requests are in the proper order
39	*@type int
40	*/		
41	this.throttle=1;				
42	
43	/**
44	* by default all requests are sent via POST to override just use ajaxObj.method="GET"; before your call
45	*@type String
46	*/
47	this.method = "POST";
48	
49	/**
50	* by default JSON encoding is the expected format, to override: ajaxObj.format = "XML"; or ajaxObj.format="TEXT";
51	* if you're planning to just load HTML snippets for innerHTML use, just set this to TEXT
52	*@type String
53	*/
54	this.format = "JSON";				
55					
56	/**
57	* array of optional headers you may pass in
58	*@type Array
59	*/
60	this.headers = new Array();			
61	
62	/**
63	* the number of seconds to wait before calling network down function, set to -1  disable feature, defaults to 5 seconds
64	*@type int
65	*/
66	this.abort_timeout = 30000;	
67			
68	/** 
69	* the number of failed requests before mybic is disabled -> prevents repeated error notifications, no more ajax requests will fire after this amount of failures
70	*@type int
71	*/
72	this.failed_threshold = 3;		
73	
74	/**
75	*  set this to 1 if you have a polling object and you don't want to see debug msgs every second or activity indicators, nice to keep out of firebug
76	*@type
77	*/	
78	this.ignoreCall = 0;
79					
80	/**
81	* set this to one in your client code if you want to make sure your callback functions completes before making another ajax call in the queue
82	*@type int
83	*/
84	this.stopRequest = 0;				
85
86	/** 
87	* ERROR HANDLERS YOU CAN SET, TO OVERRIDE OR COMPLIMENT EXISTING FUNCTIONALITY
88	*/
89	
90	/**
91	* Set this to a function in your website that will handle pop up errors in your call back function more gracefully DO FOR LIVE SITES!
92	* this is used when your callback function experiences a fatal error, mybic can execute a nicer function for you and pass you the error object
93	* note: do not assign with parens, do this ajaxObj.jsErrorHandler = myFunction;
94	*@type function
95	*/
96	this.jsErrorHandler = '';       
97	   
98	/**
99	* set this to a function in your website that will handle pop up errors in your call back function more gracefully
100	*/
101	this.notAuthorizedHandler = '';    
102	
103	/**
104	* the function that will be called if mybic cannot make a request to the server (server down)
105	* if 'disabled' is passed to your function, then no more ajax calls can be made, you might want to reload the whole page at this point
106	*/ 
107	this.net_down_func = this.down;		
108	
109	
110	/*-- SYSTEM PROPERTIES - no need to change the properites below --*/
111	/**
112	*@private
113	*/
114	this.version = '1.0.1';
115	
116	/**
117	* the xmlhttprequest variable, starts off as null
118	*@private
119	*/
120	this.req = null;	
121				
122	/**
123	* used for showing expandable visual debug data
124	*@private
125	*/
126	this.debugID = 0;
127					
128	/**
129	* array of errors generated
130	*@private
131	*/
132	this.errors = new Array();
133	
134	/**
135	* the queue that will handle the throttling requests to keep your stuff in sync
136	*@private
137	*/	
138	this.queue = new Array();	
139	
140	/**
141	* the current index for the throttling array
142	*@private
143	*/			
144	this.queue_in_process = 0;
145	
146	/**
147	* system uses this to see what calls to ignore from the queue
148	*@private
149	*/				
150	this.currentCallIgnore=0;
151	
152	/**
153	* the timer used to check the readystate of the xmlhttprequest to prevent memory leaks
154	*@private
155	*/				
156	this.readySateTimer = '';
157	
158	/**
159	* the callback function, when the ajax request is sent, this is the function that will be called
160	*@private
161	*/				
162	this.callBack = '';	
163	
164	/**
165	* cache which version of msxml to use on IE to avoid using the loop every time
166	*@private
167	*/	
168	this.IEObjCache = 0;
169	
170	/**
171	* number of failed requests in a row
172	*@private
173	*/					
174	this.failed_requests=0	
175	
176	/**
177	* holds the callback function for ajax calls
178	*@private
179	*/		
180	this.readyStateFunction = (readyStateFunction) ? readyStateFunction : this.responseHandler;
181	
182	/**
183	* holds the current queue of msgs to try to match up request/responses
184	*@private
185	*/	
186	this._msgQueueInfo = new Array();	
187	
188	/**
189	* the timer used to check the readystate of the xmlhttprequest to prevent memory leaks
190	*@private
191	*/	
192	this.readyStateTimer   = '';   
193	
194	/**
195	* the time interval used to check the readystate of the xmlhttprequest to prevent memory leaks
196	*@private
197	*/	
198	this.poolTimerInterval = 50;    
199	
200}
201
202/**
203* Method to create an XMLHTTP object
204*@access private
205*/
206XMLHTTP.prototype = {
207	getXMLHTTP:function() {
208	
209		// moz-IE7 XMLHTTPRequest object
210		if (window.XMLHttpRequest) { this.req = new XMLHttpRequest(); }
211		else if (this.IEObjCache != 0) { alert(this.IEObjCache);try {this.req = new ActiveXObject(this.IEObjCache);}catch(e){} }
212		else if (window.ActiveXObject){
213			// 6.0 is recommended for all vista + users, 3.0 is recommended over all 4 & 5 versions
214			var progIDs = [ 'MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.3.0','Microsoft.XMLHTTP'];
215	        for (var i = 0; i < progIDs.length; i++) {
216	            try {
217	                this.req = new ActiveXObject(progIDs[i]);
218	      			this.IEObjCache = progIDs[i];
219	                break;
220	            }
221	            catch (ex) {}
222	        }
223	   } else {
224			if(this.debug == 1) { this.showDebug("<BR>FATAL ERROR: Could not create XMLHTTPRequest Object!<BR>");	}
225	   }
226		return this.req;
227	},
228	/**
229	* Main API method to use for AJAX requests
230	* example: ajaxObj.call("action=loadComments&id=1", myCallBackFunction);
231	*@access public
232	*@param string A url encoded string of data to send to the server
233	*@param string A callback function that the server will launch when the response is generated
234	*@param string Used by the response handler function to send back throttled requests, you won't need to worry about this param
235	*/
236	call:function(queryVars, userCallback, queue_request) {
237	
238		// test for too many failed requests
239		if(this.failed_requests >= this.failed_threshold) {
240			// call network down method with instruction to notify of mybic being disabled
241			this.net_down_func('disable');
242			return false;
243		} else {
244			var currentVars;
245			var callback;
246			this.fullUrl = '';
247	
248			if(this.throttle == 1 && queue_request != 'queue' || this.stopRequest == 1) {		// throttling keeps your requests in sync, so things aren't out of order
249				this.add2Queue(queryVars, userCallback);
250			}
251		
252			if(this.queue_in_process == 0) {
253				if(!this.getXMLHTTP()) {
254					return false;
255				}
256			
257				if(this.throttle == 1) {
258					this.queue_in_process = 1;
259					var currentCall = this.queue.shift();	// get the current call to make
260					currentVars = currentCall.queryVars;
261					callback = currentCall.userCallback;
262					this.format = currentCall.format;
263					this.method = currentCall.method;
264					this.abort_timeout = currentCall.abortTimeout;
265					this.currentCallIgnore = currentCall.ignoreCall;
266					this.async = currentCall.async;
267				} else {
268					currentVars = queryVars;
269					callback = userCallback;
270					var ignoreCall=0;
271				
272				}
273				this.callBack = callback;
274		
275				// check for JSON encoding
276				if(this.format != 'JSON') {
277					currentVars = currentVars+'&json=false';
278				}
279				
280				// if get is used, append the query variables to the url string 
281				this.full_url = (this.method == "POST") ? this.server_url : this.server_url + '?'+ currentVars;
282			
283				if(this.debug == 1 && this.currentCallIgnore != 1) {
284					try {
285					var matches = currentVars.match(/action=(\w+)&?/);
286					this.showDebug('new', 'MYBIC - CALLING: '+matches[1]);
287					this.showDebug("Server Page: "+this.server_url+"<BR>HTTP Method: "+this.method+"<BR>Encoding Format: "+this.format+"<BR>Query String: "+currentVars+"<BR>");
288					}catch(e){}
289				}
290			
291				// open connection
292				this.req.open(this.method, this.full_url, this.async);
293			
294				// set any optional headers
295				if(this.headers){
296					for(var i in this.headers) {
297						if(i != '' && (this.headers[i] instanceof String)) {
298							try {
299								this.req.setRequestHeader( i, this.headers[i]);
300								if(this.debug == 1) { this.showDebug('Setting Custom Header: '+this.headers[i]+'<br>');}
301							} catch(e) {}
302						}
303					}
304				}
305				// START TIMER TO ABORT REQUEST
306				if(this.abort_timeout != -1) {
307					this.end_timer = setInterval(this.endCall.mybicBind(this), this.abort_timeout);
308				}
309				// send request
310				if(this.method == 'POST') {
311					this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
312					this.request = currentVars;
313					this.req.send(currentVars);
314				} else {
315					this.req.send(null);
316				}
317			
318				// START POLLING FOR READYSTATECHANGE
319				if (this.readyStateFunction) {
320						this.readyStateTimer = window.setInterval(
321				        this.readyPoolFunc.mybicBind(this),
322				        this.poolTimerInterval      // poll every 50 milliseconds for ready state
323				    );
324				 }
325			
326			}
327		}
328	
329	},
330	
331	/**
332	*
333	*@private
334	*/	
335	readyPoolFunc:function() {
336		if(this.req && this.req.readyState == 4) {
337			window.clearInterval(this.readyStateTimer);
338			this.readyStateTimer = null;
339			// call the current response handlet - responseHandler by default 
340			this.readyStateFunction();
341		}
342	},
343
344/**
345* Default method for parsing the response from the server. It will try to eval the obj.method_to_call property and pass the native JS object
346*private
347*/
348	responseHandler:function() {
349		if(this.req) {
350			try {
351			// only if req shows "complete"
352			if (this.req.readyState == 4) {
353				// only if "OK"	
354				if (this.req.status && this.req.status == 200) {
355					if(this.req.responseText.indexOf('ajax_msg_failed') != -1) {
356						this.showDebug("Fatal Error: mybic_server sent back ajax_msg_failed! - MSG: "+this.req.responseText+"<br/>");
357						if(this.req.responseText.indexOf('notauth') != -1) { 
358							if(this.abort_timeout != -1) { clearInterval(this.end_timer); }
359							if(this.notAuthorizedHandler == '') {
360								this.callBack('notauthorized');
361							} else {
362								try {
363									this.notAuthorizedHandler();
364								}catch(e) {
365								
366								}
367							}
368						
369						} else {
370							this.callBack(false); 
371						}
372					} else {
373						// clear out network down timer
374						if(this.abort_timeout != -1) {
375							clearInterval(this.end_timer);
376						}
377						if(this.throttle == 1) {
378							var req = this._msgQueueInfo.shift();
379							var format = req.format;
380						} else {
381							var format = this.format;	
382						}
383					
384						if(format == "JSON") {
385						try {
386							var myObject = JSON.parse(this.req.responseText);
387						// callback function we passed to the server to process the results
388					
389						if(document.getElementById(this.callBack)) {
390							document.getElementById(this.callBack).innerHTML = myObject;
391						} else {
392							this.callBack(myObject);
393						}
394					
395						} catch(e) {
396						
397								if(this.jsErrorHandler == '') {
398									alert('An error occurred in your response function, NOT mybic related. Error Name: ' + e.name + '  Message:' + e.message);
399								} else {
400									// try to call the users javascript error handling function, have to show a popup 
400if that sucker has en error in it too
401									try { this.jsErrorHandler(e); } catch(err) { alert('Error: your errorhandling function has an error - name: '+err.name + ' message: '+err.message)}
402								}
403								
404						}
405						} else if(this.format == "XML") {
406							// send the raw xml data to the callback function
407							this.callBack(this.req.responseXML);	
408						} else {
409							try {
410								if(document.getElementById(this.callBack)) {
411								document.getElementById(this.callBack).innerHTML = this.req.responseText;
412								} else {
413									this.callBack(this.req.responseText);
414								}
415							} catch(e) {
416								if(this.jsErrorHandler == '') {
417									alert('An error occurred in your response function, NOT mybic related. Error Name: ' + e.name + '  Message:' + e.message);
418								} else {
419									// try to call the users javascript error handling function, have to show a popup if that sucker has en error in it too
420									try { this.jsErrorHandler(e); } catch(err) { alert('Error: your errorhandling function has an error - name: '+err.name + ' message: '+err.message)}
421								}
422							}
423
424						}
425				
426					}
427				
428					this.failed_requests = 0; // reset failed requests back to 0
429				} else {
430					// server is came back with a bad status
431					try{
432					this.showDebug("Fatal Error: MSG: "+this.req.responseText+" StatusText: "+this.req.statusText+"<br/>");
433					} catch(e){}
434					this.endCall();	
435				}
436				try {
437					if(this.debug == 1 && this.currentCallIgnore != 1) {
438							// STRIP HTML
439							var str = this.req.responseText.replace(/(\<)/gi, '&lt;');
440							var str = str.replace(/(\>)/gi, '&gt;');
441							this.showDebug("HTTP Server Response:<br/> "+str+"<br>");
442						}
443				} catch(e) { }
444				
445				// reset the method, format, etc back to class defaults
446				this.restoreDefaults();
447			
448				// reset our queue and call
449				this.queue_in_process = 0;
450				this.req = null;
451				if(this.queue.length > 0) {
452				
453					this.call('','','queue');
454				}
455			}
456			} catch(e) { 
457			/*network is down*/}
458		}
459	
460	},
461
462
463	/**
464	* This method will allow you to lazy load javascript source files for on-demand javascript processing
465	* Just pass in the url of the javascript file you wish to pull in and you're all set, its not ajaxified so you 
466	* can pull in scripts from any URL you want! You can also use this function to remove scripts from the DOM as well
467	* Just pass in 'remove' as the 2nd parameter with the 1st parameter being the file you want to remove
468	* Removal is good for memory heavy desktop type apps you might be creating
469	*@param string The URL of the script you wish to load
470	*@param string OPTIONAL If you wish to remove a javascript file from the DOM then just pass in 'remove' as the 2nd parameter
471	*/
472	loadScript:function(url, remove) {
473		try{
474			// lets check to see if the script is already loaded, if so lets remove it and add a new one
475			var scripts = document.getElementsByTagName('script');
476			s_len = scripts.length;
477			for(var i=0;i<s_len;i++){
478				var reg = new RegExp(url+"$");
479				if (reg.test(scripts[i].src)) {
480					var p2 = scripts[i];
481					p2.parentNode.removeChild(p2);
482					break;
483				}	
484			}
485			if(remove != 'remove') {
486				newScript = document.createElement("script");
487				newScript.setAttribute("type", "text/javascript");
488				newScript.setAttribute("src", url);
489				document.getElementsByTagName('head')[0].appendChild(newScript);
490			}
491		} catch(e) {
492			this.showDebug("MyBIC - loadScript failed URL: "+url+" ErrName: "+e.name+" Msg: "+e.message);	
493		}
494
495	},
496
497	/**
498	* This method will allow you to create a "command queue" so ajax requests are sent in order they were fired. 
499	* You will be able to keep your request/responses in order they were sent
500	*@private
501	*/
502	add2Queue:function(queryVars, userCallback) {
503		var addAjax = new Array();
504		addAjax['queryVars'] = queryVars;
505		addAjax['userCallback'] = userCallback;
506		addAjax['ignoreCall'] = this.ignoreCall;
507		addAjax['abortTimeout'] = this.abort_timeout;
508		addAjax['format'] = this.format;
509		addAjax['method'] = this.method;
510		addAjax['async'] = this.async;
511		var opts = new Object();
512		opts.format = this.format;
513		this._msgQueueInfo.push(opts);
514		this.ignoreCall=0;	// reset back to original state
515		this.queue.push(addAjax);
516	},
517
518
519	/**
520	* Method called after callback function is called to return the class to a default state
521	*@private
522	*/
523	restoreDefaults:function()
524	{
525		this.method = "POST";
526		this.format = "JSON";	
527		this.callback = "";
528		this.abort_timeout = 30000;
529		this.failed_threshold = 3;	
530		this.async = true;
531	
532	},
533
534	/**
535	* This method will allow you to get all your form fields in ONE magical step!
536	* right before your ajaxObj.call statement all you have to do is: var form_vars = ajaxObj.getForm('formid');
537	* that will loop through the form id you pass, and put all the form variables into your query string!
538	*@param string The ID of the form you wish to submit
539	*@return string An encoded query string, ready to send to the server
540	*/
541
542	getForm:function(formid) {
543		var formobj = document.getElementById(formid);
544		var fields = new Array();
545		var form_len = formobj.elements.length;
546		for (var x = 0; x < form_len; x++) {
547		
548			// rf, 10.07.2017, disabled elements may not be transfered
549			if (formobj.elements[x].disabled == true) continue;
550		
551			switch(formobj.elements[x].type) {
552			   case 'select-one':
553		
554				fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].options[formobj.elements[x].selectedIndex].value));
555				break;
556				case 'select-multiple':
557				var obj = formobj.elements[x];
558					for(var y=0; y < formobj.elements[x].options.length; y++) {
559					   if(formobj.elements[x].options[y].selected) {
560								if(formobj.elements[x].options[y].value == ''){
561									fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].options[y].text));
562								} else {
563									fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].options[y].value));
564								}
565					   }
566					}
567				break;
568				case 'radio':
569					   if(formobj.elements[x].checked) {
570							   fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].value));
571					   }
572		        break;
573				case 'checkbox':
574					if(formobj.elements[x].checked) {
575						fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].value));
576					}
577				break;
578				default:
579				// text, password, textarea, etc
580				fields.push(encodeURIComponent(formobj.elements[x].name)+'='+encodeURIComponent(formobj.elements[x].value));
581				break;
582			}
583		}
584		var new_qstring = '&' + fields.join('&');
585		return new_qstring;
586	},
587
588	/**
589	* This method will check the request call after x number of seconds to see if the network call is still hanging
590	* You will want to use this when your server might be down and after 5 seconds you'll want to call a function that lets the 
591	* user know you're having server issues
592	*@private
593	*/
594	endCall:function() {
595		try{
596			this.net_down_func();
597			this.req.abort();
598			this.req = null;
599			clearInterval(this.end_timer);
600			clearInterval(this.readyStateTimer);
601			// increase failed requests variable
602			this.failed_requests++;
603			// reset our queue and call
604			this.queue_in_process = 0;
605			if(this.queue.length > 0) {
606			
607				this.call('','','queue');
608			}
609		
610			if(this.debug == 1) { this.showDebug("Request Failed - Network Down! Current Failed Attempts: "+this.failed_requests+"<br>");}
611		} catch(e) {
612			// server is completely down, call netdown function
613			clearInterval(this.end_timer);
614			this.net_down_func('disable');
615		}
616		this.req = null;
617	},
618	
619	/**
620	* Default method that will be called when mybic experiences a network down situation, or is disabled
621	* This method will pop up a div alerting the user of a general network error
622	* You should define your own method to properly fit in with your page layout
623	*@private
624	*/
625	down:function(status) {
626		var notif_div = '<div id="mybic_notification" style="text-align:center;padding:20px;position:absolute;top:100px;left:100px;width:300px;border:thin solid black;background-color:#F8F021;">';
627		notif_div 	+= 	'<span id="mybic_notif_msg"> MSGHERE </span> <br><br><input type="button" value="OK" onclick="document.getElementById(\'mybic_notification\').style.display=\'none\';"></div>';
628		if(status == 'disable') {
629			var notif = 'A network issue has disabled network connections for this page. Please reload this page or contact the site administrator';
630		} else {
631			var notif = 'A network issue has occurred which canceled your last request';
632		}
633		// lets try and find an existing error message or use the current one in the DOM
634		try{
635			if(document.getElementById('mybic_notification')) {
636				document.getElementById('mybic_notification').style.display='block';
637			} else {
638				var new_div = document.createElement('div');
639				new_div.innerHTML = notif_div;
640				document.body.appendChild(new_div);
641			}
642			document.getElementById('mybic_notif_msg').innerHTML = notif;
643		} catch(e) { 
644			alert('Network Unavailable: Please re-load page or contact the site administrator');
645		}
646	},
647
648	/**
649	* This method will allow you to lazy load stylesheet source files for on-demand css
650	* Just pass in the url of the css file you wish to pull in and you're all set, its not ajaxified so you 
651	* can pull in scripts from any URL you want. 
652	*@param string The URL of the css file you wish to load /lib/css/myfile.css
653	*/
654	loadCSS:function(url)
655	{
656		try{
657			// lets check to see if the script is already loaded, if so lets remove it and add a new one
658			var scripts = document.getElementsByTagName('link');
659			s_len = scripts.length;
660			if(s_len > 0) {
661				for(var i=0;i<s_len;i++){
662					var reg = new RegExp(url+"$");
663					if (reg.test(scripts[i].href)) {
664						var p2 = scripts[i];
665						p2.parentNode.removeChild(p2);
666						break;
667					}	
668				}
669			}
670				newScript = document.createElement("link");
671				newScript.setAttribute("type", "text/css");
672				newScript.setAttribute("rel", "stylesheet");
673				newScript.setAttribute("href", url);
674				document.getElementsByTagName('head')[0].appendChild(newScript);
675			                                                 
676		} catch(e) {
677			if(this.debug==1) {this.showDebug("MyBIC - loadCSS failed URL: "+url+" ErrName: "+e.name+" Msg: "+e.message)};	
678		}
679
680	},
681	
682	/**
683	* This method will let developers view debug information on the screen from not only the system calls but also let them tap into it as well
684	*@access public
685	*@param string The Message you wish to push to debugging or pass in 'break' and the UI will break a new expandable column for you
686	*@param string OPTIONAL: If you pass in break, also send in a string that will show what the break label should be
687	*@param int OPTIONAL: If you pass in break, if you pass in a 1 to the function it will allow you have your section autoexpanded
688	*/
689	showDebug:function(msg, label, expand) {
690	  if(this.debug == 1)
691	  {
692	    if(!document.getElementById('mybic_debug')) {
693	      var errs = document.createElement('div');
694	      errs.id = 'mybic_errs';
695	      var deb = document.createElement('div');
696	      deb.id = 'mybic_debug';
697	      deb.style.border = "thick solid black";
698	      deb.style.backgroundColor = "#eeeeee";
699	      deb.style.padding = "10px"; 
700	      deb.style.margin = '75px 10px 10px 10px';
701	      deb.style.width = '90%';
702	      deb.style.position = 'absolute';
703	      deb.style.zIndex = '999';
704	      deb.innerHTML += 'MyBic Debugger: <a href="#" onclick="document.getElementById(\'mybic_errs\').style.display = (document.getElementById(\'mybic_errs\').style.display==\'none\') ? \'\':\'none\'; return false;" >hide/show me!</a>';
705	      deb.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="document.getElementById(\'mybic_errs\').innerHTML = \'\'; return false;">Clear</a>';
706	      deb.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="XMLHTTP.prototype.debug_expand(\'block\');return false;">Expand All</a>'; //TODO:
707	      deb.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="XMLHTTP.prototype.debug_expand(\'none\'); return false;">Contract All</a><br><br>';//TODO:
708	      deb.appendChild(errs);
709	      if(document.body) {
710	        document.body.appendChild(deb);
711	      } else {
712	        document.lastChild.appendChild(deb);
713	      }
714	    }
715	    var deb = document.getElementById('mybic_errs');
716	    if(msg == 'new') {
717	      this.debugID++;
718	      var dimg = '<a style="color:white;font-size:1.1em;text-decoration:none" href="#" onclick="XMLHTTP.prototype.debug_expand(this);return false;">+</a>';
719	      deb.innerHTML += '<div id="mybiclabel_'+this.debugID+'" style="display:block;border:thin solid #999999;padding:2px;background-color:#cccccc;">'+dimg+' label'+this.debugID+': '+label+'</div>';
720	    } else {
721	      deb.innerHTML +='<div class="mybic_debug'+this.debugID+'" style="padding:5px;display:none; border:thin solid white;">'+msg+'</div>';
722	    } 
723	  }   
724	},
725
726
727	/**
728	* This method is used by MyBic to visually show the debug data you've passed in
729	*@private
730	*@param object The image element that triggers the show/hide functionality
731	*/
732	debug_expand:function(el) {
733		var deb = document.getElementById('mybic_errs');
734		var deb_len = deb.childNodes.length;
735		if(el == 'none' || el == 'block') {
736			var label = "mybic_debug";
737			var links = deb.getElementsByTagName('a');
738			var links_len = links.length;
739			for(var q=0;q<links_len;q++) {
740				links[q].innerHTML = (el == 'none') ? '+' : '>';	
741			}
742		} else {
743			var label = el.parentNode.id;
744			label = label.split('_');
745			label = "mybic_debug"+label[1];
746		}
747		for(var i=0; i<deb_len; i++) {
748			// loop through and show the elements with the right classname
749			try {
750			if(deb.childNodes[i].className.match(new RegExp("(^"+ label + ".*$)"))) {
751				if(el == 'none' || el == 'block') {
752					deb.childNodes[i].style.display = el;
753				} else {
754					if(deb.childNodes[i].style.display == 'block') {
755						el.innerHTML = '+';
756						deb.childNodes[i].style.display = 'none';
757					} else {
758						el.innerHTML = '>';
759						deb.childNodes[i].style.display = 'block';
760					}
761				}
762			}
763			} catch(e) {}
764		}
765	},
766
767	/**
768	* This method is a wrapper for when you have a callback funciton that has to finish executing before any other ajax calls are made
769	* You may be in this situation when ajax calls rely on each other IE don't update this data until I finish processing the other data
770	*/
771	restart:function() {
772		this.stopRequest=0;
773		this.call('','','queue');
774	}
775	
776};
777	
778	
779/****************************************************/
780// INCLUDE JSON.ORG's JSON CLIENT SIDE SERIALIZER
781/*
782Copyright (c) 2005 JSON.org
783*/
784
785/**
786*    The global object JSON contains two methods.
787*
788*    JSON.stringify(value) takes a JavaScript value and produces a JSON text.
789*    The value must not be cyclical.
790*
791*    JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
792*    return false if there is an error.
793*/
794var JSON = function () {
795    var m = {
796            '\b': '\\b',
797            '\t': '\\t',
798            '\n': '\\n',
799            '\f': '\\f',
800            '\r': '\\r',
801            '"' : '\\"',
802            '\\': '\\\\'
803        },
804        s = {
805            'boolean': function (x) {
806                return String(x);
807            },
808            number: function (x) {
809                return isFinite(x) ? String(x) : 'null';
810            },
811            string: function (x) {
812                if (/["\\\x00-\x1f]/.test(x)) {
813                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
814                        var c = m[b];
815                        if (c) {
816                            return c;
817                        }
818                        c = b.charCodeAt();
819                        return '\\u00' +
820                            Math.floor(c / 16).toString(16) +
821                            (c % 16).toString(16);
822                    });
823                }
824                return '"' + x + '"';
825            },
826            object: function (x) {
827                if (x) {
828                    var a = [], b, f, i, l, v;
829                    if (x instanceof Array) {
830                        a[0] = '[';
831                        l = x.length;
832                        for (i = 0; i < l; i += 1) {
833                            v = x[i];
834                            f = s[typeof v];
835                            if (f) {
836                                v = f(v);
837                                if (typeof v == 'string') {
838                                    if (b) {
839                                        a[a.length] = ',';
840                                    }
841                                    a[a.length] = v;
842                                    b = true;
843                                }
844                            }
845                        }
846                        a[a.length] = ']';
847                    } else if (x instanceof Object) {
848                        a[0] = '{';
849                        for (i in x) {
850                            v = x[i];
851                            f = s[typeof v];
852                            if (f) {
853                                v = f(v);
854                                if (typeof v == 'string') {
855                                    if (b) {
856                                        a[a.length] = ',';
857                                    }
858                                    a.push(s.string(i), ':', v);
859                                    b = true;
860                                }
861                            }
862                        }
863                        a[a.length] = '}';
864                    } else {
865                        return;
866                    }
867                    return a.join('');
868                }
869                return 'null';
870            }
871        };
872    return {
873        copyright: '(c)2005 JSON.org',
874        license: 'http://www.JSON.org/license.html',
875/**
876*    Stringify a JavaScript value, producing a JSON text.
877*/
878        stringify: function (v) {
879            var f = s[typeof v];
880            if (f) {
881                v = f(v);
882                if (typeof v == 'string') {
883                    return v;
884                }
885            }
886            return null;
887        },
888/*
889    Parse a JSON text, producing a JavaScript value.
890    It returns false if there is a syntax error.
891*/
892        parse: function (text) {
893            try {
894                return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
895                        text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
896                    eval('(' + text + ')');
897            } catch (e) {
898                return false;
899            }
900        }
901    };
902}();

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.