var ForeSee = {
    'version': '3.0.0',
    'Date:': '3/12/2009',
    'enabled': true,
    'files': '/WUCOMWEB/scripts/foresee_de_DE/foresee/',
    'id': 'hRI4UQg8wFtpcIA84kQFZw==',
    'sites': [{
        path: 'westernunion.de',
        cookie: 'session',
        domain: 'westernunion.de'
    },{
        path: 'westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'qawesternunion.com',
        cookie: 'session',
        domain: 'qawesternunion.com'
    },{
        path: 'devwesternunion.com',
        cookie: 'session',
        domain: 'devwesternunion.com'
    },{
        path: 'wucr.com',
        cookie: 'session',
        domain: 'wucr.com'

    },{
        path: 'uatstg.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'uatwucr.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'uatmercury.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'qastg.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'qa.wucr.com',
        cookie: 'session',
        domain: 'wucr.com'
    },{
        path: 'devstg.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'localhost:9080',
        cookie: 'session',
        domain: 'localhost'
    },{
        path: 'qamercury.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'dev.wucr.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'uatmercury.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
    
        path: 'qavenus.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'uatvenus.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'devvenus.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'wucr.qawesternunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    },{
        path: 'devwucrus.westernunion.com',
        cookie: 'session',
        domain: 'westernunion.com'
    }]
};
function fsr$setAlive(){
    var time = new Date().getTime();
    document.cookie = 'foresee.alive=' + time + ';path=/' + ';domain=' + ForeSee.site.domain + ';';
}

(function(){
    var sites = ForeSee.sites;
    for (var i = 0, l = sites.length; i < l; i++) {
        if (document.location.href.match(sites[i].path)) {
            ForeSee.siteid = i;
            ForeSee.site = ForeSee.sites[ForeSee.siteid];
            if (ForeSee.site.files) {
                ForeSee.files = ForeSee.site.files;
            }
            break;
        }
    }
    if (!window['fsr$timer']) {
    	fsr$setAlive();
        window['fsr$timer'] = setInterval(fsr$setAlive, 1000);
    }
})();
fsr$dbug = {
    logged: [],
    timers: {},
    firebug: false,
    enabled: false,
    log: function(){
        fsr$dbug.logged.push(arguments);
    },
    nolog: function(msg){
        fsr$dbug.logged.push(arguments);
    },
    time: function(name){
        fsr$dbug.timers[name] = new Date().getTime();
    },
    timeEnd: function(name){
        if (fsr$dbug.timers[name]) {
            var end = new Date().getTime() - fsr$dbug.timers[name];
            fsr$dbug.timers[name] = false;
            fsr$dbug.log('%s: %s', name, end);
        }
        else 
            fsr$dbug.log('no such timer: %s', name);
    },
    enable: function(silent){
        if (fsr$dbug.firebug) {
            try {
                fsr$dbug.enabled = true;
                fsr$dbug.log = function(){
                    (console.debug || console.log).apply(console, arguments);
                };
                fsr$dbug.time = function(){
                    console.time.apply(console, arguments);
                };
                fsr$dbug.timeEnd = function(){
                    console.timeEnd.apply(console, arguments);
                };
                if (!silent) 
                    fsr$dbug.log('enabling dbug');
                for (var i = 0; i < fsr$dbug.logged.length; i++) {
                    fsr$dbug.log.apply(console, fsr$dbug.logged[i]);
                }
                fsr$dbug.logged = [];
            } 
            catch (e) {
                fsr$dbug.enable.delay(400);
            }
        }
    },
    disable: function(){
        if (fsr$dbug.firebug) 
            fsr$dbug.enabled = false;
        fsr$dbug.log = fsr$dbug.nolog;
        fsr$dbug.time = function(){
        };
        fsr$dbug.timeEnd = function(){
        };
    },
    cookie: function(set){
        var value = document.cookie.match('(?:^|;)\\s*fsdebug=([^;]*)');
        var debugCookie = value ? unescape(value[1]) : false;
        if ((debugCookie != 'true' || set) && !set) {
            fsr$dbug.enable();
            fsr$dbug.log('setting debugging cookie');
            var date = new Date();
            date.setTime(date.getTime() + (24 * 60 * 60 * 1000));
            document.cookie = 'fsdebug=true;expires=' + date.toGMTString() + ';path=/;';
        }
        else 
            fsr$dbug.disableCookie();
    },
    disableCookie: function(){
        fsr$dbug.log('disabling debugging cookie');
        document.cookie = 'fsdebug=false;path=/;';
    }
};

(function(){
    if (typeof loadFirebugConsole == 'function') {
        loadFirebugConsole();
    }
    var fb = typeof console != "undefined";
    var debugMethods = ['debug', 'info', 'warn', 'error', 'assert', 'dir', 'dirxml'];
    var otherMethods = ['trace', 'group', 'groupEnd', 'profile', 'profileEnd', 'count'];
    function set(methodList, defaultFunction){
        for (var i = 0; i < methodList.length; i++) {
            fsr$dbug[methodList[i]] = (fb && console[methodList[i]]) ? console[methodList[i]] : defaultFunction;
        }
    };
    set(debugMethods, fsr$dbug.log);
    set(otherMethods, function(){
    });
	
	var date = new Date();
    date.setTime(date.getTime() + (24 * 60 * 60 * 1000));
    document.cookie = 'fsdebug=true;expires=' + date.toGMTString() + ';path=/;';
})();
if (typeof console != "undefined" && console.warn) {
    fsr$dbug.firebug = true;
    var value = document.cookie.match('(?:^|;)\\s*fsdebug=([^;]*)');
    var debugCookie = value ? unescape(value[1]) : false;
    if (window.location.href.indexOf("fsdebug=true") > 0 || debugCookie == 'true') 
        fsr$dbug.enable();
    if (debugCookie == 'true') 
        fsr$dbug.log('debugging cookie enabled');
    if (window.location.href.indexOf("fsdebugCookie=true") > 0) {
        fsr$dbug.cookie();
        if (!fsr$dbug.enabled) 
            fsr$dbug.enable();
    }
    if (window.location.href.indexOf("fsdebugCookie=false") > 0) 
        fsr$dbug.disableCookie();
}
ForeSee.Native = function(options){
	options = options || {};

	var afterImplement = options.afterImplement || function(){};
	var generics = options.generics;
	generics = (generics !== false);
	var legacy = options.legacy;
	var initialize = options.initialize;
	var protect = options.protect;
	var name = options.name;

	var object = initialize || legacy;

	object.xconstructor = ForeSee.Native;
	object.fsr$family = {name: 'native'};
	if (legacy && initialize) object.prototype = legacy.prototype;
	object.prototype.xconstructor = object;

	if (name && name != 'Array'){
		var family = name.toLowerCase();
		object.prototype.fsr$family = {name: family};
	}

	var add = function(obj, name, method, force){
		if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method;
		if (generics) ForeSee.Native.genericize(obj, name, protect);
		afterImplement.call(obj, name, method);
		return obj;
	};
	
	object.fsr$implement = function(a1, a2, a3){
		if (typeof a1 == 'string') return add(this, a1, a2, a3);
		for (var p in a1) add(this, p, a1[p], a2);
		return this;
	};
	
	object.fsr$alias = function(a1, a2, a3){
		if (typeof a1 == 'string'){
			a1 = this.prototype[a1];
			if (a1) add(this, a2, a1, a3);
		} else {
			for (var a in a1) this.fsr$alias(a, a1[a], a2);
		}
		return this;
	};

	return object;
};

ForeSee.Native.fsr$implement = function(objects, properties){
	for (var i = 0, l = objects.length; i < l; i++) objects[i].fsr$implement(properties);
};

ForeSee.Native.genericize = function(object, property, check){
	if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){
		var args = Array.prototype.slice.call(arguments);
		return object.prototype[property].apply(args.shift(), args);
	};
};

ForeSee.Native.fsr$alias = function(objects, a1, a2, a3){
	for (var i = 0, j = objects.length; i < j; i++) objects[i].fsr$alias(a1, a2, a3);
};

(function(objects){
	for (var name in objects) new ForeSee.Native({name: name, initialize: objects[name], protect: true, generics: true});
})({'String': String, 'Function': Function, 'Number': Number, 'Array': Array, 'RegExp': RegExp, 'Date': Date});

ForeSee.$chk = function (obj){
	return !!(obj || obj === 0);
};

ForeSee.$clear = function (timer){
	clearTimeout(timer);
	clearInterval(timer);
	return null;
};

ForeSee.$defined = function (obj){
	return (obj != undefined);
};

ForeSee.$empty = function (){};

ForeSee.$arguments = function (i){
	return function(){
		return arguments[i];
	};
};

ForeSee.$lambda = function (value){
	return (typeof value == 'function') ? value : function(){
		return value;
	};
};

ForeSee.$extend = function (original, extended){
	for (var key in (extended || {})) original[key] = extended[key];
	return original;
};

ForeSee.$unlink = function (object){
	var unlinked;
	
	switch (ForeSee.$type(object)){
		case 'object':
			unlinked = {};
			for (var p in object) unlinked[p] = ForeSee.$unlink(object[p]);
		break;
		case 'hash':
			unlinked = ForeSee.$unlink(object.fsr$getClean());
		break;
		case 'array':
			unlinked = [];
			for (var i = 0, l = object.length; i < l; i++) unlinked[i] = ForeSee.$unlink(object[i]);
		break;
		default: return object;
	}
	
	return unlinked;
};

ForeSee.$merge = function (){
	var mix = {};
	for (var i = 0, l = arguments.length; i < l; i++){
		var object = arguments[i];
		if (ForeSee.$type(object) != 'object') continue;
		for (var key in object){
			var op = object[key], mp = mix[key];
			mix[key] = (mp && ForeSee.$type(op) == 'object' && ForeSee.$type(mp) == 'object') ? ForeSee.$merge(mp, op) : ForeSee.$unlink(op);
		}
	}
	return mix;
};

ForeSee.$pick = function (){
	for (var i = 0, l = arguments.length; i < l; i++){
		if (arguments[i] != undefined) return arguments[i];
	}
	return null;
};

ForeSee.$random = function (min, max){
	return (Math.random() * (max - min)) + min;
};

ForeSee.$splat = function (obj){
	var type = ForeSee.$type(obj);
	return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : [];
};

ForeSee.$time = Date.now || function(){
	return new Date().getTime();
};

ForeSee.$try = function (){
	for (var i = 0, l = arguments.length; i < l; i++){
		try {
			return arguments[i]();
		} catch(e){}
	}
	return null;
};

ForeSee.$type = function (obj){
	if (obj == undefined) return false;
	if (obj.fsr$family) return (obj.fsr$family.name == 'number' && !isFinite(obj)) ? false : obj.fsr$family.name;

	if (obj.nodeName){
		switch (obj.nodeType){
			case 1: return 'element';
			case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
		}
	} else if (typeof obj.length == 'number'){
		if (obj.callee) return 'arguments';
		else if (obj.item) return 'collection';
	}

	if (ForeSee.isArray(obj)) return 'array';

	return typeof obj;
};

ForeSee.isArray = function (obj){
    if (typeof obj == 'object') {
        var criterion = obj.constructor.toString().match(/array/i);
        return (criterion != null);
    }
    return false;
}
 
ForeSee.Hash = new ForeSee.Native({

	name: 'Hash',

	initialize: function(object){
		if (ForeSee.$type(object) == 'hash') object = ForeSee.$unlink(object.fsr$getClean());
		for (var key in object) this[key] = object[key];
		return this;
	}

});

ForeSee.Hash.fsr$implement({
	fsr$getLength: function(){
		var length = 0;
		for (var key in this){
			if (this.hasOwnProperty(key)) length++;
		}
		return length;
	},

	fsr$forEach: function(fn, bind){
		for (var key in this){
			if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);
		}
	},
	
	fsr$getClean: function(){
		var clean = {};
		for (var key in this){
			if (this.hasOwnProperty(key)) clean[key] = this[key];
		}
		return clean;
	},
	
	fsr$empty: function(){
		ForeSee.Hash.fsr$each(this, function(value, key){
			delete this[key];
		}, this);
		return this;
	}
});

ForeSee.Hash.fsr$alias('fsr$forEach', 'fsr$each');

ForeSee.$H = function (object){
	return new ForeSee.Hash(object);
};

Array.fsr$implement({

	fsr$forEach: function(fn, bind){
		for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this);
	}

});

Array.fsr$alias('fsr$forEach', 'fsr$each');

ForeSee.$A = function (iterable){
	if (iterable.item){
		var array = [];
		for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i];
		return array;
	}
	return Array.prototype.slice.call(iterable);
};

ForeSee.$each = function (iterable, fn, bind){
	var type = ForeSee.$type(iterable);
	((type == 'arguments' || type == 'collection' || type == 'array') ? Array : ForeSee.Hash).fsr$each(iterable, fn, bind);
};


