From: <Mit Microsoft Internet Explorer 7 gespeichert>
Subject: The W h i p p e t Archives
Date: Tue, 30 Dec 2008 20:30:12 +0100
MIME-Version: 1.0
Content-Type: multipart/related;
	type="text/html";
	boundary="----=_NextPart_000_0000_01C96ABD.6A624C80"
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5579

This is a multi-part message in MIME format.

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://thewhippetarchives.net/details.php?id=64054

<!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.16788" 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><SPAN class=3Dnavitem><A=20
      =
href=3D"http://thewhippetarchives.net/php_users/htdocs/login.php?returnto=
=3D%2Fdetails.php%3Fid%3D64054">[=20
      Login ]</A></SPAN> </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=3D64054#">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=3D64054#">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
          =
href=3D"http://thewhippetarchives.net/php_users/htdocs/login.php?returnto=
=3D%2Fdetails.php%3Fid%3D64054">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></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>=0A=
	var currentIndx=3D0;=0A=
	var MyImages =3D new Array();	=0A=
	var MyCopyright =3D new Array();=0A=
	var MyImgWidth =3D new Array();=0A=
	var photoPrefix =3D "Copyright: ";=0A=
	var MyPhotonotes =3D new Array();=0A=
	var photonotesPrefix =3D "Notes: ";=0A=
	var MyPhotoPostedBy =3D new Array();=0A=
	var photoPostedByPrefix =3D "Posted by: ";=0A=
	//var predefinedMaxWidth =3D 250;=0A=
