#!/usr/bin/perl -I/home/onetipp/trendcrawler/v1

###
# Bildschirm leeren
###
print "\033[2J";    #clear the screen
print "\033[0;0H"; 	#jump to 0,0

my $version = "v1.3 - 17.8.2016";
###
# Bibliothek einbinden
###
use lib "/home/onetipp/trendcrawler/v1";
use strict;

###
# Installationsanweisungen für benötige Module
###	
# perl -MCPAN -e 'force install "URI"'
# perl -MCPAN -e 'force install "AnyEvent"'		
# perl -MCPAN -e 'force install "Data::Dumper"'	
# perl -MCPAN -e 'force install "Encode"'
# perl -MCPAN -e 'force install "Regexp::Common"'	
# perl -MCPAN -e 'force install "WWW::Alexa::TrafficRank"'
# perl -MCPAN -e 'force install "AnyEvent::Google::PageRank"'	
# perl -MCPAN -e 'force install "Time::HiRes"'

###
# Fremde Bibliotheksprogramme einbinden
# dahinter stehen die Installationsanweisungen für die externen Bibliotheken
###
use strict;
use DBI;
use DBD::mysql;
use Data::Dumper;			# perl -MCPAN -e 'force install "Data::Dumper"'	
use Config::Simple; 		# perl -MCPAN -e 'force install "Config::Simple"'	
use Net::Twitter;			# perl -MCPAN -e 'force install "Net::Twitter"'	
use Scalar::Util 'blessed';	# perl -MCPAN -e 'force install "Scalar::Util"'	
use POSIX qw(strftime);		# perl -MCPAN -e 'force install "POSIX"'	
use LWP::UserAgent;			# perl -MCPAN -e 'force install "LWP::UserAgent"'	
use Regexp::Common;			# perl -MCPAN -e 'force install "Regexp::Common"'	
use Google::Data::JSON;		# perl -MCPAN -e 'force install "Google::Data::JSON"'	
use File::Path;				# perl -MCPAN -e 'force install "File::Path"'
use HTML::LinkExtractor;	# perl -MCPAN -e 'force install "HTML::LinkExtractor"'
#use DateTime::Format::MySQL;# perl -MCPAN -e 'force install "DateTime::Format::MySQL"'

# perl -MCPAN -e 'force install "PadWalker"'

 
use URI;							
use AnyEvent;						
use Data::Dumper;					
use Encode qw(encode decode); 		
use Regexp::Common;					
use WWW::Alexa::TrafficRank;					
use AnyEvent::Google::PageRank; 	
use Time::HiRes qw( gettimeofday ); 

###
# Variablen vordefinieren und initialisieren
###
my $UA 						= LWP::UserAgent->new();
my $Config 					= Config::Simple->new(filename=>"/home/onetipp/trendcrawler/v1/trendcrawler.cfg");
my $Keywords				= $Config->param(-block=>"KeywordListingGerman");
my $Google					= $Config->param(-block=>"Google");
my $Twitter					= $Config->param(-block=>"Twitter");
my $TimeStamp				= join ("-", (localtime));
my $Hash					= "";
my %Hash 					= ();

###
# Variablen vordefinieren und initialisieren
###
my $UA 								= LWP::UserAgent->new( timeout => 10 );
my $AlexaObject						= WWW::Alexa::TrafficRank->new();
my $PageRankObject					= AnyEvent::Google::PageRank->new( timeout => 10 );
my $TrendRankOutFile				= "/home/onetipp/trendcrawler/v1/trendcrawler_logfile.txt";
my $FoundOutFile					= "/home/onetipp/trendcrawler/v1/trendcrawler_foundfile.txt";

my $AlexaGewichtungsfaktor			= 0.0002;
my $GooglePRGewichtungsfaktor		= 0.0005;
my $TwitterGewichtungsfaktor		= 0.45;
my $FacebookGewichtungsfaktor		= 0.15;
my $DmozGewichtungsfaktor			= 0.01;
my $SpeedGewichtungsfaktor			= 0.005;
my $enc 							= 'utf-8'; # in dieser Kodierung ist das Script gespeichert
my $dsn 							= "dbi:mysql:onetipp:localhost:3306";

