
	// Define the Merriam-Webster wordclick package.
	mw				= typeof(mw) != "undefined" ? mw : {};
	mw.wordclick	= {};

	// Enumeration of enabled cookie values.
	mw.wordclick.WORDCLICK_DISABLED = "no";
	mw.wordclick.WORDCLICK_ENABLED	= "yes";

	// Name of the property for storing the enabled configuration value.
	mw.wordclick.PROPERTY_ENABLED = "wordclick.enabled";

	// This method enables/disables the wordclick feature.
	mw.wordclick.enable = function (enabled)
		{	// Set the cookie value.
			this.setCookie(mw.wordclick.PROPERTY_ENABLED, enabled == true ? mw.wordclick.WORDCLICK_ENABLED : mw.wordclick.WORDCLICK_DISABLED, 100000);
		}; // function enable (enabled)

	// This method returns a cookie value.
	mw.wordclick.getCookie = function (name, def_value)
		{	// There are cookies defined.
			if ( document.cookie.length > 0 )
				{	// Add the prefix.
					name = "mw-wordclick-" + name;
				
					// Get the starting position of the cookie.
					var start = document.cookie.indexOf(name + "=");

					// Found the cookie.
					if ( start != -1 )
						{	// Get the starting position of the cookie value.
							start = start + name.length + 1; 

							// Get the end position of the cookie value.
							var end	= document.cookie.indexOf(";", start);
							end		= end != -1 ? end : document.cookie.length;

							// Return the cookie value.
							return unescape(document.cookie.substring(start, end));
						}; // if ( document.cookie.length > 0 )
				}; // if ( document.cookie.length > 0 )

			// Return the default value.
			return def_value;
		}; // function getCookie (name, def_value)

	// This method gets the scroll coordinates.
	mw.wordclick.getScrollCoords = function ()
		{	// Get the scroll coordinates.
			// Firefox 2, Opera 9, Chrome, Safari 3 (Win), etc.
			if ( typeof(window.pageXOffset) != "undefined" )
				{	sx = window.pageXOffset;
					sy = window.pageYOffset;
				} // if ( typeof(window.pageXOffset) != "undefined" )

			// IE6, IE8, etc.
			else if ( typeof(document.documentElement.scrollLeft) != "undefined" )
				{	sx = document.documentElement.scrollLeft;
					sy = document.documentElement.scrollTop;
				} // else if ( typeof(document.documentElement.scrollLeft) != "undefined" )

			// ????
			else if ( typeof(document.body.scrollLeft) != "undefined" )
				{	sx = document.body.scrollLeft;
					sy = document.body.scrollTop;
				}; // else if ( typeof(document.body.scrollLeft) != "undefined" )	

			return { x: sx, y: sy };
		}; // function getScrollCoords ()

	// This method returns the current text selection.
	mw.wordclick.getSelection = function () 
		{	// The selected value.
			var str = "";

			try
				{	// W3C compliant browsers.
					if ( document.getSelection ) 
						{	str = document.getSelection();
						} // if ( top.document.getSelection ) 

					// Internet Explorer.
					else if ( document.selection) 
						{	// Get the selection range.
							var range = document.selection.createRange();

							// Get the selection.
							str = range ? range.text : str;
						} // else if ( document.selection) 

					// Safari.
					else if ( window.getSelection )
						{	str = " " + window.getSelection();
						}; // else if ( window.getSelection )
				} // try

			catch ( exception )
				{	
				}; // catch ( exception )

			// Preprocess the selected value.
			if ( str ) 
				{	/**
					// Remove leading non-Word characters.
					var re = new RegExp ("^\\W*", "g");
					str = str.replace(re, '');

					// remove trailing non-Word characters.
					re = new RegExp ("\\W*$", "g");
					str = str.replace (re, "");

					// The above doesn't work on NS 4.05 to remove
					// trailing characters, so do it one by one.
					var lastChar	= str[str.length-1];
					re				= new RegExp ('\\W');

					while ( re.exec(lastChar) ) 
						{	str			= str.substr (0, str.length - 1);
							lastChar	= str[str.length-1];
						}; // while ( re.exec(lastChar) ) 
					**/

					str = str + "";
					str = str.replace(/^\s+|\s+$/, "").replace(/\s+/, " ");
				}; // if ( str ) 


			return str;
		}; // function getSelection ()

	// This method returns the wordclick URL for a given word.
	mw.wordclick.getWordClickURL = function (word)
		{	// Get the reference base URL.
			var base_url = "";
			
			// No base referenece URL has been defined; therefore, define one now.
			if ( typeof(this.ref_url) == "undefined" )
				{	base_url = this.ref_url = "http://mw4.merriam-webster.com/wdictionary/%word%";
				} // if ( typeof(this.ref_url) == "undefined" )

			// Use the defined base URL.
			else
				{	base_url = this.ref_url;
				}; // else

			return base_url.replace(/%word%/g, encodeURIComponent(word));
		}; // function getWordClickURL (word)

	// This method determines whether wordclick is enabled.
	mw.wordclick.isEnabled = function ()
		{	var enabled = this.getCookie(mw.wordclick.PROPERTY_ENABLED, mw.wordclick.WORDCLICK_ENABLED) == mw.wordclick.WORDCLICK_ENABLED;

			return enabled;
		}; // function isEnabled ()

	// This method handles all mouse double click events.
	mw.wordclick.onMouseDoubleClick = function (event)
		{	// The target that was clicked.
			var target = false;

			// A word click has been pressed; therefore, process the word click.
			if ( this.isEnabled() && (target = this.wordClickPressed(event)) != false  )
				{	// Get the word to look up.
					var word = this.getSelection();					

					// The wordclick div is configured to load in the same window.
					if ( target.className == "wordclick-no-win" )
						{	document.location = encodeURIComponent(word);
							return false;
						}; // if ( target.className == "wordclick-no-win" )

					// Get the element that triggered the event.
					target = window.event ? window.event.srcElement : event.target;

					// Set the target that was clicked.
					this.target	= target;
					this.click_x	= window.event ? window.event.clientX : event.clientX;
					this.click_y	= window.event ? window.event.clientY : event.clientY;

					// Get the user agent.
					var ua = navigator.userAgent.toLowerCase();

					// The user is using a version of Safari before 3.0.
					if ( ua.indexOf('safari/4') != -1 )
						{	this.click_x -= window.pageXOffset;
							this.click_y -= window.pageYOffset;
						}; // if ( ua.indexOf('safari/') != -1 )

					// Load the word click entry.
					this.showWordClick(word, this.click_x, this.click_y);

					return true;
				}; // if ( this.isEnabled() && (target = this.wordClickPressed(event)) != false  )

			return false;
		}; // mw.wordclick.onMouseDoubleClick = function (event)

	// This method handles all mouse up event.
	mw.wordclick.onMouseUp = function (event)
		{	return false;
		}; // mw.wordclick.onMouseUp = function (event)

	// This method sets a cookie value.
	mw.wordclick.setCookie = function (name, value, expire_days)
		{	// Compute the expiration date.
			var exdate = new Date();
			exdate.setDate(exdate.getDate() + expire_days);

			// Get the domain.
			var domain	= document.location.href;
			domain		= domain.replace(/http:\/\/([^$|\/]+)[^$]*/, "$1");
			domain		= domain.replace(/(.*?)\.([^\.]+\.[^$]+)/, ".$2");

			// Set the cookie value.
			document.cookie = 
				"mw-wordclick-" + name + "=" + escape(value) + 
				((expire_days == null) ? "" : ";expires=" + exdate.toGMTString()) 
				+ ";path=/;domain=" + domain;
		}; // function setCookie (c_name, value, expire_days)

	// This method sets the reference base URL.
	mw.wordclick.setReferenceBaseURL = function (url)
		{	this.ref_url = url;
		}; // function setReferenceBaseURL (url)

	// This method shows the wordclick window.
	mw.wordclick.showWordClick = function (word, click_x, click_y)
		{	// Attempt to get the wordclick window and its frame.
			var wordclick_win	= document.getElementById("wordclick-win");
			var wordclick_frame	= document.getElementById("wordclick-win-frame");

			// It doesn't exist yet.
			if ( !wordclick_win )
				{	// Create the containing window which contain both the wordclick from and its close button.
					var wordclick_win = document.createElement("div");

					// Initialize it.
					wordclick_win.id					= "wordclick-win";
					wordclick_win.style.background		= "none";
					wordclick_win.style.backgroundColor	= "transparent";
					wordclick_win.style.border			= "0";
					wordclick_win.style.height			= "415px";
					wordclick_win.style.left			= "0";
					wordclick_win.style.position		= "absolute";
					wordclick_win.style.top				= "0";
					wordclick_win.style.width			= "400px";
					wordclick_win.style.zIndex			= "999999";

					// Create the close button.
					var close_button	= document.createElement("input");

					// Initialize it.
					close_button.title				= "Close this window";
					close_button.type				= "button";
					close_button.value				= "";
					close_button.style.border		= "0";
					close_button.style.background	= "url(http://www.merriam-webster.com/skins/wordclick/images/close-button.gif) no-repeat left top";
					close_button.style.cursor		= "pointer";
					close_button.style.height		= "17px";
					close_button.style.position		= "absolute";
					close_button.style.right		= "15px";
					close_button.style.top			= "15px";
					close_button.style.width		= "17px";
					close_button.onclick			= function () { this.parentNode.parentNode.removeChild(this.parentNode); return false; };

					// Add it.
					wordclick_win.appendChild(close_button);
				
					// Create frame.
					wordclick_frame = document.createElement("iframe");

					// Initialize it.
					wordclick_frame.id							= "wordclick-win-frame";
					wordclick_frame.allowTransparency			= true;					
					wordclick_frame.frameBorder					= 0;
					wordclick_frame.style.border				= "0";
					wordclick_frame.style.height				= "392px";
					wordclick_frame.style.margin				= "0";
					wordclick_frame.style.padding				= "0";
					wordclick_frame.style.width					= "400px";

					// Add it to the window.
					wordclick_win.appendChild(wordclick_frame);

					// Create the arrow.
					var arrow	= document.createElement("div");

					// Initialize it.
					arrow.style.background	= "url(http://www.merriam-webster.com/skins/wordclick/images/arrow-background.gif) no-repeat center top";
					arrow.style.border		= "0";
					arrow.style.clear		= "left";
					arrow.style.display		= "block";
					arrow.style.margin		= "-3px 0 0 0";
					arrow.style.padding		= "0";
					arrow.style.height		= "25px";

					// Add it to the window.
					wordclick_win.appendChild(wordclick_win.arrow = arrow);

					// Add it to the document.
					document.getElementsByTagName("body").item(0).appendChild(wordclick_win);
				}; // if ( !wordclick_win )

			// Set its src.
			wordclick_frame.src = this.getWordClickURL(word);
			
			// The scroll coordinates.
			var scroll = this.getScrollCoords();

			// Set our new coordinates.
			var offset					= typeof(click_x) !== "undefined" ? Math.max(0, scroll.x + click_x - wordclick_win.clientWidth / 2 - 30) : scroll.x;
			var x						= Math.max(0, offset);
			var y						= Math.max(0, (typeof(click_y) !== "undefined" ? Math.max(0, scroll.y + click_y - wordclick_win.clientHeight) : scroll.y) - 15);
			wordclick_win.style.left	= x + "px";			
			wordclick_win.style.top		= y + "px";

			// Hide the arrow if needed.
			wordclick_win.arrow.style.display		= y > 0 ? "block" : "none";
			wordclick_win.arrow.style.background	= x > 0 ? "url(http://www.merriam-webster.com/skins/wordclick/images/arrow-background.gif) no-repeat center top" : "url(http://www.merriam-webster.com/skins/wordclick/images/arrow-reversed-background.gif) no-repeat " + (typeof(click_x) !== "undefined" ? scroll.x + click_x : scroll.x) + "px top";

			// Return the window.
			return wordclick_win;
		}; // function showWordClick (word, click_x, click_y)

	// This method determines whether a wordclick region has been clicked.
	mw.wordclick.wordClickPressed = function (event)
		{	// Get the element that triggered the event.
			var target = window.event ? window.event.srcElement : event.target;

			// Search up the DOM tree for an element with the required CSS class name.
			while ( target && target.parentNode )
				{	// We found a node that meets the criteria; therefore, return success here.
					if ( target.className == "wordclick" || target.className == "wordclick-no-win" )
						{	return target;
						}; // if ( target.className == "wordclick" || target.className == "wordclick-no-win" )

					// Get the next node.
					target = target.parentNode;
				}; // while ( target && target.parentNode )

			// We couldn't find an ancestor DOM node which had the word click requirements defined.
			return false;
		}; // function wordClickPressed (event)

	// Use the addEventListener event model.
	if ( document.addEventListener )
		{	document.addEventListener("dblclick", function (event) { mw.wordclick.onMouseDoubleClick(event); }, false);
			document.addEventListener("mouseup", function (event) { mw.wordclick.onMouseUp(event); }, false);								
		} // if ( document.addEventListener )

	// Use the attachEvent event model.
	else if ( document.attachEvent )
		{	document.attachEvent("ondblclick", function (event) { mw.wordclick.onMouseDoubleClick(event); });
			document.attachEvent("onmouseup", function (event) { mw.wordclick.onMouseUp(event); });
		}; // else if ( document.attachEvent )