// File: /okcontent/js/Oryx/Cookies.js
AUTOCORE_SELF_CHECK.push("Oryx/Cookies.js");
// 

function setOkCookie(name,value,expires) {
    setCookie(name,value,expires);
}

function deleteOkCookie(name) {
    deleteCookie(name);
}

// -----------------------------------------------------------------------------------

function getPageTopDomain() {
 var host = window.location.host;
 var parts = host.split('.');
 var res = parts[parts.length-2] + "." + parts[parts.length-1];
 if (res.indexOf(':') != -1) {
	 res = res.substr(0,res.indexOf(':'));
 }
 return res;
}

function secondsFromNow (sec) {
   res = new Date();
   res.setTime(new Date().getTime() + sec * 1000);
   return res;
}

// -----------------------------------------------------------------------------------

function setCookie(name,value,expires) {
  var curCookie = name + "=" + escape(value) +
      ((expires) ? "; expires=" + expires.toGMTString() : "") +
      "; path=/"+
      "; domain=" + getPageTopDomain();
  document.cookie = curCookie;
}
function deleteCookie(name) {
  if (getCookie(name)) {
    document.cookie = name + "=" +
    "; domain=" + getPageTopDomain() + 
    "; path=/"+
    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}
function getCookie(name) {
	var dc = document.cookie;
  	var prefix = name + "=";
  	var begin = dc.indexOf("; " + prefix);
  	if (begin == -1) {
    	begin = dc.indexOf(prefix);
    	if (begin != 0) return null;
  	} 
	else
    	begin += 2;
  	var end = document.cookie.indexOf(";", begin);
  	if (end == -1)
    	end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}

 /* 
 */

function addNewCoresToCookie(file_nums, hash) {
	 var old_cookie = getCookie("core");
	 var old_cookie_parts = [];
	 var new_cookie = old_cookie;
	 if (old_cookie)
		old_cookie_parts = old_cookie.split(":");
	 if (old_cookie_parts.length == 0 || old_cookie_parts[0] != hash)
		old_cookie
	 if (! old_cookie || old_cookie.split(":")[0] != hash)
		new_cookie = hash;
	 var new_addition = file_nums.join(",");
	 for (var i = 1; i < old_cookie_parts.length && old_cookie_parts[0] == hash; i++) {
		 if (old_cookie_parts[i] == new_addition) {
			 return;
		 }
	 }
	 new_cookie += ":" + new_addition;
	 setCookie("core", new_cookie, secondsFromNow(86400 * 30));
}

// Backwards compatibility, but limit miniCookies to 3600 seconds.
 
function setMiniCookie(name,value) {
	NanoCookie.set(name,value,{ms:3600*1000});
}

function deleteMiniCookie(name) {
	NanoCookie.remove(name);
}

function getMiniCookie(name) {
	return NanoCookie.get(name);
}

// 
NanoCookie = {
	
	// 
	set : function(key,value,expires,test) {
		var cookies = this.deserialize();
		var d = new Date();
		var obj = new Object();
		obj["k"] = key;
		obj["v"] = value;
		if (expires.ms)
			obj["e"] = d.getTime() + parseInt(expires.ms);
		else if (expires.gmt)
			obj["e"] = expires.gmt;
		else
			obj["e"] = expires.date.getTime();
		if (isNaN(obj["e"]))
			obj["e"] = 0;
		var found = false;

		for (var i = 0; i < cookies.length; i++) {
			if (cookies[i]["k"] == key) {
				cookies[i] = obj;
				found = true;
			}
		}
		if (! found)
			cookies.push(obj);
		this.serializeAndStore(cookies);
	},
	get : function(key) {
		var cookies = this.deserialize();
		for (var i = 0; i < cookies.length; i++) {
			if (cookies[i]["k"] == key) {
				return cookies[i]["v"];
			}
		}
		return null;
	},	
	// 
	getAll : function(nano_cookie_str) {
		var cookies = this.deserialize(nano_cookie_str);
		var res = [];
		for (var i = 0; i < cookies.length; i++) {
			var obj = new Object();
			obj["key"] = cookies[i]["k"];
			obj["value"] = cookies[i]["v"];
			obj["expires"] = new Date(cookies[i]["e"]);
			res.push(obj);
		}
		return res;		
	},
	// 
	findRegExp : function(regexp) {
		var cookies = this.deserialize();
		var res = [];
		for (var i = 0; i < cookies.length; i++) {
			if (regexp.test(cookies[i]["k"])) {
				var obj = new Object();
				obj["key"] = cookies[i]["k"];
				obj["value"] = cookies[i]["v"];
				obj["expires"] = new Date(cookies[i]["e"]);
				res.push(obj);
			}
		}
		return res;
	},
	remove : function(key) {
		this.set(key,"",{ms:-1},true);		
	},
	removeAll : function() {
		deleteCookie("nano");
	},
	//
	// gets from cookie called "nano" ; alternatively you 
	// can pass it your own cookie and it'll deserialize that
	deserialize : function(nano_cookie_str) {

		var x = nano_cookie_str ? nano_cookie_str : getCookie("nano");
		
		var result = [];
		if (! x)
			return result;
		else {
			var individuals = x.split("|");
			for (var i = 0; i < individuals.length; i++) {
				var obj = new Object();
				var pairs = individuals[i].split(",");
				for (var j = 0; j < pairs.length; j++) {
					var pair = pairs[j].split("=");
					var val = unescape(pair[1]);
					var pval = parseInt(val);
					if (pval == val && ! isNaN(pval))
						val = pval;
					obj[pair[0]] = val;
				}
				result.push(obj);				
			}
			result.sort(this.compareDates);
			// 
			var d = new Date();
			var any_stripped = false;
			while(result.length > 0 && new Date(result[result.length - 1]["e"]) < d) {
				result.length--;
				any_stripped = true;
			}
			return result;
		}
	},
	// 
	serializeAndStore : function(cookies) {
		var res = "";
		for (var i = 0; i < cookies.length; i++) {
			res += (i == 0) ? "" : "|";
			res += "k=" + escape(cookies[i]["k"]);
			res += ",e=" + escape(cookies[i]["e"]);
			res += ",v=" + escape(cookies[i]["v"]);
		}
		setCookie("nano", res, secondsFromNow(3600*24*365));
	},
	compareDates : function(a,b) {
		if (a["e"] && b["e"])
			return ((a["e"] < b["e"]) ? 1 : ((a["e"] > b["e"]) ? -1 : 0));
	}
};
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/browser_detect.js
AUTOCORE_SELF_CHECK.push("browser_detect.js");
var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	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"
		},
		{		// for newer Netscapes (6+)
			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"
		},
		{ 		// for older Netscapes (4-)
			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.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/prototype-1.6.0.3.js
AUTOCORE_SELF_CHECK.push("prototype-1.6.0.3.js");
/*  Prototype JavaScript framework, version 1.6.0.3
 *  (c) 2005-2008 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://www.prototypejs.org/
 *
 *--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.6.0.3',

  Browser: {
    IE:     !!(window.attachEvent &&
      navigator.userAgent.indexOf('Opera') === -1),
    Opera:  navigator.userAgent.indexOf('Opera') > -1,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 &&
      navigator.userAgent.indexOf('KHTML') === -1,
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    SelectorsAPI: !!document.querySelector,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      document.createElement('div')['__proto__'] &&
      document.createElement('div')['__proto__'] !==
        document.createElement('form')['__proto__']
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;


/* Based on Alex Arnell's inheritance implementation. */
var Class = {
  create: function() {
    var parent = null, properties = $A(arguments);
    if (Object.isFunction(properties[0]))
      parent = properties.shift();

    function klass() {
      this.initialize.apply(this, arguments);
    }

    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    if (parent) {
      var subclass = function() { };
      subclass.prototype = parent.prototype;
      klass.prototype = new subclass;
      parent.subclasses.push(klass);
    }

    for (var i = 0; i < properties.length; i++)
      klass.addMethods(properties[i]);

    if (!klass.prototype.initialize)
      klass.prototype.initialize = Prototype.emptyFunction;

    klass.prototype.constructor = klass;

    return klass;
  }
};

Class.Methods = {
  addMethods: function(source) {
    var ancestor   = this.superclass && this.superclass.prototype;
    var properties = Object.keys(source);

    if (!Object.keys({ toString: true }).length)
      properties.push("toString", "valueOf");

    for (var i = 0, length = properties.length; i < length; i++) {
      var property = properties[i], value = source[property];
      if (ancestor && Object.isFunction(value) &&
          value.argumentNames().first() == "$super") {
        var method = value;
        value = (function(m) {
          return function() { return ancestor[m].apply(this, arguments) };
        })(property).wrap(method);

        value.valueOf = method.valueOf.bind(method);
        value.toString = method.toString.bind(method);
      }
      this.prototype[property] = value;
    }

    return this;
  }
};

var Abstract = { };

Object.extend = function(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

Object.extend(Object, {
  inspect: function(object) {
    try {
      if (Object.isUndefined(object)) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : String(object);
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  },

  toJSON: function(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (!Object.isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
  },

  toQueryString: function(object) {
    return $H(object).toQueryString();
  },

  toHTML: function(object) {
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Object.extend({ }, object);
  },

  isElement: function(object) {
    return !!(object && object.nodeType == 1);
  },

  isArray: function(object) {
    return object != null && typeof object == "object" &&
      'splice' in object && 'join' in object;
  },

  isHash: function(object) {
    return object instanceof Hash;
  },

  isFunction: function(object) {
    return typeof object == "function";
  },

  isString: function(object) {
    return typeof object == "string";
  },

  isNumber: function(object) {
    return typeof object == "number";
  },

  isUndefined: function(object) {
    return typeof object == "undefined";
  }
});

Object.extend(Function.prototype, {
  argumentNames: function() {
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
      .replace(/\s+/g, '').split(',');
    return names.length == 1 && !names[0] ? [] : names;
  },

  bind: function() {
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
    var __method = this, args = $A(arguments), object = args.shift();
    return function() {
      return __method.apply(object, args.concat($A(arguments)));
    }
  },

  bindAsEventListener: function() {
    var __method = this, args = $A(arguments), object = args.shift();
    return function(event) {
      return __method.apply(object, [event || window.event].concat(args));
    }
  },

  curry: function() {
    if (!arguments.length) return this;
    var __method = this, args = $A(arguments);
    return function() {
      return __method.apply(this, args.concat($A(arguments)));
    }
  },

  delay: function() {
    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
    return window.setTimeout(function() {
      return __method.apply(__method, args);
    }, timeout);
  },

  defer: function() {
    var args = [0.01].concat($A(arguments));
    return this.delay.apply(this, args);
  },

  wrap: function(wrapper) {
    var __method = this;
    return function() {
      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
    }
  },

  methodize: function() {
    if (this._methodized) return this._methodized;
    var __method = this;
    return this._methodized = function() {
      return __method.apply(null, [this].concat($A(arguments)));
    };
  }
});

Date.prototype.toJSON = function() {
  return '"' + this.getUTCFullYear() + '-' +
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
    this.getUTCDate().toPaddedString(2) + 'T' +
    this.getUTCHours().toPaddedString(2) + ':' +
    this.getUTCMinutes().toPaddedString(2) + ':' +
    this.getUTCSeconds().toPaddedString(2) + 'Z"';
};

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) { }
    }

    return returnValue;
  }
};

RegExp.prototype.match = RegExp.prototype.test;

RegExp.escape = function(str) {
  return String(str).replace(/([.*+?^=!:{}$()|[\]\/\\])/g, '\\$1');
};

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create({
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  execute: function() {
    this.callback(this);
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.execute();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
});
Object.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  },
  specialChar: {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  }
});

Object.extend(String.prototype, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(replacement);

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = Object.isUndefined(count) ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return String(this);
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = Object.isUndefined(truncation) ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : String(this);
  },

  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },

  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

  escapeHTML: function() {
    var self = arguments.callee;
    self.text.data = this;
    return self.div.innerHTML;
  },

  unescapeHTML: function() {
    var div = new Element('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  },

  toQueryParams: function(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return { };

    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  },

  toJSON: function() {
    return this.inspect(true);
  },

  unfilterJSON: function(filter) {
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
  },

  isJSON: function() {
    var str = this;
    if (str.blank()) return false;
    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
  },

  evalJSON: function(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) > -1;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return /^\s*$/.test(this);
  },

  interpolate: function(object, pattern) {
    return new Template(this, pattern).evaluate(object);
  }
});

if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (Object.isFunction(replacement)) return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
};

String.prototype.parseQuery = String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML, {
  div:  document.createElement('div'),
  text: document.createTextNode('')
});

String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);

var Template = Class.create({
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    if (Object.isFunction(object.toTemplateReplacements))
      object = object.toTemplateReplacements();

    return this.template.gsub(this.pattern, function(match) {
      if (object == null) return '';

      var before = match[1] || '';
      if (before == '\\') return match[2];

      var ctx = object, expr = match[3];
      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
      match = pattern.exec(expr);
      if (match == null) return before;

      while (match != null) {
        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
        ctx = ctx[comp];
        if (null == ctx || '' == match[3]) break;
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
        match = pattern.exec(expr);
      }

      return before + String.interpret(ctx);
    });
  }
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;

var $break = { };

var Enumerable = {
  each: function(iterator, context) {
    var index = 0;
    try {
      this._each(function(value) {
        iterator.call(context, value, index++);
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator, context) {
    var index = -number, slices = [], array = this.toArray();
    if (number < 1) return array;
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.collect(iterator, context);
  },

  all: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result = true;
    this.each(function(value, index) {
      result = result && !!iterator.call(context, value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result = false;
    this.each(function(value, index) {
      if (result = !!iterator.call(context, value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var results = [];
    this.each(function(value, index) {
      results.push(iterator.call(context, value, index));
    });
    return results;
  },

  detect: function(iterator, context) {
    var result;
    this.each(function(value, index) {
      if (iterator.call(context, value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator, context) {
    var results = [];
    this.each(function(value, index) {
      if (iterator.call(context, value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(filter, iterator, context) {
    iterator = iterator || Prototype.K;
    var results = [];

    if (Object.isString(filter))
      filter = new RegExp(filter);

    this.each(function(value, index) {
      if (filter.match(value))
        results.push(iterator.call(context, value, index));
    });
    return results;
  },

  include: function(object) {
    if (Object.isFunction(this.indexOf))
      if (this.indexOf(object) != -1) return true;

    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

  inGroupsOf: function(number, fillWith) {
    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  },

  inject: function(memo, iterator, context) {
    this.each(function(value, index) {
      memo = iterator.call(context, memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator.call(context, value, index);
      if (result == null || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator.call(context, value, index);
      if (result == null || value < result)
        result = value;
    });
    return result;
  },

  partition: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var trues = [], falses = [];
    this.each(function(value, index) {
      (iterator.call(context, value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator, context) {
    var results = [];
    this.each(function(value, index) {
      if (!iterator.call(context, value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator, context) {
    return this.map(function(value, index) {
      return {
        value: value,
        criteria: iterator.call(context, value, index)
      };
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.map();
  },

  zip: function() {
    var iterator = Prototype.K, args = $A(arguments);
    if (Object.isFunction(args.last()))
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      return iterator(collections.pluck(index));
    });
  },

  size: function() {
    return this.toArray().length;
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
};

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  filter:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray,
  every:   Enumerable.all,
  some:    Enumerable.any
});
function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

if (Prototype.Browser.WebKit) {
  $A = function(iterable) {
    if (!iterable) return [];
    // In Safari, only use the `toArray` method if it's not a NodeList.
    // A NodeList is a function, has an function `item` property, and a numeric
    // `length` property. Adapted from Google Doctype.
    if (!(typeof iterable === 'function' && typeof iterable.length ===
        'number' && typeof iterable.item === 'function') && iterable.toArray)
      return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--) results[length] = iterable[length];
    return results;
  };
}

Array.from = $A;

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(Object.isArray(value) ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  intersect: function(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

// use native browser JS 1.6 implementation if available
if (Object.isFunction(Array.prototype.forEach))
  Array.prototype._each = Array.prototype.forEach;

if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
};

if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
  var n = this.slice(0, i).reverse().indexOf(item);
  return (n < 0) ? n : i - n - 1;
};

Array.prototype.toArray = Array.prototype.clone;

function $w(string) {
  if (!Object.isString(string)) return [];
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if (Prototype.Browser.Opera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (Object.isArray(arguments[i])) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  };
}
Object.extend(Number.prototype, {
  toColorPart: function() {
    return this.toPaddedString(2, 16);
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator, context) {
    $R(0, this, true).each(iterator, context);
    return this;
  },

  toPaddedString: function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  },

  toJSON: function() {
    return isFinite(this) ? this.toString() : 'null';
  }
});

$w('abs round ceil floor').each(function(method){
  Number.prototype[method] = Math[method].methodize();
});
function $H(object) {
  return new Hash(object);
};

var Hash = Class.create(Enumerable, (function() {

  function toQueryPair(key, value) {
    if (Object.isUndefined(value)) return key;
    return key + '=' + encodeURIComponent(String.interpret(value));
  }

  return {
    initialize: function(object) {
      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
    },

    _each: function(iterator) {
      for (var key in this._object) {
        var value = this._object[key], pair = [key, value];
        pair.key = key;
        pair.value = value;
        iterator(pair);
      }
    },

    set: function(key, value) {
      return this._object[key] = value;
    },

    get: function(key) {
      // simulating poorly supported hasOwnProperty
      if (this._object[key] !== Object.prototype[key])
        return this._object[key];
    },

    unset: function(key) {
      var value = this._object[key];
      delete this._object[key];
      return value;
    },

    toObject: function() {
      return Object.clone(this._object);
    },

    keys: function() {
      return this.pluck('key');
    },

    values: function() {
      return this.pluck('value');
    },

    index: function(value) {
      var match = this.detect(function(pair) {
        return pair.value === value;
      });
      return match && match.key;
    },

    merge: function(object) {
      return this.clone().update(object);
    },

    update: function(object) {
      return new Hash(object).inject(this, function(result, pair) {
        result.set(pair.key, pair.value);
        return result;
      });
    },

    toQueryString: function() {
      return this.inject([], function(results, pair) {
        var key = encodeURIComponent(pair.key), values = pair.value;

        if (values && typeof values == 'object') {
          if (Object.isArray(values))
            return results.concat(values.map(toQueryPair.curry(key)));
        } else results.push(toQueryPair(key, values));
        return results;
      }).join('&');
    },

    inspect: function() {
      return '#<Hash:{' + this.map(function(pair) {
        return pair.map(Object.inspect).join(': ');
      }).join(', ') + '}>';
    },

    toJSON: function() {
      return Object.toJSON(this.toObject());
    },

    clone: function() {
      return new Hash(this);
    }
  }
})());

Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
Hash.from = $H;
var ObjectRange = Class.create(Enumerable, {
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  },

  include: function(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }
});

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
};

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
};

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responder) {
    if (!this.include(responder))
      this.responders.push(responder);
  },

  unregister: function(responder) {
    this.responders = this.responders.without(responder);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (Object.isFunction(responder[callback])) {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) { }
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate:   function() { Ajax.activeRequestCount++ },
  onComplete: function() { Ajax.activeRequestCount-- }
});

Ajax.Base = Class.create({
  initialize: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   '',
      evalJSON:     true,
      evalJS:       true
    };
    Object.extend(this.options, options || { });

    this.options.method = this.options.method.toLowerCase();

    if (Object.isString(this.options.parameters))
      this.options.parameters = this.options.parameters.toQueryParams();
    else if (Object.isHash(this.options.parameters))
      this.options.parameters = this.options.parameters.toObject();
  }
});

Ajax.Request = Class.create(Ajax.Base, {
  _complete: false,

  initialize: function($super, url, options) {
    $super(options);
    this.transport = Ajax.getTransport();
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.clone(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    this.parameters = params;

    if (params = Object.toQueryString(params)) {
      // when GET, append parameters to URL
      if (this.method == 'get')
        this.url += (this.url.include('?') ? '&' : '?') + params;
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        params += '&_=';
    }

    try {
      var response = new Ajax.Response(this);
      if (this.options.onCreate) this.options.onCreate(response);
      Ajax.Responders.dispatch('onCreate', this, response);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    // user-defined headers
    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (Object.isFunction(extras.push))
        for (var i = 0, length = extras.length; i < length; i += 2)
          headers[extras[i]] = extras[i+1];
      else
        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
    }

    for (var name in headers)
      this.transport.setRequestHeader(name, headers[name]);
  },

  success: function() {
    var status = this.getStatus();
    return !status || (status >= 200 && status < 300);
  },

  getStatus: function() {
    try {
      return this.transport.status || 0;
    } catch (e) { return 0 }
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + response.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(response, response.headerJSON);
      } catch (e) {
        this.dispatchException(e);
      }

      var contentType = response.getHeader('Content-type');
      if (this.options.evalJS == 'force'
          || (this.options.evalJS && this.isSameOrigin() && contentType
          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
        this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      // avoid memory leak in MSIE: clean up
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  isSameOrigin: function() {
    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
      protocol: location.protocol,
      domain: document.domain,
      port: location.port ? ':' + location.port : ''
    }));
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name) || null;
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval((this.transport.responseText || '').unfilterJSON());
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Response = Class.create({
  initialize: function(request){
    this.request = request;
    var transport  = this.transport  = request.transport,
        readyState = this.readyState = transport.readyState;

    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
      this.status       = this.getStatus();
      this.statusText   = this.getStatusText();
      this.responseText = String.interpret(transport.responseText);
      this.headerJSON   = this._getHeaderJSON();
    }

    if(readyState == 4) {
      var xml = transport.responseXML;
      this.responseXML  = Object.isUndefined(xml) ? null : xml;
      this.responseJSON = this._getResponseJSON();
    }
  },

  status:      0,
  statusText: '',

  getStatus: Ajax.Request.prototype.getStatus,

  getStatusText: function() {
    try {
      return this.transport.statusText || '';
    } catch (e) { return '' }
  },

  getHeader: Ajax.Request.prototype.getHeader,

  getAllHeaders: function() {
    try {
      return this.getAllResponseHeaders();
    } catch (e) { return null }
  },

  getResponseHeader: function(name) {
    return this.transport.getResponseHeader(name);
  },

  getAllResponseHeaders: function() {
    return this.transport.getAllResponseHeaders();
  },

  _getHeaderJSON: function() {
    var json = this.getHeader('X-JSON');
    if (!json) return null;
    json = decodeURIComponent(escape(json));
    try {
      return json.evalJSON(this.request.options.sanitizeJSON ||
        !this.request.isSameOrigin());
    } catch (e) {
      this.request.dispatchException(e);
    }
  },

  _getResponseJSON: function() {
    var options = this.request.options;
    if (!options.evalJSON || (options.evalJSON != 'force' &&
      !(this.getHeader('Content-type') || '').include('application/json')) ||
        this.responseText.blank())
          return null;
    try {
      return this.responseText.evalJSON(options.sanitizeJSON ||
        !this.request.isSameOrigin());
    } catch (e) {
      this.request.dispatchException(e);
    }
  }
});

Ajax.Updater = Class.create(Ajax.Request, {
  initialize: function($super, container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    };

    options = Object.clone(options);
    var onComplete = options.onComplete;
    options.onComplete = (function(response, json) {
      this.updateContent(response.responseText);
      if (Object.isFunction(onComplete)) onComplete(response, json);
    }).bind(this);

    $super(url, options);
  },

  updateContent: function(responseText) {
    var receiver = this.container[this.success() ? 'success' : 'failure'],
        options = this.options;

    if (!options.evalScripts) responseText = responseText.stripScripts();

    if (receiver = $(receiver)) {
      if (options.insertion) {
        if (Object.isString(options.insertion)) {
          var insertion = { }; insertion[options.insertion] = responseText;
          receiver.insert(insertion);
        }
        else options.insertion(receiver, responseText);
      }
      else receiver.update(responseText);
    }
  }
});

Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
  initialize: function($super, container, url, options) {
    $super(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = { };
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.options.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(response) {
    if (this.options.decay) {
      this.decay = (response.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = response.responseText;
    }
    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});
function $(element) {
  if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i]));
    return elements;
  }
  if (Object.isString(element))
    element = document.getElementById(element);
  return Element.extend(element);
}

if (Prototype.BrowserFeatures.XPath) {
  document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) || document,
      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
      results.push(Element.extend(query.snapshotItem(i)));
    return results;
  };
}

/*--------------------------------------------------------------------------*/

if (!window.Node) var Node = { };

if (!Node.ELEMENT_NODE) {
  // DOM level 2 ECMAScript Language Binding
  Object.extend(Node, {
    ELEMENT_NODE: 1,
    ATTRIBUTE_NODE: 2,
    TEXT_NODE: 3,
    CDATA_SECTION_NODE: 4,
    ENTITY_REFERENCE_NODE: 5,
    ENTITY_NODE: 6,
    PROCESSING_INSTRUCTION_NODE: 7,
    COMMENT_NODE: 8,
    DOCUMENT_NODE: 9,
    DOCUMENT_TYPE_NODE: 10,
    DOCUMENT_FRAGMENT_NODE: 11,
    NOTATION_NODE: 12
  });
}

(function() {
  var element = this.Element;
  this.Element = function(tagName, attributes) {
    attributes = attributes || { };
    tagName = tagName.toLowerCase();
    var cache = Element.cache;
    if (Prototype.Browser.IE && attributes.name) {
      tagName = '<' + tagName + ' name="' + attributes.name + '">';
      delete attributes.name;
      return Element.writeAttribute(document.createElement(tagName), attributes);
    }
    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
  };
  Object.extend(this.Element, element || { });
  if (element) this.Element.prototype = element.prototype;
}).call(window);

Element.cache = { };

Element.Methods = {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function(element) {
    element = $(element);
    Element[Element.visible(element) ? 'hide' : 'show'](element);
    return element;
  },

  hide: function(element) {
    element = $(element);
    element.style.display = 'none';
    return element;
  },

  show: function(element) {
    element = $(element);
    element.style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);
    content = Object.toHTML(content);
    element.innerHTML = content.stripScripts();
    content.evalScripts.bind(content).defer();
    return element;
  },

  replace: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    else if (!Object.isElement(content)) {
      content = Object.toHTML(content);
      var range = element.ownerDocument.createRange();
      range.selectNode(element);
      content.evalScripts.bind(content).defer();
      content = range.createContextualFragment(content.stripScripts());
    }
    element.parentNode.replaceChild(content, element);
    return element;
  },

  insert: function(element, insertions) {
    element = $(element);

    if (Object.isString(insertions) || Object.isNumber(insertions) ||
        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
          insertions = {bottom:insertions};

    var content, insert, tagName, childNodes;

    for (var position in insertions) {
      content  = insertions[position];
      position = position.toLowerCase();
      insert = Element._insertionTranslations[position];

      if (content && content.toElement) content = content.toElement();
      if (Object.isElement(content)) {
        insert(element, content);
        continue;
      }

      content = Object.toHTML(content);

      tagName = ((position == 'before' || position == 'after')
        ? element.parentNode : element).tagName.toUpperCase();

      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());

      if (position == 'top' || position == 'after') childNodes.reverse();
      childNodes.each(insert.curry(element));

      content.evalScripts.bind(content).defer();
    }

    return element;
  },

  wrap: function(element, wrapper, attributes) {
    element = $(element);
    if (Object.isElement(wrapper))
      $(wrapper).writeAttribute(attributes || { });
    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
    else wrapper = new Element('div', wrapper);
    if (element.parentNode)
      element.parentNode.replaceChild(wrapper, element);
    wrapper.appendChild(element);
    return wrapper;
  },

  inspect: function(element) {
    element = $(element);
    var result = '<' + element.tagName.toLowerCase();
    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
      var property = pair.first(), attribute = pair.last();
      var value = (element[property] || '').toString();
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
    });
    return result + '>';
  },

  recursivelyCollect: function(element, property) {
    element = $(element);
    var elements = [];
    while (element = element[property])
      if (element.nodeType == 1)
        elements.push(Element.extend(element));
    return elements;
  },

  ancestors: function(element) {
    return $(element).recursivelyCollect('parentNode');
  },

  descendants: function(element) {
    return $(element).select("*");
  },

  firstDescendant: function(element) {
    element = $(element).firstChild;
    while (element && element.nodeType != 1) element = element.nextSibling;
    return $(element);
  },

  immediateDescendants: function(element) {
    if (!(element = $(element).firstChild)) return [];
    while (element && element.nodeType != 1) element = element.nextSibling;
    if (element) return [element].concat($(element).nextSiblings());
    return [];
  },

  previousSiblings: function(element) {
    return $(element).recursivelyCollect('previousSibling');
  },

  nextSiblings: function(element) {
    return $(element).recursivelyCollect('nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return element.previousSiblings().reverse().concat(element.nextSiblings());
  },

  match: function(element, selector) {
    if (Object.isString(selector))
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(element.parentNode);
    var ancestors = element.ancestors();
    return Object.isNumber(expression) ? ancestors[expression] :
      Selector.findElement(ancestors, expression, index);
  },

  down: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return element.firstDescendant();
    return Object.isNumber(expression) ? element.descendants()[expression] :
      Element.select(element, expression)[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    var previousSiblings = element.previousSiblings();
    return Object.isNumber(expression) ? previousSiblings[expression] :
      Selector.findElement(previousSiblings, expression, index);
  },

  next: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
    var nextSiblings = element.nextSiblings();
    return Object.isNumber(expression) ? nextSiblings[expression] :
      Selector.findElement(nextSiblings, expression, index);
  },

  select: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element, args);
  },

  adjacent: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element.parentNode, args).without(element);
  },

  identify: function(element) {
    element = $(element);
    var id = element.readAttribute('id'), self = arguments.callee;
    if (id) return id;
    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
    element.writeAttribute('id', id);
    return id;
  },

  readAttribute: function(element, name) {
    element = $(element);
    if (Prototype.Browser.IE) {
      var t = Element._attributeTranslations.read;
      if (t.values[name]) return t.values[name](element, name);
      if (t.names[name]) name = t.names[name];
      if (name.include(':')) {
        return (!element.attributes || !element.attributes[name]) ? null :
         element.attributes[name].value;
      }
    }
    return element.getAttribute(name);
  },

  writeAttribute: function(element, name, value) {
    element = $(element);
    var attributes = { }, t = Element._attributeTranslations.write;

    if (typeof name == 'object') attributes = name;
    else attributes[name] = Object.isUndefined(value) ? true : value;

    for (var attr in attributes) {
      name = t.names[attr] || attr;
      value = attributes[attr];
      if (t.values[attr]) name = t.values[attr](element, value);
      if (value === false || value === null)
        element.removeAttribute(name);
      else if (value === true)
        element.setAttribute(name, name);
      else element.setAttribute(name, value);
    }
    return element;
  },

  getHeight: function(element) {
    return $(element).getDimensions().height;
  },

  getWidth: function(element) {
    return $(element).getDimensions().width;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    var elementClassName = element.className;
    return (elementClassName.length > 0 && (elementClassName == className ||
      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    if (!element.hasClassName(className))
      element.className += (element.className ? ' ' : '') + className;
    return element;
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    element.className = element.className.replace(
      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
    return element;
  },

  toggleClassName: function(element, className) {
    if (!(element = $(element))) return;
    return element[element.hasClassName(className) ?
      'removeClassName' : 'addClassName'](className);
  },

  // removes whitespace-only text node children
  cleanWhitespace: function(element) {
    element = $(element);
    var node = element.firstChild;
    while (node) {
      var nextNode = node.nextSibling;
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        element.removeChild(node);
      node = nextNode;
    }
    return element;
  },

  empty: function(element) {
    return $(element).innerHTML.blank();
  },

  descendantOf: function(element, ancestor) {
    element = $(element), ancestor = $(ancestor);

    if (element.compareDocumentPosition)
      return (element.compareDocumentPosition(ancestor) & 8) === 8;

    if (ancestor.contains)
      return ancestor.contains(element) && ancestor !== element;

    while (element = element.parentNode)
      if (element == ancestor) return true;

    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = element.cumulativeOffset();
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    style = style == 'float' ? 'cssFloat' : style.camelize();
    var value = element.style[style];
    if (!value || value == 'auto') {
      var css = document.defaultView.getComputedStyle(element, null);
      value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
    return value == 'auto' ? null : value;
  },

  getOpacity: function(element) {
    return $(element).getStyle('opacity');
  },

  setStyle: function(element, styles) {
    element = $(element);
    var elementStyle = element.style, match;
    if (Object.isString(styles)) {
      element.style.cssText += ';' + styles;
      return styles.include('opacity') ?
        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
    }
    for (var property in styles)
      if (property == 'opacity') element.setOpacity(styles[property]);
      else
        elementStyle[(property == 'float' || property == 'cssFloat') ?
          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
            property] = styles[property];

    return element;
  },

  setOpacity: function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
    return element;
  },

  getDimensions: function(element) {
    element = $(element);
    var display = element.getStyle('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (Prototype.Browser.Opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
    if (element._overflow !== 'hidden')
      element.style.overflow = 'hidden';
    return element;
  },

  undoClipping: function(element) {
    element = $(element);
    if (!element._overflow) return element;
    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
    element._overflow = null;
    return element;
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        if (element.tagName.toUpperCase() == 'BODY') break;
        var p = Element.getStyle(element, 'position');
        if (p !== 'static') break;
      }
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  absolutize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'absolute') return element;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    var offsets = element.positionedOffset();
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.width  = width + 'px';
    element.style.height = height + 'px';
    return element;
  },

  relativize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'relative') return element;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
    return element;
  },

  cumulativeScrollOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  getOffsetParent: function(element) {
    if (element.offsetParent) return $(element.offsetParent);
    if (element == document.body) return $(element);

    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return $(element);

    return $(document.body);
  },

  viewportOffset: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent == document.body &&
        Element.getStyle(element, 'position') == 'absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
        valueT -= element.scrollTop  || 0;
        valueL -= element.scrollLeft || 0;
      }
    } while (element = element.parentNode);

    return Element._returnOffset(valueL, valueT);
  },

  clonePosition: function(element, source) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || { });

    // find page position of source
    source = $(source);
    var p = source.viewportOffset();

    // find coordinate system to use
    element = $(element);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(element, 'position') == 'absolute') {
      parent = element.getOffsetParent();
      delta = parent.viewportOffset();
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
    return element;
  }
};

Element.Methods.identify.counter = 1;

Object.extend(Element.Methods, {
  getElementsBySelector: Element.Methods.select,
  childElements: Element.Methods.immediateDescendants
});

Element._attributeTranslations = {
  write: {
    names: {
      className: 'class',
      htmlFor:   'for'
    },
    values: { }
  }
};

if (Prototype.Browser.Opera) {
  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
    function(proceed, element, style) {
      switch (style) {
        case 'left': case 'top': case 'right': case 'bottom':
          if (proceed(element, 'position') === 'static') return null;
        case 'height': case 'width':
          // returns '0px' for hidden elements; we want it to return null
          if (!Element.visible(element)) return null;

          // returns the border-box dimensions rather than the content-box
          // dimensions, so we subtract padding and borders from the value
          var dim = parseInt(proceed(element, style), 10);

          if (dim !== element['offset' + style.capitalize()])
            return dim + 'px';

          var properties;
          if (style === 'height') {
            properties = ['border-top-width', 'padding-top',
             'padding-bottom', 'border-bottom-width'];
          }
          else {
            properties = ['border-left-width', 'padding-left',
             'padding-right', 'border-right-width'];
          }
          return properties.inject(dim, function(memo, property) {
            var val = proceed(element, property);
            return val === null ? memo : memo - parseInt(val, 10);
          }) + 'px';
        default: return proceed(element, style);
      }
    }
  );

  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
    function(proceed, element, attribute) {
      if (attribute === 'title') return element.title;
      return proceed(element, attribute);
    }
  );
}

else if (Prototype.Browser.IE) {
  // IE doesn't report offsets correctly for static elements, so we change them
  // to "relative" to get the values, then change them back.
  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
    function(proceed, element) {
      element = $(element);
      // IE throws an error if element is not in document
      try { element.offsetParent }
      catch(e) { return $(document.body) }
      var position = element.getStyle('position');
      if (position !== 'static') return proceed(element);
      element.setStyle({ position: 'relative' });
      var value = proceed(element);
      element.setStyle({ position: position });
      return value;
    }
  );

  $w('positionedOffset viewportOffset').each(function(method) {
    Element.Methods[method] = Element.Methods[method].wrap(
      function(proceed, element) {
        element = $(element);
        try { element.offsetParent }
        catch(e) { return Element._returnOffset(0,0) }
        var position = element.getStyle('position');
        if (position !== 'static') return proceed(element);
        // Trigger hasLayout on the offset parent so that IE6 reports
        // accurate offsetTop and offsetLeft values for position: fixed.
        var offsetParent = element.getOffsetParent();
        if (offsetParent && offsetParent.getStyle('position') === 'fixed')
          offsetParent.setStyle({ zoom: 1 });
        element.setStyle({ position: 'relative' });
        var value = proceed(element);
        element.setStyle({ position: position });
        return value;
      }
    );
  });

  Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
    function(proceed, element) {
      try { element.offsetParent }
      catch(e) { return Element._returnOffset(0,0) }
      return proceed(element);
    }
  );

  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset' + style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    function stripAlpha(filter){
      return filter.replace(/alpha\([^\)]*\)/gi,'');
    }
    element = $(element);
    var currentStyle = element.currentStyle;
    if ((currentStyle && !currentStyle.hasLayout) ||
      (!currentStyle && element.style.zoom == 'normal'))
        element.style.zoom = 1;

    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      (filter = stripAlpha(filter)) ?
        style.filter = filter : style.removeAttribute('filter');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  Element._attributeTranslations = {
    read: {
      names: {
        'class': 'className',
        'for':   'htmlFor'
      },
      values: {
        _getAttr: function(element, attribute) {
          return element.getAttribute(attribute, 2);
        },
        _getAttrNode: function(element, attribute) {
          var node = element.getAttributeNode(attribute);
          return node ? node.value : "";
        },
        _getEv: function(element, attribute) {
          attribute = element.getAttribute(attribute);
          return attribute ? attribute.toString().slice(23, -2) : null;
        },
        _flag: function(element, attribute) {
          return $(element).hasAttribute(attribute) ? attribute : null;
        },
        style: function(element) {
          return element.style.cssText.toLowerCase();
        },
        title: function(element) {
          return element.title;
        }
      }
    }
  };

  Element._attributeTranslations.write = {
    names: Object.extend({
      cellpadding: 'cellPadding',
      cellspacing: 'cellSpacing'
    }, Element._attributeTranslations.read.names),
    values: {
      checked: function(element, value) {
        element.checked = !!value;
      },

      style: function(element, value) {
        element.style.cssText = value ? value : '';
      }
    }
  };

  Element._attributeTranslations.has = {};

  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
  });

  (function(v) {
    Object.extend(v, {
      href:        v._getAttr,
      src:         v._getAttr,
      type:        v._getAttr,
      action:      v._getAttrNode,
      disabled:    v._flag,
      checked:     v._flag,
      readonly:    v._flag,
      multiple:    v._flag,
      onload:      v._getEv,
      onunload:    v._getEv,
      onclick:     v._getEv,
      ondblclick:  v._getEv,
      onmousedown: v._getEv,
      onmouseup:   v._getEv,
      onmouseover: v._getEv,
      onmousemove: v._getEv,
      onmouseout:  v._getEv,
      onfocus:     v._getEv,
      onblur:      v._getEv,
      onkeypress:  v._getEv,
      onkeydown:   v._getEv,
      onkeyup:     v._getEv,
      onsubmit:    v._getEv,
      onreset:     v._getEv,
      onselect:    v._getEv,
      onchange:    v._getEv
    });
  })(Element._attributeTranslations.read.values);
}

else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}

else if (Prototype.Browser.WebKit) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;

    if (value == 1)
      if(element.tagName.toUpperCase() == 'IMG' && element.width) {
        element.width++; element.width--;
      } else try {
        var n = document.createTextNode(' ');
        element.appendChild(n);
        element.removeChild(n);
      } catch (e) { }

    return element;
  };

  // Safari returns margins on body which is incorrect if the child is absolutely
  // positioned.  For performance reasons, redefine Element#cumulativeOffset for
  // KHTML/WebKit only.
  Element.Methods.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return Element._returnOffset(valueL, valueT);
  };
}

if (Prototype.Browser.IE || Prototype.Browser.Opera) {
  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
  Element.Methods.update = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);

    content = Object.toHTML(content);
    var tagName = element.tagName.toUpperCase();

    if (tagName in Element._insertionTranslations.tags) {
      $A(element.childNodes).each(function(node) { element.removeChild(node) });
      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
        .each(function(node) { element.appendChild(node) });
    }
    else element.innerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

if ('outerHTML' in document.createElement('div')) {
  Element.Methods.replace = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) {
      element.parentNode.replaceChild(content, element);
      return element;
    }

    content = Object.toHTML(content);
    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();

    if (Element._insertionTranslations.tags[tagName]) {
      var nextSibling = element.next();
      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
      parent.removeChild(element);
      if (nextSibling)
        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
      else
        fragments.each(function(node) { parent.appendChild(node) });
    }
    else element.outerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

Element._returnOffset = function(l, t) {
  var result = [l, t];
  result.left = l;
  result.top = t;
  return result;
};

Element._getContentFromAnonymousElement = function(tagName, html) {
  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
  if (t) {
    div.innerHTML = t[0] + html + t[1];
    t[2].times(function() { div = div.firstChild });
  } else div.innerHTML = html;
  return $A(div.childNodes);
};

Element._insertionTranslations = {
  before: function(element, node) {
    element.parentNode.insertBefore(node, element);
  },
  top: function(element, node) {
    element.insertBefore(node, element.firstChild);
  },
  bottom: function(element, node) {
    element.appendChild(node);
  },
  after: function(element, node) {
    element.parentNode.insertBefore(node, element.nextSibling);
  },
  tags: {
    TABLE:  ['<table>',                '</table>',                   1],
    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
    SELECT: ['<select>',               '</select>',                  1]
  }
};

(function() {
  Object.extend(this.tags, {
    THEAD: this.tags.TBODY,
    TFOOT: this.tags.TBODY,
    TH:    this.tags.TD
  });
}).call(Element._insertionTranslations);

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    attribute = Element._attributeTranslations.has[attribute] || attribute;
    var node = $(element).getAttributeNode(attribute);
    return !!(node && node.specified);
  }
};

Element.Methods.ByTag = { };

Object.extend(Element, Element.Methods);

if (!Prototype.BrowserFeatures.ElementExtensions &&
    document.createElement('div')['__proto__']) {
  window.HTMLElement = { };
  window.HTMLElement.prototype = document.createElement('div')['__proto__'];
  Prototype.BrowserFeatures.ElementExtensions = true;
}

Element.extend = (function() {
  if (Prototype.BrowserFeatures.SpecificElementExtensions)
    return Prototype.K;

  var Methods = { }, ByTag = Element.Methods.ByTag;

  var extend = Object.extend(function(element) {
    if (!element || element._extendedByPrototype ||
        element.nodeType != 1 || element == window) return element;

    var methods = Object.clone(Methods),
      tagName = element.tagName.toUpperCase(), property, value;

    // extend methods for specific tags
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);

    for (property in methods) {
      value = methods[property];
      if (Object.isFunction(value) && !(property in element))
        element[property] = value.methodize();
    }

    element._extendedByPrototype = Prototype.emptyFunction;
    return element;

  }, {
    refresh: function() {
      // extend methods for all tags (Safari doesn't need this)
      if (!Prototype.BrowserFeatures.ElementExtensions) {
        Object.extend(Methods, Element.Methods);
        Object.extend(Methods, Element.Methods.Simulated);
      }
    }
  });

  extend.refresh();
  return extend;
})();

Element.hasAttribute = function(element, attribute) {
  if (element.hasAttribute) return element.hasAttribute(attribute);
  return Element.Methods.Simulated.hasAttribute(element, attribute);
};

Element.addMethods = function(methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || { });
  else {
    if (Object.isArray(tagName)) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = { };
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    for (var property in methods) {
      var value = methods[property];
      if (!Object.isFunction(value)) continue;
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = value.methodize();
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    window[klass] = { };
    window[klass].prototype = document.createElement(tagName)['__proto__'];
    return window[klass];
  }

  if (F.ElementExtensions) {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (Object.isUndefined(klass)) continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;

  if (Element.extend.refresh) Element.extend.refresh();
  Element.cache = { };
};

document.viewport = {
  getDimensions: function() {
    var dimensions = { }, B = Prototype.Browser;
    $w('width height').each(function(d) {
      var D = d.capitalize();
      if (B.WebKit && !document.evaluate) {
        // Safari <3.0 needs self.innerWidth/Height
        dimensions[d] = self['inner' + D];
      } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
        // Opera <9.5 needs document.body.clientWidth/Height
        dimensions[d] = document.body['client' + D]
      } else {
        dimensions[d] = document.documentElement['client' + D];
      }
    });
    return dimensions;
  },

  getWidth: function() {
    return this.getDimensions().width;
  },

  getHeight: function() {
    return this.getDimensions().height;
  },

  getScrollOffsets: function() {
    return Element._returnOffset(
      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
  }
};
/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
 * license.  Please see http://www.yui-ext.com/ for more information. */

var Selector = Class.create({
  initialize: function(expression) {
    this.expression = expression.strip();

    if (this.shouldUseSelectorsAPI()) {
      this.mode = 'selectorsAPI';
    } else if (this.shouldUseXPath()) {
      this.mode = 'xpath';
      this.compileXPathMatcher();
    } else {
      this.mode = "normal";
      this.compileMatcher();
    }

  },

  shouldUseXPath: function() {
    if (!Prototype.BrowserFeatures.XPath) return false;

    var e = this.expression;

    // Safari 3 chokes on :*-of-type and :empty
    if (Prototype.Browser.WebKit &&
     (e.include("-of-type") || e.include(":empty")))
      return false;

    // XPath can't do namespaced attributes, nor can it read
    // the "checked" property from DOM nodes
    // PW - tweaked for local load
    if ((/(\\[\[\w-]*?:|:checked)/).test(e))
      return false;

    return true;
  },

  shouldUseSelectorsAPI: function() {
    if (!Prototype.BrowserFeatures.SelectorsAPI) return false;

    if (!Selector._div) Selector._div = new Element('div');

    // Make sure the browser treats the selector as valid. Test on an
    // isolated element to minimize cost of this check.
    try {
      Selector._div.querySelector(this.expression);
    } catch(e) {
      return false;
    }

    return true;
  },

  compileMatcher: function() {
    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m;

    if (Selector._cache[e]) {
      this.matcher = Selector._cache[e];
      return;
    }

    this.matcher = ["this.matcher = function(root) {",
                    "var r = root, h = Selector.handlers, c = false, n;"];

    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
            new Template(c[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.matcher.push("return h.unique(n);\n}");
    eval(this.matcher.join('\n'));
    Selector._cache[this.expression] = this.matcher;
  },

  compileXPathMatcher: function() {
    var e = this.expression, ps = Selector.patterns,
        x = Selector.xpath, le, m;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        if (m = e.match(ps[i])) {
          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
            new Template(x[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.xpath = this.matcher.join('');
    Selector._cache[this.expression] = this.xpath;
  },

  findElements: function(root) {
    root = root || document;
    var e = this.expression, results;

    switch (this.mode) {
      case 'selectorsAPI':
        // querySelectorAll queries document-wide, then filters to descendants
        // of the context element. That's not what we want.
        // Add an explicit context to the selector if necessary.
        if (root !== document) {
          var oldId = root.id, id = $(root).identify();
          e = "#" + id + " " + e;
        }

        results = $A(root.querySelectorAll(e)).map(Element.extend);
        root.id = oldId;

        return results;
      case 'xpath':
        return document._getElementsByXPath(this.xpath, root);
      default:
       return this.matcher(root);
    }
  },

  match: function(element) {
    this.tokens = [];

    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
    var le, p, m;

    while (e && le !== e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          // use the Selector.assertions methods unless the selector
          // is too complex.
          if (as[i]) {
            this.tokens.push([i, Object.clone(m)]);
            e = e.replace(m[0], '');
          } else {
            // reluctantly do a document-wide search
            // and look for a match in the array
            return this.findElements(document).include(element);
          }
        }
      }
    }

    var match = true, name, matches;
    for (var i = 0, token; token = this.tokens[i]; i++) {
      name = token[0], matches = token[1];
      if (!Selector.assertions[name](element, matches)) {
        match = false; break;
      }
    }

    return match;
  },

  toString: function() {
    return this.expression;
  },

  inspect: function() {
    return "#<Selector:" + this.expression.inspect() + ">";
  }
});

Object.extend(Selector, {
  _cache: { },

  xpath: {
    descendant:   "//*",
    child:        "/*",
    adjacent:     "/following-sibling::*[1]",
    laterSibling: '/following-sibling::*',
    tagName:      function(m) {
      if (m[1] == '*') return '';
      return "[local-name()='" + m[1].toLowerCase() +
             "' or local-name()='" + m[1].toUpperCase() + "']";
    },
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    id:           "[@id='#{1}']",
    attrPresence: function(m) {
      m[1] = m[1].toLowerCase();
      return new Template("[@#{1}]").evaluate(m);
    },
    attr: function(m) {
      m[1] = m[1].toLowerCase();
      m[3] = m[5] || m[6];
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
    },
    pseudo: function(m) {
      var h = Selector.xpath.pseudos[m[1]];
      if (!h) return '';
      if (Object.isFunction(h)) return h(m);
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
    },
    operators: {
      '=':  "[@#{1}='#{3}']",
      '!=': "[@#{1}!='#{3}']",
      '^=': "[starts-with(@#{1}, '#{3}')]",
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
      '*=': "[contains(@#{1}, '#{3}')]",
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
    },
    pseudos: {
      'first-child': '[not(preceding-sibling::*)]',
      'last-child':  '[not(following-sibling::*)]',
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
      'empty':       "[count(*) = 0 and (count(text()) = 0)]",
      'checked':     "[@checked]",
      'disabled':    "[(@disabled) and (@type!='hidden')]",
      'enabled':     "[not(@disabled) and (@type!='hidden')]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, v;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i in p) {
            if (m = e.match(p[i])) {
              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
              e = e.replace(m[0], '');
              break;
            }
          }
        }
        return "[not(" + exclusion.join(" and ") + ")]";
      },
      'nth-child':      function(m) {
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
      },
      'nth-last-child': function(m) {
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
      },
      'nth-of-type':    function(m) {
        return Selector.xpath.pseudos.nth("position() ", m);
      },
      'nth-last-of-type': function(m) {
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
      },
      'first-of-type':  function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
      },
      'last-of-type':   function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
      },
      'only-of-type':   function(m) {
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
      },
      nth: function(fragment, m) {
        var mm, formula = m[6], predicate;
        if (formula == 'even') formula = '2n+0';
        if (formula == 'odd')  formula = '2n+1';
        if (mm = formula.match(/^(\d+)$/)) // digit only
          return '[' + fragment + "= " + mm[1] + ']';
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
          if (mm[1] == "-") mm[1] = -1;
          var a = mm[1] ? Number(mm[1]) : 1;
          var b = mm[2] ? Number(mm[2]) : 0;
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
          "((#{fragment} - #{b}) div #{a} >= 0)]";
          return new Template(predicate).evaluate({
            fragment: fragment, a: a, b: b });
        }
      }
    }
  },

  criteria: {
    tagName:      'n = h.tagName(n, r, "#{1}", c);      c = false;',
    className:    'n = h.className(n, r, "#{1}", c);    c = false;',
    id:           'n = h.id(n, r, "#{1}", c);           c = false;',
    attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
    attr: function(m) {
      m[3] = (m[5] || m[6]);
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
    },
    pseudo: function(m) {
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
    },
    descendant:   'c = "descendant";',
    child:        'c = "child";',
    adjacent:     'c = "adjacent";',
    laterSibling: 'c = "laterSibling";'
  },

  patterns: {
    // combinators must be listed first
    // (and descendant needs to be last combinator)
    laterSibling: /^\s*~\s*/,
    child:        /^\s*>\s*/,
    adjacent:     /^\s*\+\s*/,
    descendant:   /^\s/,

    // selectors follow
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    id:           /^#([\w\-\*]+)(\b|$)/,
    className:    /^\.([\w\-\*]+)(\b|$)/,
    pseudo:
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
    attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^]]*?)))?\]/
  },

  // for Selector.match and Element#match
  assertions: {
    tagName: function(element, matches) {
      return matches[1].toUpperCase() == element.tagName.toUpperCase();
    },

    className: function(element, matches) {
      return Element.hasClassName(element, matches[1]);
    },

    id: function(element, matches) {
      return element.id === matches[1];
    },

    attrPresence: function(element, matches) {
      return Element.hasAttribute(element, matches[1]);
    },

    attr: function(element, matches) {
      var nodeValue = Element.readAttribute(element, matches[1]);
      return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
    }
  },

  handlers: {
    // UTILITY FUNCTIONS
    // joins two collections
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    // marks an array of nodes for counting
    mark: function(nodes) {
      var _true = Prototype.emptyFunction;
      for (var i = 0, node; node = nodes[i]; i++)
        node._countedByPrototype = _true;
      return nodes;
    },

    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._countedByPrototype = undefined;
      return nodes;
    },

    // mark each child node with its position (for nth calls)
    // "ofType" flag indicates whether we're indexing for nth-of-type
    // rather than nth-child
    index: function(parentNode, reverse, ofType) {
      parentNode._countedByPrototype = Prototype.emptyFunction;
      if (reverse) {
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
          var node = nodes[i];
          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
        }
      } else {
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
      }
    },

    // filters out duplicates and extends all nodes
    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (!(n = nodes[i])._countedByPrototype) {
          n._countedByPrototype = Prototype.emptyFunction;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    // COMBINATOR FUNCTIONS
    descendant: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, node.getElementsByTagName('*'));
      return results;
    },

    child: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        for (var j = 0, child; child = node.childNodes[j]; j++)
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
      }
      return results;
    },

    adjacent: function(nodes) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        var next = this.nextElementSibling(node);
        if (next) results.push(next);
      }
      return results;
    },

    laterSibling: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, Element.nextSiblings(node));
      return results;
    },

    nextElementSibling: function(node) {
      while (node = node.nextSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    previousElementSibling: function(node) {
      while (node = node.previousSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    // TOKEN FUNCTIONS
    tagName: function(nodes, root, tagName, combinator) {
      var uTagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          // fastlane for ordinary descendant combinators
          if (combinator == "descendant") {
            for (var i = 0, node; node = nodes[i]; i++)
              h.concat(results, node.getElementsByTagName(tagName));
            return results;
          } else nodes = this[combinator](nodes);
          if (tagName == "*") return nodes;
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName.toUpperCase() === uTagName) results.push(node);
        return results;
      } else return root.getElementsByTagName(tagName);
    },

    id: function(nodes, root, id, combinator) {
      var targetNode = $(id), h = Selector.handlers;
      if (!targetNode) return [];
      if (!nodes && root == document) return [targetNode];
      if (nodes) {
        if (combinator) {
          if (combinator == 'child') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (targetNode.parentNode == node) return [targetNode];
          } else if (combinator == 'descendant') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Element.descendantOf(targetNode, node)) return [targetNode];
          } else if (combinator == 'adjacent') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Selector.handlers.previousElementSibling(targetNode) == node)
                return [targetNode];
          } else nodes = h[combinator](nodes);
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node == targetNode) return [targetNode];
        return [];
      }
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
    },

    className: function(nodes, root, className, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      return Selector.handlers.byClassName(nodes, root, className);
    },

    byClassName: function(nodes, root, className) {
      if (!nodes) nodes = Selector.handlers.descendant([root]);
      var needle = ' ' + className + ' ';
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        nodeClassName = node.className;
        if (nodeClassName.length == 0) continue;
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
          results.push(node);
      }
      return results;
    },

    attrPresence: function(nodes, root, attr, combinator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      if (nodes && combinator) nodes = this[combinator](nodes);
      var results = [];
      for (var i = 0, node; node = nodes[i]; i++)
        if (Element.hasAttribute(node, attr)) results.push(node);
      return results;
    },

    attr: function(nodes, root, attr, value, operator, combinator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      if (nodes && combinator) nodes = this[combinator](nodes);
      var handler = Selector.operators[operator], results = [];
      for (var i = 0, node; node = nodes[i]; i++) {
        var nodeValue = Element.readAttribute(node, attr);
        if (nodeValue === null) continue;
        if (handler(nodeValue, value)) results.push(node);
      }
      return results;
    },

    pseudo: function(nodes, name, value, root, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      if (!nodes) nodes = root.getElementsByTagName("*");
      return Selector.pseudos[name](nodes, value, root);
    }
  },

  pseudos: {
    'first-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.previousElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'last-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.nextElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'only-child': function(nodes, value, root) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
          results.push(node);
      return results;
    },
    'nth-child':        function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root);
    },
    'nth-last-child':   function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true);
    },
    'nth-of-type':      function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, false, true);
    },
    'nth-last-of-type': function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true, true);
    },
    'first-of-type':    function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, false, true);
    },
    'last-of-type':     function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, true, true);
    },
    'only-of-type':     function(nodes, formula, root) {
      var p = Selector.pseudos;
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
    },

    // handles the an+b logic
    getIndices: function(a, b, total) {
      if (a == 0) return b > 0 ? [b] : [];
      return $R(1, total).inject([], function(memo, i) {
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        return memo;
      });
    },

    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    nth: function(nodes, formula, root, reverse, ofType) {
      if (nodes.length == 0) return [];
      if (formula == 'even') formula = '2n+0';
      if (formula == 'odd')  formula = '2n+1';
      var h = Selector.handlers, results = [], indexed = [], m;
      h.mark(nodes);
      for (var i = 0, node; node = nodes[i]; i++) {
        if (!node.parentNode._countedByPrototype) {
          h.index(node.parentNode, reverse, ofType);
          indexed.push(node.parentNode);
        }
      }
      if (formula.match(/^\d+$/)) { // just a number
        formula = Number(formula);
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.nodeIndex == formula) results.push(node);
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        if (m[1] == "-") m[1] = -1;
        var a = m[1] ? Number(m[1]) : 1;
        var b = m[2] ? Number(m[2]) : 0;
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
          for (var j = 0; j < l; j++)
            if (node.nodeIndex == indices[j]) results.push(node);
        }
      }
      h.unmark(nodes);
      h.unmark(indexed);
      return results;
    },

    'empty': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        // IE treats comments as element nodes
        if (node.tagName == '!' || node.firstChild) continue;
        results.push(node);
      }
      return results;
    },

    'not': function(nodes, selector, root) {
      var h = Selector.handlers, selectorType, m;
      var exclusions = new Selector(selector).findElements(root);
      h.mark(exclusions);
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node._countedByPrototype) results.push(node);
      h.unmark(exclusions);
      return results;
    },

    'enabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node.disabled && (!node.type || node.type !== 'hidden'))
          results.push(node);
      return results;
    },

    'disabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.disabled) results.push(node);
      return results;
    },

    'checked': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.checked) results.push(node);
      return results;
    }
  },

  operators: {
    '=':  function(nv, v) { return nv == v; },
    '!=': function(nv, v) { return nv != v; },
    '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
    '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
    '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
    '$=': function(nv, v) { return nv.endsWith(v); },
    '*=': function(nv, v) { return nv.include(v); },
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
     '-').include('-' + (v || "").toUpperCase() + '-'); }
  },

  split: function(expression) {
    var expressions = [];
    expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
      expressions.push(m[1].strip());
    });
    return expressions;
  },

  matchElements: function(elements, expression) {
    var matches = $$(expression), h = Selector.handlers;
    h.mark(matches);
    for (var i = 0, results = [], element; element = elements[i]; i++)
      if (element._countedByPrototype) results.push(element);
    h.unmark(matches);
    return results;
  },

  findElement: function(elements, expression, index) {
    if (Object.isNumber(expression)) {
      index = expression; expression = false;
    }
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    expressions = Selector.split(expressions.join(','));
    var results = [], h = Selector.handlers;
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
      selector = new Selector(expressions[i].strip());
      h.concat(results, selector.findElements(element));
    }
    return (l > 1) ? h.unique(results) : results;
  }
});

if (Prototype.Browser.IE) {
  Object.extend(Selector.handlers, {
    // IE returns comment nodes on getElementsByTagName("*").
    // Filter them out.
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        if (node.tagName !== "!") a.push(node);
      return a;
    },

    // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node.removeAttribute('_countedByPrototype');
      return nodes;
    }
  });
}

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, options) {
    if (typeof options != 'object') options = { hash: !!options };
    else if (Object.isUndefined(options.hash)) options.hash = true;
    var key, value, submitted = false, submit = options.submit;

    var data = elements.inject({ }, function(result, element) {
      if (!element.disabled && element.name) {
        key = element.name; value = $(element).getValue();
        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
          if (key in result) {
            // a key is already present; construct an array of values
            if (!Object.isArray(result[key])) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return options.hash ? data : Object.toQueryString(data);
  }
};

Form.Methods = {
  serialize: function(form, options) {
    return Form.serializeElements(Form.getElements(form), options);
  },

  getElements: function(form) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
          elements.push(Element.extend(child));
        return elements;
      }
    );
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name) return $A(inputs).map(Element.extend);

    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) || (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('disable');
    return form;
  },

  enable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('enable');
    return form;
  },

  findFirstElement: function(form) {
    var elements = $(form).getElements().findAll(function(element) {
      return 'hidden' != element.type && !element.disabled;
    });
    var firstByIndex = elements.findAll(function(element) {
      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
    }).sortBy(function(element) { return element.tabIndex }).first();

    return firstByIndex ? firstByIndex : elements.find(function(element) {
      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  },

  request: function(form, options) {
    form = $(form), options = Object.clone(options || { });

    var params = options.parameters, action = form.readAttribute('action') || '';
    if (action.blank()) action = window.location.href;
    options.parameters = form.serialize(true);

    if (params) {
      if (Object.isString(params)) params = params.toQueryParams();
      Object.extend(options.parameters, params);
    }

    if (form.hasAttribute('method') && !options.method)
      options.method = form.method;

    return new Ajax.Request(action, options);
  }
};

/*--------------------------------------------------------------------------*/

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
};

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = { };
        pair[element.name] = value;
        return Object.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  setValue: function(element, value) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    Form.Element.Serializers[method](element, value);
    return element;
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
          !['button', 'reset', 'submit'].include(element.type)))
        element.select();
    } catch (e) { }
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.disabled = false;
    return element;
  }
};

/*--------------------------------------------------------------------------*/

var Field = Form.Element;
var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element, value) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element, value);
      default:
        return Form.Element.Serializers.textarea(element, value);
    }
  },

  inputSelector: function(element, value) {
    if (Object.isUndefined(value)) return element.checked ? element.value : null;
    else element.checked = !!value;
  },

  textarea: function(element, value) {
    if (Object.isUndefined(value)) return element.value;
    else element.value = value;
  },

  select: function(element, value) {
    if (Object.isUndefined(value))
      return this[element.type == 'select-one' ?
        'selectOne' : 'selectMany'](element);
    else {
      var opt, currentValue, single = !Object.isArray(value);
      for (var i = 0, length = element.length; i < length; i++) {
        opt = element.options[i];
        currentValue = this.optionValue(opt);
        if (single) {
          if (currentValue == value) {
            opt.selected = true;
            return;
          }
        }
        else opt.selected = value.include(currentValue);
      }
    }
  },

  selectOne: function(element) {
    var index = element.selectedIndex;
    return index >= 0 ? this.optionValue(element.options[index]) : null;
  },

  selectMany: function(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(this.optionValue(opt));
    }
    return values;
  },

  optionValue: function(opt) {
    // extend element because hasAttribute may not be native
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
  }
};

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
  initialize: function($super, element, frequency, callback) {
    $super(callback, frequency);
    this.element   = $(element);
    this.lastValue = this.getValue();
  },

  execute: function() {
    var value = this.getValue();
    if (Object.isString(this.lastValue) && Object.isString(value) ?
        this.lastValue != value : String(this.lastValue) != String(value)) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
});

Form.Element.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = Class.create({
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    Form.getElements(this.element).each(this.registerCallback, this);
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        default:
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
});

Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) var Event = { };

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_HOME:     36,
  KEY_END:      35,
  KEY_PAGEUP:   33,
  KEY_PAGEDOWN: 34,
  KEY_INSERT:   45,

  cache: { },

  relatedTarget: function(event) {
    var element;
    switch(event.type) {
      case 'mouseover': element = event.fromElement; break;
      case 'mouseout':  element = event.toElement;   break;
      default: return null;
    }
    return Element.extend(element);
  }
});

Event.Methods = (function() {
  var isButton;

  if (Prototype.Browser.IE) {
    var buttonMap = { 0: 1, 1: 4, 2: 2 };
    isButton = function(event, code) {
      return event.button == buttonMap[code];
    };

  } else if (Prototype.Browser.WebKit) {
    isButton = function(event, code) {
      switch (code) {
        case 0: return event.which == 1 && !event.metaKey;
        case 1: return event.which == 1 && event.metaKey;
        default: return false;
      }
    };

  } else {
    isButton = function(event, code) {
      return event.which ? (event.which === code + 1) : (event.button === code);
    };
  }

  return {
    isLeftClick:   function(event) { return isButton(event, 0) },
    isMiddleClick: function(event) { return isButton(event, 1) },
    isRightClick:  function(event) { return isButton(event, 2) },

    element: function(event) {
      event = Event.extend(event);

      var node          = event.target,
          type          = event.type,
          currentTarget = event.currentTarget;

      if (currentTarget && currentTarget.tagName) {
        // Firefox screws up the "click" event when moving between radio buttons
        // via arrow keys. It also screws up the "load" and "error" events on images,
        // reporting the document as the target instead of the original image.
        if (type === 'load' || type === 'error' ||
          (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
            && currentTarget.type === 'radio'))
              node = currentTarget;
      }
      if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
      return Element.extend(node);
    },

    findElement: function(event, expression) {
      var element = Event.element(event);
      if (!expression) return element;
      var elements = [element].concat(element.ancestors());
      return Selector.findElement(elements, expression, 0);
    },

    pointer: function(event) {
      var docElement = document.documentElement,
      body = document.body || { scrollLeft: 0, scrollTop: 0 };
      return {
        x: event.pageX || (event.clientX +
          (docElement.scrollLeft || body.scrollLeft) -
          (docElement.clientLeft || 0)),
        y: event.pageY || (event.clientY +
          (docElement.scrollTop || body.scrollTop) -
          (docElement.clientTop || 0))
      };
    },

    pointerX: function(event) { return Event.pointer(event).x },
    pointerY: function(event) { return Event.pointer(event).y },

    stop: function(event) {
      Event.extend(event);
      event.preventDefault();
      event.stopPropagation();
      event.stopped = true;
    }
  };
})();

Event.extend = (function() {
  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
    m[name] = Event.Methods[name].methodize();
    return m;
  });

  if (Prototype.Browser.IE) {
    Object.extend(methods, {
      stopPropagation: function() { this.cancelBubble = true },
      preventDefault:  function() { this.returnValue = false },
      inspect: function() { return "[object Event]" }
    });

    return function(event) {
      if (!event) return false;
      if (event._extendedByPrototype) return event;

      event._extendedByPrototype = Prototype.emptyFunction;
      var pointer = Event.pointer(event);
      Object.extend(event, {
        target: event.srcElement,
        relatedTarget: Event.relatedTarget(event),
        pageX:  pointer.x,
        pageY:  pointer.y
      });
      return Object.extend(event, methods);
    };

  } else {
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
    Object.extend(Event.prototype, methods);
    return Prototype.K;
  }
})();

Object.extend(Event, (function() {
  var cache = Event.cache;

  function getEventID(element) {
    if (element._prototypeEventID) return element._prototypeEventID[0];
    arguments.callee.id = arguments.callee.id || 1;
    return element._prototypeEventID = [++arguments.callee.id];
  }

  function getDOMEventName(eventName) {
    if (eventName && eventName.include(':')) return "dataavailable";
    return eventName;
  }

  function getCacheForID(id) {
    return cache[id] = cache[id] || { };
  }

  function getWrappersForEventName(id, eventName) {
    var c = getCacheForID(id);
    return c[eventName] = c[eventName] || [];
  }

  function createWrapper(element, eventName, handler) {
    var id = getEventID(element);
    var c = getWrappersForEventName(id, eventName);
    if (c.pluck("handler").include(handler)) return false;

    var wrapper = function(event) {
      if (!Event || !Event.extend ||
        (event.eventName && event.eventName != eventName))
          return false;

      Event.extend(event);
      handler.call(element, event);
    };

    wrapper.handler = handler;
    c.push(wrapper);
    return wrapper;
  }

  function findWrapper(id, eventName, handler) {
    var c = getWrappersForEventName(id, eventName);
    return c.find(function(wrapper) { return wrapper.handler == handler });
  }

  function destroyWrapper(id, eventName, handler) {
    var c = getCacheForID(id);
    if (!c[eventName]) return false;
    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
  }

  function destroyCache() {
    for (var id in cache)
      for (var eventName in cache[id])
        cache[id][eventName] = null;
  }


  // Internet Explorer needs to remove event handlers on page unload
  // in order to avoid memory leaks.
  if (window.attachEvent) {
    window.attachEvent("onunload", destroyCache);
  }

  // Safari has a dummy event handler on page unload so that it won't
  // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
  // object when page is returned to via the back button using its bfcache.
  if (Prototype.Browser.WebKit) {
    window.addEventListener('unload', Prototype.emptyFunction, false);
  }

  return {
    observe: function(element, eventName, handler) {
      element = $(element);
      var name = getDOMEventName(eventName);

      var wrapper = createWrapper(element, eventName, handler);
      if (!wrapper) return element;

      if (element.addEventListener) {
        element.addEventListener(name, wrapper, false);
      } else {
        element.attachEvent("on" + name, wrapper);
      }

      return element;
    },

    stopObserving: function(element, eventName, handler) {
      element = $(element);
      var id = getEventID(element), name = getDOMEventName(eventName);

      if (!handler && eventName) {
        getWrappersForEventName(id, eventName).each(function(wrapper) {
          element.stopObserving(eventName, wrapper.handler);
        });
        return element;

      } else if (!eventName) {
        Object.keys(getCacheForID(id)).each(function(eventName) {
          element.stopObserving(eventName);
        });
        return element;
      }

      var wrapper = findWrapper(id, eventName, handler);
      if (!wrapper) return element;

      if (element.removeEventListener) {
        element.removeEventListener(name, wrapper, false);
      } else {
        element.detachEvent("on" + name, wrapper);
      }

      destroyWrapper(id, eventName, handler);

      return element;
    },

    fire: function(element, eventName, memo) {
      element = $(element);
      if (element == document && document.createEvent && !element.dispatchEvent)
        element = document.documentElement;

      var event;
      if (document.createEvent) {
        event = document.createEvent("HTMLEvents");
        event.initEvent("dataavailable", true, true);
      } else {
        event = document.createEventObject();
        event.eventType = "ondataavailable";
      }

      event.eventName = eventName;
      event.memo = memo || { };

      if (document.createEvent) {
        element.dispatchEvent(event);
      } else {
        element.fireEvent(event.eventType, event);
      }

      return Event.extend(event);
    }
  };
})());

Object.extend(Event, Event.Methods);

Element.addMethods({
  fire:          Event.fire,
  observe:       Event.observe,
  stopObserving: Event.stopObserving
});

Object.extend(document, {
  fire:          Element.Methods.fire.methodize(),
  observe:       Element.Methods.observe.methodize(),
  stopObserving: Element.Methods.stopObserving.methodize(),
  loaded:        false
});

(function() {
  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
     Matthias Miller, Dean Edwards and John Resig. */

  var timer;

  function fireContentLoadedEvent() {
    if (document.loaded) return;
    if (timer) window.clearInterval(timer);
    document.fire("dom:loaded");
    document.loaded = true;
  }

  if (document.addEventListener) {
    if (Prototype.Browser.WebKit) {
      timer = window.setInterval(function() {
        if (/loaded|complete/.test(document.readyState))
          fireContentLoadedEvent();
      }, 0);

      Event.observe(window, "load", fireContentLoadedEvent);

    } else {
      document.addEventListener("DOMContentLoaded",
        fireContentLoadedEvent, false);
    }

  } else {
    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
    $("__onDOMContentLoaded").onreadystatechange = function() {
      if (this.readyState == "complete") {
        this.onreadystatechange = null;
        fireContentLoadedEvent();
      }
    };
  }
})();
/*------------------------------- DEPRECATED -------------------------------*/

Hash.toQueryString = Object.toQueryString;

var Toggle = { display: Element.toggle };

Element.Methods.childOf = Element.Methods.descendantOf;

var Insertion = {
  Before: function(element, content) {
    return Element.insert(element, {before:content});
  },

  Top: function(element, content) {
    return Element.insert(element, {top:content});
  },

  Bottom: function(element, content) {
    return Element.insert(element, {bottom:content});
  },

  After: function(element, content) {
    return Element.insert(element, {after:content});
  }
};

var $continue = new Error('"throw $continue" is deprecated, use "return" instead');

// This should be moved to script.aculo.us; notice the deprecated methods
// further below, that map to the newer Element methods.
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  // caches x/y coordinate pair to use with overlap
  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = Element.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = Element.cumulativeScrollOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = Element.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  // within must be called directly before
  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },

  // Deprecation layer -- use newer Element methods now (1.5.2).

  cumulativeOffset: Element.Methods.cumulativeOffset,

  positionedOffset: Element.Methods.positionedOffset,

  absolutize: function(element) {
    Position.prepare();
    return Element.absolutize(element);
  },

  relativize: function(element) {
    Position.prepare();
    return Element.relativize(element);
  },

  realOffset: Element.Methods.cumulativeScrollOffset,

  offsetParent: Element.Methods.getOffsetParent,

  page: Element.Methods.viewportOffset,

  clone: function(source, target, options) {
    options = options || { };
    return Element.clonePosition(target, source, options);
  }
};

/*--------------------------------------------------------------------------*/

if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
  function iter(name) {
    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
  }

  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
  function(element, className) {
    className = className.toString().strip();
    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
  } : function(element, className) {
    className = className.toString().strip();
    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
    if (!classNames && !className) return elements;

    var nodes = $(element).getElementsByTagName('*');
    className = ' ' + className + ' ';

    for (var i = 0, child, cn; child = nodes[i]; i++) {
      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
          (classNames && classNames.all(function(name) {
            return !name.toString().blank() && cn.include(' ' + name + ' ');
          }))))
        elements.push(Element.extend(child));
    }
    return elements;
  };

  return function(className, parentElement) {
    return $(parentElement || document.body).getElementsByClassName(className);
  };
}(Element.Methods);

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set($A(this).concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set($A(this).without(classNameToRemove).join(' '));
  },

  toString: function() {
    return $A(this).join(' ');
  }
};

Object.extend(Element.ClassNames.prototype, Enumerable);

/*--------------------------------------------------------------------------*/

Element.addMethods(); 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/Oryx/Utilities.js
AUTOCORE_SELF_CHECK.push("Oryx/Utilities.js");
//
/* ----------------------------------------------------------------

OkCupid Utilities file

	- usefulish stuff
	
This file contains general utilities used through the site

---------------------------------------------------------------- */

var Utilities = {
	
	/* Browser Functioning ------------------------------------------------------------------------ */
	
	handleEnter:function(e,f) //Needs testing
	{
		/* 
		Important: f cannot return ANYTHING.  No returns can be 
		made except the negated keyCode
		*/
		f = f || function (){};
		var Ucode=e.keyCode? e.keyCode : e.charCode;
		if (Ucode == 13){f();}
		e = (e) ? e : ((window.event) ? window.event : "");
		if (e) {return !( e.keyCode==13 || e.which==13 );}
	},
	preloadImages:function() 
	{
		var preload_arr = new Array();
		for(var i = 0; i < arguments.length; i++) {
			var preload_img = new Image();
			preload_img.src = arguments[i];
			preload_arr.push(preload_img);
		}
	},
	
	/* String functions --------------------------------------------------------------------------- */
	
	quickTrim:function(str) 
	{
        return str.replace(/(^\s+)([^\s]*)(\s+$)/, '$2');
    },
	stripBreaks:function(str) 
	{
		var res = str.replace(/\n/g," ");  	// ??
		res = res.replace(/\n/g," ");		// ??
		return res;
	},
	stripComments:function(str) 
	{
	    str = str.replace(/<!--[\w\s\/\-,]*-->/g, " ");
	    return str;
	},
    jogf:function(string,key)
    {
		// IE needs the var
        for(var item in key)
            string = string.replace("%" + item,key[item]);
        return string;
    },
    
	/* Math functions ----------------------------------------------------------------------------- */
	
	leadZero:function(n) {
		if (n < 10) n = "0" + n;
		return n;
	},
	formatBigInteger:function(integer) // Can this be simplified?
	{
	    var result = '',
	    	pattern = "###,###,###,###";

	    // cast that to a string.
	    integer = "" + integer + "";

	    integerIndex = integer.length - 1;
	    patternIndex = pattern.length - 1;

	    while ( (integerIndex >= 0) && (patternIndex >= 0) )
	    {
	        var digit = integer.charAt( integerIndex );
	        integerIndex--;

	        // Skip non-digits from the source integer (eradicate current formatting).
	        if ( (digit < '0') || (digit > '9') )  continue;

	        // Got a digit from the integer, now plug it into the pattern.
	        while ( patternIndex >= 0 )
	        {
	            var patternChar = pattern.charAt( patternIndex );
	            patternIndex--;

	            // Substitute digits for '#' chars, treat other chars literally.
	            if ( patternChar == '#' )
	            {
	                result = digit + result;
	                break;
	            }
	            else
	            {
	                result = patternChar + result;
	            }
	        }
	    }
	    return result;
	},
	
	/* Array Functions ---------------------------------------------------------------------------- */
	
	// note: currently doubled up below for backwards compatibility
	
	pushFront:function(A, x, maxsize) 
	{
	 	var i=A.length;
	 	if (maxsize && i>maxsize - 1)
	  	i=maxsize - 1;
	 	while (i>0) {
	  		A[i] = A[i-1];
	  		i--;
	 	}
	 	A[0] = x;
	},

	popMiddle:function(A,i) 
	{
	  	var x;
	  	if (i>A.length-1) return (false);
	  	for (x=i; x<A.length-1; x++) A[x]=A[x+1];
	  	A.length=A.length-1;
	  	return (true);
	},

	popFront:function(A) 
	{
	  	return (popMiddle(A,0));
	},

	moveToFront:function(A,i) 
	{
	 	var temp=A[i];
	 	while (i>0) {
	  		A[i]=A[i-1];
	  		i--;
	 	}
	 	A[0]=temp;
	},
	
	
	/* Interface ---------------------------------------------------------------------------------- */

	// Takes a form and wings it to a service.  Dependencies underway.  Localize needs a little more thought
	jackForm:function(form, url, success, dependent, localize)
	{
	    
		this.parameters = $(form).serialize();
		this.success = success;
		
		var pass = this;
				
		new Ajax.Request(url,
			{
				parameters:pass.parameters,
				method:"post",
				onSuccess:pass.success
			}
		);
	},

	setDefaultText:function(objt,text) //browse usage, may be more automated, drop dual calls, maybe action bind
	{
		var obj = objt,
			txt = text;
			
		util.doOnDomLoad(
				function() {
					if ($(obj)) {
						obj = $(obj);
						if (obj.value == '') 
							obj.value = txt;
						obj.observe("focus", function(){
							if (obj.value == txt) 
								obj.value = '';
							obj.addClassName('focus');
						});
						obj.observe("blur", function(){
							if (obj.value == '') 
								obj.value = txt;
							obj.removeClassName('focus');
						});
					}
				}
		);
	},
	
	/*
	Toggle has become fairly complex, so I'm stopping the feat creep here.  
	If you need to expand on it, or it's not doing what it should, let me
	know.  If it gets any bulkier its going to need to be broken down into
	more functions. Check the documentation.
	*/
	toggle_set:new Array(),
	triggers:new Array(),
	toggle:function(obj,bit,destiny,set,trig_obj)
	{
		var element = $(obj),
			display = element.getStyle("display"),
			trigger;
		
		/* 
		The below code is a bit ugly, but not wrong.  
		Dislike nested ifs, but that's sort of the 
		way these animated funcs work themsleves out.

		Will tackle it another time - PW 
		*/
		
		if(trig_obj) 
			trigger = $(trig_obj);
		else 
			trigger = false;
		
		if(set || set == 0) {
			if(typeof(this.toggle_set[set])=="undefined") this.toggle_set[set] = new Array();
			this.toggle_set[set][this.toggle_set[set].length] = element;
		}

		destiny = (destiny ? destiny : "block");
		if (bit) $bit.toggle(bit);
		
		if (display == "none") {
			if(set || set == 0) for(iter=0;iter<this.toggle_set[set].length;++iter) this.toggle_set[set][iter].style.display = "none";
			element.style.display = destiny;
		}
		else element.style.display = "none";
		
		if(trigger && (set || set == 0)) {
			if(typeof(this.triggers[set]) == "undefined") this.triggers[set] = new Array();
			this.triggers[set][this.triggers[set].length] = trigger;
		}
		
		if((set || set == 0) && typeof(this.triggers[set]) != "undefined") {
			for(iter=0;iter<this.triggers[set].length;++iter) this.triggers[set][iter].removeClassName("active");

			if (display == "none" && trigger != false) 
				trigger.addClassName("active");
			else if(trigger != false)
				trigger.removeClassName("active");
		}
	},

	randomQuip:function(lines,returnit)
	{
	    pickquip = Math.round(Math.random()*(lines.length-1));
	    if(!returnit)
	        document.write(lines[pickquip]);
        else
            return lines[pickquip];
	},
	

	/*
	This function needs some work.
	*/
	buddyCallWrapper:function(params,addRemove,notify,optmessage) {
		params.ajax = 1;
		new Ajax.Request("/profile", {
			parameters:params,
			onSuccess:function(response) {
				var text = "";
				switch(parseInt(response.responseText)){
					case 0:
						text = "User has been removed from your favorites.";
						if(addRemove == 1) text = (notify ? "User saved! They've been sent a message to let them know they're one of your favorites." : "User Saved!");
						break;
					case 12: text = "User saved! They've been sent a message to let them know they're one of your favorites."; break;
					default: text = "Couldn't save for some reason. Sorry. Try later."; break;
				}
				var target = (optmessage ? optmessage : 'save_buttons');
				if($(target)) $(target).innerHTML = '<a class="buddy_removed" href="#nogo">'+text+'</a>';
				if (Mailbox && Mailbox.m_current_thread) Mailbox.addSystemMessage ('buddy', text);
			}
		});
	},
	
	/* Site specific ------------------------------------------------------------------------------ */


    // 
    
    updateStats: function(name, value, type, hash, optional_params) {
         new Ajax.Request("/poststat",{
             method : "get",
             parameters : {"name" : name, "value" : value, "type" : type, "hash" : hash, "rnd" : Math.random()},
             onSuccess  : util.updateStats_cb.bindAsEventListener(util, optional_params)
             });
    },
    
    updateStats_cb : function(transport, optional_params) {
               
         var res = transport.responseText.evalJSON();
         if (res.error) {
             alert("Stat posting error" + res.error);
         }
 	 if (optional_params && optional_params["cb"]) {
	     optional_params.cb();
         }
         if (optional_params && optional_params["redirect_to"]) {
             window.location.href = optional_params["redirect_to"];
         }
    },

    
	checkNonbotAjax:function(url) // may move this to profile if it has no other use
	{
		jax = new Ajax.Request(
			url,
			{
				method: "get",
				parameters: {"nonbot": 1},
				onSuccess: function(){},
				onFailure: function(){}
			}
		);
		return true;//jax;  // why pass object?
	},

    printOptimateAd: function() {
         var optimates = ["business","green","technology","entertainment","relationships","astrology"];
         var i = Math.floor(Math.random() * optimates.length);
         var choice = optimates[i];
         $("optimate-ad").innerHTML = '<a target="new" href="/ads3?adClicked='+(i+10)+'&sourcePage=unavailable&sourceViewer=unavailable&redirect=/adcode/optimate_' + choice + '.html">Here\'s something random: <strong>'
         + choice + ' movie</strong></a>';
    },
    
	displayAdvert:function(position,keywords,isloggedin,slot_name)
	{

	    slot_name = slot_name || "Other";
	
		switch(position)
		{
			case "sky" 	: slot_addon = "Sky"; break;
			case "LB" 	: slot_addon = "Ldr"; break;
			case "rect" : slot_addon = "Box"; break;
		}
	
	    if (position != "transitional") { slot_name = slot_name + "_" +  slot_addon;}

	    if (position == "Left" || position == "sky") {
	        width = 160; height = 600;
	    } else if (position == "Top" || position == "LB") {
	        width = 728; height = 90;
	    } else if (position == "Middle" || position == "rect") {
	        width = 300; height = 250;
	    } else if (position == "Right3") {
	        width = 200; height = 500;
	    } else if (position == "Transitional" || position == "transitional") {
	        width = 500; height = 500;
		} else {
	        width = 40; height = 40;
	    }
	    
	    // Width and height added to url to pass cgi to ZEDO
	    var url = "http://ads.okcimg.com/google/ad_manager?ad_slot="+slot_name+"&keywords="+keywords+"&pass_height="+height+"&pass_width="+width;

	    document.write("<iframe id=\"ad_frame_"+position+"\"  width=" + width + " height=" + height + 
	            " marginwidth=0 marginheight=0 hspace=0 vspace=0" + 
	            " frameborder=0 scrolling=no bordercolor=\"#000000\"" +
	            " src=\"" + url + "\"></iframe>");
	},

    ads3_call:function(id, params) {
        
        if(GOOGLE_PUNCH == true) {
            return;
        }

        var get_src = window.location.toString();
        var parseit = get_src.substring(get_src.indexOf("/",7));
        if(parseit.indexOf("?") != -1) parseit = parseit.substring(0,parseit.indexOf("?"));

        params += "&sourcePage=" + parseit;
        params += "&section=" + id;



        new Ajax.Request(
            "/ads3",
            {
                method:'get',
                parameters: params,
                evalScripts: true,
                onSuccess:function(response)
                {
                    if(id=='ad_set_top_profile' && response.responseText.indexOf("good_to_show") != -1)
                    {
                        $('topset').style.background = "#CDD9E6";
                        $('top_cycle').style.display = "block";
                        $('ad_set_top_profile').innerHTML = response.responseText;
                    } else {
                        $('topset').style.display = "none";
                    }   
                }
            }
        );
     },
     
     // Moved back here because we'll have to flip for non-admin accounts
     flipDesign:function() {
         var c = getCookie("redesign");
         if (c && c == "1") {
	     util.updateStats("ui - flip from redesign", 1, "counter", "usxK7602Ep+KxarPcj+Cs4vm3YA=");
                setCookie("redesign","0",secondsFromNow(86400*30));
         }
         else {
	     util.updateStats("ui - flip to redesign", 1, "counter", "N+mQqECk84TokAOpPNLkOJ0glcs=");
                setCookie("redesign","1",secondsFromNow(86400*30));
         }
	 setTimeout("document.location.reload();",500);
     },

	
	/* Fixes the left_bar/main_content height problem ------------------------ */

	adjustMCHeight:function() {
		// none of this matters if the left_bar isn't present
		//
		if ($('left_bar')) {
			var lb_height = $('left_bar').getHeight() + 10; // 10px for margin
			var mc_height = $('main_content').getHeight();
		
			if (!$('hold_mc_height')) {
				// create the hidden input to hold previous size
				var hold_mc_height = '<p class="hidden"><input type="hidden" name="hold_mc_height" value="'+ mc_height +'" id="hold_mc_height" /><\/p>';
			
				// insert it into the bottom of the footer
				$('footer').insert(hold_mc_height, { position: "bottom" });
			}
			else if (lb_height < $F('hold_mc_height')) {					
			  if(BrowserDetect.browser =="Explorer" && BrowserDetect.version == 6)
				    $('main_content').style.height = $F('hold_mc_height') + "px";
				else 
				    $('main_content').style.minHeight = $F('hold_mc_height') + "px";
			}
		
			if (lb_height > mc_height) {
			    if(BrowserDetect.browser =="Explorer" && BrowserDetect.version == 6)
				    $('main_content').style.height = lb_height + "px";
				else 
				    $('main_content').style.minHeight = lb_height + "px";
				
			}
		}
	},

	update_buzz_topic:function(topic)
	{
		$('set_topic_btn').style.display = "none";
		$('set_topic_spinner').style.display = "inline";
		
		$('lb_set_chat_input').style.background = "#1E3F66";
		$('lb_set_chat_input').style.color = "#325279";
		
		new Ajax.Request(
			"/instantevents",
			{
				method:"get",
				parameters:{
					buzz_topic:topic,
					"im.add_topic_ajax":1
				},
				onSuccess:function(response)
				{
					$('lb_set_chat_input').disabled = true;
					$('set_topic_success').style.display = "inline";
					$('set_topic_spinner').style.display = "none";
					
					if($("topic_name"))
						$("topic_name").value = $('lb_set_chat_input').value;
				}
			}
		);
	},
    
	/* IE fixes ----------------------------------------------------------------------------------- */

	// because IE seems to only like document.getElementsByClassName() and
	// not element.getElementsByClassName()
	//
	getElementsByClassName:function(parent, class_name)
	{
		var o = parent.getElementsByTagName('*'); // get all elements under parent
		var a = new Array();
	
		for (var i = 0; i < o.length; i++) {
			// does the element have the class attribute and does class_name exist 
			if (o[i].attributes["class"] && o[i].attributes["class"].value.toString().indexOf(class_name) != -1) {
				a.push(o[i]); // push elements onto array
			}
		}
	
		return a;
	},
	
	clearRecentlyViewed : function() {
		new Ajax.Request("/sookie/clear_recently_viewed.html?" + Math.random());	
		if($("lsRecent")) $("lsRecent").hide();
		else if($("recently_viewed")) $("recently_viewed").hide();
		if($("lsRecentContent")) $("lsRecentContent").hide();	
	},
	
	toggleSavedProfiles:function(id)
	{
		var saved_display = NanoCookie.get('saved_display');
		
		// toggle the section
		this.toggle(id, 32);
		
		// set the cookie for 2 hours if it isn't set
		if (!saved_display) NanoCookie.set('saved_display', '1', {ms: 7200*1000});
	},
    
    // 
    uidBit: function(uid_str, which_bit) {
        if (which_bit < 1 || which_bit > 8) alert ("Whoa; UID bit function works 1..8");
        var tail = uid_str.substr(uid_str.length - 9);
        while(tail.charAt(0) == "0") {
            tail = tail.substr(1);
        }
        var num = parseInt(tail);
        if (num & Math.pow(2,(which_bit-1))) {
            return 1;
        }
        else {
            return 0;
        }
    },

    // simple profiling

	startTimer: function(label) {
		if (! this.timerStats) {
			this.timerStats = {};
		}
		if (! this.timerStats[label]) {
			this.timerStats[label] = {"starts" : [], "stops" : []};
		}
		this.timerStats[label].starts.push(new Date());		
	},

	stopTimer : function(label) {
		if (! this.timerStats 
			|| ! this.timerStats[label] 
			|| this.timerStats[label].stops.length >= this.timerStats[label].starts.length) {
			alert("prematurely called stopTimer. Make sure you call startTimer first for label " + label);
		}
		else {
			this.timerStats[label].stops.push(new Date());
		}
	},
	
	summarizeTimers : function() {
		var res = "";
		for (var key in this.timerStats) {
			var label_time = 0;
			var samples = this.timerStats[key].stops.length;
			for (var i = 0; i < samples; i++) {
				label_time += this.timerStats[key].stops[i].getTime() - this.timerStats[key].starts[i].getTime();		
			}
			res+="<br /> " + key + ": " + (label_time / samples) + "ms avg. -- " + samples + " sample(s) -- " + label_time + "ms total";
		}
		return res;
	},
	
	doOnDomLoad : function(func) {
		if (! this.m_dom_load_funcs) {
			this.m_dom_load_funcs = [];	
		}
		this.m_dom_load_funcs.push(func);
	},
	
	executeDomLoad : function() {
		if (this.m_dom_load_funcs) {
			for (var i = 0; i < this.m_dom_load_funcs.length; i++) {
				setTimeout(this.m_dom_load_funcs[i], 500);
			}
		}		
     },


	fillInTheP:function() {
		var temp=window.location.href;

		if (temp.indexOf("login?p=") != -1) {
			$('page_url_p').value = temp.substring(temp.indexOf("login?p=")+8);
		}
		else if (temp.indexOf("signup") != -1 && $('page_url_p').value == "") {
			$('page_url_p').value ="/home";
		}
		else if (temp.indexOf("login") == -1 && temp.indexOf(".com") != -1) {
			temp=temp.substring(temp.indexOf(".com"));
			if (temp.indexOf("/") != -1) {
				temp=temp.substring(temp.indexOf("/"));
			}
			if (temp.length > 3) {
				$('page_url_p').value = temp;
			}
		}
	},
	
	hideBottomBar:function() {
		if ($('footer_signup_wrapper'))
			$('footer_signup_wrapper').hide();
	},
	
	toggleClass:function(b, c) {
		// get class the old school way because Prototype's hasClass() doesn't work well in IE
		var hasClass = b.attributes['class'].value.search(c);
		
		// using this method because add/removeClass() doesn't work well in IEs either
		if (hasClass != -1)
			b.className = b.className.replace(new RegExp(' '+c+'\\b'), '');
		else
			b.className += ' '+c;
	},
	// 
	constrainImageWidthAfterLoad : function(im, maxwidth) {
		if (im.width > maxwidth) {
			im.style.width = "";
			im.style.height = "";
			im.height = Math.round(maxwidth * im.height / im.width);
			im.width = maxwidth;
		}
	},

	// 

	floatADivOnDomLoad : function(id, parentid) {
		util.doOnDomLoad( function() {
			if ($(id)) document.observe('scroll', util.floatADivOnScrollHandler.bind(this,id,parentid));
			// this is for the IEs                                                                                   
			if (window.attachEvent && $(id)) window.attachEvent("onscroll", util.floatADivOnScrollHandler.bind(this,id, parentid));	
		});
	},
	
	// 
	floatADivOnScrollHandler : function(id, parentid) {
		var b = $(id);
		var par = $(parentid);
		var coff = par.cumulativeOffset()[1];
		var csoff = par.cumulativeScrollOffset()[1];
		if (coff < csoff) 
			b.style.position = "fixed";
		else 
			b.style.position = "static";
	},
	// 
	toMask : function() {
	  	var res = 0;
	
	  	if(typeof arguments[0] == "object")
			bits = arguments[0];
		else 
			bits = arguments;
			
	  	for (var i = 0; i < bits.length;i++) {
		 	if (bits[i] > 31 || bits[i] < 0)
				throw("fillBitsInMask expects ints in [0..30] due to JS bitwise limitations");
			res = res | Math.pow(2,bits[i]);
	  	}
	  	return res;
	},
	// 
	fromMaskToList : function(mask) {
		var res = [];
		for (var i = 0; i < 31; i++)
			if (Math.pow(2,i) & mask)
				res.push(i);
		return res;
	},
	// 
	isBitSetInMask : function(mask, bit) {
		return Math.pow(2, bit) & mask ? 1 : 0;
	},
	
	/* Mobile toggle */
	
	flipMobile:function(mobile) {
		if(mobile) {
			target = 0;
			cgi = "enable_mobile=";
		} else {
			target = 1;
			cgi = "disable_mobile=";
		}
		
		url = window.location.toString().replace(/[&?](en|dis)able_mobile=1/g,"");

		gluon = (url.indexOf("?") != -1 ? "&" : "?");
		url = url + gluon + cgi + "1";
		
		new Ajax.Request(
			"/settings", 
			{
				method: 'get', 
				parameters: {
					update_ui_prefs:1,
					bit:62,
					val:target
				},
				onSuccess:function() { window.location = url; }
			}
		);
	}
};
/*  */


/* Extensions to the Element class ------------------------------------------ */

// Use Object.extend instead of Element.prototype= because IE6 doesn't support that.  Thanks Prototype!
Object.extend(Element.Methods, {
	
	// Finds inputs with the given class name and returns the values of the ones that are selected.
	getValues: function (element, class_name) {
		return element.select('input.' + class_name).collect(function(input) {return input.checked ? input.value : 0}).without(0).reduce() || null;
	},
	
	// Pulses an element if it's visible; otherwise, makes it visible.
	showOrPulse: function (element) {
		element.visible() ? element.pulsate ({pulses: 2, duration: 0.6}) : element.show ();
	},
	
	// Remove the class names from elements in the array passed in.
	removeClassNames: function (element, class_names) {
		for (var i = 0; i < class_names.length; i++) {
			element.removeClassName (class_names[i]);
		}
		return element;
	}
});

// Add the methods to the element class
Element.addMethods ();

/* /extensions to the Element class ----------------------------------------- */


/* Further work and future integration */

function updateFavCount() {
	var num_favs_online = document.getElementById('favs_online').getElementsByTagName('li').length - 1;
	var favs_count_span = document.getElementById('favs_count');
	
	if (num_favs_online > 0) {
		favs_count_span.getElementsByTagName('strong')[0].innerHTML = num_favs_online;
		favs_count_span.style.display = "";
	}
}

function checkForm(tab){ // check if user has made a from entry

    if((FormId == "profileeditform") && (tab == "profileedit" ||  tab == "details")) {

        tab = (tab == "details" ? tab : "essays");

        $("tab-" + OldId).removeClassName("tab-on");
        $("tab-" + tab).addClassName("tab-on");
        displayDiv(tab);
    } else {
        if(FormId != 'picturerows' && SerializedForm != Form.serialize(FormId)) {

            $(FormId).action += "?tab=" + tab; // redirect to tabbed page after form submission

            if(FormId == "settingsform"){ // check if user entered password
    	        if(!document.getElementById("settingsSubmit").disabled) {
        		    $(FormId).submit(); // submit changes
        	    } else {
        		    alert("Please enter your password to save your settings.");
        		    document.getElementById("oldPassword").focus();
        	    }
            } else {
                $(FormId).submit(); // submit changes
            }

        } else { // send user to tabbed page

            if(tab == "details"){ // "details" and "essays" tab share the same page
                page = "profileedit";
            } else {
                page = tab;
            }
            document.location.href = "/" + page + "?tab=" + tab;
        }
    }

}

var util = Utilities;

// these functions probably have prototype equivalents; deprecate or move to utility array funcs
// Note: these do NOT have prototype equivalents; assess later, fine for now

/* standard?  how far back does this go? */

if(typeof Array.prototype.push=='undefined')
  Array.prototype.push=function(){
    var i=0;
    b=this.length;a=arguments;
    for(i;i<a.length;i++)this[b+i]=a[i];
    return this.length;
  };



function pushFront(A, x, maxsize) {
 var i=A.length;
 if (maxsize && i>maxsize - 1)
  i=maxsize - 1;
 while (i>0) {
  A[i] = A[i-1];
  i--;
 }
 A[0] = x;
}

function popMiddle(A,i) {
  var x;
  if (i>A.length-1)
    return (false);
  for (x=i; x<A.length-1; x++)
     A[x]=A[x+1];
  A.length=A.length-1;
  return (true);
}

function popFront(A) {
  return (popMiddle(A,0));
}

function moveToFront(A,i) {
 var temp=A[i];
 while (i>0) {
  A[i]=A[i-1];
  i--;
 }
 A[0]=temp;
}

// 

function $RF(el, radioGroup) {
    if($(el).type && $(el).type.toLowerCase() == 'radio') {
        var radioGroup = $(el).name;
        var el = $(el).form;
    } else if ($(el).tagName.toLowerCase() != 'form') {
        return false;
    }

    var checked = $(el).getInputs('radio', radioGroup).find(
        function(re) {return re.checked;}
    );
    return (checked) ? $F(checked) : null;
}


function favorites_toggle() {
    var toggle_text = $("favs_toggle");
    
    if($bit.get(33) == 1)
        toggle_text.innerHTML = "Show offline users";
    else
        toggle_text.innerHTML = "Hide offline users";
        
    util.toggle('favs_offline', 33);
}

function topics_toggle() {
    var topic_toggle = $("topic_toggle");
    
    if($bit.get(36) == 0)
        topic_toggle.innerHTML = "Show Topics";
    else
        topic_toggle.innerHTML = "Hide Topics";
        
	util.toggle('lb_recent_topics',36);
}





/* On DOM/window load events */
util.doOnDomLoad(
			function()
			{
				if($("ads3_set_leftbar")) Utilities.ads3_call("ads3_set_leftbar","showAd=1&adEvent=4&adEventAdId=1");
			
					// fill in the hidden p on logged out pages only
					if ($('header_login')) util.fillInTheP();
			
					// show the save profiles menu in the left bar for two ours (based on the cookie)
					if ($('lb_favorites_menu') && !NanoCookie.get('saved_display')) $('lb_favorites_menu').style.display = "";
					
					// adjust the page's height on load
					// you can move this if it makes you unhappy here [AS]
					Utilities.adjustMCHeight();
			}
);

Utilities.setDefaultText("mainMenuSearchBox", ""); // old search box
Utilities.setDefaultText("site_search_query", ""); // new search box

var GOOGLE_PUNCH = false;
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/prototype_abort.js
AUTOCORE_SELF_CHECK.push("prototype_abort.js");
if (typeof(Ajax) != "undefined") {
   Ajax.Request.prototype.abort = function() {
    var abort_type = typeof this.transport.abort;
    if (abort_type == "function") {
        this.transport.onreadystatechange = Prototype.emptyFunction;
        this.transport.abort();
        Ajax.activeRequestCount--;
    }
   };
					       } 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/scriptaculous-1.8.1-for-autocore/scriptaculous.js
AUTOCORE_SELF_CHECK.push("scriptaculous-1.8.1-for-autocore/scriptaculous.js");

var Scriptaculous = {
  Version: '1.8.1',
  require: function(libraryName) {
    // inserting via DOM fails in Safari 2.0, so brute force approach
    document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
  },
  REQUIRED_PROTOTYPE: '1.6.0',
  load: function() {
    function convertVersionString(versionString){
      var r = versionString.split('.');
      return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
    }
 
//    if((typeof Prototype=='undefined') || 
//       (typeof Element == 'undefined') || 
//       (typeof Element.Methods=='undefined') ||
//       (convertVersionString(Prototype.Version) < 
//        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
//       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
//        Scriptaculous.REQUIRED_PROTOTYPE);
    
//    $A(document.getElementsByTagName("script")).findAll( function(s) {
//      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
//    }).each( function(s) {
//      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
//      var includes = s.src.match(/\?.*load=([a-z,]*)/);
//      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
//       function(include) { Scriptaculous.require(path+include+'.js') });
//    });
  }
}

Scriptaculous.load(); 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/scriptaculous-1.8.1-for-autocore/effects.js
AUTOCORE_SELF_CHECK.push("scriptaculous-1.8.1-for-autocore/effects.js");
// script.aculo.us effects.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008

// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
//  Justin Palmer (http://encytemedia.com/)
//  Mark Pilgrim (http://diveintomark.org/)
//  Martin Bialasinki
// 
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ 

// converts rgb() and #xxx to #xxxxxx format,  
// returns self (or first argument) if not convertable  
String.prototype.parseColor = function() {  
  var color = '#';
  if (this.slice(0,4) == 'rgb(') {  
    var cols = this.slice(4,this.length-1).split(',');  
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);  
  } else {  
    if (this.slice(0,1) == '#') {  
      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();  
      if (this.length==7) color = this.toLowerCase();  
    }  
  }  
  return (color.length==7 ? color : (arguments[0] || this));  
};

/*--------------------------------------------------------------------------*/

Element.collectTextNodes = function(element) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
  }).flatten().join('');
};

Element.collectTextNodesIgnoreClass = function(element, className) {  
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue : 
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
        Element.collectTextNodesIgnoreClass(node, className) : ''));
  }).flatten().join('');
};

Element.setContentZoom = function(element, percent) {
  element = $(element);  
  element.setStyle({fontSize: (percent/100) + 'em'});   
  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
  return element;
};

Element.getInlineOpacity = function(element){
  return $(element).style.opacity || '';
};

Element.forceRerendering = function(element) {
  try {
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    element.removeChild(n);
  } catch(e) { }
};

/*--------------------------------------------------------------------------*/

var Effect = {
  _elementDoesNotExistError: {
    name: 'ElementDoesNotExistError',
    message: 'The specified DOM element does not exist, but is required for this effect to operate'
  },
  Transitions: {
    linear: Prototype.K,
    sinoidal: function(pos) {
      return (-Math.cos(pos*Math.PI)/2) + 0.5;
    },
    reverse: function(pos) {
      return 1-pos;
    },
    flicker: function(pos) {
      var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
      return pos > 1 ? 1 : pos;
    },
    wobble: function(pos) {
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
    },
    pulse: function(pos, pulses) { 
      pulses = pulses || 5; 
      return (
        ((pos % (1/pulses)) * pulses).round() == 0 ? 
              ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 
          1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
        );
    },
    spring: function(pos) { 
      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 
    },
    none: function(pos) {
      return 0;
    },
    full: function(pos) {
      return 1;
    }
  },
  DefaultOptions: {
    duration:   1.0,   // seconds
    fps:        100,   // 100= assume 66fps max.
    sync:       false, // true for combining
    from:       0.0,
    to:         1.0,
    delay:      0.0,
    queue:      'parallel'
  },
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
    
    element = $(element);
    $A(element.childNodes).each( function(child) {
      if (child.nodeType==3) {
        child.nodeValue.toArray().each( function(character) {
          element.insertBefore(
            new Element('span', {style: tagifyStyle}).update(
              character == ' ' ? String.fromCharCode(160) : character), 
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if (((typeof element == 'object') || 
        Object.isFunction(element)) && 
       (element.length))
      elements = element;
    else
      elements = $(element).childNodes;
      
    var options = Object.extend({
      speed: 0.1,
      delay: 0.0
    }, arguments[2] || { });
    var masterDelay = options.delay;

    $A(elements).each( function(element, index) {
      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
    });
  },
  PAIRS: {
    'slide':  ['SlideDown','SlideUp'],
    'blind':  ['BlindDown','BlindUp'],
    'appear': ['Appear','Fade']
  },
  toggle: function(element, effect) {
    element = $(element);
    effect = (effect || 'appear').toLowerCase();
    var options = Object.extend({
      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
    }, arguments[2] || { });
    Effect[element.visible() ? 
      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
  }
};

Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create(Enumerable, {
  initialize: function() {
    this.effects  = [];
    this.interval = null;    
  },
  _each: function(iterator) {
    this.effects._each(iterator);
  },
  add: function(effect) {
    var timestamp = new Date().getTime();
    
    var position = Object.isString(effect.options.queue) ? 
      effect.options.queue : effect.options.queue.position;
    
    switch(position) {
      case 'front':
        // move unstarted effects after this effect  
        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
            e.startOn  += effect.finishOn;
            e.finishOn += effect.finishOn;
          });
        break;
      case 'with-last':
        timestamp = this.effects.pluck('startOn').max() || timestamp;
        break;
      case 'end':
        // start effect after last queued effect has finished
        timestamp = this.effects.pluck('finishOn').max() || timestamp;
        break;
    }
    
    effect.startOn  += timestamp;
    effect.finishOn += timestamp;

    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
      this.effects.push(effect);
    
    if (!this.interval)
      this.interval = setInterval(this.loop.bind(this), 15);
  },
  remove: function(effect) {
    this.effects = this.effects.reject(function(e) { return e==effect });
    if (this.effects.length == 0) {
      clearInterval(this.interval);
      this.interval = null;
    }
  },
  loop: function() {
    var timePos = new Date().getTime();
    for(var i=0, len=this.effects.length;i<len;i++) 
      this.effects[i] && this.effects[i].loop(timePos);
  }
});

Effect.Queues = {
  instances: $H(),
  get: function(queueName) {
    if (!Object.isString(queueName)) return queueName;
    
    return this.instances.get(queueName) ||
      this.instances.set(queueName, new Effect.ScopedQueue());
  }
};
Effect.Queue = Effect.Queues.get('global');

Effect.Base = Class.create({
  position: null,
  start: function(options) {
    function codeForEvent(options,eventName){
      return (
        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
      );
    }
    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
    this.currentFrame = 0;
    this.state        = 'idle';
    this.startOn      = this.options.delay*1000;
    this.finishOn     = this.startOn+(this.options.duration*1000);
    this.fromToDelta  = this.options.to-this.options.from;
    this.totalTime    = this.finishOn-this.startOn;
    this.totalFrames  = this.options.fps*this.options.duration;
    
    eval('this.render = function(pos){ '+
      'if (this.state=="idle"){this.state="running";'+
      codeForEvent(this.options,'beforeSetup')+
      (this.setup ? 'this.setup();':'')+ 
      codeForEvent(this.options,'afterSetup')+
      '};if (this.state=="running"){'+
      'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
      'this.position=pos;'+
      codeForEvent(this.options,'beforeUpdate')+
      (this.update ? 'this.update(pos);':'')+
      codeForEvent(this.options,'afterUpdate')+
      '}}');
    
    this.event('beforeStart');
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ? 
        'global' : this.options.queue.scope).add(this);
  },
  loop: function(timePos) {
    if (timePos >= this.startOn) {
      if (timePos >= this.finishOn) {
        this.render(1.0);
        this.cancel();
        this.event('beforeFinish');
        if (this.finish) this.finish(); 
        this.event('afterFinish');
        return;  
      }
      var pos   = (timePos - this.startOn) / this.totalTime,
          frame = (pos * this.totalFrames).round();
      if (frame > this.currentFrame) {
        this.render(pos);
        this.currentFrame = frame;
      }
    }
  },
  cancel: function() {
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ? 
        'global' : this.options.queue.scope).remove(this);
    this.state = 'finished';
  },
  event: function(eventName) {
    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
    if (this.options[eventName]) this.options[eventName](this);
  },
  inspect: function() {
    var data = $H();
    for(property in this)
      if (!Object.isFunction(this[property])) data.set(property, this[property]);
    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
  }
});

Effect.Parallel = Class.create(Effect.Base, {
  initialize: function(effects) {
    this.effects = effects || [];
    this.start(arguments[1]);
  },
  update: function(position) {
    this.effects.invoke('render', position);
  },
  finish: function(position) {
    this.effects.each( function(effect) {
      effect.render(1.0);
      effect.cancel();
      effect.event('beforeFinish');
      if (effect.finish) effect.finish(position);
      effect.event('afterFinish');
    });
  }
});

Effect.Tween = Class.create(Effect.Base, {
  initialize: function(object, from, to) {
    object = Object.isString(object) ? $(object) : object;
    var args = $A(arguments), method = args.last(), 
      options = args.length == 5 ? args[3] : null;
    this.method = Object.isFunction(method) ? method.bind(object) :
      Object.isFunction(object[method]) ? object[method].bind(object) : 
      function(value) { object[method] = value };
    this.start(Object.extend({ from: from, to: to }, options || { }));
  },
  update: function(position) {
    this.method(position);
  }
});

Effect.Event = Class.create(Effect.Base, {
  initialize: function() {
    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
  },
  update: Prototype.emptyFunction
});

Effect.Opacity = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    // make this work on IE on elements without 'layout'
    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
      this.element.setStyle({zoom: 1});
    var options = Object.extend({
      from: this.element.getOpacity() || 0.0,
      to:   1.0
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(position) {
    this.element.setOpacity(position);
  }
});

Effect.Move = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
    if (this.options.mode == 'absolute') {
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    this.element.setStyle({
      left: (this.options.x  * position + this.originalLeft).round() + 'px',
      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
    });
  }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
  return new Effect.Move(element, 
    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};

Effect.Scale = Class.create(Effect.Base, {
  initialize: function(element, percent) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      scaleX: true,
      scaleY: true,
      scaleContent: true,
      scaleFromCenter: false,
      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
      scaleFrom: 100.0,
      scaleTo:   percent
    }, arguments[2] || { });
    this.start(options);
  },
  setup: function() {
    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
    this.elementPositioning = this.element.getStyle('position');
    
    this.originalStyle = { };
    ['top','left','width','height','fontSize'].each( function(k) {
      this.originalStyle[k] = this.element.style[k];
    }.bind(this));
      
    this.originalTop  = this.element.offsetTop;
    this.originalLeft = this.element.offsetLeft;
    
    var fontSize = this.element.getStyle('font-size') || '100%';
    ['em','px','%','pt'].each( function(fontSizeType) {
      if (fontSize.indexOf(fontSizeType)>0) {
        this.fontSize     = parseFloat(fontSize);
        this.fontSizeType = fontSizeType;
      }
    }.bind(this));
    
    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
    
    this.dims = null;
    if (this.options.scaleMode=='box')
      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
    if (/^content/.test(this.options.scaleMode))
      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
    if (!this.dims)
      this.dims = [this.options.scaleMode.originalHeight,
                   this.options.scaleMode.originalWidth];
  },
  update: function(position) {
    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
    if (this.options.scaleContent && this.fontSize)
      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
  },
  finish: function(position) {
    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
  },
  setDimensions: function(height, width) {
    var d = { };
    if (this.options.scaleX) d.width = width.round() + 'px';
    if (this.options.scaleY) d.height = height.round() + 'px';
    if (this.options.scaleFromCenter) {
      var topd  = (height - this.dims[0])/2;
      var leftd = (width  - this.dims[1])/2;
      if (this.elementPositioning == 'absolute') {
        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
      } else {
        if (this.options.scaleY) d.top = -topd + 'px';
        if (this.options.scaleX) d.left = -leftd + 'px';
      }
    }
    this.element.setStyle(d);
  }
});

Effect.Highlight = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    // Prevent executing on elements not in the layout flow
    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
    // Disable background image during the effect
    this.oldStyle = { };
    if (!this.options.keepBackgroundImage) {
      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
      this.element.setStyle({backgroundImage: 'none'});
    }
    if (!this.options.endcolor)
      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
    if (!this.options.restorecolor)
      this.options.restorecolor = this.element.getStyle('background-color');
    // init color calculations
    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
  },
  update: function(position) {
    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
  },
  finish: function() {
    this.element.setStyle(Object.extend(this.oldStyle, {
      backgroundColor: this.options.restorecolor
    }));
  }
});

Effect.ScrollTo = function(element) {
  var options = arguments[1] || { },
    scrollOffsets = document.viewport.getScrollOffsets(),
    elementOffsets = $(element).cumulativeOffset(),
    max = (window.height || document.body.scrollHeight) - document.viewport.getHeight();  

  if (options.offset) elementOffsets[1] += options.offset;

  return new Effect.Tween(null,
    scrollOffsets.top,
    elementOffsets[1] > max ? max : elementOffsets[1],
    options,
    function(p){ scrollTo(scrollOffsets.left, p.round()) }
  );
};

/* ------------- combination effects ------------- */

Effect.Fade = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  var options = Object.extend({
    from: element.getOpacity() || 1.0,
    to:   0.0,
    afterFinishInternal: function(effect) { 
      if (effect.options.to!=0) return;
      effect.element.hide().setStyle({opacity: oldOpacity}); 
    }
  }, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Appear = function(element) {
  element = $(element);
  var options = Object.extend({
  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
  to:   1.0,
  // force Safari to render floated elements properly
  afterFinishInternal: function(effect) {
    effect.element.forceRerendering();
  },
  beforeSetup: function(effect) {
    effect.element.setOpacity(effect.options.from).show(); 
  }}, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Puff = function(element) {
  element = $(element);
  var oldStyle = { 
    opacity: element.getInlineOpacity(), 
    position: element.getStyle('position'),
    top:  element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height
  };
  return new Effect.Parallel(
   [ new Effect.Scale(element, 200, 
      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
     Object.extend({ duration: 1.0, 
      beforeSetupInternal: function(effect) {
        Position.absolutize(effect.effects[0].element)
      },
      afterFinishInternal: function(effect) {
         effect.effects[0].element.hide().setStyle(oldStyle); }
     }, arguments[1] || { })
   );
};

Effect.BlindUp = function(element) {
  element = $(element);
  element.makeClipping();
  return new Effect.Scale(element, 0,
    Object.extend({ scaleContent: false, 
      scaleX: false, 
      restoreAfterFinish: true,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping();
      } 
    }, arguments[1] || { })
  );
};

Effect.BlindDown = function(element) {
  element = $(element);
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleX: false,
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
    },  
    afterFinishInternal: function(effect) {
      effect.element.undoClipping();
    }
  }, arguments[1] || { }));
};

Effect.SwitchOff = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  return new Effect.Appear(element, Object.extend({
    duration: 0.4,
    from: 0,
    transition: Effect.Transitions.flicker,
    afterFinishInternal: function(effect) {
      new Effect.Scale(effect.element, 1, { 
        duration: 0.3, scaleFromCenter: true,
        scaleX: false, scaleContent: false, restoreAfterFinish: true,
        beforeSetup: function(effect) { 
          effect.element.makePositioned().makeClipping();
        },
        afterFinishInternal: function(effect) {
          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
        }
      })
    }
  }, arguments[1] || { }));
};

Effect.DropOut = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left'),
    opacity: element.getInlineOpacity() };
  return new Effect.Parallel(
    [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
    Object.extend(
      { duration: 0.5,
        beforeSetup: function(effect) {
          effect.effects[0].element.makePositioned(); 
        },
        afterFinishInternal: function(effect) {
          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
        } 
      }, arguments[1] || { }));
};

Effect.Shake = function(element) {
  element = $(element);
  var options = Object.extend({
    distance: 20,
    duration: 0.5
  }, arguments[1] || {});
  var distance = parseFloat(options.distance);
  var split = parseFloat(options.duration) / 10.0;
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left') };
    return new Effect.Move(element,
      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
        effect.element.undoPositioned().setStyle(oldStyle);
  }}) }}) }}) }}) }}) }});
};

Effect.SlideDown = function(element) {
  element = $(element).cleanWhitespace();
  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({ 
    scaleContent: false, 
    scaleX: false, 
    scaleFrom: window.opera ? 0 : 1,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().setStyle({height: '0px'}).show(); 
    },
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
    }, arguments[1] || { })
  );
};

Effect.SlideUp = function(element) {
  element = $(element).cleanWhitespace();
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, window.opera ? 0 : 1,
   Object.extend({ scaleContent: false, 
    scaleX: false, 
    scaleMode: 'box',
    scaleFrom: 100,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().show();
    },  
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    },
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
    }
   }, arguments[1] || { })
  );
};

// Bug in opera makes the TD containing this element expand for a instance after finish 
Effect.Squish = function(element) {
  return new Effect.Scale(element, window.opera ? 1 : 0, { 
    restoreAfterFinish: true,
    beforeSetup: function(effect) {
      effect.element.makeClipping(); 
    },  
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping(); 
    }
  });
};

Effect.Grow = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.full
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();    
  var initialMoveX, initialMoveY;
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      initialMoveX = initialMoveY = moveX = moveY = 0; 
      break;
    case 'top-right':
      initialMoveX = dims.width;
      initialMoveY = moveY = 0;
      moveX = -dims.width;
      break;
    case 'bottom-left':
      initialMoveX = moveX = 0;
      initialMoveY = dims.height;
      moveY = -dims.height;
      break;
    case 'bottom-right':
      initialMoveX = dims.width;
      initialMoveY = dims.height;
      moveX = -dims.width;
      moveY = -dims.height;
      break;
    case 'center':
      initialMoveX = dims.width / 2;
      initialMoveY = dims.height / 2;
      moveX = -dims.width / 2;
      moveY = -dims.height / 2;
      break;
  }
  
  return new Effect.Move(element, {
    x: initialMoveX,
    y: initialMoveY,
    duration: 0.01, 
    beforeSetup: function(effect) {
      effect.element.hide().makeClipping().makePositioned();
    },
    afterFinishInternal: function(effect) {
      new Effect.Parallel(
        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
          new Effect.Scale(effect.element, 100, {
            scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
        ], Object.extend({
             beforeSetup: function(effect) {
               effect.effects[0].element.setStyle({height: '0px'}).show(); 
             },
             afterFinishInternal: function(effect) {
               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
             }
           }, options)
      )
    }
  });
};

Effect.Shrink = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.none
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var moveX, moveY;
  
  switch (options.direction) {
    case 'top-left':
      moveX = moveY = 0;
      break;
    case 'top-right':
      moveX = dims.width;
      moveY = 0;
      break;
    case 'bottom-left':
      moveX = 0;
      moveY = dims.height;
      break;
    case 'bottom-right':
      moveX = dims.width;
      moveY = dims.height;
      break;
    case 'center':  
      moveX = dims.width / 2;
      moveY = dims.height / 2;
      break;
  }
  
  return new Effect.Parallel(
    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
    ], Object.extend({            
         beforeStartInternal: function(effect) {
           effect.effects[0].element.makePositioned().makeClipping(); 
         },
         afterFinishInternal: function(effect) {
           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
       }, options)
  );
};

Effect.Pulsate = function(element) {
  element = $(element);
  var options    = arguments[1] || { };
  var oldOpacity = element.getInlineOpacity();
  var transition = options.transition || Effect.Transitions.sinoidal;
  var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
  reverser.bind(transition);
  return new Effect.Opacity(element, 
    Object.extend(Object.extend({  duration: 2.0, from: 0,
      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
    }, options), {transition: reverser}));
};

Effect.Fold = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height };
  element.makeClipping();
  return new Effect.Scale(element, 5, Object.extend({   
    scaleContent: false,
    scaleX: false,
    afterFinishInternal: function(effect) {
    new Effect.Scale(element, 1, { 
      scaleContent: false, 
      scaleY: false,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping().setStyle(oldStyle);
      } });
  }}, arguments[1] || { }));
};

Effect.Morph = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      style: { }
    }, arguments[1] || { });
    
    if (!Object.isString(options.style)) this.style = $H(options.style);
    else {
      if (options.style.include(':'))
        this.style = options.style.parseStyle();
      else {
        this.element.addClassName(options.style);
        this.style = $H(this.element.getStyles());
        this.element.removeClassName(options.style);
        var css = this.element.getStyles();
        this.style = this.style.reject(function(style) {
          return style.value == css[style.key];
        });
        options.afterFinishInternal = function(effect) {
          effect.element.addClassName(effect.options.style);
          effect.transforms.each(function(transform) {
            effect.element.style[transform.style] = '';
          });
        }
      }
    }
    this.start(options);
  },
  
  setup: function(){
    function parseColor(color){
      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
      color = color.parseColor();
      return $R(0,2).map(function(i){
        return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
      });
    }
    this.transforms = this.style.map(function(pair){
      var property = pair[0], value = pair[1], unit = null;

      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
        value = value.parseColor();
        unit  = 'color';
      } else if (property == 'opacity') {
        value = parseFloat(value);
        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
          this.element.setStyle({zoom: 1});
      } else if (Element.CSS_LENGTH.test(value)) {
          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
          value = parseFloat(components[1]);
          unit = (components.length == 3) ? components[2] : null;
      }

      var originalValue = this.element.getStyle(property);
      return { 
        style: property.camelize(), 
        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 
        targetValue: unit=='color' ? parseColor(value) : value,
        unit: unit
      };
    }.bind(this)).reject(function(transform){
      return (
        (transform.originalValue == transform.targetValue) ||
        (
          transform.unit != 'color' &&
          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
        )
      )
    });
  },
  update: function(position) {
    var style = { }, transform, i = this.transforms.length;
    while(i--)
      style[(transform = this.transforms[i]).style] = 
        transform.unit=='color' ? '#'+
          (Math.round(transform.originalValue[0]+
            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
          (Math.round(transform.originalValue[1]+
            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
          (Math.round(transform.originalValue[2]+
            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
        (transform.originalValue +
          (transform.targetValue - transform.originalValue) * position).toFixed(3) + 
            (transform.unit === null ? '' : transform.unit);
    this.element.setStyle(style, true);
  }
});

Effect.Transform = Class.create({
  initialize: function(tracks){
    this.tracks  = [];
    this.options = arguments[1] || { };
    this.addTracks(tracks);
  },
  addTracks: function(tracks){
    tracks.each(function(track){
      track = $H(track);
      var data = track.values().first();
      this.tracks.push($H({
        ids:     track.keys().first(),
        effect:  Effect.Morph,
        options: { style: data }
      }));
    }.bind(this));
    return this;
  },
  play: function(){
    return new Effect.Parallel(
      this.tracks.map(function(track){
        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
        var elements = [$(ids) || $$(ids)].flatten();
        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
      }).flatten(),
      this.options
    );
  }
});

Element.CSS_PROPERTIES = $w(
  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 
  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
  'fontSize fontWeight height left letterSpacing lineHeight ' +
  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
  'right textIndent top width wordSpacing zIndex');
  
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
  var style, styleRules = $H();
  if (Prototype.Browser.WebKit)
    style = new Element('div',{style:this}).style;
  else {
    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
    style = String.__parseStyleElement.childNodes[0].style;
  }
  
  Element.CSS_PROPERTIES.each(function(property){
    if (style[property]) styleRules.set(property, style[property]); 
  });
  
  if (Prototype.Browser.IE && this.include('opacity'))
    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);

  return styleRules;
};

if (document.defaultView && document.defaultView.getComputedStyle) {
  Element.getStyles = function(element) {
    var css = document.defaultView.getComputedStyle($(element), null);
    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
      styles[property] = css[property];
      return styles;
    });
  };
} else {
  Element.getStyles = function(element) {
    element = $(element);
    var css = element.currentStyle, styles;
    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
      results[property] = css[property];
      return results;
    });
    if (!styles.opacity) styles.opacity = element.getOpacity();
    return styles;
  };
};

Effect.Methods = {
  morph: function(element, style) {
    element = $(element);
    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
    return element;
  },
  visualEffect: function(element, effect, options) {
    element = $(element)
    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
    new Effect[klass](element, options);
    return element;
  },
  highlight: function(element, options) {
    element = $(element);
    new Effect.Highlight(element, options);
    return element;
  }
};

$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
  'pulsate shake puff squish switchOff dropOut').each(
  function(effect) { 
    Effect.Methods[effect] = function(element, options){
      element = $(element);
      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
      return element;
    }
  }
);

$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 
  function(f) { Effect.Methods[f] = Element[f]; }
);

Element.addMethods(Effect.Methods);
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/FacebookConnect.js
AUTOCORE_SELF_CHECK.push("FacebookConnect.js");
FacebookConnect = {
    key : "66620421d55cbafb1a0f8dbe12a5a592",
    receiver : "/fbconnect/xd_receiver.htm",
    inited : false,

    init : function(initDone) {
        if (this.inited) {
            return;
        }
        FB.init(this.key, this.receiver);
        FB.ensureInit(function() { FacebookConnect.inited=true; initDone(); });
    },

    notInited : function(funcName) {
        alert(funcName + " called before init in FacebookConnect.js");
    },

    // doneFn takes an int, which can be one of:
    // FB.ConnectState.connected
    // FB.ConnectState.userNotLoggedIn
    // FB.ConnectState.appNotAuthorized
    getConnStatus : function(doneFn) {
        if (!this.inited) {
            this.notInited("getConnStatus");
            return;
        }
        FB.Connect.get_status().waitUntilReady(doneFn);
    },

    afterFbLogin : function(isLoggedIn) {
        var loc = window.location.pathname;
        var newLoc = "/login?p=" + escape(loc);
        if (isLoggedIn) {
            newLoc += "&fb_connect=1";
        }
        window.location.href = newLoc;
    },

    getUserData : function(handler) {
        var uid = FB.Connect.get_loggedInUser();
        var api = FB.ApiClient(this.key);
        api.fql_query("SELECT first_name, last_name, pic_big, birthday_date, " +
                      "sex, meeting_sex, meeting_for, relationship_status, " +
                      "current_location, activities, interests, music, tv, " +
                      "movies, books, about_me, profile_blurb " +
                      "from user where uid=" + uid, handler);
    },

    requireSession : function(nextFunction) {
        return FB.Connect.requireSession(nextFunction);
    }

}
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/iqadventure.js
AUTOCORE_SELF_CHECK.push("iqadventure.js");

// JavaScript Document

var wordsFillInTheBlank = new Array();
var solutionsFillInTheBlank = new Array();

wordsFillInTheBlank[0] = 'da_k';
wordsFillInTheBlank[1] = 'repe_t';
wordsFillInTheBlank[2] = 'p_ce';
wordsFillInTheBlank[3] = 'spe_t';
wordsFillInTheBlank[4] = 'pat_os';
wordsFillInTheBlank[5] = '_ther';
wordsFillInTheBlank[6] = 'h_rt';
wordsFillInTheBlank[7] = '_oment';
wordsFillInTheBlank[8] = 'cul_';
wordsFillInTheBlank[9] = 'p_th';
wordsFillInTheBlank[10] = '_pposite';
wordsFillInTheBlank[11] = 'ra_ine';
wordsFillInTheBlank[12] = '_upine';
wordsFillInTheBlank[13] = 'cr_ss';
wordsFillInTheBlank[14] = 'pr_scribe';
wordsFillInTheBlank[15] = 'm_sk';
wordsFillInTheBlank[16] = 'a_ert';

solutionsFillInTheBlank[0] = 'rn';
solutionsFillInTheBlank[1] = 'an';
solutionsFillInTheBlank[2] = 'au';
solutionsFillInTheBlank[3] = 'nl';
solutionsFillInTheBlank[4] = 'ih';
solutionsFillInTheBlank[5] = 'oe';
solutionsFillInTheBlank[6] = 'ua';
solutionsFillInTheBlank[7] = 'mf';
solutionsFillInTheBlank[8] = 'tlm';
solutionsFillInTheBlank[9] = 'ai';
solutionsFillInTheBlank[10] = 'oa';
solutionsFillInTheBlank[11] = 'vpn';
solutionsFillInTheBlank[12] = 'sl';
solutionsFillInTheBlank[13] = 'oa';
solutionsFillInTheBlank[14] = 'eo';
solutionsFillInTheBlank[15] = 'au';
solutionsFillInTheBlank[16] = 'lv';


var boggle = new Array();

boggle[0] = "res";
boggle[1] = "rest";
boggle[2] = "resting";
boggle[3] = "restart";
boggle[4] = "restarted";
boggle[5] = "restarts";
boggle[6] = "resin";
boggle[7] = "resinate";
boggle[8] = "resinates";
boggle[9] = "resinated";
boggle[10] = "resile";
boggle[11] = "resiles";
boggle[12] = "resiled";
boggle[13] = "ret";
boggle[14] = "rets";
boggle[15] = "retsina";
boggle[16] = "retsinas";
boggle[17] = "retia";
boggle[18] = "retial";
boggle[19] = "retine";
boggle[20] = "retines";
boggle[21] = "retina";
boggle[22] = "retinal";
boggle[23] = "retinae";
boggle[24] = "retinas";
boggle[25] = "retint";
boggle[26] = "retinted";
boggle[27] = "retints";
boggle[28] = "retire";
boggle[29] = "retires";
boggle[30] = "retired";
boggle[31] = "retain";
boggle[32] = "retail";
boggle[33] = "retailer";
boggle[34] = "retailers";
boggle[35] = "retailed";
boggle[36] = "retape";
boggle[37] = "retapes";
boggle[38] = "retaped";
boggle[39] = "red";
boggle[40] = "reds";
boggle[41] = "redstart";
boggle[42] = "redstarts";
boggle[43] = "redness";
boggle[44] = "rednesses";
boggle[45] = "rei";
boggle[46] = "reis";
boggle[47] = "rein";
boggle[48] = "reinless";
boggle[49] = "reinter";
boggle[50] = "reinters";
boggle[51] = "reg";
boggle[52] = "regna";
boggle[53] = "regnal";
boggle[54] = "regent";
boggle[55] = "regental";
boggle[56] = "regents";
boggle[57] = "reges";
boggle[58] = "regal";
boggle[59] = "regalia";
boggle[60] = "regale";
boggle[61] = "regaler";
boggle[62] = "regalers";
boggle[63] = "regales";
boggle[64] = "regaled";
boggle[65] = "rend";
boggle[66] = "rends";
boggle[67] = "renest";
boggle[68] = "renested";
boggle[69] = "renests";
boggle[70] = "renal";
boggle[71] = "rename";
boggle[72] = "renames";
boggle[73] = "rent";
boggle[74] = "rental";
boggle[75] = "rente";
boggle[76] = "renter";
boggle[77] = "renters";
boggle[78] = "rentes";
boggle[79] = "rented";
boggle[80] = "rents";
boggle[81] = "rentier";
boggle[82] = "rentiers";
boggle[83] = "relist";
boggle[84] = "relit";
boggle[85] = "relic";
boggle[86] = "relict";
boggle[87] = "relicts";
boggle[88] = "relics";
boggle[89] = "reline";
boggle[90] = "relines";
boggle[91] = "relating";
boggle[92] = "relacing";
boggle[93] = "relace";
boggle[94] = "relaces";
boggle[95] = "relapse";
boggle[96] = "relapser";
boggle[97] = "relapses";
boggle[98] = "relapsed";
boggle[99] = "relate";
boggle[100] = "relater";
boggle[101] = "relaters";
boggle[102] = "relates";
boggle[103] = "related";
boggle[104] = "relet";
boggle[105] = "relets";
boggle[106] = "stein";
boggle[107] = "stelic";
boggle[108] = "stela";
boggle[109] = "stelai";
boggle[110] = "stelae";
boggle[111] = "stelar";
boggle[112] = "stele";
boggle[113] = "steles";
boggle[114] = "stied";
boggle[115] = "sting";
boggle[116] = "stinger";
boggle[117] = "stint";
boggle[118] = "stinter";
boggle[119] = "stinters";
boggle[120] = "stinted";
boggle[121] = "stints";
boggle[122] = "stile";
boggle[123] = "stilt";
boggle[124] = "stilted";
boggle[125] = "stilts";
boggle[126] = "stiles";
boggle[127] = "stir";
boggle[128] = "stirp";
boggle[129] = "stirpes";
boggle[130] = "stirps";
boggle[131] = "stirs";
boggle[132] = "stain";
boggle[133] = "stainer";
boggle[134] = "stained";
boggle[135] = "stainless";
boggle[136] = "stair";
boggle[137] = "stairs";
boggle[138] = "stale";
boggle[139] = "staler";
boggle[140] = "staled";
boggle[141] = "staling";
boggle[142] = "stalag";
boggle[143] = "stales";
boggle[144] = "stalest";
boggle[145] = "star";
boggle[146] = "staring";
boggle[147] = "stare";
boggle[148] = "stares";
boggle[149] = "starling";
boggle[150] = "starlet";
boggle[151] = "starlets";
boggle[152] = "starless";
boggle[153] = "start";
boggle[154] = "startle";
boggle[155] = "startler";
boggle[156] = "startled";
boggle[157] = "startling";
boggle[158] = "startles";
boggle[159] = "started";
boggle[160] = "starts";
boggle[161] = "starets";
boggle[162] = "stared";
boggle[163] = "stars";
boggle[164] = "stapes";
boggle[165] = "ser";
boggle[166] = "set";
boggle[167] = "seta";
boggle[168] = "setae";
boggle[169] = "setal";
boggle[170] = "sedge";
boggle[171] = "sedges";
boggle[172] = "sei";
boggle[173] = "seine";
boggle[174] = "seines";
boggle[175] = "seg";
boggle[176] = "segni";
boggle[177] = "sen";
boggle[178] = "send";
boggle[179] = "senile";
boggle[180] = "seniles";
boggle[181] = "sene";
boggle[182] = "senega";
boggle[183] = "senegas";
boggle[184] = "senate";
boggle[185] = "senates";
boggle[186] = "sent";
boggle[187] = "senti";
boggle[188] = "sel";
boggle[189] = "sit";
boggle[190] = "site";
boggle[191] = "sited";
boggle[192] = "sitar";
boggle[193] = "sitars";
boggle[194] = "sic";
boggle[195] = "sics";
boggle[196] = "sice";
boggle[197] = "sices";
boggle[198] = "siege";
boggle[199] = "sieges";
boggle[200] = "sial";
boggle[201] = "sin";
boggle[202] = "sine";
boggle[203] = "sing";
boggle[204] = "singe";
boggle[205] = "singer";
boggle[206] = "singed";
boggle[207] = "singes";
boggle[208] = "sinless";
boggle[209] = "sines";
boggle[210] = "sinter";
boggle[211] = "sinters";
boggle[212] = "silent";
boggle[213] = "silenter";
boggle[214] = "silents";
boggle[215] = "silage";
boggle[216] = "silages";
boggle[217] = "silane";
boggle[218] = "silanes";
boggle[219] = "silt";
boggle[220] = "silted";
boggle[221] = "silts";
boggle[222] = "siltier";
boggle[223] = "sir";
boggle[224] = "sire";
boggle[225] = "sires";
boggle[226] = "sired";
boggle[227] = "sirs";
boggle[228] = "ted";
boggle[229] = "teds";
boggle[230] = "teind";
boggle[231] = "teinds";
boggle[232] = "teg";
boggle[233] = "ten";
boggle[234] = "tend";
boggle[235] = "tends";
boggle[236] = "tenia";
boggle[237] = "tenias";
boggle[238] = "teniae";
boggle[239] = "tent";
boggle[240] = "tentless";
boggle[241] = "tentage";
boggle[242] = "tentages";
boggle[243] = "tenter";
boggle[244] = "tenters";
boggle[245] = "tented";
boggle[246] = "tents";
boggle[247] = "tentie";
boggle[248] = "tentier";
boggle[249] = "tel";
boggle[250] = "telic";
boggle[251] = "telia";
boggle[252] = "tela";
boggle[253] = "telae";
boggle[254] = "tele";
boggle[255] = "teles";
boggle[256] = "telesis";
boggle[257] = "tis";
boggle[258] = "tic";
boggle[259] = "tics";
boggle[260] = "tical";
boggle[261] = "tie";
boggle[262] = "tier";
boggle[263] = "tiers";
boggle[264] = "ties";
boggle[265] = "tied";
boggle[266] = "tieless";
boggle[267] = "tin";
boggle[268] = "tinder";
boggle[269] = "tinders";
boggle[270] = "tine";
boggle[271] = "tines";
boggle[272] = "tined";
boggle[273] = "ting";
boggle[274] = "tinge";
boggle[275] = "tinges";
boggle[276] = "tinged";
boggle[277] = "tinea";
boggle[278] = "tineal";
boggle[279] = "tineas";
boggle[280] = "tint";
boggle[281] = "tintless";
boggle[282] = "tinter";
boggle[283] = "tinters";
boggle[284] = "tinted";
boggle[285] = "tints";
boggle[286] = "til";
boggle[287] = "tile";
boggle[288] = "tiler";
boggle[289] = "tilers";
boggle[290] = "tiles";
boggle[291] = "tiled";
boggle[292] = "tilt";
boggle[293] = "tilter";
boggle[294] = "tilters";
boggle[295] = "tilted";
boggle[296] = "tilts";
boggle[297] = "tire";
boggle[298] = "tires";
boggle[299] = "tirl";
boggle[300] = "tirled";
boggle[301] = "tired";
boggle[302] = "tace";
boggle[303] = "taces";
boggle[304] = "tas";
boggle[305] = "tain";
boggle[306] = "taint";
boggle[307] = "tainted";
boggle[308] = "taints";
boggle[309] = "tail";
boggle[310] = "tailer";
boggle[311] = "tailers";
boggle[312] = "tailed";
boggle[313] = "tae";
boggle[314] = "tale";
boggle[315] = "taler";
boggle[316] = "talers";
boggle[317] = "tales";
boggle[318] = "talent";
boggle[319] = "talented";
boggle[320] = "talents";
boggle[321] = "tali";
boggle[322] = "tala";
boggle[323] = "talas";
boggle[324] = "tar";
boggle[325] = "taring";
boggle[326] = "tare";
boggle[327] = "tares";
boggle[328] = "tarletan";
boggle[329] = "tarp";
boggle[330] = "tarps";
boggle[331] = "tart";
boggle[332] = "tartness";
boggle[333] = "tartnesses";
boggle[334] = "tartan";
boggle[335] = "tarted";
boggle[336] = "tarts";
boggle[337] = "tared";
boggle[338] = "tars";
boggle[339] = "tarsi";
boggle[340] = "tap";
boggle[341] = "tape";
boggle[342] = "tapes";
boggle[343] = "taper";
boggle[344] = "tapering";
boggle[345] = "tapered";
boggle[346] = "tapers";
boggle[347] = "tapeline";
boggle[348] = "tapelines";
boggle[349] = "tapeta";
boggle[350] = "tapetal";
boggle[351] = "tapestries";
boggle[352] = "tapestried";
boggle[353] = "taped";
boggle[354] = "taps";
boggle[355] = "cis";
boggle[356] = "cist";
boggle[357] = "cite";
boggle[358] = "citer";
boggle[359] = "citers";
boggle[360] = "cites";
boggle[361] = "cited";
boggle[362] = "cinder";
boggle[363] = "cinders";
boggle[364] = "cine";
boggle[365] = "cines";
boggle[366] = "cineast";
boggle[367] = "cineaste";
boggle[368] = "cineastes";
boggle[369] = "cineasts";
boggle[370] = "cinema";
boggle[371] = "cinemas";
boggle[372] = "cire";
boggle[373] = "cires";
boggle[374] = "cat";
boggle[375] = "cats";
boggle[376] = "cate";
boggle[377] = "cater";
boggle[378] = "caters";
boggle[379] = "cates";
boggle[380] = "catena";
boggle[381] = "catenae";
boggle[382] = "catenate";
boggle[383] = "catenates";
boggle[384] = "catenated";
boggle[385] = "catenas";
boggle[386] = "case";
boggle[387] = "cain";
boggle[388] = "calends";
boggle[389] = "calesa";
boggle[390] = "calesas";
boggle[391] = "car";
boggle[392] = "caries";
boggle[393] = "caried";
boggle[394] = "caring";
boggle[395] = "carina";
boggle[396] = "carinal";
boggle[397] = "carinae";
boggle[398] = "carinate";
boggle[399] = "carinas";
boggle[400] = "care";
boggle[401] = "cares";
boggle[402] = "carl";
boggle[403] = "carle";
boggle[404] = "carles";
boggle[405] = "carlin";
boggle[406] = "carline";
boggle[407] = "carlines";
boggle[408] = "carling";
boggle[409] = "carless";
boggle[410] = "carp";
boggle[411] = "carpel";
boggle[412] = "carpet";
boggle[413] = "carpets";
boggle[414] = "carped";
boggle[415] = "carps";
boggle[416] = "cart";
boggle[417] = "cartage";
boggle[418] = "cartages";
boggle[419] = "carte";
boggle[420] = "cartel";
boggle[421] = "cartes";
boggle[422] = "carted";
boggle[423] = "carts";
boggle[424] = "caret";
boggle[425] = "carets";
boggle[426] = "caress";
boggle[427] = "cared";
boggle[428] = "cars";
boggle[429] = "carse";
boggle[430] = "carses";
boggle[431] = "cap";
boggle[432] = "cape";
boggle[433] = "capes";
boggle[434] = "caper";
boggle[435] = "capering";
boggle[436] = "capered";
boggle[437] = "capers";
boggle[438] = "capris";
boggle[439] = "caprine";
boggle[440] = "capelet";
boggle[441] = "capelets";
boggle[442] = "capelin";
boggle[443] = "capelan";
boggle[444] = "caped";
boggle[445] = "caps";
boggle[446] = "capsid";
boggle[447] = "cerise";
boggle[448] = "cerite";
boggle[449] = "cerites";
boggle[450] = "ceria";
boggle[451] = "cerias";
boggle[452] = "cering";
boggle[453] = "cerate";
boggle[454] = "cerates";
boggle[455] = "cerated";
boggle[456] = "ceratin";
boggle[457] = "certes";
boggle[458] = "cere";
boggle[459] = "ceres";
boggle[460] = "cered";
boggle[461] = "cep";
boggle[462] = "cepe";
boggle[463] = "cepes";
boggle[464] = "ceps";
boggle[465] = "scat";
boggle[466] = "scats";
boggle[467] = "scale";
boggle[468] = "scaler";
boggle[469] = "scalers";
boggle[470] = "scales";
boggle[471] = "scaled";
boggle[472] = "scaleni";
boggle[473] = "scalene";
boggle[474] = "scalier";
boggle[475] = "scaliest";
boggle[476] = "scaling";
boggle[477] = "scalage";
boggle[478] = "scalages";
boggle[479] = "scar";
boggle[480] = "scarier";
boggle[481] = "scariest";
boggle[482] = "scaring";
boggle[483] = "scare";
boggle[484] = "scarlet";
boggle[485] = "scarlets";
boggle[486] = "scarless";
boggle[487] = "scarp";
boggle[488] = "scarped";
boggle[489] = "scarps";
boggle[490] = "scart";
boggle[491] = "scarted";
boggle[492] = "scarts";
boggle[493] = "scares";
boggle[494] = "scared";
boggle[495] = "scars";
boggle[496] = "scape";
boggle[497] = "scapes";
boggle[498] = "scaped";
boggle[499] = "sat";

boggle[500] = "sate";
boggle[501] = "sates";
boggle[502] = "sated";
boggle[503] = "sati";
boggle[504] = "satis";
boggle[505] = "satin";
boggle[506] = "sating";
boggle[507] = "satire";
boggle[508] = "satires";
boggle[509] = "sac";
boggle[510] = "saice";
boggle[511] = "sain";
boggle[512] = "sained";
boggle[513] = "saint";
boggle[514] = "sainted";
boggle[515] = "saints";
boggle[516] = "sail";
boggle[517] = "sailer";
boggle[518] = "sailers";
boggle[519] = "sailed";
boggle[520] = "sae";
boggle[521] = "sal";
boggle[522] = "sale";
boggle[523] = "sales";
boggle[524] = "salic";
boggle[525] = "salient";
boggle[526] = "salients";
boggle[527] = "saline";
boggle[528] = "salines";
boggle[529] = "salina";
boggle[530] = "salinas";
boggle[531] = "salt";
boggle[532] = "saltness";
boggle[533] = "saltnesses";
boggle[534] = "salter";
boggle[535] = "salters";
boggle[536] = "salted";
boggle[537] = "salts";
boggle[538] = "saltie";
boggle[539] = "saltier";
boggle[540] = "saltiers";
boggle[541] = "salties";
boggle[542] = "salep";
boggle[543] = "saleps";
boggle[544] = "sari";
boggle[545] = "saris";
boggle[546] = "sarin";
boggle[547] = "sap";
boggle[548] = "saps";
boggle[549] = "sec";
boggle[550] = "sect";
boggle[551] = "sects";
boggle[552] = "sectile";
boggle[553] = "sectaries";
boggle[554] = "sea";
boggle[555] = "seat";
boggle[556] = "seats";
boggle[557] = "seater";
boggle[558] = "seaters";
boggle[559] = "seated";
boggle[560] = "seating";
boggle[561] = "seal";
boggle[562] = "sealer";
boggle[563] = "sealers";
boggle[564] = "sealed";
boggle[565] = "sealing";
boggle[566] = "sealant";
boggle[567] = "sealants";
boggle[568] = "sealeries";
boggle[569] = "sear";
boggle[570] = "searing";
boggle[571] = "searest";
boggle[572] = "seared";
boggle[573] = "sears";
boggle[574] = "series";
boggle[575] = "seriate";
boggle[576] = "seriates";
boggle[577] = "seriated";
boggle[578] = "serial";
boggle[579] = "serin";
boggle[580] = "serine";
boggle[581] = "serines";
boggle[582] = "sering";
boggle[583] = "seringa";
boggle[584] = "seringas";
boggle[585] = "sera";
boggle[586] = "serac";
boggle[587] = "serai";
boggle[588] = "serais";
boggle[589] = "serail";
boggle[590] = "seral";
boggle[591] = "serape";
boggle[592] = "serapes";
boggle[593] = "sere";
boggle[594] = "seres";
boggle[595] = "serest";
boggle[596] = "sered";
boggle[597] = "sers";
boggle[598] = "sepal";
boggle[599] = "sepaled";
boggle[600] = "sepaline";
boggle[601] = "sepses";
boggle[602] = "sepsis";
boggle[603] = "drest";
boggle[604] = "dreg";
boggle[605] = "des";
boggle[606] = "destine";
boggle[607] = "destines";
boggle[608] = "destain";
boggle[609] = "desire";
boggle[610] = "desires";
boggle[611] = "desired";
boggle[612] = "detain";
boggle[613] = "detail";
boggle[614] = "detailer";
boggle[615] = "detailers";
boggle[616] = "detailed";
boggle[617] = "dei";
boggle[618] = "deist";
boggle[619] = "deice";
boggle[620] = "deices";
boggle[621] = "deicer";
boggle[622] = "deicers";
boggle[623] = "deil";
boggle[624] = "degame";
boggle[625] = "degames";
boggle[626] = "degas";
boggle[627] = "degasser";
boggle[628] = "degassers";
boggle[629] = "degasses";
boggle[630] = "degassed";
boggle[631] = "degases";
boggle[632] = "den";
boggle[633] = "denial";
boggle[634] = "dene";
boggle[635] = "denes";
boggle[636] = "dent";
boggle[637] = "dental";
boggle[638] = "dentalia";
boggle[639] = "dented";
boggle[640] = "dents";
boggle[641] = "del";
boggle[642] = "deli";
boggle[643] = "delis";
boggle[644] = "delist";
boggle[645] = "delict";
boggle[646] = "delicts";
boggle[647] = "delineate";
boggle[648] = "delineates";
boggle[649] = "delineated";
boggle[650] = "delating";
boggle[651] = "delaine";
boggle[652] = "delaines";
boggle[653] = "delate";
boggle[654] = "delates";
boggle[655] = "delated";
boggle[656] = "delta";
boggle[657] = "deltas";
boggle[658] = "dele";
boggle[659] = "deles";
boggle[660] = "deled";
boggle[661] = "ers";
boggle[662] = "erst";
boggle[663] = "etic";
boggle[664] = "eta";
boggle[665] = "etas";
boggle[666] = "etape";
boggle[667] = "etapes";
boggle[668] = "edge";
boggle[669] = "edges";
boggle[670] = "egest";
boggle[671] = "egesta";
boggle[672] = "egested";
boggle[673] = "egests";
boggle[674] = "egal";
boggle[675] = "end";
boggle[676] = "ends";
boggle[677] = "endgame";
boggle[678] = "endgames";
boggle[679] = "eng";
boggle[680] = "enlist";
boggle[681] = "enlace";
boggle[682] = "enlaces";
boggle[683] = "enema";
boggle[684] = "enemas";
boggle[685] = "enate";
boggle[686] = "enates";
boggle[687] = "entrap";
boggle[688] = "entraps";
boggle[689] = "entreat";
boggle[690] = "entreats";
boggle[691] = "entases";
boggle[692] = "entasis";
boggle[693] = "enter";
boggle[694] = "enteric";
boggle[695] = "entera";
boggle[696] = "enteral";
boggle[697] = "enters";
boggle[698] = "elint";
boggle[699] = "elints";
boggle[700] = "elating";
boggle[701] = "elain";
boggle[702] = "elapse";
boggle[703] = "elapses";
boggle[704] = "elapsed";
boggle[705] = "elan";
boggle[706] = "eland";
boggle[707] = "elands";
boggle[708] = "elate";
boggle[709] = "elater";
boggle[710] = "elaterin";
boggle[711] = "elaters";
boggle[712] = "elates";
boggle[713] = "elated";
boggle[714] = "its";
boggle[715] = "ice";
boggle[716] = "ices";
boggle[717] = "ingest";
boggle[718] = "ingesta";
boggle[719] = "ingested";
boggle[720] = "ingests";
boggle[721] = "ingate";
boggle[722] = "ingates";
boggle[723] = "inlet";
boggle[724] = "inlets";
boggle[725] = "inlace";
boggle[726] = "inlaces";
boggle[727] = "intreat";
boggle[728] = "intreats";
boggle[729] = "intreated";
boggle[730] = "inter";
boggle[731] = "interact";
boggle[732] = "interacts";
boggle[733] = "interacted";
boggle[734] = "interlace";
boggle[735] = "interlaces";
boggle[736] = "interlap";
boggle[737] = "interlaps";
boggle[738] = "inters";
boggle[739] = "inti";
boggle[740] = "intis";
boggle[741] = "irate";
boggle[742] = "irater";
boggle[743] = "ire";
boggle[744] = "ires";
boggle[745] = "ired";
boggle[746] = "ate";
boggle[747] = "ates";
boggle[748] = "atelic";
boggle[749] = "atilt";
boggle[750] = "act";
boggle[751] = "acts";
boggle[752] = "acted";
boggle[753] = "actin";
boggle[754] = "acting";
boggle[755] = "actinal";
boggle[756] = "acing";
boggle[757] = "ace";
boggle[758] = "aces";
boggle[759] = "asci";
boggle[760] = "ascites";
boggle[761] = "asepses";
boggle[762] = "asepsis";
boggle[763] = "ais";
boggle[764] = "ait";
boggle[765] = "aits";
boggle[766] = "ain";
boggle[767] = "ail";
boggle[768] = "ailed";
boggle[769] = "air";
boggle[770] = "airless";
boggle[771] = "airt";
boggle[772] = "airted";
boggle[773] = "airts";
boggle[774] = "airest";
boggle[775] = "aired";
boggle[776] = "airs";
boggle[777] = "aerie";
boggle[778] = "aerier";
boggle[779] = "aeries";
boggle[780] = "aeriest";
boggle[781] = "aeried";
boggle[782] = "ale";
boggle[783] = "ales";
boggle[784] = "alist";
boggle[785] = "alit";
boggle[786] = "alien";
boggle[787] = "alienage";
boggle[788] = "alienages";
boggle[789] = "alienate";
boggle[790] = "alienates";
boggle[791] = "alienated";
boggle[792] = "aline";
boggle[793] = "aliner";
boggle[794] = "aliners";
boggle[795] = "alines";
boggle[796] = "alined";
boggle[797] = "ala";
boggle[798] = "alan";
boggle[799] = "aland";
boggle[800] = "alands";
boggle[801] = "alane";
boggle[802] = "alang";
boggle[803] = "alant";
boggle[804] = "alants";
boggle[805] = "alae";
boggle[806] = "alate";
boggle[807] = "alates";
boggle[808] = "alated";
boggle[809] = "alas";
boggle[810] = "alt";
boggle[811] = "alter";
boggle[812] = "altering";
boggle[813] = "alters";
boggle[814] = "alts";
boggle[815] = "alert";
boggle[816] = "alertness";
boggle[817] = "alerts";
boggle[818] = "arise";
boggle[819] = "arisen";
boggle[820] = "ariel";
boggle[821] = "aril";
boggle[822] = "ariled";
boggle[823] = "are";
boggle[824] = "ares";
boggle[825] = "arles";
boggle[826] = "art";
boggle[827] = "artless";
boggle[828] = "artal";
boggle[829] = "artel";
boggle[830] = "arts";

boggle[831] = "artisan";
boggle[832] = "ars";
boggle[833] = "arse";
boggle[834] = "arses";
boggle[835] = "arsis";
boggle[836] = "ape";
boggle[837] = "apes";
boggle[838] = "aper";
boggle[839] = "aperies";
boggle[840] = "aperient";
boggle[841] = "aperients";
boggle[842] = "apers";
boggle[843] = "apres";
boggle[844] = "apetalies";
boggle[845] = "aped";
boggle[846] = "apse";
boggle[847] = "apses";
boggle[848] = "apsis";
boggle[849] = "apsides";
boggle[850] = "ecarte";
boggle[851] = "ecartes";
boggle[852] = "escalate";
boggle[853] = "escalates";
boggle[854] = "escalated";
boggle[855] = "escar";
boggle[856] = "escarp";
boggle[857] = "escarped";
boggle[858] = "escarps";
boggle[859] = "escars";
boggle[860] = "escape";
boggle[861] = "escaper";
boggle[862] = "escapers";
boggle[863] = "escapes";
boggle[864] = "escaped";
boggle[865] = "eat";
boggle[866] = "eats";
boggle[867] = "eater";
boggle[868] = "eaters";
boggle[869] = "eaten";
boggle[870] = "eating";
boggle[871] = "ear";
boggle[872] = "earing";
boggle[873] = "earl";
boggle[874] = "earlier";
boggle[875] = "earliest";
boggle[876] = "earless";
boggle[877] = "eared";
boggle[878] = "ears";
boggle[879] = "erica";
boggle[880] = "ericas";
boggle[881] = "era";
boggle[882] = "eras";
boggle[883] = "ere";
boggle[884] = "erses";
boggle[885] = "epact";
boggle[886] = "epacts";
boggle[887] = "gest";
boggle[888] = "gestic";
boggle[889] = "gestical";
boggle[890] = "gestalt";
boggle[891] = "gestalts";
boggle[892] = "get";
boggle[893] = "gets";
boggle[894] = "geta";
boggle[895] = "getas";
boggle[896] = "ged";
boggle[897] = "geds";
boggle[898] = "genital";
boggle[899] = "genic";
boggle[900] = "genial";
boggle[901] = "gene";
boggle[902] = "genes";
boggle[903] = "gent";
boggle[904] = "gentle";
boggle[905] = "gentler";
boggle[906] = "gentles";
boggle[907] = "gentled";
boggle[908] = "gentrice";
boggle[909] = "gentrices";
boggle[910] = "gentes";
boggle[911] = "gents";
boggle[912] = "gel";
boggle[913] = "gelati";
boggle[914] = "gelatin";
boggle[915] = "gelatine";
boggle[916] = "gelatines";
boggle[917] = "gelant";
boggle[918] = "gelants";
boggle[919] = "gelate";
boggle[920] = "gelates";
boggle[921] = "gelated";
boggle[922] = "gelt";
boggle[923] = "gelts";
boggle[924] = "gnat";
boggle[925] = "gnats";
boggle[926] = "gender";
boggle[927] = "genders";
boggle[928] = "genet";
boggle[929] = "genets";
boggle[930] = "genetic";
boggle[931] = "genetics";
boggle[932] = "genie";
boggle[933] = "genies";
boggle[934] = "gentlest";
boggle[935] = "gentries";
boggle[936] = "gem";
boggle[937] = "gems";
boggle[938] = "geste";
boggle[939] = "gestes";
boggle[940] = "gests";
boggle[941] = "gan";
boggle[942] = "gander";
boggle[943] = "ganders";
boggle[944] = "gane";
boggle[945] = "ganister";
boggle[946] = "gantlet";
boggle[947] = "gantlets";
boggle[948] = "gantries";
boggle[949] = "gal";
boggle[950] = "gale";
boggle[951] = "gales";
boggle[952] = "galenic";
boggle[953] = "gala";
boggle[954] = "galas";
boggle[955] = "galere";
boggle[956] = "galeres";
boggle[957] = "gae";
boggle[958] = "gaen";
boggle[959] = "gaes";
boggle[960] = "gat";
boggle[961] = "gate";
boggle[962] = "gates";
boggle[963] = "gated";
boggle[964] = "gats";
boggle[965] = "gam";
boggle[966] = "game";
boggle[967] = "games";
boggle[968] = "gamest";
boggle[969] = "gamester";
boggle[970] = "gamesters";
boggle[971] = "gams";
boggle[972] = "gas";
boggle[973] = "gast";
boggle[974] = "gastric";
boggle[975] = "gastrin";
boggle[976] = "gastral";
boggle[977] = "gastrea";
boggle[978] = "gastreas";
boggle[979] = "gaster";
boggle[980] = "gasters";
boggle[981] = "gasted";
boggle[982] = "gasts";
boggle[983] = "gasmen";
boggle[984] = "gasser";
boggle[985] = "gassers";
boggle[986] = "gasses";
boggle[987] = "gassed";
boggle[988] = "gassier";
boggle[989] = "gaselier";
boggle[990] = "gaseliers";
boggle[991] = "gases";
boggle[992] = "nerd";
boggle[993] = "nerds";
boggle[994] = "nest";
boggle[995] = "net";
boggle[996] = "nets";
boggle[997] = "neist";
boggle[998] = "negate";
boggle[999] = "negater";
boggle[1000] = "negaters";
boggle[1001] = "negates";
boggle[1002] = "negated";
boggle[1003] = "nit";
boggle[1004] = "nits";
boggle[1005] = "niter";
boggle[1006] = "niters";
boggle[1007] = "nice";
boggle[1008] = "nicer";
boggle[1009] = "nil";
boggle[1010] = "neat";
boggle[1011] = "neater";
boggle[1012] = "neats";
boggle[1013] = "nema";
boggle[1014] = "nemas";
boggle[1015] = "nestle";
boggle[1016] = "nestler";
boggle[1017] = "nestlers";
boggle[1018] = "nestles";
boggle[1019] = "nestled";
boggle[1020] = "nester";
boggle[1021] = "nesters";
boggle[1022] = "nested";
boggle[1023] = "nests";
boggle[1024] = "ness";
boggle[1025] = "nesses";
boggle[1026] = "nag";
boggle[1027] = "naled";
boggle[1028] = "naleds";
boggle[1029] = "nae";
boggle[1030] = "nates";
boggle[1031] = "nam";
boggle[1032] = "name";
boggle[1033] = "names";
boggle[1034] = "nastier";
boggle[1035] = "nasties";
boggle[1036] = "lest";
boggle[1037] = "let";
boggle[1038] = "lets";
boggle[1039] = "led";
boggle[1040] = "ledge";
boggle[1041] = "ledges";
boggle[1042] = "lei";
boggle[1043] = "leis";
boggle[1044] = "leg";
boggle[1045] = "legend";
boggle[1046] = "legends";
boggle[1047] = "leges";
boggle[1048] = "legate";
boggle[1049] = "legates";
boggle[1050] = "legated";
boggle[1051] = "lend";
boggle[1052] = "lends";
boggle[1053] = "lenis";
boggle[1054] = "lenes";
boggle[1055] = "lent";
boggle[1056] = "lis";
boggle[1057] = "list";
boggle[1058] = "lister";
boggle[1059] = "listed";
boggle[1060] = "listen";
boggle[1061] = "lisente";
boggle[1062] = "lit";
boggle[1063] = "lits";
boggle[1064] = "liter";
boggle[1065] = "liters";
boggle[1066] = "litas";
boggle[1067] = "lice";
boggle[1068] = "lie";
boggle[1069] = "lier";
boggle[1070] = "liers";
boggle[1071] = "lies";
boggle[1072] = "lied";
boggle[1073] = "liege";
boggle[1074] = "liegeman";
boggle[1075] = "lieges";
boggle[1076] = "lien";
boggle[1077] = "liar";
boggle[1078] = "liars";
boggle[1079] = "lin";
boggle[1080] = "line";
boggle[1081] = "liner";
boggle[1082] = "liners";
boggle[1083] = "lines";
boggle[1084] = "lined";
boggle[1085] = "ling";
boggle[1086] = "linger";
boggle[1087] = "lingers";
boggle[1088] = "linga";
boggle[1089] = "lingam";
boggle[1090] = "lingams";
boggle[1091] = "lingas";
boggle[1092] = "lineage";
boggle[1093] = "lineages";
boggle[1094] = "lineate";
boggle[1095] = "lineated";
boggle[1096] = "linage";
boggle[1097] = "linages";
boggle[1098] = "lint";
boggle[1099] = "linter";
boggle[1100] = "linters";
boggle[1101] = "lints";
boggle[1102] = "lintier";
boggle[1103] = "lira";
boggle[1104] = "liras";
boggle[1105] = "lire";
boggle[1106] = "lat";
boggle[1107] = "lats";
boggle[1108] = "late";
boggle[1109] = "later";
boggle[1110] = "lated";
boggle[1111] = "laten";
boggle[1112] = "lateness";
boggle[1113] = "latenesses";
boggle[1114] = "latent";
boggle[1115] = "latents";
boggle[1116] = "lati";
boggle[1117] = "latices";
boggle[1118] = "lac";
boggle[1119] = "lacs";
boggle[1120] = "lacier";
boggle[1121] = "laciest";
boggle[1122] = "lacing";
boggle[1123] = "laciness";
boggle[1124] = "lacinesses";
boggle[1125] = "lace";
boggle[1126] = "laces";
boggle[1127] = "lacer";
boggle[1128] = "lacertid";
boggle[1129] = "lacertids";
boggle[1130] = "lacers";
boggle[1131] = "las";
boggle[1132] = "lase";
boggle[1133] = "laser";
boggle[1134] = "lasers";
boggle[1135] = "laic";
boggle[1136] = "laics";
boggle[1137] = "lain";
boggle[1138] = "lair";
boggle[1139] = "laired";
boggle[1140] = "lairs";
boggle[1141] = "lar";
boggle[1142] = "lari";
boggle[1143] = "laris";
boggle[1144] = "larine";
boggle[1145] = "lares";
boggle[1146] = "lars";
boggle[1147] = "lap";
boggle[1148] = "laps";
boggle[1149] = "lapse";
boggle[1150] = "lapser";
boggle[1151] = "lapses";
boggle[1152] = "lapsed";
boggle[1153] = "lag";
boggle[1154] = "lager";
boggle[1155] = "lagers";
boggle[1156] = "lagend";
boggle[1157] = "lagends";
boggle[1158] = "land";
boggle[1159] = "lands";
boggle[1160] = "lander";
boggle[1161] = "landers";
boggle[1162] = "lane";
boggle[1163] = "lanes";
boggle[1164] = "lang";
boggle[1165] = "latria";
boggle[1166] = "latrias";
boggle[1167] = "latrine";
boggle[1168] = "latrines";
boggle[1169] = "laterite";
boggle[1170] = "laterites";
boggle[1171] = "lam";
boggle[1172] = "lame";
boggle[1173] = "lament";
boggle[1174] = "lamenter";
boggle[1175] = "lamenters";
boggle[1176] = "lamented";
boggle[1177] = "laments";
boggle[1178] = "lames";
boggle[1179] = "lamest";
boggle[1180] = "lams";
boggle[1181] = "lamster";
boggle[1182] = "lamsters";
boggle[1183] = "last";
boggle[1184] = "laster";
boggle[1185] = "lasters";
boggle[1186] = "lasted";
boggle[1187] = "lasts";
boggle[1188] = "lass";
boggle[1189] = "lasses";
boggle[1190] = "lassie";
boggle[1191] = "lassies";
boggle[1192] = "lases";
boggle[1193] = "lased";
boggle[1194] = "leper";
boggle[1195] = "lepers";
boggle[1196] = "less";
boggle[1197] = "lessen";
boggle[1198] = "lessened";
boggle[1199] = "rise";
boggle[1200] = "riser";
boggle[1201] = "risen";
boggle[1202] = "rite";
boggle[1203] = "rites";
boggle[1204] = "rictal";
boggle[1205] = "rice";
boggle[1206] = "rices";
boggle[1207] = "riel";
boggle[1208] = "ria";
boggle[1209] = "rias";
boggle[1210] = "rial";
boggle[1211] = "rin";
boggle[1212] = "rind";
boggle[1213] = "rinds";
boggle[1214] = "ring";
boggle[1215] = "ringer";
boggle[1216] = "ringers";
boggle[1217] = "ringed";
boggle[1218] = "rile";
boggle[1219] = "riles";
boggle[1220] = "riled";
boggle[1221] = "rat";
boggle[1222] = "rats";
boggle[1223] = "rate";
boggle[1224] = "rater";
boggle[1225] = "raters";
boggle[1226] = "rates";
boggle[1227] = "rated";
boggle[1228] = "ratel";
boggle[1229] = "ratine";
boggle[1230] = "ratines";
boggle[1231] = "rating";
boggle[1232] = "racist";
boggle[1233] = "racier";
boggle[1234] = "raciest";
boggle[1235] = "racing";
boggle[1236] = "raciness";
boggle[1237] = "racinesses";
boggle[1238] = "race";
boggle[1239] = "races";
boggle[1240] = "ras";
boggle[1241] = "rase";
boggle[1242] = "raise";
boggle[1243] = "raiser";
boggle[1244] = "raised";
boggle[1245] = "rain";
boggle[1246] = "rained";
boggle[1247] = "rainless";
boggle[1248] = "rail";
boggle[1249] = "railer";
boggle[1250] = "railers";
boggle[1251] = "railed";
boggle[1252] = "rale";
boggle[1253] = "rales";
boggle[1254] = "rap";
boggle[1255] = "rape";
boggle[1256] = "rapes";
boggle[1257] = "raped";
boggle[1258] = "raps";
boggle[1259] = "rec";
boggle[1260] = "recti";
boggle[1261] = "recta";
boggle[1262] = "rectal";
boggle[1263] = "recs";
boggle[1264] = "recite";
boggle[1265] = "reciter";
boggle[1266] = "reciters";
boggle[1267] = "recites";
boggle[1268] = "recited";
boggle[1269] = "recital";
boggle[1270] = "recap";
boggle[1271] = "recaps";
boggle[1272] = "rescind";
boggle[1273] = "rescinds";
boggle[1274] = "rescinder";
boggle[1275] = "rescinders";
boggle[1276] = "rescale";
boggle[1277] = "rescales";
boggle[1278] = "rescaled";
boggle[1279] = "rescaling";
boggle[1280] = "resail";
boggle[1281] = "resailed";
boggle[1282] = "resale";
boggle[1283] = "resales";
boggle[1284] = "react";
boggle[1285] = "reacts";
boggle[1286] = "reacted";
boggle[1287] = "reacting";
boggle[1288] = "real";
boggle[1289] = "realer";
boggle[1290] = "reales";
boggle[1291] = "realest";
boggle[1292] = "realist";
boggle[1293] = "realise";
boggle[1294] = "realiser";
boggle[1295] = "realised";
boggle[1296] = "realness";
boggle[1297] = "realnesses";
boggle[1298] = "realties";
boggle[1299] = "reap";
boggle[1300] = "reaped";
boggle[1301] = "reaps";
boggle[1302] = "rep";
boggle[1303] = "repaint";
boggle[1304] = "repainted";
boggle[1305] = "repaints";
boggle[1306] = "repel";
boggle[1307] = "reps";
boggle[1308] = "relend";
boggle[1309] = "relends";
boggle[1310] = "relent";
boggle[1311] = "relents";
boggle[1312] = "relisted";
boggle[1313] = "relier";
boggle[1314] = "reliers";
boggle[1315] = "relies";
boggle[1316] = "relied";
boggle[1317] = "relined";
boggle[1318] = "repeat";
boggle[1319] = "repeats";
boggle[1320] = "repeater";
boggle[1321] = "repeaters";
boggle[1322] = "repeated";
boggle[1323] = "repeating";
boggle[1324] = "repeal";
boggle[1325] = "repealer";
boggle[1326] = "repealers";
boggle[1327] = "repealed";
boggle[1328] = "repealing";
boggle[1329] = "retag";
boggle[1330] = "retaliate";
boggle[1331] = "retaliates";
boggle[1332] = "retaliated";
boggle[1333] = "respace";
boggle[1334] = "respaces";
boggle[1335] = "respect";
boggle[1336] = "respects";
boggle[1337] = "respecter";
boggle[1338] = "respecters";
boggle[1339] = "respected";
boggle[1340] = "respecting";
boggle[1341] = "resist";
boggle[1342] = "resists";
boggle[1343] = "resid";
boggle[1344] = "restage";
boggle[1345] = "restages";
boggle[1346] = "restaged";
boggle[1347] = "rests";
boggle[1348] = "resids";
boggle[1349] = "pat";
boggle[1350] = "pats";
boggle[1351] = "pate";
boggle[1352] = "pater";
boggle[1353] = "paters";
boggle[1354] = "pates";
boggle[1355] = "pated";
boggle[1356] = "paten";
boggle[1357] = "patent";
boggle[1358] = "patented";
boggle[1359] = "patents";
boggle[1360] = "patient";
boggle[1361] = "patienter";
boggle[1362] = "patients";
boggle[1363] = "patin";
boggle[1364] = "patine";
boggle[1365] = "patines";
boggle[1366] = "patined";
boggle[1367] = "patina";
boggle[1368] = "patinae";
boggle[1369] = "patinate";
boggle[1370] = "patinas";
boggle[1371] = "pac";
boggle[1372] = "pact";
boggle[1373] = "pacts";
boggle[1374] = "pacs";
boggle[1375] = "pacing";
boggle[1376] = "pace";
boggle[1377] = "paces";
boggle[1378] = "pacer";
boggle[1379] = "pacers";
boggle[1380] = "pas";
boggle[1381] = "pase";
boggle[1382] = "paise";
boggle[1383] = "pain";
boggle[1384] = "pained";
boggle[1385] = "painless";
boggle[1386] = "paint";
boggle[1387] = "painter";
boggle[1388] = "painters";
boggle[1389] = "painted";
boggle[1390] = "paints";
boggle[1391] = "paintier";
boggle[1392] = "pail";
boggle[1393] = "pair";
boggle[1394] = "paired";
boggle[1395] = "pairs";
boggle[1396] = "pal";
boggle[1397] = "pale";
boggle[1398] = "paler";
boggle[1399] = "pales";
boggle[1400] = "palest";
boggle[1401] = "palet";
boggle[1402] = "palets";
boggle[1403] = "paled";
boggle[1404] = "paleness";
boggle[1405] = "palenesses";
boggle[1406] = "palier";
boggle[1407] = "paliest";
boggle[1408] = "paling";
boggle[1409] = "palate";
boggle[1410] = "palates";
boggle[1411] = "paltrier";
boggle[1412] = "paltriest";
boggle[1413] = "palter";
boggle[1414] = "paltering";
boggle[1415] = "palters";
boggle[1416] = "par";
boggle[1417] = "paris";
boggle[1418] = "paries";
boggle[1419] = "paring";
boggle[1420] = "pare";
boggle[1421] = "pares";
boggle[1422] = "parle";
boggle[1423] = "parles";
boggle[1424] = "parled";
boggle[1425] = "parling";
boggle[1426] = "parlante";
boggle[1427] = "part";
boggle[1428] = "partner";
boggle[1429] = "partners";
boggle[1430] = "partlet";
boggle[1431] = "partlets";
boggle[1432] = "partan";
boggle[1433] = "parted";
boggle[1434] = "parts";
boggle[1435] = "parties";
boggle[1436] = "partied";
boggle[1437] = "partisan";
boggle[1438] = "paresis";
boggle[1439] = "pared";
boggle[1440] = "pars";
boggle[1441] = "parse";
boggle[1442] = "parses";
boggle[1443] = "parsed";
boggle[1444] = "pecten";
boggle[1445] = "pectin";
boggle[1446] = "pectines";
boggle[1447] = "pecs";
boggle[1448] = "pes";
boggle[1449] = "pea";
boggle[1450] = "peat";
boggle[1451] = "peats";
boggle[1452] = "peatier";
boggle[1453] = "peacing";
boggle[1454] = "peas";
boggle[1455] = "peal";
boggle[1456] = "pealed";
boggle[1457] = "pealing";
boggle[1458] = "pear";
boggle[1459] = "pearl";
boggle[1460] = "pearler";
boggle[1461] = "pearlers";
boggle[1462] = "pearled";
boggle[1463] = "pearlite";
boggle[1464] = "pearlites";
boggle[1465] = "pearlier";
boggle[1466] = "pearliest";
boggle[1467] = "pearling";
boggle[1468] = "peart";
boggle[1469] = "pears";
boggle[1470] = "per";
boggle[1471] = "peri";
boggle[1472] = "peris";
boggle[1473] = "perinea";
boggle[1474] = "perineal";
boggle[1475] = "peril";
boggle[1476] = "periled";
boggle[1477] = "perlite";
boggle[1478] = "perlites";
boggle[1479] = "pert";
boggle[1480] = "pertness";
boggle[1481] = "pertnesses";
boggle[1482] = "perse";
boggle[1483] = "perses";
boggle[1484] = "persist";
boggle[1485] = "persisted";
boggle[1486] = "persists";
boggle[1487] = "prise";
boggle[1488] = "prised";
boggle[1489] = "price";
boggle[1490] = "prices";
boggle[1491] = "prier";
boggle[1492] = "priers";
boggle[1493] = "pries";
boggle[1494] = "priest";
boggle[1495] = "pried";
boggle[1496] = "print";
boggle[1497] = "printed";
boggle[1498] = "prints";
boggle[1499] = "prat";
boggle[1500] = "prats";
boggle[1501] = "prate";
boggle[1502] = "prater";
boggle[1503] = "praters";
boggle[1504] = "prates";
boggle[1505] = "prated";
boggle[1506] = "prating";
boggle[1507] = "practise";
boggle[1508] = "practised";
boggle[1509] = "prase";
boggle[1510] = "praise";
boggle[1511] = "praiser";
boggle[1512] = "praised";
boggle[1513] = "praline";
boggle[1514] = "pralines";
boggle[1515] = "precis";
boggle[1516] = "precise";
boggle[1517] = "preciser";
boggle[1518] = "precised";
boggle[1519] = "preciseness";
boggle[1520] = "precisenesses";
boggle[1521] = "precited";
boggle[1522] = "prescient";
boggle[1523] = "prescind";
boggle[1524] = "prescinds";
boggle[1525] = "presa";
boggle[1526] = "presale";
boggle[1527] = "preact";
boggle[1528] = "preacts";
boggle[1529] = "preacted";
boggle[1530] = "preacting";
boggle[1531] = "prelate";
boggle[1532] = "prelates";
boggle[1533] = "prelatic";
boggle[1534] = "prelacies";
boggle[1535] = "presage";
boggle[1536] = "presager";
boggle[1537] = "presagers";
boggle[1538] = "presages";
boggle[1539] = "presaged";
boggle[1540] = "prest";
boggle[1541] = "prests";
boggle[1542] = "press";
boggle[1543] = "pressmen";
boggle[1544] = "pressman";
boggle[1545] = "pele";
boggle[1546] = "peles";
boggle[1547] = "pelite";
boggle[1548] = "pelites";
boggle[1549] = "pelage";
boggle[1550] = "pelages";
boggle[1551] = "pelt";
boggle[1552] = "peltries";
boggle[1553] = "pelts";
boggle[1554] = "perea";
boggle[1555] = "pet";
boggle[1556] = "petal";
boggle[1557] = "petaled";
boggle[1558] = "petaline";
boggle[1559] = "pets";
boggle[1560] = "pest";
boggle[1561] = "pestle";
boggle[1562] = "pestles";
boggle[1563] = "pestled";
boggle[1564] = "pestling";
boggle[1565] = "pests";
boggle[1566] = "ped";
boggle[1567] = "peds";
boggle[1568] = "psi";
boggle[1569] = "psis";
boggle[1570] = "eger";
boggle[1571] = "egers";
boggle[1572] = "egalite";
boggle[1573] = "egalites";
boggle[1574] = "ender";
boggle[1575] = "enders";
boggle[1576] = "enlister";
boggle[1577] = "enlisted";
boggle[1578] = "entries";
boggle[1579] = "entreated";
boggle[1580] = "entreaties";
boggle[1581] = "eager";
boggle[1582] = "eagers";
boggle[1583] = "eateries";
boggle[1584] = "east";
boggle[1585] = "easter";
boggle[1586] = "easterlies";
boggle[1587] = "easters";
boggle[1588] = "easts";
boggle[1589] = "ease";
boggle[1590] = "easel";
boggle[1591] = "eases";
boggle[1592] = "eased";
boggle[1593] = "easier";
boggle[1594] = "easies";
boggle[1595] = "ems";
boggle[1596] = "estrin";
boggle[1597] = "estral";
boggle[1598] = "estreat";
boggle[1599] = "estreats";
boggle[1600] = "estreated";
boggle[1601] = "estreating";
boggle[1602] = "ester";
boggle[1603] = "esterase";
boggle[1604] = "esters";
boggle[1605] = "ess";
boggle[1606] = "esses";
boggle[1607] = "age";
boggle[1608] = "ager";
boggle[1609] = "agers";
boggle[1610] = "ages";
boggle[1611] = "aged";
boggle[1612] = "agedness";
boggle[1613] = "agednesses";
boggle[1614] = "ageist";
boggle[1615] = "agene";
boggle[1616] = "agenes";
boggle[1617] = "agent";
boggle[1618] = "agents";
boggle[1619] = "ageless";
boggle[1620] = "agenesia";
boggle[1621] = "agenesias";
boggle[1622] = "agenetic";
boggle[1623] = "agentries";
boggle[1624] = "and";
boggle[1625] = "ands";
boggle[1626] = "ane";
boggle[1627] = "anes";
boggle[1628] = "anele";
boggle[1629] = "aneles";
boggle[1630] = "aneled";
boggle[1631] = "ani";
boggle[1632] = "anis";
boggle[1633] = "anise";
boggle[1634] = "anil";
boggle[1635] = "anile";
boggle[1636] = "anger";
boggle[1637] = "angers";
boggle[1638] = "angel";
boggle[1639] = "angelic";
boggle[1640] = "angelica";
boggle[1641] = "angelicas";
boggle[1642] = "angeled";
boggle[1643] = "anlace";
boggle[1644] = "anlaces";
boggle[1645] = "anlas";
boggle[1646] = "anestri";
boggle[1647] = "ant";
boggle[1648] = "antler";
boggle[1649] = "antlers";
boggle[1650] = "antra";
boggle[1651] = "antral";
boggle[1652] = "antre";
boggle[1653] = "antres";
boggle[1654] = "ante";
boggle[1655] = "antes";
boggle[1656] = "anted";
boggle[1657] = "ants";
boggle[1658] = "antsier";
boggle[1659] = "anti";
boggle[1660] = "antis";
boggle[1661] = "antisera";
boggle[1662] = "alias";
boggle[1663] = "alar";
boggle[1664] = "atlas";
boggle[1665] = "atria";
boggle[1666] = "atrial";
boggle[1667] = "atelier";
boggle[1668] = "ateliers";
boggle[1669] = "amen";
boggle[1670] = "amend";
boggle[1671] = "amends";
boggle[1672] = "amender";
boggle[1673] = "amenders";
boggle[1674] = "ament";
boggle[1675] = "aments";
boggle[1676] = "astrict";
boggle[1677] = "astricts";
boggle[1678] = "astricted";
boggle[1679] = "astringe";
boggle[1680] = "astringes";
boggle[1681] = "astringed";
boggle[1682] = "astral";
boggle[1683] = "aster";
boggle[1684] = "asteria";
boggle[1685] = "asterias";
boggle[1686] = "asters";
boggle[1687] = "ass";
boggle[1688] = "assert";
boggle[1689] = "asset";
boggle[1690] = "asses";
boggle[1691] = "assent";
boggle[1692] = "assenter";
boggle[1693] = "assenters";
boggle[1694] = "assented";
boggle[1695] = "aside";
boggle[1696] = "asides";
boggle[1697] = "triste";
boggle[1698] = "trite";
boggle[1699] = "triter";
boggle[1700] = "trice";
boggle[1701] = "trices";
boggle[1702] = "triceps";
boggle[1703] = "tricepses";
boggle[1704] = "trier";
boggle[1705] = "triers";
boggle[1706] = "tries";
boggle[1707] = "tried";
boggle[1708] = "triene";
boggle[1709] = "trienes";
boggle[1710] = "triac";
boggle[1711] = "triacs";
boggle[1712] = "trial";
boggle[1713] = "trine";
boggle[1714] = "trines";
boggle[1715] = "trined";
boggle[1716] = "trinal";
boggle[1717] = "tract";
boggle[1718] = "tracts";
boggle[1719] = "tractile";
boggle[1720] = "tracing";
boggle[1721] = "trace";
boggle[1722] = "traces";
boggle[1723] = "trait";
boggle[1724] = "traits";
boggle[1725] = "train";
boggle[1726] = "trainer";
boggle[1727] = "trainers";
boggle[1728] = "trained";
boggle[1729] = "trail";
boggle[1730] = "trailer";
boggle[1731] = "trailers";
boggle[1732] = "trailed";
boggle[1733] = "trap";
boggle[1734] = "trapes";
boggle[1735] = "traps";
boggle[1736] = "treat";
boggle[1737] = "treats";
boggle[1738] = "treater";
boggle[1739] = "treaters";
boggle[1740] = "treated";
boggle[1741] = "treatise";
boggle[1742] = "treaties";
boggle[1743] = "treating";
boggle[1744] = "tress";
boggle[1745] = "tag";
boggle[1746] = "tan";
boggle[1747] = "tanist";
boggle[1748] = "tang";
boggle[1749] = "tanged";
boggle[1750] = "talar";
boggle[1751] = "talars";
boggle[1752] = "taenia";
boggle[1753] = "taenias";
boggle[1754] = "taeniae";
boggle[1755] = "tam";
boggle[1756] = "tame";
boggle[1757] = "tames";
boggle[1758] = "tams";
boggle[1759] = "tass";
boggle[1760] = "tasse";
boggle[1761] = "tassel";
boggle[1762] = "tasseled";
boggle[1763] = "tasseling";
boggle[1764] = "tasses";
boggle[1765] = "tassie";
boggle[1766] = "tassies";
boggle[1767] = "telestic";
boggle[1768] = "telega";
boggle[1769] = "telegas";
boggle[1770] = "terai";
boggle[1771] = "terais";
boggle[1772] = "tepa";
boggle[1773] = "tepas";
boggle[1774] = "tepal";
boggle[1775] = "tiering";
boggle[1776] = "tisane";
boggle[1777] = "tisanes";
boggle[1778] = "tide";
boggle[1779] = "tideland";
boggle[1780] = "tidelands";
boggle[1781] = "tides";
boggle[1782] = "elegant";
boggle[1783] = "elite";
boggle[1784] = "elites";
boggle[1785] = "erase";
boggle[1786] = "erect";
boggle[1787] = "erects";
boggle[1788] = "erecter";
boggle[1789] = "erecters";
boggle[1790] = "erected";
boggle[1791] = "erecting";
boggle[1792] = "erectile";
boggle[1793] = "etna";
boggle[1794] = "etnas";
boggle[1795] = "espalier";
boggle[1796] = "espaliers";
boggle[1797] = "especial";
boggle[1798] = "esprit";
boggle[1799] = "esprits";
boggle[1800] = "edit";
boggle[1801] = "edits";
boggle[1802] = "sri";
boggle[1803] = "sris";
boggle[1804] = "spa";
boggle[1805] = "spat";
boggle[1806] = "spats";
boggle[1807] = "spate";
boggle[1808] = "spates";
boggle[1809] = "spacier";
boggle[1810] = "spaciest";
boggle[1811] = "spacing";
boggle[1812] = "space";
boggle[1813] = "spaces";
boggle[1814] = "spacer";
boggle[1815] = "spas";
boggle[1816] = "spait";
boggle[1817] = "spaits";
boggle[1818] = "spail";
boggle[1819] = "spae";
boggle[1820] = "spaes";
boggle[1821] = "spale";
boggle[1822] = "spales";
boggle[1823] = "spar";
boggle[1824] = "sparing";
boggle[1825] = "spare";
boggle[1826] = "spares";
boggle[1827] = "sparling";
boggle[1828] = "sparest";
boggle[1829] = "spared";
boggle[1830] = "spec";
boggle[1831] = "specter";
boggle[1832] = "specters";
boggle[1833] = "specs";
boggle[1834] = "specie";
boggle[1835] = "species";
boggle[1836] = "speciate";
boggle[1837] = "speciates";
boggle[1838] = "speciated";
boggle[1839] = "special";
boggle[1840] = "specialer";
boggle[1841] = "specialest";
boggle[1842] = "specialties";
boggle[1843] = "spear";
boggle[1844] = "spearing";
boggle[1845] = "speared";
boggle[1846] = "sprit";
boggle[1847] = "sprits";
boggle[1848] = "sprite";
boggle[1849] = "sprites";
boggle[1850] = "sprier";
boggle[1851] = "spriest";
boggle[1852] = "spring";
boggle[1853] = "springe";
boggle[1854] = "springer";
boggle[1855] = "springers";
boggle[1856] = "springes";
boggle[1857] = "springed";
boggle[1858] = "springal";
boggle[1859] = "sprint";
boggle[1860] = "sprinted";
boggle[1861] = "sprints";
boggle[1862] = "sprat";
boggle[1863] = "sprats";
boggle[1864] = "sprain";
boggle[1865] = "sprained";
boggle[1866] = "spelt";
boggle[1867] = "spelts";
boggle[1868] = "speiss";
boggle[1869] = "sped";
boggle[1870] = "selenic";
boggle[1871] = "seracs";
boggle[1872] = "setline";
boggle[1873] = "setlines";
boggle[1874] = "sets";
boggle[1875] = "sesame";
boggle[1876] = "sesames";
boggle[1877] = "seis";
boggle[1878] = "sites";
boggle[1879] = "sits";
boggle[1880] = "siesta";
boggle[1881] = "siestas";
boggle[1882] = "sis";
boggle[1883] = "sisal";
boggle[1884] = "sistra";
boggle[1885] = "sister";
boggle[1886] = "sistering";
boggle[1887] = "side";
boggle[1888] = "sideline";
boggle[1889] = "sidelines";
boggle[1890] = "sidelined";
boggle[1891] = "sideling";
boggle[1892] = "siderite";
boggle[1893] = "siderites";
boggle[1894] = "sidereal";
boggle[1895] = "sides";
boggle[1896] = "megass";
boggle[1897] = "megasse";
boggle[1898] = "megasses";
boggle[1899] = "men";
boggle[1900] = "mend";
boggle[1901] = "mends";
boggle[1902] = "mender";
boggle[1903] = "menders";
boggle[1904] = "menial";
boggle[1905] = "menage";
boggle[1906] = "menages";
boggle[1907] = "menta";
boggle[1908] = "mental";
boggle[1909] = "meager";
boggle[1910] = "mean";
boggle[1911] = "meander";
boggle[1912] = "meanders";
boggle[1913] = "meaner";
boggle[1914] = "meaners";
boggle[1915] = "meanest";
boggle[1916] = "meanie";
boggle[1917] = "meanies";
boggle[1918] = "meant";
boggle[1919] = "meal";
boggle[1920] = "mealie";
boggle[1921] = "mealier";
boggle[1922] = "mealies";
boggle[1923] = "mealiest";
boggle[1924] = "meat";
boggle[1925] = "meatless";
boggle[1926] = "meats";
boggle[1927] = "meatier";
boggle[1928] = "mesa";
boggle[1929] = "mesas";
boggle[1930] = "mess";
boggle[1931] = "message";
boggle[1932] = "messages";
boggle[1933] = "messaged";
boggle[1934] = "messan";
boggle[1935] = "messes";
boggle[1936] = "messed";
boggle[1937] = "messier";
boggle[1938] = "mag";
boggle[1939] = "mage";
boggle[1940] = "mages";
boggle[1941] = "magestical";
boggle[1942] = "magnesic";
boggle[1943] = "magnesia";
boggle[1944] = "magnesias";
boggle[1945] = "magnet";
boggle[1946] = "magnets";
boggle[1947] = "magnetic";
boggle[1948] = "magnetics";
boggle[1949] = "man";
boggle[1950] = "mandrel";
boggle[1951] = "mane";
boggle[1952] = "manes";
boggle[1953] = "maned";
boggle[1954] = "manege";
boggle[1955] = "maneges";
boggle[1956] = "maneless";
boggle[1957] = "manic";
boggle[1958] = "manics";
boggle[1959] = "mania";
boggle[1960] = "maniac";
boggle[1961] = "maniacs";
boggle[1962] = "manias";
boggle[1963] = "manila";
boggle[1964] = "manilas";
boggle[1965] = "mange";
boggle[1966] = "manger";
boggle[1967] = "mangers";
boggle[1968] = "manges";
boggle[1969] = "mangel";
boggle[1970] = "manlier";
boggle[1971] = "manliest";
boggle[1972] = "manless";
boggle[1973] = "mantle";
boggle[1974] = "mantles";
boggle[1975] = "mantlet";
boggle[1976] = "mantlets";
boggle[1977] = "mantled";
boggle[1978] = "mantric";
boggle[1979] = "mantra";
boggle[1980] = "mantras";
boggle[1981] = "mantrap";
boggle[1982] = "mantraps";
boggle[1983] = "mantel";
boggle[1984] = "mantelet";
boggle[1985] = "mantelets";
boggle[1986] = "mantes";
boggle[1987] = "mantis";
boggle[1988] = "mantises";
boggle[1989] = "mantid";
boggle[1990] = "mantids";
boggle[1991] = "male";
boggle[1992] = "males";
boggle[1993] = "maleness";
boggle[1994] = "malenesses";
boggle[1995] = "malic";
boggle[1996] = "malice";
boggle[1997] = "malices";
boggle[1998] = "maline";
boggle[1999] = "malines";
boggle[2000] = "malinger";
boggle[2001] = "malingers";
boggle[2002] = "malate";
boggle[2003] = "malates";
boggle[2004] = "malaise";
boggle[2005] = "malar";
boggle[2006] = "malars";
boggle[2007] = "malapert";
boggle[2008] = "malaperts";
boggle[2009] = "malt";
boggle[2010] = "maltreat";
boggle[2011] = "maltreats";
boggle[2012] = "maltreated";
boggle[2013] = "maltreating";
boggle[2014] = "malted";
boggle[2015] = "malteds";
boggle[2016] = "malts";
boggle[2017] = "maltier";
boggle[2018] = "mae";
boggle[2019] = "maes";
boggle[2020] = "maestri";
boggle[2021] = "mat";
boggle[2022] = "matless";
boggle[2023] = "matrices";
boggle[2024] = "matres";
boggle[2025] = "mate";
boggle[2026] = "mater";
boggle[2027] = "materiel";
boggle[2028] = "material";
boggle[2029] = "maters";
boggle[2030] = "mates";
boggle[2031] = "mated";
boggle[2032] = "mats";
boggle[2033] = "mas";
boggle[2034] = "mast";
boggle[2035] = "master";
boggle[2036] = "masteries";
boggle[2037] = "mastering";
boggle[2038] = "masters";
boggle[2039] = "masted";
boggle[2040] = "masts";
boggle[2041] = "mass";
boggle[2042] = "masse";
boggle[2043] = "masses";
boggle[2044] = "massed";
boggle[2045] = "massier";
boggle[2046] = "maser";
boggle[2047] = "masers";
boggle[2048] = "segetal";
boggle[2049] = "sends";
boggle[2050] = "sender";
boggle[2051] = "senders";
boggle[2052] = "sentries";
boggle[2053] = "seatrain";
boggle[2054] = "seam";
boggle[2055] = "seas";
boggle[2056] = "seaside";
boggle[2057] = "seasides";
boggle[2058] = "sag";
boggle[2059] = "sage";
boggle[2060] = "sager";
boggle[2061] = "sages";
boggle[2062] = "sagest";
boggle[2063] = "sand";
boggle[2064] = "sands";
boggle[2065] = "sander";
boggle[2066] = "sanders";
boggle[2067] = "sane";
boggle[2068] = "saner";
boggle[2069] = "sanes";
boggle[2070] = "sanest";
boggle[2071] = "saned";
boggle[2072] = "sanies";
boggle[2073] = "sang";
boggle[2074] = "sanger";
boggle[2075] = "sangers";
boggle[2076] = "salaries";
boggle[2077] = "salaried";
boggle[2078] = "satrap";
boggle[2079] = "satraps";
boggle[2080] = "same";
boggle[2081] = "strict";
boggle[2082] = "stricter";
boggle[2083] = "stria";
boggle[2084] = "striate";
boggle[2085] = "striates";
boggle[2086] = "striated";
boggle[2087] = "striae";
boggle[2088] = "string";
boggle[2089] = "stringer";
boggle[2090] = "stringers";
boggle[2091] = "stringed";
boggle[2092] = "strati";
boggle[2093] = "strait";
boggle[2094] = "straits";
boggle[2095] = "straiter";
boggle[2096] = "straiten";
boggle[2097] = "strain";
boggle[2098] = "strainer";
boggle[2099] = "strainers";
boggle[2100] = "strained";
boggle[2101] = "strap";
boggle[2102] = "straps";
boggle[2103] = "strep";
boggle[2104] = "streps";
boggle[2105] = "stag";
boggle[2106] = "stage";
boggle[2107] = "stager";
boggle[2108] = "stagers";
boggle[2109] = "stages";
boggle[2110] = "staged";
boggle[2111] = "stand";
boggle[2112] = "stands";
boggle[2113] = "stander";
boggle[2114] = "standers";
boggle[2115] = "stane";
boggle[2116] = "stanes";
boggle[2117] = "staned";
boggle[2118] = "stang";
boggle[2119] = "stanged";
boggle[2120] = "stamen";
boggle[2121] = "stases";
boggle[2122] = "stasis";
boggle[2123] = "stelene";
boggle[2124] = "steric";
boggle[2125] = "sterical";
boggle[2126] = "sterile";
boggle[2127] = "stere";
boggle[2128] = "steres";
boggle[2129] = "sterlet";
boggle[2130] = "sterlets";
boggle[2131] = "sterling";
boggle[2132] = "step";
boggle[2133] = "steps";
boggle[2134] = "sties";
boggle[2135] = "smalt";
boggle[2136] = "smalts";
boggle[2137] = "smalti";
boggle[2138] = "italic";
boggle[2139] = "italics";
boggle[2140] = "iterate";
boggle[2141] = "iterates";
boggle[2142] = "iterated";
boggle[2143] = "iterating";
boggle[2144] = "istle";
boggle[2145] = "istles";
boggle[2146] = "ides";
boggle[2147] = "ids";
boggle[2148] = "deleting";
boggle[2149] = "deleing";
boggle[2150] = "delisted";
boggle[2151] = "delicate";
boggle[2152] = "delicates";
boggle[2153] = "deringer";
boggle[2154] = "deringers";
boggle[2155] = "derat";
boggle[2156] = "derats";
boggle[2157] = "derail";
boggle[2158] = "derailed";
boggle[2159] = "dere";
boggle[2160] = "depaint";
boggle[2161] = "depaints";
boggle[2162] = "depart";
boggle[2163] = "departs";
boggle[2164] = "depreciate";
boggle[2165] = "depreciates";
boggle[2166] = "depreciated";
boggle[2167] = "deprecate";
boggle[2168] = "deprecates";
boggle[2169] = "deprecated";
boggle[2170] = "deprecating";
boggle[2171] = "detrital";
boggle[2172] = "detract";
boggle[2173] = "detracts";
boggle[2174] = "detracted";
boggle[2175] = "detracting";
boggle[2176] = "detrain";
boggle[2177] = "detrained";
boggle[2178] = "despair";
boggle[2179] = "desperate";
boggle[2180] = "desist";
boggle[2181] = "desists";
boggle[2182] = "desand";
boggle[2183] = "desands";
boggle[2184] = "desalt";
boggle[2185] = "desalts";
boggle[2186] = "destrier";
boggle[2187] = "destriers";
boggle[2188] = "deists";
boggle[2189] = "dit";
boggle[2190] = "dita";
boggle[2191] = "ditas";
boggle[2192] = "dite";
boggle[2193] = "dites";
boggle[2194] = "dits";
boggle[2195] = "die";
boggle[2196] = "diel";
boggle[2197] = "diet";
boggle[2198] = "diets";
boggle[2199] = "dies";
boggle[2200] = "disrate";
boggle[2201] = "disrates";
boggle[2202] = "disrated";
boggle[2203] = "disrating";
boggle[2204] = "dispart";
boggle[2205] = "disparts";
boggle[2206] = "dispel";
boggle[2207] = "disaster";
boggle[2208] = "disasters";
boggle[2209] = "district";
boggle[2210] = "districts";
boggle[2211] = "districted";
boggle[2212] = "distract";
boggle[2213] = "distracts";
boggle[2214] = "distracted";
boggle[2215] = "distracting";
boggle[2216] = "distrait";
boggle[2217] = "distrain";
boggle[2218] = "distrained";
boggle[2219] = "distal";
boggle[2220] = "dissent";
boggle[2221] = "dissenter";
boggle[2222] = "dissenters";
boggle[2223] = "disseat";


var smallWords = new Array();
var smallWords_definition = new Array();


smallWords[0] = "AAH";
smallWords[1] = "AAL";
smallWords[2] = "AAS";
smallWords[3] = "ABA";
smallWords[4] = "ABO";
smallWords[5] = "ABS";
smallWords[6] = "ABY";
smallWords[7] = "ACE";
smallWords[8] = "ACT";
smallWords[9] = "ADD";
smallWords[10] = "ADO";
smallWords[11] = "ADS";
smallWords[12] = "ADZ";
smallWords[13] = "AFF";
smallWords[14] = "AFT";
smallWords[15] = "AGA";
smallWords[16] = "AGE";
smallWords[17] = "AGO";
smallWords[18] = "AHA";
smallWords[19] = "AID";
smallWords[20] = "AIL";
smallWords[21] = "AIM";
smallWords[22] = "AIN";
smallWords[23] = "AIR";
smallWords[24] = "AIS";
smallWords[25] = "AIT";
smallWords[26] = "ALA";
smallWords[27] = "ALB";
smallWords[28] = "ALE";
smallWords[29] = "ALL";
smallWords[30] = "ALP";
smallWords[31] = "ALS";
smallWords[32] = "ALT";
smallWords[33] = "AMA";
smallWords[34] = "AMI";
smallWords[35] = "AMP";
smallWords[36] = "AMU";
smallWords[37] = "ANA";
smallWords[38] = "AND";
smallWords[39] = "ANE";
smallWords[40] = "ANI";
smallWords[41] = "ANT";
smallWords[42] = "ANY";
smallWords[43] = "APE";
smallWords[44] = "APT";
smallWords[45] = "ARB";
smallWords[46] = "ARC";
smallWords[47] = "ARE";
smallWords[48] = "ARF";
smallWords[49] = "ARK";
smallWords[50] = "ARM";
smallWords[51] = "ARS";
smallWords[52] = "ART";
smallWords[53] = "ASH";
smallWords[54] = "ASK";
smallWords[55] = "ASP";
smallWords[56] = "ASS";
smallWords[57] = "ATE";
smallWords[58] = "ATT";
smallWords[59] = "AUK";
smallWords[60] = "AVA";
smallWords[61] = "AVE";
smallWords[62] = "AVO";
smallWords[63] = "AWA";
smallWords[64] = "AWE";
smallWords[65] = "AWL";
smallWords[66] = "AWN";
smallWords[67] = "AXE";
smallWords[68] = "AYE";
smallWords[69] = "AYS";
smallWords[70] = "AZO";
smallWords[71] = "BAA";
smallWords[72] = "BAD";
smallWords[73] = "BAG";
smallWords[74] = "BAH";
smallWords[75] = "BAL";
smallWords[76] = "BAM";
smallWords[77] = "BAN";
smallWords[78] = "BAP";
smallWords[79] = "BAR";
smallWords[80] = "BAS";
smallWords[81] = "BAT";
smallWords[82] = "BAY";
smallWords[83] = "BED";
smallWords[84] = "BEE";
smallWords[85] = "BEG";
smallWords[86] = "BEL";
smallWords[87] = "BEN";
smallWords[88] = "BET";
smallWords[89] = "BEY";
smallWords[90] = "BIB";
smallWords[91] = "BID";
smallWords[92] = "BIG";
smallWords[93] = "BIN";
smallWords[94] = "BIO";
smallWords[95] = "BIS";
smallWords[96] = "BIT";
smallWords[97] = "BIZ";
smallWords[98] = "BOA";
smallWords[99] = "BOB";
smallWords[100] = "BOD";
smallWords[101] = "BOG";
smallWords[102] = "BOO";
smallWords[103] = "BOP";
smallWords[104] = "BOS";
smallWords[105] = "BOT";
smallWords[106] = "BOW";
smallWords[107] = "BOX";
smallWords[108] = "BOY";
smallWords[109] = "BRA";
smallWords[110] = "BRO";
smallWords[111] = "BRR";
smallWords[112] = "BUB";
smallWords[113] = "BUD";
smallWords[114] = "BUG";
smallWords[115] = "BUM";
smallWords[116] = "BUN";
smallWords[117] = "BUR";
smallWords[118] = "BUS";
smallWords[119] = "BUT";
smallWords[120] = "BUY";
smallWords[121] = "BYE";
smallWords[122] = "BYS";
smallWords[123] = "CAB";
smallWords[124] = "CAD";
smallWords[125] = "CAM";
smallWords[126] = "CAN";
smallWords[127] = "CAP";
smallWords[128] = "CAR";
smallWords[129] = "CAT";
smallWords[130] = "CAW";
smallWords[131] = "CAY";
smallWords[132] = "CEE";
smallWords[133] = "CEL";
smallWords[134] = "CEP";
smallWords[135] = "CHI";
smallWords[136] = "CIS";
smallWords[137] = "COB";
smallWords[138] = "COD";
smallWords[139] = "COG";
smallWords[140] = "COL";
smallWords[141] = "CON";
smallWords[142] = "COO";
smallWords[143] = "COP";
smallWords[144] = "COR";
smallWords[145] = "COS";
smallWords[146] = "COT";
smallWords[147] = "COW";
smallWords[148] = "COX";
smallWords[149] = "COY";
smallWords[150] = "COZ";
smallWords[151] = "CRY";
smallWords[152] = "CUB";
smallWords[153] = "CUD";
smallWords[154] = "CUE";
smallWords[155] = "CUM";
smallWords[156] = "CUP";
smallWords[157] = "CUR";
smallWords[158] = "CUT";
smallWords[159] = "CWM";
smallWords[160] = "DAB";
smallWords[161] = "DAD";
smallWords[162] = "DAG";
smallWords[163] = "DAH";
smallWords[164] = "DAK";
smallWords[165] = "DAL";
smallWords[166] = "DAM";
smallWords[167] = "DAP";
smallWords[168] = "DAW";
smallWords[169] = "DAY";
smallWords[170] = "DEB";
smallWords[171] = "DEE";
smallWords[172] = "DEL";
smallWords[173] = "DEN";
smallWords[174] = "DEV";
smallWords[175] = "DEW";
smallWords[176] = "DEX";
smallWords[177] = "DEY";
smallWords[178] = "DIB";
smallWords[179] = "DID";
smallWords[180] = "DIE";
smallWords[181] = "DIG";
smallWords[182] = "DIM";
smallWords[183] = "DIN";
smallWords[184] = "DIP";
smallWords[185] = "DIS";
smallWords[186] = "DIT";
smallWords[187] = "DOC";
smallWords[188] = "DOE";
smallWords[189] = "DOG";
smallWords[190] = "DOL";
smallWords[191] = "DOM";
smallWords[192] = "DON";
smallWords[193] = "DOR";
smallWords[194] = "DOS";
smallWords[195] = "DOT";
smallWords[196] = "DOW";
smallWords[197] = "DRY";
smallWords[198] = "DUB";
smallWords[199] = "DUD";
smallWords[200] = "DUE";
smallWords[201] = "DUG";
smallWords[202] = "DUI";
smallWords[203] = "DUN";
smallWords[204] = "DUO";
smallWords[205] = "DUP";
smallWords[206] = "DYE";
smallWords[207] = "EAR";
smallWords[208] = "EAT";
smallWords[209] = "EAU";
smallWords[210] = "EBB";
smallWords[211] = "ECU";
smallWords[212] = "EDH";
smallWords[213] = "EEL";
smallWords[214] = "EFF";
smallWords[215] = "EFS";
smallWords[216] = "EFT";
smallWords[217] = "EGG";
smallWords[218] = "EGO";
smallWords[219] = "EKE";
smallWords[220] = "ELD";
smallWords[221] = "ELF";
smallWords[222] = "ELK";
smallWords[223] = "ELL";
smallWords[224] = "ELM";
smallWords[225] = "ELS";
smallWords[226] = "EME";
smallWords[227] = "EMF";
smallWords[228] = "EMS";
smallWords[229] = "EMU";
smallWords[230] = "END";
smallWords[231] = "ENG";
smallWords[232] = "ENS";
smallWords[233] = "EON";
smallWords[234] = "ERA";
smallWords[235] = "ERE";
smallWords[236] = "ERG";
smallWords[237] = "ERN";
smallWords[238] = "ERR";
smallWords[239] = "ERS";
smallWords[240] = "ESS";
smallWords[241] = "ETA";
smallWords[242] = "ETH";
smallWords[243] = "EVE";
smallWords[244] = "EWE";
smallWords[245] = "EYE";
smallWords[246] = "FAD";
smallWords[247] = "FAG";
smallWords[248] = "FAN";
smallWords[249] = "FAR";
smallWords[250] = "FAS";
smallWords[251] = "FAT";
smallWords[252] = "FAX";
smallWords[253] = "FAY";
smallWords[254] = "FED";
smallWords[255] = "FEE";
smallWords[256] = "FEH";
smallWords[257] = "FEM";
smallWords[258] = "FEN";
smallWords[259] = "FER";
smallWords[260] = "FET";
smallWords[261] = "FEU";
smallWords[262] = "FEW";
smallWords[263] = "FEY";
smallWords[264] = "FEZ";
smallWords[265] = "FIB";
smallWords[266] = "FID";
smallWords[267] = "FIE";
smallWords[268] = "FIG";
smallWords[269] = "FIL";
smallWords[270] = "FIN";
smallWords[271] = "FIR";
smallWords[272] = "FIT";
smallWords[273] = "FIX";
smallWords[274] = "FIZ";
smallWords[275] = "FLU";
smallWords[276] = "FLY";
smallWords[277] = "FOB";
smallWords[278] = "FOE";
smallWords[279] = "FOG";
smallWords[280] = "FOH";
smallWords[281] = "FON";
smallWords[282] = "FOP";
smallWords[283] = "FOR";
smallWords[284] = "FOU";
smallWords[285] = "FOX";
smallWords[286] = "FOY";
smallWords[287] = "FRO";
smallWords[288] = "FRY";
smallWords[289] = "FUB";
smallWords[290] = "FUD";
smallWords[291] = "FUG";
smallWords[292] = "FUN";
smallWords[293] = "FUR";
smallWords[294] = "GAB";
smallWords[295] = "GAD";
smallWords[296] = "GAE";
smallWords[297] = "GAG";
smallWords[298] = "GAL";
smallWords[299] = "GAM";
smallWords[300] = "GAN";
smallWords[301] = "GAP";
smallWords[302] = "GAR";
smallWords[303] = "GAS";
smallWords[304] = "GAT";
smallWords[305] = "GAY";
smallWords[306] = "GED";
smallWords[307] = "GEE";
smallWords[308] = "GEL";
smallWords[309] = "GEM";
smallWords[310] = "GEN";
smallWords[311] = "GET";
smallWords[312] = "GEY";
smallWords[313] = "GHI";
smallWords[314] = "GIB";
smallWords[315] = "GID";
smallWords[316] = "GIE";
smallWords[317] = "GIG";
smallWords[318] = "GIN";
smallWords[319] = "GIP";
smallWords[320] = "GIT";
smallWords[321] = "GNU";
smallWords[322] = "GOA";
smallWords[323] = "GOB";
smallWords[324] = "GOD";
smallWords[325] = "GOO";
smallWords[326] = "GOR";
smallWords[327] = "GOT";
smallWords[328] = "GOX";
smallWords[329] = "GOY";
smallWords[330] = "GUL";
smallWords[331] = "GUM";
smallWords[332] = "GUN";
smallWords[333] = "GUT";
smallWords[334] = "GUV";
smallWords[335] = "GUY";
smallWords[336] = "GYM";
smallWords[337] = "GYP";
smallWords[338] = "HAD";
smallWords[339] = "HAE";
smallWords[340] = "HAG";
smallWords[341] = "HAH";
smallWords[342] = "HAJ";
smallWords[343] = "HAM";
smallWords[344] = "HAO";
smallWords[345] = "HAP";
smallWords[346] = "HAS";
smallWords[347] = "HAT";
smallWords[348] = "HAW";
smallWords[349] = "HAY";
smallWords[350] = "HEH";
smallWords[351] = "HEM";
smallWords[352] = "HEN";
smallWords[353] = "HEP";
smallWords[354] = "HER";
smallWords[355] = "HES";
smallWords[356] = "HET";
smallWords[357] = "HEW";
smallWords[358] = "HEX";
smallWords[359] = "HEY";
smallWords[360] = "HIC";
smallWords[361] = "HID";
smallWords[362] = "HIE";
smallWords[363] = "HIM";
smallWords[364] = "HIN";
smallWords[365] = "HIP";
smallWords[366] = "HIS";
smallWords[367] = "HIT";
smallWords[368] = "HMM";
smallWords[369] = "HOB";
smallWords[370] = "HOD";
smallWords[371] = "HOE";
smallWords[372] = "HOG";
smallWords[373] = "HON";
smallWords[374] = "HOP";
smallWords[375] = "HOT";
smallWords[376] = "HOW";
smallWords[377] = "HOY";
smallWords[378] = "HUB";
smallWords[379] = "HUE";
smallWords[380] = "HUG";
smallWords[381] = "HUH";
smallWords[382] = "HUM";
smallWords[383] = "HUN";
smallWords[384] = "HUP";
smallWords[385] = "HUT";
smallWords[386] = "HYP";
smallWords[387] = "ICE";
smallWords[388] = "ICH";
smallWords[389] = "ICK";
smallWords[390] = "ICY";
smallWords[391] = "IDS";
smallWords[392] = "IFF";
smallWords[393] = "IFS";
smallWords[394] = "ILK";
smallWords[395] = "ILL";
smallWords[396] = "IMP";
smallWords[397] = "INK";
smallWords[398] = "INN";
smallWords[399] = "INS";
smallWords[400] = "ION";
smallWords[401] = "IRE";
smallWords[402] = "IRK";
smallWords[403] = "ISM";
smallWords[404] = "ITS";
smallWords[405] = "IVY";
smallWords[406] = "JAB";
smallWords[407] = "JAG";
smallWords[408] = "JAM";
smallWords[409] = "JAR";
smallWords[410] = "JAW";
smallWords[411] = "JAY";
smallWords[412] = "JEE";
smallWords[413] = "JET";
smallWords[414] = "JEU";
smallWords[415] = "JEW";
smallWords[416] = "JIB";
smallWords[417] = "JIG";
smallWords[418] = "JIN";
smallWords[419] = "JOB";
smallWords[420] = "JOE";
smallWords[421] = "JOG";
smallWords[422] = "JOT";
smallWords[423] = "JOW";
smallWords[424] = "JOY";
smallWords[425] = "JUG";
smallWords[426] = "JUN";
smallWords[427] = "JUS";
smallWords[428] = "JUT";
smallWords[429] = "KAB";
smallWords[430] = "KAE";
smallWords[431] = "KAF";
smallWords[432] = "KAS";
smallWords[433] = "KAT";
smallWords[434] = "KAY";
smallWords[435] = "KEA";
smallWords[436] = "KEF";
smallWords[437] = "KEG";
smallWords[438] = "KEN";
smallWords[439] = "KEP";
smallWords[440] = "KEX";
smallWords[441] = "KEY";
smallWords[442] = "KHI";
smallWords[443] = "KID";
smallWords[444] = "KIF";
smallWords[445] = "KIN";
smallWords[446] = "KIP";
smallWords[447] = "KIR";
smallWords[448] = "KIT";
smallWords[449] = "KOA";
smallWords[450] = "KOB";
smallWords[451] = "KOI";
smallWords[452] = "KOP";
smallWords[453] = "KOR";
smallWords[454] = "KOS";
smallWords[455] = "KUE";
smallWords[456] = "LAB";
smallWords[457] = "LAC";
smallWords[458] = "LAD";
smallWords[459] = "LAG";
smallWords[460] = "LAM";
smallWords[461] = "LAP";
smallWords[462] = "LAR";
smallWords[463] = "LAS";
smallWords[464] = "LAT";
smallWords[465] = "LAV";
smallWords[466] = "LAW";
smallWords[467] = "LAX";
smallWords[468] = "LAY";
smallWords[469] = "LEA";
smallWords[470] = "LED";
smallWords[471] = "LEE";
smallWords[472] = "LEG";
smallWords[473] = "LEI";
smallWords[474] = "LEK";
smallWords[475] = "LET";
smallWords[476] = "LEU";
smallWords[477] = "LEV";
smallWords[478] = "LEX";
smallWords[479] = "LEY";
smallWords[480] = "LEZ";
smallWords[481] = "LIB";
smallWords[482] = "LID";
smallWords[483] = "LIE";
smallWords[484] = "LIN";
smallWords[485] = "LIP";
smallWords[486] = "LIS";
smallWords[487] = "LIT";
smallWords[488] = "LOB";
smallWords[489] = "LOG";
smallWords[490] = "LOO";
smallWords[491] = "LOP";
smallWords[492] = "LOT";
smallWords[493] = "LOW";
smallWords[494] = "LOX";
smallWords[495] = "LUG";
smallWords[496] = "LUM";
smallWords[497] = "LUV";
smallWords[498] = "LUX";
smallWords[499] = "LYE";
smallWords[500] = "MAC";
smallWords[501] = "MAD";
smallWords[502] = "MAE";
smallWords[503] = "MAG";
smallWords[504] = "MAN";
smallWords[505] = "MAP";
smallWords[506] = "MAR";
smallWords[507] = "MAS";
smallWords[508] = "MAT";
smallWords[509] = "MAW";
smallWords[510] = "MAX";
smallWords[511] = "MAY";
smallWords[512] = "MED";
smallWords[513] = "MEL";
smallWords[514] = "MEM";
smallWords[515] = "MEN";
smallWords[516] = "MET";
smallWords[517] = "MEW";
smallWords[518] = "MHO";
smallWords[519] = "MIB";
smallWords[520] = "MID";
smallWords[521] = "MIG";
smallWords[522] = "MIL";
smallWords[523] = "MIM";
smallWords[524] = "MIR";
smallWords[525] = "MIS";
smallWords[526] = "MIX";
smallWords[527] = "MOA";
smallWords[528] = "MOB";
smallWords[529] = "MOC";
smallWords[530] = "MOD";
smallWords[531] = "MOG";
smallWords[532] = "MOL";
smallWords[533] = "MOM";
smallWords[534] = "MON";
smallWords[535] = "MOO";
smallWords[536] = "MOP";
smallWords[537] = "MOR";
smallWords[538] = "MOS";
smallWords[539] = "MOT";
smallWords[540] = "MOW";
smallWords[541] = "MUD";
smallWords[542] = "MUG";
smallWords[543] = "MUM";
smallWords[544] = "MUN";
smallWords[545] = "MUS";
smallWords[546] = "MUT";
smallWords[547] = "NAB";
smallWords[548] = "NAE";
smallWords[549] = "NAG";
smallWords[550] = "NAH";
smallWords[551] = "NAM";
smallWords[552] = "NAN";
smallWords[553] = "NAP";
smallWords[554] = "NAW";
smallWords[555] = "NAY";
smallWords[556] = "NEB";
smallWords[557] = "NEE";
smallWords[558] = "NET";
smallWords[559] = "NEW";
smallWords[560] = "NIB";
smallWords[561] = "NIL";
smallWords[562] = "NIM";
smallWords[563] = "NIP";
smallWords[564] = "NIT";
smallWords[565] = "NIX";
smallWords[566] = "NOB";
smallWords[567] = "NOD";
smallWords[568] = "NOG";
smallWords[569] = "NOH";
smallWords[570] = "NOM";
smallWords[571] = "NOO";
smallWords[572] = "NOR";
smallWords[573] = "NOS";
smallWords[574] = "NOT";
smallWords[575] = "NOW";
smallWords[576] = "NTH";
smallWords[577] = "NUB";
smallWords[578] = "NUN";
smallWords[579] = "NUS";
smallWords[580] = "NUT";
smallWords[581] = "OAF";
smallWords[582] = "OAK";
smallWords[583] = "OAR";
smallWords[584] = "OAT";
smallWords[585] = "OBE";
smallWords[586] = "OBI";
smallWords[587] = "OCA";
smallWords[588] = "ODD";
smallWords[589] = "ODE";
smallWords[590] = "ODS";
smallWords[591] = "OES";
smallWords[592] = "OFF";
smallWords[593] = "OFT";
smallWords[594] = "OHM";
smallWords[595] = "OHO";
smallWords[596] = "OHS";
smallWords[597] = "OIL";
smallWords[598] = "OKA";
smallWords[599] = "OKE";
smallWords[600] = "OLD";
smallWords[601] = "OLE";
smallWords[602] = "OMS";
smallWords[603] = "ONE";
smallWords[604] = "ONS";
smallWords[605] = "OOH";
smallWords[606] = "OOT";
smallWords[607] = "OPE";
smallWords[608] = "OPS";
smallWords[609] = "OPT";
smallWords[610] = "ORA";
smallWords[611] = "ORB";
smallWords[612] = "ORC";
smallWords[613] = "ORE";
smallWords[614] = "ORS";
smallWords[615] = "ORT";
smallWords[616] = "OSE";
smallWords[617] = "OUD";
smallWords[618] = "OUR";
smallWords[619] = "OUT";
smallWords[620] = "OVA";
smallWords[621] = "OWE";
smallWords[622] = "OWL";
smallWords[623] = "OWN";
smallWords[624] = "OXO";
smallWords[625] = "OXY";
smallWords[626] = "PAC";
smallWords[627] = "PAD";
smallWords[628] = "PAH";
smallWords[629] = "PAL";
smallWords[630] = "PAM";
smallWords[631] = "PAN";
smallWords[632] = "PAP";
smallWords[633] = "PAR";
smallWords[634] = "PAS";
smallWords[635] = "PAT";
smallWords[636] = "PAW";
smallWords[637] = "PAX";
smallWords[638] = "PAY";
smallWords[639] = "PEA";
smallWords[640] = "PEC";
smallWords[641] = "PED";
smallWords[642] = "PEE";
smallWords[643] = "PEG";
smallWords[644] = "PEH";
smallWords[645] = "PEN";
smallWords[646] = "PEP";
smallWords[647] = "PER";
smallWords[648] = "PES";
smallWords[649] = "PET";
smallWords[650] = "PEW";
smallWords[651] = "PHI";
smallWords[652] = "PHT";
smallWords[653] = "PIA";
smallWords[654] = "PIC";
smallWords[655] = "PIE";
smallWords[656] = "PIG";
smallWords[657] = "PIN";
smallWords[658] = "PIP";
smallWords[659] = "PIS";
smallWords[660] = "PIT";
smallWords[661] = "PIU";
smallWords[662] = "PIX";
smallWords[663] = "PLY";
smallWords[664] = "POD";
smallWords[665] = "POH";
smallWords[666] = "POI";
smallWords[667] = "POL";
smallWords[668] = "POM";
smallWords[669] = "POP";
smallWords[670] = "POT";
smallWords[671] = "POW";
smallWords[672] = "POX";
smallWords[673] = "PRO";
smallWords[674] = "PRY";
smallWords[675] = "PSI";
smallWords[676] = "PUB";
smallWords[677] = "PUD";
smallWords[678] = "PUG";
smallWords[679] = "PUL";
smallWords[680] = "PUN";
smallWords[681] = "PUP";
smallWords[682] = "PUR";
smallWords[683] = "PUS";
smallWords[684] = "PUT";
smallWords[685] = "PYA";
smallWords[686] = "PYE";
smallWords[687] = "PYX";
smallWords[688] = "QAT";
smallWords[689] = "QUA";
smallWords[690] = "RAD";
smallWords[691] = "RAG";
smallWords[692] = "RAH";
smallWords[693] = "RAJ";
smallWords[694] = "RAM";
smallWords[695] = "RAN";
smallWords[696] = "RAP";
smallWords[697] = "RAS";
smallWords[698] = "RAT";
smallWords[699] = "RAW";
smallWords[700] = "RAX";
smallWords[701] = "RAY";
smallWords[702] = "REB";
smallWords[703] = "REC";
smallWords[704] = "RED";
smallWords[705] = "REE";
smallWords[706] = "REF";
smallWords[707] = "REG";
smallWords[708] = "REI";
smallWords[709] = "REM";
smallWords[710] = "REP";
smallWords[711] = "RES";
smallWords[712] = "RET";
smallWords[713] = "REV";
smallWords[714] = "REX";
smallWords[715] = "RHO";
smallWords[716] = "RIA";
smallWords[717] = "RIB";
smallWords[718] = "RID";
smallWords[719] = "RIF";
smallWords[720] = "RIG";
smallWords[721] = "RIM";
smallWords[722] = "RIN";
smallWords[723] = "RIP";
smallWords[724] = "ROB";
smallWords[725] = "ROC";
smallWords[726] = "ROD";
smallWords[727] = "ROE";
smallWords[728] = "ROM";
smallWords[729] = "ROT";
smallWords[730] = "ROW";
smallWords[731] = "RUB";
smallWords[732] = "RUE";
smallWords[733] = "RUG";
smallWords[734] = "RUM";
smallWords[735] = "RUN";
smallWords[736] = "RUT";
smallWords[737] = "RYA";
smallWords[738] = "RYE";
smallWords[739] = "SAB";
smallWords[740] = "SAC";
smallWords[741] = "SAD";
smallWords[742] = "SAE";
smallWords[743] = "SAG";
smallWords[744] = "SAL";
smallWords[745] = "SAP";
smallWords[746] = "SAT";
smallWords[747] = "SAU";
smallWords[748] = "SAW";
smallWords[749] = "SAX";
smallWords[750] = "SAY";
smallWords[751] = "SEA";
smallWords[752] = "SEC";
smallWords[753] = "SEE";
smallWords[754] = "SEG";
smallWords[755] = "SEI";
smallWords[756] = "SEL";
smallWords[757] = "SEN";
smallWords[758] = "SER";
smallWords[759] = "SET";
smallWords[760] = "SEW";
smallWords[761] = "SEX";
smallWords[762] = "SHA";
smallWords[763] = "SHE";
smallWords[764] = "SHH";
smallWords[765] = "SHY";
smallWords[766] = "SIB";
smallWords[767] = "SIC";
smallWords[768] = "SIM";
smallWords[769] = "SIN";
smallWords[770] = "SIP";
smallWords[771] = "SIR";
smallWords[772] = "SIS";
smallWords[773] = "SIT";
smallWords[774] = "SIX";
smallWords[775] = "SKA";
smallWords[776] = "SKI";
smallWords[777] = "SKY";
smallWords[778] = "SLY";
smallWords[779] = "SOB";
smallWords[780] = "SOD";
smallWords[781] = "SOL";
smallWords[782] = "SON";
smallWords[783] = "SOP";
smallWords[784] = "SOS";
smallWords[785] = "SOT";
smallWords[786] = "SOU";
smallWords[787] = "SOW";
smallWords[788] = "SOX";
smallWords[789] = "SOY";
smallWords[790] = "SPA";
smallWords[791] = "SPY";
smallWords[792] = "SRI";
smallWords[793] = "STY";
smallWords[794] = "SUB";
smallWords[795] = "SUE";
smallWords[796] = "SUM";
smallWords[797] = "SUN";
smallWords[798] = "SUP";
smallWords[799] = "SUQ";
smallWords[800] = "SYN";
smallWords[801] = "TAB";
smallWords[802] = "TAD";
smallWords[803] = "TAE";
smallWords[804] = "TAG";
smallWords[805] = "TAJ";
smallWords[806] = "TAM";
smallWords[807] = "TAN";
smallWords[808] = "TAO";
smallWords[809] = "TAP";
smallWords[810] = "TAR";
smallWords[811] = "TAS";
smallWords[812] = "TAT";
smallWords[813] = "TAU";
smallWords[814] = "TAV";
smallWords[815] = "TAW";
smallWords[816] = "TAX";
smallWords[817] = "TEA";
smallWords[818] = "TED";
smallWords[819] = "TEE";
smallWords[820] = "TEG";
smallWords[821] = "TEL";
smallWords[822] = "TEN";
smallWords[823] = "TET";
smallWords[824] = "TEW";
smallWords[825] = "THE";
smallWords[826] = "THO";
smallWords[827] = "THY";
smallWords[828] = "TIC";
smallWords[829] = "TIE";
smallWords[830] = "TIL";
smallWords[831] = "TIN";
smallWords[832] = "TIP";
smallWords[833] = "TIS";
smallWords[834] = "TIT";
smallWords[835] = "TOD";
smallWords[836] = "TOE";
smallWords[837] = "TOG";
smallWords[838] = "TOM";
smallWords[839] = "TON";
smallWords[840] = "TOO";
smallWords[841] = "TOP";
smallWords[842] = "TOR";
smallWords[843] = "TOT";
smallWords[844] = "TOW";
smallWords[845] = "TOY";
smallWords[846] = "TRY";
smallWords[847] = "TSK";
smallWords[848] = "TUB";
smallWords[849] = "TUG";
smallWords[850] = "TUI";
smallWords[851] = "TUN";
smallWords[852] = "TUP";
smallWords[853] = "TUT";
smallWords[854] = "TUX";
smallWords[855] = "TWA";
smallWords[856] = "TWO";
smallWords[857] = "TYE";
smallWords[858] = "UDO";
smallWords[859] = "UGH";
smallWords[860] = "UKE";
smallWords[861] = "ULU";
smallWords[862] = "UMM";
smallWords[863] = "UMP";
smallWords[864] = "UNS";
smallWords[865] = "UPO";
smallWords[866] = "UPS";
smallWords[867] = "URB";
smallWords[868] = "URD";
smallWords[869] = "URN";
smallWords[870] = "USE";
smallWords[871] = "UTA";
smallWords[872] = "UTS";
smallWords[873] = "VAC";
smallWords[874] = "VAN";
smallWords[875] = "VAR";
smallWords[876] = "VAS";
smallWords[877] = "VAT";
smallWords[878] = "VAU";
smallWords[879] = "VAV";
smallWords[880] = "VAW";
smallWords[881] = "VEE";
smallWords[882] = "VEG";
smallWords[883] = "VET";
smallWords[884] = "VEX";
smallWords[885] = "VIA";
smallWords[886] = "VIE";
smallWords[887] = "VIG";
smallWords[888] = "VIM";
smallWords[889] = "VIS";
smallWords[890] = "VOE";
smallWords[891] = "VOW";
smallWords[892] = "VOX";
smallWords[893] = "VUG";
smallWords[894] = "WAB";
smallWords[895] = "WAD";
smallWords[896] = "WAE";
smallWords[897] = "WAG";
smallWords[898] = "WAN";
smallWords[899] = "WAP";
smallWords[900] = "WAR";
smallWords[901] = "WAS";
smallWords[902] = "WAT";
smallWords[903] = "WAW";
smallWords[904] = "WAX";
smallWords[905] = "WAY";
smallWords[906] = "WEB";
smallWords[907] = "WED";
smallWords[908] = "WEE";
smallWords[909] = "WEN";
smallWords[910] = "WET";
smallWords[911] = "WHA";
smallWords[912] = "WHO";
smallWords[913] = "WHY";
smallWords[914] = "WIG";
smallWords[915] = "WIN";
smallWords[916] = "WIS";
smallWords[917] = "WIT";
smallWords[918] = "WIZ";
smallWords[919] = "WOE";
smallWords[920] = "WOG";
smallWords[921] = "WOK";
smallWords[922] = "WON";
smallWords[923] = "WOO";
smallWords[924] = "WOP";
smallWords[925] = "WOS";
smallWords[926] = "WOT";
smallWords[927] = "WOW";
smallWords[928] = "WRY";
smallWords[929] = "WUD";
smallWords[930] = "WYE";
smallWords[931] = "WYN";
smallWords[932] = "XIS";
smallWords[933] = "YAH";
smallWords[934] = "YAK";
smallWords[935] = "YAM";
smallWords[936] = "YAP";
smallWords[937] = "YAR";
smallWords[938] = "YAW";
smallWords[939] = "YAY";
smallWords[940] = "YEA";
smallWords[941] = "YEH";
smallWords[942] = "YEN";
smallWords[943] = "YEP";
smallWords[944] = "YES";
smallWords[945] = "YET";
smallWords[946] = "YEW";
smallWords[947] = "YID";
smallWords[948] = "YIN";
smallWords[949] = "YIP";
smallWords[950] = "YOB";
smallWords[951] = "YOD";
smallWords[952] = "YOK";
smallWords[953] = "YOM";
smallWords[954] = "YON";
smallWords[955] = "YOU";
smallWords[956] = "YOW";
smallWords[957] = "YUK";
smallWords[958] = "YUM";
smallWords[959] = "YUP";
smallWords[960] = "ZAG";
smallWords[961] = "ZAP";
smallWords[962] = "ZAX";
smallWords[963] = "ZED";
smallWords[964] = "ZEE";
smallWords[965] = "ZEK";
smallWords[966] = "ZIG";
smallWords[967] = "ZIN";
smallWords[968] = "ZIP";
smallWords[969] = "ZIT";
smallWords[970] = "ZOA";
smallWords[971] = "ZOO";


smallWords_definition[0] = "to exclaim in delight";
smallWords_definition[1] = "East Indian shrub";
smallWords_definition[2] = "[aa] (rough, cindery lava)";
smallWords_definition[3] = "sleeveless garment";
smallWords_definition[4] = "aborigine";
smallWords_definition[5] = "[ab] (abdominal muscle)";
smallWords_definition[6] = "to pay the penalty for (abye)";
smallWords_definition[7] = "to make a perfect shot";
smallWords_definition[8] = "to perform by action";
smallWords_definition[9] = "to perform addition";
smallWords_definition[10] = "bustle";
smallWords_definition[11] = "[ad] (advertisement)";
smallWords_definition[12] = "cutting tool (adze)";
smallWords_definition[13] = "off";
smallWords_definition[14] = "toward the stern";
smallWords_definition[15] = "Turkish military officer";
smallWords_definition[16] = "to grow old";
smallWords_definition[17] = "in the past";
smallWords_definition[18] = "intj. expressing sudden realization";
smallWords_definition[19] = "to help";
smallWords_definition[20] = "to suffer pain";
smallWords_definition[21] = "to point in a direction";
smallWords_definition[22] = "Hebrew letter (ayin)";
smallWords_definition[23] = "to broadcast";
smallWords_definition[24] = "[ai] (three-toed sloth)";
smallWords_definition[25] = "small island";
smallWords_definition[26] = "wing";
smallWords_definition[27] = "long-sleeved vestment";
smallWords_definition[28] = "alcoholic beverage";
smallWords_definition[29] = "everything one has";
smallWords_definition[30] = "high mountain";
smallWords_definition[31] = "[al] (East Indian tree)";
smallWords_definition[32] = "high-pitched note";
smallWords_definition[33] = "Oriental nurse (amah)";
smallWords_definition[34] = "friend";
smallWords_definition[35] = "unit of electric current strength (ampere)";
smallWords_definition[36] = "atomic mass unit";
smallWords_definition[37] = "collection of information on a subject";
smallWords_definition[38] = "added condition";
smallWords_definition[39] = "one";
smallWords_definition[40] = "tropical American black cuckoo";
smallWords_definition[41] = "small insect";
smallWords_definition[42] = "one or another";
smallWords_definition[43] = "to mimic";
smallWords_definition[44] = "appropriate";
smallWords_definition[45] = "stock trader";
smallWords_definition[46] = "to travel a curved course";
smallWords_definition[47] = "unit of surface measure/conj. of be";
smallWords_definition[48] = "dog's bark";
smallWords_definition[49] = "large boat";
smallWords_definition[50] = "to supply with weapons";
smallWords_definition[51] = "[ar] (letter 'r')";
smallWords_definition[52] = "skill acquired by experience";
smallWords_definition[53] = "tree/to burn into ashes";
smallWords_definition[54] = "to question";
smallWords_definition[55] = "venemous snake";
smallWords_definition[56] = "donkey";
smallWords_definition[57] = "reckless impulse driving one to ruin";
smallWords_definition[58] = "Laotian monetary unit";
smallWords_definition[59] = "diving seabird";
smallWords_definition[60] = "at all";
smallWords_definition[61] = "expression of greeting";
smallWords_definition[62] = "monetary unit of Macau";
smallWords_definition[63] = "away";
smallWords_definition[64] = "to inspire with awe";
smallWords_definition[65] = "pointed punching tool";
smallWords_definition[66] = "bristlelike appendage of certain grasses";
smallWords_definition[67] = "to cut with an axe";
smallWords_definition[68] = "affirmative vote";
smallWords_definition[69] = "[ay] (affirmative vote)";
smallWords_definition[70] = "containing nitrogen";
smallWords_definition[71] = "[baa] (to bleat)";
smallWords_definition[72] = "something bad";
smallWords_definition[73] = "to put into a bag";
smallWords_definition[74] = "intj. expressing disgust";
smallWords_definition[75] = "type of shoe (balmoral)";
smallWords_definition[76] = "to strike with a dull sound";
smallWords_definition[77] = "to prohibit/Rumanian coin";
smallWords_definition[78] = "small roll";
smallWords_definition[79] = "to exclude";
smallWords_definition[80] = "[ba] (eternal soul in Egyptian mythology)";
smallWords_definition[81] = "to hit a baseball";
smallWords_definition[82] = "to howl";
smallWords_definition[83] = "to provide with a bed";
smallWords_definition[84] = "winged insect";
smallWords_definition[85] = "to plead";
smallWords_definition[86] = "unit of power";
smallWords_definition[87] = "inner room";
smallWords_definition[88] = "to wager";
smallWords_definition[89] = "Turkish ruler";
smallWords_definition[90] = "to drink alcohol";
smallWords_definition[91] = "to make a bid";
smallWords_definition[92] = "large";
smallWords_definition[93] = "to store in a bin";
smallWords_definition[94] = "biography";
smallWords_definition[95] = "[bi] (bisexual)";
smallWords_definition[96] = "to restrain with a bit";
smallWords_definition[97] = "business";
smallWords_definition[98] = "large snake";
smallWords_definition[99] = "to move up and down";
smallWords_definition[100] = "body";
smallWords_definition[101] = "to impede";
smallWords_definition[102] = "to deride";
smallWords_definition[103] = "to hit";
smallWords_definition[104] = "[bo] (pal)";
smallWords_definition[105] = "botfly larva";
smallWords_definition[106] = "to bend forward at the waist";
smallWords_definition[107] = "to put into a box";
smallWords_definition[108] = "male child";
smallWords_definition[109] = "brassiere";
smallWords_definition[110] = "brother";
smallWords_definition[111] = "intj. used to indicate coldness (brrr)";
smallWords_definition[112] = "young fellow";
smallWords_definition[113] = "to grow buds";
smallWords_definition[114] = "to annoy";
smallWords_definition[115] = "to live idly";
smallWords_definition[116] = "small bread roll";
smallWords_definition[117] = "to remove a rough edge from (burr)";
smallWords_definition[118] = "to transport by bus";
smallWords_definition[119] = "flatfish";
smallWords_definition[120] = "to purchase";
smallWords_definition[121] = "free advance to next tournament round";
smallWords_definition[122] = "[by] (side issue)";
smallWords_definition[123] = "to drive a taxi";
smallWords_definition[124] = "ungentlemanly man";
smallWords_definition[125] = "rotating machine part";
smallWords_definition[126] = "to be able/to put into a can";
smallWords_definition[127] = "to put a cover onto";
smallWords_definition[128] = "automobile";
smallWords_definition[129] = "to anchor to a cathead";
smallWords_definition[130] = "to caw like a crow";
smallWords_definition[131] = "small low island";
smallWords_definition[132] = "letter 'c'";
smallWords_definition[133] = "drawn frame of animation";
smallWords_definition[134] = "large mushroom (cepe)";
smallWords_definition[135] = "Greek letter";
smallWords_definition[136] = "having certain atoms on same side of molecule";
smallWords_definition[137] = "corncob";
smallWords_definition[138] = "to fool";
smallWords_definition[139] = "to cheat at dice";
smallWords_definition[140] = "depression between two mountains";
smallWords_definition[141] = "to swindle";
smallWords_definition[142] = "to make the sound of a dove";
smallWords_definition[143] = "to steal";
smallWords_definition[144] = "intj. expressing surprise";
smallWords_definition[145] = "lettuce variety";
smallWords_definition[146] = "lightweight bed";
smallWords_definition[147] = "to intimidate";
smallWords_definition[148] = "to direct a racing boat (coxswain)";
smallWords_definition[149] = "shy/to caress";
smallWords_definition[150] = "cousin";
smallWords_definition[151] = "to weep";
smallWords_definition[152] = "young of certain animals";
smallWords_definition[153] = "food portion to be chewed again";
smallWords_definition[154] = "to signal a start";
smallWords_definition[155] = "together with";
smallWords_definition[156] = "to place into a cup";
smallWords_definition[157] = "mongrel dog";
smallWords_definition[158] = "to make an incision";
smallWords_definition[159] = "circular basin with steep walls (cirque)";
smallWords_definition[160] = "to touch lightly";
smallWords_definition[161] = "father";
smallWords_definition[162] = "hanging shred";
smallWords_definition[163] = "dash in Morse code";
smallWords_definition[164] = "transportion by relay";
smallWords_definition[165] = "lentil dish";
smallWords_definition[166] = "to build a dam";
smallWords_definition[167] = "to dip into water";
smallWords_definition[168] = "to dawn";
smallWords_definition[169] = "24 hours";
smallWords_definition[170] = "debutante";
smallWords_definition[171] = "letter 'd'";
smallWords_definition[172] = "differential calculus operator";
smallWords_definition[173] = "to live in a lair";
smallWords_definition[174] = "Hindu god (deva)";
smallWords_definition[175] = "to wet with dew";
smallWords_definition[176] = "sulfate used as stimulant";
smallWords_definition[177] = "former North African ruler";
smallWords_definition[178] = "to fish";
smallWords_definition[179] = "[do-conj] (to execute)";
smallWords_definition[180] = "to cease living/to make a die";
smallWords_definition[181] = "to scoop earth from the ground";
smallWords_definition[182] = "obscure/to make obscure";
smallWords_definition[183] = "to make a loud noise";
smallWords_definition[184] = "to immerse briefly";
smallWords_definition[185] = "to disrespect";
smallWords_definition[186] = "dot in Morse code";
smallWords_definition[187] = "doctor";
smallWords_definition[188] = "female deer";
smallWords_definition[189] = "to follow after like a dog";
smallWords_definition[190] = "unit of pain intensity";
smallWords_definition[191] = "title given to certain monks";
smallWords_definition[192] = "to put on";
smallWords_definition[193] = "black European beetle";
smallWords_definition[194] = "[do] (first tone of diatonic musical scale)";
smallWords_definition[195] = "to cover with dots";
smallWords_definition[196] = "to prosper";
smallWords_definition[197] = "having no moisture/prohibitionist/to make dry";
smallWords_definition[198] = "to confer knighthood upon";
smallWords_definition[199] = "bomb that fails to explode";
smallWords_definition[200] = "something owed";
smallWords_definition[201] = "teat, udder";
smallWords_definition[202] = "[duo-pl] (instrumental duet)";
smallWords_definition[203] = "of a dull brown color/to demand payment";
smallWords_definition[204] = "instrumental duet";
smallWords_definition[205] = "to open";
smallWords_definition[206] = "to color";
smallWords_definition[207] = "hearing organ";
smallWords_definition[208] = "to consume";
smallWords_definition[209] = "water";
smallWords_definition[210] = "to recede";
smallWords_definition[211] = "old French coin";
smallWords_definition[212] = "Old English letter";
smallWords_definition[213] = "snakelike fish";
smallWords_definition[214] = "letter 'f' (ef)";
smallWords_definition[215] = "[ef] (letter 'f')";
smallWords_definition[216] = "newt";
smallWords_definition[217] = "to throw eggs at";
smallWords_definition[218] = "conscious self";
smallWords_definition[219] = "to get with great difficulty";
smallWords_definition[220] = "old age";
smallWords_definition[221] = "small, often mischievous fairy";
smallWords_definition[222] = "large deer";
smallWords_definition[223] = "letter 'l'";
smallWords_definition[224] = "deciduous tree";
smallWords_definition[225] = "[el] (letter 'l')";
smallWords_definition[226] = "uncle";
smallWords_definition[227] = "electromotive force";
smallWords_definition[228] = "[em] (printer's measurement)";
smallWords_definition[229] = "large, flightless bird";
smallWords_definition[230] = "to terminate";
smallWords_definition[231] = "phonetic symbol";
smallWords_definition[232] = "entity";
smallWords_definition[233] = "long period of time (aeon)";
smallWords_definition[234] = "chronological period (epoch)";
smallWords_definition[235] = "previous to; before";
smallWords_definition[236] = "unit of work or energy";
smallWords_definition[237] = "erne";
smallWords_definition[238] = "to make a mistake";
smallWords_definition[239] = "European climbing plant (ervil)";
smallWords_definition[240] = "letter 's' (es)";
smallWords_definition[241] = "Greek letter";
smallWords_definition[242] = "Old English letter (edh)";
smallWords_definition[243] = "evening";
smallWords_definition[244] = "female sheep";
smallWords_definition[245] = "organ of sight/to watch closely";
smallWords_definition[246] = "passing fancy";
smallWords_definition[247] = "to make weary by hard work";
smallWords_definition[248] = "to use a fan to cool";
smallWords_definition[249] = "at or to a great distance";
smallWords_definition[250] = "[fa] (fourth tone of diatonic musical scale)";
smallWords_definition[251] = "obese/to make fat";
smallWords_definition[252] = "to reproduce by electronic means";
smallWords_definition[253] = "to join closely";
smallWords_definition[254] = "federal agent";
smallWords_definition[255] = "to pay a fee to";
smallWords_definition[256] = "Hebrew letter (pe)";
smallWords_definition[257] = "passive homosexual";
smallWords_definition[258] = "marsh";
smallWords_definition[259] = "for";
smallWords_definition[260] = "to fetch";
smallWords_definition[261] = "to grant land to under Scottish feudal law";
smallWords_definition[262] = "amounting to or consisting of a small number";
smallWords_definition[263] = "crazy";
smallWords_definition[264] = "brimless cap worn by men in the Near East";
smallWords_definition[265] = "to tell a white lie";
smallWords_definition[266] = "topmast support bar";
smallWords_definition[267] = "intj. expressing disapproval";
smallWords_definition[268] = "to adorn";
smallWords_definition[269] = "coin of Iraq, Jordan";
smallWords_definition[270] = "to equip with fins";
smallWords_definition[271] = "evergreen tree";
smallWords_definition[272] = "healthy/to be suitable for";
smallWords_definition[273] = "to repair";
smallWords_definition[274] = "hissing or sputtering sound";
smallWords_definition[275] = "virus disease";
smallWords_definition[276] = "to move through the air";
smallWords_definition[277] = "to deceive";
smallWords_definition[278] = "enemy";
smallWords_definition[279] = "to cover with fog";
smallWords_definition[280] = "intj. faugh";
smallWords_definition[281] = "warm, dry wind (foehn)";
smallWords_definition[282] = "to deceive";
smallWords_definition[283] = "directed or sent to";
smallWords_definition[284] = "drunk";
smallWords_definition[285] = "to outwit";
smallWords_definition[286] = "farewell feast or gift";
smallWords_definition[287] = "away";
smallWords_definition[288] = "to cook over direct heat in hot fat or oil";
smallWords_definition[289] = "to fob";
smallWords_definition[290] = "old-fashioned person";
smallWords_definition[291] = "to make stuffy";
smallWords_definition[292] = "to act playfully";
smallWords_definition[293] = "to cover with fur";
smallWords_definition[294] = "to chatter";
smallWords_definition[295] = "to roam about restlessly";
smallWords_definition[296] = "to go";
smallWords_definition[297] = "to prevent from talking";
smallWords_definition[298] = "girl";
smallWords_definition[299] = "to visit socially";
smallWords_definition[300] = "[gin-conj] (to begin)";
smallWords_definition[301] = "to make an opening in";
smallWords_definition[302] = "to compel";
smallWords_definition[303] = "to supply with gas";
smallWords_definition[304] = "pistol";
smallWords_definition[305] = "merry/homosexual";
smallWords_definition[306] = "food fish";
smallWords_definition[307] = "to turn right";
smallWords_definition[308] = "to become like jelly";
smallWords_definition[309] = "to adorn with gemstones";
smallWords_definition[310] = "knowledge obtained by investigation";
smallWords_definition[311] = "to obtain";
smallWords_definition[312] = "very";
smallWords_definition[313] = "liquid butter made in India (ghee)";
smallWords_definition[314] = "to fasten with a wedge";
smallWords_definition[315] = "disease of sheep";
smallWords_definition[316] = "to give";
smallWords_definition[317] = "to catch fish with a pronged spear";
smallWords_definition[318] = "to begin/to remove seeds from cotton";
smallWords_definition[319] = "to gyp";
smallWords_definition[320] = "intj. used as an order of dismissal";
smallWords_definition[321] = "large antelope";
smallWords_definition[322] = "Asian gazelle";
smallWords_definition[323] = "to fill a pit with waste";
smallWords_definition[324] = "to treat as a god (a supernatural being)";
smallWords_definition[325] = "slimy stuff";
smallWords_definition[326] = "intj. used as a mild oath";
smallWords_definition[327] = "[get-conj] (to obtain)";
smallWords_definition[328] = "gaseous oxygen";
smallWords_definition[329] = "non-Jewish person";
smallWords_definition[330] = "design in oriental carpets";
smallWords_definition[331] = "to chew without teeth";
smallWords_definition[332] = "to shoot with a gun";
smallWords_definition[333] = "to remove the guts of";
smallWords_definition[334] = "governor";
smallWords_definition[335] = "to ridicule";
smallWords_definition[336] = "large room for sports activities";
smallWords_definition[337] = "to swindle";
smallWords_definition[338] = "[have-conj] (to possess)";
smallWords_definition[339] = "to have";
smallWords_definition[340] = "to hack";
smallWords_definition[341] = "ha";
smallWords_definition[342] = "pilgrimage to Mecca (hadj)";
smallWords_definition[343] = "to overact";
smallWords_definition[344] = "Vietnamese monetary unit";
smallWords_definition[345] = "to happen";
smallWords_definition[346] = "[ha] (sound expressing triumph)";
smallWords_definition[347] = "to provide with a hat";
smallWords_definition[348] = "to turn left";
smallWords_definition[349] = "to make into hay";
smallWords_definition[350] = "Hebrew letter (heth)";
smallWords_definition[351] = "to add an edge to";
smallWords_definition[352] = "female chicken";
smallWords_definition[353] = "hip";
smallWords_definition[354] = "case of the pronoun she";
smallWords_definition[355] = "[he] (male person)";
smallWords_definition[356] = "Hebrew letter (heth)";
smallWords_definition[357] = "to cut with an ax";
smallWords_definition[358] = "to cast an evil spell upon";
smallWords_definition[359] = "intj. used to attract attention";
smallWords_definition[360] = "intj. used to represent a hiccup";
smallWords_definition[361] = "[hide-conj] (to conceal)";
smallWords_definition[362] = "to hurry";
smallWords_definition[363] = "objective case of the pronoun he";
smallWords_definition[364] = "Hebrew unit of liquid measure";
smallWords_definition[365] = "aware of the most current styles";
smallWords_definition[366] = "possessive form of the pronoun he";
smallWords_definition[367] = "to strike";
smallWords_definition[368] = "intj. expressing thought";
smallWords_definition[369] = "to provide with hobnails";
smallWords_definition[370] = "portable trough";
smallWords_definition[371] = "to use a hoe";
smallWords_definition[372] = "to take more than one's share";
smallWords_definition[373] = "honeybun";
smallWords_definition[374] = "to move by jumping on one foot";
smallWords_definition[375] = "having a high temperature/to heat";
smallWords_definition[376] = "method of doing something";
smallWords_definition[377] = "heavy barge";
smallWords_definition[378] = "center of a wheel";
smallWords_definition[379] = "color";
smallWords_definition[380] = "to grasp with both arms";
smallWords_definition[381] = "intj. expressing surprise";
smallWords_definition[382] = "to sing without words";
smallWords_definition[383] = "barbarian";
smallWords_definition[384] = "intj. used to mark a marching cadence";
smallWords_definition[385] = "to live in a hut";
smallWords_definition[386] = "hypochondria";
smallWords_definition[387] = "to cover with ice";
smallWords_definition[388] = "fish disease";
smallWords_definition[389] = "intj. expressing distaste";
smallWords_definition[390] = "covered with ice";
smallWords_definition[391] = "[id] (part of psyche)";
smallWords_definition[392] = "if and only if";
smallWords_definition[393] = "[if] (possible condition)";
smallWords_definition[394] = "kind";
smallWords_definition[395] = "evil";
smallWords_definition[396] = "to graft feathers onto a bird's wing";
smallWords_definition[397] = "to apply ink to";
smallWords_definition[398] = "to house at an inn";
smallWords_definition[399] = "[in] (influence)";
smallWords_definition[400] = "electrically charged atom";
smallWords_definition[401] = "to anger";
smallWords_definition[402] = "to annoy";
smallWords_definition[403] = "doctrine";
smallWords_definition[404] = "possesive form of [it]";
smallWords_definition[405] = "climbing vine";
smallWords_definition[406] = "to poke";
smallWords_definition[407] = "to cut unevenly";
smallWords_definition[408] = "to force together tightly";
smallWords_definition[409] = "to cause to shake";
smallWords_definition[410] = "to jabber";
smallWords_definition[411] = "corvine bird";
smallWords_definition[412] = "to turn right (gee)";
smallWords_definition[413] = "to fly in a jet";
smallWords_definition[414] = "game";
smallWords_definition[415] = "to bargain with {offensive}";
smallWords_definition[416] = "to refuse to proceed further";
smallWords_definition[417] = "to bob";
smallWords_definition[418] = "Muslim supernatural being (jinn)";
smallWords_definition[419] = "to work by the piece";
smallWords_definition[420] = "fellow";
smallWords_definition[421] = "to run slowly";
smallWords_definition[422] = "to write down quickly";
smallWords_definition[423] = "to toll";
smallWords_definition[424] = "to rejoice";
smallWords_definition[425] = "to put into a jug";
smallWords_definition[426] = "coin of North Korea";
smallWords_definition[427] = "legal right";
smallWords_definition[428] = "to protrude";
smallWords_definition[429] = "ancient Hebrew unit of measure";
smallWords_definition[430] = "crow-like bird";
smallWords_definition[431] = "Hebrew letter (kaph)";
smallWords_definition[432] = "large cupboard/pl. of ka";
smallWords_definition[433] = "evergreen shrub";
smallWords_definition[434] = "letter 'k'";
smallWords_definition[435] = "parrot";
smallWords_definition[436] = "marijuana";
smallWords_definition[437] = "small barrel";
smallWords_definition[438] = "to know";
smallWords_definition[439] = "to catch";
smallWords_definition[440] = "dry, hollow stalk";
smallWords_definition[441] = "to provide with a key";
smallWords_definition[442] = "Greek letter (chi)";
smallWords_definition[443] = "to tease";
smallWords_definition[444] = "marijuana (kef)";
smallWords_definition[445] = "group of related people";
smallWords_definition[446] = "to sleep";
smallWords_definition[447] = "alcoholic beverage";
smallWords_definition[448] = "to equip";
smallWords_definition[449] = "timber tree";
smallWords_definition[450] = "reddish brown antelope";
smallWords_definition[451] = "large Japanese carp";
smallWords_definition[452] = "hill";
smallWords_definition[453] = "Hebrew unit of measure";
smallWords_definition[454] = "land measure in India";
smallWords_definition[455] = "letter 'q'";
smallWords_definition[456] = "laboratory";
smallWords_definition[457] = "resinous substance secreted by insects";
smallWords_definition[458] = "boy";
smallWords_definition[459] = "to fall behind";
smallWords_definition[460] = "to flee";
smallWords_definition[461] = "to drink with the tongue";
smallWords_definition[462] = "Roman tutelary god";
smallWords_definition[463] = "[la] (sixth tone of diatonic musical scale)";
smallWords_definition[464] = "former Latvian monetary unit";
smallWords_definition[465] = "lavatory";
smallWords_definition[466] = "to sue";
smallWords_definition[467] = "not strict or stringent";
smallWords_definition[468] = "to place";
smallWords_definition[469] = "meadow";
smallWords_definition[470] = "[lead-conj] (to show the way)";
smallWords_definition[471] = "shelter from the wind";
smallWords_definition[472] = "to walk hurriedly";
smallWords_definition[473] = "flower necklace";
smallWords_definition[474] = "Albanian monetary unit";
smallWords_definition[475] = "to rent";
smallWords_definition[476] = "monetary unit of Rumania";
smallWords_definition[477] = "Bulgarian monetary unit";
smallWords_definition[478] = "law";
smallWords_definition[479] = "lea";
smallWords_definition[480] = "lesbian";
smallWords_definition[481] = "liberation";
smallWords_definition[482] = "to provide with a lid";
smallWords_definition[483] = "to become horizontal/to tell untruths";
smallWords_definition[484] = "waterfall (linn)";
smallWords_definition[485] = "to touch with the lips";
smallWords_definition[486] = "[li] (Chinese unit of distance)";
smallWords_definition[487] = "[light] to illuminate";
smallWords_definition[488] = "to throw in a high arc";
smallWords_definition[489] = "to cut down trees for timber";
smallWords_definition[490] = "to subject to a forfeit at the card game loo";
smallWords_definition[491] = "to chop off";
smallWords_definition[492] = "to distribute proportionately";
smallWords_definition[493] = "close to the ground/to make the sound of cattle";
smallWords_definition[494] = "to supply with lox (liquid oxygen)";
smallWords_definition[495] = "to pull with effort";
smallWords_definition[496] = "chimney";
smallWords_definition[497] = "sweetheart";
smallWords_definition[498] = "unit of illumination";
smallWords_definition[499] = "solution used to make soap";
smallWords_definition[500] = "raincoat";
smallWords_definition[501] = "insane/to madden";
smallWords_definition[502] = "more";
smallWords_definition[503] = "magazine";
smallWords_definition[504] = "adult human male";
smallWords_definition[505] = "to draw a map";
smallWords_definition[506] = "to destroy the perfection of";
smallWords_definition[507] = "[ma] (mother)";
smallWords_definition[508] = "to pack into a dense mass";
smallWords_definition[509] = "to mow";
smallWords_definition[510] = "maximum";
smallWords_definition[511] = "to have permission";
smallWords_definition[512] = "medical";
smallWords_definition[513] = "honey";
smallWords_definition[514] = "Hebrew letter";
smallWords_definition[515] = "[man] (adult human male)";
smallWords_definition[516] = "[meet-conj] (to make the acquaintance of)";
smallWords_definition[517] = "to meow";
smallWords_definition[518] = "unit of electrical conductance";
smallWords_definition[519] = "playing marble";
smallWords_definition[520] = "middle";
smallWords_definition[521] = "playing marble";
smallWords_definition[522] = "unit of length";
smallWords_definition[523] = "primly demure";
smallWords_definition[524] = "Russian peasant commune";
smallWords_definition[525] = "[mi] (third tone of diatonic musical scale)";
smallWords_definition[526] = "to combine";
smallWords_definition[527] = "extinct flightless bird";
smallWords_definition[528] = "to crowd about";
smallWords_definition[529] = "soft leather heelless shoe (moccasin)";
smallWords_definition[530] = "one who wears boldly stylish clothes";
smallWords_definition[531] = "to move away";
smallWords_definition[532] = "unit of quantity in chemistry (mole)";
smallWords_definition[533] = "mother";
smallWords_definition[534] = "man";
smallWords_definition[535] = "to make the sound of a cow";
smallWords_definition[536] = "to wipe with a mop";
smallWords_definition[537] = "forest humus";
smallWords_definition[538] = "[mo] (moment)";
smallWords_definition[539] = "witty saying";
smallWords_definition[540] = "to cut down grass";
smallWords_definition[541] = "to cover with mud";
smallWords_definition[542] = "to assault with intent to rob";
smallWords_definition[543] = "to act in disguise";
smallWords_definition[544] = "man";
smallWords_definition[545] = "[mu] (Greek letter)";
smallWords_definition[546] = "mutt";
smallWords_definition[547] = "to capture";
smallWords_definition[548] = "no; not";
smallWords_definition[549] = "to find fault incessantly";
smallWords_definition[550] = "no";
smallWords_definition[551] = "[nim-conj] (to steal)";
smallWords_definition[552] = "Indian flat round leavened bread";
smallWords_definition[553] = "to sleep briefly";
smallWords_definition[554] = "no";
smallWords_definition[555] = "negative vote";
smallWords_definition[556] = "bird beak";
smallWords_definition[557] = "born with the name of";
smallWords_definition[558] = "to catch in a net";
smallWords_definition[559] = "existing only a short time";
smallWords_definition[560] = "to provide with a penpoint";
smallWords_definition[561] = "nothing";
smallWords_definition[562] = "to steal";
smallWords_definition[563] = "to bite quickly";
smallWords_definition[564] = "insect egg";
smallWords_definition[565] = "to veto/water sprite";
smallWords_definition[566] = "wealthy person";
smallWords_definition[567] = "to move the head downward";
smallWords_definition[568] = "strong ale/to fill space with bricks";
smallWords_definition[569] = "classical drama of Japan";
smallWords_definition[570] = "name";
smallWords_definition[571] = "now";
smallWords_definition[572] = "and not";
smallWords_definition[573] = "[no] (negative reply)";
smallWords_definition[574] = "in no way";
smallWords_definition[575] = "present time";
smallWords_definition[576] = "pert. to item number n";
smallWords_definition[577] = "protuberance";
smallWords_definition[578] = "woman belonging to a religious order";
smallWords_definition[579] = "[nu] (Greek letter)";
smallWords_definition[580] = "to gather nuts";
smallWords_definition[581] = "clumsy person";
smallWords_definition[582] = "hardwood tree";
smallWords_definition[583] = "to row with oars";
smallWords_definition[584] = "cereal grass";
smallWords_definition[585] = "African sorcery (obeah)";
smallWords_definition[586] = "African sorcery (obeah)";
smallWords_definition[587] = "South American herb";
smallWords_definition[588] = "one that is odd/unusual";
smallWords_definition[589] = "lyric poem";
smallWords_definition[590] = "[od] (hypothetical force of natural power)";
smallWords_definition[591] = "[oe] (Faroean wind)";
smallWords_definition[592] = "to kill";
smallWords_definition[593] = "often";
smallWords_definition[594] = "unit of electrical resistance";
smallWords_definition[595] = "intj. expressing surprise";
smallWords_definition[596] = "[oh] (to exclaim oh)";
smallWords_definition[597] = "to supply with oil";
smallWords_definition[598] = "Turkish unit of weight";
smallWords_definition[599] = "Turkish unit of weight (oka)";
smallWords_definition[600] = "living or existing for a relatively long time";
smallWords_definition[601] = "shout of approval";
smallWords_definition[602] = "[om] (mantra used in meditation)";
smallWords_definition[603] = "number 1";
smallWords_definition[604] = "[on] (side of wicket in cricket)";
smallWords_definition[605] = "to exclaim in amazement";
smallWords_definition[606] = "out";
smallWords_definition[607] = "to open";
smallWords_definition[608] = "[op] (style of abstract art)";
smallWords_definition[609] = "to choose";
smallWords_definition[610] = "[os-pl] (orifice)";
smallWords_definition[611] = "to form into a sphere";
smallWords_definition[612] = "marine mammal (orca)";
smallWords_definition[613] = "mineral or rock containing valuable metal";
smallWords_definition[614] = "[or] (heraldic color gold)";
smallWords_definition[615] = "table scrap";
smallWords_definition[616] = "ridge of sand (esker)";
smallWords_definition[617] = "stringed instrument of northern Africa";
smallWords_definition[618] = "belonging to us";
smallWords_definition[619] = "to be revealed";
smallWords_definition[620] = "[ovum-pl] (female reproductive cell)";
smallWords_definition[621] = "to be under obligation to pay";
smallWords_definition[622] = "nocturnal bird";
smallWords_definition[623] = "to possess";
smallWords_definition[624] = "containing oxygen";
smallWords_definition[625] = "containing oxygen";
smallWords_definition[626] = "shoe patterned after a moccasin";
smallWords_definition[627] = "to line with padding";
smallWords_definition[628] = "intj. used as an exclamation of disgust";
smallWords_definition[629] = "to hang around with as friends";
smallWords_definition[630] = "jack of clubs";
smallWords_definition[631] = "to criticize harshly";
smallWords_definition[632] = "soft food for infants";
smallWords_definition[633] = "to shoot par on a hole";
smallWords_definition[634] = "[pa] (father)";
smallWords_definition[635] = "to touch lightly";
smallWords_definition[636] = "to scrape at with a paw";
smallWords_definition[637] = "ceremonial embrace";
smallWords_definition[638] = "to give money in order to buy something";
smallWords_definition[639] = "edible seed of an annual herb";
smallWords_definition[640] = "pectoral muscle";
smallWords_definition[641] = "natural soil aggregate";
smallWords_definition[642] = "to urinate {offensive}";
smallWords_definition[643] = "to nail (a wooden pin)";
smallWords_definition[644] = "Hebrew letter (pe)";
smallWords_definition[645] = "to write";
smallWords_definition[646] = "to fill with energy";
smallWords_definition[647] = "for each";
smallWords_definition[648] = "foot/pl. of pe (Hebrew letter)";
smallWords_definition[649] = "to caress with the hand";
smallWords_definition[650] = "bench for seating people in church";
smallWords_definition[651] = "Greek letter";
smallWords_definition[652] = "intj. used as an expression of mild anger";
smallWords_definition[653] = "brain membrane";
smallWords_definition[654] = "photograph";
smallWords_definition[655] = "to pi";
smallWords_definition[656] = "to bear pigs (cloven-hoofed mammals)";
smallWords_definition[657] = "to fasten with a pin";
smallWords_definition[658] = "to break through the shell of an egg";
smallWords_definition[659] = "[pi] (Greek letter)";
smallWords_definition[660] = "to mark with cavities or depressions";
smallWords_definition[661] = "more used as a musical direction";
smallWords_definition[662] = "container for the Eucharist (pyx)";
smallWords_definition[663] = "to supply with or offer repeatedly";
smallWords_definition[664] = "to produce seed vessels";
smallWords_definition[665] = "intj. expressing disgust";
smallWords_definition[666] = "Hawaiian food";
smallWords_definition[667] = "politician";
smallWords_definition[668] = "English immigrant in Australia {offensive}";
smallWords_definition[669] = "to make a sharp, explosive sound";
smallWords_definition[670] = "to put into a pot";
smallWords_definition[671] = "explosive sound";
smallWords_definition[672] = "to infect with syphilis";
smallWords_definition[673] = "argument or vote in favor of something";
smallWords_definition[674] = "to inquire impertinently into private matters";
smallWords_definition[675] = "Greek letter";
smallWords_definition[676] = "tavern";
smallWords_definition[677] = "pudding";
smallWords_definition[678] = "to fill in with clay or mortar";
smallWords_definition[679] = "coin of Afghanistan";
smallWords_definition[680] = "to make a pun (a play on words)";
smallWords_definition[681] = "to give birth to puppies";
smallWords_definition[682] = "to purr";
smallWords_definition[683] = "viscous fluid formed in infected tissue";
smallWords_definition[684] = "to place in a particular position";
smallWords_definition[685] = "copper coin of Burma";
smallWords_definition[686] = "book of ecclesiastical rules";
smallWords_definition[687] = "container for the Eucharist";
smallWords_definition[688] = "evergreen shrub (kat)";
smallWords_definition[689] = "in the capacity of";
smallWords_definition[690] = "to fear";
smallWords_definition[691] = "to scold";
smallWords_definition[692] = "intj. used to cheer on a team or player";
smallWords_definition[693] = "dominion; sovereignty";
smallWords_definition[694] = "to strike with great force";
smallWords_definition[695] = "[run-conj] (to move by rapid steps)";
smallWords_definition[696] = "to strike sharply";
smallWords_definition[697] = "Ethiopian prince";
smallWords_definition[698] = "to hunt rats (long-tailed rodents)";
smallWords_definition[699] = "uncooked/sore or irritated spot";
smallWords_definition[700] = "to stretch out";
smallWords_definition[701] = "to emit rays";
smallWords_definition[702] = "Confederate soldier";
smallWords_definition[703] = "recreation";
smallWords_definition[704] = "of the color red/to put into order";
smallWords_definition[705] = "female Eurasian sandpiper";
smallWords_definition[706] = "to referee";
smallWords_definition[707] = "regulation";
smallWords_definition[708] = "erroneous form of former Portuguese coin";
smallWords_definition[709] = "quantity of ionizing radiation";
smallWords_definition[710] = "cross-ribbed fabric";
smallWords_definition[711] = "thing or matter";
smallWords_definition[712] = "to soak in order to loosen fiber from wood";
smallWords_definition[713] = "to increase the speed of";
smallWords_definition[714] = "animal with a single wavy layer of hair/king";
smallWords_definition[715] = "Greek letter";
smallWords_definition[716] = "long, narrow inlet";
smallWords_definition[717] = "to poke fun at";
smallWords_definition[718] = "to free from something objectionable";
smallWords_definition[719] = "to lay off from employment";
smallWords_definition[720] = "to put in proper condition for use";
smallWords_definition[721] = "to provide with a rim (an outer edge)";
smallWords_definition[722] = "to run or melt";
smallWords_definition[723] = "to tear or cut apart roughly";
smallWords_definition[724] = "to take property from illegally";
smallWords_definition[725] = "lengendary bird of prey";
smallWords_definition[726] = "to provide with a rod";
smallWords_definition[727] = "mass of eggs within a female fish";
smallWords_definition[728] = "male gypsy";
smallWords_definition[729] = "to decompose";
smallWords_definition[730] = "to propel by means of oars";
smallWords_definition[731] = "to move along the surface of a body";
smallWords_definition[732] = "to feel sorrow or remorse for";
smallWords_definition[733] = "to tear roughly";
smallWords_definition[734] = "alcoholic liquor/odd";
smallWords_definition[735] = "to move by rapid steps";
smallWords_definition[736] = "to make ruts (grooves) in";
smallWords_definition[737] = "Scandinavian handwoven rug";
smallWords_definition[738] = "cereal grass";
smallWords_definition[739] = "to sob";
smallWords_definition[740] = "pouchlike structure in an animal or plant";
smallWords_definition[741] = "unhappy";
smallWords_definition[742] = "so";
smallWords_definition[743] = "to bend downward from weight or pressure";
smallWords_definition[744] = "salt";
smallWords_definition[745] = "to weaken gradually";
smallWords_definition[746] = "[sit-conj] (to rest on the buttocks)";
smallWords_definition[747] = "xu";
smallWords_definition[748] = "to cut or divide with a saw";
smallWords_definition[749] = "saxophone";
smallWords_definition[750] = "to utter";
smallWords_definition[751] = "ocean";
smallWords_definition[752] = "secant";
smallWords_definition[753] = "to perceive with the eyes";
smallWords_definition[754] = "advocate of racial segregation";
smallWords_definition[755] = "large whale (rorqual)";
smallWords_definition[756] = "self";
smallWords_definition[757] = "monetary unit of Japan";
smallWords_definition[758] = "unit of weight of India";
smallWords_definition[759] = "to put in a particular position";
smallWords_definition[760] = "to mend or fasten with a needle and thread";
smallWords_definition[761] = "to determine the sex of";
smallWords_definition[762] = "intj. used to urge silence (shh)";
smallWords_definition[763] = "female person";
smallWords_definition[764] = "intj. used to urge silence";
smallWords_definition[765] = "timid/to move suddenly back in fear";
smallWords_definition[766] = "sibling";
smallWords_definition[767] = "to urge to attack";
smallWords_definition[768] = "simulation";
smallWords_definition[769] = "to commit a sin";
smallWords_definition[770] = "to drink in small quantities";
smallWords_definition[771] = "respectful form of address used to a man";
smallWords_definition[772] = "sister";
smallWords_definition[773] = "to rest on the buttocks";
smallWords_definition[774] = "number 6";
smallWords_definition[775] = "Jamaican music";
smallWords_definition[776] = "to travel on skis";
smallWords_definition[777] = "to hit or throw toward the sky";
smallWords_definition[778] = "crafty";
smallWords_definition[779] = "to cry with a convulsive catching of the breath";
smallWords_definition[780] = "to cover with sod (turf)";
smallWords_definition[781] = "fifth tone of diatonic musical scale (so)";
smallWords_definition[782] = "male child";
smallWords_definition[783] = "to dip or soak in a liquid";
smallWords_definition[784] = "fifth tones of diatonic musical scale";
smallWords_definition[785] = "habitual drunkard";
smallWords_definition[786] = "former French coin";
smallWords_definition[787] = "to scatter over land for growth, as seed";
smallWords_definition[788] = "knitted or woven coverings for the foot";
smallWords_definition[789] = "soybean";
smallWords_definition[790] = "mineral spring";
smallWords_definition[791] = "to watch secretly";
smallWords_definition[792] = "mister; sir used as a Hindu title of respect";
smallWords_definition[793] = "to keep in a pigpen";
smallWords_definition[794] = "to act as a substitute";
smallWords_definition[795] = "to institute legal proceedings against";
smallWords_definition[796] = "to add into one total";
smallWords_definition[797] = "to expose to the sun";
smallWords_definition[798] = "to eat supper";
smallWords_definition[799] = "marketplace (souk)";
smallWords_definition[800] = "syne";
smallWords_definition[801] = "to name or designate";
smallWords_definition[802] = "small boy";
smallWords_definition[803] = "to";
smallWords_definition[804] = "to provide with a tag";
smallWords_definition[805] = "tall, conical cap worn in Muslim countries";
smallWords_definition[806] = "tight-fitting Scottish cap";
smallWords_definition[807] = "brown from the sun's rays";
smallWords_definition[808] = "path of virtuous conduct";
smallWords_definition[809] = "to strike gently";
smallWords_definition[810] = "to cover with tar";
smallWords_definition[811] = "[ta] (thanks)";
smallWords_definition[812] = "to make tatting";
smallWords_definition[813] = "greek letter";
smallWords_definition[814] = "Hebrew letter";
smallWords_definition[815] = "to convert into white leather";
smallWords_definition[816] = "to place a tax on";
smallWords_definition[817] = "beverage made by infusing leaves in water";
smallWords_definition[818] = "to spread for drying";
smallWords_definition[819] = "to place a golf ball on a small peg";
smallWords_definition[820] = "yearling sheep";
smallWords_definition[821] = "ancient mound in the Middle East";
smallWords_definition[822] = "number 10";
smallWords_definition[823] = "Hebrew letter (teth)";
smallWords_definition[824] = "to work hard";
smallWords_definition[825] = "article used to specify or make particular";
smallWords_definition[826] = "though";
smallWords_definition[827] = "possessive form of the pronoun thou";
smallWords_definition[828] = "involuntary muscular contraction";
smallWords_definition[829] = "to fasten with a cord or rope";
smallWords_definition[830] = "sesame plant";
smallWords_definition[831] = "to coat with tin";
smallWords_definition[832] = "to tilt";
smallWords_definition[833] = "seventh tone of diatonic musical scale";
smallWords_definition[834] = "small bird";
smallWords_definition[835] = "British unit of weight";
smallWords_definition[836] = "to touch with the toe";
smallWords_definition[837] = "to clothe";
smallWords_definition[838] = "male of various animals";
smallWords_definition[839] = "unit of weight";
smallWords_definition[840] = "in addition";
smallWords_definition[841] = "to cut off the top";
smallWords_definition[842] = "high, craggy hill";
smallWords_definition[843] = "to total";
smallWords_definition[844] = "to pull by means of a rope or chain";
smallWords_definition[845] = "to amuse oneself as if with a toy";
smallWords_definition[846] = "to attempt";
smallWords_definition[847] = "to utter a scolding exclamation";
smallWords_definition[848] = "to wash in a tub";
smallWords_definition[849] = "to pull with force";
smallWords_definition[850] = "bird of New Zealand";
smallWords_definition[851] = "to store in a large cask";
smallWords_definition[852] = "to copulate with a ewe";
smallWords_definition[853] = "to utter an exclamation of impatience";
smallWords_definition[854] = "tuxedo";
smallWords_definition[855] = "two";
smallWords_definition[856] = "number 2";
smallWords_definition[857] = "chain on a ship";
smallWords_definition[858] = "Japanese herb";
smallWords_definition[859] = "sound of a cough or grunt";
smallWords_definition[860] = "ukulele";
smallWords_definition[861] = "Eskimo knife";
smallWords_definition[862] = "intj. expressing hesitation (um)";
smallWords_definition[863] = "to umpire";
smallWords_definition[864] = "[un] (one)";
smallWords_definition[865] = "upon";
smallWords_definition[866] = "[up] (to raise)";
smallWords_definition[867] = "urban area";
smallWords_definition[868] = "annual bean grown in India";
smallWords_definition[869] = "type of vase";
smallWords_definition[870] = "to put into service";
smallWords_definition[871] = "large lizard";
smallWords_definition[872] = "[ut] (musical tone)";
smallWords_definition[873] = "vacuum cleaner";
smallWords_definition[874] = "large motor vehicle";
smallWords_definition[875] = "unit of reactive power";
smallWords_definition[876] = "anatomical duct";
smallWords_definition[877] = "to put into a vat";
smallWords_definition[878] = "Hebrew letter (vav)";
smallWords_definition[879] = "Hebrew letter";
smallWords_definition[880] = "Hebrew letter (vav)";
smallWords_definition[881] = "letter 'v'";
smallWords_definition[882] = "vegetable";
smallWords_definition[883] = "to treat animals medically";
smallWords_definition[884] = "to annoy";
smallWords_definition[885] = "by way of";
smallWords_definition[886] = "to strive for superiority";
smallWords_definition[887] = "charge paid to a bookie on a bet";
smallWords_definition[888] = "energy";
smallWords_definition[889] = "force or power";
smallWords_definition[890] = "small bay, creek, or inlet";
smallWords_definition[891] = "to make a vow";
smallWords_definition[892] = "voice";
smallWords_definition[893] = "small cavity in a rock or lode";
smallWords_definition[894] = "web";
smallWords_definition[895] = "to form into a wad";
smallWords_definition[896] = "woe";
smallWords_definition[897] = "to move briskly up and down or to and fro";
smallWords_definition[898] = "to become wan/unnaturally pale";
smallWords_definition[899] = "to wrap";
smallWords_definition[900] = "to engage in war";
smallWords_definition[901] = "[be-conj] (to exist)";
smallWords_definition[902] = "hare/wet";
smallWords_definition[903] = "Hebrew letter (vav)";
smallWords_definition[904] = "to coat with wax";
smallWords_definition[905] = "method of doing something";
smallWords_definition[906] = "to provide with a web";
smallWords_definition[907] = "to marry";
smallWords_definition[908] = "short time/very small";
smallWords_definition[909] = "benign skin tumor";
smallWords_definition[910] = "soaked with a liquid/to make wet";
smallWords_definition[911] = "who";
smallWords_definition[912] = "what or which person or persons";
smallWords_definition[913] = "reason or cause of something";
smallWords_definition[914] = "to provide with a wig";
smallWords_definition[915] = "to be victorious/to winnow";
smallWords_definition[916] = "to know";
smallWords_definition[917] = "intelligence/to know";
smallWords_definition[918] = "wizard";
smallWords_definition[919] = "tremendous grief";
smallWords_definition[920] = "dark-skinned foreigner";
smallWords_definition[921] = "cooking utensil";
smallWords_definition[922] = "to dwell";
smallWords_definition[923] = "to seek the affection of";
smallWords_definition[924] = "Italian {offensive}";
smallWords_definition[925] = "[wo] (woe)";
smallWords_definition[926] = "to know";
smallWords_definition[927] = "to excite to enthusiastic approval";
smallWords_definition[928] = "contorted/to contort";
smallWords_definition[929] = "insane";
smallWords_definition[930] = "letter 'y'";
smallWords_definition[931] = "rune for 'W' (wynn)";
smallWords_definition[932] = "[xi] (Greek letter)";
smallWords_definition[933] = "intj. used as an exclamation of disgust";
smallWords_definition[934] = "to chatter";
smallWords_definition[935] = "plant having an edible root";
smallWords_definition[936] = "to bark shrilly";
smallWords_definition[937] = "yare";
smallWords_definition[938] = "to deviate from an intended course";
smallWords_definition[939] = "to this extent";
smallWords_definition[940] = "affirmative vote";
smallWords_definition[941] = "yeah";
smallWords_definition[942] = "to yearn";
smallWords_definition[943] = "yes";
smallWords_definition[944] = "to give an affirmative reply to";
smallWords_definition[945] = "up to now";
smallWords_definition[946] = "evergreen tree or shrub";
smallWords_definition[947] = "Jew {offensive}";
smallWords_definition[948] = "feminine passive principle {Chinese}";
smallWords_definition[949] = "to yelp";
smallWords_definition[950] = "hoodlum";
smallWords_definition[951] = "Hebrew letter";
smallWords_definition[952] = "boisterous laugh";
smallWords_definition[953] = "day";
smallWords_definition[954] = "yonder";
smallWords_definition[955] = "2d person sing. or pl. pronoun";
smallWords_definition[956] = "to yowl";
smallWords_definition[957] = "to laugh loudly";
smallWords_definition[958] = "intj. expressing tasteful pleasure";
smallWords_definition[959] = "yep";
smallWords_definition[960] = "to turn sharply";
smallWords_definition[961] = "to kill or destroy";
smallWords_definition[962] = "tool for cutting roof slates";
smallWords_definition[963] = "letter 'z'";
smallWords_definition[964] = "letter 'z'";
smallWords_definition[965] = "inmate in a Soviet labor camp";
smallWords_definition[966] = "to turn sharply";
smallWords_definition[967] = "zinfandel";
smallWords_definition[968] = "to move rapidly";
smallWords_definition[969] = "pimple";
smallWords_definition[970] = "whole product of a fertilized egg";
smallWords_definition[971] = "place where animals are kept";

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	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"
		},
		{		// for newer Netscapes (6+)
			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"
		},
		{ 		// for older Netscapes (4-)
			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.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();


var QUESTION_NAMES = ["color-madness", "100s", "three-letter-words", "fill-in-the-blank", "word-grid", "add-it-up", "tetris", "mega-grid","steps-forward", "shapes-grid", "complements", "hi-fives", "smiles", "root-beer", "warm-up"];


var EXPLORER = false;
var NEXT_QUESTION_OPTION_1 = "";
var NEXT_QUESTION_OPTION_2 = "";


if (BrowserDetect.browser == "Explorer") 
    EXPLORER = true;


 function submitUtility(formid) {
	$(formid).submit();
 }

// -----------------------------------------------------------

 function askNextQuestion() {

     var next = $("next_question");
     if (! next || ! next.value || next.value == "") {


         var num_answered = getNumberAnswered("verbal") + getNumberAnswered("math") + getNumberAnswered("spatial") + getNumberAnswered("social");
         if (num_answered > 0)
         {

             showNextQuestionMenu("");
             $("question-master-warm-up").style.display = "none";

         }
         else
         {
             
             initializeWarmUp();
             showQuestion("warm-up");
         }
     }
     else {
         if (next.value == "root-beer") initializeRootBeer();
         showQuestion(next.value);

     }
 }

 // -----------------------------------------------------------

 function showQuestion(name) {
   for (var i = 0; i < QUESTION_NAMES.length; i++) {
       if (name == QUESTION_NAMES[i]) {

           var total_answered =
               getNumberAnswered("spatial")
               + getNumberAnswered("math")
               + getNumberAnswered("verbal")
               + getNumberAnswered("social");
           total_answered ++;
           $("question-master-" + name).style.display = "block";
           $("number-" + name).innerHTML = "<i style='font-size: 18px;'>Puzzle " + total_answered + "</i><br/>";
       }
       else {
           
           $("question-master-" + QUESTION_NAMES[i]).style.display = "none";
       }
   }
 }

 // -----------------------------------------------------------

function showQuestionMini(name) {
    $("question-master-" + name).style.display = "block";    
}



 // ----------------------------------redo stuff -------------------

function markQuestionAsRedo(name) {

  setMiniCookie("can_" + name + "_redo","yes","");

}

function unmarkQuestionAsRedo(name) {

  setMiniCookie("can_" + name + "_redo","no","");

}

 

function canRedoQuestion(name) {

  var redo = getMiniCookie("can_" + name + "_redo","");

 if (redo && redo == "yes") {
  unmarkQuestionAsRedo(name);
  return true;

 }

 else {

   return false;

 }

}



function redoQuestion() {
    var x = parseInt($F('next-page'));
    x--;
    $('next-page').value = x;
    $('testform').submit();
}

function declineRedo(name){
	 // called if user decides to not redo question	 

	 Effect.Fade('question-redo-' + name, {delay: .3, duration: 1, afterFinish: function() {
		      finishQuestion(name)
      ;}})


}
function disableRedoButtons(name) {
	 // this is called when the taker clicks either button, to
	 // prevent crazy-clicking

	 $('redo-' + name).disabled = "disabled";
	 $('decline-redo-' + name).disabled = "disabled";	


}




//-----------------------------------------------


 function finishQuestion(name) {	
   $("testform").name = "break-persistance-" + Math.random().toString();

   stopGame(name);

   if (canRedoQuestion(name)) {

      Effect.Fade("question-content-" + name);
      Effect.Appear("question-redo-" + name, {delay: .5, queue:'end'});

   }
   else {

	doScoring(name);
	showResults(name);
	showNextQuestionMenu(name);
	GAME_STARTED = false;
	TIMES_UP = false;
	END_EARLY = false;
	LOCK_QUESTION = false; 

   }
 }

 // -----------------------------------------------------------


function doScoring(name) {


    var score = 0;
    var num_correct = 0;
    var num_incorrect = 0;

    var resultsHeadline = "";
    var resultsGenre = "";
    var resultsText1 = "";
    var resultsText2 = "";	 
    var resultsComment = "";
    var resultsEarned = "Earned!";


    // ------------------------------

    if (name == "color-madness") {
	  resultsGenre = "spatial";

      num_correct = safeParse(document.getElementById("result1-" + name).innerHTML);
	  num_incorrect = safeParse(document.getElementById("result2-" + name).innerHTML);


	  resultsHeadline = num_correct;
	  resultsText1 = "you spotted";
	  resultsText2 = "changing blocks";

	  if (num_correct == 1) resultsText2 = "changing block";

	  resultsComment = "You got <b>" + num_correct + "</b> right and " ;

	  if (num_incorrect == 0) {
	     resultsComment += "<b>0</b> wrong. ";
	  }	  
	  else if (num_incorrect == 1) {
	     resultsComment += "just <b>1</b> one wrong. "		  
	  }
	  else {
             resultsComment += "<b>" + num_incorrect + "</b> wrong. ";
	  }

	  var d = num_correct - num_incorrect;

	  if (d > 0 && num_correct > 3) {
	         resultsComment += "That's a very good score. Getting more right than wrong on this question is hard. ";
          }
	  else if ( d == 0 && num_correct > 2){
		   resultsComment +=  "A 50% ratio is quite good on this puzzle. ";
	  }
	  else if ( d < 0 && num_correct > 2) {
	         resultsComment += "Don't worry that you got more wrong than right on this puzzle. It's very difficult. ";

	  }
	  if (num_correct + num_incorrect == 0) "In fact, you didn't even click a single square. Why don't you try another question type this time? ";
          resultsComment += "In fact, the average taker gets less than half right on this guy. ";

	  if ( d > 3 && num_correct > 3) resultsComment += "Your net difference of <b>&#43;" + d + "</b> is particularly outstanding. ";



	  var total_answered = num_correct + num_incorrect;

          score = num_correct - num_incorrect/3 - 1 ;
	  if (score < num_correct/2) score = Math.floor(num_correct/2);

    }

    // ------------------------------

    else if (name == "shapes-grid") {
	  resultsGenre = "spatial";
          num_correct = safeParse(document.getElementById('debug-' + name).innerHTML);
          num_incorrect = safeParse(document.getElementById('debug2-' + name).innerHTML);


	  resultsHeadline = num_correct;
	  resultsText1 = "you got";
	  resultsText2 = "of the positions right";


	  if (num_correct == 1) resultsText2 = "position right";

	  var extraComment = "";  
	  var even = "";
	  var d = num_correct - num_incorrect;
	  var total_answered = num_correct + num_incorrect;	   

          if (total_answered < 5) {
	         resultsComment += "It looks like you had a hard time with this puzzle, getting ";
		 extraComment = ".  But don't worry about it too much. There'll be plenty more scoring chances on the test. ";
	  }	  
	  else if (d > 3) {
	         resultsComment = "You made short work of this puzzle, getting ";
	         extraComment = ". That's an exceptionally high ratio. ";
		 even = "even";
          }
	  else if ( d > 0 && d <=3) {
	         resultsComment += "You did very well on this puzzle, getting ";
	         extraComment = ". That's a well above-average ratio. ";
		 even = "even";
	  }
	  else if ( d <= 0 && d >= -2 ){
  	         resultsComment +=  "You did pretty well on this puzzle, getting  ";
		 extraComment = ". The average taker gets slightly less than half right. ";  

	  }
	  else if ( d < -2 ) {
	         resultsComment += "It looks like you had a hard time with this puzzle, getting ";
		 extraComment = ". But don't worry about it too much. There'll be plenty more scoring chances on the test. ";	  
	  }

	  var grids = "grids";
          if (num_correct == 1) grids = "grid";
	  resultsComment += "<b>" + num_correct + "</b> " + grids +" right and " ;

	  if (num_incorrect == 0) {
	     resultsComment += "<b>0</b> wrong";
	  }	  
	  else if (num_incorrect == 1) {
	     resultsComment += "just <b>1</b> one wrong"		  
	  }
	  else {
             resultsComment += "<b>" + num_incorrect + "</b> wrong";
	  }

          resultsComment += extraComment + "<br/><br/>";
	  resultsComment += "You'll do " + even + " better next time you take it. ";
          resultsComment += "This puzzle is the office favorite here at <b>OkCupid</b> ";
          resultsComment += "(the current top score without an error is <b>10</b> grids in a minute). ";


          score = num_correct - num_incorrect / 2;


    }

    // ------------------------------

    else if (name == "complements") {
	resultsGenre = "spatial";

        num_correct = CORRECT_COMPLEMENTS;
        num_incorrect = INCORRECT_COMPLEMENTS;



	resultsHeadline = num_correct;
	resultsText1 = "You got";
	resultsText2 = "of the pairs right";


	if (num_correct == 1) resultsText2 = "pair right";
        if (num_correct == 7) resultsHeadline = "all 7";



        if(num_correct == 7) {
		resultsComment = "It's <i>very hard</i> to get every		pair right in just 30 seconds. ";
		resultsComment += "Excellent. ";
	  }
        else if (num_correct > 3){
		resultsComment = "You did very well on this puzzle. It's near impossible to get them all right in the time allotted. ";
            	resultsComment += "We've practically got this puzzle		memorized and it's still a race. ";
		
        }
	else {
                resultsComment = "You did okay on this puzzle. It's near impossible to get them all right in the time allotted,	and that's why it's the last spatial test.  ";

	}


	if (num_incorrect == 0 && num_correct > 2) {
	   resultsComment += "And since you made <b>no</b> incorrect matches, we'll kick in a few bonus points. ";

	}
        else if (num_correct == 1 && num_correct > 2) {
	   resultsComment += "Since you only got one match wrong, we'll kick in a few bonus points. ";
	}

        score = 10 * num_correct / 7 -  2 * num_incorrect;

    }

    else if (name == "tetris") {
	resultsGenre = "spatial";

        var time;

        if (!TETRIS_SOLVED) {
	     resultsHeadline = "?";
	     resultsText1 = "";
	     resultsText2 = "you didn't complete the grid.";

           resultsComment = "You didn't solve this puzzle, but we won't deduct too many points. It was kind of a weird question, and maybe you've never played <i>Tetris</i>  before. ";
           resultsComment += "But choose something that suits your strengths  ";
           resultsComment += "this time.";
	     score = 0;
        }
        else {

          time = TimeLapsed;

	    resultsHeadline = time;
	    resultsText1 = "you completed the grid in";
	    resultsText2 = "seconds";

          if (time < 10) {
             resultsComment  = "That's very fast. The average time for someone with your current score profile is <b>10</b> seconds.";
          }
          else if (time < 20 && time >= 10) {
             resultsComment  = "That's quite a good time. The average time for someone with your current score profile is just under <b>19</b> seconds.";
          }
          else {
             resultsComment = "Good job. It's not as easy as it seems, huh? " +
             "The average time for someone with your score profile is " +
             "<b>24</b> seconds.";
          }


          score = 10 - (time - 5) * .4;

        }






    }

    // ------------------------------

    else if (name == "fill-in-the-blank") {

        var non_words = 0;
        var num_words_made = RARITY_FILL_IN_THE_BLANK.length;
        var common = 0;
        var uncommon = 0;
        var common_text;
        var uncommon_text;
        
	var str = "";

	resultsGenre = "verbal";

	resultsText1 = "you completed";
	resultsText2 = "words";


        // fill in str and count up common and uncommons

        var uncommon_words = new Array();
        var common_words = new Array();

        uncommon_words[0] = "dank";
        uncommon_words[1] = "repent";
        uncommon_words[2] = "puce";
        uncommon_words[3] = "spelt";
        uncommon_words[4] = "pathos";
        uncommon_words[5] = "ether";
        uncommon_words[6] = "hart";
        uncommon_words[7] = "foment";
        uncommon_words[8] = "cull";
        uncommon_words[9] = "pith";
        uncommon_words[10] = "apposite";
        uncommon_words[11] = "rapine";
        uncommon_words[12] = "lupine";
        uncommon_words[13] = "crass";
        uncommon_words[14] = "proscribe";
        uncommon_words[15] = "musk";
        uncommon_words[16] = "avert";
        common_words[0] = "dark";
        common_words[1] = "repeat";
        common_words[2] = "pace";
        common_words[3] = "spent";
        common_words[4] = "patios";
        common_words[5] = "other";
        common_words[6] = "hurt";
        common_words[7] = "moment";
        common_words[8] = "cult";
        common_words[9] = "path";
        common_words[10] = "opposite";
        common_words[11] = "ravine";
        common_words[12] = "supine";
        common_words[13] = "cross";
        common_words[14] = "prescribe";
        common_words[15] = "mask";
        common_words[16] = "alert";


        str += '<br/><h3 style="text-align:center;"><span style="visibility:hidden">un</span>common / uncommon</h3>';


        for (var i = 0 ; i < num_words_made; i ++ ) {



            if (RARITY_FILL_IN_THE_BLANK[i] == 0) {
               str += "<u>" + common_words[i] + "</u>";
               str += " / ";
               str += uncommon_words[i];
               str += "<br/>";


               common ++;


            }
            else if (RARITY_FILL_IN_THE_BLANK[i] == 1) {
               str += common_words[i];
               str += " / ";
               str += "<u>" + uncommon_words[i] + "</u>";
               str += "<br/>";
               uncommon ++;

            }
            else {
               non_words++;

            }


        }
   resultsHeadline = num_words_made - non_words;
	var were1 = "were";
	var were2 = "were";

	if (uncommon ==1) were1 = "was";
	if (common == 1) were2 = "were";


	resultsComment = "Of the <u>words you spelled</u>, <b>" 
			+ common
			+ "</b> " + were2 + " the common possibility and <b>"
			+ uncommon
			+ "</b> " + were1 + " the rarer one:<br/>";

	resultsComment += "<center>" + str + "</center><br/>";

    if (uncommon > 0){

        if (uncommon + common > 3) {
            resultsComment += "Overall, that's quite a good ratio. Most people spell only one or two rare words out of every ten. "
        }

        resultsComment += "You got triple points on this puzzle for each rarer spelling. ";


    }
    else {
        resultsComment += "You spelled only common words, which will cost you a few points. You should be able to make that up later, though. ";
    }

    if (uncommon + common == 0) resultsComment = "You didn't complete any words! If there is a bug in the test, please report it!";



        score = 10 * (common  + 3 * uncommon - 2 * non_words) / 20;

        normalizeScore(score);

    }

	 // ------------------------------

    else if (name == "three-letter-words") {


        var str = "";
        var num_words = WORD_ENTRIES.length;


	resultsGenre = "verbal";
        resultsHeadline = num_words;
	resultsText1 = "you got";	
	resultsText2 = "three letter words";



        for (var i = 0; i  < num_words; i ++) {

            str += "<span style='text-transform:lowercase'>" + WORD_ENTRIES[i] + "</span> &#8212 <i>"  + DEFINITIONS[i] + "</i><br/>";

        }
	if (num_words > 0) {
		resultsComment += "Here's what you spelled, along with definitions:";
		resultsComment += "<div class='indent short-word-list'>" + str + "</div>";
	}

	var avg_score = 9;

        if (num_words == 0) {
		resultsComment += "As you can see...you didn't spell a single word. Maybe there's something wrong with your keyboard?";
        }
        else if (num_words == 1) {
		resultsComment += "You spelled only the above word. That's not so good, but there'll be plenty of chances to make up points on the test. ";
		resultsComment += "Maybe choose another question type this time. ";

	}
        else if (num_words > 1 && num_words <= 5) {
		resultsComment += "You spelled only a handful of words. That't not so that great, but there'll be plenty of chances to make up points on the test. ";
		resultsComment += "Maybe choose another question type this time. ";

	}
        else if (num_words > 5 && num_words <= 13) {
		resultsComment += "You did pretty well to get <b>" + num_words + "</b> words. ";
		resultsComment += "The question's also a little bit of a typing test, which is unfortunate. Our guess ";
		resultsComment += "is that you'd do even better ";
		resultsComment += "with a pen and paper. ";
		resultsComment += "You should try other verbal questions, because it's looking like you're developing an affinity for them. ";
        	avg_score = 11;
        }
        else if (num_words > 13 && num_words <= 24) {
		resultsComment += "<b>" + num_words + "</b> words is a very good score on this question. ";

		resultsComment += "You should try other verbal questions, because you're doing quite well on them overall. ";
        	avg_score = 13;
        }
        else if (num_words > 24) {
		resultsComment += "<b>" + num_words + "</b> words is outstanding. ";
		resultsComment += "You should try other verbal questions if you enjoy them, because you're doing very well on them overall. ";
        	avg_score = 15;
        }

	resultsComment += "<br/><br/>We use a Scrabble-type for this question, which lists <b>941</b> three-letter possibilities (most of which are very rare indeed). "
	resultsComment += "The average taker with your overall score profile gets " + avg_score + ".";


        score = Math.round(10 * num_words / 30);

    }

    // ------------------------------

    else if (name == "mega-grid") {


        var str = "";
        var num_words = MEGA_ENTRIES.length;
        var points_word;
        var total_points = 0;





        for (var i = 0; i  < num_words; i ++) {

            total_points += MEGA_POINTS[i];

            if (MEGA_POINTS[i] == 1) points_word = "point";
            else points_word = "points";

            str += MEGA_ENTRIES[i] + " &#8212 "  + MEGA_POINTS[i] + " " + points_word+ "<br/>";

        }

	if(num_words > 1) {

		resultsComment += "Your total broke down like so:";
		resultsComment += "<div class='indent short-word-list'>" + str + "</div>";

	}

        if (total_points <= 5) {

           resultsComment += "Maybe you weren't trying, because that's not a very good score on this question. ";
        }
        else if (total_points > 5 && total_points <= 25) {
           resultsComment += "You did pretty well. ";
	   resultsComment += "There's only one more verbal question possible on the test; ";
 	   resultsComment += "if you have more to go, you might consider exploring the other types to round out your score. ";
        }
        else if (total_points > 25 && total_points <= 50) {

           resultsComment += "You did really well. ";
	   resultsComment += "There's one more verbal question on the test, and if you get the chance, take it. You'd doing well above average on these questions. ";
        }
        else if (total_points > 50) {

          resultsComment += "You did exceptionally well. ";
	  resultsComment += "There's one more verbal question on the test, and if you get the chance, take it. You'd doing well above average on these questions. ";
        }

	resultsGenre = "verbal";
        resultsHeadline = total_points;
	resultsText1 = "you scored";	
	resultsText2 = "points on the grid";




        score = 10 * total_points / 60;



    }
    // ------------------------------

    else if (name == "word-grid") {

        var common = 0;
        var uncommon = 0;
        var non_words = 0;
        var common_text;
        var uncommon_text;



        var word_grid_answers = new Array();

        //3 horizontal words
        word_grid_answers[0] = WORD_GRID_LETTERS[0] + WORD_GRID_LETTERS[1] +WORD_GRID_LETTERS[2];
        word_grid_answers[1] = WORD_GRID_LETTERS[3] + WORD_GRID_LETTERS[4] +WORD_GRID_LETTERS[5];
        word_grid_answers[2] = WORD_GRID_LETTERS[6] + WORD_GRID_LETTERS[7] +WORD_GRID_LETTERS[8];

        //3 vertical
        word_grid_answers[3] = WORD_GRID_LETTERS[0] + WORD_GRID_LETTERS[3] + WORD_GRID_LETTERS[6];
        word_grid_answers[4] = WORD_GRID_LETTERS[1] + WORD_GRID_LETTERS[4] + WORD_GRID_LETTERS[7];
        word_grid_answers[5] = WORD_GRID_LETTERS[2] + WORD_GRID_LETTERS[5] + WORD_GRID_LETTERS[8];

        //1 diagonal
        word_grid_answers[6] = WORD_GRID_LETTERS[6] + WORD_GRID_LETTERS[4] + WORD_GRID_LETTERS[2];



        //check these words for validity then rarity
        var rarity;
	var str ="";
        for (var i = 0 ; i < word_grid_answers.length; i++ ){


           rarity = getRarityWordGrid(word_grid_answers[i]);




           if (rarity == "uncommon") {
              uncommon ++;
              str += word_grid_answers[i] + "&#8212;an uncommon word<br/>";
           }
           else if (rarity == "common") {
              common++;
              str += word_grid_answers[i] + "&#8212;a common word<br/>";


           }
           else if (!rarity) {

              non_words++;
              str += word_grid_answers[i] + "&#8212;not a word<br/>";

           }


        }


	document.getElementById('results-word-grid-table').style.display = "";





	resultsComment += "<h3 style='text-align:center;'>which yields</h3>";
	resultsComment += "<div class='indent short-word-list' style='text-align:center;'>" + str + "</div>";


	resultsComment += "You get bonus points here for each <i>common</i> word you spell (out of the possible 7), ";
	resultsComment += "So you did well on this last verbal question. ";


        if (word_grid_answers[0] == "p" && word_grid_answers[1] == "a"  && word_grid_answers[2] == "y" ) {


           resultsComment = "You didn't even try! We hope you like the other questions better! ";
        }




        fillResultsWordGrid(WORD_GRID_LETTERS[1], WORD_GRID_LETTERS[2], WORD_GRID_LETTERS[3], WORD_GRID_LETTERS[5], WORD_GRID_LETTERS[6], WORD_GRID_LETTERS[7]);


        score = Math.round(10 * common/7);


	resultsGenre = "verbal";
        resultsHeadline = score;
	resultsText1 = "you scored";	
	resultsText2 = "points out of 10 on the grid";



    }

    // ------------------------------


    else if (name == "100s") {

        num_correct = safeParse(document.getElementById('score-100s').innerHTML);



        resultsGenre = "math";
        resultsHeadline = num_correct;
        resultsText1 = "you made";	
        resultsText2 = "groups of 100";




        if (num_correct == 1)
           resultsComment = "Just 1 group of 100 isn't so great, but it's not the worst we've seen either. ";
        else if (num_correct == 0)
           resultsComment = "That's not very good. Please check your keyboard. ";
        else if (num_correct > 1 && num_correct <= 4)
           resultsComment = "Not bad: that's roughly average. ";
        else if (num_correct> 4 && num_correct <= 7)
           resultsComment = "Well done; that's above average. ";
        else if (num_correct  > 7 )
           resultsComment = "<b>" + num_correct + "</b> groups is very high. Great job. ";

        var score_reaction =" <b>9</b>";
        if (num_correct == 9) score_reaction = ", in fact, 9 as well";
        if (num_correct > 9) score_reaction = " just 9, so you beat even us geniuses";
            
        resultsComment += "The current record in the office here is" + score_reaction + ". Although a lot of this puzzle involves searching through the grid ";
        resultsComment += "(and not so much actual calculation) the ability to sort through arrays of numbers quickly correlates strongly to mathematical ability. ";


        score = 10 * num_correct / 8;


    }

    // ------------------------------

    else if (name == "add-it-up") {



        var points;
        num_correct = safeParse(document.getElementById('debug1-add-it-up').innerHTML);
        num_incorrect = safeParse(document.getElementById('debug2-add-it-up').innerHTML);

        points = num_correct - 2 * num_incorrect;




	resultsGenre = "math";
        resultsHeadline = points;
	resultsText1 = "you scored";	
	resultsText2 = "points";



	resultsComment = "We score this puzzle by awarding 1 point for every correct answer and subtracting 2 for each wrong one. "; 

        if (num_correct == 1)
           resultsComment += "You got <b>1</b> problem right ";
        else
           resultsComment += "You got <b>" + num_correct + "</b> problems right ";



        if (num_incorrect == 0)
           resultsComment += "and missed <b>none</b>. ";
        else if (num_incorrect == 1)
           resultsComment += "and missed just <b>1</b>. ";
        else
           resultsComment += "and missed <b>" + num_incorrect + "</b>. ";


	resultsComment += "<br/><br/>";


        resultsComment += "The current in-house record for this game here at " +
                "OkCupid is <b>23</b> points (25 right and 1 wrong). ";

        if (points <= 7 )
	   resultsComment += "You didn't do that well by comparison, but then again, we've played it a million times. ";
        else if (points > 7 && points <= 14)
	   resultsComment += "You didn't do so badly by comparison, considering we've tried it a million times. ";
        else if (points > 14 && points < 23)
           resultsComment += "You actually came pretty close&#8212;well done.";
        else if (points == 23)
           resultsComment += "You did amazingly well to equal it.";
        else if (points > 23)
           resultsComment += "You must be a genius or something. Great job.";




        score = 10 * points / 18;


    }


    // ------------------------------	 
    else if (name == "steps-forward") {

	resultsGenre = "math";
        var time;

        if (!STEPS_FORWARD_SOLVED) {
	     resultsHeadline = "?";
	     resultsText1 = "";
	     resultsText2 = "you didn't get the center piece to 0";

           resultsComment = "You didn't solve this puzzle, but we won't deduct too many points. It was kind of a weird question, " + 
				"and it can be tedious if you don't get the hints. ";
           resultsComment += "Choose something that suits your strengths next. ";
	   score = 0;
        }
        else {

          time = TimeLapsed;

	    resultsHeadline = time;
	    resultsText1 = "you solved the square in";
	    resultsText2 = "seconds";

          if (time < 100) {
             resultsComment  = "That was very fast. The average time for " +
                     "someone with your current overall score profile is <b>102</b> seconds.";
          }
          else if (time < 200 && time >= 100) {
             var adjusted_time = time + 18;
             resultsComment  = "That was quite good. The average for " +
             "someone with your current overall score profile is <b>" + adjusted_time +
             " </b> seconds.";
          }
          else {
             resultsComment = "Good job. It's not as easy as it seems, huh?  In fact, <b>68</b>% " +
                     "of takers with your current overall score profile run out of time.";
          }


          score = Math.floor( (329 - time) / 30 );

        }

	resultsComment += "<br/><br/>";
	resultsComment += "The trick to this puzzle is to discover that if the center value is divisible by <b>3</b>, "; 
	resultsComment += "clicking on the '3' square divides it; otherwise it <i>multiplies</i> it. ";
	resultsComment += "By using the '1' square to make the center divisible by 3, then clicking the '3', ";
	resultsComment += "and repeating as necessary, you can reduce the center very quickly. ";

    }

    // ------------------------------
    else if (name == "hi-fives") {


	resultsText1 = "you got";
	resultsText2 = "of the pairs right";
	resultsGenre = "social";



        if($("testform").hi_fives_1[0].checked) num_correct ++;
        if($("testform").hi_fives_2[1].checked) num_correct ++;
        if($("testform").hi_fives_3[1].checked) num_correct ++;
        if($("testform").hi_fives_4[0].checked) num_correct ++;
        if($("testform").hi_fives_5[0].checked) num_correct ++;
        if($("testform").hi_fives_6[1].checked) num_correct ++;
        if($("testform").hi_fives_7[0].checked) num_correct ++;
        if($("testform").hi_fives_8[1].checked) num_correct ++;



	resultsHeadline = num_correct;
	if (num_correct == 8) resultsHeadline = "all 8";

	document.getElementById('results-hi-fives-table').style.display = "";

        score = 10 * num_correct/8;

    }

    // ------------------------------	 
    else if (name == "smiles") {



	resultsText1 = "you got";
	resultsText2 = "of the smiles right";
	resultsGenre = "social";



        if($("testform").smiles_1[1].checked) num_correct ++;
        if($("testform").smiles_2[1].checked) num_correct ++;
        if($("testform").smiles_3[1].checked) num_correct ++;
        if($("testform").smiles_4[0].checked) num_correct ++;
        if($("testform").smiles_5[0].checked) num_correct ++;
        if($("testform").smiles_6[1].checked) num_correct ++;
                                                


	resultsHeadline = num_correct;
	if (num_correct == 6) resultsHeadline = "all 6";

	document.getElementById('results-smiles-table').style.display = "";




        score = 10* num_correct/6;

    }

    // ------------------------------	 

    else if (name == "root-beer") {

		

	resultsGenre = "social";		 

	resultsText1 = "you got the order";


        var damage = 0;

        for ( var i = 0; i < ROOT_BEER_ORDER.length; i ++) {
			
            damage += (i - ROOT_BEER_ORDER[i]) * (i - ROOT_BEER_ORDER[i]);

        }

        if (damage ==0) {
		resultsHeadline = "totally";
		resultsText2 = "right";	
		resultsComment = "Congratulations! You got the list exactly right. That's all the more impressive considering that ";
		resultsComment += "these people are all strangers to you. Only about <b>5</b>% of our test takers score nail this question like that. ";
        }
        else if (damage > 0 && damage <= 2) {
		resultsHeadline = "almost";
		resultsText2 = "right";	
		resultsComment = "Well done. We don't want to say the exact correct order because people's feelings are involved, " ;
		resultsComment += "but you got just a couple of the bullshitters flipped. You did exceptionally well considering that ";
		resultsComment += "they were all strangers to you. ";

        }

        else if (damage > 2 && damage <= 6) {

		resultsHeadline = "nearly";
		resultsText2 = "right";	
		resultsComment = "Good job. We don't want to say the exact correct order because people's feelings are involved, " ;
		resultsComment += "but you got just a few of the bullshitters mixed up. One was off by two spaces, which kept your score ";
		resultsComment += "from being in the top rank. But you still did very well considering they were all strangers to you. ";

        }
        else if (damage > 6 && damage <= 10) {

		resultsHeadline = "more or less";
		resultsText2 = "right";	
		resultsComment = "We don't want to say the exact correct order because people's feelings are involved, " ;
		resultsComment += "but you got just a few of the bullshitters mixed up. A couple were off by more than a space, which kept your score ";
		resultsComment += "from being in the top rank. But you still did pretty well considering they were all strangers to you. ";


        }
        else if (damage > 10 && damage < 20) {

		resultsHeadline = "somewhat";
		resultsText2 = "right";	
		resultsComment = "We don't want to say the exact correct order because people's feelings are involved, " ;
		resultsComment += "but you got several of the bullshitters mixed up. One was off by three spaces, which kept your score ";
		resultsComment += "from being above average. But you still did pretty well considering you don't know these people. ";

        }
        else if (damage == 20 ) {
		resultsHeadline = "completely";
		resultsText2 = "wrong";	
		resultsComment = "You somehow managed to get the list completely flipped. Maybe you're an interpersonal genius, and just read the instructions wrong? " ;
		resultsComment = "Or maybe you're just a really bad guesser? ";
        }

        score = 10 * (40 - damage) / 40;

    }

    // ------------------------------	 

    else if (name == "warm-up"){
      resultsHeadline = "you've been sorted!";
      resultsText2 = "now choose your next question";	
      resultsText1 ="";
      $('results-text1').style.height = '0px';
      $('whats-next').style.display = "none";

      resultsComment = "<h3 style='text-align:center;'>From now on, you can choose your own adventure.</h3><br/> There are <B>16</b> puzzles to choose from, and ";
      resultsComment += "you'll always be offered the ";
      resultsComment += "most fun one available in a particular genre. You'll end up taking <b>10</b> on this test."; 



      var warm_up_genre ="social";
      var warm_up_bonus = 1;


      // if in order by size
      if (areArraysSame(WARM_UP_ORDER,[1,5,4,3,2]) || areArraysSame(WARM_UP_ORDER,[2, 3, 4, 5, 1])) {
          warm_up_genre = "spatial";

      }
      


      // if in alphabetical order
      if (areArraysSame(WARM_UP_ORDER,[1,2,3,5,4]) || areArraysSame(WARM_UP_ORDER,[4, 5, 3, 2, 1])) {      
          warm_up_genre = "math";

      }
      

      // if in order by definition
      if (areArraysSame(WARM_UP_ORDER,[5,1,4,2,3]) || areArraysSame(WARM_UP_ORDER,[3, 2, 4, 1, 5])) {            
          warm_up_genre = "verbal";

      }
      

      
      

      addToScore(warm_up_genre, warm_up_bonus);
    }


    else alert("bad question name. please email christian@okcupid.com");


    score = normalizeScore(score);

	if(resultsGenre != "")
	{
		addToNumberAnswered(resultsGenre);
		addToScore(resultsGenre, score);
		document.getElementById('results-points-added').style.className = resultsGenre;
		document.getElementById('results-class').innerHTML = resultsGenre;
	}

    if (score == 0) resultsEarned = "Lost.";

    document.getElementById('results-headline').innerHTML = resultsHeadline;
    document.getElementById('results-text1').innerHTML = resultsText1;
    document.getElementById('results-text2').innerHTML = resultsText2;
    document.getElementById('results-comment').innerHTML = resultsComment;	 
    document.getElementById('results-earned').innerHTML = resultsEarned;

	//
	// Tf the taker is on the warm-up we don't want to comment on points lost or earned yet.
	// 
	if (name == "warm-up") {
		$('results-points-added').style.display = "none";
	}
	else {
		$('results-points-added').style.display = "";		
	}

}









 // -----------------------------------------------------------



function showNextQuestionMenu(name) {

    // Step 1 : figure out 2 genres
    var total_answered =
        getNumberAnswered("spatial")
        + getNumberAnswered("math")
        + getNumberAnswered("verbal")
        + getNumberAnswered("social");

    var question1_genre;
    var question2_genre;


    var spatial_questions = new Array('shapes-grid', 'color-madness',  'complements');
    var social_questions = new   Array('hi-fives','smiles','root-beer');
    var math_questions = new  Array('100s','add-it-up','steps-forward');
    var verbal_questions = new  Array('fill-in-the-blank','three-letter-words','mega-grid');

    if (total_answered < 6) {
        switch (total_answered) {
        case 0:
            question1_genre = "math";
            question2_genre = "verbal";
            break;
        case 1:
            question1_genre = "social";
            question2_genre = "spatial";
            break;
        case 2:
            question1_genre = "math";
            question2_genre = "spatial";
            break;
        case 3:
            question1_genre = "social";
            question2_genre = "verbal";
            break;
        case 4:
            question1_genre = "verbal";
            question2_genre = "spatial";
            break;
        case 5:
            question1_genre = "math";
            question2_genre = "social";
            break;
        }
    } else if (total_answered == 6) {
        // if someone has not answered a particular type of question  by now, we make them take it.

        var least_popular_genre = getGenreByPopularity("last");

        if (getNumberAnswered(least_popular_genre) == 0) {

            question1_genre = least_popular_genre;
            question2_genre = false;
        }
        else{

            question1_genre = getGenreByPopularity(0); // selects mos tpopular type of q available
            question2_genre = getGenreByPopularity(1); // selects second-most popular type of q available

        }

    }
    else if (total_answered > 6 && total_answered < 10){

        question1_genre = getGenreByPopularity(0); 
        question2_genre = getGenreByPopularity(1); 

    }
    else if (total_answered >= 10) {

	 	//needs to submit test and show results-page here
	 	//alert('Test should submit and show results page now');
	
		
		
        Effect.Appear("final-tally-action", {delay: 2, queue: 'end'});
	
        return;

    }

    // STEP 2

    var question1_name;
    var question2_name;

    switch (question1_genre) {

    case "spatial":
        question1_name =
        spatial_questions[getNumberAnswered("spatial")];
        break;


    case "verbal":
        question1_name =
        verbal_questions[getNumberAnswered("verbal")];
        break;

    case "math":
        question1_name = math_questions[getNumberAnswered("math")];
        break;

    case "social":
        question1_name =
        social_questions[getNumberAnswered("social")];
        break;
    }


    switch (question2_genre) {

    case "spatial":
        question2_name =
        spatial_questions[getNumberAnswered("spatial")];
        break;

    case "verbal":
        question2_name =
        verbal_questions[getNumberAnswered("verbal")];
        break;

    case "math":
        question2_name = math_questions[getNumberAnswered("math")];
        break;

    case "social":
        question2_name =
        social_questions[getNumberAnswered("social")];
        break;

	case false:
        question2_name = false;
        break;


    }
    
    
    //STEP 3

    // we should've just created each question as an object instead of  all these arrays, maybe go back and do it

    var menu_names = new Array();
    var menu_descriptions = new Array();

    menu_names["color-madness"] =  "Color Madness";
    menu_descriptions["color-madness"] = "Find the steady squares in an ever-changing array.";

    menu_names["100s"] =  "Make the 100s";
    menu_descriptions["100s"] = "Pick numbers from a grid in groups that add to 100.";

    menu_names["three-letter-words"] =  "3 Letter Sprint";
    menu_descriptions["three-letter-words"] = "Type as many three-letter words as you can.";


    menu_names["fill-in-the-blank"] =  "F__ in the Blank";
    menu_descriptions["fill-in-the-blank"] = "Complete words as they appear; make rarer ones as you do.";


    menu_names["word-grid"] =  "Simple Word Shuffle";
    menu_descriptions["word-grid"] = "Drag letters into a grid to form simple words.";


    menu_names["add-it-up"] =  "Add It Up";
    menu_descriptions["add-it-up"] = "Do the simple arithmetic with speed and accuracy.";


    menu_names["tetris"] =  "A Moscow Puzzle";
    menu_descriptions["tetris"] = "Select the pieces to complete <b>Tetris</b>-style game board.";


    menu_names["mega-grid"] =  "Ultimate Word Grid";
    menu_descriptions["mega-grid"] = "Look for words on the best <b>Boggle</b>-style grid in existence.";


    menu_names["steps-forward"] =  "2 Steps Forward...";
    menu_descriptions["steps-forward"] = "Uncover the hidden ways of an arithmetical square. [difficult]";


    menu_names["shapes-grid"] =  "Shapes in Your Face";
    menu_descriptions["shapes-grid"] = "Remember patterns as  they flash before your eyes and face.";

    menu_names["complements"] =  "With Our Complements";
    menu_descriptions["complements"] = "Identify complementary  abstract images.";


    menu_names["hi-fives"] =  "Hi-Fives";
    menu_descriptions["hi-fives"] = "Identify who's friends in a video of people hi-fiving.";

    menu_names["smiles"] =  "Crocodile Smiles";
    menu_descriptions["smiles"] = "Pick the fake smiles from a video lineup.";


    menu_names["root-beer"] =  "Root Beer Industry";
    menu_descriptions["root-beer"] = "Judge confidence levels as people discuss a tasty beverage. [sound required!]";


    // this is where the next question menu is actually filled


    NEXT_QUESTION_OPTION_1 = question1_name;
    NEXT_QUESTION_OPTION_2 = question2_name;
    

    //capitalize() is a prototype method; if it doesn't work, delete it.
    
    document.getElementById('menu-title1').innerHTML = question1_genre.capitalize() + ": " + menu_names[question1_name];
    document.getElementById('menu-description1').innerHTML =  menu_descriptions[question1_name];
    document.getElementById('menu-bar1').className = question1_genre +"-bar" ;

    if(question2_genre) {


            document.getElementById('menu-title2').innerHTML = question2_genre.capitalize() + ": " + menu_names[question2_name];
	    document.getElementById('menu-description2').innerHTML =   menu_descriptions[question2_name];
	    document.getElementById('menu-bar2').className = question2_genre + "-bar" ;
    }
    else {
	$('whats-next').innerHTML = "Hey! You haven't taken a " +  question1_genre + " question yet.<br/>Just try this one...";		
	document.getElementById('menu-bar2').style.display = "none";
    }

    Effect.Appear("next-question-menu",{duration:1, delay: 2, queue: "end"});


}

// -----------------------------------------------------------

function askOption(num) {
    if (num == 1) {
        setNextQuestionAndSubmit(NEXT_QUESTION_OPTION_1);
    }
    else {
        setNextQuestionAndSubmit(NEXT_QUESTION_OPTION_2);
    }
}

// -----------------------------------------------------------

function normalizeScore(score) {

   score = Math.round(score);
   if (score < 0) score = 0;
   if (score > 10) score = 10;
   
   return score;	
}

 // -----------------------------------------------------------

function compareNumAnswered(a, b) {

    // compare values flipped because we want the array in greatest to least

    if (a.num < b.num) {
        return 1;
    }
    else if (a.num > b.num) {
        return -1;
    }
    else {
        return 0;
    }
}

 // -----------------------------------------------------------

function getGenreByPopularity(rank) {

    
    var number_answered = new Array();
    
    var spatial =  getNumberAnswered("spatial");
    var math =  getNumberAnswered("math");
    var verbal =  getNumberAnswered("verbal");
    var social = getNumberAnswered("social");
    
    // build array of possibilities

    number_answered[0] = {genre : "spatial", num : spatial, possible: 3 };
    number_answered[1] = {genre : "math", num : math, possible: 3}; 
    number_answered[2] = {genre : "verbal", num : verbal, possible: 3}; 
    number_answered[3] = {genre : "social", num : social, possible: 3}; 
 

    // order by num

    number_answered.sort(compareNumAnswered);

    // return eligible genre in appropriate rank

    var counter = 0;


    if (rank == "last")
        return number_answered[3].genre;
    
    else {
        for (var i = 0; i < number_answered.length; i++) {
            

            
            if (number_answered[i].num < number_answered[i].possible) {
            


                if (counter == rank) {

                    return number_answered[i].genre;
                
                } else counter++;
            }
            
        
    
        }
    }
    alert("Out of questions! Something is f'd.");

}


 // -----------------------------------------------------------

function setNextQuestionAndSubmit(name) {

	cleanupHighlights();

    $("next_question").value = name;
    //alert($("next_question").value);
    $('testform').submit();
}

// -----------------------------------------------------------


function addToNumberAnswered(type) {
     setNumberAnswered(type, getNumberAnswered(type) + 1);
 }


 // -----------------------------------------------------------

 function setNumberAnswered(type, value) {
    $(type+ "_number_answered").value = value; 
 }

 // -----------------------------------------------------------

 function getNumberAnswered(type) {
    var res = parseInt($(type + "_number_answered").value);

   if (isNaN(res)) {
      return 0;
    }
    return res;
 }

 // -----------------------------------------------------------

 function setScore(type, value) {
    $(type+ "_score").value = value; 
 }

 // -----------------------------------------------------------

 function addToScore(type, value) {
    setScore(type, getScore(type) + value);
 }

 // -----------------------------------------------------------

 function getScore(type) {
    var res = parseInt($(type+ "_score").value);
    if (isNaN(res)) {
      return 0;
    }
    return res;
 }

 function showResults(name) {

     Effect.Fade("question-content-" + name, {duration:1, delay: .5, afterFinish: function(){scroll(0,100)}});
     Effect.Appear("question-results", {duration:1, delay:1, queue: "end"});


  
 }

 // -----------------------------------------------------------
 function endQuestionEarly(name) {

     END_EARLY = true;


 }

 // -----------------------------------------------------------


 function stopGame(name) {
     switch(name) {

     case "color-madness":
         stopColors();

         break;

     case "word-grid":
         stopWordGrid();
         break;

           
     }
     

 }



 // -----------------------------------------------------------

 //
 // menu hover functions
 //

/*
-------------------> These were causing annoying errors in firefox, cleanup stops it
*/
function cleanupHighlights() {
	$("menu-bar1").onmouseover = "";
	$("menu-bar2").onmouseover = "";
	$("menu-bar1").onmousout = "";
	$("menu-bar2").onmousout = "";
}

function highlightDescription(index) {
	 var id = "menu-description" + index;
	 document.getElementById(id).style.opacity  = 1;
	 id="menu-title" + index;
	 document.getElementById(id).style.textDecoration = "underline";
	 
}
function fadeDescription(index) {
	 var id = "menu-description" + index;
	 document.getElementById(id).style.opacity  = .5;
	 id="menu-title" + index;
	 document.getElementById(id).style.textDecoration  = "none";
	 
}




 //
 // timer functions
 //


 var TIMES_UP = false;
 var GAME_STARTED = false;
 var TimeStart;
 var TimeDuration;
 var TimeLapsed;
 var END_EARLY = false;


 function startTimer(duration, name) {
     TimeLapsed = 0;
     GAME_STARTED = true;
     TimeDuration = duration;
     TimeStart = new Date();
     loopTimer(name);

 }


 function loopTimer(name) {

    displayTimeLeft(name);

    if (TimeLapsed >= TimeDuration || END_EARLY) {
        TIMES_UP = true;
        finishQuestion(name);

    }

     
    else {
        var action = "loopTimer('" + name + "')";
        setTimeout(action,300);
    }
 }



 function displayTimeLeft(name) {

    var d = new Date();
    var timeRemaining;
    
    var timerDisplay = $("clock-" + name);

    TimeLapsed = d.getTime() - TimeStart.getTime();

    TimeLapsed = TimeLapsed / 1000;

    TimeLapsed = Math.floor(TimeLapsed);

    timeRemaining = TimeDuration - TimeLapsed;

    timerDisplay.innerHTML =  timeRemaining;

 }

 //
 // general functions
 //

var LOCK_QUESTION = false; // this var keeps user from clicking during effects

function unlockQuestion() {
    LOCK_QUESTION = false;

}

function lockQuestion() {
    LOCK_QUESTION = true;
}

function preLoadImage(img) {
    var preload = new Image();
    var path = "http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/";
    preload.src = path + img; 
    


}

preLoadImage('verbal_question.gif');
preLoadImage('math_question.gif');


//preLoadImage('spatial_question.gif');
//preLoadImage('social_question.gif');





 function safeParse(x) {
    if(isNaN(parseInt(x))) {
        return 0;
    }
    else return parseInt(x);

 }


 function setFocus(id) {
    document.getElementById(id).focus();
 }

 //
 // color-madness functions
 //



 var T_COLOR_MADNESS; // this is for the setTimeout function 

 function parseColor(elem) {

    var color = elem.style.backgroundColor;
    var red;
    var blue;
    var green;
    var temp = new Array();

//  $('madness-debug').innerHTML += color + " / ";

    if(color.indexOf("#") != -1) {

        red = color.substring (1,3);
        green = color.substring (3,5);        
        blue = color.substring (5,7);
        
        temp[0] = parseInt( red, 16);
        temp[1] = parseInt( green, 16);
        temp[2] = parseInt( blue, 16);

    }
    else {    


        
        var i = color.indexOf('(');
        var j = color.indexOf(')');
        
        color = color.substring( i + 1 , j);
        
        temp = color.split(',');
        
        
        // make sure temp is integers
        for ( i = 0 ; i < temp.length; i++ ) {
            
            temp[i] = safeParse(temp[i]);
            //alert(temp[i]);
        }
    }
    
    return temp;
 }


 function mutateColor(color) {

    var i;
    var rand;


    for ( i = 0 ; i < color.length; i++){

        rand = Math.floor ( (Math.random() *  101) - 20 );
        color[i] += rand;
        if (color[i] < 0) color[i] = 1;
        if (color[i] > 255) color[i] = color[i] % 255;

    }
    if (color[0] < 128) color[0] = 128;

    return color;

 }



 function swapClasses(all) {

    var rand = new Array();

    // this determines which blocks wont blink

    
    var divs = new Array();
    var statics = new Array();
    for (var i = 0; i < all.length; i++) {
        if (all[i].className == "change" || all[i].className == "static" ) divs[divs.length] = all[i];
    }

    
    rand[0] = Math.floor ( Math.random() * divs.length);
    rand[1] = Math.floor ( Math.random() * divs.length);
    rand[2] = Math.floor ( Math.random() * divs.length);

    // need to check that these new randoms are all different that the old ones.

    var ok = new Array();
    ok[0] = false;
    ok[1] = false;
    ok[2] = false;

    while (!ok[0] || !ok[1] || !ok[2]){
        for ( i = 0 ; i < ok.length; i ++) {
            if (divs[rand[i]].className == "static") {
                rand[i] = Math.floor ( Math.random() * divs.length);
            } else ok[i] = true;
        }
    }

    for ( i=0; i < divs.length; i++) {


        if (i == rand[0] || i == rand[1] || i == rand[2]) {

            divs[i].className = "static";
            //alert(divs[i].id);
        }
        else divs[i].className = "change";


    }



 }


 function startColors(){

    var all = $('color-blocks-wrapper').select('.color-madness-row div');
    
    swapClasses(all);
    //setStatics(all);
    changeColors();

 }

 function setStatics(all){

    var static = new Array();

    for (var i = 0; i < all.length; i++) {
        if (all[i].className == "static") static[static.length] = all[i];
    }

    for ( i=0; i < static.length; i++) {

        var color = new Array;
        if(!static[i].style.backgroundColor) static[i].style.backgroundColor = "rgb(255,0,0)";

        color = parseColor(static[i]);
        color = mutateColor(color);
    }

 }

 function printColorMadnessBlocks(rows, cols) {

    //alert("printing");
    var str = "";
    var i  = 0;
    var j = 0;
    var id = 0;

    var objClass = "";
    var rand = new Array();


    // this determines which blocks wont blink
    rand[0] = Math.floor ( Math.random() * cols * rows);
    rand[1] = Math.floor ( Math.random() * cols * rows);
    rand[2] = Math.floor ( Math.random() * cols * rows);


    for (i = 0; i < cols; i++) {
        str += '<div  style="float:left;" class="color-madness-row">';
        for ( j = 0; j < rows; j++) {

            if( id == rand[0] || id == rand[1] || id == rand[2]) objClass = "static";
            else objClass = "change";

            str += '<div name=\'color-block\' ';
            str += 'id = \'block' + id + '\' ';
            str += 'class = \'' + objClass + '\' ';
            str += 'onclick=\'scoreColorMadness(this)\'>';
            str += '</div>';
            id++;
        }
        str+= '</div>';
    }
    
    document.write(str);

 }



 function changeColors() {

    var timeBetween = 500;
    
    var change = new Array();
    var all = $('color-blocks-wrapper').select('.color-madness-row div');

    for (var i = 0; i < all.length; i++) {
        if (all[i].className == "change") {
            change[change.length] = all[i];

        }
    }


    
    for ( i=0; i < change.length; i++) {

        var color = new Array (255,0,0);

        if(change[i].style.backgroundColor){
            color = parseColor(change[i]);
        } else {

        }

        color = mutateColor(color);

        change[i].style.backgroundColor = "rgb("+color[0]+","+color[1]+","+color[2]+")";

    }


    T_COLOR_MADNESS = setTimeout('changeColors()', timeBetween);

 }


 function stopColors() {

    clearTimeout(T_COLOR_MADNESS);

 }

 function scoreColorMadness(obj){

    if (TIMES_UP) return;
    if (!GAME_STARTED) return;

    if(obj.className == "static") {
        var total = safeParse($('result1-color-madness').innerHTML);
        total ++;
        //$('debug1-color-madness').innerHTML = total;
        $('result1-color-madness').innerHTML = total;
    }
    if(obj.className == "change") {
        var total = safeParse($('result2-color-madness').innerHTML);
        total ++;
        //$('debug2-color-madness').innerHTML = total;
        $('result2-color-madness').innerHTML = total;
    }


    stopColors();
    startColors();

 }

 function startColorMadness(seconds){
    
    startTimer(seconds, 'color-madness');
    startColors();
 }


//
// 100s functions
//


function start100s(seconds){

    GAME_STARTED = true;
    print100sGrid(8,8, true);
    startTimer(seconds, '100s');
}



function rand100s(m,n)
{
    return ( Math.floor ( Math.random ( ) * (n-m) + m ));
}




function clearTallies() {

    var tally=$("tally");
    var clearTally=$("clearTally");

    tally.innerHTML = "0";
    clearTally.style.display = "none";
}



function selectNumber(number) {

    if (TIMES_UP) return;
    if (!GAME_STARTED) return;


    var clickedCell=$(number);
    var score=$("score-100s");
    var tally=$("tally");
    var clearTally=$("clearTally");


    var clickedValue = safeParse(clickedCell.innerHTML);
    var tallyValue = safeParse(tally.innerHTML);
    var scoreValue = safeParse(score.innerHTML);
    var extra = " points!";

    
    clickedCell.innerHTML ="&nbsp;";
    clickedCell.style.backgroundColor = "#ffffff";

    tallyValue += clickedValue;

    clearTally.style.display = "";

    tally.innerHTML = tallyValue;

    if (tallyValue == 100) {

        scoreValue ++;
        score.innerHTML = scoreValue;
        Effect.Shake('score-100s');
        clearTallies();



    } else if ( tallyValue > 100) {

        Effect.Shake('tally', {duration : .5});
        Effect.Fade('tally', {duration: .3, delay: .3,  queue: 'end', afterFinish: clearTallies})
        Effect.Appear('you-went-over', {duration: .3, queue: 'end'});
        Effect.Fade('you-went-over', {duration: .3, delay: .4, queue: 'end'});
        Effect.Appear('tally', {duration: .3, queue: 'end'});



    }


}


function print100sGrid(rows, cols, numbers)
{

    //alert('print');
    var grid_container = $("grid-container");


    var m = 5;
    var n = 40;


    var table;


    table = "<table class='grid-100s' id='grid-100s'>";


    for (var i = 0; i < rows; i++) {

        table += "<tr>";


        for (var j = 0; j < rows; j++){
            if (numbers) number = rand100s (m,n);
            else number = "<span style='color:#ffddcc;'>88</span>";

            cellId = "cell-" + String(i+1)+String(j+1);
            table += "<td id=" + cellId + " onClick='selectNumber(\"" + cellId + "\")'>" + number + "</td>";
        }

        table += "</tr>";
    }



    table += "</table>";

    grid_container.innerHTML = table;




}


//
// 3-letter-word functions
//


var WORD_ENTRIES = new Array();
var DEFINITIONS = new Array();

function checkWord() {

    if (TIMES_UP) return;
    if (!GAME_STARTED) return;


    var score = safeParse($("score-three-letter-words").innerHTML);
    var blank = $("blank");
    var answers = $("word-list");

    if(blank.value.length == 3) {

        var definition = validateThreeLetterWords(blank.value.toUpperCase());

        if(definition){

            score ++;
            answers.innerHTML += blank.value + "&nbsp;&#8212;&nbsp; <i>" + definition + "</i><br/>";
            $("score-three-letter-words").innerHTML = score;
            //$("results1-three-letter-words").innerHTML = score;
        }



    }
    blank.value = "";
    setTimeout("setFocus('blank')", 100);    

}

function setFocus(id) {
    $(id).focus();

}

function keypressThreeLetterWords(e) {

    var Ucode=e.keyCode? e.keyCode : e.charCode;

        if (Ucode == 13)

        {
            //  alert('enter');
            checkWord();

        }

		e = (e) ? e : ((window.event) ? window.event : "");
		if (e) {

		// process event here
		// alert( evt.keyCode); // IE and Safari
		// alert( evt.which); // FF

		return !( e.keyCode==13 || e.which==13 );

		}



}


function alreadyEnteredThreeLetterWords(word) {

    for (var i = 0; i < WORD_ENTRIES.length; i++) {

        if( word==WORD_ENTRIES[i] ) {
            return true;
        }
    }

    return false;
}

function validateThreeLetterWords(word){

    //alert(smallWords.length);


    if(!alreadyEnteredThreeLetterWords(word)) {

        for (var i = 0; i < smallWords.length; i++) {

            if( word==smallWords[i] ) {
                WORD_ENTRIES[WORD_ENTRIES.length] = word;
		DEFINITIONS[DEFINITIONS.length] = smallWords_definition[i];
                return smallWords_definition[i];
            }
        }
    }
    return false;

}


function startThreeLetterWords(seconds) {

    GAME_STARTED = true;
    //$('blank').disabled = ""
    startTimer(seconds, 'three-letter-words');
    setTimeout("setFocus('blank')", 100);    


}


//
// fill-in-the-blank functions
//

var COUNTER_FILL_IN_THE_BLANK = 0;
var RARITY_FILL_IN_THE_BLANK = new Array();


function keypressFillInTheBlank(e) {

    var Ucode=e.keyCode? e.keyCode : e.charCode;
	
	if(Ucode == 13) return generalEnterKill(e);
    
	if (LOCK_QUESTION) return generalKeyboardKill(e);
    
    if ((Ucode >= 65 && Ucode <=90)	 || (Ucode-32 >= 65 && Ucode-32 <=90)) {


        scoreFillInTheBlank();

        if (EXPLORER) new Effect.Opacity('entry-fill-in-the-blank',  {from: 1.0, to: 0});

        new Effect.Opacity('question-fill-in-the-blank', {from: 1.0, to: 0, afterFinish: showFillInTheBlank });

    }
}





function scoreFillInTheBlank(){

    lockQuestion();

    var letter_index;

    if ($('entry-fill-in-the-blank').value) { 
        letter_index = solutionsFillInTheBlank[COUNTER_FILL_IN_THE_BLANK].indexOf($('entry-fill-in-the-blank').value);
    }	
    else letter_index = -1;

    
    if (letter_index >= 0 || !TIMES_UP) {
        RARITY_FILL_IN_THE_BLANK[RARITY_FILL_IN_THE_BLANK.length] = letter_index ;
    } 


    COUNTER_FILL_IN_THE_BLANK ++;


}


function showFillInTheBlank(){

    if (COUNTER_FILL_IN_THE_BLANK >= wordsFillInTheBlank.length ) {
        endQuestionEarly('fill-in-the-blank');
        return;
    }

    else if (TIMES_UP) return;
    else if (!GAME_STARTED) return;

    var word = wordsFillInTheBlank[COUNTER_FILL_IN_THE_BLANK];
    var blankIndex = word.indexOf('_');

    $('before').innerHTML = word.substring(0, blankIndex);
    $('after').innerHTML = word.substring(blankIndex+1);
    $('entry-fill-in-the-blank').value = "";
    unlockQuestion();
    
    new Effect.Opacity('question-fill-in-the-blank', { from: 0, to: 1.0, afterFinish: function(){
           setTimeout("setFocus('entry-fill-in-the-blank')", 100);    
           $('entry-fill-in-the-blank').focus();
    }});
    if (EXPLORER) new Effect.Opacity('entry-fill-in-the-blank', {from: 0, to: 1.0});


}

function stopFillInTheBlank() {
    new Effect.Opacity('question-fill-in-the-blank', {from: 1.0, to: 0});
    if (EXPLORER) new Effect.Opacity('entry-fill-in-the-blank',  {from: 1.0, to: 0} );

}

function generalEnterKill(e) {
	e = (e) ? e : ((window.event) ? window.event : "");
	if (e) {
		return !( e.keyCode==13 || e.which==13 );
	}
}

function generalKeyboardKill(e) {

    e = (e) ? e : ((window.event) ? window.event : "");
    if (e) {
        return false;
            
    }
    

}

function startFillInTheBlank(seconds){
    GAME_STARTED = true;
    showFillInTheBlank();
    startTimer(seconds, 'fill-in-the-blank');

}



//
// word-grid-functions
//




var WORD_GRID_LETTERS = new Array();

WORD_GRID_LETTERS[0] = "p";
WORD_GRID_LETTERS[1] = "";
WORD_GRID_LETTERS[2] = "";

WORD_GRID_LETTERS[3] = "";
WORD_GRID_LETTERS[4] = "a";
WORD_GRID_LETTERS[5] = "";

WORD_GRID_LETTERS[6] = "";
WORD_GRID_LETTERS[7] = "";
WORD_GRID_LETTERS[8] = "y";


function fillResultsWordGrid(c1, c2, c3, c5, c6, c7) {

	 $('results-word-grid-c1').innerHTML = c1;
	 $('results-word-grid-c2').innerHTML = c2;
	 $('results-word-grid-c3').innerHTML = c3;
	 $('results-word-grid-c5').innerHTML = c5;
	 $('results-word-grid-c6').innerHTML = c6;
	 $('results-word-grid-c7').innerHTML = c7;
	 

}


function startWordGrid(seconds) {

	 $('finish-word-grid').disabled = "";

	 new Draggable('d',{revert:false});
	 new Draggable('o',{revert:false});
	 new Draggable('r1',{revert:false});
	 new Draggable('r2',{revert:false});
	 new Draggable('e',{revert:false});
	 new Draggable('t',{revert:false});




	 var cell_num;
	 var letter;	

	 Droppables.add('cell1-word-grid', {
		accept: 'letter-word-grid',
		onHover: function(element) {
	 
	 },
	 onDrop: function(element) 
	 { 
	   cell_num = 1;
	   letter = element.id.charAt(0);

	   WORD_GRID_LETTERS[cell_num] = letter;


  
	 } });


	 Droppables.add('cell2-word-grid', {
	       accept: 'letter-word-grid',
	       onHover: function(element) {
	 
	 },
	 onDrop: function(element) 
	 { 
	       cell_num = 2;
	       letter = element.id.charAt(0);

	       WORD_GRID_LETTERS[cell_num] = letter;

	 } });

	 Droppables.add('cell3-word-grid', {
	       accept: 'letter-word-grid',
	       onHover: function(element) {
	 
	 },
	 onDrop: function(element) 
	 { 
	       cell_num = 3;
	       letter = element.id.charAt(0);
	       WORD_GRID_LETTERS[cell_num] = letter;
	 } });

	 Droppables.add('cell5-word-grid', {
	       accept: 'letter-word-grid',
	       onHover: function(element) {
	 
	 },
	 onDrop: function(element) 
	 { 
	       cell_num = 5;
	       letter = element.id.charAt(0);
	       WORD_GRID_LETTERS[cell_num] = letter;
	 } });


	 Droppables.add('cell6-word-grid', {
	       accept: 'letter-word-grid',
	       onHover: function(element) {
	 },
	 onDrop: function(element) 
	 { 
	       cell_num = 6;
	       letter = element.id.charAt(0);
	       WORD_GRID_LETTERS[cell_num] = letter;
	 } });

	 Droppables.add('cell7-word-grid', {
	       accept: 'letter-word-grid',
	       onHover: function(element) {
	 
	 },
	 onDrop: function(element) 
	 { 
	       cell_num = 7;
	       letter = element.id.charAt(0);
	       WORD_GRID_LETTERS[cell_num] = letter;

         } });

	 startTimer(seconds, 'word-grid');
	 //$('finished-word-grid').style.display = "";


}


function getRarityWordGrid(word) {



	 var word_grid_words = new Array();
	 word_grid_words[0]="dry";
	 word_grid_words[1]="try";
	 word_grid_words[2]="ped";
	 word_grid_words[3]="oar";
	 word_grid_words[4]="ear";
	 word_grid_words[5]="pod";
	 word_grid_words[6]="pet";
	 word_grid_words[7]="per";
	 word_grid_words[8]="rat";
	 word_grid_words[9]="rad";
	 word_grid_words[10]="pot";
	 word_grid_words[11]="toy";
	 word_grid_words[12]="dey";
	 word_grid_words[13]="tad";
	 word_grid_words[14]="eat";
         word_grid_words[15]="tao";
         word_grid_words[16]="tar";
         word_grid_words[17]="oat";
         word_grid_words[18]="pod";
         word_grid_words[19]="pro";


	 var word_grid_rarities = new Array();
	 word_grid_rarities[0]="common";
	 word_grid_rarities[1]="common";
	 word_grid_rarities[2]="uncommon";
	 word_grid_rarities[3]="common";
	 word_grid_rarities[4]="common";
	 word_grid_rarities[5]="common";
	 word_grid_rarities[6]="common";
	 word_grid_rarities[7]="uncommon";
	 word_grid_rarities[8]="common";
	 word_grid_rarities[9]="common";
	 word_grid_rarities[10]="common";
	 word_grid_rarities[11]="common";
	 word_grid_rarities[12]="uncommon";
	 word_grid_rarities[13]="common";
	 word_grid_rarities[14]="common";
	 word_grid_rarities[15]="uncommon";
	 word_grid_rarities[16]="common";
	 word_grid_rarities[17]="common";
	 word_grid_rarities[18]="common";
	 word_grid_rarities[19]="common";


	
	 for (var i = 0; i < word_grid_words.length; i++) {

		if (word == word_grid_words[i])  {

		   return word_grid_rarities[i];
		}

	}
	return false;
}

function stopWordGrid() {


}

function scoreWordGrid() {


}





//
// add-it-up functions
//




var streakAddItUp = 0;
var netAddItUp = 0;
var totalAddItUp = 0;
var isBig = false;
var answerAddItUp;
var highest_number = 12;
var lowest_number = 0;

function startAddItUp(seconds) {
    $('answer-add-it-up').disabled = "";
    $('answer-add-it-up').value= "";
    $('answer-add-it-up').style.visibility = "visible";

    GAME_STARTED = true;
    startTimer(seconds, 'add-it-up');
    askQuestionAddItUp();


}

function askQuestionAddItUp(){


    var num_1;
    var num_2;
    var operator;
    var i;
    var question_text;
    var possibilities = 2;
    var range = highest_number - lowest_number + 1;

    var operators = new Array;
    operators[0] = "&#43;";
    operators[1] = "&#8722;";
    operators[2] = "&#215;";
    operators[3] = "/";



    if (highest_number > 15) possibilities = 4;

    i = Math.floor(Math.random() * possibilities);


    if ( i == 3) {
        // 50% chance of throwing it back if division is selected
        if (Math.random() > .5 ) i = Math.floor(Math.random() * possibilities);
    }

    operator = operators[i];


    num_1 = 0;
    num_2 = 0;


    while( num_1 <= num_2) {

        num_1 = Math.floor(Math.random() * range + lowest_number);
        num_2 = Math.floor(Math.random() * range + lowest_number);


    }

    if (i == 0 && isBig) {

        num_1 = Math.floor(Math.random() * 2 * range + 10);
        num_2 = Math.floor(Math.random() * 1 * range + 10);


    }


    if (i == 1 && isBig) {

        num_1 = Math.floor(Math.random() * 2 * range + 10);
        num_2 = Math.floor(Math.random() * 1 * range + 10);


    }



    if (i == 2 && isBig) {


        num_1 = Math.floor(Math.random()* range + 10);
        num_2 = Math.floor(Math.random() * 8 + 2);

    } else if (i==2 && !isBig){

        num_1 = Math.floor(Math.random() * 14);
        num_2 = Math.floor(Math.random() * 14);


    }





    while( i == 3 && (num_1 % num_2 || num_1 / num_2 > 20 || num_1 * num_2 == 0 || num_1 / num_2 == 1) ) {

        num_1 = Math.floor(Math.random() * 4 * highest_number);
        num_2 = Math.floor(Math.random() * highest_number);


    }



    question_text = num_1 + " " + operator + " " + num_2;

    switch (i) {
    case 0:
        answerAddItUp = num_1 + num_2;
        break;
    case 1:
        answerAddItUp = num_1 - num_2;
        break;

    case 2:
        answerAddItUp = num_1 * num_2;
        break;
    case 3:
        answerAddItUp = num_1 / num_2;
        break;

    }
    if (!TIMES_UP) $('question-add-it-up').innerHTML = question_text;


    setTimeout("setFocus('answer-add-it-up')", 100);
}

function keypressAddItUp(e) {

    var Ucode=e.keyCode? e.keyCode : e.charCode;
	if (Ucode == 13)

    {
        //alert('enter');
        checkAnswerAddItUp();

    }
	e = (e) ? e : ((window.event) ? window.event : "");
	if (e) {
	
	// process event here
	// alert( evt.keyCode); // IE and Safari
	// alert( evt.which); // FF
	
	return !( e.keyCode==13 || e.which==13 );
	
	}
}




function checkAnswerAddItUp(){

    if(!TIMES_UP && GAME_STARTED) {

        var count;

        totalAddItUp ++;

        if (answerAddItUp == $('answer-add-it-up').value) {
            netAddItUp ++;
            streakAddItUp ++;

            count = safeParse($('debug1-add-it-up').innerHTML);
            count++;
            $('debug1-add-it-up').innerHTML = count;

            highest_number += 1;
            if (streakAddItUp > 2 && netAddItUp > 10) {

                if( netAddItUp/totalAddItUp > .3) {
                    //if (!isBig) alert('going big');
                    isBig = true;
                }
                else isBig = false;

            }
            else {
                isBig = false;

            }



        } else {
            netAddItUp --;
            highest_number -= 3;
            streakAddItUp = 0;
            isBig = false;


            if (highest_number <= 10) highest_number = 10;


            count = safeParse($('debug2-add-it-up').innerHTML);
            count++;
            $('debug2-add-it-up').innerHTML = count;

        }

        $('answer-add-it-up').value = "";


        askQuestionAddItUp();

    }
}



//
// tetris functions
//



var TETRIS_SOLVED = false;
var NUM_PLACED_TETRIS = 0;
var PATH_A = true;
var B_ALT = false;

function clearGridTetris() {
    $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetris.gif';

    var piece_id;

    for (var i = 1; i < 8; i++) {
        piece_id = "piece-tetris_" + i;
        $(piece_id).style.visibility = "visible";
    }
        $('piece-tetris_2a').style.visibility = "visible";
        $('piece-tetris_6a').style.visibility = "visible";
        NUM_PLACED_TETRIS = 0;
        PATH_A = true;
        B_ALT = false;
        $('placed-tetris').innerHTML = NUM_PLACED_TETRIS;

}

function startTetris(seconds) {


    new Draggable('piece-tetris_1',{revert:true});
    new Draggable('piece-tetris_2',{revert:true});
    new Draggable('piece-tetris_3',{revert:true});
    new Draggable('piece-tetris_4',{revert:true});
    new Draggable('piece-tetris_5',{revert:true});
    new Draggable('piece-tetris_6',{revert:true});
    new Draggable('piece-tetris_7',{revert:true});
//    new Draggable('piece-tetris_1a',{revert:true});
    new Draggable('piece-tetris_2a',{revert:true});
    new Draggable('piece-tetris_6a',{revert:true});


    Droppables.add('board-tetris', {
        accept: 'piece-tetris',
                onHover: function(element) {

            },
                onDrop: function(element)
            {



                if (NUM_PLACED_TETRIS == 0) {
                    if(element.id == 'piece-tetris_3') {
                        //path a
                        NUM_PLACED_TETRIS++;
                        PATH_A = true;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisa1.gif';

                    }
                    if(element.id == 'piece-tetris_6') {
                        //path b
                        NUM_PLACED_TETRIS++;
                        PATH_A = false;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisb1.gif';

                    }
                }

                
                if (NUM_PLACED_TETRIS == 1) {
                    if (PATH_A && element.id == 'piece-tetris_2') {

                        NUM_PLACED_TETRIS++;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisa2.gif';

                    }
                    else if (!PATH_A && element.id == 'piece-tetris_4') {
                        
                        NUM_PLACED_TETRIS++;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisb21.gif';

                    }
                    else if (!PATH_A && element.id == 'piece-tetris_3') {
                        B_ALT = true;
                        
                        NUM_PLACED_TETRIS++;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisb22.gif';
                        //alert(NUM_PLACED_TETRIS);
                    }
                    

                    
                }

                if (NUM_PLACED_TETRIS == 2) {

                    if (PATH_A && element.id == 'piece-tetris_6a') {

                        NUM_PLACED_TETRIS++;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisa3.gif';
			TETRIS_SOLVED = true;

			
			endQuestionEarly('tetris');

                    }
                    else if (!PATH_A && !B_ALT && element.id == 'piece-tetris_3') {

                        NUM_PLACED_TETRIS++;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisb3.gif';
			TETRIS_SOLVED = true;

			endQuestionEarly('tetris');

                    }

                    else if (!PATH_A && B_ALT && element.id == 'piece-tetris_4') {

                        NUM_PLACED_TETRIS++;
                        element.style.visibility = "hidden";
                        $('board-tetris').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/tetris/tetrisb3.gif';
			TETRIS_SOLVED = true;
			endQuestionEarly('tetris');

                    }
                    

                }

            } });

    
    Effect.Appear('board-tetris', {duration: 1});
    Effect.Appear('clear-tetris', {duration: 1});
    Effect.Appear('finish-tetris', {duration : 1});
    setTimeout('fadeBackgroundTetris()', 1000);
    startTimer(seconds, 'tetris');
}

function fadeBackgroundTetris(){
    // this function is just to deal with fading  in explorer
    $('background-tetris').style.backgroundColor = "transparent";

}

function addMoveTetris() {
    var num_moves = parseInt($('moves-tetris').innerHTML);

    if(GAME_STARTED) num_moves++;

    $('moves-tetris').innerHTML = num_moves;
    $('placed-tetris').innerHTML = NUM_PLACED_TETRIS;

}


//
// mega-grid functions
//



var MEGA_ENTRIES = new Array();
var MEGA_POINTS = new Array();

function printMegaGrid(grid)
{
    var cols;
    var rows = Math.sqrt(grid.length);
    cols = rows;

    var table;
    var k = 0;
    table = "<table id='grid-mega-grid' class='grid-mega-grid verdana'>";


    for (var i = 0; i < rows; i++) {

        table += "<tr>";


        for (var j = 0; j < rows; j++){
            cellId = "mega-grid-cell-" + String(i+1)+String(j+1);
            table += "<td id=" + cellId + ">" + grid.charAt(k) + "</td>";
            k++;
        }

        table += "</tr>";
    }



    table += "</table>";


    document.write(table);

    new Effect.Opacity('grid-mega-grid', {from: 1.0 , to: 0, duration: 0});

}

function displayCallout() {
   

   //will activate this when I have time

   /* 
    var total_answered =
        getNumberAnswered("spatial")
        + getNumberAnswered("math")
        + getNumberAnswered("verbal")
        + getNumberAnswered("social");

    var math_ratio = getNumberAnswered("math") / total_answered;
    

    if(math_ratio >= .15) $('mega-callout').style.display = "";
   */
}

function scoreCallout() {
/* adding this is on the wish-list*/


}

function alreadyEnteredMegaGrid(word) {

    for (var i = 0; i < MEGA_ENTRIES.length; i++) {

        if( word==MEGA_ENTRIES[i] ) {
            return true;
        }
    }

    return false;
}

function updateScoreMegaGrid(points) {
    var scoreDiv = $("tally-mega-grid");
    var score = scoreDiv.innerHTML;
    score = safeParse(score);
    score += points;
    scoreDiv.innerHTML = score;
}

function checkWordMegaGrid(){
   var word = $("word-mega-grid").value;
   var points = 0;
   if (word != "") {

	/* Had to internalize operations; the return cases were breaking safari */
	
	if(!alreadyEnteredMegaGrid(word.toLowerCase())) {
	      for (var i = 0; i < boggle.length; i++) {

	         if( word==boggle[i] ) {
		    MEGA_ENTRIES[MEGA_ENTRIES.length] = word;
		    points = word.length;
		    if (points > 2) points = sigma(points - 3);
		    else points = 0;

		    MEGA_POINTS[MEGA_POINTS.length] = points;

		 }
	     }
	   }
      if(!TIMES_UP && GAME_STARTED) updateScoreMegaGrid(points);
      $("word-mega-grid").value = "";  
   }
}



function sigma(n) {
    if ((n == 0) || (n == 1)) {
        return 1;
    }
    else {
        result = sigma (n-1) + sigma (n-2) ;
        return result;
    }
}

function keypressMegaGrid(e) {


        var Ucode=e.keyCode? e.keyCode : e.charCode;
		if (Ucode == 13)

		{

		    checkWordMegaGrid();

		}
		e = (e) ? e : ((window.event) ? window.event : "");
		if (e) {
			
		// process event here
		// alert( evt.keyCode); // IE and Safari
		// alert( evt.which); // FF

		return !( e.keyCode==13 || e.which==13 );

	}



}

function startMegaGrid(seconds) {

    GAME_STARTED= true;
    new Effect.Opacity('grid-mega-grid', {from: 0.0 , to: 1});
//    Effect.Appear('grid-mega-grid');
    $("word-mega-grid").value = "";
    setTimeout("setFocus('word-mega-grid')",500);

    startTimer(seconds, 'mega-grid');
}



//
// steps-forward
//

function cellHover(obj) {
    
    obj.className = "active-steps-forward-hover";

}

function cellNoHover(obj) {
    obj.className = "active-steps-forward";

}

var HINT_STEPS_FORWARD = 0;
var STEPS_FORWARD_SOLVED = false;

function changeCenter(obj) {

    if (!GAME_STARTED) return;
    if (TIMES_UP) return;
    if (LOCK_QUESTION) return;

    if(GAME_STARTED && TimeLapsed > 20) {

        if (HINT_STEPS_FORWARD == 0) {
            if(!EXPLORER)Effect.Grow('hint1-steps-forward'); 
            else Effect.Appear('hint1-steps-forward');        
            HINT_STEPS_FORWARD ++;
        }

    }

    if(GAME_STARTED && TimeLapsed > 40 ) {

       if (HINT_STEPS_FORWARD == 1) {
        
        if(!EXPLORER)Effect.Grow('hint2-steps-forward'); 
        else Effect.Appear('hint2-steps-forward');
        HINT_STEPS_FORWARD ++;
       }

    }    
    var value = safeParse(obj.innerHTML);


    var operation = obj.id;
    var center_value = safeParse(document.getElementById('center-square').innerHTML)


        //alert(operation + " " + value);

        switch (operation) {

        case "subtract":
        center_value = center_value - value;
        break;
        case "add":
        center_value = center_value + value;
        break;
        case "divide":
        center_value = center_value / value;
        break;
        case "multiply":
        center_value = center_value * value;
        break;
        case "special":
        if(center_value % value == 0) {
            center_value = center_value / value;
        }
        else center_value = center_value * value;
        break;

        case "reset":
        center_value = 1000;
        break;
        }

    document.getElementById('center-square').innerHTML = center_value;

    if(center_value == 0) {
		    lockQuestion();
		    STEPS_FORWARD_SOLVED = true;

		    endQuestionEarly('steps-forward');

		    }
    

    var num_moves = document.getElementById('debug1-steps-forward').innerHTML;
    num_moves = safeParse(num_moves);
    num_moves ++;
    document.getElementById('debug1-steps-forward').innerHTML = num_moves;

    
}

function startStepsForward(seconds) {
    GAME_STARTED = true;
    
    startTimer(seconds, 'steps-forward');


    $('give-up-steps-forward').style.display = "";
}

function giveUpStepsForward(seconds) {
    TimeLapsed = seconds;
    endQuestionEarly('steps-forward');



}


//
// shapes-grid
//


var ANSWER_SHAPES_GRID;
var COUNT_SHAPES_GRID=0;
var SHAPES_GRID_CONTENTS = new Array;


function startShapesGrid(seconds) {
    GAME_STARTED = true;
    lockQuestion();
    startTimer(seconds, 'shapes-grid');
    flashShapesGrid();




}

function hoverShapeGrid(obj) {

    obj.style.opacity = 1;
    obj.style.filter = 'alpha(opacity=100)';
}

function noHoverShapeGrid(obj) {

    obj.style.opacity = .8;
    obj.style.filter = 'alpha(opacity=80)';

}


function changeShapesGrid() {

    var color = true;
    var num_shapes = 3;

    var num_circles = 0;
    var num_squares = 0;
    var num_triangles = 0 ;
    var num_octagons = 0;

    var threshold = 3;

    var rand;
    var img;
    var cell;
    var id;

    num_circles = 0;
    num_squares = 0;
    num_triangles = 0 ;
    num_octagons = 0;

    if (COUNT_SHAPES_GRID < threshold) {
        num_shapes = 3;
        document.getElementById('octagon').style.display = 'none';
    }
    else {
        num_shapes = 4;
        document.getElementById('octagon').style.display = 'inline';
    }


    for (var i = 0; i < 9 ; i ++ ) {

        rand = Math.floor(Math.random() * num_shapes);

        img = "http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/shapes/";

        switch (rand) {
        case 0:
            img += 'triangle';
            SHAPES_GRID_CONTENTS[i] = 'triangle';
            num_triangles ++;
            break;
        case 1:
            img += 'square';
            SHAPES_GRID_CONTENTS[i] = 'square';
            num_squares ++;
            break;
        case 2:
            img += 'circle';
            SHAPES_GRID_CONTENTS[i] = 'circle';
            num_circles ++;
            break;
        case 3:
            img += 'octagon';
            SHAPES_GRID_CONTENTS[i] = 'octagon';
            num_octagons ++;
            break;

        }

        if(color) img += '_color';

        img += '.gif';

        id = "img" + i;
        document.getElementById(id).src = img;


    }



}


function chooseNextShapesGrid(){
    ANSWER_SHAPES_GRID  = Math.floor(Math.random() * 9);

    document.getElementById('question-shapes-grid').src = 'http://cdn.okcimg.com/_img/layout2/iqadventure/puzzles/images/shapes/cell' + ANSWER_SHAPES_GRID + '.gif';



}

function flashShapesGrid() {
    
    var s = 1; // this is just to adjust timings

    document.getElementById('question-shapes-grid').style.display = 'none';

    changeShapesGrid();
    chooseNextShapesGrid();

    Effect.Appear('shapes-grid', {duration: 1});
    Effect.Fade('shapes-grid', {duration: .5, delay: s , queue: 'end'});
    Effect.Appear('question-shapes-grid', {delay: 1, queue: 'end'});

    setTimeout('unlockQuestion()', 2500 + 200 + s * 1000);


}

function scoreShapesGrid() {


}

function checkAnswerShapesGrid(shape) {

    if(TIMES_UP || !GAME_STARTED || LOCK_QUESTION) return;

    lockQuestion();
    
    var correct = safeParse(document.getElementById('debug-shapes-grid').innerHTML);
    var incorrect = safeParse(document.getElementById('debug2-shapes-grid').innerHTML);

    if (shape == SHAPES_GRID_CONTENTS[ANSWER_SHAPES_GRID]) {

        COUNT_SHAPES_GRID ++;
        correct++;
        document.getElementById('debug-shapes-grid').innerHTML = correct;
    }
    else {

        COUNT_SHAPES_GRID --;

        incorrect++;
        document.getElementById('debug2-shapes-grid').innerHTML = incorrect;        
    }


    flashShapesGrid();
}

//
// complements function
//


var DISPLAYED_COMPLEMENT;
var COMP_COUNTER = 0;
var CORRECT_COMPLEMENTS = 0;
var INCORRECT_COMPLEMENTS = 0;
var image_path = "http://cdn.okcimg.com/_img/layout2/iqadventure/";


function preLoadComplements() {
var img;

for (var i = 0; i < 7; i ++) {	
img = 'new_complements/' + i + '.gif';
preLoadImage(img);

}

for (i = 0; i < 7; i ++) {	
img = 'new_complements/' + i + 'i.gif';
preLoadImage(img);

}

}

function startComplements(seconds) {
GAME_STARTED = true;
startTimer(seconds, 'complements');
showComplementsScoring();
lockQuestion();

var this_img = COMP_COUNTER; 
$('complements-display').src = image_path +"puzzles/images/new_complements/" + this_img  + ".gif";
new Effect.Opacity('complements-display', {from: 0, to: 1, delay: 0, duration: 1,queue:'end'})

newComps();

}
function showComplementsScoring() {
$('complements-scoring').style.display="";

}


function nextComplementQuestion() {

if (COMP_COUNTER < 7 && !TIMES_UP) {
new Effect.Opacity ('complements-display', {from: 1, to:0, afterFinish: newOrig})
new Effect.Opacity ('complements-answers', {from: 1, to:0, afterFinish: newComps})

}
else {	
lockQuestion();
new	Effect.Opacity ('complements-display', {from: 1, to: 0});
new	Effect.Opacity ('complements-answers', {from: 1, to: 0});

endQuestionEarly('complements');

}
}


function newOrig() {

var this_img = COMP_COUNTER; 
$('complements-display').src = image_path +"puzzles/images/new_complements/" + this_img  + ".gif";
new Effect.Opacity('complements-display', {from: 0, to: 1, delay: 1, duration: 1.5,queue:'end'})


}

function checkComplementsAnswer(obj){

if(LOCK_QUESTION) return false;

else {

var val;

lockQuestion();

if(obj.id == DISPLAYED_COMPLEMENT) {
val = $('result1-complements').innerHTML;
val ++;
$('result1-complements').innerHTML  = val;		
CORRECT_COMPLEMENTS++;

}else {
val = $('result2-complements').innerHTML;
val ++;
$('result2-complements').innerHTML  = val;
INCORRECT_COMPLEMENTS++;
}
COMP_COUNTER ++;		

nextComplementQuestion();



}



}

function newComps() {



var this_img = COMP_COUNTER;	
var correct_id = Math.floor(Math.random() * 3);
DISPLAYED_COMPLEMENT = "complements-answer" + correct_id;

var other_id0 = (correct_id + 1) % 3;
var other_id1 = (correct_id + 2) % 3;	

var other_img0 = 0;
var other_img1 = 0;

$('complements-answer' + correct_id).src = image_path + "puzzles/images/new_complements/" + this_img  + "i.gif";

// need to choose two random images

while ((other_img0 == this_img) || (other_img0 == 0)) {
other_img0 = Math.floor(Math.random() * 7);
}

while ((other_img1 == this_img) || (other_img0 == other_img1) ||(other_img1 == 0)) {
	    other_img1 = Math.floor(Math.random() * 7);
}

$('complements-answer' + other_id0).src = image_path +"puzzles/images/new_complements/" + other_img0  + "i.gif";
$('complements-answer' + other_id1).src = image_path +"puzzles/images/new_complements/" + other_img1  + "i.gif";

$('complements-h3').style.visibility = "visible";

new Effect.Opacity ('complements-answers', {from: 0, to: 1, duration:.5, queue:'end', afterFinish: unlockQuestion});


}

preLoadComplements();











//
// hi-fives functions
//

//
// smiles functions
//


//
// root beer
//

var ROOT_BEER_ORDER = new Array (2,1,3,0);

function initializeRootBeer(){

    var SortableLists = {
	lists: ["root-beer-list"],
	
	updated: function(list) {

        ROOT_BEER_ORDER = Sortable.sequence(list);
        },
	
	createSortables: function (event) {
		
		var lists = SortableLists.lists;
        
		lists.each(function (id) {
			if($(id))
			{
				Sortable.create(id, {
					dropOnEmpty: false,
                            containment: lists,
                            constraint: false,
                            onUpdate: SortableLists.updated
                            });	
			}
			
            });
		
        }
    };
    SortableLists.createSortables();

}

function startRootBeer(seconds) {
    startTimer(seconds, 'root-beer');

}

//
// warm-up functions
//

var WARM_UP_ORDER = new Array(2,3,1,4,5);

function initializeWarmUp() {

    var SortableWarmUpList = {
    lists: ["warm-up-list"],

    updated: function(list) {
            WARM_UP_ORDER = Sortable.sequence('warm-up-list');

            },
    createSortables: function (event) {
            var lists = SortableWarmUpList.lists;
            lists.each(function (id) {
                    Sortable.create(id, {
                        dropOnEmpty: false,
                                containment: lists,
                                constraint: false,
                                                   onUpdate: SortableWarmUpList.updated
                                });
                });
        }
    };
    SortableWarmUpList.createSortables();
    
}




function scoreWarmUp() {
	 finishQuestion('warm-up');
}

function areArraysSame(a1,a2) {
    if (a1.length != a2.length) {
        return false;
    }
    var i = 0;;
    for (i = 0; i < a1.length; i++) {
        if (a1[i] != a2[i]) {
            return false;
        }
    }
    return true;
} 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/md5.js
AUTOCORE_SELF_CHECK.push("md5.js");


// 


function get_md5_bit (in_str, which_bit) 
{
    while (which_bit > 127) {
	in_str = hex_md5(in_str);
	which_bit -= 128;
    }
    var hex = hex_md5(in_str);
    var c_pos = hex.length - 1 - Math.floor(which_bit / 4);
    var c = hex.charAt(c_pos);
    var base10 = parseInt("0x" + c, 16);
    var char_bit = which_bit % 4;
    while (char_bit > 0) {
	base10 = base10 >> 1;
	char_bit--;
    }
    return base10 % 2;
}
//
// returns an int in [0..15] for picking which 
// group a string (probably user) is in, in an experiment
//
function get_experiment_group(uid_str, experiment_str)
{
    var hex = hex_md5(uid_str + experiment_str);
    var last_char = hex.charAt(hex.length - 1);
    return parseInt("0x" + last_char, 16);
}

// 



/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/OkLocation.js
AUTOCORE_SELF_CHECK.push("OkLocation.js");
//

//
// 
//

if (typeof Prototype =='undefined'  || Prototype.Version < "1.6" ) {
	throw("OkLocation requires Prototype 1.6 or higher.");
}



var OkLocation = Class.create({

	initialize: function(params) {
		          
		this.AjaxPath = "/locquery";
        this.Status = "pending";
		this.FormType = "text";
		this.TempId = "loc_" + Math.round(Math.random() * 1000000000);
        this.Params = params;
		this.LocId = "";
		this.QueryString = "";
		this.PossibleMatches = new Array();		
		this.AjaxResult = new Object;
        
        this.startExperience();

	},
	                
	getStatus: function() {
		return this.Status;
	},
	
	submitFormIfLocationReady: function(form_id, failure_cb, loc_mandatory) {
		if (this.Status == "success" || (!loc_mandatory && $F('text_' + this.TempId) == "")) {
			$(form_id).submit();
		}
		else if (loc_mandatory && $F('text_' + this.TempId) == "") {
			alert('You must enter a location!');
		}
		else {
			failure_cb(this);
		}
	},
	
	startExperience: function() {

		if (this.Params.previous_loc_id && this.Params.previous_loc_id != 0 && this.Params.previous_loc_id != "") {
			this.Status = "success";
			this.LocId = this.Params.previous_loc_id;
		}
		if (this.Params.previous_query_string) {
			this.QueryString = this.Params.previous_query_string;
		}
		
		this.drawInputs();
	},
	
	drawInputs: function() {
		var res = "";

		if (this.FormType == "select") {
			res += '<select id="sel_' + this.TempId + '">';
			res += '<option value=""> - choose one - </option>';
			res += '<option value="reset"> - start over - </option>';
			for (var i = 0; i < this.PossibleMatches.length; i++) {
				res += '<option value="' + this.PossibleMatches[i].locid + '">' + this.PossibleMatches[i].text + '</option>';
			}
			res += '</select>';	
			this.Status = "pulldown";
		}
		else {
            if(this.Params.replaceEnter == true)
                res += '<input class="location_input" onkeydown="if(event.keyCode==13 || event.which==13) {'+this.Params.newEnter+';return false;}" type="text" id="text_' + this.TempId + '" name="text_' + this.TempId + '" value="' + this.QueryString + '"/>';
            else
			    res += '<input class="location_input" type="text" id="text_' + this.TempId + '" name="text_' + this.TempId + '" value="' + this.QueryString + '"/>';
		}

		var input_type = "hidden";
		var id_label = "";
		var query_label = "";
		if (this.Params.debug) {
			input_type="text";
			id_label = "LocID hidden input ('" + this.Params.loc_id_input_name + "'): ";
			query_label = "Query hidden input ('" + this.Params.query_input_name + "'): ";
		}
		res += id_label + '<input type="' + input_type + '" name="' + this.Params.loc_id_input_name 
				+ '" id="' + this.Params.loc_id_input_name 
				+ '" name="' + this.Params.loc_id_input_name 
				+ '" value="' + this.LocId + '" />';
		res += query_label + '<input type="' + input_type + '" name="' + this.Params.query_input_name
				+ '" id="' + this.Params.query_input_name 
				+ '" name="' + this.Params.query_input_name 
				+ '" value="' + this.QueryString + '" />';
				
		$(this.Params.dest_div).innerHTML = res;
		if (this.FormType == "select") {
			Event.observe('sel_' + this.TempId, 'change', this.selectChange.bindAsEventListener(this));
		}
		else {
			Event.observe('text_' + this.TempId, 'keyup', this.textChange.bindAsEventListener(this));
			Event.observe('text_' + this.TempId, 'blur', this.performLookup.bindAsEventListener(this));
		}
	},

	textChange: function() {
		if ($F(this.Params.query_input_name) != $F("text_" + this.TempId)) {
			this.Status = "pending";
			this.LocId = "";
			$(this.Params.loc_id_input_name).value = "";			
			if (this.Params.cb_lost_success) {
	            this.Params.cb_lost_success(this);			
			}				
			$(this.Params.query_input_name).value = $F("text_" + this.TempId);
		}
	},

	selectChange: function() {
		var id = $F("sel_" + this.TempId);

		if (id == "reset" || id == "") {
			if($("find_btn")) $("find_btn").style.display = "inline";
			this.Status = "pulldown";
			this.LocId = "";
			this.FormType="text";
			$(this.Params.loc_id_input_name).value = "";
			$(this.Params.query_input_name).value = "";
			this.QueryString = "";
			this.PossibleMatches = new Array();		
			this.AjaxResult = new Object;
			this.drawInputs();
			if (this.Params.cb_reset) {
	            this.Params.cb_reset(this);			
			}
		}
		else {
			this.Status = "success";
			this.LocId = id;
			$(this.Params.loc_id_input_name).value = this.LocId;
			$(this.Params.query_input_name).value = this.AjaxResult.query;
			if (this.Params.cb_success) {			
	            this.Params.cb_success(this);			
			}
		}
		$(this.Params.loc_id_input_name).value = this.LocId;		
	},
	
	performLookup: function() {
		var req = new Ajax.Request(this.AjaxPath, {
			method: "get",
			parameters: {func : "query", query : $F("text_" + this.TempId), cbust : Math.round(Math.random() * 1000000000)},
			onSuccess: this.performLookup_cb.bindAsEventListener(this),
			onFailure: function() { alert("Location lookup failed!"); }
		});		
	},

	performLookup_cb: function(data) {
		this.AjaxResult = data.responseText.evalJSON();
		// Make sure the request is what the user still has in the text box to avoid race condition
		if ($("text_" + this.TempId) && $F("text_" + this.TempId) == this.AjaxResult.query) {
			if (this.AjaxResult.locid && this.AjaxResult.locid != 0 && this.AjaxResult.locid != "") {
				this.handleSuccess();
			}
			else {
				this.handleError();
			}
		}
	},
	
	handleError: function() {
		this.LocId = "";
		if (this.AjaxResult.results.length > 0) {
			this.FormType = "select";
			this.PossibleMatches = this.AjaxResult.results;
			this.drawInputs();
		}
		if (this.Params.cb_error) {
			this.Params.cb_error(this);
		}
	},
	
	handleSuccess: function() {
		this.Status = "success";
		this.LocId = this.AjaxResult.locid;
		$(this.Params.loc_id_input_name).value = this.LocId;
		if (this.Params.cb_success) {			
            this.Params.cb_success(this);			
		}
	}


});
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/OkLoginJoin.js
AUTOCORE_SELF_CHECK.push("OkLoginJoin.js");

// 

function killEnterAll(e) {
	var Ucode=e.keyCode? e.keyCode : e.charCode;
	if (Ucode == 13){}
	e = (e) ? e : ((window.event) ? window.event : "");
	if (e) {return !( e.keyCode==13 || e.which==13 );}	
}

var OKLJ = Class.create({

	inititalize : function() {
		
	},
	
	
	//
	//   optional inside params object:
	//   --------------------------------
	//   success_cb : a function to call after a successful login
	//   success_redirect : where to redirect browser after successful login
	//   failure_cb : a function to call after a failed login
	//   failure_redirect : where to redirect browser after failed login

	login : function(screenname, password, params) {
		var ajax_params = { "ajax" : 1, "username" : screenname, "password" : password, enable: params.enable ? 1 : 0};
		var req = new Ajax.Request("/login", {
			method: 'post', 
			parameters: ajax_params ,
			onSuccess: this.login_cb.bindAsEventListener(this, params), 
			onFailure: this.login_cb_failed.bindAsEventListener(this, params)});
		return req;
		
	},


	// This used to be fairly simple, but we also may get a paramter back from the login
	// service telling us we need to visit an authlink, in a hidden iframe. Can't use
	// AJAX for domain security reasons.  So we need to visit that before calling it a day. So this function
	// isn't the last one; it'll invoke login_cb_post_authlink when it's done

	login_cb : function(data, params) {
		var response = data.responseText.evalJSON();
		this.tempHoldings = {'data' : data, 'params' : params };
		if (response.hq_okc_authlink && response.hq_okc_authlink != "") {
			Element.insert(document.body, {  bottom: '<iframe style="display:none;" onload="OkLoginJoin.login_cb_post_authlink()" src="' + response.hq_okc_authlink + '" id="auth-ajax-login"></iframe>'  }  );			
			// doubly-set src for old IE bug where iframes added with src didn't work
			$('auth-ajax-login').src = response.hq_okc_authlink;
            setTimeout("OkLoginJoin.login_cb_post_authlink()", 1000);
		}
		else {
			this.login_cb_post_authlink();
		}		
	},
	
	login_cb_post_authlink : function() {
		
		var data = this.tempHoldings.data;
		var params = this.tempHoldings.params;
		var response = data.responseText.evalJSON();
		if (response.status == "success") {
			if (params.success_cb) {
				params.success_cb(response);
			}
			if (params.success_redirect) {
				document.location.href = params.success_redirect;
			}
		}
		else {
			if (params.failure_cb) {
				params.failure_cb(response);
			}
			if (params.failure_redirect) {
				document.location.href = params.failure_redirect;
			}			
		}
		
	},
	
	login_cb_failed : function(data, params) {
		alert("AJAX login Failed!");		
	},
	
	//
	//   optional inside params object:
	//   --------------------------------
	//   success_cb : a function to call after a successful logout
	//   success_redirect : where to redirect browser after successful logout

	logout : function(params) {
		var ajax_params = { "ajax" : 1 };
		var req = new Ajax.Request("/logout", {
			method: 'post',
			parameters: ajax_params ,
			onSuccess: this.logout_cb.bindAsEventListener(this, params), 
			onFailure: this.logout_cb_failed.bindAsEventListener(this, params)});
		return req;
	},

	logout_cb : function(data, params) {
		var response = data.responseText.evalJSON();
		if (response.status == "success") {
			if (params.success_cb) {
				params.success_cb(response);
			}
			if (params.success_redirect) {
				document.location.href = params.success_redirect;
			}
			Element.insert(document.body,
					{  bottom: '<iframe style="display:none;" src="http://www.okcupid.com/logout" id="auth-ajax-okc-logout"></iframe>'  }  );
		}
		else {
			alert("Logout somehow failed");
		}
	},
	
	logout_cb_failed : function(data, params) {
		alert("AJAX logout Failed!");		
	},
	

	//
	//   optional inside params object:
	//   --------------------------------
	//   success_cb : a function to call after a successful request (user exists, mail sent)
	//   success_redirect : where to redirect browser after successful request (user exists, mail sent)
	//   failure_cb : a function to call after a failed request
	//   failure_redirect : where to redirect browser after failed request

	lostPassword : function(screenname_or_email, params) {
		var ajax_params = { "ajax" : 1, "email" : screenname_or_email};
		var req = new Ajax.Request("/lostpassword", {
			method: 'post', 
			parameters: ajax_params ,
			onSuccess: this.lostPassword_cb.bindAsEventListener(this, params), 
			onFailure: this.lostPassword_cb_failed.bindAsEventListener(this, params)});
		return req;		
	},
	
	lostPassword_cb : function(data, params) {
		var response = data.responseText.evalJSON();
		if (response.status == "SUCCESS") {
			if (params.success_cb) {
				params.success_cb(response);
			}
			if (params.success_redirect) {
				document.location.href = params.success_redirect;
			}
		}
		else {
			if (params.failure_cb) {
				params.failure_cb(response);
			}
			if (params.failure_redirect) {
				document.location.href = params.failure_redirect;
			}			
		}
	},
	
	lostPassword_cb_failed : function(data, params) {
		alert("AJAX lostPassword Failed!");		
	},



	//
	// for signup, params state maintained in member, since we can't pass through cgi safely;
	// with other functions we use bindAsEventListener to pass to callback
	//
	optionalParams : { },

	//
	//   dest_div: where on the page they'll be doing the signup.
	//   signup_path : required, e.g. "/signup/paths/inga/1.html" -- path to first file in process
    //   cgi_extras : extra cgi parameters to pass to the signup service. ("cf", "gender", etc.)
	//     
	//   optional inside params object:
	//   --------------------------------
	//   success_cb : a function to call after a successful request (user exists, mail sent)
	//   success_redirect : where to redirect browser after successful request (user exists, mail sent)
	
	join : function(dest_div, signup_path, cgi_extras, params) {

			this.optionalJoinParams = params;
		
			var default_params = { "ajax" : 1, "reqs" : 0, "cbust" : Math.random() };
			var ajax_params = this.combineTwoObjs(default_params, cgi_extras);
			ajax_params["next_page"] = signup_path;
			var req = new Ajax.Updater(dest_div, "/signup", {
				method: 'post', 
				evalScripts: true,
				parameters: ajax_params });
	},

	//
	// Called by the HTML inserted via signup
	//
	// This used to be fairly simple, but we also may get a paramter back from join
	// service telling us we need to visit an authlink, in a hidden iframe. Can't use
	// AJAX for domain security reasons.  So we need to visit that before calling it a day. So this function
	// isn't the last one; it'll invoke login_cb_post_authlink when it's done

	join_cb : function (data) {
		this.tempHoldings = {'data' : data };
		if (data.hq_okc_authlink && data.hq_okc_authlink != "") {
			Element.insert(document.body, {  bottom: '<iframe style="display:none;" onload="OkLoginJoin.join_cb_post_authlink()" src="' + data.hq_okc_authlink + '" id="auth-ajax-join"></iframe>'  }  );
            setTimeout("OkLoginJoin.join_cb_post_authlink()", 1000);
		}
		else {
			this.join_cb_post_authlink()
		}
	},
	
	join_cb_post_authlink : function() {
		var data = this.tempHoldings.data;
		
		if (this.optionalJoinParams.success_cb) {
			this.optionalJoinParams.success_cb(data);
		}
		if (this.optionalJoinParams.success_redirect) {
			document.location.href = this.optionalJoinParams.success_redirect;
		}		
	},
	
	//
	// helpers
	//
	
	combineTwoObjs : function(o1, o2) {
		
		var res = new Object();
		for (var key in o1) {
			res[key] = o1[key];
		}
		for (var key in o2) {
			res[key] = o2[key];
		}
		return res;			
	}
	
});
//----------------------------------------------------------------------------------------------------------------

 	var OkLoginJoin = new OKLJ(); 

//----------------------------------------------------------------------------------------------------------------

	
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/Oryx/Bitter.js
AUTOCORE_SELF_CHECK.push("Oryx/Bitter.js");
/* ----------------------------------------------------------------

OkCupid Bitter file

	- for some triple entendre 

This is a specialized file for setting the remote 64 bit settings
variable.

---------------------------------------------------------------- */

var Bitter = {
	
	//active:"" || false,
	
	bit:{},
	persist:NaN,
	funcs:new Array(),
	map:{},
	LOAD:function(cb)
	{			
		var pass = this;
		var fire = cb || function(){};
		
		new Ajax.Request(
			"/bitter_JSON.html",
			{
				method:"get",
				onSuccess:function(response) {
					pass.bit = response.responseText.evalJSON();
					fire();
				}
			}
		);
	},
	loadFromString:function(s)
	{
		for (var i = 0 ; i < s.length; i++) {
			this.bit["_" + i] = (s.charAt(i) == "1" ? 1 : 0);
		}
	},
	sanctify:function(bit) 
	{
		if(!bit && bit != 0) {
			bit = this.persist;
		}
		
		if(isNaN(bit)) {
			bit = this.map[bit];
		}
		
		formbit = "_" + bit;
		this.persist = [formbit,bit];
		return [formbit,bit];
	},
	get:function(bit) 
	{
		_bit = this.sanctify(bit);
		_val = this.bit[_bit[0]];
		if (typeof(_val) == "undefined") _val = 0;
		return _val;
	},
	set:function(value,bit) 
	{
		//if(!this.active) return;
		
		_bit = (bit ? this.sanctify(bit) : this.persist);
		
		value = value == 1 ? 1 : 0;
		
		this.bit[_bit[0]] = value;
		
		var passbit = _bit[1];
		var passval = value;
	    var cashbrk = Math.round(Math.random()*10000000);
	
		new Ajax.Request(
			"/settings", 
			{
				method: 'get',
				parameters: {
					update_ui_prefs:1,
					bit:passbit,
					val:passval,
					bst:cashbrk
				},
				onSuccess:function(response){var sacrifice = response.responseText;}
			}
		);
	},
	trigger:function(funcs,bit) 
	{
		_bit = this.sanctify(bit);
	
		this.funcs[_bit[0]] = funcs;
		var pass = this;
	
		if(funcs.on) 	document.observe("dom:loaded", function() {if(pass.bit[_bit[0]] == 1) pass.funcs[_bit[0]].on();});
		if(funcs.off) 	document.observe("dom:loaded", function() {if(pass.bit[_bit[0]] == 0) pass.funcs[_bit[0]].off();});
	},
	toggle:function(bit) 
	{
		_val = this.get(bit);
		this.set(++_val%2);
	}
};

var $bit = Bitter;
	
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/Oryx/Sookie.js
AUTOCORE_SELF_CHECK.push("Oryx/Sookie.js");
/* 
 * 	Sookubit.js
 *  
 *  Manages the SOOKIE.sookubit object
 */

var Sookie = {
	
	url:'/sookie/remote_sookie.html',
	value:0,
	sookie:{},
	
	init:function(sookie)
	{
		if(sookie)
			this.sookie = sookie;
	},
	
	load:function()
	{
		var pass = this;
		new Ajax.Request(
			pass.url,
			{
				method:'get',
				parameters:{
					getall:1
				},
				onSuccess:function(response) {
					pass.sookie = response.responseText.evalJSON();
				}
			}
		);
	},
	
	get:function(n,o)
	{
		if(typeof this.sookie[n] == "undefined")
			return false;
		
		if(o)
			return this.sookie[n];
		else
			return this.sookie[n].value;
	},

	set:function(v,n,e)
	{
		var pass = this;
		
		params = {
			name:n,
			value:v
		}
		
		if(e) 
			params.expire = e;
		
		new Ajax.Request(
			pass.url,
			{
				method:'get',
				parameters:params,
				onSuccess:function() {
					pass.sookie[n] = v;
				}
			}
		);
	}
}

$sake = Sookie; 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/Oryx/Cookies.js
AUTOCORE_SELF_CHECK.push("Oryx/Cookies.js");
// 

function setOkCookie(name,value,expires) {
    setCookie(name,value,expires);
}

function deleteOkCookie(name) {
    deleteCookie(name);
}

// -----------------------------------------------------------------------------------

function getPageTopDomain() {
 var host = window.location.host;
 var parts = host.split('.');
 var res = parts[parts.length-2] + "." + parts[parts.length-1];
 if (res.indexOf(':') != -1) {
	 res = res.substr(0,res.indexOf(':'));
 }
 return res;
}

function secondsFromNow (sec) {
   res = new Date();
   res.setTime(new Date().getTime() + sec * 1000);
   return res;
}

// -----------------------------------------------------------------------------------

function setCookie(name,value,expires) {
  var curCookie = name + "=" + escape(value) +
      ((expires) ? "; expires=" + expires.toGMTString() : "") +
      "; path=/"+
      "; domain=" + getPageTopDomain();
  document.cookie = curCookie;
}
function deleteCookie(name) {
  if (getCookie(name)) {
    document.cookie = name + "=" +
    "; domain=" + getPageTopDomain() + 
    "; path=/"+
    "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}
function getCookie(name) {
	var dc = document.cookie;
  	var prefix = name + "=";
  	var begin = dc.indexOf("; " + prefix);
  	if (begin == -1) {
    	begin = dc.indexOf(prefix);
    	if (begin != 0) return null;
  	} 
	else
    	begin += 2;
  	var end = document.cookie.indexOf(";", begin);
  	if (end == -1)
    	end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}

 /* 
 */

function addNewCoresToCookie(file_nums, hash) {
	 var old_cookie = getCookie("core");
	 var old_cookie_parts = [];
	 var new_cookie = old_cookie;
	 if (old_cookie)
		old_cookie_parts = old_cookie.split(":");
	 if (old_cookie_parts.length == 0 || old_cookie_parts[0] != hash)
		old_cookie
	 if (! old_cookie || old_cookie.split(":")[0] != hash)
		new_cookie = hash;
	 var new_addition = file_nums.join(",");
	 for (var i = 1; i < old_cookie_parts.length && old_cookie_parts[0] == hash; i++) {
		 if (old_cookie_parts[i] == new_addition) {
			 return;
		 }
	 }
	 new_cookie += ":" + new_addition;
	 setCookie("core", new_cookie, secondsFromNow(86400 * 30));
}

// Backwards compatibility, but limit miniCookies to 3600 seconds.
 
function setMiniCookie(name,value) {
	NanoCookie.set(name,value,{ms:3600*1000});
}

function deleteMiniCookie(name) {
	NanoCookie.remove(name);
}

function getMiniCookie(name) {
	return NanoCookie.get(name);
}

// 
NanoCookie = {
	
	// 
	set : function(key,value,expires,test) {
		var cookies = this.deserialize();
		var d = new Date();
		var obj = new Object();
		obj["k"] = key;
		obj["v"] = value;
		if (expires.ms)
			obj["e"] = d.getTime() + parseInt(expires.ms);
		else if (expires.gmt)
			obj["e"] = expires.gmt;
		else
			obj["e"] = expires.date.getTime();
		if (isNaN(obj["e"]))
			obj["e"] = 0;
		var found = false;

		for (var i = 0; i < cookies.length; i++) {
			if (cookies[i]["k"] == key) {
				cookies[i] = obj;
				found = true;
			}
		}
		if (! found)
			cookies.push(obj);
		this.serializeAndStore(cookies);
	},
	get : function(key) {
		var cookies = this.deserialize();
		for (var i = 0; i < cookies.length; i++) {
			if (cookies[i]["k"] == key) {
				return cookies[i]["v"];
			}
		}
		return null;
	},	
	// 
	getAll : function(nano_cookie_str) {
		var cookies = this.deserialize(nano_cookie_str);
		var res = [];
		for (var i = 0; i < cookies.length; i++) {
			var obj = new Object();
			obj["key"] = cookies[i]["k"];
			obj["value"] = cookies[i]["v"];
			obj["expires"] = new Date(cookies[i]["e"]);
			res.push(obj);
		}
		return res;		
	},
	// 
	findRegExp : function(regexp) {
		var cookies = this.deserialize();
		var res = [];
		for (var i = 0; i < cookies.length; i++) {
			if (regexp.test(cookies[i]["k"])) {
				var obj = new Object();
				obj["key"] = cookies[i]["k"];
				obj["value"] = cookies[i]["v"];
				obj["expires"] = new Date(cookies[i]["e"]);
				res.push(obj);
			}
		}
		return res;
	},
	remove : function(key) {
		this.set(key,"",{ms:-1},true);		
	},
	removeAll : function() {
		deleteCookie("nano");
	},
	//
	// gets from cookie called "nano" ; alternatively you 
	// can pass it your own cookie and it'll deserialize that
	deserialize : function(nano_cookie_str) {

		var x = nano_cookie_str ? nano_cookie_str : getCookie("nano");
		
		var result = [];
		if (! x)
			return result;
		else {
			var individuals = x.split("|");
			for (var i = 0; i < individuals.length; i++) {
				var obj = new Object();
				var pairs = individuals[i].split(",");
				for (var j = 0; j < pairs.length; j++) {
					var pair = pairs[j].split("=");
					var val = unescape(pair[1]);
					var pval = parseInt(val);
					if (pval == val && ! isNaN(pval))
						val = pval;
					obj[pair[0]] = val;
				}
				result.push(obj);				
			}
			result.sort(this.compareDates);
			// 
			var d = new Date();
			var any_stripped = false;
			while(result.length > 0 && new Date(result[result.length - 1]["e"]) < d) {
				result.length--;
				any_stripped = true;
			}
			return result;
		}
	},
	// 
	serializeAndStore : function(cookies) {
		var res = "";
		for (var i = 0; i < cookies.length; i++) {
			res += (i == 0) ? "" : "|";
			res += "k=" + escape(cookies[i]["k"]);
			res += ",e=" + escape(cookies[i]["e"]);
			res += ",v=" + escape(cookies[i]["v"]);
		}
		setCookie("nano", res, secondsFromNow(3600*24*365));
	},
	compareDates : function(a,b) {
		if (a["e"] && b["e"])
			return ((a["e"] < b["e"]) ? 1 : ((a["e"] > b["e"]) ? -1 : 0));
	}
};
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/Oryx/Form.js
AUTOCORE_SELF_CHECK.push("Oryx/Form.js");
/* ----------------------------------------------------------------

Form.js

	- manages custom form manipulation


TODO:
	behavior variable may be unnecessary

---------------------------------------------------------------- */

var Frm = {
	
	last:false,
	locked:false,
	
	behaviors:{},
	multiv:{},
	multit:{},
	savelock:false,
	
	lock_auxiliary:function(id)
	{
		// Replace with functions to happen on lock
		return false;
	},
	
	unlock_auxiliary:function(id)
	{
		// Replace with functions to happen on unlock
		return false;
	},
	
	lock:function(id) {
		this.lock_auxiliary(id);
		this.locked = id;
	},
	unlock:function(id) {
		this.unlock_auxiliary(id);
		this.locked = false;
	},
	
	toggle:function(id,behavior,force)
	{			
		button = $(id + "_button") || false;
		if(!behavior || behavior == '') behavior = "toggle";
		if(behavior == "buff")
			this.buffed = false;
		
		
		if(this.last == "location_interface" && ($("nearme") && !$("nearme").checked) && $("anywhere") && !$("anywhere").checked) {
			check_empty();
			this.buffed = id;
			return;
		}
		
		else if(this.last && id != this.last && button) {
			$(this.last + "_button").removeClassName('active');
			$(this.last + "_drop").style.display = 'none';
			$(this.last).removeClassName("open");
		}
		if(button) this.last = id;
		if(!this.behaviors[id]) this.behaviors[id] = behavior;
		if(button) {
			if(!button.hasClassName("active")) {
				$(id).addClassName("open");
				$(button).addClassName("active");
				$(id + '_drop').style.display = "block";
			} else if (behavior == "toggle" || behavior == "adder") {
				$(id).removeClassName("open");
				$(button).removeClassName('active');
				$(id + '_drop').style.display = "none";
			}
		}
	},
	set_auxiliary:function()
	{
		// Set this if you have a local action that 
		// needs to take place during the set operation
		return false;
	},
	set:function(name,value,id,text,init,pattern)
	{
		if(!init) this.save_reset();
		
		if(!$(name)) return;

		$(name).value = value;
			
		if(!pattern)
			$(id + "_button_text").innerHTML = $(text).innerHTML;
		else {
			t = $(text).innerHTML;
			$(id + "_button_text").innerHTML = util.jogf(pattern,{s:t});
		}

		this.set_auxiliary(name,value,id,text,init,pattern);

		if(!init) this.toggle(id,this.behaviors[id]);
	},
	save_reset:function()
	{
		/* 
		This function is overwritten by match.js if it's included.
		Left in because it could have utility elsewhere.
		*/
		return false;
	},
	
	pro_show:function(from)
	{
		/* 
		This function is overwritten by match.js if it's included.
		Left in because it could have utility elsewhere.
		*/
		return false;
	},
	
	multi_set:function(name,id,point,count,pattern,width,default_text,init)
	{	
		
		c = $(id + "_check_" + point);
		
		if(c.checked != true || init) 
			c.checked = true;
		else
			c.checked = false;
		
		this.multiv[id] = [];
		this.multit[id] = [];
		
		items = $(id + "_drop").getElementsByTagName("li");
		
		for(iter=0;iter<items.length;iter++) {
			
			if(items[iter].className == "divvy") continue;
			var item = $(items[iter]).getElementsByTagName("input")[0];
			
			if(item.checked) {
				this.multiv[id][this.multiv[id].length] = item.value;
				this.multit[id][this.multit[id].length] = item.title;
			}
		}
		
		$(name).value = util.toMask(this.multiv[id]);
		
		if(this.multit[id].length != 0) {
			text = this.multit[id].join(", ");
			display = this.limit_text(pattern,text,width);
		} else {
			display = default_text;
		}
		$(id + "_button_text").innerHTML = display;
		
		if(!init) this.save_reset();
	},
	
	limit_text:function(pattern,text,width)
	{
		display = util.jogf(pattern,{s:text});
		
		flashback = pattern.substring(0,pattern.indexOf(" %s"));
		
		lim = Math.round(width/10);

		if(display.length > lim) display = display.substring(0,lim) + "...";
		
		display = display.substring(flashback.length,display.length);
		output = flashback + "<span>" + display + "</span>";
		
		return output;
	},
	
	// Special cases
	
	process_age:function(init)
	{
		minc = $("min_age").value;
		min = parseInt($("min_age").value.strip());
		max = parseInt($("max_age").value.strip());
		txt = $("ages_button_text");
		
		if(isNaN(min)) {
			min = false;
			$("min_age").value = "";
		}
		if(isNaN(max)) {
			max = false;
			$("max_age").value = "";
		}
		if(min < 18 && minc.length == 2) {
			min = 18;
			$("min_age").value = 18;
		}
		
		if(min && !max) {
			txt.innerHTML = "Ages " + min + " to 99" ;
		} else if(!min && max) {
			txt.innerHTML = "Ages 18 to " + max;
		} else if(min && max) {
			txt.innerHTML = "Ages " + min + " to " + max;
		} else {
			txt.innerHTML = "Age";
		}
		if(!init) this.save_reset();
	},
	
	process_keywords:function(v,init) 
	{
		if(v.strip().length != 0) {
			list = v.split(" ");
			text = list.join(", ");
			pattern = "Keywords: %s";
			width = 240;
			display = this.limit_text(pattern,text,width);
		} else {
 			display = "Keywords";
		}
		$("keywords_search_button_text").innerHTML = display;
		if(!init) this.save_reset();
	},
	
	process_height:function(init)
	{
		min_obj = $("height_min");
		max_obj = $("height_max");
		
		min = min_obj.value;
		max = max_obj.value;
		
		min_t = min_obj[min_obj.selectedIndex].innerHTML;
		max_t = max_obj[max_obj.selectedIndex].innerHTML;
		
		if(min > max && max != "0")
		{
			max_obj.selectedIndex = min_obj.selectedIndex;
		}
		
		if(min != "0" && max == "0") {
			display = "At least " + min_t;
		} else if (min == "0" && max != "0") {
			display = "Under " + max_t;
		} else if (min != "0" && max != "0") {
			display = "Between " + min_t + " and " + max_t;
		} else {
			display = "Height";
		}
		
		$("heights_button_text").innerHTML = display;
		
		if(!init) this.save_reset();
	},
	
	process_language:function(v,init)
	{
		objs = $("language");
		for(iter=0;iter<objs.length;++iter) {
			if(objs[iter].value==v && objs[iter].value != "") {
				desig = objs[iter].value;
				lang = objs[iter].innerHTML;
			} else if(objs[iter].value == "") {
				desig = "";
				lang = "...";
			}
		}
		
		if(lang) 
		{
			$("languages_button_text").innerHTML = "Speaks " + lang;
			$("MATCH_FILTER_LANGUAGES").value = desig;
			$("match_lang").checked = false;
		} else {
			$("languages_button_text").innerHTML = "Speaks ...";
		}
		if(!init) this.save_reset();
	},
	
	process_match_lang:function(checked,init)
	{
		console.log(init);
		
		if(!checked) {
			this.process_language($("language")[$("language").selectedIndex].value,init);
		} else {
			$("MATCH_FILTER_LANGUAGES").value = "0";
			$("languages_button_text").innerHTML = "Speaks my language(s)";
		}
		if(!init) this.save_reset();
	},
	
	// A bunch of location specific stuff

	timed:false,
	begin_check:function()
	{
		if(this.timed) clearTimeout(this.timed);
		this.timed = setTimeout("Frm.try_location()",1200);
	},
	
	try_location:function()
	{
		check_empty();
	},
	
	location_swaps:function(state)
	{
		switch(state)
		{
			case "nearme":
				$('radius').disabled = false;
			break;
			case "text":
				if($("nearme")) $("nearme").checked = false;
				$("anywhere").checked = false;
				$('radius').disabled = false;
			break;
			case "anywhere":
				$('radius').disabled = true;
			break;
		}
		this.save_reset();
	}
}

document.observe("click",function() {
	if(Frm.last && Frm.locked != Frm.last)
	{
		if(Frm.last != "location_interface") {
			$(Frm.last).removeClassName("open");
			$(Frm.last + "_button").removeClassName("active");
			$(Frm.last + "_drop").style.display = 'none';
		} else {
			check_empty();
		}
	}
	if($("searches_drop") && $("searches_drop").style.display=="block" && !Frm.savelock) {
		$("searches_drop").style.display="none";
	}
});
 
AUTOCORE_SELF_CHECK.pop();
	
// File: /okcontent/js/Oryx/TextDialogue.js
AUTOCORE_SELF_CHECK.push("Oryx/TextDialogue.js");
/* ----------------------------------------------------------------

OkCupid TextDialogues

	- Maintains some specified textbox features

This is a highly specialized file for the okcupid text boxes.

---------------------------------------------------------------- */

var TextDialogue = Class.create({
    initialize:function(obj,parameters) {
        this.o = $(obj);
        
        if(Object.isString(obj))    this.n = obj;
        else                        this.n = obj.id;
        
        if(!this.n || !this.o) return;
                
        new Draggable(this.o);

		if(Prototype.Browser.IE == false)
			this.o.style.position = "fixed";
        else {
			this.o.style.position = "absolute";
			var pass = this;
			Event.observe(window,"scroll",function(){
				// No need for prototype here; native methods used for performance
				pass.o.style.marginTop = document.documentElement.scrollTop + "px";
			});
		}

        var text = $(this.n + "_text");
        var acts = $(this.n + "_acts");
        var togg = $(this.n + "_togg");
        
        var actsTextDefault = acts.innerHTML;
        var toggTextDefault = togg.innerHTML;
        
        var altered = false;
        
        text.observe("keydown",function() {
            if(!altered) return;
            acts.innerHTML = actsTextDefault;
            togg.innerHTML = toggTextDefault;
            altered = false;
        });
        
        acts.href = "#nogo";
        acts.observe("click",function() {parameters.action(), altered = true;});
    }
});

/*
Current implementation is a little verbose; will make the class more robust if
needed.

EXAMPLE:

var messageDialogue = {
    action:function() {
		var params = {whatever:something}
        new Ajax.Request("/url",{
            parameters:params,
            onSuccess:function() {
                Do something
            }
        });
    }
}
document.observe("dom:loaded",function(){new TextDialogue("message", messageDialogue);});

*/ 
AUTOCORE_SELF_CHECK.pop();
	
addNewCoresToCookie(["0", "1", "3", "4", "5", "6", "8", "18", "22", "23", "24", "25", "27", "28", "29", "33", "40"], "0b4e60a8"); 
