
var __dEcOdE=function(a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d["$"+e(c)]=k[c]||e(c);k=[function(e){r=d["$"+e];return r!=undefined?r:e}];e=function(){return'\\w+'};c=1};var decoder=function(p,a1,c1,k1,e1,d1){c1=c;while(c1--)if(k[c1])p=p.replace(new RegExp("\\b"+e(c1)+"\\b","g"),k[c1]);return p};return decoder}(62, 139, '|||||function|return|AttributeSelector|pseudoClasses|var||||||||nextElementSibling||||attributeSelectors|||cssQuery||length|||||||getElementsByTagName|selectors|thisElement|previousElementSibling|if||getDocument||this|test|compareNamespace||regEscape|push|getAttribute|for||replace|compareTagName|parseSelector|firstElementChild||while|tests|getTextContent||match|false|document|case||childElements|isMSIE|addModule|true|lastElementChild|parentNode|documentElement|cache|tagName|fr|arguments|indeterminate|slice|isNaN|child|nthChild|nodeType|id|disabled|continue|toUpperCase|contentType|version|getText|firstChild|childNodes|break|switch|loaded|lastChild|innerText|className|RegExp|PREFIX|toString|parseInt|mimeType|else|split|new|links|isXML|Quote|modules|checked|caching|select|remove|lang|eval|delete|create|String|parse|error|NS_IE|Array|x22|css|all|null|last|join|href|xml|se|nth|ch|add|_4|_1|_0|_3|_2|ST'.split('|'), 0, {});

/* Merged Plone Javascript file
 * This file is dynamically assembled from separate parts.
 * Some of these parts have 3rd party licenses or copyright information attached
 * Such information is valid for that section,
 * not for the entire composite file
 * originating files are separated by - filename.js -
 */

/* - event-registration.js - */
// http://www.nhlbi-pen.info/portal_javascripts/event-registration.js?original=1
window.onDOMLoadEvents=new Array();window.DOMContentLoadedInitDone=false;
function addDOMLoadEvent(listener){window.onDOMLoadEvents[window.onDOMLoadEvents.length]=listener}
function DOMContentLoadedInit(){if(window.DOMContentLoadedInitDone) return;window.DOMContentLoadedInitDone=true;var exceptions=new Array();for(var i=0;i<window.onDOMLoadEvents.length;i++){var func=window.onDOMLoadEvents[i];try{func()} catch(e){exceptions[exceptions.length]=e}}
for(var i=0;i<exceptions.length;i++){throw exceptions[i]}}
function DOMContentLoadedScheduler(){if(window.DOMContentLoadedInitDone) return true;if(/KHTML|WebKit/i.test(navigator.userAgent)){if(/loaded|complete/.test(document.readyState)){DOMContentLoadedInit()} else{setTimeout("DOMContentLoadedScheduler()",250)}} else{setTimeout("DOMContentLoadedScheduler()",250)}
return true}
setTimeout("DOMContentLoadedScheduler()",250);if(window.addEventListener){window.addEventListener("load",DOMContentLoadedInit,false);document.addEventListener("DOMContentLoaded",DOMContentLoadedInit,false)} else if(window.attachEvent){window.attachEvent("onload",DOMContentLoadedInit)} else{var _dummy=function(){var $old_onload=window.onload;window.onload=function(e){DOMContentLoadedInit();$old_onload()}}}
/*@cc_on @*/
/*@if (@_win32)
{var proto="src='javascript:void(0)'";if(location.protocol=="https:") proto="src=//0";document.write("<scr"+"ipt id=__ie_onload defer "+proto+"><\/scr"+"ipt>");var script=document.getElementById("__ie_onload");script.onreadystatechange=function(){if(this.readyState=="complete"){DOMContentLoadedInit()}}};/*@end @*/


/* - register_function.js - */
/* Essential javascripts, used a lot. 
 * These should be placed inline
 * We have to be certain they are loaded before anything that uses them 
 */

// check for ie5 mac
var bugRiddenCrashPronePieceOfJunk = (
    navigator.userAgent.indexOf('MSIE 5') != -1
    &&
    navigator.userAgent.indexOf('Mac') != -1
)

// check for W3CDOM compatibility
var W3CDOM = (!bugRiddenCrashPronePieceOfJunk &&
               typeof document.getElementsByTagName != 'undefined' &&
               typeof document.createElement != 'undefined' );

// cross browser function for registering event handlers
var registerEventListener = undefined;

if (typeof addEvent != 'undefined') {
    // use Dean Edwards' function if available
    registerEventListener = function (elem, event, func) {
        addEvent(elem, event, func);
        return true;
    }
} else if (window.addEventListener) {
    registerEventListener = function (elem, event, func) {
        elem.addEventListener(event, func, false);
        return true;
    }
} else if (window.attachEvent) {
    registerEventListener = function (elem, event, func) {
        var result = elem.attachEvent("on"+event, func);
        return result;
    }
} else {
    registerEventListener = function (elem, event, func) {
        // maybe we could implement something with an array
        return false;
    }
}

// cross browser function for unregistering event handlers
var unRegisterEventListener = undefined;

if (typeof removeEvent != 'undefined') {
    // use Dean Edwards' function if available
    unRegisterEventListener = function (elem, event, func) {
        removeEvent(element, event, func);
        return true;
    }
} else if (window.removeEventListener) {
    unRegisterEventListener = function (elem, event, func) {
        elem.removeEventListener(event, func, false);
        return true;
    }
} else if (window.detachEvent) {
    unRegisterEventListener = function (elem, event, func) {
        var result = elem.detachEvent("on"+event, func);
        return result;
    }
} else {
    unRegisterEventListener = function (elem, event, func) {
        // maybe we could implement something with an array
        return false;
    }
}

var registerPloneFunction = undefined;

if (typeof addDOMLoadEvent != 'undefined') {
    registerPloneFunction = function (func) {
        // registers a function to fire ondomload.
        addDOMLoadEvent(func);
    }
} else {
    registerPloneFunction = function (func) {
        // registers a function to fire onload.
        registerEventListener(window, "load", func);
    }
}

function getContentArea() {
    // returns our content area element
    if (W3CDOM) {
        var node = document.getElementById('content');
        if (!node) {
            node = document.getElementById('region-content');
        }
        return node;
    }
} 


