var authFollowUpFunc = null;
var isAuthFollowUp = false;
var strCompareAlphaNumeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

function parseJSON(json){ try { if(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)){ var j = eval('(' + json + ')'); return j; } }catch(e){ throw new SyntaxError("parseJSON"); } }
function trimString(str) { return str.replace(/^\s+/, '').replace(/\s+$/, ''); }
function trimFormElements(myForm) { for(i=0; i < myForm.elements.length; i++) {	myForm.elements[i].value = trimString(myForm.elements[i].value); } return; }
function isNotEmpty(value) { return (undefined != value && value != '' && null != value) ? true : false; }
function isAlphaNumeric(str){ return isStringMatch(str,strCompareAlphaNumeric);}
function isStringMatch(strData,strCompare){var bFlag=true;var iDataLen=strData.length;if(iDataLen>0){for(var iCount=0;iCount<iDataLen;iCount++){var cData=strData.charAt(iCount);if(strCompare.indexOf(cData)<0){return false;}}return true;}else{return false;}}

function isValidUsername(user){var strCompare=strCompareAlphaNumeric+".-_";return((user.length>=4&&user.length<=14&&isStringMatch(user,strCompare))?true : false);}
function isValidPassword(pwd, user) {
    var strCompare=strCompareAlphaNumeric+".-_";
    return( pwd != user &&
            pwd.length >=7 &&
            pwd.length<=64 );}
function isValidVerifyPassword(pwd, verifypwd) { return (pwd == verifypwd); }
function isValidEmail(email) { var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/; return re.test(email); }

function removeEscapedHTMLComments(html) 
{
    var i = 0;
    var ix = html.indexOf("<!--");
    while (ix >= 0 &&  i<5)    {
        var ix2 = html.indexOf("-->");
        //alert("ix=" + ix + " ix2 = " + ix2 + " html =" +  html);
        if (ix2>ix)         {
            html=html.substring(0,(ix-1)) + html.substring(ix, ix2+3) ;
            ix = html.indexOf("<!--");
        }
        i++;
    }
    return removeScriptTag(html) ;
}

function removeScriptTag(html) {
    var ix = html.indexOf("&lt;script");
    var i = 0;
    while (ix >= 0 && i<5) {
        var ix2;
        
        if (html.indexOf("/script&gt;") != -1) {
        	ix2 = html.indexOf("/script&gt;") + 11;
        } else if (html.indexOf("&gt;") != -1) {
        	ix2 = html.indexOf("&gt;") + 4;
        } else {
        	ix2 = ix + 10;
        }

        html=html.substring(0,(ix-1)) + html.substring(ix2, html.length) ;
        ix = html.indexOf("&lt;script");
        i++;
    }

    return html;
}


function populateUsername(email)
{
    if(isValidEmail(email)){
        var suggestedUsername = email.substring(0,email.indexOf('@'));
        var joinUser = document.getElementById("joinUser").value;
        if(suggestedUsername.length <= 14 && (undefined==joinUser||null==joinUser||joinUser==''))
            document.getElementById("joinUser").value=suggestedUsername;
    }
}

function reloadCaptcha() 
{
    var rand_no = Math.random();    rand_no = rand_no*10000;    rand_no = Math.ceil(rand_no );
    document.getElementById("GCA_IMG").innerHTML = "<img width=310 height=80 style='border:3px solid gray' src='/GCA?cid=" + rand_no + "'>";
    document.getElementById("GCA_CID").innerHTML = "<input type='hidden' name='joinCID' id='joinCID' value='" + rand_no + "'>";
}

