.WAFL (l E.ӵAM7)M!a'ntry(|P.%}6NLh.ӵAM7)M!a'url >http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime text/htmlhntt"da00c6-b8fa-a8504200"hvrsdata NASA Makes A Heated 3-D Look Into Hurricane Erin's Eye

Science News

NASA Makes A Heated 3-D Look Into Hurricane Erin's Eye

ScienceDaily (Oct. 11, 2005)

Hurricane Erin raced across the North Atlantic and along the eastern seaboard in September 2001. She was used as an experiment for a study to improve hurricane tracking and intensity predictions, allowing meteorologists to provide more accurate and timely warnings to the public. Studies show that temperatures measured at an extremely high altitude collected from a hurricane's center or eye can provide improved understanding of how hurricanes change intensity.

Hurricane Erin was analyzed during the fourth Convection And Moisture EXperiment (CAMEX-4), which took place from August 16 through September 24, 2001. The mission originated from the Naval Air Station in Jacksonville, Fla. The mission united researchers from 10 universities, five NASA centers and the National Oceanic and Atmospheric Administration. CAMEX-4 is a series of field research investigations to study tropical cyclones — storms commonly known as hurricanes.

Twenty instrumented packages, called dropsondes, were dropped into Erin's eye by two NASA research aircraft (the ER-2 and DC-8). The special packages included instruments that mapped temperature patterns.

For the first time, researchers were able to reconstruct the structure of the eye in three dimensions from as high as 70,000 feet, down to the ocean surface, in great detail. The dropsondes showed Erin's warm core decreasing while it was rapidly weakening, making the storm more vulnerable to wind shear, a change in horizontal winds, which led to the storm falling apart.

Hurricane Erin's rainfall pattern adjusted quickly to surprisingly small changes in wind speed patterns in the surrounding atmosphere. Weak horizontal winds rearrange rain and wind structure, which create uneven weather conditions around the hurricane's core.

Observations from the study show the relationship between warm air from the eye of the storm is linked to reduction in sea surface pressure, which is the basic process that drives the hurricane's destructive winds.

Although little is known about the birth of a hurricane and what causes it to strengthen or weaken, scientists have made substantial steps toward improving predictions of where a hurricane will move or make landfall. The ability to forecast intensity change, however, has always been a challenge for meteorologists.

The research done on Hurricane Erin was important because it could help forecasters understand factors that control rain intensity and distribution for hurricanes landing along the Eastern Seaboard.

Freshwater flooding is the number one killer from hurricanes in the Western Hemisphere and the study of a hurricane's rainfall pattern could better prepare us for the next big storm.

This research paper, titled "Warm Core Structure of Hurricane Erin Diagnosed from High Altitude Dropsondes During CAMEX-4" by J. Halverson et al., is going to be published in an upcoming issue of the American Meteorological Society's Journal of Atmospheric Science, CAMEX Special Issue, at the end of 2005.

Adapted from materials provided by NASA/Goddard Space Flight Center.

APA

MLA

Search ScienceDaily

Number of stories in archives: 44,032

Find with keyword(s):
 
Enter a keyword or phrase to search ScienceDaily's archives for related news topics,
the latest news stories, reference articles, science videos, images, and books.
 

Science Video News


3D Hurricane Tracking

Meteorologists have developed a new method for analyzing hurricane strength. A series of mathematical formulas transform data from Doppler radars. ...  > full story

Breaking News

... from NewsDaily.com

In Other News ...

Free Subscriptions

... from ScienceDaily

Get the latest science news with our free email newsletters, updated daily and weekly. Or view hourly updated newsfeeds in your RSS reader:

Feedback

... we want to hear from you!