ForeSee.Browser = new ForeSee.Hash({
	Type: {name: 'unknown', version: ''},
	Engine: {name: 'unknown', version: ''},
	Platform: {name: (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase(), os: 'unknown'},
	Features: {xpath: !!(document.evaluate), air: !!(window.runtime)},
	Plugins: {},
    searchString: function(data){
        for (var i = 0; i < data.length; i++) {
            var dataString = data[i].string;
            var dataProp = data[i].prop;
            this.versionSearchString = data[i].versionSearch || data[i].identity;
            if (dataString) {
                if (dataString.indexOf(data[i].subString) != -1) 
                    return data[i].identity;
            }
            else if (dataProp) 
                return data[i].identity;
        }
    },
    searchVersion: function(dataString){
        var index = dataString.indexOf(this.versionSearchString);
        if (index == -1) 
            return;
        return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
    },
    dataBrowser: [{
        string: navigator.userAgent,
        subString: "Chrome",
        identity: "Chrome"
    }, {
        string: navigator.userAgent,
        subString: "OmniWeb",
        versionSearch: "OmniWeb/",
        identity: "OmniWeb"
    }, {
        string: navigator.vendor,
        subString: "Apple",
        identity: "Safari",
        versionSearch: "Version"
    }, {
        prop: window.opera,
        identity: "Opera"
    }, {
        string: navigator.vendor,
        subString: "iCab",
        identity: "iCab"
    }, {
        string: navigator.vendor,
        subString: "KDE",
        identity: "Konqueror"
    }, {
        string: navigator.userAgent,
        subString: "Firefox",
        identity: "Firefox"
    }, {
        string: navigator.vendor,
        subString: "Camino",
        identity: "Camino"
    }, { 
        string: navigator.userAgent,
        subString: "Netscape",
        identity: "Netscape"
    }, {
        string: navigator.userAgent,
        subString: "MSIE",
        identity: "Explorer",
        versionSearch: "MSIE"
    }, {
        string: navigator.userAgent,
        subString: "Gecko",
        identity: "Mozilla",
        versionSearch: "rv"
    }, { 
        string: navigator.userAgent,
        subString: "Mozilla",
        identity: "Netscape",
        versionSearch: "Mozilla"
    }],
    dataOS: [{
        string: navigator.platform,
        subString: "Win",
        identity: "Windows"
    }, {
        string: navigator.platform,
        subString: "Mac",
        identity: "Mac"
    }, {
        string: navigator.platform,
        subString: "Linux",
        identity: "Linux"
    }]
});

if (window.opera) ForeSee.Browser.Engine = {name: 'presto', version: (document.getElementsByClassName) ? 950 : 925};
else if (window.ActiveXObject) ForeSee.Browser.Engine = {name: 'trident', version: (window.XMLHttpRequest) ? 5 : 4};
else if (!navigator.taintEnabled) ForeSee.Browser.Engine = {name: 'webkit', version: (ForeSee.Browser.Features.xpath) ? 420 : 419};
else if (document.getBoxObjectFor != null) ForeSee.Browser.Engine = {name: 'gecko', version: (document.getElementsByClassName) ? 19 : 18};
ForeSee.Browser.Engine[ForeSee.Browser.Engine.name] = ForeSee.Browser.Engine[ForeSee.Browser.Engine.name + ForeSee.Browser.Engine.version] = true;

if (window.orientation != undefined) ForeSee.Browser.Platform.name = 'ipod';

ForeSee.Browser.Platform[ForeSee.Browser.Platform.name] = true;

ForeSee.Browser.Request = function(){
	return ForeSee.$try(function(){
		return new XMLHttpRequest();
	}, function(){
		return new ActiveXObject('MSXML2.XMLHTTP');
	});
};

ForeSee.Browser.Features.xhr = !!(ForeSee.Browser.Request());

ForeSee.Browser.Plugins.Flash = (function(){
	var version = (ForeSee.$try(function(){
		return navigator.plugins['Shockwave Flash'].description;
	}, function(){
		return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
	}) || '0 r0').match(/\d+/g);
	return {version: parseInt(version[0] || 0 + '.' + version[1] || 0), build: parseInt(version[2] || 0)};
})();

ForeSee.Browser.Type.name = ForeSee.Browser.searchString(ForeSee.Browser.dataBrowser) || "unknown";
ForeSee.Browser.Type.version = ForeSee.Browser.searchVersion(navigator.userAgent) || ForeSee.Browser.searchVersion(navigator.appVersion) || "unknown";
ForeSee.Browser.Platform.os = ForeSee.Browser.searchString(ForeSee.Browser.dataOS) || "unknown";

ForeSee.$exec = function (text){
	if (!text) return text;
	if (window.execScript){
		window.execScript(text);
	} else {
		var script = document.createElement('script');
		script.setAttribute('type', 'text/javascript');
		script.text = text;
		document.fsr$head.appendChild(script);
		document.fsr$head.removeChild(script);
	}
	return text;
};

ForeSee.Native.UID = 1;

ForeSee.$uid = (ForeSee.Browser.Engine.trident) ? function(item){
	return (item.fsr$uid || (item.fsr$uid = [ForeSee.Native.UID++]))[0];
} : function(item){
	return item.fsr$uid || (item.fsr$uid = ForeSee.Native.UID++);
};

ForeSee.Window = new ForeSee.Native({

	name: 'Window',

	initialize: function(win){
		ForeSee.$uid(win);
		if (!win.Element){
			win.Element = ForeSee.$empty;
			if (ForeSee.Browser.Engine.webkit) win.document.createElement("iframe"); 
			win.Element.prototype = (ForeSee.Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {};
		}
		return ForeSee.$extend(win, ForeSee.Window.Prototype);
	},

	afterImplement: function(property, value){
		window[property] = ForeSee.Window.Prototype[property] = value;
		ForeSee.Window.Prototype[property] = value;
	}

});

ForeSee.Window.Prototype = {fsr$family: {name: 'window'}};

new ForeSee.Window(window);

ForeSee.Document = new ForeSee.Native({

	name: 'Document',

	initialize: function(doc){
		ForeSee.$uid(doc);
		doc.fsr$head = doc.getElementsByTagName('head')[0];
		doc.fsr$html = doc.getElementsByTagName('html')[0];
		doc.fsr$window = doc.defaultView || doc.parentWindow;
		if (ForeSee.Browser.Engine.trident4) ForeSee.$try(function(){
			doc.execCommand("BackgroundImageCache", false, true);
		});
		return ForeSee.$extend(doc, ForeSee.Document.Prototype);
	},

	afterImplement: function(property, value){
		document[property] = ForeSee.Document.Prototype[property] = value;
		ForeSee.Document.Prototype[property] = value;
	}

});

ForeSee.Document.Prototype = {fsr$family: {name: 'document'}};

new ForeSee.Document(document);

Array.fsr$implement({

	fsr$indexOf: function(item, from){
		var len = this.length;
		for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){
			if (this[i] === item) return i;
		}
		return -1;
	},

	fsr$map: function(fn, bind){
		var results = [];
		for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this);
		return results;
	},

	fsr$associate: function(keys){
		var obj = {}, length = Math.min(this.length, keys.length);
		for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
		return obj;
	},

	fsr$contains: function(item, from){
		return this.fsr$indexOf(item, from) != -1;
	},

	fsr$extend: function(array){
		for (var i = 0, j = array.length; i < j; i++) this.push(array[i]);
		return this;
	},

	fsr$include: function(item){
		if (!this.fsr$contains(item)) this.push(item);
		return this;
	},

	fsr$flatten: function(){
		var array = [];
		for (var i = 0, l = this.length; i < l; i++){
			var type = ForeSee.$type(this[i]);
			if (!type) continue;
			array = array.concat((type == 'array' || type == 'collection' || type == 'arguments') ? Array.fsr$flatten(this[i]) : this[i]);
		}
		return array;
	},
	
	fsr$slice: function(){
		return Array.prototype.slice.apply(this, arguments);
	}
});

Function.fsr$implement({

	fsr$extend: function(properties){
		for (var property in properties) this[property] = properties[property];
		return this;
	},

	fsr$create: function(options){
		var self = this;
		options = options || {};
		return function(event){
			var args = options.arguments;
			args = (args != undefined) ? ForeSee.$splat(args) : Array.fsr$slice(arguments, (options.event) ? 1 : 0);
			if (options.event) args = [event || window.event].fsr$extend(args);
			var returns = function(){
				return self.apply(options.bind || null, args);
			};
			if (options.delay) return setTimeout(returns, options.delay);
			if (options.periodical) return setInterval(returns, options.periodical);
			if (options.attempt) return ForeSee.$try(returns);
			return returns();
		};
	},

	fsr$pass: function(args, bind){
		return this.fsr$create({arguments: args, bind: bind});
	},

	fsr$attempt: function(args, bind){
		return this.fsr$create({arguments: args, bind: bind, attempt: true})();
	},

	fsr$bind: function(bind, args){
		return this.fsr$create({bind: bind, arguments: args});
	},

	fsr$bindWithEvent: function(bind, args){
		return this.fsr$create({bind: bind, event: true, arguments: args});
	},

	fsr$delay: function(delay, bind, args){
		return this.fsr$create({delay: delay, bind: bind, arguments: args})();
	},

	fsr$periodical: function(interval, bind, args){
		return this.fsr$create({periodical: interval, bind: bind, arguments: args})();
	},

	fsr$run: function(args, bind){
		return this.apply(bind, ForeSee.$splat(args));
	}

});

Number.fsr$implement({

	fsr$toInt: function(base){
		return parseInt(this, base || 10);
	}

});

String.fsr$implement({

	fsr$test: function(regex, params){
		return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this);
	},

	fsr$contains: function(string, separator){
		return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1;
	},

	fsr$trim: function(){
		return this.replace(/^\s+|\s+$/g, '');
	},

	fsr$clean: function(){
		return this.replace(/\s+/g, ' ').fsr$trim();
	},

	fsr$camelCase: function(){
		return this.replace(/-\D/g, function(match){
			return match.charAt(1).toUpperCase();
		});
	},

	fsr$hyphenate: function(){
		return this.replace(/[A-Z]/g, function(match){
			return ('-' + match.charAt(0).toLowerCase());
		});
	},

	fsr$capitalize: function(){
		return this.replace(/\b[a-z]/g, function(match){
			return match.toUpperCase();
		});
	},

	fsr$escapeRegExp: function(){
		return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
	},

	fsr$toInt: function(base){
		return parseInt(this, base || 10);
	},

	fsr$stripScripts: function(option){
		var scripts = '';
		var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(){
			scripts += arguments[1] + '\n';
			return '';
		});
		if (option === true) ForeSee.$exec(scripts);
		else if (ForeSee.$type(option) == 'function') option(scripts, text);
		return text;
	},

	fsr$substitute: function(object, regexp){
		return this.replace(regexp || (/\\?\{([^}]+)\}/g), function(match, name){
			if (match.charAt(0) == '\\') return match.slice(1);
			return (object[name] != undefined) ? object[name] : '';
		});
	}

});

ForeSee.Hash.fsr$implement({

	fsr$has: Object.prototype.hasOwnProperty,

	fsr$keyOf: function(value){
		for (var key in this){
			if (this.hasOwnProperty(key) && this[key] === value) return key;
		}
		return null;
	},
	
	fsr$extend: function(properties){
		ForeSee.Hash.fsr$each(properties, function(value, key){
			ForeSee.Hash.fsr$set(this, key, value);
		}, this);
		return this;
	},

	fsr$combine: function(properties){
		ForeSee.Hash.fsr$each(properties, function(value, key){
			ForeSee.Hash.fsr$include(this, key, value);
		}, this);
		return this;
	},

	fsr$erase: function(key){
		if (this.hasOwnProperty(key)) delete this[key];
		return this;
	},

	fsr$get: function(key){
		return (this.hasOwnProperty(key)) ? this[key] : null;
	},

	fsr$set: function(key, value){
		if (!this[key] || this.hasOwnProperty(key)) this[key] = value;
		return this;
	},

	fsr$include: function(key, value){
		var k = this[key];
		if (k == undefined) this[key] = value;
		return this;
	},

	fsr$toQueryString: function(base){
		var queryString = [];
		ForeSee.Hash.fsr$each(this, function(value, key){
			if (base) key = base + '[' + key + ']';
			var result;
			switch (ForeSee.$type(value)){
				case 'object': result = ForeSee.Hash.fsr$toQueryString(value, key); break;
				case 'array':
					var qs = {};
					value.fsr$each(function(val, i){
						qs[i] = val;
					});
					result = ForeSee.Hash.fsr$toQueryString(qs, key);
				break;
				default: result = key + '=' + encodeURIComponent(value);
			}
			if (value != undefined) queryString.push(result);
		});
		
		return queryString.join('&');
	}

});

ForeSee.Hash.fsr$alias({fsr$keyOf: 'fsr$indexOf', fsr$hasValue: 'fsr$contains'});