function showPopupRegister()
{
    var rand_no = Math.random();    rand_no = rand_no*10000;    rand_no = Math.ceil(rand_no );
    document.getElementById("GCA_IMG").innerHTML = "<img width=310 height=80 style='border:3px solid gray'  src='/GCA?cid=" + rand_no + "'>";
    document.getElementById("GCA_CID").innerHTML = "<input type='hidden' name='joinCID' id='joinCID' value='" + rand_no + "'>";

    closePanel('authPopup','authPopupHide');showPanel('joinPopup','authPopupShow');
    document.joinForm.email.focus();

    return false; 
}
function showPopupRegisterThanks(){ closePanel('joinPopup','authPopupHide');showPanel('joinThanksPopup','authPopupShow');window.scrollTo(0,0);return false; }
function showPopupLogin(){ closePanel('joinPopup','authPopupHide');showPanel('authPopup','authPopupShow');document.loginForm.login.focus();window.scrollTo(0,0);return false; }
function showPopupLostPassword() { closePanel('authPopup','authPopupHide');showPanel('lostPasswordPopup','authPopupShow');document.lostPasswordForm.lostPasswordEmail.focus();return false; }
function showPopupChangeMktg() { showPanel('changeMktgPopup','authPopupShow');window.scrollTo(0,0);return false; }
function showPopupChangeEmail() { showPanel('changeEmailPopup','authPopupShow');document.changeEmailForm.newEmail.focus();return false; }
function showPopupChangePwd() { showPanel('changePasswordPopup','authPopupShow');document.changePasswordForm.oldPass.focus();return false; }
function showFlaggingPanel(target) {
    var panelElement = document.getElementById(target);
    if (panelElement.className == 'panelShow') {
        panelElement.className='panelHide';
    } else {
        panelElement.className='panelShow';
    }
}

function closePanel(target,cssHide) {
    $('.authPopupShow').css( { top: '75px' });
    document.getElementById(target).className=cssHide;
    document.getElementById("overlay").className="hiddenBG";
}

function showPanel(target,cssShow)
{
    document.getElementById(target).className=cssShow;
    document.getElementById("overlay").className="greyedOutBG";
    var docheight = $(document).height();
    var docwidth = $(document).width();
    document.getElementById("overlay").style.width= docwidth + 'px';
    document.getElementById("overlay").style.height= docheight + 'px';
}

function resetPanel(formId) {
    document.getElementById(formId).reset();
    var errorArray = document.getElementsByClassNameWithinId('invalidMsg',formId);
    for (var i=0; i<errorArray.length; i++){
        errorArray[i].innerHTML = '';
    }
    var inputErrorArray = document.getElementsByClassNameWithinId('invalid',formId);
    for (var j=0; j<inputErrorArray.length; j++){
        inputErrorArray[j].className = 'normal';
    }
}

function closeAndResetPanel(formId,target){
    resetPanel(formId);
    closePanel(target,'authPopupHide');
}

function toggleInputTag(fieldElement,errmsgElement,errorCode,isValid)
{
    if (isValid) {
        resetInputTag(fieldElement,errmsgElement);
        return true;
    } else {
        if (fieldElement != undefined) fieldElement.className = "invalid";
        if (errmsgElement != undefined) document.getElementById(errmsgElement).innerHTML = getAuthError(errorCode);
        return false;
    }
}

function resetInputTag(fieldElement,errmsgElement)
{
    if (fieldElement != undefined) fieldElement.className = "normal";
    if (errmsgElement != undefined) document.getElementById(errmsgElement).innerHTML="";
}

function highlightInputTag(fieldElement,errmsgElement,errMsg)
{
    //if (fieldElement.parentNode.nodeName == "LABEL") fieldElement.parentNode.className = " invalid";
    if (fieldElement != undefined) fieldElement.className = "invalid";
    if (errmsgElement != undefined) document.getElementById(errmsgElement).innerHTML = errMsg;
}

function loginResponse(request)
{
    var doc =  parseJSON(request.responseText);
    if (doc != undefined && doc.response_code == "1") {
        if (null != authFollowUpFunc) {
            authFollowUpFunc();
        } else {
            // reload the page so the cookies will be set
            window.location.reload(true);
        }
    } else {
      if (doc != undefined && doc.errors != undefined) {
        for(var i=0; i<doc.errors.length; i++) {
            var error = doc.errors[i];
            if (error.code == "-6" || error.code == "-2") {
                document.getElementById("loginErrMsg").innerHTML=getAuthError("-2");
            } else {
                document.getElementById("loginErrMsg").innerHTML=error.propertymessage;
            }
        }
      } else {
        document.getElementById("loginErrMsg").innerHTML=getAuthError("svcDown");
      }        
    }
}