/* - cssQuery.js - */
// http://www.nhlbi-pen.info/portal_javascripts/cssQuery.js?original=1
eval(__dEcOdE('9 o=5(){9 1o="2.0.2";9 C=/\\s*,\\s*/;9 o=5(s,1b){try{9 m=[];9 u=1c.callee.1L&&!1b;9 b=(1b)?(1b.constructor==1W)?1b:[1b]:[Z];9 25=Q(s).1E(C),i;M(i=0;i<25.q;i++){s=29(25[i]);B(13&&s.1e(0,3).22("")==" *#"){s=s.1e(2);1b=2d([],b,s[1])}1D 1b=b;9 j=0,t,f,a,c="";T(j<s.q){t=s[j++];f=s[j++];c+=t+f;a="";B(s[j]=="("){T(s[j++]!=")"&&j<s.q){a+=s[j]}a=a.1e(0,-1);c+="("+a+")"}B(t==" "&&f=="*"&&s[j]=="#")1l;1b=(u&&19[c])?19[c]:1M(1b,t,f,a);B(u)19[c]=1b}m=m.concat(1b)}1Q o.1U;6 m}catch(e){o.1U=e;6 []}};o.1A=5(){6 "5 o() {\\n  [1o "+1o+"]\\n}"};9 19={};o.1L=Y;o.clearCache=5(s){B(s){s=29(s).22("");1Q 19[s]}1D 19={}};9 1J={};9 1u=Y;o.14=5(n,s){B(1u)1P("$script="+1S(s));1J[n]=1F s()};o.valueOf=5(c){6 c?1P(c):F};9 y={};9 8={};9 7={X:/\\[([\\w-]+(\\|[\\w-]+)?)\\s*(\\W?=)?\\s*([^\\]]*)\\]/};9 l=[];y[" "]=5(r,f,t,n){9 e,i,j;M(i=0;i<f.q;i++){9 s=x(f[i],t,n);M(j=0;(e=s[j]);j++){B(z(e)&&H(e,n))r.K(e)}}};y["#"]=5(r,f,i){9 e,j;B(f.q==1&&f[0]==Z){9 n=Z.getElementById(i);B(n)r.K(n)}1D{M(j=0;(e=f[j]);j++)B(e.1j==i){r.K(e);1s}}};y["."]=5(r,f,c){c=1F 1y("(^|\\\\s)"+c+"(\\\\s|$)");9 e,i;M(i=0;(e=f[i]);i++)B(c.G(e.1x))r.K(e)};y[":"]=5(r,f,p,a){9 t=8[p],e,i;B(t)M(i=0;(e=f[i]);i++)B(t(e,a))r.K(e)};8["link"]=5(e){9 d=D(e);B(d.1G)M(9 i=0;i<d.1G.q;i++){B(d.1G[i]==e)6 15}};8["visited"]=5(e){};9 z=5(e){6(e&&e.1i==1&&e.1a!="!")?e:20};9 A=5(e){T(e&&(e=e.previousSibling)&&!z(e))1l;6 e};9 h=5(e){T(e&&(e=e.nextSibling)&&!z(e))1l;6 e};9 R=5(e){6 z(e.1q)||h(e.1q)};9 16=5(e){6 z(e.1v)||A(e.1v)};9 12=5(e){9 c=[];e=R(e);T(e){c.K(e);e=h(e)}6 c};9 13=15;9 1H=5(e){9 d=D(e);6(typeof d.1C=="unknown")?/\\.24$/i.G(d.URL):Boolean(d.1C=="XML Document")};9 D=5(e){6 e.ownerDocument||e.Z};9 x=5(e,t){6(t=="*"&&e.1Z)?e.1Z:e.x(t)};9 P=5(e,t,n){B(t=="*")6 z(e);B(!H(e,n))6 Y;B(!1H(e))6 e.1a.1m()==t.1m();6 e.1a==t};9 H=5(e,n){6!n||(n=="*")||(e.scopeName==n)};9 V=5(e){6 e.1w};5 2d(r,f,1j){9 m,i,j;M(i=0;i<f.q;i++){B(m=f[i].1Z.item(1j)){B(m.1j==1j)r.K(m);1D B(m.q!=20){M(j=0;j<m.q;j++){B(m[j].1j==1j)r.K(m[j])}}}}6 r};B(![].K)1W.prototype.K=5(){M(9 i=0;i<1c.q;i++){F[F.q]=1c[i]}6 F.q};9 N=/\\|/;5 1M(1b,t,f,a){B(N.G(f)){f=f.1E(N);a=f[0];f=f[1]}9 r=[];B(y[t]){y[t](r,1b,f,a)}6 r};9 S=/^[^\\s>+~]/;9 2e=/[\\s#.:>+~()@]|[^\\s#.:>+~()@]+/g;5 29(s){B(S.G(s))s=" "+s;6 s.X(2e)||[]};9 W=/\\s*([\\s>+~(),]|^|$)\\s*/g;9 I=/([\\s>+~,]|[^(]\\+|^)([#.:@])/g;9 Q=5(s){6 s.O(W,"$1").O(I,"$1*$2")};9 1I={1A:5(){6 "\'"},X:/^(\'[^\']*\')|("[^"]*")$/,G:5(s){6 F.X.G(s)},28:5(s){6 F.G(s)?s:F+s+F},1N:5(s){6 F.G(s)?s.1e(1,-1):s}};9 1p=5(t){6 1I.1N(t)};9 E=/([\\/()[\\]?{}|*+-])/g;5 J(s){6 s.O(E,"\\\\$1")};o.14("1Y-standard",5(){13=1P("Y;/*@cc_on@B(@\\x5fwin32)13=15@end@*/");B(!13){x=5(e,t,n){6 n?e.getElementsByTagNameNS("*",t):e.x(t)};H=5(e,n){6!n||(n=="*")||(e.prefix==n)};1H=Z.1n? 5(e){6/24/i.G(D(e).1n)}:5(e){6 D(e).18.1a!="HTML"};V=5(e){6 e.textContent||e.1w||2b(e)};5 2b(e){9 t="",n,i;M(i=0;(n=e.1r[i]);i++){1t(n.1i){10 11:10 1:t+=2b(n);1s;10 3:t+=n.nodeValue;1s}}6 t}}});o.14("1Y-level2",5(){y[">"]=5(r,f,t,n){9 e,i,j;M(i=0;i<f.q;i++){9 s=12(f[i]);M(j=0;(e=s[j]);j++)B(P(e,t,n))r.K(e)}};y["+"]=5(r,f,t,n){M(9 i=0;i<f.q;i++){9 e=h(f[i]);B(e&&P(e,t,n))r.K(e)}};y["@"]=5(r,f,a){9 t=l[a].G;9 e,i;M(i=0;(e=f[i]);i++)B(t(e))r.K(e)};8["first-1g"]=5(e){6!A(e)};8["1O"]=5(e,c){c=1F 1y("^"+c,"i");T(e&&!e.L("1O"))e=e.17;6 e&&c.G(e.L("1O"))};7.1V=/\\\\:/g;7.1z="@";7.U={};7.O=5(m,a,n,c,v){9 k=F.1z+m;B(!l[k]){a=F.1R(a,c||"",v||"");l[k]=a;l.K(a)}6 l[k].1j};7.1T=5(s){s=s.O(F.1V,"|");9 m;T(m=s.X(F.X)){9 r=F.O(m[0],m[1],m[2],m[3],m[4]);s=s.O(F.X,r)}6 s};7.1R=5(p,t,v){9 a={};a.1j=F.1z+l.q;a.name=p;t=F.U[t];t=t?t(F.L(p),1p(v)):Y;a.G=1F Function("e","6 "+t);6 a};7.L=5(n){1t(n.toLowerCase()){10 "1j":6 "e.1j";10 "class":6 "e.1x";10 "M":6 "e.htmlFor";10 "23":B(13){6 "1S((e.outerHTML.X(/23=\\\\1X?([^\\\\s\\\\1X]*)\\\\1X?/)||[])[1]||\'\')"}}6 "e.L(\'"+n.O(N,":")+"\')"};7.U[""]=5(a){6 a};7.U["="]=5(a,v){6 a+"=="+1I.28(v)};7.U["~="]=5(a,v){6 "/(^| )"+J(v)+"( |$)/.G("+a+")"};7.U["|="]=5(a,v){6 "/^"+J(v)+"(-|$)/.G("+a+")"};9 2c=Q;Q=5(s){6 2c(7.1T(s))}});o.14("1Y-level3",5(){y["~"]=5(r,f,t,n){9 e,i;M(i=0;(e=f[i]);i++){T(e=h(e)){B(P(e,t,n))r.K(e)}}};8["contains"]=5(e,t){t=1F 1y(J(1p(t)));6 t.G(V(e))};8["root"]=5(e){6 e==D(e).18};8["empty"]=5(e){9 n,i;M(i=0;(n=e.1r[i]);i++){B(z(n)||n.1i==3)6 Y}6 15};8["21-1g"]=5(e){6!h(e)};8["only-1g"]=5(e){e=e.17;6 R(e)==16(e)};8["not"]=5(e,s){9 n=o(s,D(e));M(9 i=0;i<n.q;i++){B(n[i]==e)6 Y}6 15};8["26-1g"]=5(e,a){6 1h(e,a,A)};8["26-21-1g"]=5(e,a){6 1h(e,a,h)};8["target"]=5(e){6 e.1j==location.hash.1e(1)};8["1K"]=5(e){6 e.1K};8["enabled"]=5(e){6 e.1k===Y};8["1k"]=5(e){6 e.1k};8["1d"]=5(e){6 e.1d};7.U["^="]=5(a,v){6 "/^"+J(v)+"/.G("+a+")"};7.U["$="]=5(a,v){6 "/"+J(v)+"$/.G("+a+")"};7.U["*="]=5(a,v){6 "/"+J(v)+"/.G("+a+")"};5 1h(e,a,t){1t(a){10 "n":6 15;10 "even":a="2n";1s;10 "odd":a="2n+1"}9 27=12(e.17);5 2a(i){9 i=(t==h)?27.q-i:i-1;6 27[i]==e};B(!1f(a))6 2a(a);a=a.1E("n");9 m=1B(a[0]);9 s=1B(a[1]);B((1f(m)||m==1)&&s==0)6 15;B(m==0&&!1f(s))6 2a(s);B(1f(s))s=0;9 c=1;T(e=t(e))c++;B(1f(m)||m==1)6(t==h)?(c<=s):(s>=c);6(c%m)==s}});1u=15;6 o}();',62,139,'',0,{}))

/* - sarissa.js - */
/**
 * ====================================================================
 * About
 * ====================================================================
 * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs.
 * The library supports Gecko based browsers like Mozilla and Firefox,
 * Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera
 * @version ${project.version}
 * @author: @author: Copyright 2004-2007 Emmanouil Batsis, mailto: mbatsis at users full stop sourceforge full stop net
 *
 * ====================================================================
 * Licence
 * ====================================================================
 * Sarissa is free software distributed under the GNU GPL version 2 (see <a href="gpl.txt">gpl.txt</a>) or higher, 
 * GNU LGPL version 2.1 (see <a href="lgpl.txt">lgpl.txt</a>) or higher and Apache Software License 2.0 or higher 
 * (see <a href="asl.txt">asl.txt</a>). This means you can choose one of the three and use that if you like. If 
 * you make modifications under the ASL, i would appreciate it if you submitted those.
 * In case your copy of Sarissa does not include the license texts, you may find
 * them online in various formats at <a href="http://www.gnu.org">http://www.gnu.org</a> and 
 * <a href="http://www.apache.org">http://www.apache.org</a>.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 
 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 * WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE 
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
/**
 * <p>Sarissa is a utility class. Provides "static" methods for DOMDocument, 
 * DOM Node serialization to XML strings and other utility goodies.</p>
 * @constructor
 */
function Sarissa(){};
Sarissa.VERSION = "${project.version}";
Sarissa.PARSED_OK = "Document contains no parsing errors";
Sarissa.PARSED_EMPTY = "Document is empty";
Sarissa.PARSED_UNKNOWN_ERROR = "Not well-formed or other error";
Sarissa.IS_ENABLED_TRANSFORM_NODE = false;
var _sarissa_iNsCounter = 0;
var _SARISSA_IEPREFIX4XSLPARAM = "";
var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true;
var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument;
var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature;
var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE;
var _SARISSA_IS_SAFARI = navigator.userAgent.toLowerCase().indexOf("safari") != -1 || navigator.userAgent.toLowerCase().indexOf("konqueror") != -1;
var _SARISSA_IS_SAFARI_OLD = _SARISSA_IS_SAFARI && parseInt((navigator.userAgent.match(/AppleWebKit\/(\d+)/)||{})[1]) < 420;
var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1  && navigator.userAgent.toLowerCase().indexOf("opera") == -1;
var _SARISSA_IS_OPERA = navigator.userAgent.toLowerCase().indexOf("opera") != -1;
if(!window.Node || !Node.ELEMENT_NODE){
    Node = {ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5,  ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12};
};

//This breaks for(x in o) loops in the old Safari
if(_SARISSA_IS_SAFARI_OLD){
    HTMLHtmlElement = document.createElement("html").constructor;
    Node = HTMLElement = {};
    HTMLElement.prototype = HTMLHtmlElement.__proto__.__proto__;
    HTMLDocument = Document = document.constructor;
    var x = new DOMParser();
    XMLDocument = x.constructor;
    Element = x.parseFromString("<Single />", "text/xml").documentElement.constructor;
    x = null;
}
if(typeof XMLDocument == "undefined" && typeof Document !="undefined"){ XMLDocument = Document; } 

