function $( tag ) {
	// usage:  obj = $( somevar )  in which somevar is either an id tag or the object itself.. for when you're lazy!
	return typeof( tag ) == "object" ? tag : document.getElementById( tag );
}

function $$( tag ) {
	// the only difference between $$( ) and $( ) is that this function makes sure you got the updated version of the object.
	// $( <old_obj> ) would return the old obj, not a newly fetched object with the id of old_obj. $$( ) does.
	return $( $( tag ).id );
}

function getParentByValue( tag, key, value, stopat ) {
	// if stopat is supplied (either object or object id), we'll stop looping when we hit that object.
	var obj = $( tag );
	stopat = (typeof(stopat)=='undefined') ? (document.body ? document.body : document.documentElement) : $(stopat);
	while( obj && (typeof( obj ) == "object") && (obj != stopat) && (obj[key] != null ) && (obj[key] != value)  ) {
		obj = obj.parentNode;
	}
	return (obj && obj[key] == value ? obj : false);
}

function getParentByAttribute( tag, attribute, attributeValue, stopat ) {
	// The attributeValue argument is optional: if not supplied, the first
	// parentNode with an attribute value != null will be returned.
	var obj = $( tag );
	stopat = (typeof(stopat)=='undefined') ? (document.body ? document.body : document.documentElement) : $(stopat);
	while( obj && (typeof( obj ) == "object") && (obj != stopat) && (attributeValue ? obj.getAttribute(attribute) != attributeValue : obj.getAttribute(attribute) == null ) ) {
		obj = obj.parentNode;
	}
	return (obj && (obj.getAttribute(attribute) != null) && (attributeValue ? obj.getAttribute(attribute) == attributeValue : 1) ) ? obj : false;
}

function getParentByClass( tag, classname, stopat ) {
	return getParentByValue( tag, 'className', classname, stopat );	
}

function get_children( node ) {
	// This function returns the children of a node that are a element object
	// because Firefox considers every newline (\n) and other whitespace to be a textnode. This is DOM..
	// Hence, the pure childNodes contain a lot of undefined elements (no id, no visible innerHTML)
	//
	// Apparently, i was being silly.
	return node.getElementsByTagName( 'div' ); // returns all the elements i'll be looking for.. 
	var children = node.childNodes;
	for( var i = 0; i < children.length; i++ ) {
		if( children.item( i ).nodeType != 1 ) { 
			// child is not an element.. kill it!
			// please use caution, as this actually removes all text from your parent..
			node.removeChild(  children[i] );
		}
	}	
	return children;
}

function get_firstchild(n) {
	if( !(n.hasChildNodes()) ) {
		return;
	}
	var x=n.firstChild;
	while (x.nodeType!=1) {
		x=x.nextSibling; // this needs to fail & break the while, otherwise we'll keep running till neverland
	}
	return x;
}

function trueInt( x ) {
	return isNaN( i = parseInt( x ) ) ? 0 : i;
}

function copytoclipboard( txt ) {
	// only use strings!
	if( typeof( window.clipboardData ) == "object" )	 {
		window.clipboardData.setData( 'Text', txt );
	} else {
		// Firefox clipboard manipulation has been 'outlawed' from version 3.0 and higher.
//		netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
//		const gClipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
//		gClipboardHelper.copyString(txt); 
	}
	return txt;
}

function get_msie( ) {
	reg = /MSIE (\d+\.\d+)/;
	msie = reg.exec( navigator.userAgent );
	return (msie ? parseInt(msie[1]) : 0);
}


//Array.prototype.inArray = function (value) {
//	var i;
//	for (i=0; i < this.length; i++) {
//		if (this[i] === value) {
//			return i;
//		}
//	}
//	return false;
//};

// you'll support standards and LIKE it, MSIE
//Element.Methods.Simulated.hasAttribute = function(element, attr) {
//	//  return element.outerHTML.indexOf(" " + attr + "=") > -1;
//	return typeof element.attributes[attr] != undefined;
//};
//Element.Methods.Simulated = {
//  hasAttribute: function(element, attribute) {
//    var t = Element._attributeTranslations, node;
//    attribute = t.names[attribute] || attribute;
//    node = $(element).getAttributeNode(attribute);
//    if(!node){return false}
//    else{return node && node.specified};
//  }
//}; 