function loginRequest(loginForm)
{
    trimFormElements(loginForm);
    document.getElementById("loginErrMsg").innerHTML="";

    if (isNotEmpty(loginForm.loginUser.value) && isNotEmpty(loginForm.loginPwd.value)) {
        var shapwd = SHA256(loginForm.loginPwd.value);
        var url = "/login";
        var params =   "username=" + loginForm.loginUser.value + "&password=" + shapwd + "&persist=" + loginForm.persistUser.checked + "&clientSiteId=" + loginForm.clientSiteId.value;
        var functionToUse = loginResponse;
        makeAJAHRequest("POST",url,params,'',functionToUse);
    } else {
        document.getElementById("loginErrMsg").innerHTML=getAuthError("-2210");
    }
}


function registrationResponse(response)
{
    // reset all other errors
    resetInputTag(document.joinForm.joinEmail,"joinEmailErrMsg");
    resetInputTag(document.joinForm.joinUser,"joinUserErrMsg");
    resetInputTag(document.joinForm.joinPwd,"joinPwdErrMsg");
    
    resetInputTag("","captchaErrMsg");

    var doc =  parseJSON(response.responseText);
    if (doc != undefined && doc.response_code == "1") {
        if (null != authFollowUpFunc) {
            closePanel('joinPopup','authPopupHide');
            authFollowUpFunc();
        } else {
            showPopupRegisterThanks();
            document.getElementById("joinThanksEmail").innerHTML=document.joinForm.joinEmail.value;
        }
    } else {
      if (doc != undefined && doc.errors != undefined) {
        for(var i=0; i<doc.errors.length; i++) {
            var error = doc.errors[i];
            if (error.code == "-2190" || error.code == "-2160") {
                highlightInputTag(document.joinForm.joinEmail,"joinEmailErrMsg",error.propertymessage);
            } else if (error.code == "-2200") {
                highlightInputTag(document.joinForm.joinPwd,"joinPwdErrMsg",error.propertymessage);
            } else if (error.code == "-113") {
                highlightInputTag("","captchaErrMsg",error.propertymessage);
            } else {
                // doc.response_code in ("-2140","-2150","-2150","-2210",default)
                highlightInputTag(document.joinForm.joinUser,"joinUserErrMsg",error.propertymessage);
            }
        }
      } else {
        document.getElementById("joinErrMsg").innerHTML=getAuthError("svcDown");
      }
        // clear out password and captcha fields so user can re-enter them
        document.joinForm.joinPwd.value = '';
        document.joinForm.verifyPwd.value = ''; 
        document.joinForm.joinCaptchaText.value = '';                 
    }
}