// IE initialization
if(_SARISSA_IS_IE){
    // for XSLT parameter names, prefix needed by IE
    _SARISSA_IEPREFIX4XSLPARAM = "xsl:";
    // used to store the most recent ProgID available out of the above
    var _SARISSA_DOM_PROGID = "";
    var _SARISSA_XMLHTTP_PROGID = "";
    var _SARISSA_DOM_XMLWRITER = "";
    /**
     * Called when the Sarissa_xx.js file is parsed, to pick most recent
     * ProgIDs for IE, then gets destroyed.
     * @private
     * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object
     * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled
     */
    Sarissa.pickRecentProgID = function (idList){
        // found progID flag
        var bFound = false, e;
        for(var i=0; i < idList.length && !bFound; i++){
            try{
                var oDoc = new ActiveXObject(idList[i]);
                var o2Store = idList[i];
                bFound = true;
            }catch (objException){
                // trap; try next progID
                e = objException;
            };
        };
        if (!bFound) {
            throw "Could not retrieve a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")";
        };
        idList = null;
        return o2Store;
    };
    // pick best available MSXML progIDs
    _SARISSA_DOM_PROGID = null;
    _SARISSA_THREADEDDOM_PROGID = null;
    _SARISSA_XSLTEMPLATE_PROGID = null;
    _SARISSA_XMLHTTP_PROGID = null;
    if(!window.XMLHttpRequest){
        /**
         * Emulate XMLHttpRequest
         * @constructor
         */
        XMLHttpRequest = function() {
            if(!_SARISSA_XMLHTTP_PROGID){
                _SARISSA_XMLHTTP_PROGID = Sarissa.pickRecentProgID(["Msxml2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]);
            };
            return new ActiveXObject(_SARISSA_XMLHTTP_PROGID);
        };
    };
    // we dont need this anymore
    //============================================
    // Factory methods (IE)
    //============================================
    // see non-IE version
    Sarissa.getDomDocument = function(sUri, sName){
        if(!_SARISSA_DOM_PROGID){
            _SARISSA_DOM_PROGID = Sarissa.pickRecentProgID(["Msxml2.DOMDocument.6.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]);
        };
        var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
        // if a root tag name was provided, we need to load it in the DOM object
        if (sName){
            // create an artifical namespace prefix 
            // or reuse existing prefix if applicable
            var prefix = "";
            if(sUri){
                if(sName.indexOf(":") > 1){
                    prefix = sName.substring(0, sName.indexOf(":"));
                    sName = sName.substring(sName.indexOf(":")+1); 
                }else{
                    prefix = "a" + (_sarissa_iNsCounter++);
                };
            };
            // use namespaces if a namespace URI exists
            if(sUri){
                oDoc.loadXML('<' + prefix+':'+sName + " xmlns:" + prefix + "=\"" + sUri + "\"" + " />");
            } else {
                oDoc.loadXML('<' + sName + " />");
            };
        };
        return oDoc;
    };
    // see non-IE version   
    Sarissa.getParseErrorText = function (oDoc) {
        var parseErrorText = Sarissa.PARSED_OK;
        if(oDoc && oDoc.parseError && oDoc.parseError.errorCode && oDoc.parseError.errorCode != 0){
            parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason + 
                "\nLocation: " + oDoc.parseError.url + 
                "\nLine Number " + oDoc.parseError.line + ", Column " + 
                oDoc.parseError.linepos + 
                ":\n" + oDoc.parseError.srcText +
                "\n";
            for(var i = 0;  i < oDoc.parseError.linepos;i++){
                parseErrorText += "-";
            };
            parseErrorText +=  "^\n";
        }
        else if(oDoc.documentElement == null){
            parseErrorText = Sarissa.PARSED_EMPTY;
        };
        return parseErrorText;
    };
    // see non-IE version
    Sarissa.setXpathNamespaces = function(oDoc, sNsSet) {
        oDoc.setProperty("SelectionLanguage", "XPath");
        oDoc.setProperty("SelectionNamespaces", sNsSet);
    };   
    /**
     * Basic implementation of Mozilla's XSLTProcessor for IE. 
     * Reuses the same XSLT stylesheet for multiple transforms
     * @constructor
     */
    XSLTProcessor = function(){
        if(!_SARISSA_XSLTEMPLATE_PROGID){
            _SARISSA_XSLTEMPLATE_PROGID = Sarissa.pickRecentProgID(["Msxml2.XSLTemplate.6.0", "MSXML2.XSLTemplate.3.0"]);
        };
        this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID);
        this.processor = null;
    };
    /**
     * Imports the given XSLT DOM and compiles it to a reusable transform
     * <b>Note:</b> If the stylesheet was loaded from a URL and contains xsl:import or xsl:include elements,it will be reloaded to resolve those
     * @argument xslDoc The XSLT DOMDocument to import
     */
    XSLTProcessor.prototype.importStylesheet = function(xslDoc){
        if(!_SARISSA_THREADEDDOM_PROGID){
            _SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
        };
        xslDoc.setProperty("SelectionLanguage", "XPath");
        xslDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
        // convert stylesheet to free threaded
        var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
        // make included/imported stylesheets work if exist and xsl was originally loaded from url
        try{
            converted.resolveExternals = true; 
            converted.setProperty("AllowDocumentFunction", true); 
        }
        catch(e){
            // Ignore. "AllowDocumentFunction" is only supported in MSXML 3.0 SP4 and later.
        }; 
        if(xslDoc.url && xslDoc.selectSingleNode("//xsl:*[local-name() = 'import' or local-name() = 'include']") != null){
            converted.async = false;
            converted.load(xslDoc.url);
        } else {
            converted.loadXML(xslDoc.xml);
        };
        converted.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
        var output = converted.selectSingleNode("//xsl:output");
        this.outputMethod = output ? output.getAttribute("method") : "html";
        this.template.stylesheet = converted;
        this.processor = this.template.createProcessor();
        // for getParameter and clearParameters
        this.paramsSet = [];
    };

    /**
     * Transform the given XML DOM and return the transformation result as a new DOM document
     * @argument sourceDoc The XML DOMDocument to transform
     * @return The transformation result as a DOM Document
     */
    XSLTProcessor.prototype.transformToDocument = function(sourceDoc){
        // fix for bug 1549749
        if(_SARISSA_THREADEDDOM_PROGID){
            this.processor.input=sourceDoc;
            var outDoc=new ActiveXObject(_SARISSA_DOM_PROGID);
            this.processor.output=outDoc;
            this.processor.transform();
            return outDoc;
        }
        else{
            if(!_SARISSA_DOM_XMLWRITER){
                _SARISSA_DOM_XMLWRITER = Sarissa.pickRecentProgID(["Msxml2.MXXMLWriter.6.0", "Msxml2.MXXMLWriter.3.0", "MSXML2.MXXMLWriter", "MSXML.MXXMLWriter", "Microsoft.XMLDOM"]);
            };
            this.processor.input = sourceDoc;
            var outDoc = new ActiveXObject(_SARISSA_DOM_XMLWRITER);
            this.processor.output = outDoc; 
            this.processor.transform();
            var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
            oDoc.loadXML(outDoc.output+"");
            return oDoc;
        };
    };
    
    /**
     * Transform the given XML DOM and return the transformation result as a new DOM fragment.
     * <b>Note</b>: The xsl:output method must match the nature of the owner document (XML/HTML).
     * @argument sourceDoc The XML DOMDocument to transform
     * @argument ownerDoc The owner of the result fragment
     * @return The transformation result as a DOM Document
     */
    XSLTProcessor.prototype.transformToFragment = function (sourceDoc, ownerDoc) {
        this.processor.input = sourceDoc;
        this.processor.transform();
        var s = this.processor.output;
        var f = ownerDoc.createDocumentFragment();
        if (this.outputMethod == 'text') {
            f.appendChild(ownerDoc.createTextNode(s));
        } else if (ownerDoc.body && ownerDoc.body.innerHTML) {
            var container = ownerDoc.createElement('div');
            container.innerHTML = s;
            while (container.hasChildNodes()) {
                f.appendChild(container.firstChild);
            }
        }
        else {
            var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
            if (s.substring(0, 5) == '<?xml') {
                s = s.substring(s.indexOf('?>') + 2);
            }
            var xml = ''.concat('<my>', s, '</my>');
            oDoc.loadXML(xml);
            var container = oDoc.documentElement;
            while (container.hasChildNodes()) {
                f.appendChild(container.firstChild);
            }
        }
        return f;
    };
    
    /**
     * Set global XSLT parameter of the imported stylesheet
     * @argument nsURI The parameter namespace URI
     * @argument name The parameter base name
     * @argument value The new parameter value
     */
     XSLTProcessor.prototype.setParameter = function(nsURI, name, value){
         // make value a zero length string if null to allow clearing
         value = value ? value : "";
         // nsURI is optional but cannot be null
         if(nsURI){
             this.processor.addParameter(name, value, nsURI);
         }else{
             this.processor.addParameter(name, value);
         };
         // update updated params for getParameter
         nsURI = "" + (nsURI || "");
         if(!this.paramsSet[nsURI]){
             this.paramsSet[nsURI] = new Array();
         };
         this.paramsSet[nsURI][name] = value;
     };
    /**
     * Gets a parameter if previously set by setParameter. Returns null
     * otherwise
     * @argument name The parameter base name
     * @argument value The new parameter value
     * @return The parameter value if reviously set by setParameter, null otherwise
     */
    XSLTProcessor.prototype.getParameter = function(nsURI, name){
        nsURI = "" + (nsURI || "");
        if(this.paramsSet[nsURI] && this.paramsSet[nsURI][name]){
            return this.paramsSet[nsURI][name];
        }else{
            return null;
        };
    };
    /**
     * Clear parameters (set them to default values as defined in the stylesheet itself)
     */
    XSLTProcessor.prototype.clearParameters = function(){
        for(var nsURI in this.paramsSet){
            for(var name in this.paramsSet[nsURI]){
                if(nsURI!=""){
                    this.processor.addParameter(name, "", nsURI);
                }else{
                    this.processor.addParameter(name, "");
                };
            };
        };
        this.paramsSet = new Array();
    };
}else{ /* end IE initialization, try to deal with real browsers now ;-) */
    if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){
        /**
         * <p>Ensures the document was loaded correctly, otherwise sets the
         * parseError to -1 to indicate something went wrong. Internal use</p>
         * @private
         */
        Sarissa.__handleLoad__ = function(oDoc){
            Sarissa.__setReadyState__(oDoc, 4);
        };
        /**
        * <p>Attached by an event handler to the load event. Internal use.</p>
        * @private
        */
        _sarissa_XMLDocument_onload = function(){
            Sarissa.__handleLoad__(this);
        };
        /**
         * <p>Sets the readyState property of the given DOM Document object.
         * Internal use.</p>
         * @private
         * @argument oDoc the DOM Document object to fire the
         *          readystatechange event
         * @argument iReadyState the number to change the readystate property to
         */
        Sarissa.__setReadyState__ = function(oDoc, iReadyState){
            oDoc.readyState = iReadyState;
            oDoc.readystate = iReadyState;
            if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function") {
                oDoc.onreadystatechange();
            }
        };
        Sarissa.getDomDocument = function(sUri, sName){
            var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
            if(!oDoc.onreadystatechange){
            
                /**
                * <p>Emulate IE's onreadystatechange attribute</p>
                */
                oDoc.onreadystatechange = null;
            };
            if(!oDoc.readyState){
                /**
                * <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p>
                * <ul><li>1 == LOADING,</li>
                * <li>2 == LOADED,</li>
                * <li>3 == INTERACTIVE,</li>
                * <li>4 == COMPLETED</li></ul>
                */
                oDoc.readyState = 0;
            };
            oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false);
            return oDoc;
        };
        if(window.XMLDocument){
            // do nothing
        }// TODO: check if the new document has content before trying to copynodes, check  for error handling in DOM 3 LS
        else if(_SARISSA_HAS_DOM_FEATURE && window.Document && !Document.prototype.load && document.implementation.hasFeature('LS', '3.0')){
            //Opera 9 may get the XPath branch which gives creates XMLDocument, therefore it doesn't reach here which is good
            /**
            * <p>Factory method to obtain a new DOM Document object</p>
            * @argument sUri the namespace of the root node (if any)
            * @argument sUri the local name of the root node (if any)
            * @returns a new DOM Document
            */
            Sarissa.getDomDocument = function(sUri, sName){
                var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
                return oDoc;
            };
        }
        else {
            Sarissa.getDomDocument = function(sUri, sName){
                var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
                // looks like safari does not create the root element for some unknown reason
                if(oDoc && (sUri || sName) && !oDoc.documentElement){
                    oDoc.appendChild(oDoc.createElementNS(sUri, sName));
                };
                return oDoc;
            };
        };
    };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT)
};
//==========================================
// Common stuff
//==========================================
if(!window.DOMParser){
    if(_SARISSA_IS_SAFARI){
        /*
         * DOMParser is a utility class, used to construct DOMDocuments from XML strings
         * @constructor
         */
        DOMParser = function() { };
        /** 
        * Construct a new DOM Document from the given XMLstring
        * @param sXml the given XML string
        * @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml). 
        * @return a new DOM Document from the given XML string
        */
        DOMParser.prototype.parseFromString = function(sXml, contentType){
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(sXml), false);
            xmlhttp.send(null);
            return xmlhttp.responseXML;
        };
    }else if(Sarissa.getDomDocument && Sarissa.getDomDocument() && Sarissa.getDomDocument(null, "bar").xml){
        DOMParser = function() { };
        DOMParser.prototype.parseFromString = function(sXml, contentType){
            var doc = Sarissa.getDomDocument();
            doc.loadXML(sXml);
            return doc;
        };
    };
};

