#!/usr/bin/perl
#########################################################################################
# Software				asRep Full
# Version				1.40
# Released Date			April 15, 2004 
#
# COPYRIGHT NOTICE
# Copyright 2004 Mehmet Oner. All Rights Reserved.
#
# Web site: http://www.asrep.com/
# E-Mail: asrep@asrep.com
#	
# This is a commercial software protected by the copyright laws and international 
# copyright treaties, as well as other intellectual property laws and treaties.
#
# This software is licensed to the web site where the first update was done,
# under the terms and conditions stated in http://www.asrep.com/license.txt file,
# which was agreed by the purchaser before the purchase. Installing on an 
# other web address without prior permission is illegal. User of this software agrees 
# to supply a registration key given to the purchaser as a proof of purchase at any time 
# when the copyright owner requests it. Selling, redistributing, and renting this 
# software by any means on any medium without prior written permission from Mehmet Oner 
# is expressly and strictly forbidden and illegal. You can make uninstalled limited copies 
# for backup purposes.   
#########################################################################################
use 5.004 ;
use strict ;
my $installDir ;
BEGIN { 
   use CGI::Carp qw(fatalsToBrowser carpout ) ; carpout(\*STDOUT) ;
   $installDir = ($ENV{SCRIPT_FILENAME} =~ m<^(.*)/(.*?)$>) && (-e "$1/$2") ? $1 :
     ($0 =~ m<^(.*)[/\\](.*?)$>) && (-e "$1/$2") ? $1 :
     require FindBin && (-e "$FindBin::RealBin/$FindBin::RealScript") ? $FindBin::RealBin :
     (-e "$FindBin::Bin/$FindBin::Script") ? $FindBin::Bin :
     '.' ;
   unshift @INC, $installDir ;
}
require 'utils.pl' ;
my $cgiPars = getInputs();

require 'settings.pl' ;
my $scrUrl = Utils::Urls();
($C::Cfg{Url}, $C::Cfg{DirUrl}, $C::Cfg{AbsUrl}, $C::Cfg{BaseUrl}, $C::Cfg{PathUrl}) = Utils::Urls() ;