###
# Konstanten festlegen
###
use constant GoogleHtml     		=> "/home/onetipp/trendcrawler/v1/html/google/";
use constant TwitterHtml   	 		=> "/home/onetipp/trendcrawler/v1/html/twitter/";
eval { mkpath(GoogleHtml); mkpath(TwitterHtml); };		# File::Path

###
# Externes Twitter Modul konfigurieren und mit Werten aus der Konfigurationsdatei belegen
###
my $nt = Net::Twitter->new(
	traits   				=> [qw/API::RESTv1_1/],
	consumer_key       		=> $Twitter->{'consumer_key'},
	consumer_secret     	=> $Twitter->{'consumer_secret'},
	access_token        	=> $Twitter->{'access_token'},
	access_token_secret 	=> $Twitter->{'access_token_secret'},
	ssl                 	=> 1,  ## enable SSL! ##
	decode_html_entities   	=> 1,
);

###
# Für alle Keywords der Konfigurationsdatei führe die Suche nach Twitter und Google Trends durch
###
open(W,"+>>/home/onetipp/trendcrawler/v1/working.log");
while ( my ($key, $searchQuery) = each(%{$Keywords}) ) {
		print W localtime . " ) Suche bei Google nach Keywords: $searchQuery\n";
		googleParseSearch($searchQuery);
		
		print W localtime . " ) Suche bei Twitter nach Keywords: $searchQuery\n";
		twitterCustomSearch($searchQuery, "DE", "recent");
		twitterCustomSearch($searchQuery, "DE", "popular");
		twitterCustomSearch($searchQuery, "EN", "recent");
		twitterCustomSearch($searchQuery, "EN", "popular");
}
close W;
exit(0);

###
# Twitter Suche durchführen
###
sub twitterCustomSearch($)
{
	my $input 		= shift;
	my $lang 		= shift; # DE oder EN
	my $mixed 		= shift; # recent, popular 
	my $source		= "twitter";
	my $yesterday 	= time() - 365 * 24 * 60 * 60; #tweets from max n=120 days ago
	my $timestamp 	= strftime "%Y-%m-%d", ( localtime($yesterday) );
	my $result 		= $nt->search({q => $input, lang => $lang, count => 100, since_id => $timestamp, result_type => $mixed});

	my $TimeStampv2	= do {
		my ($s,$m,$h,$D,$M,$Y)=localtime;
		$Y+=1900;
		$M++;
		"$Y-$M-$D-$h:$m:$s" 
		};
			
	writeHtml("<hr><h1><strong><b>Trending Twitter Keywords: $input<b><strong></h1><br /><br />", TwitterHtml.$TimeStampv2.".twitter-$input-page.html");		
	my $identity; # Last returned id 
		
	foreach my $status (@{$result->{'statuses'}}) {
		my $s 		= $status->{text}; # Tweeted Text
		my @content = twitterBeautify($s);
		my $link 	= pop(@content);
		my $text 	= pop(@content);
		if (length($text) >= 10 ){
			writeHtml($text . "Link: $link" , TwitterHtml.$TimeStamp.".twitter-$input-page.html");		
		};
		
		my $newLink 	= extractLinks($link);
		next if (length($newLink)<5 || length($link)<5);
		#print "Twitter Text: $text -> $link \n";
		#print "#" x 23 . print "\nTWITTER (TRENDRANK CALCULATION): \n";
		
		my $trendrank 	= getTrendRank($newLink);
		my $debug 		= Dumper($status);
		writetoDatabase($source,$newLink,"",$s,"",$trendrank,$debug);
		
		print "Twitter [$trendrank]: $text -> $newLink\n";
		
		open(WF,"+>>$FoundOutFile");
			binmode(WF, ":utf8");
			print WF "Twitter [$trendrank]: $text -> $newLink\n";
		close WF;
	};
	
	return 1;
}