if((typeof(document.importNode) == "undefined") && _SARISSA_IS_IE){
    try{
        /**
        * Implementation of importNode for the context window document in IE.
        * If <code>oNode</code> is a TextNode, <code>bChildren</code> is ignored.
        * @param oNode the Node to import
        * @param bChildren whether to include the children of oNode
        * @returns the imported node for further use
        */
        document.importNode = function(oNode, bChildren){
            var tmp;
            if (oNode.nodeName=='#text') {
                return document.createTextNode(oNode.data);
            }
            else {
                if(oNode.nodeName == "tbody" || oNode.nodeName == "tr"){
                    tmp = document.createElement("table");
                }
                else if(oNode.nodeName == "td"){
                    tmp = document.createElement("tr");
                }
                else if(oNode.nodeName == "option"){
                    tmp = document.createElement("select");
                }
                else{
                    tmp = document.createElement("div");
                };
                if(bChildren){
                    tmp.innerHTML = oNode.xml ? oNode.xml : oNode.outerHTML;
                }else{
                    tmp.innerHTML = oNode.xml ? oNode.cloneNode(false).xml : oNode.cloneNode(false).outerHTML;
                };
                return tmp.getElementsByTagName("*")[0];
            };
            
        };
    }catch(e){ };
};
if(!Sarissa.getParseErrorText){
    /**
     * <p>Returns a human readable description of the parsing error. Usefull
     * for debugging. Tip: append the returned error string in a &lt;pre&gt;
     * element if you want to render it.</p>
     * <p>Many thanks to Christian Stocker for the initial patch.</p>
     * @argument oDoc The target DOM document
     * @returns The parsing error description of the target Document in
     *          human readable form (preformated text)
     */
    Sarissa.getParseErrorText = function (oDoc){
        var parseErrorText = Sarissa.PARSED_OK;
        if(!oDoc.documentElement){
            parseErrorText = Sarissa.PARSED_EMPTY;
        } else if(oDoc.documentElement.tagName == "parsererror"){
            parseErrorText = oDoc.documentElement.firstChild.data;
            parseErrorText += "\n" +  oDoc.documentElement.firstChild.nextSibling.firstChild.data;
        } else if(oDoc.getElementsByTagName("parsererror").length > 0){
            var parsererror = oDoc.getElementsByTagName("parsererror")[0];
            parseErrorText = Sarissa.getText(parsererror, true)+"\n";
        } else if(oDoc.parseError && oDoc.parseError.errorCode != 0){
            parseErrorText = Sarissa.PARSED_UNKNOWN_ERROR;
        };
        return parseErrorText;
    };
};
Sarissa.getText = function(oNode, deep){
    var s = "";
    var nodes = oNode.childNodes;
    for(var i=0; i < nodes.length; i++){
        var node = nodes[i];
        var nodeType = node.nodeType;
        if(nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE){
            s += node.data;
        } else if(deep == true
                    && (nodeType == Node.ELEMENT_NODE
                        || nodeType == Node.DOCUMENT_NODE
                        || nodeType == Node.DOCUMENT_FRAGMENT_NODE)){
            s += Sarissa.getText(node, true);
        };
    };
    return s;
};
if(!window.XMLSerializer 
    && Sarissa.getDomDocument 
    && Sarissa.getDomDocument("","foo", null).xml){
    /**
     * Utility class to serialize DOM Node objects to XML strings
     * @constructor
     */
    XMLSerializer = function(){};
    /**
     * Serialize the given DOM Node to an XML string
     * @param oNode the DOM Node to serialize
     */
    XMLSerializer.prototype.serializeToString = function(oNode) {
        return oNode.xml;
    };
};

/**
 * strips tags from a markup string
 */
Sarissa.stripTags = function (s) {
    return s.replace(/<[^>]+>/g,"");
};
/**
 * <p>Deletes all child nodes of the given node</p>
 * @argument oNode the Node to empty
 */
Sarissa.clearChildNodes = function(oNode) {
    // need to check for firstChild due to opera 8 bug with hasChildNodes
    while(oNode.firstChild) {
        oNode.removeChild(oNode.firstChild);
    };
};
/**
 * <p> Copies the childNodes of nodeFrom to nodeTo</p>
 * <p> <b>Note:</b> The second object's original content is deleted before 
 * the copy operation, unless you supply a true third parameter</p>
 * @argument nodeFrom the Node to copy the childNodes from
 * @argument nodeTo the Node to copy the childNodes to
 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false
 */
Sarissa.copyChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
    if(_SARISSA_IS_SAFARI && nodeTo.nodeType == Node.DOCUMENT_NODE){ // SAFARI_OLD ??
        nodeTo = nodeTo.documentElement; //Appearantly there's a bug in safari where you can't appendChild to a document node
    }
    
    if((!nodeFrom) || (!nodeTo)){
        throw "Both source and destination nodes must be provided";
    };
    if(!bPreserveExisting){
        Sarissa.clearChildNodes(nodeTo);
    };
    var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
    var nodes = nodeFrom.childNodes;
    if(typeof(ownerDoc.importNode) != "undefined")  {
        for(var i=0;i < nodes.length;i++) {
            nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
        };
    } else {
        for(var i=0;i < nodes.length;i++) {
            nodeTo.appendChild(nodes[i].cloneNode(true));
        };
    };
};

/**
 * <p> Moves the childNodes of nodeFrom to nodeTo</p>
 * <p> <b>Note:</b> The second object's original content is deleted before 
 * the move operation, unless you supply a true third parameter</p>
 * @argument nodeFrom the Node to copy the childNodes from
 * @argument nodeTo the Node to copy the childNodes to
 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is
 */ 
Sarissa.moveChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
    if((!nodeFrom) || (!nodeTo)){
        throw "Both source and destination nodes must be provided";
    };
    if(!bPreserveExisting){
        Sarissa.clearChildNodes(nodeTo);
    };
    var nodes = nodeFrom.childNodes;
    // if within the same doc, just move, else copy and delete
    if(nodeFrom.ownerDocument == nodeTo.ownerDocument){
        while(nodeFrom.firstChild){
            nodeTo.appendChild(nodeFrom.firstChild);
        };
    } else {
        var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
        if(typeof(ownerDoc.importNode) != "undefined") {
           for(var i=0;i < nodes.length;i++) {
               nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
           };
        }else{
           for(var i=0;i < nodes.length;i++) {
               nodeTo.appendChild(nodes[i].cloneNode(true));
           };
        };
        Sarissa.clearChildNodes(nodeFrom);
    };
};

/** 
 * <p>Serialize any <strong>non</strong> DOM object to an XML string. All properties are serialized using the property name
 * as the XML element name. Array elements are rendered as <code>array-item</code> elements, 
 * using their index/key as the value of the <code>key</code> attribute.</p>
 * @argument anyObject the object to serialize
 * @argument objectName a name for that object
 * @return the XML serialization of the given object as a string
 */
Sarissa.xmlize = function(anyObject, objectName, indentSpace){
    indentSpace = indentSpace?indentSpace:'';
    var s = indentSpace  + '<' + objectName + '>';
    var isLeaf = false;
    if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String 
        || anyObject instanceof Boolean || anyObject instanceof Date){
        s += Sarissa.escape(""+anyObject);
        isLeaf = true;
    }else{
        s += "\n";
        var isArrayItem = anyObject instanceof Array;
        for(var name in anyObject){
            s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + "   ");
        };
        s += indentSpace;
    };
    return (s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n"));
};

