var Hashtable = (function() { 
	var prefix = ' $'; 
	function isNull(object) {return !object && ('object' == typeof object);} 
	function isNumber(object) {return 'number' == typeof object;} 
	function isUndefined(object) {return 'undefined' == typeof object;} 
	function Element(key, value) { 
	this.key = key; 
	this.value = value; 
	this.next = null; 
} 

function Hashtable() { 
	var table = {data : []}, 
	entries = 0; 

	this.get = function(key) {var index, tableData = table.data; 
	if(!isNull(key) && !isUndefined(key) 
	&& isNumber(index = table[prefix + key])) 
	{ 
		var node = tableData[index]; 
		while(node && (node.key !== key)) {node = node.next;} 
		if(node) {return node.value;} 
	} 
}; 

this.put = function(key, value) {var index, prefixedKey, tableData = table.data; 
if(isNull(key) || isUndefined(key) || isUndefined(value)) {return;} 
if(isNumber(index = table[prefixedKey = prefix + key])) { 
var node = tableData[index], previousNode = null; 
while(node && (node.key !== key)) { 
previousNode = node; 
node = node.next; 
} 
if(node) { 
var oldValue = node.value; 
node.value = value; 
return oldValue; 
} else { 
previousNode.next = new Element(key, value); 
} 
} 
else { 
table[prefixedKey] = tableData.length; 
tableData[tableData.length] = new Element(key, value); 
} 
++entries; 
}; 
this.remove = function(key) {var index, prefixedKey, tableData = table.data; 
if(!isNull(key) && !isUndefined(key) 
&& isNumber(index = table[prefixedKey = prefix + key])) 
{ 
var node = tableData[index], previousNode = null, returnValue; 
while(node && (node.key !== key)) { 
previousNode = node; 
node = node.next; 
} 
if(!node) {return;} 
returnValue = node.value; 
if(previousNode) {previousNode.next = node.next;} 
else {tableData[index] = node.next;} 
if(!tableData[index]) { 
for(var length = tableData.length - 1; index < length; ++index) { 
tableData[index] = tableData[index + 1]; 
--table[prefix + tableData[index].key]; 
} 
delete tableData[index]; 
delete table[prefixedKey]; 
} 
--entries; 
return returnValue; 
} 
}; 
} 

Hashtable.prototype.containsKey = function(key) { 
return !isUndefined(this.get(key)); 
}; 
return Hashtable; 
})(); 
var fade = (function() { 
var global = this, 
objects = new Hashtable(); 

function getOpacity(object) { 
	if(global.getComputedStyle) { 
	getOpacity = function(object) { 
	return parseFloat( 
	global.getComputedStyle(object, null).getPropertyValue('opacity') 
	) * 100; 
}; 
} else if(object.filters) { 
getOpacity = function(object) { 
// return object.filters['DXImageTransform.Microsoft.Alpha'].Opacity; 
return object.filters.alpha.Opacity; 
}; 
} else { 
getOpacity = function() {return 100;}; 
} 
return getOpacity(object); 
} 

function setOpacity(object, opacity) { 
if(object.filters) { 
setOpacity = function(object, opacity) { 
// object.filters['DXImageTransform.Microsoft.Alpha'].Opacity = opacity; 
object.filters.alpha.Opacity = opacity; 
}; 
} else if(object.style && object.style.setProperty) { 
setOpacity = function(object, opacity) { 
object.style.setProperty('opacity', opacity / 100, ''); 
}; 
} else { 
setOpacity = function() {}; 
} 
setOpacity(object, opacity); 
} 

return function(object, targetOpacity, rate, delta) { 
var opacity = getOpacity(object); 

function stepFade() {var onTarget; 
opacity += delta; 
onTarget = (0 < delta) ? 
opacity >= targetOpacity 
: opacity <= targetOpacity; 
if(onTarget) { 
opacity = targetOpacity; 
objects.remove(object); 
} 
setOpacity(object, opacity); 
if(!onTarget) {objects.put(object, setTimeout(stepFade, rate));} 
} 
/* Deze function vertrouwd op sluiting, door de inner function hierboven. 
* Als dit niet lukt, wordt deze stilletjes afgebroken. 
*/ 
stepFade.toString = function() {return ';';}; 

/* Als het object in behandeling is wordt deze gestopt. */ 
if(objects.containsKey(object)) {clearTimeout(objects.get(object));} 
/* Maximum Opacity in gekko is 99. */ 
if(100 == targetOpacity) {--targetOpacity;} 
if(opacity > targetOpacity) {delta = -delta;} 
if(delta && rate) {objects.put(object, setTimeout(stepFade, rate));} 
} 
})(); 