###
# Google Suche durchführen
###
sub googleParseSearch($)
{
	my $input 	= shift;
	my $source	= "google_cms";
	my $json 	= googleCustomSearch($input);
	my $gdata;
	my $hash;
	
	eval {
		$gdata 	= Google::Data::JSON->new(json => $json);
		$hash  	= $gdata->as_hash;
	};
	if (ref($hash) ne 'HASH' || $@ ){
		print "Google::Data::JSON JSON HASH Error\n";
		sleep 2;
		return;
	}
	#warn $@ if $@;
	
	my %hash 	= ();
	my $arrRef 	= $hash->{'results'};

	my $TimeStampv2	= do {
		my ($s,$m,$h,$D,$M,$Y)=localtime;
		$Y+=1900;
		$M++;
		"$Y-$M-$D-$h:$m:$s" 
	};
	
	
	writeHtml("<hr><h1><strong><b>Trending Google Keywords: $input<b><strong></h1><br /><br />", GoogleHtml.$TimeStampv2.".google-$input-page.html");	
	foreach my $hashref (@$arrRef) {

		my $resultUrl 	= $hashref->{unescapedUrl};
		my $title		= $hashref->{titleNoFormatting};
		my $text_content	= $hashref->{contentNoFormatting};
		my $content 	= "Title: " . $title . "<br>";
		$content 		.= "Content: " . $text_content . "<br>";
		$content 		.= "Url: " . makeLinkable($resultUrl) . "<br>";
		
		my $image		= $hashref->{richSnippet}->{cseImage}->{src};
		$content 		.= "Image: <img src=\"".$image."\" alt=\"search\" />" . "<br>";
		
		if ( !$Hash{$resultUrl} ) {
			$Hash{$resultUrl} = $resultUrl;
			writeHtml($content, GoogleHtml.$TimeStamp.".google-$input-page.html");		
		}
			
		# Trendrank berechnen von $resultUrl
		my $newLink 	= extractLinks($resultUrl);
		next if (length($newLink)<5 || length($resultUrl)<5);
		#print "#" x 23 . print "\nGOOGLE (TRENDRANK CALCULATION): \n";
		my $trendrank 	= getTrendRank($newLink);
		my $debug 		= Dumper($hashref);
		writetoDatabase($source,$newLink,$title,$text_content,$image,$trendrank,$debug);
		
		print "$TimeStampv2 - Google [$trendrank]: $title -> $newLink\n";
		open(WF,"+>>$FoundOutFile");
			binmode(WF, ":utf8");
			print WF "$TimeStampv2 - Google [$trendrank]: $title -> $newLink\n";
		close WF;
	}
	
	return 1;
}

###
# Ausgabe HTML Datei mit Trends drin schreiben
###
sub writeHtml($)
{
	my $input = shift;
	my $file = shift;
	
	open (OUT, "+>>$file");
		binmode(OUT, ":utf8");
		print OUT "$input<br><hr><br>\n";
	close OUT; 
	return;
}

###
# Google Custom Search Wert aus Konfigurationsdatei auslesen und mit Hilfe des übergebenen Keywortes HTTP Request für Suche stellen
###
sub googleCustomSearch($)
{
	my $input 	= shift;
	my $uri 	= $Google->{'custom_search_page'};
	return get($uri.$input);
}

###
# Aus einem Text- einen HTML Anker Link bilden
###
sub makeLinkable($)
{
	my $input = shift;
	$input =~ s[($RE{URI}{HTTP})][<a href="$1" target="_blank">$1</a>]g;
	return $input;
}

###
# HTTP GET Request senden
###
sub get($)
{
	my $input = shift;
	my $response 	= $UA->get($input);
	if ( $response->is_success ) {
		return $response->content;
	}
}

###
# Inhalt der Twitter Tweets ordentlich für Ausgabe formatieren
###
sub twitterBeautify($)
{
	my $input	= shift;
	my $link	= "";
	my @c 		= split(" ",$input);
	my $text	= "";
	foreach my $c (@c){
		$c = trim($c);
		next if ($c =~/\@/ig);		
		if ( $c =~ /^https?:\/\//ig ){
			#print "\tc found link=$c\n";
			$link = make_longlink($c);
			if ( $Hash{$link} ) {
				return "";
			} else {
				$Hash{$link} = $link;
			}
			#$text .= " ". makeLinkable($link). " ";
			#$text .= "$link ";
		} else {
			$text .= "$c ";
		}
	}
	my @a = ();
		push(@a, $text);
		push(@a, makeLinkable($link));
	return @a;
	#return "Content: ". $text."<br>\n";
}

###
# Aus einem kurzen Link von einem Linkverkürzer wieder den Original Link machen
###
sub make_longlink($)
{
	my $shortlink	= shift;
	my $response 	= $UA->head($shortlink);
	if ( $response->is_success ) {
		return $response->request->uri->as_string;
	}
}