if (! keys %$cgiPars) {# JS for diagnosis and view code
  viewJS(\%C::Cfg) ;

}elsif (exists($cgiPars->{rep}) && $cgiPars->{rep} eq 'v') { # view report + click code
  if (exists($cgiPars->{transport}) && $cgiPars->{transport} eq 'img') {
    saveViewFromImg(\%C::Cfg, $cgiPars) ;
    sendDummyImage() ;
  }else{
    saveView(\%C::Cfg, $cgiPars) ;
    clickJS(\%C::Cfg, $cgiPars, $C::Cfg{Url}) ;
  }

}elsif (exists($cgiPars->{rep}) && $cgiPars->{rep} eq 'altads') { 
  saveAltAds(\%C::Cfg, $cgiPars) ;
  sendDummyImage() ;
  
}elsif (exists($cgiPars->{rep}) && ($cgiPars->{rep} eq 'c' || $cgiPars->{rep} eq 's')) { 
  if ($cgiPars->{rep} eq 'c'){ # click report
    saveClick(\%C::Cfg, $cgiPars) ;
  }else{ # submit report
    saveSubmit(\%C::Cfg, $cgiPars) ;
  }
  if (exists($cgiPars->{transport}) && $cgiPars->{transport} eq 'img') {
     sendDummyImage() ;
  }else {
     print "Cache-Control: no-store, no-cache, must-revalidate\n" ;
     print "Cache-Control: post-check=0, pre-check=0\n" ;
  	 print "Content-Type: text/html\n\n" ;
  	 print "<html><head><title>asRep</title></head><body>",
      "<script language='javascript' type='text/javascript'><!--\n",
      "window.close();\n",
      "//--></script>\n",
	  "You can safely close this window.",
	  "</body></html>" ;
  }

}else { # for sake of completeness
  print "Content-Type: text/javascript\n\n " ;
}
#------------------------------
sub getInputs {
  my %pars = () ;
  my $qstr = '' ;
  if ($ENV{'REQUEST_METHOD'} eq 'POST') {
     read(STDIN, $qstr, $ENV{'CONTENT_LENGTH'}, 0)  if $ENV{'CONTENT_LENGTH'} > 0;
  }else {
     $qstr = $ENV{'QUERY_STRING'} || $ENV{'REDIRECT_QUERY_STRING'} ;
  }
  if (length $qstr) {
     foreach (split(/[&;]/, $qstr)) {
       my ($param, $value) = split('=', $_, 2) ;
       $pars{unescape($param)} = unescape(defined($value) ? $value : '') ;
     }
  }
  return \%pars ;
}
#------------------------
sub escape {
   my ($toencode) = @_ ;

   $toencode =~ s/([^a-zA-Z0-9_.-])/uc sprintf('%%%02x',ord($1))/eg ;
   return $toencode;
}
#------------------------
sub unescape {
   my ($todecode) = @_ ;

   $todecode =~ tr/+/ / ;  # pluses become spaces
   $todecode =~ s/%([0-9a-fA-F]{2})/chr hex($1)/ge;
   return $todecode;
}
#------------------------------
my %Cookies = () ;
my $CookiesSet = 0 ;
#------------------------
# Fetch the cookies from environment
sub getCookie {
  my ($name) = @_ ;
  my @pairs = split("; ?", $ENV{HTTP_COOKIE} || $ENV{COOKIE}) ;
  if (!$CookiesSet) {
    foreach (@pairs) {
      s/\s*(.*?)\s*/$1/ ;
      my ($key, $value) = split("=") ;
      next if !defined($value);
      my @values = () ;
      if ($value ne '') {
         @values = map unescape($_), split(/[&;]/, $value.'&dmy') ;
         pop @values ;
      }
      $Cookies{unescape($key)} ||= \@values ;
    }
    $CookiesSet = 1 ;
  }
  return () unless %Cookies ;
  return keys %Cookies unless $name ;
  return () unless $Cookies{$name} ;
  return wantarray ? @{ $Cookies{$name} } : $Cookies{$name}->[0] ;
}
#------------------------------
sub setCookie {
   my ($name, $value, $expires, $path, $domain, $secure) = @_ ;

   return undef unless defined($name) && $name ne '' ;
   my @values ;
   if (ref($value)) {
      if (ref($value) eq 'ARRAY') {
         @values = @$value ;
      } elsif (ref($value) eq 'HASH') {
         @values = %$value ;
      }
   } else {
      @values = ($value) ;
   }
   $path ||= "/" ;
   if (length($expires)) {
      my @mons  = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/ ;
      my @wdays = qw/Sun Mon Tue Wed Thu Fri Sat/ ;
      my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($expires) ;
      $expires = sprintf('%s, %02d-%s-%04d %02d:%02d:%02d GMT', $wdays[$wday], $mday, $mons[$mon], $year+1900, $hour, $min, $sec) ;
   }
   my @constant_values ;
   push(@constant_values, "domain=$domain") if $domain ;
   push(@constant_values, "path=$path") if $path ;
   push(@constant_values, "expires=$expires") if $expires ;
   push(@constant_values, "secure") if $secure ;

   my $key = escape($name) ;
   my $cookie = $key . '=' . join("&", map escape($_), @values) ;
   return join("; ", $cookie, @constant_values) ;
}
#------------------------------
sub sendDummyImage{
  print "Cache-Control: no-store, no-cache, must-revalidate\n" ;
  print "Cache-Control: post-check=0, pre-check=0\n" ;
  print "Content-Type: image/gif\n\n" ;
  print "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\xFF\xFF\xFF" .
	"\x21\xF9\x04\x01\x00\x00\x01\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x40\x02\x02\x4C\x01\x00\x3B" ;
}
#------------------------------
sub saveViewFromImg {
  my ($cfg, $pars) = @_ ;

  my $errstr ;
  my $dbh = Utils::DBI_Connect('mysql',$cfg->{DbName},$cfg->{DbHost},$cfg->{DbPort},$cfg->{DbUser},$cfg->{DbPass}, \$errstr) ;
  return unless $dbh ;

  # save click received from cookie
  if (getCookie("asRep_click")) {
    my %kv = () ;
    foreach (split /\&/, getCookie("asRep_click")) {
       my ($k, $v) = split /=/ ;
	   $kv{$k} = unescape($v) ;
	}
	if ($kv{rep} eq 'c'){
      saveClickRecord($dbh, $cfg, $kv{tv}, $kv{id}, $kv{tc}, status2Url($kv{st}), $kv{cau}, $kv{cver}) ;
	}elsif ($kv{rep} eq 's'){
	  saveSubmitRecord($dbh, $cfg, $kv{tv}, $kv{id}, $kv{ts}, $kv{q}, $kv{web}, $kv{wsno}) ;
	}
    print "Set-Cookie: ", setCookie('asRep_click', '', time()-24*60*60, '/'), "\n" ;
  }
  # If there is no page info, forget it.
  unless ($ENV{"HTTP_REFERER"}) {
    $dbh->disconnect() ;
    return ;
  }

  # save new view record  
  my ($domain, $page) = urlParts($ENV{"HTTP_REFERER"});

  my $domainId = saveStringDb($dbh, $cfg->{Tbl}{Domains}, $domain) ;
  my ($pageId, $inserted) = saveStringDb($dbh, $cfg->{Tbl}{Pages}, $page) ;
  saveDirsDb($dbh, $cfg, $page, $pageId) if ($inserted) ;

  my $gasIds = [0,0,0,0] ;
  my ($wsChId1,$wsChId2) = (0,0) ;
  my $pinfoId = savePageInfoDb($dbh, $cfg, $pageId,$domainId,$gasIds,$wsChId1,$wsChId2) ;
  ###
  my ($rdomain, $rpage) = urlParts('Unknown (IMG tracking, JavaScript is disabled)');
  my $rdomainId = saveStringDb($dbh, $cfg->{Tbl}{rDomains}, $rdomain) ;
  my $rpageId = saveRefPageDb($dbh, $cfg, $rpage, $rdomainId) ;
  ###
  my $ip = 0+Utils::IPstr2num(Utils::VisIP());
  my $ccode = IP2CC($dbh, $cfg, $ip) ;
  ###
  my $nav = 'other' ;
  my $uagent = '' ;
  if ($ENV{"HTTP_USER_AGENT"}) {
    $uagent = $ENV{"HTTP_USER_AGENT"} ;
    if ( ($uagent =~ /MSIE/) && ($uagent !~ /opera/i)){ $nav = 'msie' ;
    }elsif ($uagent =~ /gecko/i){ $nav = 'gecko' ;
    }else{ $nav = 'other' ; }
  }
  
  my $auinfo1 = $nav eq 'msie' ? 1 : ($nav eq 'gecko' ? 2 : 4 ) ;
  my $auinfo2 = 0;
  ###
  $pars->{tv} = Utils::GMTime() ;
  $pars->{id} = Utils::FingerPrint(int(rand(1024)).$ip.$domain.$page.$uagent, 1)  ;
  
  my $qstr = "INSERT INTO $cfg->{Tbl}{Logs}".
  " (vTime,Id,cTime,adId,auInfo1,auInfo2,Ip,cCode,piId,rpagId)" .
  " VALUES ($pars->{tv},$pars->{id},0,0,$auinfo1,$auinfo2,$ip,".$dbh->quote($ccode).",$pinfoId,$rpageId)" ;
  my $errstr ;
  Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
  
  $dbh->disconnect() ;
}
#------------------------------
sub saveView {
  my ($cfg, $pars) = @_ ;
  
  my $errstr ;
  my $dbh = Utils::DBI_Connect('mysql',$cfg->{DbName},$cfg->{DbHost},$cfg->{DbPort},$cfg->{DbUser},$cfg->{DbPass}, \$errstr) ;
  return unless $dbh ;

  # save click received from cookie
  if (exists($pars->{cdata}) && $pars->{cdata}) {
    my %kv = () ;
    for (split /&/, $pars->{cdata}) {
	  my ($k, $v) = split /=/ ;
	  $kv{$k} = unescape($v) ;
	}
	if ($kv{rep} eq 'c'){
       saveClickRecord($dbh, $cfg, $kv{tv}, $kv{id}, $kv{tc}, status2Url($kv{st}), $kv{cau}, $kv{cver}) ;
	}elsif ($kv{rep} eq 's'){
	   saveSubmitRecord($dbh, $cfg, $kv{tv}, $kv{id}, $kv{ts}, $kv{q}, $kv{web}, $kv{wsno}) ;
	}
  }

  # save new view record  
  my ($domain, $page) = urlParts(unescape($pars->{p}) || $ENV{"HTTP_REFERER"} || 'Direct Request');

  my $domainId = saveStringDb($dbh, $cfg->{Tbl}{Domains}, $domain) ;
  my ($pageId, $inserted) = saveStringDb($dbh, $cfg->{Tbl}{Pages}, $page) ;
  saveDirsDb($dbh, $cfg, $page, $pageId) if ($inserted) ;
  my $gasIds = saveGasVarsDb($dbh, $cfg, $pars) ;
  my ($wsChId1,$wsChId2) = saveWSChannelsDb($dbh, $cfg, $pars) ;
  my $pinfoId = savePageInfoDb($dbh, $cfg, $pageId,$domainId,$gasIds,$wsChId1,$wsChId2) ;
  ###
  my ($rdomain, $rpage) = urlParts($pars->{ref} || 'Direct Request');
  my $rdomainId = saveStringDb($dbh, $cfg->{Tbl}{rDomains}, $rdomain) ;
  my $rpageId = saveRefPageDb($dbh, $cfg, $rpage, $rdomainId) ;
  ###
  my $ip = 0+Utils::IPstr2num(Utils::VisIP());
  my $ccode = IP2CC($dbh, $cfg, $ip) ;
  ###
  my $auinfo1 = (($pars->{wsn} > 2 ? 2 : $pars->{wsn}) * 64) + 
   		     (( ($gasIds->[0]>0 ? 1:0)+($gasIds->[1]>0 ? 1:0)+($gasIds->[2]>0 ? 1:0) ) * 16) + 
   		     (( $gasIds->[3]>0 ? 1:0 ) * 8) + 
  		     ($pars->{nav} eq 'msie' ? 1 : ($pars->{nav} eq 'gecko' ? 2 : 4 )) ;
  my $auinfo2 = 0;
  my $ii = 0 ;
  for(my $i=0 ; $i < $pars->{asn} ; ++$i){
	if (exists($pars->{'format'.$i}) && index($pars->{'format'.$i},'0ads')>=0 ) { # ad link
	}else{
	  if ($ii < 3){
	    $auinfo2 |= (exists($pars->{'aua'.$i}) ? ($pars->{'aua'.$i}?1:0) : 0) << $ii++ ;
	  }
	}
  }
  ###
  my $qstr = "INSERT INTO $cfg->{Tbl}{Logs}".
  " (vTime,Id,cTime,adId,auInfo1,auInfo2,Ip,cCode,piId,rpagId)" .
  " VALUES ($pars->{tv},$pars->{id},0,0,$auinfo1,$auinfo2,$ip,".$dbh->quote($ccode).",$pinfoId,$rpageId)" ;
  my $errstr ;
  Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
  
  $dbh->disconnect() ;
}
#------------------------------
sub saveAltAds {
  my ($cfg, $pars) = @_ ;
  
  my $errstr ;
  my $dbh = Utils::DBI_Connect('mysql',$cfg->{DbName},$cfg->{DbHost},$cfg->{DbPort},$cfg->{DbUser},$cfg->{DbPass}, \$errstr) ;
  return unless $dbh ;
  
  my $qstr = "UPDATE $cfg->{Tbl}{Logs}".
  		" SET auInfo2=(auInfo2 & (255-7)) | ($pars->{altads} & 7)" .
  		" WHERE vTime=$pars->{tv} AND Id=$pars->{id}" ;
  my $errstr ;
  Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
  
  $dbh->disconnect() ;
}
#------------------------------
sub urlParts {
  my ($url) = @_ ;

  my ($domain, $page) ;
  my $domsi = index($url, '://') ;
  $domsi = $domsi < 0 ? 0 : 3+$domsi ;
  my $domei = index($url, '/', $domsi) ;
  if ($domei < 0) {
    $domain = lc substr($url, $domsi) ;   
    $page = '/' ;
  }else {
    $domain = lc substr($url, $domsi, $domei-$domsi) ;   
    $page = substr($url, $domei) ;
  }
  $domain = substr($domain, 4) if substr($domain, 0, 4) eq 'www.' ;
  return ($domain, $page) ;
}
#------------------------------
sub saveGasVarsDb{
  my ($dbh, $cfg, $pars) = @_ ;
  
  my $errstr ;
  my @ids = (0,0,0, 0) ; #0,1,2 : ad units, 3: ad links
  my @gvkeys = ('format','fb','color_bg','color_text','color_link','color_url','color_border','color_line') ;
  my $ii = 0 ;
  for (my $i=0 ; $i < $pars->{asn} ; $i++) {
    my $fpstr = '' ;
    my $wherestr = '' ;
    my $valstr = '' ;
  
    foreach my $k (@gvkeys){
	  my $v = exists($pars->{$k.$i}) ? $pars->{$k.$i} : '';
	  $fpstr .= $v ;
	  $wherestr .= ' AND ' . $k . '=' . $dbh->quote($v) ;
	  $valstr .= ',' . $dbh->quote($v) ;
    }
    my $chid = saveChannelDb($dbh, $cfg, exists($pars->{'channel'.$i}) ? $pars->{'channel'.$i} : "", 0) ;

    my $fp = Utils::FingerPrint($chid.$fpstr, 2) ;
    my $qstr = "SELECT Id FROM $cfg->{Tbl}{AdSense} WHERE FP=$fp AND chId=$chid $wherestr LIMIT 1" ;
    my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
	my $asid = 0 ;
    if ($sth) {
       ($asid) = $sth->fetchrow_array() ;
  	   $sth->finish() ;
    }
    if (!$asid) { # Not in table
       $qstr = "INSERT INTO $cfg->{Tbl}{AdSense} (Id,FP,chId," . join(',', @gvkeys) . ") VALUES (NULL,$fp,$chid$valstr)" ;
       Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
       $asid = 0+$dbh->{'mysql_insertid'} ;
    }
	if (exists($pars->{'format'.$i}) && index($pars->{'format'.$i},'0ads')>=0 ) { # ad link
	  $ids[3] = $asid ;
	}else{
	  if ($ii < 3){ $ids[$ii++] = $asid ; }
	}
  }
  return \@ids ;
}
#------------------------------
sub saveWSChannelsDb{
  my ($dbh, $cfg, $pars)=@_ ;

  my @ids = (0,0) ;
  for (my $i=0 ; $i < $pars->{wsn} ; $i++) {
    $ids[$i] = saveChannelDb($dbh, $cfg, exists($pars->{'wsc'.$i}) ? $pars->{'wsc'.$i} : "", 1) ;
  }
  return @ids ;
}
#------------------------------
sub saveChannelDb{
  my ($dbh, $cfg, $channel, $ws) = @_ ;
  
  my $id = 0 ;
  my $qstr = "SELECT Id FROM $cfg->{Tbl}{Channels} WHERE channel=".$dbh->quote($channel)." AND " .
          ($ws ? "ISNULL(ws)=0":"ISNULL(ws)>0") ." LIMIT 1" ;
  my $errstr ;
  my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
  if ($sth) {
     ($id) = $sth->fetchrow_array() ;
   	 $sth->finish() ;
  }
  if (!$id) { # Not in table
     $qstr = "INSERT INTO $cfg->{Tbl}{Channels} (Id,channel,ws,name) VALUES (NULL,".$dbh->quote($channel).
	 	     ",".($ws ? "''":"NULL").",'')" ;
     Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
     $id = $dbh->{'mysql_insertid'} ;
  }
  return 0+$id ;
}
#------------------------------
sub saveDirsDb {
  my ($dbh, $cfg, $page, $pageId) = @_ ;
  
  my $qstr = "INSERT INTO $cfg->{Tbl}{Dirs} (pagId,offset,leaf) VALUES " ;
  my $sep = '' ;
  my $qmarkoff = index($page, '?', 0) ;
  my $limit = ($qmarkoff >= 0 && $qmarkoff < 255) ? $qmarkoff : 255 ;
  my $i = index($page, '/', 0) ;
  while($i >= 0 && $i < $limit){
    my $offset = $i + 1 ;
	$i = index($page, '/', $offset) ;
	if ($i < 0 || $i >= $limit) { # longest directory (leaf)
	  $qstr .= "$sep($pageId, $offset, '')" ;
	}else{
	  $qstr .= "$sep($pageId, $offset, NULL)" ;
	}
	$sep = ',' ;
  }
  my $errstr ;
  Utils::DBI_DoQuery($dbh, $qstr, \$errstr) if $sep ;
}
#------------------------------
sub savePageInfoDb{
  my ($dbh, $cfg, $pageId,$domId,$asIds,$wsChId0,$wsChId1) = @_ ;
  
  my $errstr ;
  my $id = 0 ;
  my $qstr = "SELECT Id FROM $cfg->{Tbl}{PageInfo}".
  		  " WHERE pagId=$pageId AND domId=$domId AND asId0=$asIds->[0] AND asId1=$asIds->[1] AND asId2=$asIds->[2] AND asId3=$asIds->[3]".
		  " AND wsChId0=$wsChId0 AND wsChId1=$wsChId1 LIMIT 1" ;
  my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
  if ($sth) {
     ($id) = $sth->fetchrow_array() ;
  	 $sth->finish() ; ;
  }
  if (!$id) { # Not in table
     $qstr = "INSERT INTO $cfg->{Tbl}{PageInfo} (Id,pagId,domId,asId0,asId1,asId2,asId3,wsChId0,wsChId1)" .
	 	     " VALUES (NULL,$pageId,$domId,$asIds->[0],$asIds->[1],$asIds->[2],$asIds->[3],$wsChId0,$wsChId1)" ;
     Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
     $id = $dbh->{'mysql_insertid'} ;
  }
  return 0+$id ;
}
#------------------------------
sub saveRefPageDb {
  my ($dbh, $cfg, $page, $rdomId) = @_ ;

  my $errstr ;
  my $id = 0 ;
  my $fp = Utils::FingerPrint($page, 2) ;
  my $qstr = "SELECT Id FROM $cfg->{Tbl}{rPages} WHERE FP=$fp AND rdomId=$rdomId AND Value=".$dbh->quote($page)." LIMIT 1" ;
  my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
  if ($sth) {
     ($id) = $sth->fetchrow_array() ;
  	 $sth->finish() ; ;
  }
  if (!$id) { # Not in table
     $qstr = "INSERT INTO $cfg->{Tbl}{rPages} (Id, FP, rdomId, Value) VALUES (NULL,$fp,$rdomId,".$dbh->quote($page).")" ;
     Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
     $id = 0+$dbh->{'mysql_insertid'} ;
  }
  return 0+$id ;
}
#------------------------------
sub saveStringDb {
  my ($dbh, $tbl, $str) = @_ ;
  
  my $errstr ;
  my $id = 0 ;
  my $inserted = 0 ;
  my $fp = Utils::FingerPrint($str, 2) ;
  my $qstr = "SELECT Id FROM $tbl WHERE FP=$fp AND Value=".$dbh->quote($str)." LIMIT 1" ;
  my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
  if ($sth) {
     ($id) = $sth->fetchrow_array() ;
     $sth->finish() ;
  }
  unless ($id) { # Not in table
     $qstr = "INSERT INTO $tbl (Id,FP,Value) VALUES (NULL, $fp, " . $dbh->quote($str) . ")" ;
     Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
     $id = $dbh->{'mysql_insertid'} ;
	 $inserted = 1 ;
  }
  return wantarray ? (0+$id, $inserted) : 0+$id ;
}
#------------------------------
sub IP2CC {
  my ($dbh, $cfg, $ip) = @_ ;
  
  my $qstr = "SELECT Code FROM $cfg->{Tbl}{IpRanges}" .
     " WHERE ($ip>>16)=IpSeg AND $ip>=StartIp AND $ip<=EndIp LIMIT 1" ;
  my $errstr ;
  my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
  my ($ccode) = $sth->fetchrow_array() ;
  $sth->finish();
  return $ccode ? $ccode : "??" ;
}
#------------------------------
sub status2Url{
  my($status) = @_ ;

  my $adurl = 'Unknown' ;
  if (defined($status) && length($status)>1) {
    $adurl = $status ;
    my @segments = split / /, $status ;
	my $url = '' ;
    for my $segment (@segments) {
	  if (index($segment, '.') > -1 && length($segment)>length($url)){
	    $url = $segment ;
	  }
    }
    if ($url) {
	   my ($ad, $ap) = urlParts($url) ;
	   $adurl = $ad . ($ap eq '/' ? '':$ap) ;
	}
  }
  return $adurl ;
}
#------------------------------
sub saveClick {
  my ($cfg, $pars) = @_ ;
  
  my $errstr ;
  my $dbh = Utils::DBI_Connect('mysql', $cfg->{DbName}, $cfg->{DbHost}, $cfg->{DbPort},
                               $cfg->{DbUser}, $cfg->{DbPass}, \$errstr) ;
  return unless $dbh ;

  saveClickRecord($dbh, $cfg, $pars->{tv}, $pars->{id}, $pars->{tc}, status2Url($pars->{st}), $pars->{cau}, $pars->{cver}) ;
  
  $dbh->disconnect();
}
#------------------------------
sub saveClickRecord {
  my ($dbh, $cfg, $tv, $id, $tc, $adurl, $cau, $cver) = @_ ;
  
  return if ($cau<0 || $cau>3) ;

  my $qstr = "SELECT cTime, auInfo1, auInfo2, Ip, cCode, piId, rpagId, adId FROM $cfg->{Tbl}{Logs} WHERE vTime=$tv AND Id=$id" ;
  my $errstr ;
  my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
  return if (!$sth) ; 
  my $row_r = $sth->fetchrow_arrayref() ;
  $sth->finish();
  return if (!$row_r) ;
  
  $tc=1 if(!$tc) ;
  
  if ($row_r->[0]==0 || ($cver && ($row_r->[2]&192)==128 && $cau==(($row_r->[2]&48)>>4))) { #update the current record
    my $adUrlId = saveStringDb($dbh, $cfg->{Tbl}{AdUrls}, $adurl) ;
    my $auinfo2 = ($cver?0:1)*128 + ($cau & 3) * 16 ;

    $qstr = "UPDATE $cfg->{Tbl}{Logs} SET cTime=$tc,adId=$adUrlId,auInfo2=(auInfo2&15)|$auinfo2".
  	   " WHERE vTime=$tv AND Id=$id" . ($cver ? "" : " AND cTime=0")  ;
    Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
  
  }elsif ($row_r->[0] < $tc && $cver){ # Insert as new record
    my $adUrlId = saveStringDb($dbh, $cfg->{Tbl}{AdUrls}, $adurl) ;
    if ($row_r->[1]&2 || $adUrlId != $row_r->[7]){ # if gecko or new ad
      my $auinfo2 = ($cver?0:1)*128 + ($cau & 3) * 16 ;

      $id = ($id+$tc) % 256 ;
	  $row_r->[2] = ($row_r->[2]&15)|$auinfo2 ;
      $qstr = "INSERT INTO $cfg->{Tbl}{Logs}".
        " (vTime,Id,cTime,auInfo1,auInfo2,Ip,cCode,piId,rpagId,adId)" .
  	    " VALUES ($tv,$id,$tc,$row_r->[1],$row_r->[2],$row_r->[3],".$dbh->quote($row_r->[4]).
		",$row_r->[5],$row_r->[6],$adUrlId)" ;
  	  Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
	}
  }
}
#------------------------------
sub saveSubmit {
  my ($cfg, $pars) = @_ ;
  my $errstr ;
  my $dbh = Utils::DBI_Connect('mysql', $cfg->{DbName}, $cfg->{DbHost}, $cfg->{DbPort},
                               $cfg->{DbUser}, $cfg->{DbPass}, \$errstr) ;
  return unless $dbh ;

  saveSubmitRecord($dbh, $cfg, $pars->{tv}, $pars->{id}, $pars->{ts}, $pars->{q}, $pars->{web}, $pars->{wsno}) ;
  
  $dbh->disconnect();
}
#------------------------------
sub saveSubmitRecord {
  my ($dbh, $cfg, $tv, $id, $ts, $q, $web, $wsno) = @_ ;
  
  my $qstr = "SELECT cTime, auInfo1, auInfo2, Ip, cCode, piId, rpagId, adId FROM $cfg->{Tbl}{Logs} WHERE vTime=$tv AND Id=$id" ;
  my $errstr ;
  my $sth = Utils::DBI_ExecQuery($dbh, $qstr, \$errstr) ;
  return if (!$sth) ; 
  my $row_r = $sth->fetchrow_arrayref() ;
  $sth->finish();
  return if (!$row_r) ;

  $ts=1 if(!$ts) ;
  
  if ($row_r->[0] == 0) { #update the current record
    my $queryId = saveStringDb($dbh, $cfg->{Tbl}{AdUrls}, $q) ;
    my $auinfo2 = ($web?1:0)*128 + 64 + ($wsno & 3) * 16 ;

    $qstr = "UPDATE $cfg->{Tbl}{Logs} SET cTime=$ts,adId=$queryId,auInfo2=(auInfo2&15)|$auinfo2".
  	   " WHERE vTime=$tv AND Id=$id AND cTime=0" ;
    Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
  }elsif ($row_r->[0] < $ts){ # Insert as new record
    my $queryId = saveStringDb($dbh, $cfg->{Tbl}{AdUrls}, $q) ;
    if ($queryId != $row_r->[7]){
      my $auinfo2 = ($web?1:0)*128 + 64 + ($wsno & 3) * 16 ;
      $id = ($id+$ts) % 256 ;
	  $row_r->[2] = ($row_r->[2]&15)|$auinfo2 ;
      $qstr = "INSERT INTO $cfg->{Tbl}{Logs}".
       " (vTime,Id,cTime,auInfo1,auInfo2,Ip,cCode,piId,rpagId,adId)" .
  	   " VALUES ($tv,$id,$ts,$row_r->[1],$row_r->[2],$row_r->[3],".$dbh->quote($row_r->[4]).
	   ",$row_r->[5],$row_r->[6],$queryId)" ;
      Utils::DBI_DoQuery($dbh, $qstr, \$errstr) ;
	}
  }
}
#------------------------------
sub viewJS {
  my ($cfg) = @_ ;

  my $vIP = 0+Utils::IPstr2num(Utils::VisIP()) ;
  my $thePage = $ENV{"HTTP_REFERER"} || '' ;
  my $uAgent = $ENV{"HTTP_USER_AGENT"} || '' ;
  my $recViewTime = Utils::GMTime() ;
  my $recId = Utils::FingerPrint(int(rand(1024)).$vIP.$thePage.$uAgent, 1) ;

  $scrUrl = $cfg->{Url} ;

  print "Cache-Control: no-store, no-cache, must-revalidate\n" ;
  print "Cache-Control: post-check=0, pre-check=0\n" ;

  if (getCookie('asRepBlockTracking')) { # block tracking
    print "Set-Cookie: ", setCookie('asRepBlockTracking', '1', time()+180*24*60*60, $cfg->{PathUrl}), "\n" ;
    print "Content-Type: text/javascript\n\n" ;
    print " \n" ;
    return ;
  }
  if (exists($cfg->{blockedIps}) && @{$cfg->{blockedIps}}) {
    foreach my $iprange (@{$cfg->{blockedIps}}) {
      if ($vIP >= $iprange->[0] && $vIP < ($iprange->[0]+$iprange->[1])) {
        print "Content-Type: text/javascript\n\n" ;
        print " \n" ;
    	return ;
	  }
	}
  }
  print "Content-Type: text/javascript\n\n" ;

  print <<"END_JS" ;
function asRep_nav(){
if(navigator.appName.toLowerCase()=="microsoft internet explorer"&&typeof(window.onbeforeunload)!='undefined')return 'msie';
if(navigator.userAgent.search(/gecko/i)>=0)return 'gecko';
return 'other';
}
function asRep_getifrms(nam){
if(document.all&&document.all(nam)){var a=document.all(nam);return a.length?a:new Array(a);}
if(document.getElementsByName&&document.getElementsByName(nam))return document.getElementsByName(nam);
if(document.getElementsByTagName&&document.getElementsByTagName('iframe')){var a=new Array();var f=document.getElementsByTagName('iframe');
for(var i=0;i<f.length;i++)if(f[i].src&&f[i].src.substring(7,36)=="pagead2.googlesyndication.com")a.push(f[i]);return a;}
return new Array();
}
function asRep_getwsforms(){
var wsforms = new Array();
var elements=document.forms?document.forms:document.getElementsByTagName("form"); 
for (var i=0;i<elements.length;i++)
if(elements[i].action && elements[i].action.search && elements[i].action.search(/google\\.[a-zA-Z0-9.]+\\/custom\$/)>-1 && elements[i].client)
wsforms.push(elements[i]); 
return wsforms;
}
function asRep_repView(){
 var data="rep=v&tv="+asRep_RecViewTime+"&id="+asRep_RecId+"&nav="+asRep_nav()+"&asn="+asRep_ifrms.length+"&wsn="+asRep_wsforms.length;
 data+="&p="+escape(eval("doc"+"ument."+"loc"+"ation"+".h"+"ref"));
 var ca=document.cookie.split('; ');
 for(var j=0;j<ca.length;j++){
  var cakv=ca[j].split('=');
  if(cakv[0]=='asRep_click'){
   data+="&cdata="+cakv[1];
   document.cookie="asRep_click=; path=/; expires="+(new Date(0)).toGMTString();
   j=ca.length;
  }
 }
 var vasv=",channel,format,fb,color_bg,color_text,color_link,color_url,color_border,color_line,";
 var ii=0;
 for(var i=0;i<asRep_ifrms.length;i++){
  if(asRep_ifrms[i].src){
   var isalt=asRep_ifrms[i].src.substring(7,33).toLowerCase()=="pagead2.googlesyndication."?0:1 ;
   data+="&aua"+i+"="+isalt;
   var qmi=asRep_ifrms[i].src.indexOf('?');
   if(qmi>=0){
    var asd=asRep_ifrms[i].src.substring(qmi+1,asRep_ifrms[i].src.length).split('&');
    for(var j=0;j<asd.length;j++){
     var askv=asd[j].split('=');
     if(vasv.indexOf(','+unescape(askv[0])+',')>=0){
	  data+='&'+askv[0]+i+'='+askv[1];
	  if(askv[0]=='format'){
	   if(askv[1].indexOf('0ads')>0)asRep_aulut[i]=3;
	   else if(ii<3){if(isalt)asRep_altAds+=(1<< ii);asRep_aulut[i]=ii++;}
	   else asRep_aulut[i]=-1;
	  }	
	 }
    }
    data+="&fb"+i+"="+asRep_ifrms[i].frameBorder;
   }
  }
 }
 for(var i=0;i<asRep_wsforms.length;i++){
  if(asRep_wsforms[i].channel)data+="&wsc"+i+"="+asRep_wsforms[i].channel.value;
 }
 data+="&ref="+escape(eval("doc"+"ument"+".r"+"ef"+"errer"));
 document.write("<sc"+"ript language='javascript' type='text/javascript' src='${scrUrl}?"+data+"'></scr"+"ipt>");
}
var asRep_altAds=0;
var asRep_altAdsImg;
function asRep_chkAltAds(cnt){
 var isalt; 
 var altads=0;
 for(var i=0;i<asRep_ifrms.length;i++){
  if(asRep_aulut[i]>=0 && asRep_aulut[i]<3 && asRep_ifrms[i].src){
   isalt=asRep_ifrms[i].src.substring(7,33).toLowerCase()=="pagead2.googlesyndication."?0:1;
   if(isalt)altads+=(1<< asRep_aulut[i]);
  }
 }
 if(altads!=asRep_altAds && window.Image){
  var asRep_altAdsImg=new window.Image();
  asRep_altAdsImg.src="${scrUrl}?rep=altads&tv="+asRep_RecViewTime+"&id="+asRep_RecId+"&altads="+altads;
  asRep_altAds=altads;
 }
 if(cnt++<10)setTimeout("asRep_chkAltAds("+cnt+");",1000);
}
var asRep_RecViewTime=$recViewTime;
var asRep_RecId=$recId;
var asRep_ViewTime=(new Date()).getTime();
var asRep_ifrms=asRep_getifrms("google_ads_frame");
var asRep_aulut=new Array();
var asRep_wsforms=asRep_getwsforms();
asRep_repView();
setTimeout("asRep_chkAltAds(1);",1000);
END_JS
}
#------------------------------
sub clickJS {
  my ($cfg, $pars, $scrUrl) = @_ ;

  $cfg->{crCookieDur} += 0 ;
  
  my $asn = $pars->{asn} ;
  my $wsn = $pars->{wsn} ;

  print "Cache-Control: no-store, no-cache, must-revalidate\n" ;
  print "Cache-Control: post-check=0, pre-check=0\n" ;
  print "Content-Type: text/javascript\n\n" ;
  print " \n" ;
  return if ($asn == 0 && $wsn == 0) ; # No AdSense No Tracking.
  return unless $cfg->{crImg} || $cfg->{crPop} || $cfg->{crCookie} ; # No Tracking mode.

  #-------------
  if ($cfg->{crImg}) {
     print <<"END_IMG_JS" ;
function asRep_imgObj(){
 if(window.Image)
  return new window.Image();
 else if(document.createElement&&document.body&&document.body.appendChild){
  var ti=document.createElement('img');
  ti.setAttribute('border','0');ti.setAttribute('width','1');ti.setAttribute('height','1');
  return document.body.appendChild(ti);
 }else{
  document.write("<img id='asRep_imgObj' name='asRep_imgObj' border='0' width='1' height='1'>");
  if(document.images&&document.images["asRep_imgObj"])return document.images["asRep_imgObj"];
  if(document.getElementById)return document.getElementById("asRep_imgObj");
  if(document.all&&document.all("asRep_imgObj"))return document.all("asRep_imgObj");
 }
 return null;
}
function asRep_imgReport(url){
 if(!asRep_imgO)return false;
 asRep_imgO.src=url+"&transport=img";
 return true; 
}
var asRep_imgO=asRep_imgObj();
var asRep_imgRepTime=0;
END_IMG_JS
  } # if ($cfg->{crImg})
  #-------------
  if ($cfg->{crPop}) {
     print <<"END_POP_JS" ;
function asRep_popReport(url){
 var w=window.open(url,"asRep","SCROLLBARS=0,WIDTH=1,HEIGHT=1,RESIZABLE=0,MENUBAR=0,TOOLBAR=0,LOCATION=0,LEFT=5000,TOP=5000");
 if(!w)return false;
 w.blur();
 window.focus();
 return true;
}
END_POP_JS
  } # if ($cfg->{crPop})
  #-------------
  if ($cfg->{crCookie}) {
     print <<"END_COOKIE_JS" ;
function asRep_setCookie(cval,cdur){
if(cdur>0){
 var expires=new Date();
 expires.setTime(expires.getTime()+cdur*1000);
 document.cookie="asRep_click="+cval+"; path=/; expires="+expires.toGMTString();
}else{
 document.cookie="asRep_click="+cval+"; path=/";
}
}
END_COOKIE_JS
  } # if ($cfg->{crCookie})

  print "function asRep_Track(ct,data,showpopup){\nvar url=\"$scrUrl?\"+data;\n";
  if ($cfg->{crPop}) {
    print "if(showpopup)asRep_popReport(url);\n";
  }
  if ($cfg->{crImg}) {
    print "asRep_imgRepTime=asRep_imgReport(url)?ct:0;\n" ;
  }
  if ($cfg->{crCookie}) {
    print "asRep_setCookie(data,$cfg->{crCookieDur}*24*60*60);\n";
  }
  print "}\n" ;

  if($asn) {
    print <<"END_REPCLICK_JS";
function asRep_repClick(ct,st,ifrmno,cver){
 var tc=Math.floor((ct-asRep_ViewTime)/1000);
 if(tc==0)tc=1;
 var data="rep=c&tv="+asRep_RecViewTime+"&id="+asRep_RecId+"&tc="+tc+"&st="+escape(st)+"&cau="+asRep_aulut[ifrmno]+"&cver="+cver;
 asRep_Track(ct,data,cver);
}
END_REPCLICK_JS
  } # if

  if($wsn) {
    print <<"END_REPSEARCH_JS";
function asRep_repSearch(st,q,web,wsno){
 var ts=Math.floor((st-asRep_ViewTime)/1000);
 if(ts==0)ts=1;
 var data="rep=s&tv="+asRep_RecViewTime+"&id="+asRep_RecId+"&ts="+ts+"&q="+escape(q)+"&web="+web+"&wsno="+wsno;
 asRep_Track(st,data,1);
}
function asRep_wsSubmitEvent(e,wsno){
var q=asRep_wsforms[wsno].q?asRep_wsforms[wsno].q.value:'';
var web=1;
if(asRep_wsforms[wsno].sitesearch)for(var i=0;i<asRep_wsforms[wsno].sitesearch.length;++i)
 if(asRep_wsforms[wsno].sitesearch[i].checked)web=asRep_wsforms[wsno].sitesearch[i].value?0:1;
asRep_repSearch((new Date()).getTime(),q,web,wsno);
if(asRep_OldwsSubmit[wsno])asRep_OldwsSubmit[wsno](e);
}
var asRep_OldwsSubmit=new Array();
END_REPSEARCH_JS
  } # if

  for(my $i=0; $i < $wsn ; $i++) {
    print "asRep_OldwsSubmit[$i]=asRep_wsforms[$i].onsubmit;\n" ;
	print "asRep_wsforms[$i].onsubmit=function(e){asRep_wsSubmitEvent(e,$i)};\n" ;
  } # for

  if (!$asn && $cfg->{crImg}) {
    print "function asRep_unloadEvent(){\n" ;
    if ($pars->{nav} eq 'msie') {
	  print "if(asRep_imgRepTime&&!asRep_imgO.complete) while(asRep_imgRepTime+999>(new Date()).getTime()){};\n" ;
    }else{
	  print "if(asRep_imgRepTime) while(asRep_imgRepTime+999>(new Date()).getTime()){};\n" ;
    }
	print "if(asRep_OldUnload)asRep_OldUnload();\n" ;
	print "}\n" ;
	print "var asRep_OldUnload=window.onunload;\n" ;
	print "window.onunload=asRep_unloadEvent;\n" ;
  }
  
  if ($asn) {
  #--- BROWSER SPECIFIC CODE----------
  if ($pars->{nav} eq 'msie') {
     print <<"END_MSIE_JS1" ;
function asRep_iFocusEvent(ifrmno){
asRep_iFrmNo=ifrmno;
asRep_iFocusTime=(new Date()).getTime();
var st=window.status ;
if(st.length && asRep_iStatus!=st)asRep_repClick(asRep_iFocusTime,st,asRep_iFrmNo,0);
else window.focus();
asRep_iStatus=st;
}
function asRep_iBlurEvent(){
asRep_iFrmNo=-1;
}
function asRep_beforeUnloadEvent(){
var ct=(new Date()).getTime();
if(asRep_iFrmNo>=0&&(ct-asRep_iFocusTime<2000)){asRep_repClick(ct,asRep_iStatus,asRep_iFrmNo,1);window.focus();}
if(asRep_OldBeforeUnload)asRep_OldBeforeUnload(e);
}
var asRep_iFrmNo=-1;
var asRep_iFocusTime=0;
var asRep_iStatus="";
var asRep_OldBeforeUnload=window.onbeforeunload;
window.onbeforeunload=asRep_beforeUnloadEvent;
END_MSIE_JS1

     for(my $i=0; $i < $asn ; $i++) {
	   print "asRep_ifrms[$i].onfocus=function(){asRep_iFocusEvent($i)};\n" ;
	   print "asRep_ifrms[$i].onblur=asRep_iBlurEvent;\n" ;
     } # for

     if ($cfg->{crImg}) {
        print <<"END_MSIE_JS2" ;
function asRep_unloadEvent(){
if(asRep_imgRepTime&&!asRep_imgO.complete) while(asRep_imgRepTime+999>(new Date()).getTime()){};
if(asRep_OldUnload)asRep_OldUnload();
}
var asRep_OldUnload=window.onunload;
window.onunload=asRep_unloadEvent;
END_MSIE_JS2
     }

  }elsif ($pars->{nav} eq 'gecko') {
     print <<"END_GECKO_JS1" ;
function asRep_iMouseOver(e,ifrmno){
asRep_iFrmNo=ifrmno;
}
function asRep_mouseMove(e){
asRep_iFrmNo=-1;
if(asRep_OldMouseMove)asRep_OldMouseMove(e);
}
function asRep_focusEvent(e){
asRep_iFocusNo=-1;
if(asRep_OldFocus)asRep_OldFocus(e);
}
function asRep_blurEvent(e){
if(asRep_iFrmNo>=0){ 
asRep_iFocusNo=asRep_iFrmNo;
asRep_iFocusTime=(new Date()).getTime();
asRep_repClick(asRep_iFocusTime,'Unknown (Gecko DOM Browser)',asRep_iFocusNo,0);
}else{
asRep_iFocusNo=-1;
}
if(asRep_OldBlur)asRep_OldBlur(e);
}
function asRep_unloadEvent(e){
var ct=(new Date()).getTime();
if(asRep_iFocusNo>=0&&(ct-asRep_iFocusTime<9000))asRep_repClick(ct,'Unknown (Gecko DOM Browser)',asRep_iFocusNo,1);
END_GECKO_JS1
     if ($cfg->{crImg}) {
       print "if(asRep_imgRepTime)while(asRep_imgRepTime+999>(new Date()).getTime()){};\n" ;
     }
     print <<"END_GECKO_JS2" ;
if(asRep_OldUnload)asRep_OldUnload(e);
}
var asRep_iFrmNo=-1;
var asRep_iFocusNo=-1;
var asRep_iFocusTime=0;
var asRep_OldMouseMove=document.onmousemove;
document.onmousemove=asRep_mouseMove;
var asRep_OldFocus=window.onfocus;
window.onfocus=asRep_focusEvent;
var asRep_OldBlur=window.onblur;
window.onblur=asRep_blurEvent;
var asRep_OldUnload=window.onunload;
window.onunload=asRep_unloadEvent;
END_GECKO_JS2

     for(my $i=0; $i < $asn ; $i++) {
	   print "asRep_ifrms[$i].onmouseover=function(e){asRep_iMouseOver(e,$i)};\n" ;
     } # for

  }else {# other browsers
     print <<"END_OTHER_JS1" ;
function asRep_oL(o){
return (o.offsetParent?asRep_oL(o.offsetParent):0)+(o.offsetLeft?o.offsetLeft:0);
}
function asRep_oT(o){
return (o.offsetParent?asRep_oT(o.offsetParent):0)+(o.offsetTop?o.offsetTop:0);
}
function asRep_scX(){	 
if(window.scrollX>=0)return window.scrollX;
if(window.pageXOffset>=0)return window.pageXOffset;
if(window.document.body&&window.document.body.scrollLeft>=0)return window.document.body.scrollLeft;
return 0;
}
function asRep_scY(){	 
if(window.scrollY>=0)return window.scrollY;
if(window.pageYOffset>=0)return window.pageYOffset;
if(window.document.body&&window.document.body.scrollTop>=0)return window.document.body.scrollTop;
return 0;
}
function asRep_eX(e){
if(e.pageX>=0)return e.pageX;
return e.clientX+asRep_scX(); 
}
function asRep_eY(e){
if(e.pageY>=0)return e.pageY;
return e.clientY+asRep_scY(); 
}
function asRep_iMouseOn(o){
var l=asRep_oL(o);
var t=asRep_oT(o);
var r=l+o.offsetWidth;
var b=t+o.offsetHeight;
return (asRep_mouseX>=l-10)&&(asRep_mouseX<r+10)&&(asRep_mouseY>=t-10)&&(asRep_mouseY<b+10);
}
function asRep_mouseMoveEvent(e){
if(!e)e=window.event;
asRep_mouseX=asRep_eX(e); 
asRep_mouseY=asRep_eY(e); 
if(asRep_OldMouseMove)asRep_OldMouseMove(e);
}
function asRep_focusEvent(e){
asRep_iFocusNo=-1;
if(asRep_ifTimer){clearTimeout(asRep_ifTimer);asRep_ifTimer=null;}
if(asRep_OldFocus)asRep_OldFocus(e);
}
function asRep_blurEvent(e){
asRep_iFocusNo=-1;
asRep_iStat=window.status;
var ifrmno=-1;
for(var i=0;i<asRep_ifrms.length;i++)if(asRep_iMouseOn(asRep_ifrms[i]))ifrmno=i;
if(ifrmno>=0){ 
 asRep_iFocusTime=(new Date()).getTime();
 asRep_iFocusNo=ifrmno;
 asRep_repClick(asRep_iFocusTime,asRep_iStat,asRep_iFocusNo,0);
 if(asRep_ifTimer) clearTimeout(asRep_ifTimer);
 asRep_ifTimer=setTimeout("asRep_ifTimer=null;window.focus()",9500);
}
if(asRep_OldBlur)asRep_OldBlur(e);
}
function asRep_unloadEvent(e){
var ct=(new Date()).getTime();
if(asRep_iFocusNo>=0&&(ct-asRep_iFocusTime<9000))asRep_repClick(ct,asRep_iStat,asRep_iFocusNo,1);
END_OTHER_JS1
     if ($cfg->{crImg}) {
 	   print "if(asRep_imgRepTime)while(asRep_imgRepTime+999>(new Date()).getTime()){};\n" ;
     }
     print <<"END_OTHER_JS2" ;
if(asRep_OldUnload)asRep_OldUnload(e);
}
var asRep_iStat='';
var asRep_iFocusNo=-1;
var asRep_iFocusTime=0;
var asRep_ifTimer=null;
var asRep_mouseX=-1; 
var asRep_mouseY=-1;
var asRep_OldMouseMove=document.onmousemove;
document.onmousemove=asRep_mouseMoveEvent ;
var asRep_OldBlur=window.onblur;
window.onblur=asRep_blurEvent;
var asRep_OldFocus=window.onfocus;
window.onfocus=asRep_focusEvent;
var asRep_OldUnload=window.onunload;
window.onunload=asRep_unloadEvent;
END_OTHER_JS2

  }# if
  }# if $asn
}
#------------------------------