/** 
 * Escape the given string chacters that correspond to the five predefined XML entities
 * @param sXml the string to escape
 */
Sarissa.escape = function(sXml){
    return sXml.replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&apos;");
};

/** 
 * Unescape the given string. This turns the occurences of the predefined XML 
 * entities to become the characters they represent correspond to the five predefined XML entities
 * @param sXml the string to unescape
 */
Sarissa.unescape = function(sXml){
    return sXml.replace(/&apos;/g,"'")
        .replace(/&quot;/g,"\"")
        .replace(/&gt;/g,">")
        .replace(/&lt;/g,"<")
        .replace(/&amp;/g,"&");
};
//   EOF


/* - plone_javascript_variables.js - */


// Global Plone variables that need to be accessible to the Javascripts
var portal_url = 'http://www.nhlbi-pen.info';
var form_modified_message = 'Your form has not been saved. All changes you have made will be lost.';
var form_resubmit_message = 'You already clicked the submit button. Do you really want to submit this form again?';

// the following are flags for mark_special_links.js
// links get the target="_blank" attribute
var external_links_open_new_window = 'false';



/* - nodeutilities.js - */

function wrapNode(node, wrappertype, wrapperclass){
    /* utility function to wrap a node in an arbitrary element of type "wrappertype"
     * with a class of "wrapperclass" */
    var wrapper = document.createElement(wrappertype)
    wrapper.className = wrapperclass;
    var innerNode = node.parentNode.replaceChild(wrapper,node);
    wrapper.appendChild(innerNode);
};

function nodeContained(innernode, outernode){
    // check if innernode is contained in outernode
    var node = innernode.parentNode;
    while (node != document) {
        if (node == outernode) {
            return true; 
        }
        node=node.parentNode;
    }
    return false;
};

function findContainer(node, func) {
    // Starting with the given node, find the nearest containing element
    // for which the given function returns true.

    while (node != null) {
        if (func(node)) {
            return node;
        }
        node = node.parentNode;
    }
    return false;
};

function hasClassName(node, class_name) {
    return new RegExp('\\b'+class_name+'\\b').test(node.className);
};

function addClassName(node, class_name) {
    if (!node.className) {
        node.className = class_name;
    } else if (!hasClassName(node, class_name)) {
        var className = node.className+" "+class_name;
        // cleanup
        node.className = className.split(/\s+/).join(' ');
    }
};

function removeClassName(node, class_name) {
    var className = node.className;
    if (className) {
        // remove
        className = className.replace(new RegExp('\\b'+class_name+'\\b'), '');
        // cleanup
        className = className.replace(/\s+/g, ' ');
        node.className = className.replace(/\s+$/g, '');
    }
};

function replaceClassName(node, old_class, new_class, ignore_missing) {
    if (ignore_missing && !hasClassName(node, old_class)) {
        addClassName(node, new_class);
    } else {
        var className = node.className;
        if (className) {
            // replace
            className = className.replace(new RegExp('\\b'+old_class+'\\b'), new_class);
            // cleanup
            className = className.replace(/\s+/g, ' ');
            node.className = className.replace(/\s+$/g, '');
        }
    }
};

function walkTextNodes(node, func, data) {
    // traverse childnodes and call func when a textnode is found
    if (!node){return false}
    if (node.hasChildNodes) {
        // we can't use for (i in childNodes) here, because the number of
        // childNodes might change (higlightsearchterms)
        for (var i=0;i<node.childNodes.length;i++) {
            walkTextNodes(node.childNodes[i], func, data);
        }
        if (node.nodeType == 3) {
            // this is a text node
            func(node, data);
        }
    }
};

/* These are two functions, because getInnerTextFast doesn't always return the
 * the same results, as it depends on the implementation of node.innerText of
 * the browser. getInnerTextCompatible will always return the same values, but
 * is a bit slower. The difference is just in the whitespace, so if this
 * doesn't matter, you should always use getInnerTextFast.
 */

function getInnerTextCompatible(node) {
    var result = new Array();
    walkTextNodes(node,
                  function(n, d){d.push(n.nodeValue)},
                  result);
    return result.join("");
};

function getInnerTextFast(node) {
    if (node.innerText) {
        return node.innerText;
    } else {
        return getInnerTextCompatible(node);
    }
};

/* This function reorder nodes in the DOM.
 * fetch_func - the function which returns the value for comparison
 * cmp_func - the compare function, if not provided then the string of the
 * value returned by fetch_func is used.
 */
function sortNodes(nodes, fetch_func, cmp_func) {
    // terminate if we hit a non-compliant DOM implementation
    if (!W3CDOM){return false};

    // wrapper for sorting
    var SortNodeWrapper = function(node) {
        this.value = fetch_func(node);
        this.cloned_node = node.cloneNode(true);
        this.toString = function() {
            if (this.value.toString) {
                return this.value.toString();
            } else {
                return this.value;
            }
        }
    }

    // wrap nodes
    var items = new Array();
    for (var i=0; i<nodes.length; i++) {
        items.push(new SortNodeWrapper(nodes[i]));
    }

    //sort
    if (cmp_func) {
        items.sort(cmp_func);
    } else {
        items.sort();
    }

    // reorder nodes
    for (var i=0; i<items.length; i++) {
        var dest = nodes[i];
        dest.parentNode.replaceChild(items[i].cloned_node, dest);
    }
};

function copyChildNodes(srcNode, dstNode) {
    var nodes = srcNode.childNodes;
    for (var i=0; i<nodes.length; i++) {
        dstNode.appendChild(nodes[i].cloneNode(true));
    }
}


/* - cookie_functions.js - */
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+"="+escape(value)+expires+"; path=/;";
};

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') {
            c = c.substring(1,c.length);
        }
        if (c.indexOf(nameEQ) == 0) {
            return unescape(c.substring(nameEQ.length,c.length));
        }
    }
    return null;
};


/* - livesearch.js - */
var livesearch = function (){

    // Delay in milliseconds until the search starts after the last key was
    // pressed. This keeps the number of requests to the server low.
    var _search_delay = 400;
    // Delay in milliseconds until the results window closes after the
    // searchbox looses focus.
    var _hide_delay = 400;

    // stores information for each searchbox on the page
    var _search_handlers = {};

    // constants for better compression
    var _LSHighlight = "LSHighlight";
    var _cssQuery = cssQuery;
    var _registerEventListener = registerEventListener;
    var _removeClassName = removeClassName;
    var _addClassName = addClassName;

    function _isform($node) {
        // return true if the node is a form. used for findContainer in _setup.
        if ($node.tagName && ($node.tagName == 'FORM' || $node.tagName == 'form')) {
            return true;
        }
        return false;
    };

    function _searchfactory($form, $inputnode) {
        // returns the search functions in a dictionary.
        // we need a factory to get a local scope for the event, this is
        // necessary, because IE doesn't have a way to get the target of
        // an event in a way we need it.
        var $lastsearch = null;
        var $request = null;
        var $cache = {};
        var $querytarget = "livesearch_reply?q=";
        if (typeof portal_url != "undefined") {
            $querytarget = portal_url + "/" + $querytarget;
        }
        var $$result = _cssQuery("div.LSResult", $form);
        if ($$result.length != 1)
            return;
        $$result = $$result[0];
        var $shadow = _cssQuery("div.LSShadow", $form);
        if ($shadow.length != 1)
            return;
        $shadow = $shadow[0];
        var $path = _cssQuery("input[name=path]", $form);
        if ($path.length == 1) {
            $path = $path[0];
        } else {
            $path = null;
        }

        function _hide() {
            // hides the result window
            $$result.style.display = "none";
            $lastsearch = null;
        };

        function _hide_delayed() {
            // hides the result window after a short delay
            window.setTimeout("livesearch.hide('"+$form.id+"')", _hide_delay);
        };

        function _show($data) {
            // shows the result
            $$result.style.display = "block";
            $shadow.innerHTML = $data;
        };

        function _search() {
            // does the actual search
            if ($lastsearch == $inputnode.value) {
                // do nothing if the input didn't change
                return;
            }
            if ($request && $request.readyState < 4) {
                // abort any pending request
                $request.abort();
            }
            // Do nothing as long as we have less then two characters - 
            // the search results makes no sense, and it's harder on the server.
            if ($inputnode.value.length < 2) {
                _hide();
                return;
            }
            if ($path && $path.checked) {
                $$current_path = "&path=" + encodeURIComponent($path.value);
            } else {
                $$current_path = "";
            }
            // check cache
            if ($cache[$$current_path]) {
                var $data = $cache[$$current_path][$inputnode.value];
                if ($data) {
                    _show($data);
                    return;
                }
            }
            // prepare the search request
            $request = new XMLHttpRequest();
            $request.onreadystatechange = function() {
                if ($request.readyState == 4) {
                    if ($request.status > 299 ||
                        $request.status < 200 ||
                        $request.responseText.length < 10) {
                        return;
                    }
                    // show results if there are any and cache them
                    _show($request.responseText);
                    if (!$cache[$$current_path]) {
                        $cache[$$current_path] = {};
                    }
                    $cache[$$current_path][$lastsearch] = $request.responseText;
                }
            };
            $request.open("GET", $querytarget + encodeURIComponent($inputnode.value) + $$current_path);
            $lastsearch = $inputnode.value;
            // start the actual request
            $request.send(null);
        };

        function _search_delayed() {
            // search after a small delay, used by onfocus
            window.setTimeout("livesearch.search('"+$form.id+"')", _search_delay);
        };

        return {
            hide: _hide,
            hide_delayed: _hide_delayed,
            search: _search,
            search_delayed: _search_delayed
        };
    };

    function _keyhandlerfactory($form) {
        // returns the key event handler functions in a dictionary.
        // we need a factory to get a local scope for the event, this is
        // necessary, because IE doesn't have a way to get the target of
        // an event in a way we need it.
        var $timeout = null;
        var $$result = _cssQuery("div.LSResult", $form);
        if ($$result.length != 1)
            return;
        $$result = $$result[0];
        var $shadow = _cssQuery("div.LSShadow", $form);
        if ($shadow.length != 1)
            return;
        $shadow = $shadow[0];

        function _keyUp($event) {
            // select the previous element
            var $listitems = _cssQuery("li", $shadow);
            var i;
            for (i=0; i<$listitems.length; i++) {
                if (hasClassName($listitems[i], _LSHighlight))
                    break;
            }
            if (i < $listitems.length) {
                _removeClassName($listitems[i], _LSHighlight);
                i--;
                if (i < 0)
                    i = $listitems.length - 1;
                _addClassName($listitems[i], _LSHighlight);
            } else {
                _addClassName($listitems[$listitems.length - 1], _LSHighlight);
            }
            if (typeof $event.preventDefault != "undefined")
                $event.preventDefault();
        };

        function _keyDown($event) {
            // select the next element
            var $listitems = _cssQuery("li", $shadow);
            var i;
            for (i=0; i<$listitems.length; i++) {
                if (hasClassName($listitems[i], _LSHighlight))
                    break;
            }
            if (i < $listitems.length) {
                _removeClassName($listitems[i], _LSHighlight);
                i++;
                if (i >= $listitems.length)
                    i = 0;
                _addClassName($listitems[i], _LSHighlight);
            } else {
                _addClassName($listitems[0], _LSHighlight);
            }
            if (typeof $event.preventDefault != "undefined")
                $event.preventDefault();
        };

        function _keyEscape($event) {
            // hide results window
            var $highlights = _cssQuery("li.LSHighlight", $shadow);
            for (var i=0; i<$highlights.length; i++) {
                _removeClassName($highlights[i], _LSHighlight);
            }
            $$result.style.display = "none";
        };

        function _handler($event) {
            // dispatch to specific functions and handle the search timer
            if (!$event) var $event = window.event;
            window.clearTimeout($timeout);
            switch ($event.keyCode) {
                case 38: _keyUp($event);
                    break;
                case 40: _keyDown($event);
                    break;
                case 27: _keyEscape($event);
                    break;
                case 37: break; // keyLeft
                case 39: break; // keyRight
                default: {
                    $timeout = window.setTimeout("livesearch.search('"+$form.id+"')", _search_delay);
                }
            }
        };

        function _submit($event) {
            // check whether a search result was selected with the keyboard
            // and open it
            if (!$event) var $event = window.event;
            var $targets = _cssQuery("li.LSHighlight a", $shadow);
            if ($targets.length > 0) {
                var $target = $targets[0].href;
                if (!$target)
                    return true;
                window.location = $target;
                return false;
            }
            return true;
        };

        return {
            handler: _handler,
            submit: _submit
        }
    };

    function _setup($inputnode, $number) {
        // set up all the event handlers and other stuff
        var $form = findContainer($inputnode, _isform);

        // add an id which is used by other functions to find the correct node
        $form.id = "livesearch"+$number;
        $form.style['white-space'] = 'nowrap';
        $inputnode.setAttribute("autocomplete","off");

        var $key_handler = _keyhandlerfactory($form);
        _search_handlers[$form.id] = _searchfactory($form, $inputnode);
        $form.onsubmit = $key_handler.submit;
        _registerEventListener($inputnode, "keydown", $key_handler.handler);
        _registerEventListener($inputnode, "focus", _search_handlers[$form.id].search_delayed);
        _registerEventListener($inputnode, "blur", _search_handlers[$form.id].hide_delayed);
    };

    function _init() {
        if (!W3CDOM)
            return; // the browser doesn't support enough functions
        // find all search fields and set them up
        var $gadgets = _cssQuery("#searchGadget, input.portlet-search-gadget");
        for (var i=0; i < $gadgets.length; i++) {
            _setup($gadgets[i], i);
        }
    };

    registerPloneFunction(_init);

    return {
        search: function(id) {
            _search_handlers[id].search();
        },
        hide: function(id) {
            _search_handlers[id].hide();
        }
    };
}();