###
# Zeichen Space entfernen
###
sub trim($)
{
	my $string = shift;
	$string =~ s/^\s+//;
	$string =~ s/\s+$//;
	return $string;
}


sub getTrendRank(){
	
	my $url 	= shift;
	next if (length($url)<10);
	
	open(W,"+>>$TrendRankOutFile");
	binmode(W, ":utf8");

	if ($url !~ /^https?/ig ){
		$url = "http://".$url;
	}
	#print "#" x 75;
	#print "\n";
	##print "Trend Rank der Webseite: $url\n"; 
	my $AlexaRank 		= checkAlexa($url);
	my $AlexaFactor 	= calcAlexaFactor($AlexaRank);
	##print "Alexa Rank: $AlexaRank -> Trend Factor: $AlexaFactor";	
	##print "\n";
	my $PageRank 		= checkGooglePR($url);	
	my $PageFactor 		= calcGoogleFactor($PageRank);
	##print "Google Page Rank: $PageRank -> Trend Factor: $PageFactor";	
	##print "\n";
	my $TwitterRank 	= checkTwitterLinks($url);	
	my $TwitterFactor 	= calcTwitterFactor($TwitterRank);
	##print "Anzahl Twitter Links: $TwitterRank -> Trend Factor: $TwitterFactor";	
	##print "\n";
	my $FacebookRank	= checkFacebookLikes($url);	
	my $FacebookFactor	= calcFacebookFactor($FacebookRank);
	##print "Anzahl Facebook Likes: $FacebookRank -> Trend Factor: $FacebookFactor";	
	##print "\n";
	my $DmozRank 		= checkDmoz($url);	
	my $DmozFactor 		= calcDmozFactor($DmozRank);
	##print "Dmoz.org Eintrag: $DmozRank -> Trend Factor: $DmozFactor";	
	##print "\n";
	my $SpeedRank 		= checkDownloadTime($url);	
	my $SpeedFactor		= calcSpeedFactor($SpeedRank);
	##print "Website Download Zeit: $SpeedRank -> Trend Factor: $SpeedFactor";	
	##print "\n";
	my $TrendRank 		= sprintf ("%.7f",$AlexaFactor+$PageFactor+$TwitterFactor+$FacebookFactor+$DmozFactor+$SpeedFactor);
	#print "TrendRank für '$url': '$TrendRank'";
	print W "Uri:$url\nTrendrank:$TrendRank\nFacebookRank:$FacebookRank\nTwitterRank:$TwitterRank\n";
	##print "\n";
	
	return $TrendRank;
} # sub getTrendRank(){


###
# Speed Teilnutzwert berechnen
###
sub calcSpeedFactor($)
{
	my $input = shift;
	my $factorVal;
	if ( $input <= 0.1 ) {
		$factorVal = 10;
	} elsif ( $input <= 0.13 ) {
		$factorVal = 9;
	} elsif ( $input <= 0.15 ) {
		$factorVal = 8;
	} elsif ( $input <= 0.18 ) {
		$factorVal = 7;
	} elsif ( $input <= 0.21 ) {
		$factorVal = 6;
	} elsif ( $input <= 0.25 ) {
		$factorVal = 5;
	} elsif ( $input <= 0.31 ) {
		$factorVal = 4;
	} elsif ( $input <= 0.35 ) {
		$factorVal = 3;
	} elsif ( $input <= 0.41 ) {
		$factorVal = 2;
	} elsif ( $input <= 0.45 ) {
		$factorVal = 1;
	} else {
		$factorVal = 1;
	}

	return sprintf ("%.7f",$factorVal*$SpeedGewichtungsfaktor);
}

###
# Dmoz Teilnutzwert berechnen
###
sub calcDmozFactor($)
{
	my $input = shift;
	return sprintf ("%.7f",$input*$DmozGewichtungsfaktor*7);
}