function registrationRequest(joinForm)
{
    trimFormElements(joinForm);
    var isValid = true;
    var joinEmailList;
 
    if (joinForm.joinEmailList.checked == true) { joinEmailList = "Y" } else { joinEmailList = "N" };
    
    var joinuseragreement = document.getElementById("joinuseragreement");   
    if (joinuseragreement !=null) {
        if (!joinuseragreement.checked) {
            isValid = (toggleInputTag(joinForm.joinuseragreement, "joinUserAcceptanceErrMsg","-2310", false  )) ? isValid : false ;
        } else {
            document.getElementById("joinUserAcceptanceErrMsg").innerHTML=" ";
        }
    }
    var joinprivacypolicy = document.getElementById("joinprivacypolicy");   
    if (joinprivacypolicy !=null) {
        if (!joinprivacypolicy.checked) {
            isValid = (toggleInputTag(joinForm.joinprivacypolicy, "joinPrivacyPolicyErrMsg","-2320", false  )) ? isValid : false ;
        } else {
            document.getElementById("joinPrivacyPolicyErrMsg").innerHTML=" ";
        }
    }

    if (isNotEmpty(joinForm.joinEmail.value)) {
        isValid = (toggleInputTag(joinForm.joinEmail, "joinEmailErrMsg","-2160", isValidEmail(joinForm.joinEmail.value) )) ? isValid : false ;
    } else {
        isValid = (toggleInputTag(joinForm.joinEmail, "joinEmailErrMsg","reqd", false  )) ? isValid : false ;
    }
    if (isNotEmpty(joinForm.joinUser.value)) {
        isValid = (toggleInputTag(joinForm.joinUser,"joinUserErrMsg","-2150",isValidUsername(joinForm.joinUser.value))) ? isValid : false ;
    } else {
        isValid = (toggleInputTag(joinForm.joinUser,"joinUserErrMsg","reqd", false  )) ? isValid : false ;
    }
    if (isNotEmpty(joinForm.joinPwd.value)) {
        isValid = (toggleInputTag(joinForm.joinPwd, "joinPwdErrMsg","-2200",isValidPassword(joinForm.joinPwd.value, joinForm.joinUser.value) )) ? isValid : false ;
    } else {
        isValid = (toggleInputTag(joinForm.joinPwd, "joinPwdErrMsg","reqd", false  )) ? isValid : false ;
    }
    if (isNotEmpty(joinForm.verifyPwd.value)) {
        isValid = (toggleInputTag(joinForm.verifyPwd, "verifyPwdErrMsg","-114", isValidVerifyPassword(joinForm.joinPwd.value,joinForm.verifyPwd.value) )) ? isValid : false ;
    } else {
        isValid = (toggleInputTag(joinForm.verifyPwd, "verifyPwdErrMsg","reqd", false  )) ? isValid : false ;
    }
    isValid = (toggleInputTag(joinForm.joinCaptchaText, "captchaErrMsg","reqd", isNotEmpty(joinForm.joinCaptchaText.value)  )) ? isValid : false ;

    if (isValid) {
        var shapwd = SHA256(joinForm.joinPwd.value);
        //alert ("Hashed passwd = " + shapwd);
        var url = "/registration?" + "email=" + joinForm.joinEmail.value + "&username=" + joinForm.joinUser.value + "&password=" + shapwd + "&captcha_text="  + joinForm.joinCaptchaText.value + "&cid2=" + joinForm.joinCID.value + "&reviewSubmit=" + joinForm.reviewSubmit.value + "&joinEmailList=" + joinEmailList;
        var functionToUse = registrationResponse;
        makeAJAHRequest("POST",url,'','',functionToUse);
    } else {
        // clear out password and captcha fields so user can re-enter them
        joinForm.joinPwd.value = '';
        joinForm.verifyPwd.value = ''; 
        joinForm.joinCaptchaText.value = '';        	     
        reloadCaptcha();
    }
}

function logOutResponse(request)
{
    /*redirect to homepage if user signs out, regardless of the page they are on*/
    window.location = "/";
}

function logOutRequest()
{
  /* Check whether User is on Write Review or Reviw Edit Page */
  if ((window.location.href != null) &&
      ((window.location.href.indexOf("/PER-") != -1) || (window.location.href.indexOf("/WR-") != -1) || ((window.location.href.indexOf("/WRWL") != -1) && (document.reviewForm != null)) )){
      var answer = confirm("Are you sure you want to navigate away from this page?\nYou will lose any unsaved work.");
      if (answer){
         continueLogOutResquest();
      }
   } else{
      continueLogOutResquest();
   }
}

function continueLogOutResquest()
{
   var url = "/logout";
   var functionToUse = logOutResponse;
   makeAJAHRequest("POST",url,'','',functionToUse);
}

function lostPasswordRequest(lostPasswordForm)
{
    var isValid = (toggleInputTag(lostPasswordForm.lostPasswordEmail, "lostPasswordErrMsg","-2160", isValidEmail(lostPasswordForm.lostPasswordEmail.value) )) ? true : false ;
    if (isValid) {
        var url = "/lostPassword?" + "email=" + lostPasswordForm.lostPasswordEmail.value;
        var functionToUse = lostPasswordResponse;
        makeAJAHRequest("POST",url,'','',functionToUse);
    }
}