ForeSee.Event = new ForeSee.Native({

	name: 'Event',

	initialize: function(event, win){
		win = win || window;
		var doc = win.document;
		event = event || win.event;
		if (event.fsr$extended) return event;
		this.fsr$extended = true;
		var type = event.type;
		var target = event.target || event.srcElement;
		while (target && target.nodeType == 3) target = target.parentNode;
		
		if (type.fsr$test(/key/)){
			var code = event.which || event.keyCode;
			var key = ForeSee.Event.Keys.fsr$keyOf(code);
			if (type == 'keydown'){
				var fKey = code - 111;
				if (fKey > 0 && fKey < 13) key = 'f' + fKey;
			}
			key = key || String.fromCharCode(code).toLowerCase();
		} else if (type.match(/(click|mouse|menu)/i)){
			doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.getElementsByTagName('html')[0] : doc.body;
			var page = {
				x: event.pageX || event.clientX + doc.scrollLeft,
				y: event.pageY || event.clientY + doc.scrollTop
			};
			var client = {
				x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX,
				y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY
			};
			if (type.match(/DOMMouseScroll|mousewheel/)){
				var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
			}
			var rightClick = (event.which == 3) || (event.button == 2);
			var related = null;
			if (type.match(/over|out/)){
				switch (type){
					case 'mouseover': related = event.relatedTarget || event.fromElement; break;
					case 'mouseout': related = event.relatedTarget || event.toElement;
				}
				if (!(function(){
					while (related && related.nodeType == 3) related = related.parentNode;
					return true;
				}).fsr$create({attempt: ForeSee.Browser.Engine.gecko})()) related = false;
			}
		}

		return ForeSee.$extend(this, {
			event: event,  
			type: type,
			
			page: page,
			client: client,
			rightClick: rightClick,
			
			wheel: wheel,
			
			relatedTarget: related,
			target: target,
			
			code: code,
			key: key,
			
			shift: event.shiftKey,
			control: event.ctrlKey,
			alt: event.altKey,
			meta: event.metaKey
		});
	}

});

ForeSee.Event.Keys = new ForeSee.Hash({
	'enter': 13,
	'up': 38,
	'down': 40,
	'left': 37,
	'right': 39,
	'esc': 27,
	'space': 32,
	'backspace': 8,
	'tab': 9,
	'delete': 46
});

ForeSee.Class = new ForeSee.Native({

	name: 'Class',

	initialize: function(properties){
		properties = properties || {};
		var klass = function(empty){
			for (var key in this) this[key] = ForeSee.$unlink(this[key]);
			for (var mutator in ForeSee.Class.Mutators){
				if (!this[mutator]) continue;
				ForeSee.Class.Mutators[mutator](this, this[mutator]);
				delete this[mutator];
			}

			this.constructor = klass;
			if (empty === ForeSee.$empty) return this;
			
			var self = (this.initialize) ? this.initialize.apply(this, arguments) : this;
			if (this.options && this.options.initialize) this.options.initialize.call(this);
			return self;
		};

		ForeSee.$extend(klass, this);
		klass.constructor = ForeSee.Class;
		klass.prototype = properties;
		return klass;
	}

});

ForeSee.Class.fsr$implement({

	fsr$implement: function(){
		ForeSee.Class.Mutators.Implements(this.prototype, Array.fsr$slice(arguments));
		return this;
	}

});

ForeSee.Class.Mutators = {
  
  Implements: function(self, klasses){
  	ForeSee.$splat(klasses).fsr$each(function(klass){
  		ForeSee.$extend(self, (ForeSee.$type(klass) == 'class') ? new klass(ForeSee.$empty) : klass);
  	});
  },
  
  Extends: function(self, klass){
  	var instance = new klass(ForeSee.$empty);
  	delete instance.parent;
  	delete instance.parentOf;

  	for (var key in instance){
  		var current = self[key], previous = instance[key];
  		if (current == undefined){
  			self[key] = previous;
  			continue;
  		}

  		var ctype = ForeSee.$type(current), ptype = ForeSee.$type(previous);
  		if (ctype != ptype) continue;

  		switch (ctype){
  			case 'function': 
  				if (!arguments.callee.caller) self[key] = eval('(' + String(current).replace(/\bthis\.parent\(\s*(\))?/g, function(full, close){
  					return 'arguments.callee._parent_.call(this' + (close || ', ');
  				}) + ')');

  				self[key]._parent_ = previous;
  			  break;
  			case 'object': self[key] = ForeSee.$merge(previous, current);
  		}

  	}

  	self.parent = function(){
  		return arguments.callee.caller._parent_.apply(this, arguments);
  	};

  	self.parentOf = function(descendant){
  		return descendant._parent_.apply(this, Array.fsr$slice(arguments, 1));
  	};
  }
  
};


