function add_bookmark(){
   var url="http://coupons.smarter.com"
   var title="coupons.smarter.com"
   if ((navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4)){
      if (confirm('Bookmark Smarter.com?')){
         window.external.AddFavorite (url,title);
      }
   }
   else{
      var msg = "Sorry. The automatic creation of bookmarks does not work.";
      if (navigator.appName == "Netscape") msg += " (Press <CTRL+D>)";
      alert(msg);
   }
}

function add_bookmark_page(mtitle){
   var url=top.document.location;
   var title=mtitle;
   if ((navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4)){
      if (confirm('Add '+mtitle+' to your favorite?')){
         window.external.AddFavorite (url,title);
      }
   }
   else{
      var msg = "Sorry. The automatic creation of bookmarks does not work.";
      if (navigator.appName == "Netscape") msg += " (Press <CTRL+D>)";
      alert(msg);
   }
}



function getCookie(name){
   var result = null;
   var myCookie = " " + document.cookie + ";";
   var searchName = " " + name + "=";
   var startOfCookie = myCookie.indexOf(searchName);
   var endOfCookie;

   if (startOfCookie != -1){
      startOfCookie += searchName.length;
      endOfCookie = myCookie.indexOf(";",startOfCookie);
      result = unescape(myCookie.substring(startOfCookie,endOfCookie));
   }
   return result;
}
function setCookie(name,value,path,domain,expires,secure){
   var expString  = ((expires == null) ? "" : ("; expires=" + expires.toGMTString()));
   var pathString  = ((path == null) ? "" : ("; path=" + path));
   var domainString = ((domain == null) ? "" : ("; domain=" + domain));
   var secureString = ((secure == true) ? "; secure" : "");
   document.cookie = name + "=" + escape(value) + expString + pathString + domainString + secureString;
}
function todayDate(){
   var today = new Date();
   return getMonthName(today) + ' ' + today.getDate() + ', ' + today.getFullYear();
}
function getMonthName(dat){
   var m = new Array(12);
   m[0] = "January";
   m[1] = "February";
   m[2] = "March";
   m[3] = "April";
   m[4] = "May";
   m[5] = "June";
   m[6] = "July";
   m[7] = "August";
   m[8] = "September";
   m[9] = "October";
   m[10] = "November";
   m[11] = "December";
   return m[dat.getMonth()];
}
function check_mail(vemail){
   if (vemail.value == ""){
      alert("Please enter email address");
      return false;
   }
   else{
      var gem = vemail.value.match(/\b(^(\S+@).+((\.com)|(\.net)|(\.edu)|(\.mil)|(\.gov)|(\.org)|(\..{2,2}))$)\b/gi);
      if (!gem){
         alert("Please enter a valid email address");
         vemail.focus();
         vemail.select();
         return false;
      }
      else{
         return true;
      }
   }
}
function MM_preloadImages() { //v3.0
   var d = document;
   if( d.images ) {
      if( !d.MM_p ) d.MM_p = new Array();
      var i,j = d.MM_p.length,a = MM_preloadImages.arguments;
      for( i=0; i < a.length; i++ )
      if ( a[i].indexOf( "#" ) !=0 ) {
         d.MM_p[j] = new Image;
         d.MM_p[j++].src=a[i];
      }
   }
}
function preloadImages(name,num,tp) {
   for (i=0; i<num.length; i++){
      MM_preloadImages(name + num[i] + 'on.png',name + num[i] + 'off.' + tp);
   }
}
function preloadImagesS(name) {
   MM_preloadImages(name);
}
function changeImageState(img_name,img_path,state,tp) {
   if (document.images) {
      //document.images[img].src = 'images/menu/'+img + state +'.gif';
      document.images[img_name].src = img_path + img_name + state + '.' + tp;
   }
}