function lostPasswordResponse(request)
{
    var doc =  parseJSON(request.responseText);

    if (doc != undefined && doc.response_code == "1") {
        document.getElementById("lostPasswordFormSuccess").className = "contentShow";
        document.getElementById("lostPasswordFormBox").className = "contentHide";
    } else {
        if (doc != undefined && doc.errors != undefined) {
            for(var i=0; i<doc.errors.length; i++) {
                highlightInputTag(document.lostPasswordForm.lostPasswordEmail,"lostPasswordErrMsg",doc.errors[i].propertymessage);
            }
        } else {
            document.getElementById("lostPasswordErrMsg").innerHTML=getAuthError("svcDown");
        }
        document.getElementById("lostPasswordFormSuccess").className = "contentHide";
        document.getElementById("lostPasswordFormBox").className = "contentShow";
    }
}

function hideConfirmMessage(panelName) {
    document.getElementById(panelName + "FormSuccess").className = "contentHide";
    document.getElementById(panelName + "FormBox").className = "contentShow";
}

function resendLostPasswordRequest()
{
    var url = "/lostPassword?" + "email=" + document.lostPasswordForm.lostPasswordEmail.value;
    var functionToUse = resendLostPasswordResponse;
    makeAJAHRequest("POST",url,'','',functionToUse);
}

function resendLostPasswordResponse(request)
{
    var doc =  parseJSON(request.responseText);
    if (doc != undefined && doc.response_code == "1") {
        document.getElementById("lostPwdEmailMsg").className = "contentShow";
    } else {
        document.getElementById("lostPwdEmailMsg").innerHTML = getAuthError("-1");
        document.getElementById("lostPwdEmailMsg").className = "contentShow";
    }
}

function resendActivationEmailRequest(email)
{
    var url = "/resendActivation?" + "email=" + email;
    var functionToUse = resendActivationEmailResponse;
    makeAJAHRequest("POST",url,'','',functionToUse);
}

function resendActivationEmailResponse(request)
{
    var doc =  parseJSON(request.responseText);
    if (doc != undefined && doc.response_code == "1") {
        document.getElementById("activationEmailMsg").className = "contentShow";
    } else {
        document.getElementById("activationEmailMsg").innerHTML = getAuthError("-1");
        document.getElementById("activationEmailMsg").className = "contentShow";
    }
}

var currentReviewId = "";
var currentReviewRating = "";
function rateHelpfulRequest(reviewId) { currentReviewId = reviewId; currentReviewRating = "2"; rateReviewRequest(); }
function rateNotHelpfulRequest(reviewId) { currentReviewId = reviewId; currentReviewRating = "1"; rateReviewRequest(); }
function rateReviewRequest()
{
    var attrList = "reviewId=" + currentReviewId + "&reviewRating=" + currentReviewRating ;
	var functionToUse = rateReviewResponse;
	var target = document.getElementById("reviewRating-" + currentReviewId);   
	makeAJAHRequest("POST","/rateReview",attrList,target,functionToUse);
}
function rateReviewResponse(request,target)
{
    closePanel('authPopup','authPopupHide');
    var doc =  parseJSON(request.responseText);
    if (doc != undefined && doc.response_code == "1") {
        if (currentReviewRating == "2") {
		  target.innerHTML = comm_msg_thankyou_rating_helpful;
		} else {
		  target.innerHTML = $('.reviewUnhelpfulMsg')[0].innerHTML
		}
        if (isAuthFollowUp) {
        	document.getElementById("loggedOutLink").innerHTML = comm_msg_signed_in;
        }
    } else {
      if (doc != undefined && doc.errors != undefined) {
        for(var i=0; i<doc.errors.length; i++) {
            if (isAuthenticated(doc.errors[i].propertymessage)) {
                target.innerHTML="<strong>" + doc.errors[i].propertymessage + "</strong>";
                repositionAuthPopup(target);
            } else {
            	isAuthFollowUp = true;
                authFollowUpFunc = rateReviewRequest;  // set global variable
                document.getElementById("panelTitleLogin").innerHTML=auth_pleaseSignInForFeedback;
                document.getElementById("panelTitleRegister").innerHTML=auth_pleaseRegisterForFeedback;
                showPopupLogin();
                repositionAuthPopup(target);
                target.innerHTML="<strong>" + getAuthError("-2820") + "</strong>";
                break;
            }                
        }
      } else {
        target.innerHTML="<strong>" + getAuthError("svcDown") + "</strong>";
      }        
    }
}

