From: <Mit Microsoft Internet Explorer 7 gespeichert>
Subject: The W h i p p e t Archives
Date: Thu, 14 Aug 2008 15:52:42 +0200
MIME-Version: 1.0
Content-Type: multipart/related;
	type="text/html";
	boundary="----=_NextPart_000_003B_01C8FE25.C917E2D0"
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3350

This is a multi-part message in MIME format.

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/details.php?id=52159

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>The W h i p p e t Archives</TITLE>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META=20
content=3D"Database containing whippet pedigrees including thousands of =
photos. A place for the community of whippet lovers worldwide!"=20
name=3Ddescription>
<META content=3D"whippet, pedigree, whippet pedigrees" name=3Dkeywords>
<META content=3D"Karin Schellner" name=3Dauthor>
<META content=3Den name=3Dlanguage><LINK=20
href=3D"http://thewhippetarchives.net/styles/basic.css" type=3Dtext/css=20
rel=3Dstylesheet><!-- yui -->
<SCRIPT language=3DJavaScript>=0A=
<!--=0A=
=0A=
function SymError()=0A=
{=0A=
  return true;=0A=
}=0A=
=0A=
window.onerror =3D SymError;=0A=
=0A=
var SymRealWinOpen =3D window.open;=0A=
=0A=
function SymWinOpen(url, name, attributes)=0A=
{=0A=
  return (new Object());=0A=
}=0A=
=0A=
window.open =3D SymWinOpen;=0A=
=0A=
//-->=0A=
</SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/yahoo.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/dom.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/event.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/animation.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/dragdrop.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/container.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/autocomplete.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT src=3D"http://thewhippetarchives.net/js/yui/connection.js"=20
type=3Dtext/javascript></SCRIPT>
<LINK href=3D"http://thewhippetarchives.net/styles/yui/container.css"=20
type=3Dtext/css rel=3Dstylesheet><LINK=20
href=3D"http://thewhippetarchives.net/favicon.ico" rel=3D"shortcut =
icon">
<SCRIPT src=3D"http://thewhippetarchives.net/js/twa.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT type=3Dtext/javascript>=0A=
//SuckerTree Horizontal Menu (Sept 14th, 06)=0A=
//By Dynamic Drive: http://www.dynamicdrive.com/style/=0A=
var menuids=3D["treemenu1"] //Enter id(s) of SuckerTree UL menus, =
separated by commas=0A=
function buildsubmenus_horizontal(){=0A=
for (var i=3D0; i<menuids.length; i++){=0A=
  var =
ultags=3Ddocument.getElementById(menuids[i]).getElementsByTagName("ul")=0A=
    for (var t=3D0; t<ultags.length; t++){=0A=
		if (ultags[t].parentNode.parentNode.id=3D=3Dmenuids[i]){ //if this is =
a first level submenu=0A=
			ultags[t].style.top=3Dultags[t].parentNode.offsetHeight+"px" =
//dynamically position first level submenus to be height of main menu =
item=0A=
			=
ultags[t].parentNode.getElementsByTagName("a")[0].className=3D"mainfolder=
icon"=0A=
		}=0A=
		else{ //else if this is a sub level menu (ul)=0A=
		  =
ultags[t].style.left=3Dultags[t-1].getElementsByTagName("a")[0].offsetWid=
th+"px" //position menu to the right of menu item that activated it=0A=
    	=
ultags[t].parentNode.getElementsByTagName("a")[0].className=3D"subfolderi=
con"=0A=
		}=0A=
    ultags[t].parentNode.onmouseover=3Dfunction(){=0A=
    this.getElementsByTagName("ul")[0].style.visibility=3D"visible"=0A=
    }=0A=
    ultags[t].parentNode.onmouseout=3Dfunction(){=0A=
    this.getElementsByTagName("ul")[0].style.visibility=3D"hidden"=0A=
    }=0A=
    }=0A=
  }=0A=
}=0A=
if (window.addEventListener)=0A=
window.addEventListener("load", buildsubmenus_horizontal, false)=0A=
else if (window.attachEvent)=0A=
window.attachEvent("onload", buildsubmenus_horizontal)=0A=
</SCRIPT>

<META content=3D"MSHTML 6.00.6000.16705" name=3DGENERATOR></HEAD>
<BODY><!--div class=3D"container"--><!-- header -->
<TABLE=20
style=3D"BACKGROUND-IMAGE: =
url(http://thewhippetarchives.net/images/header_background_new.gif); =
BACKGROUND-REPEAT: repeat"=20
width=3D"100%">
  <TBODY>
  <TR>
    <TD><IMG alt=3D"The Whippet Archives"=20
      =
src=3D"http://thewhippetarchives.net/images/title_new_sponsored1.gif"=20
      useMap=3D#Map border=3D0> </TD>
    <TD align=3Dright>
      <TABLE width=3D"100%" border=3D0>
        <TBODY>
        <TR>
          <TD><SPAN class=3Dnavitem><A class=3DbuttonLink=20
            =
href=3D"http://thewhippetarchives.net/php_users/htdocs/logoff.php">[=20
            Logoff ]</A></SPAN></TD></TR>
        <TR>
          <TD><SPAN class=3Dnavitem><A class=3DbuttonLink=20
            =
href=3D"http://thewhippetarchives.net/php_users/htdocs/users_edit.php?ret=
urnto=3D%2Fdetails.php%3Fid%3D52159">[=20
            My Profile =
]</A></SPAN></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<DIV class=3Dnavarea>
<DIV class=3Dsuckertreemenu>
<TABLE width=3D"99%">
  <TBODY>
  <TR>
    <TD>
      <UL id=3Dtreemenu1>
        <LI><A style=3D"BORDER-LEFT: #aaaaaa 1px solid"=20
        href=3D"http://thewhippetarchives.net/newest.php">Newest =
Entries</A> </LI>
        <LI><A =
href=3D"http://thewhippetarchives.net/details.php?id=3D52159#">Dogs=20
        <IMG =
src=3D"http://thewhippetarchives.net/images/sort_desc.gif"></A>=20
        <UL>
          <LI><A =
href=3D"http://thewhippetarchives.net/search.php">Search Dogs</A>=20

          <LI><A =
href=3D"http://thewhippetarchives.net/browseDogs.php">Browse=20
          Dogs</A>=20
          <LI><A href=3D"http://thewhippetarchives.net/addDog.php">Add =
Dog</A>=20
          </LI></UL></LI>
        <LI><A=20
        =
href=3D"http://thewhippetarchives.net/details.php?id=3D52159#">Persons =
<IMG=20
        src=3D"http://thewhippetarchives.net/images/sort_desc.gif"></A>=20
        <UL>
          <LI><A =
href=3D"http://thewhippetarchives.net/searchPerson.php">Search=20
          Persons</A>=20
          <LI><A =
href=3D"http://thewhippetarchives.net/browsePersons.php">Browse=20
          Persons</A>=20
          <LI><A=20
          =
onclick=3D'setSearchTextOnPersonPanel("normalMode");panel.show();'=20
          =
href=3D"http://thewhippetarchives.net/details.php?id=3D52159#">Add=20
          Person</A> </LI></UL></A></LI>
        <LI><A=20
        =
href=3D"http://thewhippetarchives.net/testmating.php">Testmating</A> =
</LI>
        <LI><A =
href=3D"http://thewhippetarchives.net/standard.php">Standard</A>=20
        </LI>
        <LI><A=20
        =
href=3D"http://thewhippetarchives.net/php_users/htdocs/users.php">Members=
</A>=20
        </LI>
        <LI><A href=3D"http://thewhippetarchives.net/help.php">Help</A> =
</LI>
        <LI><A=20
        =
href=3D"http://thewhippetarchives.net/statistics.php">Statistics</A>=20
      </LI></UL></TD>
    <TD style=3D"WHITE-SPACE: nowrap" align=3Dright>
      <FORM action=3Dhttp://thewhippetarchives.net/results.php =
method=3Dget><INPUT=20
      style=3D"WIDTH: 150px" name=3Dkeyword> <INPUT class=3Dbutton =
onclick=3D"if (keyword.value.length < 3) { alert('Your search term has =
to contain at least 3 letters! Please retry.'); return false;}" =
type=3Dsubmit value=3D"Search Dog">=20
      <INPUT type=3Dhidden value=3Dsimple name=3Dmode> =
</FORM></TD></TR></TBODY></TABLE><BR=20
style=3D"CLEAR: left"></DIV></DIV>
<SCRIPT language=3Djavascript type=3D"">=0A=
=0A=
	//panel =3D createPanel(document.getElementsByTagName('body')[0]);=0A=
=0A=
</SCRIPT>
<MAP name=3DMap><AREA shape=3DRECT alt=3D"The Whippet Archives" =
coords=3D1,1,584,98=20
  href=3D"http://thewhippetarchives.net/index.php"><AREA shape=3DRECT =
target=3D_blank=20
  alt=3D"Whippet Club Deutschland" coords=3D584,1,710,89=20
  href=3D"http://www.wcd-online.de/"></MAP>
<SCRIPT language=3Djavascript>
	var currentIndx=3D0;
	var MyImages =3D new Array();=09
	var MyCopyright =3D new Array();
	var MyImgWidth =3D new Array();
	var photoPrefix =3D "Copyright: ";
	var MyPhotonotes =3D new Array();
	var photonotesPrefix =3D "Notes: ";
	var MyPhotoPostedBy =3D new Array();
	var photoPostedByPrefix =3D "Posted by: ";
	//var predefinedMaxWidth =3D 250;

	function next(){=09
		document.theImage.removeAttribute("width");		=09
		if (currentIndx<MyImages.length-1){
			currentIndx=3DcurrentIndx+1;
			document.theImage.src=3DMyImages[currentIndx];
			document.theImage.width=3DMyImgWidth[currentIndx];
			if (MyCopyright[currentIndx] !=3D "")=20
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];
			else=20
				document.getElementById("theCopyright").innerHTML=3D"";
			if (MyPhotoPostedBy[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];
			else=20
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";			=09
			if (MyPhotonotes[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];
			else=20
				document.getElementById("thePhotonotes").innerHTML=3D"";			=09
		} else {					=09
			currentIndx=3D0					=09
			document.theImage.src=3DMyImages[currentIndx];
			document.theImage.width=3DMyImgWidth[currentIndx];
			if (MyCopyright[currentIndx] !=3D "")=20
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];=09
			else=20
				document.getElementById("theCopyright").innerHTML=3D"";
			if (MyPhotoPostedBy[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];
			else=20
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";			=09
			if (MyPhotonotes[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];
			else=20
				document.getElementById("thePhotonotes").innerHTML=3D"";			=09
		}
	}
=09
	function previous(){
		document.theImage.removeAttribute("width");
		if (currentIndx>0) {
			currentIndx=3DcurrentIndx-1;
			document.theImage.src=3DMyImages[currentIndx];
			document.theImage.width=3DMyImgWidth[currentIndx];
			if (MyCopyright[currentIndx] !=3D "") =09
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];=09
			else=20
				document.getElementById("theCopyright").innerHTML=3D"";
			if (MyPhotoPostedBy[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];
			else=20
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";			=09
			if (MyPhotonotes[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];
			else=20
				document.getElementById("thePhotonotes").innerHTML=3D"";			=09
		} else {
			currentIndx=3DMyImages.length-1;
			document.theImage.src=3DMyImages[currentIndx];
			document.theImage.width=3DMyImgWidth[currentIndx];
			if (MyCopyright[currentIndx] !=3D "")=20
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];=09
			else=20
				document.getElementById("theCopyright").innerHTML=3D"";
			if (MyPhotoPostedBy[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];
			else=20
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";			=09
			if (MyPhotonotes[currentIndx] !=3D "")=20
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];
			else=20
				document.getElementById("thePhotonotes").innerHTML=3D"";			=09
		}
	}
=09
/*
	function getImageWidth(myImgObj) {
		if (myImgObj !=3D null)
			return myImgObj.width;
		else
			return -1;
	}
=09
	function setToProperWidth(imgEl) {
		var imgWidth =3D this.getImageWidth(imgEl);
		if ((imgWidth !=3D null) && (imgWidth !=3D -1)) {
			if (imgWidth >=3D predefinedMaxWidth)=20
				imgEl.width =3D predefinedMaxWidth;
		} else {
			imgEl.width =3D predefinedMaxWidth;
		}
	}
*/=09
=09
</SCRIPT>

<DIV class=3Dmain>
<DIV class=3Dcontent>
<TABLE>
  <TBODY>
  <TR>
    <TD>
      <DIV=20
      style=3D"BORDER-RIGHT: #aaa 1px solid; PADDING-RIGHT: 10px; =
BORDER-TOP: #aaa 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; =
MARGIN: 10px; BORDER-LEFT: #aaa 1px solid; PADDING-TOP: 10px; =
BORDER-BOTTOM: #aaa 1px solid">
      <DIV align=3Dcenter>
      <H3>Airescot May Marigold</H3>
      <SCRIPT language=3Djavascript>
							MyImages[0] =3D "pics/medium/1630/med_48974c17ee26f.jpg";
							MyCopyright[0] =3D "Nenne Runsten";
							MyPhotoPostedBy[0] =3D "Bianca Weisl";
							MyPhotonotes[0] =3D "8 weeks";
														MyImgWidth[0] =3D "250";
						</SCRIPT>

      <SCRIPT language=3Djavascript>
							MyImages[1] =3D "pics/medium/1630/med_48974c3f1606f.jpg";
							MyCopyright[1] =3D "Bianca Weisl";
							MyPhotoPostedBy[1] =3D "Bianca Weisl";
							MyPhotonotes[1] =3D "9 weeks";
														MyImgWidth[1] =3D "250";
						</SCRIPT>

      <TABLE border=3D0>
        <TBODY>
        <TR>
          <TD vAlign=3Dbottom><IMG onclick=3Dprevious() height=3D12=20
            src=3D"http://thewhippetarchives.net/images/previous.gif" =
width=3D12></TD>
          <TD align=3Dmiddle><IMG alt=3D"picture of dog"=20
            =
src=3D"http://thewhippetarchives.net/pics/medium/1630/med_48974c17ee26f.j=
pg"=20
            width=3D250 name=3DtheImage> <BR>
            <DIV style=3D"WIDTH: 250px"><LABEL><SPAN =
id=3DtheCopyright>Copyright:=20
            Nenne Runsten </SPAN></LABEL></DIV>
            <DIV style=3D"WIDTH: 250px"><LABEL><SPAN =
id=3DthePhotoPostedBy>Posted=20
            by: Bianca Weisl </SPAN></LABEL></DIV>
            <DIV style=3D"WIDTH: 250px"><LABEL><SPAN =
id=3DthePhotonotes>Notes: 8=20
            weeks </SPAN></LABEL></DIV></TD>
          <TD vAlign=3Dbottom><IMG onclick=3Dnext() height=3D12=20
            src=3D"http://thewhippetarchives.net/images/next.gif"=20
        width=3D12></TD></TR></TBODY></TABLE></DIV></DIV>
      <TABLE>
        <TBODY></TBODY></TABLE></TD>
    <TD>
      <TABLE width=3D400 border=3D0>
        <TBODY>
        <TR>
          <TD width=3D160><STRONG>Registered Name: </STRONG></TD>
          <TD>Airescot May Marigold</TD></TR>
        <TR>
          <TD><STRONG>Breeder: </STRONG></TD>
          <TD><A=20
            =
href=3D"http://thewhippetarchives.net/managePerson.php?personId=3D347">Ne=
nne=20
            Runsten</A><BR></TD></TR>
        <TR>
          <TD><STRONG>Owner: </STRONG></TD>
          <TD><A=20
            =
href=3D"http://thewhippetarchives.net/managePerson.php?personId=3D9349">B=
ianca=20
            Weisl</A><BR></TD></TR>
        <TR>
          <TD><STRONG>Kennel: </STRONG></TD>
          <TD>Airescot</TD></TR>
        <TR>
          <TD><STRONG>Sire: </STRONG></TD>
          <TD><A =
href=3D"http://thewhippetarchives.net/details.php?id=3D1660">Wolf=20
            Tone Viking</A></TD></TR>
        <TR>
          <TD><STRONG>Dam: </STRONG></TD>
          <TD><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D5546">Collooney=20
            Winner Takes It All</A></TD></TR>
        <TR>
          <TD><STRONG>Call Name: </STRONG></TD>
          <TD>Wendy</TD></TR>
        <TR>
          <TD><STRONG>Sex: </STRONG></TD>
          <TD>female</TD></TR>
        <TR>
          <TD><STRONG>Date of Birth: </STRONG></TD>
          <TD>29 MAY 2008 </TD></TR>
        <TR>
          <TD><STRONG>Date of Death: </STRONG></TD>
          <TD></TD></TR>
        <TR>
          <TD><STRONG>Land of Birth: </STRONG></TD>
          <TD>Sweden</TD></TR>
        <TR>
          <TD><STRONG>Land of Standing: </STRONG></TD>
          <TD>Austria</TD></TR>
        <TR>
          <TD><STRONG>Size: </STRONG></TD>
          <TD></TD></TR>
        <TR>
          <TD><STRONG>Weight: </STRONG></TD>
          <TD></TD></TR>
        <TR>
          <TD><STRONG>Colour: </STRONG></TD>
          <TD>Blue Fawn and White</TD></TR>
        <TR>
          <TD><STRONG>Distinguishing Features: </STRONG></TD>
          <TD></TD></TR>
        <TR>
          <TD><STRONG>Titles: </STRONG></TD>
          <TD></TD></TR>
        <TR>
          <TD vAlign=3Dtop><STRONG>Known Offspring: </STRONG></TD>
          <TD>
            <DIV style=3D"OVERFLOW: auto; HEIGHT: 55px"></DIV></TD></TR>
        <TR>
          <TD align=3Dright colSpan=3D2>
            <FORM action=3Dmanage.php method=3Dget><INPUT type=3Dhidden =
value=3D52159=20
            name=3Did> <INPUT class=3Dbutton type=3Dsubmit =
value=3DUpdate name=3Daction> <INPUT class=3Dbutton =
onclick=3D"javascript: =
deletionForbiddenDialog('admin@thewhippetarchives.net','dogs');" =
type=3Dbutton value=3DDelete name=3Daction>=20
            </FORM></TD></TR></TBODY></TABLE></TD>
    <TD vAlign=3Dtop>
      <TABLE cellPadding=3D10>
        <TBODY>
        <TR>
          <TD>
            <DIV></DIV></TD></TR>
        <TR>
          <TD><STRONG>Siblings: </STRONG><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D52158">Airescot=20
            May Madam</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D52160">Airescot=20
            May Masquerade</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D52161">Airescot=20
            May Mazarine</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D52163">Airescot=20
            May Melody</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D52162">Airescot=20
            May Memory</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D52164">Airescot=20
            May Morning</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D52157">Airescot=20
            Odd Man Out In=20
May</A><BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></DIV><!--=
 pedigree -->
<DIV style=3D"PADDING-LEFT: 25px; FLOAT: left">
<TABLE>
  <TBODY>
  <TR>
    <TD>
      <FORM action=3D""><LABEL>Generations in pedigree </LABEL><INPUT =
type=3Dhidden=20
      value=3D52159 name=3Did> <SELECT onchange=3Dsubmit(); name=3Dgens> =
<OPTION=20
        value=3D2>2</OPTION> <OPTION value=3D3>3</OPTION> <OPTION =
value=3D4=20
        selected>4</OPTION> <OPTION value=3D5>5</OPTION> <OPTION=20
        value=3D6>6</OPTION> <OPTION value=3D7>7</OPTION> <OPTION =
value=3D8>8</OPTION>=20
        <OPTION value=3D9>9</OPTION></SELECT> </FORM></TD>
    <TD style=3D"PADDING-LEFT: 20px"><LABEL>Printable version of =
pedigree=20
      <BR>(<A=20
      =
href=3D"http://thewhippetarchives.net/printable_pedigree.php?id=3D52159&a=
mp;gens=3D4&amp;images=3Dyes"=20
      target=3D_blank> with</A> / <A=20
      =
href=3D"http://thewhippetarchives.net/printable_pedigree.php?id=3D52159&a=
mp;gens=3D4&amp;images=3Dno"=20
      target=3D_blank>without images</A>) </LABEL></TD>
    <TD style=3D"PADDING-LEFT: 20px"><LABEL><A=20
      =
href=3D"http://thewhippetarchives.net/pedigree_htmlcode.php?id=3D52159&am=
p;gens=3D4">HTML=20
      code</A> for this pedigree<BR>(e.g. to embed on your private=20
      website)</LABEL> </TD></TR></TBODY></TABLE></DIV>
<DIV style=3D"CLEAR: both">
<TABLE id=3Dpedigree width=3D"97%" align=3Dcenter border=3D0>
  <TBODY>
  <TR>
    <TH colSpan=3D4>Pedigree</TH></TR>
  <TR>
    <TD rowSpan=3D8><A=20
href=3D"http://thewhippetarchives.net/details.php?id=3D52159">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/1630/th_48974c17ed2c4.jp=
g"=20
      width=3D100></P>Airescot May Marigold</A><LABEL><BR>Blue Fawn and =
White=20
      <BR>Sweden<BR>2008</LABEL></TD>
    <TD rowSpan=3D4><LABEL><FONT color=3Dred>Sw Nor Fin =
Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1660">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_46b4cdf3b7234.jpg"=20
      width=3D100></P>Wolf Tone Viking</A><LABEL><BR>Fawn Brindle=20
      <BR>Sweden<BR>1997</LABEL></TD>
    <TD rowSpan=3D2><LABEL><FONT color=3Dred>Int Fin Nor Sw Est Ch=20
      FinW-98</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1663">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/76/th_47780fd22084d.jpg"=
=20
      width=3D100></P>Bohem Flight Time</A><LABEL><BR>Black Brindle and =
White=20
      <BR>USA<BR>1992</LABEL></TD>
    <TD><LABEL><FONT color=3Dred>MSBIS, Am Ch, Am F.Ch. JC,=20
      ROMX</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D224">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4616caaeac93e.jpg"=20
      width=3D100></P>Chelsea Drakkar of Oxford</A><LABEL><BR>White and =
Red=20
      <BR>USA<BR>1988</LABEL></TD></TR>
  <TR>
    <TD><LABEL><FONT color=3Dred>Am Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1667">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4687b474c9c0c.jpg"=20
      width=3D100></P>Bohem Delacreme=20
    Demoiselle</A><LABEL><BR>USA<BR>1986</LABEL></TD></TR>
  <TR>
    <TD rowSpan=3D2><A =
href=3D"http://thewhippetarchives.net/details.php?id=3D857">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4694e6de34dc3.jpg"=20
      width=3D100></P>Signum Soprani</A><LABEL><BR>Black Brindle=20
      <BR>Sweden<BR>1993</LABEL></TD>
    <TD><LABEL><FONT color=3Dred>S Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1568">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/anonymous/th_47567cbc93c=
da.jpg"=20
      width=3D100></P>Airescot Fandango</A><LABEL><BR>Black Brindle=20
      <BR>Norway<BR>1992</LABEL></TD></TR>
  <TR>
    <TD><LABEL><FONT color=3Dred>Sw Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1570">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/443/th_477bbfcd18433.JPG=
"=20
      width=3D100></P>Merci Isle Whisper To A Purr</A><LABEL><BR>Brindle =
and White=20
      Ticked <BR>USA<BR>1989</LABEL></TD></TR>
  <TR>
    <TD rowSpan=3D4><LABEL><FONT color=3Dred>Swedish&amp; Danish=20
      Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D5546">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4672b037e8d3b.jpg"=20
      width=3D100></P>Collooney Winner Takes It All</A><LABEL><BR>Fawn =
Brindle and=20
      White <BR>Ireland<BR>2003</LABEL></TD>
    <TD rowSpan=3D2><LABEL><FONT color=3Dred>Can, Am, UK &amp; Nord=20
      Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1546">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/anonymous/th_Rascal.jpg"=
=20
      width=3D100></P>Airescot Ruby Rascal</A><LABEL><BR>Fawn Brindle =
and White=20
      <BR>Sweden<BR>2000</LABEL></TD>
    <TD><LABEL><FONT color=3Dred>AUST, FIN, DK, N, S =
Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1531">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4651abc4b93de.jpg"=20
      width=3D100></P>Statuesque Extortion (i.i.d.)</A><LABEL><BR>Fawn =
Brindle and=20
      White <BR>Australia<BR>1996</LABEL></TD></TR>
  <TR>
    <TD><LABEL><FONT color=3Dred>Swed,Dan,Fin, &amp; Int =
Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1551">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/anonymous/th_Redee.jpg" =

      width=3D100></P>Airescot Red Redee</A><LABEL><BR>Red Fawn=20
      <BR>Sweden<BR>1996</LABEL></TD></TR>
  <TR>
    <TD rowSpan=3D2><LABEL><FONT color=3Dred>Ch &amp; Ir =
Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D5547">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4683dfaea1a9c.jpg"=20
      width=3D100></P>Collooney Silver Silas</A><LABEL><BR>Fawn=20
      <BR>Ireland<BR>1999</LABEL></TD>
    <TD><LABEL><FONT color=3Dred>UK Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D822">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4686dccbd0fbc.jpg"=20
      width=3D100></P>Rum Punch of Falconcrag</A><LABEL><BR>Fawn =
<BR>United=20
      Kingdom<BR>1996</LABEL></TD></TR>
  <TR>
    <TD><A =
href=3D"http://thewhippetarchives.net/details.php?id=3D13245">Collooney=20
      Silver Lace</A><LABEL><BR>Ireland<BR>1995</LABEL></TD></TR>
  <TR></TD></TR></TBODY></TABLE></DIV></DIV>
<DIV></DIV>
<DIV class=3Dfooter>
<P>Please keep in mind that this website is not affiliated with any =
organisation=20
and it is not an official registration database but a place for the =
community of=20
whippet lovers worldwide. Therefore no guarantees as to the correctness =
of the=20
information can be given.</P>
<P align=3Dcenter>Copyright =A9 2006-2008 Karin Schellner. All Rights =
Reserved. <A=20
style=3D"COLOR: #e0e0e0" =
href=3D"http://thewhippetarchives.net/aboutus.php">About us=20
/ Disclaimers.</A> </P></DIV>
<SCRIPT language=3DJavaScript =
src=3D"http://thewhippetarchives.net/js/wz_tooltip.js"=20
type=3Dtext/javascript></SCRIPT>

<SCRIPT language=3Djavascript>
	panel =3D createPanel(document.getElementsByTagName('body')[0]);
</SCRIPT>

<SCRIPT language=3DJavaScript>=0A=
<!--=0A=
var SymRealOnLoad;=0A=
var SymRealOnUnload;=0A=
=0A=
function SymOnUnload()=0A=
{=0A=
  window.open =3D SymWinOpen;=0A=
  if(SymRealOnUnload !=3D null)=0A=
     SymRealOnUnload();=0A=
}=0A=
=0A=
function SymOnLoad()=0A=
{=0A=
  if(SymRealOnLoad !=3D null)=0A=
     SymRealOnLoad();=0A=
  window.open =3D SymRealWinOpen;=0A=
  SymRealOnUnload =3D window.onunload;=0A=
  window.onunload =3D SymOnUnload;=0A=
}=0A=
=0A=
SymRealOnLoad =3D window.onload;=0A=
window.onload =3D SymOnLoad;=0A=
=0A=
//-->=0A=
</SCRIPT>
</BODY></HTML>

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/images/title_new_sponsored1.gif

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
0AZ90Aid0Aq90Azd0ACdAAA7

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/images/sort_desc.gif

R0lGODlhDAAMAJEAAJqamsyZZv///wAAACH5BAEAAAIALAAAAAAMAAwAAAIYlI+pywIPowGh2goO
vSGjjS2bJ5LNiTIFADs=

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/images/previous.gif

R0lGODlhDAAMAJEAAJqamsyZZv///wAAACH5BAEAAAIALAAAAAAMAAwAAAIalI+JAHoQmoNxhivX
xYryvmUJJY6VYzCoUwAAOw==

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/medium/1630/med_48974c17ee26f.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAvAD6
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
+f8A7G08Vqto8k13IxVoxknOTjFdJokFtYXVgqaVc3FzIvmASR7Q5HbJ616/4Hl0HwXi8v7SFtUg
m/dwxjc8i+XxsYjBGSwPuorg/HVzq11rh1WS0a0tZFVfmlDeUFOMDHRevA71xySlGxPLcl1CVf7N
ubaQtb3Ei4UN1J6tg/3QeOtcOba71Ax6dZzeeWjZsyxheQPmUH1roIJ9N1TQsalc3MWqW27DuSwP
O5cADgYLEjviovCmvWljJcia0kuDHOzxkLtkbcrD09cVgqPJrEORHL6pb6nYeVp8sv7rgmGM4U9u
SOp60200t2urhIlb91y8Y5Zeecev1rU1LWr9bwW+oRxrDK6yuUjAfABGAfxP412llYaWlobi3F5G
1zDsCCQIVw3BJxk8Y7j+ldEIyktBK55ybaeUsYHjeCdmRFLD5B7+lbvhHSry91y202K3jvSh3FWl
2oMcn5uw966e20fQtpSS0JBO4gyNgn35rf0/S9LN9HcwLJDMFCB0kPTAA4PHQCrlDszTkZzOrafH
beIpjBaxW0SJGRGJPMWNhnnJ52nFOtIZrK61Ca+hiReVk8tch/QfTkdPSug8T+E76OQ6lZ3801o6
qksTgMVQHOB7cmsrVdMMqxtFJFLCnzygLhEHXBA71zVLJ+8S13KOm6HDqkcdpbXAmeeVQOOVJByT
7Y/SqOraYIkeG1dPMRQBEASrEk8A9+B+ZrTglmsNVEsFssedrReW5KoMdDhs9CevvXS/YtNj8trm
VkCYUTjdubJJb5fQcDg44pXQ0lI4m80e6ttCjuruEt58ZhRmJ+UgjIx6Dnmqg0q2uYHY3KRW8bAu
8Y+8COB/jXpXiOOzjs9NtZIjmNt5uN2FfI4UDPGeKzNU0fTwLtbZGt4iN/2lhnLYYlQOAeAPekpx
6DdPocLpmlLPdRBLcR2zZKvknd6/l/Wti0mtYLuYR+dcJHy4I6KM4HqDVhNOkvpoIUuDaQgb4167
lLEFm71FNZ6qb9obCVH8ks5ZRt+UYzk4680n7xDiRXE0sluWto5PsqEyOzADA7KD/PiuL1+3W5dL
ldrs5KyKi7SrA46dh716PBfTLMIJkJEu1N5Axg/xY6en5Vzl/aTabqCeUEdzK8kpUbS4zkLkc9qm
nLldyVE5Q2UUcu2786KJozIqZydw6A4rc0myfUJA9oFZlIjIULxx+GcVlzXckt4JJonaV2KopbK8
HkH1wDXb2dhpo0+aVzJBFasrOYjtL9xx3HTmtpN9R2LXhHRrXS9Sik1a4ZoWZEuEA2KAD/e6/Xb6
d69C1XW7fQXbXIdWsr60gH2VIZn3SuhYtG+0AbiB346V5Vb3E09jLdG0ZrSaRWjcc7nzj5wTx9K3
W02G8itob/T4lvluYgzQlY49jYGdpJ55ycEDp0ow05XakJdj2H4pSaD44+Htmmo65a2N3KRdj7Pm
U8Icpjgj8fTvXybarFeaRMHnAZZkWCLucfe+gwfTmvry51LRdceZL3SDGbZLoQtMQo2CMDcADgDn
r6cjvXyLHpa22oHZIssJmOHXI2AHvx9K6ZyTRasaN1YJcQ2CxSxLcQyPEuQAM53APk/rVTxBcB7i
3vIlgUhypSEYBOeSABgVQ8QzyXN2BHxJKSGRM44J6DrTrO1udSItkV55VO5WCktkDkGsoxcUm2O1
noaXiGMyvY3lxMoS+TCpkjy8YBOPQ4/ziqB0SRrNJbS5Ro5isZQHJz3PtVubXp44I4VVHtwCEZ0B
ZOMEA9QPapNJvoJ5rWCJCZXbJO3qcY/liqd1sapxUbPcwpppJbG1tjHGoA2B++NxP9a73RNEeWyh
ittSSe0BO5VYjnjp+YPSuE04G5vLdY4DKYBuZEGS3Peu/wDC1/b6foNsl6oUNNI7REYB5ABz7flx
WOJbUdDCY7VLe0tpE0x0SOKSQKCSSj5/D1rCm0ySOaRFFyArEAByMfpVzW9Rt7+yuzbCN7q3lEqs
p3cA84H0qE+I9dclhbREHnODz+tZxU0vdJizvUOm3N49zOGvLeBSm1JMFS3fPX0pdCsm1FmiWaR7
ZZlhaAsq7/nAySevQ5wD1rmpNRt49YEaI7JKqrIe7n5eR69K1Zddmt5LaCWRnRXESl1AODyeR9f1
px903tqbdl4ft7bUtRuJrMG0Mu2JVcEkDhmx6DNYGm6Pa2N9dQylVgkd1GMM6gEbTn3xXnmv6zq0
epSaeLueO0Vt0aK2AQcHJ9a6rw9qEFrDGLmVpCw7jpXZToJq7e45S8jP1CNLG/Hmk3UyHeox0bnv
9D0rN0HXJLnxAxviVRjtU84T2rqp4lvbz7Qi7YwMAntVODSWtp2lCI8bHO4VvZQVkRFHSCFTIPLY
MCM8Gta1gKMm4nrWfpcKm23xOoK9q1YJ1mtZ492yTYdrj+E9qxbsbpXR1+jX0MkbWkzruK/db+IV
534ksLvSbgQxAJp0zFQQSeSQeR6dqrXlg2k2h1CW6liRH+V8ZLE967LQ7uHxJoP2W8WSN5kPlSkY
3EdwexFZzp86JnC6uZs0UUNlbNIyNGh3vNt5A28jnpk5rLvNUlvLpotpEDoIztz8hxwPbNVtVmuL
FbfTZRK1zvHmp/CSBgNk9+TVeySOzfyi4e4BJAPdj2z7ZNeby23M3oyzNJbGCyLyyySJC52NyN2Q
uQPatO1vidEsFIkZp3bc5H3Tjrg/WuMv9Vc61NGseMo4JXpnOePyH5VPaX1xFZW0bvtaMurb2IG7
GBn+daSpu2hb8jYuy2n3AnRGy8fQsW8wDd/iDiklhV4EuI5PJ+0PudU42tgZP41navdXV5HaxhPm
iiaVmBIyWH4cf/Xq3qLQDR7aWZi7hlb5XwcBRkfiT+lJpkyTL+o2flaXFdIGc7FVoP4sAnkj6Gsu
xSb7O9xtLRLlm3D5wuegNa7S+Vp63EshlctuIbGWAHA4/wA8U29lS0e7+QPGB8vPQdqla3RLSlqZ
2jaBa6pKXnjWNIssmPqM8Grl3enSTe2U8fm2rRkxTDJBdgBz9B096m0+G2N+0sDBo44+cnG3jJFU
7uC5nlYERzRMpC9/Xg/QYoTakCi2Z0YX+xYtPE6x24bbNMc7n6EAD+taDX1i2gyCF0e7ijVETLF+
WGGBAOcAYwxxWPeaQ9xH8kjFLYkuv3d6Y/nxWho11aWGhwzFBGlupZgeoyxweevX9K0j7q5luS4N
anofgmGTSdPXWNXY29t9kuFt4A+WR8AfdyeDnsMEnkHGa8li0bUJdal1GOOIWltuLo4XETsmd2Bg
YznBHoK0l1O+nGkm7kWeG4JkRFwPlz0/DBFdPbvANYmRBiKQAFWxyOh/mautiJJWSE00eVaVYrea
2iJ5yqYmZpH+bkZZiSMYBwfWmyXkOkaraz6QrtPz5iscBiex9PpXba5HpVhdH7AAJGYwRruPzHAO
0+2etZGoaMYdVEkpild1dvk6k7SSPTg/jQqqnNX2Y+tjjvEUg/snT5FiWMzbmcL6g8fzqHwdl9ai
4+VVZuPpWt4lggjsNLfa/kh5TtI5xnjmjw7cFEjjgSFYfLcylUyxYZxuJ9iOBxXYn7pT30IvBETP
HqT+bHDH5R+Zx19ge1X9QiZo4fIUzFY+NyZJYnpg4/lmsvSzNDp6RWs0Qkkff8xIKgHgj8a27qa+
huSxjeW6lCqwh5AOMggY9P5VhUXv3REu6KryXFuiSxwBGBywZAAi4xg/jV+21GwNtF5ljcs+wbir
KATjnHNVZbuO4i2zyjzGGcAcn0Ldh9KzigJ+S0tNvbIycUklLchRLCPsjgmxHjczLt4OBx/MZpbq
YCXcZXd2kQhz2/WsCS+/0KAISZIyeen0qA3sksSq7E7SSTW/s3uatnaalYJrl0bjTgzzoPlRzyfb
6cGsKDVDbTlZ7VwyEgrwcEGn6VqEtvcLPbsqsqiQDufaq95dB5d8i/6z5gT1FOm3DQqMl1OhTxTB
IyQmCWEHq5HAq5BqhJ8sOrwk43ZwPxrmdEjtbxbr7a7DA/dbe55qCZ0tl2h26Zx2Nae0u7GseTe5
1mn6l5d20DzLsBypB6ip/EWrG1iSS0bcAcNg5rio7oXO0nqvr1ro9MgN3AUjUOH+Ujq1SzZJWug0
bx3Npd4325WvLJxzFu6fTNdl4c+I9pqN1bWEVhJGPOUW53ABTnkY/wB3PP6Vwvi7wdcabZRXyxkR
Pwy/3TR8Noo4PENrNdARrFuKs3TJ4ppIiUrntvxG0tkt4tdtEy0QVZ1A7BgQ36YryI6k0t4ht2JL
uWyV6t1PP519IxSQy25hlCyQyptYHoQa8R+Kfgy78L3NvqOnxO+jN/q3HOxucq39DXO6am7oynGx
y9xIjTC4Yx5mjEoJH3fmKnH5VDLcJFPaKS+xmHzbuAQSM+/asAXq/ZZIyM8YX2yST/Sobi+Yxoow
ShyGI596pUyeY766v2BSaNnK4Ee08lhz1+lWZLiM6Upm5XzURmdRngD9feuPhvUFrasx2OnAOevz
dadc6zJJp3lRyOuJd4Q8jORzWPsmxuRvXGrqt3GHXABZhjoCORxS65rC3Ft5yOdsm1SpGPl6GuOn
uh5xMilmIxknGD0q7p95DLN5V25+zMQu3HI44OfY4NV7FL3iU7nSaXex2EL7GBSRMH5uRkZI/PNb
+l6hG1urSZdJHJdGzkBuOvrxXnZZlhkEW4AHaVJ7ZrZ0vU9t3axPhS23px2qJ0r6lRdmburutqjx
gmLMioQ3Qgg8VjaxJbrowt4pi5SV4SCOTGMc/mTVa6vJtUnkhCD9/NHnHXO7Oc9u9at5a2D6Tr77
BLcR3Alt36lQTyD7YyaIx5bXLs3qirYxtqNjptvZfLc20BYMTyo35Iz75NbM8dy/hoTTACdUSO3k
Q/N/rssPrjnn0qON47eCFbRFiWYiabHGAFIKr+ZNTaPePqNvKZ7cIkMW4OCQWUFjUyu9QSuU/Ft4
xtYZJIQFiPlFjjO4N2ODzzWe05ur/T5Z0dY5JGVH7bSmB+uajuYHkupI2upJS4WaRFJ2ZLAZHpye
tbviy3Njq+mPAMwLcqoIB5GMZ5J/yaa5YtL1M7WZzXiBnl0bSgI1cL5hP8R6jOc0zQrSePQ7+RLZ
likiYiTGcFRj8K6BltYbmygu0eKJmkQ+X1Q5HXOeKzNdN0kk9nZ3bvDAREQPkJyR2/D9a1c38KG9
NjnE0ousyW7Z8iOPoc7mYZI/MYrr9DLTXSi6jZo4Bl8ONwYZGcHORjNUvDMUU2saogcRq867ZG5w
oBPArqNK8NX2oXxl0srHEHLSSNyBzwRjrU1HzPlFy30OP1CSz1HWpl0q3AUZKhkA8x/WtaPw23lr
5skAkwNwDjr3r0610XRLGWOdrQeYytmXZjqTk8cVX/4RXRzzGs8ifwvvI3D1xWiptJJDUYrc+Zyc
hue1MVskeneg9h2xTBxxXWZFy2uWhBx1HQ5/CnXFyZQO2BiqRNLu4pWAtW87RcA8HnFOuLl5yS+C
RwOOgqkTyKN2QaOUCz5pSFQAQfWt/wAMak8WoW8ynmJ1Le4zXLuTlPSrWkS+VqEe8kRk7WPsafKX
CTiz69020ttU01EuIlkgkAyGGc1w3j3wm2mzaa+nW5EAu1DbVyAD6+1dX8Kb1rrw7bRS/wCthJjP
uB0r1BYI5LfE0auvXDDipcbl81jm/D+izXc8fmIY7dOCOn4Cu51jQNP1jRJNL1CBZbWRdpTOP1qG
0kAb5RxVi91KOzh3O3znoKmMeTUUpOWh85eOPgAltO8uhXoiiP3YpeQP+BE15ve/CbxNbcoltcYP
RJRn9a+pNcluL35yx2+lc6UkVucVlKtZ7GkaN1qfMt54N8S2bIJtIusKB8yJuH5isuW0vFuQFt5w
VYHZsOfyr60gu5oD8rZyMY7VUvLqR2yep9AKftIidFny42hatPtMGl38g6sRA5x+lOj0HWI2zLpd
9GnBJa3YD+VfRtxcMpyrYx1FImt3duu2GZ0HU4NCmnoJ0Wj5zZ3heXzIm5wNxGOam052l1i2kQKD
kAbzge9fQM2umcbL9IbmM9VlRWz+YrIvovCt/IBeaDaJg5DQZiYH1+XAqlGLWjIcZI8pa3+xaxIi
tlwd2VPQ49akihaTTbg+aMO0bg78BRyDx36iu51vw3oF2TJp1/e205GB5irIv07GuZm8M31vFJHb
mC8i7AHaT+BqHTkhqXcj02dDYQQsCV3FnPU7dp/mcVZgvV2ThkKqsCQKq9CMHP41z0y3enSRCeGW
Fs7DG6lcj6/hUdxqMswaMHaQAQOzcY/pWbg7i59DXmM1pI6KGQyfKvGDInUKPT0/Kur8QaVeajp0
EhWRfLAkwRkhlIPP5kVy9ncRXcULTAGZFG1cdc8Zz+AFbupT3LWGWkkCFy5xyRkYAPPI4BrCabas
7ExMHVrtkmUuBAfMZ5Nx+YYCnFPv7Qtpt3cQRIskkgdAzZ3oRgt/X8637HSYtWhtl1eJZZoEUKG4
4PTdWh4j063tYreKaKJYXCn5D0AIIA/wrVJ2UnoaavUXw54T02whhmlkLXpQdDySOM+1djYlVby4
3aONF5RTjngY7Z5rndKuJLlZZU2qHXbGzdVC4y2PeopdYRVeW2mje4jlHDkhcHnOe/TFac0Y6ldD
rJLZJUZFWeRYlL+THnJYnAx/hULamY2KGwnyvHKmluoFOmRX0bH96ignbtyx549TwTmqpupwcZJx
6mt732Mtz5UHXFIetOHUU319q0IEHWjnJFORdzbR1PSgjk0wG4OM/hzTgh69sUoCiM59eKcG3ego
AQHpQMcjPPrQSAcnn2prkZ6UhHvvwR8SR+dDaO4LE45PtX0ZFOJE46V8T/CqUx+NNOjD4BlHevsa
wnw6Rtkmma3ubIk8mPPpXK6tfteXmBwE4HvXQX8gS3bniuU8sAsQOtY1HpYumtbmtYyb42VhwR61
lXifvSBU1lIQy+tS3iAsW9a5ZK50xdjHcZ6DOKryRlnORkVedcHB79KRcEc9aSQ2zFntwr4PQ1k3
9u0ZyorqbmHeoJ61RvY1aAg4zirSIbOGvJCgJP6dqw7i5IY5PFdBqsWGYEYz6Vx2pq8TEjpWsSWS
m7IbqaRdRdX4c1itOw4JqAznfyasix2cV+LqAxXISaMjBVxkGsq70DTppC0Eclux/uNx+RrLtLo7
wAfyrat7gO2M5I71putTNpGHLod5YSLJE5lgHVl6qPcV0vhu8iurUxy5dkJLZbO4DvVyFgVHWq93
pm5TNaqqTKdwIGAT74rGpSUtUZuPVHU288aJJKgRifvmTKkc9hnB6dKztQUXjMqlBGCzrk8gAHn8
fT6VzFwbmS0Vd7hi4QoOpOefp0/WtG5vY4oVXzJpNvCkr1TP/wCviuSV9Ex3aRdYyLE6WhWEuu2L
5uTx0HpWY8QGXE0exoxGQOcDOST79arPczJ5TBw55XGM7QD3/Kqup6hFNHmcbLjndtGA3pipSuyH
Jvc3r9L7SmtmtLmO7sid0chOxxx0I71zj+MtSLsYrNRGTlQ2Ccds1lXGpEbYkdynI2sTgcdR+VUh
dEjPmsM/9M67Iy0C5yOMYNJICCQfWnHgiiY5JPYcVuMSMYcMD0HOacFyqnpUaH5ual5EY70wY3A6
nt0pDg8DrQSelNweTTAUnmmE5Y5p2cnmmbcnr0pAdJ8PUaTxro6KxUm5TJHpmvtizVXZWH8Axmvh
nwnqB0zxHYXvaGVWOfTNfZvg7WI72xLFuTzTZcVoXtXn3SlFf5fQVjSFl6Zx/Op7wESu6ncuc8Vn
vfKz7Oh71yzd2dMFZE0VyA4+bjvmrf2kt8rGsYgNI2Dg9frU+5tingn2Oc1JRZkIx7g460qnLc/k
RWe024urZUkce9RQzqQdshLg9zSsM1biZUQggVh3jkgkZAHYVblukZSJG2n0NYuoXix5XduHsc0x
JGXqwDKSRz64rj9SVWDGt/ULkEtg81zGoz/N161cRONzDulAPANZ9ydpBFXrg5fr1qncxnBOOa0Q
rWJLB/36DPeu9t7O0dATGAxHUHFef6bzdIMbueldxbudo7VtAxqLUssgjGwHODwauWkiiBg2OnH1
qi1m5j3oS2Odo61VEzJOgwcZ5FJqzJ6Fjegu0fYH2tuP9Kzb54DL+8c5b5FAGSBnr+prN12+kggd
o2ZXZgB9KyJ9QkcKoXc278Sa5KlO8rg7JGvrOoYMn2ddzL8u8jBGc5NczcXWQxPO8c8UhbfLIJW8
qAHkr39hVS+aQ4ihXAcAqCeQKIwSMnqNWZnGIxlugq/5kS/LwccZyazI3EC4U/vQOWFG7PVc1bjc
EiiUx6ZxTXDEnjipWTIYZ5HSnp2UgElfzrW4yr5Z3e5HFSBQVBB46GpMYXfzzkUwL+7I5yTRcCLB
wcEHHpTFJzipWjIYgdR3qPkAj86oBhHpRkA0v50FcjjrTAdGvVq9w+C3iuVmjsZ8tNF8gbdyV7f4
V4gvpXR+BdTOleKLCfOIzKqsfbIpMuErOx9VwXYkR35X1BqH+zHnLTxjJPIFbA0yOFklLK0MoDDF
aFuqxgeUBtFcs97HVF6aHlF1q81tdzxsCI4yCr+xPT8D/I1NDr0jISqkg85FL40srbT/ABBN9pdl
t5QZFUDrk5P65qhbajpsabtwCjoAP8aqyN403JXsaxvLi4gEkcbY9hisuS6RnYqwWZeoPH86kufE
9pbRklgwIxx2/CuI8QeK7KVsxyIreu6hpFKlLrodNN4jhiRhJKiEfw5rBvfEIcbwdy9smuCvNWtH
dnkmeRiewrPm1lM/u42I7bjihRb2Q5exhvI7eXWWmOEU47c80ixz3IBdOD+Brgf7Zuf+WZVP90VX
fVLwkH7Q4+hxVqmznnXpfZPRX03BOfve1VLm32oykciuMt9bv7eQOtw7Y4wxyK6fSNdj1A+VchUn
OCD2ar5bGKqKWw7R4v8ATuSOPWuxt0OB2rE07TyZ3lIOAeK6e1thtAOauAqhctE+UYqvrUcUNq82
3D1s2VqGA2msvxrCIbDcchepParlsZLVnnetIZ4VYI2EBPHrWOSI+N4yeefXFVrnV2mkZUchQflG
eMVnSXLHnmsFB9RyabNhZYtqFmBYc4bpmq10yNuIkRnY5Y9M/wD1qzHdm5waZkD1FP2ZNkSyffJB
Jz3zTiTk4H6VDGAWyTxVjb9KewrERbJz+FK5ywJ7CoWkwhHvQG+UcnNFhE+4bPcmmCTDge5qLzPT
vTC/znFHKMsFgCfQioJPvZHSl3ZPXgc00nkimkFhmOKkDBgPWmEcHNID7UwsSKeamik8uZHXqpDC
oTgEU5AWwF60WCx9v+GV/tTRbOZZDgwqRk5zxWwbSaCIl1wgHBBrhfg7qbT+FdNjcg7YlXg56cdR
9K9F1WbFk3oFzWMoq50K60Pln4763LLrggt5nXyTsypwc4yf5ivLl1fUAdn2ybn1bNdr8cbSTT/H
E0MrBi487jtuP/1q88H3s/jWiiraiqVZKXuslnu7mZ/3s0jD3Ymq+7nmn8njuKawANNIwcm92PB+
U0i8qcdqQf0o/wD18UyRHfCkDvTozkYxTQu5ge1CcSAHPBoGSMPm475oYlJQyHBB+Uj2oU4cGjtg
8elDEep+FNSW80uN2IMoGGHvXQWlyWcAcD3rx3RdTl0ucupPl/xJnrXoumX8V5As8MvB6+1Tex2R
tUjfqegadPtYAtj+tZfxL3t4Pu5IhuxgMfQZ5pmkTiYqrMOO9dZapA9u9veAPBKpRlYcEHtWikYT
jZnysmTIOBjNDMduK9C8cfDu80G5a807dc6YW3KRy0Y9G9veuKax5GTnd0+tTJ2ZJUXLAZ6dqcik
wueuCMVopZJESXIbjIweafDGPLYqOnoKlyAzUtmI5zk9j6VeFvGBgocj3qxGqKqAqu4nn1q0ZLMn
O5PyNQ2waOVkHGVOaRDlTzSsR06E96TaVHPBzWpIgHI4pxXB6U1uDTiQyjJPSmigHIOAaD2zTUPJ
qRcHr0PFDExnUYpUXB6GkxjmplzkigYIuVJ9+Se1B9FyBn86CwPHbPFBOWOBxSEfVfwGtmPgnTJ2
QgOjj64dhmvRPEjGPSJiOpAA/OuY+DMX2XwFokcgI3WwkGf9olv612WrQmSW0jQKUDhmz9aiS1N4
M+TP2hQ7fESUNjK28eB+dea4wAf9mvZf2lLOFPHcbsHimktVbheDgnFeRpCMSF+BjGDTMZvUqEYc
/nSc5qeSEhi25SCeajZNqHB5FO5FxhIxkdqAcCmdueM0uc4FMY5D3PUU+MHcDx71EoxkEcipUxjI
6jmgQ9V4Iz1/SmsR05470Rhtm3BOelIyEPnGPWkAoOUxV/Sbq5s5MwPtQjkN0NU4Y95Iz8oBOfYV
diEZgIABbtk8GpbHGTi7o7Hw14kYyEyLt2Ng85FexeHNTtdQtlSQqwYcivnXRMxyzRsRu4bg+9be
h+Ir7T9fa2jYNG8nyg8YzyBVLTVHW2qkVzbn0ibZo4/3Y8yHH3TXkPxM8GTyXA1Tw1bBkAP2i3iH
zK394L3z3x+VegeGvERNojykMhbDD0Nb9zCs7x3VqdrfxD1FVujFxtoz5Fkml8xlkyGzyCMEVLC8
hhAGTubgZ9v/AK9eh/FzS4rjxpCYhFBJNHulfGA3JG4+/auHuLZrSby3Kv8AxK6n5WGe2aiSsZN2
KqI4V5DkbevPeogjYHymtIRR+U23cxA5yOM1XAyARFx9KjmAwm4fHrT5Gz+lNGWcAAkngV67oXw2
srK1im8Qs894yhvsiPsVM9AxHJPsMfWtJSUVdm1ChUrzVOmrtnkRGTgZLHsK17Dw1rN6AbXS7yRD
/F5RC4+p4r2210+3sAFsLW3tR6wxhT/3194/iakaEscuSx9zXNLFpbI+kocL15q9SaX4nkCeAvED
DJtIUH/TS6iX/wBmqVfAGtbMlbIfW8i/+Kr1n7LntTWtAOgAqPrb7HT/AKqpb1PwPKT4D1pVLEWJ
/wC3uP8AxqO98G6raWklxN9jEUa7m23UZOPoDmvV2swOtV7qwikgeOVAyOMEHuKaxT7ES4YilpN/
ceImFezpx/tCk8nBPzrjH94V3mqeCAQZNOlIP/POT+hrkfsVwLxrbyX89SQUxyMda66c4VPhPAxW
W1sI/wB6tO/Q+uPhNq41fwXo6+UImt7dIhgcEKMdfwrtr63WNZbqWcBYgGUHtjk15z8FLSa28B6Q
ZEKsPMzz/wBNG/xrY+I3idIrGaysyFn2YZmOACQdo/Oplo9TOnTc2owR4F8e/Edl4m8Vo2mz+bFb
ReXvYgDdnkCvNoUOWMjRkdACwPFdHc+EdWkmkkZYXZmLHD9zUP8AwiGrE/6mP/v4KFOlbc2nlWKb
vyP7jnniLE42gf7w5qJ4Xxxt/wC+hXTL4P1bODHEPrIKefB2p9xAP+Bf/Wp+0pdyVlGKf2H9xyH2
aTOcJ/30KPs8uf4f++x/jXUy+FdQjB3eSfoT/hVSXQr2PqiH6GqVSm+opZZiI7xf3GF5EhJzt5/2
h/jTo4JFzwuP98f41oyafcx/ehP4YNVnjZPvKV+oqlys55YacPiVvkMaJ9gC7QQP7wpiQSNw23GQ
fvCpBS0+VEey8x6oUlkYAYIwBntV600ieRUkWOUqcYK9DWdj2qzZSTRyZhDMByygZyKmUFYqFC8k
my/bafPbXjO0DIhG0k/zpLmynbU4p0iLR/KWPTp1q9pT/wBp6hDZwqUnlbaN/AB9zXew+Ar6yvln
vzC1vFjdsJOc9+nvUK9rWOqpQp00kp3DTlLQQJaSeS0gAZWyVz2Oa7rwlPeR3DW+ortdEBBByGFc
N4tddLhjFlISFYPgdOK67R7qKeWGYOVLR5HoQRTW5lNNwuzgvi5p15qHiffaxGSEQKmQwHO4nua4
h9A1VioNuVUcDMin+tdj8Sbsr4hUKT/qhn8zXMJeHuaicrPY6aGXwqwUnO1/Id/ZV9EFHkx8/eyy
4PTjr7VbFrLgf6PGPYEYH61UN3k9eKYbn3rO/kbf2VBfb/D/AIIfCnRo9U8TxXF0M2Wnj7TMT0OP
uj8T/I16pPdm5unnc/M7FvpXKeEIk0TwnHF9261EieX1CD7o/r+NaIuB2qMVLaCPW4awyhCWIl10
Xp/w5tm4O3GeKb5mTjNZaXJ9TU0c/wCNcVj61STNWNiccg+2akyM4P6VlrKRyDzUonYjmlYadti5
IckelROM5xUQmJ6U8PnrRYXNcRQP4kLfjXVaR8NrjV9EvL62s4E1C9hEUM0smNqbhnI9wOvWuetD
bQ3Ect6sjW6kM6xqWLD04r3rSPEWkTQWcVlewgyJ8sIIBUDtXThkr8zPmuIa01FUorfW4eEvD40T
w/p+myusjWkW13QYBbqT+ea8C8fXlr4m1TWLWCcRyQ3yo7IOQqDsemc/yr3Dxh4007QofsouIhNI
hbBYGvnmLSYrW7vLmDfvuZWlcseeST0/Gtq9ZRWm55WTZfOvU55r3UW0QKij72BjJ6mlC9eMfjUH
zAnNAkYdK4Ln2lmTmJcZ6n6VHIuDjoPaj7QV64pj3GfQ0ajvAilQfWqFxbBh93NXJJweoqjPcben
86tXMJuJmXVmDnisi5seuBW3Pcjuaz5pwec1vBtHm1405HN3enjeSvyn6VSezkXoQa6C5fefWqTq
SeldUakjwq2Fpt6GQYJR1RvyqSzuZLSbeo68EHvWmimrCqCPmUEe9U6vRozhg7NShKzGW+vR29zF
craiR0OdrcfqK6q6+Jd1LaIlsGQk4ZGxgD0965praCQYaFPqBg1Wl0dGH7pmU+h5FQpxSsVWwdSp
Lnep1eq6la6lawLDJ5sv3nc8f8BxmvQ/BUayaRZMVwcbPrXG+EPhcbywivNXnubZ2beEiA+52yT6
16tZ2FvapFDbgJFHjnPAH1rSMXe55+IrxdNUoq1mePfEmIP4nmGPuIo4rk2gxXXfEaaM+K7sowYE
LyD7VyLz+9Zyb5merQUVRj6FeRWHTNRZb1p0smc1BvaqSMpzs9Du7u78+8kZfuD5EA6BRwKVJOao
xAYq1F171xzfM22fT4OmqVONOOyLySZqaNn4wRiqyAYqxH2rJo7lMtq3FWF7VVj9O1WENSzRXZMF
Oen61MnToc1ACdoPerCH5j9aQWuSxSEdqsKVLBnVSR0JFQdDxUq1IWT0ZKnlJnZGq55OABk0Mqyd
RTe+KeBjNSzVQViCS1UjoKrPa4+7+laftQoBp3E4GG9sevJqtLCRkYrpHjU5OKpzRJ6VSZzSVznJ
o25zVCeNyD1rppo1C5xVGaNfSqUjF0+Y5eaFz1xVGaGQHpXS3CgMRis6ZQGNbRkcVWgjDMTd6BDV
+ZRmqxHNa8zZxukkxixAc4zUyRr3FNVjingk0rjSSJBEoHQZp6F4WDwbRIpypdcjP0qNDwKkFT1N
Y8so6o7XSPiRfW9oyalZmaZRhDCw2sPfJzU2tfEWO60V7extJ4rliM+YAFA78gmuDPWmsM9a19tI
895XQvdXINUnkvbl55FRXbGQvTgVlyRnmtKWq7cg0KTZpOjGKsjMkRhUW01fkGTUG0VqmcM6auf/
2Q==

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/images/next.gif

R0lGODlhDAAMAJEAAJqamsyZZv///wAAACH5BAEAAAIALAAAAAAMAAwAAAIYlI8JkBrcDAgvikmh
o3XnhnWb5pCKaTUFADs=

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/1630/th_48974c17ed2c4.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgASwBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
4GXQrLQltJdNN1dXGCbtiiqBgY/djG4gYOTnGfxrC1e0XF691BdtdefsVlJjGGGSQDzk5HGOgrSi
8STrDIkDKk8odVeTDAAqSuc9evNUYNae6t5bXXZwLksGkL/KSewAAArjp0+d3ejHyonsvDOn3Cx+
VenZzyseRuyfRu3H5V1OoaE1lbwXUPkC3MaokgYj94ox8w9TyeTWH4dnsdOUW8LkqcugPTPfrW3p
XifS727e0uNQQWkpKNbXHBB/hMfHUc859PrWk4J6I09loNs9Fs5hAb9BbqsgDFRgyAYx39MfnVCf
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

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_46b4cdf3b7234.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAVABk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
5vxfaR33wq02SFEjkknVpXI+8QCu5j3PAq34AtwNCj3EObeBiCPu8ZH5dOv9af4p0pm+FOkxS5UC
V5AB3CkjH61QsdI07UvDYs7kCJHAwIVHmbQQWK+npn3HWrnilG9NLcxo4KVWCquVktfU4S7tba88
QLp9rd2YCyeVG5f5COvJ6Hrj8K74/DbxFJp0c9jqOi3TJjfFbTkMwHIAyACT7kVW0Pw7q+o+ItT0
/wAKWlppiwjdDKACzL0CsTncSOp45HasLVfGviXRNTnsNVt2g1GJglwHYhm/yOhGRzUSnUb/AHaR
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

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/76/th_47780fd22084d.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgATQBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
vTapp1x51tqOjXYRiEDK3DEjac84Gfm79u1WTrek2yrmSWKSTDK+4NsXrzuwB05OR3q7qV9b2NnL
dXsgit41Mjs47e/Xnt6+lcf471bQNW0KwtYtRNvJciO6aYKE2KDwvcknB4HIOM45rhoxlU0Wxd2u
p2thrNnN4ni043UwkmjWWKUDbGcMwZST3HBIHY9cCtCV5Y0miE8kEwBUrLI29Txjnofr0JJ5INeW
W1xDf3Gkwamk0ljay4t5CpZFbKkP5nTjZgDvnGTXtdrYWmv6Lsb/AI/of9UWOWKn7qEnt6Z6Hj1z
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
XLiVLpRLPBG78rk9Tgn0/wA/WigFGTR//9k=

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4616caaeac93e.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gOTAK/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwK
DAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQU
FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgAYwBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
/OzV9Zlnu4ZL29aK6fYUuT86tGeA7Y/iHQnrwadoF1D4nudVt7i2Xynj85Psqjerx5Pyg9iC2fwr
PdtLhsx9oZ7m4uId6sGG2Js9GHcH/PWtEpY2tpFcQahJb2SB5D9njCyi4aMKAD/dPfkd6hntvmev
QiilutIivbVIDd2geaN4Hi+YJgbXB6jBwe3QU2ynFpp8h1SzuXsjIuZM5aHzB85ww53BcjpyBzUA
e6sLm5NnC5d4gPJuUYO/Gw7QSd3r7VXi1i/lihM0waS0j8r7PKg5jUnh/XGcc9hSuTu+Us6R4pCg
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
yvExvN7z/vXDbdzdcUUUVmbLY//Z

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4687b474c9c0c.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gOTAK/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwK
DAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQU
FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgASQBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
851aKfR7W01S3eRyyIslu0LHO5gN6noPQk+oqzJZK4eaYsSehIyT9K7TxH4G1G117TvC1xIkUSDz
llljAFykeHwG6DOwZ+h9abqnhPUX1ZNOhs5JL6RgkUYXGT6L/jXkVuaydj9PU6SajCW6T/4J4l8S
NZmitjo2npILu4t2lDwHLxqCOQBySf6V8+67rPiXS702qa3qpCKDzNIp57EHmvt7wx8LfEWgfFS4
1DWdAktrRdOEcN60mGjmEm4qQpJIIAOcY7fxYr5b+O3jjTr/AMbeK7b7LMrvPApmkDF98cZWRhuw
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

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4694e6de34dc3.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgARABk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
8Yh8Oq7bdw3fWrS+FYS2DKgIOD+8HWupt9HtJIgmW2Dsj4rR0fwla3N5BbWdqXmkcKqhiSx/M1KU
zF1OzPWvDEvhH4ZeFdA8P3l3Fa6trCR3M0rRbt5b5h5jYxsyNmPTJ9TV/wAM3+ta/qs+jRQto8MS
P+9QB4xGj7MR4wDnAAIx0Y+grxP4w2OoyzRWuoRbb7duFujCcoo+UfOOgIA+XAxgV13wh8Y30Nja
20ESpc2cZSQsCDLyCVYdzjcc/wCS3TU2jeFd009D0PxZ8LrOCyF9p2r6lb6gmPMneTzRJ7leMfRS
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
LccLVkAAuZsf7qf/ABNFFFXYk//Z

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/anonymous/th_47567cbc93cda.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgATABk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
838PeH18X2tlDNcMk6W8rmRnxu2FiQSQf4QvNT6N4N8NyyXDS6/YKsab2DSucf8Ajq5/Orvwo03W
Zbyw/si2iuJ4LiZ2WVx5ZjKJndk/d/nmvQbXXrq3tNQttT8P6ZLeROIrlvsirkn7yjauWGemOfc1
U2ktb/Ixw1OUrrszT+Hnh3QvCtkt/dyWT3Mr7raaUYKAcZUMTzz1+lcb+0p4hmim0S2sbllJiecs
p6hjgH9K7DxA+mTeIbLTLYhLG2gVI03liPQE8842968f+OdrqWreP4rXTbG5uAsUdtCI42O4jggf
iSKmNPlcbPXUiUueVuh59aPd30Moe4kYKozk8nnpntXafCK1sbvUZ5tTs77VWtDGYNNhQuJQW+Yt
gHO0DIB4Jxnjg83qvhzWvC1/b22rWb27zBZBvZT8pJGflJ969G+BetXelW92bJVEf2km+nK8Rwqu
QSex+9j6GtJystDqp07tJo9B+KnxTs9T8MroXhW1v/NaUR3A+zNGsaLndGc4OcgZGOxqtp/jrXfh
jodppGtaIBNO7vAwmTa3zKDuIPy4LKO9edzWmox32qvYafJLFceYY50yRlg21icf7Qqtd6trniGd
W8SymeaCAxRM0QT5QQ2MY65/p6Vmqa0fU0c5JOD2Rhp4m1y18dT39tClncyXbH7NERj525jz6HOK
f8RLrUbjxKbu8tBbC+Ecqi3YbX4GWOABnPXpyDXV+GfhxF4sGmagt2yrc3ji5SMEGFY8ZwwPO7I5
wMFhXUfGRtOM6aXY2SSvbwm1jSN8MnQrgd8DI/4FSvaVidZQvPc8e1Sxu7T7P5epG4863+0BElG5
V7ggHqO49j6GvedIuW0XwfbS2Amm8q3QSliTy65YD6Zrx218I+JNNvbaYeHbv7bE6tGwBcABgwGB
wDxg57GvbL2W912/08f2DLp2nRQhtRSRXh2yAfKsQOM9TzjGO+cUVZOMR4eknOyN+x8Q6zZ6fawQ
TqESJRxASfxxkZxiinrqllp0MNsGKIiAKqSMoA6evtRXB7ddz1Vg/IwfCfiGHw/8PryTX3S0ntIB
ayCHZKyyqdp4U4JJx3+vOaml+J+hXmhQ6jYM1zdxtiRNm0q5QliAeuAK8d8Oa5b6rpF7o2prBvuJ
Q8TuzRQjONxbDADkA5xjrVjS5dFtdEu5bayEZsrqGRR56+Zd5JDYDBgQucYB6HPvXqTjCUWm+54q
qSTTsun/AAT0XT9Ug1ljrVrprB1dC0Ua/PLIcEk4GO4wcnNdhpUdtJONQuLXyLkSs/7xAGh3JzyQ
Md2zx3r5+h1TTm+0wWFjqttayTtIkTQrMFzjAIJAOMcd+Tya6vw/DPo0AQyalZRahslCTRGHKxvk
tgNzkHbjI4bPIrjw9Onhn7i173b03tZs1qP20rt3tsrJW+aJfF0uk64+sBo5boWJkhe4aVYimd23
apzvAJPGR8vqeKb8PbIy+Hf7JsYIbNGt83N9GQd0hQcMeOf3h7noQM1iNbRN4iE0s1hEuoSb/OCb
93zZIAb7uRwBkH19a6Xfo19fLplhHbm7MO9ZY1CEcbgVx09COv8ATrq4pOPKluRRpWmpy6fmT3Pj
q58I6DZ6RPpcOoTzTlFMYJAjQKoPAPJGSAPXn0rF8baZNqOrxy6HDKsUxKbHyrqWSTO8HBVuRxj+
VdPC09tBCl6v25pGSRUIw0eO4x3HHQdB0rQDMLS5MMpivJSrZ6fNwA3Xp2P+c4PEOWljZUlHroWP
g1FZ6f4Wtrc3RM0rs21+gk43bTgHBPPP+Fch4ylCeJtQliKkWm5gTx8x29/rmtKzmn8NPdfbYoTH
czPOjnorgZZf1J6VjaTeQ3/iwzjbdWt9fRJnIzjocAg55xxxVQevNIzqu0bI94+H+h+Zo1vealI1
w8gzHlidy54Yn6f5NbnifShe2sj2+1bkIQM9GHYH/GtiCNIYo441CxooVVHQAdKJVDLUz9/R7GlN
uDutz468Wa3eR67cw6ifsc8LGPynBzgE4PA6UV9Ia5ot6+oO9pkxsM/MucH24oojhKVjaWNq3Pn5
o4YlCm2APTAxioXtwE3GNFC/dA5q+0MWDuuWDdBgdai8qOWTDTJJnp+65H49zXm854/Kb3w60mK/
1vN15XlwqXAxnDdjj6A/iBWf8SNUFjNfI8rs32keUNxGBtUlcj1I/nXSfDy3gia/uiV3RpiP5cDp
yffAx+deQ/E2/a81W1ijVgVLFCTy3zEAge5PFd9CCcUdVP3aZzepXMl79jR5FCwhmUgY6n278V23
gbV9O0rSZ7eyVzrdwoRZ3iJ43AlFz6gD0qbR9Ej0+G1m8mNriJBufliGxz7etabzmeT99GZAD3Xg
H/GlPEQ2SM/a8ruLrGuSXFvbBXkjaSNhGn3GSQtuO4ce4P1p+g3surLHaWszmQ5VWY8qxIGPp1NU
tXspLxVeznw4+5HIeDkevUDpx3qnYXGu2WoRm3thFggMQ6kH9RnpxVRdOSumaKtfc7f4lebD4ZSV
5FaeFxLuxjcVXa2PqpP1xWH8MoEm1Pw9FGAB9tV12qfmVXABP4Lmq/jZ9W8RaZZeSVNpLOwdg2Nr
BtpGDjIGWGRn7prsvhJYlPGOl2yKFhtkZvu5+UIQOfripnPRR7jqu8kj3qe+itAftbeUB/G3Cn8e
gP1qZZkfayMGRhkEHOaWePepDNuUjoRxXOXel/Y7tbvSpDC6H5oMnypfqOx9xWySNtjojBC5zL97
/eIorwv4g+LYYvEkkV7dG3njjRWjWTAXjPHr1zmirVNkOpFHm8rBSTnLMMgE4P8AShzGi+dK6ovG
ZC/y88fj346mpIrPdMzOp455IyfYd6iltDpl7FqGqb2xIyKIVGYj/wAs44l/56MOS55AIxg8151K
Cn1OOlS5ndnWajfJpXgm6W0Qiby9rLIdrKufvMOoLeh5wB6GvK9EsJ7/AFVdS1J2DBtyAjGT6+2O
MV1+pxveWtr9qRra3LloraNf3aEAZJP8TE/xH0NVTZOCvluEjzu54B7cVtOqorliaVql/diXmyZy
IrjIHy4DE/n61GkdxIz/ADH0DjuPwqMWM/LExsP9nnn14pBa3MiuAxWMc5ccE+2OPSuTQw1LdpLK
ARLJuYAjCsePyp90JlQspj4wT9aqtbyAoEGPmwZeV4/CoLiF1lUSSFlxu+Uds8e9CS6Cu1uiS7lk
S4061cA7Z2kX2yN3J+pr1z4K2c1xrN5fSL5ccMIiC4AyWOf5L+orzrxZYR211owjCuZY0Y5B2k/Z
kz7dR9ea9e+BlvJH4cvnlJIe64JOcgIv+NdbSc4+h1r40vI9En3YwvTvWbeFguTgitCfJbO7gDpW
Bq18Y4ZHChtoJAJ610xR0tnzf8VNIub3xjdSwXaxrtGRJySTk/lyB+FFVfEP/CWXmtXlxHZ20sUk
rNGxKj5cnA5weBgUV2K6Rlp3R3jeB7xm3S3cBY9eM46Z5x7fpWNqXh25GswxNNDIhvEfzQgcA+SE
yfTDIwx2NetydKz7sCEPcRogmA+9tGTwQOevG4kYNciw8IJ2MopLQ5C78OwzqkdxrEAWMbVQovy/
+PetN/4Rm2VoyNQ37e0cWePoD/jXVwWzToZprqdvMYtsBVAuewKgHH1ND6basTvV3/35Wb+ZqlhK
NtjNxuzkH0e0gQLcXl4UxgAWrAfyxmqGo3ei6eN8jXuBydsa5/XpXcvpGmt9+wtX/wB6JT/MVNDp
1nbj9xawRf7kaj+QqvqtD+ULS6HlP/CR6RNxbWGr3GOASFH8s1Z+1y3agQeF9Xk9Nx2KPcHZXqoA
GMU4DrVfV6C2gLlm92cVF4NuPEmm6XdxW72d5pySK9nPOGV1bhCGxjjHPpgV0vhXxJfeHbSLR306
2VoyzS/vDneWORnoemAfTFWrpytvLjoVII9R6H2rznT/ABFcX/i2fT3trOKKMGYvFGQ7sWUEsc88
fyqfYxclod+ChGdaMZanol18VtNgyupaZqCk9ZLPbOnv1Kt/47WRefFXwNeI0MmsXNkx6rPZy5H5
A1wviZjHFNt7MRXiWuTPLczu5ywqp01DY9bHYGnRgpxvqe56pr3h2a6L2fiXT5ISOGZ3U/iCtFeC
QQoY+c9aKPaM8b2CfU//2Q==

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/443/th_477bbfcd18433.JPG

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAUwBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
8lsbEHxBDaXHyAyhX9uea9s1/Wrz7JNf+H4ohbWEOyIyxljOR94gdgoB61RsNL0fXPEytZafMpQe
Y0pdQq46sx9K53RLppJ5be0laRnZpBCTkKTnI54/HB7VT1KL+yfx94MjSXbJr0MgWIFMGXOemOBw
CT247VymlXd1o+ox2esLcW81m21oGG3jOcH1616n8M54IfFcrHT1gkjthGAIyNrcbiM+238zXQfF
fwhba3ZRaotrJNqVv8oWDhpExnafU+n1x3pXtoIwrjV/MsLK7iAS2uWCKT0z6Vm3PiDT47to5bqO
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

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4672b037e8d3b.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gOTAK/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwK
DAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQU
FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgASwBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
+v7vTLZ5rreLlvP3lmjQfxDHy7enBrjdL8EzfCOG9t9M13XBYTM12Tax/aC7sozG+1CT1Hb+HGet
d/8Ab5mI/cEA+/NY2s/EjQNDvv7PvdStY9S8vzTYLKGuAnYmMcge5wK/HcKqvtLUU3J9j1FNQT81
Y/Oz46zD4afFvTL2y0S+m17UlS6D6kbiEyz5x5sQGweYWHYAhsYB6nudD+C3xKttUvPEPivU30PR
1tYb/VDfaq1xPJIUkWIrDsdWIlZmCOQMttPt2HxS8b6d4u+KV1d6x4dsLaGKKOHStXktxPMYQCxD
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

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/anonymous/th_Rascal.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgARQBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
37tidSusdPNf/wBCNTRqckHCKMnJ4AFVbw7dSulPTzXP6mtXR9V0eTwnLHrOnTG6n3RzWw/eOVyR
gHhcHg5zXVJ2Wh5tOHM9TK8TT3OhtbuLbzYZG2s5baAeMADHU59e1aEcoYKy5wanea01K4s7Z7Bh
YqeAzjci9SMZwTwBntV2/tA6ia2h2qx+6eMDtXLGpOnL33ozrlThUj+7Wxm7s5GMg0q4jBJwM/jT
C+1MYwaRj+7ORnv1rsOMilkBU/LyazLjOC2CcVoO6xqSV4PrWbczhgc49hQwMm+3Bcjv2rnr8Agh
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

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4651abc4b93de.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgARABk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
9yiurqW1LtMUbPmER9SBwQPToBn39qj03xFa6nFs1OynmMZMmTaGRR7ocHOPXrXM+EE8UWt9DYXm
kRfZkg8wMpHlru6R9AMjnI57Vt67rd1pOkS2cFsIbppQqRxOrOYznLhR90HaQK82lCUKju7o6Hyy
+FET6Z4Zu7vH26NrpkIRLxQuRjkjgHoT06ZNdPpenJa6ZHAn2e1sxDtiVAGIJBG4vnkkGvK5bi8L
f2a6zDTNQVohJKhWSORkLghsY7EevNcN4e8BXN94glt9cnb7NHNLb4EjB2dVDKQCOQQc/QGt4xgn
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

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/anonymous/th_Redee.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAUQBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
880H5pJGktYzamJIZJQuVUMVG49+MDp6HvU6aPJZeIPsNykb7CrMw+6R6549Dn6U7whcyW/ieyiR
91teJJDJGcYbcpbB/EAfga6vXdJEdpCxyzKDEd/3iACAOOuRx+NccrNXOiKTZyN/aGTTXVYxlpiU
wmcbVHy4HoVH45rF1SFE0FVSM5MuSTEFyQuOhGen866iNnW7a3G1cHYH7AYPT1zxj61NqaR3K+XL
+9CAg54ZTnr9c1EZWepbiedW0XmxIsqRphNoOzk/4mnJZxx2pTHO7qeprob2wiM6G3kKx5ztJ3E8
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
LP/Z

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4683dfaea1a9c.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAUwBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
+e25pp6V0lv4S1W7toZ7W38yORdwYOoH6mpG8F6qgzNHDEPV5kH9aqVWCdnJfeZJMzvCd39l1y2J
OEkbym+h4H64ra8W6KjTPPANsrctxw3/ANeuZvLeSwvGiJHmRMDkHI9QQa9B1RxcWscoYjcAQR3B
Ga4675ZqS6nbQtKLiy18MfH2meGtFGlX4mtpPMZ3k2bkYnucc9AB07V6Jous6NdWs9xbXsU0Sxkl
FlVxH7kduAOor571W03kk43diBVBrCaO08/GUDbCR2OK5ZYXmT5JtX76o05uXdXsW/EWpNq+vXd+
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
gMbjGM9KKKK522fX04Rtt3/M/9k=

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4686dccbd0fbc.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgASgBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
8xtpI7C1SZ0aSaTIG4YAHTIqPU9RkmvkntpWXZGiqcYPCgHPrzmm6g73Ny8hjMcKLiJCP4RwK6n4
aeE4tVvG1HXYJxoNqR5zqCAzFgoXI7DOTjoB2yKZexlaFNqczAi1lmtESRZXVCyx7wVGW/h5OB9a
xrawF3KCsqBS2WBblV6kn8Oa+j/FMUHh2LSr2xtZG0rzPImtYVCwMh/i24wGzjB79DXlvxR+HVz4
X1GO+0pHfR7x/LXnm3ZuPLYk9OTgn8fUsSdzhHQ6jdlY3EMAyEaRuuOgHqabfaZNabQG84NnhOSM
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
Q9oxfPzMY1O4+vWimzEieQA+n8hRRco//9k=

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: text/css;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/styles/basic.css

BODY {
	BORDER-RIGHT: #aaa 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #aaa 1px =
solid; PADDING-LEFT: 0px; FONT-SIZE: 12px; PADDING-BOTTOM: 0px; MARGIN: =
0px; BORDER-LEFT: #aaa 1px solid; COLOR: #333333; PADDING-TOP: 0px; =
BORDER-BOTTOM: #aaa 1px solid; FONT-FAMILY: Verdana, Arial, Helvetica, =
sans-serif; BACKGROUND-COLOR: #eeeeee
}
TABLE {
=09
}
.newstable {
	BORDER-RIGHT: #aaaaaa 2px solid; BORDER-TOP: #aaaaaa 2px solid; =
BORDER-LEFT: #aaaaaa 2px solid; BORDER-BOTTOM: #aaaaaa 2px solid; =
BACKGROUND-COLOR: #e0e0e0
}
TD {
	FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
HEIGHT: 20px
}
#doglist {
	BORDER-RIGHT: #e0e0e0 2px solid; BORDER-TOP: #e0e0e0 2px solid; =
BORDER-LEFT: #e0e0e0 2px solid; WIDTH: 95%; BORDER-BOTTOM: #e0e0e0 2px =
solid
}
#categorylist {
	BORDER-RIGHT: #aaa 1px solid; BORDER-TOP: #aaa 1px solid; BORDER-LEFT: =
#aaa 1px solid; BORDER-BOTTOM: #aaa 1px solid; HEIGHT: 460px
}
#doglist TR {
	BACKGROUND-COLOR: #e0e0e0
}
#doglist TH {
	FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
HEIGHT: 20px; BACKGROUND-COLOR: #aaa
}
#pedigree TH {
	FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
HEIGHT: 20px; BACKGROUND-COLOR: #aaa
}
#categorylist TH {
	FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
HEIGHT: 20px; BACKGROUND-COLOR: #aaa
}
#standard_table TH {
	FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
HEIGHT: 20px; BACKGROUND-COLOR: #aaa
}
#doglist TH {
	TEXT-ALIGN: left
}
#categorylist TH {
	TEXT-ALIGN: left
}
#doglist .tablesubheadline {
	FONT-WEIGHT: bold; COLOR: #666; FONT-STYLE: italic
}
#printable_pedigree {
=09
}
#printable_pedigree TH {
	FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
HEIGHT: 20px
}
#printable_pedigree TD {
	TEXT-ALIGN: center
}
#pedigree {
	BORDER-RIGHT: #aaa 1px double; BORDER-TOP: #aaa 1px double; =
BORDER-LEFT: #aaa 1px double; BORDER-BOTTOM: #aaa 1px double
}
#pedigree TR {
	BACKGROUND-COLOR: #e0e0e0
}
#pedigree TD {
	TEXT-ALIGN: center
}
#standard_table {
	BORDER-RIGHT: #aaa 1px double; BORDER-TOP: #aaa 1px double; =
BORDER-LEFT: #aaa 1px double; BORDER-BOTTOM: #aaa 1px double
}
#standard_table TR {
	BACKGROUND-COLOR: #e0e0e0
}
#standard_table TD {
	PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-SIZE: 10px; PADDING-BOTTOM: =
10px; PADDING-TOP: 10px; TEXT-ALIGN: left
}
H2 {
	FONT-WEIGHT: normal; FONT-SIZE: 20px; PADDING-BOTTOM: 5px; COLOR: #aaa; =
PADDING-TOP: 5px; FONT-STYLE: normal; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif
}
H3 {
	FONT-SIZE: 16px; COLOR: #333333; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif
}
SELECT {
	BORDER-RIGHT: #aaa 1px solid; BORDER-TOP: #aaa 1px solid; FONT-SIZE: =
10px; BORDER-LEFT: #aaa 1px solid; COLOR: #333333; BORDER-BOTTOM: #aaa =
1px solid; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; =
BACKGROUND-COLOR: #e7e7e7
}
INPUT {
	BORDER-RIGHT: #cc9966 1px solid; BORDER-TOP: #cc9966 1px solid; =
PADDING-LEFT: 2px; FONT-SIZE: 10px; BORDER-LEFT: #cc9966 1px solid; =
COLOR: #333333; BORDER-BOTTOM: #cc9966 1px solid; FONT-FAMILY: Verdana, =
Arial, Helvetica, sans-serif; BACKGROUND-COLOR: #e7e7e7
}
TEXTAREA {
	BORDER-RIGHT: #cc9966 1px solid; BORDER-TOP: #cc9966 1px solid; =
PADDING-LEFT: 2px; FONT-SIZE: 10px; BORDER-LEFT: #cc9966 1px solid; =
COLOR: #333333; BORDER-BOTTOM: #cc9966 1px solid; FONT-FAMILY: Verdana, =
Arial, Helvetica, sans-serif; BACKGROUND-COLOR: #e7e7e7
}
INPUT.radio {
	BORDER-RIGHT: 0px; BORDER-TOP: 0px; PADDING-LEFT: 5px; FONT-SIZE: 10px; =
BORDER-LEFT: 0px; COLOR: #333333; BORDER-BOTTOM: 0px; FONT-FAMILY: =
Verdana, Arial, Helvetica, sans-serif; BACKGROUND-COLOR: #eeeeee
}
INPUT[readonly] {
	COLOR: #aaa; BACKGROUND-COLOR: #eeeeee
}
TEXTAREA[readonly] {
	COLOR: #aaa; BACKGROUND-COLOR: #eeeeee
}
.button {
	BORDER-RIGHT: #cc9966 2px solid; BORDER-TOP: #cc9966 1px solid; =
FONT-SIZE: 10px; BORDER-LEFT: #cc9966 1px solid; COLOR: #333333; =
BORDER-BOTTOM: #cc9966 2px solid; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif; BACKGROUND-COLOR: #e7e7e7
}
[disabled].button {
	COLOR: #aaa; BACKGROUND-COLOR: #eeeeee
}
INPUT[disabled] {
	COLOR: #aaa; BACKGROUND-COLOR: #eeeeee
}
LABEL {
	FONT-SIZE: 10px
}
.header {
	MARGIN-LEFT: 150px; BORDER-BOTTOM: #bbb 1px solid; POSITION: relative; =
BACKGROUND-COLOR: #808080
}
.navarea {
	CLEAR: both; PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: =
5px; MARGIN: 0px; COLOR: #aaaaaa; PADDING-TOP: 5px; BORDER-BOTTOM: =
#aaaaaa 1px solid; WHITE-SPACE: nowrap; POSITION: relative; =
BACKGROUND-COLOR: #e0e0e0
}
.selectednavitem {
	BORDER-RIGHT: #aaa 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #aaa 1px =
solid; PADDING-LEFT: 10px; FONT-WEIGHT: bold; PADDING-BOTTOM: 10px; =
BORDER-LEFT: #aaa 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #aaa 1px =
solid; POSITION: relative; BACKGROUND-COLOR: #dfd4be
}
.navitem {
	PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: =
5px; PADDING-TOP: 5px; FONT-FAMILY: Verdana, Arial, Helvetica, =
sans-serif; WHITE-SPACE: nowrap
}
.separator {
	PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; COLOR: =
#aaaaaa; PADDING-TOP: 5px
}
.main {
	BORDER-RIGHT: #e0e0e0 15px solid; BORDER-TOP: #e0e0e0 15px solid; =
MARGIN: 0px; BORDER-LEFT: #e0e0e0 15px solid; BORDER-BOTTOM: #e0e0e0 =
15px solid
}
.content {
	PADDING-RIGHT: 10px; PADDING-LEFT: 10px; FONT-SIZE: 12px; =
PADDING-BOTTOM: 10px; PADDING-TOP: 10px; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif
}
.footer {
	CLEAR: both; PADDING-RIGHT: 20px; PADDING-LEFT: 20px; FONT-SIZE: 9px; =
PADDING-BOTTOM: 5px; PADDING-TOP: 5px; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif; BACKGROUND-COLOR: #aaaaaa
}
A:link {
	COLOR: #cc9966; TEXT-DECORATION: none
}
A:visited {
	COLOR: #cc9966; TEXT-DECORATION: none
}
A:active {
	COLOR: #cc9966; TEXT-DECORATION: none
}
A:hover {
	COLOR: #ff9900; TEXT-DECORATION: none
}
A.a-pict:link {
	BORDER-RIGHT: #cc9966 thin; BORDER-TOP: #cc9966 thin; BORDER-LEFT: =
#cc9966 thin; BORDER-BOTTOM: #cc9966 thin
}
A.a-pict:visited {
	BORDER-RIGHT: #cc9966 thin; BORDER-TOP: #cc9966 thin; BORDER-LEFT: =
#cc9966 thin; BORDER-BOTTOM: #cc9966 thin
}
A.a-pict:active {
	BORDER-RIGHT: #cc9966 thin; BORDER-TOP: #cc9966 thin; BORDER-LEFT: =
#cc9966 thin; BORDER-BOTTOM: #cc9966 thin
}
A.a-pict:hover {
	BORDER-RIGHT: #cc9966; BORDER-TOP: #cc9966; BORDER-LEFT: #cc9966; =
BORDER-BOTTOM: #cc9966
}
A IMG {
	BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: =
0px
}
#sireDiv {
	MARGIN: 1em; WIDTH: 40%; POSITION: relative
}
#damDiv {
	MARGIN: 1em; WIDTH: 40%; POSITION: relative
}
#kennelDiv {
	MARGIN: 1em; WIDTH: 40%; POSITION: relative
}
#sireInput {
	DISPLAY: block; WIDTH: 100%; POSITION: relative
}
#damInput {
	DISPLAY: block; WIDTH: 100%; POSITION: relative
}
#kennelInput {
	DISPLAY: block; WIDTH: 100%; POSITION: relative
}
#sireContainer {
	BORDER-RIGHT: #777 1px solid; BORDER-TOP: #777 1px solid; DISPLAY: =
none; FONT-SIZE: 85%; RIGHT: 4px; BACKGROUND: #eee; OVERFLOW: hidden; =
BORDER-LEFT: #777 1px solid; BOTTOM: 4px; BORDER-BOTTOM: #777 1px solid; =
POSITION: relative
}
#damContainer {
	BORDER-RIGHT: #777 1px solid; BORDER-TOP: #777 1px solid; DISPLAY: =
none; FONT-SIZE: 85%; RIGHT: 4px; BACKGROUND: #eee; OVERFLOW: hidden; =
BORDER-LEFT: #777 1px solid; BOTTOM: 4px; BORDER-BOTTOM: #777 1px solid; =
POSITION: relative
}
#kennelContainer {
	BORDER-RIGHT: #777 1px solid; BORDER-TOP: #777 1px solid; DISPLAY: =
none; FONT-SIZE: 85%; RIGHT: 4px; BACKGROUND: #eee; OVERFLOW: hidden; =
BORDER-LEFT: #777 1px solid; BOTTOM: 4px; BORDER-BOTTOM: #777 1px solid; =
POSITION: relative
}
#sireContainer .yui-content {
	BORDER-RIGHT: #404040 1px solid; BORDER-TOP: #404040 1px solid; =
Z-INDEX: 9050; BACKGROUND: #fff; OVERFLOW: hidden; BORDER-LEFT: #404040 =
1px solid; WIDTH: 100%; BORDER-BOTTOM: #404040 1px solid; POSITION: =
absolute
}
#damContainer .yui-content {
	BORDER-RIGHT: #404040 1px solid; BORDER-TOP: #404040 1px solid; =
Z-INDEX: 9050; BACKGROUND: #fff; OVERFLOW: hidden; BORDER-LEFT: #404040 =
1px solid; WIDTH: 100%; BORDER-BOTTOM: #404040 1px solid; POSITION: =
absolute
}
#kennelContainer .yui-content {
	BORDER-RIGHT: #404040 1px solid; BORDER-TOP: #404040 1px solid; =
Z-INDEX: 9050; BACKGROUND: #fff; OVERFLOW: hidden; BORDER-LEFT: #404040 =
1px solid; WIDTH: 100%; BORDER-BOTTOM: #404040 1px solid; POSITION: =
absolute
}
#sireContainer UL {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 5px; WIDTH: =
100%; PADDING-TOP: 5px; LIST-STYLE-TYPE: none; POSITION: relative
}
#damContainer UL {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 5px; WIDTH: =
100%; PADDING-TOP: 5px; LIST-STYLE-TYPE: none; POSITION: relative
}
#kennelContainer UL {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 5px; WIDTH: =
100%; PADDING-TOP: 5px; LIST-STYLE-TYPE: none; POSITION: relative
}
#sireContainer LI {
	PADDING-RIGHT: 5px; DISPLAY: list-item; PADDING-LEFT: 5px; =
PADDING-BOTTOM: 0px; CURSOR: default; PADDING-TOP: 0px; WHITE-SPACE: =
nowrap
}
#damContainer LI {
	PADDING-RIGHT: 5px; DISPLAY: list-item; PADDING-LEFT: 5px; =
PADDING-BOTTOM: 0px; CURSOR: default; PADDING-TOP: 0px; WHITE-SPACE: =
nowrap
}
#kennelContainer LI {
	PADDING-RIGHT: 5px; DISPLAY: list-item; PADDING-LEFT: 5px; =
PADDING-BOTTOM: 0px; CURSOR: default; PADDING-TOP: 0px; WHITE-SPACE: =
nowrap
}
#sireContainer LI.highlight {
	BACKGROUND: #ddd
}
#damContainer LI.highlight {
	BACKGROUND: #ddd
}
#kennelContainer LI.highlight {
	BACKGROUND: #ddd
}
.suckertreemenu UL {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: =
0px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none
}
.suckertreemenu UL LI {
	DISPLAY: inline; FLOAT: left; POSITION: relative; BACKGROUND-COLOR: =
#eeeeee
}
.suckertreemenu UL LI A {
	BORDER-RIGHT: #aaaaaa 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: =
#aaaaaa 1px solid; DISPLAY: block; PADDING-LEFT: 5px; FONT-SIZE: 12px; =
PADDING-BOTTOM: 5px; BORDER-LEFT: #aaaaaa 0px solid; PADDING-TOP: 5px; =
BORDER-BOTTOM: #aaaaaa 1px solid; FONT-FAMILY: Verdana, Arial, =
Helvetica, sans-serif; WHITE-SPACE: nowrap; TEXT-DECORATION: none
}
.suckertreemenu UL LI UL {
	DISPLAY: block; LEFT: 0px; VISIBILITY: hidden; POSITION: absolute; TOP: =
1em
}
.suckertreemenu UL LI UL LI {
	DISPLAY: list-item; FLOAT: none
}
.suckertreemenu UL LI UL LI UL {
	LEFT: 159px; TOP: 0px
}
.suckertreemenu UL LI UL LI A {
	BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #ccc 1px =
solid; DISPLAY: block; PADDING-LEFT: 5px; FONT-SIZE: 12px; =
PADDING-BOTTOM: 5px; BORDER-LEFT: #ccc 1px solid; WIDTH: 160px; =
PADDING-TOP: 5px; BORDER-BOTTOM: #ccc 1px solid; FONT-FAMILY: Verdana, =
Arial, Helvetica, sans-serif; WHITE-SPACE: nowrap; TEXT-DECORATION: none
}
.suckertreemenu UL LI A:hover {
	COLOR: #e0e0e0; BACKGROUND-COLOR: #cc9966
}
.suckertreemenu .mainfoldericon {
=09
}
.suckertreemenu .subfoldericon {
	BACKGROUND: url(../images/sort_desc_active.gif) no-repeat right center
}
* HTML P#iepara {
	PADDING-TOP: 1em
}

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: text/css;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/styles/yui/container.css

.overlay {
	DISPLAY: block; POSITION: absolute
}
.tt {
	BORDER-RIGHT: #fcc90d 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: =
#fcc90d 1px solid; PADDING-LEFT: 2px; VISIBILITY: hidden; =
PADDING-BOTTOM: 2px; FONT: 100% sans-serif; BORDER-LEFT: #fcc90d 1px =
solid; WIDTH: auto; COLOR: #333; PADDING-TOP: 2px; BORDER-BOTTOM: =
#fcc90d 1px solid; POSITION: absolute; BACKGROUND-COLOR: #fdffb4
}
* HTML BODY.masked SELECT {
	VISIBILITY: hidden
}
* HTML DIV.panel-container SELECT {
	VISIBILITY: inherit
}
* HTML DIV.drag SELECT {
	VISIBILITY: hidden
}
* HTML DIV.hide-select SELECT {
	VISIBILITY: hidden
}
.mask {
	DISPLAY: none; FILTER: alpha(opacity=3D50); LEFT: 0px; POSITION: =
absolute; TOP: 0px; BACKGROUND-COLOR: #222; -moz-opacity: 0.5; opacity: =
.50
}
[id].mask {
	POSITION: fixed
}
.hide-scrollbars * {
	OVERFLOW: hidden
}
.hide-scrollbars TEXTAREA {
	DISPLAY: none; OVERFLOW: hidden
}
.hide-scrollbars SELECT {
	DISPLAY: none; OVERFLOW: hidden
}
.show-scrollbars TEXTAREA {
	OVERFLOW: visible
}
.show-scrollbars SELECT {
	OVERFLOW: visible
}
.panel-container {
	Z-INDEX: 6; VISIBILITY: hidden; OVERFLOW: visible; WIDTH: auto; =
POSITION: absolute; BACKGROUND-COLOR: transparent
}
.matte {
	PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; =
PADDING-TOP: 3px; BACKGROUND-COLOR: #eeeeee
}
.matte .underlay {
	DISPLAY: none
}
.shadow {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; =
PADDING-TOP: 0px; BACKGROUND-COLOR: transparent
}
.shadow .underlay {
	FILTER: alpha(opacity=3D70); LEFT: 3px; VISIBILITY: inherit; WIDTH: =
100%; POSITION: absolute; TOP: 3px; HEIGHT: 100%; BACKGROUND-COLOR: =
#e0e0e0; -moz-opacity: 0.7; opacity: .70
}
.panel {
	BORDER-RIGHT: #aaa 1px solid; BORDER-TOP: #aaa 1px solid; Z-INDEX: 1; =
LEFT: 0px; VISIBILITY: hidden; FONT: 1em Arial; OVERFLOW: auto; =
BORDER-LEFT: #aaa 1px solid; BORDER-BOTTOM: #aaa 1px solid; POSITION: =
relative; TOP: 0px; BORDER-COLLAPSE: separate; BACKGROUND-COLOR: #eeeeee
}
.panel .hd {
	BORDER-RIGHT: #eeeeee 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: =
#eeeeee 1px solid; PADDING-LEFT: 2px; FONT-WEIGHT: bold; FONT-SIZE: 1em; =
PADDING-BOTTOM: 2px; OVERFLOW: hidden; BORDER-LEFT: #eeeeee 1px solid; =
COLOR: #eeeeee; PADDING-TOP: 2px; BORDER-BOTTOM: #333333 1px solid; =
HEIGHT: 20px; BACKGROUND-COLOR: #aaaaaa
}
.panel .bd {
	PADDING-RIGHT: 4px; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; OVERFLOW: =
hidden; PADDING-TOP: 4px
}
.panel .bd P {
	MARGIN: 0px 0px 1em
}
.panel .close {
	PADDING-RIGHT: 0px; PADDING-LEFT: 0px; Z-INDEX: 6; RIGHT: 4px; =
VISIBILITY: inherit; PADDING-BOTTOM: 0px; MARGIN: 0px; WIDTH: 12px; =
CURSOR: pointer; PADDING-TOP: 0px; BACKGROUND-REPEAT: no-repeat; =
POSITION: absolute; TOP: 5px; HEIGHT: 12px
}
.panel .nonsecure {
	BACKGROUND-IMAGE: url(close.gif)
}
.panel .secure {
	BACKGROUND-IMAGE: =
url(https://a248.e.akamai.net/sec.yimg.com/i/nt/ic/ut/alt3/close12_1.gif)=

}
.panel .ft {
	PADDING-RIGHT: 4px; PADDING-LEFT: 4px; PADDING-BOTTOM: 4px; OVERFLOW: =
hidden; PADDING-TOP: 4px
}
.simple-dialog .bd .icon {
	FLOAT: left; WIDTH: 16px; MARGIN-RIGHT: 10px; BACKGROUND-REPEAT: =
no-repeat; HEIGHT: 16px
}
.dialog .ft {
	PADDING-RIGHT: 5px; PADDING-BOTTOM: 5px; TEXT-ALIGN: right
}
.simple-dialog .ft {
	PADDING-RIGHT: 5px; PADDING-BOTTOM: 5px; TEXT-ALIGN: right
}
.dialog FORM {
	MARGIN: 0px
}
.simple-dialog FORM {
	MARGIN: 0px
}
.button-group BUTTON {
	BORDER-RIGHT: #797979 2px solid; PADDING-RIGHT: 2px; BORDER-TOP: #fff =
2px solid; PADDING-LEFT: 2px; PADDING-BOTTOM: 2px; MARGIN: 2px; FONT: =
100 76% verdana; VERTICAL-ALIGN: middle; BORDER-LEFT: #fff 2px solid; =
CURSOR: hand; COLOR: #333; PADDING-TOP: 2px; BORDER-BOTTOM: #797979 2px =
solid; BACKGROUND-COLOR: #e4e4e4; TEXT-DECORATION: none
}
.button-group BUTTON.default {
	FONT-WEIGHT: bold
}
.button-group BUTTON:hover {
	BORDER-RIGHT: #90a029 2px solid; BORDER-TOP: #fff 2px solid; =
BORDER-LEFT: #fff 2px solid; BORDER-BOTTOM: #90a029 2px solid; =
BACKGROUND-COLOR: #ebf09e
}
.button-group BUTTON.hover {
	BORDER-RIGHT: #90a029 2px solid; BORDER-TOP: #fff 2px solid; =
BORDER-LEFT: #fff 2px solid; BORDER-BOTTOM: #90a029 2px solid; =
BACKGROUND-COLOR: #ebf09e
}
.button-group BUTTON:active {
	BORDER-RIGHT: #e4e4e4 2px solid; BORDER-TOP: #333 2px solid; =
BORDER-LEFT: #333 2px solid; BORDER-BOTTOM: #e4e4e4 2px solid; =
BACKGROUND-COLOR: #bbb
}

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/js/yui/yahoo.js

/*                                                                       =
                                                                         =
     =20
Copyright (c) 2006, Yahoo! Inc. All rights reserved.                     =
                                                                         =
     =20
Code licensed under the BSD License:                                     =
                                                                         =
     =20
http://developer.yahoo.net/yui/license.txt                               =
                                                                         =
     =20
version: 0.10.0                                                          =
                                                                         =
     =20
*/=20

/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

/**
 * The Yahoo global namespace
 * @constructor
 */
var YAHOO =3D window.YAHOO || {};

/**
 * Returns the namespace specified and creates it if it doesn't exist
 *
 * YAHOO.namespace("property.package");
 * YAHOO.namespace("YAHOO.property.package");
 *
 * Either of the above would create YAHOO.property, then
 * YAHOO.property.package
 *
 * @param  {String} sNameSpace String representation of the desired=20
 *                             namespace
 * @return {Object}            A reference to the namespace object
 */
YAHOO.namespace =3D function( sNameSpace ) {

    if (!sNameSpace || !sNameSpace.length) {
        return null;
    }

    var levels =3D sNameSpace.split(".");

    var currentNS =3D YAHOO;

    // YAHOO is implied, so it is ignored if it is included
    for (var i=3D(levels[0] =3D=3D "YAHOO") ? 1 : 0; i<levels.length; =
++i) {
        currentNS[levels[i]] =3D currentNS[levels[i]] || {};
        currentNS =3D currentNS[levels[i]];
    }

    return currentNS;
};

/**
 * Global log method.
 */
YAHOO.log =3D function(sMsg,sCategory) {
    if(YAHOO.widget.Logger) {
        YAHOO.widget.Logger.log(null, sMsg, sCategory);
    } else {
        return false;
    }
};

YAHOO.namespace("util");
YAHOO.namespace("widget");
YAHOO.namespace("example");

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/js/yui/dom.js

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
*/

/**
 * @class Provides helper methods for DOM elements.
 */
YAHOO.util.Dom =3D function() {
   var ua =3D navigator.userAgent.toLowerCase();
   var isOpera =3D (ua.indexOf('opera') !=3D -1);
   var isIE =3D (ua.indexOf('msie') !=3D -1 && !isOpera); // not opera =
spoof
   var id_counter =3D 0;
  =20
   return {
      /**
       * Returns an HTMLElement reference
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID for getting a DOM reference, an actual DOM reference, or an Array =
of IDs and/or HTMLElements.
       * @return {HTMLElement/Array} A DOM reference to an HTML element =
or an array of HTMLElements.
       */
      get: function(el) {
         if (typeof el !=3D 'string' && !(el instanceof Array) )
         { // assuming HTMLElement or HTMLCollection, so pass back as is
            return el;
         }
        =20
         if (typeof el =3D=3D 'string')=20
         { // ID
            return document.getElementById(el);
         }
         else
         { // array of ID's and/or elements
            var collection =3D [];
            for (var i =3D 0, len =3D el.length; i < len; ++i)
            {
               collection[collection.length] =3D this.get(el[i]);
            }
           =20
            return collection;
         }

         return null; // safety, should never happen
      },
  =20
      /**
       * Normalizes currentStyle and ComputedStyle.
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {String} property The style property whose value is =
returned.
       * @return {String/Array} The current value of the style property =
for the element(s).
       */
      getStyle: function(el, property) {
         var f =3D function(el) {
            var value =3D null;
            var dv =3D document.defaultView;
           =20
            if (property =3D=3D 'opacity' && el.filters)=20
            {// IE opacity
               value =3D 1;
               try {
                  value =3D =
el.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100;
               } catch(e) {
                  try {
                     value =3D el.filters.item('alpha').opacity / 100;
                  } catch(e) {}
               }
            }
            else if (el.style[property])=20
            {
               value =3D el.style[property];
            }
            else if (el.currentStyle && el.currentStyle[property]) {
               value =3D el.currentStyle[property];
            }
            else if ( dv && dv.getComputedStyle )
            {  // convert camelCase to hyphen-case
              =20
               var converted =3D '';
               for(var i =3D 0, len =3D property.length;i < len; ++i) {
                  if (property.charAt(i) =3D=3D =
property.charAt(i).toUpperCase())=20
                  {
                     converted =3D converted + '-' + =
property.charAt(i).toLowerCase();
                  } else {
                     converted =3D converted + property.charAt(i);
                  }
               }
              =20
               if (dv.getComputedStyle(el, '') && =
dv.getComputedStyle(el, '').getPropertyValue(converted)) {
                  value =3D dv.getComputedStyle(el, =
'').getPropertyValue(converted);
               }
            }
     =20
            return value;
         };
        =20
         return this.batch(el, f, this, true);
      },
  =20
      /**
       * Wrapper for setting style properties of HTMLElements.  =
Normalizes "opacity" across modern browsers.
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {String} property The style property to be set.
       * @param {String} val The value to apply to the given property.
       */
      setStyle: function(el, property, val) {
         var f =3D function(el) {
            switch(property) {
               case 'opacity' :
                  if (isIE && typeof el.style.filter =3D=3D 'string') { =
// in case not appended
                     el.style.filter =3D 'alpha(opacity=3D' + val * 100 =
+ ')';
                    =20
                     if (!el.currentStyle || !el.currentStyle.hasLayout) =
{
                        el.style.zoom =3D 1; // when no layout or cant =
tell
                     }
                  } else {
                     el.style.opacity =3D val;
                     el.style['-moz-opacity'] =3D val;
                     el.style['-khtml-opacity'] =3D val;
                  }

                  break;
               default :
                  el.style[property] =3D val;
            }
           =20
         };
        =20
         this.batch(el, f, this, true);
      },
     =20
      /**
       * Gets the current position of an element based on page =
coordinates.  Element must be part of the DOM tree to have page =
coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       @ return {Array} The XY position of the element(s)
       */
      getXY: function(el) {
         var f =3D function(el) {
  =20
         // has to be part of document to have pageXY
            if (el.parentNode =3D=3D=3D null || this.getStyle(el, =
'display') =3D=3D 'none') {
               return false;
            }
           =20
            var parent =3D null;
            var pos =3D [];
            var box;
           =20
            if (el.getBoundingClientRect) { // IE
               box =3D el.getBoundingClientRect();
               var scrollTop =3D =
Math.max(document.documentElement.scrollTop, document.body.scrollTop);
               var scrollLeft =3D =
Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
              =20
               return [box.left + scrollLeft, box.top + scrollTop];
            }
            else if (document.getBoxObjectFor) { // gecko
               box =3D document.getBoxObjectFor(el);
              =20
               var borderLeft =3D parseInt(this.getStyle(el, =
'borderLeftWidth'));
               var borderTop =3D parseInt(this.getStyle(el, =
'borderTopWidth'));
              =20
               pos =3D [box.x - borderLeft, box.y - borderTop];
            }
            else { // safari & opera
               pos =3D [el.offsetLeft, el.offsetTop];
               parent =3D el.offsetParent;
               if (parent !=3D el) {
                  while (parent) {
                     pos[0] +=3D parent.offsetLeft;
                     pos[1] +=3D parent.offsetTop;
                     parent =3D parent.offsetParent;
                  }
               }
               if (
                  ua.indexOf('opera') !=3D -1=20
                  || ( ua.indexOf('safari') !=3D -1 && this.getStyle(el, =
'position') =3D=3D 'absolute' )=20
               ) {
                  pos[0] -=3D document.body.offsetLeft;
                  pos[1] -=3D document.body.offsetTop;
               }=20
            }
           =20
            if (el.parentNode) { parent =3D el.parentNode; }
            else { parent =3D null; }
     =20
            while (parent && parent.tagName !=3D 'BODY' && =
parent.tagName !=3D 'HTML')=20
            { // account for any scrolled ancestors
               pos[0] -=3D parent.scrollLeft;
               pos[1] -=3D parent.scrollTop;
     =20
               if (parent.parentNode) { parent =3D parent.parentNode; }=20
               else { parent =3D null; }
            }
     =20
            return pos;
         };
        =20
         return this.batch(el, f, this, true);
      },
     =20
      /**
       * Gets the current X position of an element based on page =
coordinates.  The element must be part of the DOM tree to have page =
coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       * @return {String/Array} The X position of the element(s)
       */
      getX: function(el) {
         return this.getXY(el)[0];
      },
     =20
      /**
       * Gets the current Y position of an element based on page =
coordinates.  Element must be part of the DOM tree to have page =
coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       * @return {String/Array} The Y position of the element(s)
       */
      getY: function(el) {
         return this.getXY(el)[1];
      },
     =20
      /**
       * Set the position of an html element in page coordinates, =
regardless of how the element is positioned.
       * The element(s) must be part of the DOM tree to have page =
coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       * @param {Array} pos Contains X & Y values for new position =
(coordinates are page-based)
       * @param {Boolean} noRetry By default we try and set the position =
a second time if the first fails
       */
      setXY: function(el, pos, noRetry) {
         var f =3D function(el) {
  =20
            var style_pos =3D this.getStyle(el, 'position');
            if (style_pos =3D=3D 'static') { // default to relative
               this.setStyle(el, 'position', 'relative');
               style_pos =3D 'relative';
            }
           =20
            var pageXY =3D YAHOO.util.Dom.getXY(el);
            if (pageXY =3D=3D=3D false) { return false; } // has to be =
part of doc to have pageXY
           =20
            var delta =3D [
               parseInt( YAHOO.util.Dom.getStyle(el, 'left'), 10 ),
               parseInt( YAHOO.util.Dom.getStyle(el, 'top'), 10 )
            ];
        =20
            if ( isNaN(delta[0]) ) // defaults to 'auto'
            {=20
               delta[0] =3D (style_pos =3D=3D 'relative') ? 0 : =
el.offsetLeft;
            }=20
            if ( isNaN(delta[1]) ) // defaults to 'auto'
            {=20
               delta[1] =3D (style_pos =3D=3D 'relative') ? 0 : =
el.offsetTop;
            }=20
     =20
            if (pos[0] !=3D=3D null) { el.style.left =3D pos[0] - =
pageXY[0] + delta[0] + 'px'; }
            if (pos[1] !=3D=3D null) { el.style.top =3D pos[1] - =
pageXY[1] + delta[1] + 'px'; }
     =20
            var newXY =3D this.getXY(el);
     =20
            // if retry is true, try one more time if we miss
            if (!noRetry && (newXY[0] !=3D pos[0] || newXY[1] !=3D =
pos[1]) ) {
               var retry =3D function() { YAHOO.util.Dom.setXY(el, pos, =
true); };
               setTimeout(retry, 0); // "delay" for IE resize timing =
issue
            }
         };
        =20
         this.batch(el, f, this, true);
      },
     =20
      /**
       * Set the X position of an html element in page coordinates, =
regardless of how the element is positioned.
       * The element must be part of the DOM tree to have page =
coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {Int} x to use as the X coordinate for the element(s).
       */
      setX: function(el, x) {
         this.setXY(el, [x, null]);
      },
     =20
      /**
       * Set the Y position of an html element in page coordinates, =
regardless of how the element is positioned.
       * The element must be part of the DOM tree to have page =
coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {Int} x to use as the Y coordinate for the element(s).
       */
      setY: function(el, y) {
         this.setXY(el, [null, y]);
      },
     =20
      /**
       * Returns the region position of the given element.
       * The element must be part of the DOM tree to have a region =
(display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as =
an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @return {Region/Array} A Region or array of Region instances =
containing "top, left, bottom, right" member data.
       */
      getRegion: function(el) {
         var f =3D function(el) {
            return new YAHOO.util.Region.getRegion(el);
         };
        =20
         return this.batch(el, f, this, true);
      },
     =20
      /**
       * Returns the width of the client (viewport).
       * Now using getViewportWidth.  This interface left intact for =
back compat.
       * @return {Int} The width of the viewable area of the page.
       */
      getClientWidth: function() {
         return this.getViewportWidth();
      },
     =20
      /**
       * Returns the height of the client (viewport).
       * Now using getViewportHeight.  This interface left intact for =
back compat.
       * @return {Int} The height of the viewable area of the page.
       */
      getClientHeight: function() {
         return this.getViewportHeight();
      },

      /**
       * Returns a array of HTMLElements with the given class
       * For optimized performance, include a tag and/or root node if =
possible
       * @param {String} className The class name to match against
       * @param {String} tag (optional) The tag name of the elements =
being collected
       * @param {String/HTMLElement} root (optional) The HTMLElement or =
an ID to use as the starting point=20
       * @return {Array} An array of elements that have the given class =
name
       */
      getElementsByClassName: function(className, tag, root) {
         var re =3D new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
        =20
         var method =3D function(el) { return re.test(el['className']); =
};
        =20
         return this.getElementsBy(method, tag, root);
      },

      /**
       * Determines whether an HTMLElement has the given className
       * @param {String/HTMLElement/Array} el The element or collection =
to test
       * @param {String} className the class name to search for
       * @return {Boolean/Array} A boolean value or array of boolean =
values
       */
      hasClass: function(el, className) {
         var f =3D function(el) {
            var re =3D new RegExp('(?:^|\\s+)' + className + =
'(?:\\s+|$)');
            return re.test(el['className']);
         };
        =20
         return this.batch(el, f, this, true);
      },
  =20
      /**
       * Adds a class name to a given element or collection of elements
       * @param {String/HTMLElement/Array} el The element or collection =
to add the class to
       * @param {String} className the class name to add to the class =
attribute
       */
      addClass: function(el, className) {
         var f =3D function(el) {
            if (this.hasClass(el, className)) { return; } // already =
present
           =20
            el['className'] =3D [el['className'], className].join(' ');
         };
        =20
         this.batch(el, f, this, true);
      },
  =20
      /**
       * Removes a class name from a given element or collection of =
elements
       * @param {String/HTMLElement/Array} el The element or collection =
to remove the class from
       * @param {String} className the class name to remove from the =
class attribute
       */
      removeClass: function(el, className) {
         var f =3D function(el) {
            if (!this.hasClass(el, className)) { return; } // not =
present
           =20
            var re =3D new RegExp('(?:^|\\s+)' + className + =
'(?:\\s+|$)', 'g');
            var c =3D el['className'];
           =20
            el['className'] =3D c.replace( re, ' ');
         };
        =20
         this.batch(el, f, this, true);
      },
     =20
      /**
       * Replace a class with another class for a given element or =
collection of elements.
       * If no oldClassName is present, the newClassName is simply =
added.
       * @param {String/HTMLElement/Array} el The element or collection =
to remove the class from
       * @param {String} oldClassName the class name to be replaced
       * @param {String} newClassName the class name that will be =
replacing the old class name
       */
      replaceClass: function(el, oldClassName, newClassName) {
         var f =3D function(el) {
            this.removeClass(el, oldClassName);
            this.addClass(el, newClassName);
         };
        =20
         this.batch(el, f, this, true);
      },
     =20
      /**
       * Generates a unique ID
       * @param {String/HTMLElement/Array} el (optional) An optional =
element array of elements to add an ID to (no ID is added if one is =
already present)
       * @param {String} prefix (optional) an optional prefix to use =
(defaults to "yui-gen")
       * @return {String/Array} The generated ID, or array of generated =
IDs (or original ID if already present on an element)
       */
      generateId: function(el, prefix) {
         prefix =3D prefix || 'yui-gen';
        =20
         var f =3D function(el) {
            el =3D el || {}; // just generating ID in this case
           =20
            if (!el.id) { el.id =3D prefix + id_counter++; } // dont =
override existing
           =20
            return el.id;
         };
        =20
         return this.batch(el, f, this, true);
      },
     =20
      /**
       * Determines whether an HTMLElement is an ancestor of another =
HTML element in the DOM hierarchy
       * @param {String/HTMLElement} haystack The possible ancestor
       * @param {String/HTMLElement} needle The possible descendent
       * @return {Boolean} Whether or not the haystack is an ancestor of =
needle
       */
      isAncestor: function(haystack, needle) {
         haystack =3D this.get(haystack);
         if (!haystack || !needle) { return false; }
        =20
         var f =3D function(needle) {
            if (haystack.contains && ua.indexOf('safari') < 0)=20
            { // safari "contains" is broken
               return haystack.contains(needle);
            }
            else if ( haystack.compareDocumentPosition )=20
            {
               return !!(haystack.compareDocumentPosition(needle) & 16);
            }
            else=20
            { // loop up and test each parent
               var parent =3D needle.parentNode;
              =20
               while (parent) {
                  if (parent =3D=3D haystack) {
                     return true;
                  }
                  else if (parent.tagName =3D=3D 'HTML') {
                     return false;
                  }
                 =20
                  parent =3D parent.parentNode;
               }
              =20
               return false;
            }   =20
         };
        =20
         return this.batch(needle, f, this, true);    =20
      },
     =20
      /**
       * Determines whether an HTMLElement is present in the current =
document
       * @param {String/HTMLElement} el The element to search for
       * @return {Boolean} Whether or not the element is present in the =
current document
       */
      inDocument: function(el) {
         var f =3D function(el) {
            return this.isAncestor(document.documentElement, el);
         };
        =20
         return this.batch(el, f, this, true);
      },
     =20
      /**
       * Returns a array of HTMLElements that pass the test applied by =
supplied boolean method
       * For optimized performance, include a tag and/or root node if =
possible
       * @param {Function} method A boolean method to test elements with
       * @param {String} tag (optional) The tag name of the elements =
being collected
       * @param {String/HTMLElement} root (optional) The HTMLElement or =
an ID to use as the starting point=20
       */
      getElementsBy: function(method, tag, root) {
         tag =3D tag || '*';
         root =3D this.get(root) || document;
        =20
         var nodes =3D [];
         var elements =3D root.getElementsByTagName(tag);
        =20
         if ( !elements.length && (tag =3D=3D '*' && root.all) ) {
            elements =3D root.all; // IE < 6
         }
        =20
         for (var i =3D 0, len =3D elements.length; i < len; ++i)=20
         {
            if ( method(elements[i]) ) { nodes[nodes.length] =3D =
elements[i]; }
         }

         return nodes;
      },
     =20
      /**
       * Returns an array of elements that have had the supplied method =
applied.
       * The method is called with the element(s) as the first arg, and =
the optional param as the second ( method(el, o) )
       * @param {String/HTMLElement/Array} el (optional) An element or =
array of elements to apply the method to
       * @param {Function} method The method to apply to the element(s)
       * @param {Generic} (optional) o An optional arg that is passed to =
the supplied method
       * @param {Boolean} (optional) override Whether or not to override =
the scope of "method" with "o"
       * @return {HTMLElement/Array} The element(s) with the method =
applied
       */
      batch: function(el, method, o, override) {
         el =3D this.get(el);
         var scope =3D (override) ? o : window;
        =20
         if (!el || el.tagName || !el.length)=20
         { // is null or not a collection (tagName for SELECT and others =
that can be both an element and a collection)
            return method.call(scope, el, o);
         }=20
        =20
         var collection =3D [];
        =20
         for (var i =3D 0, len =3D el.length; i < len; ++i)
         {
            collection[collection.length] =3D method.call(scope, el[i], =
o);
         }
        =20
         return collection;
      },
     =20
      /**
       * Returns the height of the document.
       * @return {Int} The height of the actual document (which includes =
the body and its margin).
       */
      getDocumentHeight: function() {
         var scrollHeight=3D-1,windowHeight=3D-1,bodyHeight=3D-1;
         var marginTop =3D parseInt(this.getStyle(document.body, =
'marginTop'), 10);
         var marginBottom =3D parseInt(this.getStyle(document.body, =
'marginBottom'), 10);
        =20
         var mode =3D document.compatMode;
        =20
         if ( (mode || isIE) && !isOpera ) { // (IE, Gecko)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  scrollHeight =3D ((window.innerHeight && =
window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
                  windowHeight =3D =
[document.documentElement.clientHeight,self.innerHeight||-1].sort(functio=
n(a, b){return(a-b);})[1];
                  bodyHeight =3D document.body.offsetHeight + marginTop =
+ marginBottom;
                  break;
              =20
               default: // Quirks
                  scrollHeight =3D document.body.scrollHeight;
                  bodyHeight =3D document.body.clientHeight;
            }
         } else { // Safari & Opera
            scrollHeight =3D document.documentElement.scrollHeight;
            windowHeight =3D self.innerHeight;
            bodyHeight =3D document.documentElement.clientHeight;
         }
     =20
         var h =3D =
[scrollHeight,windowHeight,bodyHeight].sort(function(a, =
b){return(a-b);});
         return h[2];
      },
     =20
      /**
       * Returns the width of the document.
       * @return {Int} The width of the actual document (which includes =
the body and its margin).
       */
      getDocumentWidth: function() {
         var docWidth=3D-1,bodyWidth=3D-1,winWidth=3D-1;
         var marginRight =3D parseInt(this.getStyle(document.body, =
'marginRight'), 10);
         var marginLeft =3D parseInt(this.getStyle(document.body, =
'marginLeft'), 10);
        =20
         var mode =3D document.compatMode;
        =20
         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  docWidth =3D document.documentElement.clientWidth;
                  bodyWidth =3D document.body.offsetWidth + marginLeft + =
marginRight;
                  winWidth =3D self.innerWidth || -1;
                  break;
                 =20
               default: // Quirks
                  bodyWidth =3D document.body.clientWidth;
                  winWidth =3D document.body.scrollWidth;
                  break;
            }
         } else { // Safari
            docWidth =3D document.documentElement.clientWidth;
            bodyWidth =3D document.body.offsetWidth + marginLeft + =
marginRight;
            winWidth =3D self.innerWidth;
         }
     =20
         var w =3D [docWidth,bodyWidth,winWidth].sort(function(a, =
b){return(a-b);});
         return w[2];
      },

      /**
       * Returns the current height of the viewport.
       * @return {Int} The height of the viewable area of the page =
(excludes scrollbars).
       */
      getViewportHeight: function() {
         var height =3D -1;
         var mode =3D document.compatMode;
     =20
         if ( (mode || isIE) && !isOpera ) {
            switch (mode) { // (IE, Gecko)
               case 'CSS1Compat': // Standards mode
                  height =3D document.documentElement.clientHeight;
                  break;
     =20
               default: // Quirks
                  height =3D document.body.clientHeight;
            }
         } else { // Safari, Opera
            height =3D self.innerHeight;
         }
     =20
         return height;
      },
     =20
      /**
       * Returns the current width of the viewport.
       * @return {Int} The width of the viewable area of the page =
(excludes scrollbars).
       */
     =20
      getViewportWidth: function() {
         var width =3D -1;
         var mode =3D document.compatMode;
        =20
         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
            case 'CSS1Compat': // Standards mode=20
               width =3D document.documentElement.clientWidth;
               break;
              =20
            default: // Quirks
               width =3D document.body.clientWidth;
            }
         } else { // Safari
            width =3D self.innerWidth;
         }
        =20
         return width;
      }
   };
}();

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
*/

/**
 * @class A region is a representation of an object on a grid.  It is =
defined
 * by the top, right, bottom, left extents, so is rectangular by =
default.  If=20
 * other shapes are required, this class could be extended to support =
it.
 *
 * @param {int} t the top extent
 * @param {int} r the right extent
 * @param {int} b the bottom extent
 * @param {int} l the left extent
 * @constructor
 */
YAHOO.util.Region =3D function(t, r, b, l) {

    /**
     * The region's top extent
     * @type int
     */
    this.top =3D t;
   =20
    /**
     * The region's top extent as index, for symmetry with set/getXY
     * @type int
     */
    this[1] =3D t;

    /**
     * The region's right extent
     * @type int
     */
    this.right =3D r;

    /**
     * The region's bottom extent
     * @type int
     */
    this.bottom =3D b;

    /**
     * The region's left extent
     * @type int
     */
    this.left =3D l;
   =20
    /**
     * The region's left extent as index, for symmetry with set/getXY
     * @type int
     */
    this[0] =3D l;
};

/**
 * Returns true if this region contains the region passed in
 *
 * @param  {Region}  region The region to evaluate
 * @return {boolean}        True if the region is contained with this =
region,=20
 *                          else false
 */
YAHOO.util.Region.prototype.contains =3D function(region) {
    return ( region.left   >=3D this.left   &&=20
             region.right  <=3D this.right  &&=20
             region.top    >=3D this.top    &&=20
             region.bottom <=3D this.bottom    );

    // this.logger.debug("does " + this + " contain " + region + " ... " =
+ ret);
};

/**
 * Returns the area of the region
 *
 * @return {int} the region's area
 */
YAHOO.util.Region.prototype.getArea =3D function() {
    return ( (this.bottom - this.top) * (this.right - this.left) );
};

/**
 * Returns the region where the passed in region overlaps with this one
 *
 * @param  {Region} region The region that intersects
 * @return {Region}        The overlap region, or null if there is no =
overlap
 */
YAHOO.util.Region.prototype.intersect =3D function(region) {
    var t =3D Math.max( this.top,    region.top    );
    var r =3D Math.min( this.right,  region.right  );
    var b =3D Math.min( this.bottom, region.bottom );
    var l =3D Math.max( this.left,   region.left   );
   =20
    if (b >=3D t && r >=3D l) {
        return new YAHOO.util.Region(t, r, b, l);
    } else {
        return null;
    }
};

/**
 * Returns the region representing the smallest region that can contain =
both
 * the passed in region and this region.
 *
 * @param  {Region} region The region that to create the union with
 * @return {Region}        The union region
 */
YAHOO.util.Region.prototype.union =3D function(region) {
    var t =3D Math.min( this.top,    region.top    );
    var r =3D Math.max( this.right,  region.right  );
    var b =3D Math.max( this.bottom, region.bottom );
    var l =3D Math.min( this.left,   region.left   );

    return new YAHOO.util.Region(t, r, b, l);
};

/**
 * toString
 * @return string the region properties
 */
YAHOO.util.Region.prototype.toString =3D function() {
    return ( "Region {" +
             "t: "    + this.top    +=20
             ", r: "    + this.right  +=20
             ", b: "    + this.bottom +=20
             ", l: "    + this.left   +=20
             "}" );
};

/**
 * Returns a region that is occupied by the DOM element
 *
 * @param  {HTMLElement} el The element
 * @return {Region}         The region that the element occupies
 * @static
 */
YAHOO.util.Region.getRegion =3D function(el) {
    var p =3D YAHOO.util.Dom.getXY(el);

    var t =3D p[1];
    var r =3D p[0] + el.offsetWidth;
    var b =3D p[1] + el.offsetHeight;
    var l =3D p[0];

    return new YAHOO.util.Region(t, r, b, l);
};

/////////////////////////////////////////////////////////////////////////=
////


/**
 * @class
 *
 * A point is a region that is special in that it represents a single =
point on=20
 * the grid.
 *
 * @param {int} x The X position of the point
 * @param {int} y The Y position of the point
 * @constructor
 * @extends Region
 */
YAHOO.util.Point =3D function(x, y) {
    /**
     * The X position of the point
     * @type int
     */
    this.x      =3D x;

    /**
     * The Y position of the point
     * @type int
     */
    this.y      =3D y;
    this.top    =3D y;
    this[1] =3D y;
   =20
    this.right  =3D x;
    this.bottom =3D y;
    this.left   =3D x;
    this[0] =3D x;
};

YAHOO.util.Point.prototype =3D new YAHOO.util.Region();


------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/js/yui/event.js

/*                                                                       =
                                                                         =
     =20
Copyright (c) 2006, Yahoo! Inc. All rights reserved.                     =
                                                                         =
     =20
Code licensed under the BSD License:                                     =
                                                                         =
     =20
http://developer.yahoo.net/yui/license.txt                               =
                                                                         =
     =20
version: 0.10.0                                                          =
                                                                         =
     =20
*/=20

/**
 * The CustomEvent class lets you define events for your application
 * that can be subscribed to by one or more independent component.
 *
 * @param {String} type The type of event, which is passed to the =
callback
 *                 when the event fires
 * @param {Object} oScope The context the event will fire from.  "this" =
will
 *                 refer to this object in the callback.  Default value: =

 *                 the window object.  The listener can override this.
 * @constructor
 */
YAHOO.util.CustomEvent =3D function(type, oScope) {
    /**
     * The type of event, returned to subscribers when the event fires
     * @type string
     */
    this.type =3D type;

    /**
     * The scope the the event will fire from by default.  Defaults to =
the window=20
     * obj
     * @type object
     */
    this.scope =3D oScope || window;

    /**
     * The subscribers to this event
     * @type Subscriber[]
     */
    this.subscribers =3D [];

    // Register with the event utility for automatic cleanup.  Made =
optional
    // so that CustomEvent can be used independently of pe.event
    if (YAHOO.util.Event) {=20
        YAHOO.util.Event.regCE(this);
    }
};

YAHOO.util.CustomEvent.prototype =3D {
    /**
     * Subscribes the caller to this event
     * @param {Function} fn       The function to execute
     * @param {Object}   obj      An object to be passed along when the =
event fires
     * @param {boolean}  bOverride If true, the obj passed in becomes =
the execution
     *                            scope of the listener
     */
    subscribe: function(fn, obj, bOverride) {
        this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, =
bOverride) );
    },

    /**
     * Unsubscribes the caller from this event
     * @param {Function} fn  The function to execute
     * @param {Object}   obj An object to be passed along when the event =
fires
     * @return {boolean} True if the subscriber was found and detached.
     */
    unsubscribe: function(fn, obj) {
        var found =3D false;
        for (var i=3D0, len=3Dthis.subscribers.length; i<len; ++i) {
            var s =3D this.subscribers[i];
            if (s && s.contains(fn, obj)) {
                this._delete(i);
                found =3D true;
            }
        }

        return found;
    },

    /**
     * Notifies the subscribers.  The callback functions will be =
executed
     * from the scope specified when the event was created, and with the =
following
     * parameters:
     *   <pre>
     *   - The type of event
     *   - All of the arguments fire() was executed with as an array
     *   - The custom object (if any) that was passed into the =
subscribe() method
     *   </pre>
     *  =20
     * @param {Array} an arbitrary set of parameters to pass to the =
handler
     */
    fire: function() {
        for (var i=3D0, len=3Dthis.subscribers.length; i<len; ++i) {
            var s =3D this.subscribers[i];
            if (s) {
                var scope =3D (s.override) ? s.obj : this.scope;
                s.fn.call(scope, this.type, arguments, s.obj);
            }
        }
    },

    /**
     * Removes all listeners
     */
    unsubscribeAll: function() {
        for (var i=3D0, len=3Dthis.subscribers.length; i<len; ++i) {
            this._delete(i);
        }
    },

    /**
     * @private
     */
    _delete: function(index) {
        var s =3D this.subscribers[index];
        if (s) {
            delete s.fn;
            delete s.obj;
        }

        delete this.subscribers[index];
    }
};

/////////////////////////////////////////////////////////////////////

/**
 * @class Stores the subscriber information to be used when the event =
fires.
 * @param {Function} fn       The function to execute
 * @param {Object}   obj      An object to be passed along when the =
event fires
 * @param {boolean}  bOverride If true, the obj passed in becomes the =
execution
 *                            scope of the listener
 * @constructor
 */
YAHOO.util.Subscriber =3D function(fn, obj, bOverride) {
    /**
     * The callback that will be execute when the event fires
     * @type function
     */
    this.fn =3D fn;

    /**
     * An optional custom object that will passed to the callback when
     * the event fires
     * @type object
     */
    this.obj =3D obj || null;

    /**
     * The default execution scope for the event listener is defined =
when the
     * event is created (usually the object which contains the event).
     * By setting override to true, the execution scope becomes the =
custom
     * object passed in by the subscriber
     * @type boolean
     */
    this.override =3D (bOverride);
};

/**
 * Returns true if the fn and obj match this objects properties.
 * Used by the unsubscribe method to match the right subscriber.
 *
 * @param {Function} fn the function to execute
 * @param {Object} obj an object to be passed along when the event fires
 * @return {boolean} true if the supplied arguments match this=20
 *                   subscriber's signature.
 */
YAHOO.util.Subscriber.prototype.contains =3D function(fn, obj) {
    return (this.fn =3D=3D fn && this.obj =3D=3D obj);
};

/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

// Only load this library once.  If it is loaded a second time, existing
// events cannot be detached.
if (!YAHOO.util.Event) {

/**
 * @class
 * The event utility provides functions to add and remove event =
listeners,
 * event cleansing.  It also tries to automatically remove listeners it
 * registers during the unload event.
 * @constructor
 */
    YAHOO.util.Event =3D function() {

        /**
         * True after the onload event has fired
         * @type boolean
         * @private
         */
        var loadComplete =3D  false;

        /**
         * Cache of wrapped listeners
         * @type array
         * @private
         */
        var listeners =3D [];

        /**
         * Listeners that will be attached during the onload event
         * @type array
         * @private
         */
        var delayedListeners =3D [];

        /**
         * User-defined unload function that will be fired before all =
events
         * are detached
         * @type array
         * @private
         */
        var unloadListeners =3D [];

        /**
         * Cache of the custom events that have been defined.  Used for
         * automatic cleanup
         * @type array
         * @private
         */
        var customEvents =3D [];

        /**
         * Cache of DOM0 event handlers to work around issues with DOM2 =
events
         * in Safari
         * @private
         */
        var legacyEvents =3D [];

        /**
         * Listener stack for DOM0 events
         * @private
         */
        var legacyHandlers =3D [];

        /**
         * The number of times to poll after window.onload.  This number =
is
         * increased if additional late-bound handlers are requested =
after
         * the page load.
         * @private
         */
        var retryCount =3D 0;

        /**
         * onAvailable listeners
         * @private
         */
        var onAvailStack =3D [];

        /**
         * Lookup table for legacy events
         * @private
         */
        var legacyMap =3D [];

        /**
         * Counter for auto id generation
         * @private
         */
        var counter =3D 0;

        return { // PREPROCESS

            /**
             * The number of times we should look for elements that are =
not
             * in the DOM at the time the event is requested after the =
document
             * has been loaded.  The default is 200@50 ms, so it will =
poll
             * for 10 seconds or until all outstanding handlers are =
bound
             * (whichever comes first).
             * @type int
             */
            POLL_RETRYS: 200,

            /**
             * The poll interval in milliseconds
             * @type int
             */
            POLL_INTERVAL: 50,

            /**
             * Element to bind, int constant
             * @type int
             */
            EL: 0,

            /**
             * Type of event, int constant
             * @type int
             */
            TYPE: 1,

            /**
             * Function to execute, int constant
             * @type int
             */
            FN: 2,

            /**
             * Function wrapped for scope correction and cleanup, int =
constant
             * @type int
             */
            WFN: 3,

            /**
             * Object passed in by the user that will be returned as a=20
             * parameter to the callback, int constant
             * @type int
             */
            SCOPE: 3,

            /**
             * Adjusted scope, either the element we are registering the =
event
             * on or the custom object passed in by the listener, int =
constant
             * @type int
             */
            ADJ_SCOPE: 4,

            /**
             * Safari detection is necessary to work around the =
preventDefault
             * bug that makes it so you can't cancel a href click from =
the=20
             * handler.  There is not a capabilities check we can use =
here.
             * @private
             */
            isSafari: =
(/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),

            /**
             * IE detection needed to properly calculate pageX and =
pageY. =20
             * capabilities checking didn't seem to work because another =

             * browser that does not provide the properties have the =
values=20
             * calculated in a different manner than IE.
             * @private
             */
            isIE: (!this.isSafari && =
!navigator.userAgent.match(/opera/gi) &&=20
                    navigator.userAgent.match(/msie/gi)),

            /**
             * @private
             */
            addDelayedListener: function(el, sType, fn, oScope, =
bOverride) {
                delayedListeners[delayedListeners.length] =3D
                    [el, sType, fn, oScope, bOverride];

                // If this happens after the inital page load, we need =
to
                // reset the poll counter so that we continue to search =
for
                // the element for a fixed period of time.
                if (loadComplete) {
                    retryCount =3D this.POLL_RETRYS;
                    this.startTimeout(0);
                    // this._tryPreloadAttach();
                }
            },

            /**
             * @private
             */
            startTimeout: function(interval) {
                var i =3D (interval || interval =3D=3D=3D 0) ? interval =
: this.POLL_INTERVAL;
                var self =3D this;
                var callback =3D function() { self._tryPreloadAttach(); =
};
                this.timeout =3D setTimeout(callback, i);
            },

            /**
             * Executes the supplied callback when the item with the =
supplied
             * id is found.  This is meant to be used to execute =
behavior as
             * soon as possible as the page loads.  If you use this =
after the
             * initial page load it will poll for a fixed time for the =
element.
             * The number of times it will poll and the frequency are
             * configurable.  By default it will poll for 10 seconds.
             * @param {string} p_id the id of the element to look for.
             * @param {function} p_fn what to execute when the element =
is found.
             * @param {object} p_obj an optional object to be passed =
back as
             * a parameter to p_fn.
             * @param {boolean} p_override If set to true, p_fn will =
execute
             * in the scope of p_obj
             *
             */
            onAvailable: function(p_id, p_fn, p_obj, p_override) {
                onAvailStack.push( { id:       p_id,=20
                                     fn:       p_fn,=20
                                     obj:      p_obj,=20
                                     override: p_override } );

                retryCount =3D this.POLL_RETRYS;
                this.startTimeout(0);
                // this._tryPreloadAttach();
            },

            /**
             * Appends an event handler
             *
             * @param {Object}   el        The html element to assign =
the=20
             *                             event to
             * @param {String}   sType     The type of event to append
             * @param {Function} fn        The method the event invokes
             * @param {Object}   oScope    An arbitrary object that will =
be=20
             *                             passed as a parameter to the =
handler
             * @param {boolean}  bOverride If true, the obj passed in =
becomes
             *                             the execution scope of the =
listener
             * @return {boolean} True if the action was successful or =
defered,
             *                        false if one or more of the =
elements=20
             *                        could not have the event bound to =
it.
             */
            addListener: function(el, sType, fn, oScope, bOverride) {

                if (!fn || !fn.call) {
                    return false;
                }

                // The el argument can be an array of elements or =
element ids.
                if ( this._isValidCollection(el)) {
                    var ok =3D true;
                    for (var i=3D0,len=3Del.length; i<len; ++i) {
                        ok =3D ( this.on(el[i],=20
                                       sType,=20
                                       fn,=20
                                       oScope,=20
                                       bOverride) && ok );
                    }
                    return ok;

                } else if (typeof el =3D=3D "string") {
                    var oEl =3D this.getEl(el);
                    // If the el argument is a string, we assume it is=20
                    // actually the id of the element.  If the page is =
loaded
                    // we convert el to the actual element, otherwise we =

                    // defer attaching the event until onload event =
fires

                    // check to see if we need to delay hooking up the =
event=20
                    // until after the page loads.
                    if (loadComplete && oEl) {
                        el =3D oEl;
                    } else {
                        // defer adding the event until onload fires
                        this.addDelayedListener(el,=20
                                                sType,=20
                                                fn,=20
                                                oScope,=20
                                                bOverride);

                        return true;
                    }
                }

                // Element should be an html element or an array if we =
get=20
                // here.
                if (!el) {
                    return false;
                }

                // we need to make sure we fire registered unload events =

                // prior to automatically unhooking them.  So we hang on =
to=20
                // these instead of attaching them to the window and =
fire the
                // handles explicitly during our one unload event.
                if ("unload" =3D=3D sType && oScope !=3D=3D this) {
                    unloadListeners[unloadListeners.length] =3D
                            [el, sType, fn, oScope, bOverride];
                    return true;
                }


                // if the user chooses to override the scope, we use the =
custom
                // object passed in, otherwise the executing scope will =
be the
                // HTML element that the event is registered on
                var scope =3D (bOverride) ? oScope : el;

                // wrap the function so we can return the oScope object =
when
                // the event fires;
                var wrappedFn =3D function(e) {
                        return fn.call(scope, =
YAHOO.util.Event.getEvent(e),=20
                                oScope);
                    };

                var li =3D [el, sType, fn, wrappedFn, scope];
                var index =3D listeners.length;
                // cache the listener so we can try to automatically =
unload
                listeners[index] =3D li;

                if (this.useLegacyEvent(el, sType)) {
                    var legacyIndex =3D this.getLegacyIndex(el, sType);
                    if (legacyIndex =3D=3D -1) {

                        legacyIndex =3D legacyEvents.length;
                        legacyMap[el.id + sType] =3D legacyIndex;

                        // cache the signature for the DOM0 event, and=20
                        // include the existing handler for the event, =
if any
                        legacyEvents[legacyIndex] =3D=20
                            [el, sType, el["on" + sType]];
                        legacyHandlers[legacyIndex] =3D [];

                        el["on" + sType] =3D=20
                            function(e) {
                                YAHOO.util.Event.fireLegacyEvent(
                                    YAHOO.util.Event.getEvent(e), =
legacyIndex);
                            };
                    }

                    // add a reference to the wrapped listener to our =
custom
                    // stack of events
                    legacyHandlers[legacyIndex].push(index);

                // DOM2 Event model
                } else if (el.addEventListener) {
                    el.addEventListener(sType, wrappedFn, false);
                // Internet Explorer abstraction
                } else if (el.attachEvent) {
                    el.attachEvent("on" + sType, wrappedFn);
                }

                return true;
               =20
            },

            /**
             * Shorthand for YAHOO.util.Event.addListener
             * @type function
             */
            // on: this.addListener,

            /**
             * When using legacy events, the handler is routed to this =
object
             * so we can fire our custom listener stack.
             * @private
             */
            fireLegacyEvent: function(e, legacyIndex) {
                var ok =3D true;

                var le =3D legacyHandlers[legacyIndex];
                for (var i=3D0,len=3Dle.length; i<len; ++i) {
                    var index =3D le[i];
                    if (index) {
                        var li =3D listeners[index];
                        if ( li && li[this.WFN] ) {
                            var scope =3D li[this.ADJ_SCOPE];
                            var ret =3D li[this.WFN].call(scope, e);
                            ok =3D (ok && ret);
                        } else {
                            // This listener was removed, so delete it =
from
                            // the array
                            delete le[i];
                        }
                    }
                }

                return ok;
            },

            /**
             * Returns the legacy event index that matches the supplied=20
             * signature
             * @private
             */
            getLegacyIndex: function(el, sType) {
                /*
                for (var i=3D0,len=3DlegacyEvents.length; i<len; ++i) {
                    var le =3D legacyEvents[i];
                    if (le && le[0] =3D=3D=3D el && le[1] =3D=3D=3D =
sType) {
                        return i;
                    }
                }
                return -1;
                */

                var key =3D this.generateId(el) + sType;
                if (typeof legacyMap[key] =3D=3D "undefined") {=20
                    return -1;
                } else {
                    return legacyMap[key];
                }

            },

            /**
             * Logic that determines when we should automatically use =
legacy
             * events instead of DOM2 events.
             * @private
             */
            useLegacyEvent: function(el, sType) {

                if (!el.addEventListener && !el.attachEvent) {
                    return true;
                } else if (this.isSafari) {
                    if ("click" =3D=3D sType || "dblclick" =3D=3D sType) =
{
                        return true;
                    }
                }

                return false;
            },
                   =20
            /**
             * Removes an event handler
             *
             * @param {Object} el the html element or the id of the =
element to=20
             * assign the event to.
             * @param {String} sType the type of event to remove
             * @param {Function} fn the method the event invokes
             * @return {boolean} true if the unbind was successful, =
false=20
             * otherwise
             */
            removeListener: function(el, sType, fn, index) {

                if (!fn || !fn.call) {
                    return false;
                }

                // The el argument can be a string
                if (typeof el =3D=3D "string") {
                    el =3D this.getEl(el);
                // The el argument can be an array of elements or =
element ids.
                } else if ( this._isValidCollection(el)) {
                    var ok =3D true;
                    for (var i=3D0,len=3Del.length; i<len; ++i) {
                        ok =3D ( this.removeListener(el[i], sType, fn) =
&& ok );
                    }
                    return ok;
                }

                if ("unload" =3D=3D sType) {

                    for (i=3D0, len=3DunloadListeners.length; i<len; =
i++) {
                        var li =3D unloadListeners[i];
                        if (li &&=20
                            li[0] =3D=3D el &&=20
                            li[1] =3D=3D sType &&=20
                            li[2] =3D=3D fn) {
                                delete unloadListeners[i];
                                return true;
                        }
                    }

                    return false;
                }

                var cacheItem =3D null;
 =20
                if ("undefined" =3D=3D typeof index) {
                    index =3D this._getCacheIndex(el, sType, fn);
                }

                if (index >=3D 0) {
                    cacheItem =3D listeners[index];
                }

                if (!el || !cacheItem) {
                    return false;
                }


                if (el.removeEventListener) {
                    el.removeEventListener(sType, cacheItem[this.WFN], =
false);
                } else if (el.detachEvent) {
                    el.detachEvent("on" + sType, cacheItem[this.WFN]);
                }

                // removed the wrapped handler
                delete listeners[index][this.WFN];
                delete listeners[index][this.FN];
                delete listeners[index];

                return true;

            },

            /**
             * Returns the event's target element
             * @param {Event} ev the event
             * @param {boolean} resolveTextNode when set to true the =
target's
             *                  parent will be returned if the target is =
a=20
             *                  text node
             * @return {HTMLElement} the event's target
             */
            getTarget: function(ev, resolveTextNode) {
                var t =3D ev.target || ev.srcElement;

                if (resolveTextNode && t && "#text" =3D=3D t.nodeName) {
                    return t.parentNode;
                } else {
                    return t;
                }
            },

            /**
             * Returns the event's pageX
             * @param {Event} ev the event
             * @return {int} the event's pageX
             */
            getPageX: function(ev) {
                var x =3D ev.pageX;
                if (!x && 0 !=3D=3D x) {
                    x =3D ev.clientX || 0;

                    if ( this.isIE ) {
                        x +=3D this._getScrollLeft();
                    }
                }

                return x;
            },

            /**
             * Returns the event's pageY
             * @param {Event} ev the event
             * @return {int} the event's pageY
             */
            getPageY: function(ev) {
                var y =3D ev.pageY;
                if (!y && 0 !=3D=3D y) {
                    y =3D ev.clientY || 0;

                    if ( this.isIE ) {
                        y +=3D this._getScrollTop();
                    }
                }

                return y;
            },

            /**
             * Returns the pageX and pageY properties as an indexed =
array.
             * @type int[]
             */
            getXY: function(ev) {
                return [this.getPageX(ev), this.getPageY(ev)];
            },

            /**
             * Returns the event's related target=20
             * @param {Event} ev the event
             * @return {HTMLElement} the event's relatedTarget
             */
            getRelatedTarget: function(ev) {
                var t =3D ev.relatedTarget;
                if (!t) {
                    if (ev.type =3D=3D "mouseout") {
                        t =3D ev.toElement;
                    } else if (ev.type =3D=3D "mouseover") {
                        t =3D ev.fromElement;
                    }
                }

                return t;
            },

            /**
             * Returns the time of the event.  If the time is not =
included, the
             * event is modified using the current time.
             * @param {Event} ev the event
             * @return {Date} the time of the event
             */
            getTime: function(ev) {
                if (!ev.time) {
                    var t =3D new Date().getTime();
                    try {
                        ev.time =3D t;
                    } catch(e) {=20
                        // can't set the time property =20
                        return t;
                    }
                }

                return ev.time;
            },

            /**
             * Convenience method for stopPropagation + preventDefault
             * @param {Event} ev the event
             */
            stopEvent: function(ev) {
                this.stopPropagation(ev);
                this.preventDefault(ev);
            },

            /**
             * Stops event propagation
             * @param {Event} ev the event
             */
            stopPropagation: function(ev) {
                if (ev.stopPropagation) {
                    ev.stopPropagation();
                } else {
                    ev.cancelBubble =3D true;
                }
            },

            /**
             * Prevents the default behavior of the event
             * @param {Event} ev the event
             */
            preventDefault: function(ev) {
                if (ev.preventDefault) {
                    ev.preventDefault();
                } else {
                    ev.returnValue =3D false;
                }
            },
            =20
            /**
             * Finds the event in the window object, the caller's =
arguments, or
             * in the arguments of another method in the callstack.  =
This is
             * executed automatically for events registered through the =
event
             * manager, so the implementer should not normally need to =
execute
             * this function at all.
             * @param {Event} the event parameter from the handler
             * @return {Event} the event=20
             */
            getEvent: function(e) {
                var ev =3D e || window.event;

                if (!ev) {
                    var c =3D this.getEvent.caller;
                    while (c) {
                        ev =3D c.arguments[0];
                        if (ev && Event =3D=3D ev.constructor) {
                            break;
                        }
                        c =3D c.caller;
                    }
                }

                return ev;
            },

            /**
             * Returns the charcode for an event
             * @param {Event} ev the event
             * @return {int} the event's charCode
             */
            getCharCode: function(ev) {
                return ev.charCode || ((ev.type =3D=3D "keypress") ? =
ev.keyCode : 0);
            },

            /**
             * @private
             * Locating the saved event handler data by function ref
             */
            _getCacheIndex: function(el, sType, fn) {
                for (var i=3D0,len=3Dlisteners.length; i<len; ++i) {
                    var li =3D listeners[i];
                    if ( li                 &&=20
                         li[this.FN] =3D=3D fn  &&=20
                         li[this.EL] =3D=3D el  &&=20
                         li[this.TYPE] =3D=3D sType ) {
                        return i;
                    }
                }

                return -1;
            },

            /**
             * Generates an unique ID for the element if it does not =
already=20
             * have one.
             * @param el the element
             * @return {string} the id of the element
             */
            generateId: function(el) {
                var id =3D el.id;

                if (!id) {
                    id =3D "yuievtautoid-" + (counter++);
                    el.id =3D id;
                }

                return id;
            },

            /**
             * We want to be able to use getElementsByTagName as a =
collection
             * to attach a group of events to.  Unfortunately, different =

             * browsers return different types of collections.  This =
function
             * tests to determine if the object is array-like.  It will =
also=20
             * fail if the object is an array, but is empty.
             * @param o the object to test
             * @return {boolean} true if the object is array-like and =
populated
             * @private
             */
            _isValidCollection: function(o) {

                return ( o                    && // o is something
                         o.length             && // o is indexed
                         typeof o !=3D "string" && // o is not a string
                         !o.tagName           && // o is not an HTML =
element
                         !o.alert             && // o is not a window
                         typeof o[0] !=3D "undefined" );

            },

            /**
             * @private
             * DOM element cache
             */
            elCache: {},

            /**
             * We cache elements bound by id because when the unload =
event=20
             * fires, we can no longer use document.getElementById
             * @private
             */
            getEl: function(id) {
                return document.getElementById(id);
            },

            /**
             * Clears the element cache
             * @deprecated
             * @private
             */
            clearCache: function() { },

            /**
             * Called by CustomEvent instances to provide a handle to =
the=20
             * event * that can be removed later on.  Should be package=20
             * protected.
             * @private
             */
            regCE: function(ce) {
                customEvents.push(ce);
            },

            /**
             * @private
             * hook up any deferred listeners
             */
            _load: function(e) {
                loadComplete =3D true;
            },

            /**
             * Polling function that runs before the onload event fires, =

             * attempting * to attach to DOM Nodes as soon as they are=20
             * available
             * @private
             */
            _tryPreloadAttach: function() {

                if (this.locked) {
                    return false;
                }

                this.locked =3D true;


                // keep trying until after the page is loaded.  We need =
to=20
                // check the page load state prior to trying to bind the =

                // elements so that we can be certain all elements have =
been=20
                // tested appropriately
                var tryAgain =3D !loadComplete;
                if (!tryAgain) {
                    tryAgain =3D (retryCount > 0);
                }

                // Delayed listeners
                var stillDelayed =3D [];

                for (var i=3D0,len=3DdelayedListeners.length; i<len; =
++i) {
                    var d =3D delayedListeners[i];
                    // There may be a race condition here, so we need to =

                    // verify the array element is usable.
                    if (d) {

                        // el will be null if document.getElementById =
did not
                        // work
                        var el =3D this.getEl(d[this.EL]);

                        if (el) {
                            this.on(el, d[this.TYPE], d[this.FN],=20
                                    d[this.SCOPE], d[this.ADJ_SCOPE]);
                            delete delayedListeners[i];
                        } else {
                            stillDelayed.push(d);
                        }
                    }
                }

                delayedListeners =3D stillDelayed;

                // onAvailable
                notAvail =3D [];
                for (i=3D0,len=3DonAvailStack.length; i<len ; ++i) {
                    var item =3D onAvailStack[i];
                    if (item) {
                        el =3D this.getEl(item.id);

                        if (el) {
                            var scope =3D (item.override) ? item.obj : =
el;
                            item.fn.call(scope, item.obj);
                            delete onAvailStack[i];
                        } else {
                            notAvail.push(item);
                        }
                    }
                }

                retryCount =3D (stillDelayed.length =3D=3D=3D 0 &&=20
                                    notAvail.length =3D=3D=3D 0) ? 0 : =
retryCount - 1;

                if (tryAgain) {
                    this.startTimeout();
                }

                this.locked =3D false;

            },

            /**
             * Removes all listeners registered by pe.event.  Called=20
             * automatically during the unload event.
             * @private
             */
            _unload: function(e, me) {
                for (var i=3D0,len=3DunloadListeners.length; i<len; ++i) =
{
                    var l =3D unloadListeners[i];
                    if (l) {
                        var scope =3D (l[this.ADJ_SCOPE]) ? =
l[this.SCOPE]: window;
                        l[this.FN].call(scope, this.getEvent(e), =
l[this.SCOPE] );
                    }
                }

                if (listeners && listeners.length > 0) {
                    for (i=3D0,len=3Dlisteners.length; i<len ; ++i) {
                        l =3D listeners[i];
                        if (l) {
                            this.removeListener(l[this.EL], =
l[this.TYPE],=20
                                    l[this.FN], i);
                        }
                    }

                    this.clearCache();
                }

                for (i=3D0,len=3DcustomEvents.length; i<len; ++i) {
                    customEvents[i].unsubscribeAll();
                    delete customEvents[i];
                }

                for (i=3D0,len=3DlegacyEvents.length; i<len; ++i) {
                    // dereference the element
                    delete legacyEvents[i][0];
                    // delete the array item
                    delete legacyEvents[i];
                }
            },

            /**
             * Returns scrollLeft
             * @private
             */
            _getScrollLeft: function() {
                return this._getScroll()[1];
            },

            /**
             * Returns scrollTop
             * @private
             */
            _getScrollTop: function() {
                return this._getScroll()[0];
            },

            /**
             * Returns the scrollTop and scrollLeft.  Used to calculate =
the=20
             * pageX and pageY in Internet Explorer
             * @private
             */
            _getScroll: function() {
                var dd =3D document.documentElement; db =3D =
document.body;
                if (dd && dd.scrollTop) {
                    return [dd.scrollTop, dd.scrollLeft];
                } else if (db) {
                    return [db.scrollTop, db.scrollLeft];
                } else {
                    return [0, 0];
                }
            }
        };
    } ();

    /**
     * @private
     */
    YAHOO.util.Event.on =3D YAHOO.util.Event.addListener;

    if (document && document.body) {
        YAHOO.util.Event._load();
    } else {
        YAHOO.util.Event.on(window, "load", YAHOO.util.Event._load,=20
                YAHOO.util.Event, true);
    }

    YAHOO.util.Event.on(window, "unload", YAHOO.util.Event._unload,=20
                YAHOO.util.Event, true);

    YAHOO.util.Event._tryPreloadAttach();

}


------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/js/yui/animation.js

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.10.0
*/

/**
 *
 * Base class for animated DOM objects.
 * @class Base animation class that provides the interface for building =
animated effects.
 * <p>Usage: var myAnim =3D new YAHOO.util.Anim(el, { width: { from: 10, =
to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
 * @requires YAHOO.util.AnimMgr
 * @requires YAHOO.util.Easing
 * @requires YAHOO.util.Dom
 * @requires YAHOO.util.Event
 * @requires YAHOO.util.CustomEvent
 * @constructor
 * @param {String or HTMLElement} el Reference to the element that will =
be animated
 * @param {Object} attributes The attribute(s) to be animated. =20
 * Each attribute is an object with at minimum a "to" or "by" member =
defined. =20
 * Additional optional members are "from" (defaults to current value), =
"units" (defaults to "px"). =20
 * All attribute names use camelCase.
 * @param {Number} duration (optional, defaults to 1 second) Length of =
animation (frames or seconds), defaults to time-based
 * @param {Function} method (optional, defaults to =
YAHOO.util.Easing.easeNone) Computes the values that are applied to the =
attributes per frame (generally a YAHOO.util.Easing method)
 */

YAHOO.util.Anim =3D function(el, attributes, duration, method)=20
{
   if (el) {
      this.init(el, attributes, duration, method);=20
   }
};

YAHOO.util.Anim.prototype =3D {
   /**
    * Returns the value computed by the animation's "method".
    * @param {String} attribute The name of the attribute.
    * @param {Number} start The value this attribute should start from =
for this animation.
    * @param {Number} end  The value this attribute should end at for =
this animation.
    * @return {Number} The Value to be applied to the attribute.
    */
   doMethod: function(attribute, start, end) {
      return this.method(this.currentFrame, start, end - start, =
this.totalFrames);
   },
  =20
   /**
    * Applies a value to an attribute
    * @param {String} attribute The name of the attribute.
    * @param {Number} val The value to be applied to the attribute.
    * @param {String} unit The unit ('px', '%', etc.) of the value.
    */
   setAttribute: function(attribute, val, unit) {
      YAHOO.util.Dom.setStyle(this.getEl(), attribute, val + unit);=20
   },                 =20
  =20
   /**
    * Returns current value of the attribute.
    * @param {String} attribute The name of the attribute.
    * @return {Number} val The current value of the attribute.
    */
   getAttribute: function(attribute) {
      return parseFloat( YAHOO.util.Dom.getStyle(this.getEl(), =
attribute));
   },
  =20
   /**
    * The default unit to use for all attributes if not defined per =
attribute.
    * @type String
    */
   defaultUnit: 'px',
  =20
   /**
    * Per attribute units that should be used by default.
    * @type Object
    */
   defaultUnits: { opacity: ' ' },

   /**
    * @param {String or HTMLElement} el Reference to the element that =
will be animated
    * @param {Object} attributes The attribute(s) to be animated. =20
    * Each attribute is an object with at minimum a "to" or "by" member =
defined. =20
    * Additional optional members are "from" (defaults to current =
value), "units" (defaults to "px"). =20
    * All attribute names use camelCase.
    * @param {Number} duration (optional, defaults to 1 second) Length =
of animation (frames or seconds), defaults to time-based
    * @param {Function} method (optional, defaults to =
YAHOO.util.Easing.easeNone) Computes the values that are applied to the =
attributes per frame (generally a YAHOO.util.Easing method)
    */=20
   init: function(el, attributes, duration, method) {
  =20
      /**
       * Whether or not the animation is running.
       * @private
       * @type Boolean
       */
      var isAnimated =3D false;
     =20
      /**
       * A Date object that is created when the animation begins.
       * @private
       * @type Date
       */
      var startTime =3D null;
     =20
      /**
       * A Date object that is created when the animation ends.
       * @private
       * @type Date
       */
      var endTime =3D null;
     =20
      /**
       * The number of frames this animation was able to execute.
       * @private
       * @type Int
       */
      var actualFrames =3D 0;
     =20
      /**
       * The attribute values that will be used if no "from" is =
supplied.
       * @private
       * @type Object
       */
      var defaultValues =3D {};     =20

      /**
       * The element to be animated.
       * @private
       * @type HTMLElement
       */
      el =3D YAHOO.util.Dom.get(el);
     =20
      /**
       * The collection of attributes to be animated. =20
       * Each attribute must have at least a "to" or "by" defined in =
order to animate. =20
       * If "to" is supplied, the animation will end with the attribute =
at that value. =20
       * If "by" is supplied, the animation will end at that value plus =
its starting value.=20
       * If both are supplied, "to" is used, and "by" is ignored.=20
       * @member YAHOO#util#Anim
       * Optional additional member include "from" (the value the =
attribute should start animating from, defaults to current value), and =
"unit" (the units to apply to the values).
       * @type Object
       */
      this.attributes =3D attributes || {};
     =20
      /**
       * The length of the animation.  Defaults to "1" (second).
       * @type Number
       */
      this.duration =3D duration || 1;
     =20
      /**
       * The method that will provide values to the attribute(s) during =
the animation.=20
       * Defaults to "YAHOO.util.Easing.easeNone".
       * @type Function
       */
      this.method =3D method || YAHOO.util.Easing.easeNone;

      /**
       * Whether or not the duration should be treated as seconds.
       * Defaults to true.
       * @type Boolean
       */
      this.useSeconds =3D true; // default to seconds
     =20
      /**
       * The location of the current animation on the timeline.
       * In time-based animations, this is used by AnimMgr to ensure the =
animation finishes on time.
       * @type Int
       */
      this.currentFrame =3D 0;
     =20
      /**
       * The total number of frames to be executed.
       * In time-based animations, this is used by AnimMgr to ensure the =
animation finishes on time.
       * @type Int
       */
      this.totalFrames =3D YAHOO.util.AnimMgr.fps;
     =20
     =20
      /**
       * Returns a reference to the animated element.
       * @return {HTMLElement}
       */
      this.getEl =3D function() { return el; };
     =20
     =20
      /**
       * Sets the default value to be used when "from" is not supplied.
       * @param {String} attribute The attribute being set.
       * @param {Number} val The default value to be applied to the =
attribute.
       */
      this.setDefault =3D function(attribute, val) {
         if ( val.constructor !=3D Array && (val =3D=3D 'auto' || =
isNaN(val)) ) { // if 'auto' or NaN, set defaults for well known =
attributes, zero for others
            switch(attribute) {
               case'width':
                  val =3D el.clientWidth || el.offsetWidth; // computed =
width
                  break;
               case 'height':
                  val =3D el.clientHeight || el.offsetHeight; // =
computed height
                  break;
               case 'left':
                  if (YAHOO.util.Dom.getStyle(el, 'position') =3D=3D =
'absolute') {
                     val =3D el.offsetLeft; // computed left
                  } else {
                     val =3D 0;
                  }
                  break;
               case 'top':
                  if (YAHOO.util.Dom.getStyle(el, 'position') =3D=3D =
'absolute') {
                     val =3D el.offsetTop; // computed top
                  } else {
                     val =3D 0;
                  }
                  break;                    =20
               default:
                  val =3D 0;
            }
         }

         defaultValues[attribute] =3D val;
      };
     =20
      /**
       * Returns the default value for the given attribute.
       * @param {String} attribute The attribute whose value will be =
returned.
       */     =20
      this.getDefault =3D function(attribute) {
         return defaultValues[attribute];
      };
     =20
      /**
       * Checks whether the element is currently animated.
       * @return {Boolean} current value of isAnimated.   =20
       */
      this.isAnimated =3D function() {
         return isAnimated;
      };
     =20
      /**
       * Returns the animation start time.
       * @return {Date} current value of startTime.    =20
       */
      this.getStartTime =3D function() {
         return startTime;
      };     =20
     =20
      /**
       * Starts the animation by registering it with the animation =
manager.  =20
       */
      this.animate =3D function() {
         if ( this.isAnimated() ) { return false; }
        =20
         this.onStart.fire();
         this._onStart.fire();
        =20
         this.totalFrames =3D ( this.useSeconds ) ? =
Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;
         YAHOO.util.AnimMgr.registerElement(this);
        =20
         // get starting values or use defaults
         var attributes =3D this.attributes;
         var el =3D this.getEl();
         var val;
        =20
         for (var attribute in attributes) {
            val =3D this.getAttribute(attribute);
            this.setDefault(attribute, val);
         }
        =20
         isAnimated =3D true;
         actualFrames =3D 0;
         startTime =3D new Date();  =20
      };
       =20
      /**
       * Stops the animation.  Normally called by AnimMgr when animation =
completes.
       */=20
      this.stop =3D function() {
         if ( !this.isAnimated() ) { return false; }=20
        =20
         this.currentFrame =3D 0;
        =20
         endTime =3D new Date();
        =20
         var data =3D {
            time: endTime,
            duration: endTime - startTime,
            frames: actualFrames,
            fps: actualFrames / this.duration
         };

         isAnimated =3D false; =20
         actualFrames =3D 0;
        =20
         this.onComplete.fire(data);
      };
     =20
      /**
       * Feeds the starting and ending values for each animated =
attribute to doMethod once per frame, then applies the resulting value =
to the attribute(s).
       * @private
       */
      var onTween =3D function() {
         var start;
         var end =3D null;
         var val;
         var unit;
         var attributes =3D this['attributes'];
        =20
         for (var attribute in attributes) {
            unit =3D attributes[attribute]['unit'] || =
this.defaultUnits[attribute] || this.defaultUnit;
  =20
            if (typeof attributes[attribute]['from'] !=3D 'undefined') {
               start =3D attributes[attribute]['from'];
            } else {
               start =3D this.getDefault(attribute);
            }
  =20

            // To beats by, per SMIL 2.1 spec
            if (typeof attributes[attribute]['to'] !=3D 'undefined') {
               end =3D attributes[attribute]['to'];
            }=20
            else if (typeof attributes[attribute]['by'] !=3D =
'undefined')=20
            {
               if (start.constructor =3D=3D Array) {
                  end =3D [];
                  for (var i =3D 0, len =3D start.length; i < len; ++i)
                  {
                     end[i] =3D start[i] + =
attributes[attribute]['by'][i];
                  }
               }
               else
               {
                  end =3D start + attributes[attribute]['by'];
               }
            }
  =20
            // if end is null, dont change value
            if (end !=3D=3D null && typeof end !=3D 'undefined') {
  =20
               val =3D this.doMethod(attribute, start, end);

               // negative not allowed for these (others too, but these =
are most common)
               if ( (attribute =3D=3D 'width' || attribute =3D=3D =
'height' || attribute =3D=3D 'opacity') && val < 0 ) {
                  val =3D 0;
               }

               this.setAttribute(attribute, val, unit);=20
            }
         }
        =20
         actualFrames +=3D 1;
      };
     =20
      /**
       * Custom event that fires after onStart, useful in subclassing
       * @private
       */  =20
      this._onStart =3D new YAHOO.util.CustomEvent('_onStart', this);
     =20
      /**
       * Custom event that fires when animation begins
       * Listen via subscribe method (e.g. =
myAnim.onStart.subscribe(someFunction)
       */  =20
      this.onStart =3D new YAHOO.util.CustomEvent('start', this);
     =20
      /**
       * Custom event that fires between each frame
       * Listen via subscribe method (e.g. =
myAnim.onTween.subscribe(someFunction)
       */
      this.onTween =3D new YAHOO.util.CustomEvent('tween', this);
     =20
      /**
       * Custom event that fires after onTween
       * @private
       */
      this._onTween =3D new YAHOO.util.CustomEvent('_tween', this);
     =20
      /**
       * Custom event that fires when animation ends
       * Listen via subscribe method (e.g. =
myAnim.onComplete.subscribe(someFunction)
       */
      this.onComplete =3D new YAHOO.util.CustomEvent('complete', this);

      this._onTween.subscribe(onTween);
   }
};

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.10.0
*/

/**
 * @class Handles animation queueing and threading.
 * Used by Anim and subclasses.
 */
YAHOO.util.AnimMgr =3D new function() {
   /**=20
    * Reference to the animation Interval
    * @private
    * @type Int
    */
   var thread =3D null;
  =20
   /**=20
    * The current queue of registered animation objects.
    * @private
    * @type Array
    */  =20
   var queue =3D [];

   /**=20
    * The number of active animations.
    * @private
    * @type Int
    */     =20
   var tweenCount =3D 0;

   /**=20
    * Base frame rate (frames per second).=20
    * Arbitrarily high for better x-browser calibration (slower browsers =
drop more frames).
    * @type Int
    *=20
    */
   this.fps =3D 200;

   /**=20
    * Interval delay in milliseconds, defaults to fastest possible.
    * @type Int
    *=20
    */
   this.delay =3D 1;

   /**
    * Adds an animation instance to the animation queue.
    * All animation instances must be registered in order to animate.
    * @param {object} tween The Anim instance to be be registered
    */
   this.registerElement =3D function(tween) {
      if ( tween.isAnimated() ) { return false; }// but not if already =
animating
     =20
      queue[queue.length] =3D tween;
      tweenCount +=3D 1;

      this.start();
   };
  =20
   /**
    * Starts the animation thread.
	 * Only one thread can run at a time.
    */  =20
   this.start =3D function() {
      if (thread =3D=3D=3D null) { thread =3D setInterval(this.run, =
this.delay); }
   };

   /**
    * Stops the animation thread or a specific animation instance.
    * @param {object} tween A specific Anim instance to stop (optional)
    * If no instance given, Manager stops thread and all animations.
    */  =20
   this.stop =3D function(tween) {
      if (!tween)
      {
         clearInterval(thread);
         for (var i =3D 0, len =3D queue.length; i < len; ++i) {
            if (queue[i].isAnimated()) {
               queue[i].stop(); =20
            }
         }
         queue =3D [];
         thread =3D null;
         tweenCount =3D 0;
      }
      else {
         tween.stop();    =20
         tweenCount -=3D 1;
        =20
         if (tweenCount <=3D 0) { this.stop(); }
      }
   };
  =20
   /**
    * Called per Interval to handle each animation frame.
    */  =20
   this.run =3D function() {
      for (var i =3D 0, len =3D queue.length; i < len; ++i) {
         var tween =3D queue[i];
         if ( !tween || !tween.isAnimated() ) { continue; }

         if (tween.currentFrame < tween.totalFrames || tween.totalFrames =
=3D=3D=3D null)
         {
            tween.currentFrame +=3D 1;
           =20
            if (tween.useSeconds) {
               correctFrame(tween);
            }
           =20
            tween.onTween.fire();    =20
            tween._onTween.fire();       =20
         }
         else { YAHOO.util.AnimMgr.stop(tween); }
      }
   };
  =20
   /**
    * On the fly frame correction to keep animation on time.
    * @private
    * @param {Object} tween The Anim instance being corrected.
    */
   var correctFrame =3D function(tween) {
      var frames =3D tween.totalFrames;
      var frame =3D tween.currentFrame;
      var expected =3D (tween.currentFrame * tween.duration * 1000 / =
tween.totalFrames);
      var elapsed =3D (new Date() - tween.getStartTime());
      var tweak =3D 0;
     =20
      if (elapsed < tween.duration * 1000) { // check if falling behind
         tweak =3D Math.round((elapsed / expected - 1) * =
tween.currentFrame);
      } else { // went over duration, so jump to end
         tweak =3D frames - (frame + 1);=20
      }
      if (tweak > 0 && isFinite(tweak)) { // adjust if needed
         if (tween.currentFrame + tweak >=3D frames) {// dont go past =
last frame
            tweak =3D frames - (frame + 1);
         }
        =20
         tween.currentFrame +=3D tweak;    =20
      }
   };
};

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.10.0
*/

/**
 *
 * @class Used to calculate Bezier splines for any number of control =
points.
 *
 */
YAHOO.util.Bezier =3D new function()=20
{
   /**
    * Get the current position of the animated element based on t.
    * Each point is an array of "x" and "y" values (0 =3D x, 1 =3D y)
    * At least 2 points are required (start and end).
    * First point is start. Last point is end.
    * Additional control points are optional.   =20
    * @param {Array} points An array containing Bezier points
    * @param {Number} t A number between 0 and 1 which is the basis for =
determining current position
    * @return {Array} An array containing int x and y member data
    */
   this.getPosition =3D function(points, t)
   { =20
      var n =3D points.length;
      var tmp =3D [];

      for (var i =3D 0; i < n; ++i){
         tmp[i] =3D [points[i][0], points[i][1]]; // save input
      }
     =20
      for (var j =3D 1; j < n; ++j) {
         for (i =3D 0; i < n - j; ++i) {
            tmp[i][0] =3D (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, =
10)][0];
            tmp[i][1] =3D (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, =
10)][1];=20
         }
      }
  =20
      return [ tmp[0][0], tmp[0][1] ];=20
  =20
   };
};

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.10.0
*/

/**
 * @class Class for defining the acceleration rate and path of =
animations.
 */
YAHOO.util.Easing =3D new function() {

   /**
    * Uniform speed between points.
    * @param {Number} t Time value used to compute current value.
    * @param {Number} b Starting value.
    * @param {Number} c Delta between start and end values.
    * @param {Number} d Total length of animation.
    * @return {Number} The computed value for the current animation =
frame.
    */
   this.easeNone =3D function(t, b, c, d) {
	return b+c*(t/=3Dd);=20
   };
  =20
   /**
    * Begins slowly and accelerates towards end.
    * @param {Number} t Time value used to compute current value.
    * @param {Number} b Starting value.
    * @param {Number} c Delta between start and end values.
    * @param {Number} d Total length of animation.
    * @return {Number} The computed value for the current animation =
frame.
    */
   this.easeIn =3D function(t, b, c, d) {
   	return b+c*((t/=3Dd)*t*t);
   };
  =20
   /**
    * Begins quickly and decelerates towards end.
    * @param {Number} t Time value used to compute current value.
    * @param {Number} b Starting value.
    * @param {Number} c Delta between start and end values.
    * @param {Number} d Total length of animation.
    * @return {Number} The computed value for the current animation =
frame.
    */
   this.easeOut =3D function(t, b, c, d) {
   	var ts=3D(t/=3Dd)*t;
   	var tc=3Dts*t;
   	return b+c*(tc + -3*ts + 3*t);
   };
  =20
   /**
    * Begins slowly and decelerates towards end.
    * @param {Number} t Time value used to compute current value.
    * @param {Number} b Starting value.
    * @param {Number} c Delta between start and end values.
    * @param {Number} d Total length of animation.
    * @return {Number} The computed value for the current animation =
frame.
    */
   this.easeBoth =3D function(t, b, c, d) {
   	var ts=3D(t/=3Dd)*t;
   	var tc=3Dts*t;
   	return b+c*(-2*tc + 3*ts);
   };
  =20
   /**
    * Begins by going below staring value.
    * @param {Number} t Time value used to compute current value.
    * @param {Number} b Starting value.
    * @param {Number} c Delta between start and end values.
    * @param {Number} d Total length of animation.
    * @return {Number} The computed value for the current animation =
frame.
    */
   this.backIn =3D function(t, b, c, d) {
   	var ts=3D(t/=3Dd)*t;
   	var tc=3Dts*t;
   	return b+c*(-3.4005*tc*ts + 10.2*ts*ts + -6.2*tc + 0.4*ts);
   };
  =20
   /**
    * End by going beyond ending value.
    * @param {Number} t Time value used to compute current value.
    * @param {Number} b Starting value.
    * @param {Number} c Delta between start and end values.
    * @param {Number} d Total length of animation.
    * @return {Number} The computed value for the current animation =
frame.
    */
   this.backOut =3D function(t, b, c, d) {
   	var ts=3D(t/=3Dd)*t;
   	var tc=3Dts*t;
   	return b+c*(8.292*tc*ts + -21.88*ts*ts + 22.08*tc + -12.69*ts + =
5.1975*t);
   };
  =20
   /**
    * Starts by going below staring value, and ends by going beyond =
ending value.
    * @param {Number} t Time value used to compute current value.
    * @param {Number} b Starting value.
    * @param {Number} c Delta between start and end values.
    * @param {Number} d Total length of animation.
    * @return {Number} The computed value for the current animation =
frame.
    */
   this.backBoth =3D function(t, b, c, d) {
   	var ts=3D(t/=3Dd)*t;
   	var tc=3Dts*t;
   	return b+c*(0.402*tc*ts + -2.1525*ts*ts + -3.2*tc + 8*ts + -2.05*t);
   };
};

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.10.0
*/

/**
 * @class Anim subclass for moving elements along a path defined by the =
"points" member of "attributes".  All "points" are arrays with x, y =
coordinates.
 * <p>Usage: <code>var myAnim =3D new YAHOO.util.Motion(el, { points: { =
to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
 * @requires YAHOO.util.Anim
 * @requires YAHOO.util.AnimMgr
 * @requires YAHOO.util.Easing
 * @requires YAHOO.util.Bezier
 * @requires YAHOO.util.Dom
 * @requires YAHOO.util.Event
 * @requires YAHOO.util.CustomEvent=20
 * @constructor
 * @param {String or HTMLElement} el Reference to the element that will =
be animated
 * @param {Object} attributes The attribute(s) to be animated. =20
 * Each attribute is an object with at minimum a "to" or "by" member =
defined. =20
 * Additional optional members are "from" (defaults to current value), =
"units" (defaults to "px"). =20
 * All attribute names use camelCase.
 * @param {Number} duration (optional, defaults to 1 second) Length of =
animation (frames or seconds), defaults to time-based
 * @param {Function} method (optional, defaults to =
YAHOO.util.Easing.easeNone) Computes the values that are applied to the =
attributes per frame (generally a YAHOO.util.Easing method)
 */
YAHOO.util.Motion =3D function(el, attributes, duration, method) {
   if (el) {
      this.initMotion(el, attributes, duration, method);
   }
};

YAHOO.util.Motion.prototype =3D new YAHOO.util.Anim();

/**
 * Per attribute units that should be used by default.
 * Motion points default to 'px' units.
 * @type Object
 */
YAHOO.util.Motion.prototype.defaultUnits.points =3D 'px';

/**
 * Returns the value computed by the animation's "method".
 * @param {String} attribute The name of the attribute.
 * @param {Number} start The value this attribute should start from for =
this animation.
 * @param {Number} end  The value this attribute should end at for this =
animation.
 * @return {Number} The Value to be applied to the attribute.
 */
YAHOO.util.Motion.prototype.doMethod =3D function(attribute, start, end) =
{
   var val =3D null;
  =20
   if (attribute =3D=3D 'points') {
      var translatedPoints =3D this.getTranslatedPoints();
      var t =3D this.method(this.currentFrame, 0, 100, this.totalFrames) =
/ 100;			=09
  =20
      if (translatedPoints) {
         val =3D YAHOO.util.Bezier.getPosition(translatedPoints, t);
      }
     =20
   } else {
      val =3D this.method(this.currentFrame, start, end - start, =
this.totalFrames);
   }
  =20
   return val;
};

/**
 * Returns current value of the attribute.
 * @param {String} attribute The name of the attribute.
 * @return {Number} val The current value of the attribute.
 */
YAHOO.util.Motion.prototype.getAttribute =3D function(attribute) {
   var val =3D null;
  =20
   if (attribute =3D=3D 'points') {
      val =3D [ this.getAttribute('left'), this.getAttribute('top') ];
      if ( isNaN(val[0]) ) { val[0] =3D 0; }
      if ( isNaN(val[1]) ) { val[1] =3D 0; }
   } else {
      val =3D parseFloat( YAHOO.util.Dom.getStyle(this.getEl(), =
attribute) );
   }
  =20
   return val;
};

/**
 * Applies a value to an attribute
 * @param {String} attribute The name of the attribute.
 * @param {Number} val The value to be applied to the attribute.
 * @param {String} unit The unit ('px', '%', etc.) of the value.
 */
YAHOO.util.Motion.prototype.setAttribute =3D function(attribute, val, =
unit) {
   if (attribute =3D=3D 'points') {
      YAHOO.util.Dom.setStyle(this.getEl(), 'left', val[0] + unit);
      YAHOO.util.Dom.setStyle(this.getEl(), 'top', val[1] + unit);
   } else {
      YAHOO.util.Dom.setStyle(this.getEl(), attribute, val + unit);=20
   }
};

/**
 * @param {String or HTMLElement} el Reference to the element that will =
be animated
 * @param {Object} attributes The attribute(s) to be animated. =20
 * Each attribute is an object with at minimum a "to" or "by" member =
defined. =20
 * Additional optional members are "from" (defaults to current value), =
"units" (defaults to "px"). =20
 * All attribute names use camelCase.
 * @param {Number} duration (optional, defaults to 1 second) Length of =
animation (frames or seconds), defaults to time-based
 * @param {Function} method (optional, defaults to =
YAHOO.util.Easing.easeNone) Computes the values that are applied to the =
attributes per frame (generally a YAHOO.util.Easing method)
 */=20
YAHOO.util.Motion.prototype.initMotion =3D function(el, attributes, =
duration, method) {
   YAHOO.util.Anim.call(this, el, attributes, duration, method);
  =20
   attributes =3D attributes || {};
   attributes.points =3D attributes.points || {};
   attributes.points.control =3D attributes.points.control || [];
  =20
   this.attributes =3D attributes;
  =20
   var start;
   var end =3D null;
   var translatedPoints =3D null;
  =20
   this.getTranslatedPoints =3D function() { return translatedPoints; };
  =20
   var translateValues =3D function(val, self) {
      var pageXY =3D YAHOO.util.Dom.getXY(self.getEl());
      val =3D [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + =
start[1] ];
  =20
      return val;=20
   };
  =20
   var onStart =3D function() {
      start =3D this.getAttribute('points');
      var attributes =3D this.attributes;
      var control =3D  attributes['points']['control'] || [];

      if (control.length > 0 && control[0].constructor !=3D Array) { // =
could be single point or array of points
         control =3D [control];
      }
     =20
      if (YAHOO.util.Dom.getStyle(this.getEl(), 'position') =3D=3D =
'static') { // default to relative
         YAHOO.util.Dom.setStyle(this.getEl(), 'position', 'relative');
      }

      if (typeof attributes['points']['from'] !=3D 'undefined') {
         YAHOO.util.Dom.setXY(this.getEl(), =
attributes['points']['from']); // set to from point
         start =3D this.getAttribute('points'); // get actual offset =
values
      }=20
      else if ((start[0] =3D=3D=3D 0 || start[1] =3D=3D=3D 0)) { // =
these sometimes up when auto
         YAHOO.util.Dom.setXY(this.getEl(), =
YAHOO.util.Dom.getXY(this.getEl())); // set it to current position, =
giving offsets
         start =3D this.getAttribute('points'); // get actual offset =
values
      }

      var i, len;
      // TO beats BY, per SMIL 2.1 spec
      if (typeof attributes['points']['to'] !=3D 'undefined') {
         end =3D translateValues(attributes['points']['to'], this);
        =20
         for (i =3D 0, len =3D control.length; i < len; ++i) {
            control[i] =3D translateValues(control[i], this);
         }
        =20
      } else if (typeof attributes['points']['by'] !=3D 'undefined') {
         end =3D [ start[0] + attributes['points']['by'][0], start[1] + =
attributes['points']['by'][1]];
        =20
         for (i =3D 0, len =3D control.length; i < len; ++i) {
            control[i] =3D [ start[0] + control[i][0], start[1] + =
control[i][1] ];
         }
      }

      if (end) {
         translatedPoints =3D [start];
        =20
         if (control.length > 0) { translatedPoints =3D =
translatedPoints.concat(control); }
        =20
         translatedPoints[translatedPoints.length] =3D end;
      }
   };
  =20
   this._onStart.subscribe(onStart);
};

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.10.0
*/

/**
 * @class Anim subclass for scrolling elements to a position defined by =
the "scroll" member of "attributes".  All "scroll" members are arrays =
with x, y scroll positions.
 * <p>Usage: <code>var myAnim =3D new YAHOO.util.Scroll(el, { scroll: { =
to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
 * @requires YAHOO.util.Anim
 * @requires YAHOO.util.AnimMgr
 * @requires YAHOO.util.Easing
 * @requires YAHOO.util.Bezier
 * @requires YAHOO.util.Dom
 * @requires YAHOO.util.Event
 * @requires YAHOO.util.CustomEvent=20
 * @constructor
 * @param {String or HTMLElement} el Reference to the element that will =
be animated
 * @param {Object} attributes The attribute(s) to be animated. =20
 * Each attribute is an object with at minimum a "to" or "by" member =
defined. =20
 * Additional optional members are "from" (defaults to current value), =
"units" (defaults to "px"). =20
 * All attribute names use camelCase.
 * @param {Number} duration (optional, defaults to 1 second) Length of =
animation (frames or seconds), defaults to time-based
 * @param {Function} method (optional, defaults to =
YAHOO.util.Easing.easeNone) Computes the values that are applied to the =
attributes per frame (generally a YAHOO.util.Easing method)
 */
YAHOO.util.Scroll =3D function(el, attributes, duration,  method) {
   if (el) {
      YAHOO.util.Anim.call(this, el, attributes, duration, method);
   }
};

YAHOO.util.Scroll.prototype =3D new YAHOO.util.Anim();

/**
 * Per attribute units that should be used by default.
 * Scroll positions default to no units.
 * @type Object
 */
YAHOO.util.Scroll.prototype.defaultUnits.scroll =3D ' ';

/**
 * Returns the value computed by the animation's "method".
 * @param {String} attribute The name of the attribute.
 * @param {Number} start The value this attribute should start from for =
this animation.
 * @param {Number} end  The value this attribute should end at for this =
animation.
 * @return {Number} The Value to be applied to the attribute.
 */
YAHOO.util.Scroll.prototype.doMethod =3D function(attribute, start, end) =
{
   var val =3D null;

   if (attribute =3D=3D 'scroll') {
      val =3D [
         this.method(this.currentFrame, start[0], end[0] - start[0], =
this.totalFrames),
         this.method(this.currentFrame, start[1], end[1] - start[1], =
this.totalFrames)
      ];
     =20
   } else {
      val =3D this.method(this.currentFrame, start, end - start, =
this.totalFrames);
   }
   return val;
};

/**
 * Returns current value of the attribute.
 * @param {String} attribute The name of the attribute.
 * @return {Number} val The current value of the attribute.
 */
YAHOO.util.Scroll.prototype.getAttribute =3D function(attribute) {
   var val =3D null;
   var el =3D this.getEl();
  =20
   if (attribute =3D=3D 'scroll') {
      val =3D [ el.scrollLeft, el.scrollTop ];
   } else {
      val =3D parseFloat( YAHOO.util.Dom.getStyle(el, attribute) );
   }
  =20
   return val;
};

/**
 * Applies a value to an attribute
 * @param {String} attribute The name of the attribute.
 * @param {Number} val The value to be applied to the attribute.
 * @param {String} unit The unit ('px', '%', etc.) of the value.
 */
YAHOO.util.Scroll.prototype.setAttribute =3D function(attribute, val, =
unit) {
   var el =3D this.getEl();
  =20
   if (attribute =3D=3D 'scroll') {
      el.scrollLeft =3D val[0];
      el.scrollTop =3D val[1];
   } else {
      YAHOO.util.Dom.setStyle(el, attribute, val + unit);=20
   }
};

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/js/yui/dragdrop.js

/*                                                                       =
                                                                         =
     =20
Copyright (c) 2006, Yahoo! Inc. All rights reserved.                     =
                                                                         =
     =20
Code licensed under the BSD License:                                     =
                                                                         =
     =20
http://developer.yahoo.net/yui/license.txt                               =
                                                                         =
     =20
version: 0.10.0                                                          =
                                                                         =
     =20
*/=20

/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

/**
 * Defines the interface and base operation of items that that can be=20
 * dragged or can be drop targets.  It was designed to be extended, =
overriding
 * the event handlers for startDrag, onDrag, onDragOver, onDragOut.
 * Up to three html elements can be associated with a DragDrop instance:
 * <ul>
 * <li>linked element: the element that is passed into the constructor.
 * This is the element which defines the boundaries for interaction with =

 * other DragDrop objects.</li>
 * <li>handle element(s): The drag operation only occurs if the element =
that=20
 * was clicked matches a handle element.  By default this is the linked=20
 * element, but there are times that you will want only a portion of the =

 * linked element to initiate the drag operation, and the =
setHandleElId()=20
 * method provides a way to define this.</li>
 * <li>drag element: this represents an the element that would be moved =
along
 * with the cursor during a drag operation.  By default, this is the =
linked
 * element itself as in {@link YAHOO.util.DD}.  setDragElId() lets you =
define
 * a separate element that would be moved, as in {@link =
YAHOO.util.DDProxy}
 * </li>
 * </ul>
 * This class should not be instantiated until the onload event to =
ensure that
 * the associated elements are available.
 * The following would define a DragDrop obj that would interact with =
any=20
 * other * DragDrop obj in the "group1" group:
 * <pre>
 *  dd =3D new YAHOO.util.DragDrop("div1", "group1");
 * </pre>
 * Since none of the event handlers have been implemented, nothing would =

 * actually happen if you were to run the code above.  Normally you =
would=20
 * override this class or one of the default implementations, but you =
can=20
 * also override the methods you want on an instance of the class...
 * <pre>
 *  dd.onDragDrop =3D function(e, id) {
 *   alert("dd was dropped on " + id);
 *  }
 * </pre>
 * @constructor
 * @param {String} id of the element that is linked to this instance
 * @param {String} sGroup the group of related DragDrop objects
 */
YAHOO.util.DragDrop =3D function(id, sGroup) {
    if (id) {
        this.init(id, sGroup);=20
    }
};

YAHOO.util.DragDrop.prototype =3D {

    /**
     * The id of the element associated with this object.  This is what =
we=20
     * refer to as the "linked element" because the size and position of =

     * this element is used to determine when the drag and drop objects =
have=20
     * interacted.
     *
     * @type String
     */
    id: null,

    /**
     * The id of the element that will be dragged.  By default this is =
same=20
     * as the linked element , but could be changed to another element. =
Ex:=20
     * YAHOO.util.DDProxy
     *
     * @type String
     * @private
     */
    dragElId: null,=20

    /**
     * the id of the element that initiates the drag operation.  By =
default=20
     * this is the linked element, but could be changed to be a child of =
this
     * element.  This lets us do things like only starting the drag when =
the=20
     * header element within the linked html element is clicked.
     *
     * @type String
     * @private
     */
    handleElId: null,=20

    /**
     * An associative array of HTML tags that will be ignored if =
clicked.
     * @type {string: string}
     */
    invalidHandleTypes: null,=20

    /**
     * An associative array of ids for elements that will be ignored if =
clicked
     * @type {string: string}
     */
    invalidHandleIds: null,=20

    /**
     * An indexted array of css class names for elements that will be =
ignored
     * if clicked.
     * @type string[]
     */
    invalidHandleClasses: null,=20

    /**
     * The linked element's absolute X position at the time the drag was =

     * started
     *
     * @type int
     * @private
     */
    startPageX: 0,

    /**
     * The linked element's absolute X position at the time the drag was =

     * started
     *
     * @type int
     * @private
     */
    startPageY: 0,

    /**
     * The group defines a logical collection of DragDrop objects that =
are=20
     * related.  Instances only get events when interacting with other=20
     * DragDrop object in the same group.  This lets us define multiple=20
     * groups using a single DragDrop subclass if we want.
     * @type {string: string}
     */
    groups: null,

    /**
     * Individual drag/drop instances can be locked.  This will prevent=20
     * onmousedown start drag.
     *
     * @type boolean
     * @private
     */
    locked: false,

    /**
     * Lock this instance
     */
    lock: function() { this.locked =3D true; },

    /**
     * Unlock this instace
     */
    unlock: function() { this.locked =3D false; },

    /**
     * By default, all insances can be a drop target.  This can be =
disabled by
     * setting isTarget to false.
     *
     * @type boolean
     */
    isTarget: true,

    /**
     * The padding configured for this drag and drop object for =
calculating
     * the drop zone intersection with this object.
     * @type int[]
     */
    padding: null,

    /**
     * @private
     */
    _domRef: null,

    /**
     * Internal typeof flag
     * @private
     */
    __ygDragDrop: true,

    /**
     * Set to true when horizontal contraints are applied
     *
     * @type boolean
     * @private
     */
    constrainX: false,

    /**
     * Set to true when vertical contraints are applied
     *
     * @type boolean
     * @private
     */
    constrainY: false,

    /**
     * The left constraint
     *
     * @type int
     * @private
     */
    minX: 0,

    /**
     * The right constraint
     *
     * @type int
     * @private
     */
    maxX: 0,

    /**
     * The up constraint=20
     *
     * @type int
     * @private
     */
    minY: 0,

    /**
     * The down constraint=20
     *
     * @type int
     * @private
     */
    maxY: 0,

    /**
     * Maintain offsets when we resetconstraints.  Used to maintain the=20
     * slider thumb value, and this needs to be fixed.
     * @type boolean
     */
    maintainOffset: false,

    /**
     * Array of pixel locations the element will snap to if we specified =
a=20
     * horizontal graduation/interval.  This array is generated =
automatically
     * when you define a tick interval.
     * @type int[]
     */
    xTicks: null,

    /**
     * Array of pixel locations the element will snap to if we specified =
a=20
     * vertical graduation/interval.  This array is generated =
automatically=20
     * when you define a tick interval.
     * @type int[]
     */
    yTicks: null,

    /**
     * By default the drag and drop instance will only respond to the =
primary
     * button click (left button for a right-handed mouse).  Set to true =
to
     * allow drag and drop to start with any mouse click that is =
propogated
     * by the browser
     * @type boolean
     */
    primaryButtonOnly: true,

    /**
     * The availabe property is false until the linked dom element is =
accessible.
     * @type boolean
     */
    available: false,

    /**
     * Code that executes immediately before the startDrag event
     * @private
     */
    b4StartDrag: function(x, y) { },

    /**
     * Abstract method called after a drag/drop object is clicked
     * and the drag or mousedown time thresholds have beeen met.
     *
     * @param {int} X click location
     * @param {int} Y click location
     */
    startDrag: function(x, y) { /* override this */ },

    /**
     * Code that executes immediately before the onDrag event
     * @private
     */
    b4Drag: function(e) { },

    /**
     * Abstract method called during the onMouseMove event while =
dragging an=20
     * object.
     *
     * @param {Event} e
     */
    onDrag: function(e) { /* override this */ },

    /**
     * Code that executes immediately before the onDragEnter event
     * @private
     */
    // b4DragEnter: function(e) { },

    /**
     * Abstract method called when this element fist begins hovering =
over=20
     * another DragDrop obj
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the =
element
     * id this is hovering over.  In INTERSECT mode, an array of one or =
more=20
     * dragdrop items being hovered over.
     */
    onDragEnter: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the onDragOver event
     * @private
     */
    b4DragOver: function(e) { },

    /**
     * Abstract method called when this element is hovering over another =

     * DragDrop obj
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the =
element
     * id this is hovering over.  In INTERSECT mode, an array of dd =
items=20
     * being hovered over.
     */
    onDragOver: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the onDragOut event
     * @private
     */
    b4DragOut: function(e) { },

    /**
     * Abstract method called when we are no longer hovering over an =
element
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the =
element
     * id this was hovering over.  In INTERSECT mode, an array of dd =
items=20
     * that the mouse is no longer over.
     */
    onDragOut: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the onDragDrop event
     * @private
     */
    b4DragDrop: function(e) { },

    /**
     * Abstract method called when this item is dropped on another =
DragDrop=20
     * obj
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the =
element
     * id this was dropped on.  In INTERSECT mode, an array of dd items =
this=20
     * was dropped on.
     */
    onDragDrop: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the endDrag event
     * @private
     */
    b4EndDrag: function(e) { },

    /**
     * Fired when we are done dragging the object
     *
     * @param {Event} e
     */
    endDrag: function(e) { /* override this */ },

    /**
     * Code executed immediately before the onMouseDown event

     * @param {Event} e
     * @private
     */
    b4MouseDown: function(e) {  },

    /**
     * Event handler that fires when a drag/drop obj gets a mousedown
     * @param {Event} e
     */
    onMouseDown: function(e) { /* override this */ },

    /**
     * Event handler that fires when a drag/drop obj gets a mouseup
     * @param {Event} e
     */
    onMouseUp: function(e) { /* override this */ },
  =20
    /**
     * Override the onAvailable method to do what is needed after the =
initial
     * position was determined.
     */
    onAvailable: function () {=20
    },

    /**
     * Returns a reference to the linked element
     *
     * @return {HTMLElement} the html element=20
     */
    getEl: function() {=20
        if (!this._domRef) {
            this._domRef =3D this.DDM.getElement(this.id);=20
        }

        return this._domRef;
    },

    /**
     * Returns a reference to the actual element to drag.  By default =
this is
     * the same as the html element, but it can be assigned to another=20
     * element. An example of this can be found in YAHOO.util.DDProxy
     *
     * @return {HTMLElement} the html element=20
     */
    getDragEl: function() {
        return this.DDM.getElement(this.dragElId);
    },

    /**
     * Sets up the DragDrop object.  Must be called in the constructor =
of any
     * YAHOO.util.DragDrop subclass
     *
     * @param id the id of the linked element
     * @param {String} sGroup the group of related items
     * element is supposed to be a target only, set to false.
     */
    init: function(id, sGroup) {
        this.initTarget(id, sGroup);
        YAHOO.util.Event.addListener(this.id, "mousedown",=20
                                          this.handleMouseDown, this, =
true);
    },

    /**
     * Initializes Targeting functionality only... the object does not
     * get a mousedown handler.
     *
     * @param id the id of the linked element
     * @param {String} sGroup the group of related items
     * element is supposed to be a target only, set to false.
     */
    initTarget: function(id, sGroup) {

        // create a local reference to the drag and drop manager
        this.DDM =3D YAHOO.util.DDM;


        // set the default padding
        this.padding =3D [0, 0, 0, 0];

        // initialize the groups array
        this.groups =3D {};

        // set the id
        this.id =3D id;

        // the element is a drag handle by default
        this.setDragElId(id);=20

        // by default, clicked anchors will not start drag operations
        this.invalidHandleTypes =3D { A: "A" };
        this.invalidHandleIds =3D {};
        this.invalidHandleClasses =3D [];

        // We don't want to register this as the handle with the manager
        // so we just set the id rather than calling the setter
        this.handleElId =3D id;

        // cache the position of the element if we can
        // if (document && document.body) {
            // this.setInitPosition();
        // }

        // var self =3D this;
        YAHOO.util.Event.onAvailable(id, this.handleOnAvailable, this, =
true);

        // add to an interaction group
        this.addToGroup((sGroup) ? sGroup : "default");
    },

    /**
     * Executed when the linked element is available
     * @private
     */
    handleOnAvailable: function() {
        this.available =3D true;
        this.resetConstraints();
        this.onAvailable();
    },

     /**
     * Configures the padding for the target zone in px.  Effectively =
expands
     * (or reduces) the virtual object size for targeting calculations.  =

     * Supports css-style shorthand; if only one parameter is passed, =
all sides
     * will have that padding, and if only two are passed, the top and =
bottom
     * will have the first param, the left and right the second.
     * @param {int} iTop    Top pad
     * @param {int} iRight  Right pad
     * @param {int} iBot    Bot pad
     * @param {int} iLeft   Left pad
     */
    setPadding: function(iTop, iRight, iBot, iLeft) {
        // this.padding =3D [iLeft, iRight, iTop, iBot];
        if (!iRight && 0 !=3D=3D iRight) {
            this.padding =3D [iTop, iTop, iTop, iTop];
        } else if (!iBot && 0 !=3D=3D iBot) {
            this.padding =3D [iTop, iRight, iTop, iRight];
        } else {
            this.padding =3D [iTop, iRight, iBot, iLeft];
        }
    },

    /**
     * Stores the initial placement of the dd element
     */
    setInitPosition: function(diffX, diffY) {
        var el =3D this.getEl();

        if (!this.DDM.verifyEl(el)) {
            return;
        }

        var dx =3D diffX || 0;
        var dy =3D diffY || 0;

        var p =3D YAHOO.util.Dom.getXY( el );

        this.initPageX =3D p[0] - dx;
        this.initPageY =3D p[1] - dy;

        this.lastPageX =3D p[0];
        this.lastPageY =3D p[1];


        this.setStartPosition(p);
    },

    /**
     * Sets the start position of the element.  This is set when the obj
     * is initialized, the reset when a drag is started.
     * @param pos current position (from previous lookup)
     * @private
     */
    setStartPosition: function(pos) {

        var p =3D pos || YAHOO.util.Dom.getXY( this.getEl() );

        this.startPageX =3D p[0];
        this.startPageY =3D p[1];
    },

    /**
     * Add this instance to a group of related drag/drop objects.  All=20
     * instances belong to at least one group, and can belong to as many =

     * groups as needed.
     *
     * @param sGroup {string} the name of the group
     */
    addToGroup: function(sGroup) {
        this.groups[sGroup] =3D true;
        this.DDM.regDragDrop(this, sGroup);
    },

    /**
     * Allows you to specify that an element other than the linked =
element=20
     * will be moved with the cursor during a drag
     *
     * @param id the id of the element that will be used to initiate the =
drag
     */
    setDragElId: function(id) {
        this.dragElId =3D id;
    },

    /**
     * Allows you to specify a child of the linked element that should =
be=20
     * used to initiate the drag operation.  An example of this would be =
if=20
     * you have a content div with text and links.  Clicking anywhere in =
the=20
     * content area would normally start the drag operation.  Use this =
method
     * to specify that an element inside of the content div is the =
element=20
     * that starts the drag operation.
     *
     * @param id the id of the element that will be used to initiate the =
drag
     */
    setHandleElId: function(id) {
        this.handleElId =3D id;
        this.DDM.regHandle(this.id, id);
    },

    /**
     * Allows you to set an element outside of the linked element as a =
drag=20
     * handle
     */
    setOuterHandleElId: function(id) {
        YAHOO.util.Event.addListener(id, "mousedown",=20
                this.handleMouseDown, this, true);
        this.setHandleElId(id);
    },

    /**
     * Remove all drag and drop hooks for this element
     */
    unreg: function() {
        YAHOO.util.Event.removeListener(this.id, "mousedown",=20
                this.handleMouseDown);
        this._domRef =3D null;
        this.DDM._remove(this);
    },

    /**
     * Returns true if this instance is locked, or the drag drop mgr is =
locked
     * (meaning that all drag/drop is disabled on the page.)
     *
     * @return {boolean} true if this obj or all drag/drop is locked, =
else=20
     * false
     */
    isLocked: function() {
        return (this.DDM.isLocked() || this.locked);
    },

    /**
     * Fired when this object is clicked
     *
     * @param {Event} e=20
     * @param {YAHOO.util.DragDrop} oDD the clicked dd object (this dd =
obj)
     * @private
     */
    handleMouseDown: function(e, oDD) {


        var EU =3D YAHOO.util.Event;

        var button =3D e.which || e.button;

        if (this.primaryButtonOnly && button > 1) {
            return;
        }

        if (this.isLocked()) {
            return;
        }


        this.DDM.refreshCache(this.groups);

        // Only process the event if we really clicked within the linked =

        // element.  The reason we make this check is that in the case =
that=20
        // another element was moved between the clicked element and the =

        // cursor in the time between the mousedown and mouseup events. =
When=20
        // this happens, the element gets the next mousedown event=20
        // regardless of where on the screen it happened. =20
        var pt =3D new YAHOO.util.Point(EU.getPageX(e), EU.getPageY(e));
        if ( this.DDM.isOverTarget(pt, this) )  {


            //  check to see if the handle was clicked
            var srcEl =3D EU.getTarget(e);

            if (this.isValidHandleChild(srcEl) &&
                    (this.id =3D=3D this.handleElId ||=20
                     this.DDM.handleWasClicked(srcEl, this.id)) ) {


                // set the initial element position
                this.setStartPosition();


                this.b4MouseDown(e);
                this.onMouseDown(e);
                this.DDM.handleMouseDown(e, this);

                this.DDM.stopEvent(e);
            }
        }
    },

    /**
     * Allows you to specify a tag name that should not start a drag =
operation
     * when clicked.  This is designed to facilitate embedding links =
within a
     * drag handle that do something other than start the drag.
     *=20
     * @param {string} tagName the type of element to exclude
     */
    addInvalidHandleType: function(tagName) {
        var type =3D tagName.toUpperCase();
        this.invalidHandleTypes[type] =3D type;
    },

    /**
     * Lets you to specify an element id for a child of a drag handle
     * that should not initiate a drag
     * @param {string} id the element id of the element you wish to =
ignore
     */
    addInvalidHandleId: function(id) {
        this.invalidHandleIds[id] =3D id;
    },

    /**
     * Lets you specify a css class of elements that will not initiate a =
drag
     * @param {string} cssClass the class of the elements you wish to =
ignore
     */
    addInvalidHandleClass: function(cssClass) {
        this.invalidHandleClasses.push(cssClass);
    },

    /**
     * Unsets an excluded tag name set by addInvalidHandleType
     *=20
     * @param {string} tagName the type of element to unexclude
     */
    removeInvalidHandleType: function(tagName) {
        var type =3D tagName.toUpperCase();
        // this.invalidHandleTypes[type] =3D null;
        delete this.invalidHandleTypes[type];
    },
   =20
    /**
     * Unsets an invalid handle id
     * @param {string} the id of the element to re-enable
     */
    removeInvalidHandleId: function(id) {
        delete this.invalidHandleIds[id];
    },

    /**
     * Unsets an invalid css class
     * @param {string} the class of the element(s) you wish to re-enable
     */
    removeInvalidHandleClass: function(cssClass) {
        for (var i=3D0, len=3Dthis.invalidHandleClasses.length; i<len; =
++i) {
            if (this.invalidHandleClasses[i] =3D=3D cssClass) {
                delete this.invalidHandleClasses[i];
            }
        }
    },

    /**
     * Checks the tag exclusion list to see if this click should be =
ignored
     *
     * @param {ygNode} node
     * @return {boolean} true if this is a valid tag type, false if not
     */
    isValidHandleChild: function(node) {
        // var type =3D node.nodeName;

        // if (type =3D=3D "#text") {
            // type =3D node.parentNode.nodeName;
        // }

        var valid =3D true;
        var n =3D (node.nodeName =3D=3D "#text") ? node.parentNode : =
node;
        valid =3D valid && !this.invalidHandleTypes[n.nodeName];
        valid =3D valid && !this.invalidHandleIds[n.id];

        for (var i=3D0, len=3Dthis.invalidHandleClasses.length; valid && =
i<len; ++i) {
            valid =3D !YAHOO.util.Dom.hasClass(n, =
this.invalidHandleClasses[i]);
        }


        return valid;

        //return ( !(this.invalidHandleTypes[n.nodeName] ||=20
                    //this.invalidHandleIds[n.id]) );
    },

    /**
     * Create the array of horizontal tick marks if an interval was =
specified
     * in setXConstraint().
     *
     * @private
     */
    setXTicks: function(iStartX, iTickSize) {
        this.xTicks =3D [];
        this.xTickSize =3D iTickSize;
       =20
        var tickMap =3D {};

        for (var i =3D this.initPageX; i >=3D this.minX; i =3D i - =
iTickSize) {
            if (!tickMap[i]) {
                this.xTicks[this.xTicks.length] =3D i;
                tickMap[i] =3D true;
            }
        }

        for (i =3D this.initPageX; i <=3D this.maxX; i =3D i + =
iTickSize) {
            if (!tickMap[i]) {
                this.xTicks[this.xTicks.length] =3D i;
                tickMap[i] =3D true;
            }
        }

        this.xTicks.sort(this.DDM.numericSort) ;
    },

    /**
     * Create the array of vertical tick marks if an interval was =
specified in=20
     * setYConstraint().
     *
     * @private
     */
    setYTicks: function(iStartY, iTickSize) {
        this.yTicks =3D [];
        this.yTickSize =3D iTickSize;

        var tickMap =3D {};

        for (var i =3D this.initPageY; i >=3D this.minY; i =3D i - =
iTickSize) {
            if (!tickMap[i]) {
                this.yTicks[this.yTicks.length] =3D i;
                tickMap[i] =3D true;
            }
        }

        for (i =3D this.initPageY; i <=3D this.maxY; i =3D i + =
iTickSize) {
            if (!tickMap[i]) {
                this.yTicks[this.yTicks.length] =3D i;
                tickMap[i] =3D true;
            }
        }

        this.yTicks.sort(this.DDM.numericSort) ;
    },

    /**
     * By default, the element can be dragged any place on the screen.  =
Use=20
     * this method to limit the horizontal travel of the element.  Pass =
in=20
     * 0,0 for the parameters if you want to lock the drag to the y =
axis.
     *
     * @param {int} iLeft the number of pixels the element can move to =
the left
     * @param {int} iRight the number of pixels the element can move to =
the=20
     * right
     * @param {int} iTickSize optional parameter for specifying that the =

     * element
     * should move iTickSize pixels at a time.
     */
    setXConstraint: function(iLeft, iRight, iTickSize) {
        this.leftConstraint =3D iLeft;

        this.rightConstraint =3D iRight;

        this.minX =3D this.initPageX - iLeft;
        this.maxX =3D this.initPageX + iRight;
        if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }

        this.constrainX =3D true;
    },

    /**
     * By default, the element can be dragged any place on the screen.  =
Set=20
     * this to limit the vertical travel of the element.  Pass in 0,0 =
for the
     * parameters if you want to lock the drag to the x axis.
     *
     * @param {int} iUp the number of pixels the element can move up
     * @param {int} iDown the number of pixels the element can move down
     * @param {int} iTickSize optional parameter for specifying that the =

     * element should move iTickSize pixels at a time.
     */
    setYConstraint: function(iUp, iDown, iTickSize) {
        this.topConstraint =3D iUp;
        this.bottomConstraint =3D iDown;

        this.minY =3D this.initPageY - iUp;
        this.maxY =3D this.initPageY + iDown;
        if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }

        this.constrainY =3D true;
       =20
    },

    /**
     * resetConstraints must be called if you manually reposition a dd =
element.
     * @param {boolean} maintainOffset
     */
    resetConstraints: function() {


        // Maintain offsets if necessary
        if (this.initPageX || this.initPageX =3D=3D=3D 0) {
            // figure out how much this thing has moved
            var dx =3D (this.maintainOffset) ? this.lastPageX - =
this.initPageX : 0;
            var dy =3D (this.maintainOffset) ? this.lastPageY - =
this.initPageY : 0;

            this.setInitPosition(dx, dy);

        // This is the first time we have detected the element's =
position
        } else {
            this.setInitPosition();
        }

        if (this.constrainX) {
            this.setXConstraint( this.leftConstraint,=20
                                 this.rightConstraint,=20
                                 this.xTickSize        );
        }

        if (this.constrainY) {
            this.setYConstraint( this.topConstraint,=20
                                 this.bottomConstraint,=20
                                 this.yTickSize         );
        }
    },

    /**
     * Normally the drag element is moved pixel by pixel, but we can =
specify=20
     * that it move a number of pixels at a time.  This method resolves =
the=20
     * location when we have it set up like this.
     *
     * @param {int} val where we want to place the object
     * @param {int[]} tickArray sorted array of valid points
     * @return {int} the closest tick
     * @private
     */
    getTick: function(val, tickArray) {

        if (!tickArray) {
            // If tick interval is not defined, it is effectively 1 =
pixel,=20
            // so we return the value passed to us.
            return val;=20
        } else if (tickArray[0] >=3D val) {
            // The value is lower than the first tick, so we return the =
first
            // tick.
            return tickArray[0];
        } else {
            for (var i=3D0, len=3DtickArray.length; i<len; ++i) {
                var next =3D i + 1;
                if (tickArray[next] && tickArray[next] >=3D val) {
                    var diff1 =3D val - tickArray[i];
                    var diff2 =3D tickArray[next] - val;
                    return (diff2 > diff1) ? tickArray[i] : =
tickArray[next];
                }
            }

            // The value is larger than the last tick, so we return the =
last
            // tick.
            return tickArray[tickArray.length - 1];
        }
    },

    /**
     * toString method
     * @return {string} string representation of the dd obj
     */
    toString: function(val, tickArray) {
        return ("YAHOO.util.DragDrop {" + this.id + "}");
    }

};

/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

// Only load the library once.  Rewriting the manager class would orphan =

// existing drag and drop instances.
if (!YAHOO.util.DragDropMgr) {

    /**
     * Handles the element interaction for all DragDrop items in the=20
     * window.  Generally, you will not call this class directly, but it =
does
     * have helper methods that could be useful in your DragDrop=20
     * implementations.  This class should not be instantiated; all =
methods=20
     * are are static.
     *
     * @constructor
     */
    YAHOO.util.DragDropMgr =3D new function() {

        /**
         * Two dimensional Array of registered DragDrop objects.  The =
first=20
         * dimension is the DragDrop item group, the second the DragDrop =

         * object.
         *
         * @type {string: string}
         * @private
         */
        this.ids =3D {};

        /**
         * Array of element ids defined as drag handles.  Used to =
determine=20
         * if the element that generated the mousedown event is actually =
the=20
         * handle and not the html element itself.
         *
         * @type {string: string}
         * @private
         */
        this.handleIds =3D {};

        /**
         * the DragDrop object that is currently being dragged
         *
         * @type DragDrop
         * @private
         **/
        this.dragCurrent =3D null;

        /**
         * the DragDrop object(s) that are being hovered over
         *
         * @type Array
         * @private
         */
        this.dragOvers =3D {};

        /**
         * @private
         */

        /**
         * the X distance between the cursor and the object being =
dragged
         *
         * @type int
         * @private
         */
        this.deltaX =3D 0;

        /**
         * the Y distance between the cursor and the object being =
dragged
         *
         * @type int
         * @private
         */
        this.deltaY =3D 0;

        /**
         * Flag to determine if we should prevent the default behavior =
of the
         * events we define. By default this is true, but this can be =
set to=20
         * false if you need the default behavior (not recommended)
         *
         * @type boolean
         */
        this.preventDefault =3D true;

        /**
         * Flag to determine if we should stop the propagation of the =
events=20
         * we generate. This is true by default but you may want to set =
it to
         * false if the html element contains other features that =
require the
         * mouse click.
         *
         * @type boolean
         */
        this.stopPropagation =3D true;

        /**
         * @private
         */
        this.initalized =3D false;

        /**
         * All drag and drop can be disabled.
         *
         * @private
         */
        this.locked =3D false;
       =20
        /**
         * Called the first time an element is registered.
         *
         * @private
         */
        this.init =3D function() {
        };

        /**
         * In point mode, drag and drop interaction is defined by the=20
         * location of the cursor during the drag/drop
         * @type int
         */
        this.POINT     =3D 0;

        /**
         * In intersect mode, drag and drop interactio nis defined by =
the=20
         * overlap of two or more drag and drop objects.
         * @type int
         */
        this.INTERSECT =3D 1;

        /**
         * The current drag and drop mode.  Default it point mode
         * @type int
         */
        this.mode =3D this.POINT;

        /**
         * Runs method on all drag and drop objects
         * @private
         */
        this._execOnAll =3D function(sMethod, args) {
            for (var i in this.ids) {
                for (var j in this.ids[i]) {
                    var oDD =3D this.ids[i][j];
                    if (! this.isTypeOfDD(oDD)) {
                        continue;
                    }
                    oDD[sMethod].apply(oDD, args);
                }
            }
        };

        /**
         * Drag and drop initialization.  Sets up the global event =
handlers
         * @private
         */
        this._onLoad =3D function() {

            // Switched to onAvailable in 2.0.1 (in DragDrop.initTarget)
            // this._execOnAll("setInitPosition", []);


            var EU =3D YAHOO.util.Event;

            EU.on(document, "mouseup",   this.handleMouseUp, this, =
true);
            EU.on(document, "mousemove", this.handleMouseMove, this, =
true);
            EU.on(window,   "unload",    this._onUnload, this, true);
            EU.on(window,   "resize",    this._onResize, this, true);
            // EU.on(window,   "mouseout",    this._test);

            this.initalized =3D true;

        };

        /**
         * Reset constraints on all drag and drop objs
         * @private
         */
        this._onResize =3D function(e) {
            this._execOnAll("resetConstraints", []);
        };

        /**
         * Lock all drag and drop functionality
         */
        this.lock =3D function() { this.locked =3D true; };

        /**
         * Unlock all drag and drop functionality
         */
        this.unlock =3D function() { this.locked =3D false; };

        /**
         * Is drag and drop locked?
         *
         * @return {boolean} True if drag and drop is locked, false =
otherwise.
         */
        this.isLocked =3D function() { return this.locked; };

        /**
         * Location cache that is set for all drag drop objects when a =
drag is
         * initiated, cleared when the drag is finished.
         *
         * @private
         */
        this.locationCache =3D {};

        /**
         * Set useCache to false if you want to force object the lookup =
of each
         * drag and drop linked element constantly during a drag.
         * @type boolean
         */
        this.useCache =3D true;

        /**
         * The number of pixels that the mouse needs to move after the=20
         * mousedown before the drag is initiated.  Default=3D3;
         * @type int
         */
        this.clickPixelThresh =3D 3;

        /**
         * The number of milliseconds after the mousedown event to =
initiate the
         * drag if we don't get a mouseup event. Default=3D1000
         * @type int
         */
        this.clickTimeThresh =3D 1000;

        /**
         * Flag that indicates that either the drag pixel threshold or =
the=20
         * mousdown time threshold has been met
         * @type boolean
         * @private
         */
        this.dragThreshMet =3D false;

        /**
         * Timeout used for the click time threshold
         * @type Object
         * @private
         */
        this.clickTimeout =3D null;

        /**
         * The X position of the mousedown event stored for later use =
when a=20
         * drag threshold is met.
         * @type int
         * @private
         */
        this.startX =3D 0;

        /**
         * The Y position of the mousedown event stored for later use =
when a=20
         * drag threshold is met.
         * @type int
         * @private
         */
        this.startY =3D 0;

        /**
         * Each DragDrop instance must be registered with the =
DragDropMgr. =20
         * This is executed in ygDragDrop.init()
         *
         * @param {DragDrop} oDD the DragDrop object to register
         * @param {String} sGroup the name of the group this element =
belongs to
         */
        this.regDragDrop =3D function(oDD, sGroup) {
            if (!this.initialized) { this.init(); }
           =20
            if (!this.ids[sGroup]) {
                this.ids[sGroup] =3D {};
            }
            this.ids[sGroup][oDD.id] =3D oDD;
        };

        /**
         * Unregisters a drag and drop item.  This is executed in=20
         * ygDragDrop.unreg, use that method instead of calling this =
directly.
         * @private
         */
        this._remove =3D function(oDD) {
            for (var g in oDD.groups) {
                if (g && this.ids[g][oDD.id]) {
                    delete this.ids[g][oDD.id];
                }
            }
            delete this.handleIds[oDD.id];
        };

        /**
         * Each DragDrop handle element must be registered.  This is =
done
         * automatically when executing ygDragDrop.setHandleElId()
         *
         * @param {String} sDDId the DragDrop id this element is a =
handle for
         * @param {String} sHandleId the id of the element that is the =
drag=20
         * handle
         */
        this.regHandle =3D function(sDDId, sHandleId) {
            if (!this.handleIds[sDDId]) {
                this.handleIds[sDDId] =3D {};
            }
            this.handleIds[sDDId][sHandleId] =3D sHandleId;
        };

        /**
         * Utility function to determine if a given element has been=20
         * registered as a drag drop item.
         *
         * @param {String} id the element id to check
         * @return {boolean} true if this element is a DragDrop item,=20
         * false otherwise
         */
        this.isDragDrop =3D function(id) {
            return ( this.getDDById(id) ) ? true : false;
        };

        /**
         * Returns the drag and drop instances that are in all groups =
the
         * passed in instance belongs to.
         *
         * @param {ygDragDrop} p_oDD the obj to get related data for
         * @param {boolean} bTargetsOnly if true, only return targetable =
objs
         * @return {ygDragDrop[]} the related instances
         */
        this.getRelated =3D function(p_oDD, bTargetsOnly) {
            var oDDs =3D [];
            for (var i in p_oDD.groups) {
                for (j in this.ids[i]) {
                    var dd =3D this.ids[i][j];
                    if (! this.isTypeOfDD(dd)) {
                        continue;
                    }
                    if (!bTargetsOnly || dd.isTarget) {
                        oDDs[oDDs.length] =3D dd;
                    }
                }
            }

            return oDDs;
        };

        /**
         * Returns true if the specified dd target is a legal target for =

         * the specifice drag obj
         *
         * @param {ygDragDrop} the drag obj
         * @param {ygDragDrop) the target
         * @return {boolean} true if the target is a legal target for =
the=20
         * dd obj
         */
        this.isLegalTarget =3D function (oDD, oTargetDD) {
            var targets =3D this.getRelated(oDD);
            for (var i=3D0, len=3Dtargets.length;i<len;++i) {
                if (targets[i].id =3D=3D oTargetDD.id) {
                    return true;
                }
            }

            return false;
        };

        /**
         * My goal is to be able to transparently determine if an object =
is
         * typeof ygDragDrop, and the exact subclass of ygDragDrop.  =
typeof=20
         * returns "object", oDD.constructor.toString() always returns
         * "ygDragDrop" and not the name of the subclass.  So for now it =
just
         * evaluates a well-known variable in ygDragDrop.
         *
         * @param {Object} the object to evaluate
         * @return {boolean} true if typeof oDD =3D ygDragDrop
         */
        this.isTypeOfDD =3D function (oDD) {
            return (oDD && oDD.__ygDragDrop);
        };

        /**
         * Utility function to determine if a given element has been=20
         * registered as a drag drop handle for the given Drag Drop =
object.
         *
         * @param {String} id the element id to check
         * @return {boolean} true if this element is a DragDrop handle, =
false=20
         * otherwise
         */
        this.isHandle =3D function(sDDId, sHandleId) {
            return ( this.handleIds[sDDId] &&=20
                            this.handleIds[sDDId][sHandleId] );
        };

        /**
         * Returns the DragDrop instance for a given id
         *
         * @param {String} id the id of the DragDrop object
         * @return {DragDrop} the drag drop object, null if it is not =
found
         */
        this.getDDById =3D function(id) {
            for (var i in this.ids) {
                if (this.ids[i][id]) {
                    return this.ids[i][id];
                }
            }
            return null;
        };

        /**
         * Fired after a registered DragDrop object gets the mousedown =
event.
         * Sets up the events required to track the object being dragged
         *
         * @param {Event} e the event
         * @param oDD the DragDrop object being dragged
         * @private
         */
        this.handleMouseDown =3D function(e, oDD) {

            this.currentTarget =3D YAHOO.util.Event.getTarget(e);

            this.dragCurrent =3D oDD;

            var el =3D oDD.getEl();

            // track start position
            this.startX =3D YAHOO.util.Event.getPageX(e);
            this.startY =3D YAHOO.util.Event.getPageY(e);

            this.deltaX =3D this.startX - el.offsetLeft;
            this.deltaY =3D this.startY - el.offsetTop;

            this.dragThreshMet =3D false;

            this.clickTimeout =3D setTimeout(=20
                    function() {=20
                        var DDM =3D YAHOO.util.DDM;
                        DDM.startDrag(DDM.startX, DDM.startY);=20
                    },=20
                    this.clickTimeThresh );
        };

        /**
         * Fired when either the drag pixel threshol or the mousedown =
hold=20
         * time threshold has been met.
         *=20
         * @param x {int} the X position of the original mousedown
         * @param y {int} the Y position of the original mousedown
         */
        this.startDrag =3D function(x, y) {
            clearTimeout(this.clickTimeout);
            if (this.dragCurrent) {
                this.dragCurrent.b4StartDrag(x, y);
                this.dragCurrent.startDrag(x, y);
            }
            this.dragThreshMet =3D true;
        };

        /**
         * Internal function to handle the mouseup event.  Will be =
invoked=20
         * from the context of the document.
         *
         * @param {Event} e the event
         * @private
         */
        this.handleMouseUp =3D function(e) {

            if (! this.dragCurrent) {
                return;
            }

            clearTimeout(this.clickTimeout);

            if (this.dragThreshMet) {
                this.fireEvents(e, true);
            } else {
            }

            this.stopDrag(e);

            this.stopEvent(e);
        };

        /**
         * Utility to stop event propagation and event default, if these =

         * features are turned on.
         *
         * @param {Event} e the event as returned by this.getEvent()
         */
        this.stopEvent =3D function(e) {
            if (this.stopPropagation) {
                YAHOO.util.Event.stopPropagation(e);
            }

            if (this.preventDefault) {
                YAHOO.util.Event.preventDefault(e);
            }
        };

        /**=20
         * Internal function to clean up event handlers after the drag=20
         * operation is complete
         *
         * @param {Event} e the event
         * @private
         */
        this.stopDrag =3D function(e) {

            // Fire the drag end event for the item that was dragged
            if (this.dragCurrent) {
                if (this.dragThreshMet) {
                    this.dragCurrent.b4EndDrag(e);
                    this.dragCurrent.endDrag(e);
                }

                this.dragCurrent.onMouseUp(e);
            }

            this.dragCurrent =3D null;
            this.dragOvers =3D {};
        };

        /**=20
         * Internal function to handle the mousemove event.  Will be =
invoked=20
         * from the context of the html element.
         *
         * @TODO figure out what we can do about mouse events lost when =
the=20
         * user drags objects beyond the window boundary.  Currently we =
can=20
         * detect this in internet explorer by verifying that the mouse =
is=20
         * down during the mousemove event.  Firefox doesn't give us the =

         * button state on the mousemove event.
         *
         * @param {Event} e the event
         * @private
         */
        this.handleMouseMove =3D function(e) {
            if (! this.dragCurrent) {
                return;
            }

            // var button =3D e.which || e.button;

            // check for IE mouseup outside of page boundary
            if (YAHOO.util.Event.isIE && !e.button) {
                this.stopEvent(e);
                return this.handleMouseUp(e);
            }

            if (!this.dragThreshMet) {
                var diffX =3D Math.abs(this.startX - =
YAHOO.util.Event.getPageX(e));
                var diffY =3D Math.abs(this.startY - =
YAHOO.util.Event.getPageY(e));
                if (diffX > this.clickPixelThresh ||=20
                            diffY > this.clickPixelThresh) {
                    this.startDrag(this.startX, this.startY);
                }
            }

            if (this.dragThreshMet) {
                this.dragCurrent.b4Drag(e);
                this.dragCurrent.onDrag(e);
                this.fireEvents(e, false);
            }

            this.stopEvent(e);
        };

        /**
         * Iterates over all of the DragDrop elements to find ones we =
are=20
         * hovering over or dropping on
         *
         * @param {Event} e the event
         * @param {boolean} isDrop is this a drop op or a mouseover op?
         * @private
         */
        this.fireEvents =3D function(e, isDrop) {
            var dc =3D this.dragCurrent;

            // If the user did the mouse up outside of the window, we =
could=20
            // get here even though we have ended the drag.
            if (!dc || dc.isLocked()) {
                return;
            }

            var x =3D YAHOO.util.Event.getPageX(e);
            var y =3D YAHOO.util.Event.getPageY(e);
            var pt =3D new YAHOO.util.Point(x,y);

            // cache the previous dragOver array
            var oldOvers =3D [];

            var outEvts   =3D [];
            var overEvts  =3D [];
            var dropEvts  =3D [];
            var enterEvts =3D [];

            // Check to see if the object we were hovering over is no =
longer=20
            // being hovered over so we can fire the onDragOut event
            for (var i in this.dragOvers) {

                var ddo =3D this.dragOvers[i];

                if (! this.isTypeOfDD(ddo)) {
                    continue;
                }

                if (! this.isOverTarget(pt, ddo, this.mode)) {
                    outEvts.push( ddo );
                }

                oldOvers[i] =3D true;
                delete this.dragOvers[i];
            }

            for (var sGroup in dc.groups) {
               =20
                if ("string" !=3D typeof sGroup) {
                    continue;
                }

                for (i in this.ids[sGroup]) {
                    var oDD =3D this.ids[sGroup][i];
                    if (! this.isTypeOfDD(oDD)) {
                        continue;
                    }

                    if (oDD.isTarget && !oDD.isLocked() && oDD !=3D dc) =
{
                        if (this.isOverTarget(pt, oDD, this.mode)) {
                            // look for drop interactions
                            if (isDrop) {
                                dropEvts.push( oDD );
                            // look for drag enter and drag over =
interactions
                            } else {

                                // initial drag over: dragEnter fires
                                if (!oldOvers[oDD.id]) {
                                    enterEvts.push( oDD );
                                // subsequent drag overs: dragOver fires
                                } else {
                                    overEvts.push( oDD );
                                }

                                this.dragOvers[oDD.id] =3D oDD;
                            }
                        }
                    }
                }
            }

            if (this.mode) {
                if (outEvts.length) {
                    dc.b4DragOut(e, outEvts);
                    dc.onDragOut(e, outEvts);
                }

                if (enterEvts.length) {
                    dc.onDragEnter(e, enterEvts);
                }

                if (overEvts.length) {
                    dc.b4DragOver(e, overEvts);
                    dc.onDragOver(e, overEvts);
                }

                if (dropEvts.length) {
                    dc.b4DragDrop(e, dropEvts);
                    dc.onDragDrop(e, dropEvts);
                }

            } else {
                // fire dragout events
                var len =3D 0;
                for (i=3D0, len=3DoutEvts.length; i<len; ++i) {
                    dc.b4DragOut(e, outEvts[i].id);
                    dc.onDragOut(e, outEvts[i].id);
                }
                =20
                // fire enter events
                for (i=3D0,len=3DenterEvts.length; i<len; ++i) {
                    // dc.b4DragEnter(e, oDD.id);
                    dc.onDragEnter(e, enterEvts[i].id);
                }
        =20
                // fire over events
                for (i=3D0,len=3DoverEvts.length; i<len; ++i) {
                    dc.b4DragOver(e, overEvts[i].id);
                    dc.onDragOver(e, overEvts[i].id);
                }

                // fire drop events
                for (i=3D0, len=3DdropEvts.length; i<len; ++i) {
                    dc.b4DragDrop(e, dropEvts[i].id);
                    dc.onDragDrop(e, dropEvts[i].id);
                }

            }

        };

        /**
         * Helper function for getting the best match from the list of =
drag=20
         * and drop objects returned by the drag and drop events when we =
are=20
         * in INTERSECT mode.  It returns either the first object that =
the=20
         * cursor is over, or the object that has the greatest overlap =
with=20
         * the dragged element.
         *
         * @param  {ygDragDrop[]} dds The array of drag and drop objects =

         * targeted
         * @return {ygDragDrop}       The best single match
         */
        this.getBestMatch =3D function(dds) {
            var winner =3D null;
            // Return null if the input is not what we expect
            //if (!dds || !dds.length || dds.length =3D=3D 0) {
               // winner =3D null;
            // If there is only one item, it wins
            //} else if (dds.length =3D=3D 1) {

            var len =3D dds.length;

            if (len =3D=3D 1) {
                winner =3D dds[0];
            } else {
                // Loop through the targeted items
                for (var i=3D0; i<len; ++i) {
                    var dd =3D dds[i];
                    // If the cursor is over the object, it wins.  If =
the=20
                    // cursor is over multiple matches, the first one we =
come
                    // to wins.
                    if (dd.cursorIsOver) {
                        winner =3D dd;
                        break;
                    // Otherwise the object with the most overlap wins
                    } else {
                        if (!winner ||=20
                            winner.overlap.getArea() < =
dd.overlap.getArea()) {
                            winner =3D dd;
                        }
                    }
                }
            }

            return winner;
        };

        /**
         * Refreshes the cache of the top-left and bottom-right points =
of the=20
         * drag and drop objects in the specified groups
         *
         * @param {Array} aGroups an associative array of groups to =
refresh
         */
        this.refreshCache =3D function(aGroups) {
            for (sGroup in aGroups) {
                if ("string" !=3D typeof sGroup) {
                    continue;
                }
                for (i in this.ids[sGroup]) {
                    var oDD =3D this.ids[sGroup][i];

                    if (this.isTypeOfDD(oDD)) {
                        var loc =3D this.getLocation(oDD);
                        if (loc) {
                            this.locationCache[oDD.id] =3D loc;
                        } else {
                            delete this.locationCache[oDD.id];
                            // this will unregister the drag and drop =
object if
                            // the element is not in a usable state
                            oDD.unreg();
                        }
                    }
                }
            }
        };

        /**
         * This checks to make sure an element exists and is in the DOM. =
 The
         * main purpose is to handle cases where innerHTML is used to =
remove
         * drag and drop objects from the DOM.  IE provides an =
'unspecified
         * error' when trying to access the offsetParent of such an =
element
         * @param {HTMLElement} el the element to check
         * @return {boolean} true if the element looks usable
         */
        this.verifyEl =3D function(el) {
            try {
                if (el) {
                    var parent =3D el.offsetParent;
                    if (parent) {
                        return true;
                    }
                }
            } catch(e) {
            }

            return false;
        };
       =20
        /**
         * Returns the an array containing the drag and drop element's =
position
         * and size, including the ygDragDrop.padding configured for it
         *
         * @param {ygDragDrop} oDD the drag and drop object to get the=20
         * location for
         * @return array containing the top left and bottom right points =
of the=20
         * element=20
         */
        this.getLocation =3D function(oDD) {
            if (! this.isTypeOfDD(oDD)) {
                return null;
            }

            var el =3D oDD.getEl();

            if (!this.verifyEl(el)) {
                return null;
            }


            // var aPos =3D ygPos.getPos(el);
            var aPos =3D YAHOO.util.Dom.getXY(el);

            x1 =3D aPos[0];
            x2 =3D x1 + el.offsetWidth;

            y1 =3D aPos[1];
            y2 =3D y1 + el.offsetHeight;

            var t =3D y1 - oDD.padding[0];
            var r =3D x2 + oDD.padding[1];
            var b =3D y2 + oDD.padding[2];
            var l =3D x1 - oDD.padding[3];

            return new YAHOO.util.Region( t, r, b, l );

        };

        /**
         * Checks the cursor location to see if it over the target
         *=20
         * @param {YAHOO.util.Point} pt The point to evaluate
         * @param {ygDragDrop} oDDTarget the DragDrop object we are =
inspecting
         * @return {boolean} true if the mouse is over the target
         * @private
         */
        this.isOverTarget =3D function(pt, oDDTarget, intersect) {
            // use cache if available
            var loc =3D this.locationCache[oDDTarget.id];
            if (!loc || !this.useCache) {
                loc =3D this.getLocation(oDDTarget);
                this.locationCache[oDDTarget.id] =3D loc;

            }


            // var cursorIsOver =3D  (x >=3D loc[3] && x <=3D loc[1] && =
y >=3D loc[0] && y <=3D loc[2]);
            //oDDTarget.cursorIsOver =3D loc.contains( new =
YAHOO.util.Point(x, y) );
            oDDTarget.cursorIsOver =3D loc.contains( pt );
            oDDTarget.overlap =3D null;

            // if (this.INTERSECT =3D=3D this.mode) {
            if (intersect) {

                // var curRegion =3D=20
                  //   YAHOO.util.Region.getRegion(
                  //   this.dragCurrent.getDragEl());
                var el =3D this.dragCurrent.getDragEl();
                var x =3D pt.x - this.dragCurrent.deltaX;
                var y =3D pt.y - this.dragCurrent.deltaY;
                var curRegion =3D new YAHOO.util.Region( y, x + =
el.offsetWidth,
                                                       y + =
el.offsetHeight, x );

                var overlap =3D curRegion.intersect(loc);

                if (overlap) {
                    oDDTarget.overlap =3D overlap;
                    return true;
                } else {
                    return false;
                }

            } else {
                return oDDTarget.cursorIsOver;
            }
        };

        /**
         * @private
         */
        this._onUnload =3D function(e, me) {
            this.unregAll();
        };

        /**
         * Cleans up the drag and drop events and objects.
         *
         * @private
         */
        this.unregAll =3D function() {

            if (this.dragCurrent) {
                this.stopDrag();
                this.dragCurrent =3D null;
            }

            this._execOnAll("unreg", []);

            for (i in this.elementCache) {
                delete this.elementCache[i];
            }

            this.elementCache =3D {};
            this.ids =3D {};
        };

        /**
         * A cache of DOM elements
         *
         * @private
         */
        this.elementCache =3D {};
       =20
        /**
         * Get the wrapper for the DOM element specified
         *
         * @param {String} id the id of the elment to get
         * @return {YAHOO.util.DDM.ElementWrapper} the wrapped element
         * @private
         */
        this.getElWrapper =3D function(id) {
            var oWrapper =3D this.elementCache[id];
            if (!oWrapper || !oWrapper.el) {
                oWrapper =3D this.elementCache[id] =3D=20
                    new =
this.ElementWrapper(document.getElementById(id));
            }
            return oWrapper;
        };

        /**
         * Returns the actual DOM element
         *
         * @param {String} id the id of the elment to get
         * @return {Object} The element
         */
        this.getElement =3D function(id) {
            // return this.getElWrapper(id).el;
            return document.getElementById(id);
        };
       =20
        /**
         * Returns the style property for the DOM element (i.e.,=20
         * document.getElById(id).style)
         *
         * @param {String} id the id of the elment to get
         * @return {Object} The style property of the element
         */
        this.getCss =3D function(id) {
            // return this.getElWrapper(id).css;
            var css =3D null;
            var el =3D document.getElementById(id);
            if (el) {
                css =3D el.style;
            }

            return css;
        };

        /**
         * Inner class for cached elements
         */
        this.ElementWrapper =3D function(el) {
                /**
                 * @private
                 */
                this.el =3D el || null;
                /**
                 * @private
                 */
                this.id =3D this.el && el.id;
                /**
                 * @private
                 */
                this.css =3D this.el && el.style;
            };

        /**
         * Returns the X position of an html element
         * @param el the element for which to get the position
         * @return {int} the X coordinate
         */
        this.getPosX =3D function(el) {
            return YAHOO.util.Dom.getX(el);
        };

        /**
         * Returns the Y position of an html element
         * @param el the element for which to get the position
         * @return {int} the Y coordinate
         */
        this.getPosY =3D function(el) {
            return YAHOO.util.Dom.getY(el);=20
        };

        /**
         * Swap two nodes.  In IE, we use the native method, for others =
we=20
         * emulate the IE behavior
         *
         * @param n1 the first node to swap
         * @param n2 the other node to swap
         */
        this.swapNode =3D function(n1, n2) {
            if (n1.swapNode) {
                n1.swapNode(n2);
            } else {
                // the node reference order for the swap is a little =
tricky.=20
                var p =3D n2.parentNode;
                var s =3D n2.nextSibling;
                n1.parentNode.replaceChild(n2, n1);
                p.insertBefore(n1,s);
            }
        };

        /**
         * @private
         */
        this.getScroll =3D function () {
            var t, l;
            if (document.documentElement && =
document.documentElement.scrollTop) {
                t =3D document.documentElement.scrollTop;
                l =3D document.documentElement.scrollLeft;
            } else if (document.body) {
                t =3D document.body.scrollTop;
                l =3D document.body.scrollLeft;
            }
            return { top: t, left: l };
        };

        /**
         * Returns the specified element style property
         * @param {HTMLElement} el          the element
         * @param {string}      styleProp   the style property
         * @return {string}     The value of the style property
         * @deprecated, use YAHOO.util.Dom.getStyle
         */
        this.getStyle =3D function(el, styleProp) {
            return YAHOO.util.Dom.getStyle(el, styleProp);
        };

        /**
         * Gets the scrollTop
         *
         * @return {int} the document's scrollTop
         */
        this.getScrollTop =3D function () { return this.getScroll().top; =
};

        /**
         * Gets the scrollLeft
         *
         * @return {int} the document's scrollTop
         */
        this.getScrollLeft =3D function () { return =
this.getScroll().left; };

        this.moveToEl =3D function (moveEl, targetEl) {
            var aCoord =3D YAHOO.util.Dom.getXY(targetEl);
            YAHOO.util.Dom.setXY(moveEl, aCoord);
        };

        /**
         * Gets the client height
         *
         * @return {int} client height in px
         */
        this.getClientHeight =3D function() {
            return (window.innerHeight) ? window.innerHeight :=20
                (document.documentElement && =
document.documentElement.clientHeight) ?
                document.documentElement.clientHeight : =
document.body.offsetHeight;
        };

        /**
         * Gets the client width
         *
         * @return {int} client width in px
         */
        this.getClientWidth =3D function() {
            return (window.innerWidth) ? window.innerWidth :=20
                (document.documentElement && =
document.documentElement.clientWidth) ?
                document.documentElement.clientWidth : =
document.body.offsetWidth;
        };

        /**
         * numeric array sort function
         */
        this.numericSort =3D function(a, b) { return (a - b); };

        /**
         * @private
         */
        this._timeoutCount =3D 0;

        /**
         * @private
         * Trying to make the load order less important.  Without this =
we get
         * an error if this file is loaded before the Event Utility.
         */
        this._addListeners =3D function() {
            if ( YAHOO.util.Event && document ) {
                this._onLoad();
            } else {
                if (this._timeoutCount > 1000) {
                } else {
                    setTimeout(YAHOO.util.DDM._addListeners, 10);
                    if (document && document.body) {
                        this._timeoutCount +=3D 1;
                    }
                }
            }
        };

        /**
         * Recursively searches the immediate parent and all child nodes =
for=20
         * the handle element in order to determine wheter or not it was =

         * clicked.
         *
         * @param node the html element to inspect
         */
        this.handleWasClicked =3D function(node, id) {
            if (this.isHandle(id, node.id)) {
                return true;
            } else {
                // check to see if this is a text node child of the one =
we want
                var p =3D node.parentNode;

                while (p) {
                    if (this.isHandle(id, p.id)) {
                        return true;
                    } else {
                        p =3D p.parentNode;
                    }
                }
            }

            return false;
        };

    } ();

    // shorter alias, save a few bytes
    YAHOO.util.DDM =3D YAHOO.util.DragDropMgr;
    YAHOO.util.DDM._addListeners();

}

/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

/**
 * A DragDrop implementation where the linked element follows the=20
 * mouse cursor during a drag.
 *
 * @extends YAHOO.util.DragDrop
 * @constructor
 * @param {String} id the id of the linked element=20
 * @param {String} sGroup the group of related DragDrop items
 */
YAHOO.util.DD =3D function(id, sGroup) {
    if (id) {
        this.init(id, sGroup);
    }
};

YAHOO.util.DD.prototype =3D new YAHOO.util.DragDrop();

/**
 * When set to true, the utility automatically tries to scroll the =
browser
 * window wehn a drag and drop element is dragged near the viewport =
boundary.
 * Defaults to true.
 *
 * @type boolean
 */
YAHOO.util.DD.prototype.scroll =3D true;=20

/**
 * Sets the pointer offset to the distance between the linked element's =
top=20
 * left corner and the location the element was clicked
 *
 * @param {int} iPageX the X coordinate of the click
 * @param {int} iPageY the Y coordinate of the click
 */
YAHOO.util.DD.prototype.autoOffset =3D function(iPageX, iPageY) {
    var el =3D this.getEl();
    var aCoord =3D YAHOO.util.Dom.getXY(el);
    var x =3D iPageX - aCoord[0];
    var y =3D iPageY - aCoord[1];
    this.setDelta(x, y);
};

/**=20
 * Sets the pointer offset.  You can call this directly to force the =
offset to
 * be in a particular location (e.g., pass in 0,0 to set it to the =
center of the
 * object, as done in YAHOO.widget.Slider)
 *
 * @param {int} iDeltaX the distance from the left
 * @param {int} iDeltaY the distance from the top
 */
YAHOO.util.DD.prototype.setDelta =3D function(iDeltaX, iDeltaY) {
    this.deltaX =3D iDeltaX;
    this.deltaY =3D iDeltaY;
};

/**
 * Sets the drag element to the location of the mousedown or click =
event,=20
 * maintaining the cursor location relative to the location on the =
element=20
 * that was clicked.  Override this if you want to place the element in =
a=20
 * location other than where the cursor is.
 *
 * @param {int} iPageX the X coordinate of the mousedown or drag event
 * @param {int} iPageY the Y coordinate of the mousedown or drag event
 */

YAHOO.util.DD.prototype.setDragElPos =3D function(iPageX, iPageY) {
    // the first time we do this, we are going to check to make sure
    // the element has css positioning

    var el =3D this.getDragEl();

    // if (!this.cssVerified) {
        // var pos =3D el.style.position;
    // }

    this.alignElWithMouse(el, iPageX, iPageY);
};

/**
 * Sets the element to the location of the mousedown or click event,=20
 * maintaining the cursor location relative to the location on the =
element=20
 * that was clicked.  Override this if you want to place the element in =
a=20
 * location other than where the cursor is.
 *
 * @param {HTMLElement} el the element to move
 * @param {int} iPageX the X coordinate of the mousedown or drag event
 * @param {int} iPageY the Y coordinate of the mousedown or drag event
 */
YAHOO.util.DD.prototype.alignElWithMouse =3D function(el, iPageX, =
iPageY) {
    var oCoord =3D this.getTargetCoord(iPageX, iPageY);
    var aCoord =3D [oCoord.x, oCoord.y];
    YAHOO.util.Dom.setXY(el, aCoord);

    this.cachePosition(oCoord.x, oCoord.y);

    this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, =
el.offsetWidth);
};

/**
 * Saves the most recent position so that we can reset the constraints =
and
 * tick marks on-demand.  We need to know this so that we can calculate =
the
 * number of pixels the element is offset from its original position.
 */
YAHOO.util.DD.prototype.cachePosition =3D function(iPageX, iPageY) {
    if (iPageX) {
        this.lastPageX =3D iPageX;
        this.lastPageY =3D iPageY;
    } else {
        var aCoord =3D YAHOO.util.Dom.getXY(this.getEl());
        this.lastPageX =3D aCoord[0];
        this.lastPageY =3D aCoord[1];
    }
};

/**
 * Auto-scroll the window if the dragged object has been moved beyond =
the=20
 * visible window boundary.
 *
 * @param {int} x the drag element's x position
 * @param {int} y the drag element's y position
 * @param {int} h the height of the drag element
 * @param {int} w the width of the drag element
 * @private
 */
YAHOO.util.DD.prototype.autoScroll =3D function(x, y, h, w) {

    if (this.scroll) {
        // The client height
        var clientH =3D this.DDM.getClientHeight();

        // The client width
        var clientW =3D this.DDM.getClientWidth();

        // The amt scrolled down
        var st =3D this.DDM.getScrollTop();

        // The amt scrolled right
        var sl =3D this.DDM.getScrollLeft();

        // Location of the bottom of the element
        var bot =3D h + y;

        // Location of the right of the element
        var right =3D w + x;

        // The distance from the cursor to the bottom of the visible =
area,=20
        // adjusted so that we don't scroll if the cursor is beyond the
        // element drag constraints
        var toBot =3D (clientH + st - y - this.deltaY);

        // The distance from the cursor to the right of the visible area
        var toRight =3D (clientW + sl - x - this.deltaX);


        // How close to the edge the cursor must be before we scroll
        // var thresh =3D (document.all) ? 100 : 40;
        var thresh =3D 40;

        // How many pixels to scroll per autoscroll op.  This helps to =
reduce=20
        // clunky scrolling. IE is more sensitive about this ... it =
needs this=20
        // value to be higher.
        var scrAmt =3D (document.all) ? 80 : 30;

        // Scroll down if we are near the bottom of the visible page and =
the=20
        // obj extends below the crease
        if ( bot > clientH && toBot < thresh ) {=20
            window.scrollTo(sl, st + scrAmt);=20
        }

        // Scroll up if the window is scrolled down and the top of the =
object
        // goes above the top border
        if ( y < st && st > 0 && y - st < thresh ) {=20
            window.scrollTo(sl, st - scrAmt);=20
        }

        // Scroll right if the obj is beyond the right border and the =
cursor is
        // near the border.
        if ( right > clientW && toRight < thresh ) {=20
            window.scrollTo(sl + scrAmt, st);=20
        }

        // Scroll left if the window has been scrolled to the right and =
the obj
        // extends past the left border
        if ( x < sl && sl > 0 && x - sl < thresh ) {=20
            window.scrollTo(sl - scrAmt, st);
        }
    }
};

/**
 * Finds the location the element should be placed if we want to move
 * it to where the mouse location less the click offset would place us.
 *
 * @param {int} iPageX the X coordinate of the click
 * @param {int} iPageY the Y coordinate of the click
 * @return an object that contains the coordinates (Object.x and =
Object.y)
 * @private
 */
YAHOO.util.DD.prototype.getTargetCoord =3D function(iPageX, iPageY) {


    var x =3D iPageX - this.deltaX;
    var y =3D iPageY - this.deltaY;

    if (this.constrainX) {
        if (x < this.minX) { x =3D this.minX; }
        if (x > this.maxX) { x =3D this.maxX; }
    }

    if (this.constrainY) {
        if (y < this.minY) { y =3D this.minY; }
        if (y > this.maxY) { y =3D this.maxY; }
    }

    x =3D this.getTick(x, this.xTicks);
    y =3D this.getTick(y, this.yTicks);


    return {x:x, y:y};
};

/**=20
 * Event that fires prior to the onMouseDown event.  Overrides=20
 * YAHOO.util.DragDrop.
 */
YAHOO.util.DD.prototype.b4MouseDown =3D function(e) {
    // this.resetConstraints();
    this.autoOffset(YAHOO.util.Event.getPageX(e),=20
                        YAHOO.util.Event.getPageY(e));
};

/**=20
 * Event that fires prior to the onDrag event.  Overrides=20
 * YAHOO.util.DragDrop.
 */
YAHOO.util.DD.prototype.b4Drag =3D function(e) {
    this.setDragElPos(YAHOO.util.Event.getPageX(e),=20
                        YAHOO.util.Event.getPageY(e));
};

/////////////////////////////////////////////////////////////////////////=
//////
// Debugging ygDragDrop events that can be overridden
/////////////////////////////////////////////////////////////////////////=
//////
/*
YAHOO.util.DD.prototype.startDrag =3D function(x, y) {
};

YAHOO.util.DD.prototype.onDrag =3D function(e) {
};

YAHOO.util.DD.prototype.onDragEnter =3D function(e, id) {
};

YAHOO.util.DD.prototype.onDragOver =3D function(e, id) {
};

YAHOO.util.DD.prototype.onDragOut =3D function(e, id) {
};

YAHOO.util.DD.prototype.onDragDrop =3D function(e, id) {
};

YAHOO.util.DD.prototype.endDrag =3D function(e) {
};
*/

/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

/**
 * A DragDrop implementation that inserts an empty, bordered div into
 * the document that follows the cursor during drag operations.  At the =
time of
 * the click, the frame div is resized to the dimensions of the linked =
html
 * element, and moved to the exact location of the linked element.
 *
 * References to the "frame" element refer to the single proxy element =
that
 * was created to be dragged in place of all DDProxy elements on the
 * page.
 *
 * @extends YAHOO.util.DD
 * @constructor
 * @param {String} id the id of the linked html element
 * @param {String} sGroup the group of related DragDrop objects
 */
YAHOO.util.DDProxy =3D function(id, sGroup) {
    if (id) {
        this.forceCssPosition =3D false;

        this.init(id, sGroup);
        this.initFrame();=20
    }
};

YAHOO.util.DDProxy.prototype =3D new YAHOO.util.DD();

/**
 * A reference to the one proxy div element we create for all instances =
of this=20
 * class
 *
 * @type HTMLElement
 */
YAHOO.util.DDProxy.frameDiv =3D null;

/**
 * the drag frame div id
 *
 * @type String
 */
YAHOO.util.DDProxy.dragElId =3D "ygddfdiv";

/**
 * The border width of the frame.  This is used when we resize the frame =
to
 * the size of the linked element.  We substract the border width to =
make
 * the div the correct size.
 *
 * @TODO find a better way to handle this
 *
 * @type int
 */
YAHOO.util.DDProxy.prototype.borderWidth =3D 2;

/**
 * By default we resize the drag frame to be the same size as the =
element
 * we want to drag (this is to get the frame effect).  We can turn it =
off
 * if we want a different behavior (ex: ygDDMy2)
 *
 * @type boolean
 */
YAHOO.util.DDProxy.prototype.resizeFrame =3D true;

/**
 * By default the frame is positioned exactly where the drag element is, =
so
 * we use the cursor offset provided by YAHOO.util.DD.  Another option =
that works only if
 * you do not have constraints on the obj is to have the drag frame =
centered
 * around the cursor.  Set centerFrame to true for this effect.  Ex:=20
 * ygDDMy2
 *
 * @type boolean
 */
YAHOO.util.DDProxy.prototype.centerFrame =3D false;

/**
 * Create the drag frame if needed
 */
YAHOO.util.DDProxy.createFrame =3D function() {
    var THIS =3D YAHOO.util.DDProxy;

    if (!document || !document.body) {
        setTimeout(THIS.createFrame, 50);
        return;
    }

    if (!THIS.frameDiv) {
        THIS.frameDiv =3D document.createElement("div");
        THIS.frameDiv.id =3D THIS.dragElId;
        var s =3D THIS.frameDiv.style;
        s.position =3D "absolute";
        s.visibility =3D "hidden";
        s.cursor =3D "move";
        s.border =3D "2px solid #aaa";
        s.zIndex =3D 999;
        document.body.appendChild(THIS.frameDiv);

    }
};

/**
 * Initialization for the drag frame element.  Must be called in the
 * constructor of all subclasses
 */
YAHOO.util.DDProxy.prototype.initFrame =3D function() {
    YAHOO.util.DDProxy.createFrame();
    this.setDragElId(YAHOO.util.DDProxy.dragElId);
    this.useAbsMath =3D true;

};

/**
 * Resizes the drag frame to the dimensions of the clicked object, =
positions=20
 * it over the object, and finally displays it
 *
 * @param {int} iPageX X click position
 * @param {int} iPageY Y click position
 * @private
 */
YAHOO.util.DDProxy.prototype.showFrame =3D function(iPageX, iPageY) {
    var el =3D this.getEl();

    var s =3D this.getDragEl().style;

    if (this.resizeFrame) {
        s.width =3D (parseInt(el.offsetWidth, 10) - =
(2*this.borderWidth)) + "px";
        s.height =3D (parseInt(el.offsetHeight, 10) - =
(2*this.borderWidth)) + "px";
    }

    if (this.centerFrame) {
        this.setDelta(Math.round(parseInt(s.width, 10)/2),=20
                Math.round(parseInt(s.width, 10)/2));
    }

    this.setDragElPos(iPageX, iPageY);

    s.visibility =3D "";
};

// overrides YAHOO.util.DragDrop
YAHOO.util.DDProxy.prototype.b4MouseDown =3D function(e) {
    var x =3D YAHOO.util.Event.getPageX(e);
    var y =3D YAHOO.util.Event.getPageY(e);
    this.autoOffset(x, y);
    this.setDragElPos(x, y);
};

// overrides YAHOO.util.DragDrop
YAHOO.util.DDProxy.prototype.b4StartDrag =3D function(x, y) {
    // show the drag frame
    this.showFrame(x, y);
};

// overrides YAHOO.util.DragDrop
YAHOO.util.DDProxy.prototype.b4EndDrag =3D function(e) {

    // hide the drag frame
    var s =3D this.getDragEl().style;
    s.visibility =3D "hidden";
};

// overrides YAHOO.util.DragDrop
// By default we try to move the element to the last location of the =
frame. =20
// This is so that the default behavior mirrors that of YAHOO.util.DD. =20
YAHOO.util.DDProxy.prototype.endDrag =3D function(e) {
    var lel =3D this.getEl();
    var del =3D this.getDragEl();

    // Show the drag frame briefly so we can get its position
    del.style.visibility =3D "";

    // Hide the linked element before the move to get around a Safari=20
    // rendering bug.
    lel.style.visibility =3D "hidden";
    YAHOO.util.DDM.moveToEl(lel, del);
    del.style.visibility =3D "hidden";
    lel.style.visibility =3D "";
};

/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

/**
 * A DragDrop implementation that does not move, but can be a drop=20
 * target.  You would get the same result by simply omitting =
implementation=20
 * for the event callbacks, but this way we reduce the processing cost =
of the=20
 * event listener and the callbacks.
 *
 * @extends YAHOO.util.DragDrop=20
 * @constructor
 * @param {String} id the id of the element that is a drop target
 * @param {String} sGroup the group of related DragDrop objects
 */
=20
YAHOO.util.DDTarget =3D function(id, sGroup) {
    if (id) {
        this.initTarget(id, sGroup);
    }
};

YAHOO.util.DDTarget.prototype =3D new YAHOO.util.DragDrop();


------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/js/yui/container.js

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 0.10.0
*/
/**
* @class=20
* Config is a utility used within an object to allow the implementer to =
maintain a list of local configuration properties and listen for changes =
to those properties dynamically using CustomEvent. The initial values =
are also maintained so that the configuration can be reset at any given =
point to its initial state.
* @param {object}	owner	The owner object to which this Config object =
belongs
* @constructor
*/
YAHOO.util.Config =3D function(owner) {
	if (owner) {
		this.init(owner);
	}
}

YAHOO.util.Config.prototype =3D {
=09
	/**
	* Object reference to the owner of this Config object
	* @type object
	*/
	owner : null,

	/**
	* Object reference to the owner of this Config object
	* args: key, value
	* @type YAHOO.util.CustomEvent
	*/
	configChangedEvent : null,

	/**
	* Boolean flag that specifies whether a queue is currently being =
executed
	* @type boolean
	*/
	queueInProgress : false,

	/**
	* Adds a property to the Config object's private config hash.=20
	* @param {string}	key	The configuration property's name
	* @param {object}	propertyObject	The object containing all of this =
property's arguments
	*/
	addProperty : function(key, propertyObject){},

	/**
	* Returns a key-value configuration map of the values currently set in =
the Config object.
	* @return {object} The current config, represented in a key-value map
	*/
	getConfig : function(){},

	/**
	* Returns the value of specified property.
	* @param {key}		The name of the property
	* @return {object}	The value of the specified property
	*/
	getProperty : function(key){},

	/**
	* Resets the specified property's value to its initial value.
	* @param {key}		The name of the property
	*/
	resetProperty : function(key){},

	/**
	* Sets the value of a property. If the silent property is passed as =
true, the property's event will not be fired.
	* @param {key}		The name of the property
	* @param {value}	The value to set the property to
	* @param {boolean}	Whether the value should be set silently, without =
firing the property event.
	* @return {boolean}	true, if the set was successful, false if it =
failed.
	*/
	setProperty : function(key,value,silent){},

	/**
	* Sets the value of a property and queues its event to execute. If the =
event is already scheduled to execute, it is
	* moved from its current position to the end of the queue.
	* @param {key}		The name of the property
	* @param {value}	The value to set the property to
	* @return {boolean}	true, if the set was successful, false if it =
failed.
	*/=09
	queueProperty : function(key,value){},

	/**
	* Fires the event for a property using the property's current value.
	* @param {key}		The name of the property
	*/
	refireEvent : function(key){},

	/**
	* Applies a key-value object literal to the configuration, replacing =
any existing values, and queueing the property events.
	* Although the values will be set, fireQueue() must be called for their =
associated events to execute.
	* @param {object}	userConfig	The configuration object literal
	* @param {boolean}	init		When set to true, the initialConfig will be =
set to the userConfig passed in, so that calling a reset will reset the =
properties to the passed values.
	*/
	applyConfig : function(userConfig,init){},

	/**
	* Refires the events for all configuration properties using their =
current values.
	*/
	refresh : function(){},

	/**
	* Fires the normalized list of queued property change events
	*/
	fireQueue : function(){},

	/**
	* Subscribes an external handler to the change event for any given =
property.=20
	* @param {string}	key			The property name
	* @param {Function}	handler		The handler function to use subscribe to =
the property's event
	* @param {object}	obj			The object to use for scoping the event handler =
(see CustomEvent documentation)
	* @param {boolean}	override	Optional. If true, will override "this" =
within the handler to map to the scope object passed into the method.
	*/=09
	subscribeToConfigEvent : function(key,handler,obj,override){},

	/**
	* Unsubscribes an external handler from the change event for any given =
property.=20
	* @param {string}	key			The property name
	* @param {Function}	handler		The handler function to use subscribe to =
the property's event
	* @param {object}	obj			The object to use for scoping the event handler =
(see CustomEvent documentation)
	*/
	unsubscribeFromConfigEvent: function(key,handler,obj){},

	/**
	* Validates that the value passed in is a boolean.
	* @param	{object}	val	The value to validate
	* @return	{boolean}	true, if the value is valid
	*/=09
	checkBoolean: function(val) {
		if (typeof val =3D=3D 'boolean') {
			return true;
		} else {
			return false;
		}
	},

	/**
	* Validates that the value passed in is a number.
	* @param	{object}	val	The value to validate
	* @return	{boolean}	true, if the value is valid
	*/
	checkNumber: function(val) {
		if (isNaN(val)) {
			return false;
		} else {
			return true;
		}
	}
}


/**
* Initializes the configuration object and all of its local members.
* @param {object}	owner	The owner object to which this Config object =
belongs
*/
YAHOO.util.Config.prototype.init =3D function(owner) {

	this.owner =3D owner;
	this.configChangedEvent =3D new =
YAHOO.util.CustomEvent("configChanged");
	this.queueInProgress =3D false;

	/* Private Members */

	var config =3D {};
	var initialConfig =3D {};
	var eventQueue =3D [];

	/**
	* @private
	* Fires a configuration property event using the specified value.=20
	* @param {string}	key			The configuration property's name
	* @param {value}	object		The value of the correct type for the property
	*/=20
	var fireEvent =3D function( key, value ) {
		key =3D key.toLowerCase();

		var property =3D config[key];

		if (typeof property !=3D 'undefined' && property.event) {
			property.event.fire(value);
		}=09
	}
	/* End Private Members */

	this.addProperty =3D function( key, propertyObject ) {
		key =3D key.toLowerCase();

		config[key] =3D propertyObject;

		propertyObject.event =3D new YAHOO.util.CustomEvent(key);
		propertyObject.key =3D key;

		if (propertyObject.handler) {
			propertyObject.event.subscribe(propertyObject.handler, this.owner, =
true);
		}

		this.setProperty(key, propertyObject.value, true);
	=09
		if (! propertyObject.suppressEvent) {
			this.queueProperty(key, propertyObject.value);
		}
	}

	this.getConfig =3D function() {
		var cfg =3D {};
		=09
		for (var prop in config) {
			var property =3D config[prop]
			if (typeof property !=3D 'undefined' && property.event) {
				cfg[prop] =3D property.value;
			}
		}
	=09
		return cfg;
	}

	this.getProperty =3D function(key) {
		key =3D key.toLowerCase();

		var property =3D config[key];
		if (typeof property !=3D 'undefined' && property.event) {
			return property.value;
		} else {
			return undefined;
		}
	}


	this.resetProperty =3D function(key) {
		key =3D key.toLowerCase();

		var property =3D config[key];
		if (typeof property !=3D 'undefined' && property.event) {
			this.setProperty(key, initialConfig[key].value);
		} else {
			return undefined;
		}
	}


	this.setProperty =3D function(key, value, silent) {
		key =3D key.toLowerCase();

		if (this.queueInProgress && ! silent) {
			this.queueProperty(key,value); // Currently running through a =
queue...=20
			return true;
		} else {
			var property =3D config[key];
			if (typeof property !=3D 'undefined' && property.event) {
				if (property.validator && ! property.validator(value)) { // =
validator
					return false;
				} else {
					property.value =3D value;
					if (! silent) {
						fireEvent(key, value);
						this.configChangedEvent.fire([key, value]);
					}
					return true;
				}
			} else {
				return false;
			}
		}
	}

	this.queueProperty =3D function(key, value) {
		key =3D key.toLowerCase();

		var property =3D config[key];
						=09
		if (typeof property !=3D 'undefined' && property.event) {
			if (typeof value !=3D 'undefined' && property.validator && ! =
property.validator(value)) { // validator
				return false;
			} else {

				if (typeof value !=3D 'undefined') {
					property.value =3D value;
				} else {
					value =3D property.value;
				}

				var foundDuplicate =3D false;

				for (var i=3D0;i<eventQueue.length;i++) {
					var queueItem =3D eventQueue[i];

					if (queueItem) {
						var queueItemKey =3D queueItem[0];
						var queueItemValue =3D queueItem[1];
					=09
						if (queueItemKey.toLowerCase() =3D=3D key) {
							// found a dupe... push to end of queue, null current item, and =
break
							eventQueue[i] =3D null;
							eventQueue.push([key, (typeof value !=3D 'undefined' ? value : =
queueItemValue)]);
							foundDuplicate =3D true;
							break;
						}
					}
				}
			=09
				if (! foundDuplicate && typeof value !=3D 'undefined') { // this is =
a refire, or a new property in the queue
					eventQueue.push([key, value]);
				}
			}

			if (property.supercedes) {
				for (var s=3D0;s<property.supercedes.length;s++) {
					var supercedesCheck =3D property.supercedes[s];

					for (var q=3D0;q<eventQueue.length;q++) {
						var queueItemCheck =3D eventQueue[q];

						if (queueItemCheck) {
							var queueItemCheckKey =3D queueItemCheck[0];
							var queueItemCheckValue =3D queueItemCheck[1];
						=09
							if ( queueItemCheckKey.toLowerCase() =3D=3D =
supercedesCheck.toLowerCase() ) {
								eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
								eventQueue[q] =3D null;
								break;
							}
						}
					}
				}
			}

			return true;
		} else {
			return false;
		}
	}

	this.refireEvent =3D function(key) {
		key =3D key.toLowerCase();

		var property =3D config[key];
		if (typeof property !=3D 'undefined' && property.event && typeof =
property.value !=3D 'undefined') {
			if (this.queueInProgress) {
				this.queueProperty(key);
			} else {
				fireEvent(key, property.value);
			}
		}
	}

	this.applyConfig =3D function(userConfig, init) {
		if (init) {
			initialConfig =3D userConfig;
		}
		for (var prop in userConfig) {
			this.queueProperty(prop, userConfig[prop]);
		}
	}

	this.refresh =3D function() {
		for (var prop in config) {
			this.refireEvent(prop);
		}
	}

	this.fireQueue =3D function() {
		this.queueInProgress =3D true;
		for (var i=3D0;i<eventQueue.length;i++) {
			var queueItem =3D eventQueue[i];
			if (queueItem) {
				var key =3D queueItem[0];
				var value =3D queueItem[1];
			=09
				var property =3D config[key];
				property.value =3D value;

				fireEvent(key,value);
			}
		}
	=09
		this.queueInProgress =3D false;
		eventQueue =3D new Array();
	}

	this.subscribeToConfigEvent =3D function(key, handler, obj, override) {
		key =3D key.toLowerCase();

		var property =3D config[key];
		if (typeof property !=3D 'undefined' && property.event) {
			if (! YAHOO.util.Config.alreadySubscribed(property.event, handler, =
obj)) {
				property.event.subscribe(handler, obj, override);
			}
			return true;
		} else {
			return false;
		}
	}


	this.unsubscribeFromConfigEvent =3D function(key, handler, obj) {
		key =3D key.toLowerCase();

		var property =3D config[key];
		if (typeof property !=3D 'undefined' && property.event) {
			return property.event.unsubscribe(handler, obj);
		} else {
			return false;
		}
	}

	// TODO: REMOVE
	this.outputEventQueue =3D function() {
		var output =3D "";
		for (var q=3D0;q<eventQueue.length;q++) {
			var queueItem =3D eventQueue[q];
			if (queueItem) {
				output +=3D queueItem[0] + "=3D" + queueItem[1] + ", ";
			}
		}
		return output;
	}
}

/**
* Checks to determine if a particular function/object pair are already =
subscribed to the specified CustomEvent
* @param {YAHOO.util.CustomEvent} evt	The CustomEvent for which to check =
the subscriptions
* @param {Function}	fn	The function to look for in the subscribers list
* @param {object}	obj	The execution scope object for the subscription
* @return {boolean}	true, if the function/object pair is already =
subscribed to the CustomEvent passed in
*/
YAHOO.util.Config.alreadySubscribed =3D function(evt, fn, obj) {
	for (var e=3D0;e<evt.subscribers.length;e++) {
		var subsc =3D evt.subscribers[e];
		if (subsc && subsc.obj =3D=3D obj && subsc.fn =3D=3D fn) {
			return true;
			break;
		}
	}
	return false;
}/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class=20
* Module is a JavaScript representation of the Standard Module Format. =
Standard Module Format is a simple standard for markup containers where =
child nodes representing the header, body, and footer of the content are =
denoted using the CSS classes "hd", "bd", and "ft" respectively. Module =
is the base class for all other classes in the YUI Container package.
* @param {string}	el	The element ID representing the Module <em>OR</em>
* @param {Element}	el	The element representing the Module
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this module. See configuration =
documentation for more details.
* @constructor
*/
YAHOO.widget.Module =3D function(el, userConfig) {
	if (el) {=20
		this.init(el, userConfig);=20
	}
}

/**
* Constant representing the prefix path to use for non-secure images
* @type string
*/
YAHOO.widget.Module.IMG_ROOT =3D "http://us.i1.yimg.com/us.yimg.com/i/";

/**
* Constant representing the prefix path to use for securely served =
images
* @type string
*/
YAHOO.widget.Module.IMG_ROOT_SSL =3D =
"https://a248.e.akamai.net/sec.yimg.com/i/";

/**
* Constant for the default CSS class name that represents a Module
* @type string
* @final
*/
YAHOO.widget.Module.CSS_MODULE =3D "module";

/**
* Constant representing the module header
* @type string
* @final
*/
YAHOO.widget.Module.CSS_HEADER =3D "hd";

/**
* Constant representing the module body
* @type string
* @final
*/
YAHOO.widget.Module.CSS_BODY   =3D "bd";

/**
* Constant representing the module footer
* @type string
* @final
*/
YAHOO.widget.Module.CSS_FOOTER =3D "ft";

YAHOO.widget.Module.prototype =3D {

	/**
	* The class's constructor function
	* @type function
	*/
	constructor : YAHOO.widget.Module,

	/**
	* The main module element that contains the header, body, and footer
	* @type Element
	*/
	element : null,=20

	/**
	* The header element, denoted with CSS class "hd"
	* @type Element
	*/
	header : null,

	/**
	* The body element, denoted with CSS class "bd"
	* @type Element
	*/
	body : null,

	/**
	* The footer element, denoted with CSS class "ft"
	* @type Element
	*/
	footer : null,

	/**
	* The id of the element
	* @type string
	*/
	id : null,

	/**
	* Array of elements
	* @type Element[]
	*/
	childNodesInDOM : null,

	/**
	* The string representing the image root
	* @type string
	*/
	imageRoot : YAHOO.widget.Module.IMG_ROOT,

	/**
	* CustomEvent fired prior to class initalization.
	* args: class reference of the initializing class, such as =
this.beforeInitEvent.fire(YAHOO.widget.Module)
	* @type YAHOO.util.CustomEvent
	*/
	beforeInitEvent : null,

	/**
	* CustomEvent fired after class initalization.
	* args: class reference of the initializing class, such as =
this.initEvent.fire(YAHOO.widget.Module)
	* @type YAHOO.util.CustomEvent
	*/
	initEvent : null,

	/**
	* CustomEvent fired when the Module is appended to the DOM
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	appendEvent : null,

	/**
	* CustomEvent fired before the Module is rendered
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	beforeRenderEvent : null,

	/**
	* CustomEvent fired after the Module is rendered
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	renderEvent : null,

	/**
	* CustomEvent fired when the header content of the Module is modified
	* args: string/element representing the new header content
	* @type YAHOO.util.CustomEvent
	*/
	changeHeaderEvent : null,

	/**
	* CustomEvent fired when the body content of the Module is modified
	* args: string/element representing the new body content
	* @type YAHOO.util.CustomEvent
	*/
	changeBodyEvent : null,

	/**
	* CustomEvent fired when the footer content of the Module is modified
	* args: string/element representing the new footer content
	* @type YAHOO.util.CustomEvent
	*/
	changeFooterEvent : null,

	/**
	* CustomEvent fired when the content of the Module is modified
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	changeContentEvent : null,

	/**
	* CustomEvent fired when the Module is destroyed
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	destroyEvent : null,

	/**
	* CustomEvent fired before the Module is shown
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	beforeShowEvent : null,

	/**
	* CustomEvent fired after the Module is shown
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	showEvent : null,

	/**
	* CustomEvent fired before the Module is hidden
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	beforeHideEvent : null,
=09
	/**
	* CustomEvent fired after the Module is hidden
	* args: none
	* @type YAHOO.util.CustomEvent
	*/
	hideEvent : null,
	=09
	/**
	* Initializes the custom events for Module which are fired =
automatically at appropriate times by the Module class.
	*/
	initEvents : function() {

		this.beforeInitEvent		=3D new YAHOO.util.CustomEvent("beforeInit");
		this.initEvent				=3D new YAHOO.util.CustomEvent("init");

		this.appendEvent			=3D new YAHOO.util.CustomEvent("append");

		this.beforeRenderEvent		=3D new =
YAHOO.util.CustomEvent("beforeRender");
		this.renderEvent			=3D new YAHOO.util.CustomEvent("render");

		this.changeHeaderEvent		=3D new =
YAHOO.util.CustomEvent("changeHeader");
		this.changeBodyEvent		=3D new YAHOO.util.CustomEvent("changeBody");
		this.changeFooterEvent		=3D new =
YAHOO.util.CustomEvent("changeFooter");

		this.changeContentEvent		=3D new =
YAHOO.util.CustomEvent("changeContent");

		this.destroyEvent			=3D new YAHOO.util.CustomEvent("destroy");
		this.beforeShowEvent		=3D new YAHOO.util.CustomEvent("beforeShow");
		this.showEvent				=3D new YAHOO.util.CustomEvent("show");
		this.beforeHideEvent		=3D new YAHOO.util.CustomEvent("beforeHide");
		this.hideEvent				=3D new YAHOO.util.CustomEvent("hide");
	},=20

	/**
	* String representing the current user-agent platform
	* @type string
	*/
	platform : function() {
					var ua =3D navigator.userAgent.toLowerCase();
					if (ua.indexOf("windows") !=3D -1 || ua.indexOf("win32") !=3D -1) {
						return "windows";
					} else if (ua.indexOf("macintosh") !=3D -1) {
						return "mac";
					} else {
						return false;
					}
				}(),

	/**
	* String representing the current user-agent browser
	* @type string
	*/
	browser : function() {
			var ua =3D navigator.userAgent.toLowerCase();
				  if (ua.indexOf('opera')!=3D-1) { // Opera (check first in case of =
spoof)
					 return 'opera';
				  } else if (ua.indexOf('msie 7')!=3D-1) { // IE7
					 return 'ie7';
				  } else if (ua.indexOf('msie') !=3D-1) { // IE
					 return 'ie';
				  } else if (ua.indexOf('safari')!=3D-1) { // Safari (check before =
Gecko because it includes "like Gecko")
					 return 'safari';
				  } else if (ua.indexOf('gecko') !=3D -1) { // Gecko
					 return 'gecko';
				  } else {
					 return false;
				  }
			}(),

	/**
	* Boolean representing whether or not the current browsing context is =
secure (https)
	* @type boolean
	*/
	isSecure : function() {
		if (window.location.href.toLowerCase().indexOf("https") =3D=3D 0) {
			this.imageRoot =3D YAHOO.widget.Module.IMG_ROOT_SSL;
			return true;
		} else {
			return false;
		}
	}(),

	/**
	* Initializes the custom events for Module which are fired =
automatically at appropriate times by the Module class.
	*/
	initDefaultConfig : function() {
		// Add properties //

		this.cfg.addProperty("visible", { value:true, =
handler:this.configVisible, validator:this.cfg.checkBoolean } );
		this.cfg.addProperty("effect", { suppressEvent:true, =
supercedes:["visible"] } );
		this.cfg.addProperty("monitorresize", { value:true, =
handler:this.configMonitorResize } );
	},

	/**
	* The Module class's initialization method, which is executed for =
Module and all of its subclasses. This method is automatically called by =
the constructor, and  sets up all DOM references for pre-existing =
markup, and creates required markup if it is not already present.
	* @param {string}	el	The element ID representing the Module <em>OR</em>
	* @param {Element}	el	The element representing the Module
	* @param {object}	userConfig	The configuration object literal =
containing the configuration that should be set for this module. See =
configuration documentation for more details.
	*/
	init : function(el, userConfig) {

		this.initEvents();

		this.beforeInitEvent.fire(YAHOO.widget.Module);

		this.cfg =3D new YAHOO.util.Config(this);
	=09
		if (typeof el =3D=3D "string") {
			var elId =3D el;

			el =3D document.getElementById(el);
			if (! el) {
				el =3D document.createElement("DIV");
				el.id =3D elId;
			}
		}

		this.element =3D el;
	=09
		if (el.id) {
			this.id =3D el.id;
		}=20

		var childNodes =3D this.element.childNodes;

		if (childNodes) {
			for (var i=3D0;i<childNodes.length;i++) {
				var child =3D childNodes[i];
				switch (child.className) {
					case YAHOO.widget.Module.CSS_HEADER:
						this.header =3D child;
						break;
					case YAHOO.widget.Module.CSS_BODY:
						this.body =3D child;
						break;
					case YAHOO.widget.Module.CSS_FOOTER:
						this.footer =3D child;
						break;
				}
			}
		}

		this.initDefaultConfig();

		YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Module.CSS_MODULE);

		if (userConfig) {
			this.cfg.applyConfig(userConfig, true);
		}

		// Subscribe to the fireQueue() method of Config so that any queued =
configuration changes are
		// excecuted upon render of the Module
		if (! YAHOO.util.Config.alreadySubscribed(this.renderEvent, =
this.cfg.fireQueue, this.cfg)) {
			this.renderEvent.subscribe(this.cfg.fireQueue, this.cfg, true);
		}

		this.initEvent.fire(YAHOO.widget.Module);
	},

	/**
	* Initialized an empty DOM element that is placed out of the visible =
area that can be used to detect text resize.
	*/
	initResizeMonitor : function() {
		var resizeMonitor =3D document.getElementById("_yuiResizeMonitor");
		if (! resizeMonitor) {
			resizeMonitor =3D document.createElement("DIV");
			resizeMonitor.style.position =3D "absolute";
			resizeMonitor.id =3D "_yuiResizeMonitor";
			resizeMonitor.style.width =3D "1em";
			resizeMonitor.style.height =3D "1em";
			resizeMonitor.style.top =3D "-1000px";
			resizeMonitor.style.left =3D "-1000px";
			resizeMonitor.innerHTML =3D "&nbsp;";
			document.body.appendChild(resizeMonitor);
		}
		this.resizeMonitor =3D resizeMonitor;
		YAHOO.util.Event.addListener(this.resizeMonitor, "resize", =
this.onDomResize, this, true);
	},

	/**
	* Event handler fired when the resize monitor element is resized.
	*/
	onDomResize : function(e, obj) { },

	/**
	* Sets the Module's header content to the HTML specified, or appends =
the passed element to the header. If no header is present, one will be =
automatically created.
	* @param {string}	headerContent	The HTML used to set the header =
<em>OR</em>
	* @param {Element}	headerContent	The Element to append to the header
	*/=09
	setHeader : function(headerContent) {
		if (! this.header) {
			this.header =3D document.createElement("DIV");
			this.header.className =3D YAHOO.widget.Module.CSS_HEADER;
		}
	=09
		if (typeof headerContent =3D=3D "string") {
			this.header.innerHTML =3D headerContent;
		} else {
			this.header.innerHTML =3D "";
			this.header.appendChild(headerContent);
		}

		this.changeHeaderEvent.fire(headerContent);
		this.changeContentEvent.fire();
	},

	/**
	* Appends the passed element to the header. If no header is present, =
one will be automatically created.
	* @param {Element}	element	The element to append to the header
	*/=09
	appendToHeader : function(element) {
		if (! this.header) {
			this.header =3D document.createElement("DIV");
			this.header.className =3D YAHOO.widget.Module.CSS_HEADER;
		}
	=09
		this.header.appendChild(element);
		this.changeHeaderEvent.fire(element);
		this.changeContentEvent.fire();
	},

	/**
	* Sets the Module's body content to the HTML specified, or appends the =
passed element to the body. If no body is present, one will be =
automatically created.
	* @param {string}	bodyContent	The HTML used to set the body <em>OR</em>
	* @param {Element}	bodyContent	The Element to append to the body
	*/	=09
	setBody : function(bodyContent) {
		if (! this.body) {
			this.body =3D document.createElement("DIV");
			this.body.className =3D YAHOO.widget.Module.CSS_BODY;
		}

		if (typeof bodyContent =3D=3D "string")
		{
			this.body.innerHTML =3D bodyContent;
		} else {
			this.body.innerHTML =3D "";
			this.body.appendChild(bodyContent);
		}

		this.changeBodyEvent.fire(bodyContent);
		this.changeContentEvent.fire();
	},

	/**
	* Appends the passed element to the body. If no body is present, one =
will be automatically created.
	* @param {Element}	element	The element to append to the body
	*/
	appendToBody : function(element) {
		if (! this.body) {
			this.body =3D document.createElement("DIV");
			this.body.className =3D YAHOO.widget.Module.CSS_BODY;
		}

		this.body.appendChild(element);
		this.changeBodyEvent.fire(element);
		this.changeContentEvent.fire();
	},

	/**
	* Sets the Module's footer content to the HTML specified, or appends =
the passed element to the footer. If no footer is present, one will be =
automatically created.
	* @param {string}	footerContent	The HTML used to set the footer =
<em>OR</em>
	* @param {Element}	footerContent	The Element to append to the footer
	*/=09
	setFooter : function(footerContent) {
		if (! this.footer) {
			this.footer =3D document.createElement("DIV");
			this.footer.className =3D YAHOO.widget.Module.CSS_FOOTER;
		}

		if (typeof footerContent =3D=3D "string") {
			this.footer.innerHTML =3D footerContent;
		} else {
			this.footer.innerHTML =3D "";
			this.footer.appendChild(footerContent);
		}

		this.changeFooterEvent.fire(footerContent);
		this.changeContentEvent.fire();
	},

	/**
	* Appends the passed element to the footer. If no footer is present, =
one will be automatically created.
	* @param {Element}	element	The element to append to the footer
	*/
	appendToFooter : function(element) {
		if (! this.footer) {
			this.footer =3D document.createElement("DIV");
			this.footer.className =3D YAHOO.widget.Module.CSS_FOOTER;
		}

		this.footer.appendChild(element);
		this.changeFooterEvent.fire(element);
		this.changeContentEvent.fire();
	},

	/**
	* Renders the Module by inserting the elements that are not already in =
the main Module into their correct places. Optionally appends the Module =
to the specified node prior to the render's execution. NOTE: For Modules =
without existing markup, the appendToNode argument is REQUIRED. If this =
argument is ommitted and the current element is not present in the =
document, the function will return false, indicating that the render was =
a failure.
	* @param {string}	appendToNode	The element id to which the Module =
should be appended to prior to rendering <em>OR</em>
	* @param {Element}	appendToNode	The element to which the Module should =
be appended to prior to rendering=09
	* @param {Element}	moduleElement	OPTIONAL. The element that represents =
the actual Standard Module container.=20
	* @return {boolean} Success or failure of the render
	*/
	render : function(appendToNode, moduleElement) {
		this.beforeRenderEvent.fire();

		if (! moduleElement) {
			moduleElement =3D this.element;
		}

		var me =3D this;
		var appendTo =3D function(element) {
			if (typeof element =3D=3D "string") {
				element =3D document.getElementById(element);
			}
		=09
			if (element) {
				element.appendChild(me.element);
				me.appendEvent.fire();
			}
		}

		if (appendToNode) {
			appendTo(appendToNode);
		} else { // No node was passed in. If the element is not pre-marked =
up, this fails
			if (! YAHOO.util.Dom.inDocument(this.element)) {
				return false;
			}
		}

		// Need to get everything into the DOM if it isn't already
	=09
		if (this.header && ! YAHOO.util.Dom.inDocument(this.header)) {
			// There is a header, but it's not in the DOM yet... need to add it
			var firstChild =3D moduleElement.firstChild;
			if (firstChild) { // Insert before first child if exists
				moduleElement.insertBefore(this.header, firstChild);
			} else { // Append to empty body because there are no children
				moduleElement.appendChild(this.header);
			}
		}

		if (this.body && ! YAHOO.util.Dom.inDocument(this.body)) {
			// There is a body, but it's not in the DOM yet... need to add it
			if (this.footer && YAHOO.util.Dom.isAncestor(this.moduleElement, =
this.footer)) { // Insert before footer if exists in DOM
				moduleElement.insertBefore(this.body, this.footer);
			} else { // Append to element because there is no footer
				moduleElement.appendChild(this.body);
			}
		}

		if (this.footer && ! YAHOO.util.Dom.inDocument(this.footer)) {
			// There is a footer, but it's not in the DOM yet... need to add it
			moduleElement.appendChild(this.footer);
		}

		this.renderEvent.fire();
		return true;
	},

	/**
	* Removes the Module element from the DOM and sets all child elements =
to null.
	*/
	destroy : function() {
		if (this.element) {
			var parent =3D this.element.parentNode;
		}
		if (parent) {
			parent.removeChild(this.element);
		}

		this.element =3D null;
		this.header =3D null;
		this.body =3D null;
		this.footer =3D null;

		this.destroyEvent.fire();
	},

	/**
	* Shows the Module element by setting the visible configuration =
property to true. Also fires two events: beforeShowEvent prior to the =
visibility change, and showEvent after.
	*/
	show : function() {
		this.cfg.setProperty("visible", true);
	},

	/**
	* Hides the Module element by setting the visible configuration =
property to false. Also fires two events: beforeHideEvent prior to the =
visibility change, and hideEvent after.
	*/
	hide : function() {
		this.cfg.setProperty("visible", false);
	},

	// BUILT-IN EVENT HANDLERS FOR MODULE //

	/**
	* Default event handler for changing the visibility property of a =
Module. By default, this is achieved by switching the "display" style =
between "block" and "none".
	* This method is responsible for firing showEvent and hideEvent.
	*/
	configVisible : function(type, args, obj) {
		var visible =3D args[0];
		if (visible) {
			this.beforeShowEvent.fire();
			YAHOO.util.Dom.setStyle(this.element, "display", "block");
			this.showEvent.fire();
		} else {
			this.beforeHideEvent.fire();
			YAHOO.util.Dom.setStyle(this.element, "display", "none");
			this.hideEvent.fire();
		}
	},

	/**
	* Default event handler for the "monitorresize" configuration property
	*/
	configMonitorResize : function(type, args, obj) {
		var monitor =3D args[0];
		if (monitor) {
			this.initResizeMonitor();
		} else {
			YAHOO.util.Event.removeListener(this.resizeMonitor, "resize", =
this.onDomResize);
			this.resizeMonitor =3D null;
		}
	}
}
/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class Overlay is a Module that is absolutely positioned above the =
page flow. It has convenience methods for positioning and sizing, as =
well as options for controlling zIndex and constraining the Overlay's =
position to the current visible viewport. Overlay also contains a =
dynamicly generated IFRAME which is placed beneath it for Internet =
Explorer 6 and 5.x so that it will be properly rendered above SELECT =
elements.
* @param {string}	el	The element ID representing the Overlay <em>OR</em>
* @param {Element}	el	The element representing the Overlay
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Overlay. See configuration =
documentation for more details.
* @constructor
*/
YAHOO.widget.Overlay =3D function(el, userConfig) {
	if (arguments.length > 0) {
		YAHOO.widget.Overlay.superclass.constructor.call(this, el, =
userConfig);
	}
}

YAHOO.widget.Overlay.prototype =3D new YAHOO.widget.Module();
YAHOO.widget.Overlay.prototype.constructor =3D YAHOO.widget.Overlay;

/**
* Reference to the Overlay's superclass, Module
* @type class
* @final
*/
YAHOO.widget.Overlay.superclass =3D YAHOO.widget.Module.prototype;

/**
* The URL of the blank image that will be placed in the iframe
* @type string
* @final
*/
YAHOO.widget.Overlay.IFRAME_SRC =3D "promo/m/irs/blank.gif";

/**
* Constant representing the top left corner of an element, used for =
configuring the context element alignment
* @type string
* @final
*/
YAHOO.widget.Overlay.TOP_LEFT =3D "tl";

/**
* Constant representing the top right corner of an element, used for =
configuring the context element alignment
* @type string
* @final
*/
YAHOO.widget.Overlay.TOP_RIGHT =3D "tr";

/**
* Constant representing the top bottom left corner of an element, used =
for configuring the context element alignment
* @type string
* @final
*/
YAHOO.widget.Overlay.BOTTOM_LEFT =3D "bl";

/**
* Constant representing the bottom right corner of an element, used for =
configuring the context element alignment
* @type string
* @final
*/
YAHOO.widget.Overlay.BOTTOM_RIGHT =3D "br";

/**
* Constant representing the default CSS class used for an Overlay
* @type string
* @final
*/
YAHOO.widget.Overlay.CSS_OVERLAY =3D "overlay";

/**
* CustomEvent fired before the Overlay is moved.
* args: x,y that the Overlay will be moved to
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Overlay.prototype.beforeMoveEvent =3D null;

/**
* CustomEvent fired after the Overlay is moved.
* args: x,y that the Overlay was moved to
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Overlay.prototype.moveEvent =3D null;

/*
* The Overlay initialization method, which is executed for Overlay and =
all of its subclasses. This method is automatically called by the =
constructor, and  sets up all DOM references for pre-existing markup, =
and creates required markup if it is not already present.
* @param {string}	el	The element ID representing the Overlay <em>OR</em>
* @param {Element}	el	The element representing the Overlay
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Overlay. See configuration =
documentation for more details.
*/
YAHOO.widget.Overlay.prototype.init =3D function(el, userConfig) {
	YAHOO.widget.Overlay.superclass.init.call(this, el/*, userConfig*/);  =
// Note that we don't pass the user config in here yet because we only =
want it executed once, at the lowest subclass level
=09
	this.beforeInitEvent.fire(YAHOO.widget.Overlay);

	YAHOO.util.Dom.addClass(this.element, =
YAHOO.widget.Overlay.CSS_OVERLAY);

	if (userConfig) {
		this.cfg.applyConfig(userConfig, true);
	}

	if (this.platform =3D=3D "mac" && this.browser =3D=3D "gecko") {
		if (! =
YAHOO.util.Config.alreadySubscribed(this.showEvent,this.showMacGeckoScrol=
lbars,this)) {
			this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);
		}
		if (! =
YAHOO.util.Config.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrol=
lbars,this)) {
			this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);
		}
	}

	this.initEvent.fire(YAHOO.widget.Overlay);

}

/**
* Initializes the custom events for Overlay which are fired =
automatically at appropriate times by the Overlay class.
*/
YAHOO.widget.Overlay.prototype.initEvents =3D function() {
	YAHOO.widget.Overlay.superclass.initEvents.call(this);

	this.beforeMoveEvent =3D new YAHOO.util.CustomEvent("beforeMove", =
this);
	this.moveEvent =3D new YAHOO.util.CustomEvent("move", this);
}

/**
* Initializes the class's configurable properties which can be changed =
using the Overlay's Config object (cfg).
*/
YAHOO.widget.Overlay.prototype.initDefaultConfig =3D function() {
	YAHOO.widget.Overlay.superclass.initDefaultConfig.call(this);

	// Add overlay config properties //
	this.cfg.addProperty("x", { handler:this.configX, =
validator:this.cfg.checkNumber, suppressEvent:true, =
supercedes:["iframe"] } );
	this.cfg.addProperty("y", { handler:this.configY, =
validator:this.cfg.checkNumber, suppressEvent:true, =
supercedes:["iframe"] } );
	this.cfg.addProperty("xy",{ handler:this.configXY, suppressEvent:true, =
supercedes:["iframe"] } );

	this.cfg.addProperty("context",	{ handler:this.configContext, =
suppressEvent:true, supercedes:["iframe"] } );
	this.cfg.addProperty("fixedcenter", { value:false, =
handler:this.configFixedCenter, validator:this.cfg.checkBoolean, =
supercedes:["iframe","visible"] } );

	this.cfg.addProperty("width", { handler:this.configWidth, =
suppressEvent:true, supercedes:["iframe"] } );
	this.cfg.addProperty("height", { handler:this.configHeight, =
suppressEvent:true, supercedes:["iframe"] } );

	this.cfg.addProperty("zIndex", { value:null, handler:this.configzIndex =
} );

	this.cfg.addProperty("constraintoviewport", { value:false, =
handler:this.configConstrainToViewport, validator:this.cfg.checkBoolean, =
supercedes:["iframe","x","y","xy"] } );
	this.cfg.addProperty("iframe", { value:(this.browser =3D=3D "ie" ? true =
: false), handler:this.configIframe, validator:this.cfg.checkBoolean, =
supercedes:["zIndex"] } );
}

/**
* Moves the Overlay to the specified position. This function is =
identical to calling this.cfg.setProperty("xy", [x,y]);
* @param {int}	x	The Overlay's new x position
* @param {int}	y	The Overlay's new y position
*/
YAHOO.widget.Overlay.prototype.moveTo =3D function(x, y) {
	this.cfg.setProperty("xy",[x,y]);
}

/**
* Adds a special CSS class to the Overlay when Mac/Gecko is in use, to =
work around a Gecko bug where
* scrollbars cannot be hidden. See =
https://bugzilla.mozilla.org/show_bug.cgi?id=3D187435
*/
YAHOO.widget.Overlay.prototype.hideMacGeckoScrollbars =3D function() {
	YAHOO.util.Dom.removeClass(this.element, "show-scrollbars");
	YAHOO.util.Dom.addClass(this.element, "hide-scrollbars");
}

/**
* Removes a special CSS class from the Overlay when Mac/Gecko is in use, =
to work around a Gecko bug where
* scrollbars cannot be hidden. See =
https://bugzilla.mozilla.org/show_bug.cgi?id=3D187435
*/
YAHOO.widget.Overlay.prototype.showMacGeckoScrollbars =3D function() {
	YAHOO.util.Dom.removeClass(this.element, "hide-scrollbars");
	YAHOO.util.Dom.addClass(this.element, "show-scrollbars");
}

// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //

/**
* The default event handler fired when the "visible" property is =
changed. This method is responsible for firing showEvent and hideEvent.
*/
YAHOO.widget.Overlay.prototype.configVisible =3D function(type, args, =
obj) {
	var visible =3D args[0];
	var currentVis =3D YAHOO.util.Dom.getStyle(this.element, "visibility");

	var effect =3D this.cfg.getProperty("effect");

	var effectInstances =3D new Array();
	if (effect) {
		if (effect instanceof Array) {
			for (var i=3D0;i<effect.length;i++) {
				var eff =3D effect[i];
				effectInstances[effectInstances.length] =3D eff.effect(this, =
eff.duration);
			}
		} else {
			effectInstances[effectInstances.length] =3D effect.effect(this, =
effect.duration);
		}
	}

	var isMacGecko =3D (this.platform =3D=3D "mac" && this.browser =3D=3D =
"gecko");

	if (visible) { // Show
		if (isMacGecko) {
			this.showMacGeckoScrollbars();
		}=09

		if (effect) { // Animate in
			if (visible) { // Animate in if not showing
				if (currentVis !=3D "visible") {
					this.beforeShowEvent.fire();
					for (var i=3D0;i<effectInstances.length;i++) {
						var e =3D effectInstances[i];
						if (i =3D=3D 0 && ! =
YAHOO.util.Config.alreadySubscribed(e.animateInCompleteEvent,this.showEve=
nt.fire,this.showEvent)) {
							=
e.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,tru=
e); // Delegate showEvent until end of animateInComplete
						}
						e.animateIn();
					}
				}
			}
		} else { // Show
			if (currentVis !=3D "visible") {
				this.beforeShowEvent.fire();
				YAHOO.util.Dom.setStyle(this.element, "visibility", "visible");
				this.cfg.refireEvent("iframe");
				this.showEvent.fire();
			}
		}

	} else { // Hide
		if (isMacGecko) {
			this.hideMacGeckoScrollbars();
		}=09

		if (effect) { // Animate out if showing
			if (currentVis !=3D "hidden") {
				this.beforeHideEvent.fire();
				for (var i=3D0;i<effectInstances.length;i++) {
					var e =3D effectInstances[i];
					if (i =3D=3D 0 && ! =
YAHOO.util.Config.alreadySubscribed(e.animateOutCompleteEvent,this.hideEv=
ent.fire,this.hideEvent)) {			=09
						=
e.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,tr=
ue); // Delegate hideEvent until end of animateOutComplete
					}
					e.animateOut();
				}
			}
		} else { // Simple hide
			if (currentVis !=3D "hidden") {
				this.beforeHideEvent.fire();
				YAHOO.util.Dom.setStyle(this.element, "visibility", "hidden");
				this.cfg.refireEvent("iframe");
				this.hideEvent.fire();
			}
		}=09
	}
}

/**
* Center event handler used for centering on scroll/resize, but only if =
the Overlay is visible
*/
YAHOO.widget.Overlay.prototype.doCenterOnDOMEvent =3D function() {
	if (this.cfg.getProperty("visible")) {
		this.center();
	}
}

/**
* The default event handler fired when the "fixedcenter" property is =
changed.
*/
YAHOO.widget.Overlay.prototype.configFixedCenter =3D function(type, =
args, obj) {
	var val =3D args[0];

	if (val) {
		this.center();
		=09
		if (! YAHOO.util.Config.alreadySubscribed(this.beforeShowEvent, =
this.center, this)) {
			this.beforeShowEvent.subscribe(this.center, this, true);
		}
	=09
		if (! =
YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowResizeEven=
t, this.doCenterOnDOMEvent, this)) {
			=
YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.doCenterOnDOMEvent,=
 this, true);
		}

		if (! =
YAHOO.util.Config.alreadySubscribed(YAHOO.widget.Overlay.windowScrollEven=
t, this.doCenterOnDOMEvent, this)) {
			YAHOO.widget.Overlay.windowScrollEvent.subscribe( =
this.doCenterOnDOMEvent, this, true);
		}
	} else {
		=
YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.doCenterOnDOMEven=
t, this);
		=
YAHOO.widget.Overlay.windowScrollEvent.unsubscribe(this.doCenterOnDOMEven=
t, this);
	}
}

/**
* The default event handler fired when the "height" property is changed.
*/
YAHOO.widget.Overlay.prototype.configHeight =3D function(type, args, =
obj) {
	var height =3D args[0];
	var el =3D this.element;
	YAHOO.util.Dom.setStyle(el, "height", height);
	this.cfg.refireEvent("iframe");
}

/**
* The default event handler fired when the "width" property is changed.
*/
YAHOO.widget.Overlay.prototype.configWidth =3D function(type, args, obj) =
{
	var width =3D args[0];
	var el =3D this.element;
	YAHOO.util.Dom.setStyle(el, "width", width);
	this.cfg.refireEvent("iframe");
}

/**
* The default event handler fired when the "zIndex" property is changed.
*/
YAHOO.widget.Overlay.prototype.configzIndex =3D function(type, args, =
obj) {
	var zIndex =3D args[0];

	var el =3D this.element;

	if (! zIndex) {
		zIndex =3D YAHOO.util.Dom.getStyle(el, "zIndex");
		if (! zIndex || isNaN(zIndex)) {
			zIndex =3D 0;
		}
	}

	if (this.iframe) {
		if (zIndex <=3D 0) {
			zIndex =3D 1;
		}
		YAHOO.util.Dom.setStyle(this.iframe, "zIndex", (zIndex-1));
	}

	YAHOO.util.Dom.setStyle(el, "zIndex", zIndex);
	this.cfg.setProperty("zIndex", zIndex, true);
}

/**
* The default event handler fired when the "xy" property is changed.
*/
YAHOO.widget.Overlay.prototype.configXY =3D function(type, args, obj) {
	var pos =3D args[0];
	var x =3D pos[0];
	var y =3D pos[1];

	this.cfg.setProperty("x", x);
	this.cfg.setProperty("y", y);

	this.beforeMoveEvent.fire([x,y]);

	x =3D this.cfg.getProperty("x");
	y =3D this.cfg.getProperty("y");

	this.cfg.refireEvent("iframe");
	this.moveEvent.fire([x,y]);
}

/**
* The default event handler fired when the "x" property is changed.
*/
YAHOO.widget.Overlay.prototype.configX =3D function(type, args, obj) {
	var x =3D args[0];
	var y =3D this.cfg.getProperty("y");

	this.cfg.setProperty("x", x, true);
	this.cfg.setProperty("y", y, true);

	this.beforeMoveEvent.fire([x,y]);

	x =3D this.cfg.getProperty("x");
	y =3D this.cfg.getProperty("y");

	YAHOO.util.Dom.setX(this.element, x, true);
=09
	this.cfg.setProperty("xy", [x, y], true);

	this.cfg.refireEvent("iframe");
	this.moveEvent.fire([x, y]);
}

/**
* The default event handler fired when the "y" property is changed.
*/
YAHOO.widget.Overlay.prototype.configY =3D function(type, args, obj) {
	var x =3D this.cfg.getProperty("x");
	var y =3D args[0];

	this.cfg.setProperty("x", x, true);
	this.cfg.setProperty("y", y, true);

	this.beforeMoveEvent.fire([x,y]);

	x =3D this.cfg.getProperty("x");
	y =3D this.cfg.getProperty("y");

	YAHOO.util.Dom.setY(this.element, y, true);

	this.cfg.setProperty("xy", [x, y], true);

	this.cfg.refireEvent("iframe");
	this.moveEvent.fire([x, y]);
}

/**
* The default event handler fired when the "iframe" property is changed.
*/
YAHOO.widget.Overlay.prototype.configIframe =3D function(type, args, =
obj) {
	var val =3D args[0];

	var el =3D this.element;

	if (val) {
		var x =3D this.cfg.getProperty("x");
		var y =3D this.cfg.getProperty("y");

		if (! x || ! y) {
			this.syncPosition();
			x =3D this.cfg.getProperty("x");
			y =3D this.cfg.getProperty("y");
		}

		if (! isNaN(x) && ! isNaN(y)) {
			if (! this.iframe) {
				this.iframe =3D document.createElement("iframe");
			=09
				var parent =3D el.parentNode;
				if (parent) {
					parent.appendChild(this.iframe);
				} else {
					document.body.appendChild(this.iframe);
				}

				this.iframe.src =3D this.imageRoot + =
YAHOO.widget.Overlay.IFRAME_SRC;
				YAHOO.util.Dom.setStyle(this.iframe, "position", "absolute");
				YAHOO.util.Dom.setStyle(this.iframe, "border", "none");
				YAHOO.util.Dom.setStyle(this.iframe, "margin", "0");
				YAHOO.util.Dom.setStyle(this.iframe, "padding", "0");
				YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
			}

			YAHOO.util.Dom.setStyle(this.iframe, "left", x-2 + "px");
			YAHOO.util.Dom.setStyle(this.iframe, "top", y-2 + "px");

			var width =3D el.clientWidth;
			var height =3D el.clientHeight;

			YAHOO.util.Dom.setStyle(this.iframe, "width", (width+2) + "px");
			YAHOO.util.Dom.setStyle(this.iframe, "height", (height+2) + "px");

			if (! this.cfg.getProperty("visible")) {
				this.iframe.style.display =3D "none";
			} else {
				this.iframe.style.display =3D "block";
			}
		}
	} else {
		if (this.iframe) {
			this.iframe.style.display =3D "none";
		}
	}
}

/**
* The default event handler fired when the "constraintoviewport" =
property is changed.
*/
YAHOO.widget.Overlay.prototype.configConstrainToViewport =3D =
function(type, args, obj) {
	var val =3D args[0];
	if (val) {
		if (! YAHOO.util.Config.alreadySubscribed(this.beforeMoveEvent, =
this.enforceConstraints, this)) {
			this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
		}
	} else {
		this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
	}
}

/**
* The default event handler fired when the "context" property is =
changed.
*/
YAHOO.widget.Overlay.prototype.configContext =3D function(type, args, =
obj) {
	var contextArgs =3D args[0];

	if (contextArgs) {
		var contextEl =3D contextArgs[0];
		var elementMagnetCorner =3D contextArgs[1];
		var contextMagnetCorner =3D contextArgs[2];

		if (contextEl) {
			if (typeof contextEl =3D=3D "string") {
				this.cfg.setProperty("context", =
[document.getElementById(contextEl),elementMagnetCorner,contextMagnetCorn=
er], true);
			}
		=09
			if (elementMagnetCorner && contextMagnetCorner) {
				this.align(elementMagnetCorner, contextMagnetCorner);
			}
		}=09
	}
}


// END BUILT-IN PROPERTY EVENT HANDLERS //

/**
* Aligns the Overlay to its context element using the specified corner =
points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, =
and BOTTOM_RIGHT.
* @param {string} elementAlign		The string representing the corner of =
the Overlay that should be aligned to the context element
* @param {string} contextAlign		The corner of the context element that =
the elementAlign corner should stick to.
*/
YAHOO.widget.Overlay.prototype.align =3D function(elementAlign, =
contextAlign) {
	var contextArgs =3D this.cfg.getProperty("context");
	if (contextArgs) {
		var context =3D contextArgs[0];
	=09
		var element =3D this.element;
		var me =3D this;

		if (! elementAlign) {
			elementAlign =3D contextArgs[1];
		}

		if (! contextAlign) {
			contextAlign =3D contextArgs[2];
		}

		if (element && context) {
			var elementRegion =3D YAHOO.util.Dom.getRegion(element);
			var contextRegion =3D YAHOO.util.Dom.getRegion(context);

			var doAlign =3D function(v,h) {
				switch (elementAlign) {
					case YAHOO.widget.Overlay.TOP_LEFT:
						me.moveTo(h,v);
						break;
					case YAHOO.widget.Overlay.TOP_RIGHT:
						me.moveTo(h-element.offsetWidth,v);
						break;
					case YAHOO.widget.Overlay.BOTTOM_LEFT:
						me.moveTo(h,v-element.offsetHeight);
						break;
					case YAHOO.widget.Overlay.BOTTOM_RIGHT:
						me.moveTo(h-element.offsetWidth,v-element.offsetHeight);
						break;
				}
			}

			switch (contextAlign) {
				case YAHOO.widget.Overlay.TOP_LEFT:
					doAlign(contextRegion.top, contextRegion.left);
					break;
				case YAHOO.widget.Overlay.TOP_RIGHT:
					doAlign(contextRegion.top, contextRegion.right);
					break;	=09
				case YAHOO.widget.Overlay.BOTTOM_LEFT:
					doAlign(contextRegion.bottom, contextRegion.left);
					break;
				case YAHOO.widget.Overlay.BOTTOM_RIGHT:
					doAlign(contextRegion.bottom, contextRegion.right);
					break;
			}
		}
	}
}

/**
* The default event handler executed when the moveEvent is fired, if the =
"constraintoviewport" is set to true.
*/
YAHOO.widget.Overlay.prototype.enforceConstraints =3D function(type, =
args, obj) {
	var pos =3D args[0];

	var x =3D pos[0];
	var y =3D pos[1];

	var width =3D parseInt(this.cfg.getProperty("width"));

	if (isNaN(width)) {
		width =3D 0;
	}

	var offsetHeight =3D this.element.offsetHeight;
	var offsetWidth =3D (width>0?width:this.element.offsetWidth); =
//this.element.offsetWidth;

	var viewPortWidth =3D YAHOO.util.Dom.getViewportWidth();
	var viewPortHeight =3D YAHOO.util.Dom.getViewportHeight();

	var scrollX =3D window.scrollX || document.documentElement.scrollLeft;
	var scrollY =3D window.scrollY || document.documentElement.scrollTop;

	var topConstraint =3D scrollY + 10;
	var leftConstraint =3D scrollX + 10;
	var bottomConstraint =3D scrollY + viewPortHeight - offsetHeight - 10;
	var rightConstraint =3D scrollX + viewPortWidth - offsetWidth - 10;
=09
	if (x < leftConstraint) {
		x =3D leftConstraint;
	} else if (x > rightConstraint) {
		x =3D rightConstraint;
	}

	if (y < topConstraint) {
		y =3D topConstraint;
	} else if (y > bottomConstraint) {
		y =3D bottomConstraint;
	}

	this.cfg.setProperty("x", x, true);
	this.cfg.setProperty("y", y, true);
	this.cfg.setProperty("xy", [x,y], true);
}

/**
* Centers the container in the viewport.
*/
YAHOO.widget.Overlay.prototype.center =3D function() {
	var scrollX =3D window.scrollX || document.documentElement.scrollLeft;
	var scrollY =3D window.scrollY || document.documentElement.scrollTop;

	var viewPortWidth =3D YAHOO.util.Dom.getClientWidth();
	var viewPortHeight =3D YAHOO.util.Dom.getClientHeight();

	var elementWidth =3D this.element.offsetWidth;
	var elementHeight =3D this.element.offsetHeight;

	var x =3D (viewPortWidth / 2) - (elementWidth / 2) + scrollX;
	var y =3D (viewPortHeight / 2) - (elementHeight / 2) + scrollY;
=09
	this.element.style.left =3D parseInt(x) + "px";
	this.element.style.top =3D parseInt(y) + "px";
	this.syncPosition();

	this.cfg.refireEvent("iframe");
}

/**
* Synchronizes the Panel's "xy", "x", and "y" properties with the =
Panel's position in the DOM. This is primarily used to update position =
information during drag & drop.
*/
YAHOO.widget.Overlay.prototype.syncPosition =3D function() {
	var pos =3D YAHOO.util.Dom.getXY(this.element);
	this.cfg.setProperty("x", pos[0], true);
	this.cfg.setProperty("y", pos[1], true);
	this.cfg.setProperty("xy", pos, true);
}

/**
* Event handler fired when the resize monitor element is resized.
*/
YAHOO.widget.Overlay.prototype.onDomResize =3D function(e, obj) {
	YAHOO.widget.Overlay.superclass.onDomResize.call(this, e, obj);
	this.cfg.refireEvent("iframe");
}

/**
* A singleton CustomEvent used for reacting to the DOM event for window =
scroll
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Overlay.windowScrollEvent =3D new =
YAHOO.util.CustomEvent("windowScroll");

/**
* A singleton CustomEvent used for reacting to the DOM event for window =
resize
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Overlay.windowResizeEvent =3D new =
YAHOO.util.CustomEvent("windowResize");

/**
* The DOM event handler used to fire the CustomEvent for window scroll
* @type Function
*/
YAHOO.widget.Overlay.windowScrollHandler =3D function(e) {
	YAHOO.widget.Overlay.windowScrollEvent.fire();
}

/**
* The DOM event handler used to fire the CustomEvent for window resize
* @type Function
*/
YAHOO.widget.Overlay.windowResizeHandler =3D function(e) {
	YAHOO.widget.Overlay.windowResizeEvent.fire();
}


if (YAHOO.widget.Overlay._initialized =3D=3D undefined) {
	YAHOO.util.Event.addListener(window, "scroll", =
YAHOO.widget.Overlay.windowScrollHandler);
	YAHOO.util.Event.addListener(window, "resize", =
YAHOO.widget.Overlay.windowResizeHandler);
	/**
	* @private
	*/
	YAHOO.widget.Overlay._initialized =3D true;
}
/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class
* OverlayManager is used for maintaining the focus status of multiple =
Overlays.
* @param {Array}	overlays	Optional. A collection of Overlays to register =
with the manager.
* @param {object}	userConfig		The object literal representing the user =
configuration of the OverlayManager
* @constructor
*/
YAHOO.widget.OverlayManager =3D function(userConfig) {
	this.init(userConfig);
}

/**
* The CSS class representing a focused Overlay
* @type string
*/
YAHOO.widget.OverlayManager.CSS_FOCUSED =3D "focused";

YAHOO.widget.OverlayManager.prototype =3D {

	constructor : YAHOO.widget.OverlayManager,

	/**
	* The array of Overlays that are currently registered
	* @type Array
	*/
	overlays : new Array(),

	/**
	* Initializes the default configuration of the OverlayManager
	*/=09
	initDefaultConfig : function() {
		this.cfg.addProperty("overlays", { suppressEvent:true } );
		this.cfg.addProperty("focusevent", { value:"mousedown" } );
	},=20

	/**
	* Returns the currently focused Overlay
	* @return {Overlay}	The currently focused Overlay
	*/
	getActive : function() {},

	/**
	* Focuses the specified Overlay
	* @param {Overlay}	The Overlay to focus
	* @param {string}	The id of the Overlay to focus
	*/
	focus : function(overlay) {},

	/**
	* Removes the specified Overlay from the manager
	* @param {Overlay}	The Overlay to remove
	* @param {string}	The id of the Overlay to remove
	*/
	remove: function(overlay) {},

	/**
	* Removes focus from all registered Overlays in the manager
	*/
	blurAll : function() {},

	/**
	* Initializes the OverlayManager
	* @param {Array}	overlays	Optional. A collection of Overlays to =
register with the manager.
	* @param {object}	userConfig		The object literal representing the user =
configuration of the OverlayManager
	*/
	init : function(userConfig) {
		this.cfg =3D new YAHOO.util.Config(this);

		this.initDefaultConfig();

		if (userConfig) {
			this.cfg.applyConfig(userConfig, true);
		}
		this.cfg.fireQueue();

		var activeOverlay =3D null;

		this.getActive =3D function() {
			return activeOverlay;
		}

		this.focus =3D function(overlay) {
			var o =3D this.find(overlay);
			if (o) {
				this.blurAll();
				activeOverlay =3D o;
				YAHOO.util.Dom.addClass(activeOverlay.element, =
YAHOO.widget.OverlayManager.CSS_FOCUSED);
				this.overlays.sort(this.compareZIndexDesc);
				var topZIndex =3D YAHOO.util.Dom.getStyle(this.overlays[0].element, =
"zIndex");
				if (! isNaN(topZIndex) && this.overlays[0] !=3D overlay) {
					activeOverlay.cfg.setProperty("zIndex", (parseInt(topZIndex) + 1));
				}
				this.overlays.sort(this.compareZIndexDesc);
			}
		}

		this.remove =3D function(overlay) {
			var o =3D this.find(overlay);
			if (o) {
				var originalZ =3D YAHOO.util.Dom.getStyle(o.element, "zIndex");
				o.cfg.setProperty("zIndex", -1000, true);
				this.overlays.sort(this.compareZIndexDesc);
				this.overlays =3D this.overlays.slice(0, this.overlays.length-1);
				o.cfg.setProperty("zIndex", originalZ, true);

				o.cfg.setProperty("manager", null);
				o.focusEvent =3D null
				o.blurEvent =3D null;
				o.focus =3D null;
				o.blur =3D null;
			}
		}

		this.blurAll =3D function() {
			activeOverlay =3D null;
			for (var o=3D0;o<this.overlays.length;o++) {
				YAHOO.util.Dom.removeClass(this.overlays[o].element, =
YAHOO.widget.OverlayManager.CSS_FOCUSED);
			}	=09
		}

		var overlays =3D this.cfg.getProperty("overlays");

		if (overlays) {
			this.register(overlays);
			this.overlays.sort(this.compareZIndexDesc);
		}
	},

	/**
	* Registers an Overlay or an array of Overlays with the manager. Upon =
registration, the Overlay receives functions for focus and blur, along =
with CustomEvents for each.
	* @param {Overlay}	overlay		An Overlay to register with the manager.
	* @param {Overlay[]}	overlay		An array of Overlays to register with the =
manager.
	* @return	{boolean}	True if any Overlays are registered.
	*/
	register : function(overlay) {
		if (overlay instanceof YAHOO.widget.Overlay) {
			overlay.cfg.addProperty("manager", { value:this } );

			overlay.focusEvent =3D new YAHOO.util.CustomEvent("focus");
			overlay.blurEvent =3D new YAHOO.util.CustomEvent("blur");
		=09
			var mgr=3Dthis;

			overlay.focus =3D function() {
				mgr.focus(this);
				this.focusEvent.fire();
			}=20

			overlay.blur =3D function() {
				mgr.blurAll();
				this.blurEvent.fire();
			}

			var focusOnDomEvent =3D function(e,obj) {
				mgr.focus(overlay);
			}
		=09
			var focusevent =3D this.cfg.getProperty("focusevent");
			=
YAHOO.util.Event.addListener(overlay.element,focusevent,focusOnDomEvent,t=
his,true);

			var zIndex =3D YAHOO.util.Dom.getStyle(overlay.element, "zIndex");
			if (! isNaN(zIndex)) {
				overlay.cfg.setProperty("zIndex", parseInt(zIndex));
			} else {
				overlay.cfg.setProperty("zIndex", 0);
			}
		=09
			this.overlays.push(overlay);
			return true;
		} else if (overlay instanceof Array) {
			var regcount =3D 0;
			for (var i=3D0;i<overlay.length;i++) {
				if (this.register(overlay[i])) {
					regcount++;
				}
			}
			if (regcount > 0) {
				return true;
			}
		} else {
			return false;
		}
	},

	/**
	* Attempts to locate an Overlay by instance or ID.
	* @param {Overlay}	overlay		An Overlay to locate within the manager
	* @param {string}	overlay		An Overlay id to locate within the manager
	* @return	{Overlay}	The requested Overlay, if found, or null if it =
cannot be located.
	*/
	find : function(overlay) {
		if (overlay instanceof YAHOO.widget.Overlay) {
			for (var o=3D0;o<this.overlays.length;o++) {
				if (this.overlays[o] =3D=3D overlay) {
					return this.overlays[o];
				}
			}
		} else if (typeof overlay =3D=3D "string") {
			for (var o=3D0;o<this.overlays.length;o++) {
				if (this.overlays[o].id =3D=3D overlay) {
					return this.overlays[o];
				}
			}		=09
		}
		return null;
	},

	/**
	* Used for sorting the manager's Overlays by z-index.
	* @private
	*/
	compareZIndexDesc : function(o1, o2) {
		var zIndex1 =3D o1.cfg.getProperty("zIndex");
		var zIndex2 =3D o2.cfg.getProperty("zIndex");

		if (zIndex1 > zIndex2) {
			return -1;
		} else if (zIndex1 < zIndex2) {
			return 1;
		} else {
			return 0;
		}
	},

	/**
	* Shows all Overlays in the manager.
	*/
	showAll : function() {
		for (var o=3D0;o<this.overlays.length;o++) {
			this.overlays[o].show();
		}
	},

	/**
	* Hides all Overlays in the manager.
	*/
	hideAll : function() {
		for (var o=3D0;o<this.overlays.length;o++) {
			this.overlays[o].hide();
		}
	}

}/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class=20
* KeyListener is a utility that provides an easy interface for listening =
for keydown/keyup events fired against DOM elements.
* @param {Element}	attachTo	The element or element ID to which the key =
event should be attached
* @param {string}	attachTo	The element or element ID to which the key =
event should be attached
* @param (object}	keyData		The object literal representing the key(s) to =
detect. Possible attributes are shift(boolean), alt(boolean), =
ctrl(boolean) and keys(either an int or an array of ints representing =
keycodes).
* @param {function}	handler		The CustomEvent handler to fire when the =
key event is detected
* @param {object}	handler		An object literal representing the handler.=20
* @param {string}	event		Optional. The event (keydown or keyup) to =
listen for. Defaults automatically to keydown.
* @constructor
*/
YAHOO.util.KeyListener =3D function(attachTo, keyData, handler, event) {
	if (! event) {
		event =3D YAHOO.util.KeyListener.KEYDOWN;
	}

	var keyEvent =3D new YAHOO.util.CustomEvent("keyPressed");
=09
	this.enabledEvent =3D new YAHOO.util.CustomEvent("enabled");
	this.disabledEvent =3D new YAHOO.util.CustomEvent("disabled");

	if (typeof attachTo =3D=3D 'string') {
		attachTo =3D document.getElementById(attachTo);
	}

	if (typeof handler =3D=3D 'function') {
		keyEvent.subscribe(handler);
	} else {
		keyEvent.subscribe(handler.fn, handler.scope, handler.correctScope);
	}

	/**
	* Handles the key event when a key is pressed.
	* @private
	*/
	var handleKeyPress =3D function(e, obj) {
		var keyPressed =3D e.charCode || e.keyCode;
	=09
		if (! keyData.shift)	keyData.shift =3D false;
		if (! keyData.alt)		keyData.alt =3D false;
		if (! keyData.ctrl)		keyData.ctrl =3D false;

		// check held down modifying keys first
		if (e.shiftKey =3D=3D keyData.shift &&=20
			e.altKey   =3D=3D keyData.alt &&
			e.ctrlKey  =3D=3D keyData.ctrl) { // if we pass this, all modifiers =
match

			if (keyData.keys instanceof Array) {
				for (var i=3D0;i<keyData.keys.length;i++) {
					if (keyPressed =3D=3D keyData.keys[i]) {
						keyEvent.fire(keyPressed, e);
						break;
					}
				}
			} else {
				if (keyPressed =3D=3D keyData.keys) {
					keyEvent.fire(keyPressed, e);
				}
			}
		}
	}

	this.enable =3D function() {
		if (! this.enabled) {
			YAHOO.util.Event.addListener(attachTo, event, handleKeyPress);
			this.enabledEvent.fire(keyData);
		}
		this.enabled =3D true;
	}

	this.disable =3D function() {
		if (this.enabled) {
			YAHOO.util.Event.removeListener(attachTo, event, handleKeyPress);
			this.disabledEvent.fire(keyData);
		}
		this.enabled =3D false;
	}

}

/**
* Constant representing the DOM "keydown" event.
* @final
*/
YAHOO.util.KeyListener.KEYDOWN =3D "keydown";

/**
* Constant representing the DOM "keyup" event.
* @final
*/
YAHOO.util.KeyListener.KEYUP =3D "keyup";

/**
* Enables the KeyListener, by dynamically attaching the key event to the =
appropriate DOM element.
*/
YAHOO.util.KeyListener.prototype.enable =3D function() {};

/**
* Disables the KeyListener, by dynamically removing the key event from =
the appropriate DOM element.
*/
YAHOO.util.KeyListener.prototype.disable =3D function() {};

/**
* CustomEvent fired when the KeyListener is enabled
* args: keyData
* @type YAHOO.util.CustomEvent
*/
YAHOO.util.KeyListener.prototype.enabledEvent =3D null;

/**
* CustomEvent fired when the KeyListener is disabled
* args: keyData
* @type YAHOO.util.CustomEvent
*/
YAHOO.util.KeyListener.prototype.disabledEvent =3D null;
/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class
* Tooltip is an implementation of Overlay that behaves like an OS =
tooltip, displaying when the user mouses over a particular element, and =
disappearing on mouse out.
* @param {string}	el	The element ID representing the Tooltip <em>OR</em>
* @param {Element}	el	The element representing the Tooltip
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Overlay. See configuration =
documentation for more details.
* @constructor
*/
YAHOO.widget.Tooltip =3D function(el, userConfig) {
	if (arguments.length > 0) {
		YAHOO.widget.Tooltip.superclass.constructor.call(this, el, =
userConfig);
	}
}

YAHOO.widget.Tooltip.prototype =3D new YAHOO.widget.Overlay();
YAHOO.widget.Tooltip.prototype.constructor =3D YAHOO.widget.Tooltip;

/**
* Reference to the Tooltip's superclass, Overlay
* @type class
* @final
*/
YAHOO.widget.Tooltip.superclass =3D YAHOO.widget.Overlay.prototype;

/**
* Constant representing the Tooltip CSS class
* @type string
* @final
*/
YAHOO.widget.Tooltip.CSS_TOOLTIP =3D "tt";

/*
* The Tooltip initialization method. This method is automatically called =
by the constructor. A Tooltip is automatically rendered by the init =
method, and it also is set to be invisible by default, and constrained =
to viewport by default as well.
* @param {string}	el	The element ID representing the Tooltip <em>OR</em>
* @param {Element}	el	The element representing the Tooltip
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Tooltip. See configuration =
documentation for more details.
*/
YAHOO.widget.Tooltip.prototype.init =3D function(el, userConfig) {
	if (document.readyState && document.readyState !=3D "complete") {
		var deferredInit =3D function() {
			this.init(el, userConfig);
		}
		YAHOO.util.Event.addListener(window, "load", deferredInit, this, =
true);
	} else {
		YAHOO.widget.Tooltip.superclass.init.call(this, el);

		this.beforeInitEvent.fire(YAHOO.widget.Tooltip);

		YAHOO.util.Dom.addClass(this.element, =
YAHOO.widget.Tooltip.CSS_TOOLTIP);

		if (userConfig) {
			this.cfg.applyConfig(userConfig, true);
		}
	=09
		this.cfg.queueProperty("visible",false);
		this.cfg.queueProperty("constraintoviewport",true);

		this.setBody("");
		this.render(this.cfg.getProperty("container"));

		this.initEvent.fire(YAHOO.widget.Tooltip);
	}
}

/**
* Initializes the class's configurable properties which can be changed =
using the Overlay's Config object (cfg).
*/
YAHOO.widget.Tooltip.prototype.initDefaultConfig =3D function() {
	YAHOO.widget.Tooltip.superclass.initDefaultConfig.call(this);

	this.cfg.addProperty("preventoverlap",		{ value:true, =
handler:this.configPreventOverlap, validator:this.cfg.checkBoolean, =
supercedes:["x","y","xy"] } );

	this.cfg.addProperty("showdelay",			{ value:200, =
handler:this.configShowDelay, validator:this.cfg.checkNumber } );
	this.cfg.addProperty("autodismissdelay",	{ value:5000, =
handler:this.configAutoDismissDelay, validator:this.cfg.checkNumber } );
	this.cfg.addProperty("hidedelay",			{ value:250, =
handler:this.configHideDelay, validator:this.cfg.checkNumber } );

	this.cfg.addProperty("text",				{ handler:this.configText, =
suppressEvent:true } );
	this.cfg.addProperty("container",			{ value:document.body, =
handler:this.configContainer } );
}

// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //

/**
* The default event handler fired when the "text" property is changed.
*/
YAHOO.widget.Tooltip.prototype.configText =3D function(type, args, obj) =
{
	var text =3D args[0];
	if (text) {
		this.setBody(text);
	}
}

/**
* The default event handler fired when the "container" property is =
changed.
*/
YAHOO.widget.Tooltip.prototype.configContainer =3D function(type, args, =
obj) {
	var container =3D args[0];
	if (typeof container =3D=3D 'string') {
		this.cfg.setProperty("container", document.getElementById(container), =
true);
	}
}

/**
* The default event handler fired when the "preventoverlap" property is =
changed.
*/
YAHOO.widget.Tooltip.prototype.configPreventOverlap =3D function(type, =
args, obj) {
	var preventoverlap =3D args[0];
	if (preventoverlap) {
		if (! YAHOO.util.Config.alreadySubscribed(this.moveEvent, =
this.preventOverlap, this)) {
			this.moveEvent.subscribe(this.preventOverlap, this, true);
		}
	} else {
		this.moveEvent.unsubscribe(this.preventOverlap, this);
	}
}

/**
* The default event handler fired when the "context" property is =
changed.
*/
YAHOO.widget.Tooltip.prototype.configContext =3D function(type, args, =
obj) {
	var context =3D args[0];
	if (context) {
		if (typeof context =3D=3D "string") {
			this.cfg.setProperty("context", document.getElementById(context), =
true);
		}
	=09
		var contextElement =3D this.cfg.getProperty("context");

		if (contextElement && contextElement.title && ! =
this.cfg.getProperty("text")) {
			this.cfg.setProperty("text", contextElement.title);
		}

		YAHOO.util.Event.addListener(contextElement, "mouseover", =
this.onContextMouseOver, this);
		YAHOO.util.Event.addListener(contextElement, "mouseout", =
this.onContextMouseOut, this);
	}
}

// END BUILT-IN PROPERTY EVENT HANDLERS //

// BEGIN BUILT-IN DOM EVENT HANDLERS //

/**
* The default event handler fired when the user mouses over the context =
element.
* @param {DOMEvent} e	The current DOM event
* @param {object}	obj	The object argument
*/
YAHOO.widget.Tooltip.prototype.onContextMouseOver =3D function(e, obj) {
	if (! obj) {
		obj =3D this;
	}
=09
	var context =3D obj.cfg.getProperty("context");
=09
	if (context.title) {
		obj.tempTitle =3D context.title;
		context.title =3D "";
	}

	/**
	* The unique process ID associated with the thread responsible for =
showing the Tooltip.
	* @type int
	*/
	this.procId =3D obj.doShow(e);
}

/**
* The default event handler fired when the user mouses out of the =
context element.
* @param {DOMEvent} e	The current DOM event
* @param {object}	obj	The object argument
*/
YAHOO.widget.Tooltip.prototype.onContextMouseOut =3D function(e, obj) {
	if (! obj) {
		obj =3D this;
	}

	var context =3D obj.cfg.getProperty("context");

	if (obj.tempTitle) {
		context.title =3D obj.tempTitle;
	}
=09
	if (this.procId) {
		clearTimeout(this.procId);
	}

	setTimeout(function() {
				obj.hide();
				}, obj.cfg.getProperty("hidedelay"));
}

// END BUILT-IN DOM EVENT HANDLERS //

/**
* Processes the showing of the Tooltip by setting the timeout delay and =
offset of the Tooltip.
* @param {DOMEvent} e	The current DOM event
* @return {int}	The process ID of the timeout function associated with =
doShow
*/
YAHOO.widget.Tooltip.prototype.doShow =3D function(e) {

	var pageX =3D YAHOO.util.Event.getPageX(e);
	var pageY =3D YAHOO.util.Event.getPageY(e);
=09
	var context =3D this.cfg.getProperty("context");
	var yOffset =3D 25;
	if (this.browser =3D=3D "opera" && context.tagName =3D=3D "A") {
		yOffset +=3D 12;
	}

	var me =3D this;
	return setTimeout(
		function() {
			me.moveTo(pageX, pageY + yOffset);
			me.show();
			me.doHide();
		},
	this.cfg.getProperty("showdelay"));
}

/**
* Sets the timeout for the auto-dismiss delay, which by default is 5 =
seconds, meaning that a tooltip will automatically dismiss itself after =
5 seconds of being displayed.
*/
YAHOO.widget.Tooltip.prototype.doHide =3D function() {
	var me =3D this;
	setTimeout(
		function() {
			me.hide();
		},
		this.cfg.getProperty("autodismissdelay"));
}

/**
* Fired when the Tooltip is moved, this event handler is used to prevent =
the Tooltip from overlapping with its context element.
*/
YAHOO.widget.Tooltip.prototype.preventOverlap =3D function(type, args, =
obj) {
	var pos =3D args[0];
	var x =3D pos[0];
	var y =3D pos[1];

	var elementRegion =3D YAHOO.util.Dom.getRegion(this.element);
	var contextRegion =3D =
YAHOO.util.Dom.getRegion(this.cfg.getProperty("context"));
=09
	var intersection =3D contextRegion.intersect(elementRegion);
	if (intersection) { // they overlap
		var overlapHeight =3D intersection.bottom - intersection.top;
		y =3D (y - overlapHeight - 10);
		this.cfg.setProperty("y", y);
	}
}
/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class
* Panel is an implementation of Overlay that behaves like an OS window, =
with a draggable header and an optional close icon at the top right.
* @param {string}	el	The element ID representing the Panel <em>OR</em>
* @param {Element}	el	The element representing the Panel
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Panel. See configuration =
documentation for more details.
* @constructor
*/
YAHOO.widget.Panel =3D function(el, userConfig) {
	if (arguments.length > 0) {
		YAHOO.widget.Panel.superclass.constructor.call(this, el, userConfig);
	}
}

YAHOO.widget.Panel.prototype =3D new YAHOO.widget.Overlay();
YAHOO.widget.Panel.prototype.constructor =3D YAHOO.widget.Panel;

/**
* Reference to the Panel's superclass, Overlay
* @type class
* @final
*/
YAHOO.widget.Panel.superclass =3D YAHOO.widget.Overlay.prototype;

/**
* Constant representing the default CSS class used for a Panel
* @type string
* @final
*/
YAHOO.widget.Panel.CSS_PANEL =3D "panel";

/**
* Constant representing the default CSS class used for a Panel's =
wrapping container
* @type string
* @final
*/
YAHOO.widget.Panel.CSS_PANEL_CONTAINER =3D "panel-container";

/**
* CustomEvent fired after the modality mask is shown
* args: none
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Panel.prototype.showMaskEvent =3D null;

/**
* CustomEvent fired after the modality mask is hidden
* args: none
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Panel.prototype.hideMaskEvent =3D null;

/*
* The Overlay initialization method, which is executed for Overlay and =
all of its subclasses. This method is automatically called by the =
constructor, and  sets up all DOM references for pre-existing markup, =
and creates required markup if it is not already present.
* @param {string}	el	The element ID representing the Overlay <em>OR</em>
* @param {Element}	el	The element representing the Overlay
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Overlay. See configuration =
documentation for more details.
*/
YAHOO.widget.Panel.prototype.init =3D function(el, userConfig) {
	YAHOO.widget.Panel.superclass.init.call(this, el/*, userConfig*/);  // =
Note that we don't pass the user config in here yet because we only want =
it executed once, at the lowest subclass level
=09
	this.beforeInitEvent.fire(YAHOO.widget.Panel);

	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Panel.CSS_PANEL);

	this.buildWrapper();		=09
=09
	if (userConfig) {
		this.cfg.applyConfig(userConfig, true);
	}

	this.beforeRenderEvent.subscribe(function() {
		var draggable =3D this.cfg.getProperty("draggable");
		if (draggable) {
			if (! this.header) {
				this.setHeader("&nbsp;");
			}
		}
	}, this, true);

	this.initEvent.fire(YAHOO.widget.Panel);

}

/**
* Initializes the custom events for Module which are fired automatically =
at appropriate times by the Module class.
*/
YAHOO.widget.Panel.prototype.initEvents =3D function() {
	YAHOO.widget.Panel.superclass.initEvents.call(this);

	this.showMaskEvent =3D new YAHOO.util.CustomEvent("showMask");
	this.hideMaskEvent =3D new YAHOO.util.CustomEvent("hideMask");
}

/**
* Initializes the class's configurable properties which can be changed =
using the Panel's Config object (cfg).
*/
YAHOO.widget.Panel.prototype.initDefaultConfig =3D function() {
	YAHOO.widget.Panel.superclass.initDefaultConfig.call(this);

	// Add panel config properties //

	this.cfg.addProperty("close", { value:true, handler:this.configClose, =
validator:this.cfg.checkBoolean, supercedes:["visible"] } );
	this.cfg.addProperty("draggable", { value:true,	=
handler:this.configDraggable, validator:this.cfg.checkBoolean, =
supercedes:["visible"] } );

	this.cfg.addProperty("underlay", { value:"shadow", =
handler:this.configUnderlay, supercedes:["visible"] } );
	this.cfg.addProperty("modal",	{ value:false, handler:this.configModal, =
validator:this.cfg.checkBoolean, supercedes:["visible"] } );

	this.cfg.addProperty("keylisteners", { handler:this.configKeyListeners, =
suppressEvent:true, supercedes:["visible"] } );
}

// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //

/**
* The default event handler fired when the "close" property is changed. =
The method controls the appending or hiding of the close icon at the top =
right of the Panel.
*/
YAHOO.widget.Panel.prototype.configClose =3D function(type, args, obj) {
	var val =3D args[0];

	var doHide =3D function(e, obj) {
		obj.hide();
	}

	if (val) {
		if (! this.close) {
			this.close =3D document.createElement("DIV");
			YAHOO.util.Dom.addClass(this.close, "close");

			if (this.isSecure) {
				YAHOO.util.Dom.addClass(this.close, "secure");
			} else {
				YAHOO.util.Dom.addClass(this.close, "nonsecure");
			}

			this.close.innerHTML =3D "&nbsp;";
			this.innerElement.appendChild(this.close);
			YAHOO.util.Event.addListener(this.close, "click", doHide, this);=09
		} else {
			this.close.style.display =3D "block";
		}
	} else {
		if (this.close) {
			this.close.style.display =3D "none";
		}
	}
}

/**
* The default event handler fired when the "draggable" property is =
changed.
*/
YAHOO.widget.Panel.prototype.configDraggable =3D function(type, args, =
obj) {
	var val =3D args[0];
	if (val) {
		if (this.header) {
			YAHOO.util.Dom.setStyle(this.header,"cursor","move");
			this.registerDragDrop();
		}
	} else {
		if (this.dd) {
			this.dd.unreg();
		}
		if (this.header) {
			YAHOO.util.Dom.setStyle(this.header,"cursor","auto");
		}
	}
}

/**
* The default event handler fired when the "underlay" property is =
changed.
*/
YAHOO.widget.Panel.prototype.configUnderlay =3D function(type, args, =
obj) {
	var val =3D args[0];

	switch (val.toLowerCase()) {
		case "shadow":
			YAHOO.util.Dom.removeClass(this.element, "matte");
			YAHOO.util.Dom.addClass(this.element, "shadow");

			if (! this.underlay) { // create if not already in DOM
				this.underlay =3D document.createElement("DIV");
				this.underlay.className =3D "underlay";
				this.underlay.innerHTML =3D "&nbsp;";
				this.element.appendChild(this.underlay);
			}=20

			this.sizeUnderlay();
			break;
		case "matte":
			YAHOO.util.Dom.removeClass(this.element, "shadow");
			YAHOO.util.Dom.addClass(this.element, "matte");
			break;
		case "none":
		default:
			YAHOO.util.Dom.removeClass(this.element, "shadow");
			YAHOO.util.Dom.removeClass(this.element, "matte");
			break;
	}
}

/**
* The default event handler fired when the "modal" property is changed. =
This handler subscribes or unsubscribes to the show and hide events to =
handle the display or hide of the modality mask.
*/
YAHOO.widget.Panel.prototype.configModal =3D function(type, args, obj) {
	var modal =3D args[0];

	if (modal) {
		this.buildMask();

		if (! YAHOO.util.Config.alreadySubscribed( this.showEvent, =
this.showMask, this ) ) {
			this.showEvent.subscribe(this.showMask, this, true);
		}
		if (! YAHOO.util.Config.alreadySubscribed( this.hideEvent, =
this.hideMask, this) ) {
			this.hideEvent.subscribe(this.hideMask, this, true);
		}
		if (! YAHOO.util.Config.alreadySubscribed( =
YAHOO.widget.Overlay.windowResizeEvent, this.sizeMask, this ) ) {
			YAHOO.widget.Overlay.windowResizeEvent.subscribe(this.sizeMask, this, =
true);
		}
	} else {
		this.beforeShowEvent.unsubscribe(this.showMask, this);
		this.hideEvent.unsubscribe(this.hideMask, this);
		YAHOO.widget.Overlay.windowResizeEvent.unsubscribe(this.sizeMask);
	}
}

YAHOO.widget.Panel.prototype.configKeyListeners =3D function(type, args, =
obj) {
	var listeners =3D args[0];

	if (listeners) {
		if (listeners instanceof Array) {
			for (var i=3D0;i<listeners.length;i++) {
				var listener =3D listeners[i];

				if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, =
listener.enable, listener)) {
					this.showEvent.subscribe(listener.enable, listener, true);
				}
				if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, =
listener.disable, listener)) {
					this.hideEvent.subscribe(listener.disable, listener, true);
				}
			}
		} else {
			if (! YAHOO.util.Config.alreadySubscribed(this.showEvent, =
listeners.enable, listeners)) {
				this.showEvent.subscribe(listeners.enable, listeners, true);
			}
			if (! YAHOO.util.Config.alreadySubscribed(this.hideEvent, =
listeners.disable, listeners)) {
				this.hideEvent.subscribe(listeners.disable, listeners, true);
			}
		}
	}=20
}

// END BUILT-IN PROPERTY EVENT HANDLERS //


/**
* Builds the wrapping container around the Panel that is used for =
positioning the shadow and matte underlays. The container element is =
assigned to a  local instance variable called container, and the element =
is reinserted inside of it.
*/
YAHOO.widget.Panel.prototype.buildWrapper =3D function() {
	var elementParent =3D this.element.parentNode;

	var elementClone =3D this.element.cloneNode(true);
	this.innerElement =3D elementClone;
	this.innerElement.style.visibility =3D "inherit";

	YAHOO.util.Dom.addClass(this.innerElement, "panel");

	var wrapper =3D document.createElement("DIV");
	wrapper.className =3D YAHOO.widget.Panel.CSS_PANEL_CONTAINER;
	wrapper.id =3D elementClone.id + "_c";
=09
	wrapper.appendChild(elementClone);
=09
	if (elementParent) {
		elementParent.replaceChild(wrapper, this.element);
	}

	this.element =3D wrapper;

	// Resynchronize the local field references

	var childNodes =3D this.innerElement.childNodes;
	if (childNodes) {
		for (var i=3D0;i<childNodes.length;i++) {
			var child =3D childNodes[i];
			switch (child.className) {
				case YAHOO.widget.Module.CSS_HEADER:
					this.header =3D child;
					break;
				case YAHOO.widget.Module.CSS_BODY:
					this.body =3D child;
					break;
				case YAHOO.widget.Module.CSS_FOOTER:
					this.footer =3D child;
					break;
			}
		}
	}

	this.initDefaultConfig(); // We've changed the DOM, so the =
configuration must be re-tooled to get the DOM references right
}

/**
* Adjusts the size of the shadow based on the size of the element.
*/
YAHOO.widget.Panel.prototype.sizeUnderlay =3D function() {
	if (this.underlay && this.browser !=3D "gecko" && this.browser !=3D =
"safari") {
		this.underlay.style.width =3D this.innerElement.offsetWidth + "px";
		this.underlay.style.height =3D this.innerElement.offsetHeight + "px";
	}
}

/**
* Event handler fired when the resize monitor element is resized.
*/
YAHOO.widget.Panel.prototype.onDomResize =3D function(e, obj) {=20
	YAHOO.widget.Panel.superclass.onDomResize.call(this, e, obj);
	var me =3D this;
	setTimeout(function() {
		me.sizeUnderlay();
	}, 0);
};

/**
* Registers the Panel's header for drag & drop capability.
*/
YAHOO.widget.Panel.prototype.registerDragDrop =3D function() {
	if (this.header) {
		this.dd =3D new YAHOO.util.DD(this.element.id, "panel");

		if (! this.header.id) {
			this.header.id =3D this.id + "_h";
		}
	=09
		var me =3D this;

		this.dd.startDrag =3D function() {
			if (me.browser =3D=3D "ie") {
				YAHOO.util.Dom.addClass(me.element,"drag");
			}

			if (me.cfg.getProperty("constraintoviewport")) {
				var offsetHeight =3D me.element.offsetHeight;
				var offsetWidth =3D me.element.offsetWidth;

				var viewPortWidth =3D YAHOO.util.Dom.getViewportWidth();
				var viewPortHeight =3D YAHOO.util.Dom.getViewportHeight();

				var scrollX =3D window.scrollX || =
document.documentElement.scrollLeft;
				var scrollY =3D window.scrollY || =
document.documentElement.scrollTop;

				var topConstraint =3D scrollY + 10;
				var leftConstraint =3D scrollX + 10;
				var bottomConstraint =3D scrollY + viewPortHeight - offsetHeight - =
10;
				var rightConstraint =3D scrollX + viewPortWidth - offsetWidth - 10;

				this.minX =3D leftConstraint
				this.maxX =3D rightConstraint;
				this.constrainX =3D true;

				this.minY =3D topConstraint;
				this.maxY =3D bottomConstraint;
				this.constrainY =3D true;
			} else {
				this.constrainX =3D false;
				this.constrainY =3D false;
			}
	=09
		}
	=09
		this.dd.onDrag =3D function() {
			me.syncPosition();
			me.cfg.refireEvent("iframe");
			if (this.platform =3D=3D "mac" && this.browser =3D=3D "gecko") {
				this.showMacGeckoScrollbars();
			}
		}

		this.dd.endDrag =3D function() {
			if (me.browser =3D=3D "ie") {
				YAHOO.util.Dom.removeClass(me.element,"drag");
			}
		}

		this.dd.setHandleElId(this.header.id);
		this.dd.addInvalidHandleType("INPUT");
		this.dd.addInvalidHandleType("SELECT");
		this.dd.addInvalidHandleType("TEXTAREA");
	}
}

/**
* Builds the mask that is laid over the document when the Panel is =
configured to be modal.
*/
YAHOO.widget.Panel.prototype.buildMask =3D function() {
	if (! this.mask) {
		this.mask =3D document.createElement("DIV");
		this.mask.id =3D this.id + "_mask";
		this.mask.className =3D "mask";
		this.mask.innerHTML =3D "&nbsp;";

		var maskClick =3D function(e, obj) {
			YAHOO.util.Event.stopEvent(e);
		}

		YAHOO.util.Event.addListener(this.mask, maskClick, this);

		if (this.browser =3D=3D "opera") {
			this.mask.style.backgroundColor =3D "transparent";
		}
		document.body.appendChild(this.mask);
	}
}

/**
* Hides the modality mask.
*/
YAHOO.widget.Panel.prototype.hideMask =3D function() {
	if (this.cfg.getProperty("modal") && this.mask) {
		this.mask.tabIndex =3D -1;
		this.mask.style.display =3D "none";
		this.hideMaskEvent.fire();
		YAHOO.util.Dom.removeClass(document.body, "masked");
	}
}

/**
* Shows the modality mask.
*/
YAHOO.widget.Panel.prototype.showMask =3D function() {
	if (this.cfg.getProperty("modal") && this.mask) {
		YAHOO.util.Dom.addClass(document.body, "masked");
		this.sizeMask();
		this.mask.style.display =3D "block";
		this.mask.tabIndex =3D 0;
		this.showMaskEvent.fire();
	}
}

/**
* Sets the size of the modality mask to cover the entire scrollable area =
of the document
*/
YAHOO.widget.Panel.prototype.sizeMask =3D function() {
	if (this.mask) {
		this.mask.style.height =3D YAHOO.util.Dom.getDocumentHeight()+"px";
		this.mask.style.width =3D YAHOO.util.Dom.getDocumentWidth()+"px";
	}
}

/**
* The default event handler fired when the "height" property is changed.
*/
YAHOO.widget.Panel.prototype.configHeight =3D function(type, args, obj) =
{
	var height =3D args[0];
	var el =3D this.innerElement;
	YAHOO.util.Dom.setStyle(el, "height", height);
	this.cfg.refireEvent("underlay");
	this.cfg.refireEvent("iframe");
}

/**
* The default event handler fired when the "width" property is changed.
*/
YAHOO.widget.Panel.prototype.configWidth =3D function(type, args, obj) {
	var width =3D args[0];
	var el =3D this.innerElement;
	YAHOO.util.Dom.setStyle(el, "width", width);
	this.cfg.refireEvent("underlay");
	this.cfg.refireEvent("iframe");
}

/**
* Renders the Panel by inserting the elements that are not already in =
the main Panel into their correct places. Optionally appends the Panel =
to the specified node prior to the render's execution. NOTE: For Panels =
without existing markup, the appendToNode argument is REQUIRED. If this =
argument is ommitted and the current element is not present in the =
document, the function will return false, indicating that the render was =
a failure.
* @param {string}	appendToNode	The element id to which the Module should =
be appended to prior to rendering <em>OR</em>
* @param {Element}	appendToNode	The element to which the Module should =
be appended to prior to rendering=09
* @return {boolean} Success or failure of the render
*/
YAHOO.widget.Panel.prototype.render =3D function(appendToNode) {
	return YAHOO.widget.Panel.superclass.render.call(this, appendToNode, =
this.innerElement);
}
/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class
* Dialog is an implementation of Panel that can be used to submit form =
data. Built-in functionality for buttons with event handlers is =
included, and button sets can be build dynamically, or the preincluded =
ones for Submit/Cancel and OK/Cancel can be utilized. Forms can be =
processed in 3 ways -- via an asynchronous Connection utility call, a =
simple form POST or GET, or manually.
* @param {string}	el	The element ID representing the Dialog <em>OR</em>
* @param {Element}	el	The element representing the Dialog
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Dialog. See configuration =
documentation for more details.
* @constructor
*/
YAHOO.widget.Dialog =3D function(el, userConfig) {
	if (arguments.length > 0) {
		YAHOO.widget.Dialog.superclass.constructor.call(this, el, userConfig);
	}
}

YAHOO.widget.Dialog.prototype =3D new YAHOO.widget.Panel();
YAHOO.widget.Dialog.prototype.constructor =3D YAHOO.widget.Dialog;

/**
* Reference to the Dialog's superclass, Panel
* @type class
* @final
*/
YAHOO.widget.Dialog.superclass =3D YAHOO.widget.Panel.prototype;

/**
* Constant representing the default CSS class used for a Dialog
* @type string
* @final
*/
YAHOO.widget.Dialog.CSS_DIALOG =3D "dialog";


/**
* CustomEvent fired prior to submission
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Dialog.prototype.beforeSubmitEvent =3D null;

/**
* CustomEvent fired after submission
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Dialog.prototype.submitEvent =3D null;

/**
* CustomEvent fired prior to manual submission
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Dialog.prototype.manualSubmitEvent =3D null;

/**
* CustomEvent fired prior to asynchronous submission
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Dialog.prototype.asyncSubmitEvent =3D null;

/**
* CustomEvent fired prior to form-based submission
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Dialog.prototype.formSubmitEvent =3D null;

/**
* CustomEvent fired after cancel
* @type YAHOO.util.CustomEvent
*/
YAHOO.widget.Dialog.prototype.cancelEvent =3D null;


/**
* Initializes the class's configurable properties which can be changed =
using the Dialog's Config object (cfg).
*/
YAHOO.widget.Dialog.prototype.initDefaultConfig =3D function() {
	YAHOO.widget.Dialog.superclass.initDefaultConfig.call(this);

	/**
	* The internally maintained callback object for use with the Connection =
utility
	* @type object
	* @private
	*/
	var callback =3D {
		success : null,
		failure : null,
		argument: null,
		scope : this
	}

	this.configOnSuccess =3D function(type, args, obj) {
		var fn =3D args[0];
		callback.success =3D fn;
	}

	this.configOnFailure =3D function(type, args, obj) {
		var fn =3D args[0];
		callback.failure =3D fn;
	}


	this.doSubmit =3D function() {
		var method =3D this.cfg.getProperty("postmethod");
		switch (method) {
			case "async":
				YAHOO.util.Connect.setForm(this.form.name);
				var cObj =3D YAHOO.util.Connect.asyncRequest('POST', =
this.form.action, callback);
				this.asyncSubmitEvent.fire();
				break;
			case "form":
				this.form.submit();
				this.formSubmitEvent.fire();
				break;
			case "none":
			case "manual":
				this.manualSubmitEvent.fire();
				break;
		}
	}

	// Add form dialog config properties //
	this.cfg.addProperty("postmethod", { value:"async", =
validator:function(val) {=20
													if (val !=3D "form" && val !=3D "async" && val !=3D "none" =
&& val !=3D "manual") {
														return false;
													} else {
														return true;
													}
												} });

	this.cfg.addProperty("onsuccess",	{ handler:this.configOnSuccess, =
suppressEvent:true } );
	this.cfg.addProperty("onfailure",	{ handler:this.configOnFailure, =
suppressEvent:true } );

	this.cfg.addProperty("buttons",		{ value:"none",	=
handler:this.configButtons } );
}

/**
* Initializes the custom events for Dialog which are fired automatically =
at appropriate times by the Dialog class.
*/
YAHOO.widget.Dialog.prototype.initEvents =3D function() {
	YAHOO.widget.Dialog.superclass.initEvents.call(this);
=09
	this.beforeSubmitEvent	=3D new YAHOO.util.CustomEvent("beforeSubmit");
	this.submitEvent		=3D new YAHOO.util.CustomEvent("submit");

	this.manualSubmitEvent	=3D new YAHOO.util.CustomEvent("manualSubmit");
	this.asyncSubmitEvent	=3D new YAHOO.util.CustomEvent("asyncSubmit");
	this.formSubmitEvent	=3D new YAHOO.util.CustomEvent("formSubmit");

	this.cancelEvent		=3D new YAHOO.util.CustomEvent("cancel");
}

/*
* The Dialog initialization method, which is executed for Dialog and all =
of its subclasses. This method is automatically called by the =
constructor, and  sets up all DOM references for pre-existing markup, =
and creates required markup if it is not already present.
* @param {string}	el	The element ID representing the Dialog <em>OR</em>
* @param {Element}	el	The element representing the Dialog
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this Dialog. See configuration =
documentation for more details.
*/
YAHOO.widget.Dialog.prototype.init =3D function(el, userConfig) {
	YAHOO.widget.Dialog.superclass.init.call(this, el/*, userConfig*/);  // =
Note that we don't pass the user config in here yet because we only want =
it executed once, at the lowest subclass level
=09
	this.beforeInitEvent.fire(YAHOO.widget.Dialog);

	YAHOO.util.Dom.addClass(this.element, YAHOO.widget.Dialog.CSS_DIALOG);

	if (userConfig) {
		this.cfg.applyConfig(userConfig, true);
	}

	this.renderEvent.subscribe(this.registerForm, this, true);

	this.showEvent.subscribe(this.focusFirst, this, true);
	this.beforeHideEvent.subscribe(this.blurButtons, this, true);

	this.beforeRenderEvent.subscribe(function() {
		var buttonCfg =3D this.cfg.getProperty("buttons");
		if (buttonCfg && buttonCfg !=3D "none") {
			if (! this.footer) {
				this.setFooter("");
			}
		}
	}, this, true);

	this.initEvent.fire(YAHOO.widget.Dialog);
}

/**
* Prepares the Dialog's internal FORM object, creating one if one is not =
currently present.
*/
YAHOO.widget.Dialog.prototype.registerForm =3D function() {
	var form =3D this.element.getElementsByTagName("FORM")[0];

	if (! form) {
		var formHTML =3D "<form name=3D\"frm_" + this.id + "\" =
action=3D\"\"></form>";
		this.body.innerHTML +=3D formHTML;
		form =3D this.element.getElementsByTagName("FORM")[0];
	}

	this.firstFormElement =3D function() {
		for (var f=3D0;f<form.elements.length;f++ ) {
			var el =3D form.elements[f];
			if (el.focus) {
				if (el.type && el.type !=3D "hidden") {
					return el;
					break;
				}
			}
		}
		return null;
	}();

	this.lastFormElement =3D function() {
		for (var f=3Dform.elements.length-1;f>=3D0;f-- ) {
			var el =3D form.elements[f];
			if (el.focus) {
				if (el.type && el.type !=3D "hidden") {
					return el;
					break;
				}
			}
		}
		return null;
	}();

	this.form =3D form;

	if (this.cfg.getProperty("modal") && this.form) {

		var me =3D this;
	=09
		var firstElement =3D this.firstFormElement || this.firstButton;
		if (firstElement) {
			this.preventBackTab =3D new YAHOO.util.KeyListener(firstElement, { =
shift:true, keys:9 }, {fn:me.focusLast, scope:me, correctScope:true} );
			this.showEvent.subscribe(this.preventBackTab.enable, =
this.preventBackTab, true);
			this.hideEvent.subscribe(this.preventBackTab.disable, =
this.preventBackTab, true);
		}

		var lastElement =3D this.lastButton || this.lastFormElement;
		if (lastElement) {
			this.preventTabOut =3D new YAHOO.util.KeyListener(lastElement, { =
shift:false, keys:9 }, {fn:me.focusFirst, scope:me, correctScope:true} =
);
			this.showEvent.subscribe(this.preventTabOut.enable, =
this.preventTabOut, true);
			this.hideEvent.subscribe(this.preventTabOut.disable, =
this.preventTabOut, true);
		}
	}
}

// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //

/**
* The default event handler for the "buttons" configuration property
*/
YAHOO.widget.Dialog.prototype.configButtons =3D function(type, args, =
obj) {
	var buttons =3D args[0];
	if (buttons !=3D "none") {
		this.buttonSpan =3D null;
		this.buttonSpan =3D document.createElement("SPAN");
		this.buttonSpan.className =3D "button-group";

		for (var b=3D0;b<buttons.length;b++) {
			var button =3D buttons[b];

			var htmlButton =3D document.createElement("BUTTON");

			if (button.isDefault) {
				htmlButton.className =3D "default";
				this.defaultHtmlButton =3D htmlButton;
			}

			htmlButton.appendChild(document.createTextNode(button.text));
			YAHOO.util.Event.addListener(htmlButton, "click", button.handler, =
this, true);

			this.buttonSpan.appendChild(htmlButton);	=09
			button.htmlButton =3D htmlButton;

			if (b =3D=3D 0) {
				this.firstButton =3D button.htmlButton;
			}

			if (b =3D=3D (buttons.length-1)) {
				this.lastButton =3D button.htmlButton;
			}

		}

		this.setFooter(this.buttonSpan);

		this.cfg.refireEvent("iframe");
		this.cfg.refireEvent("underlay");
	}
}

/**
* The default handler fired when the "success" property is changed. Used =
for asynchronous submission only.
*/=20
YAHOO.widget.Dialog.prototype.configOnSuccess =3D =
function(type,args,obj){};

/**
* The default handler fired when the "failure" property is changed. Used =
for asynchronous submission only.
*/=20
YAHOO.widget.Dialog.prototype.configOnFailure =3D =
function(type,args,obj){};

/**
* Executes a submission of the form based on the value of the postmethod =
property.
*/
YAHOO.widget.Dialog.prototype.doSubmit =3D function() {};

/**
* The default event handler used to focus the first field of the form =
when the Dialog is shown.
*/
YAHOO.widget.Dialog.prototype.focusFirst =3D function(type,args,obj) {
	if (args) {
		var e =3D args[1];
		if (e) {
			YAHOO.util.Event.stopEvent(e);
		}
	}

	if (this.firstFormElement) {
		this.firstFormElement.focus();
	} else {
		this.focusDefaultButton();
	}
}

/**
* Sets the focus to the last button in the button or form element in the =
Dialog
*/
YAHOO.widget.Dialog.prototype.focusLast =3D function(type,args,obj) {
	if (args) {
		var e =3D args[1];
		if (e) {
			YAHOO.util.Event.stopEvent(e);
		}
	}

	var buttons =3D this.cfg.getProperty("buttons");
	if (buttons && buttons instanceof Array) {
		this.focusLastButton();
	} else {
		if (this.lastFormElement) {
			this.lastFormElement.focus();
		}
	}
}

/**
* Sets the focus to the button that is designated as the default. By =
default, his handler is executed when the show event is fired.
*/
YAHOO.widget.Dialog.prototype.focusDefaultButton =3D function() {
	if (this.defaultHtmlButton) {
		this.defaultHtmlButton.focus();
	}
}

/**
* Blurs all the html buttons
*/
YAHOO.widget.Dialog.prototype.blurButtons =3D function() {
	var buttons =3D this.cfg.getProperty("buttons");
	if (buttons && buttons instanceof Array) {
		var html =3D buttons[0].htmlButton;
		if (html) {
			html.blur();
		}
	}
}

/**
* Sets the focus to the first button in the button list
*/
YAHOO.widget.Dialog.prototype.focusFirstButton =3D function() {
	var buttons =3D this.cfg.getProperty("buttons");
	if (buttons && buttons instanceof Array) {
		var html =3D buttons[0].htmlButton;
		if (html) {
			html.focus();
		}
	}
}

/**
* Sets the focus to the first button in the button list
*/
YAHOO.widget.Dialog.prototype.focusLastButton =3D function() {
	var buttons =3D this.cfg.getProperty("buttons");
	if (buttons && buttons instanceof Array) {
		var html =3D buttons[buttons.length-1].htmlButton;
		if (html) {
			html.focus();
		}
	}
}

// END BUILT-IN PROPERTY EVENT HANDLERS //

/**
* Built-in function hook for writing a validation function that will be =
checked for a "true" value prior to a submit. This function, as =
implemented by default, always returns true, so it should be overridden =
if validation is necessary.
*/
YAHOO.widget.Dialog.prototype.validate =3D function() {
	return true;
}

/**
* Executes a submit of the Dialog followed by a hide, if validation is =
successful.
*/
YAHOO.widget.Dialog.prototype.submit =3D function() {
	if (this.validate()) {
		this.beforeSubmitEvent.fire();
		this.doSubmit();
		this.submitEvent.fire();
		this.hide();
		return true;
	} else {
		return false;
	}
}

/**
* Executes the cancel of the Dialog followed by a hide.
*/
YAHOO.widget.Dialog.prototype.cancel =3D function() {
	this.cancelEvent.fire();
	this.hide();=09
}

/**
* Returns a JSON-compatible data structure representing the data =
currently contained in the form.
* @return {object} A JSON object reprsenting the data of the current =
form.
*/
YAHOO.widget.Dialog.prototype.getData =3D function() {
	var form =3D this.form;
	var data =3D {};

	if (form) {
		for (var i in this.form) {
			var formItem =3D form[i];
			if (formItem) {
				if (formItem.tagName) { // Got a single form item
					switch (formItem.tagName) {
						case "INPUT":
							switch (formItem.type) {
								case "checkbox":=20
									data[i] =3D formItem.checked;
									break;
								case "textbox":
								case "text":
								case "hidden":
									data[i] =3D formItem.value;
									break;
							}
							break;
						case "TEXTAREA":
							data[i] =3D formItem.value;
							break;
						case "SELECT":
							var val =3D new Array();
							for (var x=3D0;x<formItem.options.length;x++)	{
								var option =3D formItem.options[x];
								if (option.selected) {
									var selval =3D option.value;
									if (! selval || selval =3D=3D "") {
										selval =3D option.text;
									}
									val[val.length] =3D selval;
								}
							}
							data[i] =3D val;
							break;
					}
				} else if (formItem[0] && formItem[0].tagName) { // this is an array =
of form items
					switch (formItem[0].tagName) {
						case "INPUT" :
							switch (formItem[0].type) {
								case "radio":
									for (var r=3D0; r<formItem.length; r++) {
										var radio =3D formItem[r];
										if (radio.checked) {
											data[radio.name] =3D radio.value;
											break;
										}
									}
									break;
								case "checkbox":
									var cbArray =3D new Array();
									for (var c=3D0; c<formItem.length; c++) {
										var check =3D formItem[c];
										if (check.checked) {
											cbArray[cbArray.length] =3D check.value;
										}
									}
									data[formItem[0].name] =3D cbArray;
									break;
							}
					}
				}
			}
		}=09
	}
	return data;
}/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class
* SimpleDialog is a simple implementation of Dialog that can be used to =
submit a single value. Forms can be processed in 3 ways -- via an =
asynchronous Connection utility call, a simple form POST or GET, or =
manually.
* @param {string}	el	The element ID representing the SimpleDialog =
<em>OR</em>
* @param {Element}	el	The element representing the SimpleDialog
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this SimpleDialog. See =
configuration documentation for more details.
* @constructor
*/
YAHOO.widget.SimpleDialog =3D function(el, userConfig) {
	if (arguments.length > 0) {
		YAHOO.widget.SimpleDialog.superclass.constructor.call(this, el, =
userConfig);
	}
}

YAHOO.widget.SimpleDialog.prototype =3D new YAHOO.widget.Dialog();
YAHOO.widget.SimpleDialog.prototype.constructor =3D =
YAHOO.widget.SimpleDialog;

/**
* Reference to the SimpleDialog's superclass, Dialog
* @type class
* @final
*/
YAHOO.widget.SimpleDialog.superclass =3D YAHOO.widget.Dialog.prototype;

/**
* Constant for the standard network icon for a blocking action
* @type string
* @final
*/
YAHOO.widget.SimpleDialog.ICON_BLOCK =3D "nt/ic/ut/bsc/blck16_1.gif";

/**
* Constant for the standard network icon for alarm
* @type string
* @final
*/
YAHOO.widget.SimpleDialog.ICON_ALARM =3D "nt/ic/ut/bsc/alrt16_1.gif";

/**
* Constant for the standard network icon for help
* @type string
* @final
*/
YAHOO.widget.SimpleDialog.ICON_HELP  =3D "nt/ic/ut/bsc/hlp16_1.gif";

/**
* Constant for the standard network icon for info
* @type string
* @final
*/
YAHOO.widget.SimpleDialog.ICON_INFO  =3D "nt/ic/ut/bsc/info16_1.gif";

/**
* Constant for the standard network icon for warn
* @type string
* @final
*/
YAHOO.widget.SimpleDialog.ICON_WARN  =3D "nt/ic/ut/bsc/warn16_1.gif";

/**
* Constant for the standard network icon for a tip
* @type string
* @final
*/
YAHOO.widget.SimpleDialog.ICON_TIP   =3D "nt/ic/ut/bsc/tip16_1.gif";

/**
* Constant representing the default CSS class used for a SimpleDialog
* @type string
* @final
*/
YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG =3D "simple-dialog";

/**
* Initializes the class's configurable properties which can be changed =
using the SimpleDialog's Config object (cfg).
*/
YAHOO.widget.SimpleDialog.prototype.initDefaultConfig =3D function() {
	YAHOO.widget.SimpleDialog.superclass.initDefaultConfig.call(this);

	// Add dialog config properties //
	this.cfg.addProperty("icon",	{ value:"none",	handler:this.configIcon, =
suppressEvent:true } );
	this.cfg.addProperty("text",	{ value:"", handler:this.configText, =
suppressEvent:true, supercedes:["icon"] } );
}


/*
* The SimpleDialog initialization method, which is executed for =
SimpleDialog and all of its subclasses. This method is automatically =
called by the constructor, and  sets up all DOM references for =
pre-existing markup, and creates required markup if it is not already =
present.
* @param {string}	el	The element ID representing the SimpleDialog =
<em>OR</em>
* @param {Element}	el	The element representing the SimpleDialog
* @param {object}	userConfig	The configuration object literal containing =
the configuration that should be set for this SimpleDialog. See =
configuration documentation for more details.
*/
YAHOO.widget.SimpleDialog.prototype.init =3D function(el, userConfig) {
	YAHOO.widget.SimpleDialog.superclass.init.call(this, el/*, =
userConfig*/);  // Note that we don't pass the user config in here yet =
because we only want it executed once, at the lowest subclass level

	this.beforeInitEvent.fire(YAHOO.widget.SimpleDialog);

	YAHOO.util.Dom.addClass(this.element, =
YAHOO.widget.SimpleDialog.CSS_SIMPLEDIALOG);

	this.cfg.queueProperty("postmethod", "manual");

	if (userConfig) {
		this.cfg.applyConfig(userConfig, true);
	}

	this.beforeRenderEvent.subscribe(function() {
		if (! this.body) {
			this.setBody("");
		}
	}, this, true);

	this.initEvent.fire(YAHOO.widget.SimpleDialog);

}
/**
* Prepares the SimpleDialog's internal FORM object, creating one if one =
is not currently present, and adding the value hidden field.
*/
YAHOO.widget.SimpleDialog.prototype.registerForm =3D function() {
	YAHOO.widget.SimpleDialog.superclass.registerForm.call(this);
	this.form.innerHTML +=3D "<input type=3D\"hidden\" name=3D\"" + this.id =
+ "\" value=3D\"\"/>";
}

// BEGIN BUILT-IN PROPERTY EVENT HANDLERS //

/**
* Fired when the "icon" property is set.
*/
YAHOO.widget.SimpleDialog.prototype.configIcon =3D =
function(type,args,obj) {
	var icon =3D args[0];
	if (icon && icon !=3D "none") {
		var iconHTML =3D "<img src=3D\"" + this.imageRoot + icon + "\" =
class=3D\"icon\" />";
		this.body.innerHTML =3D iconHTML + this.body.innerHTML;
	}
}

/**
* Fired when the "text" property is set.
*/
YAHOO.widget.SimpleDialog.prototype.configText =3D =
function(type,args,obj) {
	var text =3D args[0];
	if (text) {
		this.setBody(text);
	}
}
// END BUILT-IN PROPERTY EVENT HANDLERS //
/**
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
* @class
* ContainerEffect encapsulates animation transitions that are executed =
when an Overlay is shown or hidden.
* @param {Overlay}	overlay		The Overlay that the animation should be =
associated with
* @param {object}	attrIn		The object literal representing the animation =
arguments to be used for the animate-in transition. The arguments for =
this literal are: attributes(object, see YAHOO.util.Anim for =
description), duration(float), and method(i.e. =
YAHOO.util.Easing.easeIn).
* @param {object}	attrOut		The object literal representing the animation =
arguments to be used for the animate-out transition. The arguments for =
this literal are: attributes(object, see YAHOO.util.Anim for =
description), duration(float), and method(i.e. =
YAHOO.util.Easing.easeIn).
* @param {Element}	targetElement	Optional. The target element that =
should be animated during the transition. Defaults to overlay.element.
* @constructor
*/
YAHOO.widget.ContainerEffect =3D function(overlay, attrIn, attrOut, =
targetElement) {
	this.overlay =3D overlay;

	this.attrIn =3D attrIn;
	this.attrOut =3D attrOut;

	this.targetElement =3D targetElement || overlay.element;

	this.beforeAnimateInEvent =3D new =
YAHOO.util.CustomEvent("beforeAnimateIn");
	this.beforeAnimateOutEvent =3D new =
YAHOO.util.CustomEvent("beforeAnimateOut");

	this.animateInCompleteEvent =3D new =
YAHOO.util.CustomEvent("animateInComplete");
	this.animateOutCompleteEvent =3D new =
YAHOO.util.CustomEvent("animateOutComplete");
}

/**
* Initializes the animation classes and events.
* @param {class}	Optional. The animation class to instantiate. Defaults =
to YAHOO.util.Anim. Other options include YAHOO.util.Motion.
*/
YAHOO.widget.ContainerEffect.prototype.init =3D function(animClass) {
	if (! animClass) {
		animClass =3D YAHOO.util.Anim;
	}
	this.animIn =3D new animClass(this.targetElement, =
this.attrIn.attributes, this.attrIn.duration, this.attrIn.method);
	this.animIn.onStart.subscribe(this.handleStartAnimateIn, this);
	this.animIn.onTween.subscribe(this.handleTweenAnimateIn, this);
	this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn, this);

	this.animOut =3D new animClass(this.targetElement, =
this.attrOut.attributes, this.attrOut.duration, this.attrOut.method);
	this.animOut.onStart.subscribe(this.handleStartAnimateOut, this);
	this.animOut.onTween.subscribe(this.handleTweenAnimateOut, this);
	this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut, this);
}

/**
* Triggers the in-animation.
*/
YAHOO.widget.ContainerEffect.prototype.animateIn =3D function() {
	this.beforeAnimateInEvent.fire();
	this.animIn.animate();
}

/**
* Triggers the out-animation.
*/
YAHOO.widget.ContainerEffect.prototype.animateOut =3D function() {
	this.beforeAnimateOutEvent.fire();
	this.animOut.animate();
}

/**
* The default onStart handler for the in-animation.
*/
YAHOO.widget.ContainerEffect.prototype.handleStartAnimateIn =3D =
function(type, args, obj) { }
/**
* The default onTween handler for the in-animation.
*/
YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateIn =3D =
function(type, args, obj) { }
/**
* The default onComplete handler for the in-animation.
*/
YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateIn =3D =
function(type, args, obj) { }

/**
* The default onStart handler for the out-animation.
*/
YAHOO.widget.ContainerEffect.prototype.handleStartAnimateOut =3D =
function(type, args, obj) { }
/**
* The default onTween handler for the out-animation.
*/
YAHOO.widget.ContainerEffect.prototype.handleTweenAnimateOut =3D =
function(type, args, obj) { }
/**
* The default onComplete handler for the out-animation.
*/
YAHOO.widget.ContainerEffect.prototype.handleCompleteAnimateOut =3D =
function(type, args, obj) { }

/**
* A pre-configured ContainerEffect instance that can be used for fading =
an overlay in and out.
* @param {Overlay}	The Overlay object to animate
* @param {float}	The duration of the animation
* @type ContainerEffect
*/
YAHOO.widget.ContainerEffect.FADE =3D function(overlay, dur) {
	var fade =3D new YAHOO.widget.ContainerEffect(overlay, { =
attributes:{opacity: {from:0, to:1}}, duration:dur, =
method:YAHOO.util.Easing.easeIn }, { attributes:{opacity: {to:0}}, =
duration:dur, method:YAHOO.util.Easing.easeOut} );

	fade.handleStartAnimateIn =3D function(type,args,obj) {
		YAHOO.util.Dom.addClass(obj.overlay.element, "hide-select");
	=09
		if (! obj.overlay.underlay) {
			obj.overlay.cfg.refireEvent("underlay");
		}

		if (obj.overlay.underlay) {
			obj.initialUnderlayOpacity =3D =
YAHOO.util.Dom.getStyle(obj.overlay.underlay, "opacity");
			obj.overlay.underlay.style.filter =3D null;
		}

		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "visible"); =

		YAHOO.util.Dom.setStyle(obj.overlay.element, "opacity", 0);
	}

	fade.handleCompleteAnimateIn =3D function(type,args,obj) {
		YAHOO.util.Dom.removeClass(obj.overlay.element, "hide-select");

		if (obj.overlay.element.style.filter) {
			obj.overlay.element.style.filter =3D null;
		}		=09
	=09
		if (obj.overlay.underlay) {
			YAHOO.util.Dom.setStyle(obj.overlay.underlay, "opacity", =
obj.initialUnderlayOpacity);
		}

		obj.overlay.cfg.refireEvent("iframe");
		obj.animateInCompleteEvent.fire();
	}

	fade.handleStartAnimateOut =3D function(type, args, obj) {
		YAHOO.util.Dom.addClass(obj.overlay.element, "hide-select");

		if (obj.overlay.underlay) {
			obj.overlay.underlay.style.filter =3D null;
		}
	}

	fade.handleCompleteAnimateOut =3D  function(type, args, obj) {=20
		YAHOO.util.Dom.removeClass(obj.overlay.element, "hide-select");
		if (obj.overlay.element.style.filter) {
			obj.overlay.element.style.filter =3D null;
		}			=09
		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "hidden");
		YAHOO.util.Dom.setStyle(obj.overlay.element, "opacity", 1);=20

		obj.overlay.cfg.refireEvent("iframe");

		obj.animateOutCompleteEvent.fire();
	};=09

	fade.init();
	return fade;
};


/**
* A pre-configured ContainerEffect instance that can be used for sliding =
an overlay in and out.
* @param {Overlay}	The Overlay object to animate
* @param {float}	The duration of the animation
* @type ContainerEffect
*/
YAHOO.widget.ContainerEffect.SLIDE =3D function(overlay, dur) {
	var x =3D overlay.cfg.getProperty("x") || =
YAHOO.util.Dom.getX(overlay.element);
	var y =3D overlay.cfg.getProperty("y") || =
YAHOO.util.Dom.getY(overlay.element);

	var clientWidth =3D YAHOO.util.Dom.getClientWidth();
	var offsetWidth =3D overlay.element.offsetWidth;

	var slide =3D new YAHOO.widget.ContainerEffect(overlay, {=20
															attributes:{ points: { to:[x, y] } },=20
															duration:dur,=20
															method:YAHOO.util.Easing.easeIn=20
														},=20
														{=20
															attributes:{ points: { to:[(clientWidth+25), y] } },
															duration:dur,=20
															method:YAHOO.util.Easing.easeOut
														}=20
												);

	slide.handleStartAnimateIn =3D function(type,args,obj) {
		obj.overlay.element.style.left =3D (-25-offsetWidth) + "px";
		obj.overlay.element.style.top  =3D y + "px";
	}
=09
	slide.handleTweenAnimateIn =3D function(type, args, obj) {


		var pos =3D YAHOO.util.Dom.getXY(obj.overlay.element);

		var currentX =3D pos[0];
		var currentY =3D pos[1];

		if (YAHOO.util.Dom.getStyle(obj.overlay.element, "visibility") =3D=3D =
"hidden" && currentX < x) {
			YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", =
"visible");
		}

		obj.overlay.cfg.setProperty("xy", [currentX,currentY], true);
		obj.overlay.cfg.refireEvent("iframe");
	}
=09
	slide.handleCompleteAnimateIn =3D function(type, args, obj) {
		obj.overlay.cfg.setProperty("xy", [x,y], true);
		obj.startX =3D x;
		obj.startY =3D y;
		obj.overlay.cfg.refireEvent("iframe");
		obj.animateInCompleteEvent.fire();
	}

	slide.handleStartAnimateOut =3D function(type, args, obj) {
		var clientWidth =3D YAHOO.util.Dom.getViewportWidth();
	=09
		var pos =3D YAHOO.util.Dom.getXY(obj.overlay.element);

		var x =3D pos[0];
		var y =3D pos[1];

		var currentTo =3D obj.animOut.attributes.points.to;
		obj.animOut.attributes.points.to =3D [(clientWidth+25), y];
	}

	slide.handleTweenAnimateOut =3D function(type, args, obj) {
		var pos =3D YAHOO.util.Dom.getXY(obj.overlay.element);

		var x =3D pos[0];
		var y =3D pos[1];

		obj.overlay.cfg.setProperty("xy", [x,y], true);
		obj.overlay.cfg.refireEvent("iframe");
	}

	slide.handleCompleteAnimateOut =3D function(type, args, obj) {=20
		YAHOO.util.Dom.setStyle(obj.overlay.element, "visibility", "hidden");		=

		var offsetWidth =3D obj.overlay.element.offsetWidth;

		obj.overlay.cfg.setProperty("xy", [x,y]);
		obj.animateOutCompleteEvent.fire();
	};=09

	slide.init(YAHOO.util.Motion);
	return slide;
}

------=_NextPart_000_003B_01C8FE25.C917E2D0
Content-Type: application/octet-stream
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/js/yui/autocomplete.js

/**
 * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
 */
/************************************************************************=
****/
/************************************************************************=
****/
/************************************************************************=
****/

/**
 * Class providing the customizable functionality of a plug-and-play =
DHTML
 * auto complete widget.  Some key features:
 * <ul>
 * <li>Navigate with up/down arrow keys and/or mouse to pick a =
selection</li>
 * <li>The drop down container can "roll down" or "fly out" via =
configurable
 * animation</li>
 * <li>UI look-and-feel customizable through CSS, including container
 * attributes, borders, position, fonts, etc</li>
 * </ul>
 *
 * requires YAHOO.util.Event Event utility
 * requires YAHOO.widget.DataSource Data source class
 * see YAHOO.util.Animation Animation utility
 * see JSON JSON library
 *
 * @constructor
 * @param {element | string} inputEl DOM element reference or string ID =
of the auto complete input field
 * @param {element | string} containerEl DOM element reference or string =
ID of the auto complete &lt;div&gt;
 *                              container
 * @param {object} oDataSource Instance of YAHOO.widget.DataSource for =
query/results
 * @param {object} oConfigs Optional object literal of config params
 */
YAHOO.widget.AutoComplete =3D =
function(inputEl,containerEl,oDataSource,oConfigs) {
    if(inputEl && containerEl && oDataSource) {
        // Validate data source
        if (oDataSource.getResults) {
            this.dataSource =3D oDataSource;
        }
        else {
            //YAHOO.log("Could not instantiate AutoComplete due to an =
invalid DataSource", "error");
            return;
        }
        // Validate input element
        if(YAHOO.util.Dom.inDocument(inputEl)) {
            if(typeof inputEl =3D=3D "string") {
                    this._sName =3D inputEl + =
YAHOO.widget.AutoComplete._nIndex;
                    this._oTextbox =3D document.getElementById(inputEl);
            }
            else {
                this._sName =3D (inputEl.id) ?
                    inputEl.id + YAHOO.widget.AutoComplete._nIndex :
                    "yac_inputEl" + YAHOO.widget.AutoComplete._nIndex;
                this._oTextbox =3D inputEl;
            }
        }
        else {
            //YAHOO.log("Could not instantiate AutoComplete due to an =
invalid input element", "error");
            return;
        }

        // Validate container element
        if(YAHOO.util.Dom.inDocument(containerEl)) {
            if(typeof containerEl =3D=3D "string") {
                    this._oContainer =3D =
document.getElementById(containerEl);
            }
            else {
                this._oContainer =3D containerEl;
            }
        }
        else {
            //YAHOO.log("Could not instantiate AutoComplete due to an =
invalid container element", "error");
            return;
        }

        // Set any config params passed in to override defaults
        if (typeof oConfigs =3D=3D "object") {
            for(var sConfig in oConfigs) {
                if (sConfig) {
                    this[sConfig] =3D oConfigs[sConfig];
                }
            }
        }

        // Initialization sequence
        var oSelf =3D this;
        var oTextbox =3D this._oTextbox;
        var oContainer =3D this._oContainer;

        =
YAHOO.util.Event.addListener(oTextbox,'keyup',oSelf._onTextboxKeyUp,oSelf=
);
        =
YAHOO.util.Event.addListener(oTextbox,'keydown',oSelf._onTextboxKeyDown,o=
Self);
        =
YAHOO.util.Event.addListener(oTextbox,'keypress',oSelf._onTextboxKeyPress=
,oSelf);
        =
YAHOO.util.Event.addListener(oTextbox,'focus',oSelf._onTextboxFocus,oSelf=
);
        =
YAHOO.util.Event.addListener(oTextbox,'blur',oSelf._onTextboxBlur,oSelf);=

        =
YAHOO.util.Event.addListener(oContainer,'mouseover',oSelf._onContainerMou=
seover,oSelf);
        =
YAHOO.util.Event.addListener(oContainer,'mouseout',oSelf._onContainerMous=
eout,oSelf);
        =
YAHOO.util.Event.addListener(oContainer,'scroll',oSelf._onContainerScroll=
,oSelf);
        if(oTextbox.form && this.allowBrowserAutocomplete) {
            =
YAHOO.util.Event.addListener(oTextbox.form,'submit',oSelf._onFormSubmit,o=
Self);
        }

        this.textboxFocusEvent =3D new =
YAHOO.util.CustomEvent("textboxFocus", this);
        this.textboxKeyEvent =3D new =
YAHOO.util.CustomEvent("textboxKey", this);
        this.dataRequestEvent =3D new =
YAHOO.util.CustomEvent("dataRequest", this);
        this.dataReturnEvent =3D new =
YAHOO.util.CustomEvent("dataReturn", this);
        this.dataErrorEvent =3D new YAHOO.util.CustomEvent("dataError", =
this);
        this.containerExpandEvent =3D new =
YAHOO.util.CustomEvent("containerExpand", this);
        this.typeAheadEvent =3D new YAHOO.util.CustomEvent("typeAhead", =
this);
        this.itemMouseOverEvent =3D new =
YAHOO.util.CustomEvent("itemMouseOver", this);
        this.itemMouseOutEvent =3D new =
YAHOO.util.CustomEvent("itemMouseOut", this);
        this.itemArrowToEvent =3D new =
YAHOO.util.CustomEvent("itemArrowTo", this);
        this.itemArrowFromEvent =3D new =
YAHOO.util.CustomEvent("itemArrowFrom", this);
        this.itemSelectEvent =3D new =
YAHOO.util.CustomEvent("itemSelect", this);
        this.selectionEnforceEvent =3D new =
YAHOO.util.CustomEvent("selectionEnforce", this);
        this.containerCollapseEvent =3D new =
YAHOO.util.CustomEvent("containerCollapse", this);
        this.textboxBlurEvent =3D new =
YAHOO.util.CustomEvent("textboxBlur", this);

        // Turn off autocomplete on textbox
        oTextbox.setAttribute("autocomplete","off");

        // Validate and initialize public configs
        this._initProps();
    }
    // Required arguments were not found
    else {
        //YAHOO.log("Could not instantiate AutoComplete due invalid =
arguments", "error");
    }
};


/************************************************************************=
***
 * Public member variables
 =
*************************************************************************=
**/
/**
 * The data source object that encapsulates the data used for auto =
completion.
 * This object should be an inherited object from =
YAHOO.widget.DataSource.
 *
 * @type object
 */
YAHOO.widget.AutoComplete.prototype.dataSource =3D null;

/**
 * Number of characters that must be entered before querying for =
results.
 * Default: 1.
 *
 * @type number
 */
YAHOO.widget.AutoComplete.prototype.minQueryLength =3D 1;

/**
 * Maximum number of results to display in auto complete container. =
Default: 10.
 *
 * @type number
 */
YAHOO.widget.AutoComplete.prototype.maxResultsDisplayed =3D 10;

/**
 * Number of seconds to delay before submitting a query request.  If a =
query
 * request is received before a previous one has completed its delay, =
the
 * previous request is cancelled and the new request is set to the =
delay.
 * Default: 0.5.
 *
 * @type number
 */
YAHOO.widget.AutoComplete.prototype.queryDelay =3D 0.5;

/**
 * Class name of a highlighted item within the auto complete container.
 * Default: "highlight".
 *
 * @type string
 */
YAHOO.widget.AutoComplete.prototype.highlightClassName =3D "highlight";

/**
 * Query delimiter. A single character separator for multiple delimited
 * selections. Multiple delimiter characteres may be defined as an array =
of
 * strings. A null value or empty string indicates that query results =
cannot
 * be delimited. This feature is not recommended if you need =
forceSelection to
 * be true. Default: null.
 *
 * @type string or array
 */
YAHOO.widget.AutoComplete.prototype.delimChar =3D null;

/**
 * Whether or not the auto complete input field should be automatically =
updated
 * with the first query result as the user types, auto-selecting the =
substring
 * that the user has not typed. Default: false.
 *
 * @type boolean
 */
YAHOO.widget.AutoComplete.prototype.typeAhead =3D false;

/**
 * Whether or not to animate the expansion/collapse of the auto complete
 * container in the horizontal direction.  Default: false.
 *
 * @type boolean
 */
YAHOO.widget.AutoComplete.prototype.animHoriz =3D false;

/**
 * Whether or not to animate the expansion/collapse of the auto complete
 * container in the vertical direction.  Default: true.
 *
 * @type boolean
 */
YAHOO.widget.AutoComplete.prototype.animVert =3D true;

/**
 * Speed of container expand/collapse animation, in seconds. Default: =
0.3.
 *
 * @type number
 */
YAHOO.widget.AutoComplete.prototype.animSpeed =3D 0.3;

/**
 * Whether or not to force the user's selection to match one of the =
query
 * results. Enabling this feature essentially transforms the auto =
complete form
 * input field into a &lt;select&gt; field. This feature is not =
recommended
 * with delimiter character(s) defined. Default: false.
 *
 * @type boolean
 */
YAHOO.widget.AutoComplete.prototype.forceSelection =3D false;

/**
 * Whether or not to allow browsers to cache user typed input, which =
effectively
 * does not set the input attribute autocomplete=3D"off". When users =
click the
 * back button after form submission, typed input can be prefilled by =
the
 * browser. Default: true.
 *
 * @type boolean
 */
YAHOO.widget.AutoComplete.prototype.allowBrowserAutocomplete =3D true;

/************************************************************************=
***
 * Public methods
 =
*************************************************************************=
**/
 /**
 * Public accessor to the unique name of the auto complete instance.
 *
 * @return {string} Unique name of the auto complete instance
 */
YAHOO.widget.AutoComplete.prototype.getName =3D function() {
    return this._sName;
};

/**
 * Public accessor to the internal array of DOM &lt;li&gt; element IDs =
that
 * display query results within the auto complete container.
 *
 * @return {array} Array of &lt;li&gt; element IDs within the auto =
complete
 *                 container
 */
YAHOO.widget.AutoComplete.prototype.getListIds =3D function() {
    return this._aListIds;
};

/**
 * Sets HTML markup for the auto complete container header. This markup =
will be
 * inserted within a &lt;div&gt; tag with a class of "ac_hd".
 *
 * @param {string} sHeader HTML markup for container header
 */
YAHOO.widget.AutoComplete.prototype.setHeader =3D function(sHeader) {
    if(sHeader) {
        this._oHeader.innerHTML =3D sHeader;
        this._oHeader.style.display =3D "block";
    }
};

/**
 * Sets HTML markup for the auto complete container footer. This markup =
will be
 * inserted within a &lt;div&gt; tag with a class of "ac_ft".
 *
 * @param {string} sFooter HTML markup for container footer
 */
YAHOO.widget.AutoComplete.prototype.setFooter =3D function(sFooter) {
    if(sFooter) {
        this._oFooter.innerHTML =3D sFooter;
        this._oFooter.style.display =3D "block";
    }
};

/**
 * Whether or not to use an iFrame to layer over Windows form elements =
in
 * IE. Set to true only when the auto complete container will be on top =
of a
 * &lt;select&gt; field in IE and thus exposed to the IE z-index bug =
(i.e.,
 * 5.5 < IE < 7). Default:false.
 *
 * @type boolean
 */
YAHOO.widget.AutoComplete.prototype.useIFrame =3D false;

/**
 * Overridable method that converts a result item object into HTML =
markup
 * for display. Return data values are accessible via the oResultItem =
object,
 * and the key return value will always be oResultItem[0]. Markup will =
be
 * displayed within &lt;li&gt; element tags in the container.
 *
 * @param {object} oResultItem Result item object representing one query =
result
 * @param {string} sQuery The current query string
 * @return {string} HTML markup of formatted result data
 */
YAHOO.widget.AutoComplete.prototype.formatResult =3D =
function(oResultItem, sQuery) {
    var sResult =3D oResultItem[0];
    if(sResult) {
        return sResult;
    }
    else {
        return "";
    }
};

/************************************************************************=
***
 * Events
 =
*************************************************************************=
**/
/**
 * Fired when the auto complete text input box receives focus. =
Subscribers
 * receive the following array:<br>
 *     -  args[0] The auto complete object instance
 */
YAHOO.widget.AutoComplete.prototype.textboxFocusEvent =3D null;

/**
 * Fired when the auto complete text input box receives key input. =
Subscribers
 * receive the following array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The keycode number
 */
YAHOO.widget.AutoComplete.prototype.textboxKeyEvent =3D null;

/**
 * Fired when the auto complete instance makes a query to the data =
source.
 * Subscribers receive the following array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The query string
 */
YAHOO.widget.AutoComplete.prototype.dataRequestEvent =3D null;

/**
 * Fired when the auto complete instance receives query results from the =
data
 * source. Subscribers receive the following array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The query string
 *     - args[2] Results array
 */
YAHOO.widget.AutoComplete.prototype.dataReturnEvent =3D null;

/**
 * Fired when the auto complete instance does not receive query results =
from the
 * data source due to an error. Subscribers receive the following =
array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The query string
 */
YAHOO.widget.AutoComplete.prototype.dataErrorEvent =3D null;

/**
 * Fired when the auto complete container is expanded. Subscribers =
receive the
 * following array:<br>
 *     - args[0] The auto complete object instance
 */
YAHOO.widget.AutoComplete.prototype.containerExpandEvent =3D null;

/**
 * Fired when the auto complete textbox has been prefilled by the =
type-ahead
 * feature. Subscribers receive the following array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The query string
 *     - args[2] The prefill string
 */
YAHOO.widget.AutoComplete.prototype.typeAheadEvent =3D null;

/**
 * Fired when result item has been moused over. Subscribers receive the =
following
 * array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The &lt;li&gt element item moused to
 */
YAHOO.widget.AutoComplete.prototype.itemMouseOverEvent =3D null;

/**
 * Fired when result item has been moused out. Subscribers receive the
 * following array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The &lt;li&gt; element item moused from
 */
YAHOO.widget.AutoComplete.prototype.itemMouseOutEvent =3D null;

/**
 * Fired when result item has been arrowed to. Subscribers receive the =
following
 * array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The &lt;li&gt; element item arrowed to
 */
YAHOO.widget.AutoComplete.prototype.itemArrowToEvent =3D null;

/**
 * Fired when result item has been arrowed away from. Subscribers =
receive the
 * following array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The &lt;li&gt; element item arrowed from
 */
YAHOO.widget.AutoComplete.prototype.itemArrowFromEvent =3D null;

/**
 * Fired when an item is selected via mouse click, ENTER key, or TAB =
key.
 * Subscribers receive the following array:<br>
 *     - args[0] The auto complete object instance
 *     - args[1] The selected &lt;li&gt; element item
 */
YAHOO.widget.AutoComplete.prototype.itemSelectEvent =3D null;

/**
 * Fired if forceSelection is enabled and the user's input has been =
cleared
 * because it did not match one of the returned query results. =
Subscribers
 * receive the following array:<br>
 *     - args[0] The auto complete object instance
 */
YAHOO.widget.AutoComplete.prototype.selectionEnforceEvent =3D null;

/**
 * Fired when the auto complete container is collapsed. Subscribers =
receive the
 * following array:<br>
 *     - args[0] The auto complete object instance
 */
YAHOO.widget.AutoComplete.prototype.containerCollapseEvent =3D null;

/**
 * Fired when the auto complete text input box loses focus. Subscribers =
receive
 * an array of the following array:<br>
 *     - args[0] The auto complete object instance
 */
YAHOO.widget.AutoComplete.prototype.textboxBlurEvent =3D null;

/************************************************************************=
***
 * Private member variables
 =
*************************************************************************=
**/
/**
 * Internal class variable to index multiple auto complete instances.
 *
 * @type number
 * @private
 */
YAHOO.widget.AutoComplete._nIndex =3D 0;

/**
 * Name of auto complete instance.
 *
 * @type string
 * @private
 */
YAHOO.widget.AutoComplete.prototype._sName =3D null;

/**
 * Text input box DOM element.
 *
 * @type object
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oTextbox =3D null;

/**
 * Whether or not the textbox is currently in focus. If query results =
come back
 * but the user has already moved on, do not proceed with auto complete =
behavior.
 *
 * @type boolean
 * @private
 */
YAHOO.widget.AutoComplete.prototype._bFocused =3D true;

/**
 * Animation instance for container expand/collapse.
 *
 * @type boolean
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oAnim =3D null;

/**
 * Container DOM element.
 *
 * @type object
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oContainer =3D null;

/**
 * Whether or not the auto complete container is currently open.
 *
 * @type boolean
 * @private
 */
YAHOO.widget.AutoComplete.prototype._bContainerOpen =3D false;

/**
 * Whether or not the mouse is currently over the auto complete
 * container. This is necessary in order to prevent clicks on container =
items
 * from being text input box blur events.
 *
 * @type boolean
 * @private
 */
YAHOO.widget.AutoComplete.prototype._bOverContainer =3D false;

/**
 * iFrame DOM element. Only used in IE for iframe trick.
 *
 * @type object
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oIFrame =3D null;

/**
 * Content DOM element. Only used in IE for iFrame trick.
 *
 * @type object
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oContent =3D null;

/**
 * Container header DOM element.
 *
 * @type object
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oHeader =3D null;

/**
 * Container footer DOM element.
 *
 * @type object
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oFooter =3D null;

/**
 * Array of &lt;li&gt; elements IDs used to display query results within =
the
 * auto complete container.
 *
 * @type array
 * @private
 */
YAHOO.widget.AutoComplete.prototype._aListIds =3D null;

/**
 * Number of &lt;li&gt; elements currently displayed in auto complete =
container.
 *
 * @type number
 * @private
 */
YAHOO.widget.AutoComplete.prototype._nDisplayedItems =3D 0;

/**
 * Current query string
 *
 * @type string
 * @private
 */
YAHOO.widget.AutoComplete.prototype._sCurQuery =3D null;

/**
 * Past queries this session (for saving delimited queries).
 *
 * @type string
 * @private
 */
YAHOO.widget.AutoComplete.prototype._sSavedQuery =3D null;

/**
 * Pointer to the currently highlighted &lt;li&gt; element in the =
container.
 *
 * @type object
 * @private
 */
YAHOO.widget.AutoComplete.prototype._oCurItem =3D null;

/**
 * Whether or not an item has been selected since the container was =
populated
 * with results. Reset to false by _populateList, and set to true when =
item is
 * selected.
 *
 * @type boolean
 * @private
 */
YAHOO.widget.AutoComplete.prototype._bItemSelected =3D false;

/**
 * Key code of the last key pressed in textbox.
 *
 * @type number
 * @private
 */
YAHOO.widget.AutoComplete.prototype._nKeyCode =3D null;

/**
 * Delay timeout ID.
 *
 * @type number
 * @private
 */
YAHOO.widget.AutoComplete.prototype._nDelayID =3D -1;

/************************************************************************=
***
 * Private methods
 =
*************************************************************************=
**/
/**
 * Updates and validates latest public config properties.
 *
 * @private
 */
YAHOO.widget.AutoComplete.prototype._initProps =3D function() {
    // Correct any invalid values
    var minQueryLength =3D this.minQueryLength;
    if(isNaN(minQueryLength) || (minQueryLength < 1)) {
        minQueryLength =3D 1;
    }
    var maxResultsDisplayed =3D this.maxResultsDisplayed;
    if(isNaN(this.maxResultsDisplayed) || (this.maxResultsDisplayed < =
1)) {
        this.maxResultsDisplayed =3D 10;
    }
    var queryDelay =3D this.queryDelay;
    if(isNaN(this.queryDelay) || (this.queryDelay < 0)) {
        this.queryDelay =3D 0.5;
    }
    var aDelimChar =3D (this.delimChar) ? this.delimChar : null;
    if(aDelimChar) {
        if(typeof aDelimChar =3D=3D "string") {
            this.delimChar =3D [aDelimChar];
        }
        else if(aDelimChar.constructor !=3D Array) {
            this.delimChar =3D null;
        }
    }
    var animSpeed =3D this.animSpeed;
    if(this.animHoriz || this.animVert) {
        if(isNaN(animSpeed) || (animSpeed < 0)) {
            animSpeed =3D 0.3;
        }

        if(!this._oAnim && YAHOO.util.Anim) {
            this._oAnim =3D new YAHOO.util.Anim(this._oContainer, {}, =
animSpeed);
        }
        else if(this._oAnim) {
            this._oAnim.duration =3D animSpeed;
        }
    }
    if(this.forceSelection && this.delimChar) {
        //YAHOO.log(oSelf.getName() + " has enabled force selection with =
delimiter character(s) defined.","warn");
    }
    if (!this._aListIds) {
        this._aListIds =3D [];
    }

    if(!this._aListIds || (this.maxResultsDisplayed !=3D =
this._aListIds.length)) {
        this._initContainer();
    }
};

/**
 * Initializes the auto complete container
 *
 * @private
 */
YAHOO.widget.AutoComplete.prototype._initContainer =3D function() {
    // Create the max number of <li> elements, but hide them all
    this._aListIds =3D [];
    var aItemsMarkup =3D [];
    var sName =3D this._sName;
    var sPrefix =3D sName + "item";
    var sHeaderID =3D sName + "header";
    var sFooterID =3D sName + "footer";

    for(var i =3D this.maxResultsDisplayed-1; i >=3D 0 ; i--) {
        var sItemID =3D sPrefix + i;
        this._aListIds[i] =3D sItemID;
        aItemsMarkup.unshift("<li id=3D'" + sItemID + "'></li>\n");
    }

    var sList =3D "<ul id=3D'" + sName + "list'>" +
        aItemsMarkup.join("") + "</ul>";

    // Need this iFrame trick to make sure the container appears over =
form
    // elements to workaround IE z-index bug
    var sContent =3D (this.useIFrame) ?
            ["<div id=3D'",
            sName,
            "content'>",
            "<div id=3D'",
            sHeaderID,
            "' class=3D'ac_hd'></div><div class=3D'ac_bd'>",
            sList,
            "</div><div id=3D'",
            sFooterID,
            "' class=3D'ac_ft'></div>",
            "</div><iframe id=3D'",
            sName,
            "iframe' src=3D'about:blank' frameborder=3D'0' =
scrolling=3D'no'>",
            "</iframe>"] :

            ["<div id=3D'",
            sHeaderID,
            "' class=3D'ac_hd'></div><div class=3D'ac_bd'>",
            sList,
            "</div><div id=3D'",
            sFooterID,
            "' class=3D'ac_ft'></div>"];

    sContent =3D sContent.join("");
    this._oContainer.innerHTML =3D sContent;

    this._oHeader =3D document.getElementById(sHeaderID);
    this._oFooter =3D document.getElementById(sFooterID);

    if (this.useIFrame) {
        this._oContent =3D document.getElementById(sName + "content");
        this._oIFrame =3D document.getElementById(sName + "iframe");
        this._oContent.style.position =3D "relative";
        this._oIFrame.style.position =3D "relative";
        this._oContent.style.zIndex =3D 9050;
    }

    this._oContainer.style.display =3D "none";
    this._oHeader.style.display =3D "none";
    this._oFooter.style.display =3D "none";

    this._initItems();
};

/**
 * Initializes up to YAHOO.widget.AutoComplete#maxResultsDisplayed =
&lt;li&gt;
 * elements in the container.
 *
 * @private
 */
YAHOO.widget.AutoComplete.prototype._initItems =3D function() {
    // set properties & events for each item now that they are in the =
DOM
    for(var i =3D this.maxResultsDisplayed-1; i >=3D 0 ; i--) {
        var oItem =3D document.getElementById(this._aListIds[i]);
        this._initItem(oItem, i);
    }
};

/**
 * Initializes each &lt;li&gt; element in the container .
 *
 * @param {object} oItem The &lt;li&gt; DOM element
 * @param {number} onItemIndex The index of the element
 * @private
 */
YAHOO.widget.AutoComplete.prototype._initItem =3D function(oItem, =
nItemIndex) {
    var oSelf =3D this;
    oItem.style.display =3D "none";
    oItem._nItemIndex =3D nItemIndex;
    oItem.mouseover =3D oItem.mouseout =3D oItem.onclick =3D null;
    =
YAHOO.util.Event.addListener(oItem,'mouseover',oSelf._onItemMouseover,oSe=
lf);
    =
YAHOO.util.Event.addListener(oItem,'mouseout',oSelf._onItemMouseout,oSelf=
);
    =
YAHOO.util.Event.addListener(oItem,'click',oSelf._onItemMouseclick,oSelf)=
;
};

/**
 * Handles &lt;li&gt; element mouseover events in the container.
 *
 * @param {event} v The mouseover event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onItemMouseover =3D =
function(v,oSelf) {
    oSelf._toggleHighlight(this,'mouseover');
    oSelf.itemMouseOverEvent.fire(oSelf, this);
    //YAHOO.log(oSelf.getName() + " moused over " + this.id);

};

/**
 * Handles &lt;li&gt; element mouseout events in the container.
 *
 * @param {event} v The mouseout event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onItemMouseout =3D =
function(v,oSelf) {
    oSelf._toggleHighlight(this,'mouseout');
    oSelf.itemMouseOutEvent.fire(oSelf, this);
    //YAHOO.log(oSelf.getName() + " moused out from " + this.id);
};

/**
 * Handles &lt;li&gt; element click events in the container.
 *
 * @param {event} v The click event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onItemMouseclick =3D =
function(v,oSelf) {
    // In case item has not been moused over
    oSelf._toggleHighlight(this,'mouseover');
    oSelf._selectItem(this);
};

/**
 * Handles container mouseover events.
 *
 * @param {event} v The mouseover event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onContainerMouseover =3D =
function(v,oSelf) {
    oSelf._bOverContainer =3D true;
};

/**
 * Handles container mouseout events.
 *
 * @param {event} v The mouseout event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onContainerMouseout =3D =
function(v,oSelf) {
    oSelf._bOverContainer =3D false;
    // If container is still active
    if(oSelf._oCurItem) {
        oSelf._toggleHighlight(oSelf._oCurItem,'mouseover');
    }
};

/**
 * Handles container scroll events.
 *
 * @param {event} v The scroll event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onContainerScroll =3D =
function(v,oSelf) {
    oSelf._oTextbox.focus();
};


/**
 * Handles textbox keydown events of functional keys, mainly for UI =
behavior.
 *
 * @param {event} v The keydown event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onTextboxKeyDown =3D =
function(v,oSelf) {
    var nKeyCode =3D v.keyCode;

    switch (nKeyCode) {
        case 9: // tab
            if(oSelf.delimChar && (oSelf._nKeyCode !=3D nKeyCode)) {
                if(oSelf._bContainerOpen) {
                    YAHOO.util.Event.stopEvent(v);
                }
            }
            // select an item or clear out
            if(oSelf._oCurItem) {
                oSelf._selectItem(oSelf._oCurItem);
            }
            else {
                oSelf._clearList();
            }
            break;
        case 13: // enter
            if(oSelf._nKeyCode !=3D nKeyCode) {
                if(oSelf._bContainerOpen) {
                    YAHOO.util.Event.stopEvent(v);
                }
            }
            if(oSelf._oCurItem) {
                oSelf._selectItem(oSelf._oCurItem);
            }
            else {
                oSelf._clearList();
            }
            break;
        case 27: // esc
            oSelf._clearList();
            return;
        case 39: // right
            oSelf._jumpSelection();
            break;
        case 38: // up
            YAHOO.util.Event.stopEvent(v);
            oSelf._moveSelection(nKeyCode);
            break;
        case 40: // down
            YAHOO.util.Event.stopEvent(v);
            oSelf._moveSelection(nKeyCode);
            break;
        default:
            break;
    }
};

/**
 * Handles textbox keypress events, mainly for FF.
 *
 * @param {event} v The keyup event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onTextboxKeyPress =3D =
function(v,oSelf) {
    var nKeyCode =3D v.keyCode;

    // for FF < 1.0
    switch (nKeyCode) {
    case 9: // tab
    case 13: // enter
        if(oSelf.delimChar && (oSelf._nKeyCode !=3D nKeyCode)) {
            if(oSelf._bContainerOpen) {
                YAHOO.util.Event.stopEvent(v);
            }
        }
        break;
    case 38: // up
    case 40: // down
        YAHOO.util.Event.stopEvent(v);
        break;
    default:
        break;
    }
};

/**
 * Handles textbox keyup events that trigger queries.
 *
 * @param {event} v The keyup event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onTextboxKeyUp =3D =
function(v,oSelf) {
    // Check to see if any of the public properties have been updated
    oSelf._initProps();

    var nKeyCode =3D v.keyCode;
    oSelf._nKeyCode =3D nKeyCode;
    var sChar =3D String.fromCharCode(nKeyCode);
    var sText =3D this.value; //string in textbox

    // Filter out chars that don't trigger queries
    if (oSelf._isIgnoreKey(nKeyCode) || (sText.toLowerCase() =3D=3D =
this._sCurQuery)) {
        return;
    }
    else {
        oSelf.textboxKeyEvent.fire(oSelf, nKeyCode);
        //YAHOO.log(oSelf.getName() + " received key input " + =
nKeyCode);
    }

    // Set timeout on the request
    if (oSelf.queryDelay > 0) {
        var nDelayID =3D
            =
setTimeout(function(){oSelf._sendQuery(sText);},(oSelf.queryDelay * =
1000));

        if (oSelf._nDelayID !=3D -1) {
            clearTimeout(oSelf._nDelayID);
        }

        oSelf._nDelayID =3D nDelayID;
    }
    else {
        // No delay so send request immediately
        oSelf._sendQuery(sText);
    }
};

/**
 * Whether or not key is functional or should be ignored. Note that the =
right
 * arrow key is NOT an ignored key since it triggers queries for certain =
intl
 * charsets.
 *
 * @param {number} nKeycode Code of key pressed
 * @return {boolean} Whether or not to be ignore key
 * @private
 */
YAHOO.widget.AutoComplete.prototype._isIgnoreKey =3D function(nKeyCode) =
{
    if(this.typeAhead) { // fewer query triggers when type ahead is on
        if((nKeyCode =3D=3D 8) || // backspace
        (nKeyCode =3D=3D 39) || // right
        (nKeyCode =3D=3D 46)) { // delete
            return true;
        }
    }
    if ((nKeyCode =3D=3D 9) || (nKeyCode =3D=3D 13)  || // tab, enter
            (nKeyCode =3D=3D 16) || (nKeyCode =3D=3D 17) || // shift, =
ctl
            (nKeyCode >=3D 18 && nKeyCode <=3D 20) || // =
alt,pause/break,caps lock
            (nKeyCode =3D=3D 27) || // esc
            (nKeyCode >=3D 33 && nKeyCode <=3D 35) || // page up,page =
down,end
            (nKeyCode >=3D 36 && nKeyCode <=3D 38) || // home,left,up
            (nKeyCode =3D=3D 40) || // down
            (nKeyCode >=3D 44 && nKeyCode <=3D 45)) { // print =
screen,insert
        return true;
    }
    return false;
};

/**
 * Handles text input box receiving focus.
 *
 * @param {event} v The focus event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onTextboxFocus =3D function =
(v,oSelf) {
    oSelf._oTextbox.setAttribute("autocomplete","off");
    oSelf._bFocused =3D true;
    oSelf.textboxFocusEvent.fire(oSelf);
    //YAHOO.log(oSelf.getName() + " textbox focused");
};

/**
 * Handles text input box losing focus.
 *
 * @param {event} v The focus event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onTextboxBlur =3D function =
(v,oSelf) {
    // Don't treat as a blur if it was a selection via mouse click
    if(!oSelf._bOverContainer || (oSelf._nKeyCode =3D=3D 9)) {
        // Current query needs to be validated
        if(oSelf.forceSelection && !oSelf._bItemSelected) {
            if(!oSelf._bContainerOpen || (oSelf._bContainerOpen && =
!oSelf._textMatchesOption())) {
                oSelf._clearSelection();
            }
        }

        if(oSelf._bContainerOpen) {
            oSelf._clearList();
        }
        oSelf._bFocused =3D false;
        oSelf.textboxBlurEvent.fire(oSelf);
        //YAHOO.log(oSelf.getName() + " textbox blurred");
    }
};

/**
 * Handles form submission event.
 *
 * @param {event} v The submit event
 * @param {object} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._onFormSubmit =3D function(v,oSelf) =
{
    oSelf._oTextbox.setAttribute("autocomplete","on");
};

/**
 * Makes query request to the data source.
 *
 * @param {string} sQuery Query string.
 * @private
 */
YAHOO.widget.AutoComplete.prototype._sendQuery =3D function(sQuery) {
    // Delimiter has been enabled
    var aDelimChar =3D (this.delimChar) ? this.delimChar : null;
    if(aDelimChar) {
        // Loop through all possible delimiters and find the latest one
        // A " " may be a false positive if they are defined as =
delimiters AND
        // are used to separate delimited queries
        var nDelimIndex =3D -1;
        for(var i =3D aDelimChar.length-1; i >=3D 0; i--) {
            var nNewIndex =3D sQuery.lastIndexOf(aDelimChar[i]);
            if(nNewIndex > nDelimIndex) {
                nDelimIndex =3D nNewIndex;
            }
        }
        // If we think the last delimiter is a space (" "), make sure it =
is NOT
        // a false positive by also checking the char directly before it
        if(aDelimChar[i] =3D=3D " ") {
            for (var j =3D aDelimChar.length-1; j >=3D 0; j--) {
                if(sQuery[nDelimIndex - 1] =3D=3D aDelimChar[j]) {
                    nDelimIndex--;
                    break;
                }
            }
        }
        // A delimiter has been found so extract the latest query
        if (nDelimIndex > -1) {
            var nQueryStart =3D nDelimIndex + 1;
            // Trim any white space from the beginning...
            while(sQuery.charAt(nQueryStart) =3D=3D " ") {
                nQueryStart +=3D 1;
            }
            // ...and save the rest of the string for later
            this._sSavedQuery =3D sQuery.substring(0,nQueryStart);
            // Here is the query itself
            sQuery =3D sQuery.substr(nQueryStart);
        }
        else if(sQuery.indexOf(this._sSavedQuery) < 0){
            this._sSavedQuery =3D null;
        }
    }

    // Don't search queries that are too short
    if (sQuery.length < this.minQueryLength) {
        if (this._nDelayID !=3D -1) {
            clearTimeout(this._nDelayID);
        }
        this._clearList();
        return;
    }

    sQuery =3D encodeURI(sQuery);
    this._nDelayID =3D -1;    // Reset timeout ID because request has =
been made
    this.dataRequestEvent.fire(this, sQuery);
    //YAHOO.log(this.getName() + " requested data for query \"" + sQuery =
+ "\"");
    this.dataSource.getResults(this._populateList, sQuery, this);
};

/**
 * Hides all visuals related to the array of &lt;li&gt; elements in the =
container.
 *
 * @private
 */
YAHOO.widget.AutoComplete.prototype._clearList =3D function() {
    this._oContainer.scrollTop =3D 0;
    var aItems =3D this._aListIds;

    for(var i =3D aItems.length-1; i >=3D 0 ; i--) {
        document.getElementById(aItems[i]).style.display =3D "none";
    }

    if (this._oCurItem) {
        this._toggleHighlight(this._oCurItem,'mouseout');
    }

    this._oCurItem =3D null;
    this._nDisplayedItems =3D 0;
    this._sCurQuery =3D null;
    this._toggleContainer(false);
};

/**
 * Populates the array of &lt;li&gt; elements in the container with =
query
 * results. This method is passed to YAHOO.widget.DataSource#getResults =
as a
 * callback function so results from the datasource are returned to the
 * auto complete instance.
 *
 * @param {string} sQuery The query string
 * @param {object} aResults An array of query result objects from the =
data source
 * @param {string} oSelf The auto complete instance
 * @private
 */
YAHOO.widget.AutoComplete.prototype._populateList =3D function(sQuery, =
aResults, oSelf) {
    if(aResults =3D=3D=3D null) {
        oSelf.dataErrorEvent.fire(oSelf, sQuery);
        //YAHOO.log(oSelf.getName() + " data error for query \"" + =
sQuery + "\"");
    }
    else {
        oSelf.dataReturnEvent.fire(oSelf, sQuery, aResults);
        //YAHOO.log(oSelf.getName() + " received " + aResults.length + " =
results for query \"" + sQuery + "\"");
    }

    if (!oSelf._bFocused || !aResults) {
        return;
    }

    var isOpera =3D (navigator.userAgent.toLowerCase().indexOf("opera") =
!=3D -1);
    oSelf._oContainer.style.width =3D (!isOpera) ? null : "";
    oSelf._oContainer.style.height =3D (!isOpera) ? null : "";

    var sCurQuery =3D decodeURI(sQuery);
    oSelf._sCurQuery =3D sCurQuery;
    var aItems =3D oSelf._aListIds;
    oSelf._bItemSelected =3D false;

    var nItems =3D Math.min(aResults.length,oSelf.maxResultsDisplayed);
    oSelf._nDisplayedItems =3D nItems;
    if (nItems > 0) {
        // Fill items with data
        for(var i =3D nItems-1; i >=3D 0 ; i--) {
            var oItemi =3D document.getElementById(aItems[i]);
            var oResultItemi =3D aResults[i];
            oItemi.innerHTML =3D oSelf.formatResult(oResultItemi, =
sCurQuery);
            oItemi.style.display =3D "list-item";
            oItemi._sResultKey =3D oResultItemi[0];
            oItemi._oResultData =3D oResultItemi;

        }

        // Empty out remaining items if any
        for(var j =3D aItems.length-1; j >=3D nItems ; j--) {
            var oItemj =3D document.getElementById(aItems[j]);
            oItemj.innerHTML =3D null;
            oItemj.style.display =3D "none";
            oItemj._sResultKey =3D null;
            oItemj._oResultData =3D null;
        }

        // Select first item and show UI
        var oFirstItem =3D document.getElementById(aItems[0]);
        oSelf._toggleHighlight(oFirstItem,'mouseover');
        oSelf._toggleContainer(true);
        oSelf.itemArrowToEvent.fire(oSelf, oFirstItem);
        //YAHOO.log(oSelf.getName() + " arrowed to item " + =
oFirstItem.id);
        oSelf._typeAhead(oFirstItem,sQuery);
        oSelf._oCurItem =3D oFirstItem;
    }
    else {
        oSelf._clearList();
    }
};

/**
 * When YAHOO.widget.AutoComplete#bForceSelection is true and the user =
attempts
 * leave the text input box without selecting an item from the query =
results,
 * the user selection is cleared.
 *
 * @private
 */
YAHOO.widget.AutoComplete.prototype._clearSelection =3D function() {
    var sValue =3D this._oTextbox.value;
    var sChar =3D (this.delimChar) ? this.delimChar[0] : null;
    var nIndex =3D (sChar) ? sValue.lastIndexOf(sChar, sValue.length-2) =
: -1;
    if(nIndex > -1) {
        this._oTextbox.value =3D sValue.substring(0,nIndex);
    }
    else {
         this._oTextbox.value =3D "";
    }
    this._sSavedQuery =3D this._oTextbox.value;

    // Fire custom event
    this.selectionEnforceEvent.fire(this);
    //YAHOO.log(this.getName() + " cleared an invalid selection");
};

/**
 * Whether or not user-typed value in the text input box matches any of =
the
 * query results.
 *
 * @private
 */
YAHOO.widget.AutoComplete.prototype._textMatchesOption =3D function() {
    var foundMatch =3D false;

    for(var i =3D this._nDisplayedItems-1; i >=3D 0 ; i--) {
        var oItem =3D document.getElementById(this._aListIds[i]);
        var sMatch =3D oItem._sResultKey.toLowerCase();
        if (sMatch =3D=3D this._sCurQuery.toLowerCase()) {
            foundMatch =3D true;
            break;
        }
    }
    return(foundMatch);
};

/**
 * Updates in the text input box with the first query result as the user =
types,
 * selecting the substring that the user has not typed.
 *
 * @param {object} oItem The &lt;li&gt; element item whose data =
populates the input field
 * @param {string} sQuery Query string
 * @private
 */
YAHOO.widget.AutoComplete.prototype._typeAhead =3D function(oItem, =
sQuery) {
    var oTextbox =3D this._oTextbox;
    var sValue =3D this._oTextbox.value; // any saved queries plus what =
user has typed

    // Don't update with type-ahead if turned off
    if (!this.typeAhead) {
        return;
    }

    // Don't update with type-ahead if text selection is not supported
    if(!oTextbox.setSelectionRange && !oTextbox.createTextRange) {
        return;
    }

    // Select the portion of text that the user has not typed
    var nStart =3D sValue.length;
    this._updateValue(oItem);
    var nEnd =3D oTextbox.value.length;
    this._selectText(oTextbox,nStart,nEnd);
    var sPrefill =3D oTextbox.value.substr(nStart,nEnd);
    this.typeAheadEvent.fire(this,sQuery,sPrefill);
    //YAHOO.log(this.getName() + " prefilled \"" + sPrefill + "\" for =
query " + sQuery + "\"");
};

/**
 * Selects text in a text input box.
 *
 * @param {object} oTextbox Text input box element in which to select =
text
 * @param {number} nStart Starting index of text string to select
 * @param {number} nEnd Ending index of text selection
 * @private
 */
YAHOO.widget.AutoComplete.prototype._selectText =3D function(oTextbox, =
nStart, nEnd) {
    if (oTextbox.setSelectionRange) { // For Mozilla
        oTextbox.setSelectionRange(nStart,nEnd);
    }
    else if (oTextbox.createTextRange) { // For IE
        var oTextRange =3D oTextbox.createTextRange();
        oTextRange.moveStart("character", nStart);
        oTextRange.moveEnd("character", nEnd-oTextbox.value.length);
        oTextRange.select();
    }
    else {
        oTextbox.select();
    }
};

/**
 * Animates expansion or collapse of the container.
 *
 * @param {boolean} bShow True if container should be expanded, false if
 *                        container should be collapsed
 * @private
 */
YAHOO.widget.AutoComplete.prototype._toggleContainer =3D function(bShow) =
{
    var oContainer =3D this._oContainer;
    // Don't animate if it's already closed && !bShow
    if (!bShow && !this._bContainerOpen) {
        oContainer.style.display =3D "none";
        return;
    }

    var oContent =3D this._oContent;
    var oIFrame =3D this._oIFrame;
    // Make the iframe used in the ie trick the same dimension as the =
content
    if (bShow && oContent && oIFrame) {
        var sDisplay =3D oContainer.style.display;
        oContainer.style.display =3D "block";
        oIFrame.style.width =3D oContent.offsetWidth+"px";
        oIFrame.style.height =3D oContent.offsetHeight+"px";
        oIFrame.style.marginTop =3D "-"+oContent.offsetHeight+"px";
        oContainer.style.display =3D sDisplay;
    }

    // If animation is enabled...
    var oAnim =3D this._oAnim;
    if (oAnim && oAnim.getEl() && (this.animHoriz || this.animVert)) {
        if(oAnim.isAnimated()) {
            oAnim.stop();
        }

        // Clone container to grab current size offscreen
        var oClone =3D oContainer.cloneNode(true);
        oContainer.parentNode.appendChild(oClone);
        oClone.style.top =3D "-9000px";
        oClone.style.display =3D "block";

        // Current size of the container is the EXPANDED size
        var wExp =3D oClone.offsetWidth;
        var hExp =3D oClone.offsetHeight;

        // Calculate COLLAPSED sizes based on horiz and vert anim
        var wColl =3D (this.animHoriz) ? 0 : wExp;
        var hColl =3D (this.animVert) ? 0 : hExp;

        // Set animation sizes
        oAnim.attributes =3D (bShow) ?
            {width: { to: wExp }, height: { to: hExp }} :
            {width: { to: wColl}, height: { to: hColl }};

        // If opening anew, set to a collapsed size...
        if(bShow && !this._bContainerOpen) {
            oContainer.style.width =3D wColl+"px";
            oContainer.style.height =3D hColl+"px";
        }
        // Else, set it to its last known size.
        else {
            oContainer.style.width =3D wExp+"px";
            oContainer.style.height =3D hExp+"px";
        }

        oContainer.parentNode.removeChild(oClone);
        oClone =3D null;

    	var oSelf =3D this;
    	var onAnimComplete =3D function() {
            // Finish the collapse
    		if(!bShow) {
                oContainer.style.display =3D "none";
    		}
    		oAnim.onComplete.unsubscribeAll();

            // Call event on expand/collapse (overridden by client)
            if(bShow) {
                oSelf.containerExpandEvent.fire(oSelf);
                //YAHOO.log(oSelf.getName() + " container expanded");
            }
            else {
                oSelf.containerCollapseEvent.fire(oSelf);
                //YAHOO.log(oSelf.getName() + " container collapsed");
            }
     	};

        // Display container and animate it
        oContainer.style.display =3D "block";
        oAnim.onComplete.subscribe(onAnimComplete);
        oAnim.animate();
        this._bContainerOpen =3D bShow;
    }
    // Else don't animate, just show or hide
    else {
        this._bContainerOpen =3D bShow;
        oContainer.style.display =3D (bShow) ? "block" : "none";

        // Call event on expand/collapse (overriden by client)
        if(bShow) {
            this.containerExpandEvent.fire(this);
            //YAHOO.log(this.getName() + " container expanded");
        }
        else {
            this.containerCollapseEvent.fire(this);
            //YAHOO.log(this.getName() + " container collapsed");
        }
    }
};

/**
 * Toggles the highlight on or off for an item in the container, and =
also cleans
 * up highlighting of any previous item.
 *
 * @param {object} oNewItem New The &lt;li&gt; element item to receive =
highlight
 *                              behavior
 * @param {string} sType "mouseover" will toggle highlight on, and =
"mouseout"
 *                       will toggle highlight off.
 * @private
 */
YAHOO.widget.AutoComplete.prototype._toggleHighlight =3D =
function(oNewItem, sType) {
    oNewItem.className =3D =
oNewItem.className.replace(this.highlightClassName,"");

    if(this._oCurItem) {
        this._oCurItem.className =3D
            =
this._oCurItem.className.replace(this.highlightClassName,"");
    }

    if(sType =3D=3D 'mouseover') {
        oNewItem.className +=3D " " + this.highlightClassName;
        this._oCurItem =3D oNewItem;
    }
};

/**
 * Updates the text input box value with selected query result. If a =
delimiter
 * has been defined, then the value gets appended with the delimiter.
 *
 * @param {object} oItem The &lt;li&gt; element item with which to =
update the value
 * @private
 */
YAHOO.widget.AutoComplete.prototype._updateValue =3D function(oItem) {
    var oTextbox =3D this._oTextbox;
    var sDelimChar =3D (this.delimChar) ? this.delimChar[0] : null;
    var sSavedQuery =3D this._sSavedQuery;
    var sResultKey =3D oItem._sResultKey;
    oTextbox.focus();

    // First clear text field
    oTextbox.value =3D "";
    // Grab data to put into text field
    if(sDelimChar) {
        if(sSavedQuery) {
            oTextbox.value =3D sSavedQuery;
        }
        oTextbox.value +=3D sResultKey + sDelimChar;
        if(sDelimChar !=3D " ") {
            oTextbox.value +=3D " ";
        }
    }
    else { oTextbox.value =3D sResultKey; }

    // scroll to bottom of textarea if necessary
    if(oTextbox.type =3D=3D "textarea") {
        oTextbox.scrollTop =3D oTextbox.scrollHeight;
    }
    // move cursor to end
    var end =3D oTextbox.value.length;
    this._selectText(oTextbox,end,end);

    this._oCurItem =3D oItem;
};

/**
 * Selects a result item from the container
 *
 * @param {object} oItem The selected &lt;li&gt; element item
 * @private
 */
YAHOO.widget.AutoComplete.prototype._selectItem =3D function(oItem) {
    this._bItemSelected =3D true;
    this._updateValue(oItem);
    this.itemSelectEvent.fire(this, oItem);
    //YAHOO.log(this.getName() + " selected item " + oItem.id);
    this._clearList();
};

/**
 * For values updated by type-ahead, the right arrow key jumps to the =
end
 * of the textbox, otherwise the container is closed.
 *
 * @private
 */
YAHOO.widget.AutoComplete.prototype._jumpSelection =3D function() {
    if(!this.typeAhead) {
        return;
    }
    else {
        this._clearList();
    }
};

/**
 * Triggered by up and down arrow keys, changes the current highlighted
 * &lt;li&gt; element item. Scrolls container if necessary.
 *
 * @param {number} nKeyCode Code of key pressed
 * @private
 */
YAHOO.widget.AutoComplete.prototype._moveSelection =3D =
function(nKeyCode) {
    if(this._bContainerOpen) {
        // determine current item's id number
        var oCurItem =3D this._oCurItem;
        var nCurItemIndex =3D -1;

        if (oCurItem) {
            nCurItemIndex =3D oCurItem._nItemIndex;
        }

        var nNewItemIndex =3D (nKeyCode =3D=3D 40) ?
                (nCurItemIndex + 1) : (nCurItemIndex - 1);

        // out of bounds
        if (nNewItemIndex < -2 || nNewItemIndex >=3D =
this._nDisplayedItems) {
            return;
        }

        if (oCurItem) {
            // Unhighlight current item
            this._toggleHighlight(oCurItem, 'mouseout');
            this.itemArrowFromEvent.fire(this, oCurItem);
            //YAHOO.log(this.getName() + " arrowed from " + =
oCurItem.id);

        }
        if (nNewItemIndex =3D=3D -1) {
           // go back to query (remove type-ahead string)
            if(this.delimChar && this._sSavedQuery) {
                if (!this._textMatchesOption()) {
                    this._oTextbox.value =3D this._sSavedQuery;
                }
                else {
                    this._oTextbox.value =3D this._sSavedQuery + =
this._sCurQuery;
                }
            }
            else {
                this._oTextbox.value =3D this._sCurQuery;
            }
            this._oCurItem =3D null;
            return;
        }
        if (nNewItemIndex =3D=3D -2) {
            // close container
            this._clearList();
            return;
        }

        var oNewItem =3D document.getElementById(this._sName + "item" + =
nNewItemIndex);

        // Scroll the container if necessary
        if((YAHOO.util.Dom.getStyle(this._oContainer,"overflow") =3D=3D =
"auto") &&
        (nNewItemIndex > -1) && (nNewItemIndex < this._nDisplayedItems)) =
{
            // User is keying down
            if(nKeyCode =3D=3D 40) {
                // Bottom of selected item is below scroll area...
                if((oNewItem.offsetTop+oNewItem.offsetHeight) > =
(this._oContainer.scrollTop + this._oContainer.offsetHeight)) {
                    // Set bottom of scroll area to bottom of selected =
item
                    this._oContainer.scrollTop =3D =
(oNewItem.offsetTop+oNewItem.offsetHeight) - =
this._oContainer.offsetHeight;
                }
                // Bottom of selected item is above scroll area...
                else if((oNewItem.offsetTop+oNewItem.offsetHeight) < =
this._oContainer.scrollTop) {
                    // Set top of selected item to top of scroll area
                    this._oContainer.scrollTop =3D oNewItem.offsetTop;

                }
            }
            // User is keying up
            else {
                // Top of selected item is above scroll area
                if(oNewItem.offsetTop < this._oContainer.scrollTop) {
                    // Set top of scroll area to top of selected item
                    this._oContainer.scrollTop =3D oNewItem.offsetTop;
                }
                // Top of selected item is below scroll area
                else if(oNewItem.offsetTop > (this._oContainer.scrollTop =
+ this._oContainer.offsetHeight)) {
                    // Set bottom of selected item to bottom of scroll =
area
                    this._oContainer.scrollTop =3D =
(oNewItem.offsetTop+oNewItem.offsetHeight) - =
this._oContainer.offsetHeight;
                }
            }
        }

        this._toggleHighlight(oNewItem, 'mouseover');
        this.itemArrowToEvent.fire(this, oNewItem);
        //YAHOO.log(this.getName() + " arrowed to " + oNewItem.id);
        if(this.typeAhead) {
            this._updateValue(oNewItem);
        }
    }
};

/************************************************************************=
****/
/************************************************************************=
****/
/************************************************************************=
****/

/**
 * Class providing encapsulation of a data source.
 *
 * @constructor
 *
 */
YAHOO.widget.DataSource =3D function() {
    /* abstract class */
};


/************************************************************************=
***
 * Public constants
 =
*************************************************************************=
**/
/**
 * Error message for null data responses.
 *
 * @type constant
 * @final
 */
YAHOO.widget.DataSource.prototype.ERROR_DATANULL =3D "Response data was =
null";

/**
 * Error message for data responses with parsing errors.
 *
 * @type constant
 * @final
 */
YAHOO.widget.DataSource.prototype.ERROR_DATAPARSE =3D "Response data =
could not be parsed";


/************************************************************************=
***
 * Public member variables
 =
*************************************************************************=
**/
/**
 * Max size of the local cache.  Set to 0 to turn off caching.  Caching =
is
 * useful to reduce the number of server connections.  Recommended only =
for data
 * sources that return comprehensive results for queries or when stale =
data is
 * not an issue. Default: 15.
 *
 * @type number
 */
YAHOO.widget.DataSource.prototype.maxCacheEntries =3D 15;

/**
 * Use this to equate cache matching with the type of matching done by =
your live
 * data source. If caching is on and queryMatchContains is true, the =
cache
 * returns results that "contain" the query string. By default,
 * queryMatchContains is set to false, meaning the cache only returns =
results
 * that "start with" the query string. Default: false.
 *
 * @type boolean
 */
YAHOO.widget.DataSource.prototype.queryMatchContains =3D false;

/**
 * Data source query subset matching. If caching is on and =
queryMatchSubset is
 * true, substrings of queries will return matching cached results. For
 * instance, if the first query is for "abc" susequent queries that =
start with
 * "abc", like "abcd", will be queried against the cache, and not the =
live data
 * source. Recommended only for data sources that return comprehensive =
results
 * for queries with very few characters. Default: false.
 *
 * @type boolean
 */
YAHOO.widget.DataSource.prototype.queryMatchSubset =3D false;

/**
 * Data source query case-sensitivity matching. If caching is on and
 * queryMatchCase is true, queries will only return results for =
case-sensitive
 * matches. Default: false.
 *
 * @type boolean
 */
YAHOO.widget.DataSource.prototype.queryMatchCase =3D false;


/************************************************************************=
***
 * Public methods
 =
*************************************************************************=
**/
/**
 * Retrieves query results, first checking the local cache, then making =
the
 * query request to the live data source as defined by the function =
doQuery.
 *
 * @param {object} oCallbackFn Callback function defined by oParent =
object to
 *                             which to return results
 * @param {string} sQuery Query string
 * @param {object} oParent The object instance that has requested data
 */
YAHOO.widget.DataSource.prototype.getResults =3D function(oCallbackFn, =
sQuery, oParent) {

    // First look in cache
    var aResults =3D this._doQueryCache(oCallbackFn,sQuery,oParent);

    // Not in cache, so get results from server
    if(aResults.length =3D=3D=3D 0) {
        this.queryEvent.fire(this, oParent, sQuery);
        //YAHOO.log("Data source for " + oParent.getName() + " made =
source query for '" + sQuery + "'.");
        this.doQuery(oCallbackFn, sQuery, oParent);
    }
};

/**
 * Abstract method implemented by subclasses to make a query to the live =
data
 * source. Must call the callback function with the response returned =
from the
 * query. Populates cache (if enabled).
 *
 * @param {object} oCallbackFn Callback function implemented by oParent =
to
 *                             which to return results
 * @param {string} sQuery Query string
 * @param {object} oParent The object instance that has requested data
 */
YAHOO.widget.DataSource.prototype.doQuery =3D function(oCallbackFn, =
sQuery, oParent) {
    /* override this */
};

/**
 * Flushes cache.
 */
YAHOO.widget.DataSource.prototype.flushCache =3D function() {
    if(this._aCache) {
        this._aCache =3D [];
    }
    if(this._aCacheHelper) {
        this._aCacheHelper =3D [];
    }
    this.cacheFlushEvent.fire(this);
    //YAHOO.log("Cache flushed");
};

/************************************************************************=
***
 * Events
 =
*************************************************************************=
**/
/**
 * Fired when a query is made to the live data source. Subscribers =
receive the
 * following array:<br>
 *     - args[0] The data source instance
 *     - args[1] The requesting object
 *     - args[2] The query string
 */
YAHOO.widget.DataSource.prototype.queryEvent =3D null;

/**
 * Fired when a query is made to the local cache. Subscribers receive =
the
 * following array:<br>
 *     - args[0] The data source instance
 *     - args[1] The requesting object
 *     - args[2] The query string
 */
YAHOO.widget.DataSource.prototype.cacheQueryEvent =3D null;

/**
 * Fired when data is retrieved from the live data source. Subscribers =
receive
 * the following array:<br>
 *     - args[0] The data source instance
 *     - args[1] The requesting object
 *     - args[2] The query string
 *     - args[3] Array of result objects
 */
YAHOO.widget.DataSource.prototype.getResultsEvent =3D null;

/**
 * Fired when data is retrieved from the local cache. Subscribers =
receive the
 * following array :<br>
 *     - args[0] The data source instance
 *     - args[1] The requesting object
 *     - args[2] The query string
 *     - args[3] Array of result objects
 */
YAHOO.widget.DataSource.prototype.getCachedResultsEvent =3D null;

/**
 * Fired when an error is encountered with the live data source. =
Subscribers
 * receive the following array:<br>
 *     - args[0] The data source instance
 *     - args[1] The requesting object
 *     - args[2] The query string
 *     - args[3] Error message string
 */
YAHOO.widget.DataSource.prototype.dataErrorEvent =3D null;

/**
 * Fired when the local cache is flushed. Subscribers receive the =
following
 * array :<br>
 *     - args[0] The data source instance
 */
YAHOO.widget.DataSource.prototype.cacheFlushEvent =3D null;

/************************************************************************=
***
 * Private member variables
 =
*************************************************************************=
**/
/**
 * Local cache of data result objects indexed chronologically.
 *
 * @type array
 * @private
 */
YAHOO.widget.DataSource.prototype._aCache =3D null;


/************************************************************************=
***
 * Private methods
 =
*************************************************************************=
**/
/**
 * Initializes data source instance.
 *
 * @private
 */
YAHOO.widget.DataSource.prototype._init =3D function() {
    // Validate and initialize public configs
    var maxCacheEntries =3D this.maxCacheEntries;
    if(isNaN(maxCacheEntries) || (maxCacheEntries < 0)) {
        maxCacheEntries =3D 0;
    }
    // Initialize local cache
    if(maxCacheEntries > 0 && !this._aCache) {
        this._aCache =3D [];
    }

    this.queryEvent =3D new YAHOO.util.CustomEvent("query", this);
    this.cacheQueryEvent =3D new YAHOO.util.CustomEvent("cacheQuery", =
this);
    this.getResultsEvent =3D new YAHOO.util.CustomEvent("getResults", =
this);
    this.getCachedResultsEvent =3D new =
YAHOO.util.CustomEvent("getCachedResults", this);
    this.dataErrorEvent =3D new YAHOO.util.CustomEvent("dataError", =
this);
    this.cacheFlushEvent =3D new YAHOO.util.CustomEvent("cacheFlush", =
this);
};

/**
 * Adds a result object to the local cache, evicting the oldest element =
if the
 * cache is full. Newer items will have higher indexes, the oldest item =
will have
 * index of 0.
 *
 * @param {object} resultObj  Object literal of data results, including =
internal
 *                            properties and an array of result objects
 * @private
 */
YAHOO.widget.DataSource.prototype._addCacheElem =3D function(resultObj) =
{
    var aCache =3D this._aCache;
    // Don't add if anything important is missing.
    if(!aCache || !resultObj || !resultObj.query || !resultObj.results) =
{
        return;
    }

    // If the cache is full, make room by removing from index=3D0
    if(aCache.length >=3D this.maxCacheEntries) {
        aCache.shift();
    }

    // Add to cache, at the end of the array
    aCache.push(resultObj);
};

/**
 * Queries the local cache for results. If query has been cached, the =
callback
 * function is called with the results, and the cached is refreshed so =
that it
 * is now the newest element.
 *
 * @param {object} oCallbackFn Callback function defined by oParent =
object to
 *                             which to return results
 * @param {string} sQuery Query string
 * @param {object} oParent The object instance that has requested data
 * @return {array} aResults Result object from local cache if found, =
otherwise
 *                          null
 * @private
 */
YAHOO.widget.DataSource.prototype._doQueryCache =3D =
function(oCallbackFn, sQuery, oParent) {
    var aResults =3D [];
    var bMatchFound =3D false;
    var aCache =3D this._aCache;
    var nCacheLength =3D (aCache) ? aCache.length : 0;
    var bMatchContains =3D this.queryMatchContains;

    // If cache is enabled...
    if((this.maxCacheEntries > 0) && aCache && (nCacheLength > 0)) {
        this.cacheQueryEvent.fire(this, oParent, sQuery);
        //YAHOO.log("Data source for " + oParent.getName() + " made =
cache query for '" + sQuery + "'.");
        // If case is unimportant, normalize query now instead of in =
loops
        if(!this.queryMatchCase) {
            var sOrigQuery =3D sQuery;
            sQuery =3D sQuery.toLowerCase();
        }

        // Loop through each cached element's query property...
        for(var i =3D nCacheLength-1; i >=3D 0; i--) {
            var resultObj =3D aCache[i];
            var aAllResultItems =3D resultObj.results;
            // If case is unimportant, normalize match key for =
comparison
            var matchKey =3D (!this.queryMatchCase) ?
                encodeURI(resultObj.query.toLowerCase()):
                encodeURI(resultObj.query);

            // If a cached match key exactly matches the query...
            if(matchKey =3D=3D sQuery) {
                    // Stash all result objects into aResult[] and stop =
looping through the cache.
                    bMatchFound =3D true;
                    aResults =3D aAllResultItems;

                    // The matching cache element was not the most =
recent,
                    // so now we need to refresh the cache.
                    if(i !=3D nCacheLength-1) {
                        // Remove element from its original location
                        aCache.splice(i,1);
                        // Add element as newest
                        this._addCacheElem(resultObj);
                    }
                    break;
            }
            // Else if this query is not an exact match and subset =
matching is enabled...
            else if(this.queryMatchSubset) {
                // Loop through substrings of each cached element's =
query property...
                for(var j =3D sQuery.length-1; j >=3D 0 ; j--) {
                    var subQuery =3D sQuery.substr(0,j);

                    // If a substring of a cached sQuery exactly matches =
the query...
                    if(matchKey =3D=3D subQuery) {
                        bMatchFound =3D true;

                        // Go through each cached result object to match =
against the query...
                        for(var k =3D aAllResultItems.length-1; k >=3D =
0; k--) {
                            var aRecord =3D aAllResultItems[k];
                            var sKeyIndex =3D (this.queryMatchCase) ?
                                encodeURI(aRecord[0]).indexOf(sQuery):
                                =
encodeURI(aRecord[0]).toLowerCase().indexOf(sQuery);

                            // A STARTSWITH match is when the query is =
found at the beginning of the key string...
                            if((!bMatchContains && (sKeyIndex =3D=3D=3D =
0)) ||
                            // A CONTAINS match is when the query is =
found anywhere within the key string...
                            (bMatchContains && (sKeyIndex > -1))) {
                                // Stash a match into aResults[].
                                aResults.unshift(aRecord);
                            }
                        }

                        // Add the subset match result set object as the =
newest element to cache,
                        // and stop looping through the cache.
                        resultObj =3D {};
                        resultObj.query =3D sQuery;
                        resultObj.results =3D aResults;
                        this._addCacheElem(resultObj);
                        break;
                    }
                }
                if(bMatchFound) {
                    break;
                }
            }
        }

        // If there was a match, send along the results.
        if(bMatchFound) {
            this.getCachedResultsEvent.fire(this, oParent, sOrigQuery, =
aResults);
            //YAHOO.log("Data source for " + oParent.getName() + " got " =
+ aResults.length + " results from cache.");
            oCallbackFn(sOrigQuery, aResults, oParent);
        }
    }
    return aResults;
};


/************************************************************************=
****/
/************************************************************************=
****/
/************************************************************************=
****/

/**
 * Implementation of YAHOO.widget.DataSource using XML HTTP requests =
that return
 * query results.
 * requires YAHOO.util.Connect XMLHTTPRequest library
 * extends YAHOO.widget.DataSource
 *
 * @constructor
 * @param {string} sScriptURI Absolute or relative URI to script that =
returns
 *                            query results as JSON, XML, or delimited =
flat data
 * @param {array} aSchema Data schema definition of results
 * @param {object} oConfigs Optional object literal of config params
 */
YAHOO.widget.DS_XHR =3D function(sScriptURI, aSchema, oConfigs) {
    // Set any config params passed in to override defaults
    if(typeof oConfigs =3D=3D "object") {
        for(var sConfig in oConfigs) {
            this[sConfig] =3D oConfigs[sConfig];
        }
    }

    // Initialization sequence
    if(!aSchema || (aSchema.constructor !=3D Array)) {
        //log this.ERROR_INIT
    }
    else {
        this.schema =3D aSchema;
    }
    this.scriptURI =3D sScriptURI;
    this._init();
};

YAHOO.widget.DS_XHR.prototype =3D new YAHOO.widget.DataSource();

/************************************************************************=
***
 * Public constants
 =
*************************************************************************=
**/
/**
 * JSON data type
 *
 * @type constant
 * @final
 */
YAHOO.widget.DS_XHR.prototype.TYPE_JSON =3D 0;

/**
 * XML data type
 *
 * @type constant
 * @final
 */
YAHOO.widget.DS_XHR.prototype.TYPE_XML =3D 1;

/**
 * Flat file data type
 *
 * @type constant
 * @final
 */
YAHOO.wi