###
# Facebook Teilnutzwert berechnen
###
sub calcFacebookFactor($)
{
	my $input = shift;
	my $factorVal;
	if ( $input >= 0 && $input <= 25 ) {
		$factorVal = 1;
	} elsif ( $input >= 26 && $input <= 50 ) { 
		$factorVal = 2;
	} elsif ( $input >= 51 && $input <= 150 ) { 
		$factorVal = 3;
	} elsif ( $input >= 151 && $input <= 350 ) { 
		$factorVal = 4;
	} elsif ( $input >= 351 && $input <= 750 ) { 
		$factorVal = 5;
	} elsif ( $input >= 751 && $input <= 1500 ) { 
		$factorVal = 6;
	} elsif ( $input >= 1501 && $input <= 5000 ) { 
		$factorVal = 7;
	} elsif ( $input >= 5001 && $input <= 12000 ) { 
		$factorVal = 8;
	} elsif ( $input >= 12001 && $input <= 25000 ) { 
		$factorVal = 9;
	} elsif ( $input >= 25001 ) { 
		$factorVal = 10;
	} elsif ( $input == 0 ) { 
		$factorVal = 1;
	} else {
		$factorVal = 1;
	}
	return sprintf ("%.7f",$factorVal*$FacebookGewichtungsfaktor);
}

###
# Twitter Teilnutzwert berechnen
###
sub calcTwitterFactor($)
{
	my $input = shift;
	my $factorVal;
	if ( $input >= 0 && $input <= 25 ) {
		$factorVal = 1;
	} elsif ( $input >= 26 && $input <= 50 ) { 
		$factorVal = 2;
	} elsif ( $input >= 51 && $input <= 150 ) { 
		$factorVal = 3;
	} elsif ( $input >= 151 && $input <= 350 ) { 
		$factorVal = 4;
	} elsif ( $input >= 351 && $input <= 750 ) { 
		$factorVal = 5;
	} elsif ( $input >= 751 && $input <= 1500 ) { 
		$factorVal = 6;
	} elsif ( $input >= 1501 && $input <= 5000 ) { 
		$factorVal = 7;
	} elsif ( $input >= 5001 && $input <= 12000 ) { 
		$factorVal = 8;
	} elsif ( $input >= 12001 && $input <= 25000 ) { 
		$factorVal = 9;
	} elsif ( $input >= 25001 ) { 
		$factorVal = 10;
	} elsif ( $input == 0 ) { 
		$factorVal = 1;
	} else {
		$factorVal = 1;
	}
	return sprintf ("%.7f",$factorVal*$TwitterGewichtungsfaktor);
}

###
# Google PageRank Teilnutzwert berechnen
###
sub calcGoogleFactor($)
{
	my $input = shift;
	return sprintf ("%.7f",$input*$GooglePRGewichtungsfaktor);
}

###
# Alexa Teilnutzwert berechnen
###
sub calcAlexaFactor($)
{
	my $input = shift;
	my $factorVal;
	if ( $input >= 1 && $input <= 25 ) {
		$factorVal = 10;
	} elsif ( $input >= 26 && $input <= 50 ) { 
		$factorVal = 9;
	} elsif ( $input >= 51 && $input <= 150 ) { 
		$factorVal = 8;
	} elsif ( $input >= 151 && $input <= 350 ) { 
		$factorVal = 7;
	} elsif ( $input >= 351 && $input <= 750 ) { 
		$factorVal = 6;
	} elsif ( $input >= 751 && $input <= 1500 ) { 
		$factorVal = 5;
	} elsif ( $input >= 1501 && $input <= 5000 ) { 
		$factorVal = 4;
	} elsif ( $input >= 5001 && $input <= 12000 ) { 
		$factorVal = 3;
	} elsif ( $input >= 12001 && $input <= 25000 ) { 
		$factorVal = 2;
	} elsif ( $input >= 25001 ) { 
		$factorVal = 1;
	} elsif ( $input == 0 ) { 
		$factorVal = 1;
	} else {
		$factorVal = 1;
	}
	return sprintf ("%.7f",$factorVal*$AlexaGewichtungsfaktor);
}

###
# Domainnamen vom übergebenen URI einsammeln
###
sub getDomain($)
{
	my $input = shift;
	my $url = URI->new( $input );
	return $url->host;
}

###
# Download Zeitraum für Webseite messen
###
sub checkDownloadTime($)
{
	my $input 		= shift;
	my $prep_start 	= gettimeofday ;
	get($input);
	my $prep_end 	= gettimeofday;

	my $val = sprintf ("%.7f",$prep_end-$prep_start);
	return $val;
}