var flagForm;
function flagRequest(reviewId) { currentReviewId = reviewId; flagForm = document.getElementById("flagForm-"+currentReviewId); flagReviewRequest(); }
function flagReviewRequest()
{
    if (flagForm.flagComment.value != undefined) { var flagComment = trimString(flagForm.flagComment.value); } else { var flagComment = ""; }                
    var flagType = flagForm.flagType;
    var flagSelected = "";
    for(var i = 0; i < flagType.length; i++) {
        if(flagType[i].checked) {
            flagSelected = flagType[i].value;
        }
    }
    flagSelected = trimString(flagSelected);
    
    if (flagSelected == "") {
        document.getElementById("flagTypeError-"+currentReviewId).innerHTML=getAuthError("-2800");
        document.getElementById("flagCommentError-"+currentReviewId).innerHTML='';
    } else if (flagComment == "" && (flagSelected == "4" || flagSelected == "5" || flagSelected == "2") ) {
        document.getElementById("flagCommentError-"+currentReviewId).innerHTML=getAuthError("-2810");
        document.getElementById("flagTypeError-"+currentReviewId).innerHTML='';
    } else if (flagComment.length > 1000) {
        document.getElementById("flagCommentError-"+currentReviewId).innerHTML=getAuthError("-2830");
        document.getElementById("flagTypeError-"+currentReviewId).innerHTML='';
    } else {
        var attrList = "reviewId=" + currentReviewId + "&flagType=" + flagSelected + "&flagComment=" + flagComment;
        var functionToUse = flagReviewResponse;
        var target = document.getElementById("reviewFlag-" + currentReviewId);   
        makeAJAHRequest("POST","/flagReview",attrList,target,functionToUse);
    }
}

function flagReviewResponse(request,target) 
{
    closePanel('authPopup','authPopupHide');
    var doc =  parseJSON(request.responseText);
    if (doc != undefined && doc.response_code == "1") {
        target.innerHTML = comm_msg_thankyou_flagged;
        if (isAuthFollowUp) {
        	document.getElementById("loggedOutLink").innerHTML = comm_msg_signed_in;
        }
    } else {
      if (doc != undefined && doc.errors != undefined) {
        for(var i=0; i<doc.errors.length; i++) {
            if (isAuthenticated(doc.errors[i].propertymessage)) {
                target.innerHTML=doc.errors[i].propertymessage;
                repositionAuthPopup(target);
            } else {
            	isAuthFollowUp = true;
                authFollowUpFunc = flagReviewRequest;  // set global variable
                document.getElementById("panelTitleLogin").innerHTML=auth_pleaseSignInForFeedback;
                document.getElementById("panelTitleRegister").innerHTML=auth_pleaseRegisterForFeedback;
                showPopupLogin();
                repositionAuthPopup(target);
                target.innerHTML="<strong>" + getAuthError("-2820") + "</strong>";
                break;
            }                
        }
      } else {
        target.innerHTML=getAuthError("svcDown");
      }        
    }
}

function repositionAuthPopup(targetElement){
/*
    $reviewId_position = $(targetElement).position();
    scrollPos  = $reviewId_position.top - 200;
    topPos = scrollPos + "px";
    $(".authPopupShow").css( { top: topPos });
    window.scrollTo(0,scrollPos);
*/
}