function popup(mid) {
   var popupOnExit  = top.MyClose;
   if ( popupOnExit && (mid>0) ) {
      var group  = getCookie("SOURCEGROUP");
      if ( group ) {
         var m_count = top.myArray.length;
         for (var i= 0; i< m_count; i++) {
            if ((group.toLowerCase() == top.myArray[i].toLowerCase())){
//alert('http://' + top.document.location.hostname + '/redir.php?m='+mid);
           window.open('http://' + top.document.location.hostname + "/check_merchant.php?m="+mid,"","toolbar=no,scrolbars=no,resizable=no,width=0,location=no,height=0");
//               window.open('http://' + top.document.location.hostname + '/redir.php?m='+mid);
               break;
            }
         }
      }
   }
}

function check_merchant(merchant){
  set_source();
  var group   = getCookie('SOURCEGROUP');
  var m_count = myArray.length;
  for (var i= 0; i< m_count; i++) {
     if ((group.toLowerCase() == myArray[i].toLowerCase())){
       window.open('/redir.php?m='+merchant);

     }
  }
}

function popdown(serverroot,slist) {
   if (!getCookie("popdown")){
      var today = new Date();
      setCookie("popdown","popdownvalue","/",".smarter.com",new Date(today.getTime() + (23-today.getUTCHours())*3600000));
      if ( top.document.location.search.indexOf('source=') > 0 ){
         source = top.document.location.search.substr(top.document.location.search.indexOf('source=')+7);
         if ( source.indexOf('&') > 0 ){
            source = source.substr(0,source.indexOf('&'));
         }
         for (var j=0; j<slist.length; j++){
            if (slist[j] == source){
               window.open('http://' + document.location.hostname + '/popdown.html', 'POPDOWN', 'innerWidth=150,innerHeight=150,width=150,height=150,resizable=no,scrollbars=no,location=no');
            }
         }
      }
      else{
         if ( getCookie("SOURCE") ){
            source = getCookie("SOURCE");
            for (var j=0; j<slist.length; j++){
               if (slist[j] == source){
                  window.open('http://' + document.location.hostname + '/popdown.html', 'POPDOWN', 'innerWidth=150,innerHeight=150,width=150,height=150,resizable=no,scrollbars=no,location=no');
               }
            }
         }
      }
      self.focus();
   }
}


function show_restriction(text){
   if ( text == "" ){
      text = 'No restrictions';
   }
   rwin = window.open('','','scrolbars=no,resizable=no,width=250,height=150');
   rwin.document.write('<html><head><title>Coupon restriction</title></head><body bgcolor="#888888"><table height="100%" width="100%"><tr><td style="font-family:Arial,Helvetica,sans-serif; font-size:9pt;color:#FFFFFF;">' + text + '</td></tr><tr><td>&nbsp;</td></tr><tr><td align="center"><a style="font-family:Arial,Helvetica,sans-serif; font-size:9pt; color:#000000;" href="JavaScript:self.close();">Close</a></td></tr></table></body></html>');
}

// @note Rename it from make_stat to orig_make_stat

// @author Kaluk Lee
// @note This function would try to find the sourcegroup request parameter
// @note This function use 30 days for the life span of a cookie.
function make_stat(category,merchant,coupon,is_frame){
   var today   = new Date();
   var newsess = 0;

   var CSession = getCookie("SESSION");
   if ( !CSession ){
      newsess = 1;
      //setCookie("SESSION","1","/",".smarter.com");
   }

   var referer  = top.document.referrer;
   var keyword  = 'Unknown';
   var isSticky = 0;

   if( referer ) {

       if ( referer.indexOf('//') >= 0 ){
          referer = referer.substr(referer.indexOf("//")+2);
       }
       if ( referer.indexOf('/') >= 0 ){
          referer = referer.substr(0,referer.indexOf("/"));
       }
       if ( referer.indexOf('?') >= 0 ){
          referer = referer.substr(0,referer.indexOf("?"));
       }
       if ( referer.indexOf(':') >= 0 ){
          referer = referer.substr(0,referer.indexOf(":"));
       }

       if ( referer && ( referer.indexOf("smarter.com") < 0 ) ){
          referer = escape(referer);

          if ( document.referrer.indexOf("?") >= 0 ){
             keyword = escape(top.document.referrer.substr(top.document.referrer.indexOf("?")+1));
         }
       }
       else {
           referer = 'Unknown';
       }
   }
   else {
       referer = 'Unknown';
   }

   var prevRef = "";
   var prevKey = "";

   if( referer == 'Unknown' ) {
       prevRef = getCookie("REFERER");
       if( prevRef != null && prevRef != 'Unknown' ) {
           referer = prevRef;
           isSticky = 1;
       }

       prevKey = getCookie("KEYWORD");
       if( prevKey != null ) {
           keyword  = prevKey;
       }
   }

   // cookie will expire in 30 days
  // setCookie('REFERER',referer,"/",".smarter.com",new Date(today.getTime() + 2592000000));
  // setCookie('KEYWORD',keyword,"/",".smarter.com",new Date(today.getTime() + 2592000000));

   var source = 'Unknown';
   source = set_source();

   //document.write('<img width="0" height="0" src="http://' + window.location.hostname + '/stat.php?newvisit=' + newsess + '&c=' + category + '&m=' + merchant + '&p=' + coupon + '&referer=' + referer + '&keyword=' + keyword + '&source=' + source + '&is_frame=' + is_frame + '">');
}