Tell us what you think of the new ScienceDaily -- we welcome both positive and negative comments. Have any problems using the site? Questions?
Post this page to your favorite social bookmarking site:
close
Include this item in your blog or web site:
close
Cite this article in your essay, paper, or report:
close
Email this page's link to a friend or colleague:
close
post.ӵXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate |P.ӵL3Hntry('KnׂW9lt]ziiVurl -http://www.sciencedaily.com/styles/main6.cssbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime text/csshntt"7f188e-55b1-589db80"hvrsdatahtml, body { margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; color: #000; background: #fff url('/images/top.gif') repeat-x top; font-size: 13px; line-height: 1.2; } #wrapper { width: 1000px; text-align: left; margin: 0 auto; } #content { display: inline; width: 678px; float: left; margin: 92px 0 0 6px; padding: 0 0 10px 0; } #date { text-align: right; padding: 0 0 10px 0; } #textsize { text-align: right; height: 20px; } #title { width: 1000px; position: absolute; top: 160px; margin: 0 auto; } #titleleft { display: inline; width: 678px; float: left; margin: 0 0 0 6px; } #titleleftcontent { padding: 0; } #titleleftcontent h1 { font-size: 20px; } #titleright { display: inline; float: left; text-align: right; width: 310px; } #titlerightcontent { padding: 0; margin: 6px 0 0 0; } #titleside { display: inline; float: left; text-align: right; width: 310px; margin: 6px 6px 0 0; } #titlesidecontent { padding: 0; } #top { border-top: 1px solid #000; } #topleft { display: inline; width: 344px; float: left; } #topleftcontent { margin: 10px 0 0 0; } #topright { display: inline; width: 334px; float: left; } #toprightcontent { margin: 10px 0 0 10px; } #mainleft { display: inline; width: 276px; float: left; } #mainleftcontent { margin: 0; } #mainright { display: inline; width: 240px; float: left; } #mainrightcontent { margin: 0 0 0 10px; } #main { border-top: 1px solid #000; } #mainmenu { display: inline; width: 130px; float: left; } #mainmenucontent { padding: 8px 0 10px 0; } #mainmenucontent ul { } #mainmenucontent li { padding: 0; } #mainlist { display: inline; width: 548px; float: left; } #mainlistcontent { padding: 8px 0 20px 10px; } .botleft { display: inline; width: 222px; float: left; } .botleftcontent { padding: 5px 0 0 0; } .botcenter { display: inline; width: 228px; float: left; } .botcentercontent { padding: 5px 0 0 10px; } .botright { width: 224px; float: left; } .botrightcontent { padding: 5px 0 0 10px; } #side { display: inline; float: right; width: 310px; margin: 92px 6px 0 0; } #sidecontent { margin: 0 0 10px 10px; padding: 5px 0 10px 0; border-top: 1px solid #000; } div.leaderboard { display: inline; float: right; width: 728px; height: 90px; margin: 0; padding: 0; border: none; } div.rectangle { width: 300px; height: 250px; padding: 0; margin: 10px 0; border: none; } div.skyscraper { float: right; width: 160px; height: 600px; margin: 7px 0 10px 5px; padding: 0; border: none; } div.custom { height: 5px; } #header { text-align: center; height: 93px; padding: 5px 5px 0 5px; margin: 0 0 -3px 0; } #headercontent { width: 990px; margin: 0 auto; } #footer { clear: both; width: 100%; padding: 10px; margin: 0; text-align: center; font-size: 13px; background: #ccc; } #footercontents { display: inline; width: 1000px; margin: 0 auto; color: #000; } #footercontents a { color: #000; text-decoration: none; } #footercontents a:hover { color: #000; text-decoration: underline; } #searchcontents { display: inline; padding: 5px 10px 0 0; float: right; color: #fff; font-size: 13px; background: transparent; vertical-align: middle; line-height: 15px; } #searchcontents a { color: #fff; text-decoration: none; } #searchcontents a:hover { text-decoration: underline; } #searchcontents input.searchinput { width: 230px; height: 17px; padding: 2px 0 0 2px; margin: 0; border: none; vertical-align: top; } #navbar { width: 100%; position: absolute; top: 97px; left: 0; } #navbarwrapper { width: 1000px; margin: 0 auto; } #navbarcontents { width: 660px; margin: 0; padding: 0 0 0 5px; background: transparent; } ul { margin: 5px 0 5px 15px; padding: 0; } li { padding: 0 0 5px 0; } ul.black { margin: 5px 0; padding: 0; list-style: none; } ul.black li { padding-left: 12px; background: white url('/images/bullet_black.gif') no-repeat; background-position: 0 3px; } ul.white { list-style-image:url('/images/bullet_white.gif'); } /************* Son-of-Suckerfish Horizontal Menu **************/ #nav, #nav ul { float: left; padding: 0; margin: 0; list-style: none; font-weight: bold; margin-bottom: 4px; font-size: 13px; background: url('/images/blank.gif') repeat-x bottom; line-height: 15px; } #nav a { display: block; width: 116px; color: #fff; background-color: #000; background: url('/images/gray.gif') repeat-x bottom; text-decoration: none; padding: 3px; } #nav a:hover { color: #fff; background-color: #900; background: url('/images/red.gif') repeat-x bottom; } #nav li { float: left; padding: 0; width: 122px; margin-top: 5px; margin-right: 10px; } #nav li a { text-align: center; vertical-align: middle; } #nav li ul { position: absolute; left: -999em; width: 155px; font-weight: normal; margin: 0; } #nav li ul li { background: none; border: 0; margin: 0; } #nav li ul li a { font-weight: normal; background: none; background-color: #ddd; color: #009; text-decoration: none; text-align: left; } #nav li ul li a strong { color: #900; } #nav li ul li a:hover { color: #900; background: none; background-color: #fff; } #nav li:hover ul, #nav li.sfhover ul { left: auto; } *:first-child+html #nav li:hover ul, #nav li.sfhover ul { position: static; } #sections { position: absolute; top: 125px; left: 0; width: 100%; border-bottom: 1px solid #fff; } #sectioncontents { width: 77em; margin: 0 auto; padding: 0; } #sectiontabs, #sectiontabs ul { float: left; list-style: none; padding: 0; margin: 0; font-size: 13px; line-height: 15px; } #sectiontabs a { display: block; width: 9em; height: 15px; padding: 2px 0; text-decoration: none; } #sectiontabs li { display: inline; float: left; padding: 0; margin: 5px 4px 0 4px; width: 9em; } #sectiontabs li a { color: #009; background-color: #eee; text-align: center; margin: 0; } #sectiontabs li a.thissection { background-color: #fff; color: #900; } #sectiontabs li a:hover { color: #900; background-color: #fff; } #sectiontabs li ul { position: absolute; left: -999em; width: 155px; margin: 0; } #sectiontabs li ul li { border: 0; margin: 0; width: 155px; } #sectiontabs li ul li a { width: 145px; background-color: #ddd; color: #009; text-decoration: none; text-align: left; padding: 2px 5px; } #sectiontabs li ul li a:hover { color: #900; background-color: #fff; } #sectiontabs li:hover ul, #sectiontabs li.sfhover ul { left: auto; } *:first-child+html #sectiontabs li:hover ul, #sectiontabs li.sfhover ul { position: static; } #tablist { border-bottom: 1px solid #999; margin: 6px 0 0 0; padding-bottom: 22px; } #tablist ul, #tablist li { display: inline; list-style-type: none; margin: 0; padding: 0; } #tablist a { background: #eee; border: 1px solid #999; color: #009; float: left; font-size: 13px; font-weight: bold; line-height: 17px; margin-right: 8px; padding: 2px 10px 2px 10px; text-decoration: none; } #tablist a:hover { background: #fff; color: #900; } #tablist li a.activetab { background: #fff; border-bottom: 1px solid #fff; color: #900; } #tablist ul a:hover { background: #fff; color: #900 !important; } #tabcontainer { background: #fff; border: 1px solid #999; border-top: none; clear: both; margin: 0; padding: 10px; } h1 { margin: 0; padding: 0; color: #900; font-size: 18px; } h1.moreleft { float: left; margin-bottom: -3px; color: #000; } h1.story { font-size: 20px; padding: 10px 0; } h2 { margin: 0; padding: 0; color: #900; font-size: 16px; } h2.block { color: #000; } h2.videos { padding-top: 6px; } h2.headleft { float: left; color: #000; padding-top: 5px; } div.headright { text-align: right; padding-top: 7px; } div.moreright { text-align: right; padding-top: 5px; margin-bottom: -3px; } div.nextedition { text-align: right; margin-top: -3px; } div.otherleft { float: left; width: 339px; margin: -15px 0 0 0; padding: 0 10px 15px 0; } div.otherright { float: left; width: 329px; margin: 5px 0 0 0; } h3 { margin: 0; padding: 0; color: #000; font-size: 14px; } hr { border: 0; border-top: 1px solid #000; height: 0; background: #000; } a { color: #009; text-decoration: none; } a:hover { text-decoration: underline; } a.red { color: #900; text-decoration: none; } a.red:hover { text-decoration: underline; } a.blue { color: #009; text-decoration: none; } a.blue:visited { color: #006; } a.blue:hover { text-decoration: underline; } a.black { color: #000; text-decoration: none; } a.black:hover { text-decoration: underline; } a.gray { color: #666; text-decoration: none; } a.gray:hover { text-decoration: underline; } img.floatLeft { float: left; margin: 2px 5px 5px 0; } .left { float: left; } .right { float: right; } .alignRight { text-align: right; } .clear { clear: both; } #topstories { position: relative; overflow: visible; padding: 0; margin: 0 0 10px 0; height: 215px; } div.panel { display:none; } #topstories div.storyphoto { float: left; width: 100px; max-height: 150px; margin: 2px 10px 2px 0; overflow: hidden; } #topstories div.storyblurb { float: left; width: 230px; } div.moreon { float: left; width: 70px; margin: 10px 5px 0 0; } div.moreon ul { padding: 0; margin: 0 0 10px 15px; list-style-image:url('/images/bullet_black.gif'); } div.moretopics { float: left; width: 249px; margin: 10px 10px 0 0; } #mainstories { position: relative; overflow: visible; padding: 0; margin: 5px 0; height: 160px; } #mainstories div.storyphoto { float: left; width: 75px; max-height: 125px; margin: 2px 10px 2px 0; overflow: hidden; } #mainstories div.storyblurb { float: left; width: 190px; } #story1 { display:block; } div.firststory { padding: 5px 0 10px 0; } div.secondstory { clear: both; padding: 5px 0 10px 0; } #videos { padding-top: 3px; } #video { padding-bottom: 5px; } #googlesearch table { margin: 0 auto; padding-top: 10px; } #googlesearch table table { margin: 0; } blockquote { margin: 0; padding: 10px; } #misc { display: none; } .amazon { clear: both; margin: 10px 0; } form { margin: 0; padding: 0; } #story { float: left; width: 365px; } #first { padding-top: 0; margin-top: 0; font-size: medium; margin-bottom: -2px; } span.date { color: #666; font-style: italic; } #seealso { float: left; width: 140px; padding: 2px 10px 10px 0; } #seealso div { padding-top: 10px; } #seealso ul { margin: 0 0 0 20px; padding: 0; } #seealso ul li { padding: 0; } #photo { margin: 5px 0; } p { font-size: 13px; padding: 5px 0; margin: 0; } #related { float: right; width: 300px; padding: 0 0 10px 10px; } #relatedstories div { padding: 5px 0; } #related_articles div { padding: 5px 0; } #morenewsleft { float: left; width: 260px; } #morenewsright { float: right; width: 230px; } #rssbox { border: 1px solid #999; padding: 10px; margin: 8px 0 10px 10px; width: 200px; } #article_note { border: 1px solid #999; padding: 10px; margin: 10px 0; } #book_details { margin: 0 0 10px 0; } #moreheadlines { float: left; padding: 2px 0 0 0; } div.edition { display: none; } div.morepanel { display: none; } #panel1 { display:block; } #scroll { padding: 2px 0 0 0; } div.scroll_topics { float: left; width: 150px; } div.scroll_headlines { float: left; width: 295px; margin: 0 0 12px 10px; } div.section_topics { float: left; width: 150px; } div.section_headlines { float: left; width: 324px; margin: 0 10px 12px 10px; } div.search_topics { float: left; width: 150px; } div.search_headlines { float: left; width: 295px; margin: 0 0 12px 10px; } #citationbox { margin: 10px 0; padding: 10px; border: 1px solid #999; } #citationformat { float: left; width: 55px; } #citationtext { margin: 0 0 0 65px; } #bottomsearch { margin: 5px 0 0 0; padding: 0; border: none; } #googleside { width: 175px; padding: 10px 0 10px 0; font-size: 13px; } #googleside div { padding: 5px 0; overflow: hidden; } #googleside div.left { float: left; font-size: 11px; padding: 0; } #googleside div.right { text-align: right; font-size: 11px; padding: 0; } #googleside div.clear { clear: both; padding: 0; } #googlerelated { width: 300px; padding: 0 0 10px 0; font-size: 13px; } #googlerelated div { padding: 5px 0; overflow: hidden; } #googlerelated div.left { float: left; font-size: 11px; padding: 0; } #googlerelated div.right { text-align: right; font-size: 11px; padding: 0; } #googlerelated div.clear { clear: both; padding: 0; } #googlestory { width: 358px; padding: 10px 0 10px 0; font-size: 13px; } #googlestory div { padding: 5px 0; overflow: hidden; } #googlestory div.left { float: left; font-size: 11px; padding: 0; } #googlestory div.right { text-align: right; font-size: 11px; padding: 0; } #googlestory div.clear { clear: both; padding: 0; } #googlesearch { float: right; width: 175px; padding: 10px 0 10px 10px; font-size: 13px; overflow: hidden; } #googlesearch div { padding: 5px 0; overflow: hidden; } #googlesearch div.left { float: left; font-size: 11px; padding: 0; } #googlesearch div.right { text-align: right; font-size: 11px; padding: 0; } #googlesearch div.clear { clear: both; padding: 0; } #googlehome { width: 180px; padding: 5px 10px 10px 0; font-size: 13px; overflow: hidden; } #googlehome div { padding: 5px 0; overflow: hidden; } #googlehome div.left { float: left; font-size: 11px; padding: 0; } #googlehome div.right { text-align: right; font-size: 11px; padding: 0; } #googlehome div.clear { clear: both; padding: 0; } #googletop { margin: 0 0 10px 0; font-size: 13px; } #googletop div { overflow: hidden; } #googletop div.left { float: left; font-size: 11px; padding: 0; } #googletop div.right { text-align: right; font-size: 11px; padding: 0; } #googletop div.clear { clear: both; padding: 0; } #googletop div.col1 { padding: 5px 5px 5px 0; float: left; width: 164px; } #googletop div.col2 { padding: 5px; float: left; width: 164px; } #googletop div.col3 { padding: 5px 0 5px 5px; float: right; width: 164px; } #googleend { margin: 0 0 10px 0; font-size: 13px; } #googleend div { overflow: hidden; } #googleend div.left { float: left; font-size: 11px; padding: 0; } #googleend div.right { text-align: right; font-size: 11px; padding: 0; } #googleend div.clear { clear: both; padding: 0; } #googleend div.col1 { padding: 5px 5px 5px 0; float: left; width: 164px; } #googleend div.col2 { padding: 5px; float: left; width: 164px; } #googleend div.col3 { padding: 5px 0 5px 5px; float: right; width: 164px; } #googlebottom { width: 678px; margin: 20px 0 10px 0; font-size: 13px; } #googlebottom div { overflow: hidden; } #googlebottom div.left { float: left; font-size: 11px; padding: 0; } #googlebottom div.right { text-align: right; font-size: 11px; padding: 0; } #googlebottom div.clear { clear: both; padding: 0; } #googlebottom div.col1 { padding: 5px 5px 5px 0; float: left; width: 210px; } #googlebottom div.col2 { padding: 5px; float: left; width: 220px; } #googlebottom div.col3 { padding: 5px 0 5px 5px; float: right; width: 210px; } #share_form { background: #eee; border: 1px solid #999; display: none; position: absolute; width: 300px; z-index: 999; } #share_title { float: left; margin: 5px; width: 60%; } #share_close { float: right; margin: 5px; font-style: italic; } #share_close a { color: #009; text-decoration: none; } #share_close a:hover { color: #900; text-decoration: none; } #share_form div.clear { clear: both; float: none; } #share_social { background: #fff; padding: 5px 10px 5px 7px; } #share_social ul { list-style: none; margin: 0; padding: 0; } #share_social ul li { float: left; margin: 0; padding: 0; width: 50%; } #share_social ul li a { background-position: 0px 2px; background-repeat: no-repeat; display: block; float: left; height: 20px; padding: 4px 0 0 22px; vertical-align: middle; text-decoration: none; color: #009; } #share_social ul li a:hover { text-decoration: underline; color: #900; } #share_delicious { background-image: url('/images/delicious.gif') !important; } #share_digg { background-image: url('/images/digg.gif') !important; } #share_furl { background-image: url('/images/furl.gif') !important; } #share_netscape { background-image: url('/images/netscape.gif') !important; } #share_yahoo_myweb { background-image: url('/images/yahoo_myweb.gif') !important; } #share_stumbleupon { background-image: url('/images/stumbleupon.gif') !important; } #share_google_bmarks { background-image: url('/images/google_bmarks.gif') !important; } #share_technorati { background-image: url('/images/technorati.gif') !important; } #share_blinklist { background-image: url('/images/blinklist.gif') !important; } #share_newsvine { background-image: url('/images/newsvine.gif') !important; } #share_magnolia { background-image: url('/images/magnolia.gif') !important; } #share_reddit { background-image: url('/images/reddit.gif') !important; } #share_facebook { background-image: url('/images/facebook.gif') !important; } #share_tailrank { background-image: url('/images/tailrank.gif') !important; } #share_slashdot { background-image: url('/images/slashdot.gif') !important; } #share_fark { background-image: url('/images/fark.gif') !important; } #blog_form { background: #eee; border: 1px solid #999; display: none; position: absolute; width: 475px; z-index: 999; } #blog_title { float: left; margin: 5px; width: 60%; } #blog_close { float: right; margin: 5px; font-style: italic; } #blog_close a { color: #009; text-decoration: none; } #blog_close a:hover { color: #900; text-decoration: none; } #blog_form div.clear { clear: both; float: none; } #blog_fields { background: #fff; padding: 1px 10px 5px 7px; text-align: left; } #blog_fields form { border: 0; margin: 0; padding: 0; } #blog_fields ul { list-style: none; margin: 0; padding: 0; } #blog_fields ul li { display: block; clear: both; margin: 0 0 7px 0; padding: 0; } #blog_fields ul li label { width: 70px; float: left; margin: 3px 0; } #blog_fields ul li input { float: right; width: 375px; padding: 0; margin: 3px; } #blog_fields ul li textarea { float: right; width: 375px; padding: 0; margin: 3px; } #blog_fields ul li label.blog_submit_label { width: 370px; float: left; } #blog_fields ul li input.blog_submit { float: right; width: 75px; } #blog_fields ul li input.blog_text { width: 375px; } #blog_fields ul li textarea.blog_summary { width: 375px; height: 150px; } #cite_form { background: #eee; border: 1px solid #999; display: none; position: absolute; width: 500px; z-index: 999; } #cite_title { float: left; margin: 5px; width: 60%; } #cite_close { float: right; margin: 5px; font-style: italic; } #cite_close a { color: #009; text-decoration: none; } #cite_close a:hover { color: #900; text-decoration: none; } #cite_form div.clear { clear: both; float: none; } #cite_fields { background: #fff; padding: 1px 10px 5px 7px; text-align: left; } #cite_fields form { border: 0; margin: 0; padding: 0; } #cite_fields ul { list-style: none; margin: 0; padding: 0; } #cite_fields ul li { display: block; clear: both; margin: 0 0 7px 0; padding: 0; } #cite_fields ul li label { width: 75px; float: left; margin: 3px 0; } #cite_fields ul li input { float: left; margin: 3px 0; } #cite_fields ul li div { float: right; width: 385px; padding: 0; margin: 3px 3px 10px 3px; } #cite_fields ul li div p { margin: 0; padding: 0; } #cite_fields ul li label.cite_submit_label { width: 395px; float: left; } #cite_fields ul li input.cite_style { float: left; width: 15px; } #cite_fields ul li input.cite_submit { float: right; width: 75px; } #cite_fields ul li div.citation { width: 385px; } #email_form { background: #eee; border: 1px solid #999; display: none; position: absolute; width: 300px; z-index: 999; } #email_title { float: left; margin: 5px; width: 60%; } #email_close { float: right; margin: 5px; font-style: italic; } #email_close a { color: #009; text-decoration: none; } #email_close a:hover { color: #900; text-decoration: none; } #email_form div.clear { clear: both; float: none; } #email_fields { background: #fff; padding: 1px 10px 5px 7px; text-align: left; } #email_fields form { border: 0; margin: 0; padding: 0; } #email_fields ul { list-style: none; margin: 0; padding: 0; } #email_fields ul li { display: block; clear: both; margin: 0 0 7px 0; padding: 0; } #email_fields ul li label { width: 95px; float: left; margin: 3px 0; } #email_fields ul li input { float: right; width: 175px; padding: 0; margin: 3px; } #email_fields ul li input.email_self { float: left; width: 15px; } #email_fields ul li input.email_submit { float: right; width: 75px; } #email_fields ul li input.email_text { width: 175px; } #feedback { width: 300px; } #feedback_form { border: 0; margin: 2px 0 0 0; padding: 0; } #feedback_form ul { list-style: none; margin: 0; padding: 0; } #feedback_form ul li { display: block; clear: both; margin: 0 0 7px 0; padding: 0; } #feedback_form ul li label { width: 75px; float: left; margin: 3px 0; } #feedback_form ul li input { float: right; width: 205px; padding: 0; margin: 3px; } #feedback_form ul li input.feedback_submit { float: right; width: 75px; } #feedback_form ul li input.feedback_text { width: 205px; } #feedback_form ul li label.feedback_submit_label { width: 190px; float: left; } #feedback_form ul li textarea { float: right; width: 205px; padding: 0; margin: 3px; } #feedback_form ul li textarea.feedback_comments { width: 205px; height: 100px; } #justin { margin: 5px 0; } #justin div { display: none; } postW9XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate W9a%VUntry(s}q1r7>XzռgڒTy u url 2http://www.sciencedaily.com/scripts/functions6.jsbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmimeapplication/x-javascripthntt"7f188d-8143-484d2700"hvrsdatafunction addLoadEvent(func) { if (!window.__load_events) { var init = function () { // quit if this function has already been called if (arguments.callee.done) return; // flag this function so we don't do the same thing twice arguments.callee.done = true; // kill the timer if (window.__load_timer) { clearInterval(window.__load_timer); window.__load_timer = null; } // execute each function in the stack in the order they were added for (var i=0;i < window.__load_events.length;i++) { window.__load_events[i](); } window.__load_events = null; }; // for Mozilla/Opera9 if (document.addEventListener) { document.addEventListener("DOMContentLoaded", init, false); } // for Internet Explorer /*@cc_on @*/ /*@if (@_win32) document.write("<\/scr"+"ipt>"); var script = document.getElementById("__ie_onload"); script.onreadystatechange = function() { if (this.readyState == "complete") { init(); // call the onload handler } }; /*@end @*/ // for Safari if (/WebKit/i.test(navigator.userAgent)) { // sniff window.__load_timer = setInterval(function() { if (/loaded|complete/.test(document.readyState)) { init(); // call the onload handler } }, 10); } // for other browsers window.onload = init; // create event function stack window.__load_events = []; } // add function to event stack window.__load_events.push(func); } function addUnloadEvent(func) { var oldonunload = window.onunload; if (typeof window.onunload != 'function') { window.onunload = func; } else { window.onunload = function() { oldonunload(); func(); } } } function suckerfish(type, tag, parentId) { if (window.attachEvent) { window.attachEvent("onload", function() { var sfEls = (parentId==null)?document.getElementsByTagName(tag):document.getElementById(parentId).getElementsByTagName(tag); type(sfEls); }); } } sfHover = function(sfEls) { for (var i=0; i 50) { urlarray = url.split('/'); url = ''; for (var i=0; i 50) { url += '/
     ' + urlarray[i]; } else { url += '/' + urlarray[i]; } } url = url.substring(1); url = url.replace('
','
'); } top += '' + "\n"; top += '' + "\n"; top += '' + "\n"; top += '' + "\n"; top += '
Web address:
     ' + url + '
' + "\n"; text += '
' + "\n"; if (document.getElementById('story')) { text += '

' + document.getElementsByTagName('h1')[1].innerHTML + '

' + "\n"; if (document.getElementById('photo')) { text += '
' + "\n"; text += document.getElementById('photo').innerHTML; text += '
' + "\n"; } text += '
'; text += document.getElementById('story').innerHTML; } else { if (document.getElementById('title')) { text += '
' + document.getElementById('title').innerHTML + '
' + "\n"; text = text.replace(document.getElementById('titleside').innerHTML,''); text += '
' + "\n"; } text += '
'; text += document.getElementById('content').innerHTML; } if (document.getElementById('seealso')) { seealso += document.getElementById('seealso').innerHTML; } if (document.getElementById('googletop')) { googletop += document.getElementById('googletop').innerHTML; } if (document.getElementById('googleend')) { googleend += document.getElementById('googleend').innerHTML; } if (document.getElementById('googlebottom')) { googlebottom += document.getElementById('googlebottom').innerHTML; } if (document.getElementById('googleside')) { googleside += document.getElementById('googleside').innerHTML; } if (document.getElementById('googlesearch')) { googlesearch += document.getElementById('googlesearch').innerHTML; } text += '
' + "\n"; text += '
' + "\n"; text += '
' + "\n"; text = text.replace(seealso,''); text = text.replace(googletop,''); text = text.replace(googlebottom,''); text = text.replace(googleend,''); text = text.replace(googleside,''); text = text.replace(googlesearch,''); text = text.replace(/]*?>[.\s\S]*?<\/scr\ipt>/gi,''); var winprint = window.open("","",options); winprint.document.open(); winprint.document.write('' + "\n"); winprint.document.write('' + "\n"); winprint.document.write('' + "\n"); if (document.getElementById('story')) { winprint.document.write('' + "\n"); } else { winprint.document.write('' + "\n"); winprint.document.write('' + "\n"); } winprint.document.write('' + "\n"); winprint.document.write('' + "\n"); winprint.document.write(top + "\n" + text + "\n" + bottom + "\n"); winprint.document.write('' + "\n"); winprint.document.close(); } /* function emailpage() { var recipient = prompt("Recipient's email address:",""); if (recipient == null) { alert("You must enter an email address.") } else { var subject = document.title; var url = document.location.href; var body = "Please see the following page ...\n\n" + "Title: " + subject + "\n" + "Link: " + url + "\n"; var message = "mailto:" + recipient + "?subject=" + escape(subject) + "&body=" + escape(body); window.location = message; window.focus(); } } */ function bookmarkpage() { var url = document.location.href; var title = document.title; if ((navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4)) { window.external.AddFavorite(url,title); } else if (navigator.appName == "Netscape") { window.sidebar.addPanel(title,url,""); } else { alert("Press CTRL-D (Netscape) or CTRL-T (Opera) to bookmark"); } } function sharepage() { var form = document.getElementById('share_form'); if (form.style.display == 'block') { form.style.display = 'none'; return; } var url = escape(document.location.href); var title = escape(document.title); var link = document.getElementById('share_link'); document.getElementById("share_delicious").href = share_url("http://del.icio.us/post?url={url}&title={title}", url, title); document.getElementById("share_digg").href = share_url("http://digg.com/submit?phase=2&url={url}&title={title}", url, title); document.getElementById("share_furl").href = share_url("http://furl.net/storeIt.jsp?u={url}&t={title}", url, title); document.getElementById("share_netscape").href = share_url("http://www.netscape.com/submit/?U={url}&T={title}", url, title); document.getElementById("share_yahoo_myweb").href = share_url("http://myweb2.search.yahoo.com/myresults/bookmarklet?u={url}&t={title}", url, title); document.getElementById("share_stumbleupon").href = share_url("http://www.stumbleupon.com/submit?url={url}&title={title}", url, title); document.getElementById("share_google_bmarks").href = share_url("http://www.google.com/bookmarks/mark?op=edit&bkmk={url}&title={title}", url, title); document.getElementById("share_technorati").href = share_url("http://www.technorati.com/faves?add={url}", url, title); document.getElementById("share_blinklist").href = share_url("http://blinklist.com/index.php?Action=Blink/addblink.php&Url={url}&Title={title}", url, title); document.getElementById("share_newsvine").href = share_url("http://www.newsvine.com/_tools/seed&save?popoff=0&u={url}&h={title}", url, title); document.getElementById("share_magnolia").href = share_url("http://ma.gnolia.com/bookmarklet/add?url={url}&title={title}", url, title); document.getElementById("share_reddit").href = share_url("http://reddit.com/submit?url={url}&title={title}", url, title); document.getElementById("share_facebook").href = share_url("http://www.facebook.com/share.php?u={url}", url, title); document.getElementById("share_tailrank").href = share_url("http://tailrank.com/share/?link_href={url}&title={title}", url, title); document.getElementById("share_slashdot").href = share_url("http://slashdot.org/bookmark.pl?url={url}&title={title}", url, title); document.getElementById("share_fark").href = share_url("http://cgi.fark.com/cgi/fark/edit.pl?new_url={url}&new_comment={title}", url, title); var offset = Position.cumulativeOffset(link); form.style.left = (offset[0] - 20) + 'px'; form.style.top = (offset[1] + link.offsetHeight + 3) + 'px'; form.style.display = 'block'; } function share_url(base, url, title) { base = base.replace('{url}', url); return base.replace('{title}', title); } function blogpage() { var form = document.getElementById('blog_form'); if (form.style.display == 'block') { form.style.display = 'none'; return; } var title = document.getElementById('blog_headline'); var link = document.getElementById('blog_url'); if (document.getElementById('metadate')) { var metadate = document.getElementById('metadate').content; } else { var metadate = ''; } var summary = document.getElementById('blog_summary'); title.value = document.title; link.value = document.location.href; if (typeof summary.innerText != 'undefined') { summary.innerText = 'ScienceDaily (' + metadate + ') -- ' + document.getElementById('metasummary').content; } else if (typeof summary.textContent != 'undefined') { summary.textContent = 'ScienceDaily (' + metadate + ') -- ' + document.getElementById('metasummary').content; } var link = document.getElementById('blog_link'); var offset = Position.cumulativeOffset(link); form.style.left = (offset[0] - 170) + 'px'; form.style.top = (offset[1] + link.offsetHeight + 3) + 'px'; form.style.display = 'block'; } function copyit() { var title = document.getElementById('blog_headline').value; var link = document.getElementById('blog_url').value; var metadate = document.getElementById('metadate').content; var summary = document.getElementById('blog_summary'); if (typeof summary.innerText != 'undefined') { summary = summary.innerText; } else if (typeof summary.textContent != 'undefined') { summary = summary.textContent; } else { summary = ''; } var text = '

' + title + '
' + "\n" + summary + ' ... > read full article

'; copy_clip(text,text); } function citepage() { var form = document.getElementById('cite_form'); if (form.style.display == 'block') { form.style.display = 'none'; return; } var metadate = document.getElementById('metadate').content; var source = document.getElementById('source').innerHTML; var title = document.title; var link = document.location.href; var cite_apa = document.getElementById('cite_apa'); var cite_mla = document.getElementById('cite_mla'); var meta = new Date(getDateFromFormat(metadate,'y-MM-dd')); var today = new Date(); var apa = '

' + source + ' (' + formatDate(meta,'y, MMM d') + '). ' + title + '. ScienceDaily. Retrieved ' + formatDate(today,'MMM d, y') + ', from ' + link + '

'; var mla = '

' + source + '. "' + title + '." ScienceDaily ' + formatDate(meta,'d MMM y') + '. ' + formatDate(today,'d MMM y') + ' <' + link + '>.' + '

'; cite_apa.innerHTML = apa; cite_mla.innerHTML = mla; var link = document.getElementById('cite_link'); var offset = Position.cumulativeOffset(link); form.style.left = (offset[0] - 170) + 'px'; form.style.top = (offset[1] + link.offsetHeight + 3) + 'px'; form.style.display = 'block'; } function citeit() { if (document.getElementById('cite_style_apa').checked) { html = document.getElementById('cite_apa').innerHTML; } else { html = document.getElementById('cite_mla').innerHTML; } plain = html.replace(/<[^>]+>/ig,""); plain = plain.replace("<","<"); plain = plain.replace(">",">"); copy_clip(html,plain); } function citation() { var metadate = document.getElementById('metadate').content; var source = document.getElementById('source').innerHTML; var title = document.title; var link = document.location.href; var citationapa = document.getElementById('citationapa'); var citationmla = document.getElementById('citationmla'); var citationtext = document.getElementById('citationtext'); link = link.replace('/releases/','­ /releases/'); var meta = new Date(getDateFromFormat(metadate,'y-MM-dd')); var today = new Date(); var apa = source + ' (' + formatDate(meta,'y, MMM d') + '). ' + title + '. ScienceDaily. Retrieved ' + formatDate(today,'MMM d, y') + ', from ' + link; var mla = source + '. "' + title + '." ScienceDaily ' + formatDate(meta,'d MMM y') + '. ' + formatDate(today,'d MMM y') + ' <' + link + '>.'; if (citationapa.checked) { citationtext.innerHTML = apa; } else { citationtext.innerHTML = mla; } } function copy_clip(html,plain) { var textHTML = html; var textPlain = plain; if (window.clipboardData && window.clipboardData.setData) { window.clipboardData.setData("Text", textPlain); } else if (window.netscape) { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); if (!trans) return false; trans.addDataFlavor("text/html"); var htmlstring = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); if (!htmlstring) return false; htmlstring.data = textHTML; trans.setTransferData("text/html", htmlstring, textHTML.length * 2); trans.addDataFlavor("text/unicode"); var unicodestring = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); unicodestring.data = textPlain; trans.setTransferData("text/unicode", unicodestring, textPlain.length * 2); var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard); if (!clipboard) return false; clipboard.setData(trans, null, Components.interfaces.nsIClipboard.kGlobalClipboard); } else { alert("Your browser does not support automatic copying to the clipboard. Please select the text and copy it manually (e.g., Ctrl-C)."); return false; } alert("The following was copied to your clipboard:\n\n" + textPlain); return false; } function emailpage() { var form = document.getElementById('email_form'); if (form.style.display == 'block') { form.style.display = 'none'; return; } var link = document.getElementById('email_link'); var offset = Position.cumulativeOffset(link); form.style.left = (offset[0] - 170) + 'px'; form.style.top = (offset[1] + link.offsetHeight + 3) + 'px'; form.style.display = 'block'; } function getxmlhttp() { var xmlhttp = false; try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch(E) { xmlhttp = false; } } if (!xmlhttp && typeof XMLHttpRequest!="undefined") { xmlhttp = new XMLHttpRequest(); } return xmlhttp; } function email_process() { email_obj = document.getElementById('email_fields'); emailHTML = email_obj.innerHTML; var emailer = '/emailer.php'; var url = document.location.href; var title = document.title; var summary = document.getElementById('metasummary').content; var to_address = document.getElementById('email_to').value; var from_address = document.getElementById('email_from').value; var from_name = document.getElementById('email_name').value; var email_self = (document.getElementById('email_self').checked == true)?1:0; var variables = 'url=' + escape(url) + '&title=' + escape(title) + '&summary=' + escape(summary) + '&to=' + escape(to_address) + '&from=' + escape(from_address) + '&name=' + escape(from_name) + '&self=' + email_self; xmlhttp = getxmlhttp(); xmlhttp.open("POST", emailer, true); xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); xmlhttp.onreadystatechange = email_change; xmlhttp.send(variables); } function email_change() { if (xmlhttp.readyState==4) { if (xmlhttp.status==200) { email_obj.innerHTML = xmlhttp.responseText; setTimeout('email_obj.innerHTML = emailHTML',2999); } else { email_obj.innerHTML = 'A problem was encountered -- email not sent.'; setTimeout('email_obj.innerHTML = emailHTML',2999); } } else { email_obj.innerHTML = 'Sending ...'; } } function feedback() { var form = document.getElementById('feedback_form'); feedback_obj = document.getElementById('feedback_response'); var feedbacker = '/feedback.php'; var url = document.location.href; var title = document.title; var email = document.getElementById('feedback_email').value; var name = document.getElementById('feedback_name').value; var comments = document.getElementById('feedback_comments').value; var useragent = navigator.userAgent; var variables = 'url=' + escape(url) + '&title=' + escape(title) + '&from=' + escape(email) + '&name=' + escape(name) + '&comments=' + escape(comments) + '&useragent=' + escape(useragent); xmlhttp = getxmlhttp(); xmlhttp.open("POST", feedbacker, true); xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); xmlhttp.onreadystatechange = feedback_change; xmlhttp.send(variables); } function feedback_change() { if (xmlhttp.readyState==4) { if (xmlhttp.status==200) { feedback_obj.innerHTML = xmlhttp.responseText; } else { feedback_obj.innerHTML = 'Problem encountered -- feedback not sent.'; } } else { feedback_obj.innerHTML = 'Sending ...'; } } function redirect(arg) { url = arg.replace(/^http[^?]*?\?url=/,''); // alert(url); location = url; } function gotostory(num) { for (var i=1; i<=stories.length; i++) { if (i == num) { document.getElementById('story'+i).style.display = 'block' } else { document.getElementById('story'+i).style.display = 'none'; } } } var currentPanel = 1; function changepanel(change) { currentPanel += change; if (currentPanel < 1) { currentPanel = 1; } else if (currentPanel > panels.length) { currentPanel = panels.length; } for (var i=1; i<=panels.length; i++) { if (i == currentPanel) { document.getElementById('panel'+i).style.display = 'block' document.getElementById('edition').innerHTML = document.getElementById('edition' + i).innerHTML; } else { document.getElementById('panel'+i).style.display = 'none'; } } } function setActiveStyleSheet(title) { var i, a, main; for (i=0; (a=document.getElementsByTagName("link")[i]); i++) { if (a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) { a.disabled = true; if (a.getAttribute("title") == title) a.disabled = false; } } } function getActiveStyleSheet() { var i, a; for (i=0; (a=document.getElementsByTagName("link")[i]); i++) { if (a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title"); } return null; } function getPreferredStyleSheet() { var i, a; for (i=0; (a=document.getElementsByTagName("link")[i]); i++) { if (a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("rel").indexOf("alt") == -1 && a.getAttribute("title")) return a.getAttribute("title"); } return null; } function createCookie(name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime() + (days*24*60*60*1000)); var expires = "; expires=" + date.toGMTString(); } else expires = ""; document.cookie = name + "=" + value + expires + "; path=/"; } function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i=0; i9?"":"0")+x} function isDate(val,format) { var date=getDateFromFormat(val,format); if (date==0) { return false; } return true; } function compareDates(date1,dateformat1,date2,dateformat2) { var d1=getDateFromFormat(date1,dateformat1); var d2=getDateFromFormat(date2,dateformat2); if (d1==0 || d2==0) { return -1; } else if (d1 > d2) { return 1; } return 0; } function formatDate(date,format) { format=format+""; var result=""; var i_format=0; var c=""; var token=""; var y=date.getYear()+""; var M=date.getMonth()+1; var d=date.getDate(); var E=date.getDay(); var H=date.getHours(); var m=date.getMinutes(); var s=date.getSeconds(); var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k; // Convert real date parts into formatted versions var value=new Object(); if (y.length < 4) {y=""+(y-0+1900);} value["y"]=""+y; value["yyyy"]=y; value["yy"]=y.substring(2,4); value["M"]=M; value["MM"]=LZ(M); value["MMM"]=MONTH_NAMES[M-1]; value["NNN"]=MONTH_NAMES[M+11]; value["d"]=d; value["dd"]=LZ(d); value["E"]=DAY_NAMES[E+7]; value["EE"]=DAY_NAMES[E]; value["H"]=H; value["HH"]=LZ(H); if (H==0){value["h"]=12;} else if (H>12){value["h"]=H-12;} else {value["h"]=H;} value["hh"]=LZ(value["h"]); if (H>11){value["K"]=H-12;} else {value["K"]=H;} value["k"]=H+1; value["KK"]=LZ(value["K"]); value["kk"]=LZ(value["k"]); if (H > 11) { value["a"]="PM"; } else { value["a"]="AM"; } value["m"]=m; value["mm"]=LZ(m); value["s"]=s; value["ss"]=LZ(s); while (i_format < format.length) { c=format.charAt(i_format); token=""; while ((format.charAt(i_format)==c) && (i_format < format.length)) { token += format.charAt(i_format++); } if (value[token] != null) { result=result + value[token]; } else { result=result + token; } } return result; } function _isInteger(val) { var digits="1234567890"; for (var i=0; i < val.length; i++) { if (digits.indexOf(val.charAt(i))==-1) { return false; } } return true; } function _getInt(str,i,minlength,maxlength) { for (var x=maxlength; x>=minlength; x--) { var token=str.substring(i,i+x); if (token.length < minlength) { return null; } if (_isInteger(token)) { return token; } } return null; } function getDateFromFormat(val,format) { val=val+""; format=format+""; var i_val=0; var i_format=0; var c=""; var token=""; var token2=""; var x,y; var now=new Date(); var year=now.getYear(); var month=now.getMonth()+1; var date=1; var hh=now.getHours(); var mm=now.getMinutes(); var ss=now.getSeconds(); var ampm=""; while (i_format < format.length) { // Get next token from format string c=format.charAt(i_format); token=""; while ((format.charAt(i_format)==c) && (i_format < format.length)) { token += format.charAt(i_format++); } // Extract contents of value based on format token if (token=="yyyy" || token=="yy" || token=="y") { if (token=="yyyy") { x=4;y=4; } if (token=="yy") { x=2;y=2; } if (token=="y") { x=2;y=4; } year=_getInt(val,i_val,x,y); if (year==null) { return 0; } i_val += year.length; if (year.length==2) { if (year > 70) { year=1900+(year-0); } else { year=2000+(year-0); } } } else if (token=="MMM"||token=="NNN"){ month=0; for (var i=0; i11)) { month=i+1; if (month>12) { month -= 12; } i_val += month_name.length; break; } } } if ((month < 1)||(month>12)){return 0;} } else if (token=="EE"||token=="E"){ for (var i=0; i12)){return 0;} i_val+=month.length;} else if (token=="dd"||token=="d") { date=_getInt(val,i_val,token.length,2); if(date==null||(date<1)||(date>31)){return 0;} i_val+=date.length;} else if (token=="hh"||token=="h") { hh=_getInt(val,i_val,token.length,2); if(hh==null||(hh<1)||(hh>12)){return 0;} i_val+=hh.length;} else if (token=="HH"||token=="H") { hh=_getInt(val,i_val,token.length,2); if(hh==null||(hh<0)||(hh>23)){return 0;} i_val+=hh.length;} else if (token=="KK"||token=="K") { hh=_getInt(val,i_val,token.length,2); if(hh==null||(hh<0)||(hh>11)){return 0;} i_val+=hh.length;} else if (token=="kk"||token=="k") { hh=_getInt(val,i_val,token.length,2); if(hh==null||(hh<1)||(hh>24)){return 0;} i_val+=hh.length;hh--;} else if (token=="mm"||token=="m") { mm=_getInt(val,i_val,token.length,2); if(mm==null||(mm<0)||(mm>59)){return 0;} i_val+=mm.length;} else if (token=="ss"||token=="s") { ss=_getInt(val,i_val,token.length,2); if(ss==null||(ss<0)||(ss>59)){return 0;} i_val+=ss.length;} else if (token=="a") { if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";} else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";} else {return 0;} i_val+=2;} else { if (val.substring(i_val,i_val+token.length)!=token) {return 0;} else {i_val+=token.length;} } } // If there are any trailing characters left in the value, it doesn't match if (i_val != val.length) { return 0; } // Is date valid for month? if (month==2) { // Check for leap year if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year if (date > 29){ return 0; } } else { if (date > 28) { return 0; } } } if ((month==4)||(month==6)||(month==9)||(month==11)) { if (date > 30) { return 0; } } // Correct hours value if (hh<12 && ampm=="PM") { hh=hh-0+12; } else if (hh>11 && ampm=="AM") { hh-=12; } var newdate=new Date(year,month-1,date,hh,mm,ss); return newdate.getTime(); } function parseDate(val) { var preferEuro=(arguments.length==2)?arguments[1]:false; generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d'); monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d'); dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M'); var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst'); var d=null; for (var i=0; i 12) return; } typeInt++; if (typeInt > 4) { typeInt = 1; } displayText = document.getElementById("justin" + typeInt).innerHTML; strippedText = displayText.replace(/<[^>]*>/g,''); if (strippedText.length > 49) { truncatedText = strippedText.substring(0,44); lastspace = truncatedText.lastIndexOf(' '); truncatedText = truncatedText.substring(0,lastspace); displayText = displayText.substring(0,displayText.indexOf('>')+1) + truncatedText + ' ...'; } document.getElementById("justindisplay").innerHTML = displayText; setTimeout('typeScroller()',5000); } addLoadEvent(function() { suckerfish(sfHover, "LI", "nav"); }); addLoadEvent(function() { suckerfish(sfHover, "LI", "sectiontabs"); }); /* addLoadEvent(function() { var cookie = readCookie("style"); var title = cookie ? cookie : getPreferredStyleSheet(); setActiveStyleSheet(title); }); addUnloadEvent(function() { var title = getActiveStyleSheet(); createCookie("style",title,365); }); var cookie = readCookie("style"); var title = cookie ? cookie : getPreferredStyleSheet(); setActiveStyleSheet(title); */ addLoadEvent(function() { var excludedomains=["localhost", "127.0.0.1", "sciencedaily", "local.sciencedaily", "www.sciencedaily.com", "www.sciencedaily.net", "new.sciencedaily.com", "www.sciencedaily.org", "sciencedaily.com", "sciencedaily.net", "sciencedaily.org", "healthology.sciencedaily.com", "sciencedaily.healthology.com", "mediwire.sciencedaily.com", "sciencedaily.mediwire.com", "healthcare.careerbuilder.com", "sciencebiotech.careerbuilder.com", "engineering.careerbuilder.com", "informationtechnology.careerbuilder.com", "www.careerbuilder.com"]; var excludedomains = excludedomains.join("|"); rexcludedomains = new RegExp(excludedomains, "i"); for (i=0; i<=(document.links.length-1); i++) { if (document.links[i].hostname.search(rexcludedomains)==-1 && document.links[i].href.indexOf("http:")!=-1) { document.links[i].target="_blank"; } if (document.links[i].href.indexOf("/goto.php")!=-1) { document.links[i].onclick=new Function("redirect(this.href); return false;"); } } }); postgڒXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate sgڒ<Cntry([mE7njޡǁ & /yurl 1http://www.sciencedaily.com/scripts/prototype.jsbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmimeapplication/x-javascripthntt"7f0242-17837-b20c0f40"hvrsdata/* Prototype JavaScript framework, version 1.5.1.1 * (c) 2005-2007 Sam Stephenson * * Prototype is freely distributable under the terms of an MIT-style license. * For details, see the Prototype web site: http://www.prototypejs.org/ * /*--------------------------------------------------------------------------*/ var Prototype = { Version: '1.5.1.1', Browser: { IE: !!(window.attachEvent && !window.opera), Opera: !!window.opera, WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1 }, BrowserFeatures: { XPath: !!document.evaluate, ElementExtensions: !!window.HTMLElement, SpecificElementExtensions: (document.createElement('div').__proto__ !== document.createElement('form').__proto__) }, ScriptFragment: ']*>([\\S\\s]*?)<\/script>', JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, emptyFunction: function() { }, K: function(x) { return x } } var Class = { create: function() { return function() { this.initialize.apply(this, arguments); } } } var Abstract = new Object(); Object.extend = function(destination, source) { for (var property in source) { destination[property] = source[property]; } return destination; } Object.extend(Object, { inspect: function(object) { try { if (object === undefined) return 'undefined'; if (object === null) return 'null'; return object.inspect ? object.inspect() : object.toString(); } catch (e) { if (e instanceof RangeError) return '...'; throw e; } }, toJSON: function(object) { var type = typeof object; switch(type) { case 'undefined': case 'function': case 'unknown': return; case 'boolean': return object.toString(); } if (object === null) return 'null'; if (object.toJSON) return object.toJSON(); if (object.ownerDocument === document) return; var results = []; for (var property in object) { var value = Object.toJSON(object[property]); if (value !== undefined) results.push(property.toJSON() + ': ' + value); } return '{' + results.join(', ') + '}'; }, keys: function(object) { var keys = []; for (var property in object) keys.push(property); return keys; }, values: function(object) { var values = []; for (var property in object) values.push(object[property]); return values; }, clone: function(object) { return Object.extend({}, object); } }); Function.prototype.bind = function() { var __method = this, args = $A(arguments), object = args.shift(); return function() { return __method.apply(object, args.concat($A(arguments))); } } Function.prototype.bindAsEventListener = function(object) { var __method = this, args = $A(arguments), object = args.shift(); return function(event) { return __method.apply(object, [event || window.event].concat(args)); } } Object.extend(Number.prototype, { toColorPart: function() { return this.toPaddedString(2, 16); }, succ: function() { return this + 1; }, times: function(iterator) { $R(0, this, true).each(iterator); return this; }, toPaddedString: function(length, radix) { var string = this.toString(radix || 10); return '0'.times(length - string.length) + string; }, toJSON: function() { return isFinite(this) ? this.toString() : 'null'; } }); Date.prototype.toJSON = function() { return '"' + this.getFullYear() + '-' + (this.getMonth() + 1).toPaddedString(2) + '-' + this.getDate().toPaddedString(2) + 'T' + this.getHours().toPaddedString(2) + ':' + this.getMinutes().toPaddedString(2) + ':' + this.getSeconds().toPaddedString(2) + '"'; }; var Try = { these: function() { var returnValue; for (var i = 0, length = arguments.length; i < length; i++) { var lambda = arguments[i]; try { returnValue = lambda(); break; } catch (e) {} } return returnValue; } } /*--------------------------------------------------------------------------*/ var PeriodicalExecuter = Class.create(); PeriodicalExecuter.prototype = { initialize: function(callback, frequency) { this.callback = callback; this.frequency = frequency; this.currentlyExecuting = false; this.registerCallback(); }, registerCallback: function() { this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, stop: function() { if (!this.timer) return; clearInterval(this.timer); this.timer = null; }, onTimerEvent: function() { if (!this.currentlyExecuting) { try { this.currentlyExecuting = true; this.callback(this); } finally { this.currentlyExecuting = false; } } } } Object.extend(String, { interpret: function(value) { return value == null ? '' : String(value); }, specialChar: { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\\': '\\\\' } }); Object.extend(String.prototype, { gsub: function(pattern, replacement) { var result = '', source = this, match; replacement = arguments.callee.prepareReplacement(replacement); while (source.length > 0) { if (match = source.match(pattern)) { result += source.slice(0, match.index); result += String.interpret(replacement(match)); source = source.slice(match.index + match[0].length); } else { result += source, source = ''; } } return result; }, sub: function(pattern, replacement, count) { replacement = this.gsub.prepareReplacement(replacement); count = count === undefined ? 1 : count; return this.gsub(pattern, function(match) { if (--count < 0) return match[0]; return replacement(match); }); }, scan: function(pattern, iterator) { this.gsub(pattern, iterator); return this; }, truncate: function(length, truncation) { length = length || 30; truncation = truncation === undefined ? '...' : truncation; return this.length > length ? this.slice(0, length - truncation.length) + truncation : this; }, strip: function() { return this.replace(/^\s+/, '').replace(/\s+$/, ''); }, stripTags: function() { return this.replace(/<\/?[^>]+>/gi, ''); }, stripScripts: function() { return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); }, extractScripts: function() { var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); return (this.match(matchAll) || []).map(function(scriptTag) { return (scriptTag.match(matchOne) || ['', ''])[1]; }); }, evalScripts: function() { return this.extractScripts().map(function(script) { return eval(script) }); }, escapeHTML: function() { var self = arguments.callee; self.text.data = this; return self.div.innerHTML; }, unescapeHTML: function() { var div = document.createElement('div'); div.innerHTML = this.stripTags(); return div.childNodes[0] ? (div.childNodes.length > 1 ? $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : div.childNodes[0].nodeValue) : ''; }, toQueryParams: function(separator) { var match = this.strip().match(/([^?#]*)(#.*)?$/); if (!match) return {}; return match[1].split(separator || '&').inject({}, function(hash, pair) { if ((pair = pair.split('='))[0]) { var key = decodeURIComponent(pair.shift()); var value = pair.length > 1 ? pair.join('=') : pair[0]; if (value != undefined) value = decodeURIComponent(value); if (key in hash) { if (hash[key].constructor != Array) hash[key] = [hash[key]]; hash[key].push(value); } else hash[key] = value; } return hash; }); }, toArray: function() { return this.split(''); }, succ: function() { return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); }, times: function(count) { var result = ''; for (var i = 0; i < count; i++) result += this; return result; }, camelize: function() { var parts = this.split('-'), len = parts.length; if (len == 1) return parts[0]; var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0]; for (var i = 1; i < len; i++) camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); return camelized; }, capitalize: function() { return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); }, underscore: function() { return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); }, dasherize: function() { return this.gsub(/_/,'-'); }, inspect: function(useDoubleQuotes) { var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { var character = String.specialChar[match[0]]; return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); }); if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; return "'" + escapedString.replace(/'/g, '\\\'') + "'"; }, toJSON: function() { return this.inspect(true); }, unfilterJSON: function(filter) { return this.sub(filter || Prototype.JSONFilter, '#{1}'); }, isJSON: function() { var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); }, evalJSON: function(sanitize) { var json = this.unfilterJSON(); try { if (!sanitize || json.isJSON()) return eval('(' + json + ')'); } catch (e) { } throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); }, include: function(pattern) { return this.indexOf(pattern) > -1; }, startsWith: function(pattern) { return this.indexOf(pattern) === 0; }, endsWith: function(pattern) { var d = this.length - pattern.length; return d >= 0 && this.lastIndexOf(pattern) === d; }, empty: function() { return this == ''; }, blank: function() { return /^\s*$/.test(this); } }); if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { escapeHTML: function() { return this.replace(/&/g,'&').replace(//g,'>'); }, unescapeHTML: function() { return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); } }); String.prototype.gsub.prepareReplacement = function(replacement) { if (typeof replacement == 'function') return replacement; var template = new Template(replacement); return function(match) { return template.evaluate(match) }; } String.prototype.parseQuery = String.prototype.toQueryParams; Object.extend(String.prototype.escapeHTML, { div: document.createElement('div'), text: document.createTextNode('') }); with (String.prototype.escapeHTML) div.appendChild(text); var Template = Class.create(); Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; Template.prototype = { initialize: function(template, pattern) { this.template = template.toString(); this.pattern = pattern || Template.Pattern; }, evaluate: function(object) { return this.template.gsub(this.pattern, function(match) { var before = match[1]; if (before == '\\') return match[2]; return before + String.interpret(object[match[3]]); }); } } var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead'); var Enumerable = { each: function(iterator) { var index = 0; try { this._each(function(value) { iterator(value, index++); }); } catch (e) { if (e != $break) throw e; } return this; }, eachSlice: function(number, iterator) { var index = -number, slices = [], array = this.toArray(); while ((index += number) < array.length) slices.push(array.slice(index, index+number)); return slices.map(iterator); }, all: function(iterator) { var result = true; this.each(function(value, index) { result = result && !!(iterator || Prototype.K)(value, index); if (!result) throw $break; }); return result; }, any: function(iterator) { var result = false; this.each(function(value, index) { if (result = !!(iterator || Prototype.K)(value, index)) throw $break; }); return result; }, collect: function(iterator) { var results = []; this.each(function(value, index) { results.push((iterator || Prototype.K)(value, index)); }); return results; }, detect: function(iterator) { var result; this.each(function(value, index) { if (iterator(value, index)) { result = value; throw $break; } }); return result; }, findAll: function(iterator) { var results = []; this.each(function(value, index) { if (iterator(value, index)) results.push(value); }); return results; }, grep: function(pattern, iterator) { var results = []; this.each(function(value, index) { var stringValue = value.toString(); if (stringValue.match(pattern)) results.push((iterator || Prototype.K)(value, index)); }) return results; }, include: function(object) { var found = false; this.each(function(value) { if (value == object) { found = true; throw $break; } }); return found; }, inGroupsOf: function(number, fillWith) { fillWith = fillWith === undefined ? null : fillWith; return this.eachSlice(number, function(slice) { while(slice.length < number) slice.push(fillWith); return slice; }); }, inject: function(memo, iterator) { this.each(function(value, index) { memo = iterator(memo, value, index); }); return memo; }, invoke: function(method) { var args = $A(arguments).slice(1); return this.map(function(value) { return value[method].apply(value, args); }); }, max: function(iterator) { var result; this.each(function(value, index) { value = (iterator || Prototype.K)(value, index); if (result == undefined || value >= result) result = value; }); return result; }, min: function(iterator) { var result; this.each(function(value, index) { value = (iterator || Prototype.K)(value, index); if (result == undefined || value < result) result = value; }); return result; }, partition: function(iterator) { var trues = [], falses = []; this.each(function(value, index) { ((iterator || Prototype.K)(value, index) ? trues : falses).push(value); }); return [trues, falses]; }, pluck: function(property) { var results = []; this.each(function(value, index) { results.push(value[property]); }); return results; }, reject: function(iterator) { var results = []; this.each(function(value, index) { if (!iterator(value, index)) results.push(value); }); return results; }, sortBy: function(iterator) { return this.map(function(value, index) { return {value: value, criteria: iterator(value, index)}; }).sort(function(left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }).pluck('value'); }, toArray: function() { return this.map(); }, zip: function() { var iterator = Prototype.K, args = $A(arguments); if (typeof args.last() == 'function') iterator = args.pop(); var collections = [this].concat(args).map($A); return this.map(function(value, index) { return iterator(collections.pluck(index)); }); }, size: function() { return this.toArray().length; }, inspect: function() { return '#'; } } Object.extend(Enumerable, { map: Enumerable.collect, find: Enumerable.detect, select: Enumerable.findAll, member: Enumerable.include, entries: Enumerable.toArray }); var $A = Array.from = function(iterable) { if (!iterable) return []; if (iterable.toArray) { return iterable.toArray(); } else { var results = []; for (var i = 0, length = iterable.length; i < length; i++) results.push(iterable[i]); return results; } } if (Prototype.Browser.WebKit) { $A = Array.from = function(iterable) { if (!iterable) return []; if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && iterable.toArray) { return iterable.toArray(); } else { var results = []; for (var i = 0, length = iterable.length; i < length; i++) results.push(iterable[i]); return results; } } } Object.extend(Array.prototype, Enumerable); if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; Object.extend(Array.prototype, { _each: function(iterator) { for (var i = 0, length = this.length; i < length; i++) iterator(this[i]); }, clear: function() { this.length = 0; return this; }, first: function() { return this[0]; }, last: function() { return this[this.length - 1]; }, compact: function() { return this.select(function(value) { return value != null; }); }, flatten: function() { return this.inject([], function(array, value) { return array.concat(value && value.constructor == Array ? value.flatten() : [value]); }); }, without: function() { var values = $A(arguments); return this.select(function(value) { return !values.include(value); }); }, indexOf: function(object) { for (var i = 0, length = this.length; i < length; i++) if (this[i] == object) return i; return -1; }, reverse: function(inline) { return (inline !== false ? this : this.toArray())._reverse(); }, reduce: function() { return this.length > 1 ? this : this[0]; }, uniq: function(sorted) { return this.inject([], function(array, value, index) { if (0 == index || (sorted ? array.last() != value : !array.include(value))) array.push(value); return array; }); }, clone: function() { return [].concat(this); }, size: function() { return this.length; }, inspect: function() { return '[' + this.map(Object.inspect).join(', ') + ']'; }, toJSON: function() { var results = []; this.each(function(object) { var value = Object.toJSON(object); if (value !== undefined) results.push(value); }); return '[' + results.join(', ') + ']'; } }); Array.prototype.toArray = Array.prototype.clone; function $w(string) { string = string.strip(); return string ? string.split(/\s+/) : []; } if (Prototype.Browser.Opera){ Array.prototype.concat = function() { var array = []; for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); for (var i = 0, length = arguments.length; i < length; i++) { if (arguments[i].constructor == Array) { for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) array.push(arguments[i][j]); } else { array.push(arguments[i]); } } return array; } } var Hash = function(object) { if (object instanceof Hash) this.merge(object); else Object.extend(this, object || {}); }; Object.extend(Hash, { toQueryString: function(obj) { var parts = []; parts.add = arguments.callee.addPair; this.prototype._each.call(obj, function(pair) { if (!pair.key) return; var value = pair.value; if (value && typeof value == 'object') { if (value.constructor == Array) value.each(function(value) { parts.add(pair.key, value); }); return; } parts.add(pair.key, value); }); return parts.join('&'); }, toJSON: function(object) { var results = []; this.prototype._each.call(object, function(pair) { var value = Object.toJSON(pair.value); if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value); }); return '{' + results.join(', ') + '}'; } }); Hash.toQueryString.addPair = function(key, value, prefix) { key = encodeURIComponent(key); if (value === undefined) this.push(key); else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value))); } Object.extend(Hash.prototype, Enumerable); Object.extend(Hash.prototype, { _each: function(iterator) { for (var key in this) { var value = this[key]; if (value && value == Hash.prototype[key]) continue; var pair = [key, value]; pair.key = key; pair.value = value; iterator(pair); } }, keys: function() { return this.pluck('key'); }, values: function() { return this.pluck('value'); }, merge: function(hash) { return $H(hash).inject(this, function(mergedHash, pair) { mergedHash[pair.key] = pair.value; return mergedHash; }); }, remove: function() { var result; for(var i = 0, length = arguments.length; i < length; i++) { var value = this[arguments[i]]; if (value !== undefined){ if (result === undefined) result = value; else { if (result.constructor != Array) result = [result]; result.push(value) } } delete this[arguments[i]]; } return result; }, toQueryString: function() { return Hash.toQueryString(this); }, inspect: function() { return '#'; }, toJSON: function() { return Hash.toJSON(this); } }); function $H(object) { if (object instanceof Hash) return object; return new Hash(object); }; // Safari iterates over shadowed properties if (function() { var i = 0, Test = function(value) { this.key = value }; Test.prototype.key = 'foo'; for (var property in new Test('bar')) i++; return i > 1; }()) Hash.prototype._each = function(iterator) { var cache = []; for (var key in this) { var value = this[key]; if ((value && value == Hash.prototype[key]) || cache.include(key)) continue; cache.push(key); var pair = [key, value]; pair.key = key; pair.value = value; iterator(pair); } }; ObjectRange = Class.create(); Object.extend(ObjectRange.prototype, Enumerable); Object.extend(ObjectRange.prototype, { initialize: function(start, end, exclusive) { this.start = start; this.end = end; this.exclusive = exclusive; }, _each: function(iterator) { var value = this.start; while (this.include(value)) { iterator(value); value = value.succ(); } }, include: function(value) { if (value < this.start) return false; if (this.exclusive) return value < this.end; return value <= this.end; } }); var $R = function(start, end, exclusive) { return new ObjectRange(start, end, exclusive); } var Ajax = { getTransport: function() { return Try.these( function() {return new XMLHttpRequest()}, function() {return new ActiveXObject('Msxml2.XMLHTTP')}, function() {return new ActiveXObject('Microsoft.XMLHTTP')} ) || false; }, activeRequestCount: 0 } Ajax.Responders = { responders: [], _each: function(iterator) { this.responders._each(iterator); }, register: function(responder) { if (!this.include(responder)) this.responders.push(responder); }, unregister: function(responder) { this.responders = this.responders.without(responder); }, dispatch: function(callback, request, transport, json) { this.each(function(responder) { if (typeof responder[callback] == 'function') { try { responder[callback].apply(responder, [request, transport, json]); } catch (e) {} } }); } }; Object.extend(Ajax.Responders, Enumerable); Ajax.Responders.register({ onCreate: function() { Ajax.activeRequestCount++; }, onComplete: function() { Ajax.activeRequestCount--; } }); Ajax.Base = function() {}; Ajax.Base.prototype = { setOptions: function(options) { this.options = { method: 'post', asynchronous: true, contentType: 'application/x-www-form-urlencoded', encoding: 'UTF-8', parameters: '' } Object.extend(this.options, options || {}); this.options.method = this.options.method.toLowerCase(); if (typeof this.options.parameters == 'string') this.options.parameters = this.options.parameters.toQueryParams(); } } Ajax.Request = Class.create(); Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; Ajax.Request.prototype = Object.extend(new Ajax.Base(), { _complete: false, initialize: function(url, options) { this.transport = Ajax.getTransport(); this.setOptions(options); this.request(url); }, request: function(url) { this.url = url; this.method = this.options.method; var params = Object.clone(this.options.parameters); if (!['get', 'post'].include(this.method)) { // simulate other verbs over post params['_method'] = this.method; this.method = 'post'; } this.parameters = params; if (params = Hash.toQueryString(params)) { // when GET, append parameters to URL if (this.method == 'get') this.url += (this.url.include('?') ? '&' : '?') + params; else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='; } try { if (this.options.onCreate) this.options.onCreate(this.transport); Ajax.Responders.dispatch('onCreate', this, this.transport); this.transport.open(this.method.toUpperCase(), this.url, this.options.asynchronous); if (this.options.asynchronous) setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10); this.transport.onreadystatechange = this.onStateChange.bind(this); this.setRequestHeaders(); this.body = this.method == 'post' ? (this.options.postBody || params) : null; this.transport.send(this.body); /* Force Firefox to handle ready state 4 for synchronous requests */ if (!this.options.asynchronous && this.transport.overrideMimeType) this.onStateChange(); } catch (e) { this.dispatchException(e); } }, onStateChange: function() { var readyState = this.transport.readyState; if (readyState > 1 && !((readyState == 4) && this._complete)) this.respondToReadyState(this.transport.readyState); }, setRequestHeaders: function() { var headers = { 'X-Requested-With': 'XMLHttpRequest', 'X-Prototype-Version': Prototype.Version, 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }; if (this.method == 'post') { headers['Content-type'] = this.options.contentType + (this.options.encoding ? '; charset=' + this.options.encoding : ''); /* Force "Connection: close" for older Mozilla browsers to work * around a bug where XMLHttpRequest sends an incorrect * Content-length header. See Mozilla Bugzilla #246651. */ if (this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) headers['Connection'] = 'close'; } // user-defined headers if (typeof this.options.requestHeaders == 'object') { var extras = this.options.requestHeaders; if (typeof extras.push == 'function') for (var i = 0, length = extras.length; i < length; i += 2) headers[extras[i]] = extras[i+1]; else $H(extras).each(function(pair) { headers[pair.key] = pair.value }); } for (var name in headers) this.transport.setRequestHeader(name, headers[name]); }, success: function() { return !this.transport.status || (this.transport.status >= 200 && this.transport.status < 300); }, respondToReadyState: function(readyState) { var state = Ajax.Request.Events[readyState]; var transport = this.transport, json = this.evalJSON(); if (state == 'Complete') { try { this._complete = true; (this.options['on' + this.transport.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(transport, json); } catch (e) { this.dispatchException(e); } var contentType = this.getHeader('Content-type'); if (contentType && contentType.strip(). match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i)) this.evalResponse(); } try { (this.options['on' + state] || Prototype.emptyFunction)(transport, json); Ajax.Responders.dispatch('on' + state, this, transport, json); } catch (e) { this.dispatchException(e); } if (state == 'Complete') { // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = Prototype.emptyFunction; } }, getHeader: function(name) { try { return this.transport.getResponseHeader(name); } catch (e) { return null } }, evalJSON: function() { try { var json = this.getHeader('X-JSON'); return json ? json.evalJSON() : null; } catch (e) { return null } }, evalResponse: function() { try { return eval((this.transport.responseText || '').unfilterJSON()); } catch (e) { this.dispatchException(e); } }, dispatchException: function(exception) { (this.options.onException || Prototype.emptyFunction)(this, exception); Ajax.Responders.dispatch('onException', this, exception); } }); Ajax.Updater = Class.create(); Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { initialize: function(container, url, options) { this.container = { success: (container.success || container), failure: (container.failure || (container.success ? null : container)) } this.transport = Ajax.getTransport(); this.setOptions(options); var onComplete = this.options.onComplete || Prototype.emptyFunction; this.options.onComplete = (function(transport, param) { this.updateContent(); onComplete(transport, param); }).bind(this); this.request(url); }, updateContent: function() { var receiver = this.container[this.success() ? 'success' : 'failure']; var response = this.transport.responseText; if (!this.options.evalScripts) response = response.stripScripts(); if (receiver = $(receiver)) { if (this.options.insertion) new this.options.insertion(receiver, response); else receiver.update(response); } if (this.success()) { if (this.onComplete) setTimeout(this.onComplete.bind(this), 10); } } }); Ajax.PeriodicalUpdater = Class.create(); Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { initialize: function(container, url, options) { this.setOptions(options); this.onComplete = this.options.onComplete; this.frequency = (this.options.frequency || 2); this.decay = (this.options.decay || 1); this.updater = {}; this.container = container; this.url = url; this.start(); }, start: function() { this.options.onComplete = this.updateComplete.bind(this); this.onTimerEvent(); }, stop: function() { this.updater.options.onComplete = undefined; clearTimeout(this.timer); (this.onComplete || Prototype.emptyFunction).apply(this, arguments); }, updateComplete: function(request) { if (this.options.decay) { this.decay = (request.responseText == this.lastText ? this.decay * this.options.decay : 1); this.lastText = request.responseText; } this.timer = setTimeout(this.onTimerEvent.bind(this), this.decay * this.frequency * 1000); }, onTimerEvent: function() { this.updater = new Ajax.Updater(this.container, this.url, this.options); } }); function $(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) elements.push($(arguments[i])); return elements; } if (typeof element == 'string') element = document.getElementById(element); return Element.extend(element); } if (Prototype.BrowserFeatures.XPath) { document._getElementsByXPath = function(expression, parentElement) { var results = []; var query = document.evaluate(expression, $(parentElement) || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (var i = 0, length = query.snapshotLength; i < length; i++) results.push(query.snapshotItem(i)); return results; }; document.getElementsByClassName = function(className, parentElement) { var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]"; return document._getElementsByXPath(q, parentElement); } } else document.getElementsByClassName = function(className, parentElement) { var children = ($(parentElement) || document.body).getElementsByTagName('*'); var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)"); for (var i = 0, length = children.length; i < length; i++) { child = children[i]; var elementClassName = child.className; if (elementClassName.length == 0) continue; if (elementClassName == className || elementClassName.match(pattern)) elements.push(Element.extend(child)); } return elements; }; /*--------------------------------------------------------------------------*/ if (!window.Element) var Element = {}; Element.extend = function(element) { var F = Prototype.BrowserFeatures; if (!element || !element.tagName || element.nodeType == 3 || element._extended || F.SpecificElementExtensions || element == window) return element; var methods = {}, tagName = element.tagName, cache = Element.extend.cache, T = Element.Methods.ByTag; // extend methods for all tags (Safari doesn't need this) if (!F.ElementExtensions) { Object.extend(methods, Element.Methods), Object.extend(methods, Element.Methods.Simulated); } // extend methods for specific tags if (T[tagName]) Object.extend(methods, T[tagName]); for (var property in methods) { var value = methods[property]; if (typeof value == 'function' && !(property in element)) element[property] = cache.findOrStore(value); } element._extended = Prototype.emptyFunction; return element; }; Element.extend.cache = { findOrStore: function(value) { return this[value] = this[value] || function() { return value.apply(null, [this].concat($A(arguments))); } } }; Element.Methods = { visible: function(element) { return $(element).style.display != 'none'; }, toggle: function(element) { element = $(element); Element[Element.visible(element) ? 'hide' : 'show'](element); return element; }, hide: function(element) { $(element).style.display = 'none'; return element; }, show: function(element) { $(element).style.display = ''; return element; }, remove: function(element) { element = $(element); element.parentNode.removeChild(element); return element; }, update: function(element, html) { html = typeof html == 'undefined' ? '' : html.toString(); $(element).innerHTML = html.stripScripts(); setTimeout(function() {html.evalScripts()}, 10); return element; }, replace: function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); if (element.outerHTML) { element.outerHTML = html.stripScripts(); } else { var range = element.ownerDocument.createRange(); range.selectNodeContents(element); element.parentNode.replaceChild( range.createContextualFragment(html.stripScripts()), element); } setTimeout(function() {html.evalScripts()}, 10); return element; }, inspect: function(element) { element = $(element); var result = '<' + element.tagName.toLowerCase(); $H({'id': 'id', 'className': 'class'}).each(function(pair) { var property = pair.first(), attribute = pair.last(); var value = (element[property] || '').toString(); if (value) result += ' ' + attribute + '=' + value.inspect(true); }); return result + '>'; }, recursivelyCollect: function(element, property) { element = $(element); var elements = []; while (element = element[property]) if (element.nodeType == 1) elements.push(Element.extend(element)); return elements; }, ancestors: function(element) { return $(element).recursivelyCollect('parentNode'); }, descendants: function(element) { return $A($(element).getElementsByTagName('*')).each(Element.extend); }, firstDescendant: function(element) { element = $(element).firstChild; while (element && element.nodeType != 1) element = element.nextSibling; return $(element); }, immediateDescendants: function(element) { if (!(element = $(element).firstChild)) return []; while (element && element.nodeType != 1) element = element.nextSibling; if (element) return [element].concat($(element).nextSiblings()); return []; }, previousSiblings: function(element) { return $(element).recursivelyCollect('previousSibling'); }, nextSiblings: function(element) { return $(element).recursivelyCollect('nextSibling'); }, siblings: function(element) { element = $(element); return element.previousSiblings().reverse().concat(element.nextSiblings()); }, match: function(element, selector) { if (typeof selector == 'string') selector = new Selector(selector); return selector.match($(element)); }, up: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(element.parentNode); var ancestors = element.ancestors(); return expression ? Selector.findElement(ancestors, expression, index) : ancestors[index || 0]; }, down: function(element, expression, index) { element = $(element); if (arguments.length == 1) return element.firstDescendant(); var descendants = element.descendants(); return expression ? Selector.findElement(descendants, expression, index) : descendants[index || 0]; }, previous: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); var previousSiblings = element.previousSiblings(); return expression ? Selector.findElement(previousSiblings, expression, index) : previousSiblings[index || 0]; }, next: function(element, expression, index) { element = $(element); if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); var nextSiblings = element.nextSiblings(); return expression ? Selector.findElement(nextSiblings, expression, index) : nextSiblings[index || 0]; }, getElementsBySelector: function() { var args = $A(arguments), element = $(args.shift()); return Selector.findChildElements(element, args); }, getElementsByClassName: function(element, className) { return document.getElementsByClassName(className, element); }, readAttribute: function(element, name) { element = $(element); if (Prototype.Browser.IE) { if (!element.attributes) return null; var t = Element._attributeTranslations; if (t.values[name]) return t.values[name](element, name); if (t.names[name]) name = t.names[name]; var attribute = element.attributes[name]; return attribute ? attribute.nodeValue : null; } return element.getAttribute(name); }, getHeight: function(element) { return $(element).getDimensions().height; }, getWidth: function(element) { return $(element).getDimensions().width; }, classNames: function(element) { return new Element.ClassNames(element); }, hasClassName: function(element, className) { if (!(element = $(element))) return; var elementClassName = element.className; if (elementClassName.length == 0) return false; if (elementClassName == className || elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) return true; return false; }, addClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).add(className); return element; }, removeClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element).remove(className); return element; }, toggleClassName: function(element, className) { if (!(element = $(element))) return; Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className); return element; }, observe: function() { Event.observe.apply(Event, arguments); return $A(arguments).first(); }, stopObserving: function() { Event.stopObserving.apply(Event, arguments); return $A(arguments).first(); }, // removes whitespace-only text node children cleanWhitespace: function(element) { element = $(element); var node = element.firstChild; while (node) { var nextNode = node.nextSibling; if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) element.removeChild(node); node = nextNode; } return element; }, empty: function(element) { return $(element).innerHTML.blank(); }, descendantOf: function(element, ancestor) { element = $(element), ancestor = $(ancestor); while (element = element.parentNode) if (element == ancestor) return true; return false; }, scrollTo: function(element) { element = $(element); var pos = Position.cumulativeOffset(element); window.scrollTo(pos[0], pos[1]); return element; }, getStyle: function(element, style) { element = $(element); style = style == 'float' ? 'cssFloat' : style.camelize(); var value = element.style[style]; if (!value) { var css = document.defaultView.getComputedStyle(element, null); value = css ? css[style] : null; } if (style == 'opacity') return value ? parseFloat(value) : 1.0; return value == 'auto' ? null : value; }, getOpacity: function(element) { return $(element).getStyle('opacity'); }, setStyle: function(element, styles, camelized) { element = $(element); var elementStyle = element.style; for (var property in styles) if (property == 'opacity') element.setOpacity(styles[property]) else elementStyle[(property == 'float' || property == 'cssFloat') ? (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') : (camelized ? property : property.camelize())] = styles[property]; return element; }, setOpacity: function(element, value) { element = $(element); element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value; return element; }, getDimensions: function(element) { element = $(element); var display = $(element).getStyle('display'); if (display != 'none' && display != null) // Safari bug return {width: element.offsetWidth, height: element.offsetHeight}; // All *Width and *Height properties give 0 on elements with display none, // so enable the element temporarily var els = element.style; var originalVisibility = els.visibility; var originalPosition = els.position; var originalDisplay = els.display; els.visibility = 'hidden'; els.position = 'absolute'; els.display = 'block'; var originalWidth = element.clientWidth; var originalHeight = element.clientHeight; els.display = originalDisplay; els.position = originalPosition; els.visibility = originalVisibility; return {width: originalWidth, height: originalHeight}; }, makePositioned: function(element) { element = $(element); var pos = Element.getStyle(element, 'position'); if (pos == 'static' || !pos) { element._madePositioned = true; element.style.position = 'relative'; // Opera returns the offset relative to the positioning context, when an // element is position relative but top and left have not been defined if (window.opera) { element.style.top = 0; element.style.left = 0; } } return element; }, undoPositioned: function(element) { element = $(element); if (element._madePositioned) { element._madePositioned = undefined; element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = ''; } return element; }, makeClipping: function(element) { element = $(element); if (element._overflow) return element; element._overflow = element.style.overflow || 'auto'; if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') element.style.overflow = 'hidden'; return element; }, undoClipping: function(element) { element = $(element); if (!element._overflow) return element; element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; element._overflow = null; return element; } }; Object.extend(Element.Methods, { childOf: Element.Methods.descendantOf, childElements: Element.Methods.immediateDescendants }); if (Prototype.Browser.Opera) { Element.Methods._getStyle = Element.Methods.getStyle; Element.Methods.getStyle = function(element, style) { switch(style) { case 'left': case 'top': case 'right': case 'bottom': if (Element._getStyle(element, 'position') == 'static') return null; default: return Element._getStyle(element, style); } }; } else if (Prototype.Browser.IE) { Element.Methods.getStyle = function(element, style) { element = $(element); style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); var value = element.style[style]; if (!value && element.currentStyle) value = element.currentStyle[style]; if (style == 'opacity') { if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) if (value[1]) return parseFloat(value[1]) / 100; return 1.0; } if (value == 'auto') { if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) return element['offset'+style.capitalize()] + 'px'; return null; } return value; }; Element.Methods.setOpacity = function(element, value) { element = $(element); var filter = element.getStyle('filter'), style = element.style; if (value == 1 || value === '') { style.filter = filter.replace(/alpha\([^\)]*\)/gi,''); return element; } else if (value < 0.00001) value = 0; style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + (value * 100) + ')'; return element; }; // IE is missing .innerHTML support for TABLE-related elements Element.Methods.update = function(element, html) { element = $(element); html = typeof html == 'undefined' ? '' : html.toString(); var tagName = element.tagName.toUpperCase(); if (['THEAD','TBODY','TR','TD'].include(tagName)) { var div = document.createElement('div'); switch (tagName) { case 'THEAD': case 'TBODY': div.innerHTML = '' + html.stripScripts() + '
'; depth = 2; break; case 'TR': div.innerHTML = '' + html.stripScripts() + '
'; depth = 3; break; case 'TD': div.innerHTML = '
' + html.stripScripts() + '
'; depth = 4; } $A(element.childNodes).each(function(node) { element.removeChild(node) }); depth.times(function() { div = div.firstChild }); $A(div.childNodes).each(function(node) { element.appendChild(node) }); } else { element.innerHTML = html.stripScripts(); } setTimeout(function() { html.evalScripts() }, 10); return element; } } else if (Prototype.Browser.Gecko) { Element.Methods.setOpacity = function(element, value) { element = $(element); element.style.opacity = (value == 1) ? 0.999999 : (value === '') ? '' : (value < 0.00001) ? 0 : value; return element; }; } Element._attributeTranslations = { names: { colspan: "colSpan", rowspan: "rowSpan", valign: "vAlign", datetime: "dateTime", accesskey: "accessKey", tabindex: "tabIndex", enctype: "encType", maxlength: "maxLength", readonly: "readOnly", longdesc: "longDesc" }, values: { _getAttr: function(element, attribute) { return element.getAttribute(attribute, 2); }, _flag: function(element, attribute) { return $(element).hasAttribute(attribute) ? attribute : null; }, style: function(element) { return element.style.cssText.toLowerCase(); }, title: function(element) { var node = element.getAttributeNode('title'); return node.specified ? node.nodeValue : null; } } }; (function() { Object.extend(this, { href: this._getAttr, src: this._getAttr, type: this._getAttr, disabled: this._flag, checked: this._flag, readonly: this._flag, multiple: this._flag }); }).call(Element._attributeTranslations.values); Element.Methods.Simulated = { hasAttribute: function(element, attribute) { var t = Element._attributeTranslations, node; attribute = t.names[attribute] || attribute; node = $(element).getAttributeNode(attribute); return node && node.specified; } }; Element.Methods.ByTag = {}; Object.extend(Element, Element.Methods); if (!Prototype.BrowserFeatures.ElementExtensions && document.createElement('div').__proto__) { window.HTMLElement = {}; window.HTMLElement.prototype = document.createElement('div').__proto__; Prototype.BrowserFeatures.ElementExtensions = true; } Element.hasAttribute = function(element, attribute) { if (element.hasAttribute) return element.hasAttribute(attribute); return Element.Methods.Simulated.hasAttribute(element, attribute); }; Element.addMethods = function(methods) { var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; if (!methods) { Object.extend(Form, Form.Methods); Object.extend(Form.Element, Form.Element.Methods); Object.extend(Element.Methods.ByTag, { "FORM": Object.clone(Form.Methods), "INPUT": Object.clone(Form.Element.Methods), "SELECT": Object.clone(Form.Element.Methods), "TEXTAREA": Object.clone(Form.Element.Methods) }); } if (arguments.length == 2) { var tagName = methods; methods = arguments[1]; } if (!tagName) Object.extend(Element.Methods, methods || {}); else { if (tagName.constructor == Array) tagName.each(extend); else extend(tagName); } function extend(tagName) { tagName = tagName.toUpperCase(); if (!Element.Methods.ByTag[tagName]) Element.Methods.ByTag[tagName] = {}; Object.extend(Element.Methods.ByTag[tagName], methods); } function copy(methods, destination, onlyIfAbsent) { onlyIfAbsent = onlyIfAbsent || false; var cache = Element.extend.cache; for (var property in methods) { var value = methods[property]; if (!onlyIfAbsent || !(property in destination)) destination[property] = cache.findOrStore(value); } } function findDOMClass(tagName) { var klass; var trans = { "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": "FrameSet", "IFRAME": "IFrame" }; if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; if (window[klass]) return window[klass]; klass = 'HTML' + tagName + 'Element'; if (window[klass]) return window[klass]; klass = 'HTML' + tagName.capitalize() + 'Element'; if (window[klass]) return window[klass]; window[klass] = {}; window[klass].prototype = document.createElement(tagName).__proto__; return window[klass]; } if (F.ElementExtensions) { copy(Element.Methods, HTMLElement.prototype); copy(Element.Methods.Simulated, HTMLElement.prototype, true); } if (F.SpecificElementExtensions) { for (var tag in Element.Methods.ByTag) { var klass = findDOMClass(tag); if (typeof klass == "undefined") continue; copy(T[tag], klass.prototype); } } Object.extend(Element, Element.Methods); delete Element.ByTag; }; var Toggle = { display: Element.toggle }; /*--------------------------------------------------------------------------*/ Abstract.Insertion = function(adjacency) { this.adjacency = adjacency; } Abstract.Insertion.prototype = { initialize: function(element, content) { this.element = $(element); this.content = content.stripScripts(); if (this.adjacency && this.element.insertAdjacentHTML) { try { this.element.insertAdjacentHTML(this.adjacency, this.content); } catch (e) { var tagName = this.element.tagName.toUpperCase(); if (['TBODY', 'TR'].include(tagName)) { this.insertContent(this.contentFromAnonymousTable()); } else { throw e; } } } else { this.range = this.element.ownerDocument.createRange(); if (this.initializeRange) this.initializeRange(); this.insertContent([this.range.createContextualFragment(this.content)]); } setTimeout(function() {content.evalScripts()}, 10); }, contentFromAnonymousTable: function() { var div = document.createElement('div'); div.innerHTML = '' + this.content + '
'; return $A(div.childNodes[0].childNodes[0].childNodes); } } var Insertion = new Object(); Insertion.Before = Class.create(); Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { initializeRange: function() { this.range.setStartBefore(this.element); }, insertContent: function(fragments) { fragments.each((function(fragment) { this.element.parentNode.insertBefore(fragment, this.element); }).bind(this)); } }); Insertion.Top = Class.create(); Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { initializeRange: function() { this.range.selectNodeContents(this.element); this.range.collapse(true); }, insertContent: function(fragments) { fragments.reverse(false).each((function(fragment) { this.element.insertBefore(fragment, this.element.firstChild); }).bind(this)); } }); Insertion.Bottom = Class.create(); Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { initializeRange: function() { this.range.selectNodeContents(this.element); this.range.collapse(this.element); }, insertContent: function(fragments) { fragments.each((function(fragment) { this.element.appendChild(fragment); }).bind(this)); } }); Insertion.After = Class.create(); Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { initializeRange: function() { this.range.setStartAfter(this.element); }, insertContent: function(fragments) { fragments.each((function(fragment) { this.element.parentNode.insertBefore(fragment, this.element.nextSibling); }).bind(this)); } }); /*--------------------------------------------------------------------------*/ Element.ClassNames = Class.create(); Element.ClassNames.prototype = { initialize: function(element) { this.element = $(element); }, _each: function(iterator) { this.element.className.split(/\s+/).select(function(name) { return name.length > 0; })._each(iterator); }, set: function(className) { this.element.className = className; }, add: function(classNameToAdd) { if (this.include(classNameToAdd)) return; this.set($A(this).concat(classNameToAdd).join(' ')); }, remove: function(classNameToRemove) { if (!this.include(classNameToRemove)) return; this.set($A(this).without(classNameToRemove).join(' ')); }, toString: function() { return $A(this).join(' '); } }; Object.extend(Element.ClassNames.prototype, Enumerable); /* Portions of the Selector class are derived from Jack Slocums DomQuery, * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style * license. Please see http://www.yui-ext.com/ for more information. */ var Selector = Class.create(); Selector.prototype = { initialize: function(expression) { this.expression = expression.strip(); this.compileMatcher(); }, compileMatcher: function() { // Selectors with namespaced attributes can't use the XPath version if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression)) return this.compileXPathMatcher(); var e = this.expression, ps = Selector.patterns, h = Selector.handlers, c = Selector.criteria, le, p, m; if (Selector._cache[e]) { this.matcher = Selector._cache[e]; return; } this.matcher = ["this.matcher = function(root) {", "var r = root, h = Selector.handlers, c = false, n;"]; while (e && le != e && (/\S/).test(e)) { le = e; for (var i in ps) { p = ps[i]; if (m = e.match(p)) { this.matcher.push(typeof c[i] == 'function' ? c[i](m) : new Template(c[i]).evaluate(m)); e = e.replace(m[0], ''); break; } } } this.matcher.push("return h.unique(n);\n}"); eval(this.matcher.join('\n')); Selector._cache[this.expression] = this.matcher; }, compileXPathMatcher: function() { var e = this.expression, ps = Selector.patterns, x = Selector.xpath, le, m; if (Selector._cache[e]) { this.xpath = Selector._cache[e]; return; } this.matcher = ['.//*']; while (e && le != e && (/\S/).test(e)) { le = e; for (var i in ps) { if (m = e.match(ps[i])) { this.matcher.push(typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m)); e = e.replace(m[0], ''); break; } } } this.xpath = this.matcher.join(''); Selector._cache[this.expression] = this.xpath; }, findElements: function(root) { root = root || document; if (this.xpath) return document._getElementsByXPath(this.xpath, root); return this.matcher(root); }, match: function(element) { return this.findElements(document).include(element); }, toString: function() { return this.expression; }, inspect: function() { return "#"; } }; Object.extend(Selector, { _cache: {}, xpath: { descendant: "//*", child: "/*", adjacent: "/following-sibling::*[1]", laterSibling: '/following-sibling::*', tagName: function(m) { if (m[1] == '*') return ''; return "[local-name()='" + m[1].toLowerCase() + "' or local-name()='" + m[1].toUpperCase() + "']"; }, className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", id: "[@id='#{1}']", attrPresence: "[@#{1}]", attr: function(m) { m[3] = m[5] || m[6]; return new Template(Selector.xpath.operators[m[2]]).evaluate(m); }, pseudo: function(m) { var h = Selector.xpath.pseudos[m[1]]; if (!h) return ''; if (typeof h === 'function') return h(m); return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); }, operators: { '=': "[@#{1}='#{3}']", '!=': "[@#{1}!='#{3}']", '^=': "[starts-with(@#{1}, '#{3}')]", '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", '*=': "[contains(@#{1}, '#{3}')]", '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" }, pseudos: { 'first-child': '[not(preceding-sibling::*)]', 'last-child': '[not(following-sibling::*)]', 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", 'checked': "[@checked]", 'disabled': "[@disabled]", 'enabled': "[not(@disabled)]", 'not': function(m) { var e = m[6], p = Selector.patterns, x = Selector.xpath, le, m, v; var exclusion = []; while (e && le != e && (/\S/).test(e)) { le = e; for (var i in p) { if (m = e.match(p[i])) { v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m); exclusion.push("(" + v.substring(1, v.length - 1) + ")"); e = e.replace(m[0], ''); break; } } } return "[not(" + exclusion.join(" and ") + ")]"; }, 'nth-child': function(m) { return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); }, 'nth-last-child': function(m) { return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); }, 'nth-of-type': function(m) { return Selector.xpath.pseudos.nth("position() ", m); }, 'nth-last-of-type': function(m) { return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); }, 'first-of-type': function(m) { m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); }, 'last-of-type': function(m) { m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); }, 'only-of-type': function(m) { var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); }, nth: function(fragment, m) { var mm, formula = m[6], predicate; if (formula == 'even') formula = '2n+0'; if (formula == 'odd') formula = '2n+1'; if (mm = formula.match(/^(\d+)$/)) // digit only return '[' + fragment + "= " + mm[1] + ']'; if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b if (mm[1] == "-") mm[1] = -1; var a = mm[1] ? Number(mm[1]) : 1; var b = mm[2] ? Number(mm[2]) : 0; predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + "((#{fragment} - #{b}) div #{a} >= 0)]"; return new Template(predicate).evaluate({ fragment: fragment, a: a, b: b }); } } } }, criteria: { tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', className: 'n = h.className(n, r, "#{1}", c); c = false;', id: 'n = h.id(n, r, "#{1}", c); c = false;', attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;', attr: function(m) { m[3] = (m[5] || m[6]); return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m); }, pseudo: function(m) { if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); }, descendant: 'c = "descendant";', child: 'c = "child";', adjacent: 'c = "adjacent";', laterSibling: 'c = "laterSibling";' }, patterns: { // combinators must be listed first // (and descendant needs to be last combinator) laterSibling: /^\s*~\s*/, child: /^\s*>\s*/, adjacent: /^\s*\+\s*/, descendant: /^\s/, // selectors follow tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, id: /^#([\w\-\*]+)(\b|$)/, className: /^\.([\w\-\*]+)(\b|$)/, pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/, attrPresence: /^\[([\w]+)\]/, attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/ }, handlers: { // UTILITY FUNCTIONS // joins two collections concat: function(a, b) { for (var i = 0, node; node = b[i]; i++) a.push(node); return a; }, // marks an array of nodes for counting mark: function(nodes) { for (var i = 0, node; node = nodes[i]; i++) node._counted = true; return nodes; }, unmark: function(nodes) { for (var i = 0, node; node = nodes[i]; i++) node._counted = undefined; return nodes; }, // mark each child node with its position (for nth calls) // "ofType" flag indicates whether we're indexing for nth-of-type // rather than nth-child index: function(parentNode, reverse, ofType) { parentNode._counted = true; if (reverse) { for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { node = nodes[i]; if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; } } else { for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++; } }, // filters out duplicates and extends all nodes unique: function(nodes) { if (nodes.length == 0) return nodes; var results = [], n; for (var i = 0, l = nodes.length; i < l; i++) if (!(n = nodes[i])._counted) { n._counted = true; results.push(Element.extend(n)); } return Selector.handlers.unmark(results); }, // COMBINATOR FUNCTIONS descendant: function(nodes) { var h = Selector.handlers; for (var i = 0, results = [], node; node = nodes[i]; i++) h.concat(results, node.getElementsByTagName('*')); return results; }, child: function(nodes) { var h = Selector.handlers; for (var i = 0, results = [], node; node = nodes[i]; i++) { for (var j = 0, children = [], child; child = node.childNodes[j]; j++) if (child.nodeType == 1 && child.tagName != '!') results.push(child); } return results; }, adjacent: function(nodes) { for (var i = 0, results = [], node; node = nodes[i]; i++) { var next = this.nextElementSibling(node); if (next) results.push(next); } return results; }, laterSibling: function(nodes) { var h = Selector.handlers; for (var i = 0, results = [], node; node = nodes[i]; i++) h.concat(results, Element.nextSiblings(node)); return results; }, nextElementSibling: function(node) { while (node = node.nextSibling) if (node.nodeType == 1) return node; return null; }, previousElementSibling: function(node) { while (node = node.previousSibling) if (node.nodeType == 1) return node; return null; }, // TOKEN FUNCTIONS tagName: function(nodes, root, tagName, combinator) { tagName = tagName.toUpperCase(); var results = [], h = Selector.handlers; if (nodes) { if (combinator) { // fastlane for ordinary descendant combinators if (combinator == "descendant") { for (var i = 0, node; node = nodes[i]; i++) h.concat(results, node.getElementsByTagName(tagName)); return results; } else nodes = this[combinator](nodes); if (tagName == "*") return nodes; } for (var i = 0, node; node = nodes[i]; i++) if (node.tagName.toUpperCase() == tagName) results.push(node); return results; } else return root.getElementsByTagName(tagName); }, id: function(nodes, root, id, combinator) { var targetNode = $(id), h = Selector.handlers; if (!nodes && root == document) return targetNode ? [targetNode] : []; if (nodes) { if (combinator) { if (combinator == 'child') { for (var i = 0, node; node = nodes[i]; i++) if (targetNode.parentNode == node) return [targetNode]; } else if (combinator == 'descendant') { for (var i = 0, node; node = nodes[i]; i++) if (Element.descendantOf(targetNode, node)) return [targetNode]; } else if (combinator == 'adjacent') { for (var i = 0, node; node = nodes[i]; i++) if (Selector.handlers.previousElementSibling(targetNode) == node) return [targetNode]; } else nodes = h[combinator](nodes); } for (var i = 0, node; node = nodes[i]; i++) if (node == targetNode) return [targetNode]; return []; } return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; }, className: function(nodes, root, className, combinator) { if (nodes && combinator) nodes = this[combinator](nodes); return Selector.handlers.byClassName(nodes, root, className); }, byClassName: function(nodes, root, className) { if (!nodes) nodes = Selector.handlers.descendant([root]); var needle = ' ' + className + ' '; for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { nodeClassName = node.className; if (nodeClassName.length == 0) continue; if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) results.push(node); } return results; }, attrPresence: function(nodes, root, attr) { var results = []; for (var i = 0, node; node = nodes[i]; i++) if (Element.hasAttribute(node, attr)) results.push(node); return results; }, attr: function(nodes, root, attr, value, operator) { if (!nodes) nodes = root.getElementsByTagName("*"); var handler = Selector.operators[operator], results = []; for (var i = 0, node; node = nodes[i]; i++) { var nodeValue = Element.readAttribute(node, attr); if (nodeValue === null) continue; if (handler(nodeValue, value)) results.push(node); } return results; }, pseudo: function(nodes, name, value, root, combinator) { if (nodes && combinator) nodes = this[combinator](nodes); if (!nodes) nodes = root.getElementsByTagName("*"); return Selector.pseudos[name](nodes, value, root); } }, pseudos: { 'first-child': function(nodes, value, root) { for (var i = 0, results = [], node; node = nodes[i]; i++) { if (Selector.handlers.previousElementSibling(node)) continue; results.push(node); } return results; }, 'last-child': function(nodes, value, root) { for (var i = 0, results = [], node; node = nodes[i]; i++) { if (Selector.handlers.nextElementSibling(node)) continue; results.push(node); } return results; }, 'only-child': function(nodes, value, root) { var h = Selector.handlers; for (var i = 0, results = [], node; node = nodes[i]; i++) if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) results.push(node); return results; }, 'nth-child': function(nodes, formula, root) { return Selector.pseudos.nth(nodes, formula, root); }, 'nth-last-child': function(nodes, formula, root) { return Selector.pseudos.nth(nodes, formula, root, true); }, 'nth-of-type': function(nodes, formula, root) { return Selector.pseudos.nth(nodes, formula, root, false, true); }, 'nth-last-of-type': function(nodes, formula, root) { return Selector.pseudos.nth(nodes, formula, root, true, true); }, 'first-of-type': function(nodes, formula, root) { return Selector.pseudos.nth(nodes, "1", root, false, true); }, 'last-of-type': function(nodes, formula, root) { return Selector.pseudos.nth(nodes, "1", root, true, true); }, 'only-of-type': function(nodes, formula, root) { var p = Selector.pseudos; return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); }, // handles the an+b logic getIndices: function(a, b, total) { if (a == 0) return b > 0 ? [b] : []; return $R(1, total).inject([], function(memo, i) { if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); return memo; }); }, // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type nth: function(nodes, formula, root, reverse, ofType) { if (nodes.length == 0) return []; if (formula == 'even') formula = '2n+0'; if (formula == 'odd') formula = '2n+1'; var h = Selector.handlers, results = [], indexed = [], m; h.mark(nodes); for (var i = 0, node; node = nodes[i]; i++) { if (!node.parentNode._counted) { h.index(node.parentNode, reverse, ofType); indexed.push(node.parentNode); } } if (formula.match(/^\d+$/)) { // just a number formula = Number(formula); for (var i = 0, node; node = nodes[i]; i++) if (node.nodeIndex == formula) results.push(node); } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b if (m[1] == "-") m[1] = -1; var a = m[1] ? Number(m[1]) : 1; var b = m[2] ? Number(m[2]) : 0; var indices = Selector.pseudos.getIndices(a, b, nodes.length); for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { for (var j = 0; j < l; j++) if (node.nodeIndex == indices[j]) results.push(node); } } h.unmark(nodes); h.unmark(indexed); return results; }, 'empty': function(nodes, value, root) { for (var i = 0, results = [], node; node = nodes[i]; i++) { // IE treats comments as element nodes if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; results.push(node); } return results; }, 'not': function(nodes, selector, root) { var h = Selector.handlers, selectorType, m; var exclusions = new Selector(selector).findElements(root); h.mark(exclusions); for (var i = 0, results = [], node; node = nodes[i]; i++) if (!node._counted) results.push(node); h.unmark(exclusions); return results; }, 'enabled': function(nodes, value, root) { for (var i = 0, results = [], node; node = nodes[i]; i++) if (!node.disabled) results.push(node); return results; }, 'disabled': function(nodes, value, root) { for (var i = 0, results = [], node; node = nodes[i]; i++) if (node.disabled) results.push(node); return results; }, 'checked': function(nodes, value, root) { for (var i = 0, results = [], node; node = nodes[i]; i++) if (node.checked) results.push(node); return results; } }, operators: { '=': function(nv, v) { return nv == v; }, '!=': function(nv, v) { return nv != v; }, '^=': function(nv, v) { return nv.startsWith(v); }, '$=': function(nv, v) { return nv.endsWith(v); }, '*=': function(nv, v) { return nv.include(v); }, '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } }, matchElements: function(elements, expression) { var matches = new Selector(expression).findElements(), h = Selector.handlers; h.mark(matches); for (var i = 0, results = [], element; element = elements[i]; i++) if (element._counted) results.push(element); h.unmark(matches); return results; }, findElement: function(elements, expression, index) { if (typeof expression == 'number') { index = expression; expression = false; } return Selector.matchElements(elements, expression || '*')[index || 0]; }, findChildElements: function(element, expressions) { var exprs = expressions.join(','), expressions = []; exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { expressions.push(m[1].strip()); }); var results = [], h = Selector.handlers; for (var i = 0, l = expressions.length, selector; i < l; i++) { selector = new Selector(expressions[i].strip()); h.concat(results, selector.findElements(element)); } return (l > 1) ? h.unique(results) : results; } }); function $$() { return Selector.findChildElements(document, $A(arguments)); } var Form = { reset: function(form) { $(form).reset(); return form; }, serializeElements: function(elements, getHash) { var data = elements.inject({}, function(result, element) { if (!element.disabled && element.name) { var key = element.name, value = $(element).getValue(); if (value != null) { if (key in result) { if (result[key].constructor != Array) result[key] = [result[key]]; result[key].push(value); } else result[key] = value; } } return result; }); return getHash ? data : Hash.toQueryString(data); } }; Form.Methods = { serialize: function(form, getHash) { return Form.serializeElements(Form.getElements(form), getHash); }, getElements: function(form) { return $A($(form).getElementsByTagName('*')).inject([], function(elements, child) { if (Form.Element.Serializers[child.tagName.toLowerCase()]) elements.push(Element.extend(child)); return elements; } ); }, getInputs: function(form, typeName, name) { form = $(form); var inputs = form.getElementsByTagName('input'); if (!typeName && !name) return $A(inputs).map(Element.extend); for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { var input = inputs[i]; if ((typeName && input.type != typeName) || (name && input.name != name)) continue; matchingInputs.push(Element.extend(input)); } return matchingInputs; }, disable: function(form) { form = $(form); Form.getElements(form).invoke('disable'); return form; }, enable: function(form) { form = $(form); Form.getElements(form).invoke('enable'); return form; }, findFirstElement: function(form) { return $(form).getElements().find(function(element) { return element.type != 'hidden' && !element.disabled && ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); }); }, focusFirstElement: function(form) { form = $(form); form.findFirstElement().activate(); return form; }, request: function(form, options) { form = $(form), options = Object.clone(options || {}); var params = options.parameters; options.parameters = form.serialize(true); if (params) { if (typeof params == 'string') params = params.toQueryParams(); Object.extend(options.parameters, params); } if (form.hasAttribute('method') && !options.method) options.method = form.method; return new Ajax.Request(form.readAttribute('action'), options); } } /*--------------------------------------------------------------------------*/ Form.Element = { focus: function(element) { $(element).focus(); return element; }, select: function(element) { $(element).select(); return element; } } Form.Element.Methods = { serialize: function(element) { element = $(element); if (!element.disabled && element.name) { var value = element.getValue(); if (value != undefined) { var pair = {}; pair[element.name] = value; return Hash.toQueryString(pair); } } return ''; }, getValue: function(element) { element = $(element); var method = element.tagName.toLowerCase(); return Form.Element.Serializers[method](element); }, clear: function(element) { $(element).value = ''; return element; }, present: function(element) { return $(element).value != ''; }, activate: function(element) { element = $(element); try { element.focus(); if (element.select && (element.tagName.toLowerCase() != 'input' || !['button', 'reset', 'submit'].include(element.type))) element.select(); } catch (e) {} return element; }, disable: function(element) { element = $(element); element.blur(); element.disabled = true; return element; }, enable: function(element) { element = $(element); element.disabled = false; return element; } } /*--------------------------------------------------------------------------*/ var Field = Form.Element; var $F = Form.Element.Methods.getValue; /*--------------------------------------------------------------------------*/ Form.Element.Serializers = { input: function(element) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': return Form.Element.Serializers.inputSelector(element); default: return Form.Element.Serializers.textarea(element); } }, inputSelector: function(element) { return element.checked ? element.value : null; }, textarea: function(element) { return element.value; }, select: function(element) { return this[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element); }, selectOne: function(element) { var index = element.selectedIndex; return index >= 0 ? this.optionValue(element.options[index]) : null; }, selectMany: function(element) { var values, length = element.length; if (!length) return null; for (var i = 0, values = []; i < length; i++) { var opt = element.options[i]; if (opt.selected) values.push(this.optionValue(opt)); } return values; }, optionValue: function(opt) { // extend element because hasAttribute may not be native return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; } } /*--------------------------------------------------------------------------*/ Abstract.TimedObserver = function() {} Abstract.TimedObserver.prototype = { initialize: function(element, frequency, callback) { this.frequency = frequency; this.element = $(element); this.callback = callback; this.lastValue = this.getValue(); this.registerCallback(); }, registerCallback: function() { setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, onTimerEvent: function() { var value = this.getValue(); var changed = ('string' == typeof this.lastValue && 'string' == typeof value ? this.lastValue != value : String(this.lastValue) != String(value)); if (changed) { this.callback(this.element, value); this.lastValue = value; } } } Form.Element.Observer = Class.create(); Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { getValue: function() { return Form.Element.getValue(this.element); } }); Form.Observer = Class.create(); Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { getValue: function() { return Form.serialize(this.element); } }); /*--------------------------------------------------------------------------*/ Abstract.EventObserver = function() {} Abstract.EventObserver.prototype = { initialize: function(element, callback) { this.element = $(element); this.callback = callback; this.lastValue = this.getValue(); if (this.element.tagName.toLowerCase() == 'form') this.registerFormCallbacks(); else this.registerCallback(this.element); }, onElementEvent: function() { var value = this.getValue(); if (this.lastValue != value) { this.callback(this.element, value); this.lastValue = value; } }, registerFormCallbacks: function() { Form.getElements(this.element).each(this.registerCallback.bind(this)); }, registerCallback: function(element) { if (element.type) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': Event.observe(element, 'click', this.onElementEvent.bind(this)); break; default: Event.observe(element, 'change', this.onElementEvent.bind(this)); break; } } } } Form.Element.EventObserver = Class.create(); Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { getValue: function() { return Form.Element.getValue(this.element); } }); Form.EventObserver = Class.create(); Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { getValue: function() { return Form.serialize(this.element); } }); if (!window.Event) { var Event = new Object(); } Object.extend(Event, { KEY_BACKSPACE: 8, KEY_TAB: 9, KEY_RETURN: 13, KEY_ESC: 27, KEY_LEFT: 37, KEY_UP: 38, KEY_RIGHT: 39, KEY_DOWN: 40, KEY_DELETE: 46, KEY_HOME: 36, KEY_END: 35, KEY_PAGEUP: 33, KEY_PAGEDOWN: 34, element: function(event) { return $(event.target || event.srcElement); }, isLeftClick: function(event) { return (((event.which) && (event.which == 1)) || ((event.button) && (event.button == 1))); }, pointerX: function(event) { return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)); }, pointerY: function(event) { return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop)); }, stop: function(event) { if (event.preventDefault) { event.preventDefault(); event.stopPropagation(); } else { event.returnValue = false; event.cancelBubble = true; } }, // find the first node with the given tagName, starting from the // node the event was triggered on; traverses the DOM upwards findElement: function(event, tagName) { var element = Event.element(event); while (element.parentNode && (!element.tagName || (element.tagName.toUpperCase() != tagName.toUpperCase()))) element = element.parentNode; return element; }, observers: false, _observeAndCache: function(element, name, observer, useCapture) { if (!this.observers) this.observers = []; if (element.addEventListener) { this.observers.push([element, name, observer, useCapture]); element.addEventListener(name, observer, useCapture); } else if (element.attachEvent) { this.observers.push([element, name, observer, useCapture]); element.attachEvent('on' + name, observer); } }, unloadCache: function() { if (!Event.observers) return; for (var i = 0, length = Event.observers.length; i < length; i++) { Event.stopObserving.apply(this, Event.observers[i]); Event.observers[i][0] = null; } Event.observers = false; }, observe: function(element, name, observer, useCapture) { element = $(element); useCapture = useCapture || false; if (name == 'keypress' && (Prototype.Browser.WebKit || element.attachEvent)) name = 'keydown'; Event._observeAndCache(element, name, observer, useCapture); }, stopObserving: function(element, name, observer, useCapture) { element = $(element); useCapture = useCapture || false; if (name == 'keypress' && (Prototype.Browser.WebKit || element.attachEvent)) name = 'keydown'; if (element.removeEventListener) { element.removeEventListener(name, observer, useCapture); } else if (element.detachEvent) { try { element.detachEvent('on' + name, observer); } catch (e) {} } } }); /* prevent memory leaks in IE */ if (Prototype.Browser.IE) Event.observe(window, 'unload', Event.unloadCache, false); var Position = { // set to true if needed, warning: firefox performance problems // NOT neeeded for page scrolling, only if draggable contained in // scrollable elements includeScrollOffsets: false, // must be called before calling withinIncludingScrolloffset, every time the // page is scrolled prepare: function() { this.deltaX = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0; this.deltaY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; }, realOffset: function(element) { var valueT = 0, valueL = 0; do { valueT += element.scrollTop || 0; valueL += element.scrollLeft || 0; element = element.parentNode; } while (element); return [valueL, valueT]; }, cumulativeOffset: function(element) { var valueT = 0, valueL = 0; do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; element = element.offsetParent; } while (element); return [valueL, valueT]; }, positionedOffset: function(element) { var valueT = 0, valueL = 0; do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; element = element.offsetParent; if (element) { if(element.tagName=='BODY') break; var p = Element.getStyle(element, 'position'); if (p == 'relative' || p == 'absolute') break; } } while (element); return [valueL, valueT]; }, offsetParent: function(element) { if (element.offsetParent) return element.offsetParent; if (element == document.body) return element; while ((element = element.parentNode) && element != document.body) if (Element.getStyle(element, 'position') != 'static') return element; return document.body; }, // caches x/y coordinate pair to use with overlap within: function(element, x, y) { if (this.includeScrollOffsets) return this.withinIncludingScrolloffsets(element, x, y); this.xcomp = x; this.ycomp = y; this.offset = this.cumulativeOffset(element); return (y >= this.offset[1] && y < this.offset[1] + element.offsetHeight && x >= this.offset[0] && x < this.offset[0] + element.offsetWidth); }, withinIncludingScrolloffsets: function(element, x, y) { var offsetcache = this.realOffset(element); this.xcomp = x + offsetcache[0] - this.deltaX; this.ycomp = y + offsetcache[1] - this.deltaY; this.offset = this.cumulativeOffset(element); return (this.ycomp >= this.offset[1] && this.ycomp < this.offset[1] + element.offsetHeight && this.xcomp >= this.offset[0] && this.xcomp < this.offset[0] + element.offsetWidth); }, // within must be called directly before overlap: function(mode, element) { if (!mode) return 0; if (mode == 'vertical') return ((this.offset[1] + element.offsetHeight) - this.ycomp) / element.offsetHeight; if (mode == 'horizontal') return ((this.offset[0] + element.offsetWidth) - this.xcomp) / element.offsetWidth; }, page: function(forElement) { var valueT = 0, valueL = 0; var element = forElement; do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; // Safari fix if (element.offsetParent == document.body) if (Element.getStyle(element,'position')=='absolute') break; } while (element = element.offsetParent); element = forElement; do { if (!window.opera || element.tagName=='BODY') { valueT -= element.scrollTop || 0; valueL -= element.scrollLeft || 0; } } while (element = element.parentNode); return [valueL, valueT]; }, clone: function(source, target) { var options = Object.extend({ setLeft: true, setTop: true, setWidth: true, setHeight: true, offsetTop: 0, offsetLeft: 0 }, arguments[2] || {}) // find page position of source source = $(source); var p = Position.page(source); // find coordinate system to use target = $(target); var delta = [0, 0]; var parent = null; // delta [0,0] will do fine with position: fixed elements, // position:absolute needs offsetParent deltas if (Element.getStyle(target,'position') == 'absolute') { parent = Position.offsetParent(target); delta = Position.page(parent); } // correct by body offsets (fixes Safari) if (parent == document.body) { delta[0] -= document.body.offsetLeft; delta[1] -= document.body.offsetTop; } // set position if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; if(options.setWidth) target.style.width = source.offsetWidth + 'px'; if(options.setHeight) target.style.height = source.offsetHeight + 'px'; }, absolutize: function(element) { element = $(element); if (element.style.position == 'absolute') return; Position.prepare(); var offsets = Position.positionedOffset(element); var top = offsets[1]; var left = offsets[0]; var width = element.clientWidth; var height = element.clientHeight; element._originalLeft = left - parseFloat(element.style.left || 0); element._originalTop = top - parseFloat(element.style.top || 0); element._originalWidth = element.style.width; element._originalHeight = element.style.height; element.style.position = 'absolute'; element.style.top = top + 'px'; element.style.left = left + 'px'; element.style.width = width + 'px'; element.style.height = height + 'px'; }, relativize: function(element) { element = $(element); if (element.style.position == 'relative') return; Position.prepare(); element.style.position = 'relative'; var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); element.style.top = top + 'px'; element.style.left = left + 'px'; element.style.height = element._originalHeight; element.style.width = element._originalWidth; } } // Safari returns margins on body which is incorrect if the child is absolutely // positioned. For performance reasons, redefine Position.cumulativeOffset for // KHTML/WebKit only. if (Prototype.Browser.WebKit) { Position.cumulativeOffset = function(element) { var valueT = 0, valueL = 0; do { valueT += element.offsetTop || 0; valueL += element.offsetLeft || 0; if (element.offsetParent == document.body) if (Element.getStyle(element, 'position') == 'absolute') break; element = element.offsetParent; } while (element); return [valueL, valueT]; } } Element.addMethods();post &XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate [mE &9yx7ntry(Hahttp://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/gifhntt"7f0209-1d3b-dc615180"hvrsdataGIF87aU\kuz2k)dѶ 񄦧bJ|#` ՅKKeeeq:::CwAA;qƉUѾց]KKK@t߀SSZZZzzzPX܄ԉ**lll::zkkQQf(28n⩊  ~11!****BBBttt)ՇPkKzt1[[ [")bbbSSS[#0<111;J$: [Ѵe*6C/h$0'! 1 !Aᢇ!,7+:JA7[7LbC`}33AUh5H[1|1BTJ^r:k݆R--g4SRr|--z;QgX Gto%%RB[s&&b~R )[s11)Ii*a)Bdֶ'1;!}tJk~(43,13P6& 4>x\Jo3@k?tQ,qddQ9'R $<ِrFi#2%6Jݮ@h g1UB# T qCAӮP(n `$DGAx4 Al" +ؠ"?@\*7!,)#l<ÍKľ*4Ρ!>aP: B\@D@;p#$:i d | MR $ffq]BX$:l( vry(CɔvɨC+*2@?d>D\n^4Ő*AJKgYPjU`l%9 2F M?n 1 "RP (QG4T8<$0?14!"# A%s Ѵt 6ž H%rѥ5pZK!΀&YRn0G*A"U_), 0d/A p[* QXa e`HFx2ɭLJmR&#H»g_uB^(r҅ $Mr:tKZ.s a әKWjQHĬ  h08n 9Ş@tlS w=yH)` ^mzA&7 @J`aźpA׼omNh5B$ ň _0a(J`' oל'#{fl0!0`5`h'`Ml45ЬFb>񋑢 x",59p> :m uH4D:AGd) Cgߘ J!hMp͕g%S&kZ'2#}8iC;Ripd 8yjS 4=gC HeYEQZ@aY cx h [x] Cޯab<A]x 7[ssLwpX#4J|DͧrlD$ @`\40Q yr$) 8@LSˬA0dpi pCD>Bwǯ~T0AѭE! [7J!4 P{"dM"8HC!H@1Pl7 3X@Öq3$ѧ,DCFA BP hk`%y7ZqE&AP!\M }0$8ǣg&lPN Bxq :@TWq  j|-My"@`349U R 0 S30"9u fRLfxA1%4C Ca5$9&Y?U(~O*yHsɃ' P #0(P.K#`"<@'5wi))x,- ,u 2 ` ̌ !S{{(?%{r   Q z[`P14x]RKpMi0 P@ zu)Wv)8)sP* 1**H!RT!)prWk%0(;⯝B/U A\`9zh02S2lrVTiV{@ZY|%Z^V@Y@_Vg")PVN/n93x43(3z^_0;; q!U( 1` R1{@a V9 ! R/n1 ݘ1iVPb@ 0c<9`/uIQ[ԯ q/97L#GQ.VC]ͼύӘ]2^5^Y8Vf Pb Q_9!`aC+B&qw*99p^3'`D`!z=$jaa!%0Q6`Pb3zU6+vAp3@P$pO& jD90fd\*%f0`$f7ĢB7:6J0g 9mC*N?@*`fp7 7j9U_CAc@_fp<s:CP7-Aa#3dMjua*S@9AcQ@0scϓ>'JPpI`BF&:8%@@Ke݆{#AjAd9)PzA-P$ 8&AUA-4@BIMظ P$dܗEaMX 6D!'I Q(29(DC g$R {V p  jD ".xT42 !$AE G' ! `jL;j7D54.0E l0 #QTC0tH`Y AaJE0hq4;@E%tJbxqQIST0NM`%㽮P 0"`u`ҏ  vv`)0 0 mŅC>ı ~p~q8!5) aL@ v}nb1ea`kH$@pu8@ A 1pHZpf[qDG r#~01)2:D [eL91?{ qufҬ/ ڐiy HT Hp0 e<`vdle=G^`` w@DgwrMQ q%A S {r4G[дkMZud4+Pm q !w}lG.~mGxQ $  D&P 0KhMOu;`LCesSkQtDMcaqI1 ڡGҥ u q l/IsdiN pMH`Q 63k%J{\'<x'P`hM @X@iS"yaݟ{apn| m x$Y|ݧ %lTr} a7 nQyH=3rc(Q bh>k*l U K{ݧC\0N-yľ(kg|IHI P0Q 8(P}Ry,y ¾ʮ!}$w5 [AHpM!Fq N\m`kޏV qTMCb v $9@HQ;O$2KhZB;&FBM0z!k F$^}l%lalver&. Dtq DuK @;hyM1y 5(U3-E2(uYE&^9M&$d^ܑ1^@ bǷjr#O: !TW~ ÿ4M>9H *+R"5R* #][n$* ta?TRoHSn$pX#yΊ8R.}aU+UG@9s^X4#)3 a I* e+*,R-R!RR3!95S֐ j!u DQ \3 V7}UB.@} 1 e Ha AB+K+^CVP, RRۏ +- 1h(ՂvIA3ZY VAXGP(( 9 q?~/Y 4?* QEJ(bUq̉\OZagQjUYVZ o) e`XW) l)G %K A nA`X(You³\2#W#?8¶G`A@@'L`@=<Qb# C=t14n<"R9 Y P%N(U.J&,TEA='=z!E b%LEYiS; JQSy:DY - 7iMGKT.S-~.ҩmߟ+$yĮV$p W\li;3!_x `33 ]̳V/mm+@Km?k E4StK]vuWnչV9VZ@k^J4,[#N1b{&GIҤO=IC'4NPB:Ic70D@c31"E_1Fg]hJlG2O#6!D2I%H`2J)ߧ2+`B`/3L1$L3D3M5dM7Srԩ1:AM(O?y.RPCE4QEeQG20@%0 R&%AD (J5զ 2ǒ HUBL!x qU-JP\>0`[e] " "RP$!k0a R^ h&RgHT 0շ$ʌRT! j \K!do\*^URL!shtU(meTDv1PV (X3$ģr0'e"VNwN yBWjH{mkeHV!ksV$U(nU]xg˖/Sxn-hha[&jB$u[X"L6OhXXk6$" " %Kcաl[O^U*t[FV)UrN0nqt'P[!&%bn޶? 3ZP{P, T qMtU@] F]bCP*jTp5p`(0oF;A7(XU2 Ƶ0n  A 2/*D)0RP(r.YU4`UA 0Ar w44R6ĈLHh|4W+ . 5*%J2I.)2-ĈW vT 핊m-x:j/T0ehttp://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/pnghntt"7f0220-2f1-59a81bc0"hvrsdataPNG  IHDR۝agAMAػ7tEXtSoftwareAdobe ImageReadyqe<IDAT8MLqpέ:ud9X@ܮBL"dǀ[䜡?Z)R ΢m{XkC 9k2<<={~Qv{X-8&P{꾒ՒK+D d{0IT~ |#-7p:3I bg7SB U:w(j$hOZ(NDoWWu .5:<9l2y R %b&OԘ8Dmd0u un%t%=Q"k{ {u3pԼv J䫓4-aJ5܍ȴhO>6@ bjhttp://www.sciencedaily.com/releases/2005/10/051007090048.htmmime text/urlhvrsdata[InternetShortcut] URL=http://m1.2mdn.net/viewad/817-grey.gif posthttp://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/pnghntt"7f01f2-26a-590f8540"hvrsdataPNG  IHDR۝agAMAػ7tEXtSoftwareAdobe ImageReadyqe<IDAT8KSaWEDB֭}a? P3B Ӿ]t +$aA I箉X^ns\[sKp;;gϲps6qt w`ÌU]|^)JrL+:Nsb&\.u,Ld2iIYB)v>)iR(D4E!JEYyZà,M!a݁*?fH>݃>G9Q7&hބ|}+ n $jԦcM̮}wٵ+U;}92XՏ$jxw?Y=g~Z\-32L>vEd̍i/ e{;^D tT]v5Jh.Az{Ѩhttp://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/pnghntt"7f1816-33e-fcf1a8c0"hvrsdataPNG  IHDR agAMAػ7iCCPICC ProfilexMKQ;RIqE(U"JP -A0n23&qrs .JqUNR( B7Em p9/8#_5lwfj^d\".|uw*6pĤpe@7˘!(w-@ CћoFiN0ųRv4/hϵS cدϿw(]]@jg]`-d,S?`]S֚r̜ÿ1_`+vr?ςXBXIot z 7PGTIoߖMKu,Jɒqi WIDAT(uM(Dq^HC %dAXbJgkii5z6ef#e1 IE7 34s(` rżDÖz[N,Hf.Y9^ Lvh @!"Cueop4"!h)iZ(˒Pm@mK~W52dA$7|u t7U+CdG8R%/Lҡ6fslgI^DÖp\}x5T{s\/^+);rf14:{| 1{ofeT ,$bj?\~-mIENDB`postmXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate Tmm:6t>ntry(Z{l"%`UCT\LFduLRurl -http://www.sciencedaily.com/images/print.pngbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/pnghntt"7f0218-2db-5998d980"hvrsdataPNG  IHDR۝agAMAػ7tEXtSoftwareAdobe ImageReadyqe<mIDAT8KSa]w8o H* ax*AKA@ܨЍu"XK9y^8ƑU;O;QݵGJȹR-X|OpixH(%,Hs$JHE_̈xxK zm)RA3RFZ7PO/B%EI_e!|$HLvx|nJ`rr$A~-vP3Eߕۻ^ J^ qP{*^ւS2[ ʚ L@gggFq{*,$35$(oUlUt]%K70>>FL&_(YA000,PX__($ q"R5Cզyg2H$nd~)Jp;;;MLL1v;8`Zz z' Q6f__VY=nddxų%l:::Xvnn íN X"8:!A9IHgK^T CR)[S"'kvcﰌxgz[IENDB`postTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate ZT?x6ntry(t%_w%k\",- +c/url -http://www.sciencedaily.com/images/email.pngbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/pnghntt"7f01fd-281-592e09c0"hvrsdataPNG  IHDR۝agAMAػ7tEXtSoftwareAdobe ImageReadyqe<IDATNaķ@9T)Xk\{n3q!;M.0lRJ;bӚ<È0'\! 8:큒:%uJTt:<Եrx`MUrY WG7鳹Of8yEa8g鑼*2My(2rEd3ܙu9R+ |O[֜0fk,W\Nf7㨹JlrNY*| 0cv,-hr&)3jjWZ rNrB?yE\ݼZ$o 3"Lr^ؕKvoB7.zֿO1[Qqp<i|?Cgꓓl6&1^R5@P^FNi,sPR`}Pl WNh ky)I13W+j~ҕ}d숚腴`af=xgX@k&q<>?|oUe9I{[IENDB`post\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate t\"Dx/ntry([ k1d]N) +url 0http://www.sciencedaily.com/images/bookmark.pngbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/pnghntt"7f01f4-26e-590f8540"hvrsdataPNG  IHDR۝agAMAػ7tEXtSoftwareAdobe ImageReadyqe<IDAT8SkQM\h~(ZMS=DoR A*=yȩOfCARzRK*ٳ1Bפ7$OxfvV .b?/K!}ۄr?<%C=];V}z΁AR(9~q:{>yGy%"~Kt.%-ٔٳ*zQai~\7''S43Z~Or[f4MWjX,m1mra5 `:fU 0L=&(*אӘC=^^Db0PodS׼Reo؋\>=?3ʚWpE?3F0`IENDB`post k1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate [ k1HAx-nntry(Hm7{keᰴ9u^ߗw?url http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/jpeghntt"800b30-3e6a-1db66440"hvrsdataJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222F," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ w!1AQaq"2B백 #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ ?Ћ)ßPI'#%M8YZeI@xUm_Y'lc볾?eI@+ɢ;YR9',?ڽJ>>Ŏ *O/T_^}뼗#8'ـr$C'T?Z(]jfN ¦c'&ƠT.,A-J%rfuF,:w;5mY4|~@nF?JBs5RMlX$r_Y29yu'AƚnG)'O@?΀yR.)YPr(w=|Kvi~R9y'w{Sm_A8ΰ('Wuo>R<ر).E9qB(>ۜL_K *O/8I*}$"`2@fwqJD퐡e#5xrusFh4f((P1h`QE6jbmn88<]\,Q$WxTm_XlcE 3(`%B(x_%R(C׭wrbi\1Ԍkqgc+Ɍ V۽BD^HGXuXS'R$rknͫ)yV ʾ[Oοx]v$g5,v$_Rm#*}>S7%D wI*ɭٸMm+nbM68s7*Ʌsȳ'ߔ0PI{%9VSA(tnT j8f1\0;:**2Mj/uhz'U̦I=qX)##މ-sY ]Ez5PS%)( ((( (()7%F}{ML>=?~ ?R^DAuQqEJM#&B>hUaTMф&@FFCJ|Iyv:y#ݓj-%W: #~b>_Ҏĭ@u{mt"?dU$3mL:lU*r (hR"QN.PVNR1c=SE p(Ey6,|f?ZJ.den<08j'k,GrPصZETPŭuO2 QTgQEQ=iR_e&ȸ<Λ(>?",hm,A%ul@wgme?S\кVڻ`{[}ѱp0=7ȩZKf'$kg<*)uZ.5MVl#@쫅CZzxr%y-h CsG ZƠß$=跛(Y \Ԥt_M)"[XfŤQ5LftOM(7 T; )y'f4Ss̆!Ty V4qkZlm ;}hCQit_{M@,- }9?N+q5iM?whEm+X>*Qo*KDedVa߯@ Ë 9Cjf{;}amia2JT ^KF6q\jq"Yr`'J.NωP]}G4nOMA?X"SSѕ]ig@/4\s)uݓ-H}Ýj7.}Agf#߼Ƅxx0e?L5>[IgsɫY4Hѻ@_~َK-u6E7n@ `Z'h=qߒ"K{W?3*447ȧ\ zG٨Aف5klkET'ɜOQ)j EM#$a98GmxTYYVk+'8UOCc=y՝ hۑok4?xDV 0 !dh#PBeI%(bE(er~:>H\pq/zͧu6v *k}=*\#WO_r{<rB#8avs)o~;}Md q? v/r{)N(X8fAV$ړqw; SECxDHc=VQDɔUׂ$P2J岔2k8@*,lpn;Kl#R2 ]>Wkm~GJas۵yFQTz2>1PڨQѠqRW-eCNY=JmO:OSIaP!j&>*x.Pt EZ{N;,by=R`*8Mu3$;=k>L0W ;q-('$  Ǒz*Ic*+}\eSrmΝ|ٌ٩B`>b WT&*w)උT#5:|حkބOVh,SV蘯VV2< ~sT`|ߗaɮF2+w:Cx\\;:OV0#7jx}1[a*ro"sOz\p?XaуVપ2%nnBewyV2в+4]-M}ߝNV֝@ V1@$s84:=^hJ?t~jOheu=?J })+O.K?js?j_h bؗOn? }$7ydQ..3zƎ?PDEy}wW*˜XhvP)ivWZ*0eŻ"^QLF\j19&J)QE0 (\ui_d5q/z^ETdWVmcW'lCG^7pNEFoRG;RR}Ҷܢʃ$(F\}=MK)e֠}\U`My_y7SгlDufogKz'sz;:tJGO^pIک-ϋKp̜5oc-YDɩiwa,E1;9mFB βK["um*os'`O{}+nYdQQS]#HqF4M7ݓREb(ޒ"6U-#dVR jKv2H0qQDn}*쿜L?%(>xX.2$Q@đ͇e<V8@Q,3*rk[!Y1G}gҝ~ۅv:>e?̸I#=r(Cm2PF;b%"1GMzqH珜X*6KULd1ț#*AǒHvJ,-QO [V(sSU{x1gWjLef\#mU Bs'S߳hkAٯd&+"2Ocޅ:ذkjc&L-ڻ洝b;Rh2:R;CZ(RR ESQExY8e^\ Zz&Mt&qQk0rq賢qd)*(UҦ۩J⫑8(\˖mC1x~TrE10,th١zT.W<PѥUdCF@?UGT=? M1ڑRwmvW(?fST94d]3P4lRlQBI"c|DOƱ`М4dV$!?/VV0)^:8Б~ BQ'Ñ;*eEj@SUQnPEdQ\lVb\t?, :[{TĤwbGM IQS~cW*n~b{RiWK;}Md2@߭OȽ`IPqOZK!G1m8ee8l;I8ndOc\-:9)Db w*M)kZb.c[" QIJ(QE1Q@@$t$QET~Ri|`g>~VRz*zڃ =Nr)"+)ņwU`)$;ӟ12teqvl{r)`I $rԌnI;~E_nɜfך5jE&9VOE}e/Y^o" ݩ'SR!2''Zn I+7UǺ`=i@,ld͹VDr%H"ekHw]!6Њu*e =Wz.!HioVȯ0U@JuXՊ3 mQRy ͝h ~i9(drqIIŠMdU 0cyetN8Ȳ4MXz=y)(/;EFdQEP- WEL^ku¨wh]ExMvüoHs'Ӆߓ@_-Zg7O8Kk8>ܼ]C/[IL,\3uv;UEs͆h& -,JӔ  {bz*am;}*#mi6jS [>zj7ztڔV o 7N{tORk ]5j <c7+~yLVY#d X) UolbA+z9/W'<إO[Ϯ@P2I)^!?ExfC qγsݝ6۝GQMX͙ò|;#Z$jkM6 H?  A?M2ԝVPj4cf*9nFL!MBAm蕀Nɝ@ \祈?*  d7إ }Am蕨Gůw}uBFnG\}+7Fw햳g]tsU YLF>C9+;JWJ!rs>ZS;)O9[TЪh"Oes#jG#=1HPo:q?K gϋt{0>P>EaɮF2hT±o?$6)49a,?ݝ6۝GVM%5~Ny첛$cR`6GVWlb #ے?i?y#(Nŝ@ Xxz}$mC?dK +OS\?2/QWݯ;iW-/0{vKs?#P#\D?JͮdqF2O߮-(F-c-Pkґؖ +ϱ&xχήwX $kZj>RE4=O'28;1rK~@$P!C!ˣ{ EVuA Ri XB/,]Ŧyf2b::I ,pոnŞ5%2|xSI$e(Aߓ u))a{Y7wcw!w <OJ|1̌ErO9?*TU sn:tjKkj[at &Q)kkn ,뛲Wq{Kp:4"պ3XG7H z7#HSQڮv +*n#:r~."hNO0).AXu(ދȞe_o*{SFVQI@JZl,{Nω! wuU]5r$vAIE-ܸ{SP*{tTϟ> [DdCXv5-Peʅ2أz lWwZ}SI0?*zױC4w0du wIEPS%(QE1Q@u_d;/zyZZwEЛ*g|vzug,æȪ? i})N'[OJKv&J`Wc,H8qKXߔ?w o\SLd{?mF͢A#!Z^ZPZVQOߘRa}Nv⌙18>찆FPu 1`S'H_!?<9@,@tbht 1gU6Ԙ8]&* u9ɛ(Z+) yOj^e"#Fl"'z݅jI$-`9ZI|>tob?W g>iXS,y8j^cZ#.? #(vAS,.LQ #'=_O"IIU`)HUۈ18*|/9L&AojD~XrOX=:ljU89Ӗ5kHpJ}F̗?}N Мt]a:*Jd#BQfnGs ,π`vܗSR*PGJ!JJVzs]Q¾[hEweedp8?I Xc21LXP !8H؄U7vgZ1*ش/^6r%p}Hl~+Ņ2K4yYIVϔ8UڡOqW1q1~FHL=Bsce9]s;G83djI/Ov؞4vo9wϑsONO4bD RE3&)hzal؂P W'94OF9JIZc }=)dt>WQPw((h\.Lgk-#xX4r.""_xϳeO>ˤvP)pq ӡ./nd%@Wy}=GylΩvӷ~Q=Ÿz6xQ-Ag?Zx CG-~I9,|WxgBϟڄx`yf=@$Rp:OsMiupxRwtT拝q}}zWYHN; 9$[^CE\4ޝ@ usR`qaҨBz-q7cc i?V8`O|~Ygw}Gnn}@}Ԝ b2BzG )󱵖>R{+$ni"-Q݌_cF͚CizP?hgJճ56m }g3tsb^H=ߛYF-ʅ0URwl–|g@h~`qޕ: ԥy{bssTTr8lk2%{h;^!^@ 0#,:M_RRWG}) >??: QGTq|u? c2+rzɋ{^z,gN9N_}V?1…HМOEŗ?hŜsdw#KIoezN yvqD9ca'QWʪxɜa7/X*,+ZW??Zih{zR4p!Ż"NutP"8躠w}i[E.铰E1F 7}ZO&/,G¶v~U%(ïXË|Ɍ/s]#0U$ZXNa;4P3g*VRz9_zn%O)4*+?ZBd1Èqj)ܤ*ji}%=z ?jx§H ފTx+9MFaiԺO[ 9,G䲠 %B{|dϬdJa]i,3, $sο>#Cr͂7/H IqG9K4x춗ej!wpɜˁyPf@H AUEK|C1`Х &m-Mly2aw$|LɁů4kO*3I޵;y5dF$B3ru #b "%L`zMKVS5&>YWkn_&*钇ޒ;htnqHDQE))E֢)(fbjA,wHB)xP;gɳ(Wo4W$v q)7 _R{H$hpِkdžZ[v oV9vS@{礞:gEHp$J}rL ֜u6ODZʍ쪧j$sH$*@7YQxTc_*C9 %G牾sj| !p#>S7WBUnwsމ-`x[^]kL] ܍Wޅ-((0(PH :Q1@1F(scA[C76kh-,IdOBR>oZ#)ZʥdVnCMd(Ǜ=LzLdTQ^>Yuoj-sq;]֐>.n-Dې7U&hH[3LGxwƞrO\^lpW dS7O#o S g)Ac N>VC.mRik[nZЊ$=Br{mc}Eø`uʍv:b} zۤ8]aC$}\OmGe*C´T`g7*E[{^rhFrIzue2h6xȯdF}.<4I*{4(JcNPA Qq4Mc®W*HRv+1;E647;Xcp :r"A%QTKjqжJg/e;X4r(e5zV?\B)µ)8֓@aQMTu" L6gX7Q(4H~iX#";8")%/MH¯i}=5~QwљQT5U%HȉXp*?܎4_q;?R'OKI'1 \Щ=TQ|2I;1ÿ쯋EBihL~iC[\~b~hrd>QEs1Wk{zQ?԰Evؘq} ?]_ێQ@wmq} iur(ؘq} ?]_ێQMؘq} -X2rQEu1C¬g*1(Q@)h (?posteᰴXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate HeᰴLU?>jntry(peGTN7^YnF">悻http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/jpeghntt"8f0b3a-7fd-9a9140"hvrsdataJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality C    $.' ",#(7),01444'9=82<.342C  2!!222222222222222222222222222222222222222222222222222O" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ w!1AQaq"2B백 #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ ?w->G Nwcɝs[p#/VhѱfNr;*n' S&]9,n6O*Xx<ޞ#ȭjt@r1ٜU{q,,J$Y~?m k+%+d^QN=r2I{:I W ^B;wlŊ@|3m`ȳ:\TwPcla ':{Mo^N?nY$>XϨsJ)IŢd<[PߠDO$_??xHT.HۨŌCpүQc(J! $(8?ҡ5U\>e.Oulh_&>dyP]$#t~ޝ߭W(OAlVK0xw+@?Ot C(==ې:tF-/cuԜA{>ơXH6BN?*w#$g'9ŘhS$z$`;FG 䞕!e.RsOLʮCnn|EpPuNY{{YyR'Pjq~flպ&ҫƆhhL0qla3Ӭ:Y>ɸȗ:̿|y M`L>ymoO=fZtlA#YE 1=dxsie4 aI2:qR`Br0=qs^N&Ɵ8y@@p:ޘK;|rF׷yץot٪%&E_*'1%N1^ ;nu&Y)Yj woPhp I¿f]Cj$ʐ5ٓQN,Q|/*gQGQ9iu6/]RM.Sڨ{粴)";#Iuq@x=?M%vֽH ou71ײ+4eS!S*;MB%I7(:۶\'.%[vv?w8λ49EIk}s;4i `LEÛ:QEV/LELj(ʼˊOz(ˑ kJAEeꓼVEi\,I,QOSqE·ME xBG5/X~+谝post"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate peG"s=~ Hntry(cWAl@LьM館"'Zurl Bhttp://www.sciencedaily.com/images/2005/07/050711014454-thumb.jpgbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/jpeghntt"80063c-7aa-1d795b40"hvrsdataJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality C    $.' ",#(7),01444'9=82<.342C  2!!222222222222222222222222222222222222222222222222222D" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ w!1AQaq"2B백 #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ ?+?qt.`]H#0\q雊fd<9Es䢗Gn`#A56t@2g=1vx3HU"?2Psq]JJ_3kvܝ֪cEUuYTuG[xho i2 _s*z=uy,v#E37v7t^\BIOdE' '^UetuoTFp2[`c!I]:QIe:mx^W,YU3s]ᐰ{=18~sUU!;Icڸ"ɲpc˨gqZph?q[u~#ib6w@l5Zhqa1<1!3gDgrk\ I?Z;v-ݪ4Eyd#LJi~ #&c7ی[z_ h#Iݓv7gKo-b8G9 s%GZwEϸYZidV1`tqBgHȷ-9υ9*9e[g~ü{|ҢkFHtªfd0qRRVv&kTk)GΛ+>֌Xmq OD1 q-5! kГ'{5fq1xޤm]| ^>ߙƵ>rR鑒ieG8&&] A EJf&wr[Tn=I6a|{߱r+Knfj5c<E,ßI+lpostьXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate cWь'ntry(mJ pM.Z/P||̬@7url Bhttp://www.sciencedaily.com/images/2007/05/070517120157-thumb.jpgbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/jpeghntt"8f4506-5eb-151ac40"hvrsdataJFIF>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality C    $.' ",#(7),01444'9=82<.342C  2!!2222222222222222222222222222222222222222222222222229" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ w!1AQaq"2B백 #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz߮ٞ ?!G狣^"U|T}̆%m؂Aps4tvZZl޿nz6ؽՈ&8HҗOzqv@e6ʿ5)Zn}{Vd}kco1|Yn 98lU}?ybK%2>DY8je%sesoNft C„̐y3]yO+;:P{56"#$:~BZ'iu^}NBTv5n ۩-\NߒmF$?lD(ߧ\Q;1$zK|YzƞꃐڝPjˡ!c%\hTz0=LOchgeݲٴ;5 # M<7eI:?lN!޷J)`w)N™2Ax"+C8#7 QM6YfWpI^ȘzW⬠rʘV,QŠ$vz>;^T2P_FsWܨD6gQ'/!|ٙ+N-> ܽܳ"F7Mm65 xOwƣWd*3{{m>X`#&e;}+% !|u*qx聯oUkb龤~STSHSPzIKI[EPEPRU,U@,rQHIE?postZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate Z=~Ȉ7ntry(http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime text/urlhvrsdata[InternetShortcut] URL=http://m1.2mdn.net/viewad/817-grey.gif postAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate http://www.sciencedaily.com/videos/images/2007/2007-09-01.jpgbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/jpeghntt"29c059-859f-c5683940"hvrsdataJFIFHHzExifMM*bj(1r2i ' 'Adobe Photoshop CS2 Windows2007:08:31 13:45:02{&(.DHHJFIFHH Adobe_CMAdobed            {" ?   3!1AQa"q2백B#$Rb34rNjC%Scs5&DTdEt6UeڄшuF'֥ـžVfv񶏐ʖ7GWgw߅5!1AQaq"2B#R3$brCScs4%&5DTdEU6teڄшuF֥ـžVfv񶏐ʖ'7GWgw߅ ?-u_0 UE!!q Ɍjɼ-6م!cu0I(gܥ?q-k7ncP+z}u{#` !o‚,z)khԖ}6}$wRݖ=-ʽn#vcLܼs\tcgKKzfQe&{[Ѕӝ9pc,$0̤?oKzمjO-;Р؂Z8AgfIȗ8{|?q]ީuZ҇Ve{HP@#C_G٢Kߗ'=oU]K-Sާ# %WO6:ykOk2(kk)Sn؝U7Fpc&xe>&sv:O,TZԸ 8?ȄvpRp<|OH}UtdzX+*uqhQ=Ƥqr0i7icJ+swbYͦ oJ89<-kl#\}2~ ٲ} foC{c[[-_YКwʣYH5h eBnsʅC̨w۽հ ˀ}*nkcXGcpѽʁBk-^mT̪}?KFלr{,dYkY[*-ޓ{wc ʤ=/rl؜2js:f;0j_x7&ѷ*ӶXΎUuvPmp7!e[M_1nj;"m3K*GNk\+vXIZb"J7&ٚ7u`4x)5@Ӵ܈g藓}7}֋ޣa<~Lu,3~(Wuil(K4(ѺWCd.&" cn)6zcbGoUq˳P5J&`q\JR%ȝ5]~A/Ww_fCi~` LzhpG؏KcSr]k<3m=!׆.aj ԘXNmzߝ8z,E7A$ZqU*o"V9y"N}5l؝IoW[e,׿1d3 ݛ|ޝ}, }0oe9B"x˞;[3l8;*}&ّ[rj:l;KgטF,|Ta[f{3U$>4\ʚ?Y{^YKgВ5>gZߌz^V ֜>ld[gɖ\{ih{oD໠4d8N_mc2Y'/l"8߈ qLԮ j~u7Z ~YO^V|[㟥WH}L5eܱIZw虓(ԧ>l?!F^.G#˔~D-ʦbDg[Q'QG}p' rsH^K*l?[_n.?$x]+0%^,o! ̦Fvu@[G  N=KOt>£PV"tM̕Tw;k>#hZ'WP) 6z&Ol pK&D*I4Na'!GoX?ԑ@8Ct>-w+.%8vÚO^M3nL)fxiɜ^O4?J Q-ƅ?B*Kr w9>U( k#̱T$vb(;m m{_޹Ӫc̗[rwK\omG]X񓳦iqqIa?g/LDч1_Ӆg/ܙc#mUx筍لlUZ?!hυg1=C[ 4\GSnoLt̋!UMϨa^v@l" s֡C\ Vho d"7fijЪO]'kk K%?O$K3nc[uCy}ʌ|^? HnE?َkZzOcV_[X=mg(T3(jIn}wSe.gKNɅ"w;F)I mڋw1рEǤt/x B#l8Fˌzv;ZQ!,1_ ,#H[o.sKt'g]Eur_µjCŃϛ;z?Ҕd,??C sGQcCystGٙmvC,蕨N]e=7S5ߒ-*~Wcac`8Tn5ira{+ d"Ƚjip]Yuu^=J~ˁHᔾǓ @o93*R{Ϗ nVԙ3Nյ1炏E QʝQL8IlsimƶkK̛ow[/}Sv=Leq.Y˥puuiϱ àEBE`k^/cZS'[7V)N[Ubܳķho7nSEƺЎ5ʙxxTmn$slJa0 >'hZ+d|JYz_C{`>3_@;?ߨeܥ)Zn Q;.?$xhx=J6Yg\n<5{?vS {y8ڱ9~/?ct]lvh?Q?PG-nx>%YzU+`ruVYp8k[7' ~3YIA\Ze\KcjH>j ř$G4LF^' []吧ɴO55Eٓ]mf ?͜ڠnSt*OΛ@Y[^G Ѐ,`">g,"?̫kי) zU<)ϗamy h*$y?j?UI%6kgk4*$ߝ¿II$RI$I지$I%I$JRI$I$$I!I$I³I$V)$݀N*Y:d%I$ RI$I$$I)I$JRI$ Photoshop 3.08BIM%8BIMHH8BIM&?8BIM 8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM@@8BIM8BIM={325a{nullboundsObjcRct1Top longLeftlongBtomlong{RghtlongslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong{RghtlongurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM `{DJFIFHH Adobe_CMAdobed            {" ?   3!1AQa"q2백B#$Rb34rNjC%Scs5&DTdEt6UeڄшuF'֥ـžVfv񶏐ʖ7GWgw߅5!1AQaq"2B#R3$brCScs4%&5DTdEU6teڄшuF֥ـžVfv񶏐ʖ'7GWgw߅ ?-u_0 UE!!q Ɍjɼ-6م!cu0I(gܥ?q-k7ncP+z}u{#` !o‚,z)khԖ}6}$wRݖ=-ʽn#vcLܼs\tcgKKzfQe&{[Ѕӝ9pc,$0̤?oKzمjO-;Р؂Z8AgfIȗ8{|?q]ީuZ҇Ve{HP@#C_G٢Kߗ'=oU]K-Sާ# %WO6:ykOk2(kk)Sn؝U7Fpc&xe>&sv:O,TZԸ 8?ȄvpRp<|OH}UtdzX+*uqhQ=Ƥqr0i7icJ+swbYͦ oJ89<-kl#\}2~ ٲ} foC{c[[-_YКwʣYH5h eBnsʅC̨w۽հ ˀ}*nkcXGcpѽʁBk-^mT̪}?KFלr{,dYkY[*-ޓ{wc ʤ=/rl؜2js:f;0j_x7&ѷ*ӶXΎUuvPmp7!e[M_1nj;"m3K*GNk\+vXIZb"J7&ٚ7u`4x)5@Ӵ܈g藓}7}֋ޣa<~Lu,3~(Wuil(K4(ѺWCd.&" cn)6zcbGoUq˳P5J&`q\JR%ȝ5]~A/Ww_fCi~` LzhpG؏KcSr]k<3m=!׆.aj ԘXNmzߝ8z,E7A$ZqU*o"V9y"N}5l؝IoW[e,׿1d3 ݛ|ޝ}, }0oe9B"x˞;[3l8;*}&ّ[rj:l;KgטF,|Ta[f{3U$>4\ʚ?Y{^YKgВ5>gZߌz^V ֜>ld[gɖ\{ih{oD໠4d8N_mc2Y'/l"8߈ qLԮ j~u7Z ~YO^V|[㟥WH}L5eܱIZw虓(ԧ>l?!F^.G#˔~D-ʦbDg[Q'QG}p' rsH^K*l?[_n.?$x]+0%^,o! ̦Fvu@[G  N=KOt>£PV"tM̕Tw;k>#hZ'WP) 6z&Ol pK&D*I4Na'!GoX?ԑ@8Ct>-w+.%8vÚO^M3nL)fxiɜ^O4?J Q-ƅ?B*Kr w9>U( k#̱T$vb(;m m{_޹Ӫc̗[rwK\omG]X񓳦iqqIa?g/LDч1_Ӆg/ܙc#mUx筍لlUZ?!hυg1=C[ 4\GSnoLt̋!UMϨa^v@l" s֡C\ Vho d"7fijЪO]'kk K%?O$K3nc[uCy}ʌ|^? HnE?َkZzOcV_[X=mg(T3(jIn}wSe.gKNɅ"w;F)I mڋw1рEǤt/x B#l8Fˌzv;ZQ!,1_ ,#H[o.sKt'g]Eur_µjCŃϛ;z?Ҕd,??C sGQcCystGٙmvC,蕨N]e=7S5ߒ-*~Wcac`8Tn5ira{+ d"Ƚjip]Yuu^=J~ˁHᔾǓ @o93*R{Ϗ nVԙ3Nյ1炏E QʝQL8IlsimƶkK̛ow[/}Sv=Leq.Y˥puuiϱ àEBE`k^/cZS'[7V)N[Ubܳķho7nSEƺЎ5ʙxxTmn$slJa0 >'hZ+d|JYz_C{`>3_@;?ߨeܥ)Zn Q;.?$xhx=J6Yg\n<5{?vS {y8ڱ9~/?ct]lvh?Q?PG-nx>%YzU+`ruVYp8k[7' ~3YIA\Ze\KcjH>j ř$G4LF^' []吧ɴO55Eٓ]mf ?͜ڠnSt*OΛ@Y[^G Ѐ,`">g,"?̫kי) zU<)ϗamy h*$y?j?UI%6kgk4*$ߝ¿II$RI$I지$I%I$JRI$I$$I!I$I³I$V)$݀N*Y:d%I$ RI$I$$I)I$JRI$8BIM!UAdobe PhotoshopAdobe Photoshop CS28BIM:http://ns.adobe.com/xap/1.0/ uuid:36516CC7E957DC11B534DDA2BC7DC82F uuid:37516CC7E957DC11B534DDA2BC7DC82F uuid:1FE7B799E657DC11B534DDA2BC7DC82F uuid:1FE7B799E657DC11B534DDA2BC7DC82F 2007-08-31T13:45:02-04:00 2007-08-31T13:45:02-04:00 2007-08-31T13:45:02-04:00 Adobe Photoshop CS2 Windows image/jpeg 3 sRGB IEC61966-2.1 1 720000/10000 720000/10000 2 256,257,258,259,262,274,277,284,530,531,282,283,296,301,318,319,529,532,306,270,271,272,305,315,33432;ADF96EACD31BB9231A43554926381551 160 123 1 36864,40960,40961,37121,37122,40962,40963,37510,40964,36867,36868,33434,33437,34850,34852,34855,34856,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37396,41483,41484,41486,41487,41488,41492,41493,41495,41728,41729,41730,41985,41986,41987,41988,41989,41990,41991,41992,41993,41994,41995,41996,42016,0,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,22,23,24,25,26,27,28,30;DA7E47EBA1E10BA5D842974740380FA2 XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#GĮ k0WɆѓGִr;i3d0c1f6n?zM _4 uL$hBd@iG&vʧV8㶛nR7uȨ\D-ưuͱ`K8ƥ%yhYJ;.ߺ! zpϡg_XQKFA=:865õ5յ679}:̯q3H4?Ya̐skqCB6m*ʘhY_hde>b asLZ-I&31HOg\5ExYuz 5yZ<읳YD ͧ "Rt9@x2Erfm/rϔN?x~Z}ksLpޢ;V$6Km?߭ȝpb[Pﲾ~ff1҈4r؉"!U+7}cA~^<LV#OG1/hgv0%'^Gx>Zhd.\Py\"a;Ǩlfw')z&|Sl_P؟zْ"v@phbMC(]KڛZ yiW/F(*4xZ/1vez&J—B59[|>(덮f^. ;7;wӠc‚)ȫn $>tQTh_u~Ta髕nOa鬝Z#%Da{7TzM*ͱqTE\HpMdn2m*MԲ7IoI2k"sԍC}p!~oW}>yp WtaO}V3(#Ejj*^V`ɧ 06xsJ-WHpqOV'˕{cn̖|h%}\lx jSif[+9.(JrJ:s֗k/xH6hehpvk/o'91>;Z?LitTxۂzV--I=̨?0DdNH'mqIq.^di[C;~ +4a&ޱ?yMߟ: ;Sro8qٌ띌'7az\h4-o5dg7Ƒ{Hޣ i+ ;Q`o.&Hy@\oy($>}]F?a[z괼)bx 8a[&VWVU#dUb%&\͛lh)1m@ ~?f5N-"H~j𶥊.ѶP-¨[eI ^m+[-j8 YYAD=jJGƓNL20{1K\iQt{=d;~F/ uvϨD4UĢ\ucr]+2EemBKf'ѲC=F(T|ή4ʒvQ W:{r:/E02vW1f_%oU›_:kHVU'4?9.g|EZ 4¾G6wiE~jEFhɔ'ӎjAi~S |%i'Ḣ)*ƹsgp<)HIhMW^ukpH7Uj%U=Gm` &G0׿*@ ̒NtzG> Y`ɚB|c_||NBbD}az(vxC @2T+yeSZYSQ>WF9x<>Kޣ,r^1U4M(R5]xqΈJK>?J[u,^t6q.F! ć+c6XJ8naaO1]u\o[@G]LaZ۳?k}lGwx98Dp+n&ig.< >䐨%cj9$jpb ~!q:M6}*q.)l*bb<ۨ/!E9HoǂX\gJT1/Shzκm90預}Lꗏ"/kÎV`ʗ [qUUfҏ (s%^֧~ZƄpJ=;skӚVRD]5/FPq頛[\y x _hM41[ō;mMaρZ1/#9aDz5Ccwr'&2L@o^b)J)_\u |@e#mb#}^D^$q\(.$@]F)ծNs,1"f !Tw6R81]􅻊33,r3 O֔Qnbx RN] ?z? >կk}W/OukI(1縻ne TcTz}V]]/eVVH,+'3^r= (n馚@xܾZ_ ]92r}ޫoۆ2}- ~J㯴YIRS6=ēy[vs/|ɾgoPf̲},- ej2X8s]Z YZД*BV9o<7ZS)ۤ˩W nf?5bo?? }hZ^ׄ''AQ[ݮ{ŗ˶/nkskM$?m.p9ۛn_ >!gqs3OVqM3Uä!#<ʒڱpƽtk^êWdo)<<|ʞGÞ VKh@ >ۼl7o6 Id9%C'VYb0>MX؆ֱe֢d1HcK`Z+5q4-2 * ¿(ncק[P B(A(PPPPPPPPžMAT PP B @( ž*hZP (((((5@-P@QUİB((p @ Ppost$-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate &R}$-ewH}ntry(y;LrQ.n/;$ Yٳ,w̛NJurl http://iv.doubleclick.net/ad/nbcu.science/environment_matter;!category=sciencedaily;f=environment;sect=matter;sub=;sz=160x600,3x3;tile=12;pos=12;ord=123456789012?bsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmime text/urlhvrsdata[InternetShortcut] URL=http://m1.2mdn.net/viewad/817-grey.gif post$ YXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate y;$ Y0)Ԉ@ntry(x{g<s׊-@i %Phttp://www.sciencedaily.com/releases/2005/10/051007090048.htmmime image/gifhvrsdataGIF89a!,D;post@iXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate x@i2و)Ԉd+ntry(tΤ]KZqjHӰ/!DcDurl 4http://www.sciencedaily.com/scripts/google-story.jsbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmimeapplication/x-javascripthntt"7f1866-6f7-cb4c46c0"hvrsdatafunction google_ad_request_done(google_ads) { if (google_ads.length > 0) { var top = '
'; if (google_info.feedback_url) { top += 'Ads by Google'; } else { top += 'Ads by Google'; } top += '

'; var first_ad_unit = '', second_ad_unit = ''; for (var i = 0; i < google_ads.length; ++i) { if (i < 5) { first_ad_unit += ''; } else if (i < 8) { second_ad_unit += ''; } } var bottom = '
'; document.getElementById("googlerelated").innerHTML = top + first_ad_unit + bottom; if (google_ads.length > 4) { document.getElementById("googlebottom").innerHTML = top + second_ad_unit + bottom; } } } google_ad_client = "pub-1787672658759074"; google_ad_output = "js"; google_max_num_ads = "8"; google_feedback = "on"; google_ad_region = "test"; postHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcate tH4FɈDntry(9SVO,1 pu"j<[89+Dzurl 8http://pagead2.googlesyndication.com/pagead/show_ads.jsbsrl>http://www.sciencedaily.com/releases/2005/10/051007090048.htmmimetext/javascripthvrsdata(function(){ var h={google_ad_channel:"channel",google_ad_host:"host",google_ad_region:"region",google_ad_section:"region",google_ad_type:"ad_type",google_adtest:"adtest",google_alternate_ad_url:"alternate_ad_url",google_alternate_color:"alt_color",google_bid:"bid",google_city:"gcs",google_color_bg:"color_bg",google_color_border:"color_border",google_color_line:"color_line",google_color_link:"color_link",google_color_text:"color_text",google_color_url:"color_url",google_contents:"contents",google_country:"gl", google_cust_age:"cust_age",google_cust_ch:"cust_ch",google_cust_gender:"cust_gender",google_cust_id:"cust_id",google_cust_interests:"cust_interests",google_cust_job:"cust_job",google_cust_l:"cust_l",google_cust_lh:"cust_lh",google_cust_u_url:"cust_u_url",google_disable_video_autoplay:"disable_video_autoplay",google_ed:"ed",google_encoding:"oe",google_feedback:"feedback_link",google_flash_version:"flash",google_gl:"gl",google_hints:"hints",google_kw:"kw",google_kw_type:"kw_type",google_language:"hl", google_referrer_url:"ref",google_region:"gr",google_reuse_colors:"reuse_colors",google_safe:"adsafe",google_targeting:"targeting",google_ui_features:"ui"},m={google_ad_format:"format",google_ad_output:"output",google_ad_callback:"callback",google_ad_override:"google_ad_override",google_ad_slot:"slotname",google_analytics_webpropids:"ga_wpids",google_correlator:"correlator",google_cpa_choice:"cpa_choice",google_image_size:"image_size",google_last_modified_time:"lmt",google_max_num_ads:"num_ads",google_max_radlink_len:"max_radlink_len", google_num_radlinks:"num_radlinks",google_num_radlinks_per_unit:"num_radlinks_per_unit",google_only_ads_with_video:"only_ads_with_video",google_page_location:"loc",google_page_url:"url",google_rl_dest_url:"rl_dest_url",google_rl_filtering:"rl_filtering",google_rl_mode:"rl_mode",google_rt:"rt",google_skip:"skip"};function n(b){return h[b]||m[b]||null}var u=document;function w(){var b=u.cookie,a=Math.round((new Date).getTime()/1000),d=b.indexOf("__utma=")>-1,e=b.indexOf("__utmb=")>-1,c=b.indexOf("__utmc=")> -1,f,g={};if(d){f=b.split("__utma=")[1].split(";")[0].split(".");g.sid=(!e||!c?a:f[4])+"";g.vid=f[1]+"."+f[2];g.from_cookie=true}else{g.sid=window&&window.gaGlobal&&window.gaGlobal.sid?window.gaGlobal.sid:a+"";g.vid=window&&window.gaGlobal&&window.gaGlobal.vid?window.gaGlobal.vid:Math.round(Math.random()*2147483647)+"."+a;g.from_cookie=false}g.hid=window&&window.gaGlobal&&window.gaGlobal.hid?window.gaGlobal.hid:Math.round(Math.random()*2147483647);window.gaGlobal=g;return g}(function(){function b(){} b.prototype.l=function(e){var c=e.indexOf("#")+1;return c?e.substr(c):""};b.prototype.n=function(e){return/[&<>\"]/.test(e)?e.replace(/&/g,"&").replace(//g,">").replace(/\"/g,"""):e};b.prototype.b=function(e){var c=""};b.prototype.m=function(e,c){try{return e.frames[c]}catch(f){return null}};b.prototype.e=function(e){var c=document.createElement("iframe");for(var f in e){c.setAttribute(f, e[f])}return c};b.prototype.i=function(e,c){var f=this;setTimeout(function(){document.body.appendChild(f.e({id:e,name:e,src:c,width:0,height:0,frameBorder:0}))},0)};b.prototype.r=function(e,c){var f=this;document.write(f.b({id:e,name:e,src:c,width:0,height:0,frameBorder:0}))};b.prototype.g=function(e,c){var f=[],g=e.length,k=0;while(k0){g.f[c]=i[o];for(var q=0;qIDICommon.MAX_URL_LENGTH){y+="$";var H=l.d(c),S=IDICommon.MAX_URL_LENGTH-1-H.length,I=IDICommon.g(y,S),J=I.length;for(var s=0;s')}if(R(b.google_ad_output,b.google_ad_client)){IDIHost.q("http://pagead2.googlesyndication.com/pagead/idi_relay.html");var c=0;if(b.google_num_0ad_slots){c+= b.google_num_0ad_slots}if(b.google_num_ad_slots){c+=b.google_num_ad_slots}if(b.google_num_sdo_slots){c+=b.google_num_sdo_slots}var f="google_inline_div"+c,g="
';a.write(g);var k="google_frame"+c,j=b.setTimeout(function(){IDIHost.h(k)},5000);IDIHost.j(d,k,b.google_ad_width,b.google_ad_height,{callback:function(l, i){P(l,i,j)},pollingInterval:500,iframeAttrs:{style:"position: absolute;left:0px",marginWidth:"0",marginHeight:"0",vspace:"0",hspace:"0",allowTransparency:"true"},parentDivId:f})}else{a.write('")}if(e!=null){a.write("
")}}}else if(b.google_ad_output== "textlink"){a.write('