=0A=
	function next(){	=0A=
		document.theImage.removeAttribute("width");			=0A=
		if (currentIndx<MyImages.length-1){=0A=
			currentIndx=3DcurrentIndx+1;=0A=
			document.theImage.src=3DMyImages[currentIndx];=0A=
			document.theImage.width=3DMyImgWidth[currentIndx];=0A=
			if (MyCopyright[currentIndx] !=3D "") =0A=
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];=0A=
			else =0A=
				document.getElementById("theCopyright").innerHTML=3D"";=0A=
			if (MyPhotoPostedBy[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";				=0A=
			if (MyPhotonotes[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotonotes").innerHTML=3D"";				=0A=
		} else {						=0A=
			currentIndx=3D0						=0A=
			document.theImage.src=3DMyImages[currentIndx];=0A=
			document.theImage.width=3DMyImgWidth[currentIndx];=0A=
			if (MyCopyright[currentIndx] !=3D "") =0A=
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];	=0A=
			else =0A=
				document.getElementById("theCopyright").innerHTML=3D"";=0A=
			if (MyPhotoPostedBy[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";				=0A=
			if (MyPhotonotes[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotonotes").innerHTML=3D"";				=0A=
		}=0A=
	}=0A=
	=0A=
	function previous(){=0A=
		document.theImage.removeAttribute("width");=0A=
		if (currentIndx>0) {=0A=
			currentIndx=3DcurrentIndx-1;=0A=
			document.theImage.src=3DMyImages[currentIndx];=0A=
			document.theImage.width=3DMyImgWidth[currentIndx];=0A=
			if (MyCopyright[currentIndx] !=3D "") 	=0A=
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];	=0A=
			else =0A=
				document.getElementById("theCopyright").innerHTML=3D"";=0A=
			if (MyPhotoPostedBy[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";				=0A=
			if (MyPhotonotes[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotonotes").innerHTML=3D"";				=0A=
		} else {=0A=
			currentIndx=3DMyImages.length-1;=0A=
			document.theImage.src=3DMyImages[currentIndx];=0A=
			document.theImage.width=3DMyImgWidth[currentIndx];=0A=
			if (MyCopyright[currentIndx] !=3D "") =0A=
				=
document.getElementById("theCopyright").innerHTML=3DphotoPrefix+MyCopyrig=
ht[currentIndx];	=0A=
			else =0A=
				document.getElementById("theCopyright").innerHTML=3D"";=0A=
			if (MyPhotoPostedBy[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotoPostedBy").innerHTML=3DphotoPostedByPref=
ix+MyPhotoPostedBy[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotoPostedBy").innerHTML=3D"";				=0A=
			if (MyPhotonotes[currentIndx] !=3D "") =0A=
				=
document.getElementById("thePhotonotes").innerHTML=3DphotonotesPrefix+MyP=
hotonotes[currentIndx];=0A=
			else =0A=
				document.getElementById("thePhotonotes").innerHTML=3D"";				=0A=
		}=0A=
	}=0A=
	=0A=
/*=0A=
	function getImageWidth(myImgObj) {=0A=
		if (myImgObj !=3D null)=0A=
			return myImgObj.width;=0A=
		else=0A=
			return -1;=0A=
	}=0A=
	=0A=
	function setToProperWidth(imgEl) {=0A=
		var imgWidth =3D this.getImageWidth(imgEl);=0A=
		if ((imgWidth !=3D null) && (imgWidth !=3D -1)) {=0A=
			if (imgWidth >=3D predefinedMaxWidth) =0A=
				imgEl.width =3D predefinedMaxWidth;=0A=
		} else {=0A=
			imgEl.width =3D predefinedMaxWidth;=0A=
		}=0A=
	}=0A=
*/	=0A=
	=0A=
</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>Let's Run Hip Hop Culture</H3>
      <SCRIPT language=3Djavascript>=0A=
							MyImages[0] =3D "pics/medium/1911/med_49331e92a36e9.jpg";=0A=
							MyCopyright[0] =3D "";=0A=
							MyPhotoPostedBy[0] =3D "petronio";=0A=
							MyPhotonotes[0] =3D "11 weeks old";=0A=
														MyImgWidth[0] =3D "250";=0A=
						</SCRIPT>

      <TABLE border=3D0>
        <TBODY>
        <TR>
          <TD align=3Dmiddle><IMG alt=3D"picture of dog"=20
            =
src=3D"http://thewhippetarchives.net/pics/medium/1911/med_49331e92a36e9.j=
pg"=20
            width=3D250 name=3DtheImage> <BR>
            <DIV style=3D"WIDTH: 250px"><LABEL><SPAN=20
            id=3DtheCopyright></SPAN></LABEL></DIV>
            <DIV style=3D"WIDTH: 250px"><LABEL><SPAN =
id=3DthePhotoPostedBy>Posted=20
            by: petronio </SPAN></LABEL></DIV>
            <DIV style=3D"WIDTH: 250px"><LABEL><SPAN =
id=3DthePhotonotes>Notes: 11=20
            weeks old =
</SPAN></LABEL></DIV></TD></TR></TBODY></TABLE></DIV></DIV>
      <TABLE>
        <TBODY>
        <TR>
          <TD></TD></TR></TBODY></TABLE></TD>
    <TD>
      <TABLE width=3D400 border=3D0>
        <TBODY>
        <TR>
          <TD width=3D160><STRONG>Registered Name: </STRONG></TD>
          <TD>Let's Run Hip Hop Culture</TD></TR>
        <TR>
          <TD><STRONG>Breeder: </STRONG></TD>
          <TD><A=20
            =
href=3D"http://thewhippetarchives.net/managePerson.php?personId=3D2641">R=
enata=20
            Petronio</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/managePerson.php?personId=3D2640">M=
ats=20
            Carlsson</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>Let's Run</TD></TR>
        <TR>
          <TD><STRONG>Sire: </STRONG></TD>
          <TD><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D1887">Adagio My=20
            Culture</A></TD></TR>
        <TR>
          <TD><STRONG>Dam: </STRONG></TD>
          <TD><A =
href=3D"http://thewhippetarchives.net/details.php?id=3D36301">The=20
            Rattigan's Airstep</A></TD></TR>
        <TR>
          <TD><STRONG>Call Name: </STRONG></TD>
          <TD>Vincent</TD></TR>
        <TR>
          <TD><STRONG>Sex: </STRONG></TD>
          <TD>male</TD></TR>
        <TR>
          <TD><STRONG>Date of Birth: </STRONG></TD>
          <TD>13 SEP 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>Brindle 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=3D64054=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>
        <TBODY>
        <TR>
          <TD></TD></TR>
        <TR>
          <TD></TD></TR>
        <TR>
          <TD style=3D"PADDING-TOP: 15px">
            <DIV></DIV></TD></TR>
        <TR>
          <TD style=3D"PADDING-TOP: 10px"><STRONG>Siblings: =
</STRONG><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D64224">Let's Run=20
            Ballet</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D64052">Let's Run=20
            Bollywood</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D64053">Let's Run=20
            Contemporary</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D64223">Let's Run=20
            Lindy Hop</A><BR><A=20
            =
href=3D"http://thewhippetarchives.net/details.php?id=3D64222">Let's Run=20
            Lyrical =
Jazz</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=3D64054 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=3D64054&a=
mp;gens=3D4&amp;images=3Dyes"=20
      target=3D_blank> with</A> / <A=20
      =
href=3D"http://thewhippetarchives.net/printable_pedigree.php?id=3D64054&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=3D64054&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=3D64054">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/1911/th_49331e92a26a2.jp=
g"=20
      width=3D100></P>Let's Run Hip Hop Culture</A><LABEL><BR>Brindle =
and White=20
      <BR>Sweden<BR>2008</LABEL></TD>
    <TD rowSpan=3D4><LABEL><FONT color=3Dred>Fin, Norw &amp; Swedish=20
      Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1887">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/2110/th_48eb5dd1af7b2.jp=
g"=20
      width=3D100></P>Adagio My Culture</A><LABEL><BR>Light Fawn=20
      <BR>Sweden<BR>2002</LABEL></TD>
    <TD rowSpan=3D2><LABEL><FONT color=3Dred>GB, Int, Swe, Norw, Dan =
&amp; Fin Ch=20
      BOB Cruft's 2008</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1890">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_46c68e3839f21.jpg"=20
      width=3D100></P>Adagio Love Supreme</A><LABEL><BR>Fawn Brindle and =
White=20
      <BR>Sweden<BR>2001</LABEL></TD>
    <TD><LABEL><FONT color=3Dred>Int &amp; Swd &amp; Nor &amp; Fin=20
      Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1576">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/anonymous/th_nelson.jpg"=
=20
      width=3D100></P>Carry On Pastrami</A><LABEL><BR>Fawn Brindle=20
      <BR>Sweden<BR>1998</LABEL></TD></TR>
  <TR>
    <TD><LABEL><FONT color=3Dred>Multi Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1577">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4686dafc746b9.jpg"=20
      width=3D100></P>Flic Flac Kiss Of Love</A><LABEL><BR>Red Fawn=20
      <BR>Germany<BR>1998</LABEL></TD></TR>
  <TR>
    <TD rowSpan=3D2><LABEL><FONT color=3Dred>Swedish =
Champion</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1888">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_46c69986ba35b.jpg"=20
      width=3D100></P>Fennaur Emmeline Pankhurst</A><LABEL><BR>Brindle =
and White=20
      <BR>Sweden<BR>2000</LABEL></TD>
    <TD><LABEL><FONT color=3Dred>Int, S, N, DK &amp; Fin =
Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1810">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_46c66744cddde.jpg"=20
      width=3D100></P>Fennaur Delacroix</A><LABEL><BR>Dark Fawn and =
White=20
      <BR>Sweden<BR>1994</LABEL></TD></TR>
  <TR>
    <TD><LABEL><FONT color=3Dred>Swedish Champion</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D1889">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4635b0030022e.jpg"=20
      width=3D100></P>Birkonbrae Summer Love</A><LABEL><BR>Brindle and =
White=20
      <BR>United Kingdom</LABEL></TD></TR>
  <TR>
    <TD rowSpan=3D4><A=20
href=3D"http://thewhippetarchives.net/details.php?id=3D36301">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/443/th_477e3d7e20080.jpg=
"=20
      width=3D100></P>The Rattigan's=20
    Airstep</A><LABEL><BR>Sweden<BR>2002</LABEL></TD>
    <TD rowSpan=3D2><LABEL><FONT color=3Dred>SU &amp; SLC =
Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D19038">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/1911/th_48a00465b3d95.jp=
g"=20
      width=3D100></P>G=E5rdsj=F6ns Ingemar</A><LABEL><BR>Brindle and =
White=20
      <BR>Sweden<BR>1996</LABEL></TD>
    <TD><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></TR>
  <TR>
    <TD><LABEL><FONT color=3Dred>SUCh</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D19039">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/76/th_477a597979896.jpg"=
=20
      width=3D100></P>G=E5rdsj=F6ns G=F6ta</A><LABEL><BR>Brindle and =
White=20
      <BR>Sweden<BR>1992</LABEL></TD></TR>
  <TR>
    <TD rowSpan=3D2><LABEL><FONT color=3Dred>SUCh</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D19015">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/76/th_477d6c15107f7.jpg"=
=20
      width=3D100></P>Khalibadh Regndans (A.I.)</A><LABEL><BR>Brindle =
and White=20
      <BR>Sweden<BR>1998</LABEL></TD>
    <TD><LABEL><FONT color=3Dred>Am Ch, JC, ROMX</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D322">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_4725f4130ce45.jpg"=20
      width=3D100></P>Starline's Reign On</A><LABEL><BR>White and Dark =
Brindle=20
      <BR>USA<BR>1990</LABEL></TD></TR>
  <TR>
    <TD><LABEL><FONT color=3Dred>Int &amp; Nord Ch</FONT><BR></LABEL><A=20
      href=3D"http://thewhippetarchives.net/details.php?id=3D10627">
      <P><IMG=20
      =
src=3D"http://thewhippetarchives.net/pics/thumbs/th_46fe6ab932fcb.jpg"=20
      width=3D100></P>Khalibadh Eldstorm</A><LABEL><BR>Black Brindle and =
White=20
      <BR>Sweden<BR>1994</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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/images/sort_desc.gif

R0lGODlhDAAMAJEAAJqamsyZZv///wAAACH5BAEAAAIALAAAAAAMAAwAAAIYlI+pywIPowGh2goO
vSGjjS2bJ5LNiTIFADs=

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/medium/1911/med_49331e92a36e9.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAsAD6
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
8dAIxj880/oaUDNLiuc9ITtTkz9KMHaTSpg4oAUZB9qcMf5FSYwTTduaB2JOMA9/SlXr0pqj609R
SGKCf8mlGe3WlAz0oAP40DEAz/hSgZJJB4pQO5z/AI0uO9ACcA9wKQAA96UjHFKOOKADB9KFx6U5
R6daMYz60hiEHcP0oK5NKRyOeaXaQeTTAbtAODyaCAe1OC85NKRQBFyAaQ9ckVJjPpTOvXGaBEbY
PSm7exqRxgHApjBqBEeOKZgVMfSmMFH+NMCIjt2pjVKwHP8AWmcCgQw89R0pNuTS5yDSH2NAiJsA
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
x7fC8tFnO30+laQvosD5hWLRilyplxm47H//2Q==

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/1911/th_49331e92a26a2.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgARgBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
8hVemKljXOfakUcCpIRncPeuc9NDkBxU4U49qYq81YUcc0ikiMLxTlWpAOKcq0hkW08Uu2pynK0F
aAKjLUTL7VqWag3KkxCVVPIJ49eRXoMOgPNo8dsNOSGeW2aQSv8AMAR3PHqegqHUs7WFZHkbrjtU
JHtXVWHhfUNU1S/srNIz9jg8+SR3wpGOQO5PX8q5Yuki7kJIyR6VqZqSexXbOaKeEyAcGimFi2g4
FSQj5nHvTUHFPh4kPvSLJlXmpUHPNCIXYBAWYnAAGc10Gk+HzIfO1M3UFuCBiCHzJGOM4AJA/HNS
2NuxiAVIi5rprrT9NtL/AMu2RpoTIIxHcsRKMD5s7cD3Ht610dz4PKCM26QNFn5lYBXUdOvfv6VD
mkCdzzgL8w+hq7pemz6pfwWdooaaZgi7jgc+prsBoSukypawfa4VKFcEFiDw2OnK89OavWnh+2xG
zMZMqsickFPmO3nHXn9KXtEDbtoeg2fwo0q30yK3mctIqhjIBg+Zjk+657Vx3xH8SWHgSaKCVri/
1e5i3R21mh/dx56k7hgE5xkHvxXs2h+anh2yF1Jvl8hQXJznjrXyZ4v1JNY8U6pqcZLLcy/Ix7xq
NqfT5QPzre0Ur2OWPNN2bKtn8Q7qyhuxpvhmWPULoMv2+4uuUDeiBQAB+fvXNxxuIv3rb5OSzYAy
TyeKuSnJqJ/ljP0obuaxpqJASBxRQRk0UiidTxTl6g+9QK2BVm1R53WOJGkdjhVUZJPsKBnS+CIU
udchSVC69wMccgZ/l+dez3elxwTXM6RgtaxKybeMsAxI/HIrhPAHgm/s9TtdS1qF7QKwMMD8O5Pd
l6gdev8ASvT/ABHd2+leH7+4vZR5cULTTOOOueB/ICsqhN7u5jWWgC+1yG61FFRAplRX+65IAP5D
+dTPbT2KXx83EzIWZgMFeSeB7ZNeX2vxY8Uw6U8JttPe93q1u77tiQ85iZc8kfKAw9DnNQTfFfxZ
NMks2kaSxXtHIy5/P/PNaezVtzK8ux634VtLW6M1y6K08Tm3LKeuMdfyH0q7q2k23kzSEsirhiVb
GGXJFeWaL8Y4rDMeq+Fbq3hZtzPaTCYA+uOOOK9J0/XLbxlo1vfeH4pri2uJjDLmPDIQACGU+mQe
e1Zyp8upanfQ2Nf8WWGgeBY726kCgwGKOJDlnl+4FX8f5H0r5elI6DpXSfEfUpdS8TvavuFlo+6z
t0P8TrxJKR6s2QPYe9cvIa1fRBSjZN9yJsDNQSsT9Kkc5qCQ46UGjGEc0U0tz1opkgW6e9ez/s22
cVxqOt3Dj99FDGiMOo3E5/8AQRXzet9d9pj+IBr6D/ZfknvdK8XpHcbL4xRrE+0YQlZNrYGM4NWo
nO6/MrJE/j34qwWWs3Nn4Ztf7WuoGKNdN8tuj9CAc5fHtgehNc18THvNSi8Lz399K8VxpsV5LaKc
RfaC7hnwOSPlGM5xXnPiKLWPCeu3ejXLxCS0fZkQLhh1DDK9CMGrvinxrc6te2TW0cUcFtY29oqt
Gp5SMbz06Fy5/Gp9mlsJVlpc0c55604E5rll8Q3Q+9Bbt9VI/katQeKZYxhtOspP97zB/JxRyM0+
sx7HQ7uTXtP7Nl+yPr+n9FJiuV92IKt+iJXzq3ihycjTrMfQyf8Axdep/s6+MrOLxlNZ6kILN7yI
R25Xdh5N33MknkgnH/6qai0TUrRmrGB4wR4fFespJkOt5NnP++axGNdv8bvD/iDSvFGsarDpcdzp
DkXJulJ+QNgEMN3Y+3TBryT/AISGXvbQ/gW/xo5WUq8UrM3nOTUMp4rFGvPvy1upHcBiKRdZEkuH
i8tCeDuzj60uVj9tFmmSM0VEzc0Ui7nOItdD4X1zUvD1211o97PaTsuGaJsbh6EdD170UVseeitr
upXut6g17ql1LdXLAKZJWycDoPYVQMYoooEN8ugIKKKADywalt0eOeOSKRo5EYMrqcFSDkEUUUAe
za98aNS1XwhcaTe6ZbPcXFsbeW6WRhuyMFtvr364rw9l5oooQ27jCtNK0UUCJI7mWNdqSED0oooo
sh3Z/9k=

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/2110/th_48eb5dd1af7b2.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
8j0ny0h2tFGSUAO5B6Vat7KUq91Dp0l4scEgf7PDvCZVkBOPqDXX+H7TR57B3YXolMAQFmU+Y4XJ
zxnBzgH0r034WQDSPCktvDhJ5pi77yuScAD64Hp61zqMea19dzb2NRJTkvdZ4dZ+Cr678LWmraXp
lxdxsD9pZU5gYE5GMZIxjpWOESOEZiAKybW+UZ6V9g6jeG3j+SVY7ZFO5QNoxg9/rivFfE/jzRtZ
1+5tf+EcgmitSFFzOBmVhwWGOo/PitpYa70Zi6vNqlojzK1aA3RKwwgH7+UHJ/pTikRkMawxFs8A
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

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_46c68e3839f21.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAQgBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
5gwLhmZZOT/doZYwQpVwpHU17GZY1A8zJycDnrT7fy7i5W2iQNI3OzjP1+leWpts7nB9zxkQQ3Gx
WjuGGf4ByO9TLZ2pl+WS6GeWMmMAV7BrOmSraX1lfJbQpNuih/eEmaMqN24Y4Odwx6Gsj4caWW8F
26TTH7VHucg4z5e4hfwxg5rVxlEzWvU8zuPLknWJd4hHCgr09/qaptpVuxbbNKueTlAR/OvaJUtx
IAwzjvtFMDWiOV8lXb/aAOPyFZe1NPZs8ROkW8LljcyH/Z8ofzzU+2NlEZmcbec7ef517LM0RA22
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
iOhaRVK8gH8KKKKsR//Z

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/anonymous/th_nelson.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
87i0mFoYyW/hGchTVaz8OR293JP9o3lz91o845B/pW/bugt4v3EI+UZO5/T/AHqesq5wIIcf7zcf
+PV897SSukx2MmXR1mYHcoA4/wBV/wDXpDpKqhzJFjnkw9P1rdDoOXtLY/8AA3H/ALNTwYTj/RFH
P8Lt/wDXqeZvqHKcrPFapCVa5tsZwT5JJP61HjT1s4ZGuoSWZ03mFhyMH/2auqnkhCAx2czleoE+
M/mhqutzEQC+m3uM7cLdxtnIznlBxx6VrB6NX/H/AIAreZzksNjIwlN/ZhSRgcDinyJafvJ/tNiy
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
P8A7D3orWMNCLn//2Q==

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4686dafc746b9.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
5D4eeJZNI1rxDbw3Motnmnurdo2DIQVfDFefRa5LWNZ069u72/uoTcTy3TyOkc5R+T1I2kYwe1bn
hnwFPpGom4k1FZIJImjkRDsZgcYGefb8vetTWfhj4f0/Spdav21K3s92TJJMCHJ7JhAWPsPxxWcs
VCdrO7IlRcpXRi6B4Pj8YzXF/pV/Y2ccESCWKaRmZzgjjIHOF9O9fZXhy1Sx020tkwEiiWP26V88
aLpPgzwxpkWsaZNrN5FKsczeVMgzjnGzH1yM9q6vwz8VtQ1C2mlsLC1uLPeUhkfdGdoH3W5OHGRk
dwQRWPt43bex1KjKMT2/UtP/ALR0u5sZJmVJ0KFlUAgGvzl8R6Vc6Tr93Y3p3XMFy0Uh9SGIJ/PN
faS/ETWQoKaZaMcfxTkV8reNxd6x8Tblb2KGJ7vUMuiZITewOAfTnrXRh61Opfl6GE01Y3vA2s6h
Y2lxG90SkNhcG2j8tSMiMkg9D0B9a90X4h6bonh/w/Hq8jpe3SlUReM/d4JOOm4V4P4CeBfFi2N0
YZZkE1u0cildrFGQ4PRgfTNeheNvCNn4yh0q3uZjZLYmTDwYbeG29QTwRtFPE1adKS6XQUryTv3K
nxe1m217UNLktzn7PG+4nHOW46EivIdeYRw3EzH55P3aAV1Wu+G7Pwzc29hYzTToELtJKAGJJPYf
SuO1Etd3fHEcWdvp7mu/DPmorW9zGrb2jsY2nafPdzBMNhRuEY5zj2FdhpVrO1tEFtfMKdXOWXPs
vQfjUdjpDRxrcXF1LEhjBRbRwZOuSDkjHbip5L2C0tDDZCYI5yGmbLse59q1hFRM5SubltNFFHtu
bwJJnlVBbH/fPA+lFc7bWsske+SYREnIUtzj1orT3iLI9gjkxD5LwIQRggkdD2/WuU1nwRLexRpb
6zd28NuAIYJV8xUGSTg5HrXaJGI8+ZGgGcjjrUskMuBmKMLnAwc5r4qFWUH7rPVaPP8AUPC+oxaO
Yxqpu1jUAKY8ZUdl544r0P4Sw6fLodzst1idwFnjxw+0cMR/e5xnrwPSmwRyuFZivTChscj2qXw4
v9mX95ICqNIpkRRyCeh/X+dDqOa1OmjJv3WaOrwvp9yo8oNEV+V+2P8AGvEfGEbH4j2cqK292gdu
O+QOv0Fe12Us91fxPdyFmXsDgCptTvLMXLLNY2k21gVaSFCwI98ZqsLilQk5NdLFVsE56RZxPhuD
ww2q3F82nwtdylZopZHYkDHOMHHXn8a6W78UaTany2jtvmGeYs/4mkF3pkdy0w0qySYjHmCFCSB2
zis2Z/DWpeYl9o9o6k/PgFD/AOO4rali6LVq0WzWrhql/wBykivqGt6BcoLifTba44xuRQePTHX9
Kp2vi3wrD+7gs7GHJwcRqP6VNL8PfC+qKyaJdXOk3XVdkhljz7qxz+RFeX/EfwJrnhpRc6lClzZs
dq3ttnHsG7g/X866oLD11alNp9mc7qVaD/eU0/NG/wCNJdNtY59V0mVraYjcyKQ0cnsVrz9vE0jX
UckFlbF/vAMoYc9QT168jniufBlCbfMMsWc+WzdT9K0tMexnYw3Uc0DngNDyR9V4r0cNGpTXLKVz
hxM6dV80Y2Na+S41Wc3d0kCu4GFRyiqPQCitm28O6W9vHnVpOBj95bup/LFFdvJfVnJzpaHsMouC
xkRFUA4GHycU2O2uxCZEBlYHJJGM57jntU0M8irIskqvIDkFiBnJ7VLO85iSSKRTEflyr/dBHbNf
GHpeYyOPzB5buBnAZm5Pvio722htRvRn8xW5IxgDP8+BU0dw0ThHLOSPmBfHX0wPzqbVhHNYT2sc
TDzSVMg5KtwR+GaE7MuEuVpkM+qiz00v8vm/eXI5Ncdea5LNIWfg9RinakLy10RjeqxkldbaHaRk
lmAJHvVWDRL55TH/AGdK/bfKyoq9uea2hTi43bO2dbkkWYNfQIA0e8jtnJrH1TxDprz5upUsWY4D
Nv5/IGpPE9zYeFoWS8miv9Q6C2h+WGM/7bH730/MV4zrGpT6jdyTTuGZj0XgD2HtXdTwCtzS0OOe
Pk3aJ734VlJ1GFrG8juoJOjo+RXuehWtlquny2mpKs8cymJ45FyCD7V8WfDbXX0TxJblmP2eZgjr
njPY/n/Ovq7wpqam/gkRv3RbBB6g+9ctWgqdVX2N1XdWn5nyV4201NE8W6tpcQxHa3UkS854B4Ga
wnOSM/oa6D4iOZvHHiCcMzbtQnJyOh8xq1fhh4Jm8T3RvJdhsbaQBk3DdK3ULjsPU/5HrzqezheT
PLtzPQ6jw74HsL3w/p1xqF9qsNzJCGZI5BtGSSMAgkcY4or3O30pjBGSsfKgj94uenfrRXkfWqst
U2dHs4rcwoodKGd814ZM5wIlA47j5sdx1okFpJDIiTTKi/MQsS5J54xuGD0qjdXZYyxwATBxwrNg
le59Ov8AOs7TpzbWM3nLGrswAAPy4wCG44z7Z7dqxSGzp7ZIW8v9/IsOzK7oVOMEc/eqdLi1+2fu
LxopQxBBjHPAOSS3XPeuWknkeBo1d0ZQWDsNwLccYOOOtULiRlVI2bKoQzFW5Lc4I/HjPSjlDWxd
tl+0avYw3DMwS9eXJXOAASDtz6dqqfErxnBodu1rYuHvpFwzlQPLHsPX+VbkcFtFZNeSSn7Q4j2J
nnoNxHrxnNfO3jqSSTxHesJWmieTcjH37fh0rvwUIcyc1stBYqTb0MrVb+S9uGlmZpJCernP/wCq
s4mpTDKXKbGDdSCKZsbdt2nPpXoynzM5krDVJUgg4IPWvefBfjy1ivVstQcx3W1AJX+7LwMN7E9a
8HKsByCOa6WC+0y/8Mm21BGttWsgWs7uNcidM8xSDsRyVb8D2I561JVVZm1Kq6eqPQPi74WEt/Nr
+lRs9tP+8vLZV+ZH7sMdVPXP198c98LPFqaFdx6deOqafdybvNxkwv054yR0z/kV1Hwa8Wz3U0eg
6oZbvcpa2kzlo8dRn0xzz6Y9K4Txdp8cvjvU4bGPFl9tZcoMAYbDED0zms7uSdGr0Kml/Eh1PosS
LGAInhkQjI/0d2xntnAormNM1sPa7pWCEscBUJ4HHb6UV5vsn2Lv5iPay3UWx5lESNukV1wTxnGc
9PxpoEhsbmOOJHjLjDPyysPQ+mDXW6jHH9hkYhgzyLG4RioIOFzjscGpY7S2KLst4lwyqflyDken
51KnYTpXOSWUiFXLfvUwCq5Pt07Vd8JWun6hcznWLh7O2jYFI4kJeXGcDJ4Hb65q7daaIL1Y4ZAg
JwSEHPX/AAqpeLH9omiZX+dGYFWA24IGOhzTU0mNxaW5z+rTS6hrMoMbxWspbbljuAycEDoOuePp
WPNpUcduTLGpnDEbnUEnrgjuDXXCCONyJB5gfGB02jtT9P8Ast2JoZbRfkkCBt3J5A5OKr2jIabe
pxp0qEQJ5Ko886/98jHXP5/kKrHwys2WihQSBQHUxg5Oex7cV6Jd6faxWjtFEFYfMDk9s4FVooVT
T1eRpH86NSBu+4BlsA9fan7V2uhqGp5lf+FkbzI5IQrhPvJ2I9uueR+dZtj4Fm8xHupXjtmP3gu7
I9evFetNo1tOHkG5S5Cklix6Y/D7xoa2KWDqkrLsZsYA5HB5/E9farWJmtEyXBMofC3wZbaJcT6x
dxHasUiCWSRVVewULnJYnAzjHvXN3miXiXU9xJBG7y/OXB6bgST9K6+aAfvBkgRsAMH6/wBRmrti
gFuULOcsEOG44PXH5flSdZt3K5dLHnkWnXEaYayeQ5PK9BzjHT2or1X+xIpfmaeZfQI7KAPzopfW
A5ZI/9k=

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_46c69986ba35b.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgARgBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
5PwyJ7ex+zz7maNjlsY5PzdM/wC1Vi609b+5SKG1V55m27hGCSTwP8mpLPd5krSIE3Y4DZ5Hf+X5
V1fg66srKzN1qLR/bAxG1CMY9snJrwacOed72PUlLkj3KXh/w/BZ6YgZ4ZmDS4a2y4ALcjI6Hpn6
V5f8QNPz4thkktJvsLSxRRGMZVlVV3KDxjLF+uK9/wBNktryK4s/DttEV2NI6w4Qr64GOck+/WpL
r4bXd14Rv735nunCzRWrLghQQSPrgEgY9q74U1C8ou9zllU5rRaseRma41uG2is9NvI4reUFpGZQ
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
NZMkQJycknqSaKKBuTasyPyV75zRRRQK5//Z

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_46c66744cddde.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgASABk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
9t8BeErLwj4LmtLKeO+naMpPcxfJ5m3IwCDxty3fqT0zXK/EDUf7Y0CyeSaG1ijldTJKW3ENEVJV
eequRjk8/WsC2vx4WOp6fHFfGwhGIbdbrouQ3ykLn25zkHvWP4hfWtbvEk1GzgijlhT5IVw0RHop
OfujnOfagDS07W9H1DSLmHRbdtNv1szA1zOVP2sYUOJMhthIUcj5j8vsD0fw90qHxB8NoLa3G7+z
blvJj3Z6HejLjoRu4PtXn0T6VpsS3NpFJKWkWOcOMBsDkjjg5x+dexfD+Sy0tXmt222l6dzE8bX4
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
d8toJ0kZStwQGXB4H0/rmiiigD//2Q==

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4635b0030022e.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgATwBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
861n4Sarp+3Go6WzFCVjaYo0hHZQRzR4Y+Ht2bO5u9Ut7mVhtSG1tZMszFgNzEZG3nsf5V6x47tv
IvdP1aWyS6trUMsu2MvIinuBkZH48fiawNF+LGgwXZNw11HbHHymzAYj1JEhBxXm5ZjauNo87d31
02PUxlCODkuVaPzNaTwXJpvh9bmyt3toocOY2id3HbOAcnjr9RzgVj3UcctxeWBKXsETGJ3C7d3G
clM5Xg9ehxxXstleW3iLR7fV7WYTabMrKkq7lXAbHIPIORivHfF3h5LGGPXopDsgmNrLKrH5l/h3
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
1Bxeo05SWxy20DrRUpX+8nNFLlZNpH//2Q==

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/443/th_477e3d7e20080.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAUABk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
+aYxItswZCrREEcdc+tFmY3lxIGUA52jp+JpFDxjeh+b35qWGIzK7SH5z/F6+1Zkml54ztaNXY4O
0kY4qlc2zxS79o2yHhSwPNLb20zvtiiYnHPHBrTgaWx3JOFZSCVGQcdf61j8D90W2xmpY3udmyRV
5zngdzSNbiICSdGVCepPynrWibt3kUZYADjHpTXkd0mg3ja4yQP73XNHPK+orsQTKNPjGwrA3LBe
7Z4+vFK0N2bWM7WaLHHlnfjPPOOlVnhYKPMJGPugVasrOYJ5ySPGingg4xn0pN21uMrXVnIkgkj3
mLgFi3I/rXQ+GVuZ8W0UatdQRvLBv52qBlwc9MDLD0+b1qvNqKZt4TZB5C4JZTl5PQCvoXTPBtl4
e8BTQ6lboNb1NA1ztYb416+Vn0HGSO59AKcFKorSWgR1dmeHQSfa4NRT986J8v2peW35DcdAQMet
VNWs7Oxtll1WKS9ec5WW3cKrKP4s4yCDwVP8sVNcJf2cjWkMc/2NZPnaPo3qOOnf3rvPhz4e8O3+
ma3a67NdC2kI8pc+W2TnLr1w2MAjleBkHjF+xUlpoVNJbHiMkNqzkpeLGh5VSpJA98UVqatpUUGq
3kFmRNBFM0auyNkgHAzgEdMHj1op2t1/In5lGG3lnUAR4QfxdBycVpiCGBo1MocD5W+uPQ1em0x5
YokjjEYUdQxqG10cxgvLu8zn7pyPx9q5nVUuom7lZ7x51WK3gKOmEZwOB0xz61SnnVJGS5UllyM9
wc+nf6V0MOnXExEKROzOw/dw5BdugxgZ/KtdPhpfWl/NF4kmNm8Sq/kt9/5gCoz0HUAnnB685qqf
K72HGN3Y4e0i86ZB5ixp1EhB6fStey08yz5eG4aKMYcohyW9hj6V30q+HILYBEPnw5Ak3b8jB5Ge
fTPHWtfRIba/tmiiUxzJz5qnLcgHt6g9MCiV92aqi31PKJRFaur3UMhJzlHjII+meKS10/XPEMy2
unWMzq7hY1ChRk8BdxwK9c1T+0Irryo9u4EFSqjO36fT+tRpOykXCKYrwElHjGMsGznjv1/OnBRT
TsP2CWtzf+DHwa1XQ9VTX/GdukUlom60tjIshEhzh2wSBtHIHqR0289He2t3ZacYNQu2uroFyZTz
uBY46+1dv4b8QPrHh22vhIGdo8SgjuOD+orkPiRdx2kEk8arnBG33Art0irmSPmHxveSX2uTSJIE
W3k2Ko4yRwWPvn9K55b65t55VEknz88MeD9K64aK8jSSzMrszGTLDJB60NpOHysQYv1VVwB/jXA8
TG4nI52PUleKPz7YO4GNwZhn6470V10sJQqtvpsboBjJkK/oKKz9pF9PxJs+xeVFOFJx0znpUqRD
JyB0q1FFAyEgsqf3sdafHFG7bBIRngDHFcPOyT3L4PeGNO0vQoNXuoI21S4BlSV8ZhQ8Dbnpkc56
84rzv9pLWJTqelW8LfeVyWHVhuXA+nWvU4rgWOk2VkgYbIUjz/urjBryb4tIbjWdN1DzEkmhQpBG
RwGDZ3Eeg4wO5PtX0EIqFNJGkU7nl91oOptbh5LG6Yy8lgCAMnPfvzWlp2ppYyNaXa3FukjDnaRk
DGB78Ct6JnCCS7kMs5HMkjZYmnp5MgYFVLKcNkZGP/1150sZBS5Wi+ezD7XdaxPHdWCO0cSsqg/x
Ke9ZP9oX1ta7L2N45I2xkg5OOh5rpdNuorScbUUw7TgICMdOw/GtWe+0u8BjngEwbg7hkDBHTP8A
T0rpg6dRXgy1Ns3PhNrjC3vbCQnEIEi47buv4ZGfxqf4gCGTSJVdn80Ecg9eax/CNkukLe3VlL5k
d1KoCgfdA6j/AD61T8Y3rSSiAliVPr/nuP0q60+Si7mct7nIMqRk7TjnP4U7dDwd2SOhX1q4YY3G
XyfXpgf55p0MUDrtQ4BHAABrwmyNBtppct3D5kEJkTONwYDn8aKsRgKoMM88athsLkdutFTdhoUF
S3aQKI3ChgCccf8A166TwfoH9rarCPLPkRMHmk6KiA5Iz6nOB/8AWNQ+D/Dra2txLNcpFb2+3zVV
gM5z3PAHHvn9a62PVtPsGXRtGOxSdrTEZAb125yT7sc4HbpXXh8NzWnUdl+ZKjfU2PEGpK1w8jMU
hjGXPb6j/P4V5XrFydW1iS5GVtx8sYY/dUf48n8a0tbvg4kgsJPMX7rTucsceg9/8+pw1tZM483c
OmB/n/Oa68VjVC8IbmnOo7blhoY2lUuxfPUnnHtSyCJiN7v8oxgH9Kijgwdu7J4xk5PXr+tJHEy5
II4yevWvFu73ZjcQxIgR18057A8U6FFlL7xtPbJ7dqkhVnLB8FBgcnGP8/0pUhLkEuq5O3g54+v6
0JvdAd18PNRC6Ne2zhGEbj7y9jXJeLPIk1oEMFDAsM5/vtWp4Mi23dzbSjMcqAt24DcH9aZ4x09h
qUEgVS+woSw5OHb/ABr1JS5sGm+hbfunJtHHNESJE2n+EnmnrCtrKHG1cY+7xjjmrOwg4dVHGQdo
60nkhEBSIDccY298Zry+ZMkVGgC48wj2Pb9KKaYEkJaRCGJ7JRSuBueDZiNL16NInVmgWYhl4+UP
+uSDXLx6jJDdq4icshBZtjFcZ9cdD0r0nSJJNLmZxaJOkg8qRFHLggnvjviqdxbQTlmtrPyU2j5G
2kbu+OTx+Ne88InGMb7GvIctqNo0Ma30UUkltKiuZFQsgIHcgcHoayYtQhgjDqGDEfN8p6elddca
E8ksj+dOm7BKRyFQflx+HGRVh7B448FhjPAAH+FRPBKcnK9gdNNnDxalBNINvmMynjIx/ngirKXE
SttZtp6bTnP5H2rr108l9qvECctgY/pThpnzA7kyOBkgelZ/2dH+YPZI4X7XacOZN2RuKZ9/5VYa
eyaWN97A4ADFsYI9uma7SbRBJG8cjKY26jHB7+lDaFGItq7SucEBR/hS/s9LqHskZXhDXNPtdWE8
8/7qRfLV1IIB4wD6dK6Xx3azlHuYtzyQsJCEGT5T4wR7BuPrWa2hRqM/u1A+VQFHP0roI9T1SOC2
gkis5fIGyKbO2QLjGCdvr9O1dMMMlSdJvRjcNLI8xW9Alw3mR4PAZfwIqa41GGNXdriMKAcljjb+
P1rrpNIhuHeS52SSynMreWuX4xztAzTG8OaeeDDErIcAjgVy/wBneYvZLucol8hGM7scZGefyorr
/wCw7JWbZBGATnjjP60Uv7Nf8wvZruf/2Q==

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/1911/th_48a00465b3d95.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
9c03wVpWnWUUUUKzOV8uSZ1BLev48nmrsulaTHdx2/lKGXoGXjgDOD09K0Wn3IDCd3bk45x71JOw
kiRMKZ89SMbQcd+f/r4r5jm5nuWm+jOH1nwLYXrMyCIYk835ECuGHIBOOR7Vk+JfBQN+LgOSGcTu
M4DNu5zxg5r0OJJU5EMgRG8sqQORnk9e/WtZoopIwkpDYxjIyRTUmupaa6nHeEPCEOk7nWMgDCI2
cfKcnp0681tXmkxXsbia2gkJUxbnGSyk5bqOnt/hW05h84KrkOVxgnGajSLypSUXHHXrUSk2wbuY
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

------=_NextPart_000_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/76/th_477a597979896.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgATgBk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
4TTNGGoSOI1jDgYjWMgdSenr161amtbfSQZ54JvtaIwRWbAX1zx1Gev/AOuupsdD0zwDZLe+JNUx
cK+6IRsc5H8IUfe9x/KvPPiF4ybxXdwR2iSQWcGcI7/NIx7kDgew57159OUqs/d+HuT7LTXc6Tw9
44gm16ytJVTDnYJ5uVjJ7jn8Pxr0S+uyj3Asn8rG3MnlgrkE8e3GP1r5rt2YXsBDIGQjkdOD/OvY
/D+qreaeZI5EnnCFDE7H5h2x6Hp3wfrwdKlBbxCUbIo6kjpqCPYxyXEsjDaqcDk46/WtHxVpWrPp
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
lP/Z

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/76/th_477d6c15107f7.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
7e/1S4h1H7LBHGBs3+Y6lh244I9ayLnxDqKLK0a2reWxUhomHT/gVcx4d8ZnXtRf7WkMEwT5UAPz
9Oh7d+KzNb8Wx21/dWiWxch8FgcAj16c0pYqbm9dDeNOiqak0dLoPj25vtTm0++t7eCdRuRl3MHG
cdO3r1rovDnizTNcWYQTCOeFtskUhAI9/cV4pot69l4mWeNYJ96JuaXJCKWBJHPBArptJ0zw7pWt
yX51Od3DFjGR8h3Z4yBz/wDqrZYtwfvMxdKMlpoexpeW3P8ApEWf98Un22HJCSKcehrgYdc8OXM7
xrdeW7SCUB2K5YdAM9vbp7VqWviTw9b219bPdAXC5dcjOTjJwfTtis549te7oXDDU1q3c6gX8WR8
wBPTmnJfoyBhjntmuHHi/QLO4tZmuRcwyZeVVyGTHqD6n9M1bl8feH5vPNorTSSf6tSNmOueT9P1
rL65U7mjpUNjrpL9EIHGSPWol1IMuRtBzgZbGTXA+JtRute0+P8AsW9i08x25MybG85n7IvHfgAj
ms7SG1vWrBtOgnuCgtHkimOzdIyjIXnnJ2t+OK0jiKk9mJ0qS6HpFvdX01/cWvlSZhRGJUrzuz2P
09e9ZfiXUtS0+0kmtnd9ik42qQCOx4rzrw18QtS0mCKG8LXLRfK7SHDso7NnkkdM13D+INK1XRTd
RyiNZc5jd+d3pWP1ionuVCNGa0R0fhy9uLzRLWe82/aHU79owM5I6UV5PZ+PLzTYBaQzWxiiJCZj
ycZ453CivTji421POlS1OEkvysuYtqNgYYACktbyNy4OSQOW962hoNjPGm5jt2nnOMmrFt4a04DY
HO7J25cdK8W8EjsdOTOVlnHEchYDqMDmoZp5WkDKGwBxyRj8K9BTw3Y5UHnbkHnrUw0y3tgfL8hy
e0q5I/Sl7aHQPYSPNxG5UM4LEcjPenrdTISHH7w+nPFehtdWqO0t5AssMa7nFug3BR1AHArIhvbW
/tpENxHCzsfJKrtOMcZHf+dapt6tB7HXc413uZCMxSH0yKmgaeKaNTlGHAHU/lXbJptnaSRxahci
STCsJ04ZNwGABnkDvWtpiWtrqpmVRI4UqgbBD5GQfr1qnrpYpUO7L/wK0a51fxXNfStJ9msImwrD
h3PGPwzn8qj+IttN4F8TXFzo/kpFqEUiCNs4i343YweD6ema9P8Ag3aaZEdT1OGVo7y8kO6zI2+V
0JwO+eOa8x+LTLr3iiVfPEcNv8qgqTk9z/SrVoRuDjbRHkwhmWUvN8+/ljncWo+15AS3MyKWz5YO
Ax9eK7BdBglACSF/lx8o/nUcHhcoyKATIM8gHp27cYrH2kXqzP2TOZESSjdOpV/TiiulfQrhGIjk
j2+4/wDrUUva+YezK8kckjJ5bO7/ANwAjn/IohjuwDIx2jJ288nBrq7PTIpbUXEW8+WQwKjkfUnI
AwOg4qC6ltrcxGM7nU7AGT5cnoRmuGGK53ZI6ZUratlG3up9oAJZgRzV2AySu4nnWHg72OPlAPzf
oDTYGijgCna7hmYgcZ6HJHU+lZmvXqLp32TaIVkxgA8n1J/X860p3nNLl6jckluVbidZbeG2tHMf
mMTjHIDP3/Aj8Kz9G0iGW0MspmaUMQhWUIMZx6H0qtukSya6x5byYhgRfvSnuR7Afriui0lWgs7e
Lb86r8xyOCa76suSOm5impPUrXOjanqTOTfQ/aAnyLKxVnx0AOMZ7dvwqu5vLxreC1SZ7+NclFyW
UqT2/HFbO18ANlm6nJ+tWNLvbuwu5pLZminKjEgAOB6ZNZRrr7RViza+I5tLWNS8ltqESKqsp2sn
OM898dvQ+1ZtvrV9dzS3R/eGeQKTtAzycH61B4xZ7i1hu52Z7u5JDzd3AJ/wxVjS7h00m2jULtjG
VDKCM9e/Hf8ASirKSpe71YN3mXILxJGUlUz1K7SOae2pnJVxIcns55/Kqc7PKYyqYwMAAYx7mqoQ
h/nkCqfmO7jPtXMttQbNGS5jDn90v/fRoqS308TpvF5AozgbwQSPcCisnVpr+n/kV7OTEQw71BZy
yYAQsRuPQkEYwMkd81HqV0ZreOICVIBIG2M/YdccfSqBjuBtLyEIpyUHIOMEZFILgmFWZeTwWJ6Y
Hb/PrQqKvzMpz0sdf4J0rTtUvHuL95IrSzhV5NnUHd09QOazvHtpos91E2kWMjRsGCSSu5VQGxhV
wB79T155o0nUUi0zXbZXjS4ubQLDk7dz7unp0J61hve3B01bCUMdreapV/u5HI6YI+ldVOSpxuiH
a1mVLdDAMyJCSg2oSeQP8OabLNi4MjvCSCVIVv1xxVjT9JRpibjzX3jIVjhQOtRpoNhJctJJkNuL
Bgcjg/4UnKLbbZPK+haa9txb5SaPngk5P4VWOsQwNG7h/LViuNv3jtHH6ipFi0+aVlSICTGcgcA5
HT8qW9aGRreAx/MpPybep7/X/wCtUe6mPXoztdKurHxB8LtfMEG2Sz5BdPmUcNwfTivOv7Yt7IpZ
zKEljwcnPOVBH4ciuo8Pa2mm6VqukmNEj1FBG/ykMpIIyMex/SuZ1fQYb27SfcFXyI43GerKgUsD
77c/U11KdNw5WZy5m7ouafei4l2qwCqCzPnovbA/GlM6NIsLNl8Hn19KpW2lw29p5XMfmtjIJzjP
8qmfSVjkWSK6m3g5wzde3+NYvl7jXNYviOaD5PKU9+TmirMdv+6TMjDjHG3+tFQmitTFlvZHHl9A
zqTj1BqyyKIYNuQG3ZHX3oooegJ7kd5F5UWVb5Qw49zx/Sp4IRKFkkLEABgoOKKKE/dLa1HXrM5E
asUDLnPXtmr2i2wFk6zt5o3FDxgnj8aKKh/CaU0nIybm38l2uUfABICY4xk0yJ5RdBi4y6k8DGOt
FFWtURtIJT9nukeTMshGQeAB+GP61uEjyoXCLtOMpjjkf/W/WiilNEsbpcQuTI7k52tsz/ARzn9a
r6ndbWYRRohjBOcZycZoorOLvKw4pctzJmupiULNkleuKKKK1OeTdz//2Q==

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_4725f4130ce45.jpg

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcg
SlBFRyB2NjIpLCBxdWFsaXR5ID0gODAK/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcU
GBgXFBYWGh0lHxobIxwWFiAsICMmJykqKRkfLTAtKDAlKCko/9sAQwEHBwcKCAoTCgoTKBoWGigo
KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo/8AAEQgAUABk
AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMF
BQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkq
NDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqi
o6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/E
AB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMR
BAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVG
R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz
tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A
43xJeNbWUckt1PZSySJaweZuLMF/1kzrk8cnHBNen22o6/o/wnaxtzNrGot8ltNbxM4MTc5BGSQB
nB9wK+YLq9ub1BFJtcx/cAUAj16den6V798DPHsOh+HL/TXezXy5RNCLu5EAIZeQMjple3rUUafs
7uW5315c1orZHCnQ/E0ce9tH1SKHG5g1s+AO56cVS0/VLmwuFmgdkl5GQQc47EV9ISfFa3+z4SPT
GulY7h/acRi2juG659tv41y3iS/8F+KIhcXsGk2+o8NJLBdqD0OcsvXnbyR3qXSS1izLmb3RheGt
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
dGjZM//Z

------=_NextPart_000_0000_01C96ABD.6A624C80
Content-Type: image/jpg
Content-Transfer-Encoding: base64
Content-Location: http://thewhippetarchives.net/pics/thumbs/th_46fe6ab932fcb.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
81vvD/iBpIgNJuMpBEpOMDOxc/rmqE/hPxHMny6VKpHcuq4/M19BXdrcwyYkKPtwD8pzx9Dx0rkf
E0HiTVjNpWlaROtpImJboRyN5qkcqhXIGemTjr261xxxEqkuWMV+P+ZxQjrsef8Ah/XfInltvGN4
95bO6p5ck5uBjPzYKkjuD17V7vqErajp8tlaRGC2nAiRw6GOOMAKp4bJ+XsB+deJQ/C7xLDeW9zq
mizQadFMvmGVs/JuHBx69M8V9NXmgWE/h21u9BtVijgQK0CZ+7j+n8vpV4lPlvDVmsqS3PnjUvh3
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
2Q==

------=_NextPart_000_0000_01C96ABD.6A624C80
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 TH {
	WHITE-SPACE: nowrap
}
#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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
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_0000_01C96ABD.6A624C80
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.widget.DS_XHR.prototype.TYPE_FLAT =3D 2;

/**
 * Error message for XHR failure.
 *
 * @type constant
 * @final
 */
YAHOO.widget.DS_XHR.prototype.ERROR_DATAXHR =3D "XHR response failed";

/************************************************************************=
***
 * Public member variables
 =
*************************************************************************=
**/
/**
 * Absolute or relative URI to script that returns query results. For =
instance,
 * queries will be sent to
 *   <scriptURI>?<scriptQueryParam>=3Duserinput
 *
 * @type string
 */
YAHOO.widget.DS_XHR.prototype.scriptURI =3D null;

/**
 * Query string parameter name sent to scriptURI. For instance, queries =
will be
 * sent to
 *   <scriptURI>?<scriptQueryParam>=3Duserinput
 * Default: "query".
 *
 * @type string
 */
YAHOO.widget.DS_XHR.prototype.scriptQueryParam =3D "query";

/**
 * String of key/value pairs to append to requests made to scriptURI. =
Define
 * this string when you want to send additional query parameters to your =
script.
 * When defined, queries will be sent to
 *   <scriptURI>?<scriptQueryParam>=3Duserinput&<scriptQueryAppend>
 * Default: "".
 *
 * @type string
 */
YAHOO.widget.DS_XHR.prototype.scriptQueryAppend =3D "";

/**
 * XHR response data type. Other types that may be defined are TYPE_XML =
and
 * TYPE_FLAT. Default: TYPE_JSON.
 *
 * @type type
 */
YAHOO.widget.DS_XHR.prototype.responseType =3D =
YAHOO.widget.DS_XHR.prototype.TYPE_JSON;

/**
 * String after which to strip results. If the results from the XHR are =
sent
 * back as HTML, the gzip HTML comment appears at the end of the data =
and should
 * be ignored.  Default: "\n&lt;!--"
 *
 * @type string
 */
YAHOO.widget.DS_XHR.prototype.responseStripAfter =3D "\n<!--";

/************************************************************************=
***
 * Public methods
 =
*************************************************************************=
**/
/**
 * Queries the live data source defined by scriptURI for results. =
Results are
 * passed back to a callback function.
 *
 * @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.DS_XHR.prototype.doQuery =3D function(oCallbackFn, sQuery, =
oParent) {
    var isXML =3D (this.responseType =3D=3D this.TYPE_XML);
    var sUri =3D this.scriptURI+"?"+this.scriptQueryParam+"=3D"+sQuery;
    if(this.scriptQueryAppend.length > 0) {
        sUri +=3D "&" + this.scriptQueryAppend;
    }
    //YAHOO.log("Data source query URL is " + sUri);
    var oResponse =3D null;

    var oSelf =3D this;
    /**
     * Sets up ajax request callback
     *
     * @param {object} oReq          HTTPXMLRequest object
     * @private
     */
    var responseSuccess =3D function(oResp) {
        if(!isXML) {
            oResp =3D oResp.responseText;
        }
        else {
            oResp =3D oResp.responseXML;
        }
        if(oResp =3D=3D=3D null) {
            oSelf.dataErrorEvent.fire(oSelf, oParent, sQuery, =
oSelf.ERROR_DATANULL);
            //YAHOO.log("Data source for " + oParent.getName() +
            //    " experienced a data error for query \"" + sQuery +
            //    "\": " + oSelf.ERROR_DATANULL, "error");
            oCallbackFn(sQuery, null, oParent);
            return;
        }

        var resultObj =3D {};
        resultObj.query =3D decodeURI(sQuery);
        resultObj.results =3D oSelf.parseResponse(sQuery, oResp, =
oParent);
        oSelf._addCacheElem(resultObj);
        oCallbackFn(sQuery, resultObj.results, oParent);
    };

    var responseFailure =3D function(oResp) {
        oSelf.dataErrorEvent.fire(oSelf, oParent, sQuery, =
oSelf.ERROR_DATAXHR);
        //YAHOO.log("Data source for " + oParent.getName() +
        //        " experienced a data error for query \"" + sQuery +
        //        "\": " + oSelf.ERROR_DATAXHR, "error");
        oCallbackFn(sQuery, null, oParent);
        return;
    };

    var oCallback =3D {
        success:responseSuccess,
        failure:responseFailure
    };

    YAHOO.util.Connect.asyncRequest("GET", sUri, oCallback, null);
};

/**
 * Parses raw response data into an array of result objects. The result =
data key
 * is always stashed in the [0] element of each result object.
 *
 * @param {string} sQuery Query string
 * @param {object} oResponse The raw response data to parse
 * @param {object} oParent The object instance that has requested data
 * @returns {array} Array of result objects
 */
YAHOO.widget.DS_XHR.prototype.parseResponse =3D function(sQuery, =
oResponse, oParent) {
    var aSchema =3D this.schema;
    var aResults =3D [];
    var bError =3D false;

    // Strip out comment at the end of results
    var nEnd =3D ((this.responseStripAfter !=3D=3D "") && =
(oResponse.indexOf)) ?
        oResponse.indexOf(this.responseStripAfter) : -1;
    if(nEnd !=3D -1) {
        oResponse =3D oResponse.substring(0,nEnd);
    }

    switch (this.responseType) {
        case this.TYPE_JSON:
            if(window.JSON) {
                var jsonObjParsed =3D JSON.parse(oResponse);
                if(!jsonObjParsed) {
                    bError =3D true;
                    break;
                }
                else {
                    // eval is necessary here since aSchema[0] is of =
unknown depth
                    var jsonListParsed =3D eval("jsonObjParsed." + =
aSchema[0]);
                    for(var i =3D jsonListParsed.length-1; i >=3D 0 ; =
i--) {
                        // eval is necessary here since aSchema[1] is of =
unknown depth
                        jsonListParsed[i][0] =3D =
eval("jsonListParsed[i]." + aSchema[1]);
                        aResults[i] =3D jsonListParsed[i];
                    }
                    break;
                }
            }
            else {
                try {
                    // trim leading spaces
                    while (oResponse.substring(0,1) =3D=3D " ") {
                        oResponse =3D oResponse.substring(1, =
oResponse.length);
                    }

                    // zero response
                    if((oResponse.indexOf("{}") =3D=3D=3D 0) ||
                        (oResponse.indexOf("{") < 0)) {
                        break;
                    }

                    // eval is necessary here
                    var jsonObjRaw =3D eval('(' + oResponse + ')');

                    // eval is necessary here since aSchema[0] is of =
unknown depth
                    var jsonListRaw =3D eval("jsonObjRaw." + =
aSchema[0]);

                    for(var j =3D jsonListRaw.length-1; j >=3D 0 ; j--) =
{
                        // eval is probably not necessary here
                        //jsonListRaw[j][0] =3D eval("jsonListRaw[j]." + =
aSchema[1]);
                        jsonListRaw[j][0] =3D =
jsonListRaw[j][aSchema[1]];
                        aResults[j] =3D jsonListRaw[j];
                    }
                    break;
                }
                catch(e) {
                    bError =3D true;
                    break;
               }
            }
            break;
        case this.TYPE_XML:
           var xmlList =3D oResponse.getElementsByTagName(aSchema[0]);
             for(var k =3D xmlList.length-1; k >=3D 0 ; k--) {
                var result =3D xmlList.item(k);//doLog(k+' is =
'+result.attributes.item(0).firstChild.nodeValue);
                var aFieldSet =3D [];
                for(var m =3D aSchema.length-1; m >=3D 1 ; m--) =
{//doLog(aSchema[m]+' is =
'+result.attributes.getNamedItem(aSchema[m]).firstChild.nodeValue);
                    var sValue =3D null;
                    // Capture each data value into an array
                    // Data may be held in an attribute...
                    var xmlAttr =3D =
result.attributes.getNamedItem(aSchema[m]);
                    if(xmlAttr) {
                        sValue =3D xmlAttr.value;//doLog('attr'+sValue);
                    }
                    // Or in a node...
                    else {
                        var xmlNode =3D =
result.getElementsByTagName(aSchema[m]);
                        if(xmlNode) {
                            sValue =3D =
xmlNode.item(0).firstChild.nodeValue;// doLog('node'+sValue);
                        }
                    }
                    aFieldSet.unshift(sValue);
                }
                aResults.unshift(aFieldSet);
            }
            break;
        case this.TYPE_FLAT:
            if(oResponse.length > 0) {
                // Delete the last line delimiter at the end of the data =
if it exists
                var newLength =3D oResponse.length-aSchema[0].length;
                if(oResponse.substr(newLength) =3D=3D aSchema[0]) {
                    oResponse =3D oResponse.substr(0, newLength);
                }
                var aRecords =3D oResponse.split(aSchema[0]);
                for(var n =3D aRecords.length-1; n >=3D 0; n--) {
                    aResults[n] =3D aRecords[n].split(aSchema[1]);
                }
            }
            break;
        default:
            break;
    }
    if(bError) {
        this.dataErrorEvent.fire(this, oParent, sQuery, =
this.ERROR_DATAPARSE);
        //YAHOO.log("Data so