#!/usr/bin/env perl
#------------------------------------------------------------------------------
#
# pgBadger - Advanced PostgreSQL log analyzer
#
# This program is open source, licensed under the PostgreSQL Licence.
# For license terms, see the LICENSE file.
#------------------------------------------------------------------------------
#
# Settings in postgresql.conf
#
# You should enable SQL query logging with log_min_duration_statement >= 0
# With stderr output
#  Log line prefix should be: log_line_prefix = '%t [%p]: [%l-1] '
#  Log line prefix should be: log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d '
#  Log line prefix should be: log_line_prefix = '%t [%p]: [%l-1] db=%d,user=%u '
# If you need report per client Ip adresses you can add client=%h or remote=%h
# pgbadger will also recognized the following form:
#     log_line_prefix = '%t [%p]: [%l-1] db=%d,user=%u,client=%h '
# or
#     log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,remote=%h '
# With syslog output
#  Log line prefix should be: log_line_prefix = 'db=%d,user=%u '
#
# Additional information that could be collected and reported
#  log_checkpoints = on
#  log_connections = on
#  log_disconnections = on
#  log_lock_waits = on
#  log_temp_files = 0
#  log_autovacuum_min_duration = 0
#------------------------------------------------------------------------------
use vars qw($VERSION);

use strict qw(vars subs);

use Getopt::Long qw(:config no_ignore_case bundling);
use IO::File;
use Benchmark;
use File::Basename;
use Storable qw(store_fd fd_retrieve);
use Time::Local 'timegm_nocheck';
use POSIX qw(locale_h sys_wait_h _exit strftime);
setlocale(LC_NUMERIC, '');
setlocale(LC_ALL,     'C');
use File::Spec qw/ tmpdir /;
use File::Temp qw/ tempfile /;
use IO::Handle;
use IO::Pipe;
use FileHandle;
use Socket;
use constant EBCDIC => "\t" ne "\011";

$VERSION = '7.1';

$SIG{'CHLD'} = 'DEFAULT';

my $TMP_DIR      = File::Spec->tmpdir() || '/tmp';
my %RUNNING_PIDS = ();
my @tempfiles    = ();
my $parent_pid   = $$;
my $interrupt    = 0;
my $tmp_last_parsed = '';
my @SQL_ACTION   = ('SELECT', 'INSERT', 'UPDATE', 'DELETE');
my @LATENCY_PERCENTILE = sort {$a <=> $b} (99,95,90);
my $graphid      = 1;
my $NODATA       = '<div class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>';
my $MAX_QUERY_LENGTH = 20480;
my $terminate = 0;
my %CACHE_DNS = ();
my $DNSLookupTimeout = 1; # (in seconds)
my $EXPLAIN_URL = 'http://explain.depesz.com/?is_public=0&is_anon=0&plan=';

my @E2A = (
   0,  1,  2,  3,156,  9,134,127,151,141,142, 11, 12, 13, 14, 15,
  16, 17, 18, 19,157, 10,  8,135, 24, 25,146,143, 28, 29, 30, 31,
 128,129,130,131,132,133, 23, 27,136,137,138,139,140,  5,  6,  7,
 144,145, 22,147,148,149,150,  4,152,153,154,155, 20, 21,158, 26,
  32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124,
  38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94,
  45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63,
 248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34,
 216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177,
 176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164,
 181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174,
 172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215,
 123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245,
 125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255,
  92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213,
  48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159
);
if (EBCDIC && ord('^') == 106) { # as in the BS2000 posix-bc coded character set
     $E2A[74] = 96;   $E2A[95] = 159;  $E2A[106] = 94;  $E2A[121] = 168;
     $E2A[161] = 175; $E2A[173] = 221; $E2A[176] = 162; $E2A[186] = 172;
     $E2A[187] = 91;  $E2A[188] = 92;  $E2A[192] = 249; $E2A[208] = 166;
     $E2A[221] = 219; $E2A[224] = 217; $E2A[251] = 123; $E2A[253] = 125;
     $E2A[255] = 126;
}
elsif (EBCDIC && ord('^') == 176) { # as in codepage 037 on os400
  $E2A[21] = 133; $E2A[37] = 10;  $E2A[95] = 172; $E2A[173] = 221;
  $E2A[176] = 94; $E2A[186] = 91; $E2A[187] = 93; $E2A[189] = 168;
}

my $pgbadger_logo =
        '<img src="data:image/png;base64,
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
">';
my $pgbadger_ico =
        'data:image/x-icon;base64,
AAABAAEAIyMQAAEABAA8BAAAFgAAACgAAAAjAAAARgAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAgAAGRsZACgqKQA2OTcASEpJAFpdWwBoa2kAeHt5AImMigCeoZ8AsLOxAMTHxQDR1NIA
5enmAPv+/AAAAAAA///////////////////////wAAD///////////H///////////AAAP//////
//9Fq7Yv////////8AAA////////8V7u7qD////////wAAD///////8B7qWN5AL///////AAAP//
///y8Avrc3rtMCH/////8AAA/////xABvbAAAJ6kAA/////wAAD////wAG5tQAAADp6RAP////AA
AP//MQBd7C2lRESOWe5xAD//8AAA//8APO7iC+7e7u4A3uxwBf/wAAD/9Aju7iAAvu7u0QAN7ukA
7/AAAP/wCe7kAAAF7ugAAAHO6xD/8AAA//AK7CAAAAHO1AAAABnrEP/wAAD/8ArAAAAAAc7kAAAA
AIwQ//AAAP/wCjAAAAAC3uQAAAAAHBCf8AAA//AIEBVnIATu5gAXZhAFEP/wAAD/8AIAqxdwBu7p
AFoX0QIQ//AAAP/wAAPsBCAL7u4QBwfmAAD/8AAA//AAA8owAC7u7lAAKbYAAJ/wAAD/8AAAAAAA
fu7uwAAAAAAA//AAAP/wAAAAAADu7u7jAAAAAAD/8AAA//AAAAAABe7u7uoAAAAAAP/wAAD/8AAA
AAAL7u7u7QAAAAAAn/AAAP/wAAAAAB3u7u7uYAAAAAD/8AAA//MAAAAATu7u7u6QAAAAAP/wAAD/
/wAAAAAM7u7u7TAAAAAD//AAAP//IQAAAAKu7u7UAAAAAB//8AAA////IAAAAAju7BAAAAAP///w
AAD////2AAA1je7ulUAAA/////AAAP/////xEAnO7u7pIAH/////8AAA//////9CABju6iACP///
///wAAD////////wAAggAP////////AAAP////////8wAAA/////////8AAA///////////w////
///////wAAD///////////////////////AAAP/////gAAAA//+//+AAAAD//Af/4AAAAP/4A//g
AAAA//AA/+AAAAD/oAA/4AAAAP8AAB/gAAAA/gAAD+AAAADwAAAB4AAAAPAAAADgAAAA4AAAAGAA
AADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAAYAAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAA
AOAAAABgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAGAAAADgAAAA4AAAAOAAAADgAAAA
8AAAAOAAAADwAAAB4AAAAPwAAAfgAAAA/gAAD+AAAAD/gAA/4AAAAP/AAH/gAAAA//gD/+AAAAD/
/Af/4AAAAP//v//gAAAA/////+AAAAA
';

####
# method used to fork as many child as wanted
##
sub spawn
{
	my $coderef = shift;

	unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
		print "usage: spawn CODEREF";
		exit 0;
	}

	my $pid;
	if (!defined($pid = fork)) {
		print STDERR "Error: cannot fork: $!\n";
		return;
	} elsif ($pid) {
		$RUNNING_PIDS{$pid} = $pid;
		return; # the parent
	}
	# the child -- go spawn
	$< = $>;
	$( = $); # suid progs only

	exit &$coderef();
}

# Command line options
my $zcat_cmd                = 'gunzip -c';
my $zcat                    = $zcat_cmd;
my $bzcat                   = 'bunzip2 -c';
my $ucat                    = 'unzip -p';
my $xzcat                   = 'xzcat';
my $gzip_uncompress_size    = "gunzip -l %f | grep -E '^\\s*[0-9]+' | awk '{print \$2}'";
my $zip_uncompress_size     = "unzip -l %f | awk '{if (NR==4) print \$1}'";
my $xz_uncompress_size      = "xz --robot -l %f | grep totals | awk '{print \$5}'";
my $format                  = '';
my $outfile                 = '';
my $outdir                  = '';
my $incremental             = '';
my $extra_files             = 0;
my $help                    = '';
my $ver                     = '';
my @dbname                  = ();
my @dbuser                  = ();
my @dbclient                = ();
my @dbappname               = ();
my @exclude_user            = ();
my @exclude_appname         = ();
my @exclude_line            = ();
my $ident                   = '';
my $top                     = 0;
my $sample                  = 3;
my $extension               = '';
my $maxlength               = 0;
my $graph                   = 1;
my $nograph                 = 0;
my $debug                   = 0;
my $nohighlight             = 0;
my $noprettify              = 0;
my $from                    = '';
my $to                      = '';
my $quiet                   = 0;
my $progress                = 1;
my $error_only              = 0;
my @exclude_query           = ();
my @exclude_time            = ();
my $exclude_file            = '';
my @include_query           = ();
my $include_file            = '';
my $disable_error           = 0;
my $disable_hourly          = 0;
my $disable_type            = 0;
my $disable_query           = 0;
my $disable_session         = 0;
my $disable_connection      = 0;
my $disable_lock            = 0;
my $disable_temporary       = 0;
my $disable_checkpoint      = 0;
my $disable_autovacuum      = 0;
my $avg_minutes             = 5;
my $histo_avg_minutes       = 60;
my $last_parsed             = '';
my $report_title            = '';
my $log_line_prefix         = '';
my $compiled_prefix         = '';
my $project_url             = 'http://dalibo.github.com/pgbadger/';
my $t_min                   = 0;
my $t_max                   = 0;
my $remove_comment          = 0;
my $select_only             = 0;
my $tsung_queries           = 0;
my $queue_size              = 0;
my $job_per_file            = 0;
my $charset                 = 'utf-8';
my $csv_sep_char            = ',';
my %current_sessions        = ();
my $incr_date               = '';
my $last_incr_date          = '';
my $anonymize               = 0;
my $noclean                 = 0;
my $retention               = 0;
my $bar_graph               = 0;
my $dns_resolv              = 0;
my $nomultiline             = 0;
my $noreport                = 0;
my $log_duration            = 0;
my $logfile_list            = '';
my $enable_checksum         = 0;

my $NUMPROGRESS = 10000;
my @DIMENSIONS  = (800, 300);
my $RESRC_URL   = '';
my $img_format  = 'png';
my @log_files   = ();
my %prefix_vars = ();

my $remote_host = '';
my $ssh_command = '';
my $ssh_bin = 'ssh';
my $ssh_identity = '';
my $ssh_user = '';
my $ssh_timeout = 10;
my $ssh_options = "-o ConnectTimeout=$ssh_timeout -o PreferredAuthentications=hostbased,publickey";

# OBSOLETE, to be removed
# List of regex that match fatal error message that do not
# generate disconnection line in log. This is to prevent
# sessions in the sessions charts to increase continually.
# See issue #176 on github
my @session_closed_msg = (
	qr/^(database|role) "[^"]+" does not exist$/,
	qr/^no pg_hba.conf entry for/,
);

my $sql_prettified;

# Do not display data in pie where percentage is lower than this value
# to avoid label overlapping.
my $pie_percentage_limit = 2;

# Get the decimal separator
my $n       = 5 / 2;
my $num_sep = ',';
$num_sep = ' ' if ($n =~ /,/);

# Inform the parent that it should stop iterate on parsing other files
sub stop_parsing
{
	&logmsg('DEBUG', "Received interrupt signal");
	$interrupt = 1;
}

# With multiprocess we need to wait for all children
sub wait_child
{
        my $sig = shift;

	$interrupt = 2;

        print STDERR "Received terminating signal ($sig).\n";
	if ($^O !~ /MSWin32|dos/i) {
		1 while wait != -1;
		$SIG{INT} = \&wait_child;
		$SIG{TERM} = \&wait_child;
		foreach my $f (@tempfiles) {
			unlink("$f->[1]") if (-e "$f->[1]");
		}
	}
	if ($last_parsed && -e "$tmp_last_parsed") {
		unlink("$tmp_last_parsed");
	}
	if ($last_parsed && -e "$last_parsed.tmp") {
		unlink("$last_parsed.tmp");
	}
	_exit(0);
}
$SIG{INT} = \&wait_child;
$SIG{TERM} = \&wait_child;
$SIG{USR2} = \&stop_parsing;

$| = 1;

# get the command line parameters
my $result = GetOptions(
	"a|average=i"              => \$avg_minutes,
	"A|histo-average=i"        => \$histo_avg_minutes,
	"b|begin=s"                => \$from,
	"B|bar-graph!"             => \$bar_graph,
	"c|dbclient=s"             => \@dbclient,
	"C|nocomment!"             => \$remove_comment,
	"d|dbname=s"               => \@dbname,
	"D|dns-resolv!"            => \$dns_resolv,
	"e|end=s"                  => \$to,
	"f|format=s"               => \$format,
	"G|nograph!"               => \$nograph,
	"h|help!"                  => \$help,
	"i|ident=s"                => \$ident,
	"I|incremental!"           => \$incremental,
	"j|jobs=i"                 => \$queue_size,
	"J|job_per_file=i"         => \$job_per_file,
	"l|last-parsed=s"          => \$last_parsed,
	"L|logfile-list=s"         => \$logfile_list,
	"m|maxlength=i"            => \$maxlength,
	"M|no-multiline!"          => \$nomultiline,
	"N|appname=s"              => \@dbappname,
	"n|nohighlight!"           => \$nohighlight,
	"o|outfile=s"              => \$outfile,
	"O|outdir=s"               => \$outdir,
	"p|prefix=s"               => \$log_line_prefix,
	"P|no-prettify!"           => \$noprettify,
	"q|quiet!"                 => \$quiet,
	"r|remote-host=s"          => \$remote_host,
        'R|retention=i'            => \$retention,
	"s|sample=i"               => \$sample,
	"S|select-only!"           => \$select_only,
	"t|top=i"                  => \$top,
	"T|title=s"                => \$report_title,
	"u|dbuser=s"               => \@dbuser,
	"U|exclude-user=s"         => \@exclude_user,
	"v|verbose!"               => \$debug,
	"V|version!"               => \$ver,
	"w|watch-mode!"            => \$error_only,
	"x|extension=s"            => \$extension,
	"X|extra-files!"           => \$extra_files,
	"z|zcat=s"                 => \$zcat,
	"pie-limit=i"              => \$pie_percentage_limit,
	"image-format=s"           => \$img_format,
	"exclude-query=s"          => \@exclude_query,
	"exclude-file=s"           => \$exclude_file,
	"exclude-appname=s"        => \@exclude_appname,
	"include-query=s"          => \@include_query,
	"exclude-line=s"           => \@exclude_line,
	"include-file=s"           => \$include_file,
	"disable-error!"           => \$disable_error,
	"disable-hourly!"          => \$disable_hourly,
	"disable-type!"            => \$disable_type,
	"disable-query!"           => \$disable_query,
	"disable-session!"         => \$disable_session,
	"disable-connection!"      => \$disable_connection,
	"disable-lock!"            => \$disable_lock,
	"disable-temporary!"       => \$disable_temporary,
	"disable-checkpoint!"      => \$disable_checkpoint,
	"disable-autovacuum!"      => \$disable_autovacuum,
	"charset=s"                => \$charset,
	"csv-separator=s"          => \$csv_sep_char,
	"exclude-time=s"           => \@exclude_time,
        'ssh-command=s'            => \$ssh_command,
        'ssh-program=s'            => \$ssh_bin,
        'ssh-identity=s'           => \$ssh_identity,
        'ssh-option=s'             => \$ssh_options,
        'ssh-user=s'               => \$ssh_user,
        'ssh-timeout=i'            => \$ssh_timeout,
	'anonymize!'               => \$anonymize,
	'noclean!'                 => \$noclean,
	'noreport!'                => \$noreport,
	'log-duration!'            => \$log_duration,
	'enable-checksum!'         => \$enable_checksum,
);
die "FATAL: use pgbadger --help\n" if (not $result);

$report_title = &escape_html($report_title) if $report_title;

if ($ver) {
	print "pgBadger version $VERSION\n";
	exit 0;
}
&usage() if ($help);

# Try to load Digest::MD5 when asked
if ($enable_checksum) {
	if (eval {require Digest::MD5;1} ne 1) {
		die("Can not load Perl module Digest::MD5.\n");
	} else {
		Digest::MD5->import('md5_hex');
	}
}

# Rewrite some command line arguments as lists
&compute_arg_list();

# If pgBadger must parse remote files set the ssh command
if ($remote_host) {
	# If no user defined ssh command
	if (!$ssh_command) {
		$ssh_command = $ssh_bin || 'ssh';
		$ssh_command .= " -i $ssh_identity" if ($ssh_identity);
		$ssh_command .= " $ssh_options" if ($ssh_options);
		if ($ssh_user) {
			$ssh_command .= " $ssh_user\@$remote_host";
		} else {
			$ssh_command .= " $remote_host";
		}
	}
}

# Log files to be parsed are passed as command line arguments
if ($#ARGV >= 0) {
	foreach my $file (@ARGV) {
		if ($file ne '-') {
			if (!$remote_host) {
				die "FATAL: logfile $file must exist!\n" if not -f $file;
				if (-z $file) {
					print "WARNING: file $file is empty\n";
					next;
				}
				push(@log_files, $file);
			} else {
				# Get files from remote host
				&logmsg('DEBUG', "Looking for remote filename using command: $ssh_command \"ls $file\"");
				my @rfiles = `$ssh_command "ls $file"`;
				foreach my $f (@rfiles) {
					push(@log_files, $f);
				}
			}
		} else {
			if ($logfile_list) {
				die "FATAL: stdin input - can not be used with logfile list (-L).\n";
			}
			push(@log_files, $file);
		}
	}

}

if ($logfile_list) {

	if (!-e $logfile_list) {
		die "FATAL: logfile list $logfile_list must exist!\n";
	}
	if (not open(IN, $logfile_list)) {
		die "FATAL: can not read logfile list $logfile_list, $!.\n";
	}
	my @files = <IN>;
	close(IN);
	foreach my $file (@files) {
		chomp($file);
		$file =~ s/\r//;
		if ($file eq '-') {
			die "FATAL: stdin input - can not be used with logfile list.\n";
		}
		if (!$remote_host) {
			die "FATAL: logfile $file must exist!\n" if not -f $file;
			if (-z $file) {
				print "WARNING: file $file is empty\n";
				next;
			}
			push(@log_files, $file);
		} else {
			# Get files from remote host
			&logmsg('DEBUG', "Looking for remote filename using command: $ssh_command \"ls $file\"");
			my @rfiles = `$ssh_command "ls $file"`;
			foreach my $f (@rfiles) {
				push(@log_files, $f);
			}
		}
	}

}

# Logfile is a mandatory parameter
if ($#log_files < 0) {
	print STDERR "FATAL: you must give a log file as command line parameter.\n\n";
	&usage();
}

# Quiet mode is forced with progress bar
$progress = 0 if ($quiet);

# Set the default number minutes for queries and connections average
$avg_minutes ||= 5;
$avg_minutes = 60 if ($avg_minutes > 60);
$avg_minutes = 1  if ($avg_minutes < 1);
$histo_avg_minutes ||= 60;
$histo_avg_minutes = 60 if ($histo_avg_minutes > 60);
$histo_avg_minutes = 1  if ($histo_avg_minutes < 1);
my @avgs   = ();
for (my $i = 0 ; $i < 60 ; $i += $avg_minutes) {
	push(@avgs, sprintf("%02d", $i));
}
my @histo_avgs = ();
for (my $i = 0 ; $i < 60 ; $i += $histo_avg_minutes) {
	push(@histo_avgs, sprintf("%02d", $i));
}

# Set error like log level regex
my $parse_regex      = qr/^(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|HINT|STATEMENT|CONTEXT)/;
my $full_error_regex = qr/^(WARNING|ERROR|FATAL|PANIC|DETAIL|HINT|STATEMENT|CONTEXT)/;
my $main_error_regex = qr/^(WARNING|ERROR|FATAL|PANIC)/;

# Set syslog prefix regex
my $other_syslog_line =
	qr/^(...)\s+(\d+)\s(\d+):(\d+):(\d+)(?:\s[^\s]+)?\s([^\s]+)\s([^\s\[]+)\[(\d+)\]:(?:\s\[[^\]]+\])?\s\[(\d+)\-\d+\]\s*(.*)/;
my $orphan_syslog_line = qr/^(...)\s+(\d+)\s(\d+):(\d+):(\d+)(?:\s[^\s]+)?\s([^\s]+)\s([^\s\[]+)\[(\d+)\]:/;
my $orphan_stderr_line = '';

# Simply genreate a random string, thanks to Perlmonks
# Set default format
my $frmt = '';
if (!$remote_host) {
	$frmt = &autodetect_format($log_files[0]);
} elsif (!$format) {
	die "FATAL: you must give a log file format (-f or --format) when using remote connection.\n\n";
}
$format ||= $frmt;

if ($format eq 'syslog2') {
	$other_syslog_line =
		qr/^(\d+-\d+)-(\d+)T(\d+):(\d+):(\d+)(?:.[^\s]+)?\s([^\s]+)\s(?:[^\s]+\s)?(?:[^\s]+\s)?([^\s\[]+)\[(\d+)\]:(?:\s\[[^\]]+\])?\s\[(\d+)\-\d+\]\s*(.*)/;
	$orphan_syslog_line = qr/^(\d+-\d+)-(\d+)T(\d+):(\d+):(\d+)(?:.[^\s]+)?\s([^\s]+)\s(?:[^\s]+\s)?(?:[^\s]+\s)?([^\s\[]+)\[(\d+)\]:/;
}

# Set default top query
$top ||= 20;

# Set the default extension and output format
if (!$extension) {
	if ($outfile =~ /\.bin/i) {
		$extension = 'binary';
	} elsif ($outfile =~ /\.json/i) {
		if (eval {require JSON::XS;1;} ne 1) {
			die("Can not save output in json format, please install Perl module JSON::XS first.\n");
		} else {
			JSON::XS->import();
		}
		$extension = 'json';
	} elsif ($outfile =~ /\.tsung/i) {
		$extension = 'tsung';
	} elsif ($outfile =~ /\.htm[l]*/i) {
		$extension = 'html';
	} elsif ($outfile) {
		$extension = 'txt';
	} else {
		$extension = 'html';
	}
} elsif (lc($extension) eq 'json') {
	if (eval {require JSON::XS;1;} ne 1) {
		die("Can not save output in json format, please install Perl module JSON::XS first.\n");
	} else {
		JSON::XS->import();
	}
}

# Set default filename of the output file
$outfile ||= 'out.' . $extension;
&logmsg('DEBUG', "Output '$extension' reports will be written to $outfile");

# Set default syslog ident name
$ident ||= 'postgres';

# Set default pie percentage limit or fix value
$pie_percentage_limit = 0   if ($pie_percentage_limit < 0);
$pie_percentage_limit = 2   if ($pie_percentage_limit eq '');
$pie_percentage_limit = 100 if ($pie_percentage_limit > 100);

# Set default download image format
$img_format = lc($img_format);
$img_format = 'jpeg' if ($img_format eq 'jpg');
$img_format = 'png' if ($img_format ne 'jpeg');

# Extract the output directory from outfile so that graphs will
# be created in the same directory
if ($outfile ne '-') {
	if (!$outdir) {
		my @infs = fileparse($outfile);
		if ($infs[0] ne '') {
			$outdir = $infs[1];
		} else {
			# maybe a confusion between -O and -o
			die "FATAL: output file $outfile is a directory, should be a file\nor maybe you want to use -O | --outdir option instead.\n";
		}
	} elsif (!-d "$outdir") {
		# An output directory has been passed as command line parameter
		die "FATAL: $outdir is not a directory or doesn't exist.\n";
	}
	$outfile = basename($outfile);
	$outfile = $outdir . '/' . $outfile;
}

# Remove graph support if output is not html
$graph = 0 unless ($extension eq 'html' or $extension eq 'binary' or $extension eq 'json');
$graph = 0 if ($nograph);

# Set some default values
my $end_top = $top - 1;
$queue_size ||= 1;
$job_per_file ||= 1;

if ($^O =~ /MSWin32|dos/i) {
	if ( ($queue_size > 1) || ($job_per_file > 1) ) {
		print STDERR "WARNING: parallel processing is not supported on this platform.\n";
		$queue_size = 1;
		$job_per_file = 1;
	}
}

if ($extension eq 'tsung') {

	# Open filehandle
	my $fh = new IO::File ">$outfile";
	if (not defined $fh) {
		die "FATAL: can't write to $outfile, $!\n";
	}
	print $fh qq{<?xml version="1.0"?>
<!DOCTYPE tsung SYSTEM "/usr/share/tsung/tsung-1.0.dtd">
<tsung loglevel="notice" version="1.0">

    <!-- Configuration du client -->
    <clients>
        <client host="localhost" use_controller_vm="true"/>
    </clients>

    <!-- Configuration du serveur -->
    <servers>
        <server host="localhost" port="5432" type="tcp"></server>
    </servers>

    <load>
        <arrivalphase phase="1" duration="1" unit="second">
            <users maxnumber="1" arrivalrate="1" unit="second"></users>
        </arrivalphase>
    </load>

<sessions>
};
	$fh->close();

} else {

	# Test file creation before going to parse log
	my $tmpfh = new IO::File ">$outfile";
	if (not defined $tmpfh) {
		die "FATAL: can't write to $outfile, $!\n";
	}
	$tmpfh->close();
	unlink($outfile) if (-e $outfile);
}

# -w and --disable-error can't go together
if ($error_only && $disable_error) {
	die "FATAL: please choose between no event report and reporting events only.\n";
}

# Set default search pattern for database, user name, application name and host in log_line_prefix
my $regex_prefix_dbname = qr/db=([^,]*)/;
my $regex_prefix_dbuser = qr/user=([^,]*)/;
my $regex_prefix_dbclient = qr/(?:client|remote)=([^,]*)/;
my $regex_prefix_dbappname = qr/app=([^,]*)/;

# Set pattern to look for query type
my $action_regex = qr/^[\s\(]*(DELETE|INSERT|UPDATE|SELECT|COPY)/is;


# Loading excluded query from file if any
if ($exclude_file) {
	open(IN, "$exclude_file") or die "FATAL: can't read file $exclude_file: $!\n";
	my @exclq = <IN>;
	close(IN);
	chomp(@exclq);
	map {s/\r//;} @exclq;
	foreach my $r (@exclq) {
		&check_regex($r, '--exclude-file');
	}
	push(@exclude_query, @exclq);
}

# Testing regex syntax
if ($#exclude_query >= 0) {
	foreach my $r (@exclude_query) {
		&check_regex($r, '--exclude-query');
	}
}

# Testing regex syntax
if ($#exclude_time >= 0) {
	foreach my $r (@exclude_time) {
		&check_regex($r, '--exclude-time');
	}
}

# Loading included query from file if any
if ($include_file) {
	open(IN, "$include_file") or die "FATAL: can't read file $include_file: $!\n";
	my @exclq = <IN>;
	close(IN);
	chomp(@exclq);
	map {s/\r//;} @exclq;
	foreach my $r (@exclq) {
		&check_regex($r, '--include-file');
	}
	push(@include_query, @exclq);
}

# Testing regex syntax
if ($#include_query >= 0) {
	foreach my $r (@include_query) {
		&check_regex($r, '--include-query');
	}
}

# Compile custom log line prefix prefix
my @prefix_params = ();
if ($log_line_prefix) {
	# Build parameters name that will be extracted from the prefix regexp
	@prefix_params = &build_log_line_prefix_regex();
	&check_regex($log_line_prefix, '--prefix');
	if ($format eq 'syslog') {
		$log_line_prefix =
			  '^(...)\s+(\d+)\s(\d+):(\d+):(\d+)(?:\s[^\s]+)?\s([^\s]+)\s([^\s\[]+)\[(\d+)\]:(?:\s\[[^\]]+\])?\s\[(\d+)\-\d+\]\s*'
			. $log_line_prefix
			. '\s*(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):\s+(?:[0-9A-Z]{5}:\s+)?(.*)';
		$compiled_prefix = qr/$log_line_prefix/;
		unshift(@prefix_params, 't_month', 't_day', 't_hour', 't_min', 't_sec', 't_host', 't_ident', 't_pid', 't_session_line');
		push(@prefix_params, 't_loglevel', 't_query');
	} elsif ($format eq 'syslog2') {
		$format = 'syslog';
		$log_line_prefix =
			  '^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)(?:.[^\s]+)?\s([^\s]+)\s(?:[^\s]+\s)?(?:[^\s]+\s)?([^\s\[]+)\[(\d+)\]:(?:\s\[[^\]]+\])?\s\[(\d+)\-\d+\]\s*'
			. $log_line_prefix
			. '\s*(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):\s+(?:[0-9A-Z]{5}:\s+)?(.*)';
		$compiled_prefix = qr/$log_line_prefix/;
		unshift(@prefix_params, 't_year', 't_month', 't_day', 't_hour', 't_min', 't_sec', 't_host', 't_ident', 't_pid', 't_session_line');
		push(@prefix_params, 't_loglevel', 't_query');
	} elsif ($format eq 'stderr') {
		$orphan_stderr_line = qr/$log_line_prefix/;
		$log_line_prefix = '^' . $log_line_prefix . '\s*(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):\s+(?:[0-9A-Z]{5}:\s+)?(.*)';
		$compiled_prefix = qr/$log_line_prefix/;
		push(@prefix_params, 't_loglevel', 't_query');
	}
} elsif ($format eq 'syslog') {
	$compiled_prefix =
qr/^(...)\s+(\d+)\s(\d+):(\d+):(\d+)(?:\s[^\s]+)?\s([^\s]+)\s([^\s\[]+)\[(\d+)\]:(?:\s\[[^\]]+\])?\s\[(\d+)\-\d+\]\s*(.*?)\s*(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):\s+(?:[0-9A-Z]{5}:\s+)?(.*)/;
	push(@prefix_params, 't_month', 't_day', 't_hour', 't_min', 't_sec', 't_host', 't_ident', 't_pid', 't_session_line',
		't_logprefix', 't_loglevel', 't_query');
} elsif ($format eq 'syslog2') {
	$format = 'syslog';
	$compiled_prefix =
qr/^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)(?:.[^\s]+)?\s([^\s]+)\s(?:[^\s]+\s)?(?:[^\s]+\s)?([^\s\[]+)\[(\d+)\]:(?:\s\[[^\]]+\])?\s\[(\d+)\-\d+\]\s*(.*?)\s*(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):\s+(?:[0-9A-Z]{5}:\s+)?(.*)/;
	push(@prefix_params, 't_year', 't_month', 't_day', 't_hour', 't_min', 't_sec', 't_host', 't_ident', 't_pid', 't_session_line',
		't_logprefix', 't_loglevel', 't_query');
} elsif ($format eq 'stderr') {
	$compiled_prefix =
qr/^(\d+-\d+-\d+\s\d+:\d+:\d+)[\.\d]*(?: [A-Z\d]{3,6})?\s\[(\d+)\]:\s\[(\d+)\-\d+\]\s*(.*?)\s*(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):\s+(?:[0-9A-Z]{5}:\s+)?(.*)/;
	push(@prefix_params, 't_timestamp', 't_pid', 't_session_line', 't_logprefix', 't_loglevel', 't_query');
	$orphan_stderr_line = qr/^(\d+-\d+-\d+\s\d+:\d+:\d+)[\.\d]*(?: [A-Z\d]{3,6})?\s\[(\d+)\]:\s\[(\d+)\-\d+\]\s*(.*?)\s*/;
}

sub check_regex
{
	my ($pattern, $varname) = @_;

	eval {m/$pattern/i;};
	if ($@) {
		die "FATAL: '$varname' invalid regex '$pattern', $!\n";
	}
}

# Check start/end date time
if ($from) {
	if ($from !~ /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})([.]\d+([+-]\d+)?)?$/) {
		die "FATAL: bad format for begin datetime, should be yyyy-mm-dd hh:mm:ss.l+tz\n";
	} else {
                my $fractional_seconds = $7 || "0";
                $from = "$1-$2-$3 $4:$5:$6.$7"
        }

}
if ($to) {
	if ($to !~ /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})([.]\d+([+-]\d+)?)?$/) {
		die "FATAL: bad format for ending datetime, should be yyyy-mm-dd hh:mm:ss.l+tz\n";
	} else {
                my $fractional_seconds = $7 || "0";
                $to = "$1-$2-$3 $4:$5:$6.$7"
        }
}

# Stores the last parsed line from log file to allow incremental parsing
my $LAST_LINE = '';

# Set the level of the data aggregator, can be minute, hour or day follow the
# size of the log file.
my $LEVEL = 'hour';

# Month names
my %month_abbr = (
	'Jan' => '01', 'Feb' => '02', 'Mar' => '03', 'Apr' => '04', 'May' => '05', 'Jun' => '06',
	'Jul' => '07', 'Aug' => '08', 'Sep' => '09', 'Oct' => '10', 'Nov' => '11', 'Dec' => '12'
);
my %abbr_month = (
	'01' => 'Jan', '02' => 'Feb', '03' => 'Mar', '04' => 'Apr', '05' => 'May', '06' => 'Jun',
	'07' => 'Jul', '08' => 'Aug', '09' => 'Sep', '10' => 'Oct', '11' => 'Nov', '12' => 'Dec'
);

# Keywords variable
my @pg_keywords = qw(
        ALL ANALYSE ANALYZE AND ANY ARRAY AS ASC ASYMMETRIC AUTHORIZATION BINARY BOTH CASE
        CAST CHECK COLLATE COLLATION COLUMN CONCURRENTLY CONSTRAINT CREATE CROSS
        CURRENT_DATE CURRENT_ROLE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER
        DEFAULT DEFERRABLE DESC DISTINCT DO ELSE END EXCEPT FALSE FETCH FOR FOREIGN FREEZE FROM
        FULL GRANT GROUP HAVING ILIKE IN INITIALLY INNER INTERSECT INTO IS ISNULL JOIN LEADING
        LEFT LIKE LIMIT LOCALTIME LOCALTIMESTAMP NATURAL NOT NOTNULL NULL ON ONLY OPEN OR
        ORDER OUTER OVER OVERLAPS PLACING PRIMARY REFERENCES RETURNING RIGHT SELECT SESSION_USER
        SIMILAR SOME SYMMETRIC TABLE THEN TO TRAILING TRUE UNION UNIQUE USER USING VARIADIC
        VERBOSE WHEN WHERE WINDOW WITH
);

my @beautify_pg_keywords = qw(
        ANALYSE ANALYZE CONCURRENTLY FREEZE ILIKE ISNULL LIKE NOTNULL PLACING RETURNING VARIADIC
);


# Highlight variables
my @KEYWORDS1 = qw(
        ALTER ADD AUTO_INCREMENT BETWEEN BY BOOLEAN BEGIN CHANGE COLUMNS COMMIT COALESCE CLUSTER
        COPY DATABASES DATABASE DATA DELAYED DESCRIBE DELETE DROP ENCLOSED ESCAPED EXISTS EXPLAIN
        FIELDS FIELD FLUSH FUNCTION GREATEST IGNORE INDEX INFILE INSERT IDENTIFIED IF INHERIT
        KEYS KILL KEY LINES LOAD LOCAL LOCK LOW_PRIORITY LANGUAGE LEAST LOGIN MODIFY
        NULLIF NOSUPERUSER NOCREATEDB NOCREATEROLE OPTIMIZE OPTION OPTIONALLY OUTFILE OWNER PROCEDURE
        PROCEDURAL READ REGEXP RENAME RETURN REVOKE RLIKE ROLE ROLLBACK SHOW SONAME STATUS
        STRAIGHT_JOIN SET SEQUENCE TABLES TEMINATED TRUNCATE TEMPORARY TRIGGER TRUSTED UN$filenumLOCK
        USE UPDATE UNSIGNED VALUES VARIABLES VIEW VACUUM WRITE ZEROFILL XOR
        ABORT ABSOLUTE ACCESS ACTION ADMIN AFTER AGGREGATE ALSO ALWAYS ASSERTION ASSIGNMENT AT ATTRIBUTE
        BACKWARD BEFORE BIGINT CACHE CALLED CASCADE CASCADED CATALOG CHAIN CHARACTER CHARACTERISTICS
        CHECKPOINT CLOSE COMMENT COMMENTS COMMITTED CONFIGURATION CONNECTION CONSTRAINTS CONTENT
        CONTINUE CONVERSION COST CSV CURRENT CURSOR CYCLE DAY DEALLOCATE DEC DECIMAL DECLARE DEFAULTS
        DEFERRED DEFINER DELIMITER DELIMITERS DICTIONARY DISABLE DISCARD DOCUMENT DOMAIN DOUBLE EACH
        ENABLE ENCODING ENCRYPTED ENUM ESCAPE EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXTENSION EXTERNAL
        FIRST FLOAT FOLLOWING FORCE FORWARD FUNCTIONS GLOBAL GRANTED HANDLER HEADER HOLD
        HOUR IDENTITY IMMEDIATE IMMUTABLE IMPLICIT INCLUDING INCREMENT INDEXES INHERITS INLINE INOUT INPUT
        INSENSITIVE INSTEAD INT INTEGER INVOKER ISOLATION LABEL LARGE LAST LC_COLLATE LC_CTYPE
        LEAKPROOF LEVEL LISTEN LOCATION LOOP MAPPING MATCH MAXVALUE MINUTE MINVALUE MODE MONTH MOVE NAMES
        NATIONAL NCHAR NEXT NO NONE NOTHING NOTIFY NOWAIT NULLS OBJECT OF OFF OIDS OPERATOR OPTIONS
        OUT OWNED PARSER PARTIAL PARTITION PASSING PASSWORD PLANS PRECEDING PRECISION PREPARE
        PREPARED PRESERVE PRIOR PRIVILEGES QUOTE RANGE REAL REASSIGN RECHECK RECURSIVE REF REINDEX RELATIVE
        RELEASE REPEATABLE REPLICA RESET RESTART RESTRICT RETURNS ROW ROWS RULE SAVEPOINT SCHEMA SCROLL SEARCH
        SECOND SECURITY SEQUENCES SERIALIZABLE SERVER SESSION SETOF SHARE SIMPLE SMALLINT SNAPSHOT STABLE
        STANDALONE START STATEMENT STATISTICS STORAGE STRICT SYSID SYSTEM TABLESPACE TEMP
        TEMPLATE TRANSACTION TREAT TYPE TYPES UNBOUNDED UNCOMMITTED UNENCRYPTED
        UNKNOWN UNLISTEN UNLOGGED UNTIL VALID VALIDATE VALIDATOR VALUE VARYING VOLATILE
        WHITESPACE WITHOUT WORK WRAPPER XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLPARSE
        XMLPI XMLROOT XMLSERIALIZE YEAR YES ZONE
);

foreach my $k (@pg_keywords) {
        push(@KEYWORDS1, $k) if (!grep(/^$k$/i, @KEYWORDS1));
}


my @KEYWORDS2 = (
	'ascii',      'age',
	'bit_length', 'btrim',
	'char_length', 'character_length', 'convert', 'chr', 'current_date', 'current_time', 'current_timestamp', 'count',
	'decode',      'date_part',        'date_trunc',
	'encode',      'extract',
	'get_byte',    'get_bit',
	'initcap',       'isfinite', 'interval',
	'justify_hours', 'justify_days',
	'lower', 'length', 'lpad', 'ltrim', 'localtime', 'localtimestamp',
	'md5',
	'now',
	'octet_length', 'overlay',
	'position',     'pg_client_encoding',
	'quote_ident',  'quote_literal',
	'repeat', 'replace', 'rpad', 'rtrim',
	'substring', 'split_part', 'strpos', 'substr', 'set_byte', 'set_bit',
	'trim', 'to_ascii', 'to_hex', 'translate', 'to_char', 'to_date', 'to_timestamp', 'to_number', 'timeofday',
	'upper',
);
my @KEYWORDS3 = ('STDIN', 'STDOUT');
my %SYMBOLS = (
	'='  => '=', '<'  => '&lt;', '>' => '&gt;', '\|' => '|', ',' => ',', '\.' => '.', '\+' => '+', '\-' => '-', '\*' => '*',
	'\/' => '/', '!=' => '!='
);
my @BRACKETS = ('(', ')');
map {$_ = quotemeta($_)} @BRACKETS;

# Inbounds of query times histogram
my @histogram_query_time = (0, 1, 5, 10, 25, 50, 100, 500, 1000, 10000);

# Inbounds of session times histogram
my @histogram_session_time = (0, 500, 1000, 30000, 60000, 600000, 1800000, 3600000, 28800000);

# Get inbounds of query times histogram
sub get_hist_inbound
{
	my ($duration, @histogram) = @_;

	for (my $i = 0; $i <= $#histogram; $i++) {
		return $histogram[$i-1] if ($histogram[$i] > $duration);
	}

	return -1;
}

# Where statistics are stored
my %overall_stat        = ();
my %overall_checkpoint  = ();
my @top_slowest         = ();
my %normalyzed_info     = ();
my %error_info          = ();
my %logs_type           = ();
my %per_minute_info     = ();
my %lock_info           = ();
my %tempfile_info       = ();
my %cancelled_info      = ();
my %connection_info     = ();
my %database_info       = ();
my %application_info    = ();
my %user_info           = ();
my %host_info           = ();
my %session_info        = ();
my %conn_received       = ();
my %checkpoint_info     = ();
my %autovacuum_info     = ();
my %autoanalyze_info    = ();
my @graph_values        = ();
my %cur_info            = ();
my %cur_temp_info       = ();
my %cur_plan_info       = ();
my %cur_cancel_info     = ();
my %cur_lock_info       = ();
my $nlines              = 0;
my %last_line           = ();
our %saved_last_line    = ();
my %tsung_session       = ();
my @top_locked_info     = ();
my @top_tempfile_info   = ();
my @top_cancelled_info  = ();
my %drawn_graphs        = ();

my $t0 = Benchmark->new;

# Write resources files from __DATA__ section if they have not been already copied
# and return the HTML links to that files. If --extra-file is not used returns the
# CSS and JS code to be embeded in HTML files
my @jscode = &write_resources();

# Automatically set parameters with incremental mode
if ($incremental) {

	# In incremental mode an output directory must be set
	if (!$outdir) {
		die "FATAL: you must specify an output directory with incremental mode, see -O or --outdir.\n"
	}
	# Ensure this is not a relative path
	if (dirname($outdir) eq '.') {
		die "FATAL: output directory ($outdir) is not an absolute path.\n";
	}
	# Ensure that the directory already exists
	if (!-d $outdir) {
		die "FATAL: output directory $outdir does not exists\n";
	}
	# Set default last parsed file in incremental mode
	if (!$last_parsed) {
		$last_parsed = $outdir . '/LAST_PARSED';
	}
	$outfile = 'index.html';
	# Set default output format
	$extension = 'binary';

} else {

	# Extra files for resources are not allowed without incremental mode
	$extra_files = 0;

}

# Reading last line parsed
if ($last_parsed && -e $last_parsed) {
	if (open(IN, "$last_parsed")) {
		my $line = <IN>;
		close(IN);
		($saved_last_line{datetime}, $saved_last_line{current_pos}, $saved_last_line{orig}) = split(/\t/, $line, 3);
		# Preserve backward compatibility with version < 5
		if ($saved_last_line{current_pos} =~ /\D/) {
			$saved_last_line{orig} = $saved_last_line{current_pos} . "\t" . $saved_last_line{orig};
			$saved_last_line{current_pos} = 0;
		}
		if ( ($format eq 'binary') || ($format eq 'csv') ) {
			$saved_last_line{current_pos} = 0;
		}

	} else {
		die "FATAL: can't read last parsed line from $last_parsed, $!\n";
	}
}
$tmp_last_parsed = 'tmp_' . basename($last_parsed) if ($last_parsed);
$tmp_last_parsed = "$TMP_DIR/$tmp_last_parsed";

# Clean the incremental directory if the feature is not disabled
if (!$noclean && $saved_last_line{datetime} && $outdir) {

	# Search the current week following the last parse date
	$saved_last_line{datetime} =~ /^(\d+)\-(\d+)\-(\d+) /;
	my $last_year  = $1;
	my $last_month = $2;
	my $last_day   = $3;
	# Get the week number following the date
	my $wn = &get_week_number($last_year, $last_month, $last_day);
	# Get the days of the current week where binary files must be preserved
	my @wdays = &get_wdays_per_month($wn - 1, "$last_year-$last_month");
	# Find obsolete dir days that shoud be cleaned
	unless(opendir(DIR, "$outdir")) {
		die "Error: can't opendir $outdir: $!";
	}
	my @dyears = grep { $_ =~ /^\d+$/ } readdir(DIR);
	closedir DIR;
	my @obsolete_days = ();
	foreach my $y (sort { $a <=> $b } @dyears) {
		unless(opendir(DIR, "$outdir/$y")) {
			die "Error: can't opendir $outdir/$y: $!";
		}
		my @dmonths = grep { $_ =~ /^\d+$/ } readdir(DIR);
		closedir DIR;
		foreach my $m (sort { $a <=> $b } @dmonths) {
			unless(opendir(DIR, "$outdir/$y/$m")) {
				die "Error: can't opendir $outdir/$y/$m: $!";
			}
			my @ddays = grep { $_ =~ /^\d+$/ } readdir(DIR);
			closedir DIR;
			foreach my $d (sort { $a <=> $b } @ddays) {
				if ("$y-$m-$d" lt $wdays[0]) {
					push(@obsolete_days, "$outdir/$y/$m/$d");
				}
			}
		}
	}
	foreach my $p (@obsolete_days) {
		unless(opendir(DIR, "$p")) {
			die "Error: can't opendir $p: $!";
		}
		my @hfiles = grep { $_ =~ /\.(html|txt|tsung|json)$/i } readdir(DIR);
		next if ($#hfiles == -1); # do not remove files if report file has not been generated
		seekdir(DIR, 0);
		my @bfiles = grep { $_ =~ /\.bin$/i } readdir(DIR);
		closedir DIR;
		foreach my $f (@bfiles) {
			&logmsg('DEBUG', "Removing obsolete binary file: $p/$f");
			unlink("$p/$f");
		}
	}
}

# Clear storage when a retention is specified in incremental mode
if ( $saved_last_line{datetime} && $outdir && $retention) {

	# Search the current week following the last parse date
	$saved_last_line{datetime} =~ /^(\d+)\-(\d+)\-(\d+) /;
	my $last_year  = $1;
	my $last_month = $2;
	my $last_day   = $3;
	# Get the current week number
	my $wn = &get_week_number($last_year, $last_month, $last_day);
	my $limit = $last_year;
	if (($wn - $retention) < 1) {
		$limit--;
		$limit .= "52";
	} else {
		$limit .= sprintf("%02d", $wn - $retention);
	}

	# Find obsolete weeks dir that shoud be cleaned
	unless(opendir(DIR, "$outdir")) {
		die "Error: can't opendir $outdir: $!";
	}
	my @dyears = grep { $_ =~ /^\d+$/ } readdir(DIR);
	closedir DIR;
	my @obsolete_weeks = ();
	foreach my $y (sort { $a <=> $b } @dyears) {
		unless(opendir(DIR, "$outdir/$y")) {
			die "Error: can't opendir $outdir/$y: $!";
		}
		my @weeks = grep { $_ =~ /^week-\d+$/ } readdir(DIR);
		closedir DIR;
		foreach my $w (sort { $a <=> $b } @weeks) {
			$w =~ /^week-(\d+)$/;
			if ("$y$1" lt $limit) {
				&logmsg('DEBUG', "Removing obsolete week directory $outdir/$y/week-$1");
				&cleanup_directory("$outdir/$y/week-$1", 1);
				push(@obsolete_weeks, "$y$1");
			}
		}
	}
	# Now removed the corresponding days 
	foreach my $y (sort { $a <=> $b } @dyears) {
		unless(opendir(DIR, "$outdir/$y")) {
			die "Error: can't opendir $outdir/$y: $!";
		}
		my @dmonths = grep { $_ =~ /^\d+$/ } readdir(DIR);
		closedir DIR;
		my @rmmonths = ();
		foreach my $m (sort { $a <=> $b } @dmonths) {
			unless(opendir(DIR, "$outdir/$y/$m")) {
				die "Error: can't opendir $outdir/$y/$m: $!";
			}
			my @rmdays = ();
			my @ddays = grep { $_ =~ /^\d+$/ } readdir(DIR);
			closedir DIR;
			foreach my $d (sort { $a <=> $b } @ddays) {
				my $weekNumber = sprintf("%02d", POSIX::strftime("%U", 1, 1, 1, $d, $m - 1, $y - 1900)+1);
				if (grep(/^$y$weekNumber$/, @obsolete_weeks)) {
					&logmsg('DEBUG', "Removing obsolete directory $outdir/$y/$m/$d");
					&cleanup_directory("$outdir/$y/$m/$d", 1);
					push(@rmdays, $d);
				}
			}
			if ($#ddays == $#rmdays) {
				&logmsg('DEBUG', "Removing obsolete empty directory $outdir/$y/$m");
				rmdir("$outdir/$y/$m");
				push(@rmmonths, $m);
			}
		}
		if ($#dmonths == $#rmmonths) {
			&logmsg('DEBUG', "Removing obsolete empty directory $outdir/$y");
			rmdir("$outdir/$y");
		}
	}

}

# Main loop reading log files
my $global_totalsize = 0;
my @given_log_files = ( @log_files );
chomp(@given_log_files);

# Verify that the file has not changed for incremental move
if (!$remote_host) {
	if ($saved_last_line{current_pos} > 0) {
		my @tmpfilelist = ();
		# Removed files that have already been parsed during previous runs
		foreach my $f (@given_log_files) {
			if ($f eq '-') {
				&logmsg('DEBUG', "waiting for log entries from stdin.");
				$saved_last_line{current_pos} = 0;
				push(@tmpfilelist, $f);
			} elsif (!&check_file_changed($f, $saved_last_line{datetime})) {
				&logmsg('DEBUG', "this file has already been parsed: $f");
			} else {
				push(@tmpfilelist, $f);
			}
		}
		@given_log_files = ();
		push(@given_log_files, @tmpfilelist);
	}
} else {
	# Disable multi process when using ssh to parse remote log
	$queue_size = 1;
}

# log files must be erased when loading stats from binary format
if ($format eq 'binary') {
	$queue_size = 1;
	$job_per_file = 1;
}

my $pipe;

# Seeking to an old log position is not possible outside incremental mode
$saved_last_line{current_pos} = 0 if (!$last_parsed);

# Start parsing all given files using multiprocess
if ( ($#given_log_files >= 0) && (($queue_size > 1) || ($job_per_file > 1)) ) {

	# Number of running process
	my $child_count = 0;
	# Set max number of parallel process
	my $parallel_process = $queue_size;
	if ($job_per_file > 1) {
		$parallel_process = $job_per_file;
	}
	# Store total size of the log files
	foreach my $logfile ( @given_log_files ) {
		$global_totalsize += &get_log_file($logfile);
	}

	# Open a pipe for interprocess communication
	my $reader = new IO::Handle;
	my $writer = new IO::Handle;
	$pipe = IO::Pipe->new($reader, $writer);
	$writer->autoflush(1);

	# Fork the logger process
	if ($progress) {
		spawn sub {
			&multiprocess_progressbar($global_totalsize);
		};
	}

	# Parse each log file following the multiprocess mode chosen (-j or -J)
	foreach my $logfile ( @given_log_files ) {

		while ($child_count >= $parallel_process) {
			my $kid = waitpid(-1, WNOHANG);
			if ($kid > 0) {
				$child_count--;
				delete $RUNNING_PIDS{$kid};
			}
			sleep(1);
		}

		# Do not use split method with compressed files
		if ( ($queue_size > 1) && ($logfile !~ /\.(gz|bz2|zip|xz)$/i) ) {
			# Create multiple processes to parse one log file by chunks of data
			my @chunks = &split_logfile($logfile);
			&logmsg('DEBUG', "The following boundaries will be used to parse file $logfile, " . join('|', @chunks));
			for (my $i = 0; $i < $#chunks; $i++) {
				while ($child_count >= $parallel_process) {
					my $kid = waitpid(-1, WNOHANG);
					if ($kid > 0) {
						$child_count--;
						delete $RUNNING_PIDS{$kid};
					}
					sleep(1);
				}
				die "FATAL: Abort signal received when processing to next chunk\n" if ($interrupt == 2);
				last if ($interrupt);
				push(@tempfiles, [ tempfile('tmp_pgbadgerXXXX', SUFFIX => '.bin', DIR => $TMP_DIR, UNLINK => 1 ) ]);
				spawn sub {
					&process_file($logfile, $tempfiles[-1]->[0], $chunks[$i], $chunks[$i+1], $i);
				};
				$child_count++;
			} 

		} else {

			# Start parsing one file per parallel process
			push(@tempfiles, [ tempfile('tmp_pgbadgerXXXX', SUFFIX => '.bin', DIR => $TMP_DIR, UNLINK => 1 ) ]);
			spawn sub {
				&process_file($logfile, $tempfiles[-1]->[0]);
			};
			$child_count++;

		}

		die "FATAL: Abort signal received when processing next file\n" if ($interrupt == 2);
		last if ($interrupt);
	}

	my $minproc = 1;
	$minproc = 0 if (!$progress);
	# Wait for all child processes to die except for the logger
	while (scalar keys %RUNNING_PIDS > $minproc) {
		my $kid = waitpid(-1, WNOHANG);
		if ($kid > 0) {
			delete $RUNNING_PIDS{$kid};
		}
		sleep(1);
	}

	# Terminate the process logger
	foreach my $k (keys %RUNNING_PIDS) {
		kill(10, $k);
		%RUNNING_PIDS = ();
	}

	# Clear previous statistics
	&init_stats_vars();

	# Load all data gathered by all the different processes
	foreach my $f (@tempfiles) {
		next if (!-e "$f->[1]" || -z "$f->[1]");
		my $fht = new IO::File;
		$fht->open("< $f->[1]") or die "FATAL: can't open temp file $f->[1], $!\n";
		&load_stats($fht);
		$fht->close();
	}

} else {

	# Multiprocessing disabled, parse log files one by one
	foreach my $logfile ( @given_log_files ) {
		last if (&process_file($logfile, '', $saved_last_line{current_pos}));
	}
}

# Get last line parsed from all process
if ($last_parsed) {
	if (open(IN, "$tmp_last_parsed") ) {
		while (my $line = <IN>) {
			chomp($line);
			my ($d, $p, $l) = split(/\t/, $line, 3);
			if (!$last_line{datetime} || ($d gt $last_line{datetime})) {
				$last_line{datetime} = $d;
				if ($p =~ /^\d+$/) {
					$last_line{orig} = $l;
					$last_line{current_pos} = $p;
				} else {
					$last_line{orig} = $p . "\t" . $l;
				}
			}
		}
		close(IN);
	}
	unlink("$tmp_last_parsed");
}

# Save last line parsed
if ($last_parsed && $last_line{datetime} && $last_line{orig}) {
	if (open(OUT, ">$last_parsed")) {
		$last_line{current_pos} ||= 0;
		print OUT "$last_line{datetime}\t$last_line{current_pos}\t$last_line{orig}\n";
		close(OUT);
	} else {
		&logmsg('ERROR', "can't save last parsed line into $last_parsed, $!");
	}
}

exit 2 if ($terminate);

my $t1 = Benchmark->new;
my $td = timediff($t1, $t0);
&logmsg('DEBUG', "the log statistics gathering took:" . timestr($td));

# Global output filehandle
my $fh = undef;

if (!$incremental && ($#given_log_files >= 0) ) {

	&logmsg('LOG', "Ok, generating $extension report...");

	if ($extension ne 'tsung') {
		$fh = new IO::File ">$outfile";
		if (not defined $fh) {
			die "FATAL: can't write to $outfile, $!\n";
		}
		if (($extension eq 'text') || ($extension eq 'txt')) {
			if ($error_only) {
				&dump_error_as_text();
			} else {
				&dump_as_text();
			}
		} elsif ($extension eq 'json') {
			if ($error_only) {
				&dump_error_as_json();
			} else {
				&dump_as_json();
			}
		} elsif ($extension eq 'binary') {
			&dump_as_binary($fh);
		} else {
			# Create instance to prettify SQL query
			if (!$noprettify) {
				$sql_prettified = SQL::Beautify->new(keywords => \@beautify_pg_keywords);
			}
			&dump_as_html('.');
		}
		$fh->close;
	} else {

		# Open filehandle
		$fh = new IO::File ">>$outfile";
		if (not defined $fh) {
			die "FATAL: can't write to $outfile, $!\n";
		}
		print $fh "</sessions>\n</tsung>\n";
		$fh->close();
	}

} elsif (!$incremental || !$noreport) {

	# Build a report per day
	my %weeks_directories = ();
	my @build_directories = ();
	if (open(IN, "$last_parsed.tmp")) {
		while (my $l = <IN>) {
			chomp($l);
			push(@build_directories, $l) if (!grep(/^$l$/, @build_directories));
		}
		close(IN);
		unlink("$last_parsed.tmp");
	} else {
		&logmsg('WARNING', "can't read file $last_parsed.tmp, $!");
		&logmsg('HINT', "maybe there's no new entries in your log since last run.");
	}
	foreach $incr_date (sort @build_directories) {

		$last_incr_date = $incr_date;

		# Set the path to binary files
		my $bpath = $incr_date;
		$bpath =~ s/\-/\//g;
		$incr_date =~ /^(\d+)-(\d+)\-(\d+)$/;

		# Get the week number following the date
		my $wn = &get_week_number($1, $2, $3);
		$weeks_directories{$wn} = "$1-$2" if (!exists $weeks_directories{$wn});

		# First clear previous stored statistics
		&init_stats_vars();

		# Load all data gathered by all the different processes
                unless(opendir(DIR, "$outdir/$bpath")) {
                        die "Error: can't opendir $outdir/$bpath: $!";
                }
                my @mfiles = grep { !/^\./ && ($_ =~ /\.bin$/) } readdir(DIR);
                closedir DIR;
		foreach my $f (@mfiles) {
			my $fht = new IO::File;
			$fht->open("< $outdir/$bpath/$f") or die "FATAL: can't open file $outdir/$bpath/$f, $!\n";
			&load_stats($fht);
			$fht->close();
		}

		&logmsg('LOG', "Ok, generating HTML daily report into $outdir/$bpath/...");

		$fh = new IO::File ">$outdir/$bpath/$outfile";
		if (not defined $fh) {
			die "FATAL: can't write to $outdir/$bpath/$outfile, $!\n";
		}
		# Create instance to prettify SQL query
		if (!$noprettify) {
			$sql_prettified = SQL::Beautify->new(keywords => \@beautify_pg_keywords);
		}
		&dump_as_html('../../..');
		$fh->close;
	}

	# Build a report per week
	foreach my $wn (sort { $a <=> $b } keys %weeks_directories) {
		&init_stats_vars();

		# Get all days of the current week
		my @wdays = &get_wdays_per_month($wn - 1, $weeks_directories{$wn});
		my $wdir = '';

		# Load data per day
		foreach $incr_date (@wdays) {
			my $bpath = $incr_date;
			$bpath =~ s/\-/\//g;
			$incr_date =~ /^(\d+)\-(\d+)\-(\d+)$/;
			$wdir = "$1/week-$wn";

			# Load all data gathered by all the differents processes
			if (-e "$outdir/$bpath") {
				unless(opendir(DIR, "$outdir/$bpath")) {
					die "Error: can't opendir $outdir/$bpath: $!";
				}
				my @mfiles = grep { !/^\./ && ($_ =~ /\.bin$/) } readdir(DIR);
				closedir DIR;
				foreach my $f (@mfiles) {
					my $fht = new IO::File;
					$fht->open("< $outdir/$bpath/$f") or die "FATAL: can't open file $outdir/$bpath/$f, $!\n";
					&load_stats($fht);
					$fht->close();
				}
			}
		}

		&logmsg('LOG', "Ok, generating HTML weekly report into $outdir/$wdir/...");
		if (!-d "$outdir/$wdir") {
			mkdir("$outdir/$wdir");
		}
		$fh = new IO::File ">$outdir/$wdir/$outfile";
		if (not defined $fh) {
			die "FATAL: can't write to $outdir/$wdir/$outfile, $!\n";
		}
		# Create instance to prettify SQL query
		if (!$noprettify) {
			$sql_prettified = SQL::Beautify->new(keywords => \@beautify_pg_keywords);
		}
		&dump_as_html('../..');
		$fh->close;

	}

	&logmsg('LOG', "Ok, generating global index to access incremental reports...");
	
	$fh = new IO::File ">$outdir/index.html";
	if (not defined $fh) {
		die "FATAL: can't write to $outdir/index.html, $!\n";
	}
	my $date = localtime(time);
	my @tmpjscode = @jscode;
	map { s/EDIT_URI/\./; } @tmpjscode;
	my $local_title = 'Global Index on incremental reports';
	if ($report_title) {
		$local_title = 'Global Index - ' . $report_title;
	}
	print $fh qq{<!DOCTYPE html>
<html lang="en">
<head>
<title>pgBadger :: $local_title</title>
<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
<meta name="robots" content="noindex,nofollow">
<meta http-equiv="Expires" content="$date">
<meta http-equiv="Generator" content="pgBadger v$VERSION">
<meta http-equiv="Date" content="$date">
<link rel="shortcut icon" href="$pgbadger_ico" />
<meta name="viewport" content="user-scalable=no, initial-scale = 1, minimum-scale = 1, maximum-scale = 1, width=device-width">
@tmpjscode
</head>

<body>

<nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container-fluid">
	<a data-placement="bottom" rel="tooltip" data-original-title="PostgreSQL Log Analyzer" href="" id="pgbadger-brand" class="brand">$pgbadger_logo $local_title</a>
    </div>
  </div>
</nav>

<div id="top"><br /><br /></div>
<div class="container" id="main-container">

<script type="text/javascript">
\$(function () {
    \$(".pgb-popover a").popover({
        placement : 'bottom',
        html : true,
    });
});
</script>
<style type="text/css">
.btn-primary {
        font-size: 2.0em;
        font-weight: bold;
        height: 60px;
        width: 184px;
}
</style>

};
	# get year directories
	unless(opendir(DIR, "$outdir")) {
		die "Error: can't opendir $outdir: $!";
	}
	my @dyears = grep { !/^\./ && /^\d{4}$/ } readdir(DIR);
	closedir DIR;
	foreach my $y (sort { $b <=> $a } @dyears) {
		print $fh qq{
<h1>Year $y</h1>
	<table class="table table-condensed"><tr>
};
		# foreach year directory look for week directories
		unless(opendir(DIR, "$outdir/$y")) {
			die "Error: can't opendir $outdir/$y: $!";
		}

		my @ymonths = grep { /^\d{2}$/ } readdir(DIR);
		closedir DIR;
		my $i = 1;
		foreach my $m (sort {$a <=> $b } @ymonths) {
			print $fh "<td><span class=\"span3\">", &get_calendar($y, $m), "</span></td>\n";
			print $fh "</tr>\n<tr>\n" if ( ($i%4) == 0 );
			$i++;
		}
		print $fh qq{
	</tr></table>
};
	}
	print $fh qq{
</div>

<footer>
<div class="">
	<small class="pull-right">Report generated by <a href="$project_url" target="_new">pgBadger $VERSION.</a></small>
</div>
</footer>

<div id="littleToc">
	<div id="littleTocTitle"><a href="#top">&nbsp;^&nbsp;</a></div>
</div>

</body>
</html>
};



	$fh->close;

}

my $t2 = Benchmark->new;
$td = timediff($t2, $t1);
&logmsg('DEBUG', "building reports took: " . timestr($td));
$td = timediff($t2, $t0);
&logmsg('DEBUG', "the total execution time took: " . timestr($td));

exit 0;

#-------------------------------------------------------------------------------

# Show pgBadger command line usage
sub usage
{
	print qq{
Usage: pgbadger [options] logfile [...]

	PostgreSQL log analyzer with fully detailed reports and graphs.

Arguments:

    logfile can be a single log file, a list of files, or a shell command
    returning a list of files. If you want to pass log content from stdin
    use - as filename. Note that input from stdin will not work with csvlog.

Options:

    -a | --average minutes : number of minutes to build the average graphs of
                             queries and connections. Default 5 minutes.
    -A | --histo-avg minutes: number of minutes to build the histogram graphs
                             of queries. Default 60 minutes.
    -b | --begin datetime  : start date/time for the data to be parsed in log.
    -B | --bar-graph       : use bar graph instead of line by default.
    -c | --dbclient host   : only report on entries for the given client host.
    -C | --nocomment       : remove comments like /* ... */ from queries.
    -d | --dbname database : only report on entries for the given database.
    -D | --dns-resolv      : client ip adresses are replaced by their DNS name.
                             Be warned that this can really slow down pgBadger.
    -e | --end datetime    : end date/time for the data to be parsed in log.
    -f | --format logtype  : possible values: syslog, syslog2, stderr and csv.
			     Default: stderr.
    -G | --nograph         : disable graphs on HTML output. Enabled by default.
    -h | --help            : show this message and exit.
    -i | --ident name      : programname used as syslog ident. Default: postgres
    -I | --incremental     : use incremental mode, reports will be generated by
                             days in a separate directory, --outdir must be set.
    -j | --jobs number     : number of jobs to run at same time. Default is 1,
			     run as single process.
    -J | --Jobs number     : number of log file to parse in parallel. Default
                             is 1, run as single process.
    -l | --last-parsed file: allow incremental log parsing by registering the
                             last datetime and line parsed. Useful if you want
                             to watch errors since last run or if you want one
                             report per day with a log rotated each week.
    -L | logfile-list file : file containing a list of log file to parse.
    -m | --maxlength size  : maximum length of a query, it will be restricted to
                             the given size. Default: no truncate
    -M | --no-multiline    : do not collect multiline statement to avoid garbage
                             especially on errors that generate a huge report.
    -n | --nohighlight     : disable SQL code highlighting.
    -N | --appname name    : only report on entries for given application name
    -o | --outfile filename: define the filename for the output. Default depends
                             on the output format: out.html, out.txt, out.bin,
                             out.json or out.tsung.
                             With module JSON::XS installed, you can output file
                             in JSON format either.
                             To dump output to stdout use - as filename.
    -O | --outdir path     : directory where out file must be saved.
    -p | --prefix string   : the value of your custom log_line_prefix as
                             defined in your postgresql.conf. Only use it if you
                             aren't using one of the standard prefixes specified
                             in the pgBadger documentation, such as if your
			     prefix includes additional variables like client ip
			     or application name. See examples below.
    -P | --no-prettify     : disable SQL queries prettify formatter.
    -q | --quiet           : don't print anything to stdout, not even a progress
			     bar.
    -r | --remote-host ip  : set the host where to execute the cat command on
			     remote logfile to parse localy the file.
    -R | --retention N     : number of week to keep in incremental mode. Default
			     to 0, disabled. Used to set the number of weel to
			     keep in output directory. Older weeks and days
			     directory are automatically removed.
    -s | --sample number   : number of query samples to store. Default: 3.
    -S | --select-only     : only report SELECT queries.
    -t | --top number      : number of queries to store/display. Default: 20.
    -T | --title string    : change title of the HTML page report.
    -u | --dbuser username : only report on entries for the given user.
    -U | --exclude-user username : exclude entries for the specified user from
			     report.
    -v | --verbose         : enable verbose or debug mode. Disabled by default.
    -V | --version         : show pgBadger version and exit.
    -w | --watch-mode      : only report errors just like logwatch could do.
    -x | --extension       : output format. Values: text, html, bin, json or
                             tsung. Default: html
    -X | --extra-files     : in incremetal mode allow pgbadger to write CSS and
			     JS files in the output directory as separate files.
    -z | --zcat exec_path  : set the full path to the zcat program. Use it if
                             zcat or bzcat or unzip is not in your path.
    --pie-limit num        : pie data lower than num% will show a sum instead.
    --exclude-query regex  : any query matching the given regex will be excluded
                             from the report. For example: "^(VACUUM|COMMIT)"
                             You can use this option multiple times.
    --exclude-file filename: path of the file which contains all the regex to
			     use to exclude queries from the report. One regex
			     per line.
    --include-query regex  : any query that does not match the given regex will
			     be excluded from the report. You can use this
			     option multiple times. For example: "(tbl1|tbl2)".
    --include-file filename: path of the file which contains all the regex of
			     the queries to include from the report. One regex
			     per line.
    --disable-error        : do not generate error report.
    --disable-hourly       : do not generate hourly report.
    --disable-type         : do not generate report of queries by type, database
			     or user.
    --disable-query        : do not generate query reports (slowest, most
                             frequent, queries by users, by database, ...).
    --disable-session      : do not generate session report.
    --disable-connection   : do not generate connection report.
    --disable-lock         : do not generate lock report.
    --disable-temporary    : do not generate temporary report.
    --disable-checkpoint   : do not generate checkpoint/restartpoint report.
    --disable-autovacuum   : do not generate autovacuum report.
    --charset              : used to set the HTML charset to be used.
			     Default: utf-8.
    --csv-separator        : used to set the CSV field separator, default: ,
    --exclude-time  regex  : any timestamp matching the given regex will be
			     excluded from the report. Example: "2013-04-12 .*"
                             You can use this option multiple times.
    --exclude-appname name : exclude entries for the specified application name
			     from report. Example: "pg_dump".
    --exclude-line regex   : pgbadger will start to exclude any log entry that
			     will match the given regex. Can be used multiple
			     time.
    --anonymize            : obscure all literals in queries, useful to hide
                             confidential data.
    --noreport             : prevent pgbadger to create reports in incremental
			     mode.
    --log-duration         : force pgbadger to associate log entries generated
                             by both log_duration = on and log_statement = 'all'
    --enable-checksum      : used to add a md5 sum under each query report.


pgBadger is able to parse a remote log file using a passwordless ssh connection.
Use the -r or --remote-host to set the host ip address or hostname. There's also
some additional options to fully control the ssh connection.

    --ssh-program ssh        path to the ssh program to use. Default: ssh.
    --ssh-user username      connection login name. Default to running user.
    --ssh-identity file      path to the identity file to use.
    --ssh-timeout second     timeout to ssh connection failure. Default 10 secs.
    --ssh-options  options   list of -o options to use for the ssh connection.
			     Options always used:
                                 -o ConnectTimeout=\$ssh_timeout
                                 -o PreferredAuthentications=hostbased,publickey

Examples:

	pgbadger /var/log/postgresql.log
	pgbadger /var/log/postgres.log.2.gz /var/log/postgres.log.1.gz \
		       /var/log/postgres.log
	pgbadger /var/log/postgresql/postgresql-2012-05-*
	pgbadger --exclude-query="^(COPY|COMMIT)" /var/log/postgresql.log
	pgbadger -b "2012-06-25 10:56:11" -e "2012-06-25 10:59:11" \
		       /var/log/postgresql.log
	cat /var/log/postgres.log | pgbadger -
	# Log prefix with stderr log output
	perl pgbadger --prefix '%t [%p]: [%l-1] user=%u,db=%d,client=%h' \
			/pglog/postgresql-2012-08-21*
	perl pgbadger --prefix '%m %u@%d %p %r %a : ' /pglog/postgresql.log
	# Log line prefix with syslog log output
	perl pgbadger --prefix 'user=%u,db=%d,client=%h,appname=%a' \
			/pglog/postgresql-2012-08-21*
	# Use my 8 CPUs to parse my 10GB file faster, much faster
	perl pgbadger -j 8 /pglog/postgresql-9.1-main.log


Generate Tsung sessions XML file with select queries only:

    perl pgbadger -S -o sessions.tsung --prefix '%t [%p]: [%l-1] user=%u,db=%d ' /pglog/postgresql-9.1.log

Reporting errors every week by cron job:

    30 23 * * 1 /usr/bin/pgbadger -q -w /var/log/postgresql.log -o /var/reports/pg_errors.html

Generate report every week using incremental behavior:

    0 4 * * 1 /usr/bin/pgbadger -q `find /var/log/ -mtime -7 -name "postgresql.log*"` \
	-o /var/reports/pg_errors-`date +%F`.html -l /var/reports/pgbadger_incremental_file.dat

This supposes that your log file and HTML report are also rotated every week.

Or better, use the auto-generated incremental reports:

    0 4 * * * /usr/bin/pgbadger -I -q /var/log/postgresql/postgresql.log.1 \
	-O /var/www/pg_reports/

will generate a report per day and per week.

In incremental mode, you can also specify the number of week to keep in the
reports:

    /usr/bin/pgbadger --retention 2 -I -q /var/log/postgresql/postgresql.log.1 \
	-O /var/www/pg_reports/

If you have a pg_dump at 23:00 and 13:00 each day during half an hour, you can
use pgbadger as follow to exclude these period from the report:

    pgbadger --exclude-time "2013-09-.* (23|13):.*" postgresql.log 

This will help avoid having COPY statements, as generated by pg_dump, on top of
the list of slowest queries. You can also use --exclude-appname "pg_dump" to
solve this problem in a simpler way.

};

	exit 0;
}

sub cleanup_directory
{
	my ($dir, $remove_dir) = @_;

	unless(opendir(DIR, "$dir")) {
		die "Error: can't opendir $dir: $!";
	}
	my @todel = grep { !/^\./ } readdir(DIR);
	closedir DIR;
	map { unlink("$dir/$_"); } @todel;
	rmdir("$dir") if ($remove_dir);
}


sub write_resources
{
	# Write resource file to report directory or return resources in and array of lines
	my $rscfh;
	my @contents = ();
	my $endfile = '';
	my $file = '';
	while (my $l = <DATA>) {
		if ($l =~ /^WRFILE: ([^\s]+)/) {
			$file = $1;
			if (!$extra_files) {
				if ($#contents > 0) {
					push(@contents, $endfile);
				}
				if ($file =~ /\.css$/i) {
					push(@contents, "<style type=\"text/css\">\n");
					$endfile = "</style>";
				} elsif ($file =~ /\.js$/i) {
					push(@contents, "<script type=\"text/javascript\">\n");
					$endfile = "</script>";
				}
				next;
			}
			$rscfh->close() if (defined $rscfh);
			if ($file =~ /\.css$/i) {
				push(@contents, "<link href=\"EDIT_URI/$file\" rel=\"stylesheet\">\n");
			} elsif ($file =~ /\.js$/i) {
					push(@contents, "<script type=\"text/javascript\" src=\"EDIT_URI/$file\"></script>\n");
			}
			if (!-e "$outdir/$file") {
				$rscfh = new IO::File ">$outdir/$file";
				die "FATAL: can't write file $outdir/$file\n" if (not defined $rscfh);
			}
			next;
		}
		if (!$extra_files) {
			push(@contents, $l);
		} else {
			$rscfh->print($l) if (defined $rscfh);
		}
	}

	$rscfh->close() if (defined $rscfh);

	# Return __DATA__ content if --extra-files is not used
	# or HTML links to resources files
	if (!$extra_files) {
		push(@contents, $endfile);
	}

	return @contents;

}

sub sort_by_week
{
	my $curr = shift;
	my $next = shift;

	$a =~ /week\-(\d+)/;
	$curr = $1;
	$b =~ /week\-(\d+)/;
	$next = $1;

	return $next <=> $curr;
}

sub init_stats_vars
{

	# Empty where statistics are stored
	%overall_stat        = ();
	%overall_checkpoint  = ();
	@top_slowest         = ();
	@top_tempfile_info   = ();
	@top_cancelled_info  = ();
	@top_locked_info     = ();
	%normalyzed_info     = ();
	%error_info          = ();
	%logs_type           = ();
	%per_minute_info     = ();
	%lock_info           = ();
	%tempfile_info       = ();
	%cancelled_info      = ();
	%connection_info     = ();
	%database_info       = ();
	%application_info    = ();
	%session_info        = ();
	%conn_received       = ();
	%checkpoint_info     = ();
	%autovacuum_info     = ();
	%autoanalyze_info    = ();
	@graph_values        = ();
	%cur_info            = ();
	$nlines              = 0;
	%tsung_session       = ();
}

####
# Main function called per each parser process
####
sub multiprocess_progressbar
{
	my $totalsize = shift;

	&logmsg('DEBUG', "Starting progressbar writer process");

	$0 = 'pgbadger logger';

	# Terminate the process when we haven't read the complete file but must exit
	local $SIG{USR1} = sub {
		print STDERR "\n";
		exit 1;
	};
	my $timeout  = 3;
	my $cursize  = 0;
	my $nqueries = 0;
	my $nerrors  = 0;
	my $last     = 0;
	$pipe->reader();
	while (my $r = <$pipe>) {
		chomp($r);
		my @infos = split(/\s+/, $r);
		last if ($infos[0] eq 'QUIT');
		$cursize  += $infos[0];
		$nqueries += $infos[1];
		$nerrors  += $infos[2];
		$cursize = $totalsize if ($cursize > $totalsize);
		print STDERR &progress_bar($cursize, $totalsize, 25, '=', $nqueries, $nerrors);
	}
	print STDERR "\n";

	exit 0;
}

####
# Main function called per each parser process
####
sub process_file
{
	my ($logfile, $tmpoutfile, $start_offset, $stop_offset, $chunk_pos) = @_;

	my $old_queries_count = 0;
	my $old_errors_count  = 0;
	my $getout            = 0;
	$start_offset       ||= 0;

	$0 = 'pgbadger parser';

	&init_stats_vars() if ($tmpoutfile);

	if (!$remote_host) {
		&logmsg('DEBUG', "Starting to parse log file: $logfile");
	} else {
		&logmsg('DEBUG', "Starting to parse remote log file: $remote_host:$logfile");
	}

	local $SIG{INT} = sub { print STDERR "Received SIGINT abort parsing...\n"; $terminate = 1; };
	local $SIG{TERM} = sub { print STDERR "Received SIGTERM abort parsing...\n"; $terminate = 1 };

	my $curdate = localtime(time);

	$pipe->writer() if (defined $pipe);

	# Syslog does not have year information, so take care of year overlapping
	my ($gsec, $gmin, $ghour, $gmday, $gmon, $gyear, $gwday, $gyday, $gisdst) = localtime(time);
	$gyear += 1900;
	my $CURRENT_DATE = $gyear . sprintf("%02d", $gmon + 1) . sprintf("%02d", $gmday);

	my $cursize = 0;

	# Get file handle and size of the file
	my ($lfile, $totalsize) = &get_log_file($logfile);
	# Reset the start position if file is smaller that the current start offset
	$start_offset = 0 if ($start_offset > $totalsize);
	# Check if the first date in the log are after the last date saved
	if (($format ne 'binary') && ($format ne 'csv')) {
		if ($start_offset && !$chunk_pos) {
			if (&check_file_changed($logfile, $saved_last_line{datetime}, 1)) {
				&logmsg('DEBUG', "This file should be parsed from the beginning: $logfile");
				&logmsg('DEBUG', "Reverting start offset $start_offset to 0 for file $logfile, stoppping offset is " . ($stop_offset || $totalsize));
				$start_offset = 0;
			}
			$cursize = $start_offset;
		}
	} else {
		$start_offset = 0;
		$stop_offset = 0;
	}

	if ($stop_offset > 0) {
		$totalsize = $stop_offset - $start_offset;
	}

	my $current_offset = $start_offset || 0;

	# Forward the progress bar to the starting point in MP mode
	#$cursize = $start_offset if ($chunk_pos == 0);

	if (!$remote_host) {
		&logmsg('DEBUG', "Starting reading file $logfile...");
	} else {
		&logmsg('DEBUG', "Starting reading file $remote_host:$logfile...");
	}

	if ($format eq 'csv') {

		require Text::CSV_XS;
		my $csv = Text::CSV_XS->new(
			{
				binary => 1,
				eol => $/,
				sep_char => $csv_sep_char,
				allow_loose_quotes => 1,
			}
		);

		# Parse csvlog lines
		CSVLOOP: while (!$csv->eof()) {
			while (my $row = $csv->getline($lfile)) {

				# We received a signal
				last CSVLOOP if ($terminate);

				# Number of columns in csvlog (22 before 9.0 and 23 from 9.0 to current)
				next if ( ($#{$row} != 22) && ($#{$row} != 21) );

				# Set progress statistics
				$cursize += length(join(',', @$row));
				$nlines++;
				if (!$tmpoutfile) {
					if ($progress && (($nlines % $NUMPROGRESS) == 0)) {
						if ($totalsize) {
							print STDERR &progress_bar($cursize, $totalsize, 25, '=');
						} else {
							print STDERR ".";
						}
					}
				} else {
					if ($progress && (($nlines % $NUMPROGRESS) == 0)) {
						$pipe->print("$cursize " . ($overall_stat{'queries_number'} - $old_queries_count) . " " . ($overall_stat{'errors_number'} - $old_errors_count) . "\n");
						$old_queries_count = $overall_stat{'queries_number'};
						$old_errors_count = $overall_stat{'errors_number'};
						$cursize = 0;
					}
				}
				next if ($row->[11] !~ $parse_regex);

				# Extract the date
				if ($row->[0] =~ m/^(\d+)-(\d+)-(\d+)\s+(\d+):(\d+):(\d+)\.(\d+)/) {

					# Remove newline characters from queries
					map { s/[\r\n]+/ /gs; } @$row;

					my $milli = $7 || 0;
					($prefix_vars{'t_year'}, $prefix_vars{'t_month'}, $prefix_vars{'t_day'}, $prefix_vars{'t_hour'}, $prefix_vars{'t_min'}, $prefix_vars{'t_sec'}) = ($1, $2, $3, $4, $5, $6);
					$prefix_vars{'t_timestamp'} = "$1-$2-$3 $4:$5:$6";

					# Skip unwanted lines
					next if ($from && ($from gt $prefix_vars{'t_timestamp'}));
					if ($to && ($to lt $prefix_vars{'t_timestamp'})) {
						if ($tmpoutfile) {
							$pipe->print("$cursize " . ($overall_stat{'queries_number'} - $old_queries_count) . " " . ($overall_stat{'errors_number'} - $old_errors_count) . "\n");
							$old_queries_count = $overall_stat{'queries_number'};
							$old_errors_count = $overall_stat{'errors_number'};
							$cursize = 0;
						}
						$getout = 2;
						last CSVLOOP;
					}

					# Jump to the last line parsed if required
					next if (!&check_incremental_position($prefix_vars{'t_timestamp'}, join(',', @$row)));

					# Store the current timestamp of the log line
					&store_current_timestamp($prefix_vars{'t_timestamp'});

					# Set query parameters as global variables
					$prefix_vars{'t_dbuser'}  = $row->[1] || '';
					$prefix_vars{'t_dbname'}  = $row->[2] || '';
					$prefix_vars{'t_appname'} = $row->[22] || '';
					$prefix_vars{'t_client'}  = $row->[4] || '';
					$prefix_vars{'t_client'}  =~ s/:.*//;
					$prefix_vars{'t_client'} = _gethostbyaddr($prefix_vars{'t_client'}) if ($dns_resolv);
					$prefix_vars{'t_host'}    = 'csv';
					$prefix_vars{'t_pid'}     = $row->[3];
					$prefix_vars{'t_session_line'} = $row->[5];
					$prefix_vars{'t_session_line'} =~ s/\..*//;
					$prefix_vars{'t_loglevel'} = $row->[11];
					$prefix_vars{'t_query'}    = $row->[13];
					# Set ERROR additional information
					$prefix_vars{'t_detail'} = $row->[14];
					$prefix_vars{'t_hint'} = $row->[15];
					$prefix_vars{'t_context'} = $row->[18];
					$prefix_vars{'t_statement'} = $row->[19];

					# Check if the log line should be excluded from the report
					if (&validate_log_line($prefix_vars{'t_pid'})) {

						# Parse the query now
						&parse_query();
						if (&store_queries($prefix_vars{'t_pid'})) {
							delete $cur_info{$prefix_vars{'t_pid'}};
						}
					}
				}
			}
			if (!$csv->eof()) {
				warn "FATAL: cannot use CSV on $logfile, " . $csv->error_diag() . " at line " . ($nlines+1), "\n";
				print STDERR "DETAIL: " . $csv->error_input(), "\n" if ($csv->error_input());
				print STDERR "reset CSV parser\n";
				$csv->SetDiag(0);
			}
		}

	}
	elsif ($format eq 'binary') {
		&load_stats($lfile);
	}
	else { # Format is not CSV.

		my $time_pattern = qr/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/;
		my $cur_pid = '';
		my @matches = ();
		my $goon = 0;
		my $has_exclusion = 0;
		if ($#exclude_line >= 0) {
			$has_exclusion = 1;
		}
		&logmsg('DEBUG', "Start parsing at offset $start_offset of file $logfile to " . ($stop_offset || $totalsize));
		if ($start_offset) {
			# Move to the starting offset position in file
			$lfile->seek($start_offset, 0);
		}
		while (my $line = <$lfile>) {

			# We received a signal
			last if ($terminate);

			# Start to exclude from parsing any desired lines
			if ($has_exclusion >= 0) {

				# Log line matches the excluded regex
				my $ef = 0;
				map { $ef = 1, last if ($line =~ /$_/is); } @exclude_line;
				next if ($ef);
			}

			$cursize += length($line);
			$current_offset += length($line);

			chomp($line);
			$line =~ s/\r//;
			$nlines++;
			next if (!$line);

			if (!$tmpoutfile) {
				if ($progress && (($nlines % $NUMPROGRESS) == 0)) {
					if ($totalsize) {
						print STDERR &progress_bar($cursize, $stop_offset || $totalsize, 25, '=');
					} else {
						print STDERR ".";
					}
				}
			} else {
				if ($progress && (($nlines % $NUMPROGRESS) == 0)) {
					$pipe->print("$cursize " . ($overall_stat{'queries_number'} - $old_queries_count) . " " . ($overall_stat{'errors_number'} - $old_errors_count) . "\n");
					$old_queries_count = $overall_stat{'queries_number'};
					$old_errors_count = $overall_stat{'errors_number'};
					$cursize = 0;
				}
			}

			%prefix_vars = ();

			# Parse syslog lines
			if ($format =~ /syslog/) {

				@matches = ($line =~ $compiled_prefix);

				if ($#matches >= 0) {

					for (my $i = 0 ; $i <= $#prefix_params ; $i++) {
						$prefix_vars{$prefix_params[$i]} = $matches[$i];
					}

					# skip non postgresql lines
					next if ($prefix_vars{'t_ident'} ne $ident);

					# Store temporary files and locks information
					&store_temporary_and_lock_infos($cur_pid);

					# Standard syslog format does not have year information, months are
					# three letters and days are not always with 2 digits.
					if ($prefix_vars{'t_month'} !~ /\d/) {
						$prefix_vars{'t_year'}  = $gyear;
						$prefix_vars{'t_day'}   = sprintf("%02d", $prefix_vars{'t_day'});
						$prefix_vars{'t_month'} = $month_abbr{$prefix_vars{'t_month'}};
						# Take care of year overlapping
						if ("$prefix_vars{'t_year'}$prefix_vars{'t_month'}$prefix_vars{'t_day'}" > $CURRENT_DATE) {
							$prefix_vars{'t_year'} = substr($CURRENT_DATE, 0, 4) - 1;
						}
					}
					$prefix_vars{'t_timestamp'} =
"$prefix_vars{'t_year'}-$prefix_vars{'t_month'}-$prefix_vars{'t_day'} $prefix_vars{'t_hour'}:$prefix_vars{'t_min'}:$prefix_vars{'t_sec'}";

					# Skip unwanted lines
					if ($#exclude_time >= 0) {
						foreach (@exclude_time) {
							if ($prefix_vars{'t_timestamp'} =~ /$_/) {
								return;
							}
						}
					}

					next if ($from && ($from gt $prefix_vars{'t_timestamp'}));
					if ($to   && ($to lt $prefix_vars{'t_timestamp'})) {
						if (!$tmpoutfile) {
							if ($totalsize) {
								print STDERR &progress_bar($cursize, $stop_offset || $totalsize, 25, '=');
							} else {
								print STDERR ".";
							}
						} else {
							$pipe->print("$cursize " . ($overall_stat{'queries_number'} - $old_queries_count) . " " . ($overall_stat{'errors_number'} - $old_errors_count) . "\n");
							$old_queries_count = $overall_stat{'queries_number'};
							$old_errors_count = $overall_stat{'errors_number'};
							$cursize = 0;
						}
						$getout = 2;
						last;
					}

					# Jump to the last line parsed if required
					next if (!&check_incremental_position($prefix_vars{'t_timestamp'}, $line));
					$cur_pid = $prefix_vars{'t_pid'};
					$goon = 1;
					$prefix_vars{'t_client'} = _gethostbyaddr($prefix_vars{'t_client'}) if ($dns_resolv);

					# Store the current timestamp of the log line
					&store_current_timestamp($prefix_vars{'t_timestamp'});

					# Extract information from log line prefix
					if (!$log_line_prefix) {
						&parse_log_prefix($prefix_vars{'t_logprefix'});
					}

					# Check if the log line should be excluded from the report
					if (&validate_log_line($prefix_vars{'t_pid'})) {

						# Process the log line
						&parse_query();
					}

				} elsif ($goon && ($line =~ $other_syslog_line)) {

					$cur_pid = $8;
					my $t_query = $10;
					$t_query =~ s/#011/\t/g;
					next if ($t_query eq "\t");

					if ($cur_info{$cur_pid}{vacuum} && ($t_query =~ /^\t(pages|tuples|buffer usage|avg read rate|system usage):/)) {
						if ($t_query =~ /^\t(pages|tuples): (\d+) removed, (\d+) remain/) {
							$autovacuum_info{tables}{$cur_info{$cur_pid}{vacuum}}{$1}{removed} += $2;
						}
						if ($t_query =~ m#^\tsystem usage: CPU .* sec elapsed (.*) sec#) {
							if ($1 > $autovacuum_info{peak}{system_usage}{elapsed}) {
								$autovacuum_info{peak}{system_usage}{elapsed} = $1;
								$autovacuum_info{peak}{system_usage}{table} = $cur_info{$cur_pid}{vacuum};
								$autovacuum_info{peak}{system_usage}{date} = 
									"$cur_info{$cur_pid}{year}-$cur_info{$cur_pid}{month}-$cur_info{$cur_pid}{day} " .
									"$cur_info{$cur_pid}{hour}:$cur_info{$cur_pid}{min}:$cur_info{$cur_pid}{sec}";
							}
						}
						next;
					} elsif ( $cur_info{$cur_pid}{parameters} && (($t_query =~ /[,\s]*\$(\d+)\s=\s/) || ($t_query =~ /^('[^']*')$/)) ) {
						# stores bind parameters if any
						$cur_info{$cur_pid}{parameters} .= " $t_query";
						next;
					} 

					# Some log line may be written by applications
					next if ($line =~ /\bLOG:  /);

					if (exists $cur_plan_info{$cur_pid}{duration}) {
						$cur_plan_info{$cur_pid}{plan} .= "\n" . $t_query;
					} elsif (exists $cur_temp_info{$cur_pid}{query}) {
						$cur_temp_info{$cur_pid}{query} .= "\n" . $t_query;
					} elsif (exists $cur_lock_info{$cur_pid}{query}) {
						$cur_lock_info{$cur_pid}{query} .= "\n" . $t_query;
					} elsif (exists $cur_cancel_info{$cur_pid}{query}) {
						$cur_cancel_info{$cur_pid}{query} .= "\n" . $t_query;
					} elsif (exists $cur_info{$cur_pid}{statement}) {
						$cur_info{$cur_pid}{statement} .= "\n" . $t_query if (!$nomultiline);
					} elsif (exists $cur_info{$cur_pid}{context}) {
						$cur_info{$cur_pid}{context} .= "\n" . $t_query;
					} elsif (exists $cur_info{$cur_pid}{detail}) {
						$cur_info{$cur_pid}{detail} .= "\n" . $t_query;
					} elsif (exists $cur_info{$cur_pid}{query}) {
						$cur_info{$cur_pid}{query} .= "\n" . $t_query if (!$nomultiline);
					}

				# Collect orphaned lines of multiline queries
				} elsif ($cur_pid && ($line !~ $orphan_syslog_line)) {

					# Some log line may be written by applications
					next if ($line =~ /\bLOG:  /);

					if (exists $cur_plan_info{$cur_pid}{duration}) {
						$cur_plan_info{$cur_pid}{plan} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{parameters}) {
						# stores bind parameters if any
						$cur_info{$cur_pid}{parameters} .= "\n" . $line;
					} elsif (exists $cur_temp_info{$cur_pid}{query}) {
						$cur_temp_info{$cur_pid}{query} .= "\n" . $line;
					} elsif (exists $cur_lock_info{$cur_pid}{query}) {
						$cur_lock_info{$cur_pid}{query} .= "\n" . $line;
					} elsif (exists $cur_cancel_info{$cur_pid}{query}) {
						$cur_cancel_info{$cur_pid}{query} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{statement}) {
						$cur_info{$cur_pid}{statement} .= "\n" . $line if (!$nomultiline);
					} elsif (exists $cur_info{$cur_pid}{context}) {
						$cur_info{$cur_pid}{context} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{detail}) {
						$cur_info{$cur_pid}{detail} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{query}) {
						$cur_info{$cur_pid}{query} .= "\n" . $line if (!$nomultiline);
					}

				} else {
					&logmsg('DEBUG', "Unknown syslog line format: $line");
				}

			} elsif ($format eq 'stderr') {

				@matches = ($line =~ $compiled_prefix);
				if ($#matches >= 0) {
					for (my $i = 0 ; $i <= $#prefix_params ; $i++) {
						$prefix_vars{$prefix_params[$i]} = $matches[$i];
					}

					# Stores temporary files and lock information
					&store_temporary_and_lock_infos($cur_pid);

					if (!$prefix_vars{'t_timestamp'} && $prefix_vars{'t_mtimestamp'}) {
						$prefix_vars{'t_timestamp'} = $prefix_vars{'t_mtimestamp'};
					} elsif (!$prefix_vars{'t_timestamp'} && $prefix_vars{'t_session_timestamp'}) {
						$prefix_vars{'t_timestamp'} = $prefix_vars{'t_session_timestamp'};
					}
					($prefix_vars{'t_year'}, $prefix_vars{'t_month'}, $prefix_vars{'t_day'}, $prefix_vars{'t_hour'},
						$prefix_vars{'t_min'}, $prefix_vars{'t_sec'}) = ($prefix_vars{'t_timestamp'} =~ $time_pattern);

					# Skip unwanted lines
					if ($#exclude_time >= 0) {
						foreach (@exclude_time) {
							if ($prefix_vars{'t_timestamp'} =~ /$_/) {
								return;
							}
						}
					}
					next if ($from && ($from gt $prefix_vars{'t_timestamp'}));
					if ($to   && ($to lt $prefix_vars{'t_timestamp'})) {
						if (!$tmpoutfile) {
							if ($totalsize) {
								print STDERR &progress_bar($cursize, $stop_offset || $totalsize, 25, '=');
							} else {
								print STDERR ".";
							}
						} else {
							$pipe->print("$cursize " . ($overall_stat{'queries_number'} - $old_queries_count) . " " . ($overall_stat{'errors_number'} - $old_errors_count) . "\n");
							$old_queries_count = $overall_stat{'queries_number'};
							$old_errors_count = $overall_stat{'errors_number'};
							$cursize = 0;
						}
						$getout = 2;
						last;
					}

					# Jump to the last line parsed if required
					next if (!&check_incremental_position($prefix_vars{'t_timestamp'}, $line));
					$cur_pid = $prefix_vars{'t_pid'};
					$prefix_vars{'t_client'} = _gethostbyaddr($prefix_vars{'t_client'}) if ($dns_resolv);

					# Store the current timestamp of the log line
					&store_current_timestamp($prefix_vars{'t_timestamp'});

					# Extract information from log line prefix
					if (!$log_line_prefix) {
						&parse_log_prefix($prefix_vars{'t_logprefix'});
					}

					# Check if the log line should be excluded from the report
					if (&validate_log_line($prefix_vars{'t_pid'})) {
						$prefix_vars{'t_host'} = 'stderr';

						# Process the log line
						&parse_query();
					}

				# Collect additional query information
				} elsif ($cur_pid && ($line !~ $orphan_stderr_line)) {

					if ($line =~ s/^(STATEMENT|DETAIL|HINT):\s+//) {
						my $lbl = lc($1);
						$line =~ s/ERROR:\s+//;
						if (exists $cur_temp_info{$cur_pid}{size}) {
							$cur_temp_info{$cur_pid}{query} .= $line;
						} elsif (exists $cur_lock_info{$cur_pid}{query}) {
							$cur_lock_info{$cur_pid}{query} .= "\n" . $line;
						} elsif (exists $cur_cancel_info{$cur_pid}{query}) {
							$cur_cancel_info{$cur_pid}{query} .= "\n" . $line;
						} else {
							$cur_info{$cur_pid}{$lbl} = $line;
						}
						next;
					} elsif ($cur_info{$cur_pid}{vacuum} && ($line =~ /^\t(pages|tuples|buffer usage|avg read rate|system usage):/)) {
						if ($line =~ /^\t(pages|tuples): (\d+) removed, (\d+) remain/) {
							$autovacuum_info{tables}{$cur_info{$cur_pid}{vacuum}}{$1}{removed} += $2;
						}
						if ($line =~ m#^\tsystem usage: CPU .* sec elapsed (.*) sec#) {
							if ($1 > $autovacuum_info{peak}{system_usage}{elapsed}) {
								$autovacuum_info{peak}{system_usage}{elapsed} = $1;
								$autovacuum_info{peak}{system_usage}{table} = $cur_info{$cur_pid}{vacuum};
								$autovacuum_info{peak}{system_usage}{date} = 
									"$cur_info{$cur_pid}{year}-$cur_info{$cur_pid}{month}-$cur_info{$cur_pid}{day} " .
									"$cur_info{$cur_pid}{hour}:$cur_info{$cur_pid}{min}:$cur_info{$cur_pid}{sec}";
							}
						}
						next;
					} elsif ( $cur_info{$cur_pid}{parameters} && (($line =~ /[,\s]*\$(\d+)\s=\s/) || ($line =~ /^'[^']*'$/)) ) {
						# stores bind parameters if any
						$cur_info{$cur_pid}{parameters} .= " $line";
						next;
					} 

					# Some log line may be written by applications
					next if ($line =~ /\bLOG:  /);

					if (exists $cur_plan_info{$cur_pid}{duration}) {
						$cur_plan_info{$cur_pid}{plan} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{parameters}) {
						# stores bind parameters if any
						$cur_info{$cur_pid}{parameters} .= "\n" . $line;
					} elsif (exists $cur_temp_info{$cur_pid}{size}) {
						if (exists $cur_info{$cur_pid}{query} && !$cur_temp_info{$cur_pid}{query}) {
							$cur_temp_info{$cur_pid}{query} = $cur_info{$cur_pid}{query};
							$cur_temp_info{$cur_pid}{timestamp} = $cur_info{$cur_pid}{'timestamp'};
							$cur_temp_info{$cur_pid}{dbname}    = $cur_info{$cur_pid}{'dbname'};
							$cur_temp_info{$cur_pid}{dbuser}    = $cur_info{$cur_pid}{'dbuser'};
							$cur_temp_info{$cur_pid}{dbclient}  = $cur_info{$cur_pid}{'client'} || $cur_info{$cur_pid}{'dbclient'};
							$cur_temp_info{$cur_pid}{dbappname} = $cur_info{$cur_pid}{'appname'};
							delete $cur_info{$cur_pid};
						}
						$cur_temp_info{$cur_pid}{query} .= "\n" . $line;
					} elsif (exists $cur_lock_info{$cur_pid}{query}) {
						$cur_lock_info{$cur_pid}{query} .= "\n" . $line;
					} elsif (exists $cur_cancel_info{$cur_pid}{query}) {
						$cur_cancel_info{$cur_pid}{query} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{statement}) {
						$cur_info{$cur_pid}{statement} .= "\n" . $line if (!$nomultiline);
					} elsif (exists $cur_info{$cur_pid}{context}) {
						$cur_info{$cur_pid}{context} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{detail}) {
						$cur_info{$cur_pid}{detail} .= "\n" . $line;
					} elsif (exists $cur_info{$cur_pid}{query}) {
						$cur_info{$cur_pid}{query} .= "\n" . $line if (!$nomultiline);
					}

				# Collect orphaned lines of multiline queries
				} elsif ($cur_pid && ($cur_info{$cur_pid}{query})) {

					$cur_info{$cur_pid}{detail} .= "\n" . $line;

				} elsif (exists $cur_plan_info{$cur_pid}{duration}) {

					$cur_plan_info{$cur_pid}{plan} .= "\n" . $line;

				}

			} else {

				# unknown format
				&logmsg('DEBUG', "Unknown line format: $line");
			}
			last if (($stop_offset > 0) && ($current_offset >= $stop_offset));
		}
		if ($last_parsed) {
			$last_line{current_pos} = $current_offset;
		}

	}
	close $lfile;

	# Inform the parent that it should stop parsing other files
	if ($terminate) {
		kill(12, $parent_pid);
		return $terminate;
	}

	# Get stats from all pending temporary storage
	foreach my $pid (sort {$cur_info{$a}{date} <=> $cur_info{$b}{date}} keys %cur_info) {
		# Stores last query information
		&store_queries($pid, 1);
	}

	# Stores last temporary files and lock information
	foreach my $pid (keys %cur_temp_info) {
		&store_temporary_and_lock_infos($pid);
	}

	# Stores last cancelled queries information
	foreach my $pid (keys %cur_cancel_info) {
		&store_temporary_and_lock_infos($pid);
	}

	# Stores last temporary files and lock information
	foreach my $pid (keys %cur_lock_info) {
		&store_temporary_and_lock_infos($pid);
	}

	if ($extension eq 'tsung') {
		foreach my $pid (sort {$a <=> $b} keys %tsung_session) {
			&store_tsung_session($pid);
		}
	}

	if ($progress && ($getout != 1)) {
		if (!$tmpoutfile) {
			if ($totalsize) {
				print STDERR &progress_bar($cursize, $stop_offset || $totalsize, 25, '=',$overall_stat{'queries_number'},$overall_stat{'errors_number'}, $logfile);
				print STDERR "\n";
			}
		} else {
			$pipe->print("$cursize " . ($overall_stat{'queries_number'} - $old_queries_count) . " " . ($overall_stat{'errors_number'} - $old_errors_count) . "\n");
		}
	}

	%cur_info = ();

	# In incremental mode data are saved to disk per day
	if ($incremental && $last_line{datetime}) {
		$incr_date = $last_line{datetime};
		$incr_date =~ s/\s.*$//;
		# set path and create subdirectories
		my $bpath = $incr_date;
		while ($bpath =~ s/([^\-]+)\-/$1\//) {
			mkdir("$outdir/$1") if (!-d "$outdir/$1");
		}
		mkdir("$outdir/$bpath") if (!-d "$outdir/$bpath");

		# Mark the directory as needing index update
		if (open(OUT, ">>$last_parsed.tmp")) {
			flock(OUT, 2) || return $getout;
			print OUT "$incr_date\n";
			close(OUT);
		} else {
			&logmsg('ERROR', "can't save last parsed line into $last_parsed.tmp, $!");
		}

		# Save binary data
		my $filenum = $$;
		$filenum++ while (-e "$outdir/$bpath/$incr_date-$filenum.bin");
		my $fhb = new IO::File ">$outdir/$bpath/$incr_date-$filenum.bin";
		if (not defined $fhb) {
			die "FATAL: can't write to $outdir/$bpath/$incr_date-$filenum.bin, $!\n";
		}
		&dump_as_binary($fhb);
		$fhb->close;
		&init_stats_vars();

	} elsif ($tmpoutfile) {

		&dump_as_binary($tmpoutfile);
		$tmpoutfile->close();

	}

	# Inform the parent that it should stop parsing other files
	if ($getout) {
		kill(12, $parent_pid);
	}

	# Save last line into temporary file
	if ($last_parsed && scalar keys %last_line) {
		if (open(OUT, ">>$tmp_last_parsed")) {
			flock(OUT, 2) || return $getout;
			$last_line{current_pos} ||= 0;

			print OUT "$last_line{datetime}\t$last_line{current_pos}\t$last_line{orig}\n";
			close(OUT);
		} else {
			&logmsg('ERROR', "can't save last parsed line into $tmp_last_parsed, $!");
		}
	}

	return $getout;
}

# Store the current timestamp of the log line
sub store_current_timestamp
{
	my $t_timestamp = shift;

	$prefix_vars{'t_date'} = $t_timestamp;
	$prefix_vars{'t_date'} =~ s/\D+//g;

	if (!$overall_stat{'first_log_ts'} || ($overall_stat{'first_log_ts'} gt $t_timestamp)) {
		$overall_stat{'first_log_ts'} = $t_timestamp;
	}
	if (!$overall_stat{'last_log_ts'} || ($overall_stat{'last_log_ts'} lt $t_timestamp)) {
		$overall_stat{'last_log_ts'} = $t_timestamp;
	}
}

# Method used to check if the file stores logs after the last incremental position or not
# This position should have been saved in the incremental file and read in the $last_parsed at
# start up. Here we just verify that the first date in file is before the last incremental date.
sub check_file_changed
{
	my ($file, $saved_date, $look_at_beginning) = @_;

	my ($lfile, $totalsize, $iscompressed) = &get_log_file($file);

	# Compressed files do not allow seeking
	if ($iscompressed) {
		close($lfile);
		return 1;
		
	}

	my ($gsec, $gmin, $ghour, $gmday, $gmon, $gyear, $gwday, $gyday, $gisdst) = localtime(time);
	$gyear += 1900;
	my $CURRENT_DATE = $gyear . sprintf("%02d", $gmon + 1) . sprintf("%02d", $gmday);

	%prefix_vars = ();
	# If seeking is not explicitely disabled
	if (!$look_at_beginning) {
		# do not seek if filesize is smaller than the seek position
		if ($saved_last_line{current_pos} < $totalsize) {
			$lfile->seek($saved_last_line{current_pos} || 0, 0);
		}
	}

	my $more_lines = 0;
	while (my $line = <$lfile>) {

		$more_lines++;

		if ($format =~ /syslog/) {

			my @matches = ($line =~ $compiled_prefix);
			if ($#matches >= 0) {

				for (my $i = 0 ; $i <= $#prefix_params ; $i++) {
					$prefix_vars{$prefix_params[$i]} = $matches[$i];
				}
				# Standard syslog format does not have year information, months are
				# three letters and days are not always with 2 digits.
				if ($prefix_vars{'t_month'} !~ /\d/) {
					$prefix_vars{'t_year'}  = $gyear;
					$prefix_vars{'t_day'}   = sprintf("%02d", $prefix_vars{'t_day'});
					$prefix_vars{'t_month'} = $month_abbr{$prefix_vars{'t_month'}};
					# Take care of year overlapping
					if ("$prefix_vars{'t_year'}$prefix_vars{'t_month'}$prefix_vars{'t_day'}" > $CURRENT_DATE) {
						$prefix_vars{'t_year'} = substr($CURRENT_DATE, 0, 4) - 1;
					}
				}
				$prefix_vars{'t_timestamp'} =
"$prefix_vars{'t_year'}-$prefix_vars{'t_month'}-$prefix_vars{'t_day'} $prefix_vars{'t_hour'}:$prefix_vars{'t_min'}:$prefix_vars{'t_sec'}";
				# This file has already been parsed
				if ($saved_date gt $prefix_vars{'t_timestamp'}) {
					close($lfile);
					return 0;
				} else {
					last;
				}
			}

		} elsif ($format eq 'stderr') {

			my @matches = ($line =~ $compiled_prefix);
			if ($#matches >= 0) {
				for (my $i = 0 ; $i <= $#prefix_params ; $i++) {
					$prefix_vars{$prefix_params[$i]} = $matches[$i];
				}
				if (!$prefix_vars{'t_timestamp'} && $prefix_vars{'t_mtimestamp'}) {
					$prefix_vars{'t_timestamp'} = $prefix_vars{'t_mtimestamp'};
				} elsif (!$prefix_vars{'t_timestamp'} && $prefix_vars{'t_session_timestamp'}) {
					$prefix_vars{'t_timestamp'} = $prefix_vars{'t_session_timestamp'};
				}
			}
			next if (!$prefix_vars{'t_timestamp'});
			# This file has already been parsed
			if ($saved_date gt $prefix_vars{'t_timestamp'}) {
				close($lfile);
				return 0;
			} else {
				last;
			}
		}
	}
	close($lfile);

	if (!$more_lines) {
		close($lfile);
		return 0;
	}

	return 1;
}


# Method used to check if we have already reached the last parsing position in incremental mode
# This position should have been saved in the incremental file and read in the $last_parsed at
# start up.
sub check_incremental_position
{
	my ($cur_date, $line) = @_;

	if ($last_parsed) {
		if ($saved_last_line{datetime}) {
			if ($cur_date lt $saved_last_line{datetime}) {
				return 0;
			} elsif (!$last_line{datetime} && ($cur_date eq $saved_last_line{datetime})) {
				return 0 if ($line ne $saved_last_line{orig});
			}
		}
		$last_line{datetime} = $cur_date;
		$last_line{orig}     = $line;
	}

	# In incremental mode data are saved to disk per day
	if ($incremental) {
		$cur_date =~ s/\s.*$//;
		# Check if the current day has changed, if so save data
		$incr_date = $cur_date if (!$incr_date);
		if ($cur_date gt $incr_date) {

			# Get stats from all pending temporary storage
			foreach my $pid (sort {$cur_info{$a}{date} <=> $cur_info{$b}{date}} keys %cur_info) {
				# Stores last queries information
				&store_queries($pid, 1);
			}
			# Stores last temporary files and lock information
			foreach my $pid (keys %cur_temp_info) {
				&store_temporary_and_lock_infos($pid);
			}
			# Stores last cancelled queries information
			foreach my $pid (keys %cur_cancel_info) {
				&store_temporary_and_lock_infos($pid);
			}
			# Stores last temporary files and lock information
			foreach my $pid (keys %cur_lock_info) {
				&store_temporary_and_lock_infos($pid);
			}

			if ($extension eq 'tsung') {
				foreach my $pid (sort {$a <=> $b} keys %tsung_session) {
					&store_tsung_session($pid);
				}
			}

			# set path and create subdirectories
			my $bpath = $incr_date;
			while ($bpath =~ s/([^\-]+)\-/$1\//) {
				mkdir("$outdir/$1") if (!-d "$outdir/$1");
			}
			mkdir("$outdir/$bpath") if (!-d "$outdir/$bpath");

			# Mark this directory as needing a reindex	
			if (open(OUT, ">>$last_parsed.tmp")) {
				flock(OUT, 2) || return 1;
				print OUT "$incr_date\n";
				close(OUT);
			} else {
				&logmsg('ERROR', "can't save last parsed line into $last_parsed.tmp, $!");
			}

			# Save binary data
			my $filenum = $$;
			$filenum++ while (-e "$outdir/$bpath/$incr_date-$filenum.bin");
			my $fhb = new IO::File ">$outdir/$bpath/$incr_date-$filenum.bin";
			if (not defined $fhb) {
				die "FATAL: can't write to $outdir/$bpath/$incr_date-$filenum.bin, $!\n";
			}
			&dump_as_binary($fhb);
			$fhb->close;
			$incr_date = $cur_date;
			&init_stats_vars();
		}
	}

	return 1;
}

# Display message following the log level
sub logmsg
{
	my ($level, $str) = @_;

	return if ($quiet && ($level ne 'FATAL'));
	return if (!$debug && ($level eq 'DEBUG'));

	if ($level =~ /(\d+)/) {
		print STDERR "\t" x $1;
	}

	print STDERR "$level: $str\n";
}

# Normalize SQL queries by removing parameters
sub normalize_query
{
	my $orig_query = shift;

	return if (!$orig_query);

	# Remove comments
	$orig_query =~ s/\/\*(.*?)\*\///gs;

	# Set the entire query lowercase
	$orig_query = lc($orig_query);

	# Remove extra space, new line and tab characters by a single space
	$orig_query =~ s/[\t\s\r\n]+/ /gs;

	# Removed start of transaction 
	if ($orig_query !~ /^\s*begin\s*;\s*$/) {
		$orig_query =~ s/^\s*begin\s*;\s*//gs
	}

	# Remove string content
	$orig_query =~ s/\\'//g;
	$orig_query =~ s/'[^']*'/''/g;
	$orig_query =~ s/''('')+/''/g;

	# Remove NULL parameters
	$orig_query =~ s/=\s*NULL/=''/g;

	# Remove numbers
	$orig_query =~ s/([^a-z_\$-])-?([0-9]+)/${1}0/g;

	# Remove hexadecimal numbers
	$orig_query =~ s/([^a-z_\$-])0x[0-9a-f]{1,10}/${1}0x/g;

	# Remove IN values
	$orig_query =~ s/in\s*\([\'0x,\s]*\)/in (...)/g;

	return $orig_query;
}

sub generate_anonymized_string
{
        my ($original, $cache, $before) = @_;

        # Prevent dates from being anonymized
        return $original if $original =~ m{\A\d\d\d\d[/:-]\d\d[/:-]\d\d\z};
        return $original if $original =~ m{\A\d\d[/:-]\d\d[/:-]\d\d\d\d\z};
	# Prevent dates format like DD/MM/YYYY HH24:MI:SS from being anonymized
        return $original if $original =~ m{\A(?:FM|FX|TM)?(?:HH|HH12|HH24|MI|SS|MS|US|SSSS|AM|A\.M\.|PM|P\.M\.|am|a\.m\.|pm|p\.m\.|Y,YYY|YYYY|YYY|YY|Y|IYYY|IYY|IY|I|BC|B\.C\.|AD|A\.D\.|bc|b\.c\.|ad|a\.d\.|MONTH|Month|month|MON|Mon|mon|MM|DAY|Day|day|DY|Dy|dy|DDD|DD|D|W|WW|IW|CC|J|Q|RM|rm|TZ|tz|[\s\/\-:])+(?:TH|th|SP)?$};
	# Prevent interval from being anonymized
	return $original if $before =~ /interval/i;

        # Range of characters to use in anonymized strings
        my @chars = ('A'..'Z', 0..9, 'a'..'z', '-', '_', '.');

        unless ($cache->{$original}) {
                # Actual anonymized version generation
                $cache->{$original} = join('', map { $chars[rand @chars] } 1..10 );
        }
        return $cache->{$original};
}


# Anonymize litteral in SQL queries by replacing parameters with fake values
sub anonymize_query
{
	my $orig_query = shift;

	return if (!$orig_query);

	# Variable to hold anonymized versions, so we can provide the same value
	# for the same input, within single query.
	my $anonymization_cache = {};

	# Remove comments
	$orig_query =~ s/\/\*(.*?)\*\///gs;

	# Clean query
	$orig_query =~ s/\\'//g;
	$orig_query =~ s/('')+//g;

	# Anonymize each values
	$orig_query =~ s/([^\s]+[\s\(]*)'([^']*)'/"$1'".generate_anonymized_string($2, $anonymization_cache, $1)."'"/eg;

	return $orig_query;
}

# Format numbers with comma for better reading
sub comma_numbers
{
	return 0 if ($#_ < 0);

	return 0 if (!$_[0]);

	my $text = reverse $_[0];

	$text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1$num_sep/g;

	return scalar reverse $text;
}

# Format numbers with comma for better reading
sub pretty_print_size
{
	my $val = shift;
	return 0 if (!$val);

	if ($val >= 1125899906842624) {
		$val = ($val / 1125899906842624);
		$val = sprintf("%0.2f", $val) . " PiB";
	} elsif ($val >= 1099511627776) {
		$val = ($val / 1099511627776);
		$val = sprintf("%0.2f", $val) . " TiB";
	} elsif ($val >= 1073741824) {
		$val = ($val / 1073741824);
		$val = sprintf("%0.2f", $val) . " GiB";
	} elsif ($val >= 1048576) {
		$val = ($val / 1048576);
		$val = sprintf("%0.2f", $val) . " MiB";
	} elsif ($val >= 1024) {
		$val = ($val / 1024);
		$val = sprintf("%0.2f", $val) . " KiB";
	} else {
		$val = $val . " B";
	}

	return $val;
}


# Format duration
sub convert_time
{
	my $time = shift;

	return '0s' if (!$time);

	my $days = int($time / 86400000);
	$time -= ($days * 86400000);
	my $hours = int($time / 3600000);
	$time -= ($hours * 3600000);
	my $minutes = int($time / 60000);
	$time -= ($minutes * 60000);
	my $seconds = int($time / 1000);
	$time -= ($seconds * 1000);
	my $milliseconds = sprintf("%.3d", $time);

	$days    = $days < 1    ? '' : $days . 'd';
	$hours   = $hours < 1   ? '' : $hours . 'h';
	$minutes = $minutes < 1 ? '' : $minutes . 'm';
	$seconds = $seconds < 1 ? '' : $seconds . 's';
	$milliseconds = $milliseconds < 1 ? '' : $milliseconds . 'ms';

	if ($days || $hours || $minutes) {
		$milliseconds = '';
	} elsif ($seconds) {
		$milliseconds =~ s/\.\d+//;
	}
	$milliseconds =~ s/^[0]+// if ($milliseconds !~ /\./);
	

	$time = $days . $hours . $minutes . $seconds . $milliseconds;
	$time = '0s' if ($time eq '');

	return $time;
}

# Stores the top N queries generating the biggest temporary file
sub set_top_tempfile_info
{
	my ($q, $sz, $date, $db, $user, $remote, $app) = @_;

	push(@top_tempfile_info, [($sz, $date, $q, $db, $user, $remote, $app)]);

	my @tmp_top_tempfile_info = sort {$b->[0] <=> $a->[0]} @top_tempfile_info;
	@top_tempfile_info = ();
	for (my $i = 0; $i <= $#tmp_top_tempfile_info; $i++) {
		push(@top_tempfile_info, $tmp_top_tempfile_info[$i]);
		last if ($i == $end_top);
	}
}

# Stores the top N queries cancelled
sub set_top_cancelled_info
{
	my ($q, $sz, $date, $db, $user, $remote, $app) = @_;

	push(@top_cancelled_info, [($sz, $date, $q, $db, $user, $remote, $app)]);

	my @tmp_top_cancelled_info = sort {$b->[0] <=> $a->[0]} @top_cancelled_info;
	@top_cancelled_info = ();
	for (my $i = 0; $i <= $#tmp_top_cancelled_info; $i++) {
		push(@top_cancelled_info, $tmp_top_cancelled_info[$i]);
		last if ($i == $end_top);
	}
}

# Stores the top N queries waiting the most
sub set_top_locked_info
{
	my ($q, $dt, $date, $db, $user, $remote, $app) = @_;

	push(@top_locked_info, [($dt, $date, $q, $db, $user, $remote, $app)]);

	my @tmp_top_locked_info = sort {$b->[0] <=> $a->[0]} @top_locked_info;
	@top_locked_info = ();
	for (my $i = 0; $i <= $#tmp_top_locked_info; $i++) {
		push(@top_locked_info, $tmp_top_locked_info[$i]);
		last if ($i == $end_top);
	}
}

# Stores the top N slowest queries
sub set_top_slowest
{
	my ($q, $dt, $date, $db, $user, $remote, $app, $bind, $plan) = @_;

	push(@top_slowest, [($dt, $date, $q, $db, $user, $remote, $app, $bind, $plan)]);

	my @tmp_top_slowest = sort {$b->[0] <=> $a->[0]} @top_slowest;
	@top_slowest = ();
	for (my $i = 0; $i <= $#tmp_top_slowest; $i++) {
		push(@top_slowest, $tmp_top_slowest[$i]);
		last if ($i == $end_top);
	}

}

# Stores top N slowest sample queries
sub set_top_sample
{
	my ($norm, $q, $dt, $date, $db, $user, $remote, $app, $bind, $plan) = @_;

	$normalyzed_info{$norm}{samples}{$dt}{query} = $q;
	$normalyzed_info{$norm}{samples}{$dt}{date}  = $date;
	$normalyzed_info{$norm}{samples}{$dt}{db}  = $db;
	$normalyzed_info{$norm}{samples}{$dt}{user}  = $user;
	$normalyzed_info{$norm}{samples}{$dt}{remote}  = $remote;
	$normalyzed_info{$norm}{samples}{$dt}{app}  = $app;
	$normalyzed_info{$norm}{samples}{$dt}{bind}  = $bind;
	$normalyzed_info{$norm}{samples}{$dt}{plan}  = $plan;

	if ($sample > 0) {
		my $i = 1;
		foreach my $k (sort {$b <=> $a} keys %{$normalyzed_info{$norm}{samples}}) {
			if ($i > $sample) {
				delete $normalyzed_info{$norm}{samples}{$k};
			}
			$i++;
		}
	}
}

# Stores top N error sample queries
sub set_top_error_sample
{
	my ($q, $date, $real_error, $detail, $context, $statement, $hint, $db, $user, $app, $remote) = @_;

	# Stop when we have our number of samples
	if (!exists $error_info{$q}{date} || ($#{$error_info{$q}{date}} < $sample)) {
		if ( ($q =~ /deadlock detected/) || ($real_error && !grep(/^\Q$real_error\E$/, @{$error_info{$q}{error}})) ) {
			if ($anonymize) {
				$context = &anonymize_query($context);
				$statement = &anonymize_query($statement);
				$detail = &anonymize_query($detail);
			}

			push(@{$error_info{$q}{date}},      $date);
			push(@{$error_info{$q}{detail}},    $detail);
			push(@{$error_info{$q}{context}},   $context);
			push(@{$error_info{$q}{statement}}, $statement);
			push(@{$error_info{$q}{hint}},      $hint);
			push(@{$error_info{$q}{error}},     $real_error);
			push(@{$error_info{$q}{db}},        $db);
			push(@{$error_info{$q}{user}},      $user);
			push(@{$error_info{$q}{app}},       $app);
			push(@{$error_info{$q}{remote}},    $remote);
		}
	}
}

sub dump_as_text
{

	# Global information
	my $curdate    = localtime(time);
	my $fmt_nlines = &comma_numbers($nlines);
	my $total_time = timestr($td);
	$total_time =~ s/^([\.0-9]+) wallclock.*/$1/;
	$total_time = &convert_time($total_time * 1000);
	my $logfile_str = $log_files[0];
	if ($#log_files > 0) {
		$logfile_str .= ', ..., ' . $log_files[-1];
	}
	print $fh qq{
pgBadger :: $report_title

- Global information ---------------------------------------------------

Generated on $curdate
Log file: $logfile_str
Parsed $fmt_nlines log entries in $total_time
Log start from $overall_stat{'first_log_ts'} to $overall_stat{'last_log_ts'}
};

	# Overall statistics
	my $fmt_unique  = &comma_numbers(scalar keys %normalyzed_info);
	my $fmt_queries = &comma_numbers($overall_stat{'queries_number'});
	my $fmt_duration = &convert_time($overall_stat{'queries_duration'});
	$overall_stat{'first_query_ts'} ||= '-';
	$overall_stat{'last_query_ts'} ||= '-';
	print $fh qq{

- Overall statistics ---------------------------------------------------

Number of unique normalized queries: $fmt_unique
Number of queries: $fmt_queries
Total query duration: $fmt_duration
First query: $overall_stat{'first_query_ts'}
Last query: $overall_stat{'last_query_ts'}
};
	foreach (sort {$overall_stat{'peak'}{$b}{query} <=> $overall_stat{'peak'}{$a}{query}} keys %{$overall_stat{'peak'}}) {
		print $fh "Query peak: ", &comma_numbers($overall_stat{'peak'}{$_}{query}), " queries/s at $_";
		last;
	}
	if (!$disable_error) {
		my $fmt_errors = &comma_numbers($overall_stat{'errors_number'});
		my $fmt_unique_error = &comma_numbers(scalar keys %error_info);
		print $fh qq{
Number of events: $fmt_errors
Number of unique normalized events: $fmt_unique_error
};
	}
	if ($tempfile_info{count}) {
		my $fmt_temp_maxsise = &comma_numbers($tempfile_info{maxsize});
		my $fmt_temp_avsize = &comma_numbers(sprintf("%.2f", ($tempfile_info{size} / $tempfile_info{count})));
		print $fh qq{Number temporary files: $tempfile_info{count}
Max size of temporary files: $fmt_temp_maxsise
Average size of temporary files: $fmt_temp_avsize
};
	}
	if ($cancelled_info{count}) {
		print $fh qq{Number cancelled queries: $cancelled_info{count}
};
	}
	if (!$disable_session && $session_info{count}) {
		my $avg_session_duration = &convert_time($session_info{duration} / $session_info{count});
		my $tot_session_duration = &convert_time($session_info{duration});
		my $avg_queries = &comma_numbers(int($overall_stat{'queries_number'}/$session_info{count}));
		my $avg_duration = &convert_time(int($overall_stat{'queries_duration'}/$session_info{count}));
		print $fh qq{Total number of sessions: $session_info{count}
Total duration of sessions: $tot_session_duration
Average duration of sessions: $avg_session_duration
Average queries per sessions: $avg_queries
Average queries duration per sessions: $avg_duration
};
		foreach (sort {$overall_stat{'peak'}{$b}{session} <=> $overall_stat{'peak'}{$a}{session}} keys %{$overall_stat{'peak'}}) {
			print $fh "Session peak: ", &comma_numbers($overall_stat{'peak'}{$_}{session}), " sessions at $_";
			last;
		}
	}
	if (!$disable_connection && $connection_info{count}) {
		print $fh "Total number of connections: $connection_info{count}\n";
		foreach (sort {$overall_stat{'peak'}{$b}{connection} <=> $overall_stat{'peak'}{$a}{connection}} keys %{$overall_stat{'peak'}}) {
			if ($overall_stat{'peak'}{$_}{connection} > 0) {
				print $fh "Connection peak: ", &comma_numbers($overall_stat{'peak'}{$_}{connection}), " conn/s at $_";
			}
			last;
		}
	}
	if (scalar keys %database_info > 1) {
		print $fh "Total number of databases: ", scalar keys %database_info, "\n";
	}
	if (!$disable_hourly && $overall_stat{'queries_number'}) {
		print $fh qq{

- Hourly statistics ----------------------------------------------------

Report not supported by text format

};
	}

	# INSERT/DELETE/UPDATE/SELECT repartition
	my $totala = 0;
	foreach my $a (@SQL_ACTION) {
		$totala += $overall_stat{$a};
	}
	if (!$disable_type && $totala) {

		my $total = $overall_stat{'queries_number'} || 1;
		print $fh "\n- Queries by type ------------------------------------------------------\n\n";
		print $fh "Type     Count     Percentage\n";
		foreach my $a (@SQL_ACTION) {
			print $fh "$a: ", &comma_numbers($overall_stat{$a}), " ", sprintf("%0.2f", ($overall_stat{$a} * 100) / $total), "%\n";
		}
		print $fh "OTHERS: ", &comma_numbers($total - $totala), " ", sprintf("%0.2f", (($total - $totala) * 100) / $total), "%\n"
			if (($total - $totala) > 0);
		print $fh "\n";

		# Show request per database statistics
		if (scalar keys %database_info > 1) {
			print $fh "\n- Request per database ------------------------------------------------------\n\n";
			print $fh "Database     Request type     Count    Duration\n";
			foreach my $d (sort keys %database_info) {
				print $fh "$d - ", &comma_numbers($database_info{$d}{count}), " ", &convert_time($database_info{$d}{duration}), "\n";
				foreach my $r (sort keys %{$database_info{$d}}) {
					next if (($r eq 'count') || ($r =~ /duration/));
					print $fh "\t$r ", &comma_numbers($database_info{$d}{$r}), " ", &convert_time($database_info{$d}{"$r|duration"}), "\n";
				}
			}
		}

		# Show request per application statistics
		if (scalar keys %application_info > 1) {
			print $fh "\n- Request per application ------------------------------------------------------\n\n";
			print $fh "Application     Request type    Count    Duration\n";
			foreach my $d (sort keys %application_info) {
				print $fh "$d - ", &comma_numbers($application_info{$d}{count}), " ", &convert_time($application_info{$d}{duration}), "\n";
				foreach my $r (sort keys %{$application_info{$d}}) {
					next if (($r eq 'count') || ($r =~ /duration/));
					print $fh "\t$r ", &comma_numbers($application_info{$d}{$r}), " ", &convert_time($application_info{$d}{"$r|duration"}), "\n";
				}
			}
		}

		# Show request per user statistics
		if (scalar keys %user_info > 1) {
			print $fh "\n- Request per user ------------------------------------------------------\n\n";
			print $fh "User     Request type     Count    duration\n";
			foreach my $d (sort keys %user_info) {
				print $fh "$d - ", &comma_numbers($user_info{$d}{count}), " ", &convert_time($user_info{$d}{duration}), "\n";
				foreach my $r (sort keys %{$user_info{$d}}) {
					next if (($r eq 'count') || ($r =~ /duration/));
					print $fh "\t$r ", &comma_numbers($user_info{$d}{$r}), " ", &convert_time($user_info{$d}{"$r|duration"}), "\n";
				}
			}
		}

		# Show request per host statistics
		if (scalar keys %host_info > 1) {
			print $fh "\n- Request per host ------------------------------------------------------\n\n";
			print $fh "Host     Request type     Count   Duration\n";
			foreach my $d (sort keys %host_info) {
				print $fh "$d - ", &comma_numbers($host_info{$d}{count}), " ", &convert_time($host_info{$d}{duration}), "\n";
				foreach my $r (sort keys %{$host_info{$d}}) {
					next if (($r eq 'count') || ($r =~ /duration/));
					print $fh "\t$r ", &comma_numbers($host_info{$d}{$r}), " ", &convert_time($host_info{$d}{"$r|duration"}), "\n";
				}
			}
		}



	}

	if (!$disable_lock && scalar keys %lock_info > 0) {
		print $fh "\n- Locks by type ------------------------------------------------------\n\n";
		print $fh "Type     Object     Count     Total Duration     Avg duration (s)\n";
		my $total_count    = 0;
		my $total_duration = 0;
		foreach my $t (sort keys %lock_info) {
			print $fh "$t\t\t", &comma_numbers($lock_info{$t}{count}), " ", &convert_time($lock_info{$t}{duration}), " ",
				&convert_time($lock_info{$t}{duration} / $lock_info{$t}{count}), "\n";
			foreach my $o (sort keys %{$lock_info{$t}}) {
				next if (($o eq 'count') || ($o eq 'duration') || ($o eq 'chronos'));
				print $fh "\t$o\t", &comma_numbers($lock_info{$t}{$o}{count}), " ", &convert_time($lock_info{$t}{$o}{duration}), " ",
					&convert_time($lock_info{$t}{$o}{duration} / $lock_info{$t}{$o}{count}), "\n";
			}
			$total_count    += $lock_info{$t}{count};
			$total_duration += $lock_info{$t}{duration};
		}
		print $fh "Total:\t\t\t", &comma_numbers($total_count), " ", &convert_time($total_duration), " ",
			&convert_time($total_duration / ($total_count || 1)), "\n";

	}

	# Show session per database statistics
	if (!$disable_session && exists $session_info{database}) {
		print $fh "\n- Sessions per database ------------------------------------------------------\n\n";
		print $fh "Database     Count     Total Duration     Avg duration (s)\n";
		foreach my $d (sort keys %{$session_info{database}}) {
			print $fh "$d - ", &comma_numbers($session_info{database}{$d}{count}), " ",
				&convert_time($session_info{database}{$d}{duration}), " ",
				&convert_time($session_info{database}{$d}{duration} / $session_info{database}{$d}{count}), "\n";
		}
	}

	# Show session per user statistics
	if (!$disable_session && exists $session_info{user}) {
		print $fh "\n- Sessions per user ------------------------------------------------------\n\n";
		print $fh "User     Count     Total Duration     Avg duration (s)\n";
		foreach my $d (sort keys %{$session_info{user}}) {
			print $fh "$d - ", &comma_numbers($session_info{user}{$d}{count}), " ", &convert_time($session_info{user}{$d}{duration}),
				" ", &convert_time($session_info{user}{$d}{duration} / $session_info{user}{$d}{count}), "\n";
		}
	}

	# Show session per host statistics
	if (!$disable_session && exists $session_info{host}) {
		print $fh "\n- Sessions per host ------------------------------------------------------\n\n";
		print $fh "User     Count     Total Duration     Avg duration (s)\n";
		foreach my $d (sort keys %{$session_info{host}}) {
			print $fh "$d - ", &comma_numbers($session_info{host}{$d}{count}), " ", &convert_time($session_info{host}{$d}{duration}),
				" ", &convert_time($session_info{host}{$d}{duration} / $session_info{host}{$d}{count}), "\n";
		}
	}

	# Show session per application statistics
	if (!$disable_session && exists $session_info{app}) {
		print $fh "\n- Sessions per application ------------------------------------------------------\n\n";
		print $fh "Application  Count     Total Duration     Avg duration (s)\n";
		foreach my $d (sort keys %{$session_info{app}}) {
			print $fh "$d - ", &comma_numbers($session_info{app}{$d}{count}), " ", &convert_time($session_info{app}{$d}{duration}),
				" ", &convert_time($session_info{app}{$d}{duration} / $session_info{app}{$d}{count}), "\n";
		}
	}


	# Show connection per database statistics
	if (!$disable_connection && exists $connection_info{database}) {
		print $fh "\n- Connections per database ------------------------------------------------------\n\n";
		print $fh "Database     User     Count\n";
		foreach my $d (sort keys %{$connection_info{database}}) {
			print $fh "$d - ", &comma_numbers($connection_info{database}{$d}), "\n";
			foreach my $u (sort keys %{$connection_info{user}}) {
				next if (!exists $connection_info{database_user}{$d}{$u});
				print $fh "\t$u ", &comma_numbers($connection_info{database_user}{$d}{$u}), "\n";
			}
		}
	}

	# Show connection per user statistics
	if (!$disable_connection && exists $connection_info{user}) {
		print $fh "\n- Connections per user ------------------------------------------------------\n\n";
		print $fh "User     Count\n";
		foreach my $d (sort keys %{$connection_info{user}}) {
			print $fh "$d - ", &comma_numbers($connection_info{user}{$d}), "\n";
		}
	}

	# Show connection per host statistics
	if (!$disable_connection && exists $connection_info{host}) {
		print $fh "\n- Connections per host ------------------------------------------------------\n\n";
		print $fh "User     Count\n";
		foreach my $d (sort keys %{$connection_info{host}}) {
			print $fh "$d - ", &comma_numbers($connection_info{host}{$d}), "\n";
		}
	}

	# Show lock wait detailed information
	if (!$disable_lock && scalar keys %lock_info > 0) {

		my @top_locked_queries;
		foreach my $h (keys %normalyzed_info) {
			if (exists($normalyzed_info{$h}{locks})) {
				push (@top_locked_queries, [$h, $normalyzed_info{$h}{locks}{count}, $normalyzed_info{$h}{locks}{wait},
				$normalyzed_info{$h}{locks}{minwait}, $normalyzed_info{$h}{locks}{maxwait}]);
			}
		}

		# Most frequent waiting queries (N)
		@top_locked_queries = sort {$b->[2] <=> $a->[2]} @top_locked_queries;
		print $fh "\n- Most frequent waiting queries (N) -----------------------------------------\n\n";
		print $fh "Rank  Count    Total wait time (s)    Min/Max/Avg duration (s)    Query\n";
		for (my $i = 0 ; $i <= $#top_locked_queries ; $i++) {
			last if ($i > $end_top);
			print $fh ($i + 1), ")   ", $top_locked_queries[$i]->[1], " - ", &convert_time($top_locked_queries[$i]->[2]),
			" - ", &convert_time($top_locked_queries[$i]->[3]), "/", &convert_time($top_locked_queries[$i]->[4]), "/",
			&convert_time(($top_locked_queries[$i]->[2] / $top_locked_queries[$i]->[1])),
			" - ", $top_locked_queries[$i]->[0], "\n";
			print $fh "--\n";
			my $k = $top_locked_queries[$i]->[0];
			my $j = 1;
			foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
			my $ttl = $top_locked_info[$i]->[1] || '';
				my $db = " - $normalyzed_info{$k}{samples}{$d}{date} - database: $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
				$db .= ", user: $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
				$db .= ", remote: $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
				$db .= ", app: $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
				$db .= ", bind query: yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
				$db =~ s/^, / - /;
				print $fh "\t- Example $j: ", &convert_time($d), "$db - ", $normalyzed_info{$k}{samples}{$d}{query}, "\n";
				$j++;
			}
		}
		print $fh "\n";
		@top_locked_queries = ();

		# Queries that waited the most
		@top_locked_info = sort {$b->[1] <=> $a->[1]} @top_locked_info;
		print $fh "\n- Queries that waited the mosts ---------------------------------------------\n\n";
		print $fh "Rank   Wait time (s)    Query\n";
		for (my $i = 0 ; $i <= $#top_locked_info ; $i++) {
			my $ttl = $top_locked_info[$i]->[1] || '';
			my $db = " - database: $top_locked_info[$i]->[3]" if ($top_locked_info[$i]->[3]);
			$db .= ", user: $top_locked_info[$i]->[4]" if ($top_locked_info[$i]->[4]);
			$db .= ", remote: $top_locked_info[$i]->[5]" if ($top_locked_info[$i]->[5]);
			$db .= ", app: $top_locked_info[$i]->[6]" if ($top_locked_info[$i]->[6]);
			$db =~ s/^, / - /;
			print $fh ($i + 1), ")   ", &convert_time($top_locked_info[$i]->[0]),
			"  $ttl$db - ", $top_locked_info[$i]->[2], "\n";
			print $fh "--\n";
		}
		print $fh "\n";
	}

	# Show temporary files detailed information
	if (!$disable_temporary && scalar keys %tempfile_info > 0) {

		my @top_temporary;
		foreach my $h (keys %normalyzed_info) {
			if (exists($normalyzed_info{$h}{tempfiles})) {
				push (@top_temporary, [$h, $normalyzed_info{$h}{tempfiles}{count}, $normalyzed_info{$h}{tempfiles}{size},
				$normalyzed_info{$h}{tempfiles}{minsize}, $normalyzed_info{$h}{tempfiles}{maxsize}]);
			}
		}

		# Queries generating the most temporary files (N)
		@top_temporary = sort {$b->[1] <=> $a->[1]} @top_temporary;
		print $fh "\n- Queries generating the most temporary files (N) ---------------------------\n\n";
		print $fh "Rank   Count   Total size    Min/Max/Avg size    Query\n";
		my $idx = 1;
		for (my $i = 0 ; $i <= $#top_temporary ; $i++) {
			last if ($i > $end_top);
			print $fh $idx, ")   ",
			$top_temporary[$i]->[1], " - ", &comma_numbers($top_temporary[$i]->[2]),
			" - ", &comma_numbers($top_temporary[$i]->[3]),
			"/", &comma_numbers($top_temporary[$i]->[4]), "/",
			&comma_numbers(sprintf("%.2f", $top_temporary[$i]->[2] / $top_temporary[$i]->[1])),
			" - ", $top_temporary[$i]->[0], "\n";
			print $fh "--\n";
			my $k = $top_temporary[$i]->[0];
			if ($normalyzed_info{$k}{count} > 1) {
				my $j = 1;
				foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
					my $db = "$normalyzed_info{$k}{samples}{$d}{date} - database: $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
					$db .= ", user: $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
					$db .= ", remote: $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
					$db .= ", app: $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
					$db .= ", bind query: yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
					$db =~ s/^, / - /;
					print $fh "\t- Example $j: ", &convert_time($d), " - $db - ", $normalyzed_info{$k}{samples}{$d}{query}, "\n";
					$j++;
				}
			}                             
			$idx++;
		}
		@top_temporary = ();

		# Top queries generating the largest temporary files
		@top_tempfile_info = sort {$b->[1] <=> $a->[1]} @top_tempfile_info;

		print $fh "\n- Queries generating the largest temporary files ----------------------------\n\n";
		print $fh "Rank   Size    Query\n";
		for (my $i = 0 ; $i <= $#top_tempfile_info ; $i++) {
			my $ttl = $top_tempfile_info[$i]->[1] || '';
			my $db = " - database: $top_tempfile_info[$i]->[3]" if ($top_tempfile_info[$i]->[3]);
			$db .= ", user: $top_tempfile_info[$i]->[4]" if ($top_tempfile_info[$i]->[4]);
			$db .= ", remote: $top_tempfile_info[$i]->[5]" if ($top_tempfile_info[$i]->[5]);
			$db .= ", app: $top_tempfile_info[$i]->[6]" if ($top_tempfile_info[$i]->[6]);
			$db =~ s/^, / - /;
			print $fh ($i + 1), ")   ", &comma_numbers($top_tempfile_info[$i]->[0]),
			" - $ttl$db - ", $top_tempfile_info[$i]->[2], "\n";
		}
		print $fh "\n";
	}

	# Show cancelled queries detailed information
	if (!$disable_query && scalar keys %cancelled_info > 0) {

		my @top_cancelled;
		foreach my $h (keys %normalyzed_info) {
			if (exists($normalyzed_info{$h}{cancelled})) {
				push (@top_cancelled, [$h, $normalyzed_info{$h}{cancelled}{count}]);
			}
		}

		# Queries generating the most cancelled files (N)
		@top_cancelled = sort {$b->[1] <=> $a->[1]} @top_cancelled;
		print $fh "\n- Queries most cancelled (N) ---------------------------\n\n";
		print $fh "Rank   Count   Query\n";
		my $idx = 1;
		for (my $i = 0 ; $i <= $#top_cancelled ; $i++) {
			last if ($i > $end_top);
			print $fh $idx, ")   ",
			$top_cancelled[$i]->[1], " - ", $top_cancelled[$i]->[0], "\n";
			print $fh "--\n";
			my $k = $top_cancelled[$i]->[0];
			if ($normalyzed_info{$k}{count} > 1) {
				my $j = 1;
				foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
					my $db = "$normalyzed_info{$k}{samples}{$d}{date} - database: $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
					$db .= ", user: $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
					$db .= ", remote: $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
					$db .= ", app: $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
					$db .= ", bind query: yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
					$db =~ s/^, / - /;
					print $fh "\t- Example $j: ", &convert_time($d), " - $db - ", $normalyzed_info{$k}{samples}{$d}{query}, "\n";
					$j++;
				}
			}                             
			$idx++;
		}
		@top_cancelled = ();

		# Top queries generating the largest cancelled files
		@top_cancelled_info = sort {$b->[1] <=> $a->[1]} @top_cancelled_info;

		print $fh "\n- Queries generating the most cancellation ----------------------------\n\n";
		print $fh "Rank   Times cancelled    Query\n";
		for (my $i = 0 ; $i <= $#top_cancelled_info ; $i++) {
			my $ttl = $top_cancelled_info[$i]->[1] || '';
			my $db = " - database: $top_cancelled_info[$i]->[3]" if ($top_cancelled_info[$i]->[3]);
			$db .= ", user: $top_cancelled_info[$i]->[4]" if ($top_cancelled_info[$i]->[4]);
			$db .= ", remote: $top_cancelled_info[$i]->[5]" if ($top_cancelled_info[$i]->[5]);
			$db .= ", app: $top_cancelled_info[$i]->[6]" if ($top_cancelled_info[$i]->[6]);
			$db =~ s/^, / - /;
			print $fh ($i + 1), ")   ", &comma_numbers($top_cancelled_info[$i]->[0]),
			" - $ttl$db - ", $top_cancelled_info[$i]->[2], "\n";
		}
		print $fh "\n";
	}

	# Show top information
	if (!$disable_query && ($#top_slowest >= 0)) {
		print $fh "\n- Slowest queries ------------------------------------------------------\n\n";
		print $fh "Rank     Duration (s)     Query\n";
		for (my $i = 0 ; $i <= $#top_slowest ; $i++) {
			my $db = " database: $top_slowest[$i]->[3]" if ($top_slowest[$i]->[3]);
			$db .= ", user: $top_slowest[$i]->[4]" if ($top_slowest[$i]->[4]);
			$db .= ", remote: $top_slowest[$i]->[5]" if ($top_slowest[$i]->[5]);
			$db .= ", app: $top_slowest[$i]->[6]" if ($top_slowest[$i]->[6]);
			$db .= ", bind query: yes" if ($top_slowest[$i]->[7]);
			$db =~ s/^, //;
			print $fh $i + 1, ") " . &convert_time($top_slowest[$i]->[0]) . "$db - $top_slowest[$i]->[2]\n";
			print $fh "--\n";
		}

		print $fh "\n- Queries that took up the most time (N) -------------------------------\n\n";
		print $fh "Rank     Total duration      Times executed     Min/Max/Avg duration (s)     Query\n";
		my $idx = 1;
		foreach my $k (sort {$normalyzed_info{$b}{duration} <=> $normalyzed_info{$a}{duration}} keys %normalyzed_info) {
			next if (!$normalyzed_info{$k}{count});
			last if ($idx > $top);
			my $q = $k;
			if ($normalyzed_info{$k}{count} == 1) {
				foreach (keys %{$normalyzed_info{$k}{samples}}) {
					$q = $normalyzed_info{$k}{samples}{$_}{query};
					last;
				}
			}
			$normalyzed_info{$k}{average} = $normalyzed_info{$k}{duration} / $normalyzed_info{$k}{count};
			print $fh "$idx) "
				. &convert_time($normalyzed_info{$k}{duration}) . " - "
				. &comma_numbers($normalyzed_info{$k}{count}) . " - "
				. &convert_time($normalyzed_info{$k}{min}) . "/"
				. &convert_time($normalyzed_info{$k}{max}) . "/"
				. &convert_time($normalyzed_info{$k}{average})
				. " - $q\n";
			print $fh "--\n";
			my $i = 1;
			foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
				my $db = " - database: $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
				$db .= ", user: $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
				$db .= ", remote: $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
				$db .= ", app: $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
				$db .= ", bind query: yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
				$db =~ s/^, / - /;
				print $fh "\t- Example $i: ", &convert_time($d), "$db - ", $normalyzed_info{$k}{samples}{$d}{query}, "\n";
				$i++;
			}
			$idx++;
		}
	}
	if (!$disable_query && (scalar keys %normalyzed_info > 0)) {
		print $fh "\n- Most frequent queries (N) --------------------------------------------\n\n";
		print $fh "Rank     Times executed     Total duration     Min/Max/Avg duration (s)     Query\n";
		my $idx = 1;
		foreach my $k (sort {$normalyzed_info{$b}{count} <=> $normalyzed_info{$a}{count}} keys %normalyzed_info) {
			next if (!$normalyzed_info{$k}{count});
			last if ($idx > $top);
			my $q = $k;
			if ($normalyzed_info{$k}{count} == 1) {
				foreach (keys %{$normalyzed_info{$k}{samples}}) {
					$q = $normalyzed_info{$k}{samples}{$_}{query};
					last;
				}
			}
			print $fh "$idx) "
				. &comma_numbers($normalyzed_info{$k}{count}) . " - "
				. &convert_time($normalyzed_info{$k}{duration}) . " - "
				. &convert_time($normalyzed_info{$k}{min}) . "/"
				. &convert_time($normalyzed_info{$k}{max}) . "/"
				. &convert_time($normalyzed_info{$k}{duration} / $normalyzed_info{$k}{count})
				. " - $q\n";
			print $fh "--\n";
			my $i = 1;
			foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
				my $db = " - database: $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
				$db .= ", user: $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
				$db .= ", remote: $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
				$db .= ", app: $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
				$db .= ", bind query: yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
				$db =~ s/^, / - /;
				print $fh "\tExample $i: ", &convert_time($d), "$db - ", $normalyzed_info{$k}{samples}{$d}{query}, "\n";
				$i++;
			}
			$idx++;
		}
	}

	if (!$disable_query && ($#top_slowest >= 0)) {
		print $fh "\n- Slowest queries (N) --------------------------------------------------\n\n";
		print $fh "Rank     Min/Max/Avg duration (s)     Times executed     Total duration     Query\n";
		my $idx = 1;
		foreach my $k (sort {$normalyzed_info{$b}{average} <=> $normalyzed_info{$a}{average}} keys %normalyzed_info) {
			next if (!$normalyzed_info{$k}{count});
			last if ($idx > $top);
			my $q = $k;
			if ($normalyzed_info{$k}{count} == 1) {
				foreach (keys %{$normalyzed_info{$k}{samples}}) {
					$q = $normalyzed_info{$k}{samples}{$_}{query};
					last;
				}
			}
			print $fh "$idx) "
				. &convert_time($normalyzed_info{$k}{min}) . "/"
				. &convert_time($normalyzed_info{$k}{max}) . "/"
				. &convert_time($normalyzed_info{$k}{average}) . " - "
				. &comma_numbers($normalyzed_info{$k}{count}) . " - "
				. &convert_time($normalyzed_info{$k}{duration})
				. " - $q\n";
			print $fh "--\n";
			my $i = 1;
			foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
				my $db = " - database: $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
				$db .= ", user: $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
				$db .= ", remote: $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
				$db .= ", app: $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
				$db .= ", bind query: yes" if ($normalyzed_info{$k}{samples}{$d}{yes});
				$db =~ s/^, / - /;
				print $fh "\tExample $i: ", &convert_time($d), "$db - ", $normalyzed_info{$k}{samples}{$d}{query}, "\n";
				$i++;
			}
			$idx++;
		}
	}
	@top_slowest = ();

	if (!$disable_error) {
		&show_error_as_text();
	}

	print $fh "\n\n";
	print $fh "Report generated by pgBadger $VERSION ($project_url).\n";

}

sub dump_error_as_text
{

	# Global information
	my $curdate    = localtime(time);
	my $fmt_nlines = &comma_numbers($nlines);
	my $total_time = timestr($td);
	$total_time =~ s/^([\.0-9]+) wallclock.*/$1/;
	$total_time = &convert_time($total_time * 1000);
	my $logfile_str = $log_files[0];
	if ($#log_files > 0) {
		$logfile_str .= ', ..., ' . $log_files[-1];
	}
	$report_title ||= 'PostgreSQL Log Analyzer';

	print $fh qq{
pgBadger :: $report_title

- Global information ---------------------------------------------------

Generated on $curdate
Log file: $logfile_str
Parsed $fmt_nlines log entries in $total_time
Log start from $overall_stat{'first_log_ts'} to $overall_stat{'last_log_ts'}
};

	&show_error_as_text();

	print $fh "\n\n";
	print $fh "Report generated by pgBadger $VERSION ($project_url).\n";
}

sub show_error_as_text
{
	return if (scalar keys %error_info == 0);

	print $fh "\n- Most frequent events (N) ---------------------------------------------\n\n";
	my $idx = 1;
	foreach my $k (sort {$error_info{$b}{count} <=> $error_info{$a}{count}} keys %error_info) {
		next if (!$error_info{$k}{count});
		last if ($idx > $top);
		if ($error_info{$k}{count} > 1) {
			my $msg = $k;
			$msg =~ s/ERROR:  (parameter "[^"]+" changed to)/LOG:  $1/;
			$msg =~ s/ERROR:  (database system was shut down)/LOG:  $1/;
			$msg =~ s/ERROR:  (recovery has paused)/LOG:  $1/;
			$msg =~ s/ERROR:  (database system was interrupted while in recovery)/LOG:  $1/;
			print $fh "$idx) " . &comma_numbers($error_info{$k}{count}) . " - $msg\n";
			print $fh "--\n";
			my $j = 1;
			for (my $i = 0 ; $i <= $#{$error_info{$k}{date}} ; $i++) {
				if (   ($error_info{$k}{error}[$i] =~ s/ERROR:  (parameter "[^"]+" changed to)/LOG:  $1/)
					|| ($error_info{$k}{error}[$i] =~ s/ERROR:  (database system was shut down)/LOG:  $1/)
					|| ($error_info{$k}{error}[$i] =~ s/ERROR:  (database system was interrupted while in recovery)/LOG:  $1/)
					|| ($error_info{$k}{error}[$i] =~ s/ERROR:  (recovery has paused)/LOG:  $1/))
				{
					$logs_type{ERROR}--;
					$logs_type{LOG}++;
				}
				print $fh "\t- Example $j: $error_info{$k}{date}[$i] - $error_info{$k}{error}[$i]\n";
				print $fh "\t\tDetail: $error_info{$k}{detail}[$i]\n"       if ($error_info{$k}{detail}[$i]);
				print $fh "\t\tContext: $error_info{$k}{context}[$i]\n"     if ($error_info{$k}{context}[$i]);
				print $fh "\t\tHint: $error_info{$k}{hint}[$i]\n"           if ($error_info{$k}{hint}[$i]);
				print $fh "\t\tStatement: $error_info{$k}{statement}[$i]\n" if ($error_info{$k}{statement}[$i]);
				print $fh "\t\tDatabase: $error_info{$k}{db}[$i]\n" if ($error_info{$k}{db}[$i]);
				$j++;
			}
		} else {
			if (   ($error_info{$k}{error}[0] =~ s/ERROR:  (parameter "[^"]+" changed to)/LOG:  $1/)
				|| ($error_info{$k}{error}[0] =~ s/ERROR:  (database system was shut down)/LOG:  $1/)
				|| ($error_info{$k}{error}[0] =~ s/ERROR:  (database system was interrupted while in recovery)/LOG:  $1/)
				|| ($error_info{$k}{error}[0] =~ s/ERROR:  (recovery has paused)/LOG:  $1/))
			{
				$logs_type{ERROR}--;
				$logs_type{LOG}++;
			}
			print $fh "$idx) " . &comma_numbers($error_info{$k}{count}) . " - $error_info{$k}{error}[0]\n";
			print $fh "--\n";
			print $fh "\t- Date: $error_info{$k}{date}[0]\n";
			print $fh "\t\tDetail: $error_info{$k}{detail}[0]\n"       if ($error_info{$k}{detail}[0]);
			print $fh "\t\tContext: $error_info{$k}{context}[0]\n"     if ($error_info{$k}{context}[0]);
			print $fh "\t\tHint: $error_info{$k}{hint}[0]\n"           if ($error_info{$k}{hint}[0]);
			print $fh "\t\tStatement: $error_info{$k}{statement}[0]\n" if ($error_info{$k}{statement}[0]);
			print $fh "\t\tDatabase: $error_info{$k}{db}[0]\n" if ($error_info{$k}{db}[0]);
		}
		$idx++;
	}

	if (scalar keys %logs_type > 0) {
		print $fh "\n- Logs per type ---------------------------------------------\n\n";

		my $total_logs = 0;
		foreach my $d (keys %logs_type) {
			$total_logs += $logs_type{$d};
		}
		print $fh "Logs type	Count	Percentage\n";
		foreach my $d (sort keys %logs_type) {
			next if (!$logs_type{$d});
			print $fh "$d\t\t", &comma_numbers($logs_type{$d}), "\t", sprintf("%0.2f", ($logs_type{$d} * 100) / $total_logs), "%\n";
		}
	}
}

sub html_header
{
	my $uri = shift;

	my $date = localtime(time);
	my $global_info = &print_global_information();

	my @tmpjscode = @jscode;
	map { s/EDIT_URI/$uri/; } @tmpjscode;

	my $local_title = 'PostgreSQL Log Analyzer';
	if ($report_title) {
		$local_title = $report_title;
	}
	$report_title ||= 'pgBadger';

	print $fh qq{<!DOCTYPE html>
<html lang="en">
<head>
<title>pgBadger :: $local_title</title>
<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
<meta name="robots" content="noindex,nofollow">
<meta http-equiv="Expires" content="$date">
<meta http-equiv="Generator" content="pgBadger v$VERSION">
<meta http-equiv="Date" content="$date">
<link rel="shortcut icon" href="$pgbadger_ico" />
@tmpjscode
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="navbar-inner">
    <div class="container-fluid">
	<a data-placement="bottom" rel="tooltip" data-original-title="PostgreSQL Log Analyzer" href="" id="pgbadger-brand" class="brand">$pgbadger_logo $report_title</a>
	  <ul class="nav collapse in" id="navigation">
};
	if (!$error_only) {
		print $fh qq{
     		<li id="menu-overview" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Overview <span class="caret"></span></a>
			<ul class="dropdown-menu">
				<li><a href="#global-stats">Global Stats</a></li>
};
		if (!$disable_hourly) {
			print $fh qq{
				<li><a href="#sql-traffic">SQL Traffic</a></li>
				<li><a href="#select-traffic">Select Traffic</a></li>
				<li><a href="#write-traffic">Write Traffic</a></li>
				<li><a href="#duration-traffic">Queries duration</a></li>
				<li><a href="#prepared-queries-ratio">Prepared queries ratio</a></li>
				<li><a href="#general-activity">General Activity</a></li>
};
		}
		print $fh qq{
          		</ul>
        	</li>
};
		if (!$disable_connection) {
			print $fh qq{
     		<li id="menu-connections" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Connections <span class="caret"></span></a>
     			<ul class="dropdown-menu">
};
			if (!$disable_hourly) {
				print $fh qq{
     				<li><a href="#established-connections">Established connections</a></li>
};
			}
			print $fh qq{
     				<li><a href="#connections-per-database">Connections per database</a></li>
     				<li><a href="#connections-per-user">Connections per user</a></li>
     				<li><a href="#connections-per-host">Connections per host</a></li>
     			</ul>
     		</li>
};
		}
		if (!$disable_session) {
			print $fh qq{
     		<li id="menu-sessions" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Sessions <span class="caret"></span></a>
     			<ul class="dropdown-menu">
};
			if (!$disable_hourly) {
				print $fh qq{
     				<li><a href="#simultaneous-sessions">Simultaneous sessions</a></li>
};
			}
			print $fh qq{
     				<li><a href="#histogram-session-times">Histogram of sessions times</a></li>
     				<li><a href="#sessions-per-database">Sessions per database</a></li>
     				<li><a href="#sessions-per-user">Sessions per user</a></li>
     				<li><a href="#sessions-per-host">Sessions per host</a></li>
     				<li><a href="#sessions-per-app">Sessions per application</a></li>
     			</ul>
     		</li>
};
		}
		if (!$disable_checkpoint) {
			print $fh qq{
     		<li id="menu-checkpoints" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Checkpoints <span class="caret"></span></a>
     			<ul class="dropdown-menu">
     				<li><a href="#checkpoints-buffers">Checkpoints buffers</a></li>
     				<li><a href="#checkpoints-files">Checkpoints files</a></li>
     				<li><a href="#checkpoint-activity">Checkpoint activity</a></li> 
     			</ul>
     		</li>
};
		}

		if (!$disable_temporary) {
			print $fh qq{
     		<li id="menu-tempfiles" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Temp Files <span class="caret"></span></a>
     			<ul class="dropdown-menu">
     				<li><a href="#tempfiles-size">Size of temporary files</a></li>
     				<li><a href="#tempfiles-number">Number of temporary files</a></li>
     				<li><a href="#tempfiles-activity">Temporary files activity</a></li>
				<li class="divider"></li>
     				<li><a href="#queries-generating-most-temporary-files">Queries generating the most files (N)</a></li>
     				<li><a href="#queries-generating-largest-temporary-files">Queries generating the largest files</a></li>
     			</ul>
		</li>
};
		}
		if (!$disable_autovacuum) {
			print $fh qq{
     		<li id="menu-vacuums" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Vacuums <span class="caret"></span></a>
     			<ul class="dropdown-menu">
     				<li><a href="#vacuums-count">Vacuums distribution</a></li>
     				<li><a href="#vacuums-activity">Vacuums activity</a></li>
     				<li><a href="#analyzes-per-table">Analyzes per Tables</a></li>
     				<li><a href="#vacuums-per-table">Vacuums per Tables</a></li>
     				<li><a href="#tuples-removed-per-table">Tuples removed</a></li>
     				<li><a href="#pages-removed-per-table">Page removed</a></li>
     			</ul>
		</li>
};
		}
		if (!$disable_lock) {
			print $fh qq{
     		<li id="menu-locks" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Locks <span class="caret"></span></a>
     			<ul class="dropdown-menu">
     				<li><a href="#locks-type">Locks by type</a></li>
				<li class="divider"></li>
     				<li><a href="#queries-most-frequent-waiting">Most frequent waiting queries (N)</a></li>
     				<li><a href="#queries-that-waited-most">Queries that waited the most</a></li>
     			</ul>
		</li>
};
	}
		if (!$disable_query) {
			if (!$disable_type) {
				print $fh qq{
     		<li id="menu-queries" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Queries <span class="caret"></span></a>
     			<ul class="dropdown-menu">
     				<li><a href="#queries-by-type">Queries by type</a></li>
     				<li><a href="#queries-by-database">Queries by database</a></li>
     				<li><a href="#queries-by-user">Queries by user</a></li>
     				<li><a href="#duration-by-user">Duration by user</a></li>
     				<li><a href="#queries-by-host">Queries by host</a></li>
     				<li><a href="#queries-by-application">Queries by application</a></li>
				<li class="divider"></li>
     				<li><a href="#queries-cancelled-number">Number of cancelled queries</a></li>
};
			}
			if ($#top_cancelled_info >= 0) {
				print $fh qq{
     				<li><a href="#queries-generating-most-cancellation">Queries generating the most cancellation (N)</a></li>
     				<li><a href="#queries-generating-most-cancelled">Most cancelled queries</a></li>
};
			}
			print $fh qq{
     			</ul>     
     		</li>
     		<li id="menu-topqueries" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Top <span class="caret"></span></a>
     			<ul class="dropdown-menu">
     				<li><a href="#histogram-query-times">Histogram of query times</a></li>
     				<li><a href="#slowest-individual-queries">Slowest individual queries</a></li>
     				<li><a href="#time-consuming-queries">Time Consuming queries (N)</a></li>
     				<li><a href="#most-frequent-queries">Most frequent queries (N)</a></li>
     				<li><a href="#normalized-slowest-queries">Normalized slowest queries</a></li>
     			</ul>
     		</li>
};
		}
	}
	if (!$disable_error) {
		print $fh qq{
     		<li id="menu-events" class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Events <span class="caret"></span></a>
     			<ul class="dropdown-menu">
     				<li><a href="#log-levels">Log levels</a></li>
     				<li><a href="#minutes-errors-levels">Events distribution</a></li>
				<li class="divider"></li>
     				<li><a href="#most-frequent-errors-events">Most frequent errors/events</a></li>
     			</ul>        
     		</li>
};
	}
	print $fh qq{
     	</ul>
     	<a class="pull-right btn btn-info" id="pop-infos" rel="popover" data-html="true" data-placement="bottom" data-original-title="Log Info" data-content="$global_info">
<i class="icon-info-sign icon-large"></i></a><a id="show-hide-menu" class="btn pull-right" data-toggle="collapse" href="#navigation"><i class="icon-reorder icon-large"></i></a>

    </div>
  </div>
</nav>

<div id="top"><br /><br /></div>
<div class="container" id="main-container">

	<ul id="slides">
};

}

sub html_footer
{
	print $fh qq{
		</li>
	</ul> <!-- end of slides -->
</div> <!-- End of main-container -->

<footer>
<div class="">
	<small class="pull-right">Report generated by <a href="$project_url" target="_new">pgBadger $VERSION.</a></small>
</div>
</footer>

<div id="littleToc">
	<div id="littleTocTitle"><a href="#top">&nbsp;^&nbsp;</a></div>
</div>

</body>
</html>
};

}


# Create global information section
sub print_global_information
{

	my $curdate    = localtime(time);
	my $fmt_nlines = &comma_numbers($nlines);
	my $total_time = timestr($td);
	$total_time =~ s/^([\.0-9]+) wallclock.*/$1/;
	$total_time = &convert_time($total_time * 1000);
	my $logfile_str = $log_files[0];
	if ($#log_files > 0) {
		$logfile_str .= ', ..., ' . $log_files[-1];
	}
	return qq{
<ul>
<li>Generated on $curdate</li>
<li>Log file: $logfile_str</li>
<li>Parsed $fmt_nlines log entries in $total_time</li>
<li>Log start from $overall_stat{'first_log_ts'} to $overall_stat{'last_log_ts'}</li>
</ul>
};

}

sub print_overall_statistics
{

	my $fmt_unique  = &comma_numbers(scalar keys %normalyzed_info);
	my $fmt_queries = &comma_numbers($overall_stat{'queries_number'});
	my $fmt_duration = &convert_time($overall_stat{'queries_duration'});
	$overall_stat{'first_query_ts'} ||= '-';
	$overall_stat{'last_query_ts'} ||= '-';
	my $query_peak = 0;
	my $query_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{query} <=> $overall_stat{'peak'}{$a}{query}} keys %{$overall_stat{'peak'}}) {
		$query_peak = &comma_numbers($overall_stat{'peak'}{$_}{query});
		$query_peak_date = $_;
		last;
	}
	my $avg_queries = &comma_numbers(int($overall_stat{'queries_number'}/($session_info{count} || 1)));
	my $avg_duration = &convert_time(int($overall_stat{'queries_duration'}/($session_info{count} || 1)));
	my $fmt_errors = &comma_numbers($overall_stat{'errors_number'});
	my $fmt_unique_error = &comma_numbers(scalar keys %error_info);
	my $autovacuum_count = &comma_numbers($autovacuum_info{count});
	my $autoanalyze_count = &comma_numbers($autoanalyze_info{count});
	my $tempfile_count = &comma_numbers($tempfile_info{count});
	my $cancelled_count = &comma_numbers($cancelled_info{count});
	my $fmt_temp_maxsise = &comma_numbers($tempfile_info{maxsize});
	my $fmt_temp_avsize = &comma_numbers(sprintf("%.2f", $tempfile_info{size} / ($tempfile_info{count} || 1)));
	my $session_count = &comma_numbers($session_info{count});
	my $avg_session_duration = &convert_time($session_info{duration} / ($session_info{count} || 1));
	my $tot_session_duration = &convert_time($session_info{duration});
	my $connection_count = &comma_numbers($connection_info{count});
	my $connection_peak = 0;
	my $connection_peak_date = '';
	my $session_peak = 0;
	my $session_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{connection} <=> $overall_stat{'peak'}{$a}{connection}} keys %{$overall_stat{'peak'}}) {
		$connection_peak = &comma_numbers($overall_stat{'peak'}{$_}{connection});
		$connection_peak_date = $_;
		last;
	}
	foreach (sort {$overall_stat{'peak'}{$b}{session} <=> $overall_stat{'peak'}{$a}{session}} keys %{$overall_stat{'peak'}}) {
		$session_peak = &comma_numbers($overall_stat{'peak'}{$_}{session});
		$session_peak_date = $_;
		last;
	}
        my $main_error = 0;
        my $total = 0;
        foreach my $k (sort {$error_info{$b}{count} <=> $error_info{$a}{count}} keys %error_info) {
                next if (!$error_info{$k}{count});
                $main_error = &comma_numbers($error_info{$k}{count}) if (!$main_error);
                $total += $error_info{$k}{count};
        }
        $total = &comma_numbers($total);

	my $db_count = scalar keys %database_info;
	print $fh qq{
	    <h1 class="page-header"><i class="icon-eye-open"></i> Overview</h1>

	    <div class="row-fluid analysis-item" id="global-stats">
		<h2 class=""><i class="icon-dashboard"></i> Global Stats</h2>
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#tab-queries" data-toggle="tab"><i class="icon-question-sign"></i> Queries</a></li>
					<li><a href="#tab-events" data-toggle="tab"><i class="icon-bullhorn"></i> Events</a></li>
					<li><a href="#tab-vacuums" data-toggle="tab"><i class="icon-cogs"></i> Vacuums</a></li>
					<li><a href="#tab-tempfiles" data-toggle="tab"><i class="icon-file"></i> Temporary files</a></li>
					<li><a href="#tab-sessions" data-toggle="tab"><i class="icon-off"></i> Sessions</a></li>
					<li><a href="#tab-connections" data-toggle="tab"><i class="icon-external-link-sign"></i> Connections</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="tab-queries">
						<ul>
							<li class="first"><span class="figure">$fmt_unique</span> <span class="figure-label">Number of unique normalized queries</span></li>
							<li><span class="figure">$fmt_queries</span> <span class="figure-label">Number of queries</span></li>
							<li><span class="figure">$fmt_duration</span> <span class="figure-label">Total query duration</span></li>
							<li><span class="figure">$overall_stat{'first_query_ts'}</span> <span class="figure-label">First query</span></li>
							<li><span class="figure">$overall_stat{'last_query_ts'}</span> <span class="figure-label">Last query</span></li>
							<li><span class="figure">$query_peak queries/s at $query_peak_date</span> <span class="figure-label">Query peak</span></li>
						</ul>
					</div>
					<div class="tab-pane" id="tab-events">
						<ul>
							<li class="first"><span class="figure">$fmt_errors</span> <span class="figure-label">Number of events</span></li>
							<li><span class="figure">$fmt_unique_error</span> <span class="figure-label">Number of unique normalized events</span></li>
							<li><span class="figure">$main_error</span> <span class="figure-label">Max number of times the same event was reported</span></li>
							<li><span class="figure">$cancelled_count</span> <span class="figure-label">Number of cancellation</span></li>
						</ul>
					</div>
					<div class="tab-pane" id="tab-vacuums">
						<ul>
							<li class="first"><span class="figure">$autovacuum_count</span> <span class="figure-label">Total number of automatic vacuums</span></li>
							<li><span class="figure">$autoanalyze_count</span> <span class="figure-label">Total number of automatic analyzes</span></li>
						</ul>
					</div>
					<div class="tab-pane" id="tab-tempfiles">
						<ul>
							<li class="first"><span class="figure">$tempfile_count</span> <span class="figure-label">Number temporary file</span></li>
							<li><span class="figure">$fmt_temp_maxsise</span> <span class="figure-label">Max size of temporary file</span></li>
							<li><span class="figure">$fmt_temp_avsize</span> <span class="figure-label">Average size of temporary file</span></li>
						</ul>
					</div>
					<div class="tab-pane" id="tab-sessions">
						<ul>
							<li class="first"><span class="figure">$session_count</span> <span class="figure-label">Total number of sessions</span></li>
							<li><span class="figure">$session_peak sessions at $session_peak_date</span> <span class="figure-label">Session peak</span></li>
							<li><span class="figure">$tot_session_duration</span> <span class="figure-label">Total duration of sessions</span></li>
							<li><span class="figure">$avg_session_duration</span> <span class="figure-label">Average duration of sessions</span></li>
							<li><span class="figure">$avg_queries</span> <span class="figure-label">Average queries per session</span></li>
							<li><span class="figure">$avg_duration</span> <span class="figure-label">Average queries duration per session</span></li>

						</ul>
					</div>
					<div class="tab-pane" id="tab-connections">
						<ul>
							<li class="first"><span class="figure">$connection_count</span> <span class="figure-label">Total number of connections</span></li>
};
	if ($connection_count) {
		print $fh qq{
							<li><span class="figure">$connection_peak connections/s at $connection_peak_date</span> <span class="figure-label">Connection peak</span></li>
};
	}
	print $fh qq{
							<li><span class="figure">$db_count</span> <span class="figure-label">Total number of databases</span></li>
						</ul>
					</div>
				</div> <!-- end div tab-content -->
			</div> <!-- end div tabbable -->
		</div> <!-- end div global-stats -->
};

}

sub print_general_activity
{
	my $queries = '';
	my $select_queries = '';
	my $write_queries = '';
	my $prepared_queries = '';
	my $connections = '';
	my $sessions = '';
	foreach my $d (sort {$a <=> $b} keys %per_minute_info) {
		my $c = 1;
		$d =~ /^\d{4}(\d{2})(\d{2})$/;
		my $zday = "$abbr_month{$1} $2";
		foreach my $h (sort {$a <=> $b} keys %{$per_minute_info{$d}}) {
			my %cur_period_info = ();
			my $write_average_duration = 0;
			my $write_average_count = 0;
			my %all_query_duration=();
			foreach my $m (keys %{$per_minute_info{$d}{$h}}) {
				$cur_period_info{count} += ($per_minute_info{$d}{$h}{$m}{query}{count} || 0);
				$cur_period_info{duration} += ($per_minute_info{$d}{$h}{$m}{query}{duration} || 0);
				$cur_period_info{min} = $per_minute_info{$d}{$h}{$m}{query}{min} if (!exists $cur_period_info{min} || ($per_minute_info{$d}{$h}{$m}{query}{min} < $cur_period_info{min}));
				$cur_period_info{max} = $per_minute_info{$d}{$h}{$m}{query}{max} if (!exists $cur_period_info{max} || ($per_minute_info{$d}{$h}{$m}{query}{max} > $cur_period_info{max}));
                                push(@{$all_query_duration{'query'}}, $per_minute_info{$d}{$h}{$m}{query}{duration}||0);

				foreach my $a (@SQL_ACTION) {
					$cur_period_info{$a}{count} += ($per_minute_info{$d}{$h}{$m}{$a}{count} || 0);
					$cur_period_info{$a}{duration} += ($per_minute_info{$d}{$h}{$m}{$a}{duration} || 0);
					push(@{$all_query_duration{$a}}, $per_minute_info{$d}{$h}{$m}{$a}{duration}||0);
					$cur_period_info{usual} += ($per_minute_info{$d}{$h}{$m}{$a}{count} || 0);
				}
				$cur_period_info{prepare} += ($per_minute_info{$d}{$h}{$m}{prepare} || 0);
				$cur_period_info{execute} += ($per_minute_info{$d}{$h}{$m}{execute} || 0);
			}

			$cur_period_info{average} = $cur_period_info{duration} / ($cur_period_info{count} || 1);
			$cur_period_info{'SELECT'}{average} = $cur_period_info{'SELECT'}{duration} / ($cur_period_info{'SELECT'}{count} || 1);

			$write_average_duration = ($cur_period_info{'INSERT'}{duration} +
					$cur_period_info{'UPDATE'}{duration} +
					$cur_period_info{'DELETE'}{duration});
			$write_average_count = ($cur_period_info{'INSERT'}{count} +
					$cur_period_info{'UPDATE'}{count} +
					$cur_period_info{'DELETE'}{count});
			$zday = "&nbsp;" if ($c > 1);
			$c++;

			my $count = &comma_numbers($cur_period_info{count});
			my $min = &convert_time($cur_period_info{min});
			my $max = &convert_time($cur_period_info{max});
			my $average = &convert_time($cur_period_info{average});
                        my %percentile =  ();
			foreach my $lp (@LATENCY_PERCENTILE) {
		 		$cur_period_info{$lp}{percentileindex} = int(@{$all_query_duration{'query'}} * $lp / 100) ;
                        	@{$all_query_duration{'query'}}= sort{ $a <=> $b } @{$all_query_duration{'query'}};
                        	$cur_period_info{$lp}{percentile} = $all_query_duration{'query'}[$cur_period_info{$lp}{percentileindex}];
				$percentile{$lp} =  &convert_time($cur_period_info{$lp}{percentile});

                        	$cur_period_info{'SELECT'}{$lp}{percentileindex} = int(@{$all_query_duration{'SELECT'}} * $lp / 100) ;
                        	@{$all_query_duration{'SELECT'}}= sort{ $a <=> $b } @{$all_query_duration{'SELECT'}};
                        	$cur_period_info{'SELECT'}{$lp}{percentile} = $all_query_duration{'SELECT'}[$cur_period_info{'SELECT'}{$lp}{percentileindex}];
				$percentile{'SELECT'}{$lp} =  &convert_time($cur_period_info{'SELECT'}{$lp}{percentile});

				@{$all_query_duration{'WRITE'}}=  sort{ $a <=> $b } (@{$all_query_duration{'INSERT'}},@{$all_query_duration{'UPDATE'}},@{$all_query_duration{'DELETE'}});
                        	$cur_period_info{'WRITE'}{$lp}{percentileindex} = int(@{$all_query_duration{'WRITE'}} * $lp / 100) ;
                        	$cur_period_info{'WRITE'}{$lp}{percentile} = $all_query_duration{'WRITE'}[$cur_period_info{'WRITE'}{$lp}{percentileindex}];
				$percentile{'WRITE'}{$lp} =  &convert_time($cur_period_info{'WRITE'}{$lp}{percentile});	
			}
			$queries .= qq{
					<tr>
						<td>$zday</td>
						<td>$h</td>
						<td>$count</td>
						<td>$min</td>
						<td>$max</td>
						<td>$average</td>
};
			foreach my $lp (@LATENCY_PERCENTILE) {
				$queries .= "<td>$percentile{$lp}</td>\n";
			}
			$queries .= qq{
					</tr>};
			$count = &comma_numbers($cur_period_info{'SELECT'}{count});
			$average = &convert_time($cur_period_info{'SELECT'}{average});
			$select_queries .= qq{
					<tr>
						<td>$zday</td>
						<td>$h</td>
						<td>$count</td>
						<td>$average</td>
};
			foreach my $lp (@LATENCY_PERCENTILE) {
				$select_queries .= "<td>$percentile{'SELECT'}{$lp}</td>\n";
			}
			$select_queries .= qq{
					</tr>};
			my $insert_count = &comma_numbers($cur_period_info{'INSERT'}{count});
			my $update_count = &comma_numbers($cur_period_info{'UPDATE'}{count});
			my $delete_count = &comma_numbers($cur_period_info{'DELETE'}{count});
			my $write_average = &convert_time($write_average_duration / ($write_average_count || 1));
			$write_queries .= qq{
					<tr>
						<td>$zday</td>
						<td>$h</td>
						<td>$insert_count</td>
						<td>$update_count</td>
						<td>$delete_count</td>
						<td>$write_average</td>} ;
			foreach my $lp (@LATENCY_PERCENTILE) {
				$write_queries .= "<td>$percentile{'WRITE'}{$lp}</td>\n";
			}
			$write_queries .= qq{
					</tr>};
			my $prepare_count = &comma_numbers($cur_period_info{prepare});
			my $execute_count = &comma_numbers($cur_period_info{execute});
			my $bind_prepare = &comma_numbers(sprintf("%.2f", $cur_period_info{execute}/($cur_period_info{prepare}||1)));
			my $prepare_usual = &comma_numbers(sprintf("%.2f", ($cur_period_info{prepare}/($cur_period_info{usual}||1)) * 100)) . "%";
			$prepared_queries .= qq{
					<tr>
						<td>$zday</td>
						<td>$h</td>
						<td>$prepare_count</td>
						<td>$execute_count</td>
						<td>$bind_prepare</td>
						<td>$prepare_usual</td>
					</tr>};
			$count = &comma_numbers($connection_info{chronos}{"$d"}{"$h"}{count});
			$average = &comma_numbers(sprintf("%0.2f", $connection_info{chronos}{"$d"}{"$h"}{count} / 3600));
			$connections .= qq{
					<tr>
						<td>$zday</td>
						<td>$h</td>
						<td>$count</td>
						<td>$average/s</td>
					</tr>};
			$count = &comma_numbers($session_info{chronos}{"$d"}{"$h"}{count});
			$cur_period_info{'session'}{average} =
				$session_info{chronos}{"$d"}{"$h"}{duration} / ($session_info{chronos}{"$d"}{"$h"}{count} || 1);
			$average = &convert_time($cur_period_info{'session'}{average});
			$sessions .= qq{
					<tr>
						<td>$zday</td>
						<td>$h</td>
						<td>$count</td>
						<td>$average</td>
					</tr>};
		}
	}

	# Set default values
	$queries = qq{<tr><td colspan="6">$NODATA</td></tr>} if (!$queries);
	$select_queries = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$select_queries);
	$write_queries = qq{<tr><td colspan="6">$NODATA</td></tr>} if (!$write_queries);
	$prepared_queries = qq{<tr><td colspan="6">$NODATA</td></tr>} if (!$prepared_queries);
	$connections = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$connections);
	$sessions = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$sessions);

	print $fh qq{
<div class="analysis-item row-fluid" id="general-activity">
	<h2 class=""><i class="icon-calendar"></i> General Activity</h2>
	<div class="span11 tabbable tabs-left">
		<ul class="nav nav-tabs">
			<li class="active"><a href="#general-activity-queries" data-toggle="tab">Queries</a></li>
		    <li><a href="#general-activity-select-queries" data-toggle="tab">SELECT Queries</a></li>
			<li><a href="#general-activity-write-queries" data-toggle="tab">Write Queries</a></li>
			<li><a href="#general-activity-prepared-queries" data-toggle="tab">Prepared Queries</a></li>
			<li><a href="#general-activity-connections" data-toggle="tab">Connections</a></li>
			<li><a href="#general-activity-sessions" data-toggle="tab">Sessions</a></li>
		</ul>
		<div class="tab-content">
			<div class="active tab-pane" id="general-activity-queries">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Count</th>
							<th>Min duration</th>
							<th>Max duration</th>
							<th>Avg duration</th>
							<th>Latency Percentile(90)</th>
							<th>Latency Percentile(95)</th>
							<th>Latency Percentile(99)</th>
						</tr>
					</thead>
					<tbody>$queries
					</tbody>
				</table>							    				        
			</div>
			<div class="tab-pane" id="general-activity-select-queries">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Count</th>
							<th>Average Duration</th>
							<th>Latency Percentile(90)</th>
							<th>Latency Percentile(95)</th>
                                                        <th>Latency Percentile(99)</th>
						</tr>
					</thead>
					<tbody>$select_queries
					</tbody>
				</table>        				        
			</div>
			<div class="tab-pane" id="general-activity-write-queries">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>INSERT</th>
							<th>UPDATE</th>
							<th>DELETE</th>
							<th>Average Duration</th>
							<th>Latency Percentile(90)</th>
							<th>Latency Percentile(95)</th>
                                                        <th>Latency Percentile(99)</th>
						</tr>
					</thead>
					<tbody>$write_queries
					</tbody>
				</table>        
			</div>
			<div class="tab-pane" id="general-activity-prepared-queries">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Prepare</th>
							<th>Bind</th>
							<th>Bind/Prepare</th>
							<th>Percentage of prepare</th>
						</tr>
					</thead>
					<tbody>$prepared_queries
					</tbody>
				</table>        
			</div>
			<div class="tab-pane" id="general-activity-connections">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Count</th>
							<th>Average / Second</th>
						</tr>
					</thead>
					<tbody>$connections
					</tbody>
				</table>        
			</div>
			<div class="tab-pane" id="general-activity-sessions">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Count</th>
							<th>Average Duration</th>
						</tr>
					</thead>
					<tbody>$sessions
					</tbody>
				</table>        
			</div>
		</div> <!-- end of div tab-content -->
		<span class="pull-right">&uarr; <small><a href="#general-activity" class="">Back to the top of the <em>General Activity</em> table</a></small></span>
	</div>

</div><!-- end of general activity -->
};

}

sub print_sql_traffic
{

	my $bind_vs_prepared = sprintf("%.2f", $overall_stat{'execute'} / ($overall_stat{'prepare'} || 1));
	my $total_usual_queries = 0;
	map { $total_usual_queries += $overall_stat{$_}; } @SQL_ACTION;
	my $prepared_vs_normal = sprintf("%.2f", ($overall_stat{'execute'} / ($total_usual_queries || 1))*100);

	my $query_peak = 0;
	my $query_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{query} <=> $overall_stat{'peak'}{$a}{query}} keys %{$overall_stat{'peak'}}) {
		$query_peak = &comma_numbers($overall_stat{'peak'}{$_}{query});
		$query_peak_date = $_;
		last;
	}

	my $select_peak = 0;
	my $select_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{select} <=> $overall_stat{'peak'}{$a}{select}} keys %{$overall_stat{'peak'}}) {
		$select_peak = &comma_numbers($overall_stat{'peak'}{$_}{select});
		$select_peak_date = $_;
		last;
	}

	my $write_peak = 0;
	my $write_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{write} <=> $overall_stat{'peak'}{$a}{write}} keys %{$overall_stat{'peak'}}) {
		$write_peak = &comma_numbers($overall_stat{'peak'}{$_}{write});
		$write_peak_date = $_;
		last;
	}
	my $fmt_duration = &convert_time($overall_stat{'queries_duration'});

	print $fh qq{
	<div id="sql-traffic" class="analysis-item row-fluid">
		<h2 class=""><i class="icon-road"></i> SQL Traffic</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$query_peak queries/s</span> <span class="figure-label">Query Peak</span></li>
					<li><span class="figure">$query_peak_date</span> <span class="figure-label">Date</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<h3 class="">Queries per second ($avg_minutes minutes average)</h3>
$drawn_graphs{queriespersecond_graph}
		</div>
	</div><!-- end of sql-traffic -->
};
	delete $drawn_graphs{queriespersecond_graph};

	print $fh qq{
	<div id="select-traffic" class="analysis-item row-fluid">
		<h2 class=""><i class="icon-road"></i> SELECT Traffic</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$select_peak queries/s</span> <span class="figure-label">Query Peak</span></li>
					<li><span class="figure">$select_peak_date</span> <span class="figure-label">Date</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<h3 class="">SELECT queries per second ($avg_minutes minutes average)</h3>
$drawn_graphs{selectqueries_graph}
		</div>
	</div><!-- end of select-traffic -->
};
	delete $drawn_graphs{selectqueries_graph};

	print $fh qq{
	<div id="write-traffic" class="analysis-item row-fluid">
		<h2 class=""><i class="icon-road"></i> INSERT/UPDATE/DELETE Traffic</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$write_peak queries/s</span> <span class="figure-label">Query Peak</span></li>
					<li><span class="figure">$write_peak_date</span> <span class="figure-label">Date</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<h3 class="">Write queries per second ($avg_minutes minutes average)</h3>
$drawn_graphs{writequeries_graph}
		</div>
	</div><!-- end of write-traffic -->
};
	delete $drawn_graphs{writequeries_graph};

	print $fh qq{
	<div id="duration-traffic" class="analysis-item row-fluid">
		<h2 class=""><i class="icon-time"></i> Queries duration</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$fmt_duration</span> <span class="figure-label">Total query duration</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<h3 class="">Average queries duration ($avg_minutes minutes average)</h3>
$drawn_graphs{durationqueries_graph}
		</div>
	</div><!-- end of duration-traffic -->
};
	delete $drawn_graphs{durationqueries_graph};

	print $fh qq{
	<div id="prepared-queries-ratio" class="analysis-item row-fluid">
		<h2 class=""><i class="icon-cog"></i> Prepared queries ratio</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$bind_vs_prepared</span> <span class="figure-label">Ratio of bind vs prepare</span></li>
					<li><span class="figure">$prepared_vs_normal %</span> <span class="figure-label">Ratio between prepared and "usual" statements</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<h3 class="">Ratio of bind vs prepare statements ($avg_minutes minutes average)</h3>
$drawn_graphs{bindpreparequeries_graph}
		</div>
	</div><!-- end of prepared-queries-ratio -->
};
	delete $drawn_graphs{bindpreparequeries_graph};

}

sub compute_query_graphs
{
	my %graph_data = ();
	if ($graph) {

		foreach my $tm (sort {$a <=> $b} keys %per_minute_info) {
			$tm =~ /(\d{4})(\d{2})(\d{2})/;
			my $y  = $1 - 1900;
			my $mo = $2 - 1;
			my $d  = $3;
			foreach my $h ("00" .. "23") {
				next if (!exists $per_minute_info{$tm}{$h});
				my %q_dataavg = ();
				my %a_dataavg = ();
				my %c_dataavg = ();
				my %s_dataavg = ();
				my %p_dataavg = ();
				foreach my $m ("00" .. "59") {
					next if (!exists $per_minute_info{$tm}{$h}{$m});

					my $rd = &average_per_minutes($m, $avg_minutes);

					if (!exists $p_dataavg{prepare}{"$rd"}) {
						$p_dataavg{prepare}{"$rd"} = 0;
						$p_dataavg{execute}{"$rd"} = 0;

						$q_dataavg{count}{"$rd"} = 0;
						$q_dataavg{duration}{"$rd"} = 0;
						$q_dataavg{max}{"$rd"} = 0;
						$q_dataavg{min}{"$rd"} = 0;

						if (!$disable_query) {
							foreach my $action (@SQL_ACTION) {
								$a_dataavg{$action}{count}{"$rd"} = 0;
								$a_dataavg{$action}{duration}{"$rd"} = 0;
								$a_dataavg{$action}{max}{"$rd"} = 0;
								$a_dataavg{$action}{min}{"$rd"} = 0;
							}
							$a_dataavg{write}{count}{"$rd"} = 0;
							$a_dataavg{write}{duration}{"$rd"} = 0;
						}

						$c_dataavg{average}{"$rd"} = 0;
						$c_dataavg{max}{"$rd"} = 0;
						$c_dataavg{min}{"$rd"} = 0;
						$s_dataavg{average}{"$rd"} = 0;
						$s_dataavg{max}{"$rd"} = 0;
						$s_dataavg{min}{"$rd"} = 0;
					}
					if (exists $per_minute_info{$tm}{$h}{$m}{prepare}) {
						$p_dataavg{prepare}{"$rd"} += $per_minute_info{$tm}{$h}{$m}{prepare};
					} elsif (exists $per_minute_info{$tm}{$h}{$m}{parse}) {
						$p_dataavg{prepare}{"$rd"} += $per_minute_info{$tm}{$h}{$m}{parse};
					}
					$p_dataavg{execute}{"$rd"} += $per_minute_info{$tm}{$h}{$m}{execute}
						if (exists $per_minute_info{$tm}{$h}{$m}{execute});

					if (exists $per_minute_info{$tm}{$h}{$m}{query}) {

						# Average per minute
						$q_dataavg{count}{"$rd"} += $per_minute_info{$tm}{$h}{$m}{query}{count};
						if (exists $per_minute_info{$tm}{$h}{$m}{query}{duration}) {
							$q_dataavg{duration}{"$rd"} += $per_minute_info{$tm}{$h}{$m}{query}{duration};
						}
						# Search minimum and maximum during this minute
						foreach my $s (keys %{$per_minute_info{$tm}{$h}{$m}{query}{second}}) {
							$q_dataavg{max}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{query}{second}{$s}
								if ($per_minute_info{$tm}{$h}{$m}{query}{second}{$s} > $q_dataavg{max}{"$rd"});
							$q_dataavg{min}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{query}{second}{$s}
								if ($per_minute_info{$tm}{$h}{$m}{query}{second}{$s} < $q_dataavg{min}{"$rd"});
						}

						if (!$disable_query) {
							foreach my $action (@SQL_ACTION) {
								$a_dataavg{$action}{count}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{$action}{count} || 0);
								$a_dataavg{$action}{duration}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{$action}{duration} || 0);
								if ( ($action ne 'SELECT') && exists $per_minute_info{$tm}{$h}{$m}{$action}{count}) {
									$a_dataavg{write}{count}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{$action}{count} || 0);
									$a_dataavg{write}{duration}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{$action}{duration} || 0);
								}
								# Search minimum and maximum during this minute
								foreach my $s (keys %{$per_minute_info{$tm}{$h}{$m}{$action}{second}}) {
									$a_dataavg{$action}{max}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{$action}{second}{$s}
										if ($per_minute_info{$tm}{$h}{$m}{$action}{second}{$s} > $a_dataavg{$action}{max}{"$rd"});
									$a_dataavg{$action}{min}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{$action}{second}{$s}
										if ($per_minute_info{$tm}{$h}{$m}{$action}{second}{$s} < $a_dataavg{$action}{min}{"$rd"});
								}
							}
						}
					}

					if (exists $per_minute_info{$tm}{$h}{$m}{connection}) {

						# Average per minute
						$c_dataavg{average}{"$rd"} += $per_minute_info{$tm}{$h}{$m}{connection}{count};

						# Search minimum and maximum during this minute
						foreach my $s (keys %{$per_minute_info{$tm}{$h}{$m}{connection}{second}}) {
							$c_dataavg{max}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{connection}{second}{$s}
								if ($per_minute_info{$tm}{$h}{$m}{connection}{second}{$s} > $c_dataavg{max}{"$rd"});
							$c_dataavg{min}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{connection}{second}{$s}
								if ($per_minute_info{$tm}{$h}{$m}{connection}{second}{$s} < $c_dataavg{min}{"$rd"});
						}
						delete $per_minute_info{$tm}{$h}{$m}{connection};
					}

					if (exists $per_minute_info{$tm}{$h}{$m}{session}) {

						# Average per minute
						$s_dataavg{average}{"$rd"} += $per_minute_info{$tm}{$h}{$m}{session}{count};

						# Search minimum and maximum during this minute
						foreach my $s (keys %{$per_minute_info{$tm}{$h}{$m}{session}{second}}) {
							$s_dataavg{max}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{session}{second}{$s}
								if ($per_minute_info{$tm}{$h}{$m}{session}{second}{$s} > $s_dataavg{max}{"$rd"});
							$s_dataavg{min}{"$rd"} = $per_minute_info{$tm}{$h}{$m}{session}{second}{$s}
								if ($per_minute_info{$tm}{$h}{$m}{session}{second}{$s} < $s_dataavg{min}{"$rd"});
						}
						delete $per_minute_info{$tm}{$h}{$m}{session};
					}
				}

				foreach my $rd (@avgs) {
					my $t = timegm_nocheck(0, $rd, $h, $d, $mo, $y) * 1000;

					next if ($t < $t_min);
					last if ($t > $t_max);

					if (exists $q_dataavg{count}) {
						# Average queries per minute
						$graph_data{query} .= "[$t, " . int(($q_dataavg{count}{"$rd"} || 0) / (60 * $avg_minutes)) . "],";
						# Max queries per minute
						$graph_data{'query-max'} .= "[$t, " . ($q_dataavg{max}{"$rd"} || 0) . "],";
						# Min queries per minute
						$graph_data{'query-min'} .= "[$t, " . ($q_dataavg{min}{"$rd"} || 0) . "],";
						# Average duration per minute
						$graph_data{query4} .= "[$t, " . sprintf("%.3f", ($q_dataavg{duration}{"$rd"} || 0) / ($q_dataavg{count}{"$rd"} || 1)) . "],";
					}
					if (scalar keys %c_dataavg) { 
						# Average connections per minute
						$graph_data{conn_avg} .= "[$t, " . int(($c_dataavg{average}{"$rd"} || 0) / (60 * $avg_minutes)) . "],";
						# Max connections per minute
						$graph_data{conn_max} .= "[$t, " . ($c_dataavg{max}{"$rd"} || 0) . "],";

						# Min connections per minute
						$graph_data{conn_min} .= "[$t, " . ($c_dataavg{min}{"$rd"} || 0) . "],";
					}
					if (scalar keys %s_dataavg) { 
						# Average connections per minute
						$graph_data{sess_avg} .= "[$t, " . int(($s_dataavg{average}{"$rd"} || 0) / (60 * $avg_minutes)) . "],";
						# Max connections per minute
						$graph_data{sess_max} .= "[$t, " . ($s_dataavg{max}{"$rd"} || 0) . "],";

						# Min connections per minute
						$graph_data{sess_min} .= "[$t, " . ($s_dataavg{min}{"$rd"} || 0) . "],";
					}
					if (!$disable_query && (scalar keys %a_dataavg > 0)) { 
						foreach my $action (@SQL_ACTION) {
							next if ($select_only && ($action ne 'SELECT'));

							# Average queries per minute
							$graph_data{"$action"} .= "[$t, " . int(($a_dataavg{$action}{count}{"$rd"} || 0) / (60 * $avg_minutes)) . "],";
							if ($action eq 'SELECT') {
								# Max queries per minute
								$graph_data{"$action-max"} .= "[$t, " . ($a_dataavg{$action}{max}{"$rd"} || 0) . "],";
								# Min queries per minute
								$graph_data{"$action-min"} .= "[$t, " . ($a_dataavg{$action}{min}{"$rd"} || 0) . "],";
								# Average query duration
								$graph_data{"$action-2"} .= "[$t, " . sprintf("%.3f", ($a_dataavg{$action}{duration}{"$rd"} || 0) / ($a_dataavg{$action}{count}{"$rd"} || 1)) . "],";
							} else {
								# Average query duration
								$graph_data{"write"} .= "[$t, " . sprintf("%.3f", ($a_dataavg{write}{duration}{"$rd"} || 0) / ($a_dataavg{write}{count}{"$rd"} || 1)) . "],";
							}
						}
					}
					if (!$disable_query && (scalar keys %p_dataavg> 0)) { 
						$graph_data{prepare} .= "[$t, " . ($p_dataavg{prepare}{"$rd"} || 0) . "],";
						$graph_data{execute} .= "[$t, " . ($p_dataavg{execute}{"$rd"} || 0) . "],";
						$graph_data{ratio_bind_prepare} .= "[$t, " . sprintf("%.2f", ($p_dataavg{execute}{"$rd"} || 0) / ($p_dataavg{prepare}{"$rd"} || 1)) . "],";
					}
				}
			}
		}
		foreach (keys %graph_data) {
			$graph_data{$_} =~ s/,$//;
		}
	}
	$drawn_graphs{'queriespersecond_graph'} = &flotr2_graph( $graphid++, 'queriespersecond_graph', $graph_data{'query-max'},
		$graph_data{query}, $graph_data{'query-min'}, 'Queries per second (' . $avg_minutes . ' minutes average)',
		'Queries per second', 'Maximum', 'Average', 'Minimum'
	);

	$drawn_graphs{'connectionspersecond_graph'} = &flotr2_graph( $graphid++, 'connectionspersecond_graph', $graph_data{conn_max},
		$graph_data{conn_avg}, $graph_data{conn_min}, 'Connections per second (' . $avg_minutes . ' minutes average)',
		'Connections per second', 'Maximum', 'Average', 'Minimum'
	);

	$drawn_graphs{'sessionspersecond_graph'} = &flotr2_graph( $graphid++, 'sessionspersecond_graph', $graph_data{sess_max},
		$graph_data{sess_avg}, $graph_data{sess_min}, 'Number of sessions (' . $avg_minutes . ' minutes average)',
		'Sessions', 'Maximum', 'Average', 'Minimum'
	);

	$drawn_graphs{'selectqueries_graph'} = &flotr2_graph( $graphid++, 'selectqueries_graph', $graph_data{"SELECT-max"},
		$graph_data{"SELECT"}, $graph_data{"SELECT-min"},
		'SELECT queries (' . $avg_minutes . ' minutes period)',
		'Queries per second', 'Maximum', 'Average', 'Minimum'
	);

	$drawn_graphs{'writequeries_graph'} = &flotr2_graph(
		$graphid++, 'writequeries_graph', $graph_data{"DELETE"}, $graph_data{"INSERT"}, $graph_data{"UPDATE"}, 'Write queries (' . $avg_minutes . ' minutes period)',
		'Queries', 'DELETE queries', 'INSERT queries', 'UPDATE queries'
	);

	if (!$select_only) {
		$drawn_graphs{'durationqueries_graph'} = &flotr2_graph(
			$graphid++, 'durationqueries_graph', $graph_data{query4}, $graph_data{"SELECT-2"}, $graph_data{write}, 'Average queries duration (' . $avg_minutes . ' minutes average)',
			'Duration', 'All queries', 'Select queries', 'Write queries'
		);
	} else {
		$drawn_graphs{'durationqueries_graph'} = &flotr2_graph(
			$graphid++, 'durationqueries_graph', $graph_data{query4}, '', '', 'Average queries duration (' . $avg_minutes . ' minutes average)',
			'Duration', 'Select queries'
		);
	}

	$drawn_graphs{'bindpreparequeries_graph'} = &flotr2_graph(
		$graphid++, 'bindpreparequeries_graph', $graph_data{prepare}, $graph_data{"execute"}, $graph_data{ratio_bind_prepare}, 'Bind versus prepare statements (' . $avg_minutes . ' minutes average)',
		'Number of statements', 'Prepare/Parse', 'Execute/Bind', 'Bind vs prepare'
	);

}

sub print_established_connection
{

	my $connection_peak = 0;
	my $connection_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{connection} <=> $overall_stat{'peak'}{$a}{connection}} keys %{$overall_stat{'peak'}}) {
		$connection_peak = &comma_numbers($overall_stat{'peak'}{$_}{connection});
		$connection_peak_date = $_;
		last;
	}

	print $fh qq{
	<div id="established-connections" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-random"></i> Established Connections</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$connection_peak connections</span> <span class="figure-label">Connection Peak</span></li>
				<li><span class="figure">$connection_peak_date</span> <span class="figure-label">Date</span></li>    
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Connections per second ($avg_minutes minutes average)</h3>
$drawn_graphs{connectionspersecond_graph}
		</div>
	</div><!-- end of Established connections -->
};
	delete $drawn_graphs{connectionspersecond_graph};

}

sub print_user_connection
{

	my %infos = ();
	my $total_count = 0;
	my $c           = 0;
	my $conn_user_info = '';
	my @main_user = ('unknown',0);
	foreach my $u (sort keys %{$connection_info{user}}) {
		$conn_user_info .= "<tr><td>$u</td><td>" .
				   &comma_numbers($connection_info{user}{$u}) . "</td></tr>";
		$total_count += $connection_info{user}{$u};
		if ($main_user[1] < $connection_info{user}{$u}) {
			$main_user[0] = $u;
			$main_user[1] = $connection_info{user}{$u};
		}
	}
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$connection_info{user}}) {
			if ((($connection_info{user}{$d} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $connection_info{user}{$d} || 0;
			} else {
				$infos{"Sum connections < $pie_percentage_limit%"} += $connection_info{user}{$d} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum connections < $pie_percentage_limit%"};
			delete $infos{"Sum connections < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{userconnections_graph} = &flotr2_piegraph($graphid++, 'graph_userconnections', 'Connections per user', %infos);
	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<div class="analysis-item row-fluid" id="connections-per-user">
		<h2><i class="icon-user"></i> Connections per user</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_user[0]</span> <span class="figure-label">Main User</span></li>
					<li><span class="figure">$total_count connections</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#connections-per-user-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#connections-per-user-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="connections-per-user-graph">
						$drawn_graphs{userconnections_graph}
					</div>
					<div class="tab-pane" id="connections-per-user-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>User</th>
									<th>Count</th>
								</tr>
							</thead>
							<tbody>
							$conn_user_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of connections per user -->
};
	delete $drawn_graphs{userconnections_graph};
}

sub print_host_connection
{
	my %infos = ();
	my $total_count = 0;
	my $c           = 0;
	my $conn_host_info = '';
	my @main_host = ('unknown',0);
	foreach my $h (sort keys %{$connection_info{host}}) {
		$conn_host_info .= "<tr><td>$h</td><td>" .
				    &comma_numbers($connection_info{host}{$h}) . "</td></tr>";
		$total_count += $connection_info{host}{$h};
		if ($main_host[1] < $connection_info{host}{$h}) {
			$main_host[0] = $h;
			$main_host[1] = $connection_info{host}{$h};
		}
	}
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$connection_info{host}}) {
			if ((($connection_info{host}{$d} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $connection_info{host}{$d} || 0;
			} else {
				$infos{"Sum connections < $pie_percentage_limit%"} += $connection_info{host}{$d} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum connections < $pie_percentage_limit%"};
			delete $infos{"Sum connections < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{hostconnections_graph} = &flotr2_piegraph($graphid++, 'graph_hostconnections', 'Connections per host', %infos);
	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<div class="analysis-item row-fluid" id="connections-per-host">
		<h2><i class="icon-sitemap"></i> Connections per host</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_host[0]</span> <span class="figure-label">Main host with $main_host[1] connections</span></li>
					<li><span class="figure">$total_count</span> <span class="figure-label">Total connections</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#connections-per-host-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#connections-per-host-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="connections-per-host-graph">
						$drawn_graphs{hostconnections_graph}
					</div>
					<div class="tab-pane" id="connections-per-host-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Host</th>
									<th>Count</th>
								</tr>
							</thead>
							<tbody>
							$conn_host_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of connections per host -->
};

	delete $drawn_graphs{hostconnections_graph};
}

sub print_database_connection
{
	my %infos = ();
	my $total_count = 0;
	my $conn_database_info = '';
	my @main_database = ('unknown',0);
	foreach my $d (sort keys %{$connection_info{database}}) {
		$conn_database_info .= "<tr><td>$d</td><td>&nbsp;</td><td>" .
					 &comma_numbers($connection_info{database}{$d}) . "</td></tr>";
		$total_count += $connection_info{database}{$d};
		if ($main_database[1] < $connection_info{database}{$d}) {
			$main_database[0] = $d;
			$main_database[1] = $connection_info{database}{$d};
		}
		foreach my $u (sort keys %{$connection_info{user}}) {
			next if (!exists $connection_info{database_user}{$d}{$u});
			$conn_database_info .= "<tr><td>&nbsp;</td><td>$u</td><td>" .
				&comma_numbers($connection_info{database_user}{$d}{$u}) . "</td></tr>";
		}
	}
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$connection_info{database}}) {
			if ((($connection_info{database}{$d} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $connection_info{database}{$d} || 0;
			} else {
				$infos{"Sum connections < $pie_percentage_limit%"} += $connection_info{database}{$d} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum connections < $pie_percentage_limit%"};
			delete $infos{"Sum connections < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{databaseconnections_graph} = &flotr2_piegraph($graphid++, 'graph_databaseconnections', 'Connections per database', %infos);
	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<div class="analysis-item row-fluid" id="connections-per-database">
		<h2><i class="icon-list-alt"></i> Connections per database</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_database[0]</span> <span class="figure-label">Main Database</span></li>
					<li><span class="figure">$total_count connections</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#connections-per-database-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#connections-per-database-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="connections-per-database-graph">
						$drawn_graphs{databaseconnections_graph}
					</div>
					<div class="tab-pane" id="connections-per-database-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Database</th>
									<th>User</th>
									<th>Count</th>
								</tr>
							</thead>
							<tbody>
							$conn_database_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of connections per database -->
};
	delete $drawn_graphs{databaseconnections_graph};
}

sub print_simultaneous_session
{

	my $session_peak = 0;
	my $session_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{session} <=> $overall_stat{'peak'}{$a}{session}} keys %{$overall_stat{'peak'}}) {
		$session_peak = &comma_numbers($overall_stat{'peak'}{$_}{session});
		$session_peak_date = $_;
		last;
	}

	print $fh qq{
	<div id="simultaneous-sessions" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-random"></i> Simultaneous sessions</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$session_peak sessions</span> <span class="figure-label">Session Peak</span></li>
				<li><span class="figure">$session_peak_date</span> <span class="figure-label">Date</span></li>    
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Number of sessions ($avg_minutes minutes average)</h3>
$drawn_graphs{sessionspersecond_graph}
		</div>
	</div><!-- end of Simultaneous sessions -->
};
	delete $drawn_graphs{sessionspersecond_graph};

}

sub print_histogram_session_times
{
	my %data = ();
	my $histogram_info = '';
	my $most_range = '';
	my $most_range_value = '';

	for (my $i = 1; $i <= $#histogram_session_time; $i++) {
                $histogram_info .= "<tr><td>" . &convert_time($histogram_session_time[$i-1]) . '-' . &convert_time($histogram_session_time[$i]) . "</td><td>" . &comma_numbers($overall_stat{histogram}{session_time}{$histogram_session_time[$i-1]}) .
                        "</td><td>" . sprintf("%0.2f", ($overall_stat{histogram}{session_time}{$histogram_session_time[$i-1]} * 100) / ($overall_stat{histogram}{session_total}||1)) . "%</td></tr>";
		$data{"$histogram_session_time[$i-1]-$histogram_session_time[$i]ms"} = ($overall_stat{histogram}{session_time}{$histogram_session_time[$i-1]} || 0);
		if ($overall_stat{histogram}{session_time}{$histogram_session_time[$i-1]} > $most_range_value) {
			$most_range = "$histogram_session_time[$i-1]-$histogram_session_time[$i]ms";
			$most_range_value = $overall_stat{histogram}{session_time}{$histogram_session_time[$i-1]};
		}
	}
	if ($overall_stat{histogram}{session_total} > 0) {
		$histogram_info .= "<tr><td> &gt; " . &convert_time($histogram_session_time[-1]) . "</td><td>" . &comma_numbers($overall_stat{histogram}{session_time}{'-1'}) .
			"</td><td>" . sprintf("%0.2f", ($overall_stat{histogram}{session_time}{'-1'} * 100) / ($overall_stat{histogram}{session_total}||1)) . "%</td></tr>";
		$data{"> $histogram_session_time[-1]ms"} = ($overall_stat{histogram}{session_time}{"-1"} || 0);
		if ($overall_stat{histogram}{session_time}{"-1"} > $most_range_value) {
			$most_range = "> $histogram_session_time[-1]ms";
			$most_range_value = $overall_stat{histogram}{session_time}{"-1"};
		}
	} else {
		$histogram_info = qq{<tr><td colspan="3">$NODATA</td></tr>};
	}

	$drawn_graphs{histogram_session_times_graph} = &flotr2_duration_histograph($graphid++, 'graph_histogram_session_times', 'Queries', \@histogram_session_time, %data);

	$most_range_value = &comma_numbers($most_range_value) if ($most_range_value);

	print $fh qq{
	<h2><i class="icon-question-sign"></i> Top Queries</h2>
	<div class="analysis-item row-fluid" id="histogram-session-times">
		<h2><i class="icon-signal"></i> Histogram of session times</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$most_range_value</span> <span class="figure-label">$most_range duration</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#histogram-session-times-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#histogram-session-times-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="histogram-session-times-graph">
						$drawn_graphs{histogram_session_times_graph}
					</div>
					<div class="tab-pane" id="histogram-session-times-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Range</th>
									<th>Count</th>
									<th>Percentage</th>
								</tr>
							</thead>
							<tbody>
							$histogram_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of queries by type -->
};
	delete $drawn_graphs{histogram_session_times_graph};
}



sub print_user_session
{
	my %infos = ();
	my $total_count = 0;
	my $c           = 0;
	my $sess_user_info = '';
	my @main_user = ('unknown',0);
	foreach my $u (sort keys %{$session_info{user}}) {
		$sess_user_info .= "<tr><td>$u</td><td>" . &comma_numbers($session_info{user}{$u}{count}) .
				   "</td><td>" . &convert_time($session_info{user}{$u}{duration}), "</td><td>" .
				   &convert_time($session_info{user}{$u}{duration} / $session_info{user}{$u}{count}) .
				   "</td></tr>";
		$total_count += $session_info{user}{$u}{count};
		if ($main_user[1] < $session_info{user}{$u}{count}) {
			$main_user[0] = $u;
			$main_user[1] = $session_info{user}{$u}{count};
		}
	}
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$session_info{user}}) {
			if ((($session_info{user}{$d}{count} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $session_info{user}{$d}{count} || 0;
			} else {
				$infos{"Sum sessions < $pie_percentage_limit%"} += $session_info{user}{$d}{count} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum sessions < $pie_percentage_limit%"};
			delete $infos{"Sum sessions < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{usersessions_graph} = &flotr2_piegraph($graphid++, 'graph_usersessions', 'Connections per user', %infos);
	$sess_user_info = qq{<tr><td colspan="5">$NODATA</td></tr>} if (!$total_count);
	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<div class="analysis-item row-fluid" id="sessions-per-user">
		<h2><i class="icon-user"></i> Sessions per user</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_user[0]</span> <span class="figure-label">Main User</span></li>
					<li><span class="figure">$total_count sessions</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#sessions-per-user-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#sessions-per-user-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="sessions-per-user-graph">
						$drawn_graphs{usersessions_graph}
					</div>
					<div class="tab-pane" id="sessions-per-user-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>User</th>
									<th>Count</th>
									<th>Total Duration</th>
									<th>Average Duration</th>
								</tr>
							</thead>
							<tbody>
							$sess_user_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of sessions per user -->
};
	delete $drawn_graphs{usersessions_graph};
}

sub print_host_session
{
	my %infos = ();
	my $total_count = 0;
	my $c           = 0;
	my $sess_host_info = '';
	my @main_host = ('unknown',0);
	foreach my $h (sort keys %{$session_info{host}}) {
		$sess_host_info .= "<tr><td>$h</td><td>" . &comma_numbers($session_info{host}{$h}{count}) .
				   "</td><td>" . &convert_time($session_info{host}{$h}{duration}) . "</td><td>" .
				   &convert_time($session_info{host}{$h}{duration} / $session_info{host}{$h}{count}) .
				   "</td></tr>";
		$total_count += $session_info{host}{$h}{count};
		if ($main_host[1] < $session_info{host}{$h}{count}) {
			$main_host[0] = $h;
			$main_host[1] = $session_info{host}{$h}{count};
		}
	}
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$session_info{host}}) {
			if ((($session_info{host}{$d}{count} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $session_info{host}{$d}{count} || 0;
			} else {
				$infos{"Sum sessions < $pie_percentage_limit%"} += $session_info{host}{$d}{count} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum sessions < $pie_percentage_limit%"};
			delete $infos{"Sum sessions < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{hostsessions_graph} = &flotr2_piegraph($graphid++, 'graph_hostsessions', 'Connections per host', %infos);
	$sess_host_info = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$total_count);
	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<div class="analysis-item row-fluid" id="sessions-per-host">
		<h2><i class="icon-sitemap"></i> Sessions per host</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_host[0]</span> <span class="figure-label">Main Host</span></li>
					<li><span class="figure">$total_count sessions</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#sessions-per-host-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#sessions-per-host-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="sessions-per-host-graph">
						$drawn_graphs{hostsessions_graph}
					</div>
					<div class="tab-pane" id="sessions-per-host-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Host</th>
									<th>Count</th>
									<th>Total Duration</th>
									<th>Average Duration</th>
								</tr>
							</thead>
							<tbody>
							$sess_host_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of sessions per host -->
};

	delete $drawn_graphs{hostsessions_graph};
}

sub print_app_session
{
	my %infos = ();
	my $total_count = 0;
	my $c           = 0;
	my $sess_app_info = '';
	my @main_app = ('unknown',0);
	foreach my $h (sort keys %{$session_info{app}}) {
		$sess_app_info .= "<tr><td>$h</td><td>" . &comma_numbers($session_info{app}{$h}{count}) .
				   "</td><td>" . &convert_time($session_info{app}{$h}{duration}) . "</td><td>" .
				   &convert_time($session_info{app}{$h}{duration} / $session_info{app}{$h}{count}) .
				   "</td></tr>";
		$total_count += $session_info{app}{$h}{count};
		if ($main_app[1] < $session_info{app}{$h}{count}) {
			$main_app[0] = $h;
			$main_app[1] = $session_info{app}{$h}{count};
		}
	}
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$session_info{app}}) {
			if ((($session_info{app}{$d}{count} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $session_info{app}{$d}{count} || 0;
			} else {
				$infos{"Sum sessions < $pie_percentage_limit%"} += $session_info{app}{$d}{count} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum sessions < $pie_percentage_limit%"};
			delete $infos{"Sum sessions < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{appsessions_graph} = &flotr2_piegraph($graphid++, 'graph_appsessions', 'Connections per application', %infos);
	$sess_app_info = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$total_count);
	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<div class="analysis-item row-fluid" id="sessions-per-app">
		<h2><i class="icon-sitemap"></i> Sessions per application</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_app[0]</span> <span class="figure-label">Main Host</span></li>
					<li><span class="figure">$total_count sessions</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#sessions-per-app-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#sessions-per-app-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="sessions-per-app-graph">
						$drawn_graphs{appsessions_graph}
					</div>
					<div class="tab-pane" id="sessions-per-app-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Application</th>
									<th>Count</th>
									<th>Total Duration</th>
									<th>Average Duration</th>
								</tr>
							</thead>
							<tbody>
							$sess_app_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of sessions per app -->
};

	delete $drawn_graphs{appsessions_graph};
}


sub print_database_session
{
	my %infos = ();
	my $total_count = 0;
	my $sess_database_info = '';
	my @main_database = ('unknown',0);
	foreach my $d (sort keys %{$session_info{database}}) {
		$sess_database_info .=  "<tr><td>$d</td><td>" . &comma_numbers($session_info{database}{$d}{count}) .
					"</td><td>" . &convert_time($session_info{database}{$d}{duration}) . "</td><td>" .
					&convert_time($session_info{database}{$d}{duration} / $session_info{database}{$d}{count}) .
					"</td></tr>";
		$total_count += $session_info{database}{$d}{count};
		if ($main_database[1] < $session_info{database}{$d}{count}) {
			$main_database[0] = $d;
			$main_database[1] = $session_info{database}{$d}{count};
		}
	}
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$session_info{database}}) {
			if ((($session_info{database}{$d}{count} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $session_info{database}{$d}{count} || 0;
			} else {
				$infos{"Sum sessions < $pie_percentage_limit%"} += $session_info{database}{$d}{count} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum sessions < $pie_percentage_limit%"};
			delete $infos{"Sum sessions < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{databasesessions_graph} = &flotr2_piegraph($graphid++, 'graph_databasesessions', 'Connections per database', %infos);
	$sess_database_info = qq{<tr><td colspan="5">$NODATA</td></tr>} if (!$total_count);

	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<div class="analysis-item row-fluid" id="sessions-per-database">
		<h2><i class="icon-list-alt"></i> Sessions per database</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_database[0]</span> <span class="figure-label">Main Database</span></li>
					<li><span class="figure">$total_count sessions</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#sessions-per-database-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#sessions-per-database-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="sessions-per-database-graph">
						$drawn_graphs{databasesessions_graph}
					</div>
					<div class="tab-pane" id="sessions-per-database-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Database</th>
									<th>User</th>
									<th>Count</th>
									<th>Total Duration</th>
									<th>Average Duration</th>
								</tr>
							</thead>
							<tbody>
							$sess_database_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of sessions per database -->
};
	delete $drawn_graphs{databasesessions_graph};
}

sub print_checkpoint
{

	# checkpoint
	my %graph_data = ();
	if ($graph) {
		foreach my $tm (sort {$a <=> $b} keys %per_minute_info) {
			$tm =~ /(\d{4})(\d{2})(\d{2})/;
			my $y  = $1 - 1900;
			my $mo = $2 - 1;
			my $d  = $3;
			foreach my $h ("00" .. "23") {
				next if (!exists $per_minute_info{$tm}{$h});
				my %chk_dataavg = ();
				my %t_dataavg = ();
				my %v_dataavg = ();
				foreach my $m ("00" .. "59") {
					next if (!exists $per_minute_info{$tm}{$h}{$m});

					my $rd = &average_per_minutes($m, $avg_minutes);

					if ($checkpoint_info{wbuffer}) {
						$chk_dataavg{wbuffer}{"$rd"} = 0 if (!exists $chk_dataavg{wbuffer}{"$rd"});
						$chk_dataavg{file_added}{"$rd"} = 0 if (!exists $chk_dataavg{file_added}{"$rd"});
						$chk_dataavg{file_removed}{"$rd"} = 0 if (!exists $chk_dataavg{file_removed}{"$rd"});
						$chk_dataavg{file_recycled}{"$rd"} = 0 if (!exists $chk_dataavg{file_recycled}{"$rd"});
						if (exists $per_minute_info{$tm}{$h}{$m}{checkpoint}) {
							$chk_dataavg{wbuffer}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{checkpoint}{wbuffer} || 0);
							$chk_dataavg{file_added}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{checkpoint}{file_added} || 0);
							$chk_dataavg{file_removed}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{checkpoint}{file_removed}  || 0);
							$chk_dataavg{file_recycled}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{checkpoint}{file_recycled} || 0);
						}
					}
				}

				foreach my $rd (@avgs) {
					my $t = timegm_nocheck(0, $rd, $h, $d, $mo, $y) * 1000;

					next if ($t < $t_min);
					last if ($t > $t_max);

					# Average of written checkpoint buffers and wal files
					if (exists $chk_dataavg{wbuffer}) {
						$graph_data{wbuffer} .= "[$t, " . ($chk_dataavg{wbuffer}{"$rd"} || 0) . "],";
						$graph_data{file_added} .= "[$t, " . ($chk_dataavg{file_added}{"$rd"} || 0) . "],";
						$graph_data{file_removed} .= "[$t, " . ($chk_dataavg{file_removed}{"$rd"} || 0) . "],";
						$graph_data{file_recycled} .= "[$t, " . ($chk_dataavg{file_recycled}{"$rd"} || 0) . "],";
					}
				}
			}
		}
		foreach (keys %graph_data) {
			$graph_data{$_} =~ s/,$//;
		}
	}
	# Checkpoint buffers and files
	$drawn_graphs{checkpointwritebuffers_graph} = 
		&flotr2_graph($graphid++, 'checkpointwritebuffers_graph', $graph_data{wbuffer}, '', '',
				'Checkpoint write buffers (' . $avg_minutes . ' minutes period)',
				'Buffers', 'Write buffers', '',  ''
		);
	$drawn_graphs{checkpointfiles_graph} =
		&flotr2_graph($graphid++, 'checkpointfiles_graph', $graph_data{file_added},
			$graph_data{file_removed}, $graph_data{file_recycled}, 'Checkpoint Wal files usage (' . $avg_minutes . ' minutes period)',
			'Number of files', 'Added', 'Removed', 'Recycled'
		);

	my $checkpoint_wbuffer_peak = 0;
	my $checkpoint_wbuffer_peak_date = '';
	foreach (sort {$overall_checkpoint{'peak'}{$b}{checkpoint_wbuffer} <=> $overall_checkpoint{'peak'}{$a}{checkpoint_wbuffer}} keys %{$overall_checkpoint{'peak'}}) {
		$checkpoint_wbuffer_peak = &comma_numbers($overall_checkpoint{'peak'}{$_}{checkpoint_wbuffer});
		$checkpoint_wbuffer_peak_date = $_;
		last;
	}
	my $walfile_usage_peak = 0;
	my $walfile_usage_peak_date = '';
	foreach (sort {$overall_checkpoint{'peak'}{$b}{walfile_usage} <=> $overall_checkpoint{'peak'}{$a}{walfile_usage}} keys %{$overall_checkpoint{'peak'}}) {
		$walfile_usage_peak = &comma_numbers($overall_checkpoint{'peak'}{$_}{walfile_usage});
		$walfile_usage_peak_date = $_;
		last;
	}

	print $fh qq{
	<h1 class="page-header"><i class="icon-pencil"></i> Checkpoints / Restartpoints</h1>

	<div id="checkpoints-buffers" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-paste"></i> Checkpoints Buffers</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$checkpoint_wbuffer_peak buffers</span> <span class="figure-label">Checkpoint Peak</span></li>
				<li><span class="figure">$checkpoint_wbuffer_peak_date</span> <span class="figure-label">Date</span></li>    
				<li><span class="figure">$overall_checkpoint{checkpoint_write} seconds</span> <span class="figure-label">Highest write time</span></li>
				<li><span class="figure">$overall_checkpoint{checkpoint_sync} seconds</span> <span class="figure-label">Sync time</span></li>
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Checkpoint write buffers ($avg_minutes minutes average)</h3>
$drawn_graphs{checkpointwritebuffers_graph}
		</div>
	</div><!-- end of Checkpoints Buffers -->
};
	delete $drawn_graphs{checkpointwritebuffers_graph};

	print $fh qq{
	<div id="checkpoints-files" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-file-alt"></i> Checkpoints Wal files</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$walfile_usage_peak files</span> <span class="figure-label">Wal files usage Peak</span></li>
				<li><span class="figure">$walfile_usage_peak_date</span> <span class="figure-label">Date</span></li>
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Checkpoint Wal files usage ($avg_minutes minutes average)</h3>
$drawn_graphs{checkpointfiles_graph}
		</div>
	</div><!-- end of Checkpoints Files -->
};
	delete $drawn_graphs{checkpointfiles_graph};

	my $buffers = '';
	my $files = '';
	my $warnings = '';
	foreach my $d (sort {$a <=> $b} keys %per_minute_info) {
		$d =~ /^\d{4}(\d{2})(\d{2})$/;
		my $zday = "$abbr_month{$1} $2";
		foreach my $h (sort {$a <=> $b} keys %{$per_minute_info{$d}}) {
			$buffers .= "<tr><td>$zday</td><td>$h</td>";
			$files .= "<tr><td>$zday</td><td>$h</td>";
			$warnings .= "<tr><td>$zday</td><td>$h</td>";
			$zday = '';
			my %cinf = ();
			my %rinf = ();
			my %cainf = ();
			my %rainf = ();
			foreach my $m (keys %{$per_minute_info{$d}{$h}}) {

				if (exists $per_minute_info{$d}{$h}{$m}{checkpoint}) {
					$cinf{wbuffer} += $per_minute_info{$d}{$h}{$m}{checkpoint}{wbuffer};
					$cinf{file_added} += $per_minute_info{$d}{$h}{$m}{checkpoint}{file_added};
					$cinf{file_removed} += $per_minute_info{$d}{$h}{$m}{checkpoint}{file_removed};
					$cinf{file_recycled} += $per_minute_info{$d}{$h}{$m}{checkpoint}{file_recycled};
					$cinf{write} += $per_minute_info{$d}{$h}{$m}{checkpoint}{write};
					$cinf{sync} += $per_minute_info{$d}{$h}{$m}{checkpoint}{sync};
					$cinf{total} += $per_minute_info{$d}{$h}{$m}{checkpoint}{total};
					$cainf{sync_files} += $per_minute_info{$d}{$h}{$m}{checkpoint}{sync_files};
					$cainf{sync_avg} += $per_minute_info{$d}{$h}{$m}{checkpoint}{sync_avg};
					$cainf{sync_longest} = $per_minute_info{$d}{$h}{$m}{checkpoint}{sync_longest}
						if ($per_minute_info{$d}{$h}{$m}{checkpoint}{sync_longest} > $cainf{sync_longest});
				}
				if (exists $per_minute_info{$d}{$h}{$m}{checkpoint}{warning}) {
					$cinf{warning} += $per_minute_info{$d}{$h}{$m}{checkpoint}{warning};
					$cinf{warning_seconds} += $per_minute_info{$d}{$h}{$m}{checkpoint}{warning_seconds};
				}
			}
			if (scalar keys %cinf) {
				$buffers .= "<td>" . &comma_numbers($cinf{wbuffer}) .
					"</td><td>" . &comma_numbers($cinf{write}) . 's' .
					"</td><td>" . &comma_numbers($cinf{sync}) . 's' .
					"</td><td>" . &comma_numbers($cinf{total}) . 's' .
					"</td></tr>";
				$files .= "<td>" . &comma_numbers($cinf{file_added}) .
					"</td><td>" . &comma_numbers($cinf{file_removed}) .
					"</td><td>" . &comma_numbers($cinf{file_recycled}) .
					"</td><td>" . &comma_numbers($cainf{sync_files}) .
					"</td><td>" . &comma_numbers($cainf{sync_longest}) . 's' .
					"</td><td>" . &comma_numbers($cainf{sync_avg}) . 's' .
					"</td></tr>";
			} else {
				$buffers .= "<td>0</td><td>0s</td><td>0s</td><td>0s</td></tr>";
				$files .= "<td>0</td><td>0</td><td>0</td><td>0</td><td>0s</td><td>0s</td></tr>";
			}
			if (exists $cinf{warning}) {
				$warnings .= "<td>" . &comma_numbers($cinf{warning}) . "</td><td>" .
					&comma_numbers(sprintf( "%.2f", ($cinf{warning_seconds} || 0) / ($cinf{warning} || 1))) .
					 "s</td></tr>";
			} else {
				$warnings .= "<td>0</td><td>0s</td></tr>";
			}
		}
	}

	$buffers = qq{<tr><td colspan="6">$NODATA</td></tr>} if (!$buffers);
	$files = qq{<tr><td colspan="8">$NODATA</td></tr>} if (!$files);
	$warnings = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$warnings);

	print $fh qq{
<div class="analysis-item row-fluid" id="checkpoint-activity">
	<h2 class=""><i class="icon-calendar"></i> Checkpoints Activity</h2>
	<div class="span11 tabbable tabs-left">
		<ul class="nav nav-tabs">
			<li class="active"><a href="#checkpoint-activity-buffers" data-toggle="tab">Checkpoints Buffers</a></li>
			<li><a href="#checkpoint-activity-files" data-toggle="tab">Checkpoints files</a></li>
			<li><a href="#checkpoint-activity-warnings" data-toggle="tab">Checkpoints Warnings</a></li>
		</ul>
		<div class="tab-content">
			<div class="active tab-pane" id="checkpoint-activity-buffers">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Written&nbsp;buffers</th>
							<th>Write&nbsp;time</th>
							<th>Sync&nbsp;time</th>
							<th>Total&nbsp;time</th>
						</tr>
					</thead>
					<tbody>$buffers
					</tbody>
				</table>							    				        
			</div>
			<div class="tab-pane" id="checkpoint-activity-files">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Added</th>
							<th>Removed</th>
							<th>Recycled</th>
							<th>Synced files</th>
							<th>Longest sync</th>
							<th>Average sync</th>
						</tr>
					</thead>
					<tbody>$files
					</tbody>
				</table>        				        
			</div>
			<div class="tab-pane" id="checkpoint-activity-warnings">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Count</th>
							<th>Avg time (sec)</th>
						</tr>
					</thead>
					<tbody>$warnings
					</tbody>
				</table>        
			</div>        
		</div> <!-- end of div tab-content -->
		<span class="pull-right">&uarr; <small><a href="#checkpoint-activity" class="">Back to the top of the <em>Checkpoint Activity</em> table</a></small></span>
	</div>

</div><!-- end of checkpoint activity -->
};

}

sub print_temporary_file
{

	# checkpoint
	my %graph_data = ();
	if ($graph) {
		foreach my $tm (sort {$a <=> $b} keys %per_minute_info) {
			$tm =~ /(\d{4})(\d{2})(\d{2})/;
			my $y  = $1 - 1900;
			my $mo = $2 - 1;
			my $d  = $3;
			foreach my $h ("00" .. "23") {
				next if (!exists $per_minute_info{$tm}{$h});
				my %chk_dataavg = ();
				my %t_dataavg = ();
				my %v_dataavg = ();
				foreach my $m ("00" .. "59") {
					next if (!exists $per_minute_info{$tm}{$h}{$m});
					my $rd = &average_per_minutes($m, $avg_minutes);
					if ($tempfile_info{count}) {
						$t_dataavg{size}{"$rd"} = 0 if (!exists $t_dataavg{size}{"$rd"});
						$t_dataavg{count}{"$rd"} = 0 if (!exists $t_dataavg{count}{"$rd"});
						if (exists $per_minute_info{$tm}{$h}{$m}{tempfile}) {
							$t_dataavg{size}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{tempfile}{size} || 0);
							$t_dataavg{count}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{tempfile}{count} || 0);
						}
					}
				}

				foreach my $rd (@avgs) {
					my $t = timegm_nocheck(0, $rd, $h, $d, $mo, $y) * 1000;

					next if ($t < $t_min);
					last if ($t > $t_max);

					if (exists $t_dataavg{size}) {
						$graph_data{size} .= "[$t, " . ($t_dataavg{size}{"$rd"} || 0) . "],";
						$graph_data{count} .= "[$t, " . ($t_dataavg{count}{"$rd"} || 0) . "],";
					}
				}
			}
		}
		foreach (keys %graph_data) {
			$graph_data{$_} =~ s/,$//;
		}
	}
	# Temporary file size
	$drawn_graphs{temporarydata_graph} =
		&flotr2_graph($graphid++, 'temporarydata_graph', $graph_data{size}, '', '',
			'Size of temporary files (' . $avg_minutes . ' minutes period)',
			'Size of files', 'Size of files'
		);
	# Temporary file number
	$drawn_graphs{temporaryfile_graph} =
		&flotr2_graph($graphid++, 'temporaryfile_graph', $graph_data{count}, '', '',
			'Number of temporary files (' . $avg_minutes . ' minutes period)',
			'Number of files', 'Number of files'
		);

	my $tempfile_size_peak = 0;
	my $tempfile_size_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{tempfile_size} <=> $overall_stat{'peak'}{$a}{tempfile_size}} keys %{$overall_stat{'peak'}}) {
		$tempfile_size_peak = &pretty_print_size($overall_stat{'peak'}{$_}{tempfile_size});
		$tempfile_size_peak_date = $_;
		last;
	}
	print $fh qq{
	<h1 class="page-header"><i class="icon-pencil"></i> Temporary Files</h1>

	<div id="tempfiles-size" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-resize-full"></i> Size of temporary files</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$tempfile_size_peak</span> <span class="figure-label">Temp Files Peak</span></li>
				<li><span class="figure">$tempfile_size_peak_date</span> <span class="figure-label">Date</span></li>
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Size of temporary files ($avg_minutes minutes average)</h3>
$drawn_graphs{temporarydata_graph}
		</div>
	</div><!-- end of Size of temporary files -->
};
	delete $drawn_graphs{temporarydata_graph};

	my $tempfile_count_peak = 0;
	my $tempfile_count_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{tempfile_count} <=> $overall_stat{'peak'}{$a}{tempfile_count}} keys %{$overall_stat{'peak'}}) {
		$tempfile_count_peak = &comma_numbers($overall_stat{'peak'}{$_}{tempfile_count});
		$tempfile_count_peak_date = $_;
		last;
	}
	print $fh qq{
	<div id="tempfiles-number" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-th"></i> Number of temporary files</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$tempfile_count_peak per second</span> <span class="figure-label">Temp Files Peak</span></li>
				<li><span class="figure">$tempfile_count_peak_date</span> <span class="figure-label">Date</span></li>
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Number of temporary files ($avg_minutes minutes average)</h3>
$drawn_graphs{temporaryfile_graph}
		</div>
	</div><!-- end of Number of temporary files -->
};
	delete $drawn_graphs{temporaryfile_graph};

	my $tempfiles_activity = '';
	foreach my $d (sort {$a <=> $b} keys %per_minute_info) {
		$d =~ /^\d{4}(\d{2})(\d{2})$/;
		my $zday = "$abbr_month{$1} $2";
		foreach my $h (sort {$a <=> $b} keys %{$per_minute_info{$d}}) {
			$tempfiles_activity .= "<tr><td>$zday</td><td>$h</td>";
			$zday = "";
			my %tinf = ();
			foreach my $m (keys %{$per_minute_info{$d}{$h}}) {
				if (exists $per_minute_info{$d}{$h}{$m}{tempfile}) {
					$tinf{size} += $per_minute_info{$d}{$h}{$m}{tempfile}{size};
					$tinf{count} += $per_minute_info{$d}{$h}{$m}{tempfile}{count};
				}
			}
			if (scalar keys %tinf) {
				my $temp_average = &pretty_print_size(sprintf("%.2f", $tinf{size} / $tinf{count}));
				$tempfiles_activity .=  "<td>" . &comma_numbers($tinf{count}) .
							"</td><td>$temp_average</td>";
			} else {
				$tempfiles_activity .= "<td>0</td><td>0</td>";
			}
		}
	}

	$tempfiles_activity = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$tempfiles_activity);

	print $fh qq{
<div class="analysis-item row-fluid" id="tempfiles-activity">
	<h2 class=""><i class="icon-calendar"></i> Temporary Files Activity</h2>
	<div class="span11 tabbable tabs-left">
		<ul class="nav nav-tabs">
			<li class="active"><a href="#tempfiles-activity-count" data-toggle="tab">Temp Files</a></li>
		</ul>
		<div class="tab-content">
			<div class="active tab-pane" id="tempfiles-activity-count">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>Count</th>
							<th>Average size</th>
						</tr>
					</thead>
					<tbody>$tempfiles_activity
					</tbody>
				</table>
			</div>
		</div> <!-- end of div tab-content -->
		<span class="pull-right">&uarr; <small><a href="#tempfiles-activity" class="">Back to the top of the <em>Temporay Files Activity</em> table</a></small></span>
	</div>

</div><!-- end of tempfile activity -->
};

}

sub print_cancelled_queries
{

	# checkpoint
	my %graph_data = ();
	if ($graph) {

		foreach my $tm (sort {$a <=> $b} keys %per_minute_info) {

			$tm =~ /(\d{4})(\d{2})(\d{2})/;
			my $y  = $1 - 1900;
			my $mo = $2 - 1;
			my $d  = $3;
			foreach my $h ("00" .. "23") {
				next if (!exists $per_minute_info{$tm}{$h});
				my %chk_dataavg = ();
				my %t_dataavg = ();
				my %v_dataavg = ();
				foreach my $m ("00" .. "59") {
					next if (!exists $per_minute_info{$tm}{$h}{$m});
					my $rd = &average_per_minutes($m, $avg_minutes);
					if ($cancelled_info{count}) {
						$t_dataavg{count}{"$rd"} = 0 if (!exists $t_dataavg{count}{"$rd"});
						if (exists $per_minute_info{$tm}{$h}{$m}{cancelled}) {
							$t_dataavg{count}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{cancelled}{count} || 0);
						}
					}
				}

				foreach my $rd (@avgs) {
					my $t = timegm_nocheck(0, $rd, $h, $d, $mo, $y) * 1000;

					next if ($t < $t_min);
					last if ($t > $t_max);

					if (exists $t_dataavg{count}) {
						$graph_data{count} .= "[$t, " . ($t_dataavg{count}{"$rd"} || 0) . "],";
					}
				}
			}
		}
		foreach (keys %graph_data) {
			$graph_data{$_} =~ s/,$//;
		}
	}
	# Number of cancelled queries graph
	$drawn_graphs{cancelledqueries_graph} =
		&flotr2_graph($graphid++, 'cancelledqueries_graph', $graph_data{count}, '', '',
			'Number of cancelled queries (' . $avg_minutes . ' minutes period)',
			'Number of cancellation', 'Number of cancellation'
		);

	my $cancelled_count_peak = 0;
	my $cancelled_count_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{cancelled_count} <=> $overall_stat{'peak'}{$a}{cancelled_count}} keys %{$overall_stat{'peak'}}) {
		$cancelled_count_peak = &comma_numbers($overall_stat{'peak'}{$_}{cancelled_count});
		$cancelled_count_peak_date = $_;
		last;
	}
	print $fh qq{
	<div id="queries-cancelled-number" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-th"></i> Number of cancelled queries</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$cancelled_count_peak per second</span> <span class="figure-label">Cancelled query Peak</span></li>
				<li><span class="figure">$cancelled_count_peak_date</span> <span class="figure-label">Date</span></li>
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Number of cancelled queries ($avg_minutes minutes average)</h3>
$drawn_graphs{cancelledqueries_graph}
		</div>
	</div><!-- end of Number of cancelled queries -->
};
	delete $drawn_graphs{cancelledqueries_graph};
}

sub print_analyze_per_table
{
	# ANALYZE stats per table
	my %infos = ();
	my $total_count   = 0;
	my $analyze_info = '';
	my @main_analyze = ('unknown',0);
	foreach my $t (sort {$autoanalyze_info{tables}{$b}{analyzes} <=> $autoanalyze_info{tables}{$a}{analyzes}} keys %{$autoanalyze_info{tables}}) {
		$analyze_info .= "<tr><td>$t</td><td>" . $autoanalyze_info{tables}{$t}{analyzes} .
			"</td></tr>";
		$total_count += $autoanalyze_info{tables}{$t}{analyzes};
		if ($main_analyze[1] < $autoanalyze_info{tables}{$t}{analyzes}) {
			$main_analyze[0] = $t;
			$main_analyze[1] = $autoanalyze_info{tables}{$t}{analyzes};
		}
	}
	$analyze_info .= "<tr><th>Total</th><td>" . &comma_numbers($total_count) . "</td></tr>";

	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %{$autoanalyze_info{tables}}) {
			if ((($autoanalyze_info{tables}{$d}{analyzes} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$infos{$d} = $autoanalyze_info{tables}{$d}{analyzes} || 0;
			} else {
				$infos{"Sum analyzes < $pie_percentage_limit%"} += $autoanalyze_info{tables}{$d}{analyzes} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum analyzes < $pie_percentage_limit%"};
			delete $infos{"Sum analyzes < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{tableanalyzes_graph} = &flotr2_piegraph($graphid++, 'graph_tableanalyzes', 'Analyzes per tables', %infos);
	$total_count = &comma_numbers($total_count);
	my $database = '';
	if ($main_analyze[0] =~ s/^([^\.]+)\.//) {
		$database = $1;
	}

	$analyze_info = qq{<tr><td colspan="2">$NODATA</td></tr>} if (!$total_count);

	print $fh qq{
	<div class="analysis-item row-fluid" id="analyzes-per-table">
		<h2><i class="icon-table"></i> Analyses per table</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_analyze[0] ($main_analyze[1])</span> <span class="figure-label">Main table analyzed (database $database)</span></li>
					<li><span class="figure">$total_count analyzes</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#analyzes-per-table-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#analyzes-per-table-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="analyzes-per-table-graph">
						$drawn_graphs{tableanalyzes_graph}
					</div>
					<div class="tab-pane" id="analyzes-per-table-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Table</th>
									<th>Number of analyzes</th>
								</tr>
							</thead>
							<tbody>
							$analyze_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of analyzes per table -->
};
	delete $drawn_graphs{tableanalyzes_graph};

}

sub print_vacuum
{

	# checkpoint
	my %graph_data = ();
	foreach my $tm (sort {$a <=> $b} keys %per_minute_info) {
		$tm =~ /(\d{4})(\d{2})(\d{2})/;
		my $y  = $1 - 1900;
		my $mo = $2 - 1;
		my $d  = $3;
		foreach my $h ("00" .. "23") {
			next if (!exists $per_minute_info{$tm}{$h});
			my %chk_dataavg = ();
			my %t_dataavg = ();
			my %v_dataavg = ();
			foreach my $m ("00" .. "59") {
				next if (!exists $per_minute_info{$tm}{$h}{$m});

				my $rd = &average_per_minutes($m, $avg_minutes);
				$v_dataavg{acount}{"$rd"} = 0 if (!exists $v_dataavg{acount}{"$rd"});
				$v_dataavg{vcount}{"$rd"} = 0 if (!exists $v_dataavg{vcount}{"$rd"});

				if (exists $per_minute_info{$tm}{$h}{$m}{autovacuum}) {
					$v_dataavg{vcount}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{autovacuum}{count} || 0);
				}
				if (exists $per_minute_info{$tm}{$h}{$m}{autoanalyze}) {
					$v_dataavg{acount}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{autoanalyze}{count} || 0);
				}
			}

			foreach my $rd (@avgs) {
				my $t = timegm_nocheck(0, $rd, $h, $d, $mo, $y) * 1000;

				next if ($t < $t_min);
				last if ($t > $t_max);

				if (exists $v_dataavg{vcount}) {
					$graph_data{vcount} .= "[$t, " . ($v_dataavg{vcount}{"$rd"} || 0) . "],";
				}
				if (exists $v_dataavg{acount}) {
					$graph_data{acount} .= "[$t, " . ($v_dataavg{acount}{"$rd"} || 0) . "],";
				}

			}
		}
	}
	foreach (keys %graph_data) {
		$graph_data{$_} =~ s/,$//;
	}

	# VACUUMs vs ANALYZEs chart
	$drawn_graphs{autovacuum_graph} =
		&flotr2_graph($graphid++, 'autovacuum_graph', $graph_data{vcount}, $graph_data{acount},
		'', 'Autovacuum actions (' . $avg_minutes . ' minutes period)', '', 'VACUUMs', 'ANALYZEs'
		);

	my $vacuum_size_peak = 0;
	my $vacuum_size_peak_date = '';
	foreach (sort {$overall_stat{'peak'}{$b}{vacuum_size} <=> $overall_stat{'peak'}{$a}{vacuum_size}} keys %{$overall_stat{'peak'}}) {
		$vacuum_size_peak = &comma_numbers($overall_stat{'peak'}{$_}{vacuum_size});
		$vacuum_size_peak_date = $_;
		last;
	}
	my $autovacuum_peak_system_usage_db = '';
	if ($autovacuum_info{peak}{system_usage}{table} =~ s/^([^\.]+)\.//) {
		$autovacuum_peak_system_usage_db = $1;
	}
	my $autoanalyze_peak_system_usage_db = '';
	if ($autoanalyze_info{peak}{system_usage}{table} =~ s/^([^\.]+)\.//) {
		$autoanalyze_peak_system_usage_db = $1;
	}
	$autovacuum_info{peak}{system_usage}{elapsed} ||= 0;
	$autoanalyze_info{peak}{system_usage}{elapsed} ||= 0;
	print $fh qq{
	<h1 class="page-header"><i class="icon-cogs"></i> Vacuums</h1>

	<div id="vacuums-count" class="analysis-item row-fluid">
	<h2 class=""><i class="icon-pencil"></i> Vacuums / Analyzes Distribution</h2>
	<div class="span3">
		<h3 class="">Key values</h3>
		<div class="well key-figures">
			<ul>
				<li><span class="figure">$autovacuum_info{peak}{system_usage}{elapsed} sec</span> <span class="figure-label">Highest CPU-cost vacuum <br />Table $autovacuum_info{peak}{system_usage}{table} <br />Database $autovacuum_peak_system_usage_db</span></li>
				<li><span class="figure">$autovacuum_info{peak}{system_usage}{date}</span> <span class="figure-label">Date</span></li>
				<li><span class="figure">$autoanalyze_info{peak}{system_usage}{elapsed} sec</span> <span class="figure-label">Highest CPU-cost analyze <br />Table $autoanalyze_info{peak}{system_usage}{table} <br />Database $autovacuum_peak_system_usage_db</span></li>
				<li><span class="figure">$autoanalyze_info{peak}{system_usage}{date}</span> <span class="figure-label">Date</span></li>
			</ul>
		</div>
	</div>
	<div class="span8">
		<h3 class="">Autovacuum actions ($avg_minutes minutes average)</h3>
$drawn_graphs{autovacuum_graph}
		</div>
	</div><!-- end of Autovacuum actions -->
};
	delete $drawn_graphs{autovacuum_graph};

	# ANALYZE stats per table
	&print_analyze_per_table();

	# VACUUM stats per table
	&print_vacuum_per_table();

	# Show tuples and pages removed per table
	&print_vacuum_tuple_removed;
	&print_vacuum_page_removed;

	my $vacuum_activity = '';
	foreach my $d (sort {$a <=> $b} keys %per_minute_info) {
		my $c = 1;
		$d =~ /^\d{4}(\d{2})(\d{2})$/;
		my $zday = "$abbr_month{$1} $2";
		foreach my $h (sort {$a <=> $b} keys %{$per_minute_info{$d}}) {
			$vacuum_activity .= "<tr><td>$zday</td><td>$h</td>";
			$zday = "";
			my %ainf = ();
			foreach my $m (keys %{$per_minute_info{$d}{$h}}) {

				if (exists $per_minute_info{$d}{$h}{$m}{autovacuum}{count}) {
					$ainf{vcount} += $per_minute_info{$d}{$h}{$m}{autovacuum}{count};
				}
				if (exists $per_minute_info{$d}{$h}{$m}{autoanalyze}{count}) {
					$ainf{acount} += $per_minute_info{$d}{$h}{$m}{autoanalyze}{count};
				}

			}
			if (scalar keys %ainf) {
				$vacuum_activity .= "<td>" . &comma_numbers($ainf{vcount}) . "</td>";
			} else {
				$vacuum_activity .= "<td>0</td>";
			}
			if (scalar keys %ainf) {
				$vacuum_activity .= "<td>" . &comma_numbers($ainf{acount}) . "</td>";
			} else {
				$vacuum_activity .= "<td>0</td>";
			}
		}
	}

	$vacuum_activity = qq{<tr><td colspan="4">$NODATA</td></tr>} if (!$vacuum_activity);

	print $fh qq{
<div class="analysis-item row-fluid" id="vacuums-activity">
	<h2 class=""><i class="icon-calendar"></i> Autovacuum Activity</h2>
	<div class="span11 tabbable tabs-left">
		<ul class="nav nav-tabs">
			<li class="active"><a href="#vacuums-activity-count" data-toggle="tab">Vacuums / Analyzes</a></li>
		</ul>
		<div class="tab-content">
			<div class="active tab-pane" id="vacuums-activity-count">
				<table class="table table-striped table-hover table-condensed">
					<thead>
						<tr>
							<th>Day</th>
							<th>Hour</th>
							<th>VACUUMs</th>
							<th>ANALYZEs</th>
						</tr>
					</thead>
					<tbody>$vacuum_activity
					</tbody>
				</table>
			</div>
		</div> <!-- end of div tab-content -->
		<span class="pull-right">&uarr; <small><a href="#vacuums-activity" class="">Back to the top of the <em>Temporay Files Activity</em> table</a></small></span>
	</div>

</div><!-- end of vacuum activity -->
};

}

sub print_vacuum_per_table
{
	# VACUUM stats per table
	my $total_count   = 0;
	my $total_idxscan = 0;
	my $vacuum_info   = '';
	my @main_vacuum   = ('unknown',0);
	foreach my $t (sort {$autovacuum_info{tables}{$b}{vacuums} <=> $autovacuum_info{tables}{$a}{vacuums}} keys %{$autovacuum_info{tables}}) {
		$vacuum_info .= "<tr><td>$t</td><td>" . $autovacuum_info{tables}{$t}{vacuums} .
			"</td><td>" . $autovacuum_info{tables}{$t}{idxscans} .
			"</td></tr>";
		$total_count += $autovacuum_info{tables}{$t}{vacuums};
		$total_idxscan += $autovacuum_info{tables}{$t}{idxscans};
		if ($main_vacuum[1] < $autovacuum_info{tables}{$t}{vacuums}) {
			$main_vacuum[0] = $t;
			$main_vacuum[1] = $autovacuum_info{tables}{$t}{vacuums};
		}
	}
	$vacuum_info .= "<tr><th>Total</th><td>" . &comma_numbers($total_count) . "</td><td>" . &comma_numbers($total_idxscan) . "</td></tr>";

	my %infos = ();
	my @small = ();
	foreach my $d (sort keys %{$autovacuum_info{tables}}) {
		if ((($autovacuum_info{tables}{$d}{vacuums} * 100) / ($total_count||1)) > $pie_percentage_limit) {
			$infos{$d} = $autovacuum_info{tables}{$d}{vacuums} || 0;
		} else {
			$infos{"Sum vacuums < $pie_percentage_limit%"} += $autovacuum_info{tables}{$d}{vacuums} || 0;
			push(@small, $d);
		}
	}
	if ($#small == 0) {
		$infos{$small[0]} = $infos{"Sum vacuums < $pie_percentage_limit%"};
		delete $infos{"Sum vacuums < $pie_percentage_limit%"};
	}
	$drawn_graphs{tablevacuums_graph} = &flotr2_piegraph($graphid++, 'graph_tablevacuums', 'Analyzes per tables', %infos);
	$vacuum_info = qq{<tr><td colspan="3">$NODATA</td></tr>} if (!$total_count);
	$total_count = &comma_numbers($total_count);
	my $database = '';
	if ($main_vacuum[0] =~ s/^([^\.]+)\.//) {
		$database = $1;
	}
	print $fh qq{
	<div class="analysis-item row-fluid" id="vacuums-per-table">
		<h2><i class="icon-table"></i> Vacuums per table</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_vacuum[0] ($main_vacuum[1])</span> <span class="figure-label">Main table vacuumed on database $database</span></li>
					<li><span class="figure">$total_count vacuums</span> <span class="figure-label">Total</span></li>    
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#vacuums-per-table-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#vacuums-per-table-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="vacuums-per-table-graph">
						$drawn_graphs{tablevacuums_graph}
					</div>
					<div class="tab-pane" id="vacuums-per-table-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Table</th>
									<th>Number of vacuums</th>
									<th>Index scans</th>
								</tr>
							</thead>
							<tbody>
							$vacuum_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of vacuums per table -->
};
	delete $drawn_graphs{tablevacuums_graph};

}

sub print_vacuum_tuple_removed
{
	# VACUUM stats per table
	my $total_count   = 0;
	my $total_idxscan = 0;
	my $total_tuple = 0;
	my $total_page = 0;
	my $vacuum_info   = '';
	my @main_tuple   = ('unknown',0);
	foreach my $t (sort {$autovacuum_info{tables}{$b}{tuples}{removed} <=> $autovacuum_info{tables}{$a}{tuples}{removed}} keys %{$autovacuum_info{tables}}) {
		$vacuum_info .= "<tr><td>$t</td><td>" . $autovacuum_info{tables}{$t}{vacuums} .
			"</td><td>" . $autovacuum_info{tables}{$t}{idxscans} .
			"</td><td>" . $autovacuum_info{tables}{$t}{tuples}{removed} .
			"</td><td>" . $autovacuum_info{tables}{$t}{pages}{removed} .
			"</td></tr>";
		$total_count += $autovacuum_info{tables}{$t}{vacuums};
		$total_idxscan += $autovacuum_info{tables}{$t}{idxscans};
		$total_tuple += $autovacuum_info{tables}{$t}{tuples}{removed};
		$total_page += $autovacuum_info{tables}{$t}{pages}{removed};
		if ($main_tuple[1] < $autovacuum_info{tables}{$t}{tuples}{removed}) {
			$main_tuple[0] = $t;
			$main_tuple[1] = $autovacuum_info{tables}{$t}{tuples}{removed};
		}
	}
	$vacuum_info .= "<tr><th>Total</th><td>" . &comma_numbers($total_count) . "</td><td>" . &comma_numbers($total_idxscan) .
			"</td><td>" . &comma_numbers($total_tuple) . "</td><td>" . &comma_numbers($total_page) . "</td></tr>";

	my %infos_tuple = ();
	my @small = ();
	foreach my $d (sort keys %{$autovacuum_info{tables}}) {
		if ((($autovacuum_info{tables}{$d}{tuples}{removed} * 100) / ($total_tuple||1)) > $pie_percentage_limit) {
			$infos_tuple{$d} = $autovacuum_info{tables}{$d}{tuples}{removed} || 0;
		} else {
			$infos_tuple{"Sum tuples removed < $pie_percentage_limit%"} += $autovacuum_info{tables}{$d}{tuples}{removed} || 0;
			push(@small, $d);
		}
	}
	if ($#small == 0) {
		$infos_tuple{$small[0]} = $infos_tuple{"Sum tuples removed < $pie_percentage_limit%"};
		delete $infos_tuple{"Sum tuples removed < $pie_percentage_limit%"};
	}
	$drawn_graphs{tuplevacuums_graph} = &flotr2_piegraph($graphid++, 'graph_tuplevacuums', 'Tuples removed per tables', %infos_tuple);
	$vacuum_info = qq{<tr><td colspan="5">$NODATA</td></tr>} if (!$total_count);
	$total_count = &comma_numbers($total_count);
	my $database = '';
	if ($main_tuple[0] =~ s/^([^\.]+)\.//) {
		$database = $1;
	}
	print $fh qq{
	<div class="analysis-item row-fluid" id="tuples-removed-per-table">
		<h2><i class="icon-table"></i> Tuples removed per table</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_tuple[0] ($main_tuple[1])</span> <span class="figure-label">Main table with removed tuples on database $database</span></li>
					<li><span class="figure">$total_tuple tuples</span> <span class="figure-label">Total removed</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#tuples-removed-per-table-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#tuples-removed-per-table-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="tuples-removed-per-table-graph">
						$drawn_graphs{tuplevacuums_graph}
					</div>
					<div class="tab-pane" id="tuples-removed-per-table-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Table</th>
									<th>Number of vacuums</th>
									<th>Index scans</th>
									<th>Tuples removed</th>
									<th>Pages removed</th>
								</tr>
							</thead>
							<tbody>
							$vacuum_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of tuples removed per table -->
};
	delete $drawn_graphs{tuplevacuums_graph};

}

sub print_vacuum_page_removed
{
	# VACUUM stats per table
	my $total_count   = 0;
	my $total_idxscan = 0;
	my $total_tuple = 0;
	my $total_page = 0;
	my $vacuum_info   = '';
	my @main_tuple   = ('unknown',0);
	my @main_page   = ('unknown',0);
	foreach my $t (sort {$autovacuum_info{tables}{$b}{pages}{removed} <=> $autovacuum_info{tables}{$a}{pages}{removed}} keys %{$autovacuum_info{tables}}) {
		$vacuum_info .= "<tr><td>$t</td><td>" . $autovacuum_info{tables}{$t}{vacuums} .
			"</td><td>" . $autovacuum_info{tables}{$t}{idxscans} .
			"</td><td>" . $autovacuum_info{tables}{$t}{tuples}{removed} .
			"</td><td>" . $autovacuum_info{tables}{$t}{pages}{removed} .
			"</td></tr>";
		$total_count += $autovacuum_info{tables}{$t}{vacuums};
		$total_idxscan += $autovacuum_info{tables}{$t}{idxscans};
		$total_tuple += $autovacuum_info{tables}{$t}{tuples}{removed};
		$total_page += $autovacuum_info{tables}{$t}{pages}{removed};
		if ($main_page[1] < $autovacuum_info{tables}{$t}{pages}{removed}) {
			$main_page[0] = $t;
			$main_page[1] = $autovacuum_info{tables}{$t}{pages}{removed};
		}
	}
	$vacuum_info .= "<tr><th>Total</th><td>" . &comma_numbers($total_count) . "</td><td>" . &comma_numbers($total_idxscan) .
			"</td><td>" . &comma_numbers($total_tuple) . "</td><td>" . &comma_numbers($total_page) . "</td></tr>";

	my %infos_page = ();
	my @small = ();
	foreach my $d (sort keys %{$autovacuum_info{tables}}) {
		if ((($autovacuum_info{tables}{$d}{pages}{removed} * 100) / ($total_page || 1)) > $pie_percentage_limit) {
			$infos_page{$d} = $autovacuum_info{tables}{$d}{pages}{removed} || 0;
		} else {
			$infos_page{"Sum pages removed < $pie_percentage_limit%"} += $autovacuum_info{tables}{$d}{pages}{removed} || 0;
			push(@small, $d);
		}
	}
	if ($#small == 0) {
		$infos_page{$small[0]} = $infos_page{"Sum pages removed < $pie_percentage_limit%"};
		delete $infos_page{"Sum pages removed < $pie_percentage_limit%"};
	}
	$drawn_graphs{pagevacuums_graph} = &flotr2_piegraph($graphid++, 'graph_pagevacuums', 'Tuples removed per tables', %infos_page);
	$vacuum_info = qq{<tr><td colspan="5">$NODATA</td></tr>} if (!$total_count);
	$total_count = &comma_numbers($total_count);
	my $database = '';
	if ($main_page[0] =~ s/^([^\.]+)\.//) {
		$database = $1;
	}
	print $fh qq{
	<div class="analysis-item row-fluid" id="pages-removed-per-table">
		<h2><i class="icon-table"></i> Pages removed per table</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_page[0] ($main_page[1])</span> <span class="figure-label">Main table with removed pages on database $database</span></li>
					<li><span class="figure">$total_page pages</span> <span class="figure-label">Total removed</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#pages-removed-per-table-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#pages-removed-per-table-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="pages-removed-per-table-graph">
						$drawn_graphs{pagevacuums_graph}
					</div>
					<div class="tab-pane" id="pages-removed-per-table-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Table</th>
									<th>Number of vacuums</th>
									<th>Index scans</th>
									<th>Tuples removed</th>
									<th>Pages removed</th>
								</tr>
							</thead>
							<tbody>
							$vacuum_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of pages removed per table -->
};
	delete $drawn_graphs{pagevacuums_graph};

}

sub print_lock_type
{
	my %locktype = ();
	my $total_count = 0;
	my $total_duration = 0;
	my $locktype_info = '';
	my @main_locktype = ('unknown',0);
	foreach my $t (sort keys %lock_info) {
		$locktype_info .= "<tr><td>$t</td><td></td><td>" . &comma_numbers($lock_info{$t}{count}) .
				  "</td><td>" . &convert_time($lock_info{$t}{duration}) . "</td><td>" .
				  &convert_time($lock_info{$t}{duration} / ($lock_info{$t}{count} || 1)) . "</td></tr>";
		$total_count += $lock_info{$t}{count};
		$total_duration += $lock_info{$t}{duration};
		if ($main_locktype[1] < $lock_info{$t}{count}) {
			$main_locktype[0] = $t;
			$main_locktype[1] = $lock_info{$t}{count};
		}
		foreach my $o (sort keys %{$lock_info{$t}}) {
			next if (($o eq 'count') || ($o eq 'duration') || ($o eq 'chronos'));
			$locktype_info .= "<tr><td></td><td>$o</td><td>" . &comma_numbers($lock_info{$t}{$o}{count}) .
					  "</td><td>" . &convert_time($lock_info{$t}{$o}{duration}) . "</td><td>" .
					  &convert_time($lock_info{$t}{$o}{duration} / $lock_info{$t}{$o}{count}) .
					  "</td></tr>\n";
		}
	}
	if ($total_count > 0) {
		$locktype_info .= "<tr><td></td><th>Total</th><td>" . &comma_numbers($total_count) .
				  "</td><td>" . &convert_time($total_duration) . "</td><td>" .
				  &convert_time($total_duration / ($total_count || 1)) . "</td></tr>";
	} else {
		$locktype_info = qq{<tr><td colspan="5">$NODATA</td></tr>};
	}
	if ($graph) {
		my @small    = ();
		foreach my $d (sort keys %lock_info) {
			if ((($lock_info{$d}{count} * 100) / ($total_count||1)) > $pie_percentage_limit) {
				$locktype{$d} = $lock_info{$d}{count} || 0;
			} else {
				$locktype{"Sum lock types < $pie_percentage_limit%"} += $lock_info{$d}{count} || 0;
				push(@small, $d);

			}
		}
		if ($#small == 0) {
			$locktype{$small[0]} = $locktype{"Sum types < $pie_percentage_limit%"};
			delete $locktype{"Sum lock types < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{lockbytype_graph} = &flotr2_piegraph($graphid++, 'graph_lockbytype', 'Type of locks', %locktype);
	$total_count = &comma_numbers($total_count);
	print $fh qq{
	<h1 class="page-header"><i class="icon-lock"></i> Locks</h1>
	<div class="analysis-item row-fluid" id="locks-type">
		<h2><i class="icon-lock"></i> Locks by types</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_locktype[0]</span> <span class="figure-label">Main Lock Type</span></li>
					<li><span class="figure">$total_count locks</span> <span class="figure-label">Total</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#locks-types-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#locks-types-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="locks-types-graph">
						$drawn_graphs{lockbytype_graph}
					</div>
					<div class="tab-pane" id="locks-types-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Type</th>
									<th>Object</th>
									<th>Count</th>
									<th>Total Duration</th>
									<th>Average Duration (s)</th>
								</tr>
							</thead>
							<tbody>
							$locktype_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of locks by type -->
};
	delete $drawn_graphs{lockbytype_graph};
}

sub print_query_type
{

	my %data = ();
        my $total_queries = 0;
        my $total_select = 0;
        my $total_write = 0;
        foreach my $a (@SQL_ACTION) {
                $total_queries += $overall_stat{$a};
		if ($a eq 'SELECT') {
			$total_select += $overall_stat{$a};
		} elsif ($a ne 'OTHERS') {
			$total_write += $overall_stat{$a};
		}
        }
	my $total = $overall_stat{'queries_number'};

	my $querytype_info = '';
        foreach my $a (@SQL_ACTION) {
                $querytype_info .= "<tr><td>$a</td><td>" . &comma_numbers($overall_stat{$a}) .
                        "</td><td>" . sprintf("%0.2f", ($overall_stat{$a} * 100) / ($total||1)) . "%</td></tr>";
        }
	if (($total - $total_queries) > 0) {
		$querytype_info .= "<tr><td>OTHERS</td><td>" . &comma_numbers($total - $total_queries) .
			"</td><td>" . sprintf("%0.2f", (($total - $total_queries) * 100) / ($total||1)) . "%</td></tr>";
	}
	$querytype_info = qq{<tr><td colspan="3">$NODATA</td></tr>} if (!$total);

	if ($graph && $total) {
		foreach my $t (@SQL_ACTION) {
			if ((($overall_stat{$t} * 100) / ($total||1)) > $pie_percentage_limit) {
				$data{$t} = $overall_stat{$t} || 0;
			} else {
				$data{"Sum query types < $pie_percentage_limit%"} += $overall_stat{$t} || 0;
			}
		}
		if (((($total - $total_queries) * 100) / ($total||1)) > $pie_percentage_limit) {
			$data{'Others'} = $total - $total_queries;
		} else {
			$data{"Sum query types < $pie_percentage_limit%"} += $total - $total_queries;
		}
	}
	$drawn_graphs{queriesbytype_graph} = &flotr2_piegraph($graphid++, 'graph_queriesbytype', 'Type of queries', %data);

	$total_select = &comma_numbers($total_select);
	$total_write = &comma_numbers($total_write);
	print $fh qq{
	<h1 class="page-header"><i class="icon-question-sign"></i> Queries</h1>
	<div class="analysis-item row-fluid" id="queries-by-type">
		<h2><i class="icon-question-sign"></i> Queries by type</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$total_select</span> <span class="figure-label">Total read queries</span></li>
					<li><span class="figure">$total_write</span> <span class="figure-label">Total write queries</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#queries-by-type-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#queries-by-type-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="queries-by-type-graph">
						$drawn_graphs{queriesbytype_graph}
					</div>
					<div class="tab-pane" id="queries-by-type-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Type</th>
									<th>Count</th>
									<th>Percentage</th>
								</tr>
							</thead>
							<tbody>
							$querytype_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of queries by type -->
};
	delete $drawn_graphs{queriesbytype_graph};

}

sub print_query_per_database
{
	my %infos = ();
	my $total_count = 0;
	my $query_database_info = '';
	my @main_database = ('unknown', 0);
	my @main_database_duration = ('unknown', 0);
	foreach my $d (sort keys %database_info) {
		$query_database_info .= "<tr><td>$d</td><td>Total</td><td>" .
					&comma_numbers($database_info{$d}{count}) . "</td><td>" .
					&convert_time($database_info{$d}{duration}) . "</td></tr>";
		$total_count += $database_info{$d}{count};
                if ($main_database[1] < $database_info{$d}{count}) {
                        $main_database[0] = $d;
                        $main_database[1] = $database_info{$d}{count};
                }
                if ($main_database_duration[1] < $database_info{$d}{duration}) {
                        $main_database_duration[0] = $d;
                        $main_database_duration[1] = $database_info{$d}{duration};
                }
		foreach my $r (sort keys %{$database_info{$d}}) {
			next if (($r eq 'count') || ($r =~ /duration/));
			$query_database_info .= "<tr><td></td><td>$r</td><td>" .
						&comma_numbers($database_info{$d}{$r}) . "</td><td>" .
						&convert_time($database_info{$d}{"$r|duration"}) . "</td></tr>";
		}
	}

	$query_database_info = qq{<tr><td colspan="3">$NODATA</td></tr>} if (!$total_count);

	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %database_info) {
			if ((($database_info{$d}{count} * 100) / ($total_count || 1)) > $pie_percentage_limit) {
				$infos{$d} = $database_info{$d}{count} || 0;
			} else {
				$infos{"Sum queries per databases < $pie_percentage_limit%"} += $database_info{$d}{count} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum queries per databases < $pie_percentage_limit%"};
			delete $infos{"Sum queries per databases < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{queriesbydatabase_graph} = &flotr2_piegraph($graphid++, 'graph_queriesbydatabase', 'Queries per database', %infos);

	$main_database[1] = &comma_numbers($main_database[1]);
	$main_database_duration[1] = &convert_time($main_database_duration[1]);
	print $fh qq{
	<div class="analysis-item row-fluid" id="queries-by-database">
		<h2><i class="icon-question-sign"></i> Queries by database</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_database[0]</span> <span class="figure-label">Main database</span></li>
					<li><span class="figure">$main_database[1]</span> <span class="figure-label">Requests</span></li>
					<li><span class="figure">$main_database_duration[1] ($main_database_duration[0])</span></li>
					<li><span class="figure-label">Main time consuming database</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#queries-by-database-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#queries-by-database-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="queries-by-database-graph">
						$drawn_graphs{queriesbydatabase_graph}
					</div>
					<div class="tab-pane" id="queries-by-database-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Database</th>
									<th>Request type</th>
									<th>Count</th>
									<th>Duration</th>
								</tr>
							</thead>
							<tbody>
							$query_database_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of queries by database -->
};
	delete $drawn_graphs{queriesbydatabase_graph};
}

sub print_query_per_application
{
	my %infos = ();
	my $total_count = 0;
	my $query_application_info = '';
	my @main_application = ('unknown', 0);
	my @main_application_duration = ('unknown', 0);
	foreach my $d (sort keys %application_info) {
		$query_application_info .= "<tr><td>$d</td><td>Total</td><td>" .
					&comma_numbers($application_info{$d}{count}) . "</td><td>" .
					&convert_time($application_info{$d}{duration}) . "</td></tr>";
		$total_count += $application_info{$d}{count};
                if ($main_application[1] < $application_info{$d}{count}) {
                        $main_application[0] = $d;
                        $main_application[1] = $application_info{$d}{count};
                }
                if ($main_application_duration[1] < $application_info{$d}{duration}) {
                        $main_application_duration[0] = $d;
                        $main_application_duration[1] = $application_info{$d}{duration};
                }
		foreach my $r (sort keys %{$application_info{$d}}) {
			next if (($r eq 'count') || ($r =~ /duration/));
			$query_application_info .= "<tr><td></td><td>$r</td><td>" .
						&comma_numbers($application_info{$d}{$r}) . "</td><td>" .
						&convert_time($application_info{$d}{"$r|duration"}) . "</td></tr>";
		}
	}
	$query_application_info = qq{<tr><td colspan="3">$NODATA</td></tr>} if (!$total_count);
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %application_info) {
			if ((($application_info{$d}{count} * 100) / ($total_count || 1)) > $pie_percentage_limit) {
				$infos{$d} = $application_info{$d}{count} || 0;
			} else {
				$infos{"Sum queries per applications < $pie_percentage_limit%"} += $application_info{$d}{count} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum queries per applications < $pie_percentage_limit%"};
			delete $infos{"Sum queries per applications < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{queriesbyapplication_graph} = &flotr2_piegraph($graphid++, 'graph_queriesbyapplication', 'Queries per application', %infos);

	$main_application[1] = &comma_numbers($main_application[1]);
	$main_application_duration[1] = &convert_time($main_application_duration[1]);
	print $fh qq{
	<div class="analysis-item row-fluid" id="queries-by-application">
		<h2><i class="icon-question-sign"></i> Queries by application</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_application[0]</span> <span class="figure-label">Main application</span></li>
					<li><span class="figure">$main_application[1]</span> <span class="figure-label">Requests</span></li>
					<li><span class="figure">$main_application_duration[1] ($main_application_duration[0])</span></li>
					<li><span class="figure-label">Main time consuming application</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#queries-by-application-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#queries-by-application-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="queries-by-application-graph">
						$drawn_graphs{queriesbyapplication_graph}
					</div>
					<div class="tab-pane" id="queries-by-application-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Application</th>
									<th>Request type</th>
									<th>Count</th>
									<th>Duration</th>
								</tr>
							</thead>
							<tbody>
							$query_application_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of queries by application -->
};
	delete $drawn_graphs{queriesbyapplication_graph};

}

sub print_query_per_user
{
	my %infos = ();
	my $total_count = 0;
	my $total_duration = 0;
	my $query_user_info = '';
	my @main_user = ('unknown', 0);
	my @main_user_duration = ('unknown', 0);
	foreach my $d (sort keys %user_info) {
		$query_user_info .= "<tr><td>$d</td><td>Total</td><td>" .
					&comma_numbers($user_info{$d}{count}) . "</td><td>" .
					&convert_time($user_info{$d}{duration}) . "</td></tr>";
		$total_count += $user_info{$d}{count};
		$total_duration += $user_info{$d}{duration};
                if ($main_user[1] < $user_info{$d}{count}) {
                        $main_user[0] = $d;
                        $main_user[1] = $user_info{$d}{count};
                }
                if ($main_user_duration[1] < $user_info{$d}{duration}) {
                        $main_user_duration[0] = $d;
                        $main_user_duration[1] = $user_info{$d}{duration};
                }
		foreach my $r (sort keys %{$user_info{$d}}) {
			next if (($r eq 'count') || ($r =~ /duration/));
			$query_user_info .= "<tr><td></td><td>$r</td><td>" .
						&comma_numbers($user_info{$d}{$r}) . "</td><td>" .
						&convert_time($user_info{$d}{"$r|duration"}) . "</td></tr>";
		}
	}
	$query_user_info = qq{<tr><td colspan="3">$NODATA</td></tr>} if (!$total_count);

	if ($graph) {
		my %small = ();
		foreach my $d (sort keys %user_info) {
			if ((($user_info{$d}{count} * 100) / ($total_count || 1)) > $pie_percentage_limit) {
				$infos{queries}{$d} = $user_info{$d}{count} || 0;
			} else {
				$infos{queries}{"Sum queries per users < $pie_percentage_limit%"} += $user_info{$d}{count} || 0;
				push(@{$small{queries}}, $d);
			}
			if ((($user_info{$d}{duration} * 100) / ($total_duration || 1)) > $pie_percentage_limit) {
				$infos{duration}{$d} = $user_info{$d}{duration} || 0;
			} else {
				$infos{duration}{"Sum duration per users < $pie_percentage_limit%"} += $user_info{$d}{duration} || 0;
				push(@{$small{duration}}, $d);                          
			}
		}
		if ($#{$small{queries}} == 0) {
			$infos{queries}{$small{queries}[0]} = $infos{queries}{"Sum queries per users < $pie_percentage_limit%"};
			delete $infos{queries}{"Sum queries per users < $pie_percentage_limit%"};
		}
		if ($#{$small{duration}} == 0){
			$infos{duration}{$small{duration}[0]} = $infos{duration}{"Sum duration per users < $pie_percentage_limit%"};
			delete $infos{duration}{"Sum duration per users < $pie_percentage_limit%"};                     
		}
	}
	$drawn_graphs{queriesbyuser_graph} = &flotr2_piegraph($graphid++, 'graph_queriesbyuser', 'Queries per user', %{$infos{queries}});
	$drawn_graphs{durationbyuser_graph} = &flotr2_piegraph($graphid++, 'graph_durationbyuser', 'Duration per user', %{$infos{duration}});

	$main_user[1] = &comma_numbers($main_user[1]);
	$main_user_duration[1] = &convert_time($main_user_duration[1]);

	print $fh qq{
	<div class="analysis-item row-fluid" id="queries-by-user">
		<h2><i class="icon-question-sign"></i> Queries by user</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_user[0]</span> <span class="figure-label">Main user</span></li>
					<li><span class="figure">$main_user[1]</span> <span class="figure-label">Requests</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#queries-by-user-graph" data-toggle="tab">Queries Chart</a></li>
					<li><a href="#queries-by-user-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="queries-by-user-graph">
						$drawn_graphs{queriesbyuser_graph}
					</div>
					<div class="tab-pane" id="queries-by-user-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>User</th>
									<th>Request type</th>
									<th>Count</th>
									<th>Duration</th>
								</tr>
							</thead>
							<tbody>
							$query_user_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of queries by user -->
};
	delete $drawn_graphs{queriesbyuser_graph};

	print $fh qq{
	<div class="analysis-item row-fluid" id="duration-by-user">
		<h2><i class="icon-time"></i> Duration by user</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_user_duration[1] ($main_user_duration[0])</span> <span class="figure-label">Main time consuming user</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#duration-by-user-graph" data-toggle="tab">Duration Chart</a></li>
					<li><a href="#duration-by-user-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="duration-by-user-graph">
						$drawn_graphs{durationbyuser_graph}
					</div>
					<div class="tab-pane" id="duration-by-user-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>User</th>
									<th>Request type</th>
									<th>Count</th>
									<th>Duration</th>
								</tr>
							</thead>
							<tbody>
							$query_user_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of duration by user -->
};
	delete $drawn_graphs{durationbyuser_graph};

}

sub print_query_per_host
{
	my %infos = ();
	my $total_count = 0;
	my $query_host_info = '';
	my @main_host = ('unknown', 0);
	my @main_host_duration = ('unknown', 0);
	foreach my $d (sort keys %host_info) {
		$query_host_info .= "<tr><td>$d</td><td>Total</td><td>" .
					&comma_numbers($host_info{$d}{count}) . "</td><td>" .
					&convert_time($host_info{$d}{duration}) . "</td></tr>";
		$total_count += $host_info{$d}{count};
                if ($main_host[1] < $host_info{$d}{count}) {
                        $main_host[0] = $d;
                        $main_host[1] = $host_info{$d}{count};
                }
                if ($main_host_duration[1] < $host_info{$d}{duration}) {
                        $main_host_duration[0] = $d;
                        $main_host_duration[1] = $host_info{$d}{duration};
                }
		foreach my $r (sort keys %{$host_info{$d}}) {
			next if (($r eq 'count') || ($r =~ /duration/));
			$query_host_info .= "<tr><td></td><td>$r</td><td>" .
						&comma_numbers($host_info{$d}{$r}) . "</td><td>" .
						&convert_time($host_info{$d}{"$r|duration"}) . "</td></tr>";
		}
	}
	$query_host_info = qq{<tr><td colspan="3">$NODATA</td></tr>} if (!$total_count);

	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %host_info) {
			if ((($host_info{$d}{count} * 100) / ($total_count || 1)) > $pie_percentage_limit) {
				$infos{$d} = $host_info{$d}{count} || 0;
			} else {
				$infos{"Sum queries per hosts < $pie_percentage_limit%"} += $host_info{$d}{count} || 0;
				push(@small, $d);
			}
		}
		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum queries per hosts < $pie_percentage_limit%"};
			delete $infos{"Sum queries per hosts < $pie_percentage_limit%"};
		}
	}
	$drawn_graphs{queriesbyhost_graph} = &flotr2_piegraph($graphid++, 'graph_queriesbyhost', 'Queries per host', %infos);

	$main_host[1] = &comma_numbers($main_host[1]);
	$main_host_duration[1] = &convert_time($main_host_duration[1]);
	print $fh qq{
	<div class="analysis-item row-fluid" id="queries-by-host">
		<h2><i class="icon-question-sign"></i> Queries by host</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$main_host[0]</span> <span class="figure-label">Main host</span></li>
					<li><span class="figure">$main_host[1]</span> <span class="figure-label">Requests</span></li>
					<li><span class="figure">$main_host_duration[1] ($main_host_duration[0])</span></li>
					<li><span class="figure-label">Main time consuming host</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#queries-by-host-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#queries-by-host-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="queries-by-host-graph">
						$drawn_graphs{queriesbyhost_graph}
					</div>
					<div class="tab-pane" id="queries-by-host-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Host</th>
									<th>Request type</th>
									<th>Count</th>
									<th>Duration</th>
								</tr>
							</thead>
							<tbody>
							$query_host_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of queries by host -->
};
	delete $drawn_graphs{queriesbyhost_graph};

}


sub print_lock_queries_report
{
	my @top_locked_queries;
	foreach my $h (keys %normalyzed_info) {
		if (exists($normalyzed_info{$h}{locks})) {
			push (@top_locked_queries, [$h, $normalyzed_info{$h}{locks}{count}, $normalyzed_info{$h}{locks}{wait},
			$normalyzed_info{$h}{locks}{minwait}, $normalyzed_info{$h}{locks}{maxwait}]);
		}
	}

	# Most frequent waiting queries (N)
	@top_locked_queries = sort {$b->[2] <=> $a->[2]} @top_locked_queries;
	print $fh qq{
                <div class="analysis-item row-fluid" id="queries-most-frequent-waiting">
                        <h2><i class="icon-ban-circle"></i> Most frequent waiting queries (N)</h2>
                        <div class="span11">
                                <table class="table table-striped" id="queries-most-frequent-waiting-table">
                                <thead>
                                        <tr>
                                                <th>Rank</th>
                                                <th>Count</th>
                                                <th>Total&nbsp;time</th>
                                                <th>Min&nbsp;time</th>
                                                <th>Max&nbsp;time</th>
                                                <th>Avg&nbsp;duration</th>
                                                <th>Query</th>
                                        </tr>
                                </thead>
                                <tbody>
};

	my $rank = 1;
	for (my $i = 0 ; $i <= $#top_locked_queries ; $i++) {
		my $count = &comma_numbers($top_locked_queries[$i]->[1]);
		my $total_time = &convert_time($top_locked_queries[$i]->[2]);
		my $min_time = &convert_time($top_locked_queries[$i]->[3]);
		my $max_time = &convert_time($top_locked_queries[$i]->[4]);
		my $avg_time = &convert_time($top_locked_queries[$i]->[2] / ($top_locked_queries[$i]->[1] || 1));
		my $query = &highlight_code($top_locked_queries[$i]->[0]);
		my $md5 = '';
		$md5 = 'md5: ' . md5_hex($top_locked_queries[$i]->[0]) if ($enable_checksum);
		my $k = $top_locked_queries[$i]->[0];
		my $example = qq{<p><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#queries-most-frequent-waiting-examples-rank-$rank">Examples</button></p>};
		$example = '' if (scalar keys %{$normalyzed_info{$k}{samples}} <= 1);
		print $fh qq{
			<tr>
			<td>$rank</td>
			<td>$count</td>
			<td>$total_time</td>
			<td>$min_time</td>
			<td>$max_time</td>
			<td>$avg_time</td>
			<td id="queries-most-frequent-waiting-examples-details-rank-$rank">
				<div id="query-a-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
				 $example
			<!-- Examples collapse -->
			<div id="queries-most-frequent-waiting-examples-rank-$rank" class="collapse">
				<dl>
};
		if ($normalyzed_info{$k}{count} > 1) {
			my $idx = 1;
			foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
				$query = &highlight_code($normalyzed_info{$k}{samples}{$d}{query});
				$md5 = '';
				$md5 = 'md5: ' . md5_hex($normalyzed_info{$k}{samples}{$d}{query}) if ($enable_checksum);
				my $details = "[ <b>Date:</b> $normalyzed_info{$k}{samples}{$d}{date}";
				$details .= " - <b>Duration:</b> " . &convert_time($d) if ($normalyzed_info{$k}{samples}{$d}{duration});
				$details .= " - <b>Database:</b> $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
				$details .= " - <b>User:</b> $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
				$details .= " - <b>Remote:</b> $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
				$details .= " - <b>Application:</b> $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
				$details .= " - <b>Bind query:</b> yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
				$details .= " ]";
				my $explain = '';
				if ($normalyzed_info{$k}{samples}{$d}{plan}) {
					my $url = $EXPLAIN_URL . url_escape($normalyzed_info{$k}{samples}{$d}{plan});
					$explain = "<div id=\"query-a-explain-$rank\" class=\"sql sql-largesize\"><a href=\"$url\" target=\"explain\" title=\"Click to beautify Explain Plan\"><i class=\"icon-compass\"></i><b>Explain plan</b></a></div>\n<pre>" . $normalyzed_info{$k}{samples}{$d}{plan} . "</pre>\n";
				}
				print $fh qq{
					<dt>
						<div id="query-a-$rank-$idx" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></li>$query</div>$md5
					</dt>
					<pre>$details</pre>
					$explain
};
				$idx++;

			}
			print $fh qq{
					</dl>
					<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#queries-most-frequent-waiting-examples-rank-$rank">x Hide</button></p>
				</div>
				<!-- end of example collapse -->
			</td>
		</tr>
};
		}
		$rank++;
	}
	if ($#top_locked_queries == -1) {
		print $fh qq{<tr><td colspan="7">$NODATA</td></tr>};
	}
        print $fh qq{
		</tbody>
		</table>
	</div>
</div><!-- end of queries-most-frequent-waiting -->
};

	@top_locked_queries = ();

	# Queries that waited the most
	@top_locked_info = sort {$b->[1] <=> $a->[1]} @top_locked_info;
	print $fh qq{
		<div class="analysis-item row-fluid" id="queries-that-waited-most">
			<h2><i class="icon-ban-circle"></i> Queries that waited the most</h2>
			<div class="span11">
				<table class="table table-striped" id="queries-that-waited-most-table">
				<thead>
					<tr>
						<th>Rank</th>
						<th>Wait&nbsp;time</th>
						<th>Query</th>
					</tr>
				</thead>
				<tbody>
};

	$rank = 1;
	for (my $i = 0 ; $i <= $#top_locked_info ; $i++) {
		my $query = &highlight_code($top_locked_info[$i]->[2]);
		my $md5 = '';
		$md5 = 'md5: ' . md5_hex($top_locked_info[$i]->[2]) if ($enable_checksum);
		my $details = "[ <b>Date:</b> " . ($top_locked_info[$i]->[1] || '');
		$details .= " - <b>Database</b>: $top_locked_info[$i]->[3]" if ($top_locked_info[$i]->[3]);
		$details .= " - <b>User:</b> $top_locked_info[$i]->[4]" if ($top_locked_info[$i]->[4]);
		$details .= " - <b>Remote:</b> $top_locked_info[$i]->[5]" if ($top_locked_info[$i]->[5]);
		$details .= " - <b>Application:</b> $top_locked_info[$i]->[6]" if ($top_locked_info[$i]->[6]);
		$details .= " - <b>Bind query:</b> yes" if ($top_locked_info[$i]->[7]);
		$details .= " ]";
		my $time = &convert_time($top_locked_info[$i]->[0]);
		print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$time</td>
				<td id="queries-that-waited-most-examples-details-rank-$rank">
					<div id="query-b-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
					<pre>$details</pre>
				</td>
				</tr>
};
		$rank++;
	}
	if ($#top_locked_info == -1) {
		print $fh qq{<tr><td colspan="3">$NODATA</td></tr>};
	}
                print $fh qq{
		</tbody>
		</table>
	</div>
</div><!-- end of queries-that-waited-most -->
};

}

sub print_tempfile_report
{
	my @top_temporary = ();
	foreach my $h (keys %normalyzed_info) {
		if (exists($normalyzed_info{$h}{tempfiles})) {
			push (@top_temporary, [$h, $normalyzed_info{$h}{tempfiles}{count}, $normalyzed_info{$h}{tempfiles}{size},
			$normalyzed_info{$h}{tempfiles}{minsize}, $normalyzed_info{$h}{tempfiles}{maxsize}]);
		}
	}

	# Queries generating the most temporary files (N)
	if ($#top_temporary >= 0) {
		@top_temporary = sort {$b->[1] <=> $a->[1]} @top_temporary;
		print $fh qq{
		<div class="analysis-item row-fluid" id="queries-generating-most-temporary-files">
			<h2><i class="icon-pencil"></i> Queries generating the most temporary files (N)</h2>
			<div class="span11">
				<table class="table table-striped" id="queries-generating-most-temporary-files-table">
				<thead>
					<tr>
						<th>Rank</th>
						<th>Count</th>
						<th>Total&nbsp;size</th>
						<th>Min&nbsp;size</th>
						<th>Max&nbsp;size</th>
						<th>Avg&nbsp;size</th>
						<th>Query</th>
					</tr>
				</thead>
				<tbody>
};
		my $rank = 1;
		for (my $i = 0 ; $i <= $#top_temporary ; $i++) {
			my $count = &comma_numbers($top_temporary[$i]->[1]);
			my $total_size = &pretty_print_size($top_temporary[$i]->[2]);
			my $min_size = &pretty_print_size($top_temporary[$i]->[3]);
			my $max_size = &pretty_print_size($top_temporary[$i]->[4]);
			my $avg_size = &pretty_print_size($top_temporary[$i]->[2] / ($top_temporary[$i]->[1] || 1));
			my $query = &highlight_code($top_temporary[$i]->[0]);
			my $md5 = '';
			$md5 = 'md5: ' . md5_hex($top_temporary[$i]->[0]) if ($enable_checksum);
			my $example = qq{<p><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#queries-generating-most-temporary-files-examples-rank-$rank">Examples</button></p>};
			$example = '' if (scalar keys %{$normalyzed_info{$top_temporary[$i]->[0]}{samples}} == 0);
			print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$count</td>
				<td>$total_size</td>
				<td>$min_size</td>
				<td>$max_size</td>
				<td>$avg_size</td>
				<td id="queries-generating-most-temporary-files-examples-details-rank-$rank">
					<div id="query-c-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
					$example
				<!-- Examples collapse -->
				<div id="queries-generating-most-temporary-files-examples-rank-$rank" class="collapse">
					<dl>
};
			my $k = $top_temporary[$i]->[0];
			if ($normalyzed_info{$k}{count} > 1) {
				my $idx = 1;
				foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
					$query = &highlight_code($normalyzed_info{$k}{samples}{$d}{query});
					my $md5 = '';
					$md5 = 'md5: ' . md5_hex($normalyzed_info{$k}{samples}{$d}{query}) if ($enable_checksum);
					my $details = "Duration: " . &convert_time($d) . "<br />";
					$details .= "Database: $normalyzed_info{$k}{samples}{$d}{db}<br/>" if ($normalyzed_info{$k}{samples}{$d}{db});
					$details .= "User: $normalyzed_info{$k}{samples}{$d}{user}<br/>" if ($normalyzed_info{$k}{samples}{$d}{user});
					$details .= "Remote: $normalyzed_info{$k}{samples}{$d}{remote}<br/>" if ($normalyzed_info{$k}{samples}{$d}{remote});
					$details .= "Application: $normalyzed_info{$k}{samples}{$d}{app}<br/>" if ($normalyzed_info{$k}{samples}{$d}{app});
					$details .= "Bind query: yes<br/>" if ($normalyzed_info{$k}{samples}{$d}{bind});
					print $fh qq{
						<dt>
						<div id="query-c-$rank-$idx" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
						
						</dt>
						<pre>$details</pre>
};
				$idx++

				}
				print $fh qq{
					</dl>
					<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#queries-generating-most-temporary-files-examples-rank-$rank">x Hide</button></p>
				</div>
				<!-- end of example collapse -->
			</td>
		</tr>
};
			}                             
			$rank++;
		}
        print $fh qq{
		</tbody>
		</table>
	</div>
</div><!-- end of queries-generating-most-temporary-files -->
};

		@top_temporary = ();
	}

	# Top queries generating the largest temporary files
	if ($#top_tempfile_info >= 0) {
		@top_tempfile_info = sort {$b->[0] <=> $a->[0]} @top_tempfile_info;
		my $largest = &comma_numbers($top_temporary[0]->[0]);
		print $fh qq{
		<div class="analysis-item row-fluid" id="queries-generating-largest-temporary-files">
			<h2><i class="icon-pencil"></i> Queries generating the largest temporary files</h2>
			<div class="span11">
				<table class="table table-striped" id="queries-generating-largest-temporary-files-table">
				<thead>
					<tr>
						<th>Rank</th>
						<th>Size</th>
						<th>Query</th>
					</tr>
				</thead>
				<tbody>
};
		my $rank = 1;
		for (my $i = 0 ; $i <= $#top_tempfile_info ; $i++) {
			my $size = &pretty_print_size($top_tempfile_info[$i]->[0]);
			my $details = "[ <b>Date:</b> $top_tempfile_info[$i]->[1]";
			$details .= " - <b>Database:</b> $top_tempfile_info[$i]->[3]" if ($top_tempfile_info[$i]->[3]);
			$details .= " - <b>User:</b> $top_tempfile_info[$i]->[4]" if ($top_tempfile_info[$i]->[4]);
			$details .= " - <b>Remote:</b> $top_tempfile_info[$i]->[5]" if ($top_tempfile_info[$i]->[5]);
			$details .= " - <b>Application:</b> $top_tempfile_info[$i]->[6]" if ($top_tempfile_info[$i]->[6]);
			$details .= " - <b>Bind yes:</b> yes" if ($top_tempfile_info[$i]->[7]);
			$details .= " ]";
			my $query = &highlight_code($top_tempfile_info[$i]->[2]);
			my $md5 = '';
			$md5 = 'md5: ' . md5_hex($top_tempfile_info[$i]->[2]) if ($enable_checksum);
			print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$size</td>
				<td id="queries-generating-largest-temporary-files-examples-details-rank-$rank">
					<div id="query-d-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
					<pre>$details</pre>
				</td>
				</tr>
};
			$rank++;
		}
		print $fh qq{
		</tbody>
		</table>
	</div>
</div><!-- end of queries-generating-largest-temporary-files -->
};
		@top_tempfile_info = ();
	}

}

sub print_cancelled_report
{
	my @top_cancelled = ();
	foreach my $h (keys %normalyzed_info) {
		if (exists($normalyzed_info{$h}{cancelled})) {
			push (@top_cancelled, [$h, $normalyzed_info{$h}{cancelled}{count}]);
		}
	}

	# Queries generating the most cancellation (N)
	if ($#top_cancelled >= 0) {
		@top_cancelled = sort {$b->[1] <=> $a->[1]} @top_cancelled;
		print $fh qq{
		<div class="analysis-item row-fluid" id="queries-generating-most-cancellation">
			<h2><i class="icon-pencil"></i> Queries generating the most cancellation (N)</h2>
			<div class="span11">
				<table class="table table-striped" id="queries-generating-most-cancellation-table">
				<thead>
					<tr>
						<th>Rank</th>
						<th>Count</th>
						<th>Query</th>
					</tr>
				</thead>
				<tbody>
};
		my $rank = 1;
		for (my $i = 0 ; $i <= $#top_cancelled ; $i++) {
			my $count = &comma_numbers($top_cancelled[$i]->[1]);
			my $query = &highlight_code($top_cancelled[$i]->[0]);
			my $md5 = '';
			$md5 = 'md5: ' . md5_hex($top_cancelled[$i]->[0]) if ($enable_checksum);
			my $example = qq{<p><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#queries-generating-most-cancellation-examples-rank-$rank">Examples</button></p>};
			$example = '' if (scalar keys %{$normalyzed_info{$top_cancelled[$i]->[0]}{samples}} == 0);
			print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$count</td>
				<td id="queries-generating-most-cancellation-examples-details-rank-$rank">
					<div id="query-c-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
					$example
				<!-- Examples collapse -->
				<div id="queries-generating-most-cancellation-examples-rank-$rank" class="collapse">
					<dl>
};
			my $k = $top_cancelled[$i]->[0];
			if ($normalyzed_info{$k}{count} >= 1) {
				my $idx = 1;
				foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
					$query = &highlight_code($normalyzed_info{$k}{samples}{$d}{query});
					my $md5 = '';
					$md5 = 'md5: ' . md5_hex($normalyzed_info{$k}{samples}{$d}{query}) if ($enable_checksum);
					my $details = "Duration: " . &convert_time($d) . "<br />";
					$details .= "Database: $normalyzed_info{$k}{samples}{$d}{db}<br/>" if ($normalyzed_info{$k}{samples}{$d}{db});
					$details .= "User: $normalyzed_info{$k}{samples}{$d}{user}<br/>" if ($normalyzed_info{$k}{samples}{$d}{user});
					$details .= "Remote: $normalyzed_info{$k}{samples}{$d}{remote}<br/>" if ($normalyzed_info{$k}{samples}{$d}{remote});
					$details .= "Application: $normalyzed_info{$k}{samples}{$d}{app}<br/>" if ($normalyzed_info{$k}{samples}{$d}{app});
					$details .= "Bind query: yes<br/>" if ($normalyzed_info{$k}{samples}{$d}{bind});
					print $fh qq{
						<dt>
						<div id="query-d-$rank-$idx" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
						
						</dt>
						<pre>$details</pre>
};
				$idx++

				}
				print $fh qq{
					</dl>
					<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#queries-generating-most-cancellation-examples-rank-$rank">x Hide</button></p>
				</div>
				<!-- end of example collapse -->
			</td>
		</tr>
};
			}                             
			$rank++;
		}
        print $fh qq{
		</tbody>
		</table>
	</div>
</div><!-- end of queries-generating-most-cancellation -->
};

		@top_cancelled = ();
	}

	# Top queries generating the most cancellation
	if ($#top_cancelled_info >= 0) {
		@top_cancelled_info = sort {$b->[0] <=> $a->[0]} @top_cancelled_info;
		my $largest = &comma_numbers($top_cancelled[0]->[0]);
		print $fh qq{
		<div class="analysis-item row-fluid" id="queries-generating-most-cancelled">
			<h2><i class="icon-pencil"></i> Queries most cancelled</h2>
			<div class="span11">
				<table class="table table-striped" id="queries-generating-most-cancelled-table">
				<thead>
					<tr>
						<th>Rank</th>
						<th>Number</th>
						<th>Query</th>
					</tr>
				</thead>
				<tbody>
};
		my $rank = 1;
		for (my $i = 0 ; $i <= $#top_cancelled_info ; $i++) {
			my $count = &comma_numbers($top_cancelled_info[$i]->[0]);
			my $details = "[ <b>Date:</b> $top_cancelled_info[$i]->[1]";
			$details .= " - <b>Database:</b> $top_cancelled_info[$i]->[3]" if ($top_cancelled_info[$i]->[3]);
			$details .= " - <b>User:</b> $top_cancelled_info[$i]->[4]" if ($top_cancelled_info[$i]->[4]);
			$details .= " - <b>Remote:</b> $top_cancelled_info[$i]->[5]" if ($top_cancelled_info[$i]->[5]);
			$details .= " - <b>Application:</b> $top_cancelled_info[$i]->[6]" if ($top_cancelled_info[$i]->[6]);
			$details .= " - <b>Bind yes:</b> yes" if ($top_cancelled_info[$i]->[7]);
			$details .= " ]";
			my $query = &highlight_code($top_cancelled_info[$i]->[2]);
			my $md5 = '';
			$md5 = 'md5: ' . md5_hex($top_cancelled_info[$i]->[2]) if ($enable_checksum);
			print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$count</td>
				<td id="queries-generating-most-cancelled-examples-details-rank-$rank">
					<div id="query-d-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
					<pre>$details</pre>
				</td>
				</tr>
};
			$rank++;
		}
		print $fh qq{
		</tbody>
		</table>
	</div>
</div><!-- end of queries-generating-most-cancelled -->
};
		@top_cancelled_info = ();
	}

}

sub print_histogram_query_times
{
	my %data = ();
	my $histogram_info = '';
	my $most_range = '';
	my $most_range_value = '';

	for (my $i = 1; $i <= $#histogram_query_time; $i++) {
                $histogram_info .= "<tr><td>$histogram_query_time[$i-1]-$histogram_query_time[$i]ms</td><td>" . &comma_numbers($overall_stat{histogram}{query_time}{$histogram_query_time[$i-1]}) .
                        "</td><td>" . sprintf("%0.2f", ($overall_stat{histogram}{query_time}{$histogram_query_time[$i-1]} * 100) / ($overall_stat{histogram}{query_total}||1)) . "%</td></tr>";
		$data{"$histogram_query_time[$i-1]-$histogram_query_time[$i]ms"} = ($overall_stat{histogram}{query_time}{$histogram_query_time[$i-1]} || 0);
		if ($overall_stat{histogram}{query_time}{$histogram_query_time[$i-1]} > $most_range_value) {
			$most_range = "$histogram_query_time[$i-1]-$histogram_query_time[$i]ms";
			$most_range_value = $overall_stat{histogram}{query_time}{$histogram_query_time[$i-1]};
		}
	}
	if ($overall_stat{histogram}{query_total} > 0) {
		$histogram_info .= "<tr><td> &gt; $histogram_query_time[-1]ms</td><td>" . &comma_numbers($overall_stat{histogram}{query_time}{'-1'}) .
			"</td><td>" . sprintf("%0.2f", ($overall_stat{histogram}{query_time}{'-1'} * 100) / ($overall_stat{histogram}{query_total}||1)) . "%</td></tr>";
		$data{"> $histogram_query_time[-1]ms"} = $overall_stat{histogram}{query_time}{"-1"} if ($overall_stat{histogram}{query_time}{"-1"} > 0);
		if ($overall_stat{histogram}{query_time}{"-1"} > $most_range_value) {
			$most_range = "> $histogram_query_time[-1]ms";
			$most_range_value = $overall_stat{histogram}{query_time}{"-1"};
		}
	} else {
		$histogram_info = qq{<tr><td colspan="3">$NODATA</td></tr>};
	}
	$drawn_graphs{histogram_query_times_graph} = &flotr2_duration_histograph($graphid++, 'graph_histogram_query_times', 'Queries', \@histogram_query_time, %data);

	$most_range_value = &comma_numbers($most_range_value) if ($most_range_value);

	print $fh qq{
	<h2><i class="icon-question-sign"></i> Top Queries</h2>
	<div class="analysis-item row-fluid" id="histogram-query-times">
		<h2><i class="icon-signal"></i> Histogram of query times</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$most_range_value</span> <span class="figure-label">$most_range duration</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#histogram-query-times-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#histogram-query-times-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="histogram-query-times-graph">
						$drawn_graphs{histogram_query_times_graph}
					</div>
					<div class="tab-pane" id="histogram-query-times-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Range</th>
									<th>Count</th>
									<th>Percentage</th>
								</tr>
							</thead>
							<tbody>
							$histogram_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of queries by type -->
};
	delete $drawn_graphs{histogram_query_times_graph};
}

sub print_slowest_individual_queries
{

	print $fh qq{
		<div class="analysis-item row-fluid" id="slowest-individual-queries">
			<h2><i class="icon-spinner"></i> Slowest individual queries</h2>
			<div class="span11">
				<table class="table table-striped" id="slowest-individual-queries-table">
				<thead>
					<tr>
						<th>Rank</th>
						<th>Duration</th>
						<th>Query</th>
					</tr>
				</thead>
				<tbody>
};

	my $idx = 1;
	for (my $i = 0 ; $i <= $#top_slowest ; $i++) {
		my $rank = $i + 1;
		my $duration = &convert_time($top_slowest[$i]->[0]);
		my $date = $top_slowest[$i]->[1] || '';
		my $details = "[ <b>Date:</b> " . ($top_slowest[$i]->[1] || '');
		$details .= " - <b>Database:</b> $top_slowest[$i]->[3]" if ($top_slowest[$i]->[3]);
		$details .= " - <b>User:</b> $top_slowest[$i]->[4]" if ($top_slowest[$i]->[4]);
		$details .= " - <b>Remote:</b> $top_slowest[$i]->[5]" if ($top_slowest[$i]->[5]);
		$details .= " - <b>Application:</b> $top_slowest[$i]->[6]" if ($top_slowest[$i]->[6]);
		$details .= " - <b>Bind query:</b> yes" if ($top_slowest[$i]->[7]);
		$details .= " ]";
		my $explain = '';
		if ($top_slowest[$i]->[8]) {
			my $url = $EXPLAIN_URL . url_escape($top_slowest[$i]->[8]);
			$explain = "<div id=\"query-d-explain-$rank-$idx\" class=\"sql sql-largesize\"><a href=\"$url\" target=\"explain\" title=\"Click to beautify Explain Plan\"><i class=\"icon-compass\"></i><b>Explain plan</b></a></div>\n<pre>" . $top_slowest[$i]->[8] . "</pre>\n";
		}
		my $query = &highlight_code($top_slowest[$i]->[2]);
		my $md5 = '';
		$md5 = 'md5: ' . md5_hex($top_slowest[$i]->[2]) if ($enable_checksum);
		print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$duration</td>
				<td id="slowest-individual-queries-examples-rank-$rank">
					<div id="query-d-$rank-$idx" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
					<pre>$details</pre>
					$explain
				</td>
				</tr>

			};
		$idx++;
	}
	if ($#top_slowest == -1) {
		print $fh qq{<tr><td colspan="3">$NODATA</td></tr>};
	}
	print $fh qq{
			</tbody>
			</table>
		</div>
	</div><!-- end of slowest-individual-queries -->
};

}

sub print_time_consuming
{
	print $fh qq{
		<div class="analysis-item row-fluid" id="time-consuming-queries">
			<h2><i class="icon-time"></i> Time consuming queries</h2>
                        <div class="span11">
                                <table class="table table-striped" id="time-consuming-queries-table">
                                <thead>
				<tr>
					<th>Rank</th>
					<th>Total duration</th>
					<th>Times executed</th>
					<th>Min duration</th>
					<th>Max duration</th>
					<th>Avg duration</th>
					<th>Query</th>
				</tr>
				</thead>
				<tbody>
};
	my $rank = 1;
	my $found = 0;
	foreach my $k (sort {$normalyzed_info{$b}{duration} <=> $normalyzed_info{$a}{duration}} keys %normalyzed_info) {
		next if (!$normalyzed_info{$k}{count} || !exists $normalyzed_info{$k}{duration});
		last if ($rank > $top);
		$found++;
		$normalyzed_info{$k}{average} = $normalyzed_info{$k}{duration} / $normalyzed_info{$k}{count};
		my $duration = &convert_time($normalyzed_info{$k}{duration});
		my $count = &comma_numbers($normalyzed_info{$k}{count});
		my $min = &convert_time($normalyzed_info{$k}{min});
		my $max = &convert_time($normalyzed_info{$k}{max});
		my $avg = &convert_time($normalyzed_info{$k}{average});
		my $query = &highlight_code($k);
		my $md5 = '';
		$md5 = 'md5: ' . md5_hex($k) if ($enable_checksum);
		my $details = '';
		my %hourly_count = ();
		my %hourly_duration = ();
		my $days = 0;
		foreach my $d (sort keys %{$normalyzed_info{$k}{chronos}}) {
			$d =~ /^(\d{4})(\d{2})(\d{2})$/;
			$days++;
			my $zday = "$abbr_month{$2} $3";
			foreach my $h (sort keys %{$normalyzed_info{$k}{chronos}{$d}}) {
				$normalyzed_info{$k}{chronos}{$d}{$h}{average} =
					$normalyzed_info{$k}{chronos}{$d}{$h}{duration} / ($normalyzed_info{$k}{chronos}{$d}{$h}{count} || 1);
				$details .= "<tr><td>$zday</td><td>$h</td><td>" .
					&comma_numbers($normalyzed_info{$k}{chronos}{$d}{$h}{count}) .   "</td><td>" .
					&convert_time($normalyzed_info{$k}{chronos}{$d}{$h}{duration}) . "</td><td>" .
					&convert_time($normalyzed_info{$k}{chronos}{$d}{$h}{average}) .  "</td></tr>";
				$zday = "";
				foreach my $m (sort keys %{$normalyzed_info{$k}{chronos}{$d}{$h}{min}}) {
					my $rd = &average_per_minutes($m, $histo_avg_minutes);
					$hourly_count{"$h:$rd"} += $normalyzed_info{$k}{chronos}{$d}{$h}{min}{$m};
					$hourly_duration{"$h:$rd"} += ($normalyzed_info{$k}{chronos}{$d}{$h}{min_duration}{$m} || 0);
				}
				if ($#histo_avgs > 0) {
					foreach my $rd (@histo_avgs) {
						next if (!exists $hourly_count{"$h:$rd"});
						$details .= "<tr><td>$zday</td><td style=\"text-align: right\">$h:$rd</td><td>" .
							&comma_numbers($hourly_count{"$h:$rd"}) .   "</td><td>" .
							&convert_time($hourly_duration{"$h:$rd"}) . "</td><td>" .
							&convert_time($hourly_duration{"$h:$rd"}/($hourly_count{"$h:$rd"}||1)) .  "</td></tr>";
					}
				}
			}
		}
		# Set graph dataset
		my %graph_data = ();
		# we need a start date for flotr2 graph, we don't care of it as we just display HH:MM
		my $etime = timegm_nocheck(0, 0, 0, 18, 4, 80) * 1000;
		my $ctime = 0;
		foreach my $h ("00" .. "23") {
			foreach my $rd (@histo_avgs) {
				$ctime = (($h*3600)+($rd*60))*1000 + $etime;
				$graph_data{count} .= "[$ctime, " . (int($hourly_count{"$h:$rd"}/$days) || 0) . "],";
				$graph_data{duration} .= "[$ctime, " . (int($hourly_duration{"$h:$rd"} / ($hourly_count{"$h:$rd"} || 1)) || 0) . "],";
			}
		}
		$graph_data{count} =~ s/,$//;
		$graph_data{duration} =~ s/,$//;
		%hourly_count = ();
		%hourly_duration = ();
		$ctime = timegm_nocheck(0, 0, 0, 19, 4, 80) * 1000;

		my $users_involved = '';
		if (scalar keys %{$normalyzed_info{$k}{users}} > 0) {
			$users_involved = qq{<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#time-consuming-queries-user-involved-rank-$rank">User(s) involved</button>};
		}
		my $apps_involved = '';
		if (scalar keys %{$normalyzed_info{$k}{apps}} > 0) {
			$apps_involved = qq{<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#time-consuming-queries-app-involved-rank-$rank">App(s) involved</button>};
		}
		my $query_histo = 
		&flotr2_histograph($graphid++, 'timeconsuming_graph_'.$rank, $graph_data{count}, $graph_data{duration}, 'Avg. queries', 'Avg. duration', $etime, $ctime);

		print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$duration</td>
				<td>$count
					<p><a href="#time-consuming-queries-details-rank-$rank" class="btn btn-mini" data-toggle="collapse">Details</a></p>
				</td>
				<td>$min</td>
				<td>$max</td>
				<td>$avg</td>
				<td id="time-consuming-queries-examples-details-rank-$rank">
					<div id="query-e-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
						<!-- Details collapse -->
					    <div id="time-consuming-queries-details-rank-$rank" class="collapse">
						<h3>Times Reported <small>Time consuming queries #$rank</small></h3>
						$query_histo
								<table class="table table-stripped table-condensed">
									<thead>
										<tr>
											<th>Day</th>
											<th>Hour</th>
											<th>Count</th>
											<th>Duration</th>
											<th>Avg duration</th>
										</tr>
									</thead>
									<tbody>
										$details
									</tbody>
								</table>
						    <p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#time-consuming-queries-details-rank-$rank">x Hide</button></p>
						</div><!-- end of details collapse -->
	<p> <button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#time-consuming-queries-examples-rank-$rank">Examples</button> $users_involved $apps_involved</p>
};
		if (scalar keys %{$normalyzed_info{$k}{users}} > 0) {
			print $fh qq{
						<!-- Involved users list collapse -->
						<div id="time-consuming-queries-user-involved-rank-$rank" class="collapse">
							<dl>
};
			my $idx = 1;
			foreach my $u (sort {$normalyzed_info{$k}{users}{$b}{duration} <=> $normalyzed_info{$k}{users}{$a}{duration}} keys %{$normalyzed_info{$k}{users}}) {
				if ($normalyzed_info{$k}{users}{$u}{duration} > 0) {
					my $details = "[<b>User:</b> $u";
					$details .= " - <b>Total duration:</b> ".&convert_time($normalyzed_info{$k}{users}{$u}{duration});
					$details .= " - <b>Times executed:</b> $normalyzed_info{$k}{users}{$u}{count}";
					$details .= " ]\n";
					print $fh qq{
							<pre>$details</pre>
};
					$idx++;
				}
			}
			print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#time-consuming-queries-user-involved-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of user involved collapse -->
};
		}

		if (scalar keys %{$normalyzed_info{$k}{apps}} > 0) {
			print $fh qq{
						<!-- Involved apps list collapse -->
						<div id="time-consuming-queries-app-involved-rank-$rank" class="collapse">
							<dl>
};
			my $idx = 1;
			foreach my $u (sort {$normalyzed_info{$k}{apps}{$b}{duration} <=> $normalyzed_info{$k}{apps}{$a}{duration}} keys %{$normalyzed_info{$k}{apps}}) {
				if ($normalyzed_info{$k}{apps}{$u}{duration} > 0) {
					my $details = "[<b>Application:</b> $u";
					$details .= " - <b>Total duration:</b> ".&convert_time($normalyzed_info{$k}{apps}{$u}{duration});
					$details .= " - <b>Times executed:</b> $normalyzed_info{$k}{apps}{$u}{count}";
					$details .= " ]\n";
					print $fh qq{
							<pre>$details</pre>
};
					$idx++;
				}
			}
			print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#time-consuming-queries-app-involved-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of app involved collapse -->
};
		}
		print $fh qq{
						<!-- Examples collapse -->
						<div id="time-consuming-queries-examples-rank-$rank" class="collapse">
							<dl>
};

		my $idx = 1;
		foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
			my $details = "[ <b>Date:</b> $normalyzed_info{$k}{samples}{$d}{date}";
			$details .= " - <b>Duration:</b> " . &convert_time($d);
			$details .= " - <b>Database:</b> $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
			$details .= " - <b>User:</b> $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
			$details .= " - <b>Remote:</b> $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
			$details .= " - <b>Application:</b> $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
			$details .= " - <b>Bind query:</b> yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
			$details .= " ]";
			my $explain = '';
			if ($normalyzed_info{$k}{samples}{$d}{plan}) {
				my $url = $EXPLAIN_URL . url_escape($normalyzed_info{$k}{samples}{$d}{plan});
				$explain = "<div id=\"query-e-explain-$rank-$idx\" class=\"sql sql-largesize\"><a href=\"$url\" target=\"explain\" title=\"Click to beautify Explain Plan\"><i class=\"icon-compass\"></i><b>Explain plan</b></a></div>\n<pre>" . $normalyzed_info{$k}{samples}{$d}{plan} . "</pre>\n";
			}
			$query = &highlight_code($normalyzed_info{$k}{samples}{$d}{query});
			my $md5 = '';
			$md5 = 'md5: ' . md5_hex($normalyzed_info{$k}{samples}{$d}{query}) if ($enable_checksum);
			print $fh qq{
								<dt>
								<div id="query-e-$rank-$idx" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
								</dt>
								<pre>$details</pre>
								$explain
};
			$idx++;
		}
		print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#time-consuming-queries-examples-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of details collapse -->
					</td>
				</tr>
};
		$rank++;
	}
	if (!$found) {
		print $fh qq{<tr><td colspan="3">$NODATA</td></tr>};
	}
	print $fh qq{
			</tbody>
			</table>
		</div>
	</div><!-- end of time-consuming-queries -->
};

}

sub print_most_frequent
{
        print $fh qq{
                <div class="analysis-item row-fluid" id="most-frequent-queries">
                        <h2><i class="icon-signal"></i> Most frequent queries (N)</h2>
                        <div class="span11">
                                <table class="table table-striped" id="most-frequent-queries-table">
                                <thead>
                                <tr>
                                        <th>Rank</th>
                                        <th>Times executed</th>
                                        <th>Total duration</th>
                                        <th>Min duration</th>
                                        <th>Max duration</th>
                                        <th>Avg duration</th>
                                        <th>Query</th>
                                </tr>
                                </thead>
                                <tbody>
};
	my $rank = 1;
	foreach my $k (sort {$normalyzed_info{$b}{count} <=> $normalyzed_info{$a}{count}} keys %normalyzed_info) {
		next if (!$normalyzed_info{$k}{count});
		last if ($rank > $top);
		$normalyzed_info{$k}{average} = $normalyzed_info{$k}{duration} / $normalyzed_info{$k}{count};
		my $duration = &convert_time($normalyzed_info{$k}{duration});
		my $count = &comma_numbers($normalyzed_info{$k}{count});
		my $min = &convert_time($normalyzed_info{$k}{min});
		my $max = &convert_time($normalyzed_info{$k}{max});
		my $avg = &convert_time($normalyzed_info{$k}{average});
		my $query = &highlight_code($k);
		my $md5 = '';
		$md5 = 'md5: ' . md5_hex($k) if ($enable_checksum);
		my %hourly_count = ();
		my %hourly_duration = ();
		my $days = 0;
                my $details = '';
		foreach my $d (sort keys %{$normalyzed_info{$k}{chronos}}) {
			$d =~ /^\d{4}(\d{2})(\d{2})$/;
			$days++;
			my $zday = "$abbr_month{$1} $2";
			foreach my $h (sort keys %{$normalyzed_info{$k}{chronos}{$d}}) {
				$normalyzed_info{$k}{chronos}{$d}{$h}{average} =
					$normalyzed_info{$k}{chronos}{$d}{$h}{duration} / $normalyzed_info{$k}{chronos}{$d}{$h}{count};
				$details .= "<tr><td>$zday</td><td>$h</td><td>" .
					&comma_numbers($normalyzed_info{$k}{chronos}{$d}{$h}{count}) .   "</td><td>" .
					&convert_time($normalyzed_info{$k}{chronos}{$d}{$h}{duration}) . "</td><td>" .
					&convert_time($normalyzed_info{$k}{chronos}{$d}{$h}{average}) .  "</td></tr>";
				$zday = "";
				foreach my $m (sort keys %{$normalyzed_info{$k}{chronos}{$d}{$h}{min}}) {
					my $rd = &average_per_minutes($m, $histo_avg_minutes);
					$hourly_count{"$h:$rd"} += $normalyzed_info{$k}{chronos}{$d}{$h}{min}{$m};
					$hourly_duration{"$h:$rd"} += ($normalyzed_info{$k}{chronos}{$d}{$h}{min_duration}{$m} || 0);
				}
				if ($#histo_avgs > 0) {
					foreach my $rd (@histo_avgs) {
						next if (!exists $hourly_count{"$h:$rd"});
						$details .= "<tr><td>$zday</td><td style=\"text-align: right\">$h:$rd</td><td>" .
							&comma_numbers($hourly_count{"$h:$rd"}) .   "</td><td>" .
							&convert_time($hourly_duration{"$h:$rd"}) . "</td><td>" .
							&convert_time($hourly_duration{"$h:$rd"}/($hourly_count{"$h:$rd"}||1)) .  "</td></tr>";
					}
				}
			}
		}
		# Set graph dataset
		my %graph_data = ();
		# we need a start date for flotr2 graph, we don't care of it as we just display HH:MM
		my $etime = timegm_nocheck(0, 0, 0, 18, 4, 80) * 1000;
		my $ctime = 0;
                foreach my $h ("00" .. "23") {
			foreach my $rd (@histo_avgs) {
				$ctime = (($h*3600)+($rd*60))*1000 + $etime;
				$graph_data{count} .= "[$ctime, " . (int($hourly_count{"$h:$rd"}/$days) || 0) . "],";
				$graph_data{duration} .= "[$ctime, " . (int($hourly_duration{"$h:$rd"} / ($hourly_count{"$h:$rd"} || 1)) || 0) . "],";
			}
		}
		$graph_data{count} =~ s/,$//;
		$graph_data{duration} =~ s/,$//;
		%hourly_count = ();
		%hourly_duration = ();
		$ctime = timegm_nocheck(0, 0, 0, 19, 4, 80) * 1000;

                my $query_histo =
                &flotr2_histograph($graphid++, 'mostfrequent_graph_'.$rank, $graph_data{count}, $graph_data{duration}, 'Avg. queries', 'Avg. duration', $etime, $ctime);

		my $users_involved = '';
		if (scalar keys %{$normalyzed_info{$k}{users}} > 0) {
			$users_involved = qq{<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-queries-user-involved-rank-$rank">User(s) involved</button>};
		}
		my $apps_involved = '';
		if (scalar keys %{$normalyzed_info{$k}{apps}} > 0) {
			$apps_involved = qq{<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-queries-app-involved-rank-$rank">App(s) involved</button>};
		}

                print $fh qq{
                                <tr>
                                <td>$rank</td>
                                <td>$count
                                        <p><a href="#most-frequent-queries-details-rank-$rank" class="btn btn-mini" data-toggle="collapse">Details</a></p>
                                </td>
                                <td>$duration</td>
                                <td>$min</td>
                                <td>$max</td>
                                <td>$avg</td>
                                <td id="most-frequent-queries-examples-details-rank-$rank">
                                        <div id="query-f-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
                                                <!-- Details collapse -->
                                            <div id="most-frequent-queries-details-rank-$rank" class="collapse">
                                                <h3>Times Reported <small>Time consuming queries #$rank</small></h3>
						$query_histo
                                                                <table class="table table-stripped table-condensed">
                                                                        <thead>
                                                                                <tr>
                                                                                        <th>Day</th>
                                                                                        <th>Hour</th>
                                                                                        <th>Count</th>
                                                                                        <th>Duration</th>
                                                                                        <th>Avg duration</th>
                                                                                </tr>
                                                                        </thead>
                                                                        <tbody>
										$details
									</tbody>
								</table>
						    <p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-queries-details-rank-$rank">x Hide</button></p>
						</div><!-- end of details collapse -->
	<p><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-queries-examples-rank-$rank">Examples</button> $users_involved $apps_involved</p>
};
		if (scalar keys %{$normalyzed_info{$k}{users}} > 0) {
			print $fh qq{
						<!-- Involved users list collapse -->
						<div id="most-frequent-queries-user-involved-rank-$rank" class="collapse">
							<dl>
};
			my $idx = 1;
			foreach my $u (sort {$normalyzed_info{$k}{users}{$b}{duration} <=> $normalyzed_info{$k}{users}{$a}{duration}} keys %{$normalyzed_info{$k}{users}}) {
				if ($normalyzed_info{$k}{users}{$u}{duration} > 0) {
					my $details = "[<b>User:</b> $u";
					$details .= " - <b>Total duration:</b> ".&convert_time($normalyzed_info{$k}{users}{$u}{duration});
					$details .= " - <b>Times executed:</b> $normalyzed_info{$k}{users}{$u}{count}";
					$details .= " ]\n";
					print $fh qq{
							<pre>$details</pre>
};
					$idx++;
				}
			}
			print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-queries-user-involved-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of user involved collapse -->
};
		}
		if (scalar keys %{$normalyzed_info{$k}{apps}} > 0) {
			print $fh qq{
						<!-- Involved apps list collapse -->
						<div id="most-frequent-queries-app-involved-rank-$rank" class="collapse">
							<dl>
};
			my $idx = 1;
			foreach my $u (sort {$normalyzed_info{$k}{apps}{$b}{duration} <=> $normalyzed_info{$k}{apps}{$a}{duration}} keys %{$normalyzed_info{$k}{apps}}) {
				if ($normalyzed_info{$k}{apps}{$u}{duration} > 0) {
					my $details = "[<b>Application:</b> $u";
					$details .= " - <b>Total duration:</b> ".&convert_time($normalyzed_info{$k}{apps}{$u}{duration});
					$details .= " - <b>Times executed:</b> $normalyzed_info{$k}{apps}{$u}{count}";
					$details .= " ]\n";
					print $fh qq{
							<pre>$details</pre>
};
					$idx++;
				}
			}
			print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-queries-app-involved-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of app involved collapse -->
};
		}
		print $fh qq{

						<!-- Examples collapse -->
						<div id="most-frequent-queries-examples-rank-$rank" class="collapse">
							<dl>
};

		my $idx = 1;
		foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
			my $details = "[ <b>Date:</b> $normalyzed_info{$k}{samples}{$d}{date}";
			$details .= " - <b>Duration:</b> " . &convert_time($d);
			$details .= " - <b>Database:</b> $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
			$details .= " - <b>User:</b> $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
			$details .= " - <b>Remote:</b> $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
			$details .= " - <b>Application:</b> $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
			$details .= " - <b>Bind query:</b> yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
			$details .= " ]";
			my $explain = '';
			if ($normalyzed_info{$k}{samples}{$d}{plan}) {
				my $url = $EXPLAIN_URL . url_escape($normalyzed_info{$k}{samples}{$d}{plan});
				$explain = "<div id=\"query-f-explain-$rank-$idx\" class=\"sql sql-largesize\"><a href=\"$url\" target=\"explain\" title=\"Click to beautify Explain Plan\"><i class=\"icon-compass\"></i><b>Explain plan</b></a></div>\n<pre>" . $normalyzed_info{$k}{samples}{$d}{plan} . "</pre>";
			}
			$query = &highlight_code($normalyzed_info{$k}{samples}{$d}{query});
			my $md5 = '';
			$md5 = 'md5: ' . md5_hex($normalyzed_info{$k}{samples}{$d}{query}) if ($enable_checksum);
			print $fh qq{
								<dt>
								<div id="query-f-$rank-$idx" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
								</dt>
								<pre>$details</pre>
								$explain
};
			$idx++;
		}
                print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-queries-examples-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of details collapse -->
					</td>
				</tr>
};
		$rank++;
	}
	if (scalar keys %normalyzed_info == 0) {
		print $fh qq{<tr><td colspan="7">$NODATA</td></tr>};
	}
        print $fh qq{
			</tbody>
			</table>
		</div>
	</div><!-- end of most-frequent-queries -->
};

}


sub print_slowest_queries
{
	print $fh qq{
		<div class="analysis-item row-fluid" id="normalized-slowest-queries">
			<h2><i class="icon-time"></i> Normalized slowest queries (N)</h2>
			<div class="span11">
				<table class="table table-striped" id="normalized-slowest-queries-table">
				<thead>
				<tr>
					<th>Rank</th>
					<th>Min duration</th>
					<th>Max duration</th>
					<th>Avg duration</th>
					<th>Times executed</th>
					<th>Total duration</th>
					<th>Query</th>
				</tr>
				</thead>
				<tbody>
};
	my $rank = 1;
	my $found = 0;
	foreach my $k (sort {$normalyzed_info{$b}{average} <=> $normalyzed_info{$a}{average}} keys %normalyzed_info) {
		next if (!$k || !$normalyzed_info{$k}{count} || !exists $normalyzed_info{$k}{duration});
		last if ($rank > $top);
		$found++;
                $normalyzed_info{$k}{average} = $normalyzed_info{$k}{duration} / $normalyzed_info{$k}{count};
                my $duration = &convert_time($normalyzed_info{$k}{duration});
                my $count = &comma_numbers($normalyzed_info{$k}{count});
                my $min = &convert_time($normalyzed_info{$k}{min});
                my $max = &convert_time($normalyzed_info{$k}{max});
                my $avg = &convert_time($normalyzed_info{$k}{average});
                my $query = &highlight_code($k);
		my $md5 = '';
		$md5 = 'md5: ' . md5_hex($k) if ($enable_checksum);
		my $details = '';
		my %hourly_count = ();
		my %hourly_duration = ();
		my $days = 0;
		foreach my $d (sort keys %{$normalyzed_info{$k}{chronos}}) {
			my $c = 1;
			$d =~ /^\d{4}(\d{2})(\d{2})$/;
			$days++;
			my $zday = "$abbr_month{$1} $2";
			foreach my $h (sort keys %{$normalyzed_info{$k}{chronos}{$d}}) {
				$normalyzed_info{$k}{chronos}{$d}{$h}{average} =
					$normalyzed_info{$k}{chronos}{$d}{$h}{duration} / $normalyzed_info{$k}{chronos}{$d}{$h}{count};
				$details .= "<tr><td>$zday</td><td>$h</td><td>" .
					&comma_numbers($normalyzed_info{$k}{chronos}{$d}{$h}{count}) .   "</td><td>" .
					&convert_time($normalyzed_info{$k}{chronos}{$d}{$h}{duration}) . "</td><td>" .
					&convert_time($normalyzed_info{$k}{chronos}{$d}{$h}{average}) .  "</td></tr>";
				$zday = "";
				foreach my $m (sort keys %{$normalyzed_info{$k}{chronos}{$d}{$h}{min}}) {
					my $rd = &average_per_minutes($m, $histo_avg_minutes);
					$hourly_count{"$h:$rd"} += $normalyzed_info{$k}{chronos}{$d}{$h}{min}{$m};
					$hourly_duration{"$h:$rd"} += ($normalyzed_info{$k}{chronos}{$d}{$h}{min_duration}{$m} || 0);
				}
				if ($#histo_avgs > 0) {
					foreach my $rd (@histo_avgs) {
						next if (!exists $hourly_count{"$h:$rd"});
						$details .= "<tr><td>$zday</td><td style=\"text-align: right\">$h:$rd</td><td>" .
							&comma_numbers($hourly_count{"$h:$rd"}) .   "</td><td>" .
							&convert_time($hourly_duration{"$h:$rd"}) . "</td><td>" .
							&convert_time($hourly_duration{"$h:$rd"}/($hourly_count{"$h:$rd"}||1)) .  "</td></tr>";
					}
				}
			}
		}
		# Set graph dataset
		my %graph_data = ();
		# we need a start date for flotr2 graph, we don't care of it as we just display HH:MM
		my $etime = timegm_nocheck(0, 0, 0, 18, 4, 80) * 1000;
		my $ctime = 0;
		foreach my $h ("00" .. "23") {
			foreach my $rd (@histo_avgs) {
				$ctime = (($h*3600)+($rd*60))*1000 + $etime;
				$graph_data{count} .= "[$ctime, " . (int($hourly_count{"$h:$rd"}/$days) || 0) . "],";
				$graph_data{duration} .= "[$ctime, " . (int($hourly_duration{"$h:$rd"} / ($hourly_count{"$h:$rd"} || 1)) || 0) . "],";
			}
		}
		$graph_data{count} =~ s/,$//;
		$graph_data{duration} =~ s/,$//;
		%hourly_count = ();
		%hourly_duration = ();
		$ctime = timegm_nocheck(0, 0, 0, 19, 4, 80) * 1000;

		my $query_histo =
		&flotr2_histograph($graphid++, 'normalizedslowest_graph_'.$rank, $graph_data{count}, $graph_data{duration}, 'Avg. queries', 'Avg. duration', $etime, $ctime);

		my $users_involved = '';
		if (scalar keys %{$normalyzed_info{$k}{users}} > 0) {
			$users_involved = qq{<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#normalized-slowest-queries-user-involved-rank-$rank">User(s) involved</button>};
		}
		my $apps_involved = '';
		if (scalar keys %{$normalyzed_info{$k}{apps}} > 0) {
			$apps_involved = qq{<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#normalized-slowest-queries-app-involved-rank-$rank">App(s) involved</button>};
		}

                print $fh qq{
                                <tr>
                                <td>$rank</td>
                                <td>$min</td>
                                <td>$max</td>
                                <td>$avg</td>
                                <td>$count
                                        <p><a href="#normalized-slowest-queries-details-rank-$rank" class="btn btn-mini" data-toggle="collapse">Details</a></p>
                                </td>
                                <td>$duration</td>
                                <td id="normalized-slowest-queries-examples-details-rank-$rank">
                                        <div id="query-g-$rank" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
                                                <!-- Details collapse -->
                                            <div id="normalized-slowest-queries-details-rank-$rank" class="collapse">
                                                <h3>Times Reported <small>Time consuming queries #$rank</small></h3>
						$query_histo
                                                                <table class="table table-stripped table-condensed">
                                                                        <thead>
                                                                                <tr>
                                                                                        <th>Day</th>
                                                                                        <th>Hour</th>
                                                                                        <th>Count</th>
                                                                                        <th>Duration</th>
                                                                                        <th>Avg duration</th>
                                                                                </tr>
                                                                        </thead>
                                                                        <tbody>
										$details
									</tbody>
								</table>
						    <p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#normalized-slowest-queries-details-rank-$rank">x Hide</button></p>
						</div><!-- end of details collapse -->
	<p><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#normalized-slowest-queries-examples-rank-$rank">Examples</button> $users_involved</p>
};
		if (scalar keys %{$normalyzed_info{$k}{users}} > 0) {
			print $fh qq{
						<!-- Involved users list collapse -->
						<div id="normalized-slowest-queries-user-involved-rank-$rank" class="collapse">
							<dl>
};
			my $idx = 1;
			foreach my $u (sort {$normalyzed_info{$k}{users}{$b}{duration} <=> $normalyzed_info{$k}{users}{$a}{duration}} keys %{$normalyzed_info{$k}{users}}) {
				if ($normalyzed_info{$k}{users}{$u}{duration} > 0) {
					my $details = "[<b>User:</b> $u";
					$details .= " - <b>Total duration:</b> ".&convert_time($normalyzed_info{$k}{users}{$u}{duration});
					$details .= " - <b>Times executed:</b> $normalyzed_info{$k}{users}{$u}{count}";
					$details .= " ]\n";
					print $fh qq{
							<pre>$details</pre>
};
					$idx++;
				}
			}
			print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#normalized-slowest-queries-user-involved-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of user involved collapse -->
};
		}
		if (scalar keys %{$normalyzed_info{$k}{apps}} > 0) {
			print $fh qq{
						<!-- Involved apps list collapse -->
						<div id="normalized-slowest-queries-app-involved-rank-$rank" class="collapse">
							<dl>
};
			my $idx = 1;
			foreach my $u (sort {$normalyzed_info{$k}{apps}{$b}{duration} <=> $normalyzed_info{$k}{apps}{$a}{duration}} keys %{$normalyzed_info{$k}{apps}}) {
				if ($normalyzed_info{$k}{apps}{$u}{duration} > 0) {
					my $details = "[<b>Application:</b> $u";
					$details .= " - <b>Total duration:</b> ".&convert_time($normalyzed_info{$k}{apps}{$u}{duration});
					$details .= " - <b>Times executed:</b> $normalyzed_info{$k}{apps}{$u}{count}";
					$details .= " ]\n";
					print $fh qq{
							<pre>$details</pre>
};
					$idx++;
				}
			}
			print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#normalized-slowest-queries-app-involved-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of app involved collapse -->
};
		}
		print $fh qq{

						<!-- Examples collapse -->
						<div id="normalized-slowest-queries-examples-rank-$rank" class="collapse">
							<dl>
};

		my $idx = 1;
		foreach my $d (sort {$b <=> $a} keys %{$normalyzed_info{$k}{samples}}) {
			my $details = "[ <b>Date:</b> $normalyzed_info{$k}{samples}{$d}{date}";
			$details .= " - <b>Duration:</b> " . &convert_time($d);
			$details .= " - <b>Database:</b> $normalyzed_info{$k}{samples}{$d}{db}" if ($normalyzed_info{$k}{samples}{$d}{db});
			$details .= " - <b>User:</b> $normalyzed_info{$k}{samples}{$d}{user}" if ($normalyzed_info{$k}{samples}{$d}{user});
			$details .= " - <b>Remote:</b> $normalyzed_info{$k}{samples}{$d}{remote}" if ($normalyzed_info{$k}{samples}{$d}{remote});
			$details .= " - <b>Application:</b> $normalyzed_info{$k}{samples}{$d}{app}" if ($normalyzed_info{$k}{samples}{$d}{app});
			$details .= " - <b>Bind query:</b> yes" if ($normalyzed_info{$k}{samples}{$d}{bind});
			$details .= " ]";
			my $explain = '';
			if ($normalyzed_info{$k}{samples}{$d}{plan}) {
				my $url = $EXPLAIN_URL . url_escape($normalyzed_info{$k}{samples}{$d}{plan});
				$explain = "<div id=\"query-g-explain-$rank-$idx\" class=\"sql sql-largesize\"><a href=\"$url\" target=\"explain\" title=\"Click to beautify Explain Plan\"><i class=\"icon-compass\"></i><b>Explain plan</b></a></div>\n<pre>" . $normalyzed_info{$k}{samples}{$d}{plan} . "</pre>\n";
			}
			$query = &highlight_code($normalyzed_info{$k}{samples}{$d}{query});
			my $md5 = '';
			$md5 = 'md5: ' . md5_hex($normalyzed_info{$k}{samples}{$d}{query}) if ($enable_checksum);
			print $fh qq{
								<dt>
								<div id="query-g-$rank-$idx" class="sql sql-largesize"><i class="icon-copy" title="Click to select query"></i>$query</div>$md5
								</dt>
								<pre>$details</pre>
								$explain
};
			$idx++;
		}
                print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#normalized-slowest-queries-examples-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of details collapse -->
					</td>
				</tr>
};
		$rank++;
	}
	if (!$found) {
		print $fh qq{<tr><td colspan="3">$NODATA</td></tr>};
	}
        print $fh qq{
			</tbody>
			</table>
		</div>
	</div><!-- end of normalized-slowest-queries -->
};

}

sub dump_as_html
{

	my $uri = shift;

	# Dump the html header
	&html_header($uri);

	if (!$error_only) {

		# Overall statistics
		print $fh qq{
	<li class="slide active-slide" id="overview-slide">
};
		&print_overall_statistics();

		# Set graphs limits
		$overall_stat{'first_log_ts'} =~ /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/;
		$t_min = timegm_nocheck(0, $5, $4, $3, $2 - 1, $1) * 1000;
		$t_min -= ($avg_minutes * 60000);

		$overall_stat{'last_log_ts'} =~ /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/;
		$t_max = timegm_nocheck(59, $5, $4, $3, $2 - 1, $1) * 1000;
		$t_max += ($avg_minutes * 60000);

		if (!$disable_hourly) {
			# Build graphs based on hourly stat
			&compute_query_graphs();

			# Show global SQL traffic
			&print_sql_traffic();

			# Show hourly statistics
			&print_general_activity();

		}

		if (!$disable_connection) {
			print $fh qq{
		</li>
		<li class="slide" id="connections-slide">
	<h1 class="page-header"><i class="icon-external-link-sign"></i> Connections</h1>

};

			# Draw connections information
			&print_established_connection() if (!$disable_hourly);

			# Show per database/user connections
			&print_database_connection() if (exists $connection_info{database});

			# Show per user connections
			&print_user_connection() if (exists $connection_info{user});

			# Show per client ip connections
			&print_host_connection() if (exists $connection_info{host});
		}


		# Show session per database statistics
		if (!$disable_session) {
			print $fh qq{
		</li>
		<li class="slide" id="sessions-slide">
	<h1 class="page-header"><i class="icon-off"></i> Sessions</h1>

};
			# Show number of simultaneous sessions
			&print_simultaneous_session();
			# Show histogram for session times
			&print_histogram_session_times();
			# Show per database sessions
			&print_database_session();
			# Show per user sessions
			&print_user_session();
			# Show per host sessions
			&print_host_session();
			# Show per application sessions
			&print_app_session();
		}


		# Display checkpoint and temporary files report
		if (!$disable_checkpoint) {
			print $fh qq{
		</li>
		<li class="slide" id="checkpoints-slide">
	};
			&print_checkpoint();
		}

		if (!$disable_temporary) {
			print $fh qq{
		</li>
		<li class="slide" id="tempfiles-slide">
};
			# Show temporary files detailed information
			&print_temporary_file();

			# Show information about queries generating temporary files
			&print_tempfile_report();
		}

		if (!$disable_autovacuum) {
			print $fh qq{
		</li>
		<li class="slide" id="vacuums-slide">
};
			# Show detailed vacuum/analyse information
			&print_vacuum();

		}

		if (!$disable_lock) {
			print $fh qq{
		</li>
		<li class="slide" id="locks-slide">
};
			# Lock stats per type
			&print_lock_type();

			# Show lock wait detailed information
			&print_lock_queries_report();
		}

		if (!$disable_query) {
			print $fh qq{
		</li>
		<li class="slide" id="queries-slide">
};
			# INSERT/DELETE/UPDATE/SELECT repartition
			if (!$disable_type) {
				&print_query_type();

				# Show requests per database
				&print_query_per_database();

				# Show requests per user
				&print_query_per_user();

				# Show requests per host
				&print_query_per_host();

				# Show requests per application
				&print_query_per_application();
;
				# Show cancelled queries detailed information
				&print_cancelled_queries();

				# Show information about cancelled queries
				&print_cancelled_report();

			}

			print $fh qq{
		</li>
		<li class="slide" id="topqueries-slide">
};
			# Show histogram for query times
			&print_histogram_query_times();

			# Show top information
			&print_slowest_individual_queries();

			# Show queries that took up the most time
			&print_time_consuming();

			# Show most frequent queries
			&print_most_frequent();

			# Print normalized slowest queries
			&print_slowest_queries
		}

	}

	# Show errors report
	if (!$disable_error) {

		if (!$error_only) {
			print $fh qq{
		</li>
		<li class="slide" id="events-slide">
};
		} else {
			print $fh qq{
		<li class="slide active-slide" id="events-slide">
};
		}
		# Show log level distribution
		&print_log_level();

		# Show Most Frequent Errors/Events
		&show_error_as_html();
	}

	# Dump the html footer
	&html_footer();

}

sub url_escape
{
	my $toencode = shift;

	return if (!$toencode);

	utf8::encode($toencode) if (($] >= 5.008) && utf8::is_utf8($toencode));

	if (EBCDIC) {
		$toencode =~ s/([^a-zA-Z0-9_.~-])/uc sprintf("%%%02x",$E2A[ord($1)])/eg;
	} else {
		$toencode =~ s/([^a-zA-Z0-9_.~-])/uc sprintf("%%%02x",ord($1))/eg;
	}

	return $toencode;
}

sub escape_html
{
	$_[0] =~ s/<([\/a-zA-Z][\s\t\>]*)/\&lt;$1/sg;

	return $_[0];
}

sub print_log_level
{
	my %infos = ();

	# Some messages have seen their log level change during log parsing.
	# Set the real log level count back
	foreach my $k (sort {$error_info{$b}{count} <=> $error_info{$a}{count}} keys %error_info) {
		next if (!$error_info{$k}{count});
		if ($error_info{$k}{count} > 1) {
			for (my $i = 0 ; $i <= $#{$error_info{$k}{date}} ; $i++) {
				if (   ($error_info{$k}{error}[$i] =~ s/ERROR:  (parameter "[^"]+" changed to)/LOG:  $1/)
					|| ($error_info{$k}{error}[$i] =~ s/ERROR:  (database system was shut down)/LOG:  $1/)
					|| ($error_info{$k}{error}[$i] =~ s/ERROR:  (database system was interrupted while in recovery)/LOG:  $1/)
					|| ($error_info{$k}{error}[$i] =~ s/ERROR:  (recovery has paused)/LOG:  $1/))
				{
					$logs_type{ERROR}--;
					$logs_type{LOG}++;
				}
			}
		} else {
			if (   ($error_info{$k}{error}[0] =~ s/ERROR:  (parameter "[^"]+" changed to)/LOG:  $1/)
				|| ($error_info{$k}{error}[0] =~ s/ERROR:  (database system was shut down)/LOG:  $1/)
				|| ($error_info{$k}{error}[0] =~ s/ERROR:  (database system was interrupted while in recovery)/LOG:  $1/)
				|| ($error_info{$k}{error}[0] =~ s/ERROR:  (recovery has paused)/LOG:  $1/))
			{
				$logs_type{ERROR}--;
				$logs_type{LOG}++;
			}
		}
	}

	# Show log types
	my $total_logs = 0;
	foreach my $d (sort keys %logs_type) {
		$total_logs += $logs_type{$d};
	}

	my $logtype_info = '';
	foreach my $d (sort keys %logs_type) {
		next if (!$logs_type{$d});
		$logtype_info .= "<tr><td>$d</td><td>" . &comma_numbers($logs_type{$d}) .
			"</td><td>" . sprintf("%0.2f", ($logs_type{$d} * 100) / ($total_logs||1)) . "%</td></tr>";
	}
	my %graph_data = ();
	my %max_events = ();
	if ($graph) {
		my @small = ();
		foreach my $d (sort keys %logs_type) {
			if ((($logs_type{$d} * 100) / ($total_logs || 1)) > $pie_percentage_limit) {
				$infos{$d} = $logs_type{$d} || 0;
			} else {
				$infos{"Sum log types < $pie_percentage_limit%"} += $logs_type{$d} || 0;
				push(@small, $d);
			}
		}

		if ($#small == 0) {
			$infos{$small[0]} = $infos{"Sum log types < $pie_percentage_limit%"};
			delete $infos{"Sum log types < $pie_percentage_limit%"};
		}
		foreach my $l (qw(FATAL WARNING ERROR PANIC)) {
			$max_events{$l} = 0;
		}
		foreach my $tm (sort {$a <=> $b} keys %per_minute_info) {
			$tm =~ /(\d{4})(\d{2})(\d{2})/;
			my $y  = $1 - 1900;
			my $mo = $2 - 1;
			my $d  = $3;
			foreach my $h ("00" .. "23") {
				next if (!exists $per_minute_info{$tm}{$h});
				my %e_dataavg = ();
				foreach my $m ("00" .. "59") {
					next if (!exists $per_minute_info{$tm}{$h}{$m});

					my $rd = &average_per_minutes($m, $avg_minutes);

					if (exists $per_minute_info{$tm}{$h}{$m}{log_level}) {

						# Average per minute
						foreach my $l (qw(FATAL WARNING ERROR PANIC)) {
							$e_dataavg{$l}{"$rd"} += ($per_minute_info{$tm}{$h}{$m}{log_level}{$l} || 0);
							$max_events{$l} += ($per_minute_info{$tm}{$h}{$m}{log_level}{$l} || 0);
						}
						delete $per_minute_info{$tm}{$h}{$m}{log_level};
					}
				}

				foreach my $rd (@avgs) {
					my $t = timegm_nocheck(0, $rd, $h, $d, $mo, $y) * 1000;

					next if ($t < $t_min);
					last if ($t > $t_max);

					if (scalar keys %e_dataavg> 0) {
						foreach my $l (qw(FATAL ERROR PANIC WARNING)) {
							$graph_data{$l} .= "[$t, " . ($e_dataavg{$l}{"$rd"} || 0) . "],";
						}
					}
				}
			}
		}
		foreach (keys %graph_data) {
			$graph_data{$_} =~ s/,$//;
		}

	}

	$drawn_graphs{'eventspersecond_graph'} = &flotr2_graph( $graphid++, 'eventspersecond_graph', $graph_data{'PANIC'},
		$graph_data{FATAL}, $graph_data{'ERROR'}, 'Errors per ' . $avg_minutes . ' minutes',
		'Errors per ' . $avg_minutes . ' minutes', 'PANIC', 'FATAL', 'ERROR', '', $graph_data{'WARNING'}, 'WARNING'
	);

	$drawn_graphs{logstype_graph} = &flotr2_piegraph($graphid++, 'graph_logstype', 'Logs per type', %infos);
	if (!$total_logs) {
		$logtype_info = qq{<tr><td colspan="7">$NODATA</td></tr>};
	}
	$logs_type{ERROR} ||= 0;
	$logs_type{FATAL} ||= 0;
	$total_logs = &comma_numbers($total_logs);
	print $fh qq{
	<h1 class="page-header"><i class="icon-bullhorn"></i> Events</h1>

	<div class="analysis-item row-fluid" id="log-levels">
		<h2><i class="icon-tags"></i> Log levels</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$total_logs</span> <span class="figure-label">Log entries</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<div class="tabbable">
				<ul class="nav nav-tabs">
					<li class="active"><a href="#log-level-graph" data-toggle="tab">Chart</a></li>
					<li><a href="#log-level-table" data-toggle="tab">Table</a></li>
				</ul>
				<div class="tab-content">
					<div class="tab-pane active" id="log-level-graph">
						$drawn_graphs{logstype_graph}
					</div>
					<div class="tab-pane" id="log-level-table">
						<table class="table table-striped table-hover">
							<thead>
								<tr>
									<th>Type</th>
									<th>Count</th>
									<th>Percentage</th>
								</tr>
							</thead>
							<tbody>
							$logtype_info
							</tbody>
						</table>    
					</div>
				</div>
			</div>
		</div>
	</div><!-- end of event flow -->

	<div class="analysis-item row-fluid" id="minutes-errors-levels">
		<h2><i class="icon-tags"></i> Events distribution</h2>
		<div class="span3">
			<h3 class="">Key values</h3>
			<div class="well key-figures">
				<ul>
					<li><span class="figure">$max_events{PANIC}</span> <span class="figure-label">PANIC entries</span></li>
					<li><span class="figure">$max_events{FATAL}</span> <span class="figure-label">FATAL entries</span></li>
					<li><span class="figure">$max_events{ERROR}</span> <span class="figure-label">ERROR entries</span></li>
					<li><span class="figure">$max_events{WARNING}</span> <span class="figure-label">WARNING entries</span></li>
				</ul>
			</div>
		</div>
		<div class="span8">
			<h3 class="">Errors per $avg_minutes minutes</h3>
$drawn_graphs{'eventspersecond_graph'}
		</div>
	</div><!-- end of errors per minutes -->

};
	delete $drawn_graphs{logstype_graph};
	delete $drawn_graphs{'eventspersecond_graph'};

}

sub show_error_as_html
{

	my $main_error = 0;
	my $total = 0;
	foreach my $k (sort {$error_info{$b}{count} <=> $error_info{$a}{count}} keys %error_info) {
		next if (!$error_info{$k}{count});
		$main_error = &comma_numbers($error_info{$k}{count}) if (!$main_error);
		$total += $error_info{$k}{count};
	}
	$total = &comma_numbers($total);

	print $fh qq{
		<div class="analysis-item row-fluid" id="most-frequent-errors-events">
  	  		<h2><i class="icon-warning-sign"></i> Most Frequent Errors/Events</h2>
			<div class="span3">
				<h3 class="">Key values</h3>
				<div class="well key-figures">
					<ul>
						<li><span class="figure">$main_error</span> <span class="figure-label">Max number of times the same event was reported</span></li>
						<li><span class="figure">$total</span> <span class="figure-label">Total events found</span></li>    
					</ul>
				</div>  	  
  	  		</div>
  	  		<div class="span8">
				<table class="table table-striped" id="most-frequent-errors-events-table">
				<thead>
					<tr>
						<th>Rank</th>
						<th>Times reported</th>
						<th>Error</th>
					</tr>
				</thead>
				<tbody>
};
	my $rank = 1;
	foreach my $k (sort {$error_info{$b}{count} <=> $error_info{$a}{count}} keys %error_info) {
		next if (!$error_info{$k}{count});
		my $count = &comma_numbers($error_info{$k}{count});
		my $msg = $k;
		$msg =~ s/ERROR:  (parameter "[^"]+" changed to)/LOG:  $1/;
		$msg =~ s/ERROR:  (database system was shut down)/LOG:  $1/;
		$msg =~ s/ERROR:  (database system was interrupted while in recovery)/LOG:  $1/;
		$msg =~ s/ERROR:  (recovery has paused)/LOG:  $1/;
		my $error_level_class = 'text-error';
		if ($msg =~ /^WARNING: /) {
			$error_level_class = 'text-warning';
		} elsif ($msg =~ /^LOG: /) {
			$error_level_class = 'text-success';
		} elsif ($msg =~ /^HINT: /) {
			$error_level_class = 'text-info';
		} elsif ($msg =~ /^FATAL: /) {
			$error_level_class = 'text-fatal';
		} elsif ($msg =~ /^PANIC: /) {
			$error_level_class = 'text-panic';
		}
		my $details = '';
                my %hourly_count = ();
                my $days = 0;
		foreach my $d (sort keys %{$error_info{$k}{chronos}}) {
			my $c = 1;
			$d =~ /^\d{4}(\d{2})(\d{2})$/;
			$days++;
			my $zday = "$abbr_month{$1} $2";
			foreach my $h (sort keys %{$error_info{$k}{chronos}{$d}}) {
				$details .= "<tr><td>$zday</td><td>$h</td><td>" .
					&comma_numbers($error_info{$k}{chronos}{$d}{$h}{count}) . "</td></tr>";
				$zday = "";
				foreach my $m (sort keys %{$error_info{$k}{chronos}{$d}{$h}{min}}) {
					my $rd = &average_per_minutes($m, $histo_avg_minutes);
					$hourly_count{"$h:$rd"} += $error_info{$k}{chronos}{$d}{$h}{min}{$m};
				}
				if ($#histo_avgs > 0) {
					foreach my $rd (@histo_avgs) {
						next if (!exists $hourly_count{"$h:$rd"});
						$details .= "<tr><td>$zday</td><td style=\"text-align: right\">$h:$rd</td><td>" .
							&comma_numbers($hourly_count{"$h:$rd"}) . "</td></tr>";
					}
				}
			}
		}
                # Set graph dataset
                my %graph_data = ();
		# we need a start date for flotr2 graph, we don't care of it as we just display HH:MM
		my $etime = timegm_nocheck(0, 0, 0, 18, 4, 80) * 1000;
		my $ctime = 0;
                foreach my $h ("00" .. "23") {
			foreach my $rd (@histo_avgs) {
				$ctime = (($h*3600)+($rd*60))*1000 + $etime;
				$graph_data{count} .= "[$ctime, " . (int($hourly_count{"$h:$rd"}/$days) || 0) . "],";
			}
                }
		$graph_data{count} =~ s/,$//;
                %hourly_count = ();
		$ctime = timegm_nocheck(0, 0, 0, 19, 4, 80) * 1000;

                my $error_histo =
                &flotr2_histograph($graphid++, 'error_graph_'.$rank, $graph_data{count}, '', 'Avg. events', '', $etime, $ctime);

		# Escape HTML code in error message
		$msg = &escape_html($msg);
		print $fh qq{
				<tr>
				<td>$rank</td>
				<td>$count
					<p><a href="#most-frequent-errors-events-details-rank-$rank" class="btn btn-mini" data-toggle="collapse">Details</a></p>
				</td>
				<td id="most-frequent-errors-events-examples-details-rank-$rank">
					<pre><span class="$error_level_class">$msg</span></pre>
						<!-- Details collapse -->
					    <div id="most-frequent-errors-events-details-rank-$rank" class="collapse">
						<h3>Times Reported <small>Most Frequent Error / Event #$rank</small></h3>
						$error_histo
								<table class="table table-stripped table-condensed">
									<thead>
										<tr>
											<th>Day</th>
											<th>Hour</th>
											<th>Count</th>
										</tr>
									</thead>
									<tbody>
										$details
									</tbody>
								</table>
						    <p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-errors-events-details-rank-$rank">x Hide</button></p>
						</div><!-- end of details collapse -->
};
		print $fh qq{
<p><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-errors-events-examples-rank-$rank">Examples</button></p>							   
} if (($sample > 0) && ($#{$error_info{$k}{date}} >= 0));
		print $fh qq{
						<!-- Examples collapse -->
						<div id="most-frequent-errors-events-examples-rank-$rank" class="collapse">
							<dl>
};

		for (my $i = 0 ; $i <= $#{$error_info{$k}{date}} ; $i++) {
			last if (($sample > 0) && ($i == $sample));
			# Escape HTML code in error message
			my $message = &escape_html($error_info{$k}{error}[$i]);
			my $details = "Date: " . $error_info{$k}{date}[$i] . "\n";
			if ($error_info{$k}{detail}[$i]) {
				$details .= "Detail: " . &escape_html($error_info{$k}{detail}[$i]) . "<br/>";
			}
			if ($error_info{$k}{context}[$i]) {
				$details .= "Context: " . &escape_html($error_info{$k}{context}[$i]) . "<br/>";
			}
			if ($error_info{$k}{hint}[$i]) {
				$details .= "Hint: " . &escape_html($error_info{$k}{hint}[$i]) . "<br/>";
			}
			if ($error_info{$k}{statement}[$i]) {
				$details .= "Statement: " . &escape_html($error_info{$k}{statement}[$i]) . "<br/>";
			}
			if ($error_info{$k}{db}[$i]) {
				$details .= "<b>Database:</b> $error_info{$k}{db}[$i] <b>User:</b> $error_info{$k}{user}[$i] <b>Remote:</b> $error_info{$k}{remote}[$i] <br/>";
			}
			print $fh qq{
								<dt><span class="$error_level_class">$message</span></dt>
								<pre>$details</pre>
};
		}
		print $fh qq{
							</dl>
							<p class="pull-right"><button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#most-frequent-errors-events-examples-rank-$rank">x Hide</button></p>
						</div>
						<!-- end of details collapse -->
					</td>
				</tr>
};
		$rank++;
	}
	if (scalar keys %error_info == 0) {
		print $fh qq{<tr><td colspan="7">$NODATA</td></tr>};
	}

	print $fh qq{
			</tbody>
			</table>
		</div>
	</div><!-- end of most-frequent-errors-events -->
};

}

sub load_stats
{

	my $fd = shift;

	my %stats = %{ fd_retrieve($fd) };
	my %_overall_stat = %{$stats{overall_stat}};
	my %_overall_checkpoint = %{$stats{overall_checkpoint}};
	my %_normalyzed_info = %{$stats{normalyzed_info}};
	my %_error_info = %{$stats{error_info}};
	my %_connection_info = %{$stats{connection_info}};
	my %_database_info = %{$stats{database_info}};
	my %_application_info = %{$stats{application_info}};
	my %_user_info = %{$stats{user_info}};
	my %_host_info = %{$stats{host_info}};
	my %_checkpoint_info = %{$stats{checkpoint_info}};
	my %_session_info = %{$stats{session_info}};
	my %_tempfile_info = %{$stats{tempfile_info}};
	my %_cancelled_info = %{$stats{cancelled_info}};
	my %_logs_type = %{$stats{logs_type}};
	my %_lock_info = %{$stats{lock_info}};
	my %_per_minute_info = %{$stats{per_minute_info}};
	my @_top_slowest = @{$stats{top_slowest}};
	my $_nlines = $stats{nlines};
	my $_first_log_timestamp = $stats{first_log_timestamp};
	my $_last_log_timestamp = $stats{last_log_timestamp};
	my @_log_files = @{$stats{log_files}};
	my %_autovacuum_info = %{$stats{autovacuum_info}};
	my %_autoanalyze_info = %{$stats{autoanalyze_info}};
	my @_top_locked_info = @{$stats{top_locked_info}};
	my @_top_tempfile_info = @{$stats{top_tempfile_info}};
	my @_top_cancelled_info = @{$stats{top_cancelled_info}};

	### overall_stat ###

	$overall_stat{queries_number} += $_overall_stat{queries_number};

	if ($_overall_stat{'first_log_ts'}) {
		$overall_stat{'first_log_ts'} = $_overall_stat{'first_log_ts'}
			if (!$overall_stat{'first_log_ts'} || 
				($overall_stat{'first_log_ts'} gt $_overall_stat{'first_log_ts'}));
	}

	$overall_stat{'last_log_ts'} = $_overall_stat{'last_log_ts'}
		if not $overall_stat{'last_log_ts'}
			or $overall_stat{'last_log_ts'} lt $_overall_stat{'last_log_ts'};

	if ($_overall_stat{'first_query_ts'}) {
		$overall_stat{'first_query_ts'} = $_overall_stat{'first_query_ts'}
			if (!$overall_stat{'first_query_ts'} ||
				($overall_stat{'first_query_ts'} gt $_overall_stat{'first_query_ts'}));
	}

	$overall_stat{'last_query_ts'} = $_overall_stat{'last_query_ts'}
		if not $overall_stat{'last_query_ts'} 
			or $overall_stat{'last_query_ts'} lt $_overall_stat{'last_query_ts'};

	$overall_stat{errors_number} += $_overall_stat{errors_number};
	$overall_stat{queries_duration} += $_overall_stat{queries_duration};

	$overall_stat{DELETE} += $_overall_stat{DELETE}
		if exists $_overall_stat{DELETE};
	$overall_stat{UPDATE} += $_overall_stat{UPDATE}
		if exists $_overall_stat{UPDATE};
	$overall_stat{INSERT} += $_overall_stat{INSERT}
		if exists $_overall_stat{INSERT};
	$overall_stat{SELECT} += $_overall_stat{SELECT}
		if exists $_overall_stat{SELECT};

	$overall_checkpoint{checkpoint_warning} += $_overall_checkpoint{checkpoint_warning};
	$overall_checkpoint{checkpoint_write} = $_overall_checkpoint{checkpoint_write}
		if ($_overall_checkpoint{checkpoint_write} > $overall_checkpoint{checkpoint_write});
	$overall_checkpoint{checkpoint_sync} = $_overall_checkpoint{checkpoint_sync}
		if ($_overall_checkpoint{checkpoint_sync} > $overall_checkpoint{checkpoint_sync});
	foreach my $k (keys %{$_overall_stat{peak}}) {
		$overall_stat{peak}{$k}{query} += $_overall_stat{peak}{$k}{query};
		$overall_stat{peak}{$k}{select} += $_overall_stat{peak}{$k}{select};
		$overall_stat{peak}{$k}{write} += $_overall_stat{peak}{$k}{write};
		$overall_stat{peak}{$k}{connection} += $_overall_stat{peak}{$k}{connection};
		$overall_stat{peak}{$k}{session} += $_overall_stat{peak}{$k}{session};
		$overall_stat{peak}{$k}{tempfile_size} += $_overall_stat{peak}{$k}{tempfile_size};
		$overall_stat{peak}{$k}{tempfile_count} += $_overall_stat{peak}{$k}{tempfile_count};
		$overall_stat{peak}{$k}{cancelled_size} += $_overall_stat{peak}{$k}{cancelled_size};
		$overall_stat{peak}{$k}{cancelled_count} += $_overall_stat{peak}{$k}{cancelled_count};
	}

	foreach my $k (keys %{$_overall_stat{histogram}{query_time}}) {
		$overall_stat{histogram}{query_time}{$k} += $_overall_stat{histogram}{query_time}{$k};
	}
	$overall_stat{histogram}{query_total} += $_overall_stat{histogram}{total};
	$overall_stat{histogram}{query_total} += $_overall_stat{histogram}{query_total};
	foreach my $k (keys %{$_overall_stat{histogram}{session_time}}) {
		$overall_stat{histogram}{session_time}{$k} += $_overall_stat{histogram}{session_time}{$k};
	}
	$overall_stat{histogram}{session_total} += $_overall_stat{histogram}{session_total};

	foreach my $k ('prepare', 'bind','execute') {
		$overall_stat{$k} += $_overall_stat{$k};
	}

	foreach my $k (keys %{$_overall_checkpoint{peak}}) {
		$overall_checkpoint{peak}{$k}{checkpoint_wbuffer} += $_overall_checkpoint{peak}{$k}{checkpoint_wbuffer};
		$overall_checkpoint{peak}{$k}{walfile_usage} += $_overall_checkpoint{peak}{$k}{walfile_usage};
	}

	### Logs level ###
	foreach my $l (qw(LOG WARNING ERROR FATAL PANIC DETAIL HINT STATEMENT CONTEXT)) {
		$logs_type{$l} += $_logs_type{$l} if exists $_logs_type{$l};
	}

	### database_info ###

	foreach my $db (keys %_database_info) {
		foreach my $k (keys %{ $_database_info{$db} }) {
			$database_info{$db}{$k} += $_database_info{$db}{$k};
		}
	}

	### application_info ###

	foreach my $app (keys %_application_info) {
		foreach my $k (keys %{ $_application_info{$app} }) {
			$application_info{$app}{$k} += $_application_info{$app}{$k};
		}
	}

	### user_info ###

	foreach my $u (keys %_user_info) {
		foreach my $k (keys %{ $_user_info{$u} }) {
			$user_info{$u}{$k} += $_user_info{$u}{$k};
		}
	}

	### host_info ###

	foreach my $h (keys %_host_info) {
		foreach my $k (keys %{ $_host_info{$h} }) {
			$host_info{$h}{$k} += $_host_info{$h}{$k};
		}
	}


	### connection_info ###

	foreach my $db (keys %{ $_connection_info{database} }) {
		$connection_info{database}{$db} += $_connection_info{database}{$db};
	}

	foreach my $db (keys %{ $_connection_info{database_user} }) {
		foreach my $user (keys %{ $_connection_info{database_user}{$db} }) {
			$connection_info{database_user}{$db}{$user} += $_connection_info{database_user}{$db}{$user};
		}
	}

	foreach my $user (keys %{ $_connection_info{user} }) {
		$connection_info{user}{$user} += $_connection_info{user}{$user};
	}

	foreach my $host (keys %{ $_connection_info{host} }) {
		$connection_info{host}{$host} += $_connection_info{host}{$host};
	}

	$connection_info{count} += $_connection_info{count};

	foreach my $day (keys %{ $_connection_info{chronos} }) {
		foreach my $hour (keys %{ $_connection_info{chronos}{$day} }) {

			$connection_info{chronos}{$day}{$hour}{count} += $_connection_info{chronos}{$day}{$hour}{count}

###############################################################################
# May be used in the future to display more detailed information on connection
#
#			foreach my $db (keys %{ $_connection_info{chronos}{$day}{$hour}{database} }) {
#				$connection_info{chronos}{$day}{$hour}{database}{$db} += $_connection_info{chronos}{$day}{$hour}{database}{$db};
#			}
#
#			foreach my $db (keys %{ $_connection_info{chronos}{$day}{$hour}{database_user} }) {
#				foreach my $user (keys %{ $_connection_info{chronos}{$day}{$hour}{database_user}{$db} }) {
#					$connection_info{chronos}{$day}{$hour}{database_user}{$db}{$user} +=
#						$_connection_info{chronos}{$day}{$hour}{database_user}{$db}{$user};
#				}
#			}
#
#			foreach my $user (keys %{ $_connection_info{chronos}{$day}{$hour}{user} }) {
#				$connection_info{chronos}{$day}{$hour}{user}{$user} +=
#					$_connection_info{chronos}{$day}{$hour}{user}{$user};
#			}
#
#			foreach my $host (keys %{ $_connection_info{chronos}{$day}{$hour}{host} }) {
#				$connection_info{chronos}{$day}{$hour}{host}{$host} +=
#					$_connection_info{chronos}{$day}{$hour}{host}{$host};
#			}
###############################################################################
		}
	}

	### log_files ###

	foreach my $f (@_log_files) {
		push(@log_files, $f) if (!grep(m#^$f$#, @_log_files));
	}

	### error_info ###

	foreach my $q (keys %_error_info) {
		$error_info{$q}{count} += $_error_info{$q}{count};
		foreach my $day (keys %{ $_error_info{$q}{chronos} }) {
			foreach my $hour (keys %{$_error_info{$q}{chronos}{$day}}) {
				$error_info{$q}{chronos}{$day}{$hour}{count} += $_error_info{$q}{chronos}{$day}{$hour}{count};
				foreach my $min (keys %{$_error_info{$q}{chronos}{$day}{$hour}{min}}) {
					$error_info{$q}{chronos}{$day}{$hour}{min}{$min} += $_error_info{$q}{chronos}{$day}{$hour}{min}{$min};
				}
			}
		}
		for (my $i = 0; $i <= $#{$_error_info{$q}{date}}; $i++) {
			&set_top_error_sample(	$q, 
									$_error_info{$q}{date}[$i], 
									$_error_info{$q}{error}[$i],
									$_error_info{$q}{detail}[$i], 
									$_error_info{$q}{context}[$i], 
									$_error_info{$q}{statement}[$i],
									$_error_info{$q}{hint}[$i], 
									$_error_info{$q}{db}[$i],
									$_error_info{$q}{user}[$i],
									$_error_info{$q}{app}[$i],
									$_error_info{$q}{remote}[$i]
									);
		}
	}

	### per_minute_info ###

	foreach my $day (keys %_per_minute_info) {
		foreach my $hour (keys %{ $_per_minute_info{$day} }) {
			foreach my $min (keys %{ $_per_minute_info{$day}{$hour} }) {
				$per_minute_info{$day}{$hour}{$min}{connection}{count} +=
					($_per_minute_info{$day}{$hour}{$min}{connection}{count} || 0);
				$per_minute_info{$day}{$hour}{$min}{session}{count} +=
					($_per_minute_info{$day}{$hour}{$min}{session}{count} || 0);
				$per_minute_info{$day}{$hour}{$min}{query}{count} +=
					($_per_minute_info{$day}{$hour}{$min}{query}{count} || 0);
				$per_minute_info{$day}{$hour}{$min}{query}{duration} += $_per_minute_info{$day}{$hour}{$min}{query}{duration};
				$per_minute_info{$day}{$hour}{$min}{query}{min} = $_per_minute_info{$day}{$hour}{$min}{query}{min} if (!exists $per_minute_info{$day}{$hour}{$min}{query}{min} || ($per_minute_info{$day}{$hour}{$min}{query}{min} > $_per_minute_info{$day}{$hour}{$min}{query}{min}));
				$per_minute_info{$day}{$hour}{$min}{query}{max} = $_per_minute_info{$day}{$hour}{$min}{query}{max} if (!exists $per_minute_info{$day}{$hour}{$min}{query}{max} || ($per_minute_info{$day}{$hour}{$min}{query}{max} < $_per_minute_info{$day}{$hour}{$min}{query}{max}));

				foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{connection}{second} }) {
					$per_minute_info{$day}{$hour}{$min}{connection}{second}{$sec} +=
						($_per_minute_info{$day}{$hour}{$min}{connection}{second}{$sec} || 0);
				}
				foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{session}{second} }) {
					$per_minute_info{$day}{$hour}{$min}{session}{second}{$sec} +=
						($_per_minute_info{$day}{$hour}{$min}{session}{second}{$sec} || 0);
				}
				foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{query}{second} }) {
					$per_minute_info{$day}{$hour}{$min}{query}{second}{$sec} +=
						($_per_minute_info{$day}{$hour}{$min}{query}{second}{$sec} || 0);
				}
				foreach my $action (@SQL_ACTION) {
					next if (!exists $_per_minute_info{$day}{$hour}{$min}{$action});
					$per_minute_info{$day}{$hour}{$min}{$action}{count} += ($_per_minute_info{$day}{$hour}{$min}{$action}{count} || 0);
					$per_minute_info{$day}{$hour}{$min}{$action}{duration} += ($_per_minute_info{$day}{$hour}{$min}{$action}{duration} || 0);
					foreach my $sec (keys %{ $_per_minute_info{$day}{$hour}{$min}{$action}{second} }) {
						$per_minute_info{$day}{$hour}{$min}{$action}{second}{$sec} +=
							($_per_minute_info{$day}{$hour}{$min}{$action}{second}{$sec} || 0);
					}
				}
				foreach my $k ('prepare', 'bind','execute') {
					if (exists $_per_minute_info{$day}{$hour}{$min}{$k}) {
						$per_minute_info{$day}{$hour}{$min}{$k} += $_per_minute_info{$day}{$hour}{$min}{$k};
					}
				}
				foreach my $log (keys %{ $_per_minute_info{$day}{$hour}{$min}{log_level} }) {
					$per_minute_info{$day}{$hour}{$min}{log_level}{$log} +=
						($_per_minute_info{$day}{$hour}{$min}{log_level}{$log} || 0);
				}

				$per_minute_info{$day}{$hour}{$min}{cancelled}{count} += $_per_minute_info{$day}{$hour}{$min}{cancelled}{count}
						if defined $_per_minute_info{$day}{$hour}{$min}{cancelled}{count};
				$per_minute_info{$day}{$hour}{$min}{tempfile}{count} += $_per_minute_info{$day}{$hour}{$min}{tempfile}{count}
						if defined $_per_minute_info{$day}{$hour}{$min}{tempfile}{count};
				$per_minute_info{$day}{$hour}{$min}{tempfile}{size} += $_per_minute_info{$day}{$hour}{$min}{tempfile}{size}
						if defined $_per_minute_info{$day}{$hour}{$min}{tempfile}{size};

				$per_minute_info{$day}{$hour}{$min}{checkpoint}{file_removed} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{file_removed};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{sync} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{wbuffer} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{wbuffer};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{file_recycled} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{file_recycled};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{total} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{total};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{file_added} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{file_added};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{write} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{write};
				$per_minute_info{$day}{$hour}{$min}{autovacuum}{count} += $_per_minute_info{$day}{$hour}{$min}{autovacuum}{count};
				$per_minute_info{$day}{$hour}{$min}{autoanalyze}{count} += $_per_minute_info{$day}{$hour}{$min}{autoanalyze}{count};

				$per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_files} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_files};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_avg} += $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_avg};
				$per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest} = $_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest}
					if ($_per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest} > $per_minute_info{$day}{$hour}{$min}{checkpoint}{sync_longest});
			}
		}
	}

	### lock_info ###

	foreach my $lock (keys %_lock_info) {
		$lock_info{$lock}{count} += $_lock_info{$lock}{count};

		foreach my $day (keys %{ $_lock_info{chronos} }) {
			foreach my $hour (keys %{ $_lock_info{chronos}{$day} }) {
				$lock_info{chronos}{$day}{$hour}{count} += $_lock_info{chronos}{$day}{$hour}{count};
				$lock_info{chronos}{$day}{$hour}{duration} += $_lock_info{chronos}{$day}{$hour}{duration};
			}
		}

		$lock_info{$lock}{duration} += $_lock_info{$lock}{duration};

		foreach my $type (keys %{$_lock_info{$lock}}) {
			next if $type =~ /^(count|chronos|duration)$/;

			$lock_info{$lock}{$type}{count} += $_lock_info{$lock}{$type}{count};
			$lock_info{$lock}{$type}{duration} += $_lock_info{$lock}{$type}{duration};
		}
	}

	### nlines ###

	$nlines += $_nlines;

	### normalyzed_info ###

	foreach my $stmt (keys %_normalyzed_info) {

		foreach my $dt (keys %{$_normalyzed_info{$stmt}{samples}} ) {
			foreach my $k (keys %{$_normalyzed_info{$stmt}{samples}{$dt}} ) {
				$normalyzed_info{$stmt}{samples}{$dt}{$k} = $_normalyzed_info{$stmt}{samples}{$dt}{$k};
			}
		}

		# Keep only the top N samples
		my $i = 1;
		foreach my $k (sort {$b <=> $a} keys %{$normalyzed_info{$stmt}{samples}}) {
			if ($i > $sample) {
				delete $normalyzed_info{$stmt}{samples}{$k};
			}
			$i++;
		}

		$normalyzed_info{$stmt}{count} += $_normalyzed_info{$stmt}{count};

		# Set min / max duration for this query
		if (!exists $normalyzed_info{$stmt}{min} || ($normalyzed_info{$stmt}{min} > $_normalyzed_info{$stmt}{min})) { 
			$normalyzed_info{$stmt}{min} = $_normalyzed_info{$stmt}{min};
		}
		if (!exists $normalyzed_info{$stmt}{max} || ($normalyzed_info{$stmt}{max} < $_normalyzed_info{$stmt}{max})) { 
			$normalyzed_info{$stmt}{max} = $_normalyzed_info{$stmt}{max};
		}

		foreach my $day (keys %{$_normalyzed_info{$stmt}{chronos}} ) {
			foreach my $hour (keys %{$_normalyzed_info{$stmt}{chronos}{$day}} ) {
				$normalyzed_info{$stmt}{chronos}{$day}{$hour}{count} +=
					$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{count};
				$normalyzed_info{$stmt}{chronos}{$day}{$hour}{duration} +=
					$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{duration};
				foreach my $min (keys %{$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min}} ) {
					$normalyzed_info{$stmt}{chronos}{$day}{$hour}{min}{$min} +=
						$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min}{$min};
				}
				foreach my $min (keys %{$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min_duration}} ) {
					$normalyzed_info{$stmt}{chronos}{$day}{$hour}{min_duration}{$min} +=
						$_normalyzed_info{$stmt}{chronos}{$day}{$hour}{min_duration}{$min};
				}
			}
		}

		$normalyzed_info{$stmt}{duration} += $_normalyzed_info{$stmt}{duration};

		if (exists $_normalyzed_info{$stmt}{locks}) {
			$normalyzed_info{$stmt}{locks}{count} += $_normalyzed_info{$stmt}{locks}{count};
			$normalyzed_info{$stmt}{locks}{wait} += $_normalyzed_info{$stmt}{locks}{wait};
			if (!exists $normalyzed_info{$stmt}{locks}{minwait} || ($normalyzed_info{$stmt}{locks}{minwait} > $_normalyzed_info{$stmt}{locks}{minwait})) { 
				$normalyzed_info{$stmt}{locks}{minwait} = $_normalyzed_info{$stmt}{locks}{minwait};
			}
			if (!exists $normalyzed_info{$stmt}{locks}{maxwait} || ($normalyzed_info{$stmt}{locks}{maxwait} < $_normalyzed_info{$stmt}{locks}{maxwait})) { 
				$normalyzed_info{$stmt}{locks}{maxwait} = $_normalyzed_info{$stmt}{locks}{maxwait};
			}
		}

		if (exists $_normalyzed_info{$stmt}{tempfiles}) {
			$normalyzed_info{$stmt}{tempfiles}{count} += $_normalyzed_info{$stmt}{tempfiles}{count};
			$normalyzed_info{$stmt}{tempfiles}{size} += $_normalyzed_info{$stmt}{tempfiles}{size};
			if (!exists $normalyzed_info{$stmt}{tempfiles}{minsize} || ($normalyzed_info{$stmt}{tempfiles}{minsize} > $_normalyzed_info{$stmt}{tempfiles}{minsize})) { 
				$normalyzed_info{$stmt}{tempfiles}{minsize} = $_normalyzed_info{$stmt}{tempfiles}{minsize};
			}
			if (!exists $normalyzed_info{$stmt}{tempfiles}{maxsize} || ($normalyzed_info{$stmt}{tempfiles}{maxsize} < $_normalyzed_info{$stmt}{tempfiles}{maxsize})) { 
				$normalyzed_info{$stmt}{tempfiles}{maxsize} = $_normalyzed_info{$stmt}{tempfiles}{maxsize};
			}
		}

		if (exists $_normalyzed_info{$stmt}{cancelled}) {
			$normalyzed_info{$stmt}{cancelled}{count} += $_normalyzed_info{$stmt}{cancelled}{count};
		}

		foreach my $u (keys %{$_normalyzed_info{$stmt}{users}} ) {
			foreach my $k (keys %{$_normalyzed_info{$stmt}{users}{$u}} ) {
				$normalyzed_info{$stmt}{users}{$u}{$k} += $_normalyzed_info{$stmt}{users}{$u}{$k};
			}
		}
		foreach my $u (keys %{$_normalyzed_info{$stmt}{apps}} ) {
			foreach my $k (keys %{$_normalyzed_info{$stmt}{apps}{$u}} ) {
				$normalyzed_info{$stmt}{apps}{$u}{$k} += $_normalyzed_info{$stmt}{apps}{$u}{$k};
			}
		}
	}

	### session_info ###

	foreach my $db (keys %{ $_session_info{database}}) {
		$session_info{database}{$db}{count} += $_session_info{database}{$db}{count};
		$session_info{database}{$db}{duration} += $_session_info{database}{$db}{duration};
	}

	$session_info{count} += $_session_info{count};

	foreach my $day (keys %{ $_session_info{chronos}}) {
		foreach my $hour (keys %{ $_session_info{chronos}{$day}}) {
			$session_info{chronos}{$day}{$hour}{count} += $_session_info{chronos}{$day}{$hour}{count};
			$session_info{chronos}{$day}{$hour}{duration} += $_session_info{chronos}{$day}{$hour}{duration};
		}
	}

	foreach my $user (keys %{ $_session_info{user}}) {
		$session_info{user}{$user}{count}    += $_session_info{user}{$user}{count};
		$session_info{user}{$user}{duration} += $_session_info{user}{$user}{duration};
	}

	$session_info{duration} += $_session_info{duration};

	foreach my $host (keys %{ $_session_info{host}}) {
		$session_info{host}{$host}{count}    += $_session_info{host}{$host}{count};
		$session_info{host}{$host}{duration} += $_session_info{host}{$host}{duration};
	}

	foreach my $app (keys %{ $_session_info{app}}) {
		$session_info{app}{$app}{count}    += $_session_info{app}{$app}{count};
		$session_info{app}{$app}{duration} += $_session_info{app}{$app}{duration};
	}

	### tempfile_info ###

	$tempfile_info{count} += $_tempfile_info{count}
		if defined $_tempfile_info{count};
	$tempfile_info{size} += $_tempfile_info{size}
		if defined $_tempfile_info{size};
	$tempfile_info{maxsize} = $_tempfile_info{maxsize}
		if defined $_tempfile_info{maxsize} and ( not defined $tempfile_info{maxsize}
			or $tempfile_info{maxsize} < $_tempfile_info{maxsize} );

	### top_slowest ###
	my @tmp_top_slowest = sort {$b->[0] <=> $a->[0]} (@top_slowest, @_top_slowest);
	@top_slowest = ();
	for (my $i = 0; $i <= $#tmp_top_slowest; $i++) {
		push(@top_slowest, $tmp_top_slowest[$i]);
		last if ($i == $end_top);
	}

	### top_locked ###
	my @tmp_top_locked_info = sort {$b->[0] <=> $a->[0]} (@top_locked_info, @_top_locked_info);
	@top_locked_info = ();
	for (my $i = 0; $i <= $#tmp_top_locked_info; $i++) {
		push(@top_locked_info, $tmp_top_locked_info[$i]);
		last if ($i == $end_top);
	}

	### top_tempfile ###
	my @tmp_top_tempfile_info = sort {$b->[0] <=> $a->[0]} (@top_tempfile_info, @_top_tempfile_info);
	@top_tempfile_info = ();
	for (my $i = 0; $i <= $#tmp_top_tempfile_info; $i++) {
		push(@top_tempfile_info, $tmp_top_tempfile_info[$i]);
		last if ($i == $end_top);
	}

	### checkpoint_info ###
	$checkpoint_info{file_removed} += $_checkpoint_info{file_removed};
	$checkpoint_info{sync} += $_checkpoint_info{sync};
	$checkpoint_info{wbuffer} += $_checkpoint_info{wbuffer};
	$checkpoint_info{file_recycled} += $_checkpoint_info{file_recycled};
	$checkpoint_info{total} += $_checkpoint_info{total};
	$checkpoint_info{file_added} += $_checkpoint_info{file_added};
	$checkpoint_info{write} += $_checkpoint_info{write};

	#### Autovacuum info ####

	$autovacuum_info{count} += $_autovacuum_info{count};

	foreach my $day (keys %{ $_autovacuum_info{chronos} }) {
		foreach my $hour (keys %{ $_autovacuum_info{chronos}{$day} }) {
			$autovacuum_info{chronos}{$day}{$hour}{count} += $_autovacuum_info{chronos}{$day}{$hour}{count};
		}
	}
	foreach my $table (keys %{ $_autovacuum_info{tables} }) {
		$autovacuum_info{tables}{$table}{vacuums} += $_autovacuum_info{tables}{$table}{vacuums};
		$autovacuum_info{tables}{$table}{idxscans} += $_autovacuum_info{tables}{$table}{idxscans};
		$autovacuum_info{tables}{$table}{tuples}{removed} += $_autovacuum_info{tables}{$table}{tuples}{removed};
		$autovacuum_info{tables}{$table}{pages}{removed} += $_autovacuum_info{tables}{$table}{pages}{removed};
	}
	if ($_autovacuum_info{peak}{system_usage}{elapsed} > $autovacuum_info{peak}{system_usage}{elapsed}) {
		$autovacuum_info{peak}{system_usage}{elapsed} = $_autovacuum_info{peak}{system_usage}{elapsed};
		$autovacuum_info{peak}{system_usage}{table} = $_autovacuum_info{peak}{system_usage}{table};
		$autovacuum_info{peak}{system_usage}{date} = $_autovacuum_info{peak}{system_usage}{date};
	}
	#### Autoanalyze info ####

	$autoanalyze_info{count} += $_autoanalyze_info{count};

	foreach my $day (keys %{ $_autoanalyze_info{chronos} }) {
		foreach my $hour (keys %{ $_autoanalyze_info{chronos}{$day} }) {
			$autoanalyze_info{chronos}{$day}{$hour}{count} += $_autoanalyze_info{chronos}{$day}{$hour}{count};
		}
	}
	foreach my $table (keys %{ $_autoanalyze_info{tables} }) {
		$autoanalyze_info{tables}{$table}{analyzes} += $_autoanalyze_info{tables}{$table}{analyzes};
	}
	if ($_autoanalyze_info{peak}{system_usage}{elapsed} > $autoanalyze_info{peak}{system_usage}{elapsed}) {
		$autoanalyze_info{peak}{system_usage}{elapsed} = $_autoanalyze_info{peak}{system_usage}{elapsed};
		$autoanalyze_info{peak}{system_usage}{table} = $_autoanalyze_info{peak}{system_usage}{table};
		$autoanalyze_info{peak}{system_usage}{date} = $_autoanalyze_info{peak}{system_usage}{date};
	}

	return;
}

sub dump_as_binary
{
	my $lfh = shift();

	store_fd({
		'overall_stat' => \%overall_stat,
		'overall_checkpoint' => \%overall_checkpoint,
		'normalyzed_info' => \%normalyzed_info,
		'error_info' => \%error_info,
		'connection_info' => \%connection_info,
		'database_info' => \%database_info,
		'application_info' => \%application_info,
		'user_info' => \%user_info,
		'host_info' => \%host_info,
		'checkpoint_info' => \%checkpoint_info,
		'session_info' => \%session_info,
		'tempfile_info' => \%tempfile_info,
		'error_info' => \%error_info,
		'logs_type' => \%logs_type,
		'lock_info' => \%lock_info,
		'per_minute_info' => \%per_minute_info,
		'top_slowest' => \@top_slowest,
		'nlines' => $nlines,
		'log_files' => \@log_files,
		'autovacuum_info' => \%autovacuum_info,
		'autoanalyze_info' => \%autoanalyze_info,
		'top_tempfile_info' => \@top_tempfile_info,
		'top_locked_info' => \@top_locked_info,
	}, $lfh) || die ("Couldn't save binary data to «$outfile»!\n");
}

sub dump_error_as_json
{
	my $json = encode_json({
		'error_info' => \%error_info,
	}) || die ("Encode object to JSON failed!\n");

	print $fh $json;
}

sub dump_as_json
{
	my $json = encode_json({
		'overall_stat' => \%overall_stat,
		'overall_checkpoint' => \%overall_checkpoint,
		'normalyzed_info' => \%normalyzed_info,
		'error_info' => \%error_info,
		'connection_info' => \%connection_info,
		'database_info' => \%database_info,
		'application_info' => \%application_info,
		'user_info' => \%user_info,
		'host_info' => \%host_info,
		'checkpoint_info' => \%checkpoint_info,
		'session_info' => \%session_info,
		'tempfile_info' => \%tempfile_info,
		'error_info' => \%error_info,
		'logs_type' => \%logs_type,
		'lock_info' => \%lock_info,
		'per_minute_info' => \%per_minute_info,
		'top_slowest' => \@top_slowest,
		'nlines' => $nlines,
		'log_files' => \@log_files,
		'autovacuum_info' => \%autovacuum_info,
		'autoanalyze_info' => \%autoanalyze_info,
		'top_tempfile_info' => \@top_tempfile_info,
		'top_locked_info' => \@top_locked_info,
	}) || die ("Encode object to JSON failed!\n");

	print $fh $json;
}

# Highlight SQL code
sub highlight_code
{
	my $code = shift;

	# Escape HTML code into SQL values
	$code = &escape_html($code);

	# Do not try to prettify queries longer
	# than 10KB as this will take too much time
	return $code if (length($code) > $MAX_QUERY_LENGTH);

	# prettify SQL query
	if (!$noprettify) {
		$sql_prettified->query($code);
		$code = $sql_prettified->beautify;
	}

	return $code if ($nohighlight);

	my $i = 0;
	my @qqcode = ();
	while ($code =~ s/("[^\"]*")/QQCODEY${i}A/s) {
		push(@qqcode, $1);
		$i++;
	}
	$i = 0;
	my @qcode = ();
	while ($code =~ s/('[^\']*')/QCODEY${i}B/s) {
		push(@qcode, $1);
		$i++;
	}

	foreach my $x (keys %SYMBOLS) {
		$code =~ s/$x/\$\$PGBGYA\$\$$SYMBOLS{$x}\$\$PGBGYB\$\$/gs;
	}
	for (my $x = 0 ; $x <= $#KEYWORDS1 ; $x++) {
		#$code =~ s/\b$KEYWORDS1[$x]\b/<span class="kw1">$KEYWORDS1[$x]<\/span>/igs;
		$code =~ s/(?<!(?-i)PGBGYB\$\$)\b$KEYWORDS1[$x]\b/<span class="kw1">$KEYWORDS1[$x]<\/span>/igs;
	}

	for (my $x = 0 ; $x <= $#KEYWORDS2 ; $x++) {
		$code =~ s/(?<!:)\b$KEYWORDS2[$x]\b/<span class="kw2">$KEYWORDS2[$x]<\/span>/igs;
	}
	for (my $x = 0 ; $x <= $#KEYWORDS3 ; $x++) {
		$code =~ s/\b$KEYWORDS3[$x]\b/<span class="kw3">$KEYWORDS3[$x]<\/span>/igs;
	}
	for (my $x = 0 ; $x <= $#BRACKETS ; $x++) {
		$code =~ s/($BRACKETS[$x])/<span class="br0">$1<\/span>/igs;
	}

	$code =~ s/\$\$PGBGYA\$\$([^\$]+)\$\$PGBGYB\$\$/<span class="sy0">$1<\/span>/gs;

	$code =~ s/\b(\d+)\b/<span class="nu0">$1<\/span>/igs;

	for (my $x = 0; $x <= $#qcode; $x++) {
		$code =~ s/QCODEY${x}B/$qcode[$x]/s;
	}
	for (my $x = 0; $x <= $#qqcode; $x++) {
		$code =~ s/QQCODEY${x}A/$qqcode[$x]/s;
	}

	$code =~ s/('[^']*')/<span class="st0">$1<\/span>/gs;
	$code =~ s/(`[^`]*`)/<span class="st0">$1<\/span>/gs;

	return $code;
}

sub compute_arg_list
{

	# Some command line arguments can be used multiple times or written
	# as a comma-separated list.
	# For example: --dbuser=postgres --dbuser=joe or --dbuser=postgres,joe
	# So we have to aggregate all the possible values
	my @tmp = ();
	foreach my $v (@exclude_user) {
		push(@tmp, split(/,/, $v));
	}
	@exclude_user = ();
	push(@exclude_user, @tmp);

	@tmp = ();
	foreach my $v (@dbname) {
		push(@tmp, split(/,/, $v));
	}
	@dbname = ();
	push(@dbname, @tmp);

	@tmp = ();
	foreach my $v (@dbuser) {
		push(@tmp, split(/,/, $v));
	}
	@dbuser = ();
	push(@dbuser, @tmp);

	@tmp = ();
	foreach my $v (@dbclient) {
		push(@tmp, split(/,/, $v));
	}
	@dbclient = ();
	push(@dbclient, @tmp);

	@tmp = ();
	foreach my $v (@dbappname) {
		push(@tmp, split(/,/, $v));
	}
	@dbappname = ();
	push(@dbappname, @tmp);

	@tmp = ();
	foreach my $v (@exclude_appname) {
		push(@tmp, split(/,/, $v));
	}
	@exclude_appname = ();
	push(@exclude_appname, @tmp);

	@tmp = ();
	foreach my $v (@exclude_line) {
		push(@tmp, split(/,/, $v));
	}
	@exclude_line = ();
	push(@exclude_line, @tmp);


}

sub validate_log_line
{
	my ($t_pid) = @_;

	# Look at particular cases of vacuum/analyze that have the database
	# name inside the log message so that they could be associated
	if ($prefix_vars{'t_query'} =~ / of table "([^\.]+)\.[^\.]+\.[^\.]+":/) {
		$prefix_vars{'t_dbname'}  = $1;
	}

	# Check user and/or database if required
	if ($#dbname >= 0) {

		# Log line does not match the required dbname
		if (!$prefix_vars{'t_dbname'} || !grep(/^$prefix_vars{'t_dbname'}$/i, @dbname)) {
			delete $current_sessions{$prefix_vars{'t_pid'}};
			return 0;
		}
	}
	if ($#dbuser >= 0) {

		# Log line does not match the required dbuser
		if (!$prefix_vars{'t_dbuser'} || !grep(/^$prefix_vars{'t_dbuser'}$/i, @dbuser)) {
			delete $current_sessions{$prefix_vars{'t_pid'}};
			return 0;
		}
	}
	if ($#dbclient >= 0) {

		# Log line does not match the required dbclient
		if (!$prefix_vars{'t_client'} || !grep(/^$prefix_vars{'t_client'}$/i, @dbclient)) {
			delete $current_sessions{$prefix_vars{'t_pid'}};
			return 0;
		}
	}
	if ($#dbappname >= 0) {

		# Log line does not match the required dbname
		if (!$prefix_vars{'t_appname'} || !grep(/^\Q$prefix_vars{'t_appname'}\E$/i, @dbappname)) {
			delete $current_sessions{$prefix_vars{'t_pid'}};
			return 0;
		}
	}
	if ($#exclude_user >= 0) {

		# Log line matches the excluded dbuser
		if ($prefix_vars{'t_dbuser'} && grep(/^$prefix_vars{'t_dbuser'}$/i, @exclude_user)) {
			delete $current_sessions{$prefix_vars{'t_pid'}};
			return 0;
		}
	}
	if ($#exclude_appname >= 0) {

		# Log line matches the excluded appname
		if ($prefix_vars{'t_appname'} && grep(/^\Q$prefix_vars{'t_appname'}\E$/i, @exclude_appname)) {
			delete $current_sessions{$prefix_vars{'t_pid'}};
			return 0;
		}
	}

	return 1;
}

sub parse_log_prefix
{
	my ($t_logprefix) = @_;

	# Extract user and database information from the logprefix part
	if ($t_logprefix) {

		# Search for database user
		if ($t_logprefix =~ $regex_prefix_dbuser) {
			$prefix_vars{'t_dbuser'} = $1;
		}

		# Search for database name
		if ($t_logprefix =~ $regex_prefix_dbname) {
			$prefix_vars{'t_dbname'} = $1;
		}

		# Search for client host name
		if ($t_logprefix =~ $regex_prefix_dbclient) {
			$prefix_vars{'t_dbclient'} = $1;
			$prefix_vars{'t_dbclient'} = _gethostbyaddr($prefix_vars{'t_dbclient'}) if ($dns_resolv);
		}

		# Search for application name
		if ($t_logprefix =~ $regex_prefix_dbappname) {
			$prefix_vars{'t_appname'} = $1;
		}

	}
}

sub parse_query
{

	my $t_pid = $prefix_vars{'t_pid'};

	# Force some LOG messages to be ERROR messages so that they will appear
	# in the event/error/warning messages report.
	if ($prefix_vars{'t_loglevel'} eq 'LOG') {
		if ($prefix_vars{'t_query'} =~ /parameter "[^"]+" changed to "[^"]+"/) {
			$prefix_vars{'t_loglevel'} = 'ERROR';
		} elsif ($prefix_vars{'t_query'} =~ /database system was shut down at /) {
			$prefix_vars{'t_loglevel'} = 'ERROR';
		} elsif ($prefix_vars{'t_query'} =~ /database system was interrupted while in recovery/) {
			$prefix_vars{'t_loglevel'} = 'ERROR';
		} elsif ($prefix_vars{'t_query'} =~ /recovery has paused/) {
			$prefix_vars{'t_loglevel'} = 'ERROR';
		}
	} elsif ($prefix_vars{'t_loglevel'} eq 'ERROR') {
		if ($prefix_vars{'t_query'} =~ /canceling statement due to statement timeout/) {
			$prefix_vars{'t_loglevel'} = 'LOG';
		}
	}

	# Remove session failure from current workload because there is no disconnection entry
	if (!$disable_session && ($prefix_vars{'t_loglevel'} eq 'FATAL')) {
		delete $current_sessions{$prefix_vars{'t_pid'}};
		if ($extension eq 'tsung') {
			delete $tsung_session{$prefix_vars{'t_pid'}}
		}
	} elsif (!$disable_session && ($prefix_vars{'t_loglevel'} eq 'WARNING')) {
		if ($prefix_vars{'t_query'} =~ /terminating connection/) {
			delete $current_sessions{$prefix_vars{'t_pid'}};
			if ($extension eq 'tsung') {
				delete $tsung_session{$prefix_vars{'t_pid'}}
			}
		}
	}

	# Do not process DEALLOCATE lines
	if ($prefix_vars{'t_query'} =~ /statement: DEALLOCATE/) {
		return;
	}

	# Do not parse lines that are not an error message when error only report is requested
	if ($error_only && ($prefix_vars{'t_loglevel'} !~ $full_error_regex)) {
		return;
	}

	# Do not parse lines that are an error-like message when error reports are not wanted
	if ($disable_error && ($prefix_vars{'t_loglevel'} =~ $full_error_regex)) {
		return;
	}

	# Store a counter of logs type
	$logs_type{$prefix_vars{'t_loglevel'}}++;

	# Replace syslog tabulation rewrite
	if ($format =~ /syslog/) {
		$prefix_vars{'t_query'} =~ s/#011/\t/g;
	}

	# Reject lines generated by debug tool
	if ( ($prefix_vars{'t_loglevel'} eq 'CONTEXT') && ($prefix_vars{'t_query'} =~ /SQL statement "/) ) {
		return;
	}

	# Stores the error's detail if previous line was an error
	if ($cur_info{$t_pid}{loglevel} =~ $main_error_regex) {
		# and current one is detailed information
		if ($prefix_vars{'t_loglevel'} =~ /(DETAIL|STATEMENT|CONTEXT|HINT)/) {
			$cur_info{$t_pid}{"\L$1\E"} .= $prefix_vars{'t_query'};
			return;
		}
	}

	my $date_part = "$prefix_vars{'t_year'}$prefix_vars{'t_month'}$prefix_vars{'t_day'}";
	my $cur_last_log_timestamp = "$prefix_vars{'t_year'}-$prefix_vars{'t_month'}-$prefix_vars{'t_day'} " .
				     "$prefix_vars{t_hour}:$prefix_vars{t_min}:$prefix_vars{t_sec}";

	# set current session workload
	if ( !$disable_session ) {
		my $sess_count = scalar keys %current_sessions;
		$overall_stat{'peak'}{$cur_last_log_timestamp}{session} = $sess_count;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{"$prefix_vars{'t_min'}"}{session}{count} = $sess_count;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{"$prefix_vars{'t_min'}"}{session}{second}{$prefix_vars{'t_sec'}} = $sess_count;
	}

	# Stores lock activity
	if (($prefix_vars{'t_loglevel'} eq 'LOG') && ($prefix_vars{'t_query'} =~ /acquired ([^\s]+) on ([^\s]+) .* after ([0-9\.]+) ms/))
	{
		return if ($disable_lock);
		$lock_info{$1}{count}++;
		$lock_info{$1}{duration} += $3;
		$lock_info{$1}{$2}{count}++;
		$lock_info{$1}{$2}{duration} += $3;
		$lock_info{$1}{chronos}{$date_part}{$prefix_vars{'t_hour'}}{count}++;
		$lock_info{$1}{chronos}{$date_part}{$prefix_vars{'t_hour'}}{duration}++;
		# Store current lock information that will be used later
		# when we will parse the query responsible for the locks
		$cur_lock_info{$t_pid}{wait} = $3;
		if ($format eq 'csv') {
			$cur_lock_info{$t_pid}{query}     = $prefix_vars{'t_statement'};
			$cur_lock_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
			$cur_lock_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
			$cur_lock_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
			$cur_lock_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
			$cur_lock_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		}
		return;
	}

	# Stores query related to temporary file information
	if (($prefix_vars{'t_loglevel'} eq 'STATEMENT') && exists $cur_temp_info{$t_pid}{size}) {
		$cur_temp_info{$t_pid}{query}     = $prefix_vars{'t_query'};
		$cur_temp_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
		$cur_temp_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
		$cur_temp_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
		$cur_temp_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
		$cur_temp_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		return;
	}

	# Stores query related to last lock information
	if (($prefix_vars{'t_loglevel'} eq 'STATEMENT') && exists $cur_lock_info{$t_pid}{wait}) {
		$cur_lock_info{$t_pid}{query}     = $prefix_vars{'t_query'};
		$cur_lock_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
		$cur_lock_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
		$cur_lock_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
		$cur_lock_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
		$cur_lock_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		return;
	}

	# Stores query related to cancelled queries information
	if (($prefix_vars{'t_loglevel'} eq 'STATEMENT') && exists $cur_cancel_info{$t_pid}{count}) {
		$cur_cancel_info{$t_pid}{query}     = $prefix_vars{'t_query'};
		$cur_cancel_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
		$cur_cancel_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
		$cur_cancel_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
		$cur_cancel_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
		$cur_cancel_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		return;
	}

	# Stores cancelled queries
	if (($prefix_vars{'t_loglevel'} eq 'LOG') && ($prefix_vars{'t_query'} =~ /canceling statement due to statement timeout/)) {
		return if ($disable_query);
		$cancelled_info{count}++;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{cancelled}{count}++;
		# Store current cancelled query information that will be used later
		# when we will parse the query that has been killed
		$overall_stat{'peak'}{$cur_last_log_timestamp}{cancelled_count}++;
		$cur_cancel_info{$t_pid}{count}++;
		if ($format eq 'csv') {
			$cur_cancel_info{$t_pid}{query}     = $prefix_vars{'t_statement'};
			$cur_cancel_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
			$cur_cancel_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
			$cur_cancel_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
			$cur_cancel_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
			$cur_cancel_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		}
		return;
	}

	# Stores temporary files activity
	if (($prefix_vars{'t_loglevel'} eq 'LOG') && ($prefix_vars{'t_query'} =~ /temporary file: path .*, size (\d+)/)) {
		return if ($disable_temporary);
		$tempfile_info{count}++;
		$tempfile_info{size} += $1;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{tempfile}{count}++;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{tempfile}{size} += $1;
		$tempfile_info{maxsize} = $1 if ($tempfile_info{maxsize} < $1);
		# Store current temporary file information that will be used later
		# when we will parse the query responsible for the tempfile
		$cur_temp_info{$t_pid}{size} = $1;
		$overall_stat{'peak'}{$cur_last_log_timestamp}{tempfile_size} += $1;
		$overall_stat{'peak'}{$cur_last_log_timestamp}{tempfile_count}++;
		if ($format eq 'csv') {
			$cur_temp_info{$t_pid}{query}     = $prefix_vars{'t_statement'};
			$cur_temp_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
			$cur_temp_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
			$cur_temp_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
			$cur_temp_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
			$cur_temp_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		}
		return;
	}

	# Stores query related to last created temporary file
	if (($prefix_vars{'t_loglevel'} eq 'STATEMENT') && $cur_temp_info{$t_pid}{size}) {
		$cur_temp_info{$t_pid}{query}     = $prefix_vars{'t_query'};
		$cur_temp_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
		$cur_temp_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
		$cur_temp_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
		$cur_temp_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
		$cur_temp_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		return;
	}

	# Stores pre-connection activity
	if (($prefix_vars{'t_loglevel'} eq 'LOG') && ($prefix_vars{'t_query'} =~ /connection received: host=([^\s]+)(?: port=(\d+))?/)) {
		return if ($disable_connection);
		$conn_received{$t_pid} = $1;
		$conn_received{$t_pid} = _gethostbyaddr($conn_received{$t_pid}) if ($dns_resolv);
		return;
	}

	# Stores connection activity
	if (   ($prefix_vars{'t_loglevel'} eq 'LOG')
		&& ($prefix_vars{'t_query'} =~ /connection authorized: user=([^\s]+) /))
	{
		$current_sessions{$prefix_vars{'t_pid'}} = 1 if (!$disable_session);

		return if ($disable_connection);

		my $usr = $1;
		my $db  = 'unknown';
		my $host  = '';
		if ($prefix_vars{'t_query'} =~ / database=([^\s]+)/) {
			$db = $1;
		} elsif ($prefix_vars{'t_dbname'}) {
			$db = $prefix_vars{'t_dbname'};
		}
		if ($prefix_vars{'t_query'} =~ / host=([^\s]+)/) {
			$host = $1;
			$host = _gethostbyaddr($host) if ($dns_resolv);
		} elsif ($prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'}) {
			$host = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'};
			$host = _gethostbyaddr($host) if ($dns_resolv);
		}
		if ($extension eq 'tsung') {
			$tsung_session{$prefix_vars{'t_pid'}}{connection}{database} = $db;
			$tsung_session{$prefix_vars{'t_pid'}}{connection}{user}     = $usr;
			$tsung_session{$prefix_vars{'t_pid'}}{connection}{date}     = $prefix_vars{'t_date'};
			return;
		}
		$overall_stat{'peak'}{$cur_last_log_timestamp}{connection}++;

		$connection_info{count}++;
		$connection_info{user}{$usr}++;
		$connection_info{database}{$db}++;
		$connection_info{database_user}{$db}{$usr}++;
		$connection_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{count}++;
###############################################################################
# May be used in the future to display more detailed information on connection
#		$connection_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{user}{$usr}++;
#		$connection_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{database}{$db}++;
#		$connection_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{database_user}{$db}{$usr}++;
###############################################################################

		if ($graph) {
			$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{"$prefix_vars{'t_min'}"}{connection}{count}++;
			$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{"$prefix_vars{'t_min'}"}{connection}{second}{$prefix_vars{'t_sec'}}++;
		}
		if (exists $conn_received{$t_pid}) {
			$connection_info{host}{$conn_received{$t_pid}}++;
			delete $conn_received{$t_pid};
		} elsif ($host) {
			$connection_info{host}{$host}++;
		}

		return;
	}

	# Store session duration
	if (($prefix_vars{'t_loglevel'} eq 'LOG')
		&& ($prefix_vars{'t_query'} =~
			/disconnection: session time: ([^\s]+) user=([^\s]+) database=([^\s]+) host=([^\s]+)/))
	{
		return if ($disable_session);

		delete $current_sessions{$prefix_vars{'t_pid'}};
		if ($extension eq 'tsung') {
			$tsung_session{$prefix_vars{'t_pid'}}{disconnection}{date} = $prefix_vars{'t_timestamp'};
		}
		my $time = $1;
		my $usr  = $2;
		my $db   = $3;
		my $host = $4;
		$host = _gethostbyaddr($host) if ($dns_resolv);

		if ($extension eq 'tsung') {
			&store_tsung_session($prefix_vars{'t_pid'});
			return;
		}

		# Store time in milliseconds
		$time =~ /(\d+):(\d+):(\d+\.\d+)/;
		$time = ($3 * 1000) + ($2 * 60 * 1000) + ($1 * 60 * 60 * 1000);
		$session_info{count}++;
		$session_info{duration} += $time;
		$session_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{count}++;
		$session_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{duration} += $time;
		$session_info{database}{$db}{count}++;
		$session_info{database}{$db}{duration} += $time;
		$session_info{user}{$usr}{count}++;
		$session_info{user}{$usr}{duration} += $time;
		$session_info{host}{$host}{count}++;
		$session_info{host}{$host}{duration} += $time;
		my $app = 'unknown';
		$app = $prefix_vars{'t_appname'} if (exists $prefix_vars{'t_appname'});
		$session_info{app}{$app}{count}++;
		$session_info{app}{$app}{duration} += $time;
		my $k = &get_hist_inbound($time, @histogram_session_time);
		$overall_stat{histogram}{session_time}{$k}++;
		$overall_stat{histogram}{session_total}++;
		return;
	}

	# Store autovacuum information
	if (
		($prefix_vars{'t_loglevel'} eq 'LOG')
		&& ($prefix_vars{'t_query'} =~
/automatic vacuum of table "([^\s]+)": index scans: (\d+)/
		   )
	   )
	{
		return if ($disable_autovacuum);
		$autovacuum_info{count}++;
		$autovacuum_info{tables}{$1}{vacuums} += 1;
		$autovacuum_info{tables}{$1}{idxscans} += $2;
		$autovacuum_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{count}++;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{autovacuum}{count}++;

		$cur_info{$t_pid}{vacuum} = $1;

		if ($format eq 'csv') {
			if ($prefix_vars{'t_query'} =~ /pages: (\d+) removed, (\d+) remain/) {
				$autovacuum_info{tables}{$cur_info{$t_pid}{vacuum}}{pages}{removed} += $1;
			}
			if ($prefix_vars{'t_query'} =~ /tuples: (\d+) removed, (\d+) remain/) {
				$autovacuum_info{tables}{$cur_info{$t_pid}{vacuum}}{tuples}{removed} += $1;
			}
			if ($prefix_vars{'t_query'} =~ m#system usage: CPU .* sec elapsed (.*) sec#) {
				if ($1 > $autovacuum_info{peak}{system_usage}{elapsed}) {
					$autovacuum_info{peak}{system_usage}{elapsed} = $1;
					$autovacuum_info{peak}{system_usage}{table} = $cur_info{$t_pid}{vacuum};
					$autovacuum_info{peak}{system_usage}{date} = 
						"$prefix_vars{'t_year'}-$prefix_vars{'t_month'}-$prefix_vars{'t_day'} " .
						"$prefix_vars{'t_hour'}:$prefix_vars{'t_min'}:$prefix_vars{'t_sec'}";
				}
			}
		}
		$cur_info{$t_pid}{year}   = $prefix_vars{'t_year'};
		$cur_info{$t_pid}{month}  = $prefix_vars{'t_month'};
		$cur_info{$t_pid}{day}    = $prefix_vars{'t_day'};
		$cur_info{$t_pid}{hour}   = $prefix_vars{'t_hour'};
		$cur_info{$t_pid}{min}    = $prefix_vars{'t_min'};
		$cur_info{$t_pid}{sec}    = $prefix_vars{'t_sec'};
		return;
	}

	# Store autoanalyze information
	if (
		($prefix_vars{'t_loglevel'} eq 'LOG')
		&& ($prefix_vars{'t_query'} =~
/automatic analyze of table "([^\s]+)"/
		   )
	   )
	{
		return if ($disable_autovacuum);
		my $table = $1;
		$autoanalyze_info{count}++;
		$autoanalyze_info{tables}{$table}{analyzes} += 1;
		$autoanalyze_info{chronos}{$date_part}{$prefix_vars{'t_hour'}}{count}++;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{autoanalyze}{count}++;
		if ($prefix_vars{'t_query'} =~ m#system usage: CPU .* sec elapsed (.*) sec#) {
			if ($1 > $autoanalyze_info{peak}{system_usage}{elapsed}) {
				$autoanalyze_info{peak}{system_usage}{elapsed} = $1;
				$autoanalyze_info{peak}{system_usage}{table} = $table;
				$autoanalyze_info{peak}{system_usage}{date} = $cur_last_log_timestamp;
			}
		}
	}

	# Store checkpoint or restartpoint information
	if (
		($prefix_vars{'t_loglevel'} eq 'LOG')
		&& ($prefix_vars{'t_query'} =~
/point complete: wrote (\d+) buffers \(([^\)]+)\); (\d+) transaction log file\(s\) added, (\d+) removed, (\d+) recycled; write=([0-9\.]+) s, sync=([0-9\.]+) s, total=([0-9\.]+) s/
		   )
	   )
	{
		# Example: LOG:  checkpoint complete: wrote 175 buffers (5.7%); 0 transaction log file(s) added, 1 removed, 2 recycled; write=17.437 s, sync=0.722 s, total=18.259 s; sync files=2, longest=0.708 s, average=0.361 s
		return if ($disable_checkpoint);

		$checkpoint_info{wbuffer} += $1;

		#$checkpoint_info{percent_wbuffer} += $2;
		$checkpoint_info{file_added}    += $3;
		$checkpoint_info{file_removed}  += $4;
		$checkpoint_info{file_recycled} += $5;
		$overall_checkpoint{'peak'}{$cur_last_log_timestamp}{walfile_usage} += ($3 + $5);
		$checkpoint_info{write}         += $6;
		$checkpoint_info{sync}          += $7;
		$checkpoint_info{total}         += $8;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{wbuffer} += $1;
		#$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{percent_wbuffer} += $2;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{file_added}    += $3;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{file_removed}  += $4;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{file_recycled} += $5;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{write}         += $6;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{sync}          += $7;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{total}         += $8;

		$overall_checkpoint{'peak'}{$cur_last_log_timestamp}{checkpoint_wbuffer} += $1;
		if ($6 > $overall_checkpoint{checkpoint_write}) {
			$overall_checkpoint{checkpoint_write} = $6;
		}
		if ($7 > $overall_checkpoint{checkpoint_sync}) {
			$overall_checkpoint{checkpoint_sync} = $7;
		}

		if ($prefix_vars{'t_query'} =~ /sync files=(\d+), longest=([0-9\.]+) s, average=([0-9\.]+) s/) {
			$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{sync_files} += $1;
			$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{sync_longest} = $2
				if ($2 > $per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{sync_longest});
			$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{sync_avg} += $3;
		}
		return;
	}

	# Store checkpoint warning information
	if (   ($prefix_vars{'t_loglevel'} eq 'LOG')
		&& ($prefix_vars{'t_query'} =~ /checkpoints are occurring too frequently \((\d+) seconds apart\)/))
	{
		return if ($disable_checkpoint);
		$checkpoint_info{warning}++;
		$checkpoint_info{warning_seconds} += $1;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{warning}++;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{warning_seconds} += $1;
		$overall_checkpoint{checkpoint_warning}++;
		return;
	}

	# Store old restartpoint information
	if (
		($prefix_vars{'t_loglevel'} eq 'LOG')
		&& ($prefix_vars{'t_query'} =~
/restartpoint complete: wrote (\d+) buffers \(([^\)]+)\); write=([0-9\.]+) s, sync=([0-9\.]+) s, total=([0-9\.]+) s/
		   )
	   )
	{
		# Example: LOG:  restartpoint complete: wrote 1568 buffers (0.3%); write=146.237 s, sync=0.251 s, total=146.489 s
		return if ($disable_checkpoint);

		$checkpoint_info{wbuffer} += $1;

		#$checkpoint_info{percent_wbuffer} += $2;
		$checkpoint_info{write}         += $6;
		$checkpoint_info{sync}          += $7;
		$checkpoint_info{total}         += $8;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{wbuffer} += $1;
		#$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{percent_wbuffer} += $2;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{write}         += $6;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{sync}          += $7;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{checkpoint}{total}         += $8;

		$overall_checkpoint{'peak'}{$cur_last_log_timestamp}{checkpoint_wbuffer} += $1;
		if ($6 > $overall_checkpoint{checkpoint_write}) {
			$overall_checkpoint{checkpoint_write} = $6;
		}
		if ($7 > $overall_checkpoint{checkpoint_sync}) {
			$overall_checkpoint{checkpoint_sync} = $7;
		}

		return;
	}

	# Look at bind/execute parameters if any
	if ($cur_info{$t_pid}{query}) {

		# Remove obsolete connection storage
		delete $conn_received{$cur_info{$t_pid}{pid}};

		# The query is complete but we are missing some debug/info/bind parameter logs
		if ($cur_info{$t_pid}{loglevel} eq 'LOG') {

			# Apply bind parameters if any
			if (($prefix_vars{'t_loglevel'} eq 'DETAIL') && ($prefix_vars{'t_query'} =~ /parameters: (.*)/)) {
				$cur_info{$t_pid}{parameters} = "$1";
				# go look at other params
				return;
			# replace the execute statements with the prepared query and set the parameters
			} elsif (($prefix_vars{'t_loglevel'} eq 'DETAIL') && ($prefix_vars{'t_query'} =~ s/prepare: PREPARE[\s\t]+([^\s\t]+)[\s\t]+AS[\s\t]+(.*)//is)) {
				my $q_name = $1;
				my $real_query = $2;
				if ($cur_info{$t_pid}{query} =~ /\b$q_name\b/) {
					$cur_info{$t_pid}{query} =~ s/EXECUTE[\s\t]+$q_name([\s\t]+)\(//is;
					$cur_info{$t_pid}{parameters} = $cur_info{$t_pid}{query};
					$cur_info{$t_pid}{parameters} =~ s/\)$//;
					$cur_info{$t_pid}{query} = $real_query;
					$cur_info{$t_pid}{'bind'} = 1;
				}
				# go look at other params
				return;
			}
		}
	}

	# Apply bind parameters if any
	if ($prefix_vars{'t_detail'} =~ /parameters: (.*)/) {
		$cur_info{$t_pid}{parameters} = "$1";
		# go look at other params
	}

	####
	# Register previous query storage into global statistics before starting to store current query
	####
	if (exists $cur_info{$t_pid}{query}) {
		# when switching to a new log message
		if ( ($prefix_vars{'t_loglevel'} eq 'LOG') || ($format eq 'csv') || ($prefix_vars{'t_loglevel'} =~ $main_error_regex) ) {
			if (&store_queries($t_pid)) {
				delete $cur_info{$t_pid};
			}
		}
	}

	####
	# Store current query information
	####

	# Log lines with duration only, generated by log_duration = on in postgresql.conf
	if ($prefix_vars{'t_query'} =~ s/duration: ([0-9\.]+) ms$//s) {
		$prefix_vars{'t_duration'} = $1;
		$prefix_vars{'t_query'} = '';
		my $k = &get_hist_inbound($1, @histogram_query_time);
		$overall_stat{histogram}{query_time}{$k}++;
		$overall_stat{histogram}{query_total}++;
		&set_current_infos($t_pid);
		return;
	}

	# Store info as tsung session following the output file extension
	if (($extension eq 'tsung') && !exists $tsung_session{$prefix_vars{'t_pid'}}{connection} && $prefix_vars{'t_dbname'}) {
		$tsung_session{$prefix_vars{'t_pid'}}{connection}{database} = $prefix_vars{'t_dbname'};
		$tsung_session{$prefix_vars{'t_pid'}}{connection}{user}     = $prefix_vars{'t_dbuser'};
		$tsung_session{$prefix_vars{'t_pid'}}{connection}{date}     = $prefix_vars{'t_date'};
	}

	my $t_action = '';
	# Store query duration generated by log_min_duration >= 0 in postgresql.conf
	if ($prefix_vars{'t_query'} =~ s/duration: ([0-9\.]+) ms  (query|statement): //is) {
		$prefix_vars{'t_duration'} = $1;
		$t_action   = $2;
		my $k = &get_hist_inbound($1, @histogram_query_time);
		$overall_stat{histogram}{query_time}{$k}++;
		$overall_stat{histogram}{query_total}++;
		if (($t_action eq 'statement') && $prefix_vars{'t_query'} =~ /^(PREPARE|EXECUTE)\b/i) {
			$overall_stat{lc($1)}++;
			$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{lc($1)}++;
			# We do not store prepare statement
			return if (lc($1) eq 'prepare');
		}
	# Log line with duration and statement from prepared queries
	} elsif ($prefix_vars{'t_query'} =~ s/duration: ([0-9\.]+) ms  (prepare|parse|bind|execute from fetch|execute)\s+[^:]+:\s//is)
	{
		$prefix_vars{'t_duration'} = $1;
		$t_action = $2;
		$t_action =~ s/ from fetch//;
		$t_action = 'prepare' if ($t_action eq 'parse');
		$overall_stat{$t_action}++;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{$t_action}++;
		# Skipping prepare, parse and bind logs
		return if ($t_action !~ /query|statement|execute/);
		my $k = &get_hist_inbound($prefix_vars{'t_duration'}, @histogram_query_time);
		$overall_stat{histogram}{query_time}{$k}++;
		$overall_stat{histogram}{query_total}++;
		$prefix_vars{'t_bind'} = 1;
	# Activate storage of the explain plan generated by auto_explain
	} elsif ($prefix_vars{'t_query'} =~ s/duration: ([0-9\.]+) ms  plan://is) {
		$cur_plan_info{$t_pid}{duration} = $1;
	# Log line without duration at all
	} elsif ($prefix_vars{'t_query'} =~ s/(query|statement): //is) {
		$t_action = $1;
		if (($t_action eq 'statement') && $prefix_vars{'t_query'} =~ /^(PREPARE|EXECUTE)\b/i) {
			$overall_stat{lc($1)}++;
			$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{lc($1)}++;
		}
	# Log line without duration at all from prepared queries
	} elsif ($prefix_vars{'t_query'} =~ s/(prepare|parse|bind|execute from fetch|execute)\s+[^:]+:\s//is)
	{
		$t_action = $1;
		$t_action =~ s/ from fetch//;
		$t_action = 'prepare' if ($t_action eq 'parse');
		$overall_stat{$t_action}++;
		$per_minute_info{$date_part}{$prefix_vars{'t_hour'}}{$prefix_vars{'t_min'}}{$t_action}++;
		# Skipping parse and bind logs
		return if ($t_action !~ /query|statement|execute/);
		$prefix_vars{'t_bind'} = 1;
	# Log line that could not be parsed
	} elsif ($prefix_vars{'t_loglevel'} eq 'LOG') {
		if ($prefix_vars{'t_query'} !~
/incomplete startup packet|connection|receive|unexpected EOF|still waiting for [^\s]+Lock|checkpoint starting:|could not send data to client|parameter .*configuration file|autovacuum launcher|automatic (analyze|vacuum)|detected deadlock while waiting for/
		   )
		{
			&logmsg('DEBUG', "Unrecognized line: $prefix_vars{'t_loglevel'}: $prefix_vars{'t_query'} at line $nlines");
		}
		return;
	}

	if ( ($format eq 'csv') && ($prefix_vars{'t_loglevel'} ne 'LOG')) {
		$cur_info{$t_pid}{detail} = $prefix_vars{'t_detail'};
		$cur_info{$t_pid}{hint} = $prefix_vars{'t_hint'};
		$cur_info{$t_pid}{context} = $prefix_vars{'t_context'};
		$cur_info{$t_pid}{statement} = $prefix_vars{'t_statement'}
	}
	&set_current_infos($t_pid);

	return 1;
}

sub set_current_infos
{

	my $t_pid = shift;

	if (!$log_duration) {
		$cur_info{$t_pid}{year}      = $prefix_vars{'t_year'};
		$cur_info{$t_pid}{month}     = $prefix_vars{'t_month'};
		$cur_info{$t_pid}{day}       = $prefix_vars{'t_day'};
		$cur_info{$t_pid}{hour}      = $prefix_vars{'t_hour'};
		$cur_info{$t_pid}{min}       = $prefix_vars{'t_min'};
		$cur_info{$t_pid}{sec}       = $prefix_vars{'t_sec'};
		$cur_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'};
		$cur_info{$t_pid}{ident}     = $prefix_vars{'t_ident'};
		$cur_info{$t_pid}{query}     = $prefix_vars{'t_query'};
		$cur_info{$t_pid}{duration}  = $prefix_vars{'t_duration'};
		$cur_info{$t_pid}{pid}       = $prefix_vars{'t_pid'};
		$cur_info{$t_pid}{session}   = $prefix_vars{'t_session_line'};
		$cur_info{$t_pid}{loglevel}  = $prefix_vars{'t_loglevel'};
		$cur_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'};
		$cur_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'};
		$cur_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'};
		$cur_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'};
		$cur_info{$t_pid}{date}      = $prefix_vars{'t_date'};
		$cur_info{$t_pid}{bind}      = $prefix_vars{'t_bind'};

		# Extract the query part from the plan
		if (exists $cur_plan_info{$t_pid} && ($cur_plan_info{$t_pid}{plan} ne '')) {
			$cur_plan_info{$t_pid}{plan} =~ s/^(?:.*?)\t([^\t]+\(cost=?)/$1/s;
			$cur_info{$t_pid}{plan} = $cur_plan_info{$t_pid}{plan};
			delete $cur_plan_info{$t_pid};
		}

	} else {
		$cur_info{$t_pid}{year}      = $prefix_vars{'t_year'} if (! $cur_info{$t_pid}{year});
		$cur_info{$t_pid}{month}     = $prefix_vars{'t_month'} if (! $cur_info{$t_pid}{month});
		$cur_info{$t_pid}{day}       = $prefix_vars{'t_day'} if (! $cur_info{$t_pid}{day});
		$cur_info{$t_pid}{hour}      = $prefix_vars{'t_hour'} if ($cur_info{$t_pid}{hour} eq '');
		$cur_info{$t_pid}{min}       = $prefix_vars{'t_min'} if (! $cur_info{$t_pid}{min} eq '');
		$cur_info{$t_pid}{sec}       = $prefix_vars{'t_sec'} if (! $cur_info{$t_pid}{sec} eq '');
		$cur_info{$t_pid}{timestamp} = $prefix_vars{'t_timestamp'} if (! $cur_info{$t_pid}{timestamp});
		$cur_info{$t_pid}{ident}     = $prefix_vars{'t_ident'} if (! $cur_info{$t_pid}{ident});
		$cur_info{$t_pid}{query}     = $prefix_vars{'t_query'} if (! $cur_info{$t_pid}{query});
		$cur_info{$t_pid}{duration}  = $prefix_vars{'t_duration'} if (! $cur_info{$t_pid}{duration});
		$cur_info{$t_pid}{pid}       = $prefix_vars{'t_pid'} if (! $cur_info{$t_pid}{pid});
		$cur_info{$t_pid}{session}   = $prefix_vars{'t_session_line'} if (! $cur_info{$t_pid}{session});
		$cur_info{$t_pid}{loglevel}  = $prefix_vars{'t_loglevel'} if (! $cur_info{$t_pid}{loglevel});
		$cur_info{$t_pid}{dbname}    = $prefix_vars{'t_dbname'} if (! $cur_info{$t_pid}{dbname});
		$cur_info{$t_pid}{dbuser}    = $prefix_vars{'t_dbuser'} if (! $cur_info{$t_pid}{dbuser});
		$cur_info{$t_pid}{dbclient}  = $prefix_vars{'t_client'} || $prefix_vars{'t_dbclient'} if (! $cur_info{$t_pid}{dbclient});
		$cur_info{$t_pid}{dbappname} = $prefix_vars{'t_appname'} if (! $cur_info{$t_pid}{dbappname});
		$cur_info{$t_pid}{date}      = $prefix_vars{'t_date'} if (! $cur_info{$t_pid}{date});
		$cur_info{$t_pid}{bind}      = $prefix_vars{'t_bind'} if (! $cur_info{$t_pid}{bind});

		# Extract the query part from the plan
		if (exists $cur_plan_info{$t_pid} && ($cur_plan_info{$t_pid}{plan} ne '')) {
			$cur_plan_info{$t_pid}{plan} =~ s/^\s*Query Text: (.*?);//s;
			$cur_info{$t_pid}{plan} = $cur_plan_info{$t_pid}{plan};
			delete $cur_plan_info{$t_pid};
		}

	}

}

sub store_tsung_session
{
	my $pid = shift;

	return if ($#{$tsung_session{$pid}{dates}} < 0);

	# Open filehandle
	my $fh = new IO::File ">>$outfile";
	if (not defined $fh) {
		die "FATAL: can't write to $outfile, $!\n";
	}
	if ($pid) {
		print $fh "  <session weight=\"100\" name=\"pgbadger-$pid\" type=\"ts_pgsql\">\n";
		if (exists $tsung_session{$pid}{connection}{database}) {
			print $fh qq{    <transaction name="connection">
      <request><pgsql type="connect" database="$tsung_session{$pid}{connection}{database}" username="$tsung_session{$pid}{connection}{user}" /></request>
      <request><pgsql type="authenticate" password="changeme"/></request>
    </transaction>
};
		}
		if ($#{$tsung_session{$pid}{dates}} >= 0) {
			my $sec = 0;
			if ($tsung_session{$pid}{connection}{date}) {
				$sec = $tsung_session{$pid}{dates}[0] - $tsung_session{$pid}{connection}{date};
			}
			print $fh "    <thinktime value=\"$sec\" random=\"true\"></thinktime>\n" if ($sec > 0);
			print $fh "    <transaction name=\"requests\">\n";
			for (my $i = 0 ; $i <= $#{$tsung_session{$pid}{queries}} ; $i++) {
				$tsung_queries++;
				$sec = 0;
				if ($i > 0) {
					$sec = $tsung_session{$pid}{dates}[$i] - $tsung_session{$pid}{dates}[$i - 1];
					print $fh "    <thinktime value=\"$sec\" random=\"true\"></thinktime>\n" if ($sec > 0);
				}
				print $fh "    <request><pgsql type='sql'><![CDATA[$tsung_session{$pid}{queries}[$i];]]></pgsql></request>\n";
			}
			print $fh "    </transaction>\n";
		}
		if ($#{$tsung_session{$pid}{dates}} >= 0) {
			my $sec = $tsung_session{$pid}{disconnection}{date} - $tsung_session{$pid}{dates}[-1];
			print $fh "    <thinktime value=\"$sec\" random=\"true\"></thinktime>\n" if ($sec > 0);
		}
		if (exists $tsung_session{$pid}{connection}{database}) {
			print $fh "    <request><pgsql type=\"close\"></pgsql></request>\n";
		}
		print $fh "  </session>\n\n";
		delete $tsung_session{$pid};
	}
	$fh->close;
}

sub store_queries
{
	my $t_pid  = shift;
	my $end  = shift;

	return 0 if (!$end && $log_duration && ($cur_info{$t_pid}{duration} eq ''));

	# Remove comments if required
	if ($remove_comment) {
		$cur_info{$t_pid}{query} =~ s/\/\*(.*?)\*\///gs;
	}

	# Anonymize query if requested by the user
	if ($anonymize && exists $cur_info{$t_pid}{query}) {
		$cur_info{$t_pid}{query} = &anonymize_query($cur_info{$t_pid}{query});
	}

	# Stores temporary files and lock information
	&store_temporary_and_lock_infos($t_pid);

	return 0 if (!exists $cur_info{$t_pid});
	return 1 if (!$cur_info{$t_pid}{year});

	# Cleanup and normalize the current query
	$cur_info{$t_pid}{query} =~ s/^[\t\s\r\n]+//s;
	$cur_info{$t_pid}{query} =~ s/[\t\s\r\n;]+$//s;

	# Replace bind parameters values in the query if any
	if (exists $cur_info{$t_pid}{parameters} && ($cur_info{$t_pid}{parameters} =~ /[,\s]*\$(\d+)\s=\s/)) {
		my @t_res = split(/[,\s]*\$(\d+)\s=\s/, $cur_info{$t_pid}{parameters});
		shift(@t_res);
		for (my $i = 0 ; $i < $#t_res ; $i += 2) {
			$cur_info{$t_pid}{query} =~ s/\$$t_res[$i]\b/$t_res[$i+1]/s;
		}
	} else {
		# parameters from EXECUTE statements
		my @t_res = split(/[\s]*,[\s]*/, $cur_info{$t_pid}{parameters});
		for (my $i = 0 ; $i <= $#t_res ; $i++) {
			my $num = $i + 1;
			$cur_info{$t_pid}{query} =~ s/\$$num\b/$t_res[$i]/s;
		}
	}

	# We only process stored object with query here
	if ($cur_info{$t_pid}{query}) {
		# Should we just want select queries
		if ($select_only) {
			return 1 if ($cur_info{$t_pid}{query} !~ /^SELECT/is);
		}

		# Should we have to exclude some queries
		if ($#exclude_query >= 0) {
			foreach (@exclude_query) {
				if ($cur_info{$t_pid}{query} =~ /$_/i) {
					$cur_info{$t_pid}{query} = '';
					return 1;
				}
			}
		}

		# Should we have to include only some queries
		if ($#include_query >= 0) {
			foreach (@include_query) {
				if ($cur_info{$t_pid}{query} !~ /$_/i) {
					$cur_info{$t_pid}{query} = '';
					return 1;
				}
			}
		}

		# Dump queries as tsung request and return
		if ($extension eq 'tsung') {
			if ($cur_info{$t_pid}{loglevel} eq 'LOG') {
				push(@{$tsung_session{$t_pid}{queries}}, $cur_info{$t_pid}{query});
				push(@{$tsung_session{$t_pid}{dates}},   $cur_info{$t_pid}{date});
				if (!exists $tsung_session{$t_pid}{connection} && $cur_info{$t_pid}{dbname}) {
					$tsung_session{$t_pid}{connection}{database} = $cur_info{$t_pid}{dbname};
					$tsung_session{$t_pid}{connection}{user}     = $cur_info{$t_pid}{dbuser};
					$tsung_session{$t_pid}{connection}{date}     = $cur_info{$t_pid}{date};
				}
			}

			# Stores global statistics
			$overall_stat{'queries_number'}++;
			$overall_stat{'queries_duration'} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			return 1;
		}

		# Truncate the query if requested by the user
		$cur_info{$t_pid}{query} = substr($cur_info{$t_pid}{query}, 0, $maxlength) . '[...]'
			if (($maxlength > 0) && (length($cur_info{$t_pid}{query}) > $maxlength));

	}

	my $cur_day_str = "$cur_info{$t_pid}{year}$cur_info{$t_pid}{month}$cur_info{$t_pid}{day}";
	my $cur_hour_str = "$cur_info{$t_pid}{hour}";

	# Store the collected information into global statistics
	if ($cur_info{$t_pid}{loglevel} =~ $main_error_regex) {

		# Add log level at beginning of the query and normalize it
		$cur_info{$t_pid}{query} = $cur_info{$t_pid}{loglevel} . ":  " . $cur_info{$t_pid}{query};
		my $normalized_error = &normalize_error($cur_info{$t_pid}{query});

		# Stores total and normalized error count
		$overall_stat{'errors_number'}++;
		$error_info{$normalized_error}{count}++;

		# Stores normalized error count per time
		$error_info{$normalized_error}{chronos}{"$cur_day_str"}{"$cur_hour_str"}{count}++;
		$error_info{$normalized_error}{chronos}{"$cur_day_str"}{"$cur_hour_str"}{min}{$cur_info{$t_pid}{min}}++;

		# Stores log level count per minute
		$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{log_level}{$cur_info{$t_pid}{loglevel}}++;

		# Stores normalized query samples
		if ($sample > 0) {
			my $cur_last_log_timestamp = "$cur_info{$t_pid}{year}-$cur_info{$t_pid}{month}-$cur_info{$t_pid}{day} " .
							"$cur_info{$t_pid}{hour}:$cur_info{$t_pid}{min}:$cur_info{$t_pid}{sec}";
			&set_top_error_sample(	$normalized_error, 
									$cur_last_log_timestamp, 
									$cur_info{$t_pid}{query}, 
									$cur_info{$t_pid}{detail},
									$cur_info{$t_pid}{context}, 
									$cur_info{$t_pid}{statement}, 
									$cur_info{$t_pid}{hint}, 
									$cur_info{$t_pid}{dbname}, 
									$cur_info{$t_pid}{dbuser},
									$cur_info{$t_pid}{dbappname},
									$cur_info{$t_pid}{dbclient}
			);
		}

	} elsif ($cur_info{$t_pid}{loglevel} eq 'LOG') {

		# Stores global statistics

		$overall_stat{'queries_number'}++;
		$overall_stat{'queries_duration'} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});

		my $cur_last_log_timestamp = "$cur_info{$t_pid}{year}-$cur_info{$t_pid}{month}-$cur_info{$t_pid}{day} " .
						"$cur_info{$t_pid}{hour}:$cur_info{$t_pid}{min}:$cur_info{$t_pid}{sec}";
		if (!$overall_stat{'first_query_ts'} || ($overall_stat{'first_query_ts'} gt $cur_last_log_timestamp)) {
			$overall_stat{'first_query_ts'}   = $cur_last_log_timestamp;
		}
		if (!$overall_stat{'last_query_ts'} || ($overall_stat{'last_query_ts'} lt $cur_last_log_timestamp)) {
			$overall_stat{'last_query_ts'} = $cur_last_log_timestamp;
		}
		$overall_stat{'peak'}{$cur_last_log_timestamp}{query}++;

		if ($graph) {
			$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{count}++;
			$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{second}{$cur_info{$t_pid}{sec}}++;
			# Store min / max duration
			if ($cur_info{$t_pid}{duration}) {
				$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
				if (!exists $per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{min} || ($per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{min} > $cur_info{$t_pid}{duration})) {
					$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{min} = $cur_info{$t_pid}{duration};
				}
				if (!exists $per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{max} || ($per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{max} < $cur_info{$t_pid}{duration})) {
					$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{query}{max} = $cur_info{$t_pid}{duration};
				}
			}
		}

		# Counter per database and application name
		if ($cur_info{$t_pid}{dbname}) {
			$database_info{$cur_info{$t_pid}{dbname}}{count}++;
			$database_info{$cur_info{$t_pid}{dbname}}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		} else {
			$database_info{unknown}{count}++;
			$database_info{unknown}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		}
		if ($cur_info{$t_pid}{dbappname}) {
			$application_info{$cur_info{$t_pid}{dbappname}}{count}++;
			$application_info{$cur_info{$t_pid}{dbappname}}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		} else {
			$application_info{unknown}{count}++;
			$application_info{unknown}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		}
		if ($cur_info{$t_pid}{dbuser}) {
			$user_info{$cur_info{$t_pid}{dbuser}}{count}++;
			$user_info{$cur_info{$t_pid}{dbuser}}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		} else {
			$user_info{unknown}{count}++;
			$user_info{unknown}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		}
		if ($cur_info{$t_pid}{dbclient}) {
			$host_info{$cur_info{$t_pid}{dbclient}}{count}++;
			$host_info{$cur_info{$t_pid}{dbclient}}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		} else {
			$host_info{unknown}{count}++;
			$host_info{unknown}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
		}

		if ($cur_info{$t_pid}{query}) {

			# Add a semi-colon at end of the query
			$cur_info{$t_pid}{query} .= ';' if ($cur_info{$t_pid}{query} !~ /;\s*$/s);

			# Normalize query
			my $normalized = &normalize_query($cur_info{$t_pid}{query});
			my $action = uc($1);
			if ($normalized =~ $action_regex) {
				$action = uc($1);
				# If this is a copy statement try to find if this is a write or read statement
				if (($action eq 'COPY') && (($normalized =~ /FROM\s+STDIN/i) || ($normalized =~ /FROM\s+'[^']+'/is))) {
					$action = 'INSERT';
				} elsif ($action eq 'COPY') {
					$action = 'SELECT';
				}
			} else {
				$action = 'OTHERS';
			}
			$overall_stat{$action}++;
			if ($action eq 'SELECT') {
				$overall_stat{'peak'}{$cur_last_log_timestamp}{select}++;
			} elsif ($action ne 'OTHERS') {
				$overall_stat{'peak'}{$cur_last_log_timestamp}{write}++;
			}
			$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{$action}{count}++;
			$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{$action}{second}{$cur_info{$t_pid}{sec}}++;
			$per_minute_info{"$cur_day_str"}{"$cur_hour_str"}{$cur_info{$t_pid}{min}}{$action}{duration} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			if ($cur_info{$t_pid}{dbname}) {
				$database_info{$cur_info{$t_pid}{dbname}}{$action}++;
				$database_info{$cur_info{$t_pid}{dbname}}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			} else {
				$database_info{unknown}{$action}++;
				$database_info{unknown}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			}
			if ($cur_info{$t_pid}{dbappname}) {
				$application_info{$cur_info{$t_pid}{dbappname}}{$action}++;
				$application_info{$cur_info{$t_pid}{dbappname}}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			} else {
				$application_info{unknown}{$action}++;
				$application_info{unknown}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			}
			if ($cur_info{$t_pid}{dbuser}) {
				$user_info{$cur_info{$t_pid}{dbuser}}{$action}++;
				$user_info{$cur_info{$t_pid}{dbuser}}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			} else {
				$user_info{unknown}{$action}++;
				$user_info{unknown}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			}
			if ($cur_info{$t_pid}{dbclient}) {
				$host_info{$cur_info{$t_pid}{dbclient}}{$action}++;
				$host_info{$cur_info{$t_pid}{dbclient}}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			} else {
				$host_info{unknown}{$action}++;
				$host_info{unknown}{"$action|duration"} += $cur_info{$t_pid}{duration} if ($cur_info{$t_pid}{duration});
			}

			# Store normalized query count
			$normalyzed_info{$normalized}{count}++;

			# Store normalized query count and duration per time
			$normalyzed_info{$normalized}{chronos}{"$cur_day_str"}{"$cur_hour_str"}{count}++;
			$normalyzed_info{$normalized}{chronos}{"$cur_day_str"}{"$cur_hour_str"}{min}{$cur_info{$t_pid}{min}}++;

			if ($cur_info{$t_pid}{duration}) {

				# Update top slowest queries statistics
				&set_top_slowest($cur_info{$t_pid}{query}, $cur_info{$t_pid}{duration}, $cur_last_log_timestamp, $cur_info{$t_pid}{dbname}, $cur_info{$t_pid}{dbuser}, $cur_info{$t_pid}{dbclient},$cur_info{$t_pid}{dbappname}, $cur_info{$t_pid}{bind}, $cur_info{$t_pid}{plan});

				# Store normalized query total duration
				$normalyzed_info{$normalized}{duration} += $cur_info{$t_pid}{duration};
				$normalyzed_info{$normalized}{chronos}{"$cur_day_str"}{"$cur_hour_str"}{min_duration}{$cur_info{$t_pid}{min}} += $cur_info{$t_pid}{duration};

				# Store min / max duration
				if (!exists $normalyzed_info{$normalized}{min} || ($normalyzed_info{$normalized}{min} > $cur_info{$t_pid}{duration})) {
					$normalyzed_info{$normalized}{min} = $cur_info{$t_pid}{duration};
				}
				if (!exists $normalyzed_info{$normalized}{max} || ($normalyzed_info{$normalized}{max} < $cur_info{$t_pid}{duration})) {
					$normalyzed_info{$normalized}{max} = $cur_info{$t_pid}{duration};
				}

				# Stores query/user information
				if ($cur_info{$t_pid}{dbuser}) {
					$normalyzed_info{$normalized}{users}{$cur_info{$t_pid}{dbuser}}{duration} += $cur_info{$t_pid}{duration};
					$normalyzed_info{$normalized}{users}{$cur_info{$t_pid}{dbuser}}{count}++;
				}

				# Stores query/app information
				if ($cur_info{$t_pid}{dbappname}) {
					$normalyzed_info{$normalized}{apps}{$cur_info{$t_pid}{dbappname}}{duration} += $cur_info{$t_pid}{duration};
					$normalyzed_info{$normalized}{apps}{$cur_info{$t_pid}{dbappname}}{count}++;
				}

				# Store normalized query count and duration per time
				$normalyzed_info{$normalized}{chronos}{"$cur_day_str"}{"$cur_hour_str"}{duration} += $cur_info{$t_pid}{duration};

				# Store normalized query samples
				&set_top_sample($normalized, $cur_info{$t_pid}{query}, $cur_info{$t_pid}{duration}, $cur_last_log_timestamp, $cur_info{$t_pid}{dbname}, $cur_info{$t_pid}{dbuser}, $cur_info{$t_pid}{dbclient},$cur_info{$t_pid}{dbappname}, $cur_info{$t_pid}{bind}, $cur_info{$t_pid}{plan});
			}
		}
	}
	return 1;
}

sub store_temporary_and_lock_infos
{
	my $t_pid = shift;

	return if (!$t_pid);

	# Store normalized query temp file size if required
	if (exists $cur_temp_info{$t_pid} && ($cur_temp_info{$t_pid}{query} ne '') && $cur_temp_info{$t_pid}{size}) {

		# Add a semi-colon at end of the query
		$cur_temp_info{$t_pid}{query} .= ';' if ($cur_temp_info{$t_pid}{query} !~ /;\s*$/s);

		# Anonymize query if requested by the user
		if ($anonymize) {
			$cur_temp_info{$t_pid}{query} = &anonymize_query($cur_temp_info{$t_pid}{query});
		}

		# Normalize query
		my $normalized = &normalize_query($cur_temp_info{$t_pid}{query});

		$normalyzed_info{$normalized}{tempfiles}{size} += $cur_temp_info{$t_pid}{size};
		$normalyzed_info{$normalized}{tempfiles}{count}++;

		if ($normalyzed_info{$normalized}{tempfiles}{maxsize} < $cur_temp_info{$t_pid}{size}) {
			$normalyzed_info{$normalized}{tempfiles}{maxsize} = $cur_temp_info{$t_pid}{size};
		}
		if (!exists($normalyzed_info{$normalized}{tempfiles}{minsize})
		    || $normalyzed_info{$normalized}{tempfiles}{minsize} > $cur_temp_info{$t_pid}{size}) {
			$normalyzed_info{$normalized}{tempfiles}{minsize} = $cur_temp_info{$t_pid}{size};
		}
		&set_top_tempfile_info($cur_temp_info{$t_pid}{query}, $cur_temp_info{$t_pid}{size}, $cur_temp_info{$t_pid}{timestamp}, $cur_temp_info{$t_pid}{dbname}, $cur_temp_info{$t_pid}{dbuser}, $cur_temp_info{$t_pid}{dbclient}, $cur_temp_info{$t_pid}{dbappname});
		delete $cur_temp_info{$t_pid};
	}

	# Store normalized query that waited the most if required
	if (exists $cur_lock_info{$t_pid}{wait} && ($cur_lock_info{$t_pid}{query} ne '')) {

		# Add a semi-colon at end of the query
		$cur_lock_info{$t_pid}{query} .= ';' if ($cur_lock_info{$t_pid}{query} !~ /;\s*$/s);

		# Anonymize query if requested by the user
		if ($anonymize) {
			$cur_temp_info{$t_pid}{query} = &anonymize_query($cur_temp_info{$t_pid}{query});
		}

		# Normalize query
		my $normalized = &normalize_query($cur_lock_info{$t_pid}{query});

		$normalyzed_info{$normalized}{locks}{wait} += $cur_lock_info{$t_pid}{wait};
		$normalyzed_info{$normalized}{locks}{count}++;
		if ($normalyzed_info{$normalized}{locks}{maxwait} < $cur_lock_info{$t_pid}{wait}) {
			$normalyzed_info{$normalized}{locks}{maxwait} = $cur_lock_info{$t_pid}{wait};
		}
		if (!exists($normalyzed_info{$normalized}{locks}{minwait})
		    || $normalyzed_info{$normalized}{locks}{minwait} > $cur_lock_info{$t_pid}{wait}) {
			$normalyzed_info{$normalized}{locks}{minwait} = $cur_lock_info{$t_pid}{wait};
		}
		&set_top_locked_info($cur_lock_info{$t_pid}{query}, $cur_lock_info{$t_pid}{wait}, $cur_lock_info{$t_pid}{timestamp}, $cur_lock_info{$t_pid}{dbname}, $cur_lock_info{$t_pid}{dbuser}, $cur_lock_info{$t_pid}{dbclient}, $cur_lock_info{$t_pid}{dbappname});
		delete $cur_lock_info{$t_pid};
	}

	# Store normalized query temp file size if required
	if (exists $cur_cancel_info{$t_pid} && ($cur_cancel_info{$t_pid}{query} ne '')) {

		# Add a semi-colon at end of the query
		$cur_cancel_info{$t_pid}{query} .= ';' if ($cur_cancel_info{$t_pid}{query} !~ /;\s*$/s);

		# Anonymize query if requested by the user
		if ($anonymize) {
			$cur_cancel_info{$t_pid}{query} = &anonymize_query($cur_cancel_info{$t_pid}{query});
		}

		# Normalize query
		my $normalized = &normalize_query($cur_cancel_info{$t_pid}{query});

		$normalyzed_info{$normalized}{cancelled}{count}++;

		&set_top_cancelled_info($cur_cancel_info{$t_pid}{query}, $cur_cancel_info{$t_pid}{count}, $cur_cancel_info{$t_pid}{timestamp}, $cur_cancel_info{$t_pid}{dbname}, $cur_cancel_info{$t_pid}{dbuser}, $cur_cancel_info{$t_pid}{dbclient}, $cur_cancel_info{$t_pid}{dbappname});
		delete $cur_cancel_info{$t_pid};
	}

}

# Normalize error messages
sub normalize_error
{
	my $orig_query = shift;

	return if (!$orig_query);

	# Remove character position
	$orig_query =~ s/ at character \d+//;

	# Remove encoding detail
	$orig_query =~ s/(byte sequence for encoding).*/$1/;

	# Replace changing parameter by ...
	$orig_query =~ s/"[^"]*"/"..."/g;
	$orig_query =~ s/\(.*\)/\(...\)/g;
	$orig_query =~ s/column .* does not exist/column "..." does not exist/;
	$orig_query =~ s/(database system was shut down at).*/$1 .../;
	$orig_query =~ s/(relation) \d+ (deleted while still in use)/$1 ... $2/g;
	$orig_query =~ s/[0-9A-F]{24}/.../g; # Remove WAL filename
	$orig_query =~ s/, u_uuid: [^,]+, file_path:.*/. Retrying/g;

	# Need more normalization stuff here
	return $orig_query;
}

sub average_per_minutes
{
	my $val = shift;
	my $idx = shift;

	my @lavgs = ();
	for (my $i = 0 ; $i < 60 ; $i += $idx) {
		push(@lavgs, sprintf("%02d", $i));
	}

	for (my $i = 0 ; $i <= $#lavgs ; $i++) {
		if ($val == $lavgs[$i]) {
			return "$lavgs[$i]";
		} elsif ($i == $#lavgs) {
			return "$lavgs[$i]";
		} elsif (($val > $lavgs[$i]) && ($val < $lavgs[$i + 1])) {
			return "$lavgs[$i]";
		}
	}
	return $val;
}

sub autodetect_format
{
	my $file = shift;

	# Open log file for reading
	my $nfound = 0;
	my $nline  = 0;
	my $fmt    = '';

	die "FATAL: can't open file $file, $!\n" unless(open(TESTFILE, $file));
	my $fltf = <TESTFILE>;
	close($fltf);
	# is file in binary format ?
	if ( $fltf =~ /^pst\d/ ) {
		$fmt = 'binary';
	}
	else { # try to detect syslogs or csv
		my ($tfile, $totalsize) = &get_log_file($file);
		my %ident_name = ();
		while (my $line = <$tfile>) {
			chomp($line);
			$line =~ s/\r//;
			next if (!$line);
			$nline++;

			# Are syslog lines ?
			if ($line =~
	/^[A-Z][a-z]{2}\s+\d+\s\d+:\d+:\d+(?:\s[^\s]+)?\s[^\s]+\s([^\s\[]+)\[\d+\]:(?:\s\[[^\]]+\])?\s\[\d+\-\d+\].*?(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):/
			   )
			{
				$fmt = 'syslog';
				$nfound++;
				$ident_name{$1}++;
			} elsif ($line =~
	/^\d+-\d+-\d+T\d+:\d+:\d+(?:.[^\s]+)?\s[^\s]+\s(?:[^\s]+\s)?(?:[^\s]+\s)?([^\s\[]+)\[\d+\]:(?:\s\[[^\]]+\])?\s\[\d+\-\d+\].*?(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):/
			   )
			{
				$fmt = 'syslog2';
				$nfound++;
				$ident_name{$1}++;

				# Are stderr lines ?
			} elsif (
				(
					$line =~
					/^\d+-\d+-\d+ \d+:\d+:\d+\.\d+(?: [A-Z\d]{3,6})?,.*,(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT),/
				)
				&& ($line =~ tr/,/,/ >= 12)
				)
			{
				$fmt = 'csv';
				$nfound++;
			} elsif ($line =~
	/\d+-\d+-\d+ \d+:\d+:\d+[\.0-9]*(?: [A-Z\d]{3,6})?(.*?)(LOG|WARNING|ERROR|FATAL|PANIC|DETAIL|STATEMENT|HINT|CONTEXT):\s+/
				)
			{
				$fmt = 'stderr';
				$nfound++;
			}
			last if (($nfound > 10) || ($nline > 5000));
		}
		$tfile->close();
		if (!$format) {
			if (!$fmt || ($nfound < 10)) {
				die "FATAL: unable to detect log file format from $file, please use -f option.\n";
			}
		}

		if (($fmt =~ /syslog/) && !$ident && (scalar keys %ident_name == 1)) {
			$ident = (keys %ident_name)[0];
		}
	}

	&logmsg('DEBUG', "Autodetected log format '$fmt' from $file");

	return $fmt;
}

sub progress_bar
{
	my ($got, $total, $width, $char, $queries, $errors) = @_;
	$width ||= 25;
	$char  ||= '=';
	my $num_width = length $total;
	my $nchars = (($width - 1) * $got / $total);
	$nchars = ($width - 1) if ($nchars >= $width);
	if ($extension eq 'tsung') {
		sprintf(
			"[%-${width}s] Parsed %${num_width}s bytes of %s (%.2f%%), queries: %d\r",
			$char x $nchars . '>',
			$got, $total, 100 * $got / +$total, ($queries || $overall_stat{'queries_number'})
		);
	} elsif ($format eq 'binary') {
		my $file = $_[-1];
		sprintf(
			"Loaded %d queries and %d events from binary file %s...\r",
			$overall_stat{'queries_number'}, $overall_stat{'errors_number'}, $file
		);
	} else {
		sprintf(
			"[%-${width}s] Parsed %${num_width}s bytes of %s (%.2f%%), queries: %d, events: %d\r",
			$char x $nchars . '>',
			$got, $total, 100 * $got / +$total, ($queries || $overall_stat{'queries_number'}), ($errors || $overall_stat{'errors_number'})
		);
	}
}

sub flotr2_graph
{
	my ($buttonid, $divid, $data1, $data2, $data3, $title, $ytitle, $legend1, $legend2, $legend3, $ytitle2, $data4, $legend4) = @_;

	if (!$data1) {
		return qq{
<div id="$divid" class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>
};
	}
	my $dateTracker_lblopts = '';
	if ($legend1) {
		$dateTracker_lblopts .= "'$legend1',";
		$legend1 = "{ data: d1, label: \"$legend1\", color: \"#6e9dc9\", mouse:{track:true}},";
	}
	if ($legend2) {
		$dateTracker_lblopts .= "'$legend2',";
		$legend2 = "{ data: d2, label: \"$legend2\", color: \"#f4ab3a\", mouse:{track:true}},";
	}
	if ($legend3) {
		$dateTracker_lblopts .= "'$legend3',";
		$legend3 = "{ data: d3, label: \"$legend3\", color: \"#ac7fa8\", mouse:{track:true}},";
	}
	if ($legend4) {
		$dateTracker_lblopts .= "'$legend4',";
		if ($ytitle2) {
			$legend4 = "{ data: d4, label: \"$legend4\", color: \"#8dbd0f\",yaxis: 2},";
		} else {
			$legend4 = "{ data: d4, label: \"$legend4\", color: \"#8dbd0f\", mouse:{track:true}},";
		}
	}
	$dateTracker_lblopts =~ s/,$//;
	$dateTracker_lblopts = "[$dateTracker_lblopts]";

	my $dateTracker_dataopts = '';
	if ($data1) {
		$data1 = "var d1 = [$data1];";
		$dateTracker_dataopts .= "d1,";
	}
	if ($data2) {
		$data2 = "var d2 = [$data2];";
		$dateTracker_dataopts .= "d2,";
	}
	if ($data3) {
		$data3 = "var d3 = [$data3];";
		$dateTracker_dataopts .= "d3,";
	}
	if ($data4) {
		$data4 = "var d4 = [$data4];";
		$dateTracker_dataopts .= "d4,";
	}
	$dateTracker_dataopts =~ s/,$//;
	$dateTracker_dataopts = "[$dateTracker_dataopts]";
	
	my $yaxis2 = '';
	if ($ytitle2) {
		$yaxis2 = "y2axis: { mode: \"normal\", title: \"$ytitle2\", min: 0, color: \"#8dbd0f\" },";
	}

	my $type = '';
	if ($ytitle eq 'Size of files') {
		$type = 'size';
	} elsif ($ytitle eq 'Duration') {
		$type = 'duration';
	}

	my $barwidth = $avg_minutes * 60 * 1000;
	my $bar_def = '';
	if ($bar_graph || ($divid eq 'eventspersecond_graph')) {
		my $stacked = 'false';
		$stacked = 'true' if ($divid eq 'eventspersecond_graph');
		$bar_def = qq{
        bars: {
            show: true,
	    stacked: $stacked,
            horizontal: false,
            shadowSize: 0,
	    barWidth: $barwidth,
        },
};
	}
	return <<EOF;
<div id="$divid" class="flotr-graph"></div>
<script type="text/javascript">
/* <![CDATA[ */
(function mouse_zoom(container) {
document.writeln('<div class="pull-right btn-group"><input type="button" class="btn" value="To Image" id="toimage$buttonid" onclick="return false;">'+
	'<input type="button" class="btn" value="Download" id="download$buttonid" onclick="return false;">' +
	'<input type="button" class="btn" value="To Chart" id="reset$buttonid" onclick="return false;"></div>'
	);
    $data1
    $data2
    $data3
    $data4
    var options = {
	$bar_def
        xaxis: {
            min: $t_min,
            max: $t_max,
            tickDecimals: 0,
            noTicks: 20,
            mode: "time",
            labelsAngle: 45
        },
        yaxis: {
            mode: "normal",
            title: "$ytitle",
	    min: null,
	    max: null,
	    autoscale: true,
	    tickFormatter: function(val){ return pretty_print_number(val,'$type') },
        },
	$yaxis2
        selection: {
            mode: "x",
            fps: 30
        },
       //title: "$title",
        legend: {
            position: "nw",
            backgroundColor: "#eee",
	    backgroundOpacity: 0.4
        },
	mouse: {
            track: true,
	    trackFormatter: function(obj){ return dateTracker(obj,'$type',$dateTracker_lblopts,$dateTracker_dataopts) },
            relative: true,
	    sensibility: 5,
	    trackDecimals: 2,
	    lineColor: 'purple',
        },
	crosshair: {
	    mode: 'x',
	    color: '#000000',
	    hideCursor: false,
	},
        HtmlText: false,
    };

    function drawGraph(opts) {
        var o = Flotr._.extend(Flotr._.clone(options), opts );
        return Flotr.draw(
        	container,
        	[
        		$legend1
        		$legend2
        		$legend3
			$legend4
    		],
    		o
    	);
    }

    var graph = drawGraph();
    Flotr.EventAdapter.observe(container, "flotr:select", function(area) {
        f = drawGraph({
            xaxis: {
                mode: "time",
                labelsAngle: 45,
                min: area.x1,
                max: area.x2
            },
            yaxis: {
                min: area.y1,
                max: area.y2,
                tickFormatter: function(val){ return pretty_print_number(val,'$type') }
            }
        });
    });
    Flotr.EventAdapter.observe(container, "flotr:click", function() {
        drawGraph();
    });
    jQuery("#reset$buttonid").click( function() {
      graph.download.restoreCanvas();
    });
    jQuery("#download$buttonid").click( function(){
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format');
    });
    jQuery("#toimage$buttonid").click( function() {
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format', null, null, true);
    });

})(document.getElementById("$divid"));
/* ]]> */
</script>
EOF

}

sub flotr2_piegraph
{
	my ($buttonid, $divid, $title, %data) = @_;

	my $type = '';
	if ($divid =~ /size/) {
		$type = 'size';
	} elsif ($divid =~ /duration/) {
		$type = 'duration';
	}

	if (scalar keys %data == 0) {
		return qq{
<div id="$divid" class="flotr-graph"><blockquote><b>NO DATASET</b></blockquote></div>
};

	}
	my @colors = ("#6e9dc9", "#f4ab3a", "#ac7fa8", "#8dbd0f");
	my @datadef = ();
	my @contdef = ();
	my $i       = 1;
	foreach my $k (sort { if ( ($a =~ /(\d+)/) && ($b =~ /(\d+)/) ) { ($a =~ /(\d+)/)[0] <=> ($b =~ /(\d+)/)[0]; } else { $a cmp $b; } } keys %data) {
		push(@datadef, "var d$i = [ [0,$data{$k}] ];\n");
		my $color = '';
		$color = ", color: \"$colors[$i-1]\"" if (($i-1) <= $#colors);
		push(@contdef, "{ data: d$i, label: \"$k\"$color },\n");
		$i++;
	}

	return <<EOF;
<div id="$divid" class="flotr-graph piegraph"></div>
<script type="text/javascript">
/* <![CDATA[ */
(function basic_pie(container) {

document.writeln('<div class="btn-group pull-right"><input type="button" class="btn" value="To Image" id="toimage$buttonid" onclick="return false;">'+
	'<input type="button" class="btn" value="Download" id="download$buttonid" onclick="return false;">' +
	'<input type="button" class="btn" value="To chart" id="reset$buttonid" onclick="return false;"></div>'
	);

    @datadef
    var graph = Flotr.draw(container, [
    @contdef
    ], {
        //title: "$title",
        HtmlText: false,
        grid: {
            verticalLines: false,
            horizontalLines: false,
	    backgroundColor: '#ffffff',
	    outline: '',
        },
        xaxis: {
            showLabels: false
        },
        yaxis: {
            showLabels: false
        },
        pie: {
            show: true,
	    explode: 6
        },
        mouse: {
            track: true,
	    trackFormatter: function(obj){ return pieTracker(obj, '$type') },
            relative: true
        },
        legend: {
            show: false,
            position: "sw",
            backgroundColor: "#D2E8FF",
	    backgroundOpacity: 0.4
        }
    });
    jQuery("#reset$buttonid").click( function() {
      graph.download.restoreCanvas();
    });
    jQuery("#download$buttonid").click( function(){
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format');
    });
    jQuery("#toimage$buttonid").click( function() {
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format', null, null, true);
    });


})(document.getElementById("$divid"));
/* ]]> */
</script>
EOF

}

sub flotr2_histograph
{
	my ($buttonid, $divid, $data1, $data2, $legend1, $legend2, $min, $max) = @_;

	if (!$data1) {
		return qq{
<div id="$divid" class="flotr-graph histo-graph"><blockquote><b>NO DATASET</b></blockquote></div>
};
	}
	$legend1 ||= 'Avg. queries';
	my $dateTracker_lblopts = "'$legend1',";
	$legend1 = "{ data: d1, label: \"$legend1\", color: \"#6e9dc9\", mouse:{track:true}, bars: {show: true,shadowSize: 0}, },";
	if ($data2) {
		$legend2 ||= 'Avg. duration';
		$dateTracker_lblopts .= "'$legend2'";
		$legend2 = "{ data: d2, label: \"$legend2\", color: \"#8dbd0f\", yaxis: 2},";
	}
	$dateTracker_lblopts =~ s/,$//;
	$dateTracker_lblopts = "[$dateTracker_lblopts]";

	my $dateTracker_dataopts = '';
	if ($data1) {
		$data1 = "var d1 = [$data1];";
		$dateTracker_dataopts .= "d1,";
	}
	if ($data2) {
		$data2 = "var d2 = [$data2];";
		$dateTracker_dataopts .= "d2";
	}
	$dateTracker_dataopts =~ s/,$//;
	$dateTracker_dataopts = "[$dateTracker_dataopts]";
	
	my $yaxis2 = "y2axis: { mode: \"normal\", noTicks: 4, title: \"Duration\", min: 0, color: \"#8dbd0f\", tickFormatter: function(val){ return pretty_print_number(val,'duration') }, },";
	$yaxis2 = '' if (!$data2);

	my $maxticks = (23*3600)+($histo_avgs[-1]*60);

	return <<EOF;
<div id="$divid" class="flotr-graph histo-graph"></div>
<script type="text/javascript">
/* <![CDATA[ */
(function mouse_zoom(container) {
    $data1
    $data2
    var options = {
        xaxis: {
	    min: $min,
	    max: $max,
	    tickDecimals: 0,
            noTicks: 48,
            mode: "time",
            labelsAngle: 45,
        },
        yaxis: {
            mode: "normal",
            title: "Count",
	    tickFormatter: function(val){ return pretty_print_number(val,'') },
            noTicks: 4,
        },
	$yaxis2
        selection: {
            mode: "x",
            fps: 30
        },
        legend: {
	    show: false,
            position: "nw",
            backgroundColor: "#eee",
	    backgroundOpacity: 0.4
        },
	mouse: {
            track: true,
	    trackFormatter: function(obj){ return histoHourTracker(obj,$dateTracker_lblopts,$dateTracker_dataopts) },
            relative: true,
	    sensibility: 5,
	    trackDecimals: 2,
	    lineColor: 'purple',
        },
	crosshair: {
	    mode: 'x',
	    color: '#000000',
	    hideCursor: false,
	},
        HtmlText: false,
    };

    function drawGraph(opts) {
        var o = Flotr._.extend(Flotr._.clone(options), opts );
        return Flotr.draw(
        	container,
        	[
        		$legend1
        		$legend2
    		],
    		o
    	);
    }

    var graph = drawGraph();
    Flotr.EventAdapter.observe(container, "flotr:select", function(area) {
        f = drawGraph({
            xaxis: {
                mode: "time",
                labelsAngle: 45,
                min: area.x1,
                max: area.x2
            },
            yaxis: {
                min: area.y1,
                max: area.y2,
                tickFormatter: function(val){ return pretty_print_number(val,'') }
            }
        });
    });
    Flotr.EventAdapter.observe(container, "flotr:click", function() {
        drawGraph();
    });
    jQuery("#reset$buttonid").click( function() {
      graph.download.restoreCanvas();
    });
    jQuery("#download$buttonid").click( function(){
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format');
    });
    jQuery("#toimage$buttonid").click( function() {
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format', null, null, true);
    });

})(document.getElementById("$divid"));
/* ]]> */
</script>
EOF

}

sub flotr2_duration_histograph
{
	my ($buttonid, $divid, $legend, $range, %data) = @_;

	if (scalar keys %data == 0) {
		return qq{
<div id="$divid" class="flotr-graph duration-histo-graph"><blockquote><b>NO DATASET</b></blockquote></div>
};
	}
	$legend ||= 'Queries';
	$legend = "{ data: d1, color: \"#6e9dc9\", mouse:{track:true}, bars: {show: true, shadowSize: 0}, },";

	my $dateTracker_dataopts = '[ d1 ]';
	my $data1 = "var d1 = [";
	my $max = 0;
	my $xmax = @$range + 1;
	my $dateTracker_lblopts = "[ '0', ";
	for (my $i = 1; $i <= $#{$range}; $i++) {
		my $k = "$range->[$i-1]-$range->[$i]ms";
		$max = $data{$k} if ($data{$k} > $max);
		$data1 .= " [$i, $data{$k}],";
		$data{"$histogram_query_time[$i-1]-$histogram_query_time[$i]ms"} = ($overall_stat{histogram}{query_time}{$histogram_query_time[$i-1]} || 0);
                $dateTracker_lblopts .= "'" . &convert_time($range->[$i-1]) . '-' . &convert_time($range->[$i]) . "',";
	}
	$dateTracker_lblopts .= "'> " . &convert_time($range->[-1]) . "'";
	$dateTracker_lblopts .= "]";
	$data1 =~ s/,$//;
	$data1 .= "];";
	if ($max > 3) {
		$max += int(($max*25)/100);
	} else {
		$max *= 2;
	}

	return <<EOF;
<div id="$divid" class="flotr-graph duration-histo-graph"></div>
<script type="text/javascript">
/* <![CDATA[ */
(function mouse_zoom(container) {
    $data1
    var options = {
	xaxis: {
		mode: "normal",
		min: 0,
		max: $xmax,
		tickDecimals: 0,
		noTicks: 20,
		tickFormatter: function(x) {
			var x = parseInt(x);
			var lbls = $dateTracker_lblopts;
			if (x >= lbls.length) {
				return '.';
			}
			return lbls[x];
		},
	},
        yaxis: {
	    mode: "normal",
            title: "Number of queries",
	    autoscaleMargin: 1,
	    min: 0,
	    max: $max,
	    tickFormatter: function(val){ return pretty_print_number(val,'') },
        },
	mouse: {
            track: true,
	    trackFormatter: function(obj){ return histoDurationTracker(obj,$dateTracker_lblopts,$dateTracker_dataopts) },
            relative: true,
	    sensibility: 5,
	    trackDecimals: 2,
	    lineColor: 'purple',
	    position: 'no',
        },
        HtmlText: false,
    };

    function drawGraph(opts) {
        var o = Flotr._.extend(Flotr._.clone(options), opts );
        return Flotr.draw(
        	container,
        	[
        		$legend
    		],
    		o
    	);
    }

    var graph = drawGraph();
    Flotr.EventAdapter.observe(container, "flotr:select", function(area) {
        f = drawGraph({
            xaxis: {
                mode: "time",
                labelsAngle: 45,
                min: area.x1,
                max: area.x2
            },
            yaxis: {
                min: area.y1,
                max: area.y2,
                tickFormatter: function(val){ return pretty_print_number(val,'') }
            }
        });
    });
    Flotr.EventAdapter.observe(container, "flotr:click", function() {
        drawGraph();
    });
    jQuery("#reset$buttonid").click( function() {
      graph.download.restoreCanvas();
    });
    jQuery("#download$buttonid").click( function(){
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format');
    });
    jQuery("#toimage$buttonid").click( function() {
	if (Flotr.isIE && Flotr.isIE < 9) {
		alert(
		"Your browser doesn't allow you to get a bitmap image from the plot, " +
		"you can only get a VML image that you can use in Microsoft Office.<br />"
		);
	}
      graph.download.saveImage('$img_format', null, null, true);
    });

})(document.getElementById("$divid"));
/* ]]> */
</script>
EOF

}


sub build_log_line_prefix_regex
{
	my %regex_map = (
		'%a' => [('t_appname',      '(.*)')],                                   # application name
		'%u' => [('t_dbuser',       '([0-9a-zA-Z\_\[\]\-]*)')],                                         # user name
		'%d' => [('t_dbname',       '([0-9a-zA-Z\_\[\]\-]*)')],                                         # database name
		'%r' => [('t_hostport',     '([a-zA-Z0-9\-\.]+|\[local\]|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|[0-9a-fA-F:]+)?[\(\d\)]*')],     # remote host and port
		'%h' => [('t_client',       '([a-zA-Z0-9\-\.]+|\[local\]|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|[0-9a-fA-F:]+)?')],              # remote host
		'%p' => [('t_pid',          '(\d+)')],                                                        # process ID
		'%t' => [('t_timestamp',    '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})(?: [A-Z\+\-\d]{3,6})?')],      # timestamp without milliseconds
		'%m' => [('t_mtimestamp',   '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\.\d+(?: [A-Z\+\-\d]{3,6})?')], # timestamp with milliseconds
		'%l' => [('t_session_line', '(\d+)')],                                                        # session line number
		'%s' => [('t_session_timestamp', '(\d{4}-\d{2}-\d{2} \d{2}):\d{2}:\d{2}(?: [A-Z\d]{3,6})?')],    # session start timestamp
		'%c' => [('t_session_id',        '([0-9a-f\.]*)')],                                               # session ID
		'%v' => [('t_virtual_xid',       '([0-9a-f\.\/]*)')],                                             # virtual transaction ID
		'%x' => [('t_xid',               '([0-9a-f\.\/]*)')],                                             # transaction ID
		'%i' => [('t_command',           '([0-9a-zA-Z\.\-\_]*)')],                                        # command tag
		'%e' => [('t_sqlstate',          '([0-9a-zA-Z]+)')],                                              # SQL state
	);
	my @param_list = ();
	$log_line_prefix =~ s/([\[\]\|\(\)\{\}])/\\$1/g;
	$log_line_prefix =~ s/\%l([^\d])\d+/\%l$1\\d\+/;
	$log_line_prefix =~ s/\%q//;
	while ($log_line_prefix =~ s/(\%[audrhptmlscvxie])/$regex_map{"$1"}->[1]/) {
		push(@param_list, $regex_map{"$1"}->[0]);
	}
	# replace %% by a single %
	$log_line_prefix =~ s/\%\%/\%/;
	return @param_list;
}

# Inclusion of Perl package SQL::Beautify
# Copyright (C) 2009 by Jonas Kramer
# Published under the terms of the Artistic License 2.0.
{

	package SQL::Beautify;

	use strict;
	use warnings;

	our $VERSION = 0.04;

	use Carp;

	# Keywords from SQL-92, SQL-99 and SQL-2003.
	use constant KEYWORDS => qw(
		ABSOLUTE ACTION ADD AFTER ALL ALLOCATE ALTER AND ANY ARE ARRAY AS ASC
		ASENSITIVE ASSERTION ASYMMETRIC AT ATOMIC AUTHORIZATION AVG BEFORE BEGIN
		BETWEEN BIGINT BINARY BIT BIT_LENGTH BLOB BOOLEAN BOTH BREADTH BY CALL
		CALLED CASCADE CASCADED CASE CAST CATALOG CHAR CHARACTER CHARACTER_LENGTH
		CHAR_LENGTH CHECK CLOB CLOSE COALESCE COLLATE COLLATION COLUMN COMMIT
		CONDITION CONNECT CONNECTION CONSTRAINT CONSTRAINTS CONSTRUCTOR CONTAINS
		CONTINUE CONVERT CORRESPONDING COUNT CREATE CROSS CUBE CURRENT CURRENT_DATE
		CURRENT_DEFAULT_TRANSFORM_GROUP CURRENT_PATH CURRENT_ROLE CURRENT_TIME
		CURRENT_TIMESTAMP CURRENT_TRANSFORM_GROUP_FOR_TYPE CURRENT_USER CURSOR
		CYCLE DATA DATE DAY DEALLOCATE DEC DECIMAL DECLARE DEFAULT DEFERRABLE
		DEFERRED DELETE DEPTH DEREF DESC DESCRIBE DESCRIPTOR DETERMINISTIC
		DIAGNOSTICS DISCONNECT DISTINCT DO DOMAIN DOUBLE DROP DYNAMIC EACH ELEMENT
		ELSE ELSEIF END EPOCH EQUALS ESCAPE EXCEPT EXCEPTION EXEC EXECUTE EXISTS
		EXIT EXTERNAL EXTRACT FALSE FETCH FILTER FIRST FLOAT FOR FOREIGN FOUND FREE
		FROM FULL FUNCTION GENERAL GET GLOBAL GO GOTO GRANT GROUP GROUPING HANDLER
		HAVING HOLD HOUR IDENTITY IF IMMEDIATE IN INDICATOR INITIALLY INNER INOUT
		INPUT INSENSITIVE INSERT INT INTEGER INTERSECT INTERVAL INTO IS ISOLATION
		ITERATE JOIN KEY LANGUAGE LARGE LAST LATERAL LEADING LEAVE LEFT LEVEL LIKE
		LIMIT LOCAL LOCALTIME LOCALTIMESTAMP LOCATOR LOOP LOWER MAP MATCH MAX
		MEMBER MERGE METHOD MIN MINUTE MODIFIES MODULE MONTH MULTISET NAMES
		NATIONAL NATURAL NCHAR NCLOB NEW NEXT NO NONE NOT NULL NULLIF NUMERIC
		OBJECT OCTET_LENGTH OF OLD ON ONLY OPEN OPTION OR ORDER ORDINALITY OUT
		OUTER OUTPUT OVER OVERLAPS PAD PARAMETER PARTIAL PARTITION PATH POSITION
		PRECISION PREPARE PRESERVE PRIMARY PRIOR PRIVILEGES PROCEDURE PUBLIC RANGE
		READ READS REAL RECURSIVE REF REFERENCES REFERENCING RELATIVE RELEASE
		REPEAT RESIGNAL RESTRICT RESULT RETURN RETURNS REVOKE RIGHT ROLE ROLLBACK
		ROLLUP ROUTINE ROW ROWS SAVEPOINT SCHEMA SCOPE SCROLL SEARCH SECOND SECTION
		SELECT SENSITIVE SESSION SESSION_USER SET SETS SIGNAL SIMILAR SIZE SMALLINT
		SOME SPACE SPECIFIC SPECIFICTYPE SQL SQLCODE SQLERROR SQLEXCEPTION SQLSTATE
		SQLWARNING START STATE STATIC SUBMULTISET SUBSTRING SUM SYMMETRIC SYSTEM
		SYSTEM_USER TABLE TABLESAMPLE TEMPORARY TEXT THEN TIME TIMESTAMP
		TIMEZONE_HOUR TIMEZONE_MINUTE TINYINT TO TRAILING TRANSACTION TRANSLATE
		TRANSLATION TREAT TRIGGER TRIM TRUE UNDER UNDO UNION UNIQUE UNKNOWN UNNEST
		UNTIL UPDATE UPPER USAGE USER USING VALUE VALUES VARCHAR VARYING VIEW WHEN
		WHENEVER WHERE WHILE WINDOW WITH WITHIN WITHOUT WORK WRITE YEAR ZONE
	);


	sub tokenize_sql
	{
		my ($query, $remove_white_tokens) = @_;

		my $re = qr{
    (
        (?:--)[\ \t\S]*      # single line comments
	|
	(?:\#|\@\-\@|\@\@|\#\#|<\->|\&<|\&>|<<\||\|>>|\&<\||\|\&>|<\^|>\^|\?\#|\?\-|\?\||\?\-\||\?\|\||\@>|<\@|\~=)
				# Geometric Operators
        |
        (?:\->>|\->|\#>|\?\&|\?)  # Json Operators
        |
        (?:<>|<=>|>=|<=|==|=|!=|!|<<|>>|<|>|\|\||\||&&|&|-|\+|\*(?!/)|/(?!\*)|\%|~|\^|\?)
                                # operators and tests
        |
        [\[\]\(\),;.]            # punctuation (parenthesis, comma)
        |
        \'\'(?!\')              # empty single quoted string
        |
        \"\"(?!\"")             # empty double quoted string
        |
        "(?>(?:(?>[^"\\]+)|""|\\.)*)+"
                                # anything inside double quotes, ungreedy
        |
        `(?>(?:(?>[^`\\]+)|``|\\.)*)+`
                                # anything inside backticks quotes, ungreedy
        |
        '(?>(?:(?>[^'\\]+)|''|\\.)*)+'
                                # anything inside single quotes, ungreedy.
        |
        /\*[\ \t\r\n\S]*?\*/      # C style comments
        |
        (?:[\w:@]+(?:\.(?:\w+|\*)?)*)
                                # words, standard named placeholders, db.table.*, db.*
        |
        (?: \$_\$ | \$\d+ | \${1,2})
                                # dollar expressions - eg $_$ $3 $$
        |
        \n                      # newline
        |
        [\t\ ]+                 # any kind of white spaces
    )
}smx;

		my @query = ();
		@query = $query =~ m{$re}smxg;

		if ($remove_white_tokens) {
			@query = grep(!/^[\s\n\r]*$/, @query);
		}

		return wantarray ? @query : \@query;
	}

	sub new
	{
		my ($class, %options) = @_;

		my $self = bless {%options}, $class;

		# Set some defaults.
		$self->{query}       = ''   unless defined($self->{query});
		$self->{spaces}      = 4    unless defined($self->{spaces});
		$self->{space}       = ' '  unless defined($self->{space});
		$self->{break}       = "\n" unless defined($self->{break});
		$self->{wrap}        = {}   unless defined($self->{wrap});
		$self->{keywords}    = []   unless defined($self->{keywords});
		$self->{rules}       = {}   unless defined($self->{rules});
		$self->{uc_keywords} = 0    unless defined $self->{uc_keywords};

		push(@{$self->{keywords}}, KEYWORDS);

		# Initialize internal stuff.
		$self->{_level} = 0;

		return $self;
	}

	# Add more SQL.
	sub add
	{
		my ($self, $addendum) = @_;

		$addendum =~ s/^\s*/ /;

		$self->{query} .= $addendum;
	}

	# Set SQL to beautify.
	sub query
	{
		my ($self, $query) = @_;

		$self->{query} = $query if (defined($query));

		return $self->{query};
	}

	# Beautify SQL.
	sub beautify
	{
		my ($self) = @_;

		$self->{_output}      = '';
		$self->{_level_stack} = [];
		$self->{_new_line}    = 1;

		my $last = '';
		$self->{_tokens} = [tokenize_sql($self->query, 1)];

		while (defined(my $token = $self->_token)) {
			my $rule = $self->_get_rule($token);

			# Allow custom rules to override defaults.
			if ($rule) {
				$self->_process_rule($rule, $token);
			}

			elsif ($token eq '(') {
				$self->_add_token($token);
				$self->_new_line;
				push @{$self->{_level_stack}}, $self->{_level};
				$self->_over unless $last and uc($last) eq 'WHERE';
			}

			elsif ($token eq ')') {
#				$self->_new_line;
				$self->{_level} = pop(@{$self->{_level_stack}}) || 0;
				$self->_add_token($token);
				$self->_new_line if ($self->_next_token
							and $self->_next_token !~ /^AS$/i
							and $self->_next_token ne ')'
							and $self->_next_token !~ /::/
							and $self->_next_token ne ';'
							and $self->_next_token ne ','
					);
			}

			elsif ($token eq ',') {
				$self->_add_token($token);
				$self->_new_line;
			}

			elsif ($token eq ';') {
				$self->_add_token($token);
				$self->_new_line;

				# End of statement; remove all indentation.
				@{$self->{_level_stack}} = ();
				$self->{_level} = 0;
			}

			elsif ($token =~ /^(?:SELECT|FROM|WHERE|HAVING|BEGIN|SET)$/i) {
				$self->_back if ($last and $last ne '(' and $last ne 'FOR');
				$self->_new_line;
				$self->_add_token($token);
				$self->_new_line if ((($token ne 'SET') || $last) and $self->_next_token and $self->_next_token ne '(' and $self->_next_token ne ';');
				$self->_over;
			}

			elsif ($token =~ /^(?:GROUP|ORDER|LIMIT)$/i) {
				$self->_back;
				$self->_new_line;
				$self->_add_token($token);
			}

			elsif ($token =~ /^(?:BY)$/i) {
				$self->_add_token($token);
				$self->_new_line;
				$self->_over;
			}

			elsif ($token =~ /^(?:CASE)$/i) {
				$self->_add_token($token);
				$self->_over;
			}

			elsif ($token =~ /^(?:WHEN)$/i) {
				$self->_new_line;
				$self->_add_token($token);
			}

			elsif ($token =~ /^(?:ELSE)$/i) {
				$self->_new_line;
				$self->_add_token($token);
			}

			elsif ($token =~ /^(?:END)$/i) {
				$self->_back;
				$self->_new_line;
				$self->_add_token($token);
			}

			elsif ($token =~ /^(?:UNION|INTERSECT|EXCEPT)$/i) {
				$self->_back unless $last and $last eq '(';
				$self->_new_line;
				$self->_add_token($token);
				$self->_new_line if ($self->_next_token and $self->_next_token ne '(');
				$self->_over;
			}

			elsif ($token =~ /^(?:LEFT|RIGHT|INNER|OUTER|CROSS)$/i) {
				$self->_back;
				$self->_new_line;
				$self->_add_token($token);
				$self->_over;
			}

			elsif ($token =~ /^(?:JOIN)$/i) {
				if ($last and $last !~ /^(?:LEFT|RIGHT|INNER|OUTER|CROSS)$/) {
					$self->_new_line;
				}

				$self->_add_token($token);
			}

			elsif ($token =~ /^(?:AND|OR)$/i) {
				$self->_new_line;
				$self->_add_token($token);
#				$self->_new_line;
			}

			elsif ($token =~ /^--/) {
				if (!$self->{no_comments}) {
					$self->_add_token($token);
					$self->_new_line;
				}
			}

			elsif ($token =~ /^\/\*.*\*\/$/s) {
				if (!$self->{no_comments}) {
					$token =~ s/\n[\s\t]+\*/\n\*/gs;
					$self->_new_line;
					$self->_add_token($token);
					$self->_new_line;
				}
			}

			else {
				$self->_add_token($token, $last);
			}

			$last = $token;
		}

		$self->_new_line;

		$self->{_output};
	}

	# Add a token to the beautified string.
	sub _add_token
	{
		my ($self, $token, $last_token) = @_;

		if ($self->{wrap}) {
			my $wrap;
			if ($self->_is_keyword($token)) {
				$wrap = $self->{wrap}->{keywords};
			} elsif ($self->_is_constant($token)) {
				$wrap = $self->{wrap}->{constants};
			}

			if ($wrap) {
				$token = $wrap->[0] . $token . $wrap->[1];
			}
		}

		my $last_is_dot = defined($last_token) && $last_token eq '.';

		if (!$self->_is_punctuation($token) and !$last_is_dot) {
			$self->{_output} .= $self->_indent;
		}

		# uppercase keywords
		$token = uc $token
			if $self->_is_keyword($token)
				and $self->{uc_keywords};

		$self->{_output} .= $token;

		# This can't be the beginning of a new line anymore.
		$self->{_new_line} = 0;
	}

	# Increase the indentation level.
	sub _over
	{
		my ($self) = @_;

		++$self->{_level};
	}

	# Decrease the indentation level.
	sub _back
	{
		my ($self) = @_;

		--$self->{_level} if ($self->{_level} > 0);
	}

	# Return a string of spaces according to the current indentation level and the
	# spaces setting for indenting.
	sub _indent
	{
		my ($self) = @_;

		if ($self->{_new_line}) {
			return $self->{space} x ($self->{spaces} * $self->{_level});
		} else {
			return $self->{space};
		}
	}

	# Add a line break, but make sure there are no empty lines.
	sub _new_line
	{
		my ($self) = @_;

		$self->{_output} .= $self->{break} unless ($self->{_new_line});
		$self->{_new_line} = 1;
	}

	# Have a look at the token that's coming up next.
	sub _next_token
	{
		my ($self) = @_;

		return @{$self->{_tokens}} ? $self->{_tokens}->[0] : undef;
	}

	# Get the next token, removing it from the list of remaining tokens.
	sub _token
	{
		my ($self) = @_;

		return shift @{$self->{_tokens}};
	}

	# Check if a token is a known SQL keyword.
	sub _is_keyword
	{
		my ($self, $token) = @_;

		return ~~ grep {$_ eq uc($token)} @{$self->{keywords}};
	}

	# Add new keywords to highlight.
	sub add_keywords
	{
		my $self = shift;

		for my $keyword (@_) {
			push @{$self->{keywords}}, ref($keyword) ? @{$keyword} : $keyword;
		}
	}

	# Add new rules.
	sub add_rule
	{
		my ($self, $format, $token) = @_;

		my $rules = $self->{rules}    ||= {};
		my $group = $rules->{$format} ||= [];

		push @{$group}, ref($token) ? @{$token} : $token;
	}

	# Find custom rule for a token.
	sub _get_rule
	{
		my ($self, $token) = @_;

		values %{$self->{rules}};    # Reset iterator.

		while (my ($rule, $list) = each %{$self->{rules}}) {
			return $rule if (grep {uc($token) eq uc($_)} @$list);
		}

		return undef;
	}

	sub _process_rule
	{
		my ($self, $rule, $token) = @_;

		my $format = {
			break => sub {$self->_new_line},
			over  => sub {$self->_over},
			back  => sub {$self->_back},
			token => sub {$self->_add_token($token)},
			push  => sub {push @{$self->{_level_stack}}, $self->{_level}},
			pop   => sub {$self->{_level} = pop(@{$self->{_level_stack}}) || 0},
			reset => sub {$self->{_level} = 0; @{$self->{_level_stack}} = ();},
		};

		for (split /-/, lc $rule) {
			&{$format->{$_}} if ($format->{$_});
		}
	}

	# Check if a token is a constant.
	sub _is_constant
	{
		my ($self, $token) = @_;

		return ($token =~ /^\d+$/ or $token =~ /^(['"`]).*\1$/);
	}

	# Check if a token is punctuation.
	sub _is_punctuation
	{
		my ($self, $token) = @_;
		return ($token =~ /^[,;.]$/);
	}

}

sub get_log_file
{
	my $logf = shift;

	my $lfile = undef;

	# get file size
	my $totalsize = 0;
	if (!$remote_host) {
		$totalsize = (stat("$logf"))[7] || 0 if ($logf ne '-');
	} elsif ($logf !~ /\.(gz|bz2|zip|xz)$/i) {
		&logmsg('DEBUG', "Looking for file size using command: $ssh_command \"ls -l $logf\" | awk '{print \$5}'");
		$totalsize = `$ssh_command "ls -l $logf" | awk '{print \$5}'`;
		chomp($totalsize);
		if ($totalsize eq '') {
			die "FATAL: can't get size of remote file, please check what's going wrong with command: $ssh_command \"ls -l $logf\" | awk '{print \$5}'\n";
		}
		&logmsg('DEBUG', "Remote file size: $totalsize");
		if (!$totalsize) {
			return $totalsize;
		}
	}
	my $iscompressed = 1;

	# Open a file handle
	if ($logf !~ /\.(gz|bz2|zip|xz)$/i) {
		if (!$remote_host) {
			open($lfile, $logf) || die "FATAL: cannot read log file $logf. $!\n";
		} else {
			# Open a pipe to zcat program for compressed log
			open($lfile,"$ssh_command \"cat $logf\" |") || die "FATAL: cannot read from pipe to $ssh_command \"cat $logf\". $!\n";
		}
		$totalsize = 0 if ($logf eq '-');
		$iscompressed = 0;
	} else {
		my $uncompress = $zcat;
		if (($logf =~ /\.bz2/i) && ($zcat =~ /^$zcat_cmd$/)) {
			$uncompress = $bzcat;
		} elsif (($logf =~ /\.zip/i) && ($zcat =~ /^$zcat_cmd$/)) {
			$uncompress = $ucat;
		}
		elsif (($logf =~ /\.xz/i) && ($zcat =~ /^$zcat_cmd$/)) {
			$uncompress = $xzcat;
		}
		if (!$remote_host) {
			&logmsg('DEBUG', "Compressed log file, will use command: $uncompress \"$logf\"");
			# Open a pipe to zcat program for compressed log
			open($lfile,"$uncompress \"$logf\" |") || die "FATAL: cannot read from pipe to $uncompress \"$logf\". $!\n";
		} else {
			&logmsg('DEBUG', "Compressed log file, will use command: $ssh_command \"$uncompress $logf\"");
			# Open a pipe to zcat program for compressed log
			open($lfile,"$ssh_command \"$uncompress $logf\" |") || die "FATAL: cannot read from pipe to $ssh_command \"$uncompress $logf\". $!\n";
		}


		# Real size of the file is unknown, try to find it
		# bz2 does not report real size
		$totalsize = 0;
		if ($logf =~ /\.(gz|zip|xz)$/i) {
			my $cmd_file_size = $gzip_uncompress_size;
			if ($logf =~ /\.zip$/i) {
				$cmd_file_size = $zip_uncompress_size;
			} elsif ($logf =~ /\.xz$/i) {
				$cmd_file_size = $xz_uncompress_size;
			}			
			$cmd_file_size =~ s/\%f/$logf/g;
			if (!$remote_host) {
				&logmsg('DEBUG', "Looking for file size using command: $cmd_file_size");
				$totalsize = `$cmd_file_size`;
			} else {
				&logmsg('DEBUG', "Looking for remote file size using command: $ssh_command $cmd_file_size");
				$totalsize = `$ssh_command $cmd_file_size`;
			}
			chomp($totalsize);
		}
		$queue_size = 0;
	}

	# In list context returns the filehandle and the size of the file
	if (wantarray()) {
		return ($lfile, $totalsize, $iscompressed);
	}
	# In scalar context return size only
	close($lfile);
	return $totalsize;
}

sub split_logfile
{
	my $logf = shift;

	# CSV file can't be parsed using multiprocessing
	return (0, -1) if ( $format eq 'csv' );

	# get file size
	my $totalsize = (stat("$logf"))[7] || 0;

	# Real size of the file is unknown, try to find it
	# bz2 does not report real size
	if ($totalsize <= 16777216) { #16MB
		#If the file is very small, many jobs actually make the parsing take longer
		#What is an acceptable file size????
		$queue_size = 0;
	} elsif ($logf =~ /\.(gz|zip|xz)$/i) {
		$totalsize = 0;
		my $cmd_file_size = $gzip_uncompress_size;
		if ($logf =~ /\.zip$/i) {
			$cmd_file_size = $zip_uncompress_size;
		} elsif ($logf =~ /\.xz$/i) {
			$cmd_file_size = $xz_uncompress_size;
		}
		$cmd_file_size =~ s/\%f/$logf/g;
		$totalsize = `$cmd_file_size`;
		chomp($totalsize);
		$queue_size = 0;
	} elsif ($logf =~ /\.bz2$/i) {
		$totalsize = 0;
		$queue_size = 0;
	}

	return (0, -1) if (!$totalsize);

	my @chunks = (0);
	my $i = 1;
	if ($last_parsed && $saved_last_line{current_pos} && ($saved_last_line{current_pos} < $totalsize)) {
		$chunks[0] = $saved_last_line{current_pos};
	}
	my ($lfile, $null) = &get_log_file($logf); # Get file handle to the file
	while ($i < $queue_size) {
		my $pos = int(($totalsize/$queue_size) * $i);
		if ($pos > $chunks[0]) {
			$lfile->seek($pos, 0);
			#Move the offset to the BEGINNING of each line, because the logic in process_file requires so
			$pos= $pos + length(<$lfile>) - 1;
			push(@chunks, $pos) if ($pos < $totalsize);
		}
		last if ($pos >= $totalsize);
		$i++;
	}
	$lfile->close();
	push(@chunks, $totalsize);

	return @chunks;
}

# Return the week number of the year for a given date
sub get_week_number
{
        my ($year, $month, $day) = @_;

#       %U     The week number of the current year as a decimal number, range 00 to 53, starting with the first
#              Sunday as the first day of week 01.
#       %V     The ISO 8601 week number (see NOTES) of the current year as a decimal number, range 01 to 53,
#              where week 1 is the first week that has at least 4 days in the new year.
#       %W     The week number of the current year as a decimal number, range 00 to 53, starting with the first
#              Monday as the first day of week 01.

	# Check if the date is valid first
	my $datefmt = POSIX::strftime("%Y-%m-%d", 1, 1, 1, $day, $month - 1, $year - 1900);
	if ($datefmt ne "$year-$month-$day") {
		return -1;
	}
	my $weekNumber = POSIX::strftime("%U", 1, 1, 1, $day, $month - 1, $year - 1900);

	return sprintf("%02d", $weekNumber+1);
}

# Returns day number of the week of a given days
sub get_day_of_week
{
        my ($year, $month, $day) = @_;

#       %w     The day of the week as a decimal, range 0 to 6, Sunday being 0.

	my $weekDay = POSIX::strftime("%w", 1,1,1,$day,--$month,$year-1900);

	return $weekDay;
}

# Returns all days following the week number
sub get_wdays_per_month
{
	my $wn = shift;
	my ($year, $month) = split(/\-/, shift);
	my @months = ();
	my @retdays = ();

	$month ||= '01';
	push(@months, "$year$month");
	my $start_month = $month;
	if ($month eq '01') {
		unshift(@months, ($year - 1) . "12");
	} else {
		unshift(@months, $year . sprintf("%02d", $month - 1));
	}
	if ($month == 12) {
		push(@months, ($year+1) . "01");
	} else {
		push(@months, $year . sprintf("%02d", $month + 1));
	}

	foreach my $d (@months) {
		$d =~ /^(\d{4})(\d{2})$/;
		my $y = $1;
		my $m = $2;
		foreach my $day ("01" .. "31") {
			# Check if the date is valid first
			my $datefmt = POSIX::strftime("%Y-%m-%d", 1, 1, 1, $day, $m - 1, $y - 1900);
			if ($datefmt ne "$y-$m-$day") {
				next;
			}
			my $weekNumber = POSIX::strftime("%U", 1, 1, 1, $day, $m - 1, $y - 1900);
			if ( ($weekNumber == $wn) || ( ($weekNumber eq '00') && (($wn == 1) || ($wn >= 52)) ) ) {
				push(@retdays, "$year-$m-$day");
				return @retdays if ($#retdays == 6);
			}
			next if ($weekNumber > $wn);
		}
	}

	return @retdays;
}

sub IsLeapYear
{
	return ((($_[0] & 3) == 0) && (($_[0] % 100 != 0) || ($_[0] % 400 == 0)));
} 

####
# Display calendar
####
sub get_calendar
{
	my ($year, $month) = @_;

	my $str = "<table class=\"table table-striped table-hover table-condensed\">\n";
	my @wday = qw(Su Mo Tu We Th Fr Sa);
	#my @wday = ('Mon','Tue','Wed','Thu','Fri','Sat','Sun');
	my @std_day = qw(Su Mo Tu We Th Fr Sa);
	my %day_lbl = ();
	for (my $i = 0; $i <= $#wday; $i++) {
		$day_lbl{$wday[$i]} = $wday[$i];
	}
	$str .= "<thead><tr><td>&nbsp;</td>";
	map { $str .= '<th>' . $day_lbl{$_} . '</th>'; } @wday;
	$str .= "</tr></thead>\n<tbody>\n";
	my @currow = ('','','','','','','');
	my $d = '';
	my $wd = 0;
	my $wn = 0;
	my $week = '';
	for $d ("01" .. "31") {
		last if (($d == 31) && grep(/^$month$/, '04','06','09','11'));
		last if (($d == 30) && ($month eq '02'));
		last if (($d == 29) && ($month eq '02') && !&IsLeapYear($year));
		$wd = &get_day_of_week($year,$month,$d);
		$wn =  &get_week_number($year,$month,$d);
		next if ($wn == -1);
		if ( !-e "$outdir/$year/$month/$d/index.html" ) {
			$currow[$wd] = "<td>$d</td>";
		} else {
			$currow[$wd] = "<td><a href=\"$year/$month/$d/index.html\" target=\"new\">$d</a></td>";
		}
		if ($wd == 6) {
			$week = sprintf("%02d", $wn);
			if (-e "$outdir/$year/week-$week/index.html") {
				$week = "<th><a href=\"$year/week-$week/index.html\" target=\"new\">$week</a>&nbsp;</th>";
			} else {
				$week = "<th>$week</th>";
			}
			map { $_ = "<td>&nbsp;</td>" if ($_ eq ''); } @currow;
			$str .= "<tr>$week" . join('', @currow) . "</tr>\n";
			@currow = ('','','','','','','');
		}
	} 
	if ( ($wd != 6) || ($currow[0] ne '') ) {
		$week = sprintf("%02d", $wn);
		if (-e "$outdir/$year/week-$week/index.html") {
			$week = "<th><a href=\"$year/week-$week/index.html\" target=\"new\">$week</a>&nbsp;</th>";
		} else {
			$week = "<th>$week</th>";
		}
		map { $_ = "<td>&nbsp;</td>" if ($_ eq ''); } @currow;
		$str .= "<tr>$week" . join('', @currow) . "</tr>\n";
		@currow = ('','','','','','','');
	}
	$str .=  "</tbody>\n</table>\n";

	my %month_name = (
		'01' => 'January', '02' => 'February', '03' => 'March', '04' => 'April',
		'05' => 'May', '06' => 'June', '07' => 'July', '08' => 'August',
		'09' => 'September', '10' => 'October', '11' => 'November', '12' => 'December'
	);
	return qq{
              <div class="panel panel-default">
                <div class="panel-heading">
                <i class="fa fa-cogs fa-2x pull-left fa-border"></i>&nbsp;<h2>$month_name{$month}</h2>
                </div>
                <div class="panel-body">
		$str
                </div>
              </div>
};

}

sub _gethostbyaddr
{
	my $ip = shift;

	my $host = undef;
	unless(exists $CACHE_DNS{$ip}) {
		eval {
			local $SIG{ALRM} = sub { die "DNS lookup timeout.\n"; };
			alarm($DNSLookupTimeout);
			$host = gethostbyaddr(inet_aton($ip), AF_INET);
			alarm(0);
		};
		if ($@) {
			$CACHE_DNS{$ip} = undef;
			#printf "_gethostbyaddr timeout : %s\n", $ip;
		}
		else {
			$CACHE_DNS{$ip} = $host;
			#printf "_gethostbyaddr success : %s (%s)\n", $ip, $host;
		}
	}

	return $CACHE_DNS{$ip} || $ip;

}

__DATA__

WRFILE: pgbadger.css

div#littleToc { display:none; }
html>body div#littleToc { display:block; background-color:white; color:black; position:fixed; bottom:10px; right:10px; width:50px; font-size:11px; text-align:left; border:0px; }
div#littleToc div#littleTocTitle { font-weight:bold; text-align:center;padding:2px; }
div#littleToc ul { padding:0px; text-indent:0px; margin:0px; }
div#littleToc li { font-size:11px; list-style-type:none; padding:0px; text-indent:0px; margin:0px; }
div#littleToc a { color:#000000; padding:2px; margin:2px; display:block; text-decoration:none; border:1px solid #CCCCCC; }
div#littleToc a:hover { text-decoration:none; background-color:#DDDDDD; }

.flotr-graph { color: #ac1316; z-index: 99;}
.sql  {font-family:monospace;}
.sql .imp {font-weight: bold; color: red;}
.sql .kw1 {color: #993333; font-weight: bold; text-transform: uppercase;}
.sql .kw2 {color: #993333; font-style: italic;}
.sql .kw3 {color: #993333; text-transform: uppercase;}
.sql .co1 {color: #808080; font-style: italic;}
.sql .co2 {color: #808080; font-style: italic;}
.sql .coMULTI {color: #808080; font-style: italic;}
.sql .es0 {color: #000099; font-weight: bold;}
.sql .br0 {color: #66cc66;}
.sql .sy0 {color: #000000;}
.sql .st0 {color: #ff0000;}
.sql .nu0 {color: #cc66cc;}
.sql span.xtra { display:block; }
.sql-smallsize  {width: 450px; }
.sql-middlesize  {width: 650px; }
.sql-largesize  {width: 100%; }

WRFILE: pgbadger.js

/* <![CDATA[ */

function dateTracker(obj, gtype, labels, datasets) 
{
	var dateToDisplay = new Date(parseInt(obj.x)); 
	var posValue = parseInt(obj.x);

	// look for the position in data arrays 
        var pos = 0;
        if (datasets != undefined) { 
                for (pos=0; pos < datasets[0].length; pos++) {
			// If timestamp are the same we have found the position
                        if (datasets[0][pos][0] == posValue) {
				// get out of here
                                break;
                        }
                }
	} else {
		return '<span class="mfigure">NO DATASET</span>';
        }

	var textToShow = '<div class="mouse-figures">On '+dateToDisplay.toGMTString();
	for (var i = 0; i < labels.length; i++) {
		if (datasets[i] != undefined) {
			textToShow += '<br><span class="mfigure">'+pretty_print_number(datasets[i][pos][1], gtype)+' <small>'+labels[i]+'</small></span>';
		}
	}
	textToShow += '</div>';
	return textToShow;
}

function histoHourTracker(obj, labels, datasets) 
{
	var dateToDisplay = new Date(parseInt(obj.x)); 
	var posValue = parseInt(obj.x);
 
	// look for the position in data arrays 
	 var pos = 0;
	 if (datasets != undefined) { 
		 for (pos=0; pos < datasets[0].length; pos++) {
			// If timestamp are the same we have found the position
			 if (datasets[0][pos][0] == posValue) {
				// get out of here
				 break;
			 }
		 }
	} else {
		return '<span class="mfigure">NO DATASET</span>';
	 }

	var textToShow = '<div class="mouse-figures">At '+dateToDisplay.toGMTString().substr(17, 5);
	for (var i = 0; i < labels.length; i++) {
		if (datasets[i] != undefined) {
			textToShow += '<br><span class="mfigure">'+pretty_print_number(datasets[i][pos][1])+' <small>'+labels[i]+'</small></span>';
		}
	}
	textToShow += '</div>';
	return textToShow;
}

function histoDurationTracker(obj, labels, datasets) 
{
	var posValue = parseInt(obj.x);
 
	// look for the position in data arrays 
	 var pos = 0;
	 if (datasets != undefined) { 
		 for (pos=0; pos < datasets[0].length; pos++) {
			// If timestamp are the same we have found the position
			 if (datasets[0][pos][0] == posValue) {
				// get out of here
				 break;
			 }
		 }
	} else {
		return '<span class="mfigure">NO DATASET</span>';
	 }

	var textToShow = '<div class="mouse-figures">';
	for (var i = 0; i < labels.length; i++) {
		if (datasets[i] != undefined) {
			textToShow += '<span class="smfigure">'+pretty_print_number(datasets[i][pos][1])+' <small>'+labels[pos+1]+'</small></span>';
		}
	}
	textToShow += '</div>';
	return textToShow;
}


function pretty_print_number(val, type) 
{
	if (type == 'size') {
		if (val >= 1125899906842624) {
			val = (val / 1125899906842624);
			val = val.toFixed(2) + " PiB";
		} else if (val >= 1099511627776) {
			val = (val / 1099511627776);
			val = val.toFixed(2) + " TiB";
		} else if (val >= 1073741824) {
			val = (val / 1073741824);
			val = val.toFixed(2) + " GiB";
		} else if (val >= 1048576) {
			val = (val / 1048576);
			val = val.toFixed(2) + " MiB";
		} else if (val >= 1024) {
			val = (val / 1024);
			val = val.toFixed(2) + " KiB";
		} else {
			val = val + " B";
		}
	} else if (type == 'duration') {
		if (val >= 1000) {
			val = (val / 1000);
			val = val.toFixed(3) + " sec";
		} else {
			val = val + " ms";
		}
	} else {
		if (val >= 1000000000000000) {
			val = (val / 1000000000000000);
			val = val.toFixed(2) + " P";
		} else if (val >= 1000000000000) {
			val = (val / 1000000000000);
			val = val.toFixed(2) + " T";
		} else if (val >= 1000000000) {
			val = (val / 1000000000);
			val = val.toFixed(2) + " G";
		} else if (val >= 1000000) {
			val = (val / 1000000);
			val = val.toFixed(2) + " M";
		} else if (val >= 1000) {
			val = (val / 1000);
			val = val.toFixed(2) + " K";
		}
	}
	return val;
}

function format_number(val) {
        var decimal = 2;
        var msep = ',';
        var deci = Math.round( Math.pow(10,decimal)*(Math.abs(val)-Math.floor(Math.abs(val)))) ;     
        val = Math.floor(Math.abs(val));
        if ((decimal==0)||(deci==Math.pow(10,decimal))) {deci=0;}
        var val_format=val+""; 
        var nb=val_format.length;
        for (var i=1;i<4;i++) {
                if (val>=Math.pow(10,(3*i))) {
                        val_format=val_format.substring(0,nb-(3*i))+msep+val_format.substring(nb-(3*i));
                }       
        }       
        if (decimal>0) {
                var decim="";
                for (var j=0;j<(decimal-deci.toString().length);j++) {decim+="0";}
                deci=decim+deci.toString();
		if (deci > 0) {
			val_format=val_format+"."+deci;
		}
        }
        if (parseFloat(val)<0) {val_format="-"+val_format;}
        return val_format;
}

function pieTracker(obj, utype) 
{
	var textToShow = '<span class="mfigure">';
	if (utype == 'duration') {
		textToShow += pretty_print_number(obj.y, utype);
	} else {
		textToShow += format_number(obj.y);
	}
	textToShow += ' <small>'+obj.series.label+'</small></span>';
	return textToShow;
}

WRFILE: bean.js
/*!
  * bean.js - copyright Jacob Thornton 2011
  * https://github.com/fat/bean
  * MIT License
  * special thanks to:
  * dean edwards: http://dean.edwards.name/
  * dperini: https://github.com/dperini/nwevents
  * the entire mootools team: github.com/mootools/mootools-core
  *//*global module:true, define:true*/
!function(e,t,n){typeof module!="undefined"?module.exports=n(e,t):typeof define=="function"&&typeof define.amd=="object"?define(n):t[e]=n(e,t)}("bean",this,function(e,t){var n=window,r=t[e],i=/over|out/,s=/[^\.]*(?=\..*)\.|.*/,o=/\..*/,u="addEventListener",a="attachEvent",f="removeEventListener",l="detachEvent",c=document||{},h=c.documentElement||{},p=h[u],d=p?u:a,v=Array.prototype.slice,m=/click|mouse|menu|drag|drop/i,g=/^touch|^gesture/i,y={one:1},b=function(e,t,n){for(n=0;n<t.length;n++)e[t[n]]=1;return e}({},("click dblclick mouseup mousedown contextmenu mousewheel DOMMouseScroll mouseover mouseout mousemove selectstart selectend keydown keypress keyup orientationchange focus blur change reset select submit load unload beforeunload resize move DOMContentLoaded readystatechange error abort scroll "+(p?"show input invalid touchstart touchmove touchend touchcancel gesturestart gesturechange gestureend message readystatechange pageshow pagehide popstate hashchange offline online afterprint beforeprint dragstart dragenter dragover dragleave drag drop dragend loadstart progress suspend emptied stalled loadmetadata loadeddata canplay canplaythrough playing waiting seeking seeked ended durationchange timeupdate play pause ratechange volumechange cuechange checking noupdate downloading cached updateready obsolete ":"")).split(" ")),w=function(){function e(e,t){while((t=t.parentNode)!==null)if(t===e)return!0;return!1}function t(t){var n=t.relatedTarget;return n?n!==this&&n.prefix!=="xul"&&!/document/.test(this.toString())&&!e(this,n):n===null}return{mouseenter:{base:"mouseover",condition:t},mouseleave:{base:"mouseout",condition:t},mousewheel:{base:/Firefox/.test(navigator.userAgent)?"DOMMouseScroll":"mousewheel"}}}(),E=function(){var e="altKey attrChange attrName bubbles cancelable ctrlKey currentTarget detail eventPhase getModifierState isTrusted metaKey relatedNode relatedTarget shiftKey srcElement target timeStamp type view which".split(" "),t=e.concat("button buttons clientX clientY dataTransfer fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" ")),n=e.concat("char charCode key keyCode".split(" ")),r=e.concat("touches targetTouches changedTouches scale rotation".split(" ")),s="preventDefault",o=function(e){return function(){e[s]?e[s]():e.returnValue=!1}},u="stopPropagation",a=function(e){return function(){e[u]?e[u]():e.cancelBubble=!0}},f=function(e){return function(){e[s](),e[u](),e.stopped=!0}},l=function(e,t,n){var r,i;for(r=n.length;r--;)i=n[r],!(i in t)&&i in e&&(t[i]=e[i])};return function(p,d){var v={originalEvent:p,isNative:d};if(!p)return v;var y,b=p.type,w=p.target||p.srcElement;v[s]=o(p),v[u]=a(p),v.stop=f(v),v.target=w&&w.nodeType===3?w.parentNode:w;if(d){if(b.indexOf("key")!==-1)y=n,v.keyCode=p.which||p.keyCode;else if(m.test(b)){y=t,v.rightClick=p.which===3||p.button===2,v.pos={x:0,y:0};if(p.pageX||p.pageY)v.clientX=p.pageX,v.clientY=p.pageY;else if(p.clientX||p.clientY)v.clientX=p.clientX+c.body.scrollLeft+h.scrollLeft,v.clientY=p.clientY+c.body.scrollTop+h.scrollTop;i.test(b)&&(v.relatedTarget=p.relatedTarget||p[(b==="mouseover"?"from":"to")+"Element"])}else g.test(b)&&(y=r);l(p,v,y||e)}return v}}(),S=function(e,t){return!p&&!t&&(e===c||e===n)?h:e},x=function(){function e(e,t,n,r,i){this.element=e,this.type=t,this.handler=n,this.original=r,this.namespaces=i,this.custom=w[t],this.isNative=b[t]&&e[d],this.eventType=p||this.isNative?t:"propertychange",this.customType=!p&&!this.isNative&&t,this.target=S(e,this.isNative),this.eventSupport=this.target[d]}return e.prototype={inNamespaces:function(e){var t,n;if(!e)return!0;if(!this.namespaces)return!1;for(t=e.length;t--;)for(n=this.namespaces.length;n--;)if(e[t]===this.namespaces[n])return!0;return!1},matches:function(e,t,n){return this.element===e&&(!t||this.original===t)&&(!n||this.handler===n)}},e}(),T=function(){var e={},t=function(n,r,i,s,o){if(!r||r==="*")for(var u in e)u.charAt(0)==="$"&&t(n,u.substr(1),i,s,o);else{var a=0,f,l=e["$"+r],c=n==="*";if(!l)return;for(f=l.length;a<f;a++)if(c||l[a].matches(n,i,s))if(!o(l[a],l,a,r))return}},n=function(t,n,r){var i,s=e["$"+n];if(s)for(i=s.length;i--;)if(s[i].matches(t,r,null))return!0;return!1},r=function(e,n,r){var i=[];return t(e,n,r,null,function(e){return i.push(e)}),i},i=function(t){return(e["$"+t.type]||(e["$"+t.type]=[])).push(t),t},s=function(n){t(n.element,n.type,null,n.handler,function(t,n,r){return n.splice(r,1),n.length===0&&delete e["$"+t.type],!1})},o=function(){var t,n=[];for(t in e)t.charAt(0)==="$"&&(n=n.concat(e[t]));return n};return{has:n,get:r,put:i,del:s,entries:o}}(),N=p?function(e,t,n,r){e[r?u:f](t,n,!1)}:function(e,t,n,r,i){i&&r&&e["_on"+i]===null&&(e["_on"+i]=0),e[r?a:l]("on"+t,n)},C=function(e,t,r){return function(i){return i=E(i||((this.ownerDocument||this.document||this).parentWindow||n).event,!0),t.apply(e,[i].concat(r))}},k=function(e,t,r,i,s,o){return function(u){if(i?i.apply(this,arguments):p?!0:u&&u.propertyName==="_on"+r||!u)u&&(u=E(u||((this.ownerDocument||this.document||this).parentWindow||n).event,o)),t.apply(e,u&&(!s||s.length===0)?arguments:v.call(arguments,u?0:1).concat(s))}},L=function(e,t,n,r,i){return function(){e(t,n,i),r.apply(this,arguments)}},A=function(e,t,n,r){var i,s,u,a=t&&t.replace(o,""),f=T.get(e,a,n);for(i=0,s=f.length;i<s;i++)f[i].inNamespaces(r)&&((u=f[i]).eventSupport&&N(u.target,u.eventType,u.handler,!1,u.type),T.del(u))},O=function(e,t,n,r,i){var u,a=t.replace(o,""),f=t.replace(s,"").split(".");if(T.has(e,a,n))return e;a==="unload"&&(n=L(A,e,a,n,r)),w[a]&&(w[a].condition&&(n=k(e,n,a,w[a].condition,!0)),a=w[a].base||a),u=T.put(new x(e,a,n,r,f[0]&&f)),u.handler=u.isNative?C(e,u.handler,i):k(e,u.handler,a,!1,i,!1),u.eventSupport&&N(u.target,u.eventType,u.handler,!0,u.customType)},M=function(e,t,n){return function(r){var i,s,o=typeof e=="string"?n(e,this):e;for(i=r.target;i&&i!==this;i=i.parentNode)for(s=o.length;s--;)if(o[s]===i)return t.apply(i,arguments)}},_=function(e,t,n){var r,i,u,a,f,l=A,c=t&&typeof t=="string";if(c&&t.indexOf(" ")>0){t=t.split(" ");for(f=t.length;f--;)_(e,t[f],n);return e}u=c&&t.replace(o,""),u&&w[u]&&(u=w[u].type);if(!t||c){if(a=c&&t.replace(s,""))a=a.split(".");l(e,u,n,a)}else if(typeof t=="function")l(e,null,t);else for(r in t)t.hasOwnProperty(r)&&_(e,r,t[r]);return e},D=function(e,t,n,r,i){var s,o,u,a,f=n,l=n&&typeof n=="string";if(t&&!n&&typeof t=="object")for(s in t)t.hasOwnProperty(s)&&D.apply(this,[e,s,t[s]]);else{a=arguments.length>3?v.call(arguments,3):[],o=(l?n:t).split(" "),l&&(n=M(t,f=r,i))&&(a=v.call(a,1)),this===y&&(n=L(_,e,t,n,f));for(u=o.length;u--;)O(e,o[u],n,f,a)}return e},P=function(){return D.apply(y,arguments)},H=p?function(e,t,r){var i=c.createEvent(e?"HTMLEvents":"UIEvents");i[e?"initEvent":"initUIEvent"](t,!0,!0,n,1),r.dispatchEvent(i)}:function(e,t,n){n=S(n,e),e?n.fireEvent("on"+t,c.createEventObject()):n["_on"+t]++},B=function(e,t,n){var r,i,u,a,f,l=t.split(" ");for(r=l.length;r--;){t=l[r].replace(o,"");if(a=l[r].replace(s,""))a=a.split(".");if(!a&&!n&&e[d])H(b[t],t,e);else{f=T.get(e,t),n=[!1].concat(n);for(i=0,u=f.length;i<u;i++)f[i].inNamespaces(a)&&f[i].handler.apply(e,n)}}return e},j=function(e,t,n){var r=0,i=T.get(t,n),s=i.length;for(;r<s;r++)i[r].original&&D(e,i[r].type,i[r].original);return e},F={add:D,one:P,remove:_,clone:j,fire:B,noConflict:function(){return t[e]=r,this}};if(n[a]){var I=function(){var e,t=T.entries();for(e in t)t[e].type&&t[e].type!=="unload"&&_(t[e].element,t[e].type);n[l]("onunload",I),n.CollectGarbage&&n.CollectGarbage()};n[a]("onunload",I)}return F});

WRFILE: underscore.js
//     Underscore.js 1.1.7
//     (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
//     Underscore is freely distributable under the MIT license.
//     Portions of Underscore are inspired or borrowed from Prototype,
//     Oliver Steele's Functional, and John Resig's Micro-Templating.
//     For all details and documentation:
//     http://documentcloud.github.com/underscore

(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.slice,u=r.unshift,a=i.toString,f=i.hasOwnProperty,l=r.forEach,c=r.map,h=r.reduce,p=r.reduceRight,d=r.filter,v=r.every,m=r.some,g=r.indexOf,y=r.lastIndexOf,b=Array.isArray,w=Object.keys,E=s.bind,S=function(e){return new k(e)};typeof module!="undefined"&&module.exports?(module.exports=S,S._=S):e._=S,S.VERSION="1.1.7";var x=S.each=S.forEach=function(e,t,r){if(e==null)return;if(l&&e.forEach===l)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(i in e&&t.call(r,e[i],i,e)===n)return}else for(var o in e)if(f.call(e,o)&&t.call(r,e[o],o,e)===n)return};S.map=function(e,t,n){var r=[];return e==null?r:c&&e.map===c?e.map(t,n):(x(e,function(e,i,s){r[r.length]=t.call(n,e,i,s)}),r)},S.reduce=S.foldl=S.inject=function(e,t,n,r){var i=n!==void 0;e==null&&(e=[]);if(h&&e.reduce===h)return r&&(t=S.bind(t,r)),i?e.reduce(t,n):e.reduce(t);x(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},S.reduceRight=S.foldr=function(e,t,n,r){e==null&&(e=[]);if(p&&e.reduceRight===p)return r&&(t=S.bind(t,r)),n!==void 0?e.reduceRight(t,n):e.reduceRight(t);var i=(S.isArray(e)?e.slice():S.toArray(e)).reverse();return S.reduce(i,t,n,r)},S.find=S.detect=function(e,t,n){var r;return T(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},S.filter=S.select=function(e,t,n){var r=[];return e==null?r:d&&e.filter===d?e.filter(t,n):(x(e,function(e,i,s){t.call(n,e,i,s)&&(r[r.length]=e)}),r)},S.reject=function(e,t,n){var r=[];return e==null?r:(x(e,function(e,i,s){t.call(n,e,i,s)||(r[r.length]=e)}),r)},S.every=S.all=function(e,t,r){var i=!0;return e==null?i:v&&e.every===v?e.every(t,r):(x(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),i)};var T=S.some=S.any=function(e,t,r){t=t||S.identity;var i=!1;return e==null?i:m&&e.some===m?e.some(t,r):(x(e,function(e,s,o){if(i|=t.call(r,e,s,o))return n}),!!i)};S.include=S.contains=function(e,t){var n=!1;return e==null?n:g&&e.indexOf===g?e.indexOf(t)!=-1:(T(e,function(e){if(n=e===t)return!0}),n)},S.invoke=function(e,t){var n=o.call(arguments,2);return S.map(e,function(e){return(t.call?t||e:e[t]).apply(e,n)})},S.pluck=function(e,t){return S.map(e,function(e){return e[t]})},S.max=function(e,t,n){if(!t&&S.isArray(e))return Math.max.apply(Math,e);var r={computed:-Infinity};return x(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},S.min=function(e,t,n){if(!t&&S.isArray(e))return Math.min.apply(Math,e);var r={computed:Infinity};return x(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},S.sortBy=function(e,t,n){return S.pluck(S.map(e,function(e,r,i){return{value:e,criteria:t.call(n,e,r,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;return n<r?-1:n>r?1:0}),"value")},S.groupBy=function(e,t){var n={};return x(e,function(e,r){var i=t(e,r);(n[i]||(n[i]=[])).push(e)}),n},S.sortedIndex=function(e,t,n){n||(n=S.identity);var r=0,i=e.length;while(r<i){var s=r+i>>1;n(e[s])<n(t)?r=s+1:i=s}return r},S.toArray=function(e){return e?e.toArray?e.toArray():S.isArray(e)?o.call(e):S.isArguments(e)?o.call(e):S.values(e):[]},S.size=function(e){return S.toArray(e).length},S.first=S.head=function(e,t,n){return t!=null&&!n?o.call(e,0,t):e[0]},S.rest=S.tail=function(e,t,n){return o.call(e,t==null||n?1:t)},S.last=function(e){return e[e.length-1]},S.compact=function(e){return S.filter(e,function(e){return!!e})},S.flatten=function(e){return S.reduce(e,function(e,t){return S.isArray(t)?e.concat(S.flatten(t)):(e[e.length]=t,e)},[])},S.without=function(e){return S.difference(e,o.call(arguments,1))},S.uniq=S.unique=function(e,t){return S.reduce(e,function(e,n,r){if(0==r||(t===!0?S.last(e)!=n:!S.include(e,n)))e[e.length]=n;return e},[])},S.union=function(){return S.uniq(S.flatten(arguments))},S.intersection=S.intersect=function(e){var t=o.call(arguments,1);return S.filter(S.uniq(e),function(e){return S.every(t,function(t){return S.indexOf(t,e)>=0})})},S.difference=function(e,t){return S.filter(e,function(e){return!S.include(t,e)})},S.zip=function(){var e=o.call(arguments),t=S.max(S.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=S.pluck(e,""+r);return n},S.indexOf=function(e,t,n){if(e==null)return-1;var r,i;if(n)return r=S.sortedIndex(e,t),e[r]===t?r:-1;if(g&&e.indexOf===g)return e.indexOf(t);for(r=0,i=e.length;r<i;r++)if(e[r]===t)return r;return-1},S.lastIndexOf=function(e,t){if(e==null)return-1;if(y&&e.lastIndexOf===y)return e.lastIndexOf(t);var n=e.length;while(n--)if(e[n]===t)return n;return-1},S.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s},S.bind=function(e,t){if(e.bind===E&&E)return E.apply(e,o.call(arguments,1));var n=o.call(arguments,2);return function(){return e.apply(t,n.concat(o.call(arguments)))}},S.bindAll=function(e){var t=o.call(arguments,1);return t.length==0&&(t=S.functions(e)),x(t,function(t){e[t]=S.bind(e[t],e)}),e},S.memoize=function(e,t){var n={};return t||(t=S.identity),function(){var r=t.apply(this,arguments);return f.call(n,r)?n[r]:n[r]=e.apply(this,arguments)}},S.delay=function(e,t){var n=o.call(arguments,2);return setTimeout(function(){return e.apply(e,n)},t)},S.defer=function(e){return S.delay.apply(S,[e,1].concat(o.call(arguments,1)))};var N=function(e,t,n){var r;return function(){var i=this,s=arguments,o=function(){r=null,e.apply(i,s)};n&&clearTimeout(r);if(n||!r)r=setTimeout(o,t)}};S.throttle=function(e,t){return N(e,t,!1)},S.debounce=function(e,t){return N(e,t,!0)},S.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments))}},S.wrap=function(e,t){return function(){var n=[e].concat(o.call(arguments));return t.apply(this,n)}},S.compose=function(){var e=o.call(arguments);return function(){var t=o.call(arguments);for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},S.after=function(e,t){return function(){if(--e<1)return t.apply(this,arguments)}},S.keys=w||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)f.call(e,n)&&(t[t.length]=n);return t},S.values=function(e){return S.map(e,S.identity)},S.functions=S.methods=function(e){var t=[];for(var n in e)S.isFunction(e[n])&&t.push(n);return t.sort()},S.extend=function(e){return x(o.call(arguments,1),function(t){for(var n in t)t[n]!==void 0&&(e[n]=t[n])}),e},S.defaults=function(e){return x(o.call(arguments,1),function(t){for(var n in t)e[n]==null&&(e[n]=t[n])}),e},S.clone=function(e){return S.isArray(e)?e.slice():S.extend({},e)},S.tap=function(e,t){return t(e),e},S.isEqual=function(e,t){if(e===t)return!0;var n=typeof e,r=typeof t;if(n!=r)return!1;if(e==t)return!0;if(!e&&t||e&&!t)return!1;e._chain&&(e=e._wrapped),t._chain&&(t=t._wrapped);if(e.isEqual)return e.isEqual(t);if(t.isEqual)return t.isEqual(e);if(S.isDate(e)&&S.isDate(t))return e.getTime()===t.getTime();if(S.isNaN(e)&&S.isNaN(t))return!1;if(S.isRegExp(e)&&S.isRegExp(t))return e.source===t.source&&e.global===t.global&&e.ignoreCase===t.ignoreCase&&e.multiline===t.multiline;if(n!=="object")return!1;if(e.length&&e.length!==t.length)return!1;var i=S.keys(e),s=S.keys(t);if(i.length!=s.length)return!1;for(var o in e)if(!(o in t)||!S.isEqual(e[o],t[o]))return!1;return!0},S.isEmpty=function(e){if(S.isArray(e)||S.isString(e))return e.length===0;for(var t in e)if(f.call(e,t))return!1;return!0},S.isElement=function(e){return!!e&&e.nodeType==1},S.isArray=b||function(e){return a.call(e)==="[object Array]"},S.isObject=function(e){return e===Object(e)},S.isArguments=function(e){return!!e&&!!f.call(e,"callee")},S.isFunction=function(e){return!!(e&&e.constructor&&e.call&&e.apply)},S.isString=function(e){return!!(e===""||e&&e.charCodeAt&&e.substr)},S.isNumber=function(e){return!!(e===0||e&&e.toExponential&&e.toFixed)},S.isNaN=function(e){return e!==e},S.isBoolean=function(e){return e===!0||e===!1},S.isDate=function(e){return!!(e&&e.getTimezoneOffset&&e.setUTCFullYear)},S.isRegExp=function(e){return!(!(e&&e.test&&e.exec)||!e.ignoreCase&&e.ignoreCase!==!1)},S.isNull=function(e){return e===null},S.isUndefined=function(e){return e===void 0},S.noConflict=function(){return e._=t,this},S.identity=function(e){return e},S.times=function(e,t,n){for(var r=0;r<e;r++)t.call(n,r)},S.mixin=function(e){x(S.functions(e),function(t){A(t,S[t]=e[t])})};var C=0;S.uniqueId=function(e){var t=C++;return e?e+t:t},S.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g},S.template=function(e,t){var n=S.templateSettings,r="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(n.interpolate,function(e,t){return"',"+t.replace(/\\'/g,"'")+",'"}).replace(n.evaluate||null,function(e,t){return"');"+t.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",i=new Function("obj",r);return t?i(t):i};var k=function(e){this._wrapped=e};S.prototype=k.prototype;var L=function(e,t){return t?S(e).chain():e},A=function(e,t){k.prototype[e]=function(){var e=o.call(arguments);return u.call(e,this._wrapped),L(t.apply(S,e),this._chain)}};S.mixin(S),x(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];k.prototype[e]=function(){return t.apply(this._wrapped,arguments),L(this._wrapped,this._chain)}}),x(["concat","join","slice"],function(e){var t=r[e];k.prototype[e]=function(){return L(t.apply(this._wrapped,arguments),this._chain)}}),k.prototype.chain=function(){return this._chain=!0,this},k.prototype.value=function(){return this._wrapped}})();

WRFILE: flotr2.js
/**
 * Flotr2 (c) 2012 Carl Sutherland
 * MIT License
 * Special thanks to:
 * Flotr: http://code.google.com/p/flotr/ (fork)
 * Flot: https://github.com/flot/flot (original fork)
 */
(function(){var e=this,t=this.Flotr,n;n={_:_,bean:bean,isIphone:/iphone/i.test(navigator.userAgent),isIE:navigator.appVersion.indexOf("MSIE")!=-1?parseFloat(navigator.appVersion.split("MSIE")[1]):!1,graphTypes:{},plugins:{},addType:function(e,t){n.graphTypes[e]=t,n.defaultOptions[e]=t.options||{},n.defaultOptions.defaultType=n.defaultOptions.defaultType||e},addPlugin:function(e,t){n.plugins[e]=t,n.defaultOptions[e]=t.options||{}},draw:function(e,t,r,i){return i=i||n.Graph,new i(e,t,r)},merge:function(e,t){var r,i,s=t||{};for(r in e)i=e[r],i&&typeof i=="object"?i.constructor===Array?s[r]=this._.clone(i):i.constructor!==RegExp&&!this._.isElement(i)&&!i.jquery?s[r]=n.merge(i,t?t[r]:undefined):s[r]=i:s[r]=i;return s},clone:function(e){return n.merge(e,{})},getTickSize:function(e,t,r,i){var s=(r-t)/e,o=n.getMagnitude(s),u=10,a=s/o;return a<1.5?u=1:a<2.25?u=2:a<3?u=i===0?2:2.5:a<7.5&&(u=5),u*o},defaultTickFormatter:function(e,t){return e+""},defaultTrackFormatter:function(e){return"("+e.x+", "+e.y+")"},engineeringNotation:function(e,t,n){var r=["Y","Z","E","P","T","G","M","k",""],i=["y","z","a","f","p","n","µ","m",""],s=r.length;n=n||1e3,t=Math.pow(10,t||2);if(e===0)return 0;if(e>1)while(s--&&e>=n)e/=n;else{r=i,s=r.length;while(s--&&e<1)e*=n}return Math.round(e*t)/t+r[s]},getMagnitude:function(e){return Math.pow(10,Math.floor(Math.log(e)/Math.LN10))},toPixel:function(e){return Math.floor(e)+.5},toRad:function(e){return-e*(Math.PI/180)},floorInBase:function(e,t){return t*Math.floor(e/t)},drawText:function(e,t,r,i,s){if(!e.fillText){e.drawText(t,r,i,s);return}s=this._.extend({size:n.defaultOptions.fontSize,color:"#000000",textAlign:"left",textBaseline:"bottom",weight:1,angle:0},s),e.save(),e.translate(r,i),e.rotate(s.angle),e.fillStyle=s.color,e.font=(s.weight>1?"bold ":"")+s.size*1.3+"px sans-serif",e.textAlign=s.textAlign,e.textBaseline=s.textBaseline,e.fillText(t,0,0),e.restore()},getBestTextAlign:function(e,t){return t=t||{textAlign:"center",textBaseline:"middle"},e+=n.getTextAngleFromAlign(t),Math.abs(Math.cos(e))>.01&&(t.textAlign=Math.cos(e)>0?"right":"left"),Math.abs(Math.sin(e))>.01&&(t.textBaseline=Math.sin(e)>0?"top":"bottom"),t},alignTable:{"right middle":0,"right top":Math.PI/4,"center top":Math.PI/2,"left top":3*(Math.PI/4),"left middle":Math.PI,"left bottom":-3*(Math.PI/4),"center bottom":-Math.PI/2,"right bottom":-Math.PI/4,"center middle":0},getTextAngleFromAlign:function(e){return n.alignTable[e.textAlign+" "+e.textBaseline]||0},noConflict:function(){return e.Flotr=t,this}},e.Flotr=n})(),Flotr.defaultOptions={colors:["#00A8F0","#C0D800","#CB4B4B","#4DA74D","#9440ED"],ieBackgroundColor:"#FFFFFF",title:null,subtitle:null,shadowSize:4,defaultType:null,HtmlText:!0,fontColor:"#545454",fontSize:7.5,resolution:1,parseFloat:!0,preventDefault:!0,xaxis:{ticks:null,minorTicks:null,showLabels:!0,showMinorLabels:!1,labelsAngle:0,title:null,titleAngle:0,noTicks:5,minorTickFreq:null,tickFormatter:Flotr.defaultTickFormatter,tickDecimals:null,min:null,max:null,autoscale:!1,autoscaleMargin:0,color:null,mode:"normal",timeFormat:null,timeMode:"UTC",timeUnit:"millisecond",scaling:"linear",base:Math.E,titleAlign:"center",margin:!0},x2axis:{},yaxis:{ticks:null,minorTicks:null,showLabels:!0,showMinorLabels:!1,labelsAngle:0,title:null,titleAngle:90,noTicks:5,minorTickFreq:null,tickFormatter:Flotr.defaultTickFormatter,tickDecimals:null,min:null,max:null,autoscale:!1,autoscaleMargin:0,color:null,scaling:"linear",base:Math.E,titleAlign:"center",margin:!0},y2axis:{titleAngle:270},grid:{color:"#545454",backgroundColor:null,backgroundImage:null,watermarkAlpha:.4,tickColor:"#DDDDDD",labelMargin:3,verticalLines:!0,minorVerticalLines:null,horizontalLines:!0,minorHorizontalLines:null,outlineWidth:1,outline:"nsew",circular:!1},mouse:{track:!1,trackAll:!1,position:"se",relative:!1,trackFormatter:Flotr.defaultTrackFormatter,margin:5,lineColor:"#FF3F19",trackDecimals:1,sensibility:2,trackY:!0,radius:3,fillColor:null,fillOpacity:.4}},function(){function t(e,t,n,r){this.rgba=["r","g","b","a"];var i=4;while(-1<--i)this[this.rgba[i]]=arguments[i]||(i==3?1:0);this.normalize()}var e=Flotr._,n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]};t.prototype={scale:function(t,n,r,i){var s=4;while(-1<--s)e.isUndefined(arguments[s])||(this[this.rgba[s]]*=arguments[s]);return this.normalize()},alpha:function(t){return!e.isUndefined(t)&&!e.isNull(t)&&(this.a=t),this.normalize()},clone:function(){return new t(this.r,this.b,this.g,this.a)},limit:function(e,t,n){return Math.max(Math.min(e,n),t)},normalize:function(){var e=this.limit;return this.r=e(parseInt(this.r,10),0,255),this.g=e(parseInt(this.g,10),0,255),this.b=e(parseInt(this.b,10),0,255),this.a=e(this.a,0,1),this},distance:function(e){if(!e)return;e=new t.parse(e);var n=0,r=3;while(-1<--r)n+=Math.abs(this[this.rgba[r]]-e[this.rgba[r]]);return n},toString:function(){return this.a>=1?"rgb("+[this.r,this.g,this.b].join(",")+")":"rgba("+[this.r,this.g,this.b,this.a].join(",")+")"},contrast:function(){var e=1-(.299*this.r+.587*this.g+.114*this.b)/255;return e<.5?"#000000":"#ffffff"}},e.extend(t,{parse:function(e){if(e instanceof t)return e;var r;if(r=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(e))return new t(parseInt(r[1],16),parseInt(r[2],16),parseInt(r[3],16));if(r=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(e))return new t(parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10));if(r=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(e))return new t(parseInt(r[1]+r[1],16),parseInt(r[2]+r[2],16),parseInt(r[3]+r[3],16));if(r=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(e))return new t(parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10),parseFloat(r[4]));if(r=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(e))return new t(parseFloat(r[1])*2.55,parseFloat(r[2])*2.55,parseFloat(r[3])*2.55);if(r=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(e))return new t(parseFloat(r[1])*2.55,parseFloat(r[2])*2.55,parseFloat(r[3])*2.55,parseFloat(r[4]));var i=(e+"").replace(/^\s*([\S\s]*?)\s*$/,"$1").toLowerCase();return i=="transparent"?new t(255,255,255,0):(r=n[i])?new t(r[0],r[1],r[2]):new t(0,0,0,0)},processColor:function(n,r){var i=r.opacity;if(!n)return"rgba(0, 0, 0, 0)";if(n instanceof t)return n.alpha(i).toString();if(e.isString(n))return t.parse(n).alpha(i).toString();var s=n.colors?n:{colors:n};if(!r.ctx)return e.isArray(s.colors)?t.parse(e.isArray(s.colors[0])?s.colors[0][1]:s.colors[0]).alpha(i).toString():"rgba(0, 0, 0, 0)";s=e.extend({start:"top",end:"bottom"},s),/top/i.test(s.start)&&(r.x1=0),/left/i.test(s.start)&&(r.y1=0),/bottom/i.test(s.end)&&(r.x2=0),/right/i.test(s.end)&&(r.y2=0);var o,u,a,f=r.ctx.createLinearGradient(r.x1,r.y1,r.x2,r.y2);for(o=0;o<s.colors.length;o++)u=s.colors[o],e.isArray(u)?(a=u[0],u=u[1]):a=o/(s.colors.length-1),f.addColorStop(a,t.parse(u).alpha(i));return f}}),Flotr.Color=t}(),Flotr.Date={set:function(e,t,n,r){n=n||"UTC",t="set"+(n==="UTC"?"UTC":"")+t,e[t](r)},get:function(e,t,n){return n=n||"UTC",t="get"+(n==="UTC"?"UTC":"")+t,e[t]()},format:function(e,t,n){function s(e){return e+="",e.length==1?"0"+e:e}if(!e)return;var r=this.get,i={h:r(e,"Hours",n).toString(),H:s(r(e,"Hours",n)),M:s(r(e,"Minutes",n)),S:s(r(e,"Seconds",n)),s:r(e,"Milliseconds",n),d:r(e,"Date",n).toString(),m:(r(e,"Month",n)+1).toString(),y:r(e,"FullYear",n).toString(),b:Flotr.Date.monthNames[r(e,"Month",n)]},o=[],u,a=!1;for(var f=0;f<t.length;++f)u=t.charAt(f),a?(o.push(i[u]||u),a=!1):u=="%"?a=!0:o.push(u);return o.join("")},getFormat:function(e,t){var n=Flotr.Date.timeUnits;return e<n.second?"%h:%M:%S.%s":e<n.minute?"%h:%M:%S":e<n.day?t<2*n.day?"%h:%M":"%b %d %h:%M":e<n.month?"%b %d":e<n.year?t<n.year?"%b":"%b %y":"%y"},formatter:function(e,t){var n=t.options,r=Flotr.Date.timeUnits[n.timeUnit],i=new Date(e*r);if(t.options.timeFormat)return Flotr.Date.format(i,n.timeFormat,n.timeMode);var s=(t.max-t.min)*r,o=t.tickSize*Flotr.Date.timeUnits[t.tickUnit];return Flotr.Date.format(i,Flotr.Date.getFormat(o,s),n.timeMode)},generator:function(e){function y(e){t(m,e,o,Flotr.floorInBase(n(m,e,o),h))}var t=this.set,n=this.get,r=this.timeUnits,i=this.spec,s=e.options,o=s.timeMode,u=r[s.timeUnit],a=e.min*u,f=e.max*u,l=(f-a)/s.noTicks,c=[],h=e.tickSize,p,d,v;d=s.tickFormatter===Flotr.defaultTickFormatter?this.formatter:s.tickFormatter;for(v=0;v<i.length-1;++v){var m=i[v][0]*r[i[v][1]];if(l<(m+i[v+1][0]*r[i[v+1][1]])/2&&m>=h)break}h=i[v][0],p=i[v][1],p=="year"&&(h=Flotr.getTickSize(s.noTicks*r.year,a,f,0),h==.5&&(p="month",h=6)),e.tickUnit=p,e.tickSize=h;var g=h*r[p];m=new Date(a);switch(p){case"millisecond":y("Milliseconds");break;case"second":y("Seconds");break;case"minute":y("Minutes");break;case"hour":y("Hours");break;case"month":y("Month");break;case"year":y("FullYear")}g>=r.second&&t(m,"Milliseconds",o,0),g>=r.minute&&t(m,"Seconds",o,0),g>=r.hour&&t(m,"Minutes",o,0),g>=r.day&&t(m,"Hours",o,0),g>=r.day*4&&t(m,"Date",o,1),g>=r.year&&t(m,"Month",o,0);var b=0,w=NaN,E;do{E=w,w=m.getTime(),c.push({v:w/u,label:d(w/u,e)});if(p=="month")if(h<1){t(m,"Date",o,1);var S=m.getTime();t(m,"Month",o,n(m,"Month",o)+1);var x=m.getTime();m.setTime(w+b*r.hour+(x-S)*h),b=n(m,"Hours",o),t(m,"Hours",o,0)}else t(m,"Month",o,n(m,"Month",o)+h);else p=="year"?t(m,"FullYear",o,n(m,"FullYear",o)+h):m.setTime(w+g)}while(w<f&&w!=E);return c},timeUnits:{millisecond:1,second:1e3,minute:6e4,hour:36e5,day:864e5,month:2592e6,year:31556952e3},spec:[[1,"millisecond"],[20,"millisecond"],[50,"millisecond"],[100,"millisecond"],[200,"millisecond"],[500,"millisecond"],[1,"second"],[2,"second"],[5,"second"],[10,"second"],[30,"second"],[1,"minute"],[2,"minute"],[5,"minute"],[10,"minute"],[30,"minute"],[1,"hour"],[2,"hour"],[4,"hour"],[8,"hour"],[12,"hour"],[1,"day"],[2,"day"],[3,"day"],[.25,"month"],[.5,"month"],[1,"month"],[2,"month"],[3,"month"],[6,"month"],[1,"year"]],monthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},function(){function t(e){return e&&e.jquery?e[0]:e}var e=Flotr._;Flotr.DOM={addClass:function(n,r){n=t(n);var i=n.className?n.className:"";if(e.include(i.split(/\s+/g),r))return;n.className=(i?i+" ":"")+r},create:function(e){return document.createElement(e)},node:function(e){var t=Flotr.DOM.create("div"),n;return t.innerHTML=e,n=t.children[0],t.innerHTML="",n},empty:function(e){e=t(e),e.innerHTML=""},remove:function(e){e=t(e),e.parentNode.removeChild(e)},hide:function(e){e=t(e),Flotr.DOM.setStyles(e,{display:"none"})},insert:function(n,r){n=t(n),e.isString(r)?n.innerHTML+=r:e.isElement(r)&&n.appendChild(r)},opacity:function(e,n){e=t(e),e.style.opacity=n},position:function(e,n){return e=t(e),e.offsetParent?(n=this.position(e.offsetParent),n.left+=e.offsetLeft,n.top+=e.offsetTop,n):{left:e.offsetLeft||0,top:e.offsetTop||0}},removeClass:function(n,r){var i=n.className?n.className:"";n=t(n),n.className=e.filter(i.split(/\s+/g),function(e){if(e!=r)return!0}).join(" ")},setStyles:function(n,r){n=t(n),e.each(r,function(e,t){n.style[t]=e})},show:function(e){e=t(e),Flotr.DOM.setStyles(e,{display:""})},size:function(e){return e=t(e),{height:e.offsetHeight,width:e.offsetWidth}}}}(),function(){var e=Flotr,t=e.bean;e.EventAdapter={observe:function(e,n,r){return t.add(e,n,r),this},fire:function(e,n,r){return t.fire(e,n,r),typeof Prototype!="undefined"&&Event.fire(e,n,r),this},stopObserving:function(e,n,r){return t.remove(e,n,r),this},eventPointer:function(t){if(!e._.isUndefined(t.touches)&&t.touches.length>0)return{x:t.touches[0].pageX,y:t.touches[0].pageY};if(!e._.isUndefined(t.changedTouches)&&t.changedTouches.length>0)return{x:t.changedTouches[0].pageX,y:t.changedTouches[0].pageY};if(t.pageX||t.pageY)return{x:t.pageX,y:t.pageY};if(t.clientX||t.clientY){var n=document,r=n.body,i=n.documentElement;return{x:t.clientX+r.scrollLeft+i.scrollLeft,y:t.clientY+r.scrollTop+i.scrollTop}}}}}(),function(){var e=Flotr,t=e.DOM,n=e._,r=function(e){this.o=e};r.prototype={dimensions:function(e,t,n,r){return e?this.o.html?this.html(e,this.o.element,n,r):this.canvas(e,t):{width:0,height:0}},canvas:function(t,n){if(!this.o.textEnabled)return;n=n||{};var r=this.measureText(t,n),i=r.width,s=n.size||e.defaultOptions.fontSize,o=n.angle||0,u=Math.cos(o),a=Math.sin(o),f=2,l=6,c;return c={width:Math.abs(u*i)+Math.abs(a*s)+f,height:Math.abs(a*i)+Math.abs(u*s)+l},c},html:function(e,n,r,i){var s=t.create("div");return t.setStyles(s,{position:"absolute",top:"-10000px"}),t.insert(s,'<div style="'+r+'" class="'+i+' flotr-dummy-div">'+e+"</div>"),t.insert(this.o.element,s),t.size(s)},measureText:function(t,r){var i=this.o.ctx,s;return!i.fillText||e.isIphone&&i.measure?{width:i.measure(t,r)}:(r=n.extend({size:e.defaultOptions.fontSize,weight:1,angle:0},r),i.save(),i.font=(r.weight>1?"bold ":"")+r.size*1.3+"px sans-serif",s=i.measureText(t),i.restore(),s)}},Flotr.Text=r}(),function(){function i(e,n,r){return t.observe.apply(this,arguments),this._handles.push(arguments),this}var e=Flotr.DOM,t=Flotr.EventAdapter,n=Flotr._,r=Flotr;Graph=function(e,i,s){this._setEl(e),this._initMembers(),this._initPlugins(),t.fire(this.el,"flotr:beforeinit",[this]),this.data=i,this.series=r.Series.getSeries(i),this._initOptions(s),this._initGraphTypes(),this._initCanvas(),this._text=new r.Text({element:this.el,ctx:this.ctx,html:this.options.HtmlText,textEnabled:this.textEnabled}),t.fire(this.el,"flotr:afterconstruct",[this]),this._initEvents(),this.findDataRanges(),this.calculateSpacing(),this.draw(n.bind(function(){t.fire(this.el,"flotr:afterinit",[this])},this))},Graph.prototype={destroy:function(){t.fire(this.el,"flotr:destroy"),n.each(this._handles,function(e){t.stopObserving.apply(this,e)}),this._handles=[],this.el.graph=null},observe:i,_observe:i,processColor:function(e,t){var i={x1:0,y1:0,x2:this.plotWidth,y2:this.plotHeight,opacity:1,ctx:this.ctx};return n.extend(i,t),r.Color.processColor(e,i)},findDataRanges:function(){var e=this.axes,t,i,s;n.each(this.series,function(e){s=e.getRange(),s&&(t=e.xaxis,i=e.yaxis,t.datamin=Math.min(s.xmin,t.datamin),t.datamax=Math.max(s.xmax,t.datamax),i.datamin=Math.min(s.ymin,i.datamin),i.datamax=Math.max(s.ymax,i.datamax),t.used=t.used||s.xused,i.used=i.used||s.yused)},this),!e.x.used&&!e.x2.used&&(e.x.used=!0),!e.y.used&&!e.y2.used&&(e.y.used=!0),n.each(e,function(e){e.calculateRange()});var o=n.keys(r.graphTypes),u=!1;n.each(this.series,function(e){if(e.hide)return;n.each(o,function(t){e[t]&&e[t].show&&(this.extendRange(t,e),u=!0)},this),u||this.extendRange(this.options.defaultType,e)},this)},extendRange:function(e,t){this[e].extendRange&&this[e].extendRange(t,t.data,t[e],this[e]),this[e].extendYRange&&this[e].extendYRange(t.yaxis,t.data,t[e],this[e]),this[e].extendXRange&&this[e].extendXRange(t.xaxis,t.data,t[e],this[e])},calculateSpacing:function(){var e=this.axes,t=this.options,r=this.series,i=t.grid.labelMargin,s=this._text,o=e.x,u=e.x2,a=e.y,f=e.y2,l=t.grid.outlineWidth,c,h,p,d;n.each(e,function(e){e.calculateTicks(),e.calculateTextDimensions(s,t)}),d=s.dimensions(t.title,{size:t.fontSize*1.5},"font-size:1em;font-weight:bold;","flotr-title"),this.titleHeight=d.height,d=s.dimensions(t.subtitle,{size:t.fontSize},"font-size:smaller;","flotr-subtitle"),this.subtitleHeight=d.height;for(h=0;h<t.length;++h)r[h].points.show&&(l=Math.max(l,r[h].points.radius+r[h].points.lineWidth/2));var v=this.plotOffset;o.options.margin===!1?(v.bottom=0,v.top=0):o.options.margin===!0?(v.bottom+=(t.grid.circular?0:o.used&&o.options.showLabels?o.maxLabel.height+i:0)+(o.used&&o.options.title?o.titleSize.height+i:0)+l,v.top+=(t.grid.circular?0:u.used&&u.options.showLabels?u.maxLabel.height+i:0)+(u.used&&u.options.title?u.titleSize.height+i:0)+this.subtitleHeight+this.titleHeight+l):(v.bottom=o.options.margin,v.top=o.options.margin),a.options.margin===!1?(v.left=0,v.right=0):a.options.margin===!0?(v.left+=(t.grid.circular?0:a.used&&a.options.showLabels?a.maxLabel.width+i:0)+(a.used&&a.options.title?a.titleSize.width+i:0)+l,v.right+=(t.grid.circular?0:f.used&&f.options.showLabels?f.maxLabel.width+i:0)+(f.used&&f.options.title?f.titleSize.width+i:0)+l):(v.left=a.options.margin,v.right=a.options.margin),v.top=Math.floor(v.top),this.plotWidth=this.canvasWidth-v.left-v.right,this.plotHeight=this.canvasHeight-v.bottom-v.top,o.length=u.length=this.plotWidth,a.length=f.length=this.plotHeight,a.offset=f.offset=this.plotHeight,o.setScale(),u.setScale(),a.setScale(),f.setScale()},draw:function(e){var n=this.ctx,r;t.fire(this.el,"flotr:beforedraw",[this.series,this]);if(this.series.length){n.save(),n.translate(this.plotOffset.left,this.plotOffset.top);for(r=0;r<this.series.length;r++)this.series[r].hide||this.drawSeries(this.series[r]);n.restore(),this.clip()}t.fire(this.el,"flotr:afterdraw",[this.series,this]),e&&e()},drawSeries:function(e){function t(e,t){var n=this.getOptions(e,t);this[t].draw(n)}var i=!1;e=e||this.series,n.each(r.graphTypes,function(n,r){e[r]&&e[r].show&&this[r]&&(i=!0,t.call(this,e,r))},this),i||t.call(this,e,this.options.defaultType)},getOptions:function(e,t){var n=e[t],i=this[t],s=e.xaxis,o=e.yaxis,u={context:this.ctx,width:this.plotWidth,height:this.plotHeight,fontSize:this.options.fontSize,fontColor:this.options.fontColor,textEnabled:this.textEnabled,htmlText:this.options.HtmlText,text:this._text,element:this.el,data:e.data,color:e.color,shadowSize:e.shadowSize,xScale:s.d2p,yScale:o.d2p,xInverse:s.p2d,yInverse:o.p2d};return u=r.merge(n,u),u.fillStyle=this.processColor(n.fillColor||e.color,{opacity:n.fillOpacity}),u},getEventPosition:function(n){var r=document,i=r.body,s=r.documentElement,o=this.axes,u=this.plotOffset,a=this.lastMousePos,f=t.eventPointer(n),l=f.x-a.pageX,c=f.y-a.pageY,h,p,d;return"ontouchstart"in this.el?(h=e.position(this.overlay),p=f.x-h.left-u.left,d=f.y-h.top-u.top):(h=this.overlay.getBoundingClientRect(),p=n.clientX-h.left-u.left-i.scrollLeft-s.scrollLeft,d=n.clientY-h.top-u.top-i.scrollTop-s.scrollTop),{x:o.x.p2d(p),x2:o.x2.p2d(p),y:o.y.p2d(d),y2:o.y2.p2d(d),relX:p,relY:d,dX:l,dY:c,absX:f.x,absY:f.y,pageX:f.x,pageY:f.y}},clickHandler:function(e){if(this.ignoreClick)return this.ignoreClick=!1,this.ignoreClick;t.fire(this.el,"flotr:click",[this.getEventPosition(e),this])},mouseMoveHandler:function(e){if(this.mouseDownMoveHandler)return;var n=this.getEventPosition(e);t.fire(this.el,"flotr:mousemove",[e,n,this]),this.lastMousePos=n},mouseDownHandler:function(e){if(this.mouseUpHandler)return;this.mouseUpHandler=n.bind(function(e){t.stopObserving(document,"mouseup",this.mouseUpHandler),t.stopObserving(document,"mousemove",this.mouseDownMoveHandler),this.mouseDownMoveHandler=null,this.mouseUpHandler=null,t.fire(this.el,"flotr:mouseup",[e,this])},this),this.mouseDownMoveHandler=n.bind(function(n){var r=this.getEventPosition(n);t.fire(this.el,"flotr:mousemove",[e,r,this]),this.lastMousePos=r},this),t.observe(document,"mouseup",this.mouseUpHandler),t.observe(document,"mousemove",this.mouseDownMoveHandler),t.fire(this.el,"flotr:mousedown",[e,this]),this.ignoreClick=!1},drawTooltip:function(t,n,r,i){var s=this.getMouseTrack(),o="opacity:0.7;background-color:#000;color:#fff;display:none;position:absolute;padding:2px 8px;-moz-border-radius:4px;border-radius:4px;white-space:nowrap;",u=i.position,a=i.margin,f=this.plotOffset;n!==null&&r!==null?(i.relative?(u.charAt(0)=="n"?o+="bottom:"+(a-f.top-r+this.canvasHeight)+"px;top:auto;":u.charAt(0)=="s"&&(o+="top:"+(a+f.top+r)+"px;bottom:auto;"),u.charAt(1)=="e"?o+="left:"+(a+f.left+n)+"px;right:auto;":u.charAt(1)=="w"&&(o+="right:"+(a-f.left-n+this.canvasWidth)+"px;left:auto;")):(u.charAt(0)=="n"?o+="top:"+(a+f.top)+"px;bottom:auto;":u.charAt(0)=="s"&&(o+="bottom:"+(a+f.bottom)+"px;top:auto;"),u.charAt(1)=="e"?o+="right:"+(a+f.right)+"px;left:auto;":u.charAt(1)=="w"&&(o+="left:"+(a+f.left)+"px;right:auto;")),s.style.cssText=o,e.empty(s),e.insert(s,t),e.show(s)):e.hide(s)},clip:function(e){var t=this.plotOffset,n=this.canvasWidth,i=this.canvasHeight;e=e||this.ctx;if(r.isIE&&r.isIE<9&&!r.isFlashCanvas){if(e===this.octx)return;e.save(),e.fillStyle=this.processColor(this.options.ieBackgroundColor),e.fillRect(0,0,n,t.top),e.fillRect(0,0,t.left,i),e.fillRect(0,i-t.bottom,n,t.bottom),e.fillRect(n-t.right,0,t.right,i),e.restore()}else e.clearRect(0,0,n,t.top),e.clearRect(0,0,t.left,i),e.clearRect(0,i-t.bottom,n,t.bottom),e.clearRect(n-t.right,0,t.right,i)},_initMembers:function(){this._handles=[],this.lastMousePos={pageX:null,pageY:null},this.plotOffset={left:0,right:0,top:0,bottom:0},this.ignoreClick=!0,this.prevHit=null},_initGraphTypes:function(){n.each(r.graphTypes,function(e,t){this[t]=r.clone(e)},this)},_initEvents:function(){var e=this.el,r,i,s;"ontouchstart"in e?(r=n.bind(function(n){s=!0,t.stopObserving(document,"touchend",r),t.fire(e,"flotr:mouseup",[event,this]),this.multitouches=null,i||this.clickHandler(n)},this),this.observe(this.overlay,"touchstart",n.bind(function(n){i=!1,s=!1,this.ignoreClick=!1,n.touches&&n.touches.length>1&&(this.multitouches=n.touches),t.fire(e,"flotr:mousedown",[event,this]),this.observe(document,"touchend",r)},this)),this.observe(this.overlay,"touchmove",n.bind(function(n){var r=this.getEventPosition(n);this.options.preventDefault&&n.preventDefault(),i=!0,this.multitouches||n.touches&&n.touches.length>1?this.multitouches=n.touches:s||t.fire(e,"flotr:mousemove",[event,r,this]),this.lastMousePos=r},this))):this.observe(this.overlay,"mousedown",n.bind(this.mouseDownHandler,this)).observe(e,"mousemove",n.bind(this.mouseMoveHandler,this)).observe(this.overlay,"click",n.bind(this.clickHandler,this)).observe(e,"mouseout",function(n){t.fire(e,"flotr:mouseout",n)})},_initCanvas:function(){function l(i,s){return i||(i=e.create("canvas"),typeof FlashCanvas!="undefined"&&typeof i.getContext=="function"&&(FlashCanvas.initElement(i),this.isFlashCanvas=!0),i.className="flotr-"+s,i.style.cssText="position:absolute;left:0px;top:0px;",e.insert(t,i)),n.each(a,function(t,n){e.show(i);if(s=="canvas"&&i.getAttribute(n)===t)return;i.setAttribute(n,t*r.resolution),i.style[n]=t+"px"}),i.context_=null,i}function c(e){window.G_vmlCanvasManager&&window.G_vmlCanvasManager.initElement(e);var t=e.getContext("2d");return window.G_vmlCanvasManager||t.scale(r.resolution,r.resolution),t}var t=this.el,r=this.options,i=t.children,s=[],o,u,a,f;for(u=i.length;u--;)o=i[u],!this.canvas&&o.className==="flotr-canvas"?this.canvas=o:!this.overlay&&o.className==="flotr-overlay"?this.overlay=o:s.push(o);for(u=s.length;u--;)t.removeChild(s[u]);e.setStyles(t,{position:"relative"}),a={},a.width=t.clientWidth,a.height=t.clientHeight;if(a.width<=0||a.height<=0||r.resolution<=0)throw"Invalid dimensions for plot, width = "+a.width+", height = "+a.height+", resolution = "+r.resolution;this.canvas=l(this.canvas,"canvas"),this.overlay=l(this.overlay,"overlay"),this.ctx=c(this.canvas),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.octx=c(this.overlay),this.octx.clearRect(0,0,this.overlay.width,this.overlay.height),this.canvasHeight=a.height,this.canvasWidth=a.width,this.textEnabled=!!this.ctx.drawText||!!this.ctx.fillText},_initPlugins:function(){n.each(r.plugins,function(e,t){n.each(e.callbacks,function(e,t){this.observe(this.el,t,n.bind(e,this))},this),this[t]=r.clone(e),n.each(this[t],function(e,r){n.isFunction(e)&&(this[t][r]=n.bind(e,this))},this)},this)},_initOptions:function(e){var i=r.clone(r.defaultOptions);i.x2axis=n.extend(n.clone(i.xaxis),i.x2axis),i.y2axis=n.extend(n.clone(i.yaxis),i.y2axis),this.options=r.merge(e||{},i),this.options.grid.minorVerticalLines===null&&this.options.xaxis.scaling==="logarithmic"&&(this.options.grid.minorVerticalLines=!0),this.options.grid.minorHorizontalLines===null&&this.options.yaxis.scaling==="logarithmic"&&(this.options.grid.minorHorizontalLines=!0),t.fire(this.el,"flotr:afterinitoptions",[this]),this.axes=r.Axis.getAxes(this.options);var s=[],o=[],u=this.series.length,a=this.series.length,f=this.options.colors,l=[],c=0,h,p,d,v;for(p=a-1;p>-1;--p)h=this.series[p].color,h&&(--a,n.isNumber(h)?s.push(h):l.push(r.Color.parse(h)));for(p=s.length-1;p>-1;--p)a=Math.max(a,s[p]+1);for(p=0;o.length<a;){h=f.length==p?new r.Color(100,100,100):r.Color.parse(f[p]);var m=c%2==1?-1:1,g=1+m*Math.ceil(c/2)*.2;h.scale(g,g,g),o.push(h),++p>=f.length&&(p=0,++c)}for(p=0,d=0;p<u;++p){v=this.series[p],v.color?n.isNumber(v.color)&&(v.color=o[v.color].toString()):v.color=o[d++].toString(),v.xaxis||(v.xaxis=this.axes.x),v.xaxis==1?v.xaxis=this.axes.x:v.xaxis==2&&(v.xaxis=this.axes.x2),v.yaxis||(v.yaxis=this.axes.y),v.yaxis==1?v.yaxis=this.axes.y:v.yaxis==2&&(v.yaxis=this.axes.y2);for(var y in r.graphTypes)v[y]=n.extend(n.clone(this.options[y]),v[y]);v.mouse=n.extend(n.clone(this.options.mouse),v.mouse),n.isUndefined(v.shadowSize)&&(v.shadowSize=this.options.shadowSize)}},_setEl:function(e){if(!e)throw"The target container doesn't exist";if(e.graph instanceof Graph)e.graph.destroy();else if(!e.clientWidth)throw"The target container must be visible";e.graph=this,this.el=e}},Flotr.Graph=Graph}(),function(){function n(t){this.orientation=1,this.offset=0,this.datamin=Number.MAX_VALUE,this.datamax=-Number.MAX_VALUE,e.extend(this,t)}function r(e,t){return e=Math.log(Math.max(e,Number.MIN_VALUE)),t!==Math.E&&(e/=Math.log(t)),e}function s(e,t){return t===Math.E?Math.exp(e):Math.pow(t,e)}var e=Flotr._,t="logarithmic";n.prototype={setScale:function(){var e=this.length,n=this.max,i=this.min,o=this.offset,u=this.orientation,a=this.options,f=a.scaling===t,l;f?l=e/(r(n,a.base)-r(i,a.base)):l=e/(n-i),this.scale=l,f?(this.d2p=function(e){return o+u*(r(e,a.base)-r(i,a.base))*l},this.p2d=function(e){return s((o+u*e)/l+r(i,a.base),a.base)}):(this.d2p=function(e){return o+u*(e-i)*l},this.p2d=function(e){return(o+u*e)/l+i})},calculateTicks:function(){var t=this.options;this.ticks=[],this.minorTicks=[],t.ticks?(this._cleanUserTicks(t.ticks,this.ticks),this._cleanUserTicks(t.minorTicks||[],this.minorTicks)):t.mode=="time"?this._calculateTimeTicks():t.scaling==="logarithmic"?this._calculateLogTicks():this._calculateTicks(),e.each(this.ticks,function(e){e.label+=""}),e.each(this.minorTicks,function(e){e.label+=""})},calculateRange:function(){if(!this.used)return;var e=this,t=e.options,n=t.min!==null?t.min:e.datamin,r=t.max!==null?t.max:e.datamax,i=t.autoscaleMargin;t.scaling=="logarithmic"&&(n<=0&&(n=e.datamin),r<=0&&(r=n));if(r==n){var s=r?.01:1;t.min===null&&(n-=s),t.max===null&&(r+=s)}if(t.scaling==="logarithmic"){n<0&&(n=r/t.base);var o=Math.log(r);t.base!=Math.E&&(o/=Math.log(t.base)),o=Math.ceil(o);var u=Math.log(n);t.base!=Math.E&&(u/=Math.log(t.base)),u=Math.ceil(u),e.tickSize=Flotr.getTickSize(t.noTicks,u,o,t.tickDecimals===null?0:t.tickDecimals),t.minorTickFreq===null&&(o-u>10?t.minorTickFreq=0:o-u>5?t.minorTickFreq=2:t.minorTickFreq=5)}else e.tickSize=Flotr.getTickSize(t.noTicks,n,r,t.tickDecimals);e.min=n,e.max=r,t.min===null&&t.autoscale&&(e.min-=e.tickSize*i,e.min<0&&e.datamin>=0&&(e.min=0),e.min=e.tickSize*Math.floor(e.min/e.tickSize)),t.max===null&&t.autoscale&&(e.max+=e.tickSize*i,e.max>0&&e.datamax<=0&&e.datamax!=e.datamin&&(e.max=0),e.max=e.tickSize*Math.ceil(e.max/e.tickSize)),e.min==e.max&&(e.max=e.min+1)},calculateTextDimensions:function(e,t){var n="",r,i;if(this.options.showLabels)for(i=0;i<this.ticks.length;++i)r=this.ticks[i].label.length,r>n.length&&(n=this.ticks[i].label);this.maxLabel=e.dimensions(n,{size:t.fontSize,angle:Flotr.toRad(this.options.labelsAngle)},"font-size:smaller;","flotr-grid-label"),this.titleSize=e.dimensions(this.options.title,{size:t.fontSize*1.2,angle:Flotr.toRad(this.options.titleAngle)},"font-weight:bold;","flotr-axis-title")},_cleanUserTicks:function(t,n){var r=this,i=this.options,s,o,u,a;e.isFunction(t)&&(t=t({min:r.min,max:r.max}));for(o=0;o<t.length;++o)a=t[o],typeof a=="object"?(s=a[0],u=a.length>1?a[1]:i.tickFormatter(s,{min:r.min,max:r.max})):(s=a,u=i.tickFormatter(s,{min:this.min,max:this.max})),n[o]={v:s,label:u}},_calculateTimeTicks:function(){this.ticks=Flotr.Date.generator(this)},_calculateLogTicks:function(){var e=this,t=e.options,n,r,s=Math.log(e.max);t.base!=Math.E&&(s/=Math.log(t.base)),s=Math.ceil(s);var o=Math.log(e.min);t.base!=Math.E&&(o/=Math.log(t.base)),o=Math.ceil(o);for(i=o;i<s;i+=e.tickSize){r=t.base==Math.E?Math.exp(i):Math.pow(t.base,i);var u=r*(t.base==Math.E?Math.exp(e.tickSize):Math.pow(t.base,e.tickSize)),a=(u-r)/t.minorTickFreq;e.ticks.push({v:r,label:t.tickFormatter(r,{min:e.min,max:e.max})});for(n=r+a;n<u;n+=a)e.minorTicks.push({v:n,label:t.tickFormatter(n,{min:e.min,max:e.max})})}r=t.base==Math.E?Math.exp(i):Math.pow(t.base,i),e.ticks.push({v:r,label:t.tickFormatter(r,{min:e.min,max:e.max})})},_calculateTicks:function(){var e=this,t=e.options,n=e.tickSize,r=e.min,i=e.max,s=n*Math.ceil(r/n),o,u,a,f,l,c;t.minorTickFreq&&(u=n/t.minorTickFreq);for(l=0;(a=f=s+l*n)<=i;++l){o=t.tickDecimals,o===null&&(o=1-Math.floor(Math.log(n)/Math.LN10)),o<0&&(o=0),a=a.toFixed(o),e.ticks.push({v:a,label:t.tickFormatter(a,{min:e.min,max:e.max})});if(t.minorTickFreq)for(c=0;c<t.minorTickFreq&&l*n+c*u<i;++c)a=f+c*u,e.minorTicks.push({v:a,label:t.tickFormatter(a,{min:e.min,max:e.max})})}}},e.extend(n,{getAxes:function(e){return{x:new n({options:e.xaxis,n:1,length:this.plotWidth}),x2:new n({options:e.x2axis,n:2,length:this.plotWidth}),y:new n({options:e.yaxis,n:1,length:this.plotHeight,offset:this.plotHeight,orientation:-1}),y2:new n({options:e.y2axis,n:2,length:this.plotHeight,offset:this.plotHeight,orientation:-1})}}}),Flotr.Axis=n}(),function(){function t(t){e.extend(this,t)}var e=Flotr._;t.prototype={getRange:function(){var e=this.data,t=e.length,n=Number.MAX_VALUE,r=Number.MAX_VALUE,i=-Number.MAX_VALUE,s=-Number.MAX_VALUE,o=!1,u=!1,a,f,l;if(t<0||this.hide)return!1;for(l=0;l<t;l++)a=e[l][0],f=e[l][1],a!==null&&(a<n&&(n=a,o=!0),a>i&&(i=a,o=!0)),f!==null&&(f<r&&(r=f,u=!0),f>s&&(s=f,u=!0));return{xmin:n,xmax:i,ymin:r,ymax:s,xused:o,yused:u}}},e.extend(t,{getSeries:function(n){return e.map(n,function(n){var r;return n.data?(r=new t,e.extend(r,n)):r=new t({data:n}),r})}}),Flotr.Series=t}(),Flotr.addType("lines",{options:{show:!1,lineWidth:2,fill:!1,fillBorder:!1,fillColor:null,fillOpacity:.4,steps:!1,stacked:!1},stack:{values:[]},draw:function(e){var t=e.context,n=e.lineWidth,r=e.shadowSize,i;t.save(),t.lineJoin="round",r&&(t.lineWidth=r/2,i=n/2+t.lineWidth/2,t.strokeStyle="rgba(0,0,0,0.1)",this.plot(e,i+r/2,!1),t.strokeStyle="rgba(0,0,0,0.2)",this.plot(e,i,!1)),t.lineWidth=n,t.strokeStyle=e.color,this.plot(e,0,!0),t.restore()},plot:function(e,t,n){function S(){!t&&e.fill&&d&&(v=o(d[0]),r.fillStyle=e.fillStyle,r.lineTo(m,p),r.lineTo(v,p),r.lineTo(v,u(d[1])),r.fill(),e.fillBorder&&r.stroke())}var r=e.context,i=e.width,s=e.height,o=e.xScale,u=e.yScale,a=e.data,f=e.stacked?this.stack:!1,l=a.length-1,c=null,h=null,p=u(0),d=null,v,m,g,y,b,w,E;if(l<1)return;r.beginPath();for(E=0;E<l;++E){if(a[E][1]===null||a[E+1][1]===null){e.fill&&E>0&&a[E][1]!==null&&(r.stroke(),S(),d=null,r.closePath(),r.beginPath());continue}v=o(a[E][0]),m=o(a[E+1][0]),d===null&&(d=a[E]),f?(b=f.values[a[E][0]]||0,w=f.values[a[E+1][0]]||f.values[a[E][0]]||0,g=u(a[E][1]+b),y=u(a[E+1][1]+w),n&&(a[E].y0=b,f.values[a[E][0]]=a[E][1]+b,E==l-1&&(a[E+1].y0=w,f.values[a[E+1][0]]=a[E+1][1]+w))):(g=u(a[E][1]),y=u(a[E+1][1]));if(g>s&&y>s||g<0&&y<0||v<0&&m<0||v>i&&m>i)continue;(c!=v||h!=g+t)&&r.moveTo(v,g+t),c=m,h=y+t,e.steps?(r.lineTo(c+t/2,g+t),r.lineTo(c+t/2,h)):r.lineTo(c,h)}(!e.fill||e.fill&&!e.fillBorder)&&r.stroke(),S(),r.closePath()},extendYRange:function(e,t,n,r){var i=e.options;if(n.stacked&&(!i.max&&i.max!==0||!i.min&&i.min!==0)){var s=e.max,o=e.min,u=r.positiveSums||{},a=r.negativeSums||{},f,l;for(l=0;l<t.length;l++)f=t[l][0]+"",t[l][1]>0?(u[f]=(u[f]||0)+t[l][1],s=Math.max(s,u[f])):(a[f]=(a[f]||0)+t[l][1],o=Math.min(o,a[f]));r.negativeSums=a,r.positiveSums=u,e.max=s,e.min=o}n.steps&&(this.hit=function(e){var t=e.data,n=e.args,r=e.yScale,i=n[0],s=t.length,o=n[1],u=e.xInverse(i.relX),a=i.relY,f;for(f=0;f<s-1;f++)if(u>=t[f][0]&&u<=t[f+1][0]){Math.abs(r(t[f][1])-a)<8&&(o.x=t[f][0],o.y=t[f][1],o.index=f,o.seriesIndex=e.index);break}},this.drawHit=function(e){var t=e.context,n=e.args,r=e.data,i=e.xScale,s=n.index,o=i(n.x),u=e.yScale(n.y),a;r.length-1>s&&(a=e.xScale(r[s+1][0]),t.save(),t.strokeStyle=e.color,t.lineWidth=e.lineWidth,t.beginPath(),t.moveTo(o,u),t.lineTo(a,u),t.stroke(),t.closePath(),t.restore())},this.clearHit=function(e){var t=e.context,n=e.args,r=e.data,i=e.xScale,s=e.lineWidth,o=n.index,u=i(n.x),a=e.yScale(n.y),f;r.length-1>o&&(f=e.xScale(r[o+1][0]),t.clearRect(u-s,a-s,f-u+2*s,2*s))})}}),Flotr.addType("bars",{options:{show:!1,lineWidth:2,barWidth:1,fill:!0,fillColor:null,fillOpacity:.4,horizontal:!1,stacked:!1,centered:!0,topPadding:.1,grouped:!1},stack:{positive:[],negative:[],_positive:[],_negative:[]},draw:function(e){var t=e.context;this.current+=1,t.save(),t.lineJoin="miter",t.lineWidth=e.lineWidth,t.strokeStyle=e.color,e.fill&&(t.fillStyle=e.fillStyle),this.plot(e),t.restore()},plot:function(e){var t=e.data,n=e.context,r=e.shadowSize,i,s,o,u,a,f;if(t.length<1)return;this.translate(n,e.horizontal);for(i=0;i<t.length;i++){s=this.getBarGeometry(t[i][0],t[i][1],e);if(s===null)continue;o=s.left,u=s.top,a=s.width,f=s.height,e.fill&&n.fillRect(o,u,a,f),r&&(n.save(),n.fillStyle="rgba(0,0,0,0.05)",n.fillRect(o+r,u+r,a,f),n.restore()),e.lineWidth&&n.strokeRect(o,u,a,f)}},translate:function(e,t){t&&(e.rotate(-Math.PI/2),e.scale(-1,1))},getBarGeometry:function(e,t,n){var r=n.horizontal,i=n.barWidth,s=n.centered,o=n.stacked?this.stack:!1,u=n.lineWidth,a=s?i/2:0,f=r?n.yScale:n.xScale,l=r?n.xScale:n.yScale,c=r?t:e,h=r?e:t,p=0,d,v,m,g,y;return n.grouped&&(this.current/this.groups,c-=a,i/=this.groups,a=i/2,c=c+i*this.current-a),o&&(d=h>0?o.positive:o.negative,p=d[c]||p,d[c]=p+h),v=f(c-a),m=f(c+i-a),g=l(h+p),y=l(p),y<0&&(y=0),e===null||t===null?null:{x:c,y:h,xScale:f,yScale:l,top:g,left:Math.min(v,m)-u/2,width:Math.abs(m-v)-u,height:y-g}},hit:function(e){var t=e.data,n=e.args,r=n[0],i=n[1],s=e.xInverse(r.relX),o=e.yInverse(r.relY),u=this.getBarGeometry(s,o,e),a=u.width/2,f=u.left,l=u.y,c,h;for(h=t.length;h--;)c=this.getBarGeometry(t[h][0],t[h][1],e),(l>0&&l<c.y||l<0&&l>c.y)&&Math.abs(f-c.left)<a&&(i.x=t[h][0],i.y=t[h][1],i.index=h,i.seriesIndex=e.index)},drawHit:function(e){var t=e.context,n=e.args,r=this.getBarGeometry(n.x,n.y,e),i=r.left,s=r.top,o=r.width,u=r.height;t.save(),t.strokeStyle=e.color,t.lineWidth=e.lineWidth,this.translate(t,e.horizontal),t.beginPath(),t.moveTo(i,s+u),t.lineTo(i,s),t.lineTo(i+o,s),t.lineTo(i+o,s+u),e.fill&&(t.fillStyle=e.fillStyle,t.fill()),t.stroke(),t.closePath(),t.restore()},clearHit:function(e){var t=e.context,n=e.args,r=this.getBarGeometry(n.x,n.y,e),i=r.left,s=r.width,o=r.top,u=r.height,a=2*e.lineWidth;t.save(),this.translate(t,e.horizontal),t.clearRect(i-a,Math.min(o,o+u)-a,s+2*a,Math.abs(u)+2*a),t.restore()},extendXRange:function(e,t,n,r){this._extendRange(e,t,n,r),this.groups=this.groups+1||1,this.current=0},extendYRange:function(e,t,n,r){this._extendRange(e,t,n,r)},_extendRange:function(e,t,n,r){var i=e.options.max;if(_.isNumber(i)||_.isString(i))return;var s=e.min,o=e.max,u=n.horizontal,a=e.orientation,f=this.positiveSums||{},l=this.negativeSums||{},c,h,p,d;(a==1&&!u||a==-1&&u)&&n.centered&&(o=Math.max(e.datamax+n.barWidth,o),s=Math.min(e.datamin-n.barWidth,s));if(n.stacked&&(a==1&&u||a==-1&&!u))for(d=t.length;d--;)c=t[d][a==1?1:0]+"",h=t[d][a==1?0:1],h>0?(f[c]=(f[c]||0)+h,o=Math.max(o,f[c])):(l[c]=(l[c]||0)+h,s=Math.min(s,l[c]));(a==1&&u||a==-1&&!u)&&n.topPadding&&(e.max===e.datamax||n.stacked&&this.stackMax!==o)&&(o+=n.topPadding*(o-s)),this.stackMin=s,this.stackMax=o,this.negativeSums=l,this.positiveSums=f,e.max=o,e.min=s}}),Flotr.addType("bubbles",{options:{show:!1,lineWidth:2,fill:!0,fillOpacity:.4,baseRadius:2},draw:function(e){var t=e.context,n=e.shadowSize;t.save(),t.lineWidth=e.lineWidth,t.fillStyle="rgba(0,0,0,0.05)",t.strokeStyle="rgba(0,0,0,0.05)",this.plot(e,n/2),t.strokeStyle="rgba(0,0,0,0.1)",this.plot(e,n/4),t.strokeStyle=e.color,t.fillStyle=e.fillStyle,this.plot(e),t.restore()},plot:function(e,t){var n=e.data,r=e.context,i,s,o,u,a;t=t||0;for(s=0;s<n.length;++s)i=this.getGeometry(n[s],e),r.beginPath(),r.arc(i.x+t,i.y+t,i.z,0,2*Math.PI,!0),r.stroke(),e.fill&&r.fill(),r.closePath()},getGeometry:function(e,t){return{x:t.xScale(e[0]),y:t.yScale(e[1]),z:e[2]*t.baseRadius}},hit:function(e){var t=e.data,n=e.args,r=n[0],s=n[1],o=r.relX,u=r.relY,a,f,l,c;s.best=s.best||Number.MAX_VALUE;for(i=t.length;i--;)f=this.getGeometry(t[i],e),l=f.x-o,c=f.y-u,a=Math.sqrt(l*l+c*c),a<f.z&&f.z<s.best&&(s.x=t[i][0],s.y=t[i][1],s.index=i,s.seriesIndex=e.index,s.best=f.z)},drawHit:function(e){var t=e.context,n=this.getGeometry(e.data[e.args.index],e);t.save(),t.lineWidth=e.lineWidth,t.fillStyle=e.fillStyle,t.strokeStyle=e.color,t.beginPath(),t.arc(n.x,n.y,n.z,0,2*Math.PI,!0),t.fill(),t.stroke(),t.closePath(),t.restore()},clearHit:function(e){var t=e.context,n=this.getGeometry(e.data[e.args.index],e),r=n.z+e.lineWidth;t.save(),t.clearRect(n.x-r,n.y-r,2*r,2*r),t.restore()}}),Flotr.addType("candles",{options:{show:!1,lineWidth:1,wickLineWidth:1,candleWidth:.6,fill:!0,upFillColor:"#00A8F0",downFillColor:"#CB4B4B",fillOpacity:.5,barcharts:!1},draw:function(e){var t=e.context;t.save(),t.lineJoin="miter",t.lineCap="butt",t.lineWidth=e.wickLineWidth||e.lineWidth,this.plot(e),t.restore()},plot:function(e){var t=e.data,n=e.context,r=e.xScale,i=e.yScale,s=e.candleWidth/2,o=e.shadowSize,u=e.lineWidth,a=e.wickLineWidth,f=a%2/2,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N;if(t.length<1)return;for(N=0;N<t.length;N++){c=t[N],h=c[0],d=c[1],v=c[2],m=c[3],g=c[4],y=r(h-s),b=r(h+s),w=i(m),E=i(v),S=i(Math.min(d,g)),x=i(Math.max(d,g)),l=e[d>g?"downFillColor":"upFillColor"],e.fill&&!e.barcharts&&(n.fillStyle="rgba(0,0,0,0.05)",n.fillRect(y+o,x+o,b-y,S-x),n.save(),n.globalAlpha=e.fillOpacity,n.fillStyle=l,n.fillRect(y,x+u,b-y,S-x),n.restore());if(u||a)h=Math.floor((y+b)/2)+f,n.strokeStyle=l,n.beginPath(),e.barcharts?(n.moveTo(h,Math.floor(E+u)),n.lineTo(h,Math.floor(w+u)),T=d<g,n.moveTo(T?b:y,Math.floor(x+u)),n.lineTo(h,Math.floor(x+u)),n.moveTo(h,Math.floor(S+u)),n.lineTo(T?y:b,Math.floor(S+u))):(n.strokeRect(y,x+u,b-y,S-x),n.moveTo(h,Math.floor(x+u)),n.lineTo(h,Math.floor(E+u)),n.moveTo(h,Math.floor(S+u)),n.lineTo(h,Math.floor(w+u))),n.closePath(),n.stroke()}},hit:function(e){var t=e.xScale,n=e.yScale,r=e.data,i=e.args,s=i[0],o=e.candleWidth/2,u=i[1],a=s.relX,f=s.relY,l=r.length,c,h,p,d,v,m,g,y;for(c=0;c<l;c++){h=r[c],p=h[2],d=h[3],v=t(h[0]-o),m=t(h[0]+o),y=n(d),g=n(p);if(a>v&&a<m&&f>g&&f<y){u.x=h[0],u.index=c,u.seriesIndex=e.index;return}}},drawHit:function(e){var t=e.context;t.save(),this.plot(_.defaults({fill:!!e.fillColor,upFillColor:e.color,downFillColor:e.color,data:[e.data[e.args.index]]},e)),t.restore()},clearHit:function(e){var t=e.args,n=e.context,r=e.xScale,i=e.yScale,s=e.lineWidth,o=e.candleWidth/2,u=e.data[t.index],a=r(u[0]-o)-s,f=r(u[0]+o)+s,l=i(u[2]),c=i(u[3])+s;n.clearRect(a,l,f-a,c-l)},extendXRange:function(e,t,n){e.options.max===null&&(e.max=Math.max(e.datamax+.5,e.max),e.min=Math.min(e.datamin-.5,e.min))}}),Flotr.addType("gantt",{options:{show:!1,lineWidth:2,barWidth:1,fill:!0,fillColor:null,fillOpacity:.4,centered:!0},draw:function(e){var t=this.ctx,n=e.gantt.barWidth,r=Math.min(e.gantt.lineWidth,n);t.save(),t.translate(this.plotOffset.left,this.plotOffset.top),t.lineJoin="miter",t.lineWidth=r,t.strokeStyle=e.color,t.save(),this.gantt.plotShadows(e,n,0,e.gantt.fill),t.restore();if(e.gantt.fill){var i=e.gantt.fillColor||e.color;t.fillStyle=this.processColor(i,{opacity:e.gantt.fillOpacity})}this.gantt.plot(e,n,0,e.gantt.fill),t.restore()},plot:function(e,t,n,r){var i=e.data;if(i.length<1)return;var s=e.xaxis,o=e.yaxis,u=this.ctx,a;for(a=0;a<i.length;a++){var f=i[a][0],l=i[a][1],c=i[a][2],h=!0,p=!0,d=!0;if(l===null||c===null)continue;var v=l,m=l+c,g=f-(e.gantt.centered?t/2:0),y=f+t-(e.gantt.centered?t/2:0);if(m<s.min||v>s.max||y<o.min||g>o.max)continue;v<s.min&&(v=s.min,h=!1),m>s.max&&(m=s.max,s.lastSerie!=e&&(p=!1)),g<o.min&&(g=o.min),y>o.max&&(y=o.max,o.lastSerie!=e&&(p=!1)),r&&(u.beginPath(),u.moveTo(s.d2p(v),o.d2p(g)+n),u.lineTo(s.d2p(v),o.d2p(y)+n),u.lineTo(s.d2p(m),o.d2p(y)+n),u.lineTo(s.d2p(m),o.d2p(g)+n),u.fill(),u.closePath()),e.gantt.lineWidth&&(h||d||p)&&(u.beginPath(),u.moveTo(s.d2p(v),o.d2p(g)+n),u[h?"lineTo":"moveTo"](s.d2p(v),o.d2p(y)+n),u[p?"lineTo":"moveTo"](s.d2p(m),o.d2p(y)+n),u[d?"lineTo":"moveTo"](s.d2p(m),o.d2p(g)+n),u.stroke(),u.closePath())}},plotShadows:function(e,t,n){var r=e.data;if(r.length<1)return;var i,s,o,u,a=e.xaxis,f=e.yaxis,l=this.ctx,c=this.options.shadowSize;for(i=0;i<r.length;i++){s=r[i][0],o=r[i][1],u=r[i][2];if(o===null||u===null)continue;var h=o,p=o+u,d=s-(e.gantt.centered?t/2:0),v=s+t-(e.gantt.centered?t/2:0);if(p<a.min||h>a.max||v<f.min||d>f.max)continue;h<a.min&&(h=a.min),p>a.max&&(p=a.max),d<f.min&&(d=f.min),v>f.max&&(v=f.max);var m=a.d2p(p)-a.d2p(h)-(a.d2p(p)+c<=this.plotWidth?0:c),g=f.d2p(d)-f.d2p(v)-(f.d2p(d)+c<=this.plotHeight?0:c);l.fillStyle="rgba(0,0,0,0.05)",l.fillRect(Math.min(a.d2p(h)+c,this.plotWidth),Math.min(f.d2p(v)+c,this.plotHeight),m,g)}},extendXRange:function(e){if(e.options.max===null){var t=e.min,n=e.max,r,i,s,o,u,a={},f={},l=null;for(r=0;r<this.series.length;++r){o=this.series[r],u=o.gantt;if(u.show&&o.xaxis==e){for(i=0;i<o.data.length;i++)u.show&&(y=o.data[i][0]+"",a[y]=Math.max(a[y]||0,o.data[i][1]+o.data[i][2]),l=o);for(i in a)n=Math.max(a[i],n)}}e.lastSerie=l,e.max=n,e.min=t}},extendYRange:function(e){if(e.options.max===null){var t=Number.MIN_VALUE,n=Number.MAX_VALUE,r,i,s,o,u={},a={},f=null;for(r=0;r<this.series.length;++r){s=this.series[r],o=s.gantt;if(o.show&&!s.hide&&s.yaxis==e){var l=Number.MIN_VALUE,c=Number.MAX_VALUE;for(i=0;i<s.data.length;i++)l=Math.max(l,s.data[i][0]),c=Math.min(c,s.data[i][0]);o.centered?(t=Math.max(l+.5,t),n=Math.min(c-.5,n)):(t=Math.max(l+1,t),n=Math.min(c,n)),o.barWidth+l>t&&(t=e.max+o.barWidth)}}e.lastSerie=f,e.max=t,e.min=n,e.tickSize=Flotr.getTickSize(e.options.noTicks,n,t,e.options.tickDecimals)}}}),function(){function e(e){return typeof e=="object"&&e.constructor&&(Image?!0:e.constructor===Image)}Flotr.defaultMarkerFormatter=function(e){return Math.round(e.y*100)/100+""},Flotr.addType("markers",{options:{show:!1,lineWidth:1,color:"#000000",fill:!1,fillColor:"#FFFFFF",fillOpacity:.4,stroke:!1,position:"ct",verticalMargin:0,labelFormatter:Flotr.defaultMarkerFormatter,fontSize:Flotr.defaultOptions.fontSize,stacked:!1,stackingType:"b",horizontal:!1},stack:{positive:[],negative:[],values:[]},draw:function(e){function h(e,t){return o=r.negative[e]||0,s=r.positive[e]||0,t>0?(r.positive[e]=o+t,o+t):(r.negative[e]=s+t,s+t)}var t=e.data,n=e.context,r=e.stacked?e.stack:!1,i=e.stackingType,s,o,u,a,f,l,c;n.save(),n.lineJoin="round",n.lineWidth=e.lineWidth,n.strokeStyle="rgba(0,0,0,0.5)",n.fillStyle=e.fillStyle;for(a=0;a<t.length;++a)f=t[a][0],l=t[a][1],r&&(i=="b"?e.horizontal?l=h(l,f):f=h(f,l):i=="a"&&(u=r.values[f]||0,r.values[f]=u+l,l=u+l)),c=e.labelFormatter({x:f,y:l,index:a,data:t}),this.plot(e.xScale(f),e.yScale(l),c,e);n.restore()},plot:function(t,n,r,i){var s=i.context;if(e(r)&&!r.complete)throw"Marker image not loaded.";this._plot(t,n,r,i)},_plot:function(t,n,r,i){var s=i.context,o=2,u=t,a=n,f;e(r)?f={height:r.height,width:r.width}:f=i.text.canvas(r),f.width=Math.floor(f.width+o*2),f.height=Math.floor(f.height+o*2),i.position.indexOf("c")!=-1?u-=f.width/2+o:i.position.indexOf("l")!=-1&&(u-=f.width),i.position.indexOf("m")!=-1?a-=f.height/2+o:i.position.indexOf("t")!=-1?a-=f.height+i.verticalMargin:a+=i.verticalMargin,u=Math.floor(u)+.5,a=Math.floor(a)+.5,i.fill&&s.fillRect(u,a,f.width,f.height),i.stroke&&s.strokeRect(u,a,f.width,f.height),e(r)?s.drawImage(r,parseInt(u+o,10),parseInt(a+o,10)):Flotr.drawText(s,r,u+o,a+o,{textBaseline:"top",textAlign:"left",size:i.fontSize,color:i.color})}})}(),function(){var e=Flotr._;Flotr.defaultPieLabelFormatter=function(e,t){return(100*t/e).toFixed(2)+"%"},Flotr.addType("pie",{options:{show:!1,lineWidth:1,fill:!0,fillColor:null,fillOpacity:.6,explode:6,sizeRatio:.6,startAngle:Math.PI/4,labelFormatter:Flotr.defaultPieLabelFormatter,pie3D:!1,pie3DviewAngle:Math.PI/2*.8,pie3DspliceThickness:20,epsilon:.1},draw:function(e){var t=e.data,n=e.context,r=e.lineWidth,i=e.shadowSize,s=e.sizeRatio,o=e.height,u=e.width,a=e.explode,f=e.color,l=e.fill,c=e.fillStyle,h=Math.min(u,o)*s/2,p=t[0][1],d=[],v=1,m=Math.PI*2*p/this.total,g=this.startAngle||2*Math.PI*e.startAngle,y=g+m,b=g+m/2,w=e.labelFormatter(this.total,p),E=a+h+4,S=Math.cos(b)*E,x=Math.sin(b)*E,T=S<0?"right":"left",N=x>0?"top":"bottom",C,k,L;n.save(),n.translate(u/2,o/2),n.scale(1,v),k=Math.cos(b)*a,L=Math.sin(b)*a,i>0&&(this.plotSlice(k+i,L+i,h,g,y,n),l&&(n.fillStyle="rgba(0,0,0,0.1)",n.fill())),this.plotSlice(k,L,h,g,y,n),l&&(n.fillStyle=c,n.fill()),n.lineWidth=r,n.strokeStyle=f,n.stroke(),C={size:e.fontSize*1.2,color:e.fontColor,weight:1.5},w&&(e.htmlText||!e.textEnabled?(divStyle="position:absolute;"+N+":"+(o/2+(N==="top"?x:-x))+"px;",divStyle+=T+":"+(u/2+(T==="right"?-S:S))+"px;",d.push('<div style="',divStyle,'" class="flotr-grid-label">',w,"</div>")):(C.textAlign=T,C.textBaseline=N,Flotr.drawText(n,w,S,x,C)));if(e.htmlText||!e.textEnabled){var A=Flotr.DOM.node('<div style="color:'+e.fontColor+'" class="flotr-labels"></div>');Flotr.DOM.insert(A,d.join("")),Flotr.DOM.insert(e.element,A)}n.restore(),this.startAngle=y,this.slices=this.slices||[],this.slices.push({radius:h,x:k,y:L,explode:a,start:g,end:y})},plotSlice:function(e,t,n,r,i,s){s.beginPath(),s.moveTo(e,t),s.arc(e,t,n,r,i,!1),s.lineTo(e,t),s.closePath()},hit:function(e){var t=e.data[0],n=e.args,r=e.index,i=n[0],s=n[1],o=this.slices[r],u=i.relX-e.width/2,a=i.relY-e.height/2,f=Math.sqrt(u*u+a*a),l=Math.atan(a/u),c=Math.PI*2,h=o.explode||e.explode,p=o.start%c,d=o.end%c,v=e.epsilon;u<0?l+=Math.PI:u>0&&a<0&&(l+=c),f<o.radius+h&&f>h&&(l>p&&l<d||p>d&&(l<d||l>p)||p===d&&(o.start===o.end&&Math.abs(l-p)<v||o.start!==o.end&&Math.abs(l-p)>v))&&(s.x=t[0],s.y=t[1],s.sAngle=p,s.eAngle=d,s.index=0,s.seriesIndex=r,s.fraction=t[1]/this.total)},drawHit:function(e){var t=e.context,n=this.slices[e.args.seriesIndex];t.save(),t.translate(e.width/2,e.height/2),this.plotSlice(n.x,n.y,n.radius,n.start,n.end,t),t.stroke(),t.restore()},clearHit:function(e){var t=e.context,n=this.slices[e.args.seriesIndex],r=2*e.lineWidth,i=n.radius+r;t.save(),t.translate(e.width/2,e.height/2),t.clearRect(n.x-i,n.y-i,2*i+r,2*i+r),t.restore()},extendYRange:function(e,t){this.total=(this.total||0)+t[0][1]}})}(),Flotr.addType("points",{options:{show:!1,radius:3,lineWidth:2,fill:!0,fillColor:"#FFFFFF",fillOpacity:1,hitRadius:null},draw:function(e){var t=e.context,n=e.lineWidth,r=e.shadowSize;t.save(),r>0&&(t.lineWidth=r/2,t.strokeStyle="rgba(0,0,0,0.1)",this.plot(e,r/2+t.lineWidth/2),t.strokeStyle="rgba(0,0,0,0.2)",this.plot(e,t.lineWidth/2)),t.lineWidth=e.lineWidth,t.strokeStyle=e.color,e.fill&&(t.fillStyle=e.fillStyle),this.plot(e),t.restore()},plot:function(e,t){var n=e.data,r=e.context,i=e.xScale,s=e.yScale,o,u,a;for(o=n.length-1;o>-1;--o){a=n[o][1];if(a===null)continue;u=i(n[o][0]),a=s(a);if(u<0||u>e.width||a<0||a>e.height)continue;r.beginPath(),t?r.arc(u,a+t,e.radius,0,Math.PI,!1):(r.arc(u,a,e.radius,0,2*Math.PI,!0),e.fill&&r.fill()),r.stroke(),r.closePath()}}}),Flotr.addType("radar",{options:{show:!1,lineWidth:2,fill:!0,fillOpacity:.4,radiusRatio:.9,sensibility:2},draw:function(e){var t=e.context,n=e.shadowSize;t.save(),t.translate(e.width/2,e.height/2),t.lineWidth=e.lineWidth,t.fillStyle="rgba(0,0,0,0.05)",t.strokeStyle="rgba(0,0,0,0.05)",this.plot(e,n/2),t.strokeStyle="rgba(0,0,0,0.1)",this.plot(e,n/4),t.strokeStyle=e.color,t.fillStyle=e.fillStyle,this.plot(e),t.restore()},plot:function(e,t){var n=e.data,r=e.context,i=Math.min(e.height,e.width)*e.radiusRatio/2,s=2*Math.PI/n.length,o=-Math.PI/2,u,a;t=t||0,r.beginPath();for(u=0;u<n.length;++u)a=n[u][1]/this.max,r[u===0?"moveTo":"lineTo"](Math.cos(u*s+o)*i*a+t,Math.sin(u*s+o)*i*a+t);r.closePath(),e.fill&&r.fill(),r.stroke()},getGeometry:function(e,t){var n=Math.min(t.height,t.width)*t.radiusRatio/2,r=2*Math.PI/t.data.length,i=-Math.PI/2,s=e[1]/this.max;return{x:Math.cos(e[0]*r+i)*n*s+t.width/2,y:Math.sin(e[0]*r+i)*n*s+t.height/2}},hit:function(e){var t=e.args,n=t[0],r=t[1],i=n.relX,s=n.relY,o,u,a,f;for(var l=0;l<r.series.length;l++){var c=r.series[l],h=c.data;for(var p=h.length;p--;){u=this.getGeometry(h[p],e),a=u.x-i,f=u.y-s,o=Math.sqrt(a*a+f*f);if(o<e.sensibility*2)return r.x=h[p][0],r.y=h[p][1],r.index=p,r.seriesIndex=l,r}}},drawHit:function(e){var t=2*Math.PI/e.data.length,n=-Math.PI/2,r=Math.min(e.height,e.width)*e.radiusRatio/2,i=e.args.series,s=i.points.hitRadius||i.points.radius||i.mouse.radius,o=e.context;o.translate(e.width/2,e.height/2);var u=e.args.index,a=e.data[u][1]/this.max,f=Math.cos(u*t+n)*r*a,l=Math.sin(u*t+n)*r*a;o.beginPath(),o.arc(f,l,s,0,2*Math.PI,!0),o.closePath(),o.stroke()},clearHit:function(e){var t=2*Math.PI/e.data.length,n=-Math.PI/2,r=Math.min(e.height,e.width)*e.radiusRatio/2,i=e.context,s=e.args.series,o=s.points?s.points.lineWidth:1;offset=(s.points.hitRadius||s.points.radius||s.mouse.radius)+o,i.translate(e.width/2,e.height/2);var u=e.args.index,a=e.data[u][1]/this.max,f=Math.cos(u*t+n)*r*a,l=Math.sin(u*t+n)*r*a;i.clearRect(f-offset,l-offset,offset*2,offset*2)},extendYRange:function(e,t){this.max=Math.max(e.max,this.max||-Number.MAX_VALUE)}}),Flotr.addType("timeline",{options:{show:!1,lineWidth:1,barWidth:.2,fill:!0,fillColor:null,fillOpacity:.4,centered:!0},draw:function(e){var t=e.context;t.save(),t.lineJoin="miter",t.lineWidth=e.lineWidth,t.strokeStyle=e.color,t.fillStyle=e.fillStyle,this.plot(e),t.restore()},plot:function(e){var t=e.data,n=e.context,r=e.xScale,i=e.yScale,s=e.barWidth,o=e.lineWidth,u;Flotr._.each(t,function(e){var t=e[0],u=e[1],a=e[2],f=s,l=Math.ceil(r(t)),c=Math.ceil(r(t+a))-l,h=Math.round(i(u)),p=Math.round(i(u-f))-h,d=l-o/2,v=Math.round(h-p/2)-o/2;n.strokeRect(d,v,c,p),n.fillRect(d,v,c,p)})},extendRange:function(e){var t=e.data,n=e.xaxis,r=e.yaxis,i=e.timeline.barWidth;n.options.min===null&&(n.min=n.datamin-i/2);if(n.options.max===null){var s=n.max;Flotr._.each(t,function(e){s=Math.max(s,e[0]+e[2])},this),n.max=s+i/2}r.options.min===null&&(r.min=r.datamin-i),r.options.min===null&&(r.max=r.datamax+i)}}),function(){var e=Flotr.DOM;Flotr.addPlugin("crosshair",{options:{mode:null,color:"#FF0000",hideCursor:!0},callbacks:{"flotr:mousemove":function(e,t){this.options.crosshair.mode&&(this.crosshair.clearCrosshair(),this.crosshair.drawCrosshair(t))}},drawCrosshair:function(t){var n=this.octx,r=this.options.crosshair,i=this.plotOffset,s=i.left+Math.round(t.relX)+.5,o=i.top+Math.round(t.relY)+.5;if(t.relX<0||t.relY<0||t.relX>this.plotWidth||t.relY>this.plotHeight){this.el.style.cursor=null,e.removeClass(this.el,"flotr-crosshair");return}r.hideCursor&&(this.el.style.cursor="none",e.addClass(this.el,"flotr-crosshair")),n.save(),n.strokeStyle=r.color,n.lineWidth=1,n.beginPath(),r.mode.indexOf("x")!=-1&&(n.moveTo(s,i.top),n.lineTo(s,i.top+this.plotHeight)),r.mode.indexOf("y")!=-1&&(n.moveTo(i.left,o),n.lineTo(i.left+this.plotWidth,o)),n.stroke(),n.restore()},clearCrosshair:function(){var e=this.plotOffset,t=this.lastMousePos,n=this.octx;t&&(n.clearRect(Math.round(t.relX)+e.left,e.top,1,this.plotHeight+1),n.clearRect(e.left,Math.round(t.relY)+e.top,this.plotWidth+1,1))}})}(),function(){function n(e,t,n,r,i,s){var o="image/"+e,u=n.getImageData(0,0,r,i),a=new Image;return n.save(),n.globalCompositeOperation="destination-over",n.fillStyle=s,n.fillRect(0,0,r,i),a.src=t.toDataURL(o),n.restore(),n.clearRect(0,0,r,i),n.putImageData(u,0,0),a}var e=Flotr.DOM,t=Flotr._;Flotr.addPlugin("download",{saveImage:function(r,i,s,o){var u=this.options.grid,a;if(Flotr.isIE&&Flotr.isIE<9)return a="<html><body>"+this.canvas.firstChild.innerHTML+"</body></html>",window.open().document.write(a);if(r!=="jpeg"&&r!=="png")return;a=n(r,this.canvas,this.ctx,this.canvasWidth,this.canvasHeight,u&&u.backgroundColor||"#ffffff");if(!t.isElement(a)||!o)return window.open(a.src);this.download.restoreCanvas(),e.hide(this.canvas),e.hide(this.overlay),e.setStyles({position:"absolute"}),e.insert(this.el,a),this.saveImageElement=a},restoreCanvas:function(){e.show(this.canvas),e.show(this.overlay),this.saveImageElement&&this.el.removeChild(this.saveImageElement),this.saveImageElement=null}})}(),function(){var e=Flotr.EventAdapter,t=Flotr._;Flotr.addPlugin("graphGrid",{callbacks:{"flotr:beforedraw":function(){this.graphGrid.drawGrid()},"flotr:afterdraw":function(){this.graphGrid.drawOutline()}},drawGrid:function(){function v(e){for(p=0;p<e.length;++p){var t=e[p].v/c.max;for(d=0;d<=w;++d)n[d===0?"moveTo":"lineTo"](Math.cos(d*S+x)*b*t,Math.sin(d*S+x)*b*t)}}function m(e,r){t.each(t.pluck(e,"v"),function(e){if(e<=c.min||e>=c.max||(e==c.min||e==c.max)&&i.outlineWidth)return;r(Math.floor(c.d2p(e))+n.lineWidth/2)})}function g(e){n.moveTo(e,0),n.lineTo(e,f)}function y(e){n.moveTo(0,e),n.lineTo(l,e)}var n=this.ctx,r=this.options,i=r.grid,s=i.verticalLines,o=i.horizontalLines,u=i.minorVerticalLines,a=i.minorHorizontalLines,f=this.plotHeight,l=this.plotWidth,c,h,p,d;(s||u||o||a)&&e.fire(this.el,"flotr:beforegrid",[this.axes.x,this.axes.y,r,this]),n.save(),n.lineWidth=1,n.strokeStyle=i.tickColor;if(i.circular){n.translate(this.plotOffset.left+l/2,this.plotOffset.top+f/2);var b=Math.min(f,l)*r.radar.radiusRatio/2,w=this.axes.x.ticks.length,S=2*(Math.PI/w),x=-Math.PI/2;n.beginPath(),c=this.axes.y,o&&v(c.ticks),a&&v(c.minorTicks),s&&t.times(w,function(e){n.moveTo(0,0),n.lineTo(Math.cos(e*S+x)*b,Math.sin(e*S+x)*b)}),n.stroke()}else n.translate(this.plotOffset.left,this.plotOffset.top),i.backgroundColor&&(n.fillStyle=this.processColor(i.backgroundColor,{x1:0,y1:0,x2:l,y2:f}),n.fillRect(0,0,l,f)),n.beginPath(),c=this.axes.x,s&&m(c.ticks,g),u&&m(c.minorTicks,g),c=this.axes.y,o&&m(c.ticks,y),a&&m(c.minorTicks,y),n.stroke();n.restore(),(s||u||o||a)&&e.fire(this.el,"flotr:aftergrid",[this.axes.x,this.axes.y,r,this])},drawOutline:function(){var e=this,t=e.options,n=t.grid,r=n.outline,s=e.ctx,o=n.backgroundImage,u=e.plotOffset,a=u.left,f=u.top,l=e.plotWidth,c=e.plotHeight,h,p,d,v,m,g;if(!n.outlineWidth)return;s.save();if(n.circular){s.translate(a+l/2,f+c/2);var y=Math.min(c,l)*t.radar.radiusRatio/2,b=this.axes.x.ticks.length,w=2*(Math.PI/b),E=-Math.PI/2;s.beginPath(),s.lineWidth=n.outlineWidth,s.strokeStyle=n.color,s.lineJoin="round";for(i=0;i<=b;++i)s[i===0?"moveTo":"lineTo"](Math.cos(i*w+E)*y,Math.sin(i*w+E)*y);s.stroke()}else{s.translate(a,f);var S=n.outlineWidth,x=.5-S+(S+1)%2/2,T="lineTo",N="moveTo";s.lineWidth=S,s.strokeStyle=n.color,s.lineJoin="miter",s.beginPath(),s.moveTo(x,x),l-=S/2%1,c+=S/2,s[r.indexOf("n")!==-1?T:N](l,x),s[r.indexOf("e")!==-1?T:N](l,c),s[r.indexOf("s")!==-1?T:N](x,c),s[r.indexOf("w")!==-1?T:N](x,x),s.stroke(),s.closePath()}s.restore(),o&&(d=o.src||o,v=(parseInt(o.left,10)||0)+u.left,m=(parseInt(o.top,10)||0)+u.top,p=new Image,p.onload=function(){s.save(),o.alpha&&(s.globalAlpha=o.alpha),s.globalCompositeOperation="destination-over",s.drawImage(p,0,0,p.width,p.height,v,m,l,c),s.restore()},p.src=d)}})}(),function(){var e=Flotr.DOM,t=Flotr._,n=Flotr,r="opacity:0.7;background-color:#000;color:#fff;position:absolute;padding:2px 8px;-moz-border-radius:4px;border-radius:4px;white-space:nowrap;";Flotr.addPlugin("hit",{callbacks:{"flotr:mousemove":function(e,t){this.hit.track(t)},"flotr:click":function(e){var n=this.hit.track(e);n&&!t.isUndefined(n.index)&&(e.hit=n)},"flotr:mouseout":function(e){e.relatedTarget!==this.mouseTrack&&this.hit.clearHit()},"flotr:destroy":function(){this.options.mouse.container&&e.remove(this.mouseTrack),this.mouseTrack=null}},track:function(e){if(this.options.mouse.track||t.any(this.series,function(e){return e.mouse&&e.mouse.track}))return this.hit.hit(e)},executeOnType:function(e,r,i){function u(e,u){t.each(t.keys(n.graphTypes),function(t){e[t]&&e[t].show&&!e.hide&&this[t][r]&&(o=this.getOptions(e,t),o.fill=!!e.mouse.fillColor,o.fillStyle=this.processColor(e.mouse.fillColor||"#ffffff",{opacity:e.mouse.fillOpacity}),o.color=e.mouse.lineColor,o.context=this.octx,o.index=u,i&&(o.args=i),this[t][r].call(this[t],o),s=!0)},this)}var s=!1,o;return t.isArray(e)||(e=[e]),t.each(e,u,this),s},drawHit:function(e){var t=this.octx,n=e.series;if(n.mouse.lineColor){t.save(),t.lineWidth=n.points?n.points.lineWidth:1,t.strokeStyle=n.mouse.lineColor,t.fillStyle=this.processColor(n.mouse.fillColor||"#ffffff",{opacity:n.mouse.fillOpacity}),t.translate(this.plotOffset.left,this.plotOffset.top);if(!this.hit.executeOnType(n,"drawHit",e)){var r=e.xaxis,i=e.yaxis;t.beginPath(),t.arc(r.d2p(e.x),i.d2p(e.y),n.points.hitRadius||n.points.radius||n.mouse.radius,0,2*Math.PI,!0),t.fill(),t.stroke(),t.closePath()}t.restore(),this.clip(t)}this.prevHit=e},clearHit:function(){var t=this.prevHit,n=this.octx,r=this.plotOffset;n.save(),n.translate(r.left,r.top);if(t){if(!this.hit.executeOnType(t.series,"clearHit",this.prevHit)){var i=t.series,s=i.points?i.points.lineWidth:1;offset=(i.points.hitRadius||i.points.radius||i.mouse.radius)+s,n.clearRect(t.xaxis.d2p(t.x)-offset,t.yaxis.d2p(t.y)-offset,offset*2,offset*2)}e.hide(this.mouseTrack),this.prevHit=null}n.restore()},hit:function(e){var n=this.options,r=this.prevHit,i,s,o,u,a,f,l,c,h;if(this.series.length===0)return;h={relX:e.relX,relY:e.relY,absX:e.absX,absY:e.absY,series:this.series};if(n.mouse.trackY&&!n.mouse.trackAll&&this.hit.executeOnType(this.series,"hit",[e,h])&&!t.isUndefined(h.seriesIndex))a=this.series[h.seriesIndex],h.series=a,h.mouse=a.mouse,h.xaxis=a.xaxis,h.yaxis=a.yaxis;else{i=this.hit.closest(e);if(i){i=n.mouse.trackY?i.point:i.x,u=i.seriesIndex,a=this.series[u],l=a.xaxis,c=a.yaxis,s=2*a.mouse.sensibility;if(n.mouse.trackAll||i.distanceX<s/l.scale&&(!n.mouse.trackY||i.distanceY<s/c.scale))h.series=a,h.xaxis=a.xaxis,h.yaxis=a.yaxis,h.mouse=a.mouse,h.x=i.x,h.y=i.y,h.dist=i.distance,h.index=i.dataIndex,h.seriesIndex=u}}if(!r||r.index!==h.index||r.seriesIndex!==h.seriesIndex)this.hit.clearHit(),h.series&&h.mouse&&h.mouse.track&&(this.hit.drawMouseTrack(h),this.hit.drawHit(h),Flotr.EventAdapter.fire(this.el,"flotr:hit",[h,this]));return h},closest:function(e){function E(e){e.distance=h,e.distanceX=p,e.distanceY=d,e.seriesIndex=b,e.dataIndex=w,e.x=g,e.y=y,f=!0}var t=this.series,n=this.options,r=e.relX,i=e.relY,s=Number.MAX_VALUE,o=Number.MAX_VALUE,u={},a={},f=!1,l,c,h,p,d,v,m,g,y,b,w;for(b=0;b<t.length;b++){l=t[b],c=l.data,v=l.xaxis.p2d(r),m=l.yaxis.p2d(i);if(l.hide)continue;for(w=c.length;w--;){g=c[w][0],y=c[w][1],c[w].y0&&(y+=c[w].y0);if(g===null||y===null)continue;if(g<l.xaxis.min||g>l.xaxis.max)continue;p=Math.abs(g-v),d=Math.abs(y-m),h=p*p+d*d,h<s&&(s=h,E(u)),p<o&&(o=p,E(a))}}return f?{point:u,x:a}:!1},drawMouseTrack:function(n){var i="",s=n.series,o=n.mouse.position,u=n.mouse.margin,a=n.x,f=n.y,l=r,c=this.mouseTrack,h=this.plotOffset,p=h.left,d=h.right,v=h.bottom,m=h.top,g=n.mouse.trackDecimals,y=this.options,b=y.mouse.container,w=0,E=0,S,x,T;c||(c=e.node('<div class="flotr-mouse-value" style="'+l+'"></div>'),this.mouseTrack=c,e.insert(b||this.el,c));if(!g||g<0)g=0;a&&a.toFixed&&(a=a.toFixed(g)),f&&f.toFixed&&(f=f.toFixed(g)),T=n.mouse.trackFormatter({x:a,y:f,series:n.series,index:n.index,nearest:n,fraction:n.fraction});if(t.isNull(T)||t.isUndefined(T)){e.hide(c);return}c.innerHTML=T,e.show(c);if(!o)return;x=e.size(c),b&&(S=e.position(this.el),w=S.top,E=S.left);if(!n.mouse.relative)i+="top:",o.charAt(0)=="n"?i+=w+u+m:o.charAt(0)=="s"&&(i+=w-u+m+this.plotHeight-x.height),i+="px;bottom:auto;left:",o.charAt(1)=="e"?i+=E-u+p+this.plotWidth-x.width:o.charAt(1)=="w"&&(i+=E+u+p),i+="px;right:auto;";else if(s.pie&&s.pie.show){var N={x:this.plotWidth/2,y:this.plotHeight/2},C=Math.min(this.canvasWidth,this.canvasHeight)*s.pie.sizeRatio/2,k=n.sAngle<n.eAngle?(n.sAngle+n.eAngle)/2:(n.sAngle+n.eAngle+2*Math.PI)/2;i+="bottom:"+(u-m-N.y-Math.sin(k)*C/2+this.canvasHeight)+"px;top:auto;",i+="left:"+(u+p+N.x+Math.cos(k)*C/2)+"px;right:auto;"}else i+="top:",/n/.test(o)?i+=w-u+m+n.yaxis.d2p(n.y)-x.height:i+=w+u+m+n.yaxis.d2p(n.y),i+="px;bottom:auto;left:",/w/.test(o)?i+=E-u+p+n.xaxis.d2p(n.x)-x.width:i+=E+u+p+n.xaxis.d2p(n.x),i+="px;right:auto;";c.style.cssText=l+i,n.mouse.relative&&(/[ew]/.test(o)?/[ns]/.test(o)||(c.style.top=w+m+n.yaxis.d2p(n.y)-e.size(c).height/2+"px"):c.style.left=E+p+n.xaxis.d2p(n.x)-e.size(c).width/2+"px")}})}(),function(){function e(e,t){return e.which?e.which===1:e.button===0||e.button===1}function t(e,t){return Math.min(Math.max(0,e),t.plotWidth-1)}function n(e,t){return Math.min(Math.max(0,e),t.plotHeight)}var r=Flotr.DOM,i=Flotr.EventAdapter,s=Flotr._;Flotr.addPlugin("selection",{options:{pinchOnly:null,mode:null,color:"#B6D9FF",fps:20},callbacks:{"flotr:mouseup":function(e){var t=this.options.selection,n=this.selection,r=this.getEventPosition(e);if(!t||!t.mode)return;n.interval&&clearInterval(n.interval),this.multitouches?n.updateSelection():t.pinchOnly||n.setSelectionPos(n.selection.second,r),n.clearSelection(),n.selecting&&n.selectionIsSane()&&(n.drawSelection(),n.fireSelectEvent(),this.ignoreClick=!0)},"flotr:mousedown":function(t){var n=this.options.selection,r=this.selection,i=this.getEventPosition(t);if(!n||!n.mode)return;if(!n.mode||!e(t)&&s.isUndefined(t.touches))return;n.pinchOnly||r.setSelectionPos(r.selection.first,i),r.interval&&clearInterval(r.interval),this.lastMousePos.pageX=null,r.selecting=!1,r.interval=setInterval(s.bind(r.updateSelection,this),1e3/n.fps)},"flotr:destroy":function(e){clearInterval(this.selection.interval)}},getArea:function(){var e=this.selection.selection,t=this.axes,n=e.first,r=e.second,i,s,o,u;return i=t.x.p2d(e.first.x),s=t.x.p2d(e.second.x),o=t.y.p2d(e.first.y),u=t.y.p2d(e.second.y),{x1:Math.min(i,s),y1:Math.min(o,u),x2:Math.max(i,s),y2:Math.max(o,u),xfirst:i,xsecond:s,yfirst:o,ysecond:u}},selection:{first:{x:-1,y:-1},second:{x:-1,y:-1}},prevSelection:null,interval:null,fireSelectEvent:function(e){var t=this.selection.getArea();e=e||"select",t.selection=this.selection.selection,i.fire(this.el,"flotr:"+e,[t,this])},setSelection:function(e,r){var i=this.options,s=this.axes.x,o=this.axes.y,u=o.scale,a=s.scale,f=i.selection.mode.indexOf("x")!=-1,l=i.selection.mode.indexOf("y")!=-1,c=this.selection.selection;this.selection.clearSelection(),c.first.y=n(f&&!l?0:(o.max-e.y1)*u,this),c.second.y=n(f&&!l?this.plotHeight-1:(o.max-e.y2)*u,this),c.first.x=t(l&&!f?0:(e.x1-s.min)*a,this),c.second.x=t(l&&!f?this.plotWidth:(e.x2-s.min)*a,this),this.selection.drawSelection(),r||this.selection.fireSelectEvent()},setSelectionPos:function(e,r){var i=this.options.selection.mode,s=this.selection.selection;i.indexOf("x")==-1?e.x=e==s.first?0:this.plotWidth:e.x=t(r.relX,this),i.indexOf("y")==-1?e.y=e==s.first?0:this.plotHeight-1:e.y=n(r.relY,this)},drawSelection:function(){this.selection.fireSelectEvent("selecting");var e=this.selection.selection,t=this.octx,n=this.options,r=this.plotOffset,i=this.selection.prevSelection;if(i&&e.first.x==i.first.x&&e.first.y==i.first.y&&e.second.x==i.second.x&&e.second.y==i.second.y)return;t.save(),t.strokeStyle=this.processColor(n.selection.color,{opacity:.8}),t.lineWidth=1,t.lineJoin="miter",t.fillStyle=this.processColor(n.selection.color,{opacity:.4}),this.selection.prevSelection={first:{x:e.first.x,y:e.first.y},second:{x:e.second.x,y:e.second.y}};var s=Math.min(e.first.x,e.second.x),o=Math.min(e.first.y,e.second.y),u=Math.abs(e.second.x-e.first.x),a=Math.abs(e.second.y-e.first.y);t.fillRect(s+r.left+.5,o+r.top+.5,u,a),t.strokeRect(s+r.left+.5,o+r.top+.5,u,a),t.restore()},updateSelection:function(){if(!this.lastMousePos.pageX)return;this.selection.selecting=!0;if(this.multitouches)this.selection.setSelectionPos(this.selection.selection.first,this.getEventPosition(this.multitouches[0])),this.selection.setSelectionPos(this.selection.selection.second,this.getEventPosition(this.multitouches[1]));else{if(this.options.selection.pinchOnly)return;this.selection.setSelectionPos(this.selection.selection.second,this.lastMousePos)}this.selection.clearSelection(),this.selection.selectionIsSane()&&this.selection.drawSelection()},clearSelection:function(){if(!this.selection.prevSelection)return;var e=this.selection.prevSelection,t=1,n=this.plotOffset,r=Math.min(e.first.x,e.second.x),i=Math.min(e.first.y,e.second.y),s=Math.abs(e.second.x-e.first.x),o=Math.abs(e.second.y-e.first.y);this.octx.clearRect(r+n.left-t+.5,i+n.top-t,s+2*t+.5,o+2*t+.5),this.selection.prevSelection=null},selectionIsSane:function(){var e=this.selection.selection;return Math.abs(e.second.x-e.first.x)>=5||Math.abs(e.second.y-e.first.y)>=5}})}(),function(){var e=Flotr.DOM;Flotr.addPlugin("labels",{callbacks:{"flotr:afterdraw":function(){this.labels.draw()}},draw:function(){function b(e,t,r){var i=r?t.minorTicks:t.ticks,s=t.orientation===1,u=t.n===1,l,h;l={color:t.options.color||d.grid.color,angle:Flotr.toRad(t.options.labelsAngle),textBaseline:"middle"};for(c=0;c<i.length&&(r?t.options.showMinorLabels:t.options.showLabels);++c){n=i[c],n.label+="";if(!n.label||!n.label.length)continue;x=Math.cos(c*a+f)*o,y=Math.sin(c*a+f)*o,l.textAlign=s?Math.abs(x)<.1?"center":x<0?"right":"left":"left",Flotr.drawText(v,n.label,s?x:3,s?y:-(t.ticks[c].v/t.max)*(o-d.fontSize),l)}}function w(e,t,r,i){function f(e){return e.options.showLabels&&e.used}function l(e,t,n,r){return e.plotOffset.left+(t?r:n?-d.grid.labelMargin:d.grid.labelMargin+e.plotWidth)}function h(e,t,n,r){return e.plotOffset.top+(t?d.grid.labelMargin:r)+(t&&n?e.plotHeight:0)}var s=t.orientation===1,o=t.n===1,u,a;u={color:t.options.color||d.grid.color,textAlign:r,textBaseline:i,angle:Flotr.toRad(t.options.labelsAngle)},u=Flotr.getBestTextAlign(u.angle,u);for(c=0;c<t.ticks.length&&f(t);++c){n=t.ticks[c];if(!n.label||!n.label.length)continue;a=t.d2p(n.v);if(a<0||a>(s?e.plotWidth:e.plotHeight))continue;Flotr.drawText(v,n.label,l(e,s,o,a),h(e,s,o,a),u),!s&&!o&&(v.save(),v.strokeStyle=u.color,v.beginPath(),v.moveTo(e.plotOffset.left+e.plotWidth-8,e.plotOffset.top+t.d2p(n.v)),v.lineTo(e.plotOffset.left+e.plotWidth,e.plotOffset.top+t.d2p(n.v)),v.stroke(),v.restore())}}function E(e,t){var r=t.orientation===1,i=t.n===1,o="",u,a,f,l=e.plotOffset;!r&&!i&&(v.save(),v.strokeStyle=t.options.color||d.grid.color,v.beginPath());if(t.options.showLabels&&(i?!0:t.used))for(c=0;c<t.ticks.length;++c){n=t.ticks[c];if(!n.label||!n.label.length||(r?l.left:l.top)+t.d2p(n.v)<0||(r?l.left:l.top)+t.d2p(n.v)>(r?e.canvasWidth:e.canvasHeight))continue;f=l.top+(r?(i?1:-1)*(e.plotHeight+d.grid.labelMargin):t.d2p(n.v)-t.maxLabel.height/2),u=r?l.left+t.d2p(n.v)-s/2:0,o="",c===0?o=" first":c===t.ticks.length-1&&(o=" last"),o+=r?" flotr-grid-label-x":" flotr-grid-label-y",h+=['<div style="position:absolute; text-align:'+(r?"center":"right")+"; ","top:"+f+"px; ",(!r&&!i?"right:":"left:")+u+"px; ","width:"+(r?s:(i?l.left:l.right)-d.grid.labelMargin)+"px; ",t.options.color?"color:"+t.options.color+"; ":" ",'" class="flotr-grid-label'+o+'">'+n.label+"</div>"].join(" "),!r&&!i&&(v.moveTo(l.left+e.plotWidth-8,l.top+t.d2p(n.v)),v.lineTo(l.left+e.plotWidth,l.top+t.d2p(n.v)))}}var t,n,r,i,s,o,u,a,f,l,c,h="",p=0,d=this.options,v=this.ctx,m=this.axes,g={size:d.fontSize};for(c=0;c<m.x.ticks.length;++c)m.x.ticks[c].label&&++p;s=this.plotWidth/p,d.grid.circular&&(v.save(),v.translate(this.plotOffset.left+this.plotWidth/2,this.plotOffset.top+this.plotHeight/2),o=this.plotHeight*d.radar.radiusRatio/2+d.fontSize,u=this.axes.x.ticks.length,a=2*(Math.PI/u),f=-Math.PI/2,b(this,m.x,!1),b(this,m.x,!0),b(this,m.y,!1),b(this,m.y,!0),v.restore()),!d.HtmlText&&this.textEnabled?(w(this,m.x,"center","top"),w(this,m.x2,"center","bottom"),w(this,m.y,"right","middle"),w(this,m.y2,"left","middle")):(m.x.options.showLabels||m.x2.options.showLabels||m.y.options.showLabels||m.y2.options.showLabels)&&!d.grid.circular&&(h="",E(this,m.x),E(this,m.x2),E(this,m.y),E(this,m.y2),v.stroke(),v.restore(),l=e.create("div"),e.setStyles(l,{fontSize:"smaller",color:d.grid.color}),l.className="flotr-labels",e.insert(this.el,l),e.insert(l,h))}})}(),function(){var e=Flotr.DOM,t=Flotr._;Flotr.addPlugin("legend",{options:{show:!0,noColumns:1,labelFormatter:function(e){return e},labelBoxBorderColor:"#CCCCCC",labelBoxWidth:14,labelBoxHeight:10,labelBoxMargin:5,container:null,position:"nw",margin:5,backgroundColor:"#F0F0F0",backgroundOpacity:.85},callbacks:{"flotr:afterinit":function(){this.legend.insertLegend()},"flotr:destroy":function(){var t=this.legend.markup;t&&(this.legend.markup=null,e.remove(t))}},insertLegend:function(){if(!this.options.legend.show)return;var n=this.series,r=this.plotOffset,i=this.options,s=i.legend,o=[],u=!1,a=this.ctx,f=t.filter(n,function(e){return e.label&&!e.hide}).length,l=s.position,c=s.margin,h=s.backgroundOpacity,p,d,v;if(f){var m=s.labelBoxWidth,g=s.labelBoxHeight,y=s.labelBoxMargin,b=r.left+c,w=r.top+c,E=0,S={size:i.fontSize*1.1,color:i.grid.color};for(p=n.length-1;p>-1;--p){if(!n[p].label||n[p].hide)continue;d=s.labelFormatter(n[p].label),E=Math.max(E,this._text.measureText(d,S).width)}var x=Math.round(m+y*3+E),T=Math.round(f*(y+g)+y);!h&&h!==0&&(h=.1);if(!i.HtmlText&&this.textEnabled&&!s.container){l.charAt(0)=="s"&&(w=r.top+this.plotHeight-(c+T)),l.charAt(0)=="c"&&(w=r.top+this.plotHeight/2-(c+T/2)),l.charAt(1)=="e"&&(b=r.left+this.plotWidth-(c+x)),v=this.processColor(s.backgroundColor,{opacity:h}),a.fillStyle=v,a.fillRect(b,w,x,T),a.strokeStyle=s.labelBoxBorderColor,a.strokeRect(Flotr.toPixel(b),Flotr.toPixel(w),x,T);var N=b+y,C=w+y;for(p=0;p<n.length;p++){if(!n[p].label||n[p].hide)continue;d=s.labelFormatter(n[p].label),a.fillStyle=n[p].color,a.fillRect(N,C,m-1,g-1),a.strokeStyle=s.labelBoxBorderColor,a.lineWidth=1,a.strokeRect(Math.ceil(N)-1.5,Math.ceil(C)-1.5,m+2,g+2),Flotr.drawText(a,d,N+m+y,C+g,S),C+=g+y}}else{for(p=0;p<n.length;++p){if(!n[p].label||n[p].hide)continue;p%s.noColumns===0&&(o.push(u?"</tr><tr>":"<tr>"),u=!0);var k=n[p],L=s.labelBoxWidth,A=s.labelBoxHeight;d=s.labelFormatter(k.label),v="background-color:"+(k.bars&&k.bars.show&&k.bars.fillColor&&k.bars.fill?k.bars.fillColor:k.color)+";",o.push('<td class="flotr-legend-color-box">','<div style="border:1px solid ',s.labelBoxBorderColor,';padding:1px">','<div style="width:',L-1,"px;height:",A-1,"px;border:1px solid ",n[p].color,'">','<div style="width:',L,"px;height:",A,"px;",v,'"></div>',"</div>","</div>","</td>",'<td class="flotr-legend-label">',d,"</td>")}u&&o.push("</tr>");if(o.length>0){var O='<table style="font-size:smaller;color:'+i.grid.color+'">'+o.join("")+"</table>";if(s.container)O=e.node(O),this.legend.markup=O,e.insert(s.container,O);else{var M={position:"absolute",zIndex:"2",border:"1px solid "+s.labelBoxBorderColor};l.charAt(0)=="n"?(M.top=c+r.top+"px",M.bottom="auto"):l.charAt(0)=="c"?(M.top=c+(this.plotHeight-T)/2+"px",M.bottom="auto"):l.charAt(0)=="s"&&(M.bottom=c+r.bottom+"px",M.top="auto"),l.charAt(1)=="e"?(M.right=c+r.right+"px",M.left="auto"):l.charAt(1)=="w"&&(M.left=c+r.left+"px",M.right="auto");var P=e.create("div"),H;P.className="flotr-legend",e.setStyles(P,M),e.insert(P,O),e.insert(this.el,P);if(!h)return;var B=s.backgroundColor||i.grid.backgroundColor||"#ffffff";t.extend(M,e.size(P),{backgroundColor:B,zIndex:"",border:""}),M.width+="px",M.height+="px",P=e.create("div"),P.className="flotr-legend-bg",e.setStyles(P,M),e.opacity(P,h),e.insert(P," "),e.insert(this.el,P)}}}}}})}(),function(){function e(e){if(this.options.spreadsheet.tickFormatter)return this.options.spreadsheet.tickFormatter(e);var t=n.find(this.axes.x.ticks,function(t){return t.v==e});return t?t.label:e}var t=Flotr.DOM,n=Flotr._;Flotr.addPlugin("spreadsheet",{options:{show:!1,tabGraphLabel:"Graph",tabDataLabel:"Data",toolbarDownload:"Download CSV",toolbarSelectAll:"Select all",csvFileSeparator:",",decimalSeparator:".",tickFormatter:null,initialTab:"graph"},callbacks:{"flotr:afterconstruct":function(){if(!this.options.spreadsheet.show)return;var e=this.spreadsheet,n=t.node('<div class="flotr-tabs-group" style="position:absolute;left:0px;width:'+this.canvasWidth+'px"></div>'),r=t.node('<div style="float:left" class="flotr-tab selected">'+this.options.spreadsheet.tabGraphLabel+"</div>"),i=t.node('<div style="float:left" class="flotr-tab">'+this.options.spreadsheet.tabDataLabel+"</div>"),s;e.tabsContainer=n,e.tabs={graph:r,data:i},t.insert(n,r),t.insert(n,i),t.insert(this.el,n),s=t.size(i).height+2,this.plotOffset.bottom+=s,t.setStyles(n,{top:this.canvasHeight-s+"px"}),this.observe(r,"click",function(){e.showTab("graph")}).observe(i,"click",function(){e.showTab("data")}),this.options.spreadsheet.initialTab!=="graph"&&e.showTab(this.options.spreadsheet.initialTab)}},loadDataGrid:function(){if(this.seriesData)return this.seriesData;var e=this.series,t={};return n.each(e,function(e,r){n.each(e.data,function(e){var n=e[0],s=e[1],o=t[n];if(o)o[r+1]=s;else{var u=[];u[0]=n,u[r+1]=s,t[n]=u}})}),this.seriesData=n.sortBy(t,function(e,t){return parseInt(t,10)}),this.seriesData},constructDataGrid:function(){if(this.spreadsheet.datagrid)return this.spreadsheet.datagrid;var r=this.series,i=this.spreadsheet.loadDataGrid(),s=["<colgroup><col />"],o,u,a,f=['<table class="flotr-datagrid"><tr class="first-row">'];f.push("<th>&nbsp;</th>"),n.each(r,function(e,t){f.push('<th scope="col">'+(e.label||String.fromCharCode(65+t))+"</th>"),s.push("<col />")}),f.push("</tr>"),n.each(i,function(t){f.push("<tr>"),n.times(r.length+1,function(r){var i="td",s=t[r],o=n.isUndefined(s)?"":Math.round(s*1e5)/1e5;if(r===0){i="th";var u=e.call(this,o);u&&(o=u)}f.push("<"+i+(i=="th"?' scope="row"':"")+">"+o+"</"+i+">")},this),f.push("</tr>")},this),s.push("</colgroup>"),a=t.node(f.join("")),o=t.node('<button type="button" class="flotr-datagrid-toolbar-button">'+this.options.spreadsheet.toolbarDownload+"</button>"),u=t.node('<button type="button" class="flotr-datagrid-toolbar-button">'+this.options.spreadsheet.toolbarSelectAll+"</button>"),this.observe(o,"click",n.bind(this.spreadsheet.downloadCSV,this)).observe(u,"click",n.bind(this.spreadsheet.selectAllData,this));var l=t.node('<div class="flotr-datagrid-toolbar"></div>');t.insert(l,o),t.insert(l,u);var c=this.canvasHeight-t.size(this.spreadsheet.tabsContainer).height-2,h=t.node('<div class="flotr-datagrid-container" style="position:absolute;left:0px;top:0px;width:'+this.canvasWidth+"px;height:"+c+'px;overflow:auto;z-index:10"></div>');return t.insert(h,l),t.insert(h,a),t.insert(this.el,h),this.spreadsheet.datagrid=a,this.spreadsheet.container=h,a},showTab:function(e){if(this.spreadsheet.activeTab===e)return;switch(e){case"graph":t.hide(this.spreadsheet.container),t.removeClass(this.spreadsheet.tabs.data,"selected"),t.addClass(this.spreadsheet.tabs.graph,"selected");break;case"data":this.spreadsheet.datagrid||this.spreadsheet.constructDataGrid(),t.show(this.spreadsheet.container),t.addClass(this.spreadsheet.tabs.data,"selected"),t.removeClass(this.spreadsheet.tabs.graph,"selected");break;default:throw"Illegal tab name: "+e}this.spreadsheet.activeTab=e},selectAllData:function(){if(this.spreadsheet.tabs){var e,t,n,r,i=this.spreadsheet.constructDataGrid();return this.spreadsheet.showTab("data"),setTimeout(function(){(n=i.ownerDocument)&&(r=n.defaultView)&&r.getSelection&&n.createRange&&(e=window.getSelection())&&e.removeAllRanges?(t=n.createRange(),t.selectNode(i),e.removeAllRanges(),e.addRange(t)):document.body&&document.body.createTextRange&&(t=document.body.createTextRange())&&(t.moveToElementText(i),t.select())},0),!0}return!1},downloadCSV:function(){var t="",r=this.series,i=this.options,s=this.spreadsheet.loadDataGrid(),o=encodeURIComponent(i.spreadsheet.csvFileSeparator);if(i.spreadsheet.decimalSeparator===i.spreadsheet.csvFileSeparator)throw"The decimal separator is the same as the column separator ("+i.spreadsheet.decimalSeparator+")";n.each(r,function(e,n){t+=o+'"'+(e.label||String.fromCharCode(65+n)).replace(/\"/g,'\\"')+'"'}),t+="%0D%0A",t+=n.reduce(s,function(t,n){var r=e.call(this,n[0])||"";r='"'+(r+"").replace(/\"/g,'\\"')+'"';var s=n.slice(1).join(o);return i.spreadsheet.decimalSeparator!=="."&&(s=s.replace(/\./g,i.spreadsheet.decimalSeparator)),t+r+o+s+"%0D%0A"},"",this),Flotr.isIE&&Flotr.isIE<9?(t=t.replace(new RegExp(o,"g"),decodeURIComponent(o)).replace(/%0A/g,"\n").replace(/%0D/g,"\r"),window.open().document.write(t)):window.open("data:text/csv,"+t)}})}(),function(){var e=Flotr.DOM;Flotr.addPlugin("titles",{callbacks:{"flotr:afterdraw":function(){this.titles.drawTitles()}},drawTitles:function(){var t,n=this.options,r=n.grid.labelMargin,i=this.ctx,s=this.axes;if(!n.HtmlText&&this.textEnabled){var o={size:n.fontSize,color:n.grid.color,textAlign:"center"};n.subtitle&&Flotr.drawText(i,n.subtitle,this.plotOffset.left+this.plotWidth/2,this.titleHeight+this.subtitleHeight-2,o),o.weight=1.5,o.size*=1.5,n.title&&Flotr.drawText(i,n.title,this.plotOffset.left+this.plotWidth/2,this.titleHeight-2,o),o.weight=1.8,o.size*=.8,s.x.options.title&&s.x.used&&(o.textAlign=s.x.options.titleAlign||"center",o.textBaseline="top",o.angle=Flotr.toRad(s.x.options.titleAngle),o=Flotr.getBestTextAlign(o.angle,o),Flotr.drawText(i,s.x.options.title,this.plotOffset.left+this.plotWidth/2,this.plotOffset.top+s.x.maxLabel.height+this.plotHeight+2*r,o)),s.x2.options.title&&s.x2.used&&(o.textAlign=s.x2.options.titleAlign||"center",o.textBaseline="bottom",o.angle=Flotr.toRad(s.x2.options.titleAngle),o=Flotr.getBestTextAlign(o.angle,o),Flotr.drawText(i,s.x2.options.title,this.plotOffset.left+this.plotWidth/2,this.plotOffset.top-s.x2.maxLabel.height-2*r,o)),s.y.options.title&&s.y.used&&(o.textAlign=s.y.options.titleAlign||"right",o.textBaseline="middle",o.angle=Flotr.toRad(s.y.options.titleAngle),o=Flotr.getBestTextAlign(o.angle,o),Flotr.drawText(i,s.y.options.title,this.plotOffset.left-s.y.maxLabel.width-2*r,this.plotOffset.top+this.plotHeight/2,o)),s.y2.options.title&&s.y2.used&&(o.textAlign=s.y2.options.titleAlign||"left",o.textBaseline="middle",o.angle=Flotr.toRad(s.y2.options.titleAngle),o=Flotr.getBestTextAlign(o.angle,o),Flotr.drawText(i,s.y2.options.title,this.plotOffset.left+this.plotWidth+s.y2.maxLabel.width+2*r,this.plotOffset.top+this.plotHeight/2,o))}else{t=[],n.title&&t.push('<div style="position:absolute;top:0;left:',this.plotOffset.left,"px;font-size:1em;font-weight:bold;text-align:center;width:",this.plotWidth,'px;" class="flotr-title">',n.title,"</div>"),n.subtitle&&t.push('<div style="position:absolute;top:',this.titleHeight,"px;left:",this.plotOffset.left,"px;font-size:smaller;text-align:center;width:",this.plotWidth,'px;" class="flotr-subtitle">',n.subtitle,"</div>"),t.push("</div>"),t.push('<div class="flotr-axis-title" style="font-weight:bold;">'),s.x.options.title&&s.x.used&&t.push('<div style="position:absolute;top:',this.plotOffset.top+this.plotHeight+n.grid.labelMargin+s.x.titleSize.height,"px;left:",this.plotOffset.left,"px;width:",this.plotWidth,"px;text-align:",s.x.options.titleAlign,';" class="flotr-axis-title flotr-axis-title-x1">',s.x.options.title,"</div>"),s.x2.options.title&&s.x2.used&&t.push('<div style="position:absolute;top:0;left:',this.plotOffset.left,"px;width:",this.plotWidth,"px;text-align:",s.x2.options.titleAlign,';" class="flotr-axis-title flotr-axis-title-x2">',s.x2.options.title,"</div>"),s.y.options.title&&s.y.used&&t.push('<div style="position:absolute;top:',this.plotOffset.top+this.plotHeight/2-s.y.titleSize.height/2,"px;left:0;text-align:",s.y.options.titleAlign,';" class="flotr-axis-title flotr-axis-title-y1">',s.y.options.title,"</div>"),s.y2.options.title&&s.y2.used&&t.push('<div style="position:absolute;top:',this.plotOffset.top+this.plotHeight/2-s.y.titleSize.height/2,"px;right:0;text-align:",s.y2.options.titleAlign,';" class="flotr-axis-title flotr-axis-title-y2">',s.y2.options.title,"</div>"),t=t.join("");var u=e.create("div");e.setStyles({color:n.grid.color}),u.className="flotr-titles",e.insert(this.el,u),e.insert(u,t)}}})}();
/* ]]> */

WRFILE: bootstrap.css

/*!
 * Bootstrap v2.3.2
 *
 * Copyright 2012 Twitter, Inc
 * Licensed under the Apache License v2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Designed and built with all the love in the world @twitter by @mdo and @fat.
 */
.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0;}
.clearfix:after{clear:both;}
.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}
.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
audio:not([controls]){display:none;}
html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
a:hover,a:active{outline:0;}
sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}
sup{top:-0.5em;}
sub{bottom:-0.25em;}
img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;}
#map_canvas img,.google-maps img{max-width:none;}
button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
button,input{*overflow:visible;line-height:normal;}
button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}
label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer;}
input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield;}
input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
textarea{overflow:auto;vertical-align:top;}
@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important;} a,a:visited{text-decoration:underline;} a[href]:after{content:" (" attr(href) ")";} abbr[title]:after{content:" (" attr(title) ")";} .ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:"";} pre,blockquote{border:1px solid #999;page-break-inside:avoid;} thead{display:table-header-group;} tr,img{page-break-inside:avoid;} img{max-width:100% !important;} @page {margin:0.5cm;}p,h2,h3{orphans:3;widows:3;} h2,h3{page-break-after:avoid;}}body{margin:0;font-family:Verdana,sans-serif;font-size:12px;line-height:20px;color:#333333;background-color:#ffffff;}
a{color:#2e8aa5;text-decoration:none;}
a:hover,a:focus{color:#1d5869;text-decoration:underline;}
.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);}
.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px;}
.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;}
.row:after{clear:both;}
[class*="span"]{float:left;min-height:1px;margin-left:20px;}
.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}
.span12{width:940px;}
.span11{width:860px;}
.span10{width:780px;}
.span9{width:700px;}
.span8{width:620px;}
.span7{width:540px;}
.span6{width:460px;}
.span5{width:380px;}
.span4{width:300px;}
.span3{width:220px;}
.span2{width:140px;}
.span1{width:60px;}
.offset12{margin-left:980px;}
.offset11{margin-left:900px;}
.offset10{margin-left:820px;}
.offset9{margin-left:740px;}
.offset8{margin-left:660px;}
.offset7{margin-left:580px;}
.offset6{margin-left:500px;}
.offset5{margin-left:420px;}
.offset4{margin-left:340px;}
.offset3{margin-left:260px;}
.offset2{margin-left:180px;}
.offset1{margin-left:100px;}
.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;}
.row-fluid:after{clear:both;}
.row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;}
.row-fluid [class*="span"]:first-child{margin-left:0;}
.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%;}
.row-fluid .span12{width:100%;*width:99.94680851063829%;}
.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%;}
.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%;}
.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%;}
.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%;}
.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%;}
.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%;}
.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%;}
.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%;}
.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%;}
.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%;}
.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%;}
.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%;}
.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%;}
.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%;}
.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%;}
.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%;}
.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%;}
.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%;}
.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%;}
.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%;}
.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%;}
.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%;}
.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%;}
.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%;}
.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%;}
.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%;}
.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%;}
.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%;}
.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%;}
.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%;}
.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%;}
.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%;}
.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%;}
.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%;}
.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%;}
[class*="span"].hide,.row-fluid [class*="span"].hide{display:none;}
[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right;}
.container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";line-height:0;}
.container:after{clear:both;}
.container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0;}
.container-fluid:after{clear:both;}
p{margin:0 0 10px;}
.lead{margin-bottom:20px;font-size:18px;font-weight:200;line-height:30px;}
small{font-size:85%;}
strong{font-weight:bold;}
em{font-style:italic;}
cite{font-style:normal;}
.muted{color:#999999;}
a.muted:hover,a.muted:focus{color:#808080;}
.text-panic{color:#000000; font-weight: bold};
a.text-panic:hover,a.text-panic:focus{color:#000000;}
.text-fatal{color:#7c0208;}
a.text-fatal:hover,a.text-fatal:focus{color:#444444;}
.text-warning{color:#c09853;}
a.text-warning:hover,a.text-warning:focus{color:#a47e3c;}
.text-error{color:#b94a48;}
a.text-error:hover,a.text-error:focus{color:#953b39;}
.text-info{color:#3a87ad;}
a.text-info:hover,a.text-info:focus{color:#2d6987;}
.text-success{color:#468847;}
a.text-success:hover,a.text-success:focus{color:#356635;}
.text-left{text-align:left;}
.text-right{text-align:right;}
.text-center{text-align:center;}
h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999999;}
h1,h2,h3{line-height:40px;}
h1{font-size:33px;}
h2{font-size:27px;}
h3{font-size:21px;}
h4{font-size:15px;}
h5{font-size:12px;}
h6{font-size:10.2px;}
h1 small{font-size:21px;}
h2 small{font-size:15px;}
h3 small{font-size:12px;}
h4 small{font-size:12px;}
.page-header{padding-bottom:9px;margin:50px 0 30px;border-bottom:1px solid #eeeeee;}
ul,ol{padding:0;margin:0 0 10px 25px;}
ul ul,ul ol,ol ol,ol ul{margin-bottom:0;}
li{line-height:20px;}
ul.unstyled,ol.unstyled{margin-left:0;list-style:none;}
ul.inline,ol.inline{margin-left:0;list-style:none;}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;*zoom:1;padding-left:5px;padding-right:5px;}
dl{margin-bottom:20px;}
dt,dd{line-height:20px;}
dt{font-weight:bold;}
dd{margin-left:10px;}
.dl-horizontal{*zoom:1;}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0;}
.dl-horizontal:after{clear:both;}
.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.dl-horizontal dd{margin-left:180px;}
hr{margin:20px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;}
abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999;}
abbr.initialism{font-size:90%;text-transform:uppercase;}
blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:15px;font-weight:300;line-height:1.25;}
blockquote small{display:block;line-height:20px;color:#999999;}blockquote small:before{content:'\2014 \00A0';}
blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;}
blockquote.pull-right small:before{content:'';}
blockquote.pull-right small:after{content:'\00A0 \2014';}
q:before,q:after,blockquote:before,blockquote:after{content:"";}
address{display:block;margin-bottom:20px;font-style:normal;line-height:20px;}
code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:10px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap;}
pre{display:block;padding:9.5px;margin:0 0 10px;font-size:11px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}pre.prettyprint{margin-bottom:20px;}
pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0;}
.pre-scrollable{max-height:340px;overflow-y:scroll;}
.label,.badge{display:inline-block;padding:2px 4px;font-size:10.152px;font-weight:bold;line-height:14px;color:#ffffff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;}
.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.badge{padding-left:9px;padding-right:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;}
.label:empty,.badge:empty{display:none;}
a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer;}
.label-important,.badge-important{background-color:#b94a48;}
.label-important[href],.badge-important[href]{background-color:#953b39;}
.label-warning,.badge-warning{background-color:#ea8157;}
.label-warning[href],.badge-warning[href]{background-color:#e45f2a;}
.label-success,.badge-success{background-color:#468847;}
.label-success[href],.badge-success[href]{background-color:#356635;}
.label-info,.badge-info{background-color:#3a87ad;}
.label-info[href],.badge-info[href]{background-color:#2d6987;}
.label-inverse,.badge-inverse{background-color:#333333;}
.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a;}
.btn .label,.btn .badge{position:relative;top:-1px;}
.btn-mini .label,.btn-mini .badge{top:0;}
table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0;}
.table{width:100%;margin-bottom:20px;}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd;}
.table th{font-weight:bold;}
.table thead th{vertical-align:bottom;}
.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;}
.table tbody+tbody{border-top:2px solid #5f5555;}
.table .table{background-color:#ffffff;}
.table-condensed th,.table-condensed td{padding:4px 5px;}
.table-bordered{border:1px solid #5f5555;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #5f5555;}
.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;}
.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;}
.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;}
.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;}
.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;}
.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;}
.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;}
.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:transparent;}
.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5;}
table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0;}
.table td.span1,.table th.span1{float:none;width:44px;margin-left:0;}
.table td.span2,.table th.span2{float:none;width:124px;margin-left:0;}
.table td.span3,.table th.span3{float:none;width:204px;margin-left:0;}
.table td.span4,.table th.span4{float:none;width:284px;margin-left:0;}
.table td.span5,.table th.span5{float:none;width:364px;margin-left:0;}
.table td.span6,.table th.span6{float:none;width:444px;margin-left:0;}
.table td.span7,.table th.span7{float:none;width:524px;margin-left:0;}
.table td.span8,.table th.span8{float:none;width:604px;margin-left:0;}
.table td.span9,.table th.span9{float:none;width:684px;margin-left:0;}
.table td.span10,.table th.span10{float:none;width:764px;margin-left:0;}
.table td.span11,.table th.span11{float:none;width:844px;margin-left:0;}
.table td.span12,.table th.span12{float:none;width:924px;margin-left:0;}
.table tbody tr.success>td{background-color:#dff0d8;}
.table tbody tr.error>td{background-color:#f2dede;}
.table tbody tr.warning>td{background-color:#fcf8e3;}
.table tbody tr.info>td{background-color:#d9edf7;}
.table-hover tbody tr.success:hover>td{background-color:#d0e9c6;}
.table-hover tbody tr.error:hover>td{background-color:#ebcccc;}
.table-hover tbody tr.warning:hover>td{background-color:#faf2cc;}
.table-hover tbody tr.info:hover>td{background-color:#c4e3f3;}
form{margin:0 0 20px;}
fieldset{padding:0;margin:0;border:0;}
legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:18px;line-height:40px;color:#333333;border:0;border-bottom:1px solid #e5e5e5;}legend small{font-size:15px;color:#999999;}
label,input,button,select,textarea{font-size:12px;font-weight:normal;line-height:20px;}
input,button,select,textarea{font-family:Verdana,sans-serif;}
label{display:block;margin-bottom:5px;}
select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:12px;line-height:20px;color:#555555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle;}
input,textarea,.uneditable-input{width:206px;}
textarea{height:auto;}
textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#ffffff;border:1px solid #cccccc;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear .2s, box-shadow linear .2s;-moz-transition:border linear .2s, box-shadow linear .2s;-o-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82, 168, 236, 0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);}
input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal;}
input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto;}
select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px;}
select{width:220px;border:1px solid #cccccc;background-color:#ffffff;}
select[multiple],select[size]{height:auto;}
select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
.uneditable-input,.uneditable-textarea{color:#999999;background-color:#fcfcfc;border-color:#cccccc;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;}
.uneditable-input{overflow:hidden;white-space:nowrap;}
.uneditable-textarea{width:auto;height:auto;}
input:-moz-placeholder,textarea:-moz-placeholder{color:#999999;}
input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999999;}
input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999999;}
.radio,.checkbox{min-height:20px;padding-left:20px;}
.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px;}
.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;}
.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;}
.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;}
.input-mini{width:60px;}
.input-small{width:90px;}
.input-medium{width:150px;}
.input-large{width:210px;}
.input-xlarge{width:270px;}
.input-xxlarge{width:530px;}
input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;}
.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;}
input,textarea,.uneditable-input{margin-left:0;}
.controls-row [class*="span"]+[class*="span"]{margin-left:20px;}
input.span12,textarea.span12,.uneditable-input.span12{width:926px;}
input.span11,textarea.span11,.uneditable-input.span11{width:846px;}
input.span10,textarea.span10,.uneditable-input.span10{width:766px;}
input.span9,textarea.span9,.uneditable-input.span9{width:686px;}
input.span8,textarea.span8,.uneditable-input.span8{width:606px;}
input.span7,textarea.span7,.uneditable-input.span7{width:526px;}
input.span6,textarea.span6,.uneditable-input.span6{width:446px;}
input.span5,textarea.span5,.uneditable-input.span5{width:366px;}
input.span4,textarea.span4,.uneditable-input.span4{width:286px;}
input.span3,textarea.span3,.uneditable-input.span3{width:206px;}
input.span2,textarea.span2,.uneditable-input.span2{width:126px;}
input.span1,textarea.span1,.uneditable-input.span1{width:46px;}
.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;}
.controls-row:after{clear:both;}
.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left;}
.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px;}
input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;}
input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;}
.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;}
.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;}
.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;}
.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;}
.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;}
.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;}
.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;}
.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;}
.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;}
.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;}
.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;}
.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;}
.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;}
.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;}
.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;}
.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;}
input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;}
.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;}
.form-actions:after{clear:both;}
.help-block,.help-inline{color:#595959;}
.help-block{display:block;margin-bottom:10px;}
.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;}
.input-append,.input-prepend{display:inline-block;margin-bottom:10px;vertical-align:middle;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:12px;}
.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;}
.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:12px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;}
.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.input-append .active,.input-prepend .active{background-color:#67f5ab;border-color:#0cb75e;}
.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;}
.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;}
.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
.input-prepend.input-append .btn-group:first-child{margin-left:0;}
input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}
.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}
.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}
.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}
.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;}
.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;}
.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;}
.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;}
.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;}
.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;}
.control-group{margin-bottom:10px;}
legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;}
.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;}
.form-horizontal .control-group:after{clear:both;}
.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;}
.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;}
.form-horizontal .help-block{margin-bottom:0;}
.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px;}
.form-horizontal .form-actions{padding-left:180px;}
.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:12px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #cccccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;}
.btn:active,.btn.active{background-color:#cccccc \9;}
.btn:first-child{*margin-left:0;}
.btn:hover,.btn:focus{color:#333333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;}
.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);}
.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
.btn-large{padding:11px 19px;font-size:15px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px;}
.btn-small{padding:2px 10px;font-size:10.2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0;}
.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px;}
.btn-mini{padding:0 6px;font-size:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}
.btn-block+.btn-block{margin-top:5px;}
input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;}
.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);}
.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#2e7aa5;background-image:-moz-linear-gradient(top, #2e8aa5, #2e62a5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#2e8aa5), to(#2e62a5));background-image:-webkit-linear-gradient(top, #2e8aa5, #2e62a5);background-image:-o-linear-gradient(top, #2e8aa5, #2e62a5);background-image:linear-gradient(to bottom, #2e8aa5, #2e62a5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2e8aa5', endColorstr='#ff2e62a5', GradientType=0);border-color:#2e62a5 #2e62a5 #1d3f69;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2e62a5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#2e62a5;*background-color:#285691;}
.btn-primary:active,.btn-primary.active{background-color:#234b7d \9;}
.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#efa080;background-image:-moz-linear-gradient(top, #f3b49b, #ea8157);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f3b49b), to(#ea8157));background-image:-webkit-linear-gradient(top, #f3b49b, #ea8157);background-image:-o-linear-gradient(top, #f3b49b, #ea8157);background-image:linear-gradient(to bottom, #f3b49b, #ea8157);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff3b49b', endColorstr='#ffea8157', GradientType=0);border-color:#ea8157 #ea8157 #d9521b;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#ea8157;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#ea8157;*background-color:#e77040;}
.btn-warning:active,.btn-warning.active{background-color:#e45f2a \9;}
.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;}
.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;}
.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;}
.btn-success:active,.btn-success.active{background-color:#408140 \9;}
.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;}
.btn-info:active,.btn-info.active{background-color:#24748c \9;}
.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;}
.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;}
button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;}
button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;}
button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;}
button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;}
.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
.btn-link{border-color:transparent;cursor:pointer;color:#2e8aa5;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.btn-link:hover,.btn-link:focus{color:#1d5869;text-decoration:underline;background-color:transparent;}
.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333333;text-decoration:none;}
[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;margin-top:1px;}
.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png");}
.icon-glass{background-position:0 0;}
.icon-music{background-position:-24px 0;}
.icon-search{background-position:-48px 0;}
.icon-envelope{background-position:-72px 0;}
.icon-heart{background-position:-96px 0;}
.icon-star{background-position:-120px 0;}
.icon-star-empty{background-position:-144px 0;}
.icon-user{background-position:-168px 0;}
.icon-film{background-position:-192px 0;}
.icon-th-large{background-position:-216px 0;}
.icon-th{background-position:-240px 0;}
.icon-th-list{background-position:-264px 0;}
.icon-ok{background-position:-288px 0;}
.icon-remove{background-position:-312px 0;}
.icon-zoom-in{background-position:-336px 0;}
.icon-zoom-out{background-position:-360px 0;}
.icon-off{background-position:-384px 0;}
.icon-signal{background-position:-408px 0;}
.icon-cog{background-position:-432px 0;}
.icon-trash{background-position:-456px 0;}
.icon-home{background-position:0 -24px;}
.icon-file{background-position:-24px -24px;}
.icon-time{background-position:-48px -24px;}
.icon-road{background-position:-72px -24px;}
.icon-download-alt{background-position:-96px -24px;}
.icon-download{background-position:-120px -24px;}
.icon-upload{background-position:-144px -24px;}
.icon-inbox{background-position:-168px -24px;}
.icon-play-circle{background-position:-192px -24px;}
.icon-repeat{background-position:-216px -24px;}
.icon-refresh{background-position:-240px -24px;}
.icon-list-alt{background-position:-264px -24px;}
.icon-lock{background-position:-287px -24px;}
.icon-flag{background-position:-312px -24px;}
.icon-headphones{background-position:-336px -24px;}
.icon-volume-off{background-position:-360px -24px;}
.icon-volume-down{background-position:-384px -24px;}
.icon-volume-up{background-position:-408px -24px;}
.icon-qrcode{background-position:-432px -24px;}
.icon-barcode{background-position:-456px -24px;}
.icon-tag{background-position:0 -48px;}
.icon-tags{background-position:-25px -48px;}
.icon-book{background-position:-48px -48px;}
.icon-bookmark{background-position:-72px -48px;}
.icon-print{background-position:-96px -48px;}
.icon-camera{background-position:-120px -48px;}
.icon-font{background-position:-144px -48px;}
.icon-bold{background-position:-167px -48px;}
.icon-italic{background-position:-192px -48px;}
.icon-text-height{background-position:-216px -48px;}
.icon-text-width{background-position:-240px -48px;}
.icon-align-left{background-position:-264px -48px;}
.icon-align-center{background-position:-288px -48px;}
.icon-align-right{background-position:-312px -48px;}
.icon-align-justify{background-position:-336px -48px;}
.icon-list{background-position:-360px -48px;}
.icon-indent-left{background-position:-384px -48px;}
.icon-indent-right{background-position:-408px -48px;}
.icon-facetime-video{background-position:-432px -48px;}
.icon-picture{background-position:-456px -48px;}
.icon-pencil{background-position:0 -72px;}
.icon-map-marker{background-position:-24px -72px;}
.icon-adjust{background-position:-48px -72px;}
.icon-tint{background-position:-72px -72px;}
.icon-edit{background-position:-96px -72px;}
.icon-share{background-position:-120px -72px;}
.icon-check{background-position:-144px -72px;}
.icon-move{background-position:-168px -72px;}
.icon-step-backward{background-position:-192px -72px;}
.icon-fast-backward{background-position:-216px -72px;}
.icon-backward{background-position:-240px -72px;}
.icon-play{background-position:-264px -72px;}
.icon-pause{background-position:-288px -72px;}
.icon-stop{background-position:-312px -72px;}
.icon-forward{background-position:-336px -72px;}
.icon-fast-forward{background-position:-360px -72px;}
.icon-step-forward{background-position:-384px -72px;}
.icon-eject{background-position:-408px -72px;}
.icon-chevron-left{background-position:-432px -72px;}
.icon-chevron-right{background-position:-456px -72px;}
.icon-plus-sign{background-position:0 -96px;}
.icon-minus-sign{background-position:-24px -96px;}
.icon-remove-sign{background-position:-48px -96px;}
.icon-ok-sign{background-position:-72px -96px;}
.icon-question-sign{background-position:-96px -96px;}
.icon-info-sign{background-position:-120px -96px;}
.icon-screenshot{background-position:-144px -96px;}
.icon-remove-circle{background-position:-168px -96px;}
.icon-ok-circle{background-position:-192px -96px;}
.icon-ban-circle{background-position:-216px -96px;}
.icon-arrow-left{background-position:-240px -96px;}
.icon-arrow-right{background-position:-264px -96px;}
.icon-arrow-up{background-position:-289px -96px;}
.icon-arrow-down{background-position:-312px -96px;}
.icon-share-alt{background-position:-336px -96px;}
.icon-resize-full{background-position:-360px -96px;}
.icon-resize-small{background-position:-384px -96px;}
.icon-plus{background-position:-408px -96px;}
.icon-minus{background-position:-433px -96px;}
.icon-asterisk{background-position:-456px -96px;}
.icon-exclamation-sign{background-position:0 -120px;}
.icon-gift{background-position:-24px -120px;}
.icon-leaf{background-position:-48px -120px;}
.icon-fire{background-position:-72px -120px;}
.icon-eye-open{background-position:-96px -120px;}
.icon-eye-close{background-position:-120px -120px;}
.icon-warning-sign{background-position:-144px -120px;}
.icon-plane{background-position:-168px -120px;}
.icon-calendar{background-position:-192px -120px;}
.icon-random{background-position:-216px -120px;width:16px;}
.icon-comment{background-position:-240px -120px;}
.icon-magnet{background-position:-264px -120px;}
.icon-chevron-up{background-position:-288px -120px;}
.icon-chevron-down{background-position:-313px -119px;}
.icon-retweet{background-position:-336px -120px;}
.icon-shopping-cart{background-position:-360px -120px;}
.icon-folder-close{background-position:-384px -120px;width:16px;}
.icon-folder-open{background-position:-408px -120px;width:16px;}
.icon-resize-vertical{background-position:-432px -119px;}
.icon-resize-horizontal{background-position:-456px -118px;}
.icon-hdd{background-position:0 -144px;}
.icon-bullhorn{background-position:-24px -144px;}
.icon-bell{background-position:-48px -144px;}
.icon-certificate{background-position:-72px -144px;}
.icon-thumbs-up{background-position:-96px -144px;}
.icon-thumbs-down{background-position:-120px -144px;}
.icon-hand-right{background-position:-144px -144px;}
.icon-hand-left{background-position:-168px -144px;}
.icon-hand-up{background-position:-192px -144px;}
.icon-hand-down{background-position:-216px -144px;}
.icon-circle-arrow-right{background-position:-240px -144px;}
.icon-circle-arrow-left{background-position:-264px -144px;}
.icon-circle-arrow-up{background-position:-288px -144px;}
.icon-circle-arrow-down{background-position:-312px -144px;}
.icon-globe{background-position:-336px -144px;}
.icon-wrench{background-position:-360px -144px;}
.icon-tasks{background-position:-384px -144px;}
.icon-filter{background-position:-408px -144px;}
.icon-briefcase{background-position:-432px -144px;}
.icon-fullscreen{background-position:-456px -144px;}
.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;z-index: 90; }.btn-group:first-child{*margin-left:0;}
.btn-group+.btn-group{margin-left:5px;}
.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px;}
.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.btn-group>.btn+.btn{margin-left:-1px;}
.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:12px;}
.btn-group>.btn-mini{font-size:9px;}
.btn-group>.btn-small{font-size:10.2px;}
.btn-group>.btn-large{font-size:15px;}
.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}
.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}
.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;}
.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;}
.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px;}
.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;}
.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;}
.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;}
.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);}
.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;}
.btn-group.open .btn-primary.dropdown-toggle{background-color:#2e62a5;}
.btn-group.open .btn-warning.dropdown-toggle{background-color:#ea8157;}
.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;}
.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;}
.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;}
.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;}
.btn .caret{margin-top:8px;margin-left:0;}
.btn-large .caret{margin-top:6px;}
.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px;}
.btn-mini .caret,.btn-small .caret{margin-top:8px;}
.dropup .btn-large .caret{border-bottom-width:5px;}
.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}
.btn-group-vertical{display:inline-block;*display:inline;*zoom:1;}
.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px;}
.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}
.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}
.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;}
.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;}
.nav{margin-left:0;margin-bottom:20px;list-style:none;}
.nav>li>a{display:block;}
.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eeeeee;}
.nav>li>a>img{max-width:none;}
.nav>.pull-right{float:right;}
.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;}
.nav li+.nav-header{margin-top:9px;}
.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;}
.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}
.nav-list>li>a{padding:3px 15px;}
.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#2e8aa5;}
.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px;}
.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;}
.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0;}
.nav-tabs:after,.nav-pills:after{clear:both;}
.nav-tabs>li,.nav-pills>li{float:left;}
.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;}
.nav-tabs{border-bottom:1px solid #ddd;}
.nav-tabs>li{margin-bottom:-1px;}
.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eeeeee #eeeeee #dddddd;}
.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;}
.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#ffffff;background-color:#2e8aa5;}
.nav-stacked>li{float:none;}
.nav-stacked>li>a{margin-right:0;}
.nav-tabs.nav-stacked{border-bottom:0;}
.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;}
.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{border-color:#ddd;z-index:2;}
.nav-pills.nav-stacked>li>a{margin-bottom:3px;}
.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;}
.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;}
.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
.nav .dropdown-toggle .caret{border-top-color:#2e8aa5;border-bottom-color:#2e8aa5;margin-top:6px;}
.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#1d5869;border-bottom-color:#1d5869;}
.nav-tabs .dropdown-toggle .caret{margin-top:8px;}
.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;}
.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;}
.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer;}
.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#ffffff;background-color:#999999;border-color:#999999;}
.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);}
.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999999;}
.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0;}
.tabbable:after{clear:both;}
.tab-content{overflow:auto;}
.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;}
.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;}
.tab-content>.active,.pill-content>.active{display:block;}
.tabs-below>.nav-tabs{border-top:1px solid #ddd;}
.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;}
.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-bottom-color:transparent;border-top-color:#ddd;}
.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd;}
.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;}
.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;}
.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;}
.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}
.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eeeeee #dddddd #eeeeee #eeeeee;}
.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;}
.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;}
.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}
.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eeeeee #eeeeee #eeeeee #dddddd;}
.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;}
.nav>.disabled>a{color:#999999;}
.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;background-color:transparent;cursor:default;}
.navbar{overflow:visible;margin-bottom:20px;*position:relative;*z-index:2;}
.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;}
.navbar-inner:after{clear:both;}
.navbar .container{width:auto;}
.nav-collapse.collapse{height:auto;overflow:visible;}
.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:22px;font-weight:200;color:#000000;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none;}
.navbar-text{margin-bottom:0;line-height:40px;color:#777777;}
.navbar-link{color:#777777;}.navbar-link:hover,.navbar-link:focus{color:#333333;}
.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;}
.navbar .btn,.navbar .btn-group{margin-top:5px;}
.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0;}
.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;}
.navbar-form:after{clear:both;}
.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;}
.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0;}
.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;}
.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;}
.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:Verdana,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
.navbar-static-top{position:static;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;}
.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px;}
.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0;}
.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}
.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}
.navbar-fixed-top{top:0;}
.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1);}
.navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1);}
.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;}
.navbar .nav.pull-right{float:right;margin-right:0;}
.navbar .nav>li{float:left;}
.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;}
.navbar .nav .dropdown-toggle .caret{margin-top:8px;}
.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;}
.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);}
.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;}
.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \9;}
.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);}
.btn-navbar .icon-bar+.icon-bar{margin-top:3px;}
.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;}
.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;}
.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;}
.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;}
.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333333;border-bottom-color:#333333;}
.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;}
.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;}
.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;}
.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;}
.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;}
.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;}
.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#ffffff;}
.navbar-inverse .brand{color:#999999;}
.navbar-inverse .navbar-text{color:#999999;}
.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;}
.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;}
.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#ffffff;}
.navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;}
.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;}
.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}
.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;}
.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}
.navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;}
.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;}
.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;}
.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;}
.navbar-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;}
.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#12576B \9;}
.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb>li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;}.breadcrumb>li>.divider{padding:0 5px;color:#ccc;}
.breadcrumb>.active{color:#999999;}
.pagination{margin:20px 0;}
.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);}
.pagination ul>li{display:inline;}
.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;}
.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;}
.pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;}
.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999999;background-color:transparent;cursor:default;}
.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}
.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}
.pagination-centered{text-align:center;}
.pagination-right{text-align:right;}
.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:15px;}
.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}
.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}
.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px;}
.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px;}
.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:10.2px;}
.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:9px;}
.pager{margin:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";line-height:0;}
.pager:after{clear:both;}
.pager li{display:inline;}
.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}
.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5;}
.pager .next>a,.pager .next>span{float:right;}
.pager .previous>a,.pager .previous>span{float:left;}
.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999999;background-color:#fff;cursor:default;}
.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;}
.thumbnails:after{clear:both;}
.row-fluid .thumbnails{margin-left:0;}
.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;}
.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;}
a.thumbnail:hover,a.thumbnail:focus{border-color:#2e8aa5;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);}
.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;}
.thumbnail .caption{padding:9px;color:#555555;}
.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.alert,.alert h4{color:#c09853;}
.alert h4{margin:0;}
.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;}
.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;}
.alert-success h4{color:#468847;}
.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;}
.alert-danger h4,.alert-error h4{color:#b94a48;}
.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;}
.alert-info h4{color:#3a87ad;}
.alert-block{padding-top:14px;padding-bottom:14px;}
.alert-block>p,.alert-block>ul{margin-bottom:0;}
.alert-block p+p{margin-top:5px;}
@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.progress .bar{width:0%;height:100%;color:#ffffff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;}
.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);}
.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;}
.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;}
.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);}
.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);}
.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);}
.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
.progress-warning .bar,.progress .bar-warning{background-color:#efa080;background-image:-moz-linear-gradient(top, #f3b49b, #ea8157);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f3b49b), to(#ea8157));background-image:-webkit-linear-gradient(top, #f3b49b, #ea8157);background-image:-o-linear-gradient(top, #f3b49b, #ea8157);background-image:linear-gradient(to bottom, #f3b49b, #ea8157);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff3b49b', endColorstr='#ffea8157', GradientType=0);}
.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#f3b49b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}
.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;}
.hero-unit li{line-height:30px;}
.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;}
.media,.media .media{margin-top:15px;}
.media:first-child{margin-top:0;}
.media-object{display:block;}
.media-heading{margin:0 0 5px;}
.media>.pull-left{margin-right:10px;}
.media>.pull-right{margin-left:10px;}
.media-list{margin-left:0;list-style:none;}
.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);}
.tooltip.top{margin-top:-3px;padding:5px 0;}
.tooltip.right{margin-left:3px;padding:0 5px;}
.tooltip.bottom{margin-top:3px;padding:5px 0;}
.tooltip.left{margin-left:-3px;padding:0 5px;}
.tooltip-inner{max-width:200px;padding:8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;}
.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;}
.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;}
.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;}
.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;}
.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:500px;padding:1px;text-align:left;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);white-space:normal;}.popover.top{margin-top:-10px;}
.popover.right{margin-left:10px;}
.popover.bottom{margin-top:10px;}
.popover.left{margin-left:-10px;}
.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;}.popover-title:empty{display:none;}
.popover-content{padding:9px 14px;}
.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid;}
.popover .arrow{border-width:11px;}
.popover .arrow:after{border-width:10px;content:"";}
.popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0, 0, 0, 0.25);bottom:-11px;}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff;}
.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0, 0, 0, 0.25);}.popover.right .arrow:after{left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff;}
.popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0, 0, 0, 0.25);top:-11px;}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff;}
.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0, 0, 0, 0.25);}.popover.left .arrow:after{right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px;}
.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;}
.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);}
.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;}
.modal.fade.in{top:10%;}
.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;}
.modal-header h3{margin:0;line-height:30px;}
.modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px;}
.modal-form{margin-bottom:0;}
.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0;}
.modal-footer:after{clear:both;}
.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;}
.modal-footer .btn-group .btn+.btn{margin-left:-1px;}
.modal-footer .btn-block+.btn-block{margin-left:0;}
.dropup,.dropdown{position:relative;}
.dropdown-toggle{*margin-bottom:-3px;}
.dropdown-toggle:active,.open .dropdown-toggle{outline:0;}
.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";}
.dropdown .caret{margin-top:8px;margin-left:2px;}
.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;}
.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;}
.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#5f5555;white-space:nowrap;}
.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{text-decoration:none;color:#ffffff;background-color:#5a5050;background-image:-moz-linear-gradient(top, #5f5555, #524949);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5f5555), to(#524949));background-image:-webkit-linear-gradient(top, #5f5555, #524949);background-image:-o-linear-gradient(top, #5f5555, #524949);background-image:linear-gradient(to bottom, #5f5555, #524949);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5f5555', endColorstr='#ff524949', GradientType=0);}
.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#2c839d;background-image:-moz-linear-gradient(top, #2e8aa5, #287991);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#2e8aa5), to(#287991));background-image:-webkit-linear-gradient(top, #2e8aa5, #287991);background-image:-o-linear-gradient(top, #2e8aa5, #287991);background-image:linear-gradient(to bottom, #2e8aa5, #287991);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2e8aa5', endColorstr='#ff287991', GradientType=0);}
.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999999;}
.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:default;}
.open{*z-index:1000;}.open>.dropdown-menu{display:block;}
.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990;}
.pull-right>.dropdown-menu{right:0;left:auto;}
.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"";}
.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;}
.dropdown-submenu{position:relative;}
.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}
.dropdown-submenu:hover>.dropdown-menu{display:block;}
.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0;}
.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;}
.dropdown-submenu:hover>a:after{border-left-color:#ffffff;}
.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;}
.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.accordion{margin-bottom:20px;}
.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
.accordion-heading{border-bottom:0;}
.accordion-heading .accordion-toggle{display:block;padding:8px 15px;}
.accordion-toggle{cursor:pointer;}
.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;}
.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}
.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);}
button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;}
.pull-right{float:right;}
.pull-left{float:left;}
.hide{display:none;}
.show{display:block;}
.invisible{visibility:hidden;}
.affix{position:fixed;}
.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;}
.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;}
@-ms-viewport{width:device-width;}.hidden{display:none;visibility:hidden;}
.visible-phone{display:none !important;}
.visible-tablet{display:none !important;}
.hidden-desktop{display:none !important;}
.visible-desktop{display:inherit !important;}
@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}.visible-print{display:none !important;}
@media print{.visible-print{display:inherit !important;} .hidden-print{display:none !important;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .row-fluid [class*="offset"]:first-child{margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;} .controls-row [class*="span"]+[class*="span"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade{top:-100px;} .modal.fade.in{top:20px;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} .media-object{margin-right:0;margin-left:0;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12,textarea.span12,.uneditable-input.span12{width:710px;} input.span11,textarea.span11,.uneditable-input.span11{width:648px;} input.span10,textarea.span10,.uneditable-input.span10{width:586px;} input.span9,textarea.span9,.uneditable-input.span9{width:524px;} input.span8,textarea.span8,.uneditable-input.span8{width:462px;} input.span7,textarea.span7,.uneditable-input.span7{width:400px;} input.span6,textarea.span6,.uneditable-input.span6{width:338px;} input.span5,textarea.span5,.uneditable-input.span5{width:276px;} input.span4,textarea.span4,.uneditable-input.span4{width:214px;} input.span3,textarea.span3,.uneditable-input.span3{width:152px;} input.span2,textarea.span2,.uneditable-input.span2{width:90px;} input.span1,textarea.span1,.uneditable-input.span1{width:28px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12,textarea.span12,.uneditable-input.span12{width:1156px;} input.span11,textarea.span11,.uneditable-input.span11{width:1056px;} input.span10,textarea.span10,.uneditable-input.span10{width:956px;} input.span9,textarea.span9,.uneditable-input.span9{width:856px;} input.span8,textarea.span8,.uneditable-input.span8{width:756px;} input.span7,textarea.span7,.uneditable-input.span7{width:656px;} input.span6,textarea.span6,.uneditable-input.span6{width:556px;} input.span5,textarea.span5,.uneditable-input.span5{width:456px;} input.span4,textarea.span4,.uneditable-input.span4{width:356px;} input.span3,textarea.span3,.uneditable-input.span3{width:256px;} input.span2,textarea.span2,.uneditable-input.span2{width:156px;} input.span1,textarea.span1,.uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999999;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .open>.dropdown-menu{display:block;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}}

/*!
 * Bootstrap Responsive v2.3.2
 *
 * Copyright 2012 Twitter, Inc
 * Licensed under the Apache License v2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Designed and built with all the love in the world @twitter by @mdo and @fat.
 */
.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:979px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}

WRFILE: fontawesome.css

/*!
 *  Font Awesome 3.1.0
 *  the iconic font designed for Bootstrap
 *  -------------------------------------------------------
 *  The full suite of pictographic icons, examples, and documentation
 *  can be found at: http://fontawesome.io
 *
 *  License
 *  -------------------------------------------------------
 *  - The Font Awesome font is licensed under the SIL Open Font License v1.1 -
 *    http://scripts.sil.org/OFL
 *  - Font Awesome CSS, LESS, and SASS files are licensed under the MIT License -
 *    http://opensource.org/licenses/mit-license.html
 *  - Font Awesome documentation licensed under CC BY 3.0 License -
 *    http://creativecommons.org/licenses/by/3.0/
 *  - Attribution is no longer required in Font Awesome 3.0, but much appreciated:
 *    "Font Awesome by Dave Gandy - http://fontawesome.io"

 *  Contact
 *  -------------------------------------------------------
 *  Email: dave@fontawesome.io
 *  Twitter: http://twitter.com/fortaweso_me
 *  Work: Lead Product Designer @ http://kyruus.com
 */

    @font-face{font-family:'FontAwesome';
	src:url('font/fontawesome-webfont.eot?v=3.1.0');
     src:url("data:font/opentype;charset=utf-8;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAsAAwAKAAIDgABwAcAAAAaAAHYFgAAABAAAXwcAAAAHAAAABwAAAAcAAAAHAAAABYAAAAcAAAAHAABdBgAAAAaAAAAHAAAABwAAAAaAAAAGgAAABYAAAAeAAAAGgAAABwAAAAcAAAAHAAB5BYAAbgaAAAAGgAAABgAAAAcAAAAGAAAABYAAAAaAABoFAAAABgAAAAeAADIGgAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABwAAAASAAAAHAABABoAAAAMAAAAEgAAABoAAAAWAAAAHAAAABgAAAAeAAAAGgP//BQAAAAaAAAAHgAAABoAAAAWAAAAEAAAABwAAAAYAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAeAAAAGAAAABAAAAAYAAAAEAAAABwAAAAaAAAAGgAAABwAAAAQAAAAHAAAABoAAegWAAAAGAAAABgAAAAaAAAAHAAAABAAAAAYC//8EgAA1BIAAdQYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAABABgAAAAaAADUGgAA1BwAAAAYAAAAGAAANBgAAAAYAAAAHAAAABYAAAAcAAAAHAAAABwAAAAWAAAAGgAAABwAAAAcAAAAGAAAABoAANQaAADUHgAAABoAAAAaAAAAHgAAAAwAAQAcAAAAHgAAABgAAAAYAAAAHAAAABwAAAAeAAAAHAAAABgAAAAYAAAADgAAABwAAAAaAAAAGAAAABIAAAAcAAAAGAAAABoAAAAYAAAAGgAAABgAAAAWAAAAFgAAABQAAAAYAAAAGgAAsAwAAAAYAAAAGgAAAB4AAAAWAAAAGAAAABwAAAAaAAAAGAP//BwAAAAcAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABoAAFQcAAAAFgAAABwAAAAYAAAAHAAAABwAAAAcAAAAHgAAABoAAEAeAAAAGgABmBwAAAAcAAAAFgAAEBgAAAAYAAAAGAAAABwAAAAcAAA8HAAAABgAAAAaAAAAGgAAbBwAAQAYAAAAGAAAABgAAAAaAAAAHgAAABAAAAAQAAAACgABAAoAAAAaAAAAEAAAABAAAAAQAAAAHAAAABgAAAAYAAAAHAAAoBwAAAAcAAAAHAAAAA4AAAAcAAAAGgAAABwAAAAQAAAAHAAAAB4AAAAeAAAAFgAAABYAAAAcAAAAGgAAAB4AAAAWAAAAFAAAABYAAAAWAAAAHgABABwAAAAeAAAAGgABABgAAAAYAAAAEAAAtBAAADQSAAE0EgABNAoAALQKAAA0EgABNBIAATQeAAAAHgAAABIAAAAMAAAAGAAAABoAAAAaAAAAGIAAABgAAAAcAAAAGgAAABoAAAAeAAAAEgAAABIAAAAYAAAAGAAAABgAAAAeAAAAHgAAABwAAQAcAAEAGgAANB4AALQcAAAAGgAAABYAAAAaAAAAEAAAABoAAAAKAAAACgABiBgAABQYAAAUHgAAABoAAAASAAAAFgAANBQAAAAaAAAAFgAAABoAAIAcAAAAGAAAABgAAAAYAAAAGAAAABYAAAAcAAAwHAAAABIAAAAYAAAAFgAAAAYAAAAYAAAAGAAAABwAANQYAAAAFgAAABAAAAAQAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAQAAAAEAAAABAAALQOCAAAEAwAABoAAHAcAAAAFAAA4BQAAAAUAAAAGgAAfBoAAHwcAAB8HAAAfBgAAHwYAAB8GgAAABoAAAAYAAAAGAAAbBYAAAAYAAAAHAAAABwAAQAWAAAAGAAAABgAAAAYAAAAFgAAABgAAAAQAAE4GAAAAAwAAAAMAAAAHAABABwAAAAWAAAAGgAAABYAAAAYAAAYGAAAABgAAAAaA//8GAAAABQAAAAQAAAAGAAAABwAAKgYAAAAHAABABoAAIAeA//8HAAAAB4AAAAcAAAAAAAAAAAMAAAAAAAD/egBaAAAAAAAAAAAAAAAAAAAAAAAAAAABAAQCAAEBAQxGb250QXdlc29tZQABAQFE+BAA+YUB+YYC+YYD+BkE+0cMA+UMBIr7lRwHgRwGAQUeoABVgDb/i4seoABVgDb/i4sMBxwghQ8cIKcRrh0AANUuEgFsAgABAAYACwARABkAHgAiACwAMAA0ADwAPgBFAEcATQBUAFwAXwBlAGgAbQBxAHkAfQCBAI0AlQCbAKAAqwCxALgAwADEAMgA0gDcAOcA8AD2AP0BAAEEAQgBEAEVARsBHwEjASkBNAE+AUgBVAFfAWwBcAF7AYcBlQGcAaIBrAGyAbYBugG/AcQByAHVAeIB6gHuAfMB9wH+AgoCFgIbAicCNAI9AkcCUgJZAmYCbwJ5AoYCjwKZAqMCrgK2AsACyQLUAuAC8AL0AvgC/AMEAw0DGQMeAyYDLAMzAzkDQwNPA1YDYwNvA3oDiQOaA6MDrwO8A8gDywPPA9cD5APzA/wEBwQOBBsEIgQvBDUEOwRGBFAEVQRaBGUEcwR9BIQEjASSBJgEowSmBKkEsQS1BMAEygTTBNoE4wT0BQYFFQUmBSsFMQU2BTwFRQVPBVcFXwVoBW0FcQV2BXwFfwWDBY0FkQWbBaIFpAWmBbMFvAXBBcYFywXUBeIF8gX9BgIGDAYUBh4GKQYwBjQGPQZEBlAGWAZcBmEGagZ1BoEGhQaMBpQGmQajBqsGuQbFBswG1wbfBucG7QbxBv4HBgcOBxcHHQcoBywHMgc2B0cHWQdoB3kHgweOB5YHoAenB60Hswe/B8sH1QfgB+cH7QfyB/wIDAgbCCUIMQg2CDsIPghFCE0IVQhjCGsIbwh4CIcIlQiZCKIIqAisCLcIwgjLCM8I2wjlCPMI+QkHCRgJHgkkCTUJRwlWCWcJbAlwCXYJgAmICZsJrAmwCbkJvwnNCdgJ4AnqCfQJ/QoBCgsKEgoaCiYKKgotCjAKMwo2CjkKPAo/CkIKRgpPCl8KYwp1CosKmAqpCq0KsQq9CsQKyArRCt0K5ArxCvoLAAsDCwcLFQsbCyYLNQtCC1ELYQtmC20LdAt5C4ALhQuPC5ULmwufC6ULqAusC7MLtgu4C70LwwvHC8sLzwvoC/NnbGFzc211c2ljc2VhcmNoZW52ZWxvcGVoZWFydHN0YXJzdGFyX2VtcHR5dXNlcmZpbG10aF9sYXJnZXRodGhfbGlzdG9rcmVtb3Zlem9vbV9pbnpvb21fb3V0b2Zmc2lnbmFsY29ndHJhc2hob21lZmlsZV9hbHR0aW1lcm9hZGRvd25sb2FkX2FsdGRvd25sb2FkdXBsb2FkaW5ib3hwbGF5X2NpcmNsZXJlcGVhdHJlZnJlc2hsaXN0X2FsdGxvY2tmbGFnaGVhZHBob25lc3ZvbHVtZV9vZmZ2b2x1bWVfZG93bnZvbHVtZV91cHFyY29kZWJhcmNvZGV0YWd0YWdzYm9va2Jvb2ttYXJrcHJpbnRjYW1lcmFmb250Ym9sZGl0YWxpY3RleHRfaGVpZ2h0dGV4dF93aWR0aGFsaWduX2xlZnRhbGlnbl9jZW50ZXJhbGlnbl9yaWdodGFsaWduX2p1c3RpZnlsaXN0aW5kZW50X2xlZnRpbmRlbnRfcmlnaHRmYWNldGltZV92aWRlb3BpY3R1cmVwZW5jaWxtYXBfbWFya2VyYWRqdXN0dGludGVkaXRzaGFyZWNoZWNrbW92ZXN0ZXBfYmFja3dhcmRmYXN0X2JhY2t3YXJkYmFja3dhcmRwbGF5cGF1c2VzdG9wZm9yd2FyZGZhc3RfZm9yd2FyZHN0ZXBfZm9yd2FyZGVqZWN0Y2hldnJvbl9sZWZ0Y2hldnJvbl9yaWdodHBsdXNfc2lnbm1pbnVzX3NpZ25yZW1vdmVfc2lnbm9rX3NpZ25xdWVzdGlvbl9zaWduaW5mb19zaWduc2NyZWVuc2hvdHJlbW92ZV9jaXJjbGVva19jaXJjbGViYW5fY2lyY2xlYXJyb3dfbGVmdGFycm93X3JpZ2h0YXJyb3dfdXBhcnJvd19kb3duc2hhcmVfYWx0cmVzaXplX2Z1bGxyZXNpemVfc21hbGxleGNsYW1hdGlvbl9zaWduZ2lmdGxlYWZmaXJlZXllX29wZW5leWVfY2xvc2V3YXJuaW5nX3NpZ25wbGFuZWNhbGVuZGFycmFuZG9tY29tbWVudG1hZ25ldGNoZXZyb25fdXBjaGV2cm9uX2Rvd25yZXR3ZWV0c2hvcHBpbmdfY2FydGZvbGRlcl9jbG9zZWZvbGRlcl9vcGVucmVzaXplX3ZlcnRpY2FscmVzaXplX2hvcml6b250YWxiYXJfY2hhcnR0d2l0dGVyX3NpZ25mYWNlYm9va19zaWduY2FtZXJhX3JldHJva2V5Y29nc2NvbW1lbnRzdGh1bWJzX3VwX2FsdHRodW1ic19kb3duX2FsdHN0YXJfaGFsZmhlYXJ0X2VtcHR5c2lnbm91dGxpbmtlZGluX3NpZ25wdXNocGluZXh0ZXJuYWxfbGlua3NpZ25pbnRyb3BoeWdpdGh1Yl9zaWdudXBsb2FkX2FsdGxlbW9ucGhvbmVjaGVja19lbXB0eWJvb2ttYXJrX2VtcHR5cGhvbmVfc2lnbnR3aXR0ZXJmYWNlYm9va2dpdGh1YnVubG9ja2NyZWRpdF9jYXJkcnNzaGRkYnVsbGhvcm5iZWxsY2VydGlmaWNhdGVoYW5kX3JpZ2h0aGFuZF9sZWZ0aGFuZF91cGhhbmRfZG93bmNpcmNsZV9hcnJvd19sZWZ0Y2lyY2xlX2Fycm93X3JpZ2h0Y2lyY2xlX2Fycm93X3VwY2lyY2xlX2Fycm93X2Rvd25nbG9iZXdyZW5jaHRhc2tzZmlsdGVyYnJpZWZjYXNlZnVsbHNjcmVlbm5vdGVxdWFsaW5maW5pdHlsZXNzZXF1YWxncm91cGxpbmtjbG91ZGJlYWtlcmN1dGNvcHlwYXBlcl9jbGlwc2F2ZXNpZ25fYmxhbmtyZW9yZGVydWxvbHN0cmlrZXRocm91Z2h1bmRlcmxpbmV0YWJsZW1hZ2ljdHJ1Y2twaW50ZXJlc3RwaW50ZXJlc3Rfc2lnbmdvb2dsZV9wbHVzX3NpZ25nb29nbGVfcGx1c21vbmV5Y2FyZXRfZG93bmNhcmV0X3VwY2FyZXRfbGVmdGNhcmV0X3JpZ2h0Y29sdW1uc3NvcnRzb3J0X2Rvd25zb3J0X3VwZW52ZWxvcGVfYWx0bGlua2VkaW51bmRvbGVnYWxkYXNoYm9hcmRjb21tZW50X2FsdGNvbW1lbnRzX2FsdGJvbHRzaXRlbWFwdW1icmVsbGFwYXN0ZWxpZ2h0X2J1bGJleGNoYW5nZWNsb3VkX2Rvd25sb2FkY2xvdWRfdXBsb2FkdXNlcl9tZHN0ZXRob3Njb3Blc3VpdGNhc2ViZWxsX2FsdGNvZmZlZWZvb2RmaWxlX3RleHRfYWx0YnVpbGRpbmdob3NwaXRhbGFtYnVsYW5jZW1lZGtpdGZpZ2h0ZXJfamV0YmVlcmhfc2lnbmYwZmVkb3VibGVfYW5nbGVfbGVmdGRvdWJsZV9hbmdsZV9yaWdodGRvdWJsZV9hbmdsZV91cGRvdWJsZV9hbmdsZV9kb3duYW5nbGVfbGVmdGFuZ2xlX3JpZ2h0YW5nbGVfdXBhbmdsZV9kb3duZGVza3RvcGxhcHRvcHRhYmxldG1vYmlsZV9waG9uZWNpcmNsZV9ibGFua3F1b3RlX2xlZnRxdW90ZV9yaWdodHNwaW5uZXJjaXJjbGVyZXBseWdpdGh1Yl9hbHRmb2xkZXJfY2xvc2VfYWx0Zm9sZGVyX29wZW5fYWx0ZXhwYW5kX2FsdGNvbGxhcHNlX2FsdHNtaWxlZnJvd25tZWhnYW1lcGFka2V5Ym9hcmRmbGFnX2FsdGZsYWdfY2hlY2tlcmVkdGVybWluYWxjb2RlcmVwbHlfYWxsc3Rhcl9oYWxmX2VtcHR5bG9jYXRpb25fYXJyb3djcm9wY29kZV9mb3JrdW5saW5rXzI3OWV4Y2xhbWF0aW9uc3VwZXJzY3JpcHRzdWJzY3JpcHRfMjgzcHV6emxlX3BpZWNlbWljcm9waG9uZW1pY3JvcGhvbmVfb2Zmc2hpZWxkY2FsZW5kYXJfZW1wdHlmaXJlX2V4dGluZ3Vpc2hlcnJvY2tldG1heGNkbmNoZXZyb25fc2lnbl9sZWZ0Y2hldnJvbl9zaWduX3JpZ2h0Y2hldnJvbl9zaWduX3VwY2hldnJvbl9zaWduX2Rvd25odG1sNWNzczNhbmNob3J1bmxvY2tfYWx0YnVsbHNleWVlbGxpcHNpc19ob3Jpem9udGFsZWxsaXBzaXNfdmVydGljYWxfMzAzcGxheV9zaWdudGlja2V0bWludXNfc2lnbl9hbHRjaGVja19taW51c2xldmVsX3VwbGV2ZWxfZG93bmNoZWNrX3NpZ25lZGl0X3NpZ25fMzEyc2hhcmVfc2lnbmNvbXBhc3Njb2xsYXBzZWNvbGxhcHNlX3RvcF8zMTdldXJnYnB1c2RpbnJqcHljbnlrcndidGNmaWxlZmlsZV90ZXh0c29ydF9ieV9hbHBoYWJldF8zMjlzb3J0X2J5X2F0dHJpYnV0ZXNzb3J0X2J5X2F0dHJpYnV0ZXNfYWx0c29ydF9ieV9vcmRlcnNvcnRfYnlfb3JkZXJfYWx0XzMzNF8zMzV5b3V0dWJlX3NpZ255b3V0dWJleGluZ3hpbmdfc2lnbnlvdXR1YmVfcGxheWRyb3Bib3hzdGFja2V4Y2hhbmdlaW5zdGFncmFtZmxpY2tyYWRuZjE3MWJpdGJ1Y2tldF9zaWdudHVtYmxydHVtYmxyX3NpZ25sb25nX2Fycm93X2Rvd25sb25nX2Fycm93X3VwbG9uZ19hcnJvd19sZWZ0bG9uZ19hcnJvd19yaWdodGFwcGxld2luZG93c2FuZHJvaWRsaW51eGRyaWJibGVza3lwZWZvdXJzcXVhcmV0cmVsbG9mZW1hbGVtYWxlZ2l0dGlwc3VuXzM2NmFyY2hpdmVidWd2a3dlaWJvcmVucmVuXzM3Ml8zNzNf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") format("truetype");


	font-weight:normal;font-style:normal}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em}[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none}.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em}a [class^="icon-"],a [class*=" icon-"],a [class^="icon-"]:before,a [class*=" icon-"]:before{display:inline}[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.2857142857142858em;text-align:center}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.5714285714285714em}ul.icons-ul{list-style-type:none;text-indent:-0.7142857142857143em;margin-left:2.142857142857143em}ul.icons-ul>li .icon-li{width:.7142857142857143em;display:inline-block;text-align:center}[class^="icon-"].hide,[class*=" icon-"].hide{display:none}.icon-muted{color:#eee}.icon-light{color:#fff}.icon-dark{color:#333}.icon-border{border:solid 1px #eee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.icon-2x{font-size:2em}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.icon-3x{font-size:3em}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.icon-4x{font-size:4em}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.icon-5x{font-size:5em}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.pull-right{float:right}.pull-left{float:left}[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em}[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em}[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0 0;background-repeat:repeat;margin-top:0}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none}.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block}.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em}.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em}.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em}.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em}.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em}.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em}.icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em}.icon-stack .icon-stack-base{font-size:2em;*line-height:1em}.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1)}.icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2)}.icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3)}.icon-flip-horizontal:before{-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);-ms-transform:scale(-1,1);-o-transform:scale(-1,1);transform:scale(-1,1)}.icon-flip-vertical:before{-webkit-transform:scale(1,-1);-moz-transform:scale(1,-1);-ms-transform:scale(1,-1);-o-transform:scale(1,-1);transform:scale(1,-1)}.icon-glass:before{content:"\f000"}.icon-music:before{content:"\f001"}.icon-search:before{content:"\f002"}.icon-envelope:before{content:"\f003"}.icon-heart:before{content:"\f004"}.icon-star:before{content:"\f005"}.icon-star-empty:before{content:"\f006"}.icon-user:before{content:"\f007"}.icon-film:before{content:"\f008"}.icon-th-large:before{content:"\f009"}.icon-th:before{content:"\f00a"}.icon-th-list:before{content:"\f00b"}.icon-ok:before{content:"\f00c"}.icon-remove:before{content:"\f00d"}.icon-zoom-in:before{content:"\f00e"}.icon-zoom-out:before{content:"\f010"}.icon-off:before{content:"\f011"}.icon-signal:before{content:"\f012"}.icon-cog:before{content:"\f013"}.icon-trash:before{content:"\f014"}.icon-home:before{content:"\f015"}.icon-file:before{content:"\f016"}.icon-time:before{content:"\f017"}.icon-road:before{content:"\f018"}.icon-download-alt:before{content:"\f019"}.icon-download:before{content:"\f01a"}.icon-upload:before{content:"\f01b"}.icon-inbox:before{content:"\f01c"}.icon-play-circle:before{content:"\f01d"}.icon-repeat:before,.icon-rotate-right:before{content:"\f01e"}.icon-refresh:before{content:"\f021"}.icon-list-alt:before{content:"\f022"}.icon-lock:before{content:"\f023"}.icon-flag:before{content:"\f024"}.icon-headphones:before{content:"\f025"}.icon-volume-off:before{content:"\f026"}.icon-volume-down:before{content:"\f027"}.icon-volume-up:before{content:"\f028"}.icon-qrcode:before{content:"\f029"}.icon-barcode:before{content:"\f02a"}.icon-tag:before{content:"\f02b"}.icon-tags:before{content:"\f02c"}.icon-book:before{content:"\f02d"}.icon-bookmark:before{content:"\f02e"}.icon-print:before{content:"\f02f"}.icon-camera:before{content:"\f030"}.icon-font:before{content:"\f031"}.icon-bold:before{content:"\f032"}.icon-italic:before{content:"\f033"}.icon-text-height:before{content:"\f034"}.icon-text-width:before{content:"\f035"}.icon-align-left:before{content:"\f036"}.icon-align-center:before{content:"\f037"}.icon-align-right:before{content:"\f038"}.icon-align-justify:before{content:"\f039"}.icon-list:before{content:"\f03a"}.icon-indent-left:before{content:"\f03b"}.icon-indent-right:before{content:"\f03c"}.icon-facetime-video:before{content:"\f03d"}.icon-picture:before{content:"\f03e"}.icon-pencil:before{content:"\f040"}.icon-map-marker:before{content:"\f041"}.icon-adjust:before{content:"\f042"}.icon-tint:before{content:"\f043"}.icon-edit:before{content:"\f044"}.icon-share:before{content:"\f045"}.icon-check:before{content:"\f046"}.icon-move:before{content:"\f047"}.icon-step-backward:before{content:"\f048"}.icon-fast-backward:before{content:"\f049"}.icon-backward:before{content:"\f04a"}.icon-play:before{content:"\f04b"}.icon-pause:before{content:"\f04c"}.icon-stop:before{content:"\f04d"}.icon-forward:before{content:"\f04e"}.icon-fast-forward:before{content:"\f050"}.icon-step-forward:before{content:"\f051"}.icon-eject:before{content:"\f052"}.icon-chevron-left:before{content:"\f053"}.icon-chevron-right:before{content:"\f054"}.icon-plus-sign:before{content:"\f055"}.icon-minus-sign:before{content:"\f056"}.icon-remove-sign:before{content:"\f057"}.icon-ok-sign:before{content:"\f058"}.icon-question-sign:before{content:"\f059"}.icon-info-sign:before{content:"\f05a"}.icon-screenshot:before{content:"\f05b"}.icon-remove-circle:before{content:"\f05c"}.icon-ok-circle:before{content:"\f05d"}.icon-ban-circle:before{content:"\f05e"}.icon-arrow-left:before{content:"\f060"}.icon-arrow-right:before{content:"\f061"}.icon-arrow-up:before{content:"\f062"}.icon-arrow-down:before{content:"\f063"}.icon-share-alt:before,.icon-mail-forward:before{content:"\f064"}.icon-resize-full:before{content:"\f065"}.icon-resize-small:before{content:"\f066"}.icon-plus:before{content:"\f067"}.icon-minus:before{content:"\f068"}.icon-asterisk:before{content:"\f069"}.icon-exclamation-sign:before{content:"\f06a"}.icon-gift:before{content:"\f06b"}.icon-leaf:before{content:"\f06c"}.icon-fire:before{content:"\f06d"}.icon-eye-open:before{content:"\f06e"}.icon-eye-close:before{content:"\f070"}.icon-warning-sign:before{content:"\f071"}.icon-plane:before{content:"\f072"}.icon-calendar:before{content:"\f073"}.icon-random:before{content:"\f074"}.icon-comment:before{content:"\f075"}.icon-magnet:before{content:"\f076"}.icon-chevron-up:before{content:"\f077"}.icon-chevron-down:before{content:"\f078"}.icon-retweet:before{content:"\f079"}.icon-shopping-cart:before{content:"\f07a"}.icon-folder-close:before{content:"\f07b"}.icon-folder-open:before{content:"\f07c"}.icon-resize-vertical:before{content:"\f07d"}.icon-resize-horizontal:before{content:"\f07e"}.icon-bar-chart:before{content:"\f080"}.icon-twitter-sign:before{content:"\f081"}.icon-facebook-sign:before{content:"\f082"}.icon-camera-retro:before{content:"\f083"}.icon-key:before{content:"\f084"}.icon-cogs:before{content:"\f085"}.icon-comments:before{content:"\f086"}.icon-thumbs-up:before{content:"\f087"}.icon-thumbs-down:before{content:"\f088"}.icon-star-half:before{content:"\f089"}.icon-heart-empty:before{content:"\f08a"}.icon-signout:before{content:"\f08b"}.icon-linkedin-sign:before{content:"\f08c"}.icon-pushpin:before{content:"\f08d"}.icon-external-link:before{content:"\f08e"}.icon-signin:before{content:"\f090"}.icon-trophy:before{content:"\f091"}.icon-github-sign:before{content:"\f092"}.icon-upload-alt:before{content:"\f093"}.icon-lemon:before{content:"\f094"}.icon-phone:before{content:"\f095"}.icon-check-empty:before{content:"\f096"}.icon-bookmark-empty:before{content:"\f097"}.icon-phone-sign:before{content:"\f098"}.icon-twitter:before{content:"\f099"}.icon-facebook:before{content:"\f09a"}.icon-github:before{content:"\f09b"}.icon-unlock:before{content:"\f09c"}.icon-credit-card:before{content:"\f09d"}.icon-rss:before{content:"\f09e"}.icon-hdd:before{content:"\f0a0"}.icon-bullhorn:before{content:"\f0a1"}.icon-bell:before{content:"\f0a2"}.icon-certificate:before{content:"\f0a3"}.icon-hand-right:before{content:"\f0a4"}.icon-hand-left:before{content:"\f0a5"}.icon-hand-up:before{content:"\f0a6"}.icon-hand-down:before{content:"\f0a7"}.icon-circle-arrow-left:before{content:"\f0a8"}.icon-circle-arrow-right:before{content:"\f0a9"}.icon-circle-arrow-up:before{content:"\f0aa"}.icon-circle-arrow-down:before{content:"\f0ab"}.icon-globe:before{content:"\f0ac"}.icon-wrench:before{content:"\f0ad"}.icon-tasks:before{content:"\f0ae"}.icon-filter:before{content:"\f0b0"}.icon-briefcase:before{content:"\f0b1"}.icon-fullscreen:before{content:"\f0b2"}.icon-group:before{content:"\f0c0"}.icon-link:before{content:"\f0c1"}.icon-cloud:before{content:"\f0c2"}.icon-beaker:before{content:"\f0c3"}.icon-cut:before{content:"\f0c4"}.icon-copy:before{content:"\f0c5"}.icon-paper-clip:before{content:"\f0c6"}.icon-save:before{content:"\f0c7"}.icon-sign-blank:before{content:"\f0c8"}.icon-reorder:before{content:"\f0c9"}.icon-list-ul:before{content:"\f0ca"}.icon-list-ol:before{content:"\f0cb"}.icon-strikethrough:before{content:"\f0cc"}.icon-underline:before{content:"\f0cd"}.icon-table:before{content:"\f0ce"}.icon-magic:before{content:"\f0d0"}.icon-truck:before{content:"\f0d1"}.icon-pinterest:before{content:"\f0d2"}.icon-pinterest-sign:before{content:"\f0d3"}.icon-google-plus-sign:before{content:"\f0d4"}.icon-google-plus:before{content:"\f0d5"}.icon-money:before{content:"\f0d6"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.icon-columns:before{content:"\f0db"}.icon-sort:before{content:"\f0dc"}.icon-sort-down:before{content:"\f0dd"}.icon-sort-up:before{content:"\f0de"}.icon-envelope-alt:before{content:"\f0e0"}.icon-linkedin:before{content:"\f0e1"}.icon-undo:before,.icon-rotate-left:before{content:"\f0e2"}.icon-legal:before{content:"\f0e3"}.icon-dashboard:before{content:"\f0e4"}.icon-comment-alt:before{content:"\f0e5"}.icon-comments-alt:before{content:"\f0e6"}.icon-bolt:before{content:"\f0e7"}.icon-sitemap:before{content:"\f0e8"}.icon-umbrella:before{content:"\f0e9"}.icon-paste:before{content:"\f0ea"}.icon-lightbulb:before{content:"\f0eb"}.icon-exchange:before{content:"\f0ec"}.icon-cloud-download:before{content:"\f0ed"}.icon-cloud-upload:before{content:"\f0ee"}.icon-user-md:before{content:"\f0f0"}.icon-stethoscope:before{content:"\f0f1"}.icon-suitcase:before{content:"\f0f2"}.icon-bell-alt:before{content:"\f0f3"}.icon-coffee:before{content:"\f0f4"}.icon-food:before{content:"\f0f5"}.icon-file-alt:before{content:"\f0f6"}.icon-building:before{content:"\f0f7"}.icon-hospital:before{content:"\f0f8"}.icon-ambulance:before{content:"\f0f9"}.icon-medkit:before{content:"\f0fa"}.icon-fighter-jet:before{content:"\f0fb"}.icon-beer:before{content:"\f0fc"}.icon-h-sign:before{content:"\f0fd"}.icon-plus-sign-alt:before{content:"\f0fe"}.icon-double-angle-left:before{content:"\f100"}.icon-double-angle-right:before{content:"\f101"}.icon-double-angle-up:before{content:"\f102"}.icon-double-angle-down:before{content:"\f103"}.icon-angle-left:before{content:"\f104"}.icon-angle-right:before{content:"\f105"}.icon-angle-up:before{content:"\f106"}.icon-angle-down:before{content:"\f107"}.icon-desktop:before{content:"\f108"}.icon-laptop:before{content:"\f109"}.icon-tablet:before{content:"\f10a"}.icon-mobile-phone:before{content:"\f10b"}.icon-circle-blank:before{content:"\f10c"}.icon-quote-left:before{content:"\f10d"}.icon-quote-right:before{content:"\f10e"}.icon-spinner:before{content:"\f110"}.icon-circle:before{content:"\f111"}.icon-reply:before,.icon-mail-reply:before{content:"\f112"}.icon-folder-close-alt:before{content:"\f114"}.icon-folder-open-alt:before{content:"\f115"}.icon-expand-alt:before{content:"\f116"}.icon-collapse-alt:before{content:"\f117"}.icon-smile:before{content:"\f118"}.icon-frown:before{content:"\f119"}.icon-meh:before{content:"\f11a"}.icon-gamepad:before{content:"\f11b"}.icon-keyboard:before{content:"\f11c"}.icon-flag-alt:before{content:"\f11d"}.icon-flag-checkered:before{content:"\f11e"}.icon-terminal:before{content:"\f120"}.icon-code:before{content:"\f121"}.icon-reply-all:before{content:"\f122"}.icon-mail-reply-all:before{content:"\f122"}.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123"}.icon-location-arrow:before{content:"\f124"}.icon-crop:before{content:"\f125"}.icon-code-fork:before{content:"\f126"}.icon-unlink:before{content:"\f127"}.icon-question:before{content:"\f128"}.icon-info:before{content:"\f129"}.icon-exclamation:before{content:"\f12a"}.icon-superscript:before{content:"\f12b"}.icon-subscript:before{content:"\f12c"}.icon-eraser:before{content:"\f12d"}.icon-puzzle-piece:before{content:"\f12e"}.icon-microphone:before{content:"\f130"}.icon-microphone-off:before{content:"\f131"}.icon-shield:before{content:"\f132"}.icon-calendar-empty:before{content:"\f133"}.icon-fire-extinguisher:before{content:"\f134"}.icon-rocket:before{content:"\f135"}.icon-maxcdn:before{content:"\f136"}.icon-chevron-sign-left:before{content:"\f137"}.icon-chevron-sign-right:before{content:"\f138"}.icon-chevron-sign-up:before{content:"\f139"}.icon-chevron-sign-down:before{content:"\f13a"}.icon-html5:before{content:"\f13b"}.icon-css3:before{content:"\f13c"}.icon-anchor:before{content:"\f13d"}.icon-unlock-alt:before{content:"\f13e"}.icon-bullseye:before{content:"\f140"}.icon-ellipsis-horizontal:before{content:"\f141"}.icon-ellipsis-vertical:before{content:"\f142"}.icon-rss-sign:before{content:"\f143"}.icon-play-sign:before{content:"\f144"}.icon-ticket:before{content:"\f145"}.icon-minus-sign-alt:before{content:"\f146"}.icon-check-minus:before{content:"\f147"}.icon-level-up:before{content:"\f148"}.icon-level-down:before{content:"\f149"}.icon-check-sign:before{content:"\f14a"}.icon-edit-sign:before{content:"\f14b"}.icon-external-link-sign:before{content:"\f14c"}.icon-share-sign:before{content:"\f14d"}
/*Art is code*/
body {
	background-color:#cdd5da;
	background: -webkit-linear-gradient( bottom, #cdd5da, #e8e7e7); 
	background: -moz-linear-gradient( bottom, #cdd5da, #e8e7e7); 
	background: -ms-linear-gradient( bottom, #cdd5da, #e8e7e7); 
	background: -o-linear-gradient( bottom, #cdd5da, #e8e7e7); 
	background: linear-gradient( to bottom, #cdd5da, #e8e7e7);
}

ul.nav li.dropdown:hover ul.dropdown-menu{
	display: block;    
}

ul.nav li.dropdown ul.dropdown-menu{
	margin: 0;
}

.navbar-inner {
	border-radius:0;
}

#pgbadger-brand {
	font-size: 1.1em;
	font-weight: bold;
}

.popover-content, .popover-title {
	color:#333;
}

h3.popover-title {
	font-weight: bold;
	font-size: 1.1em;
}

ul#slides li {
	list-style-type: none;
}

h1 {
	font-size: 2em;
}

h2 {
	font-size: 1.6em;
}

h3, h3 small {
	font-size: 1.1em;
	text-transform: uppercase;
	letter-spacing: .1em;
}

h3 small {
	font-size: 1em;
}

.analysis-item {
	background: #fff;
	margin: 2em 0;
	padding: 2em 0;
}

.analysis-item h2 {
	margin: 1em 0 .5em 1em;

}

h3 {
	margin: 0;
	padding: 0;
	color: #5f5555;
}

h1.page-header {
	margin: 1em 0 1em 0;
	padding: 0;
	color: #5f5555;
	border-bottom: none;
}

h2 {
	color:#5f5555;
}

.nav-pills, .nav-tabs {
	margin: 0 1em;
}

footer {
	margin-top: 60px;
}

.span8 .tabbable {
	margin-top: 1em;
}

#global-stats .tab-content {
	margin: 2em 0 3em 0;
}

#global-stats .tab-content li {
	display: block;
	width:14%; /*160/960*/
	float:left;
	margin-left: 3%;
}

#global-stats .tab-content li.first {
	margin-left: 0;
}

.well {
	background: #f9f9f9;
	border-radius: 0;
}

.key-figures ul {
	margin: 0;
	padding: 0;
}

.key-figures li {
	list-style-type: none;
	margin-bottom: 2em;
}

.figure {
	font-weight: bold;
	font-size: 1.4em;
	color:#2e8aa5;
}

.figure-label {
	display: block;
	color: #666;
}

.mouse-figures {
	font-weight: bold;
	font-size: 1.2em;
	margin: 0;
	padding: 0;
}       

.mfigure {
	font-weight: bold;
	font-size: 1.4em;
	color:#d26115;
}

.smfigure {
	font-weight: bold;
	font-size: 1.1em;
	color:#d26115;
}

.mfigure small {
	font-weight: bold;
	font-size: 0.6em;
	color:#ffffff;
}

.smfigure small {
	font-weight: bold;
	font-size: 0.6em;
	color:#ffffff;
}

.hfigure {
	font-weight: bold;
	font-size: 1.0em;
	color:#8dbd0f;
}

.hfigure small {
	font-weight: bold;
	font-size: 0.6em;
	color:#ffffff;
}

.navbar-inverse .navbar-inner {
	background: #5f5555;
	border: none;
}

.navbar-inverse .brand, .navbar-inverse .nav > li > a	{
	color:#eee;
}

#queriespersecond_graph, #connectionspersecond_graph, #sessionspersecond_graph, #selectqueries_graph, #writequeries_graph, #durationqueries_graph, #checkpointwritebuffers_graph, #checkpointfiles_graph, #temporarydata_graph, #temporaryfile_graph, #autovacuum_graph, #bindpreparequeries_graph, #cancelledqueries_graph, #eventspersecond_graph {
	width : 100%;
	height: 400px;
}

.linegraph
	width : 100%;
	height: 400px;
}

#queriesbytype_graph, #lockbytype_graph, #databasesessions_graph, #usersessions_graph, #hostsessions_graph, #appsessions_graph, #databaseconnections_graph, #userconnections_graph, #hostconnections_graph, #logstype_graph, #tableanalyzes_graph, #tablevacuums_graph, #tuplevacuums_graph, #pagevacuums_graph, #queriesbydatabase_graph, #queriesbyapplication_graph, #queriesbyuser_graph, #queriesbyhost_graph, #histogram_query_times_graph, #histogram_session_times_graph, #durationbyuser_graph {
	width : 100%;
	height: 320px;
}

.piegraph {
	width : 100%;
	height: 320px;
}
.histo-graph {
	width : 100%;
	height: 140px;
}
.duration-histo-graph {
	width : 100%;
	height: 300px;
}

@media (min-width:969px) {
	#show-hide-menu {
		position: absolute;
		left: -9999px;
	}

	.navbar ul.collapse {
		overflow: visible;
	}
}

@media (max-width:968px) {
	#show-hide-menu {
		position: inherit;
	}

	#global-stats .tab-content li {
		display: block;
		width:auto; /*160/960*/
		float:none;
		margin-left: 0;
		margin-bottom: 1em;
	}

	ul#slides {
		margin: 0;
		padding: 0;
	}

	ul#slides li div div {
		padding:0 1.5em;
	}


	#queriespersecond_graph, #connectionspersecond_graph, #sessionspersecond_graph, #selectqueries_graph, #writequeries_graph, #durationqueries_graph, #checkpointwritebuffers_graph, #checkpointfiles_graph, #temporarydata_graph, #temporaryfile_graph, #autovacuum_graph, #bindpreparequeries_graph, #cancelledqueries_graph, #eventspersecond_graph {
		width : 94.5%;
	}

	.linegraph {
		width : 94.5%;
	}

	#queriesbytype_graph, #lockbytype_graph, #databasesessions_graph, #usersessions_graph, #hostsessions_graph, #appsessions_graph, #databaseconnections_graph, #userconnections_graph, #hostconnections_graph, #logstype_graph, #tableanalyzes_graph, #tablevacuums_graph, #tuplevacuums_graph, #pagevacuums_graph, #queriesbydatabase_graph, #queriesbyapplication_graph, #queriesbyuser_graph, #queriesbyhost_graph, #histogram_query_times_graph, #histogram_session_times_graph, #durationbyuser_graph {
		width : 94.5%;
	}

	.piegraph {
		width : 94.5%;
	}

	.histo-graph {
		width : 84.5%;
	}

	.duration-histo-graph {
		width : 94.5%;
	}

	.key-figures ul {
		margin-top: 1.5em;
	}

	.navbar .nav {
		margin: 0 3em 2em 3em;
	}

	.navbar .nav > li {
		float: none;
	}

	.navbar ul.collapse:hover {
		overflow: visible;
	}
}

WRFILE: jquery.js

(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);

WRFILE: bootstrap.js

/*
 * Bootstrap.js by @fat & @mdo
 * Copyright 2012 Twitter, Inc.
 * http://www.apache.org/licenses/LICENSE-2.0.txt
*/
    !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('<div class="dropdown-backdrop"/>').insertBefore(e(this)).on("click",r),s.toggleClass("open")),n.focus(),!1},keydown:function(n){var r,s,o,u,a,f;if(!/(38|40|27)/.test(n.keyCode))return;r=e(this),n.preventDefault(),n.stopPropagation();if(r.is(".disabled, :disabled"))return;u=i(r),a=u.hasClass("open");if(!a||a&&n.keyCode==27)return n.which==27&&u.find(t).focus(),r.click();s=e("[role=menu] li:not(.divider):visible a",u);if(!s.length)return;f=s.index(s.filter(":focus")),n.keyCode==38&&f>0&&f--,n.keyCode==40&&f<s.length-1&&f++,~f||(f=0),s.eq(f).focus()}};var s=e.fn.dropdown;e.fn.dropdown=function(t){return this.each(function(){var r=e(this),i=r.data("dropdown");i||r.data("dropdown",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.dropdown.Constructor=n,e.fn.dropdown.noConflict=function(){return e.fn.dropdown=s,this},e(document).on("click.dropdown.data-api",r).on("click.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("click.dropdown.data-api",t,n.prototype.toggle).on("keydown.dropdown.data-api",t+", [role=menu]",n.prototype.keydown)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=n,this.$element=e(t).delegate('[data-dismiss="modal"]',"click.dismiss.modal",e.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};t.prototype={constructor:t,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var t=this,n=e.Event("show");this.$element.trigger(n);if(this.isShown||n.isDefaultPrevented())return;this.isShown=!0,this.escape(),this.backdrop(function(){var n=e.support.transition&&t.$element.hasClass("fade");t.$element.parent().length||t.$element.appendTo(document.body),t.$element.show(),n&&t.$element[0].offsetWidth,t.$element.addClass("in").attr("aria-hidden",!1),t.enforceFocus(),n?t.$element.one(e.support.transition.end,function(){t.$element.focus().trigger("shown")}):t.$element.focus().trigger("shown")})},hide:function(t){t&&t.preventDefault();var n=this;t=e.Event("hide"),this.$element.trigger(t);if(!this.isShown||t.isDefaultPrevented())return;this.isShown=!1,this.escape(),e(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),e.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal()},enforceFocus:function(){var t=this;e(document).on("focusin.modal",function(e){t.$element[0]!==e.target&&!t.$element.has(e.target).length&&t.$element.focus()})},escape:function(){var e=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(t){t.which==27&&e.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var t=this,n=setTimeout(function(){t.$element.off(e.support.transition.end),t.hideModal()},500);this.$element.one(e.support.transition.end,function(){clearTimeout(n),t.hideModal()})},hideModal:function(){var e=this;this.$element.hide(),this.backdrop(function(){e.removeBackdrop(),e.$element.trigger("hidden")})},removeBackdrop:function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},backdrop:function(t){var n=this,r=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var i=e.support.transition&&r;this.$backdrop=e('<div class="modal-backdrop '+r+'" />').appendTo(document.body),this.$backdrop.click(this.options.backdrop=="static"?e.proxy(this.$element[0].focus,this.$element[0]):e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!t)return;i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,t):t()):t&&t()}};var n=e.fn.modal;e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e.fn.modal.noConflict=function(){return e.fn.modal=n,this},e(document).on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s,o,u,a;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,o=this.options.trigger.split(" ");for(a=o.length;a--;)u=o[a],u=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):u!="manual"&&(i=u=="hover"?"mouseenter":"focus",s=u=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this)));this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,this.$element.data(),t),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e.fn[this.type].defaults,r={},i;this._options&&e.each(this._options,function(e,t){n[e]!=t&&(r[e]=t)},this),i=e(t.currentTarget)[this.type](r).data(this.type);if(!i.options.delay||!i.options.delay.show)return i.show();clearTimeout(this.timeout),i.hoverState="in",this.timeout=setTimeout(function(){i.hoverState=="in"&&i.show()},i.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var t,n,r,i,s,o,u=e.Event("show");if(this.hasContent()&&this.enabled){this.$element.trigger(u);if(u.isDefaultPrevented())return;t=this.tip(),this.setContent(),this.options.animation&&t.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,t[0],this.$element[0]):this.options.placement,t.detach().css({top:0,left:0,display:"block"}),this.options.container?t.appendTo(this.options.container):t.insertAfter(this.$element),n=this.getPosition(),r=t[0].offsetWidth,i=t[0].offsetHeight;switch(s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}this.applyPlacement(o,s),this.$element.trigger("shown")}},applyPlacement:function(e,t){var n=this.tip(),r=n[0].offsetWidth,i=n[0].offsetHeight,s,o,u,a;n.offset(e).addClass(t).addClass("in"),s=n[0].offsetWidth,o=n[0].offsetHeight,t=="top"&&o!=i&&(e.top=e.top+i-o,a=!0),t=="bottom"||t=="top"?(u=0,e.left<0&&(u=e.left*-2,e.left=0,n.offset(e),s=n[0].offsetWidth,o=n[0].offsetHeight),this.replaceArrow(u-r+s,s,"left")):this.replaceArrow(o-i,o,"top"),a&&n.offset(e)},replaceArrow:function(e,t,n){this.arrow().css(n,e?50*(1-e/t)+"%":"")},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function i(){var t=setTimeout(function(){n.off(e.support.transition.end).detach()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.detach()})}var t=this,n=this.tip(),r=e.Event("hide");this.$element.trigger(r);if(r.isDefaultPrevented())return;return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?i():n.detach(),this.$element.trigger("hidden"),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").attr("title","")},hasContent:function(){return this.getTitle()},getPosition:function(){var t=this.$element[0];return e.extend({},typeof t.getBoundingClientRect=="function"?t.getBoundingClientRect():{width:t.offsetWidth,height:t.offsetHeight},this.$element.offset())},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},arrow:function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(t){var n=t?e(t.currentTarget)[this.type](this._options).data(this.type):this;n.tip().hasClass("in")?n.hide():n.show()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var n=e.fn.tooltip;e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},e.fn.tooltip.noConflict=function(){return e.fn.tooltip=n,this}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=(typeof n.content=="function"?n.content.call(t[0]):n.content)||t.attr("data-content"),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var n=e.fn.popover;e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),e.fn.popover.noConflict=function(){return e.fn.popover=n,this}}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var n=e(this),r=n.data("target")||n.attr("href"),i=/^#\w/.test(r)&&e(r);return i&&i.length&&[[i.position().top+(!e.isWindow(t.$scrollElement.get(0))&&t.$scrollElement.scrollTop()),r]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}};var n=e.fn.scrollspy;e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e.fn.scrollspy.noConflict=function(){return e.fn.scrollspy=n,this},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active:last a")[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}};var n=e.fn.tab;e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e.fn.tab.noConflict=function(){return e.fn.tab=n,this},e(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=e(this.options.menu),this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:t.top+t.height,left:t.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length<this.options.minLength?this.shown?this.hide():this:(n=e.isFunction(this.source)?this.source(this.query,e.proxy(this.process,this)):this.source,n?this.process(n):this)},process:function(t){var n=this;return t=e.grep(t,function(e){return n.matcher(e)}),t=this.sorter(t),t.length?this.render(t.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(e){return~e.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(e){var t=[],n=[],r=[],i;while(i=e.shift())i.toLowerCase().indexOf(this.query.toLowerCase())?~i.indexOf(this.query)?n.push(i):r.push(i):t.push(i);return t.concat(n,r)},highlighter:function(e){var t=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return e.replace(new RegExp("("+t+")","ig"),function(e,t){return"<strong>"+t+"</strong>"})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("focus",e.proxy(this.focus,this)).on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this)).on("mouseleave","li",e.proxy(this.mouseleave,this))},eventSupported:function(e){var t=e in this.$element;return t||(this.$element.setAttribute(e,"return;"),t=typeof this.$element[e]=="function"),t},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},focus:function(e){this.focused=!0},blur:function(e){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(e){e.stopPropagation(),e.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(t){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")},mouseleave:function(e){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var n=e.fn.typeahead;e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>',minLength:1},e.fn.typeahead.Constructor=t,e.fn.typeahead.noConflict=function(){return e.fn.typeahead=n,this},e(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;n.typeahead(n.data())})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)).on("click.affix.data-api",e.proxy(function(){setTimeout(e.proxy(this.checkPosition,this),1)},this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))};var n=e.fn.affix;e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e.fn.affix.noConflict=function(){return e.fn.affix=n,this},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery);

WRFILE: prettify.js

!function(){var r=null;
(function(){function X(e){function j(){try{J.doScroll("left")}catch(e){P(j,50);return}w("poll")}function w(j){if(!(j.type=="readystatechange"&&x.readyState!="complete")&&((j.type=="load"?n:x)[z](i+j.type,w,!1),!m&&(m=!0)))e.call(n,j.type||j)}var Y=x.addEventListener,m=!1,C=!0,t=Y?"addEventListener":"attachEvent",z=Y?"removeEventListener":"detachEvent",i=Y?"":"on";if(x.readyState=="complete")e.call(n,"lazy");else{if(x.createEventObject&&J.doScroll){try{C=!n.frameElement}catch(A){}C&&j()}x[t](i+"DOMContentLoaded",
w,!1);x[t](i+"readystatechange",w,!1);n[t](i+"load",w,!1)}}function Q(){S&&X(function(){var e=K.length;$(e?function(){for(var j=0;j<e;++j)(function(e){P(function(){n.exports[K[e]].apply(n,arguments)},0)})(j)}:void 0)})}for(var n=window,P=n.setTimeout,x=document,J=x.documentElement,L=x.head||x.getElementsByTagName("head")[0]||J,z="",A=x.scripts,m=A.length;--m>=0;){var M=A[m],T=M.src.match(/^[^#?]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);if(T){z=T[1]||"";M.parentNode.removeChild(M);break}}var S=!0,D=
[],N=[],K=[];z.replace(/[&?]([^&=]+)=([^&]+)/g,function(e,j,w){w=decodeURIComponent(w);j=decodeURIComponent(j);j=="autorun"?S=!/^[0fn]/i.test(w):j=="lang"?D.push(w):j=="skin"?N.push(w):j=="callback"&&K.push(w)});m=0;for(z=D.length;m<z;++m)(function(){var e=x.createElement("script");e.onload=e.onerror=e.onreadystatechange=function(){if(e&&(!e.readyState||/loaded|complete/.test(e.readyState)))e.onerror=e.onload=e.onreadystatechange=r,--R,R||P(Q,0),e.parentNode&&e.parentNode.removeChild(e),e=r};e.type=
"text/javascript";e.src="https://google-code-prettify.googlecode.com/svn/loader/lang-"+encodeURIComponent(D[m])+".js";L.insertBefore(e,L.firstChild)})(D[m]);for(var R=D.length,A=[],m=0,z=N.length;m<z;++m)A.push("https://google-code-prettify.googlecode.com/svn/loader/skins/"+encodeURIComponent(N[m])+".css");A.push("https://google-code-prettify.googlecode.com/svn/loader/prettify.css");(function(e){function j(m){if(m!==w){var n=x.createElement("link");n.rel="stylesheet";n.type="text/css";if(m+1<w)n.error=
n.onerror=function(){j(m+1)};n.href=e[m];L.appendChild(n)}}var w=e.length;j(0)})(A);var $=function(){window.PR_SHOULD_USE_CONTINUATION=!0;var e;(function(){function j(a){function d(f){var b=f.charCodeAt(0);if(b!==92)return b;var a=f.charAt(1);return(b=i[a])?b:"0"<=a&&a<="7"?parseInt(f.substring(1),8):a==="u"||a==="x"?parseInt(f.substring(2),16):f.charCodeAt(1)}function h(f){if(f<32)return(f<16?"\\x0":"\\x")+f.toString(16);f=String.fromCharCode(f);return f==="\\"||f==="-"||f==="]"||f==="^"?"\\"+f:
f}function b(f){var b=f.substring(1,f.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),f=[],a=b[0]==="^",c=["["];a&&c.push("^");for(var a=a?1:0,g=b.length;a<g;++a){var k=b[a];if(/\\[bdsw]/i.test(k))c.push(k);else{var k=d(k),o;a+2<g&&"-"===b[a+1]?(o=d(b[a+2]),a+=2):o=k;f.push([k,o]);o<65||k>122||(o<65||k>90||f.push([Math.max(65,k)|32,Math.min(o,90)|32]),o<97||k>122||f.push([Math.max(97,k)&-33,Math.min(o,122)&-33]))}}f.sort(function(f,a){return f[0]-
a[0]||a[1]-f[1]});b=[];g=[];for(a=0;a<f.length;++a)k=f[a],k[0]<=g[1]+1?g[1]=Math.max(g[1],k[1]):b.push(g=k);for(a=0;a<b.length;++a)k=b[a],c.push(h(k[0])),k[1]>k[0]&&(k[1]+1>k[0]&&c.push("-"),c.push(h(k[1])));c.push("]");return c.join("")}function e(f){for(var a=f.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),c=a.length,d=[],g=0,k=0;g<c;++g){var o=a[g];o==="("?++k:"\\"===o.charAt(0)&&(o=+o.substring(1))&&(o<=k?d[o]=-1:a[g]=h(o))}for(g=
1;g<d.length;++g)-1===d[g]&&(d[g]=++j);for(k=g=0;g<c;++g)o=a[g],o==="("?(++k,d[k]||(a[g]="(?:")):"\\"===o.charAt(0)&&(o=+o.substring(1))&&o<=k&&(a[g]="\\"+d[o]);for(g=0;g<c;++g)"^"===a[g]&&"^"!==a[g+1]&&(a[g]="");if(f.ignoreCase&&F)for(g=0;g<c;++g)o=a[g],f=o.charAt(0),o.length>=2&&f==="["?a[g]=b(o):f!=="\\"&&(a[g]=o.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var j=0,F=!1,l=!1,I=0,c=a.length;I<c;++I){var p=a[I];if(p.ignoreCase)l=
!0;else if(/[a-z]/i.test(p.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){F=!0;l=!1;break}}for(var i={b:8,t:9,n:10,v:11,f:12,r:13},q=[],I=0,c=a.length;I<c;++I){p=a[I];if(p.global||p.multiline)throw Error(""+p);q.push("(?:"+e(p)+")")}return RegExp(q.join("|"),l?"gi":"g")}function m(a,d){function h(a){var c=a.nodeType;if(c==1){if(!b.test(a.className)){for(c=a.firstChild;c;c=c.nextSibling)h(c);c=a.nodeName.toLowerCase();if("br"===c||"li"===c)e[l]="\n",F[l<<1]=j++,F[l++<<1|1]=a}}else if(c==
3||c==4)c=a.nodeValue,c.length&&(c=d?c.replace(/\r\n?/g,"\n"):c.replace(/[\t\n\r ]+/g," "),e[l]=c,F[l<<1]=j,j+=c.length,F[l++<<1|1]=a)}var b=/(?:^|\s)nocode(?:\s|$)/,e=[],j=0,F=[],l=0;h(a);return{a:e.join("").replace(/\n$/,""),d:F}}function n(a,d,h,b){d&&(a={a:d,e:a},h(a),b.push.apply(b,a.g))}function x(a){for(var d=void 0,h=a.firstChild;h;h=h.nextSibling)var b=h.nodeType,d=b===1?d?a:h:b===3?S.test(h.nodeValue)?a:d:d;return d===a?void 0:d}function C(a,d){function h(a){for(var l=a.e,j=[l,"pln"],c=
0,p=a.a.match(e)||[],m={},q=0,f=p.length;q<f;++q){var B=p[q],y=m[B],u=void 0,g;if(typeof y==="string")g=!1;else{var k=b[B.charAt(0)];if(k)u=B.match(k[1]),y=k[0];else{for(g=0;g<i;++g)if(k=d[g],u=B.match(k[1])){y=k[0];break}u||(y="pln")}if((g=y.length>=5&&"lang-"===y.substring(0,5))&&!(u&&typeof u[1]==="string"))g=!1,y="src";g||(m[B]=y)}k=c;c+=B.length;if(g){g=u[1];var o=B.indexOf(g),H=o+g.length;u[2]&&(H=B.length-u[2].length,o=H-g.length);y=y.substring(5);n(l+k,B.substring(0,o),h,j);n(l+k+o,g,A(y,
g),j);n(l+k+H,B.substring(H),h,j)}else j.push(l+k,y)}a.g=j}var b={},e;(function(){for(var h=a.concat(d),l=[],i={},c=0,p=h.length;c<p;++c){var m=h[c],q=m[3];if(q)for(var f=q.length;--f>=0;)b[q.charAt(f)]=m;m=m[1];q=""+m;i.hasOwnProperty(q)||(l.push(m),i[q]=r)}l.push(/[\S\s]/);e=j(l)})();var i=d.length;return h}function t(a){var d=[],h=[];a.tripleQuotedStrings?d.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,
r,"'\""]):a.multiLineStrings?d.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,r,"'\"`"]):d.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,r,"\"'"]);a.verbatimStrings&&h.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,r]);var b=a.hashComments;b&&(a.cStyleComments?(b>1?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,r,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\n\r]*)/,
r,"#"]),h.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,r])):d.push(["com",/^#[^\n\r]*/,r,"#"]));a.cStyleComments&&(h.push(["com",/^\/\/[^\n\r]*/,r]),h.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,r]));if(b=a.regexLiterals){var e=(b=b>1?"":"\n\r")?".":"[\\S\\s]";h.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+
("/(?=[^/*"+b+"])(?:[^/\\x5B\\x5C"+b+"]|\\x5C"+e+"|\\x5B(?:[^\\x5C\\x5D"+b+"]|\\x5C"+e+")*(?:\\x5D|$))+/")+")")])}(b=a.types)&&h.push(["typ",b]);b=(""+a.keywords).replace(/^ | $/g,"");b.length&&h.push(["kwd",RegExp("^(?:"+b.replace(/[\s,]+/g,"|")+")\\b"),r]);d.push(["pln",/^\s+/,r," \r\n\t\u00a0"]);b="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(b+="(?!s*/)");h.push(["lit",/^@[$_a-z][\w$@]*/i,r],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,r],["pln",/^[$_a-z][\w$@]*/i,r],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,
r,"0123456789"],["pln",/^\\[\S\s]?/,r],["pun",RegExp(b),r]);return C(d,h)}function z(a,d,h){function b(a){var c=a.nodeType;if(c==1&&!j.test(a.className))if("br"===a.nodeName)e(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)b(a);else if((c==3||c==4)&&h){var d=a.nodeValue,i=d.match(m);if(i)c=d.substring(0,i.index),a.nodeValue=c,(d=d.substring(i.index+i[0].length))&&a.parentNode.insertBefore(l.createTextNode(d),a.nextSibling),e(a),c||a.parentNode.removeChild(a)}}
function e(a){function b(a,c){var d=c?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),h=a.nextSibling;f.appendChild(d);for(var e=h;e;e=h)h=e.nextSibling,f.appendChild(e)}return d}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),d;(d=a.parentNode)&&d.nodeType===1;)a=d;c.push(a)}for(var j=/(?:^|\s)nocode(?:\s|$)/,m=/\r\n?|\n/,l=a.ownerDocument,i=l.createElement("li");a.firstChild;)i.appendChild(a.firstChild);for(var c=[i],p=0;p<c.length;++p)b(c[p]);d===(d|0)&&c[0].setAttribute("value",
d);var n=l.createElement("ol");n.className="linenums";for(var d=Math.max(0,d-1|0)||0,p=0,q=c.length;p<q;++p)i=c[p],i.className="L"+(p+d)%10,i.firstChild||i.appendChild(l.createTextNode("\u00a0")),n.appendChild(i);a.appendChild(n)}function i(a,d){for(var h=d.length;--h>=0;){var b=d[h];U.hasOwnProperty(b)?V.console&&console.warn("cannot override language handler %s",b):U[b]=a}}function A(a,d){if(!a||!U.hasOwnProperty(a))a=/^\s*</.test(d)?"default-markup":"default-code";return U[a]}function D(a){var d=
a.h;try{var h=m(a.c,a.i),b=h.a;a.a=b;a.d=h.d;a.e=0;A(d,b)(a);var e=/\bMSIE\s(\d+)/.exec(navigator.userAgent),e=e&&+e[1]<=8,d=/\n/g,i=a.a,j=i.length,h=0,l=a.d,n=l.length,b=0,c=a.g,p=c.length,t=0;c[p]=j;var q,f;for(f=q=0;f<p;)c[f]!==c[f+2]?(c[q++]=c[f++],c[q++]=c[f++]):f+=2;p=q;for(f=q=0;f<p;){for(var x=c[f],y=c[f+1],u=f+2;u+2<=p&&c[u+1]===y;)u+=2;c[q++]=x;c[q++]=y;f=u}c.length=q;var g=a.c,k;if(g)k=g.style.display,g.style.display="none";try{for(;b<n;){var o=l[b+2]||j,H=c[t+2]||j,u=Math.min(o,H),E=l[b+
1],W;if(E.nodeType!==1&&(W=i.substring(h,u))){e&&(W=W.replace(d,"\r"));E.nodeValue=W;var Z=E.ownerDocument,s=Z.createElement("span");s.className=c[t+1];var z=E.parentNode;z.replaceChild(s,E);s.appendChild(E);h<o&&(l[b+1]=E=Z.createTextNode(i.substring(u,o)),z.insertBefore(E,s.nextSibling))}h=u;h>=o&&(b+=2);h>=H&&(t+=2)}}finally{if(g)g.style.display=k}}catch(v){V.console&&console.log(v&&v.stack||v)}}var V=window,G=["break,continue,do,else,for,if,return,while"],O=[[G,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],J=[O,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],K=[O,"abstract,assert,boolean,byte,extends,final,finally,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],
L=[K,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],O=[O,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],M=[G,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
N=[G,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],R=[G,"as,assert,const,copy,drop,enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv,pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"],G=[G,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],Q=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,
S=/\S/,T=t({keywords:[J,L,O,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",M,N,G],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),U={};i(T,["default-code"]);i(C([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",
/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);i(C([["pln",/^\s+/,r," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,r,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],
["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);i(C([],[["atv",/^[\S\s]+/]]),["uq.val"]);i(t({keywords:J,hashComments:!0,cStyleComments:!0,types:Q}),["c","cc","cpp","cxx","cyc","m"]);i(t({keywords:"null,true,false"}),["json"]);i(t({keywords:L,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:Q}),
["cs"]);i(t({keywords:K,cStyleComments:!0}),["java"]);i(t({keywords:G,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);i(t({keywords:M,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);i(t({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);i(t({keywords:N,
hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);i(t({keywords:O,cStyleComments:!0,regexLiterals:!0}),["javascript","js"]);i(t({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);i(t({keywords:R,cStyleComments:!0,multilineStrings:!0}),["rc","rs","rust"]);
i(C([],[["str",/^[\S\s]+/]]),["regex"]);var X=V.PR={createSimpleLexer:C,registerLangHandler:i,sourceDecorator:t,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:function(a,d,e){var b=document.createElement("div");b.innerHTML="<pre>"+a+"</pre>";b=b.firstChild;e&&z(b,e,!0);D({h:d,j:e,c:b,i:1});return b.innerHTML},
prettyPrint:e=e=function(a,d){function e(){for(var b=V.PR_SHOULD_USE_CONTINUATION?c.now()+250:Infinity;p<j.length&&c.now()<b;p++){for(var d=j[p],m=k,l=d;l=l.previousSibling;){var n=l.nodeType,s=(n===7||n===8)&&l.nodeValue;if(s?!/^\??prettify\b/.test(s):n!==3||/\S/.test(l.nodeValue))break;if(s){m={};s.replace(/\b(\w+)=([\w%+\-.:]+)/g,function(a,b,c){m[b]=c});break}}l=d.className;if((m!==k||f.test(l))&&!w.test(l)){n=!1;for(s=d.parentNode;s;s=s.parentNode)if(g.test(s.tagName)&&s.className&&f.test(s.className)){n=
!0;break}if(!n){d.className+=" prettyprinted";n=m.lang;if(!n){var n=l.match(q),A;if(!n&&(A=x(d))&&u.test(A.tagName))n=A.className.match(q);n&&(n=n[1])}if(y.test(d.tagName))s=1;else var s=d.currentStyle,v=i.defaultView,s=(s=s?s.whiteSpace:v&&v.getComputedStyle?v.getComputedStyle(d,r).getPropertyValue("white-space"):0)&&"pre"===s.substring(0,3);v=m.linenums;if(!(v=v==="true"||+v))v=(v=l.match(/\blinenums\b(?::(\d+))?/))?v[1]&&v[1].length?+v[1]:!0:!1;v&&z(d,v,s);t={h:n,c:d,j:v,i:s};D(t)}}}p<j.length?
P(e,250):"function"===typeof a&&a()}for(var b=d||document.body,i=b.ownerDocument||document,b=[b.getElementsByTagName("pre"),b.getElementsByTagName("code"),b.getElementsByTagName("xmp")],j=[],m=0;m<b.length;++m)for(var l=0,n=b[m].length;l<n;++l)j.push(b[m][l]);var b=r,c=Date;c.now||(c={now:function(){return+new Date}});var p=0,t,q=/\blang(?:uage)?-([\w.]+)(?!\S)/,f=/\bprettyprint\b/,w=/\bprettyprinted\b/,y=/pre|xmp/i,u=/^code$/i,g=/^(?:pre|code|xmp)$/i,k={};e()}};typeof define==="function"&&define.amd&&
define("google-code-prettify",[],function(){return X})})();return e}();R||P(Q,0)})();}()

WRFILE: pgbadger_slide.js

jQuery(function (){
	jQuery('#pgbadger-brand').tooltip();

	jQuery("#pop-infos").popover('hide');
	jQuery('.slide').hide();
	jQuery('.active-slide').show();

	/* Go to specific slide and report from external link call */
	var activeMenu = location.hash;
	if (activeMenu) {
		activeMenu = activeMenu.substring(1);
		var lkobj = document.getElementById(activeMenu);
		var liId = jQuery(lkobj).parent().attr("id");
		if (liId != undefined) {
			var slideId = '#'+liId;
			jQuery('#main-container li.slide').removeClass('active-slide').hide();
			jQuery(slideId).addClass("active-slide").fadeIn();
			window.location.hash = '#'+activeMenu;
		}
	}

	jQuery('.navbar li.dropdown').click(function() {
		var id = jQuery(this).attr("id");
		id = id.substring(5);
		var slideId = '#'+id+'-slide';
		var currentSlide = jQuery('#main-container .active-slide').attr("id");
		currentSlide = '#'+currentSlide;

		if(slideId != currentSlide) {
			jQuery('#main-container li.slide').removeClass('active-slide').hide();
			jQuery(slideId).addClass("active-slide").fadeIn();
		}
	});

	jQuery('.navbar li ul li').click(function() {
		var liId = jQuery(this).parent().parent().attr("id");
		var id = liId.substring(5);
		var slideId = '#'+id+'-slide';
		jQuery('#main-container li.slide').removeClass('active-slide').hide();
		jQuery(slideId).addClass("active-slide").fadeIn();
	});
});

jQuery(document).ready(function () {
    jQuery('.sql').dblclick(function () {
        if (this.style == undefined || this.style.whiteSpace == 'pre') {
            this.style.whiteSpace ='normal';
        } else {
            this.style.whiteSpace = 'pre';
        }
    });
    jQuery('.icon-copy').click(function () {
        var obj = $(this).parent()[0];
        if (window.getSelection) {
            var sel = window.getSelection();
            sel.removeAllRanges();
            var range = document.createRange();
            range.selectNodeContents(obj);
            sel.addRange(range);
        } else if (document.selection) {
            var textRange = document.body.createTextRange();
            textRange.moveToElementText(obj);
            textRange.select();
        }
    });
});