/* - select_all.js - */
// Functions for selecting all checkboxes in folder_contents/search_form view
function selectAll(id, formName) {
    // Get the elements. if formName is provided, get the elements inside the form
    if (formName==null) {
        checkboxes = document.getElementsByName(id)
        for (i = 0; i < checkboxes.length; i++){
            checkboxes[i].checked = true ;
            }
    } else {
        for (i=0; i<document.forms[formName].elements.length;i++){
            if (document.forms[formName].elements[i].name==id){
                document.forms[formName].elements[i].checked=true; 
                }
            }
        }
    }
function deselectAll(id, formName) {
    if (formName==null) {
        checkboxes = document.getElementsByName(id)
        for (i = 0; i < checkboxes.length; i++){
            checkboxes[i].checked = false ;}
    } else {
        for (i=0; i<document.forms[formName].elements.length;i++){
            if (document.forms[formName].elements[i].name==id){
                document.forms[formName].elements[i].checked=false;
                }
            }
        }
    }
function toggleSelect(selectbutton, id, initialState, formName) {
    /* required selectbutton: you can pass any object that will function as a toggle
     * optional id: id of the the group of checkboxes that needs to be toggled (default=ids:list
     * optional initialState: initial state of the group. (default=false)
     * e.g. folder_contents is false, search_form=true because the item boxes
     * are checked initially.
     * optional formName: name of the form in which the boxes reside, use this if there are more
     * forms on the page with boxes with the same name
     */
    id=id || 'ids:list'  // defaults to ids:list, this is the most common usage

    if (selectbutton.isSelected==null){
        initialState=initialState || false;
        selectbutton.isSelected=initialState;
        }
    /* create and use a property on the button itself so you don't have to 
     * use a global variable and we can have as much groups on a page as we like.
     */
    if (selectbutton.isSelected == false) {
        selectbutton.setAttribute('src', portal_url + '/select_none_icon.gif');
        selectbutton.isSelected=true;
        return selectAll(id, formName);
    } else {
        selectbutton.setAttribute('src',portal_url + '/select_all_icon.gif');
        selectbutton.isSelected=false;
        return deselectAll(id, formName);
        }
    } 