###
# Alexa Rank einer Webseite bestimmen
###
sub checkAlexa($)
{
	my $input 	= shift;
	my $dom		= getDomain($input);
	my $rank 	= $AlexaObject->get($dom);
	if ($rank !~ /\d/ig ){
		return 0;
	} else {
		return $rank;
	}
}
###
# Twitter Links einer URI bestimmen
###
sub checkGooglePR($)
{
	my $input 	= shift;
	my $dom		= getDomain($input);
	$dom 		= "http://".$dom;
	my $cv 		= AnyEvent->condvar;
	$cv->begin;	
	my $returnRank;
	$PageRankObject->get($dom, sub {
		my ($rank, $headers) = @_;
		#print "$url - ", defined($rank) ? $rank : "fail: $headers->{Status} - $headers->{Reason}", "\n";
		$returnRank = $rank;
		$cv->end;
	});
	$cv->recv;
	return $returnRank;
}

###
# Twitter Links einer Webseite bestimmen
###
sub checkTwitterLinks($)
{
	my $input 			= shift;
	my $twitterQuery 	= "http://urls.api.twitter.com/1/urls/count.json?url=".$input;   
	my $jsonContent		= get($twitterQuery);
	$jsonContent 		=~ /:(.*),/ig;
	return $1;
}

###
# Facebook Likes einer Webseite berechnen
###
sub checkFacebookLikes($)
{
	my $input 				= shift;
	my $facebookQuery 		= "select like_count from link_stat WHERE url ='" . $input ."'";
	my $facebookGraphQuery 	= "https://api.facebook.com/method/fql.query?query=".$facebookQuery."&format=json";
	my $jsonContent			= get($facebookGraphQuery);
	my (undef,$like_count)	= split(":",$jsonContent );
	$like_count 			=~ s/\D//ig;
	return $like_count;
}

###
# Dmoz.org Eintrag einer Webseite prüfen
###
sub checkDmoz($)
{
	return 0;
	my $input 			= shift;
	my $dom				= getDomain($input);
	my $dmozQuery 		= "http://www.dmoz.org/search?q=".$dom;
	my $dmozContent 	= get($dmozQuery);
	if ($dmozContent 	=~ m/<a href=\"$input/ig){
		return 1;
	} else {
		return 0;
	}

	return 0;
}


sub writetoDatabase(){
	sub getLM_Header($)
	{
		my $input = shift;
		my $response 	= $UA->head($input);
		if ( $response->is_success ) {
			return $response->last_modified();
		}
	}
	
	# PERL DBI CONNECT
	my $source 		= shift;
	my $url			= shift;
	my $title		= shift;
	my $content		= shift;
	my $image		= shift;
	my $trendrank	= shift;
	my $debug		= shift;
	
	if (!defined($image) || !$image || length($image) <=3){
		$image = "none";
	}
	
	my $now = do {
			my ($s,$m,$h,$D,$M,$Y)=localtime;
			$Y+=1900;
			$M++;
			"$Y-$M-$D $h:$m:$s" 
			};
	
	my $dbh = DBI->connect($dsn, "root", "###########99", {RaiseError => 0, PrintError => 1, mysql_enable_utf8 => 1, AutoCommit => 1} ) or warn "Unable to connect: $DBIconnect::errstr\n";

	my $lmh = getLM_Header($source);
	
	my $query = sprintf("%s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
		"INSERT INTO trendcrawler_v11 (aid, source, url, title, content, image, trendrank, datetime, lastmodified, debug) VALUES",
		$dbh->quote(""),
		$dbh->quote($source),
		$dbh->quote($url),
		$dbh->quote($title),
		$dbh->quote($content),
		$dbh->quote($image),
		$dbh->quote($trendrank),
		$dbh->quote($now),
		$dbh->quote($lmh),
		$dbh->quote($debug)
	);
		
	# prepare your statement for connecting to the database
	my $sth = $dbh->prepare($query);

	$sth->execute();# or warn $DBI::errstr;
	$sth->finish();
	$dbh->commit; # or warn $DBI::errstr;

	return 1;
}

sub extractLinks(){
	my $input 	= shift;
	my $LX 		= new HTML::LinkExtractor();
	$LX->parse(\$input);
	for my $Link( @{ $LX->links } ) {
		if (length($$Link{href})>4){
			return $$Link{href};
		}
	}
	return $input;
}