From: Subject: The Road Hammer: Live Review: Majesty of Madness/Van Halenized, Barrymore's Music Hall, Saturday, December 2, 2006 Date: Thu, 17 May 2007 19:27:18 -0400 MIME-Version: 1.0 Content-Type: multipart/related; type="multipart/alternative"; boundary="----=_NextPart_000_0000_01C798B9.62265700" X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3028 This is a multi-part message in MIME format. ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: image/jpeg Content-Transfer-Encoding: base64 Content-Location: http://photos1.blogger.com/x/blogger/4355/1129/320/386660/majesty.jpg /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCADVAUADASIA AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5iPBp KazAmkLYHBrjsz3uYfQRmmk5xzmgcUWYmxRke4oxz60oPvRnbzSGNI9KUYpXPOQecUnXjjNO+hPU WlHNJyvBozzSKFFLgZ703NLmgZIHYdDn61Itxzyv5VXzyKXd9KlxTNY1XHZl6OVG6Nz71BeNyF/G oA1IORz1qVCzuaSruUbMU5zkU05xSk5FLGpdworS5ztX0RNYw7m8xh9K0FWmRKqoF9KkBGBzXJOX Mz2cPS9nGw7AzjmnD9KZz0p9YnXGw9duO9SDpUWeKXPSotc2jMkyacG45qMNwKUNmpsVzjm64oU/ lSUMaZDYpx19Kp3Eu7KJ93v70txNk7FOPX3quTit6cLas4MRXv7sRTU9vHxn8qZbpvOTVtRx0xVT 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 ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.seinfeld-fan.net/pictures/other/seinfeld_other025.gif R0lGODlhoAB4APcAAP/////35//3xv/Oxv/Otf+9pf+tpffnzvfWvffOzve9vfe9rfetnPetlPel tfeUjO/nve+lhO+Uc+fezufO5+e1nOelnOele+eUjOeMa97n997e3t7Wvd7Ozt7Ord7Gvd7Gtd7G pd6UY9bezta9jNa1lNale9achNaUc9aMhNaEc9aEY9Z7Y87Wzs7Wvc7O587Orc7G3s7Gzs7Gvc69 tc69rc69nM61hM57Ws5rY8aUa8aMe8aMc8aEa8aEWsZrUr3G1r3Gvb3Grb29nL2txr2trb2tnL2t lL2tjL2le72cjL2MhL17a71zUr1jQrW9xrW9rbWtxrWlnLVjUq21xq21ra21nK2lnK2llK2lhK2c ra2UhK2Ue62Uc62Ma62MY62EUq17Y61zWq1zSq1rY6WtraWlvaWcnKVze6VrQqVjUqVjQqVSQpyt nJyljJycrZyUnJyUjJyUhJyMe5yMc5yMa5yMY5yMWpyESpSlnJScnJSMjJSEY5R7hJRzY5RzWpRz UpRzQpRjOZRaWpRaSpRSQpRSMYycjIyMnIyMjIyMe4yMc4SUhISElIRzjIRzc4RzY4RzWoRzUoRz SoRrOYRjUoRjQoRaOYRSUoRSQoRSMYRKOYRCKXuMe3uMc3uEhHuEa3uEWntjMXs5GHN7e3N7Y3Nz e3NzY3NzWnNrc3NrY3NrUnNrMXNjSnNaY3NaQnNaOXNSQnNSKXNKKXNCOXM5KWtrSmtac2tSUmtK GGtCQmspGGNrY2NrSmNjc2NaIWNSY2M5IWM5EGMpCFprUlpaUlpaQlpaMVpKUlpKQlpKMVpCGFo5 OVoxKVJSWlJSMVJCQlJCMVIpGFIpCEpSSkpKMUpCSko5OUo5IUo5EEoxKUJKMUIxSkIxGEIpMUIp CEIhGEIYEEIYADlCMTk5MTFCQjE5ITExKTExEDEpOTEpGDEpCDEhKTEhGDEhEDEYADEQGDEIEDEI AClKKSkxUiEYACEQGCEIABgpIRgpEBghCBAQEBAQABAIEBAAAAAAACwAAAAAoAB4AAAI/wDJkSNG KlE1cumMOTqUTCC1RIeKHSymKCK+f+yI8bK2b586aqWsqduXzxqvVfhGssvHriU7gQIJoupEqmYp Ur5qkirFixSvUjxLQUpFip05hNzo0Ss3bt64cUfJjStHztenRIoe1QFKM5EjRYkeKbpayqg5o+wK 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 yjD6mi/2hkwMz+37uuw+BAQAOw== ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: application/octet-stream Content-Transfer-Encoding: base64 Content-Location: http://s26.sitemeter.com/meter.asp?site=s26roadhammer R0lGODlhWAAgAPcAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz/wBmAABmMwBm ZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDMmQDMzADM/wD/AAD/MwD/ZgD/ mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMzMzMzZjMzmTMzzDMz/zNmADNmMzNmZjNmmTNm zDNm/zOZADOZMzOZZjOZmTOZzDOZ/zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP/ /2YAAGYAM2YAZmYAmWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZ AGaZM2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkA M5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplmmZlmzJlm/5mZAJmZM5mZ ZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswA mcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz/8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZmcyZ zMyZ/8zMAMzMM8zMZszMmczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A //8zAP8zM/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z///M AP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////yH5BAUAAAEALAAAAABYACAA QAj/AAEIHEiwoMGDCBMqXMhw4bWH1wJZYUWR1USLgShOvGYxYoyMXKpwoRjj0DVAXGTJ2pJxCyBW 1rgAssZqC6uVXFZZexhz5JYqWyBeWzXyEAwYgGLAiCH0ocCmUKNKnUq1qtWrTZ9itQogK8SuXqWC BXuN7FaoWqOyCnS2rdtrsg7JknrIZIy7aM1ClMhqBatrfiNaaQqoCkQYf09WkQVjVdMqgDgiFsoK xtyjMQAdTbpUM1KlmTfHUBGDC+mvet86/bq6NevWqcmmdptWte3bqmvj3s2bqm6pG3tzMemWyxYu UQ/dLbw0L2UrVtha/LsRuvXogYI+nHxyyyoYW8Jv/2HK8ppyLuiPs4oxl6P55VWWGoWhvLNo+UdR U5bINuJDjA9JFB1HxEWUGCvEsYLeSw+h9NchC87V3yFVmFSFYcpZiGFJ11z4noWDOTVbbyT29htu Zg00lWyvlXUibSPCqKKILLo4o41C3XjbiyX2aBuPPgZ5FpBCFvkQhQXqJ9V07pF401voIQfVKlWU VCVTWekl4F8ZCSgdfw/WhR5F6PVnHnomAXLcSBGhCdchCiYmlHHaNaVcZqA5t1eIHIW4USBmRkch TzE4dg16srD3EJWHmsSKYUeOVIWc75U0nmEUXaMUZPcxlamIUGHU11+BRVfRX2oelpia3506VxVs KY8nC0Wy0KQoF0jNx1lon9nXa2mngboXoKaWOiB0gO5xKKTWNNYgU4HAwEUggJiEKyCyXBvISJXN BVq0MATy7VHiLhWICiqISxog6Cpp5LtbEQnvvMLypqOOqMlGUL72xvijazGOdWONO/pLW44tIhzV WAnnZnC8aDUc22sE//gwiRcXKS+98Dbk8ccgh+xxQAA7 ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: text/css; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.blogger.com/css/blog_controls.css .item-control { DISPLAY: none } .item-control A { TEXT-DECORATION: none! important } .item-action A { TEXT-DECORATION: none! important } .widget-item-control { FLOAT: right } .quick-edit-icon { PADDING-RIGHT: 9px; PADDING-LEFT: 9px; BACKGROUND: = url(/img/icon18_edit_allbkg.gif) no-repeat left 50%; PADDING-BOTTOM: = 9px; MARGIN: 0px 0px 0px 0.5em; PADDING-TOP: 9px } .widget-item-control .quick-edit-icon { BACKGROUND: url(/img/icon18_wrench_allbkg.gif) no-repeat left 50% } .delete-comment-icon { PADDING-RIGHT: 7px; PADDING-LEFT: 7px; BACKGROUND: = url(/img/icon_delete13.gif) no-repeat left 50%; PADDING-BOTTOM: 7px; = PADDING-TOP: 7px } .email-post-icon { PADDING-RIGHT: 9px; PADDING-LEFT: 9px; BACKGROUND: = url(/img/icon18_email.gif) no-repeat left 50%; PADDING-BOTTOM: 9px; = MARGIN: 0px 0px 0px 0.5em; PADDING-TOP: 9px } ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: text/css; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Location: http://www.blogger.com/css/navbar/classic.css HTML BODY { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; MARGIN: 0px; PADDING-TOP: 0px } BODY #wrapper { MARGIN-TOP: 30px } BODY #header { MARGIN-TOP: 50px } #leftcontent { _margin-top: 30px } #rightcontent { MARGIN-TOP: 30px! important } #Main #Title { MARGIN-TOP: 30px! important } BODY #wrap #wrap2 #header { MARGIN-TOP: 0px } BODY #wrap { MARGIN-TOP: 34px } #blog-header { MARGIN-TOP: -4px } BODY #wrap4 { PADDING-RIGHT: 15px; MARGIN-TOP: -4px; PADDING-LEFT: 15px; = PADDING-BOTTOM: 0px; PADDING-TOP: 15px } #space-for-ie { DISPLAY: none; _border: 0; _display: block } #navbar-iframe { Z-INDEX: 500; LEFT: 0px; POSITION: absolute; TOP: 0px } ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: image/gif Content-Transfer-Encoding: base64 Content-Location: http://www.blogger.com/img/navbar/1/btn_search_this.gif R0lGODlhYAAPANUAAB9YjAlCeEN6rneq3VKIuxBKf0uBtWic0C5mmjVsoTxzpwhCeBhRhm+j1ghC d0J3q1mOwkJ4qxJLgD9ypDBikhJKgEN4rD5xozBiky9ikiVckRJKfSZdkSVdkRJJfSZdkj9xo2GV ySZfk36x5BFEd0J4rAlDeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAABgAA8AAAb/QA8G 9CgZj8ikcslsOp/Q54VCynQqpqx2y+16v+CweDyWcCgTyYLMbrvfbsmk5FjD7/i8eLF4RBwBWQkD IwkmIiOJIlkGIwZZiCMDhiYADY6HI1kji1kCiSMhmZuLiiaDhVuRIwJZIa2ChI+xIwRZDiZFJoEm AwgFBaNbByEHkJoKmiYNCiYMwpxc0dCLAqK9v8FaiCYIyq9avgwjAM7klVmBEQ+AWQMHnYginQWF I8HyBMYA99uc8tLi/YtmzR08LvmMmQAnDJwChVoCLChhIQAvSyMQZApxzZuJjJkODFjEzR/HaVqm ITpZ7RpGjSYb2FoIqyQ4a5HSmSjxwOIWxgiiSjIaEGLAI24GRPF7doxUwKYfW/681rReOYb8gh1o lqCBsEAlIkjMokAEBFvyRAQLQUAEgaCaxj070JakMpROqZnQF6zsWVWckl1t+6yBAG/PGAxQkExL n4p2khIIBoBjiKvlKle6ZsBQgbfNNC8st+VyFtGmOZaTrO20ZZhJQxgCABRmJaCzAjgI206P7995 Jl6QwAu48eNhHMihoKHCAoskokufTr269evTA2Dfzr379AofMGxAEyGK+fPo05ufkIFEEAA7 ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.blogger.com/css/navbar/navbar.css?v=1 #b-navbar { DISPLAY: block! important; Z-INDEX: 1; MIN-HEIGHT: 24px; LEFT: 0px; = MARGIN-BOTTOM: 10px; PADDING-BOTTOM: 4px; FONT: x-small "Trebuchet = MS",Verdana,Arial,Sans-serif; WIDTH: 100%; COLOR: #47a; BORDER-BOTTOM: = #024 1px solid; POSITION: absolute! important; TOP: 0px } .bt1 { FONT-SIZE: 1px; MARGIN: 0px 1px; LINE-HEIGHT: 1px; POSITION: relative; = HEIGHT: 1px } .bt2 { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-SIZE: 83%; PADDING-BOTTOM: = 2px; PADDING-TOP: 2px; POSITION: relative } #b-next { PADDING-LEFT: 5px } #b-search-this { MARGIN: 0px; TEXT-TRANSFORM: uppercase; CURSOR: pointer; WHITE-SPACE: = nowrap; POSITION: relative; TEXT-DECORATION: none } #b-flag-this { PADDING-LEFT: 5px; MARGIN: 0px; TEXT-TRANSFORM: uppercase; CURSOR: = pointer; WHITE-SPACE: nowrap; POSITION: relative; TEXT-DECORATION: none } #b-navbar #b-logo { BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; LEFT: 5px; = BORDER-BOTTOM-WIDTH: 0px; POSITION: absolute! important; TOP: 0.15em; = BORDER-RIGHT-WIDTH: 0px } @media All =20 { #b-search { MARGIN: 0px 0px 0px 34px; HEIGHT: 1em; BACKGROUND-COLOR: #147 } #b-search TABLE { PADDING-RIGHT: 5px } #b-search TD { FONT-SIZE: 80%; LINE-HEIGHT: 0.8em } #b-more { FLOAT: right } #b-searchbtn { MARGIN-RIGHT: 5px } #b-more { FLOAT: right } #b-search TABLE { PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FLOAT: left; PADDING-BOTTOM: = 1px; PADDING-TOP: 1px } #b-search A { LINE-HEIGHT: 1em; TEXT-DECORATION: none } #b-search A:hover { LINE-HEIGHT: 1em; TEXT-DECORATION: none } #b-search TD { LINE-HEIGHT: 0.8; PADDING-TOP: 2px } #b-search TD TD { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; = PADDING-TOP: 0px } #b-searchbtn { DISPLAY: block } } @media Handheld =20 { #b-search { DISPLAY: none! important } #b-more { DISPLAY: none! important } } .navbar-right { PADDING-RIGHT: 10px } TD.navbutton { PADDING-RIGHT: 5px; PADDING-TOP: 0.3em } TD.navsearch { PADDING-LEFT: 5px } #b-query { VERTICAL-ALIGN: top; WIDTH: 12em; MARGIN-RIGHT: 0.25em } #b-query { FONT-SIZE: x-small! important } @media All =20 { BODY DIV.b-mobile { DISPLAY: none } #b-sms { DISPLAY: none! important } } @media Handheld =20 { BODY DIV.b-mobile { DISPLAY: block } #b-sms { PADDING-RIGHT: 7px; DISPLAY: block! important; PADDING-LEFT: 7px; = FONT-SIZE: 100%; PADDING-BOTTOM: 4px; MARGIN: 0px 0px 0px 100px; = LINE-HEIGHT: 1em; PADDING-TOP: 4px; TEXT-ALIGN: left } #b-sms A { LINE-HEIGHT: 1em; MARGIN-RIGHT: 0.5em; WHITE-SPACE: nowrap; = TEXT-DECORATION: none } #b-sms A:hover { COLOR: #fff; TEXT-DECORATION: underline } } @media All =20 { #flagi { PADDING-RIGHT: 1px; DISPLAY: none; PADDING-LEFT: 1px; Z-INDEX: 300; = PADDING-BOTTOM: 1px; PADDING-TOP: 1px; TOP: 7px; BACKGROUND-COLOR: #333 } #unflagi { PADDING-RIGHT: 1px; DISPLAY: none; PADDING-LEFT: 1px; Z-INDEX: 300; = PADDING-BOTTOM: 1px; PADDING-TOP: 1px; TOP: 7px; BACKGROUND-COLOR: #333 } } @media Handheld =20 { #flagi { DISPLAY: none! important } #unflagi { DISPLAY: none! important } } #flagi-body { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; FONT-WEIGHT: bold; FONT-SIZE: = 10px; PADDING-BOTTOM: 3px; LINE-HEIGHT: 14px; PADDING-TOP: 3px; = FONT-FAMILY: "Trebuchet MS", Vedana, Arial, Sans-serif; = BACKGROUND-COLOR: #ffff99; TEXT-ALIGN: center } #flagi-body A { FONT-SIZE: 10px; COLOR: #3366cc; TEXT-DECORATION: none } #flagi-body A:hover { TEXT-DECORATION: underline } #unflagi-body { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; FONT-WEIGHT: bold; FONT-SIZE: = 10px; PADDING-BOTTOM: 3px; LINE-HEIGHT: 14px; PADDING-TOP: 3px; = FONT-FAMILY: "Trebuchet MS", Vedana, Arial, Sans-serif; = BACKGROUND-COLOR: #ffff99; TEXT-ALIGN: center } #unflagi-body A { FONT-SIZE: 10px; COLOR: #3366cc; TEXT-DECORATION: none } #unflagi-body A:hover { TEXT-DECORATION: underline } ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.blogger.com/css/navbar/1.css?v=1 #b-navbar { COLOR: #47a; BORDER-BOTTOM: #024 1px solid; BACKGROUND-COLOR: #036 } #b-search TABLE { BACKGROUND: url(../../img/navbar/1/corner.gif) #147 no-repeat left = bottom } #b-query { BORDER-RIGHT: #47a 1px solid; BORDER-TOP: #47a 1px solid; BORDER-LEFT: = #47a 1px solid; BORDER-BOTTOM: #47a 1px solid } #b-search A { COLOR: #9cf } #b-search TD { COLOR: #fff } #b-search A:hover { COLOR: #fff } #b-sms A { COLOR: #9cf } #b-sms A:hover { COLOR: #fff } #navbar-logo { BACKGROUND-IMAGE: url(../../img/navbar/1/logobar.gif); WIDTH: 24px; = HEIGHT: 24px } #b-search-this { BACKGROUND: #114477 } .bt1 { BACKGROUND-COLOR: #4477aa } .bt2 { BORDER-RIGHT: #4477aa 1px solid; BORDER-LEFT: #4477aa 1px solid; COLOR: = #99ccff; BACKGROUND-COLOR: #114477 } DIV.bt2:hover { BACKGROUND-COLOR: #4477aa } #bt-flag { PADDING-LEFT: 8px; BACKGROUND: url(../../img/navbar/1/flag.gif) = no-repeat left 50% } ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.blogger.com/js/cookies.common.js // Copyright 2005, Google Inc.=0A= // =0A= // Operations on cookies that are common across our pages.=0A= //=0A= // Original Author: Pal Takacsi-Nagy (pal@google.com)=0A= =0A= =0A= /**=0A= * Sets a Cookie with the given name and value.=0A= *=0A= * name Name of the cookie=0A= * value Value of the cookie=0A= * [expires] Expiration date of the cookie (default: end of current = session)=0A= * [path] Path where the cookie is valid (default: path of calling = document)=0A= * [domain] Domain where the cookie is valid=0A= * (default: domain of calling document)=0A= * [secure] Boolean value indicating if the cookie transmission = requires a=0A= * secure transmission=0A= */=0A= function setCookie(name, value, domain, expires, path, secure) {=0A= document.cookie =3D name + "=3D" + escape(value) +=0A= ((expires) ? "; expires=3D" + expires.toGMTString() : "") +=0A= ((path) ? "; path=3D" + path : "") +=0A= ((domain) ? "; domain=3D" + domain : "") +=0A= ((secure) ? "; secure" : "");=0A= }=0A= =0A= /**=0A= * Gets the value of the specified cookie.=0A= *=0A= * name Name of the desired cookie.=0A= *=0A= * Returns a string containing value of specified cookie,=0A= * or null if cookie does not exist.=0A= */=0A= function getCookie(name) {=0A= var dc =3D document.cookie;=0A= var prefix =3D name + "=3D";=0A= var begin =3D dc.indexOf("; " + prefix);=0A= =0A= if (begin =3D=3D -1) {=0A= begin =3D dc.indexOf(prefix);=0A= if (begin !=3D 0) return null;=0A= } else {=0A= begin +=3D 2;=0A= }=0A= =0A= var end =3D document.cookie.indexOf(";", begin);=0A= =0A= if (end =3D=3D -1) {=0A= end =3D dc.length;=0A= }=0A= =0A= return unescape(dc.substring(begin + prefix.length, end));=0A= }=0A= ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.blogger.com/app/scripts/common.js // Copied from .../google3/javascript/common.js=0A= =0A= //-----------------------------------------------------------------------= -=0A= // This file contains common utilities and basic javascript = infrastructure.=0A= //=0A= // Notes:=0A= // * Press 'D' to toggle debug mode.=0A= //=0A= // Functions:=0A= //=0A= // - Assertions=0A= // DEPRECATED: Use assert.js=0A= // AssertTrue(): assert an expression. Throws an exception if false.=0A= // Fail(): Throws an exception. (Mark block of code that should be = unreachable)=0A= // AssertEquals(): assert that two values are equal.=0A= // AssertNumArgs(): assert number of arguments for the function=0A= // AssertType(): assert that a value has a particular type=0A= //=0A= // - Cookies=0A= // SetCookie(): Sets a cookie.=0A= // ExpireCookie(): Expires a cookie.=0A= // GetCookie(): Gets a cookie value.=0A= //=0A= // - Dynamic HTML/DOM utilities=0A= // MaybeGetElement(): get an element by its id=0A= // GetElement(): get an element by its id=0A= // GetParentNode(): Get the parent of an element=0A= // GetAttribute(): Get attribute value of a DOM node=0A= // SetInnerHTML(): set the inner HTML of a node=0A= // GetInnerHTML(): get the inner HTML of a node=0A= // ClearInnerHTML(): clear the inner HTML of a node=0A= // SetCssStyle(): Sets a CSS property of a node.=0A= // GetStyleProperty(): Get CSS property from a style attribute string=0A= // ShowElement(): Show/hide element by setting the "display" css = property.=0A= // ShowBlockElement(): Show/hide block element=0A= // SetButtonText(): Set the text of a button element.=0A= // AppendNewElement(): Create and append a html element to a parent node.=0A= // CreateDIV(): Create a DIV element and append to the document.=0A= // CreateIFRAME(): Create an IFRAME and append to the document.=0A= // HasClass(): check if element has a given class=0A= // AddClass(): add a class to an element=0A= // RemoveClass(): remove a class from an element=0A= //=0A= // - Window/Screen utiltiies=0A= // GetPageOffsetLeft(): get the X page offset of an element=0A= // GetPageOffsetTop(): get the Y page offset of an element=0A= // GetPageOffset(): get the X and Y page offsets of an element=0A= // GetPageOffsetRight() : get X page offset of the right side of an = element=0A= // GetPageOffsetRight() : get Y page offset of the bottom of an element=0A= // GetScrollTop(): get the vertical scrolling pos of a window.=0A= // GetScrollLeft(): get the horizontal scrolling pos of a window=0A= // IsScrollAtEnd(): check if window scrollbar has reached its maximum = offset=0A= // ScrollTo(): scroll window to a position=0A= // ScrollIntoView(): scroll window so that an element is in view.=0A= // GetWindowWidth(): get width of a window.=0A= // GetWindowHeight(): get height of a window=0A= // GetAvailScreenWidth(): get available screen width=0A= // GetAvailScreenHeight(): get available screen height=0A= // GetNiceWindowHeight(): get a nice height for a new browser window.=0A= // Open{External/Internal}Window(): open a separate window=0A= // CloseWindow(): close a window=0A= //=0A= // - DOM walking utilities=0A= // AnnotateTerms(): find terms in a node and decorate them with some tag=0A= // AnnotateText(): find terms in a text node and decorate them with some = tag=0A= //=0A= // - String utilties=0A= // HtmlEscape(): html escapes a string=0A= // HtmlUnescape(): remove html-escaping.=0A= // QuoteEscape(): escape " quotes.=0A= // CollapseWhitespace(): collapse multiple whitespace into one = whitespace.=0A= // Trim(): trim whitespace on ends of string=0A= // IsEmpty(): check if CollapseWhiteSpace(String) =3D=3D ""=0A= // IsLetterOrDigit(): check if a character is a letter or a digit=0A= // ConvertEOLToLF(): normalize the new-lines of a string.=0A= // HtmlEscapeInsertWbrs(): HtmlEscapes and inserts s (word break = tags)=0A= // after every n non-space chars and/or after or before certain = special chars=0A= //=0A= // - TextArea utilities=0A= // GetCursorPos(): finds the cursor position of a textfield=0A= // SetCursorPos(): sets the cursor position in a textfield=0A= //=0A= // - Array utilities=0A= // FindInArray(): do a linear search to find an element value.=0A= // DeleteArrayElement(): return a new array with a specific value = removed.=0A= // CloneObject(): clone an object, copying its values recursively.=0A= // CloneEvent(): clone an event; cannot use CloneObject because it=0A= // suffers from infinite recursion=0A= //=0A= // - Formatting utilities=0A= // PrintArray(): used to print/generate HTML by combining static text=0A= // and dynamic strings.=0A= // ImageHtml(): create html for an img tag=0A= // FormatJSLink(): formats a link that invokes js code when clicked.=0A= // MakeId3(): formats an id that has two id numbers, eg, foo_3_7=0A= //=0A= // - Miscellaneous=0A= // IsDefined(): returns true if argument is not undefined=0A= //-----------------------------------------------------------------------= -=0A= =0A= // browser detection=0A= var agent =3D navigator.userAgent.toLowerCase();=0A= var is_ie =3D (agent.indexOf('msie') !=3D -1);=0A= //var is_ie5 =3D (agent.indexOf('msie 5') !=3D -1 && document.all);=0A= var is_konqueror =3D (agent.indexOf('konqueror') !=3D -1);=0A= var is_safari =3D (agent.indexOf('safari') !=3D -1) || is_konqueror;=0A= var is_nav =3D !is_ie && !is_safari && (agent.indexOf('mozilla') !=3D = -1);=0A= var is_win =3D (agent.indexOf('win') !=3D -1);=0A= delete agent;=0A= =0A= =0A= var BACKSPACE_KEYCODE =3D 8;=0A= var COMMA_KEYCODE =3D 188; // ',' key=0A= var DEBUG_KEYCODE =3D 68; // 'D' key=0A= var DELETE_KEYCODE =3D 46;=0A= var DOWN_KEYCODE =3D 40; // DOWN arrow key=0A= var ENTER_KEYCODE =3D 13; // ENTER key=0A= var ESC_KEYCODE =3D 27; // ESC key=0A= var LEFT_KEYCODE =3D 37; // LEFT arrow key=0A= var RIGHT_KEYCODE =3D 39; // RIGHT arrow key=0A= var SPACE_KEYCODE =3D 32; // space bar=0A= var TAB_KEYCODE =3D 9; // TAB key=0A= var UP_KEYCODE =3D 38; // UP arrow key=0A= var SHIFT_KEYCODE =3D 16;=0A= =0A= // This is a "constant" but has different values depending on the browser=0A= var semicolon_keycode =3D (is_ie ? 186 : 59);=0A= =0A= var MAX_EMAIL_ADDRESS_LENGTH =3D 320; // 64 + '@' + 255=0A= var MAX_SIGNATURE_LENGTH =3D 1000; // 1000 chars of maximum = signature=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Assertions=0A= // DEPRECATED: Use assert.js=0A= //-----------------------------------------------------------------------= -=0A= /**=0A= * DEPRECATED: Use assert.js=0A= */=0A= function raise(msg) {=0A= if (typeof Error !=3D 'undefined') {=0A= throw new Error(msg || 'Assertion Failed');=0A= } else {=0A= throw (msg);=0A= }=0A= }=0A= =0A= /**=0A= * DEPRECATED: Use assert.js=0A= *=0A= * Fail() is useful for marking logic paths that should=0A= * not be reached. For example, if you have a class that uses=0A= * ints for enums:=0A= *=0A= * MyClass.ENUM_FOO =3D 1;=0A= * MyClass.ENUM_BAR =3D 2;=0A= * MyClass.ENUM_BAZ =3D 3;=0A= *=0A= * And a switch statement elsewhere in your code that=0A= * has cases for each of these enums, then you can=0A= * "protect" your code as follows:=0A= *=0A= * switch(type) {=0A= * case MyClass.ENUM_FOO: doFooThing(); break;=0A= * case MyClass.ENUM_BAR: doBarThing(); break;=0A= * case MyClass.ENUM_BAZ: doBazThing(); break;=0A= * default:=0A= * Fail("No enum in MyClass with value: " + type);=0A= * }=0A= *=0A= * This way, if someone introduces a new value for this enum=0A= * without noticing this switch statement, then the code will=0A= * fail if the logic allows it to reach the switch with the=0A= * new value, alerting the developer that he should add a=0A= * case to the switch to handle the new value he has introduced.=0A= *=0A= * @param {string} opt_msg to display for failure=0A= * DEFAULT: "Assertion failed"=0A= */=0A= function Fail(opt_msg) {=0A= if (opt_msg =3D=3D=3D undefined) opt_msg =3D 'Assertion failed';=0A= if (IsDefined(DumpError)) DumpError(opt_msg + '\n');=0A= raise(opt_msg);=0A= }=0A= =0A= /**=0A= * DEPRECATED: Use assert.js=0A= *=0A= * Asserts that an expression is true (non-zero and non-null).=0A= *=0A= * Note that it is critical not to pass logic=0A= * with side-effects as the expression for AssertTrue=0A= * because if the assertions are removed by the=0A= * JSCompiler, then the expression will be removed=0A= * as well, in which case the side-effects will=0A= * be lost. So instead of this:=0A= *=0A= * AssertTrue( criticalComputation() );=0A= *=0A= * Do this:=0A= *=0A= * var result =3D criticalComputation();=0A= * AssertTrue(result);=0A= *=0A= * @param {anything} expression to evaluate=0A= * @param {string} opt_msg to display if the assertion fails=0A= *=0A= */=0A= function AssertTrue(expression, opt_msg) {=0A= if (!expression) {=0A= if (opt_msg =3D=3D=3D undefined) opt_msg =3D 'Assertion failed';=0A= Fail(opt_msg);=0A= }=0A= }=0A= =0A= /**=0A= * DEPRECATED: Use assert.js=0A= *=0A= * Asserts that two values are the same.=0A= *=0A= * @param {anything} val1=0A= * @param {anything} val2=0A= * @param {string} opt_msg to display if the assertion fails=0A= */=0A= function AssertEquals(val1, val2, opt_msg) {=0A= if (val1 !=3D val2) {=0A= if (opt_msg =3D=3D=3D undefined) {=0A= opt_msg =3D "AssertEquals failed: <" + val1 + "> !=3D <" + val2 + = ">";=0A= }=0A= Fail(opt_msg);=0A= }=0A= }=0A= =0A= /**=0A= * DEPRECATED: Use assert.js=0A= *=0A= * Asserts that a value is of the provided type.=0A= *=0A= * AssertType(6, Number);=0A= * AssertType("ijk", String);=0A= * AssertType([], Array);=0A= * AssertType({}, Object);=0A= * AssertType(ICAL_Date.now(), ICAL_Date);=0A= *=0A= * @param {anything} value=0A= * @param {constructor function} type=0A= * @param {string} opt_msg to display if the assertion fails=0A= */=0A= function AssertType(value, type, opt_msg) {=0A= // for backwards compatability only=0A= if (typeof value =3D=3D type) return;=0A= =0A= if (value || value =3D=3D "") {=0A= try {=0A= if (type =3D=3D AssertTypeMap[typeof value] || value instanceof = type) return;=0A= } catch (e) { /* failure, type was an illegal argument to instanceof = */ }=0A= }=0A= if (opt_msg =3D=3D=3D undefined) {=0A= if (typeof type =3D=3D 'function') {=0A= var match =3D type.toString().match(/^\s*function\s+([^\s\{]+)/);=0A= if (match) type =3D match[1];=0A= }=0A= opt_msg =3D "AssertType failed: <" + value + "> not typeof "+ type;=0A= }=0A= Fail(opt_msg);=0A= }=0A= =0A= var AssertTypeMap =3D {=0A= 'string' : String,=0A= 'number' : Number,=0A= 'boolean' : Boolean=0A= };=0A= =0A= /**=0A= * DEPRECATED: Use assert.js=0A= *=0A= * Asserts that the number of arguments to a=0A= * function is num. For example:=0A= *=0A= * function myFunc(one, two, three) [=0A= * AssertNumArgs(3);=0A= * ...=0A= * }=0A= *=0A= * myFunc(1, 2); // assertion fails!=0A= *=0A= * Note that AssertNumArgs does not take the function=0A= * as an argument; it is simply used in the context=0A= * of the function.=0A= *=0A= * @param {int} number of arguments expected=0A= * @param {string} opt_msg to display if the assertion fails=0A= */=0A= function AssertNumArgs(num, opt_msg) {=0A= var caller =3D AssertNumArgs.caller; // This is not supported in = safari 1.0=0A= if (caller && caller.arguments.length !=3D num) {=0A= if (opt_msg =3D=3D=3D undefined) {=0A= opt_msg =3D caller.name + ' expected ' + num + ' arguments '=0A= + ' but received ' + caller.arguments.length;=0A= }=0A= Fail(opt_msg);=0A= }=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Cookies=0A= //-----------------------------------------------------------------------= -=0A= var ILLEGAL_COOKIE_CHARS_RE =3D /[\s;]/=0A= /**=0A= * Sets a cookie.=0A= * The max_age can be -1 to set a session cookie. To expire cookies, use=0A= * ExpireCookie() instead.=0A= *=0A= * @param name The cookie name.=0A= * @param value The cookie value.=0A= * @param opt_max_age The max age in seconds (from now). Use -1 to set a=0A= * session cookie. If not provided, the default is -1 (i.e. set a = session=0A= * cookie).=0A= * @param opt_path The path of the cookie, or null to not specify a path=0A= * attribute (browser will use the full request path). If not = provided, the=0A= * default is '/' (i.e. path=3D/).=0A= * @param opt_domain The domain of the cookie, or null to not specify a = domain=0A= * attribute (brower will use the full request host name). If not = provided,=0A= * the default is null (i.e. let browser use full request host name).=0A= * @return Void.=0A= */=0A= function SetCookie(name, value, opt_max_age, opt_path, opt_domain) {=0A= =0A= value =3D '' + value;=0A= AssertTrue((typeof name =3D=3D 'string' &&=0A= typeof value =3D=3D 'string' &&=0A= !name.match(ILLEGAL_COOKIE_CHARS_RE) &&=0A= !value.match(ILLEGAL_COOKIE_CHARS_RE)),=0A= 'trying to set an invalid cookie');=0A= =0A= if (!IsDefined(opt_max_age)) opt_max_age =3D -1;=0A= if (!IsDefined(opt_path)) opt_path =3D '/';=0A= if (!IsDefined(opt_domain)) opt_domain =3D null;=0A= =0A= var domain_str =3D (opt_domain =3D=3D null) ? '' : ';domain=3D' + = opt_domain;=0A= var path_str =3D (opt_path =3D=3D null) ? '' : ';path=3D' + opt_path;=0A= =0A= var expires_str;=0A= =0A= // Case 1: Set a session cookie.=0A= if (opt_max_age < 0) {=0A= expires_str =3D '';=0A= =0A= // Case 2: Expire the cookie.=0A= // Note: We don't tell people about this option in the function doc = because=0A= // we prefer people to use ExpireCookie() to expire cookies.=0A= } else if (opt_max_age =3D=3D 0) {=0A= // Note: Don't use Jan 1, 1970 for date because NS 4.76 will try to = convert=0A= // it to local time, and if the local time is before Jan 1, 1970, = then the=0A= // browser will ignore the Expires attribute altogether.=0A= var pastDate =3D new Date(1970, 1 /*Feb*/, 1); // Feb 1, 1970=0A= expires_str =3D ';expires=3D' + pastDate.toUTCString();=0A= =0A= // Case 3: Set a persistent cookie.=0A= } else {=0A= var futureDate =3D new Date(Now() + opt_max_age * 1000);=0A= expires_str =3D ';expires=3D' + futureDate.toUTCString();=0A= }=0A= =0A= document.cookie =3D name + '=3D' + value + domain_str + path_str + = expires_str;=0A= }=0A= =0A= var EXPIRED_COOKIE_VALUE =3D 'EXPIRED';=0A= =0A= /**=0A= * Expires a cookie.=0A= *=0A= * @param name The cookie name.=0A= * @param opt_path The path of the cookie, or null to expire a cookie = set at=0A= * the full request path. If not provided, the default is '/' (i.e. = path=3D/).=0A= * @param opt_domain The domain of the cookie, or null to expire a = cookie set=0A= * at the full request host name. If not provided, the default is null = (i.e.=0A= * cookie at full request host name).=0A= * @return Void.=0A= */=0A= function ExpireCookie(name, opt_path, opt_domain) {=0A= SetCookie(name, EXPIRED_COOKIE_VALUE, 0, opt_path, opt_domain);=0A= }=0A= =0A= /** Returns the value for the first cookie with the given name=0A= * @param name : string=0A= * @return a string or the empty string if no cookie found.=0A= */=0A= function GetCookie(name) {=0A= var nameeq =3D name + "=3D";=0A= var cookie =3D String(document.cookie);=0A= for (var pos =3D -1; (pos =3D cookie.indexOf(nameeq, pos + 1)) >=3D = 0;) {=0A= var i =3D pos;=0A= // walk back along string skipping whitespace and looking for a ; = before=0A= // the name to make sure that we don't match cookies whose name = contains=0A= // the given name as a suffix.=0A= while (--i >=3D 0) {=0A= var ch =3D cookie.charAt(i);=0A= if (ch =3D=3D ';') {=0A= i =3D -1; // indicate success=0A= break;=0A= } else if (' \t'.indexOf(ch) < 0) {=0A= break;=0A= }=0A= }=0A= if (-1 =3D=3D=3D i) { // first cookie in the string or we found a ;=0A= var end =3D cookie.indexOf(';', pos);=0A= if (end < 0) { end =3D cookie.length; }=0A= return cookie.substring(pos + nameeq.length, end);=0A= }=0A= }=0A= return "";=0A= }=0A= =0A= =0A= //-----------------------------------------------------------------------= -=0A= // Time=0A= //-----------------------------------------------------------------------= -=0A= function Now() {=0A= return (new Date()).getTime();=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Dynamic HTML/DOM utilities=0A= //-----------------------------------------------------------------------= -=0A= // Gets a element by its id, may return null=0A= function MaybeGetElement(win, id) {=0A= return win.document.getElementById(id);=0A= }=0A= =0A= // Same as MaybeGetElement except that it throws an exception if it's = null=0A= function GetElement(win, id) {=0A= var el =3D win.document.getElementById(id);=0A= if (!el) {=0A= DumpError("Element " + id + " not found.");=0A= }=0A= return el;=0A= }=0A= =0A= // Gets elements by its id/name=0A= // IE treats getElementsByName as searching over ids, while Moz use = names.=0A= // so tags must have both id and name as the same string=0A= function GetElements(win, id) {=0A= return win.document.getElementsByName(id);=0A= }=0A= =0A= // Gets the parent of a html element.=0A= function GetParentNode(n) {=0A= try {=0A= return n.parentNode;=0A= } catch (e) {=0A= // n.parentNode may throw a permission-denied exception on mozilla=0A= // (e.g. on text element), ignore this exception.=0A= return n;=0A= }=0A= }=0A= =0A= function IsDescendant(parent, child) {=0A= do {=0A= if (parent =3D=3D=3D child) return true;=0A= child =3D GetParentNode(child);=0A= } while (child && child !=3D=3D document.body);=0A= return false;=0A= }=0A= =0A= // Get attribute value of a DOM node=0A= function GetAttribute(node, attribute) {=0A= if (!node.getAttribute) {=0A= return null;=0A= }=0A= var attr =3D node.getAttribute(attribute);=0A= if (is_ie && attribute =3D=3D "style") {=0A= return attr.value;=0A= } else {=0A= return attr;=0A= }=0A= }=0A= =0A= // Sets inner html of a html element=0A= function SetInnerHTML(win, id, html) {=0A= try {=0A= GetElement(win, id).innerHTML =3D html;=0A= } catch (ex) {=0A= DumpException(ex);=0A= }=0A= }=0A= =0A= // Gets inner-html of a html element=0A= function GetInnerHTML(win, id) {=0A= try {=0A= return GetElement(win, id).innerHTML;=0A= } catch (ex) {=0A= DumpException(ex);=0A= return "";=0A= }=0A= }=0A= =0A= // Clears inner html of a html element=0A= function ClearInnerHTML(win, id) {=0A= try {=0A= GetElement(win, id).innerHTML =3D "";=0A= } catch (ex) {=0A= DumpException(ex);=0A= }=0A= }=0A= =0A= // Sets a CSS style of an element=0A= function SetCssStyle(win, id, name, value) {=0A= try {=0A= var elem =3D GetElement(win, id);=0A= elem.style[name] =3D value;=0A= } catch (ex) {=0A= DumpException(ex);=0A= }=0A= }=0A= =0A= // Get CSS property from a style attribute string=0A= function GetStyleProperty(style, name) {=0A= var i =3D style.indexOf(name);=0A= if (i !=3D -1) {=0A= var j =3D style.indexOf(";", i);=0A= if (j =3D=3D -1) {=0A= j =3D style.length;=0A= }=0A= // the +1 below is for the colon following the attribute name=0A= return CollapseWhitespace(style.substring(i + name.length + 1, j));=0A= }=0A= return null;=0A= }=0A= =0A= // Show/hide an element.=0A= function ShowElement(el, show) {=0A= el.style.display =3D show ? "" : "none";=0A= }=0A= =0A= // Show/hide a block element.=0A= // ShowElement() doesn't work if object has an initial class with = display:none=0A= function ShowBlockElement(el, show) {=0A= el.style.display =3D show ? "block" : "none";=0A= }=0A= =0A= // Show/hide an inline element.=0A= // ShowElement() doesn't work when an element starts off display:none.=0A= function ShowInlineElement(el, show) {=0A= el.style.display =3D show ? "inline" : "none";=0A= }=0A= =0A= // Set the text of a button. This is to get around a bug in mozilla,=0A= // where we can't set the text of a button by setting innerHTML.=0A= function SetButtonText(button, text) {=0A= button.childNodes[0].nodeValue =3D text;=0A= }=0A= =0A= // Append a new HTML element to a HTML node.=0A= function AppendNewElement(win, parent, tag) {=0A= var e =3D win.document.createElement(tag);=0A= parent.appendChild(e);=0A= return e;=0A= }=0A= =0A= // Finds the child with the given ID, or null if there is node.=0A= // This does not search the children's children.=0A= function FindChildWithID(parent, id) {=0A= var el;=0A= for (el =3D parent.firstChild; el && el.id !=3D id; el =3D = el.nextSibling) {=0A= // skip=0A= }=0A= return el;=0A= }=0A= =0A= // Adds a disabled option to the given menu=0A= function AddMenuDisabledOption(win, menu, html) {=0A= var op =3D AppendNewElement(win, menu, 'OPTION');=0A= op.disabled =3D true;=0A= op.innerHTML =3D html;=0A= =0A= return op;=0A= }=0A= =0A= // Adds a option to the given menu=0A= function AddMenuOption(win, menu, value, html) {=0A= var op =3D AppendNewElement(win, menu, 'OPTION');=0A= op.value =3D value;=0A= op.innerHTML =3D html;=0A= =0A= return op;=0A= }=0A= =0A= // Create a new DIV (append it to the end of the document)=0A= function CreateDIV(win, id) {=0A= var div =3D MaybeGetElement(win, id);=0A= if (!div) {=0A= div =3D AppendNewElement(win, win.document.body, "div");=0A= div.id =3D id;=0A= }=0A= return div;=0A= }=0A= =0A= // Create a new IFRAME (append it to the end of the document)=0A= function CreateIFRAME(win, id, url) {=0A= var iframe =3D MaybeGetElement(win, id);=0A= if (!iframe) {=0A= // We cannot create an IFRAME directly (IE doesn't allow it), so we=0A= // create a DIV and then insert an IFRAME.=0A= // We also give the IFRAME a name (same as id)=0A= var div =3D AppendNewElement(win, win.document.body, "div");=0A= div.innerHTML =3D "";=0A= iframe =3D GetElement(win, id);=0A= }=0A= return iframe;=0A= }=0A= =0A= // Create a new TR containing the given td's=0A= function Tr(win, tds) {=0A= var tr =3D win.document.createElement("TR");=0A= for (var i =3D 0; i < tds.length; i++) {=0A= tr.appendChild(tds[i]);=0A= }=0A= return tr;=0A= }=0A= =0A= // Create a new TD, with an optional colspan=0A= function Td(win, opt_colspan) {=0A= var td =3D win.document.createElement("TD");=0A= if (opt_colspan) {=0A= td.colSpan =3D opt_colspan;=0A= }=0A= return td;=0A= }=0A= =0A= =0A= // Check if an element has a given class=0A= function HasClass(el, cl) {=0A= if (el =3D=3D null || el.className =3D=3D null) return false;=0A= var classes =3D el.className.split(" ");=0A= for (var i =3D 0; i < classes.length; i++) {=0A= if (classes[i] =3D=3D cl) {=0A= return true;=0A= }=0A= }=0A= return false;=0A= }=0A= =0A= // Add a class to element=0A= function AddClass(el, cl) {=0A= if (HasClass(el, cl)) return;=0A= el.className +=3D " " + cl;=0A= }=0A= =0A= // Remove a class from an element=0A= function RemoveClass(el, cl) {=0A= if (el.className =3D=3D null) return;=0A= var classes =3D el.className.split(" ");=0A= var result =3D [];=0A= var changed =3D false;=0A= for (var i =3D 0; i < classes.length; i++) {=0A= if (classes[i] !=3D cl) {=0A= if (classes[i]) { result.push(classes[i]); }=0A= } else {=0A= changed =3D true;=0A= }=0A= }=0A= if (changed) { el.className =3D result.join(" "); }=0A= }=0A= =0A= // Performs an in-order traversal of the tree rooted at the given node=0A= // (excluding the root node) and returns an array of nodes that match the=0A= // given selector. The selector must implement the method:=0A= //=0A= // boolean select(node);=0A= //=0A= // This method is a generalization of the DOM method = "getElementsByTagName"=0A= //=0A= function GetElementsBySelector(root, selector) {=0A= var nodes =3D [];=0A= for (var child =3D root.firstChild; child; child =3D = child.nextSibling) {=0A= AddElementBySelector_(child, selector, nodes);=0A= }=0A= return nodes;=0A= }=0A= =0A= // Recursive helper for GetElemnetsBySelector()=0A= function AddElementBySelector_(root, selector, nodes) {=0A= // First test the parent=0A= if (selector.select(root)) {=0A= nodes.push(root);=0A= }=0A= =0A= // Then recurse through the children=0A= for (var child =3D root.firstChild; child; child =3D = child.nextSibling) {=0A= AddElementBySelector_(child, selector, nodes);=0A= }=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Window/screen utilities=0A= // TODO: these should be renamed (e.g. GetWindowWidth to = GetWindowInnerWidth=0A= // and moved to geom.js)=0A= //-----------------------------------------------------------------------= -=0A= // Get page offset of an element=0A= function GetPageOffsetLeft(el) {=0A= var x =3D el.offsetLeft;=0A= if (el.offsetParent !=3D null)=0A= x +=3D GetPageOffsetLeft(el.offsetParent);=0A= return x;=0A= }=0A= =0A= // Get page offset of an element=0A= function GetPageOffsetTop(el) {=0A= var y =3D el.offsetTop;=0A= if (el.offsetParent !=3D null)=0A= y +=3D GetPageOffsetTop(el.offsetParent);=0A= return y;=0A= }=0A= =0A= // Get page offset of an element=0A= function GetPageOffset(el) {=0A= var x =3D el.offsetLeft;=0A= var y =3D el.offsetTop;=0A= if (el.offsetParent !=3D null) {=0A= var pos =3D GetPageOffset(el.offsetParent);=0A= x +=3D pos.x;=0A= y +=3D pos.y;=0A= }=0A= return {x: x, y: y};=0A= }=0A= =0A= function GetPageOffsetRight(el) {=0A= return GetPageOffsetLeft(el) + el.offsetWidth;=0A= }=0A= =0A= function GetPageOffsetBottom(el) {=0A= return GetPageOffsetTop(el) + el.offsetHeight;=0A= }=0A= =0A= // Get the y position scroll offset.=0A= function GetScrollTop(win) {=0A= // all except Explorer=0A= if ("pageYOffset" in win) {=0A= return win.pageYOffset;=0A= }=0A= // Explorer 6 Strict Mode=0A= else if ("documentElement" in win.document &&=0A= "scrollTop" in win.document.documentElement) {=0A= return win.document.documentElement.scrollTop;=0A= }=0A= // other Explorers=0A= else if ("scrollTop" in win.document.body) {=0A= return win.document.body.scrollTop;=0A= }=0A= =0A= return 0;=0A= }=0A= =0A= // Get the x position scroll offset.=0A= function GetScrollLeft(win) {=0A= // all except Explorer=0A= if ("pageXOffset" in win) {=0A= return win.pageXOffset;=0A= }=0A= // Explorer 6 Strict Mode=0A= else if ("documentElement" in win.document &&=0A= "scrollLeft" in win.document.documentElement) {=0A= return win.document.documentElement.scrollLeft;=0A= }=0A= // other Explorers=0A= else if ("scrollLeft" in win.document.body) {=0A= return win.document.body.scrollLeft;=0A= }=0A= =0A= return 0;=0A= }=0A= =0A= /**=0A= * Checks if window scrollbar has reached its maximum offset=0A= *=0A= * @param win a window object=0A= * @param opt_isHoriz true if horizontal bar, false if vertical=0A= */=0A= function IsScrollAtEnd(win, opt_isHoriz) {=0A= var total =3D=0A= (opt_isHoriz) ? document.body.offsetWidth : = document.body.offsetHeight;=0A= var inner =3D=0A= (opt_isHoriz) ? GetWindowWidth(win) : GetWindowHeight(win);=0A= var offset =3D=0A= (opt_isHoriz) ? GetScrollLeft(win) : GetScrollTop(win);=0A= =0A= return (inner + offset >=3D total || total < inner);=0A= }=0A= =0A= // Scroll window to pos=0A= // position: 0 =3D top, 0.5 =3D middle, 1 =3D bottom=0A= function ScrollTo(win, el, position) {=0A= var y =3D GetPageOffsetTop(el);=0A= y -=3D GetWindowHeight(win) * position;=0A= win.scrollTo(0, y);=0A= }=0A= =0A= // Scroll so that as far as possible the entire element is in view.=0A= var ALIGN_BOTTOM =3D 'b';=0A= var ALIGN_MIDDLE =3D 'm';=0A= var ALIGN_TOP =3D 't';=0A= function ScrollIntoView(win, el, alignment) {=0A= var el_top =3D GetPageOffsetTop(el);=0A= var el_bottom =3D el_top + el.offsetHeight;=0A= var win_top =3D GetScrollTop(win);=0A= var win_height =3D GetWindowHeight(win);=0A= var win_bottom =3D win_top + win_height;=0A= =0A= // Out of view?=0A= if (el_top < win_top ||=0A= el_bottom > win_bottom) {=0A= =0A= var scrollto_y;=0A= if (alignment =3D=3D ALIGN_BOTTOM) {=0A= scrollto_y =3D el_bottom - win_height + 5;=0A= } else if (alignment =3D=3D ALIGN_MIDDLE) {=0A= scrollto_y =3D (el_top + el_bottom) / 2 - win_height/2;=0A= } else {=0A= scrollto_y =3D el_top - 5; // ALIGN_TOP=0A= }=0A= =0A= Debug("Scrolling to " + scrollto_y);=0A= win.scrollTo(0, scrollto_y);=0A= }=0A= }=0A= =0A= function IsElementVisible(win, id) {=0A= var el =3D MaybeGetElement(win, id);=0A= if (el =3D=3D null) {=0A= return false;=0A= }=0A= var el_top =3D GetPageOffsetTop(el);=0A= var el_bottom =3D el_top + el.offsetHeight;=0A= var win_top =3D GetScrollTop(win);=0A= var win_bottom =3D win_top + GetWindowHeight(win);=0A= if (el_top >=3D win_top && el_bottom <=3D win_bottom) {=0A= return true;=0A= }=0A= return false;=0A= }=0A= =0A= function GetWindowWidth(win) {=0A= // all except Explorer=0A= if ("innerWidth" in win) {=0A= return win.innerWidth;=0A= }=0A= // Explorer 6 Strict Mode=0A= else if ("documentElement" in win.document &&=0A= "clientWidth" in win.document.documentElement) {=0A= return win.document.documentElement.clientWidth;=0A= }=0A= // other Explorers=0A= else if ("clientWidth" in win.document.body) {=0A= return win.document.body.clientWidth;=0A= }=0A= =0A= return 0;=0A= }=0A= =0A= function GetWindowHeight(win) {=0A= // all except Explorer=0A= if ("innerHeight" in win) {=0A= return win.innerHeight;=0A= }=0A= // Explorer 6 Strict Mode=0A= else if ("documentElement" in win.document &&=0A= "clientHeight" in win.document.documentElement) {=0A= return win.document.documentElement.clientHeight;=0A= }=0A= // other Explorers=0A= else if ("clientHeight" in win.document.body) {=0A= return win.document.body.clientHeight;=0A= }=0A= =0A= return 0;=0A= }=0A= =0A= function GetAvailScreenWidth(win) {=0A= return win.screen.availWidth;=0A= }=0A= =0A= function GetAvailScreenHeight(win) {=0A= return win.screen.availHeight;=0A= }=0A= =0A= // Returns a "nice" window height.=0A= // Use the screen height. (Or should we use the height of the current = window?)=0A= function GetNiceWindowHeight(win) {=0A= return Math.floor(0.8 * GetAvailScreenHeight(win));=0A= }=0A= =0A= // Used for horizontally centering a new window of the given width in the=0A= // available screen. Set the new window's distance from the left of the = screen=0A= // equal to this function's return value.=0A= // Params: width: the width of the new window=0A= // Returns: the distance from the left edge of the screen for the new = window to=0A= // be horizontally centered=0A= function GetCenteringLeft(win, width) {=0A= return (win.screen.availWidth - width) >> 1;=0A= }=0A= =0A= // Used for vertically centering a new window of the given height in the=0A= // available screen. Set the new window's distance from the top of the = screen=0A= // equal to this function's return value.=0A= // Params: height: the height of the new window=0A= // Returns: the distance from the top edge of the screen for the new = window to=0A= // be vertically aligned.=0A= function GetCenteringTop(win, height) {=0A= return (win.screen.availHeight - height) >> 1;=0A= }=0A= =0A= /*=0A= * Opens a child popup window that has no browser toolbar/decorations.=0A= * (Copied from caribou's common.js library with small modifications.)=0A= *=0A= * @param url the URL for the new window (Note: this will be = unique-ified)=0A= * @param opt_name the name of the new window=0A= * @param opt_width the width of the new window=0A= * @param opt_height the height of the new window=0A= * @param opt_center if true, the new window is centered in the = available screen=0A= * @param opt_hide_scrollbars if true, the window hides the scrollbars=0A= * @param opt_noresize if true, makes window unresizable=0A= * @param opt_blocked_msg message warning that the popup has been blocked=0A= * @return a reference to the new child window=0A= */=0A= function Popup(url, opt_name, opt_width, opt_height, opt_center,=0A= opt_hide_scrollbars, opt_noresize, opt_blocked_msg) {=0A= if (!opt_height) {=0A= opt_height =3D Math.floor(GetWindowHeight(window.top) * 0.8);=0A= }=0A= if (!opt_width) {=0A= opt_width =3D Math.min(GetAvailScreenWidth(window), opt_height);=0A= }=0A= =0A= var features =3D "resizable=3D" + (opt_noresize ? "no" : "yes") + "," +=0A= "scrollbars=3D" + (opt_hide_scrollbars ? "no" : "yes") = + "," +=0A= "width=3D" + opt_width + ",height=3D" + opt_height;=0A= if (opt_center) {=0A= features +=3D ",left=3D" + GetCenteringLeft(window, opt_width) + "," = +=0A= "top=3D" + GetCenteringTop(window, opt_height);=0A= }=0A= return OpenWindow(window, url, opt_name, features, opt_blocked_msg);=0A= }=0A= =0A= /*=0A= * Opens a new window. Returns the new window handle. Tries to open the = new=0A= * window using top.open() first. If that doesn't work, then tries = win.open().=0A= * If that still doesn't work, prints an alert.=0A= * (Copied from caribou's common.js library with small modifications.)=0A= *=0A= * @param win the parent window from which to open the new child window=0A= * @param url the URL for the new window (Note: this will be = unique-ified)=0A= * @param opt_name the name of the new window=0A= * @param opt_features the properties of the new window=0A= * @param opt_blocked_msg message warning that the popup has been blocked=0A= * @return a reference to the new child window=0A= */=0A= function OpenWindow(win, url, opt_name, opt_features, opt_blocked_msg) {=0A= var newwin =3D OpenWindowHelper(top, url, opt_name, opt_features);=0A= if (!newwin || newwin.closed || !newwin.focus) {=0A= newwin =3D OpenWindowHelper(win, url, opt_name, opt_features);=0A= }=0A= if (!newwin || newwin.closed || !newwin.focus) {=0A= if (opt_blocked_msg) alert(opt_blocked_msg);=0A= } else {=0A= // Make sure that the window has the focus=0A= newwin.focus();=0A= }=0A= return newwin;=0A= }=0A= =0A= /*=0A= * Helper for OpenWindow().=0A= * (Copied from caribou's common.js library with small modifications.)=0A= */=0A= function OpenWindowHelper(win, url, name, features) {=0A= var newwin;=0A= if (features) {=0A= newwin =3D win.open(url, name, features);=0A= } else if (name) {=0A= newwin =3D win.open(url, name);=0A= } else {=0A= newwin =3D win.open(url);=0A= }=0A= return newwin;=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // DOM walking utilities=0A= //-----------------------------------------------------------------------= -=0A= =0A= function MaybeEscape(str, escape) {=0A= return escape ? HtmlEscape(str) : str;=0A= }=0A= =0A= =0A= //-----------------------------------------------------------------------= -=0A= // Window data=0A= //-----------------------------------------------------------------------= -=0A= // Gets an array, which can store data for the window. This data=0A= // is deleted when the window is unloaded.=0A= var windata =3D [];=0A= function GetWindowData(win) {=0A= var data =3D windata[win.name];=0A= if (!data) {=0A= windata[win.name] =3D data =3D [];=0A= }=0A= return data;=0A= }=0A= =0A= // Clear js data for a window.=0A= function ClearWindowData(win_name) {=0A= if (windata[win_name]) {=0A= windata[win_name] =3D null;=0A= }=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // String utilities=0A= //-----------------------------------------------------------------------= -=0A= // Do html escaping=0A= var amp_re_ =3D /&/g;=0A= var lt_re_ =3D //g;=0A= =0A= // Convert text to HTML format. For efficiency, we just convert '&', = '<', '>'=0A= // characters.=0A= // Note: Javascript >=3D 1.3 supports lambda expression in the = replacement=0A= // argument. But it's slower on IE.=0A= // Note: we can also implement HtmlEscape by setting the value=0A= // of a textnode and then reading the 'innerHTML' value, but that=0A= // that turns out to be slower.=0A= // Params: str: String to be escaped.=0A= // Returns: The escaped string.=0A= function HtmlEscape(str) {=0A= if (!str) return "";=0A= return str.replace(amp_re_, "&").replace(lt_re_, "<").=0A= replace(gt_re_, ">").replace(quote_re_, """);=0A= }=0A= =0A= /** converts html entities to plain text. It covers the most common = named=0A= * entities and numeric entities.=0A= * It does not cover all named entities -- it covers = &{lt,gt,amp,quot,nbsp}; but=0A= * does not handle some of the more obscure ones like &{ndash,eacute};.=0A= */=0A= function HtmlUnescape(str) {=0A= if (!str) return "";=0A= return str.=0A= replace(/&#(\d+);/g,=0A= function (_, n) { return String.fromCharCode(parseInt(n, 10)); }).=0A= replace(/&#x([a-f0-9]+);/gi,=0A= function (_, n) { return String.fromCharCode(parseInt(n, 16)); }).=0A= replace(/&(\w+);/g, function (_, entity) {=0A= entity =3D entity.toLowerCase();=0A= return entity in HtmlUnescape.unesc ? HtmlUnescape.unesc[entity] : = '?';=0A= });=0A= }=0A= HtmlUnescape.unesc =3D { lt: '<', gt: '>', quot: '"', nbsp: ' ', amp: = '&' };=0A= =0A= // Replace multiple spaces with   to retain whitespace formatting=0A= // in addition to escaping '&', '<', and '>'.=0A= var dbsp_re_ =3D / /g;=0A= var ret_re_ =3D /\r/g;=0A= var nl_re_ =3D /\n/g;=0A= function HtmlWhitespaceEscape(str) {=0A= str =3D HtmlEscape(str);=0A= str =3D str.replace(dbsp_re_, "  ");=0A= str =3D str.replace(ret_re_, "");=0A= str =3D str.replace(nl_re_, "
");=0A= return str;=0A= }=0A= =0A= // Escape double quote '"' characters in addition to '&', '<', '>' so = that a=0A= // string can be included in an HTML tag attribute value within double = quotes.=0A= // Params: str: String to be escaped.=0A= // Returns: The escaped string.=0A= var quote_re_ =3D /\"/g;=0A= function QuoteEscape(str) {=0A= return HtmlEscape(str).replace(quote_re_, """);=0A= }=0A= =0A= var JS_SPECIAL_RE_ =3D /[\'\\\r\n\b\"<>&]/g;=0A= =0A= function JSEscOne_(s) {=0A= if (!JSEscOne_.js_escs_) {=0A= var escapes =3D {};=0A= escapes['\\'] =3D '\\\\';=0A= escapes['\''] =3D '\\047';=0A= escapes['\n'] =3D '\\n';=0A= escapes['\r'] =3D '\\r';=0A= escapes['\b'] =3D '\\b';=0A= escapes['\"'] =3D '\\042';=0A= escapes['<'] =3D '\\074';=0A= escapes['>'] =3D '\\076';=0A= escapes['&'] =3D '\\046';=0A= =0A= JSEscOne_.js_escs_ =3D escapes;=0A= }=0A= =0A= return JSEscOne_.js_escs_[s];=0A= }=0A= =0A= /** convert a string to a javascript string literal. This function has = the=0A= * property that the return value is also already html escaped, so the = output=0A= * can be embedded in an html handler attribute.=0A= */=0A= function ToJSString(s) {=0A= return "'" + s.toString().replace(JS_SPECIAL_RE_, JSEscOne_) + "'";=0A= }=0A= =0A= // converts multiple ws chars to a single space, and strips=0A= // leading and trailing ws=0A= var spc_re_ =3D /\s+/g;=0A= var beg_spc_re_ =3D /^ /;=0A= var end_spc_re_ =3D / $/;=0A= function CollapseWhitespace(str) {=0A= if (!str) return "";=0A= return str.replace(spc_re_, " ").replace(beg_spc_re_, "").=0A= replace(end_spc_re_, "");=0A= }=0A= =0A= var newline_re_ =3D /\r?\n/g;=0A= var spctab_re_ =3D /[ \t]+/g;=0A= var nbsp_re_ =3D /\xa0/g;=0A= function StripNewlines(str) {=0A= if (!str) return "";=0A= return str.replace(newline_re_, " ");=0A= }=0A= =0A= function CanonicalizeNewlines(str) {=0A= if (!str) return "";=0A= return str.replace(newline_re_, '\n');=0A= }=0A= =0A= function HtmlifyNewlines(str) {=0A= if (!str) return "";=0A= return str.replace(newline_re_, "
");=0A= }=0A= =0A= function NormalizeSpaces(str) {=0A= if (!str) return "";=0A= return str.replace(spctab_re_, " ").replace(nbsp_re_, " ");=0A= }=0A= =0A= // URL encodes the string.=0A= function UrlEncode(str) {=0A= return encodeURIComponent(str);=0A= }=0A= =0A= function Trim(str) {=0A= if (!str) return "";=0A= return str.replace(/^\s+/, "").replace(/\s+$/, "");=0A= }=0A= =0A= function EndsWith(str, suffix) {=0A= if (!str) return !suffix;=0A= return (str.lastIndexOf(suffix) =3D=3D (str.length - suffix.length));=0A= }=0A= =0A= // Check if a string is empty=0A= function IsEmpty(str) {=0A= return CollapseWhitespace(str) =3D=3D "";=0A= }=0A= =0A= // Check if a character is a letter=0A= function IsLetterOrDigit(ch) {=0A= return ((ch >=3D "a" && ch <=3D "z") ||=0A= (ch >=3D "A" && ch <=3D "Z") ||=0A= (ch >=3D '0' && ch <=3D '9'));=0A= }=0A= =0A= // Check if a character is a space character=0A= function IsSpace(ch) {=0A= return (" \t\r\n".indexOf(ch) >=3D 0);=0A= }=0A= =0A= // Converts any instances of "\r" or "\r\n" style EOLs into "\n" (Line = Feed),=0A= // and also trim the extra newlines and whitespaces at the end.=0A= var eol_re_ =3D /\r\n?/g;=0A= var trailingspc_re_ =3D /[\n\t ]+$/;=0A= function NormalizeText(str) {=0A= return str.replace(eol_re_, "\n").replace(trailingspc_re_, "");=0A= }=0A= =0A= // Inserts s (word break tag) after every n non-space chars and/or=0A= // after or before certain special chars. The input string should be = plain=0A= // text that has not yet been HTML-escaped.=0A= // Params:=0A= // str: The string to insert s into.=0A= // n: The maximum number of consecutive non-space characters to allow = before=0A= // adding a . To turn off this rule (i.e. if you only want to = add=0A= // breaks based on special characters), pass in the value -1.=0A= // chars_to_break_after: The list of special characters (concatenated = into a=0A= // string) after which a should be added, if there is no = natural=0A= // break at that point. To turn off this rule, pass in the empty = string.=0A= // chars_to_break_before: The list of special characters (concatenated = into a=0A= // string) before which a should be added, if there is no = natural=0A= // break at that point. To turn off this rule, pass in the empty = string.=0A= // Returns: The string str htmlescaped, and with s inserted = according to=0A= // the rules specified by the other arguments.=0A= function HtmlEscapeInsertWbrs(str, n, chars_to_break_after,=0A= chars_to_break_before) {=0A= AssertNumArgs(4);=0A= =0A= var out =3D '';=0A= var strpos =3D 0;=0A= var spc =3D 0;=0A= =0A= for (var i =3D 1; i < str.length; ++i) {=0A= var prev_char =3D str.charAt(i - 1);=0A= var next_char =3D str.charAt(i);=0A= if (IsSpace(next_char)) {=0A= spc =3D i;=0A= } else if (i - spc =3D=3D n ||=0A= chars_to_break_after.indexOf(prev_char) !=3D -1 ||=0A= chars_to_break_before.indexOf(next_char) !=3D -1) {=0A= out +=3D HtmlEscape(str.substring(strpos, i)) + '';=0A= strpos =3D i;=0A= spc =3D i;=0A= }=0A= }=0A= out +=3D HtmlEscape(str.substr(strpos));=0A= return out;=0A= }=0A= =0A= // Converts a string to its canonicalized label form.=0A= var illegal_chars_re_ =3D /[ \/(){}&|\\\"\000]/g;=0A= function CanonicalizeLabel(str, lowercase) {=0A= var uppercase =3D str.replace(illegal_chars_re_, '-');=0A= return lowercase ? uppercase.toLowerCase() : uppercase;=0A= }=0A= =0A= // Case-insensitive string comparator=0A= function CompareStringsIgnoreCase(s1, s2) {=0A= s1 =3D s1.toLowerCase();=0A= s2 =3D s2.toLowerCase();=0A= =0A= if (s1 < s2) {=0A= return -1;=0A= } else if (s1 =3D=3D s2) {=0A= return 0;=0A= } else {=0A= return 1;=0A= }=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // TextArea utilities=0A= //-----------------------------------------------------------------------= -=0A= =0A= // Gets the cursor pos in a text area. Returns -1 if the cursor pos = cannot=0A= // be determined or if the cursor out of the textfield.=0A= function GetCursorPos(win, textfield) {=0A= try {=0A= if (IsDefined(textfield.selectionEnd)) {=0A= // Mozilla directly supports this=0A= return textfield.selectionEnd;=0A= =0A= } else if (win.document.selection && = win.document.selection.createRange) {=0A= // IE doesn't export an accessor for the endpoints of a selection.=0A= // Instead, it uses the TextRange object, which has an extremely = obtuse=0A= // API. Here's what seems to work:=0A= =0A= // (1) Obtain a textfield from the current selection (cursor)=0A= var tr =3D win.document.selection.createRange();=0A= =0A= // Check if the current selection is in the textfield=0A= if (tr.parentElement() !=3D textfield) {=0A= return -1;=0A= }=0A= =0A= // (2) Make a text range encompassing the textfield=0A= var tr2 =3D tr.duplicate();=0A= tr2.moveToElementText(textfield);=0A= =0A= // (3) Move the end of the copy to the beginning of the selection=0A= tr2.setEndPoint("EndToStart", tr);=0A= =0A= // (4) The span of the textrange copy is equivalent to the cursor = pos=0A= var cursor =3D tr2.text.length;=0A= =0A= // Finally, perform a sanity check to make sure the cursor is in = the=0A= // textfield. IE sometimes screws this up when the window is = activated=0A= if (cursor > textfield.value.length) {=0A= return -1;=0A= }=0A= return cursor;=0A= } else {=0A= Debug("Unable to get cursor position for: " + navigator.userAgent);=0A= =0A= // Just return the size of the textfield=0A= // TODO: Investigate how to get cursor pos in Safari!=0A= return textfield.value.length;=0A= }=0A= } catch (e) {=0A= DumpException(e, "Cannot get cursor pos");=0A= }=0A= =0A= return -1;=0A= }=0A= =0A= function SetCursorPos(win, textfield, pos) {=0A= if (IsDefined(textfield.selectionEnd) &&=0A= IsDefined(textfield.selectionStart)) {=0A= // Mozilla directly supports this=0A= textfield.selectionStart =3D pos;=0A= textfield.selectionEnd =3D pos;=0A= =0A= } else if (win.document.selection && textfield.createTextRange) {=0A= // IE has textranges. A textfield's textrange encompasses the=0A= // entire textfield's text by default=0A= var sel =3D textfield.createTextRange();=0A= =0A= sel.collapse(true);=0A= sel.move("character", pos);=0A= sel.select();=0A= }=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Array utilities=0A= //-----------------------------------------------------------------------= -=0A= // Find an item in an array, returns the key, or -1 if not found=0A= function FindInArray(array, x) {=0A= for (var i =3D 0; i < array.length; i++) {=0A= if (array[i] =3D=3D x) {=0A= return i;=0A= }=0A= }=0A= return -1;=0A= }=0A= =0A= // Inserts an item into an array, if it's not already in the array=0A= function InsertArray(array, x) {=0A= if (FindInArray(array, x) =3D=3D -1) {=0A= array[array.length] =3D x;=0A= }=0A= }=0A= =0A= // Delete an element from an array=0A= function DeleteArrayElement(array, x) {=0A= var i =3D 0;=0A= while (i < array.length && array[i] !=3D x)=0A= i++;=0A= array.splice(i, 1);=0A= }=0A= =0A= // Copies a flat array=0A= function CopyArray(array) {=0A= var copy =3D [];=0A= for (var i =3D 0; i < array.length; i++) {=0A= copy[i] =3D array[i];=0A= }=0A= return copy;=0A= }=0A= =0A= // Clone an object (recursively)=0A= function CloneObject(x) {=0A= if ((typeof x) =3D=3D "object") {=0A= var y =3D [];=0A= for (var i in x) {=0A= y[i] =3D CloneObject(x[i]);=0A= }=0A= return y;=0A= }=0A= return x;=0A= }=0A= =0A= /**=0A= * Clone an event; cannot use CloneObject(event)=0A= * because it suffers from infinite recursion.=0A= * Thus, only a subset of the event properties are=0A= * cloned -- if you need others, just add them=0A= * to this function (just don't remove any!)=0A= */=0A= function CloneEvent(ev) {=0A= var clone =3D {};=0A= clone.clientX =3D ev.clientX;=0A= clone.clientY =3D ev.clientY;=0A= clone.pageX =3D ev.pageX;=0A= clone.pageY =3D ev.pageY;=0A= clone.type =3D ev.type;=0A= clone.srcElement =3D ev.srcElement;=0A= clone.target =3D ev.target;=0A= clone.cancelBubble =3D ev.cancelBubble;=0A= clone.explicitOriginalTarget =3D ev.explicitOriginalTarget;=0A= // add more properties here=0A= =0A= return clone;=0A= }=0A= =0A= function GetEventTarget(/*Event*/ ev) {=0A= // Event is not a type in IE; IE uses Object for events=0A= // AssertType(ev, Event, 'arg passed to GetEventTarget not an Event');=0A= return ev.srcElement || ev.target;=0A= }=0A= =0A= /** cancels the event */=0A= // from http://www.quirksmode.org/js/events_order.html=0A= function CancelEvent(/*Event*/ ev) {=0A= if (is_ie) {=0A= ev.cancelBubble =3D true;=0A= } else if (ev.stopPropagation) {=0A= ev.stopPropagation();=0A= }=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Formatting utilities=0A= //-----------------------------------------------------------------------= -=0A= // A simple printf type function that takes in a template array, and a = data=0A= // array. e.g. PrintArray(["a",,"b",,"c"], ["x", "y"]) =3D> axbyc=0A= function PrintArray(array, data) {=0A= // Check that the argument count is correct.=0A= AssertEquals(array.length, data.length * 2 + 1);=0A= =0A= for (var i =3D 0, idx =3D 1; i < data.length; i++, idx +=3D 2) {=0A= array[idx] =3D data[i];=0A= }=0A= return array.join("");=0A= }=0A= =0A= function ImageHtml(url, attributes) {=0A= return "";=0A= }=0A= =0A= // Formats an object id that has two id numbers, eg, foo_3_7=0A= function MakeId3(idprefix, m, n) {=0A= return idprefix + m + "_" + n;=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Email address parsing=0A= //-----------------------------------------------------------------------= -=0A= // Parse an email address of the form "name"
into [name, = address]=0A= function ParseAddress(addr) {=0A= var name =3D "";=0A= var address =3D "";=0A= for (var i =3D 0; i < addr.length;) {=0A= var token =3D GetEmailToken(addr, i);=0A= if (token.charAt(0) =3D=3D '<') {=0A= var end =3D token.indexOf(">");=0A= address =3D token.substring(1, (end !=3D -1) ? end : token.length);=0A= } else if (address =3D=3D "") {=0A= name +=3D token;=0A= }=0A= i +=3D token.length;=0A= }=0A= =0A= // Check if it's a simple email address of the form "jlim@google.com"=0A= if (address =3D=3D "" && name.indexOf("@") !=3D -1) {=0A= address =3D name;=0A= name =3D "";=0A= }=0A= =0A= name =3D CollapseWhitespace(name);=0A= name =3D StripQuotes(name, "'");=0A= name =3D StripQuotes(name, "\"");=0A= address =3D CollapseWhitespace(address);=0A= return [name, address];=0A= }=0A= =0A= // Given an email address, get the address part=0A= function GetAddress(address) {=0A= return ParseAddress(address)[1];=0A= }=0A= =0A= // Get the username part of an email address=0A= function GetAddressUsername(address) {=0A= address =3D GetAddress(address);=0A= var at =3D address.indexOf("@");=0A= return (at =3D=3D -1) ? address : address.substr(0, at);=0A= }=0A= =0A= // Given an email address, get the personal part=0A= function GetPersonal(address) {=0A= return ParseAddress(address)[0];=0A= }=0A= =0A= // Given an address, get a short name=0A= function GetPersonalElseUsername(address) {=0A= var personal =3D GetPersonal(address);=0A= if (personal !=3D "") {=0A= return personal;=0A= } else {=0A= return GetAddressUsername(address);=0A= }=0A= }=0A= =0A= // Strip ' or " chars around a string=0A= function StripQuotes(str, quotechar) {=0A= var len =3D str.length;=0A= if (str.charAt(0) =3D=3D quotechar &&=0A= str.charAt(len - 1) =3D=3D quotechar) {=0A= return str.substring(1, len - 1);=0A= }=0A= return str;=0A= }=0A= =0A= // Convert a string containing list of email addresses into an array=0A= // of strings=0A= function EmailsToArray(str) {=0A= var result =3D [];=0A= var email =3D "";=0A= var token;=0A= =0A= for (var i =3D 0; i < str.length; ) {=0A= token =3D GetEmailToken(str, i);=0A= if (token =3D=3D ",") {=0A= AddEmailAddress(result, email);=0A= email =3D "";=0A= i++;=0A= continue;=0A= }=0A= email +=3D token;=0A= i +=3D token.length;=0A= }=0A= =0A= // Add last=0A= if (email !=3D"" || token =3D=3D ",") {=0A= AddEmailAddress(result, email);=0A= }=0A= return result;=0A= }=0A= =0A= // Get the next token from a position in an address string=0A= var openers_ =3D "\"<([";=0A= var closers_ =3D "\">)]";=0A= function GetEmailToken(str, pos) {=0A= var ch =3D str.charAt(pos);=0A= var p =3D openers_.indexOf(ch);=0A= if (p =3D=3D -1)=0A= return ch;=0A= var end_pos =3D str.indexOf(closers_.charAt(p), pos + 1);=0A= var token =3D (end_pos >=3D 0) ? str.substring(pos, end_pos + 1) :=0A= str.substr(pos);=0A= return token;=0A= }=0A= =0A= // Add an email address to the result array.=0A= function AddEmailAddress(result, email) {=0A= email =3D CleanEmailAddress(email);=0A= result[result.length] =3D email;=0A= }=0A= =0A= // Clean up email address:=0A= // - remove extra spaces=0A= // - Surround name with quotes if it contains special characters=0A= // to check if we need " quotes=0A= // Note: do not use /g in the regular expression, otherwise the=0A= // regular expression cannot be reusable.=0A= var specialchars_re_ =3D /[()<>@,;:\\\".\[\]]/;=0A= =0A= function CleanEmailAddress(str) {=0A= var name_address =3D ParseAddress(str);=0A= var name =3D name_address[0];=0A= var address =3D name_address[1];=0A= =0A= if (name.indexOf("\"") =3D=3D -1) { // If there's no "=0A= var quote_needed =3D specialchars_re_.test(name);=0A= if (quote_needed) {=0A= name =3D "\"" + name + "\"";=0A= }=0A= }=0A= =0A= if (name =3D=3D "")=0A= return address;=0A= else if (address =3D=3D "")=0A= return name;=0A= else=0A= return name + " <" + address + ">";=0A= }=0A= =0A= //-----------------------------------------------------------------------= -=0A= // Misc=0A= //-----------------------------------------------------------------------= -=0A= // Compare long hex strings=0A= function CompareID(a, b) {=0A= if (a.length !=3D b.length) {=0A= return (a.length - b.length);=0A= } else {=0A= return (a < b) ? -1 : (a > b) ? 1 : 0;=0A= }=0A= }=0A= =0A= // Check if a value is defined=0A= function IsDefined(value) {=0A= return (typeof value) !=3D 'undefined';=0A= }=0A= =0A= function GetKeyCode(event) {=0A= var code;=0A= if (event.keyCode) {=0A= code =3D event.keyCode;=0A= } else if (event.which) {=0A= code =3D event.which;=0A= }=0A= return code;=0A= }=0A= =0A= // define a forid function to fetch a DOM node by id.=0A= function forid_1(id) {=0A= return document.getElementById(id);=0A= }=0A= function forid_2(id) {=0A= return document.all[id];=0A= }=0A= =0A= /**=0A= * Fetch an HtmlElement by id.=0A= * DEPRECATED: use $ in dom.js=0A= */=0A= var forid =3D document.getElementById ? forid_1 : forid_2;=0A= =0A= =0A= =0A= function log(msg) {=0A= /* a top level window is its own parent. Use !=3D or else fails on IE = with=0A= * infinite loop.=0A= */=0A= try {=0A= if (window.parent !=3D window && window.parent.log) {=0A= window.parent.log(window.name + '::' + msg);=0A= return;=0A= }=0A= } catch (e) {=0A= // Error: uncaught exception: Permission denied to get property = Window.log=0A= }=0A= var logPane =3D forid('log');=0A= if (logPane) {=0A= var logText =3D '

' + new = Date() +=0A= '' + msg + '

';=0A= logPane.innerHTML =3D logText + logPane.innerHTML;=0A= } else {=0A= window.status =3D msg;=0A= }=0A= }=0A= ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: application/octet-stream Content-Transfer-Encoding: quoted-printable Content-Location: http://www.blogger.com/app/scripts/dom.common.js =0A= // Commonly-used functions, reduced.=0A= =0A= function d(s) {return document.getElementById(s);}=0A= function dE(o,s) {return o.getElementsByTagName(s);}=0A= =0A= /**=0A= * toggleDisplay()=0A= *=0A= * Will toggle the display property of the style object for any=0A= * DOM element or object that supports style as a property.=0A= *=0A= * Warning: This'll wreak havoc if applied to elements. Those=0A= * babies got different types "table-row" | "block" dependant on =0A= * what browser's being used.=0A= *=0A= * Warning: Written in Texas. Yeehaw.=0A= *=0A= * Typical usage:=0A= * toggleDisplay(document.getElementById("foo"));=0A= */=0A= function toggleDisplay(o)=0A= { =0A= var display =3D getStyle(o, "display"); =0A= =0A= if (o.style)=0A= o.style.display =3D=0A= (display !=3D "none") ? "none" : getDisplayStyleByTagName(o);=0A= }=0A= =0A= =0A= function getDisplayStyleByTagName(o)=0A= {=0A= n =3D o.nodeName.toLowerCase(); =0A= return (=0A= n =3D=3D "span"=0A= || n =3D=3D "img"=0A= || n =3D=3D "a"=0A= ) ? "inline" : "block";=0A= }=0A= =0A= =0A= /**=0A= * hideElement()=0A= *=0A= * Hides an element from view.=0A= *=0A= * Typical usage:=0A= * hideElement(getElement("the-id-of-the-element"));=0A= */=0A= function hideElement(o)=0A= {=0A= if (o && o.style) o.style.display =3D "none";=0A= }=0A= =0A= =0A= =0A= /**=0A= * showElement()=0A= *=0A= * Shows an element that was hidden from view.=0A= *=0A= * Typical usage:=0A= * showElement(getElement("the-id-of-the-element"));=0A= */=0A= function showElement(o)=0A= {=0A= =0A= if (o && o.style) o.style.display =3D getDisplayStyleByTagName(o);=0A= }=0A= =0A= =0A= /**=0A= * getElement()=0A= *=0A= * Returns an element by its ID or shows an alert if it can't be found.=0A= *=0A= * Typical usage:=0A= * getElement("the-id-of-the-element");=0A= */=0A= function getElement(id) {=0A= var e =3D d(id);=0A= if (!e) {=0A= alert("Cannot get element: " + id);=0A= }=0A= return e;=0A= }=0A= =0A= /**=0A= * setInnerHTML()=0A= *=0A= * Sets the innerHTML of an element or shows an alert if can't be set.=0A= *=0A= * Typical usage:=0A= * setInnerHTML("the-id-of-the-element");=0A= */=0A= function setInnerHTML(id, html) {=0A= try {=0A= getElement(id).innerHTML =3D html;=0A= } catch (ex) {=0A= alert("Cannot set inner HTML: " + id);=0A= }=0A= }=0A= =0A= =0A= /**=0A= * setCssStyle()=0A= *=0A= * Sets the style of an element by its id or shows an alert if can't be = set.=0A= *=0A= * Typical usage:=0A= * setCssStyle("the-id-of-the-element", "display", "block");=0A= */=0A= function setCssStyle(id, name, value) {=0A= try {=0A= getElement(id).style[name] =3D value;=0A= } catch (ex) {=0A= alert("Cannot set style: " + id);=0A= }=0A= }=0A= =0A= =0A= /**=0A= * getStyle()=0A= *=0A= * Gets the computed style of any object.=0A= *=0A= * WARNING: Produces unexpected results in Safari. To achieve best =0A= * results, explicitly set the style property for that browser when the =0A= * element is rendered.=0A= *=0A= * Typical usage:=0A= * getStyle(object, "display");=0A= */=0A= function getStyle(el, style) {=0A= if (!document.getElementById || !el) return;=0A= =0A= if (document.defaultView=0A= && document.defaultView.getComputedStyle) {=0A= return document.defaultView.=0A= getComputedStyle(el, "").getPropertyValue(style);=0A= } =0A= else if (el.currentStyle) {=0A= return el.currentStyle[style];=0A= } =0A= else { =0A= return el.style.display;=0A= }=0A= }=0A= =0A= /**=0A= * getStyleAttribute()=0A= *=0A= * Returns the style attribute of the specified node.=0A= */=0A= function getStyleAttribute(node) {=0A= if (Detect.IE()) {=0A= return node.getAttribute('style').value;=0A= }else {=0A= return node.getAttribute('style');=0A= }=0A= }=0A= =0A= =0A= /*=0A= * showProps()=0A= *=0A= * Displays all the properties for a given element=0A= */=0A= function showProps(o) {=0A= s=3D""; for (p in o) {=0A= s+=3Dp+": "+o[p]+"\n
";=0A= }=0A= document.write(s);=0A= }=0A= =0A= =0A= =0A= function setIFrameEvent(iframe, eventName, func)=0A= {=0A= if (document.all) {=0A= eval('getIFrameDocument(iframe).on' + eventName + ' =3D func;');=0A= } else {=0A= iframe.contentWindow.addEventListener(eventName, func, true);=0A= }=0A= }=0A= =0A= function setIFrameBody(iframe, strStyle, innerHtml) =0A= {=0A= if (!innerHtml) innerHtml =3D '';=0A= if (innerHtml =3D=3D '' && Detect.IE()) {=0A= innerHtml =3D '
';=0A= }=0A= var doc =3D getIFrameDocument(iframe);=0A= doc.open();=0A= doc.write('' =0A= + innerHtml + '');=0A= doc.close();=0A= }=0A= =0A= =0A= function getIFrameDocument(iframe)=0A= {=0A= if (Detect.IE()) {=0A= return iframe.document;=0A= } else {=0A= return iframe.contentDocument;=0A= }=0A= }=0A= =0A= function getIFrame(strId)=0A= {=0A= if (Detect.IE()) {=0A= return document.frames[strId];=0A= } else {=0A= return document.getElementById(strId);=0A= }=0A= }=0A= =0A= =0A= function createElementandAppend(nodeName, strId, appendTo) {=0A= var el =3D document.createElement(nodeName);=0A= el.setAttribute("id", strId);=0A= if (appendTo) {=0A= appendTo.appendChild(el); =0A= } else {=0A= document.body.appendChild(el); =0A= }=0A= return el; =0A= }=0A= =0A= function createElementandInsertBefore(nodeName, strId, appendTo, = sibling) {=0A= var el =3D document.createElement(nodeName);=0A= el.setAttribute("id", strId);=0A= if (appendTo) {=0A= appendTo.insertBefore(el, sibling); =0A= } else {=0A= document.body.insertBefore(el, sibling); =0A= }=0A= return el; =0A= }=0A= =0A= =0A= /**=0A= * getXY()=0A= *=0A= * Returns the position of any element as an object.=0A= *=0A= * Typical usage:=0A= * var pos =3D getXY(object);=0A= * alert(pos.x + " " +pos.y);=0A= */=0A= function getXY(el) {=0A= var x =3D el.offsetLeft;=0A= var y =3D el.offsetTop;=0A= if (el.offsetParent !=3D null) {=0A= var pos =3D getXY(el.offsetParent);=0A= x +=3D pos.x;=0A= y +=3D pos.y;=0A= }=0A= return {x: x, y: y}=0A= }=0A= =0A= // The following 3 functions are taken from common.js=0A= function hasClass(el, cl) {=0A= if (el =3D=3D null || el.className =3D=3D null) return false;=0A= var classes =3D el.className.split(" ");=0A= for (var i =3D 0; i < classes.length; i++) {=0A= if (classes[i] =3D=3D cl) {=0A= return true;=0A= }=0A= }=0A= return false;=0A= }=0A= =0A= // Add a class to element=0A= function addClass(el, cl) {=0A= if (hasClass(el, cl)) return;=0A= el.className +=3D " " + cl;=0A= } =0A= =0A= // Remove a class from an element=0A= function removeClass(el, cl) {=0A= if (el.className =3D=3D null) return;=0A= var classes =3D el.className.split(" ");=0A= var result =3D [];=0A= var changed =3D false;=0A= for (var i =3D 0; i < classes.length; i++) {=0A= if (classes[i] !=3D cl) {=0A= if (classes[i]) { result.push(classes[i]); }=0A= } else {=0A= changed =3D true;=0A= } =0A= } =0A= if (changed) { el.className =3D result.join(" "); }=0A= } =0A= =0A= function toggleClass(el, cl) {=0A= if (hasClass(el, cl)) {=0A= removeClass(el, cl);=0A= } else {=0A= addClass(el, cl);=0A= }=0A= }=0A= =0A= =0A= /* Constants for node types, since IE doesn't support Node.TEXT_NODE */=0A= var TEXT_NODE =3D 3;=0A= var ELEMENT_NODE =3D 1;=0A= =0A= =0A= ------=_NextPart_000_0000_01C798B9.62265700 Content-Type: multipart/alternative; boundary="----=_NextPart_001_0017_01C798B9.6228C800" ------=_NextPart_001_0017_01C798B9.6228C800 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Location: http://roadhammer.blogspot.com/2006/12/live-review-majesty-of-madnessvan.html =EF=BB=BF The Road Hammer: = Live Review: Majesty of Madness/Van Halenized, Barrymore's Music Hall, = Saturday, December 2, 2006

The Road = Hammer=20

A thoughtful yet light-hearted look at politics, = society and=20 pop culture from a white-collar, Canadian redneck. Best viewed with