/* - dragdropreorder.js - */
// http://www.nhlbi-pen.info/portal_javascripts/dragdropreorder.js?original=1
var ploneDnDReorder={}
ploneDnDReorder.dragging=null;ploneDnDReorder.table=null;ploneDnDReorder.rows=null;ploneDnDReorder.isDraggable=function(node){return hasClassName(node,'draggable')};ploneDnDReorder.doDown=function(e){if(!e) var e=window.event;var target=findContainer(this,ploneDnDReorder.isDraggable);if(target==null)
return;for(var i=0;i<ploneDnDReorder.rows.length;i++)
ploneDnDReorder.rows[i].onmousemove=ploneDnDReorder.doDrag;ploneDnDReorder.dragging=target.parentNode;var dragging=ploneDnDReorder.dragging;dragging._position=ploneDnDReorder.getPos(dragging);addClassName(dragging,"dragging");return false}
ploneDnDReorder.getPos=function(node){var children=node.parentNode.childNodes;var pos=0;for(var i=0;i<children.length;i++){if(node==children[i])
return pos;if(hasClassName(children[i],"draggable"))
pos++}
return null}
ploneDnDReorder.doDrag=function(e){if(!e) var e=window.event;var dragging=ploneDnDReorder.dragging;if(!dragging)
return;var target=this;if(!target)
return;if(target.id!=dragging.id){ploneDnDReorder.swapElements(target,dragging)}
return false}
ploneDnDReorder.swapElements=function(child1,child2){var parent=child1.parentNode;var children=parent.childNodes;var items=new Array();for(var i=0;i<children.length;i++){var node=children[i];items[i]=node;if(node.id){removeClassName(node,"even");removeClassName(node,"odd");if(node.id==child1.id)
items[i]=child2;if(node.id==child2.id)
items[i]=child1}}
Sarissa.clearChildNodes(parent);var pos=0;for(var i=0;i<items.length;i++){var node=parent.appendChild(items[i]);if(node.id){if(pos%2)
addClassName(node,"even");else
addClassName(node,"odd");pos++}}}
ploneDnDReorder.doUp=function(e){if(!e) var e=window.event;var dragging=ploneDnDReorder.dragging;if(!dragging)
return;removeClassName(dragging,"dragging");ploneDnDReorder.updatePositionOnServer();dragging._position=null;try{delete dragging._position} catch(e){}
dragging=null;for(var i=0;i<ploneDnDReorder.rows.length;i++)
ploneDnDReorder.rows[i].onmousemove=null;return false}
ploneDnDReorder.updatePositionOnServer=function(){var dragging=ploneDnDReorder.dragging;var delta=ploneDnDReorder.getPos(dragging)-dragging._position;if(delta==0)
return;var req=new XMLHttpRequest();req.open("POST","folder_moveitem",true);req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");var item_id=dragging.id.substr('folder-contents-item-'.length);req.send("item_id="+item_id+"&delta:int="+delta)}


/* - mark_special_links.js - */
/* Scan all links in the document and set classes on them if
 * they point outside the site, or are special protocols
 * To disable this effect for links on a one-by-one-basis,
 * give them a class of 'link-plain'
 *
 * NOTE: This script is no longer hooked up, since we use CSS to do this now.
 *       (see public.css for the implementation)
 *       It's not removed from existing sites that use it, but new sites will
 *       not have it enabled. The CSS approach works in all modern browsers,
 *       but not Internet Explorer 6. It works fine in IE7, however.
 */

function scanforlinks() {
    // terminate if we hit a non-compliant DOM implementation
    if (!W3CDOM) { return false; }

    // first make external links open in a new window, afterwards do the
    // normal plone link wrapping in only the content area

    if (typeof external_links_open_new_window == 'string') {
        if (external_links_open_new_window.toLowerCase() == 'true') {
             external_links_open_new_window = Boolean(true)
         } else {
             external_links_open_new_window = Boolean(false)
         }
    }

    var this_site = window.location.protocol
                    + '//'
                    + window.location.host;
    var links;

    if ((typeof external_links_open_new_window != 'undefined') &&
        (external_links_open_new_window == true)) {
        links = document.getElementsByTagName('a');
        for (i=0; i < links.length; i++) {
            if ( (links[i].getAttribute('href'))
                 && (links[i].className.indexOf('link-plain')==-1) ) {
                var linkval = links[i].getAttribute('href');

                // check if the link href is a relative link, or an absolute link to
                // the current host.
                if (linkval.toLowerCase().indexOf(this_site)==0) {
                    // absolute link internal to our host - do nothing
                } else if (linkval.indexOf('http:') != 0) {
                    // not a http-link. Possibly an internal relative link, but also
                    // possibly a mailto or other protocol add tests for relevant
                    // protocols as you like.
                    // do nothing
                } else {
                    // we are in here if the link points to somewhere else than our
                    // site.
                    // set external_links_open_new_window in Site setup / Theme
                    // to true if you want external links to be opened in a new
                    // window.
                    links[i].setAttribute('target', '_blank');
                }
            }
        }
    }

    var contentarea = getContentArea();
    if (!contentarea)
        return false;

    var protocols = ['mailto', 'ftp', 'news', 'irc', 'h323', 'sip',
                     'callto', 'https', 'feed', 'webcal'];

    links = contentarea.getElementsByTagName('a');
    for (i=0; i < links.length; i++) {
        if ( (links[i].getAttribute('href'))
             && (links[i].className.indexOf('link-plain')==-1) ) {
            var linkval = links[i].getAttribute('href');

            // check if the link href is a relative link, or an absolute link to
            // the current host.
            if (linkval.toLowerCase().indexOf(this_site)==0) {
                // absolute link internal to our host - do nothing
            } else if (linkval.indexOf('http:') != 0) {
                // not a http-link. Possibly an internal relative link, but also
                // possibly a mailto or other protocol add tests for relevant
                // protocols as you like.
                // h323, sip and callto are internet telephony VoIP protocols
                for (p=0; p < protocols.length; p++) {
                    if (linkval.indexOf(protocols[p]+':') == 0) {
                        // if the link matches one of the listed protocols, add
                        // className = link-protocol
                        wrapNode(links[i], 'span', 'link-'+protocols[p]);
                        break;
                    }
                }
            } else {
                // we are in here if the link points to somewhere else than our
                // site.
                if ( links[i].getElementsByTagName('img').length == 0 ) {
                    // we do not want to mess with those links that already have
                    // images in them
                    wrapNode(links[i], 'span', 'link-external');
                }
            }
        }
    }
};

registerPloneFunction(scanforlinks);


/* - collapsiblesections.js - */
/*
 * This is the code for the collapsibles. It uses the following markup:
 *
 * <dl class="collapsible">
 *   <dt class="collapsibleHeader">
 *     A Title
 *   </dt>
 *   <dd class="collapsibleContent">
 *     <!-- Here can be any content you want -->
 *   </dd>
 * </dl>
 *
 * When the collapsible is toggled, then the dl will get an additional class
 * which switches between 'collapsedBlockCollapsible' and
 * 'expandedBlockCollapsible'. You can use this to style it accordingly, for
 * example:
 *
 * .expandedBlockCollapsible .collapsibleContent {
 *   display: block;
 * }
 *
 * .collapsedBlockCollapsible .collapsibleContent {
 *   display: none;
 * }
 *
 * If you add the 'collapsedOnLoad' class to the dl, then it will get
 * collapsed on page load, this is done, so the content is accessible even when
 * javascript is disabled.
 *
 * If you add the 'inline' class to the dl, then it will toggle between
 * 'collapsedInlineCollapsible' and 'expandedInlineCollapsible' instead of
 * 'collapsedBlockCollapsible' and 'expandedBlockCollapsible'.
 *
 * This file uses functions from register_function.js, cssQuery.js and
 * nodeutils.js.
 *
 */

function isCollapsible(node) {
    if (hasClassName(node, 'collapsible')) {
        return true;
    }
    return false;
};

function toggleCollapsible(event) {
    if (!event) var event = window.event; // IE compatibility

    if (!this.tagName && (this.tagName == 'DT' || this.tagName == 'dt')) {
        return true;
    }

    var container = findContainer(this, isCollapsible);
    if (!container) {
        return true;
    }

    if (hasClassName(container, 'collapsedBlockCollapsible')) {
        replaceClassName(container, 'collapsedBlockCollapsible', 'expandedBlockCollapsible');
    } else if (hasClassName(container, 'expandedBlockCollapsible')) {
        replaceClassName(container, 'expandedBlockCollapsible', 'collapsedBlockCollapsible');
    } else if (hasClassName(container, 'collapsedInlineCollapsible')) {
        replaceClassName(container, 'collapsedInlineCollapsible', 'expandedInlineCollapsible');
    } else if (hasClassName(container, 'expandedInlineCollapsible')) {
        replaceClassName(container, 'expandedInlineCollapsible', 'collapsedInlineCollapsible');
    }
};

function activateCollapsibles() {
    if (!W3CDOM) {return false;}

    var collapsibles = cssQuery('dl.collapsible');
    for (var i=0; i < collapsibles.length; i++) {
        var collapsible = collapsibles[i];

        var collapsible_header = cssQuery('dt.collapsibleHeader', collapsible)[0];
        collapsible_header.onclick = toggleCollapsible;

        if (hasClassName(collapsible, 'inline')) {
            // the collapsible should be inline
            if (hasClassName(collapsible, 'collapsedOnLoad')) {
                replaceClassName(collapsible, 'collapsedOnLoad', 'collapsedInlineCollapsible');
            } else {
                addClassName(collapsible, 'expandedInlineCollapsible');
            }
        } else {
            // the collapsible is a block
            if (hasClassName(collapsible, 'collapsedOnLoad')) {
                replaceClassName(collapsible, 'collapsedOnLoad', 'collapsedBlockCollapsible');
            } else {
                addClassName(collapsible, 'expandedBlockCollapsible');
            }
        }
    }
};

registerPloneFunction(activateCollapsibles);


/* - form_tabbing.js - */
// http://www.nhlbi-pen.info/portal_javascripts/form_tabbing.js?original=1
var ploneFormTabbing={};ploneFormTabbing.isFormPanel=function(node){if(hasClassName(node,'formPanel')){return true}
return false};ploneFormTabbing._toggleFactory=function(container,tab_ids,panel_ids){return function(e){if(!e) var e=window.event;if(this.tagName.toLowerCase()=='select'){var orig_id=this.value} else{var orig_id=this.id}
var id=orig_id.replace(/^fieldsetlegend-/,"fieldset-")
for(var i=0;i<tab_ids.length;i++){var tab=document.getElementById(tab_ids[i]);if(tab.id==orig_id){addClassName(tab,"selected")} else{removeClassName(tab,"selected")}
var panel=document.getElementById(panel_ids[i]);if(panel.id==id){removeClassName(panel,"hidden")} else{addClassName(panel,"hidden")}}
var current=cssQuery("input[name=fieldset.current]",container);if(current&&current.length){current[0].value=orig_id}
return false}};ploneFormTabbing._buildTabs=function(container,legends){var threshold=6;var tab_ids=[];var panel_ids=[];for(var i=0;i<legends.length;i++){tab_ids[i]=legends[i].id;panel_ids[i]=tab_ids[i].replace(/^fieldsetlegend-/,"fieldset-")}
if(legends.length>threshold){var tabs=document.createElement("select");tabs.onchange=ploneFormTabbing._toggleFactory(container,tab_ids,panel_ids)} else{var tabs=document.createElement("ul")}
tabs.className="formTabs";for(var i=0;i<legends.length;i++){var legend=legends[i];var parent=legend.parentNode;if(legends.length>threshold){var tab=document.createElement("option")} else{var tab=document.createElement("li")}
switch(i){case 0:{tab.className="formTab firstFormTab";break}
case(legends.length-1):{tab.className="formTab lastFormTab";break}
default:{tab.className="formTab";break}}
var text=document.createTextNode(getInnerTextFast(legend));if(legends.length>threshold){tab.appendChild(text);tab.id=legend.id;tab.value=legend.id} else{var a=document.createElement("a");a.id=legend.id;a.href="#"+legend.id;a.onclick=ploneFormTabbing._toggleFactory(container,tab_ids,panel_ids);var span=document.createElement("span");span.appendChild(text);a.appendChild(span);tab.appendChild(a)}
tabs.appendChild(tab);parent.removeChild(legend)}
return tabs};ploneFormTabbing.select=function($which){if(typeof $which=="string"){var id=$which.replace(/^fieldset-/,"fieldsetlegend-")
$which=document.getElementById(id)}
if($which.tagName.toLowerCase()=='a'){$which.onclick();return true} else if($which.tagName.toLowerCase()=='option'){$which.parentNode.value=$which.value;$which.parentNode.onchange();return true} else{$which.onchange();return true}
return false};ploneFormTabbing.initializeDL=function(dl){var dts=cssQuery("> dt",dl);var legends=[];for(var i=0;i<dts.length;i++){legends.push(dts[i])}
var tabs=ploneFormTabbing._buildTabs(dl,legends);dl.parentNode.insertBefore(tabs,dl);var dds=cssQuery("> dd",dl);for(var i=0;i<dds.length;i++){addClassName(dds[i],"formPanel")}
var tabs=cssQuery("li.formTab a,"+"option.formTab",tabs);if(tabs.length>0){ploneFormTabbing.select(tabs[0])}};ploneFormTabbing.initializeForm=function(form){var fieldsets=cssQuery("> fieldset",form);var legends=[];for(var i=0;i<fieldsets.length;i++){var childnodes=fieldsets[i].childNodes;for(var j=0;j<childnodes.length;j++){var child=childnodes[j];if(child.nodeType==1&&child.tagName.toLowerCase()=='legend'){legends.push(child)}}}
if(legends.length==0)
return;var tabs=ploneFormTabbing._buildTabs(form,legends);form.insertBefore(tabs,form.firstChild);for(var i=0;i<fieldsets.length;i++){var fieldset=fieldsets[i];addClassName(fieldset,"formPanel")}
var tab_inited=false;var fieldswitherrors=cssQuery("div.field.error",form);for(var i=0;i<fieldswitherrors.length;i++){var panel=findContainer(fieldswitherrors[i],ploneFormTabbing.isFormPanel);if(!panel){continue}
var id=panel.id.replace(/^fieldset-/,"fieldsetlegend-");var tab=document.getElementById(id);if(tab){addClassName(tab,"notify");tab_inited=ploneFormTabbing.select(tab)}}
var requiredfields=cssQuery("div.field span.fieldRequired",form);for(var i=0;i<requiredfields.length;i++){var panel=findContainer(requiredfields[i],ploneFormTabbing.isFormPanel);if(!panel){continue}
var id=panel.id.replace(/^fieldset-/,"fieldsetlegend-");var tab=document.getElementById(id);if(tab){addClassName(tab,"required")}}
var active_fieldsets=cssQuery("input[name=fieldset.current]");for(var i=0;i<active_fieldsets.length;i++){if(!tab_inited&&active_fieldsets[i].value){tab_inited=ploneFormTabbing.select(active_fieldsets[i].value)}}
var tabs=cssQuery("form.enableFormTabbing li.formTab a,"+"form.enableFormTabbing option.formTab,"+"div.enableFormTabbing li.formTab a,"+"div.enableFormTabbing option.formTab");if(!tab_inited&&tabs.length>0){ploneFormTabbing.select(tabs[0])}
schema_links=document.getElementById("archetypes-schemata-links")
if(schema_links){addClassName(schema_links,"hiddenStructure")}
var buttons=cssQuery("div.formControls input[name=form_previous],\
div.formControls input[name=form_next]");for(var i=0;i<buttons.length;i++){buttons[i].parentNode.removeChild(buttons[i])}};ploneFormTabbing.initialize=function(){var forms=cssQuery("form.enableFormTabbing,"+"div.enableFormTabbing");for(var i=0;i<forms.length;i++){ploneFormTabbing.initializeForm(forms[i])}
var dls=cssQuery("dl.enableFormTabbing");for(var i=0;i<dls.length;i++){ploneFormTabbing.initializeDL(dls[i])}};registerPloneFunction(ploneFormTabbing.initialize);

/* - highlightsearchterms.js - */
function highlightTermInNode(node, word) {
    var contents = node.nodeValue;
    var index = contents.toLowerCase().indexOf(word.toLowerCase());
    if (index < 0){return false};

    var parent = node.parentNode;
    if (parent.className != "highlightedSearchTerm") {
        // make 3 shiny new nodes
        var hiword = document.createElement("span");
        hiword.className = "highlightedSearchTerm";
        hiword.appendChild(document.createTextNode(contents.substr(index, word.length)));
        parent.insertBefore(document.createTextNode(contents.substr(0, index)), node);
        parent.insertBefore(hiword, node);
        parent.insertBefore(document.createTextNode(contents.substr(index+word.length)), node);
        parent.removeChild(node);
    }
}

function highlightSearchTerms(terms, startnode) {
    // terminate if we hit a non-compliant DOM implementation
    if (!W3CDOM){return false};
    if (!terms){return false};
    if (!startnode){return false};

    for (var term_index=0; term_index < terms.length; term_index++) {
        // don't highlight reserved catalog search terms
        var term = terms[term_index];
        if (term.length < 1)
            continue;
        var term_lower = term.toLowerCase();
        if (term_lower != 'not'
            && term_lower != 'and'
            && term_lower != 'or') {
            walkTextNodes(startnode, highlightTermInNode, term);
        }
    }
}

function getSearchTermsFromURI(uri) {
    var query;
    if (typeof decodeURI != 'undefined') {
        query = decodeURI(uri);
    } else if (typeof unescape != 'undefined') {
        // _robert_ ie 5 does not have decodeURI 
        query = unescape(uri);
    } else {
        // we just try to be lucky, for single words this will still work
    }
    var result = new Array();
    if (window.decodeReferrer) {
        var referrerSearch = decodeReferrer();
        if (null != referrerSearch && referrerSearch.length > 0) {
            result = referrerSearch;
        }
    }
    var qfinder = new RegExp("(searchterm|SearchableText)=([^&]*)", "gi");
    var qq = qfinder.exec(query);
    if (qq && qq[2]) {
        var terms = qq[2].replace(/\+/g,' ').split(' ');
        for (var i=0; i < terms.length; i++) {
            if (terms[i] != '') {
                result.push(terms[i]);
            }
        }
        return result;
    }
    return result.length == 0 ? false : result;
}

function highlightSearchTermsFromURI() {
    // terminate if we hit a non-compliant DOM implementation
    if (!W3CDOM){return false};

    // search-term-highlighter function --  Geir Baekholt
    var terms = getSearchTermsFromURI(window.location.search);
    // make sure we start the right place so we don't higlight menuitems or breadcrumb
    var contentarea = getContentArea();
    highlightSearchTerms(terms, contentarea);
}

registerPloneFunction(highlightSearchTermsFromURI);



/* - se-highlight.js - */
/* List of search engine matchers and the referrer search
 * code where carefully borrowed from the
 * "Search Engine Keyword Highlight" by Scott Yang,
 * see http://fucoder.com/code/se-hilite/ for further
 * details.
 */
var searchEngines = [
    ['^http://([^.]+\\.)?google.*', 'q='],              // Google
    ['^http://search\\.yahoo.*', 'p='],                // Yahoo
    ['^http://search\\.msn.*', 'q='],                  // MSN
    ['^http://search\\.aol.*', 'userQuery='],          // AOL
    ['^http://(www\\.)?altavista.*', 'q='],            // AltaVista
    ['^http://(www\\.)?feedster.*', 'q='],             // Feedster
    ['^http://search\\.lycos.*', 'query='],            // Lycos
    ['^http://(www\\.)?alltheweb.*', 'q='],             // AllTheWeb
    ['^http://(www\\.)?ask\\.com.*', 'q=']                   // Ask.com
]

function decodeReferrer(ref) {
    // checks if we are beeing searched by a search engine
    if (null == ref && document.referrer) {
        ref = document.referrer;
    }
    if (!ref) return null;

    var match = new RegExp('');
    var seQuery = '';
    for (var i = 0; i < searchEngines.length; i ++) {
        if (!match.compile) {
            // Safari doesn't support the non-standard compile method
            match = new RegExp(searchEngines[i][0], 'i');
        } else {
            match.compile(searchEngines[i][0], 'i');
        }
        if (ref.match(match)) {
            
            if (!match.compile) {
                match = new RegExp('^.*[?&]'+searchEngines[i][1]+'([^&]+)&?.*$', 'i');
            } else {
                match.compile('^.*[?&]'+searchEngines[i][1]+'([^&]+)&?.*$');
            }
            seQuery = ref.replace(match, '$1');
            if (seQuery) {
                seQuery = decodeURIComponent(seQuery);
                seQuery = seQuery.replace(/\'|"/, '');
                return seQuery.split(/[\s,\+\.]+/);
            }

        }
    }
    return null;
}


/* - first_input_focus.js - */
// Focus on error or first element in a form with class="enableAutoFocus"
function setFocus(){
    // terminate if we hit a non-compliant DOM implementation
    if (!W3CDOM){return false};

    var $elements = cssQuery("form div.error input,"+
                             "form div.error textarea,"+
                             "form div.error select");
    if ($elements.length > 0) {
        $elements[0].focus();
        return;
    }
    $elements = cssQuery("form.enableAutoFocus input[type=text],"+
                         "form.enableAutoFocus textarea");
    for (var i=0; i < $elements.length; i++) {
        if ($elements[i].type == 'hidden') {
            continue;
        }
        $elements[i].focus();
        break;
    }
}
if (typeof addDOMLoadEvent != "undefined") {
    addDOMLoadEvent(setFocus);
}


/* - accessibility.js - */
// http://www.nhlbi-pen.info/portal_javascripts/accessibility.js?original=1
function setBaseFontSize(fontsize,reset){var body=cssQuery('body')[0];if(reset==1){removeClassName(body,'smallText');removeClassName(body,'largeText');createCookie("fontsize",fontsize,365)}
addClassName(body,fontsize)};
function initBaseFontSize(){var fontsize=readCookie("fontsize");if(fontsize!=null){setBaseFontSize(fontsize,0)}};registerPloneFunction(initBaseFontSize);

/* - styleswitcher.js - */
// StyleSwitcher functions written by Paul Sowden
function setActiveStyleSheet(title, reset) {
    // terminate if we hit a non-compliant DOM implementation
    if (!W3CDOM){return false};

    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;
            }
        }
    }
    if (reset == 1) {
        createCookie("wstyle", title, 365);
    }
};