ForeSee.Chain = new ForeSee.Class({

	chain: function(){
		this.$chain = (this.$chain || []).fsr$extend(arguments);
		return this;
	},

	callChain: function(){
		return (this.$chain && this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
	},

	clearChain: function(){
		if (this.$chain) this.$chain.fsr$empty();
		return this;
	}

});


ForeSee.Events = new ForeSee.Class({

	fsr$addEvent: function(type, fn, internal){
		type = ForeSee.Events.removeOn(type);
		if (fn != ForeSee.$empty){
			this.$events = this.$events || {};
			this.$events[type] = this.$events[type] || [];
			this.$events[type].fsr$include(fn);
			if (internal) fn.internal = true;
		}
		return this;
	},

	fsr$addEvents: function(events){
		for (var type in events) this.fsr$addEvent(type, events[type]);
		return this;
	},

	fsr$fireEvent: function(type, args, delay){
		type = ForeSee.Events.removeOn(type);
		if (!this.$events || !this.$events[type]) return this;
		this.$events[type].fsr$each(function(fn){
			fn.fsr$create({'bind': this, 'delay': delay, 'arguments': args})();
		}, this);
		return this;
	},

	fsr$removeEvent: function(type, fn){
		type = ForeSee.Events.removeOn(type);
		if (!this.$events || !this.$events[type]) return this;
		if (!fn.internal) this.$events[type].fsr$erase(fn);
		return this;
	},

	fsr$removeEvents: function(type){
		for (var e in this.$events){
			if (type && type != e) continue;
			var fns = this.$events[e];
			for (var i = fns.length; i--; i) this.fsr$removeEvent(e, fns[i]);
		}
		return this;
	}

});

ForeSee.Events.removeOn = function(string){
	return string.replace(/^on([A-Z])/, function(full, first) {
		return first.toLowerCase();
	});
};

ForeSee.Options = new ForeSee.Class({

	setOptions: function(){
		this.options = ForeSee.$merge.fsr$run([this.options].fsr$extend(arguments));
		if (!this.fsr$addEvent) return this;
		for (var option in this.options){
			if (ForeSee.$type(this.options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
			this.fsr$addEvent(option, this.options[option]);
			delete this.options[option];
		}
		return this;
	}

});

ForeSee.Document.fsr$implement({

	fsr$newElement: function(tag, props){
		if (ForeSee.Browser.Engine.trident && props){
			['name', 'type', 'checked'].fsr$each(function(attribute){
				if (!props[attribute]) return;
				tag += ' ' + attribute + '="' + props[attribute] + '"';
				if (attribute != 'checked') delete props[attribute];
			});
			tag = '<' + tag + '>';
		}
		return $fsr.element(this.createElement(tag)).fsr$set(props);
	},

	fsr$newTextNode: function(text){
		return this.createTextNode(text);
	},

	fsr$getDocument: function(){
		return this;
	},

	fsr$getWindow: function(){
		return this.defaultView || this.parentWindow;
	},

	fsr$purge: function(){ 
		var elements = this.getElementsByTagName('*');
		for (var i = 0, l = elements.length; i < l; i++) ForeSee.Browser.freeMem(elements[i]);
	}

});

ForeSee.Element = new ForeSee.Native({

	name: 'Element',

	initialize: function(tag, props){
		var konstructor = ForeSee.Element.Constructors.fsr$get(tag);
		if (konstructor) return konstructor(props);
		if (typeof tag == 'string') return document.fsr$newElement(tag, props);
		return $fsr(tag).fsr$set(props);
	},

	afterImplement: function(key, value){
		if (!Array[key]) ForeSee.Elements.fsr$implement(key, ForeSee.Elements.fsr$multi(key));
		ForeSee.Element.Prototype[key] = value;
	}

});

ForeSee.Element.Prototype = {fsr$family: {name: 'element'}};

ForeSee.Element.Constructors = new ForeSee.Hash;

ForeSee.Elements = new ForeSee.Native({

	initialize: function(elements, options){
		options = ForeSee.$extend({ddup: true, cash: true}, options);
		elements = elements || [];
		if (options.ddup || options.cash){
			var uniques = {}, returned = [];
			for (var i = 0, l = elements.length; i < l; i++){
				var el = $fsr.element(elements[i], !options.cash);
				if (options.ddup){
					if (uniques[el.fsr$uid]) continue;
					uniques[el.fsr$uid] = true;
				}
				returned.push(el);
			}
			elements = returned;
		}
		return (options.cash) ? ForeSee.$extend(elements, this) : elements;
	}

});

ForeSee.Elements.fsr$implement({

	fsr$filter: function(filter, bind){
		if (!filter) return this;
		return new ForeSee.Elements(Array.fsr$filter(this, (typeof filter == 'string') ? function(item){
			return item.match(filter); 
		} : filter, bind));
	}

});

ForeSee.Elements.fsr$multi = function(property){
	return function(){
		var items = [];
		var elements = true;
		for (var i = 0, j = this.length; i < j; i++){
			var returns = this[i][property].apply(this[i], arguments);
			items.push(returns);
			if (elements) elements = (ForeSee.$type(returns) == 'element');
		}
		return (elements) ? new ForeSee.Elements(items) : items;
	};
};

ForeSee.Window.fsr$implement({

	$fsr: function(el, nocash){
		if (el && el.fsr$family && el.fsr$uid) return el;
		var type = ForeSee.$type(el);
		return ($fsr[type]) ? $fsr[type](el, nocash, this.document) : null;
	},

	$$fsr: function(selector){
		if (arguments.length == 1 && typeof selector == 'string') return this.document.fsr$getElements(selector);
		var elements = [];
		var args = Array.fsr$flatten(arguments);
		for (var i = 0, l = args.length; i < l; i++){
			var item = args[i];
			switch (ForeSee.$type(item)){
				case 'element': item = [item]; break;
				case 'string': item = this.document.fsr$getElements(item, true); break;
				default: item = false;
			}
			if (item) elements.fsr$extend(item);
		}
		return new ForeSee.Elements(elements);
	},

	fsr$getDocument: function(){
		return this.document;
	},

	fsr$getWindow: function(){
		return this;
	}

});

$fsr.string = function(id, nocash, doc){
	id = doc.getElementById(id);
	return (id) ? $fsr.element(id, nocash) : null;
};

$fsr.element = function(el, nocash){
	ForeSee.$uid(el);
	if (!nocash && !el.fsr$family && !(/^object|embed$/i).test(el.tagName)){
		var proto = ForeSee.Element.Prototype;
		for (var p in proto) el[p] = proto[p];
	};
	return el;
};

$fsr.object = function(obj, nocash, doc){
	if (obj.toElement) return $fsr.element(obj.toElement(doc), nocash);
	return null;
};

$fsr.textnode = $fsr.whitespace = $fsr.window = $fsr.document = ForeSee.$arguments(0);

ForeSee.Native.fsr$implement([ForeSee.Element, ForeSee.Document], {

	fsr$getElement: function(selector, nocash){
		return $fsr(this.fsr$getElements(selector, true)[0] || null, nocash);
	},

	fsr$getElements: function(tags, nocash){
		tags = tags.split(',');
		var elements = [];
		var ddup = (tags.length > 1);
		tags.fsr$each(function(tag){
			var partial = this.getElementsByTagName(tag.fsr$trim());
			(ddup) ? elements.fsr$extend(partial) : elements = partial;
		}, this);
		return new ForeSee.Elements(elements, {ddup: ddup, cash: !nocash});
	}

});

ForeSee.Element.Storage = {

	fsr$get: function(uid){
		return (this[uid] || (this[uid] = {}));
	}

};

ForeSee.Element.Inserters = new ForeSee.Hash({

	after: function(context, element){
		if (!element.parentNode) return;
		var next = element.nextSibling;
		(next) ? element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context);
	},

	bottom: function(context, element){
		element.appendChild(context);
	}

});

ForeSee.Element.Inserters.inside = ForeSee.Element.Inserters.bottom;

ForeSee.Element.fsr$implement({

	fsr$getDocument: function(){
		return this.ownerDocument;
	},

	fsr$getWindow: function(){
		return this.ownerDocument.fsr$getWindow();
	},

	fsr$set: function(prop, value){
		switch (ForeSee.$type(prop)){
			case 'object':
				for (var p in prop) this.fsr$set(p, prop[p]);
				break;
			case 'string':
				var property = ForeSee.Element.Properties.fsr$get(prop);
				(property && property.fsr$set) ? property.fsr$set.apply(this, Array.fsr$slice(arguments, 1)) : this.fsr$setProperty(prop, value);
		}
		return this;
	},

	fsr$inject: function(el, where){
		ForeSee.Element.Inserters.fsr$get(where || 'bottom')(this, $fsr(el, true));
		return this;
	},

	fsr$dispose: function(){
		return (this.parentNode) ? this.parentNode.removeChild(this) : this;
	},
	
	fsr$setProperty: function(attribute, value){
		var EA = ForeSee.Element.Attributes, key = EA.Props[attribute], hasValue = ForeSee.$defined(value);
		if (key && EA.Bools[attribute]) value = (value || !hasValue) ? true : false;
		else if (!hasValue) return this.removeProperty(attribute);
		(key) ? this[key] = value : this.setAttribute(attribute, value);
		return this;
	},

	fsr$setProperties: function(attributes){
		for (var attribute in attributes) this.fsr$setProperty(attribute, attributes[attribute]);
		return this;
	}
});

ForeSee.Element.Properties = new ForeSee.Hash;

ForeSee.Element.Properties.html = {fsr$set: function(){
	return this.innerHTML = Array.fsr$flatten(arguments).join('');
}};

ForeSee.Native.fsr$implement([ForeSee.Element, ForeSee.Window, ForeSee.Document], {

	fsr$addListener: function(type, fn){
		if (this.addEventListener) this.addEventListener(type, fn, false);
		else this.attachEvent('on' + type, fn);
		return this;
	},

	fsr$removeListener: function(type, fn){
		if (this.removeEventListener) this.removeEventListener(type, fn, false);
		else this.detachEvent('on' + type, fn);
		return this;
	},

	fsr$retrieve: function(property, dflt){
		var storage = ForeSee.Element.Storage.fsr$get(this.fsr$uid);
		var prop = storage[property];
		if (ForeSee.$defined(dflt) && !ForeSee.$defined(prop)) prop = storage[property] = dflt;
		return ForeSee.$pick(prop);
	},

	fsr$store: function(property, value){
		var storage = ForeSee.Element.Storage.fsr$get(this.fsr$uid);
		storage[property] = value;
		return this;
	},

	fsr$eliminate: function(property){
		var storage = ForeSee.Element.Storage.fsr$get(this.fsr$uid);
		delete storage[property];
		return this;
	}

});

ForeSee.Element.Attributes = new ForeSee.Hash({
	Props: {'html': 'innerHTML', 'class': 'className', 'for': 'htmlFor', 'text': (ForeSee.Browser.Engine.trident) ? 'innerText' : 'textContent'},
	Bools: ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readonly', 'multiple', 'selected', 'noresize', 'defer'],
	Camels: ['value', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap']
});

ForeSee.Browser.freeMem = function(item){
	if (!item) return;
	if (ForeSee.Browser.Engine.trident && (/object/i).test(item.tagName)){
		for (var p in item){
			if (typeof item[p] == 'function') item[p] = ForeSee.$empty;
		}
		ForeSee.Element.fsr$dispose(item);
	}
	if (item.fsr$uid && item.fsr$removeEvents) item.fsr$removeEvents();
};

(function(FSR$EA){

	var fsr$EAB = FSR$EA.Bools, fsr$EAC = FSR$EA.Camels;
	FSR$EA.Bools = fsr$EAB = fsr$EAB.fsr$associate(fsr$EAB);
	ForeSee.Hash.fsr$extend(ForeSee.Hash.fsr$combine(FSR$EA.Props, fsr$EAB), fsr$EAC.fsr$associate(fsr$EAC.fsr$map(function(v){
		return v.toLowerCase();
	})));
	FSR$EA.fsr$erase('Camels');

})(ForeSee.Element.Attributes);

window.fsr$addListener('unload', function(){ 
	window.fsr$removeListener('unload', arguments.callee);
	document.fsr$purge();
	if (ForeSee.Browser.Engine.trident) CollectGarbage();
});

ForeSee.Element.Properties.events = {fsr$set: function(events){
	this.fsr$addEvents(events);
}};

ForeSee.Native.fsr$implement([ForeSee.Element, ForeSee.Window, ForeSee.Document], {

	fsr$addEvent: function(type, fn){
		var events = this.fsr$retrieve('events', {});
		events[type] = events[type] || {'keys': [], 'values': []};
		if (events[type].keys.fsr$contains(fn)) return this;
		events[type].keys.push(fn);
		var realType = type, custom = ForeSee.Element.Events.fsr$get(type), condition = fn, self = this;
		if (custom){
			if (custom.onAdd) custom.onAdd.call(this, fn);
			if (custom.condition){
				condition = function(event){
					if (custom.condition.call(this, event)) return fn.call(this, event);
					return false;
				};
			}
			realType = custom.base || realType;
		}
		var defn = function(){
			return fn.call(self);
		};
		var nativeEvent = ForeSee.Element.NativeEvents[realType] || 0;
		if (nativeEvent){
			if (nativeEvent == 2){
				defn = function(event){
					event = new ForeSee.Event(event, self.fsr$getWindow());
					if (condition.call(self, event) === false) event.stop();
				};
			}
			this.fsr$addListener(realType, defn);
		}
		events[type].values.push(defn);
		return this;
	},

	fsr$removeEvent: function(type, fn){
		var events = this.fsr$retrieve('events');
		if (!events || !events[type]) return this;
		var pos = events[type].keys.fsr$indexOf(fn);
		if (pos == -1) return this;
		var key = events[type].keys.splice(pos, 1)[0];
		var value = events[type].values.splice(pos, 1)[0];
		var custom = ForeSee.Element.Events.fsr$get(type);
		if (custom){
			if (custom.onRemove) custom.onRemove.call(this, fn);
			type = custom.base || type;
		}
		return (ForeSee.Element.NativeEvents[type]) ? this.fsr$removeListener(type, value) : this;
	},

	fsr$addEvents: function(events){
		for (var event in events) { 
			if (events.hasOwnProperty(event)) {
				this.fsr$addEvent(event, events[event]);
			}
		}
		return this;
	},

	fsr$removeEvents: function(type){
		var events = this.fsr$retrieve('events');
		if (!events) return this;
		if (!type){
			for (var evType in events) {
				if (events.hasOwnProperty(evType)) {
					this.fsr$removeEvents(evType);
				}
			}
			events = null;
		} else if (events[type]){
			while (events[type].keys[0]) this.fsr$removeEvent(type, events[type].keys[0]);
			events[type] = null;
		}
		return this;
	},

	fsr$fireEvent: function(type, args, delay){
		var events = this.fsr$retrieve('events');
		if (!events || !events[type]) return this;
		events[type].keys.fsr$each(function(fn){
			fn.fsr$create({'bind': this, 'delay': delay, 'arguments': args})();
		}, this);
		return this;
	}

});

ForeSee.Element.NativeEvents = {
	click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, 
	mousewheel: 2, DOMMouseScroll: 2, 
	mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, 
	keydown: 2, keypress: 2, keyup: 2, 
	focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, 
	load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, 
	error: 1, abort: 1, scroll: 1 
};

(function(){

ForeSee.$check = function(event){
	var related = event.relatedTarget;
	if (related == undefined) return true;
	if (related === false) return false;
	return (ForeSee.$type(this) != 'document' && related != this && related.prefix != 'xul' && !this.fsr$hasChild(related));
};

ForeSee.Element.Events = new ForeSee.Hash({

	mouseenter: {
		base: 'mouseover',
		condition: ForeSee.$check
	},

	mouseleave: {
		base: 'mouseout',
		condition: ForeSee.$check
	},

	mousewheel: {
		base: (ForeSee.Browser.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel'
	}

});

})();

ForeSee.Element.fsr$implement({
	
	fsr$hasChild: function(el){
		el = $fsr(el, true);
		return (!!el && ForeSee.$A(this.getElementsByTagName(el.tagName)).fsr$contains(el));
	}
});

(function(){

ForeSee.Native.fsr$implement([ForeSee.Document, ForeSee.Window], {

	fsr$getSize: function(){
		var win = this.fsr$getWindow();
		if (ForeSee.Browser.Engine.presto || ForeSee.Browser.Engine.webkit) return {x: win.innerWidth, y: win.innerHeight};
		var doc = fsr$getCompatElement(this);
		return {x: doc.clientWidth, y: doc.clientHeight};
	},

	fsr$getScroll: function(){
		var win = this.fsr$getWindow();
		var doc = fsr$getCompatElement(this);
		return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
	},

	fsr$getScrollSize: function(){
		var doc = fsr$getCompatElement(this);
		var min = this.fsr$getSize();
		return {x: Math.max(doc.scrollWidth, min.x), y: Math.max(doc.scrollHeight, min.y)};
	}

});

function fsr$getCompatElement(element){
	var doc = element.fsr$getDocument();
	return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.getElementsByTagName('html')[0] : doc.body;
};

})();

ForeSee.Element.Events.domready = {

	onAdd: function(fn){
		if (ForeSee.Browser.loaded) fn.call(this);
	}

};

(function(){
	
	var fsr$domready = function(){
		if (ForeSee.Browser.loaded) return;
		ForeSee.Browser.loaded = true;
		window.fsr$fireEvent('domready');
		document.fsr$fireEvent('domready');
	};
	
	switch (ForeSee.Browser.Engine.name){

		case 'webkit': (function(){
			(['loaded', 'complete'].fsr$contains(document.readyState)) ? fsr$domready() : arguments.callee.fsr$delay(50);
		})(); break;

		case 'trident':
			var temp = document.createElement('div');
			(function(){
				(ForeSee.$try(function(){
					temp.doScroll('left');
					return $fsr(temp).fsr$inject(document.body).fsr$set('html', 'temp').fsr$dispose();
				})) ? fsr$domready() : arguments.callee.fsr$delay(50);
			})();
		break;
		
		default:
			window.fsr$addEvent('load', fsr$domready);
			document.fsr$addEvent('DOMContentLoaded', fsr$domready);

	}
	
})();

ForeSee.JSON = new ForeSee.Hash({

	encode: function(obj){
		switch (ForeSee.$type(obj)){
			case 'string':
				return '"' + obj.replace(/[\x00-\x1f\\"]/g, ForeSee.JSON.$replaceChars) + '"';
			case 'array':
				return '[' + String(obj.fsr$map(ForeSee.JSON.encode).fsr$filter(ForeSee.$defined)) + ']';
			case 'object': case 'hash':
				var string = [];
				ForeSee.Hash.fsr$each(obj, function(value, key){
					var json = ForeSee.JSON.encode(value);
					if (json) string.push(ForeSee.JSON.encode(key) + ':' + json);
				});
				return '{' + string + '}';
			case 'number': case 'boolean': return String(obj);
			case false: return 'null';
		}
		return null;
	},

	$specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'},

	$replaceChars: function(chr){
		return ForeSee.JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16);
	},

	decode: function(string, secure){
		if (ForeSee.$type(string) != 'string' || !string.length) return null;
		if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
		return eval('(' + string + ')');
	}

});

ForeSee.Native.fsr$implement([ForeSee.Hash, Array, String, Number], {

	fsr$toJSON: function(){
		return ForeSee.JSON.encode(this);
	}

});


ForeSee.Cookie = new ForeSee.Class({

	Implements: ForeSee.Options,

	options: {
		path: false,
		domain: false,
		duration: false,
		secure: false,
		document: document
	},

	initialize: function(key, options){
		this.key = key;
		this.setOptions(options);
	},

	write: function(value){
		value = encodeURIComponent(value);
		if (this.options.domain) value += '; domain=' + this.options.domain;
		if (this.options.path) value += '; path=' + this.options.path;
		if (this.options.duration){
			var date = new Date();
			date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
			value += '; expires=' + date.toGMTString();
		}
		if (this.options.secure) value += '; secure';
		this.options.document.cookie = this.key + '=' + value;
		return this;
	},

	read: function(){
		var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.fsr$escapeRegExp() + '=([^;]*)');
		return (value) ? decodeURIComponent(value[1]) : null;
	},

	dispose: function(){
		new ForeSee.Cookie(this.key, ForeSee.$merge(this.options, {duration: -1})).write('');
		return this;
	}

});

ForeSee.Cookie.write = function(key, value, options){
	return new ForeSee.Cookie(key, options).write(value);
};

ForeSee.Cookie.read = function(key){
	return new ForeSee.Cookie(key).read();
};

ForeSee.Cookie.dispose = function(key, options){
	return new ForeSee.Cookie(key, options).dispose();
};

ForeSee.Hash.Cookie = new ForeSee.Class({

	Extends: ForeSee.Cookie,

	options: {
		autoSave: true
	},

	initialize: function(name, options){
		this.parent(name, options);
		this.load();
	},

	save: function(){
		var value = ForeSee.JSON.encode(this.hash);
		if (!value || value.length > 4096) return false; 
		if (value == '{}') this.dispose();
		else this.write(value);
		return true;
	},

	load: function(){
		this.hash = new ForeSee.Hash(ForeSee.JSON.decode(this.read(), true));
		return this;
	}

});

ForeSee.Hash.Cookie.fsr$implement({
    fsr$get: function(name){
        return this.hash.fsr$get(name);
    },
    
    fsr$set: function(name, value){
		this.hash.fsr$set(name, value);
        this.save()
        return this;
    },
    
    fsr$erase: function(name){
 		this.hash.fsr$erase(name);
        this.save()
        return this;
    },
    
    fsr$empty: function(){
  		this.hash.fsr$empty();
        this.save()
        return this;
    }
});

ForeSee.Asset = new ForeSee.Hash({

	src: function(source){
		var src = source;
		if (source.substring(0,2) == '//') {
			src = document.location.protocol + src;
		}
		return src;
	},

	javascript: function(source, properties){
		properties = ForeSee.$extend({
			onload: ForeSee.$empty,
			document: document,
			check: ForeSee.$lambda(true)
		}, properties);
		
		var script = new ForeSee.Element('script', {'src': ForeSee.Asset.src(source), 'type': 'text/javascript'});
		
		var load = properties.onload.fsr$bind(script), check = properties.check, doc = properties.document;
		delete properties.onload; delete properties.check; delete properties.document;
		
		script.fsr$addEvents({
			load: load,
			readystatechange: function(){
				if (ForeSee.Browser.Engine.trident && ['loaded', 'complete'].fsr$contains(this.readyState)) load();
			}
		}).fsr$setProperties(properties);
		
		
		if (ForeSee.Browser.Engine.webkit419) var checker = (function(){
			if (!ForeSee.$try(check)) return;
			ForeSee.$clear(checker);
			load();
		}).fsr$periodical(50);
		
		return script.fsr$inject(document.getElementsByTagName('head')[0]);
	},

	image: function(source, properties){
		properties = ForeSee.$merge({
			'onload': ForeSee.$empty,
			'onabort': ForeSee.$empty,
			'onerror': ForeSee.$empty
		}, properties);
		var image = new Image();
		var element = $fsr(image) || new ForeSee.Element('img');
		['load', 'abort', 'error'].fsr$each(function(name){
			var type = 'on' + name;
			var event = properties[type];
			delete properties[type];
			image[type] = function(){
				if (!image) return;
				if (!element.parentNode){
					element.width = image.width;
					element.height = image.height;
				}
				image = image.onload = image.onabort = image.onerror = null;
				event.fsr$delay(1, element, element);
				element.fsr$fireEvent(name, element, 1);
			};
		});
		image.src = ForeSee.Asset.src(source);
		if (element.src != image.src) element.src = image.src;
		if (image && image.complete) image.onload.fsr$delay(1);
		return element.fsr$setProperties(properties);
	},
	
	css: function(source, properties){
		return new ForeSee.Element('link', ForeSee.$merge({
			'rel': 'stylesheet', 'media': 'screen', 'type': 'text/css', 'href': ForeSee.Asset.src(source)
		}, properties)).fsr$inject(document.getElementsByTagName('head')[0]);
	}
});

ForeSee.Request = new ForeSee.Class({

	Implements: [ForeSee.Chain, ForeSee.Events, ForeSee.Options],

	options: {
		url: '',
		data: '',
		headers: {
			'X-ForeSee.Requested-With': 'XMLHttpForeSee.Request',
			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
		},
		async: true,
		format: false,
		method: 'post',
		link: 'ignore',
		isSuccess: null,
		emulation: true,
		urlEncoded: true,
		encoding: 'utf-8',
		evalScripts: false,
		evalResponse: false
	},

	initialize: function(options){
		this.xhr = new ForeSee.Browser.Request();
		this.setOptions(options);
		this.options.isSuccess = this.options.isSuccess || this.isSuccess;
		this.headers = new ForeSee.Hash(this.options.headers);
	},

	onStateChange: function(){
		if (this.xhr.readyState != 4 || !this.running) return;
		this.running = false;
		this.status = 0;
		ForeSee.$try(function(){
			this.status = this.xhr.status;
		}.fsr$bind(this));
		if (this.options.isSuccess.call(this, this.status)){
			this.response = {text: this.xhr.responseText, xml: this.xhr.responseXML};
			this.success(this.response.text, this.response.xml);
		} else {
			this.response = {text: null, xml: null};
			this.failure();
		}
		this.xhr.onreadystatechange = ForeSee.$empty;
	},

	isSuccess: function(){
		return ((this.status >= 200) && (this.status < 300));
	},

	processScripts: function(text){
		if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return ForeSee.$exec(text);
		return text.fsr$stripScripts(this.options.evalScripts);
	},

	success: function(text, xml){
		this.onSuccess(this.processScripts(text), xml);
	},
	
	onSuccess: function(){
		this.fsr$fireEvent('complete', arguments).fsr$fireEvent('success', arguments).callChain();
	},
	
	failure: function(){
		this.onFailure();
	},

	onFailure: function(){
		this.fsr$fireEvent('complete').fsr$fireEvent('failure', this.xhr);
	},

	setHeader: function(name, value){
		this.headers.fsr$set(name, value);
		return this;
	},

	getHeader: function(name){
		return ForeSee.$try(function(){
			return this.xhr.getResponseHeader(name);
		}.fsr$bind(this));
	},

	check: function(caller){
		if (!this.running) return true;
		switch (this.options.link){
			case 'cancel': this.cancel(); return true;
			case 'chain': this.chain(caller.fsr$bind(this, Array.fsr$slice(arguments, 1))); return false;
		}
		return false;
	},

	send: function(options){
		if (!this.check(arguments.callee, options)) return this;
		this.running = true;

		var type = ForeSee.$type(options);
		if (type == 'string' || type == 'element') options = {data: options};

		var old = this.options;
		options = ForeSee.$extend({data: old.data, url: old.url, method: old.method}, options);
		var data = options.data, url = options.url, method = options.method;

		switch (ForeSee.$type(data)){
			case 'element': data = $fsr(data).fsr$toQueryString(); break;
			case 'object': case 'hash': data = ForeSee.Hash.fsr$toQueryString(data);
		}

		if (data && method == 'get'){
			url = url + (url.fsr$contains('?') ? '&' : '?') + data;
			data = null;
		}

		this.xhr.open(method.toUpperCase(), url, this.options.async);

		this.xhr.onreadystatechange = this.onStateChange.fsr$bind(this);

		this.headers.fsr$each(function(value, key){
			if (!ForeSee.$try(function(){
				this.xhr.setRequestHeader(key, value);
				return true;
			}.fsr$bind(this))) this.fsr$fireEvent('exception', [key, value]);
		}, this);

		this.fsr$fireEvent('request');
		this.xhr.send(data);
		if (!this.options.async) this.onStateChange();
		return this;
	},

	cancel: function(){
		if (!this.running) return this;
		this.running = false;
		this.xhr.abort();
		this.xhr.onreadystatechange = ForeSee.$empty;
		this.xhr = new ForeSee.Browser.Request();
		this.fsr$fireEvent('cancel');
		return this;
	}

});

(function(){

var methods = {};
['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].fsr$each(function(method){
	methods[method] = function(){
		var params = Array.fsr$link(arguments, {url: String.type, data: ForeSee.$defined}); 
		return this.send(ForeSee.$extend(params, {method: method.toLowerCase()}));
	};
});

ForeSee.Request.fsr$implement(methods);

})();

ForeSee.Browser.fsr$set("Popup", new ForeSee.Class({
	Implements:[ForeSee.Options, ForeSee.Events],
	options: {
		width: 500,
		height: 300,
		x: 50,
		y: 50,
		toolbar: 0,
		location: 0,
		directories: 0,
		status: 0,
		scrollbars: 'auto',
		resizable: 1,
		name: 'popup',
		blur: false,
		menubar: 1
},
	initialize: function(url, options){
		this.url = url || false;
		this.setOptions(options);
		if(this.url) this.openWin();
	},
	openWin: function(url){
		url = url || this.url;
		var options = 'toolbar='+this.options.toolbar+
			',location='+this.options.location+
			',directories='+this.options.directories+
			',status='+this.options.status+
			',scrollbars='+this.options.scrollbars+
			',resizable='+this.options.resizable+
			',width='+this.options.width+
			',height='+this.options.height+
			',top='+this.options.y+
			',left='+this.options.x+
			',menubar='+this.options.menubar;
		this.window = window.open(url, this.options.name, options);
		if (!this.window) {
			this.window = window.open('', this.options.name, options);
			this.window.location.href = url;
		}
		if (!this.options.blur)
			this.focus.fsr$delay(100, this);
		else
			this.window.blur();
		return this;
	},
	focus: function(){
		if (this.window) this.window.focus();
		else if (this.focusTries<10) this.focus.delay(100, this); 
		else {
			this.blocked = true;
			this.fsr$fireEvent('onBlock');
		}
		return this;
	},
	focusTries: 0,
	blocked: null,
	close: function(){
		this.window.close();
		return this;
	}
}));
ForeSee.RemoteEvent = new ForeSee.Class({

    Implements: [ForeSee.Chain, ForeSee.Events, ForeSee.Options],
    
    options: {
        host: '',
        path: '',
        url: ''
    },
    
    initialize: function(event, options){
        this.setOptions(options);
		this.event = event
    },
    
    onStateChange: function(status){
        if (!this.running) 
            return;
        this.running = false;
        this.status = 0;
        ForeSee.$try(function(){
            this.status = status;
        }.fsr$bind(this));
        if (this.isSuccess()) {
            this.success();
        }
        else {
            this.failure();
        }
    },
    
    isSuccess: function(){
        return (this.status == 1);
    },
    
    success: function(){
        this.onSuccess();
    },
    
    onSuccess: function(){
        this.fsr$fireEvent('success');
    },
    
    failure: function(){
        this.onFailure();
    },
    
    onFailure: function(){
        this.fsr$fireEvent('failure');
    },
    
    send: function(values){
        this.running = true;
        var self = this;
        var params = ForeSee.Hash.fsr$toQueryString(values);
        var url = document.location.protocol + '//' +
        this.options.host + this.options.path  + this.options.url + '?' +
        'event=' + this.event + '&' + params + '&' + 'uid=' + ForeSee.$time();
        
        new ForeSee.Asset.image(url, {
            'onload': function(image){
                self.onStateChange(1);
            },
            
            'onerror': function(){
                self.onStateChange(0);
            },
            
            'onabort': function(){
                self.onStateChange(0);
            }
        })
        
        return this;
    }
	
});

ForeSee.RemoteCookie = new ForeSee.Class({

    Implements: ForeSee.Options,
    
    options: {
        host: false,
        path: false,
        url: false,
        duration: false
    },
    
    initialize: function(id, options){
        this.id = id;
        this.setOptions(options);
    },
    
    save: function(name, value){
        if (name && value) 
            new ForeSee.RemoteEvent('setcookie', this.options).send({
                'id': this.id,
                'name': name,
                'value': value
            });
        else if (!value) 
            new ForeSee.RemoteEvent('deletecookie', this.options).send({
                'id': this.id,
                'name': name
            });
        else if (!name && !value) 
            new ForeSee.RemoteEvent('deletecookie', this.options).send({
                'id': this.id
            });
        return true;
    },
    
    load: function(key){
        return this;
    }
    
});

ForeSee.RemoteCookie.fsr$implement({
    fsr$get: function(name){
        this.load(name);
    },
    
    fsr$set: function(name, value){
        this.save(name, value)
        return this;
    },
    
    fsr$erase: function(name){
        this.save(name);
        return this;
    },
    
    fsr$empty: function(){
        this.save();
        return this;
    }
});

ForeSee.CPPS = new ForeSee.Hash({

    fsr$set: function(key, value){
        var cpps = ForeSee.c().fsr$get('cpps') ||
        {};
        cpps[key] = value;
        ForeSee.c().fsr$set('cpps', cpps);
    },
    
    fsr$get: function(key){
        var cpps = ForeSee.c().fsr$get('cpps') ||
        {};
        return cpps[key];
    },
    
    fsr$erase: function(key){
        var cpps = ForeSee.c().fsr$get('cpps') ||
        {};
        delete cpps[key];
        ForeSee.c().fsr$set('cpps', cpps);
    },
    
    fsr$toQueryString: function(){
		var c = ForeSee.c();
		
		var browser = c.fsr$get('browser');
        var o = {
            browser: browser.name + ' ' + browser.version,
            os: browser.platform,
            pv: c.fsr$get('pv'),
            url: c.fsr$get('current'),
            ref_url: c.fsr$get('ref_url'),
			locale: c.fsr$get('locale') || '',
			site: c.fsr$get('site') || '',
			referrer: c.fsr$get('referrer') || '',
			terms: c.fsr$get('terms') || '',
			sessionid: c.fsr$get('fsrid') || ''
       };

        var cpps = c.fsr$get('cpps') ||
        {};
        var h = new ForeSee.Hash(cpps);
        
        var other = o ||
        {};
        for (k in other) 
            h.fsr$set(k, other[k]);
        
        var qs = h.fsr$toQueryString('cpp');
        
        return qs;
    }
});

ForeSee.Service = new ForeSee.Class({

    Implements: [ForeSee.Chain, ForeSee.Events, ForeSee.Options],
    
    options: {        
    },
    
    initialize: function(options){
        this.setOptions(options);
    },
    
    onStateChange: function(status){
        if (!this.running) 
            return;
        this.running = false;
        this.status = 0;
        ForeSee.$try(function(){
            this.status = status;
        }.fsr$bind(this));
        if (this.status == 1) {
            this.success();
        }
        else if(this.status == 0) {
            this.failure();
        }
        else if(this.status == -1) {
            this.error();
        }
    },
    
    success: function(){
        this.onSuccess();
    },
    
    onSuccess: function(){
        this.fsr$fireEvent('complete').fsr$fireEvent('success');
    },
    
    failure: function(){
        this.onFailure();
    },
    
    onFailure: function(){
        this.fsr$fireEvent('complete').fsr$fireEvent('failure');
    },
    
    error: function(){
        this.onError();
    },
    
    onError: function(){
        this.fsr$fireEvent('complete').fsr$fireEvent('error');
    },

    ping: function(){
        this.running = true;
        var self = this;
		
		var params = this.options.params || {};
		params['protocol'] = document.location.protocol;
		params['uid'] = ForeSee.$time();
		
        var qs = ForeSee.Hash.fsr$toQueryString(params);
        var url = document.location.protocol + '//' + this.options.host + this.options.path  + this.options.url + '?' + qs;
        new ForeSee.Asset.image(url, {
            'onload': function(image){
				if (image.width == self.options.success)
                	self.onStateChange(1);
				else
                	self.onStateChange(0);
            },
            
            'onerror': function(){
                self.onStateChange(-1);
            },
            
            'onabort': function(){
                self.onStateChange(0);
            }
        });
        
        return this;
    },
    
    cancel: function(){
        if (!this.running) 
            return this;
        this.running = false;
        this.fsr$fireEvent('cancel');
        return this;
    }
    
});

ForeSee.RR = new ForeSee.Hash({
	hasRR: function() {
		if (typeof robotreplay != "undefined")
			return true;
		return false;
	},
	setOKTransmit: function() {
		if (this.hasRR()) {
			var replay_id = robotreplay.Session.rr_group_session_id;
			robotreplay.Log.setOKTransmit();
			ForeSee.CPPS.fsr$set('replay_id', replay_id);
		}
	},
	recordEvent: function(eventName, eventValue) {
		if (this.hasRR())
			robotreplay.Log.push(eventName, eventValue);
	},
	cancelRecord: function() {
		if (this.hasRR())
			robotreplay.Log.cancelRecord();		
	}
});

ForeSee.services = {
    survey: {
        host: 'www.foreseeresults.com',
        path: '/survey',
        url: '/display'
    },
    
    check: {
        host: 'controller.foreseeresults.com',
        path: '/fsrSurvey',
        url: '/OTCImg',
        success: 3
    },
    
    event: {
        host: 'events.foreseeresults.com',
        path: '/rec',
        url: '/process',
        enabled: false,
		id: false
    },
    
    domain: {
        host: 'www.foreseeresults.com',
        path: '/survey',
        url: '/FSRImg',
        success: 3
    }
}
ForeSee.UnsupportedBrowsers = {
    Explorer: 5.5,
    Safari: 2,
    Firefox: 1.4
}
ForeSee.$P = function(){
    return ForeSee.properties;
};

ForeSee.c = function(){
    return new ForeSee.Hash.Cookie('foresee.' + ForeSee.site.cookie, {
        path: '/',
        domain: ForeSee.site.domain || false
    });
};

ForeSee.log = function(msg, param){
    if (!ForeSee.services.event.enabled)
        return;

	var c = ForeSee.c()
	
    new ForeSee.RemoteEvent('logit', {
        host: ForeSee.services.event.host,
        path: ForeSee.services.event.path,
        url: ForeSee.services.event.url
    }).send({
    	'cid' : ForeSee.id,
    	'fsrid' : c.fsr$get('fsrid'),
    	'name' : c.fsr$get('sd').name,
        'msg': msg,
        'param': param,
        'tmz' : new Date().getTimezoneOffset()
    });
};

ForeSee.popNow = function(sp){
    ForeSee.pop(sp, 'now');
};

ForeSee.popLater = function(sp){
    ForeSee.pop(sp, 'later');
};

ForeSee.popImmediate = function(){
    ForeSee.pop(100, 'now');
};

ForeSee.popFeedback = function(){
	ForeSee.controller.popFeedback();
};

ForeSee.pop = function(sp, when){
    var tsp = sp;
    if (!tsp)
        tsp = ForeSee.controller.sd.criteria.sp;

    var twhen = when;
    if (!twhen)
        twhen = ForeSee.controller.sd.pop.when;

    var tsv = ForeSee.controller.sd.sv;

    if (!(tsv <= tsp))
        return;

    if (twhen == 'now') {
        if (!(ForeSee.controller.surveyShown() && tsp < 100)) {
            ForeSee.controller.popImmediate();
        }
    }
    else if (twhen == 'later') {
        if (!ForeSee.controller.trackerRunning()) {
            ForeSee.controller.popTracker();
        }
    }
};

ForeSee.close = function(){
    ForeSee.controller.cancelTracker();
};

ForeSee.run = function(){
    ForeSee.controller.run(false);
};
ForeSee.accepted = function(locale){
	ForeSee.language(locale);
    ForeSee.controller.accepted();
    ForeSee.idhtml.hide();
}

ForeSee.declined = function(locale){
	ForeSee.language(locale);
    ForeSee.controller.declined();
    ForeSee.idhtml.hide();
}

ForeSee.qualified = function(){
    ForeSee.controller.qualified();
    ForeSee.idhtml.hide();
}

ForeSee.language = function(locale){
	if (!locale)
		return;
	ForeSee.locale = locale;
	ForeSee.c().fsr$set('locale', locale);
}

ForeSee.qualify = function(q){
    ForeSee.canceled = false;
    ForeSee.qid = q;
};

ForeSee.cancel = function(){
    ForeSee.canceled = true;
};

ForeSee.canceled = false;

ForeSee.SurveyController = new ForeSee.Class({

    Implements: ForeSee.Options,

    options: {},

    initialize: function(options){
        this.setOptions(options);
        ForeSee.controller = this;
    },

    load: function(){
        if (!ForeSee.enabled)
            return;

        var self = this;
        new ForeSee.Asset.javascript(ForeSee.files + 'foresee-surveydef.js', {
            id: 'foresee-surveydef',
            onload: function(){
                fsr$dbug.log('Survey Definitions Loaded.');
				self.run(true);
            }
        });
    },

    run: function(init){
		if (init) {
			if (!this.init())
				return;
		}

        if (!this.setup())
            return;

        var p;

        this.sd = this.pd;
        this.sdi = this.pdi;
        p = this.process()


        if (p)
            return;

        this.sd = this.cd;
        this.sdi = this.cdi;

        p = this.process();
    },

    process: function(){

        if (!this.sd)
            return false;

        if (this.sd.type == 'current') {
            ForeSee.c().fsr$set('sd', {
                name: this.sd.name,
                idx: this.sd.idx
            });
        }

        if (this.processTracker()) {
            var self = this;
            (function(){
                self.launch('tracker');
            }).fsr$delay(1);
            return true;
        }

        if (this.processInvite()) {
            var self = this;
            (function(){
                self.launch('invite');
            }).fsr$delay(1);
            return true;
        }

        if (this.sd.type == 'current') {            
            if (this.inviteAccepted() && !this.surveyShown()) {
                this.setupLinks('pop', this.popLink);
                this.setupLinks('cancel', this.cancelTracker);
            }
			
            if (!this.inviteAccepted()) {
				this.setupLinks('attach', this.popAttach);
			}
        }

        return false;
    },

    processTracker: function(){
        if (!this.shouldTrack())
            return false;

        if (!this.trackerRunning())
            return false;

        return true;
    },

    shouldTrack: function(){
		if (!this.sd.ls)
			return false;

        if (this.sd.type == 'previous') {
            if (!(this.sd.pop.when == 'later') || !(this.sd.pop.after == 'leaving-section'))
                return false;
        }
        else if (this.sd.type == 'current') {
            if (!(this.sd.pop.when == 'now'))
                return false;
        }

        return true;
    },

    trackerRunning: function(){
        if (ForeSee.$defined(ForeSee.c().fsr$get('tracker')))
            return true;

        return false;
    },

    processInvite: function(){
        if (this.inviteShown())
            return false;

        if (!this.shouldInvite())
            return false;

        return true;
    },

    shouldInvite: function(){
		if (this.sd.invite === false)
			return false;
		
        if (this.sd.exclude) {
            var e = false;
            if (!e) {
                e = this.checkExclude(this.sd.exclude.local || [], document.location.href);
            }

            if (!e) {
                e = this.checkExclude(this.sd.exclude.referer || [], document.referrer);
            }

            if (e) {
                var c = ForeSee.c();
                var v = c.fsr$get('ec');
                this.sd.ec = v[this.sd.name] = v[this.sd.name] + 1;
                c.fsr$set('ec', v);
                return false;
            }
        }

        var when = (this.sd.type == 'previous') ? 'onexit' : 'onentry'
        if (this.sd.invite && this.sd.invite.when != when)
            return false;

		if (!this.sd.ls)
			return false;

        if (!(this.sd.sv > 0 && this.sd.sv <= this.sd.criteria.sp))
            return false;

        return true;
    },

    inviteShown: function(){
        if (ForeSee.$defined(ForeSee.c().fsr$get('invite')))
            return true;

        return false;
    },

    inviteAccepted: function(){
        if (ForeSee.c().fsr$get('invite') == 1)
            return true;

        return false;
    },

    surveyShown: function(){
        if (ForeSee.$defined(ForeSee.c().fsr$get('survey')))
            return true;

        return false;
    },

    launch: function(target){
        if (target == 'invite') {
            this.attemptInvite();
        }
        else if (target == 'tracker') {
            this.popImmediate();
        }
    },

    checkExclude: function(list, source){
        for (var j = 0, n = list.length; j < n; j++) {
            if (source.match(list[j])) {
                return true;
            }
        }

        return false;
    },

    attemptInvite: function(){
        var self = this;

        var fn = 'invite'
		if (ForeSee.$P().mode == 'hybrid') {
			fn = 'checkDomain';
        }

        new ForeSee.Service({
            host: ForeSee.services.check.host,
            path: ForeSee.services.check.path,
            url: ForeSee.services.check.url,
            success: ForeSee.services.check.success,

            onSuccess: function(){
                self[fn]();
            },

            onFailure: function(){
            },

            onError: function(){
                self[fn]();
            }
        }).ping();
    },

    checkDomain: function(){
        var self = this;

        var fn = 'invite'

        new ForeSee.Service({
            host: ForeSee.services.domain.host,
            path: ForeSee.services.domain.path,
            url: ForeSee.services.domain.url,
            params: {
                'do': 0
            },
            success: ForeSee.services.check.success,

            onSuccess: function(){
                self[fn]();
            },

            onFailure: function(){
            }
        }).ping();
    },

    setupLinks: function(type, fn){
        if (!this.sd.links) 
            return;
        
        var linked = 0;
        var links = this.sd.links[type] || [];
        for (var i = 0, l = links.length; i < l; i++) {
            var x = this.link(links[i].tag, links[i].attribute, links[i].patterns || [], links[i].qualifier, fn);
            linked = linked + x;
        }
        fsr$dbug.log('linked (' + type + '): ' + linked);
    },

    link: function(tag, attribute, patterns, qualifier, fn){
		var self = this;
        var linked = 0;
        $$fsr(tag).fsr$each(function(el){
            for (var i = 0, l = patterns.length; i < l; i++) {
                if (el[attribute].match(patterns[i])) {
                    linked++;
                    el.fsr$addEvents({
                        'click': function(){
							if (qualifier) {
								ForeSee.qualify(qualifier);
							}
                            fn.call(self);
                        }
                    })
                    break;
                }
            }
        });
 		return linked;
    },

    init: function(){
        fsr$dbug.log('======INIT=======');

        var c = ForeSee.c();

        var alive = c.fsr$get('alive') || 0;
        alive = alive + 1;
        c.fsr$set('alive', alive);
        this.ralive = true;

        c = ForeSee.c();
        alive = c.fsr$get('alive');
        if (!alive) {
            fsr$dbug.log('Exit...cookies are not enabled.');
            return false;
        }

        fsr$dbug.log('alive: ' + alive);


        if (!this.trackerRunning()) {
            clearInterval(fsr$timer);
            ForeSee.Cookie.dispose('foresee.alive', {
                path: '/',
                domain: ForeSee.site.domain || false
            });
        }

        var browser = ForeSee.Browser;
        c.fsr$set('browser', {
            name: ForeSee.Browser.Type.name,
            version: ForeSee.Browser.Type.version,
            platform: ForeSee.Browser.Platform.os
        });

        fsr$dbug.log('browser: ' + browser.Type.name + ' ' + browser.Type.version + ' on ' + browser.Platform.os);

        if (ForeSee.UnsupportedBrowsers[browser.Type.name]) {
            if (browser.Type.version <= ForeSee.UnsupportedBrowsers[browser.Type.name]) {
                fsr$dbug.log('Browser not surpported.');
                return false;
            }
        }


        if (this.validateIP() == 0) {
            fsr$dbug.log('Invalid IP Address.');
            return false;
        }

        var timeout;
        if (ForeSee.$defined(c.fsr$get('finish'))) {
            var ptimeout = c.fsr$get('timeout');
            var loadtime = ((ForeSee.$time() - c.fsr$get('finish')) / 1000);
            fsr$dbug.log('ptimeout: ' + ptimeout);
            fsr$dbug.log('loadtime: ' + loadtime);
            timeout = (0.90 * ptimeout) + (0.10 * (loadtime * 2));
            if (timeout < 2)
				timeout = 2;
            else if (timeout > 5)
				timeout = 5;
        }
        else {
            timeout = ForeSee.$P().tracker.timeout;
        }
        c.fsr$set('timeout', timeout);
        fsr$dbug.log('timeout: ' + timeout);

        if (!c.fsr$get('start')) {
            var rd;
            if (rd = ForeSee.Cookie.read('foresee' + '.repeatdays', {
                path: '/',
                domain: ForeSee.site.domain || false
            })) {
                fsr$dbug.log('Persistent Cookie Found: ' + rd);
                return false;
            }

            c.fsr$set('start', ForeSee.$time());

            var self = this;
            this.dhtml_win = 1;
            new ForeSee.Asset.javascript(ForeSee.files + 'foresee-dhtml-popup.js', {
                id: 'foresee-dhtml-popup',
                onload: function(){
                    fsr$dbug.log('DHTML popup script loaded (1).');
                    self.dhtml_win = 2;
                }
            });

            this.dhtml_css = 1;
            new ForeSee.Asset.css(ForeSee.files + ForeSee.$P().invite.css);
			if (ForeSee.$P().invite.css != ForeSee.$P().qualifier.css) {
				new ForeSee.Asset.css(ForeSee.files + ForeSee.$P().qualifier.css);
			}
            this.dhtml_css = 2;

            var id = this.generateid();
            c.fsr$set('fsrid', id);

            if (document.referrer && document.referrer != "") {
				c.fsr$set('ref_url', document.referrer);

				var rmatch = document.referrer.match(/^(\w+\:\/\/)?(((\w+\.?))+)\//);
				var referrer = ''
				if (rmatch && rmatch.length >=3) {
					referrer = rmatch[2]
				}
				c.fsr$set('referrer', referrer);
				fsr$dbug.log('referrer: ' + referrer);
				
				var terms = this.decodeReferrer(document.referrer)
        		c.fsr$set('terms', terms);
				fsr$dbug.log('search terms: ' + terms);
            }
        }

        fsr$dbug.log('invite: ' + (ForeSee.$pick(c.fsr$get('invite'), '')));
        fsr$dbug.log('tracker: ' + (ForeSee.$pick(c.fsr$get('tracker') || '')));

        return true;
    },

    setup: function(){
        fsr$dbug.log('======SETUP=======');

        var c = ForeSee.c();

        var pv = c.fsr$get('pv') ? c.fsr$get('pv') + 1 : 1;
        c.fsr$set('pv', pv);
        fsr$dbug.log('pv: ' + pv);

        ForeSee.sv = ForeSee.$random(0, 100);

		this.sp = new ForeSee.Hash.Cookie('foresee.sp', {
            path: '/',
            domain: ForeSee.site.domain || false
        });

        var cs, cm, cdi, ps, pm, pdi;

        ps = c.fsr$get('current');
        pdi = c.fsr$get('cdi');

        cs = document.location.href;
        c.fsr$set('current', cs);

		this.language();
		if (ForeSee.locale)
        	fsr$dbug.log('language: ' + ForeSee.locale || '');

		this.subsite();
		if (ForeSee.subsite) {
			c.fsr$set('site', ForeSee.subsite || '');
			fsr$dbug.log('site: ' + ForeSee.subsite || '');
		}

        var lc = c.fsr$get('lc') || {};
        var ls = c.fsr$get('ls') || {};
        var ec = c.fsr$get('ec') || {};

        cm = this.match(cs)
        if (cm.length != 0) {
            fsr$dbug.log('===CURRENT====');
            for (var i = 0, j = cm.length; i < j; i++) {
                var sd = ForeSee.surveydefs[cm[i]];
                sd.idx = cm[i];

				this.criteria(sd.criteria);

                sd.lc = lc[sd.name] = lc[sd.name] ? lc[sd.name] + 1 : 1;
                sd.ec = ec[sd.name] = ec[sd.name] ? ec[sd.name] : 0;
                sd.type = 'current'

				this.configLoyalty(sd);

				var ld = this.loyaltyDef(sd);

				var li = this.checkLoyalty(ld, sd.lc, sd.ec);

                if (li > -1) {
					sd.ls= ls[sd.name] = true;
					if (ForeSee.$type(sd.criteria.lf) == 'array') {
						sd.criteria.lf = sd.criteria.lf[li];
						sd.criteria.sp = sd.criteria.sp[li];
						sd.pop.when = sd.pop.when[li];
					}
                    if (sd.pin) {
                        var p = c.fsr$get('p') || {};
                        p[sd.name] = 1;
                        c.fsr$set('p', p);
                    }
                }
				else {
					sd.ls = ls[sd.name] = false;
					if (ForeSee.$type(sd.criteria.lf) == 'array') {
						sd.criteria.lf = sd.criteria.lf[0];
						sd.criteria.sp = sd.criteria.sp[0];
						sd.pop.when = sd.pop.when[0];
					}
				}

                this.configure(sd);

				cdi = sd.idx;
                c.fsr$set('cdi', sd.idx);

                this.cd = sd;

                break;
            }
            c.fsr$set('lc', lc);
            c.fsr$set('ls', ls);
            c.fsr$set('ec', ec);
        }

        if (ForeSee.$defined(pdi) && (pdi != cdi)) {
            fsr$dbug.log('===PREVIOUS===');
            var sd = ForeSee.surveydefs[pdi];
            sd.idx = pdi;

 			this.criteria(sd);

            sd.lc = lc[sd.name];
            sd.ls = ls[sd.name] || false;
            sd.type = 'previous'

			this.configLoyalty(sd);

            this.configure(sd);

            this.pd = sd;
        }

        if (!this.cd && !this.pd)
            return false;

        return true;
    },

    configLoyalty: function(sd){
		if (ForeSee.$type(sd.criteria.lf) == 'number') {
			sd.criteria.lf = {
				v: sd.criteria.lf,
				o: '>='
			};
		}
	},

    loyaltyDef: function(sd){
		var ld = sd.criteria.lf;
		if (ForeSee.$type(sd.criteria.lf) == 'object') {
			ld = [sd.criteria.lf];
		}

		return ld;
	},

    checkLoyalty: function(ld, lc, ec){
		var k = -1;
        for (var i = 0, l = ld.length; i < l; i++) {
            if (ld[i].o == '>=') {
                if (lc >= ld[i].v)
					k = i;;
            }
            else if (ld[i].o == '=') {
                if ((lc - ec) == ld[i].v)
					k = i;;
            }
            else if (ld[i].o == '>') {
                if (lc > ld[i].v)
					k = i;
            }
        }

        return k;
    },

    validateIP: function(ip){
        var match = 1;

        var d = ForeSee.$P().ipexclude;

        if (!d)
            return match;

        var ip;
        if (d.src == 'cookie') {
            if (d.type && d.type == 'client')
                ip = ForeSee.Cookie.read(d.name, {
                    path: '/',
                    domain: ForeSee.site.domain || false
                });
            else
                ip = ForeSee.c().fsr$get('ip');
        }
        else if (d.src == 'variable') {
            if (d.type && d.type == 'client')
                ip = window[d.name];
            else
                ip = ForeSee[d.name];
        }

		ip = ip || '';

        for (var i = 0; i < d.ips.length; i++) {
            if (ip.match(d.ips[i])) {
                match = 0;
                break;
            }
        }
        return match;
    },

    configure: function(sd){
        var c = ForeSee.c();

        fsr$dbug.log('sid: ' + sd.name);
        fsr$dbug.log('lc: ' + sd.lc);
        fsr$dbug.log('lf: ' + sd.criteria.lf.v + ' (' + sd.criteria.lf.o + ') ');

        sd.sv = ForeSee.sv;
        fsr$dbug.log('sv: ' + sd.sv);

        if (ForeSee.$type(sd.criteria.sp) == 'array')
            sd.criteria.sp = sd.criteria.sp[(new Date()).getDay()];

		var lname = (!ForeSee.locale) ? sd.name : sd.name +  '-' + ForeSee.locale
		sd.criteria.sp = this.sp.fsr$get(lname) || this.sp.fsr$get(sd.name) ||sd.criteria.sp;

        fsr$dbug.log('sp: ' + sd.criteria.sp);

        if (sd.invite)
            sd.invite = ForeSee.$merge(ForeSee.$P().invite, sd.invite);

        sd.tracker = ForeSee.$merge(ForeSee.$P().tracker, sd.tracker);

        sd.survey = ForeSee.$merge(ForeSee.$P().survey, sd.survey);

        sd.qualifier = ForeSee.$merge(ForeSee.$P().qualifier, sd.qualifier);

        sd.cancel = ForeSee.$merge(ForeSee.$P().cancel, sd.cancel);

        sd.pop = ForeSee.$merge(ForeSee.$P().pop, sd.pop);

        sd.repeatdays = ForeSee.$pick(ForeSee.$P().repeatdays, sd.repeatdays);

        var local = [].fsr$extend(ForeSee.$P().exclude.local);
        if (sd.exclude && sd.exclude.local)
            sd.exclude.local = local.fsr$extend(sd.exclude.local);
        else if (sd.exclude)
            sd.exclude.local = local;
        else
            sd.exclude = {
                'local': local
            };

        var referer = [].fsr$extend(ForeSee.$P().exclude.referer);
        if (sd.exclude && sd.exclude.referer)
            sd.exclude.referer = referer.fsr$extend(sd.exclude.referer);
        else if (sd.exclude)
            sd.exclude.referer = referer;
        else
            sd.exclude = {
                'referer': referer
            };
    },

    unload: function(){
		if (!ForeSee.enabled)
			return;

        if (!this.runload && this.ralive) {
            this.runload = true;
            this.uninit();
        }
        return;
    },

    uninit: function(){
        var c = ForeSee.c();

        var alive = c.fsr$get('alive') || 0;
        c.fsr$set('alive', (alive - 1) > 0 ? alive - 1 : 0);

        c.fsr$set('previous', c.fsr$get('current'));
        c.fsr$set('finish', ForeSee.$time());
    },

    match: function(source){
        if (!source)
            return;

        var m = [];

        var d = ForeSee.surveydefs;
        var pin = ForeSee.c().fsr$get('p') || {};

        for (var i = 0, p, l = d.length, k = 0; i < l; i++) {
            var pk = k;

            p = d[i].include.urls || [];
            for (var j = 0, n = p.length; j < n; j++) {
                if (source.match(p[j])) {
                    m[k++] = i;
                    break;
                }
            }

            if (k != pk)
                break;

            p = d[i].include.cookies || [];
            for (var j = 0, n = p.length; j < n; j++) {
                var value;
                if (value = ForeSee.Cookie.read(p[j].name, {
                    path: p[j].path || false,
                    domain: p[j].domain || false
                })) {
                    if (value.match(p[j].value || '.')) {
                        m[k++] = i;
                        break;
                    }
                }
            }

            if (k != pk)
                break;

            p = d[i].include.variables || [];            
            for (var j = 0, n = p.length; j < n; j++) {
				var name = p[j].name; var value = p[j].value;
				if (ForeSee.$type(name) != 'array') {
					name = [name]; value = [value];
				}
                var v, z = true;
            	for (var x = 0, y = name.length; x < y; x++) {
					if (v = eval(name[x])) {
						if (!v.match(value[x])) {
							z = false;
							break;
						}
					}
				}
				
				if (z) {
					m[k++] = i;
					break;
				}
            }

            if (k != pk)
                break;

            if (pin[d[i].name])
                m[k++] = i;

            if (k != pk)
                break;
        }

        return m;
    },

    invite: function(){
		ForeSee.invite = 0;

		if (ForeSee.locale)
        	ForeSee.c().fsr$set('locale', ForeSee.locale);

        var self = this;
        if (this.sd.invite) {
            (function(){
				ForeSee.log(100, ForeSee.c().fsr$get('current'));
                self.prepareDHTML('invite', 'accepted', 'declined', 'closed');
            }).fsr$delay((this.sd.invite.delay || 0) * 1000);
        }
        else {
            (function(){
                self.accepted();
                self.closed();

            }).fsr$delay(0);
        }
    },

    prepareDHTML: function(type, accepted, declined, closed){
        var self = this;
        if (!ForeSee.$defined(this.dhtml_css)) {
            this.dhtml_css = 1;
            new ForeSee.Asset.css(ForeSee.files + this.sd[type].css);
            this.dhtml_css = 2;
        }

        if (!ForeSee.$defined(this.dhtml_win)) {
            this.dhtml_win = 1;
            new ForeSee.Asset.javascript(ForeSee.files + 'foresee-dhtml-popup.js', {
                id: 'foresee-dhtml-popup',
                onload: function(){
                    fsr$dbug.log('DHTML popup script loaded (2).');
                    self.dhtml_win = 2;
                    self.showDHTML(type, accepted, declined, closed);
                }
            });
        }
        else if (this.dhtml_win == 1) {
            var checker = (function(){
                if (self.dhtml_win == 1)
                    return;
                ForeSee.$clear(checker);
                self.showDHTML(type, accepted, declined, closed);
            }).fsr$periodical(50);
        }
        else if (this.dhtml_win == 2) {
            (function(){
                self.showDHTML(type, accepted, declined, closed);
            }).fsr$delay(1);
        }
    },

    showDHTML: function(type, accepted, declined, closed){
        var self = this;

        var dhtml = this.sd[type].dhtml || this.sd[type];

        this.page(dhtml);

        var buttons = [];
        if (dhtml.buttons) {
			var i = 0;
			if (dhtml.buttons.accept) {
                buttons[i] = {
                    properties: {
                        id: 'accept'
                    },
                    style: 'fsr_button fsr_accept',
                    text: dhtml.buttons.accept,
                    onClick: function(){
                        self[accepted]();
                    },
                    onMouseover: function(){
                        this.className = 'fsr_closeSticky fsr_button fsr_mouseover_accept';
                    },
                    onMouseout: function(){
                        this.className = 'fsr_closeSticky fsr_button fsr_accept';
                    }
                };
                i++;
            };
			if (dhtml.buttons.decline) {
				buttons[i] = {
					properties: {
						id: 'decline'
					},
					style: 'fsr_button fsr_decline',
					text: dhtml.buttons.decline,
					onClick: function(){
						self[declined]();
					},
					onMouseover: function(){
						this.className = 'fsr_closeSticky fsr_button fsr_mouseover_decline';
					},
					onMouseout: function(){
						this.className = 'fsr_closeSticky fsr_button fsr_decline';
					}
				};
				i++;
			};
        }

        var options = {
            position: {
                x: dhtml.x,
                y: dhtml.y
            },
            wrapWithUi: true,
            uiOptions: {
                width: dhtml.width + 'px',
                baseHref: ForeSee.files,
                buttons: buttons
            },
            modalOptions: {
                modalStyle: {
                    'background-color': dhtml.bgcolor,
                    'opacity': dhtml.opacity
                },
                'hideOnClick': dhtml.hideOnClick
            },
            requestOptions: {
                evalScripts: true
            }
        };

		ForeSee[type] = 0;

        var idhtml;
		if (dhtml.content) {
            options.content = dhtml.content;
			idhtml = new ForeSee.StickyWinModal(options);
		}
		else {
            options.url = ForeSee.files + (dhtml.url.dhtml || dhtml.url);
            idhtml = new ForeSee.StickyWinModal.Ajax(options);
		}

        if (closed) {
			idhtml.fsr$addEvent('onClose', function(){
				self[closed]();
			});
		}

		if (dhtml.content)
        	idhtml.show();
		else
        	idhtml.update();

		ForeSee.idhtml = idhtml;
    },

    accepted: function(){
        ForeSee.invite = 1;
		ForeSee.log(101);
        ForeSee.c().fsr$set('invite', ForeSee.invite);


        if (ForeSee.$P().mode == 'hybrid') {
            new ForeSee.Service({
                host: ForeSee.services.domain.host,
                path: ForeSee.services.domain.path,
                url: ForeSee.services.domain.url,
                params: {
                    'do': 1,
                    'rw': this.sd.repeatdays*24*60
                }
            }).ping();
        }

		ForeSee.RR.setOKTransmit();

        var self = this;
        self.processAccept();
        },

    declined: function(){
        ForeSee.invite = -1;
		ForeSee.log(102);
        ForeSee.c().fsr$set('invite', ForeSee.invite);

		ForeSee.RR.cancelRecord();
	},

    closed: function(){
        ForeSee.c().fsr$set('invite', ForeSee.invite);

        if (this.sd.repeatdays) {
            ForeSee.Cookie.write('foresee' + '.repeatdays', this.sd.repeatdays, {
                path: '/',
                domain: ForeSee.site.domain || false,
                duration: this.sd.repeatdays
            });
        }
    },

    qualified: function(){
        ForeSee.qualifier = 1;
		ForeSee.log(301);
        ForeSee.c().fsr$set('qualifier', ForeSee.qualifier);

        var self = this;
        self.processQualifier();
        },

    processAccept: function(){
        
        if (this.sd.pop.when == 'later') {
            if (this.sd.pop.tracker) 
                this.popTracker();
            this.setupLinks('pop', this.popLink);
            this.setupLinks('cancel', this.cancelTracker);
        }
        else if (this.sd.pop.when == 'now') {
            ForeSee.c().fsr$set('survey', 1);
            if (!this.sd.pop.what != 'qualifier') {
                this.popSurvey();
            }
            else {
                this.popQualifier();
            }
        }
        else if (this.sd.pop.when == 'both') {
            this.popTracker();
            this.popSurvey();
        }
    },

    processQualifier: function(){
        if (!ForeSee.canceled) {
            this.popSurvey();
        }
        else {
            this.popCancel();
        }
    },

    popImmediate: function(){
        var self = this;

        var c = ForeSee.c();

        if (this.trackerRunning()) {
            if (ForeSee.Browser.Type.name != 'Firefox' || !this.sd.qualifier.dhtml) {
                c.fsr$set('force', 1);
            }
            else {
				this.cancelTracker();
                (function(){
					ForeSee.log(300, ForeSee.c().fsr$get('current'));
                    self.prepareDHTML('qualifier', 'qualified');
                }).fsr$delay((this.sd.qualifier.delay || 0) * 1000);
            }
        }
        else {
            ForeSee.c().fsr$set('survey', 1);
            if (!this.sd.pop.what != 'qualifier') {
                this.popSurvey();
            }
            else {
                this.popQualifier();
            }
        }
    },

    popSurvey: function(){
        var survey = this.sd.survey;
        var pop = this.sd.pop;
        this.popMain(this.sid(), survey.width, survey.height, pop.pu, survey.loading, '400');
    },

    popFeedback: function(){
        var sd = ForeSee.$P();

		var sid = 'feedback';
        var l = ForeSee.locale;
        if (l) {
            sid = sid + '-' + l;
        }
		this.popMain(sid, sd.survey.width, sd.survey.height, false, sd.survey.loading, '600');
    },

	popMain: function(sid, width, height, pu, loading, type){
        var service = ForeSee.services.survey;

		var params = new ForeSee.Hash({
            'sid': sid,
            'cid': ForeSee.id,
            'version': ForeSee.version
        }).fsr$toQueryString();

        var cpps = ForeSee.CPPS.fsr$toQueryString();

        var url = document.location.protocol + '//' + service.host + service.path + service.url + '?' + params + '&' + cpps;

        if (loading) {
            this.page(ForeSee.$P().loading);
            url = ForeSee.files + ForeSee.$P().loading.url + '?url=' + url;
        }

        this.pop('fsr' + type, url, (window.screen.width - width) / 2, (window.screen.height - height) / 2, width, height, pu);
        ForeSee.log(type, ForeSee.c().fsr$get('current'));
    },

    popTracker: function(){
		fsr$timer = setInterval(fsr$setAlive, 1000);
        this.popOther(this.sd.tracker, true, '200');
    },

    popQualifier: function(){
        this.popOther(this.sd.qualifier, this.sd.pop.pu, '300');
    },

    popCancel: function(){
         this.popOther(this.sd.cancel, false, '500')
    },

    popLink: function(){
        if (!this.surveyShown()) {
            this.popImmediate();
        }
	},

    cancelTracker: function(){
        if (this.trackerRunning()) {
			var w = window.open('', 'fsr200');
            if (w) {
                w.close();
            }
        }
    },

    popOther: function(d, pu, type){
        this.page(d);

        var left = (window.screen.width - d.width) / 2;
        var top = (window.screen.height - d.height) / 2;

        var url = ForeSee.files +  (d.url.pop || d.url) + '?' + 'siteid=' + ForeSee.siteid + '&' + 'sdidx=' + this.sd.idx;

        this.pop('fsr' + type, url, left, top, d.width, d.height, pu);
        ForeSee.log(type, ForeSee.c().fsr$get('current'));
    },

    popAttach: function(){
        var self = this;

        if (!(this.sd.sv > 0 && this.sd.sv <= this.sd.criteria.sp))
            return;
			
		if (ForeSee.locale)
        	ForeSee.c().fsr$set('locale', ForeSee.locale);

        (function(){
            self.accepted();
            self.closed();
            
        }).fsr$delay(0);
	},
	
	sid: function(){
        var c = ForeSee.c();

        var sid = this.sd.name;

        var q1 = this.sd.pop.now;
        if (q1) {
            sid = sid + '-' + q1;
        }

        var q2 = ForeSee.qid;
        if (q2) {
            sid = sid + '-' + q2;
        }

        var l = c.fsr$get('locale');
        if (l) {
            sid = sid + '-' + l;
        }

        return sid;
    },

    pop: function(name, url, left, top, width, height, under, delay){
        (function(){
            new ForeSee.Browser.Popup(url, {
                name: name,
                toolbar: 0,
                location: 0,
                directories: 0,
                status: 0,
                scrollbars: 1,
                resizable: 1,
                width: width,
                height: height,
                x: left,
                y: top,
                blur: under,
                menubar: 0
            });
        }).fsr$delay(delay || 0);
    },

    language: function(){
        var d = ForeSee.$P().language;

        if (!d)
            return;

		var locale = d.locale;

        var source;
        if (d.src == 'location') {
            source = document.location.href;
        }
        else if (d.src == 'cookie') {
            if (d.type && d.type == 'client')
                source = ForeSee.Cookie.read(d.name, {
                    path: '/',
                    domain: ForeSee.site.domain || false
                });
            else
                source = ForeSee.c().fsr$get('lang');
        }
        else if (d.src == 'variable') {
            if (d.type && d.type == 'client')
                source = window[d.name];
            else
                source = ForeSee[d.name];
        }

		source = source || '';

        var l = d.locales || [];
        for (var i = 0, len = l.length; i < len; i++) {
            if (source.match(l[i].match)) {
				locale = l[i].locale;
                break;
            }
        }

		ForeSee.locale = locale;
    },

    page: function(d){
        var locale = ForeSee.c().fsr$get('locale');

        if (!locale)
            return;

        var p = d.locales || [];
        for (var i = 0, len = p.length; i < len; i++) {
            if (p[i].locale == locale) {
                if (p[i].url)
                	d.url = p[i].url;
                if (p[i].content)
                	d.content = p[i].content;
				if (p[i].buttons) {
					d.buttons = {accept: '', decline: ''};
					if (p[i].buttons.accept)
						d.buttons.accept = p[i].buttons.accept;
					if (p[i].buttons.decline)
						d.buttons.decline = p[i].buttons.decline;
				}
                if (p[i].width)
                    d.width = p[i].width;
                if (p[i].height)
                    d.height = p[i].height;
                break;
            }
        }
    },

    criteria: function(d){
        var locale = ForeSee.locale;

        if (!locale)
            return;

        var p = d.locales || [];
        for (var i = 0, len = p.length; i < len; i++) {
            if (p[i].locale == locale) {
                d.sp = p[i].sp;
                d.lf = p[i].lf;
                break;
            }
        }
    },

    subsite: function(){
        var list = ForeSee.$P().subsites;

        if (!list)
            return;

        var source = document.location.href;

        var m = -1;
        for (var j = 0, n = list.length; j < n; j++) {
            if (source.match(list[j])) {
                m = j;
				ForeSee.subsite = list[j];
                break;
            }
        }

        if (m == -1) {
			ForeSee.subsite = 'other';
		}
    },

	generateid: function(){
		var id = '';
		
        if (!ForeSee.services.event.enabled)
            return id;

        if (!ForeSee.services.event.id)
            return id;

		id = ((new Date())-0) + "_" + Math.round(Math.random()*100000000);
		
		return id;
    },

    decodeReferrer: function(referrer){
        referrer = decodeURIComponent(referrer);
        var query = null;

		var matches = document.referrer.match(/[?&]q=([^&]*)/) || document.referrer.match(/[?&]p=([^&]*)/) || document.referrer.match(/[?&]query=([^&]*)/);
  		if (!matches) return;
  		var query = unescape(matches[1]);

        if (query) {
            query = query.replace(/\+/g, " ");
        }

        return query;
    }
});

new ForeSee.SurveyController({});

window.fsr$addEvent('domready', function(){
    (function(){
        ForeSee.controller.load();
    }).fsr$delay(1);
});

window.fsr$addEvent('unload', function(){
    ForeSee.controller.unload();
});