function isAuthenticated(errorMsg){return((errorMsg=="AUTH_REQUIRED" || errorMsg=="TOKENEXP")?false : true);}
function isValidToken(errorMsg){return((errorMsg=="TOKENEXP")?false : true);}
function hideRegisterLink(){document.getElementById("registerLink").innerHTML="";}
function enterSubmit(ev,funcPointer){var e=ev||window.event;var unicode=e.keyCode?e.keyCode : e.which?e.which : e.charCode;if(unicode==13){funcPointer();}}
function loginSubmit(){loginRequest(document.loginForm);window.scrollTo(0,0);}
function regSubmit(){registrationRequest(document.joinForm);window.scrollTo(0,0);}
function lostPwdSubmit(){lostPasswordRequest(document.lostPasswordForm);window.scrollTo(0,0);}

document.getElementsByClassNameWithinId = function(clsName, parentId, tagName){
    if (undefined == tagName || null == tagName || tagName == '') tagName = '*';
    var retVal = new Array();
    var elements = document.getElementById(parentId).getElementsByTagName(tagName);
    for(var i = 0;i < elements.length;i++){
        if(elements[i].className.indexOf(" ") >= 0){
            var classes = elements[i].className.split(" ");
            for(var j = 0;j < classes.length;j++){
                if(classes[j] == clsName)
                    retVal.push(elements[i]);
            }
        }
        else if(elements[i].className == clsName)
            retVal.push(elements[i]);
    }
    return retVal;
}

function SHA256(s){
 
	var chrsz   = 8;
	var hexcase = 0;
 
	function safe_add (x, y) {
		var lsw = (x & 0xFFFF) + (y & 0xFFFF);
		var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
		return (msw << 16) | (lsw & 0xFFFF);
	}
 
	function S (X, n) { return ( X >>> n ) | (X << (32 - n)); }
	function R (X, n) { return ( X >>> n ); }
	function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); }
	function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); }
	function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); }
	function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); }
	function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); }
	function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); }
 
	function core_sha256 (m, l) {
		var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
		var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
		var W = new Array(64);
		var a, b, c, d, e, f, g, h, i, j;
		var T1, T2;
 
		m[l >> 5] |= 0x80 << (24 - l % 32);
		m[((l + 64 >> 9) << 4) + 15] = l;
 
		for ( var i = 0; i<m.length; i+=16 ) {
			a = HASH[0];
			b = HASH[1];
			c = HASH[2];
			d = HASH[3];
			e = HASH[4];
			f = HASH[5];
			g = HASH[6];
			h = HASH[7];
 
			for ( var j = 0; j<64; j++) {
				if (j < 16) W[j] = m[j + i];
				else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
 
				T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
				T2 = safe_add(Sigma0256(a), Maj(a, b, c));
 
				h = g;
				g = f;
				f = e;
				e = safe_add(d, T1);
				d = c;
				c = b;
				b = a;
				a = safe_add(T1, T2);
			}
 
			HASH[0] = safe_add(a, HASH[0]);
			HASH[1] = safe_add(b, HASH[1]);
			HASH[2] = safe_add(c, HASH[2]);
			HASH[3] = safe_add(d, HASH[3]);
			HASH[4] = safe_add(e, HASH[4]);
			HASH[5] = safe_add(f, HASH[5]);
			HASH[6] = safe_add(g, HASH[6]);
			HASH[7] = safe_add(h, HASH[7]);
		}
		return HASH;
	}
 
	function str2binb (str) {
		var bin = Array();
		var mask = (1 << chrsz) - 1;
		for(var i = 0; i < str.length * chrsz; i += chrsz) {
			bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
		}
		return bin;
	}
 
	function Utf8Encode(string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	}
 
	function binb2hex (binarray) {
		var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
		var str = "";
		for(var i = 0; i < binarray.length * 4; i++) {
			str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
			hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
		}
		return str;
	}
 
	s = Utf8Encode(s);
	return binb2hex(core_sha256(str2binb(s), s.length * chrsz));

}