/*
 This function set the cookie for the source and sourcegroup.
*/
function set_source() {
   var today       = new Date();
   var source      = 'Unknown';
   var sourcegroup = 'Unknown';

   source = find_source();
   sourcegroup = find_sourcegroup();

   //setCookie('SOURCE',source,"/",".smarter.com",new Date(today.getTime() + 2592000000));
   //setCookie('SOURCEGROUP',sourcegroup,"/",".smarter.com",new Date(today.getTime() + 2592000000));
   return source;

}


function traffic_tracking(m_name) {
    var source = find_source();
    if (m_name){
      window.status=' '+m_name+' coupons - Updated Daily!';
    }
    else{
      window.status='Thank you for visiting smarter.';
    }
    //document.write('<img width="1" height="1" src="/traffictracking.php?source=' + source + '">');
  
}



function check_for_time(url){
        if (window.opener.closed){
                window.open(url,'','toolbar=yes,scrolbars=yes,resizable=yes,width=0,location=yes,height=0,screenY=offscreen,screenX=offscreen,menubar=yes');
        }else if (opener.length==0){
                try {
                        str = opener.location.href;
                } catch(er) {
                        window.open(url,'','toolbar=yes,scrolbars=yes,resizable=yes,width=0,location=yes,height=0,screenY=offscreen,screenX=offscreen,menubar=yes');
                }
        } else {
                try {
                        str = opener.top.location.href;
                } catch(er) {
                        window.open(url,'','toolbar=yes,scrolbars=yes,resizable=yes,width=0,location=yes,height=0,screenY=offscreen,screenX=offscreen,menubar=yes');
                }
        }
        self.close();
        window.close();
}

function clear_hot(){
   setCookie("FRAME1","","/");
   setCookie("FRAME_LOADED","","/");
}



/*
  This function is factored from the make_stat function.
  The main purpose of this function is locating source
  information from the incoming request URL. If it could
  not locate the source, then it would try to get it
  from exisiting Source cookie.
*/
function find_source() {
   var source = 'Unknown';

   if ( top.document.location.search.indexOf('source=') > 0 ){
      source = top.document.location.search.substr(top.document.location.search.indexOf('source=')+7);
      if ( source.indexOf('&') > 0 ){
         source = source.substr(0,source.indexOf('&'));
      }
      source = escape(source);
   }
   else{
      source = 'Unknown';
   }

   if ( source == 'Unknown' ){

      var regExpObj1  = /^\/([^\/]+)\/([^\/]+)\/$/;
      var regExpObj2  = /^\/([^\/]+)\/([^\/]+)\/([^\/]+)\/$/;
      var regExpObj3  = /^\/([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/]+)\/$/;

      var url  = top.document.location.pathname;
      if ( regExpObj1.exec(url) ){
         source   = regExpObj1.exec(url)[2];
      }
      if ( regExpObj2.exec(url) ){
         source   = regExpObj2.exec(url)[3];
      }

      if ( regExpObj3.exec(url) ){
         source   = regExpObj3.exec(url)[4];
      }
   }

   if ( source == 'Unknown' ){
      if ( getCookie('SOURCE') ){
         source = getCookie('SOURCE');
      }
   }
   return source;
}