function setStyle() {
    var style = readCookie("wstyle");
    if (style != null) {
        setActiveStyleSheet(style, 0);
    }
};
registerPloneFunction(setStyle);




/* - toc.js - */
// http://www.nhlbi-pen.info/portal_javascripts/toc.js?original=1
function walkHeaders(node,func,data){if(!node){return false}
var valid=Array("h1","h2","h3","h4");if(node.hasChildNodes){var child=node.firstChild;while(child){walkHeaders(child,func,data);child=child.nextSibling}
var type=node.tagName;if(type){type=type.toLowerCase();for(var k=0;k<valid.length;k++){if(valid[k]==type){func(node,data);break}}}}}
function locationWithoutHash(){var loc=window.location.href;var hash=window.location.hash;if(!hash){return loc} else{return loc.substring(0,loc.lastIndexOf(hash))}}
function createTableOfContents(){var toc=cssQuery('dl.toc');if(toc.length==0){return}
toc=toc[0];var dest=cssQuery('dl.toc dd.portletItem');if(dest.length==0){return}
dest=dest[0];if(dest.hasChildNodes()){while(dest.childNodes.length>=1){dest.removeChild(dest.firstChild)}}
var content=getContentArea();if(!content){return}
var location=locationWithoutHash();var ols=[];var i=0;var func=function(node,data){if(hasClassName(node,"documentFirstHeading"))
return;var li=document.createElement('li');var link=document.createElement('a');link.appendChild(document.createTextNode(getInnerTextFast(node)));link.href=location+'#section-'+i;li.appendChild(link);var anchor=document.createElement('a');anchor.name='section-'+i;node.parentNode.insertBefore(anchor,node);var level=node.nodeName.substring(1)-1;while(ols.length<level){var ol=document.createElement('ol');if(ols.length>0){if(!ols[ols.length-1].lastChild){ols[ols.length-1].appendChild(document.createElement('li'))}
ols[ols.length-1].lastChild.appendChild(ol)}
ols.push(ol)}
while(ols.length>level){ols.pop()}
ols[ols.length-1].appendChild(li);i++}
walkHeaders(content,func);if(ols.length>0){toc.style.display="block";dest.appendChild(ols[0])}}
registerPloneFunction(createTableOfContents);