function find_sourcegroup() {
   var sourcegroup = 'Unknown';

   if ( top.document.location.search.indexOf('source=') > 0 ){
      source = top.document.location.search.substr(top.document.location.search.indexOf('source=')+7);
      if ( source.indexOf('&') > 0 ){
         source = source.substr(0,source.indexOf('&'));
      }

      if( source.indexOf("_") > 0 ) {
         sourcegroup = source.substr(0, source.indexOf("_"));
      }
      else {
         sourcegroup = source;
      }

      sourcegroup = escape(sourcegroup);
   }
   else{
      sourcegroup = 'Unknown';
   }

   if ( sourcegroup == 'Unknown' ){

      var regExpObj1  = /^\/([^\/]+)\/([^\/]+)\/$/;
      var regExpObj2  = /^\/([^\/]+)\/([^\/]+)\/([^\/]+)\/$/;
      var regExpObj3  = /^\/([^\/]+)\/([^\/]+)\/([^\/]+)\/([^\/]+)\/$/;

      var url  = top.document.location.pathname;
      if ( regExpObj1.exec(url) ){
         sourcegroup = regExpObj1.exec(url)[1];
      }
      if ( regExpObj2.exec(url) ){
         sourcegroup = regExpObj2.exec(url)[2];
      }

      if ( regExpObj3.exec(url) ){
         sourcegroup = regExpObj3.exec(url)[3];
      }
   }

   if ( sourcegroup == 'Unknown' ){
      if ( getCookie('SOURCEGROUP') ){
         sourcegroup = getCookie('SOURCEGROUP');
      }
   }
   return sourcegroup;
}


// @author Kaluk Lee
// return value of a parameter in the URL.
function getSearchInfo(key) {
   var value = 'unset';

   if ( top.document.location.search.indexOf(key) > 0 ) {
      value = top.document.location.search.substr(top.document.location.search.indexOf(key)+key.length);
      if ( value.indexOf('=') > 0 ) {
          // I believe we need to handle the case the char & is used for the source.
          // For example, overture_flowers_&_gifts

          value = value.substr(0, value.indexOf('='));
          value = value.substr(0, value.lastIndexOf('&'));
      }
      value = escape(value);
   }

   return value;
}

function addm(form_name,listto,listfrom){
   var tmpValue;
   var selValue;
   var selText;
   var fromlen;
   var selitem;
   var len;
   eval("fromlen=window.document.forms['" + form_name + "']." + listfrom + ".length");
   for (var j=0; j<fromlen; j++){
      eval("selitem=window.document.forms['" + form_name + "']." + listfrom + "[" + j + "].selected");
      if (selitem){
         selIndex = j;
         eval("selValue=window.document.forms['" + form_name + "']." + listfrom + ".options[" + selIndex + "].value");
         eval("selText=window.document.forms['" + form_name + "']." + listfrom + ".options[" + selIndex + "].text");
         eval("len=window.document.forms['" + form_name + "']." + listto + ".length");
         for (var i=0; i < len; i++){
            eval("tmpValue=window.document.forms['" + form_name + "']." + listto + ".options[" + i + "].value");
            if ( tmpValue == selValue ){
               break;
            }
         }
         if ( tmpValue != selValue ){
            var opt = new Option(selText,selValue);
            eval("window.document.forms['" + form_name + "']." + listto + ".options[" + "window.document.forms['" + form_name + "']." + listto + ".length]=opt");
         }
      }
   }
}
function add(form_name,listto,listfrom){
   eval("selIndex=window.document.forms['" + form_name + "']." + listfrom + ".selectedIndex");
   if ( selIndex < 0 ) return;
   eval("selValue=window.document.forms['" + form_name + "']." + listfrom + ".options[" + selIndex + "].value");
   eval("selText=window.document.forms['" + form_name + "']." + listfrom + ".options[" + selIndex + "].text");
   eval("len=window.document.forms['" + form_name + "']." + listto + ".length");
   for (i=0; i < len; i++){
      eval("tmpValue=window.document.forms['" + form_name + "']." + listto + ".options[" + i + "].value");
      if ( tmpValue == selValue ) return;
   }
   var opt = new Option(selText,selValue);
   eval("window.document.forms['" + form_name + "']." + listto + ".options[" + "window.document.forms['" + form_name + "']." + listto + ".length]=opt");
}
function remove(form_name,listfrom){
   eval("selIndex=window.document.forms['" + form_name + "']." + listfrom + ".selectedIndex");
   if ( selIndex < 0 ) return;
   eval("selIndex=window.document.forms['" + form_name + "']." + listfrom + ".options[" + selIndex + "] = null");
}
function removem(form_name,listfrom){
   var arrstr = "0";
   eval("fromlen=window.document.forms['" + form_name + "']." + listfrom + ".length");
   for (var j=0; j<fromlen; j++){
      eval("selitem=window.document.forms['" + form_name + "']." + listfrom + "[" + j + "].selected");
      if (selitem){
         selIndex = j;
         eval("selValue=window.document.forms['" + form_name + "']." + listfrom + ".options[" + selIndex + "].value");
         arrstr = arrstr + ',' + selValue;
      }
   }
   eval("selItem=new Array(" + arrstr + ")");
   for (var j=0; j<selItem.length; j++){
      eval("len=window.document.forms['" + form_name + "']." + listfrom + ".length");
      for (var i=0; i < len; i++){
         eval("tmpValue=window.document.forms['" + form_name + "']." + listfrom + ".options[" + i + "].value");
         if ( selItem[j] == tmpValue ){
            eval("window.document.forms['" + form_name + "']." + listfrom + ".options[" + i + "] = null");
            break;
         }
      }
   }
}
function list2str(form_name,listfrom,strto){
   var result = "";
   var tmpValue = "";
   eval("len=window.document.forms['" + form_name + "']." + listfrom + ".length");
   for (i=0; i < len; i++){
      eval("tmpValue=window.document.forms['" + form_name + "']." + listfrom + ".options[" + i + "].value");
      result = result + tmpValue + ";";
   }
   eval("window.document.forms['" + form_name + "']." + strto + ".value='" + result + "'");
}
function sbmit(){
   if ( window.document.form_news_letter ){
      if (check_mail(window.document.form_news_letter.email)){
         window.document.form_news_letter.submit();
      }
   }
   else{
      if (check_mail(top.frames[0].document.form_news_letter.email)){
         top.frames[0].document.form_news_letter.submit();
      }
   }
}
function mouseover(rt,id){
   if ( !isLoadedPage ) return;
   if ( !self.document.all ) return;
   self.document.all['cat1_' + id].background = rt + 'images/category_background_active.gif';
   self.document.all['cat2_' + id].background = rt + 'images/category_background_active.gif';
   self.document.all['cat3_' + id].background = rt + 'images/category_background_active.gif';
   self.document.all['cat_arrow_' + id].src   = rt + 'images/category_arrow.gif';
}
function mouseout(rt,id,status){
   if ( !isLoadedPage ) return;
   if ( !self.document.all ) return;
   if ( status != 'on' ){
      self.document.all['cat1_' + id].background = rt + 'images/category_background.gif';
      self.document.all['cat2_' + id].background = rt + 'images/category_background.gif';
      self.document.all['cat3_' + id].background = rt + 'images/category_background.gif';
      self.document.all['cat_arrow_' + id].src   = rt + 'images/category_background.gif';
   }
}
function mouseclick(rt,url,id){
   if ( !isLoadedPage ) return;
   if ( !self.document.all ) return;
   mouseover(rt,id);
   top.document.location.href=url;
}
function searchMenu(href,opt){
   new_url = '';
   href1 = href.substr(0,href.indexOf(".html"));
   if ( href1 != '' ){
      lschar = href1.substr(href1.length-2);
      new_url = href1;
      if ( lschar == "_m" || lschar == "_p" ){
         new_url = href1.substr(0,href1.length-2);;
      }
      new_url = new_url+opt+'.html';
   }
   else{
      new_url = href + '&ST=' + opt;
   }
   return new_url;
}

function afp_stat() {

    // using function written by Valery Zavolodko
    // for smarter.com/jscript/cookie.js)
    var afpie = getCookie("AFP");

    var afp_statscript = "http://affiliates.smarter.com/afp_altclick.php";

    var url = top.document.location.search;
    var src = "";
    var params = "";

    if( afpie != "1" ) {
        // if cookie "AFP" is absent, create new cookie for AFP
        // don't set expiration time to remove cookie after browser window is closed
        setCookie("AFP", "1", "/", ".smarter.com");

        if (url.indexOf('crid=') > 0 && url.indexOf('afid=') > 0) {
            params = url.substring(url.indexOf('crid='), url.length);
            src = afp_statscript + '?' + params;
            document.write('<img src="'+ src + '" border="0" alt="" width="1" height="1">');
            //  = params.split();
             crid = ""; afid = "";

            pairs = params.split("&");

            cridpair = pairs[0];
            pair = cridpair.split("=");
            crid = pair[1];

            afidpair = pairs[1];
            pair = afidpair.split("=");
            afid = pair[1];

            setCookie("CRID", crid, "/", ".smarter.com");
            setCookie("AFID", afid, "/", ".smarter.com");
        }
    }
}

function showmenu()
{
  var el = document.getElementById("channels");
  var iframe_menu = document.getElementById('iframe_menu');
  if (el) {
    el.style.visibility = "visible";
      iframe_menu.style.width = el.offsetWidth;
      iframe_menu.style.height = el.offsetHeight;
      iframe_menu.style.top = el.style.top;
      iframe_menu.style.left = document.body.clientWidth-el.offsetWidth;
      iframe_menu.style.zIndex = el.style.zIndex - 1;
      iframe_menu.style.display = "block";
    show = 1;
  }
}
function hidemenu()
{
  show = 0;
  setTimeout("hide()", 600);
}
function hide()
{
  var el = document.getElementById("channels");
  var iframe_menu = document.getElementById('iframe_menu');
  if (el) {
    if (!show)
    {
      el.style.visibility = "hidden";
      iframe_menu.style.display = "none";
    }
  }
}

//add base64encode and base64decode by Genray 2005-6-22
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);

function base64encode(str) {
    var out, i, len;
    var c1, c2, c3;

    len = str.length;
    i = 0;
    out = "";
    while(i < len) {
 c1 = str.charCodeAt(i++) & 0xff;
 if(i == len)
 {
     out += base64EncodeChars.charAt(c1 >> 2);
     out += base64EncodeChars.charAt((c1 & 0x3) << 4);
     out += "==";
     break;
 }
 c2 = str.charCodeAt(i++);
 if(i == len)
 {
     out += base64EncodeChars.charAt(c1 >> 2);
     out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
     out += base64EncodeChars.charAt((c2 & 0xF) << 2);
     out += "=";
     break;
 }
 c3 = str.charCodeAt(i++);
 out += base64EncodeChars.charAt(c1 >> 2);
 out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
 out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
 out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}

function base64decode(str) {
    var c1, c2, c3, c4;
    var i, len, out;

    len = str.length;
    i = 0;
    out = "";
    while(i < len) {
 /* c1 */
 do {
     c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
 } while(i < len && c1 == -1);
 if(c1 == -1)
     break;

 /* c2 */
 do {
     c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
 } while(i < len && c2 == -1);
 if(c2 == -1)
     break;

 out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));

 /* c3 */
 do {
     c3 = str.charCodeAt(i++) & 0xff;
     if(c3 == 61)
  return out;
     c3 = base64DecodeChars[c3];
 } while(i < len && c3 == -1);
 if(c3 == -1)
     break;

 out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));

 /* c4 */
 do {
     c4 = str.charCodeAt(i++) & 0xff;
     if(c4 == 61)
  return out;
     c4 = base64DecodeChars[c4];
 } while(i < len && c4 == -1);
 if(c4 == -1)
     break;
 out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
    }
    return out;
}