Deployment preparation for testbed
diff --git a/Makefile.PL b/Makefile.PL
index 792222c..ac97d41 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -18,6 +18,7 @@
     'Mojolicious' => '4.92',
     'Mojolicious::Plugin::TagHelpers::Pagination' => 0.01,
     'Mojolicious::Plugin::Notifications' => 0.03,
+    'Mojolicious::Plugin::CHI' => 0.09,
 #    'Mojolicious::Plugin::Search' => 0.01,
     'Mojolicious::Plugin::Number::Commify' => '0.022',
     'JSON::XS' => 0.0
diff --git a/korap.conf b/korap.conf
index 1e88892..7f6b63b 100644
--- a/korap.conf
+++ b/korap.conf
@@ -4,9 +4,17 @@
   },
   Notifications => {
     Alertify => 1,
+    Humane => 1,
     JSON => 1
   },
   Search => {
     engine => 'Korap::Plugin::KorapSearch'
+  },
+  CHI => {
+    default => {
+      driver => 'FastMmap',
+      root_dir => app->home . '/cache',
+      cache_size => '12m'
+    }
   }
 }
diff --git a/lib/Korap.pm b/lib/Korap.pm
index a1025d9..fbd7219 100644
--- a/lib/Korap.pm
+++ b/lib/Korap.pm
@@ -8,19 +8,30 @@
   my $self = shift;
 
   $self->plugin('Config');
+  $self->plugin('CHI');
   $self->plugin('TagHelpers::Pagination' => {
     prev => '<span><i class="fa fa-caret-left"></i></span>',
     next => '<span><i class="fa fa-caret-right"></i></span>',
-    ellipsis => '<span>&hellip;</span>',
+    ellipsis => '<span><i class="fa fa-ellipsis-h"></i></span>',
     separator => '',
     current => '<span>{current}</span>',
     page => '<span>{page}</span>'
   });
   $self->plugin('Notifications');
   $self->plugin('Number::Commify');
-
   push(@{$self->plugins->namespaces}, __PACKAGE__ . '::Plugin');
   $self->plugin('KorapSearch');
+  $self->plugin('KorapInfo');
+  $self->plugin('KorapTagHelpers');
+
+  $self->helper(
+    date_format => sub {
+      my ($c, $date) = @_;
+      return $date;
+    }
+  );
+
+  # TODO: Write search snippet
 
   # Routes
   my $r = $self->routes;
@@ -42,6 +53,10 @@
     }
   );
 
+  # Tutorial
+  $r->get('/tutorial')->to('tutorial#page')->name('tutorial');
+  $r->get('/tutorial/(*tutorial)')->to('tutorial#page');
+
   $r->get('/util/query')->to('search#query');
 
   $r->get('/:resource' => [qw/collection corpus/])->to('search#info');
@@ -51,6 +66,7 @@
   $r->get('/:resource/:cid', resource => [qw/collection corpus/])->search;
   $r->get('/:resource/')->search;
   # /matchInfo?id=...&f=&l=&spans
+
 };
 
 
diff --git a/lib/Korap/Plugin/KorapInfo.pm b/lib/Korap/Plugin/KorapInfo.pm
new file mode 100644
index 0000000..77a3061
--- /dev/null
+++ b/lib/Korap/Plugin/KorapInfo.pm
@@ -0,0 +1,41 @@
+package Korap::Plugin::KorapInfo;
+use Mojo::Base 'Mojolicious::Plugin';
+
+sub register {
+  my ($plugin, $mojo, $param) = @_;
+  $param ||= {};
+
+  # Load parameter from Config file
+  if (my $config_param = $mojo->config('KorAP')) {
+    $param = { %$param, %$config_param };
+  };
+
+  my $api = $param->{api};
+
+  # Todo: Make this recognize the user!
+  $mojo->helper(
+    info_on => sub {
+      my $c = shift;
+      my $src = shift;
+      $src = 'VirtualCollection' if $src eq 'collection';
+      $src = 'Corpus' if $src eq 'corpus';
+
+      my $url = Mojo::URL->new($api)->path('resource/' . $src);
+
+      my $chi = $c->chi;
+      if (my $json = $chi->get($url->to_string)) {
+	return $json;
+      }
+      elsif (my $response = $c->ua->get($url)->success) {
+	my $json = $response->json;
+	$c->chi->set($url->to_string => $json);
+	return $json;
+      };
+      $c->notify(error => 'Unable to retrieve resource');
+      return [];
+    }
+  );
+};
+
+
+1;
diff --git a/lib/Korap/Plugin/KorapMatchinfo.pm b/lib/Korap/Plugin/KorapMatchinfo.pm
new file mode 100644
index 0000000..6cd6a10
--- /dev/null
+++ b/lib/Korap/Plugin/KorapMatchinfo.pm
@@ -0,0 +1,44 @@
+package Korap::Plugin::KorapMatchInfo;
+use Mojo::Base 'Mojolicious::Plugin';
+
+sub register {
+  my ($plugin, $mojo, $param) = @_;
+  $param ||= {};
+
+  # Load parameter from Config file
+  if (my $config_param = $mojo->config('KorAP')) {
+    $param = { %$param, %$config_param };
+  };
+
+  my $api = $param->{api};
+
+  # Todo: Make this recognize the user!
+  $mojo->helper(
+    info_on => sub {
+      my $c = shift;
+      my $src = shift;
+
+/resource/matchInfo?id=match-WPD!WPD_TTT.07206-p151-152&f=treetagger&l=morpho&spans=true
+
+      $src = 'VirtualCollection' if $src eq 'collection';
+      $src = 'Corpus' if $src eq 'corpus';
+
+      my $url = Mojo::URL->new($api)->path('resource/' . $src);
+
+      my $chi = $c->chi;
+      if (my $json = $chi->get($url->to_string)) {
+	return $json;
+      }
+      elsif (my $response = $c->ua->get($url)->success) {
+	my $json = $response->json;
+	$c->chi->set($url->to_string => $json);
+	return $json;
+      };
+      $c->notify(error => 'Unable to retrieve resource');
+      return [];
+    }
+  );
+};
+
+
+1;
diff --git a/lib/Korap/Plugin/KorapSearch.pm b/lib/Korap/Plugin/KorapSearch.pm
index a6aaac1..b57e608 100644
--- a/lib/Korap/Plugin/KorapSearch.pm
+++ b/lib/Korap/Plugin/KorapSearch.pm
@@ -1,8 +1,10 @@
 package Korap::Plugin::KorapSearch;
 use Mojo::Base 'Mojolicious::Plugin';
+use Mojo::JSON qw/decode_json/;
 use Mojo::ByteStream 'b';
 
 # TODO: This will probably be an engine for M::P::Search
+# cutoff has to be true or false
 
 sub register {
   my ($plugin, $mojo, $param) = @_;
@@ -24,6 +26,23 @@
 
       my %param = @_;
 
+      # Test envronment
+#      if ($c->app->mode eq 'test') {
+#	my $json = b(join(' ', <DATA>))->encode;
+#	$json = decode_json($json);
+#
+#	$c->stash('search.count' => 10);
+#	$c->stash('search.startPage' => 1);
+#	$c->stash('search.totalResults' => 666);
+#	$c->stash('search.itemsPerPage' => 10);
+#	$_->{'search.bm.hit'} = 20;
+#	$_->{'search.bm.result'} = 10;
+#	$_->{'search.query'} = $json->{request}->{query};
+#	$_->{'search.hits'} = $json->{matches};
+#	return $cb->();
+#      };
+
+
       $c->stash(
 	'search.count' =>
 	  delete($param{count}) //
@@ -60,29 +79,43 @@
 
       my %query = (q => $query);
       $query{ql} = scalar $c->param('ql') // 'poliqarp';
-      $query{startPage} = $start_page if $start_page;
       $query{count} = $count if $count;
 
-      $query{lctx} = 'chars';
-      $query{lctxs} = 120;
-      $query{rctx} = 'chars';
-      $query{rctxs} = 120;
-
-      $query{cutoff} = $param{cutoff} // $c->param('cutoff');
-
-
       $url->query(\%query);
+      my $cache_url = $url->to_string;
 
-      $c->stash('search.totalResults' => 0);
+      $url->query({ctx => 'paragraph'});
+
+      # Check cache for total results
+      my $total_results = $c->chi->get('total-' . $cache_url);
+      if (defined $total_results) {
+	$c->stash('search.totalResults' => $total_results);
+	$c->app->log->warn('Get total result from cache');
+	$url->query({cutoff => 'true'});
+	$url->query({cutOff => 'true'});
+      }
+      else {
+	$c->stash('search.totalResults' => 0);
+      };
+
+      $url->query({page => $start_page});
+
       $c->stash('search.itemsPerPage' => $count);
 
       my $ua = Mojo::UserAgent->new($url);
       $c->app->log->debug($url->to_string);
 
+      $c->app->log->debug("Start tx");
+
       # Blocking request
       # TODO: Make non-blocking
       my $tx = $ua->get($url);
 
+      if (my $e = $tx->error) {
+	$c->notify(error => $e->{code} . ': ' . $e->{message} . ' (remote)');
+	return;
+      };
+
       # Request successful
       if (my $res = $tx->success) {
 	my $json = $res->json;
@@ -103,7 +136,12 @@
 	  $_->{'search.itemsPerPage'} = $json->{itemsPerPage};
 	  $_->{'search.query'}        = $json->{request}->{query};
 	  $_->{'search.hits'}         = $json->{matches};
-	  $_->{'search.totalResults'} = $json->{totalResults};
+	};
+
+	if ($json->{totalResults} > -1) {
+	  $c->app->log->warn('Set total result from cache');
+	  $c->stash('search.totalResults' => $json->{totalResults});
+	  $c->chi->set('total-' . $cache_url => $json->{totalResults}, '30min');
 	};
 
 	if ($json->{error}) {
@@ -114,7 +152,7 @@
       # Request failed
       else {
 	my $res = $tx->res;
-	$c->notify('error' =>  $res->code . ': ' . $res->message);
+	$c->notify('error' =>  $res->{code} . ': ' . $res->{message} . ' (remote)');
       };
 
       # Run embedded template
@@ -159,3 +197,390 @@
 
 
 1;
+
+__DATA__
+{
+  "query" : "tokens:mate/l:baum",
+  "matches" : [ {
+    "author" : "Peter200,Srittau,AHoerstemeier",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Palm Beach Gardens",
+    "foundries" : "corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 xip xip/morpho xip/constituency xip/dependency treetagger treetagger/morpho connexor connexor/morpho connexor/syntax connexor/phrase mate mate/morpho mate/dependency opennlp opennlp/morpho base base/sentences base/paragraphs",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_PPP.00430",
+    "snippet" : "<span class=\"context-left\">MacArtur stellte sich die Straßen der Stadt links und rechts gesäümt mit Blumen und </span><span class=\"match\">Bäumen</span><span class=\"context-right\"> vor. Millionen von USD wurden dafür verwendet um dies zu ermöglichen. Letztlich wurde an allen Straßen und Wasserstraßen mächtige Kiefern und andere schattenspendende Laubbäume gepflanzt. Da er ein Naturliebhaber war, mussten alle älteren Bäume stehen bleiben und Straßen darum herum geführt werden. Für die damalige Zeit für Amerika eine total neue Erfahrung. Dies verteuerte das Bauvorhaben erheblich, aber MacArthur ließ sich nicht beirren. Ebenso waren die ersten Gebäude, die gebaut wurden, Kirchen der verschiedensten Konfessionen, um sicher zu stellen, dass jeder Mensch nach seinem Glauben leben konnte.</span>",
+    "ID" : "match-WPD!WPD_PPP.00430-p189-190",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Peter200,Srittau,AHoerstemeier",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Palm Beach Gardens",
+    "foundries" : "corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 xip xip/morpho xip/constituency xip/dependency treetagger treetagger/morpho connexor connexor/morpho connexor/syntax connexor/phrase mate mate/morpho mate/dependency opennlp opennlp/morpho base base/sentences base/paragraphs",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_PPP.00430",
+    "snippet" : "<span class=\"context-left\">MacArtur stellte sich die Straßen der Stadt links und rechts gesäümt mit Blumen und Bäumen vor. Millionen von USD wurden dafür verwendet um dies zu ermöglichen. Letztlich wurde an allen Straßen und Wasserstraßen mächtige Kiefern und andere schattenspendende Laubbäume gepflanzt. Da er ein Naturliebhaber war, mussten alle älteren </span><span class=\"match\">Bäume</span><span class=\"context-right\"> stehen bleiben und Straßen darum herum geführt werden. Für die damalige Zeit für Amerika eine total neue Erfahrung. Dies verteuerte das Bauvorhaben erheblich, aber MacArthur ließ sich nicht beirren. Ebenso waren die ersten Gebäude, die gebaut wurden, Kirchen der verschiedensten Konfessionen, um sicher zu stellen, dass jeder Mensch nach seinem Glauben leben konnte.</span>",
+    "ID" : "match-WPD!WPD_PPP.00430-p223-224",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Kdwnv,Doc Sleeve,Ninjamask",
+    "textClass" : "kultur film",
+    "corpusID" : "WPD",
+    "title" : "Mein Nachbar Totoro",
+    "foundries" : "opennlp opennlp/morpho treetagger treetagger/morpho xip xip/morpho xip/constituency xip/dependency connexor connexor/morpho connexor/syntax connexor/phrase corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 base base/sentences base/paragraphs mate mate/morpho mate/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_MMM.04644",
+    "snippet" : "<span class=\"context-left\">Ein Vater zieht mit seinen zwei Töchtern aufs Land, um in der Nähe seiner Frau sein zu können, die sich in einem Hospital von einer schweren Krankheit erholt. Nachdem sich die drei in dem anfangs etwas gruseligen Haus eingewöhnt haben, begegnet das jüngere Mädchen dem </span><span class=\"match\">Baum-</span><span class=\"context-right\"> und Naturgeist Totoro, und beide Mädchen schließen mit dem seltsamen Wesen schnell Freundschaft. Als sich das kleine Mädchen schließlich alleine aufmacht, um seine Mutter zu besuchen, hilft Totoro der älteren Schwester, die Ausreißerin wieder zu finden...</span>",
+    "ID" : "match-WPD!WPD_MMM.04644-p94-95",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Nordelch,0",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Norra Kvill Nationalpark",
+    "foundries" : "mate mate/morpho mate/dependency base base/sentences base/paragraphs opennlp opennlp/morpho treetagger treetagger/morpho xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_NNN.05211",
+    "snippet" : "<span class=\"context-left\">Norra Kvill ist ein schwedischer Nationalpark der aus einem urwaldartigen Nadelwald im Hochland von Småland besteht. Seit über 150 Jahren wurde hier kein </span><span class=\"match\">Baum</span><span class=\"context-right\"> gefällt und manche Kiefern sind 350 Jahre alt, 35 m hoch und haben einen Umfang von 250 cm. Der wildnisartige Charakter entsteht durch umgefallene Bäume und gigantische Steinblöcke. Am Waldboden existiert eine reichhaltige Flora. 1986 wurde die Fläche des Nationalparks erweitert.</span>",
+    "ID" : "match-WPD!WPD_NNN.05211-p23-24",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Nordelch,0",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Norra Kvill Nationalpark",
+    "foundries" : "mate mate/morpho mate/dependency base base/sentences base/paragraphs opennlp opennlp/morpho treetagger treetagger/morpho xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_NNN.05211",
+    "snippet" : "<span class=\"context-left\">Norra Kvill ist ein schwedischer Nationalpark der aus einem urwaldartigen Nadelwald im Hochland von Småland besteht. Seit über 150 Jahren wurde hier kein Baum gefällt und manche Kiefern sind 350 Jahre alt, 35 m hoch und haben einen Umfang von 250 cm. Der wildnisartige Charakter entsteht durch umgefallene </span><span class=\"match\">Bäume</span><span class=\"context-right\"> und gigantische Steinblöcke. Am Waldboden existiert eine reichhaltige Flora. 1986 wurde die Fläche des Nationalparks erweitert.</span>",
+    "ID" : "match-WPD!WPD_NNN.05211-p48-49",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Vith-gilles,Head,Srbauer",
+    "textClass" : "wissenschaft populaerwissenschaft freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Rheindahlen",
+    "foundries" : "opennlp opennlp/morpho base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency treetagger treetagger/morpho mate mate/morpho mate/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_RRR.04289",
+    "snippet" : "<span class=\"context-left\">Der Stadtteil Rheindahlen besteht aus folgenden Honschaften: Bau, </span><span class=\"match\">Baum</span><span class=\"context-right\">, Broich, Dorthausen, Eickelnberg, Gatzweiler, Genhausen, Genhodder, Genholland, Genhülsen, Gerkerath, Gerkerathmühle, Gerkerathwinkel, Griesbarth, Grotherath, Günhoven, Herdt, Hilderath, Knoor, Koch, Kothausen, Mennrath, Mennrathheide, Mennrathschmidt, Merreter, Peel, Saas, Schriefers, Schriefersmühle, Sittard, Sittardheide, Viehstrasse, Voosen, Wolfsittard, Woof, Wyenhütte und Rheindahlen.</span>",
+    "ID" : "match-WPD!WPD_RRR.04289-p99-100",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "OTTO.R.M.,Factumquintus,Necrophorus",
+    "textClass" : "wissenschaft populaerwissenschaft",
+    "corpusID" : "WPD",
+    "title" : "Chamäleons",
+    "foundries" : "base base/sentences base/paragraphs opennlp opennlp/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho connexor connexor/morpho connexor/syntax connexor/phrase xip xip/morpho xip/constituency xip/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_CCC.02337",
+    "snippet" : "<span class=\"context-left\">Sie sind </span><span class=\"match\">baum-</span><span class=\"context-right\"> oder strauchbewohnende, und zum Teil auch Erdbewohnende Echsen mit einem seitlich abgeflachten Rumpf. Ein charakteristisches Merkmal dieser Tiere ist die herausschleuderbare Zunge, der Schwanz, der eingerollt werden kann und die Augen, die sich unabhängig voneinander bewegen und gemeinsam ein Blickfeld von 342° ermöglichen.</span>",
+    "ID" : "match-WPD!WPD_CCC.02337-p37-38",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "ErikDunsing,Raymond,NiKo",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Moerser Schloss",
+    "foundries" : "treetagger treetagger/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase xip xip/morpho xip/constituency xip/dependency mate mate/morpho mate/dependency opennlp opennlp/morpho base base/sentences base/paragraphs",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_MMM.08381",
+    "snippet" : "<span class=\"context-left\">Der östliche Teil des Schlosses wurde abgerissen und eine Windmühle sowie ein Wohnhaus sollten dort gebaut werden. Durch Probleme der Besitzverhältnisse der zum Schlosskauf gehörenden Grundstücke wurde es 1810 wieder weiterverkauft. Der Textilunternehmer Witgens, welcher der bedeutendste Unternehmer in Moers war, kaufte es für 2000 Franc. Er hatte schon zuvor in die östlich des Schlosses gelegenen Gebäude Wohnhaus und Fabrik gebaut. Die inneren Festungsanlagen wurden abgerissen und mit </span><span class=\"match\">Bäumen</span><span class=\"context-right\"> bepflanzt. Teile des Schlossgrundstückes wurden verkauft und von den neuen Besitzern in Gärten und Parkanlagen umgewandelt. Witgens ließ die mit Gräben durchzogene Wildnis 1838 in den heutigen Schlosspark umbauen. Das Schloss und der Park gingen 1905 in die Hand der Stadt über, die sie heute noch besitzt.</span>",
+    "ID" : "match-WPD!WPD_MMM.08381-p1449-1450",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "ErikDunsing,Raymond,NiKo",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Moerser Schloss",
+    "foundries" : "treetagger treetagger/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase xip xip/morpho xip/constituency xip/dependency mate mate/morpho mate/dependency opennlp opennlp/morpho base base/sentences base/paragraphs",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_MMM.08381",
+    "snippet" : "<span class=\"context-left\">Seit der Schleifung der Festungsanlagen durch Friedrich den Großen im Jahre 1762 waren die Festungsinsel und die einstigen Steinwälle und Gräben immer mehr verkommen. Dorngestrüpp wucherte über der verfallenen Insel und der Moerser Bürger mied es, dort entlang zu wandern. Nur vereinzelte Ziegenherden, die anspruchslos genug waren, wurden zum Grasen in die Wildnis geschickt. Wintgens, der den größten Teil der Anlage bereits gekauft hatte, ließ die Wildnis in einen Schlosspark, den heutigen Stadtpark, umbauen. Eigens zu diesem Zwecke ließ er den Hofarchitekten Maximilian Weyhe aus Düsseldorf kommen. Dieser hatte schon einige bedeutende Parkanlagen gestaltet, sein Abbild ist heute auf einer Bronzeplatte im Stadtpark verewigt. Weyhe wollte aber keinen Park in barocken geometrischen Formen bauen. Der Geschmack der Zeit war viel mehr hin zum Naturpark gewandert. Man legte Wert auf runde Formen, wilde freie </span><span class=\"match\">Bäume</span><span class=\"context-right\"> und große Steine im Park. Alles sollte natürlich wirken und nicht mit dem Zeichenbrett konstruiert. Weyhe ließ sogar eine beträchtliche Anzahl an exotischen Bäumen pflanzen. Interessant ist auch, dass er eine Turmruine anlegen ließ, da dies zu dieser Zeit als &quot;schick&quot; im Garten galt (genau wie Säulen oder Ähnliches). Auch wurden die Wasserläufe gekonnt in die Anlage integriert, und auf den einstigen Verteidigungswällen und Dämmen wurden Wege angelegt, die der Moerser Bürger heute noch gerne für einen Spaziergang durch den wunderbaren Park nutzt. Erstmals konnte der Bürger den Park jedoch im Jahre 1905 betreten, denn in diesem Jahre fiel der Besitz des Schlosses und des Parks in die Hände der Stadt Moers.</span>",
+    "ID" : "match-WPD!WPD_MMM.08381-p2076-2077",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "ErikDunsing,Raymond,NiKo",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Moerser Schloss",
+    "foundries" : "treetagger treetagger/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase xip xip/morpho xip/constituency xip/dependency mate mate/morpho mate/dependency opennlp opennlp/morpho base base/sentences base/paragraphs",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_MMM.08381",
+    "snippet" : "<span class=\"context-left\">Seit der Schleifung der Festungsanlagen durch Friedrich den Großen im Jahre 1762 waren die Festungsinsel und die einstigen Steinwälle und Gräben immer mehr verkommen. Dorngestrüpp wucherte über der verfallenen Insel und der Moerser Bürger mied es, dort entlang zu wandern. Nur vereinzelte Ziegenherden, die anspruchslos genug waren, wurden zum Grasen in die Wildnis geschickt. Wintgens, der den größten Teil der Anlage bereits gekauft hatte, ließ die Wildnis in einen Schlosspark, den heutigen Stadtpark, umbauen. Eigens zu diesem Zwecke ließ er den Hofarchitekten Maximilian Weyhe aus Düsseldorf kommen. Dieser hatte schon einige bedeutende Parkanlagen gestaltet, sein Abbild ist heute auf einer Bronzeplatte im Stadtpark verewigt. Weyhe wollte aber keinen Park in barocken geometrischen Formen bauen. Der Geschmack der Zeit war viel mehr hin zum Naturpark gewandert. Man legte Wert auf runde Formen, wilde freie Bäume und große Steine im Park. Alles sollte natürlich wirken und nicht mit dem Zeichenbrett konstruiert. Weyhe ließ sogar eine beträchtliche Anzahl an exotischen </span><span class=\"match\">Bäumen</span><span class=\"context-right\"> pflanzen. Interessant ist auch, dass er eine Turmruine anlegen ließ, da dies zu dieser Zeit als &quot;schick&quot; im Garten galt (genau wie Säulen oder Ähnliches). Auch wurden die Wasserläufe gekonnt in die Anlage integriert, und auf den einstigen Verteidigungswällen und Dämmen wurden Wege angelegt, die der Moerser Bürger heute noch gerne für einen Spaziergang durch den wunderbaren Park nutzt. Erstmals konnte der Bürger den Park jedoch im Jahre 1905 betreten, denn in diesem Jahre fiel der Besitz des Schlosses und des Parks in die Hände der Stadt Moers.</span>",
+    "ID" : "match-WPD!WPD_MMM.08381-p2100-2101",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Gabor,Asb,ChristophDemmer",
+    "textClass" : "wissenschaft populaerwissenschaft",
+    "corpusID" : "WPD",
+    "title" : "Ramismus",
+    "foundries" : "corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 base base/sentences base/paragraphs opennlp opennlp/morpho treetagger treetagger/morpho mate mate/morpho mate/dependency xip xip/morpho xip/constituency xip/dependency connexor connexor/morpho connexor/syntax connexor/phrase",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_RRR.00717",
+    "snippet" : "<span class=\"context-left\">Siehe auch: Ramifizierung, Ramifikation, Organon, Kategorienlehre, </span><span class=\"match\">Baum</span><span class=\"context-right\"> des Wissens, Arbor porphyriana, Philippismus, Neuaristotelismus, Melanchthonismus, Calvinismus, Reformation</span>",
+    "ID" : "match-WPD!WPD_RRR.00717-p159-160",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Martin-vogel,Sybilla,Gorgodon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Khasi",
+    "foundries" : "base base/sentences base/paragraphs connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_KKK.03618",
+    "snippet" : "<span class=\"context-left\">nur alleinstehende </span><span class=\"match\">Bäume</span><span class=\"context-right\"> dürfen geschlagen werden, keine Bäume aus einem Wald heraus</span>",
+    "ID" : "match-WPD!WPD_KKK.03618-p830-831",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Martin-vogel,Sybilla,Gorgodon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Khasi",
+    "foundries" : "base base/sentences base/paragraphs connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_KKK.03618",
+    "snippet" : "<span class=\"context-left\">nur alleinstehende Bäume dürfen geschlagen werden, keine </span><span class=\"match\">Bäume</span><span class=\"context-right\"> aus einem Wald heraus</span>",
+    "ID" : "match-WPD!WPD_KKK.03618-p835-836",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Stechlin,Orchi,Vlado",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Waldvöglein",
+    "foundries" : "xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase mate mate/morpho mate/dependency base base/sentences base/paragraphs treetagger treetagger/morpho opennlp opennlp/morpho",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_WWW.00689",
+    "snippet" : "<span class=\"context-left\">Cephalanthera schaberi </span><span class=\"match\">Baum</span><span class=\"context-right\">.</span>",
+    "ID" : "match-WPD!WPD_WWW.00689-p158-159",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Boris Kaiser,Plattmaster,Semon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Unterliek",
+    "foundries" : "connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_UUU.01708",
+    "snippet" : "<span class=\"context-left\">Befindet sich das Unterliek an einem </span><span class=\"match\">Baum</span><span class=\"context-right\"> (z.B. beim Großsegel), spricht man auch von dem Baumliek. Dessen Spannung, d.h. der Zug, unter dem das Segeltuch im Bereich des Unterlieks steht, wird über den Unterliekstrecker (eine Leine) gesteuert, der am Schothorn befestigt wird. Wird der Unterliekstrecker stark durchgesetzt (d.h. viel Zug mit dieser Leine ausgeübt), erhält das Unterliek ein flaches Profil (d.h. ist bei seitlichem Winddruck wenig gewölbt).</span>",
+    "ID" : "match-WPD!WPD_UUU.01708-p25-26",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Boris Kaiser,Plattmaster,Semon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Unterliek",
+    "foundries" : "connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_UUU.01708",
+    "snippet" : "<span class=\"context-left\">Man kann ein Segel an einem </span><span class=\"match\">Baum</span><span class=\"context-right\"> mit losem Unterliek fahren (z.B. bei Rollgroßanlagen): Dann ist das Segel im Bereich des Unterlieks nur am Hals und Schothorn mit dem Baum verbunden. Oder das Unterliek ist auf seiner ganzen Länge am Baum befestigt. Dies geschieht häufig, indem in das Unterliek zur Verdickung desselben ein Tau eingenäht wird und dieses dann in eine Keep (d.h. eine Nut) im Baum eingeführt wird.</span>",
+    "ID" : "match-WPD!WPD_UUU.01708-p92-93",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Boris Kaiser,Plattmaster,Semon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Unterliek",
+    "foundries" : "connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_UUU.01708",
+    "snippet" : "<span class=\"context-left\">Man kann ein Segel an einem Baum mit losem Unterliek fahren (z.B. bei Rollgroßanlagen): Dann ist das Segel im Bereich des Unterlieks nur am Hals und Schothorn mit dem </span><span class=\"match\">Baum</span><span class=\"context-right\"> verbunden. Oder das Unterliek ist auf seiner ganzen Länge am Baum befestigt. Dies geschieht häufig, indem in das Unterliek zur Verdickung desselben ein Tau eingenäht wird und dieses dann in eine Keep (d.h. eine Nut) im Baum eingeführt wird.</span>",
+    "ID" : "match-WPD!WPD_UUU.01708-p115-116",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Boris Kaiser,Plattmaster,Semon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Unterliek",
+    "foundries" : "connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_UUU.01708",
+    "snippet" : "<span class=\"context-left\">Man kann ein Segel an einem Baum mit losem Unterliek fahren (z.B. bei Rollgroßanlagen): Dann ist das Segel im Bereich des Unterlieks nur am Hals und Schothorn mit dem Baum verbunden. Oder das Unterliek ist auf seiner ganzen Länge am </span><span class=\"match\">Baum</span><span class=\"context-right\"> befestigt. Dies geschieht häufig, indem in das Unterliek zur Verdickung desselben ein Tau eingenäht wird und dieses dann in eine Keep (d.h. eine Nut) im Baum eingeführt wird.</span>",
+    "ID" : "match-WPD!WPD_UUU.01708-p126-127",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Boris Kaiser,Plattmaster,Semon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Unterliek",
+    "foundries" : "connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_UUU.01708",
+    "snippet" : "<span class=\"context-left\">Man kann ein Segel an einem Baum mit losem Unterliek fahren (z.B. bei Rollgroßanlagen): Dann ist das Segel im Bereich des Unterlieks nur am Hals und Schothorn mit dem Baum verbunden. Oder das Unterliek ist auf seiner ganzen Länge am Baum befestigt. Dies geschieht häufig, indem in das Unterliek zur Verdickung desselben ein Tau eingenäht wird und dieses dann in eine Keep (d.h. eine Nut) im </span><span class=\"match\">Baum</span><span class=\"context-right\"> eingeführt wird.</span>",
+    "ID" : "match-WPD!WPD_UUU.01708-p152-153",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Boris Kaiser,Plattmaster,Semon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Unterliek",
+    "foundries" : "connexor connexor/morpho connexor/syntax connexor/phrase opennlp opennlp/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_UUU.01708",
+    "snippet" : "<span class=\"context-left\">Wird das Segel ohne </span><span class=\"match\">Baum</span><span class=\"context-right\"> gefahren (z.B: Fock oder Genua bei Amwindkursen), wird die Schot direkt am Schothorn befestigt. Die Profilierung des Unterlieks, d.h. ob es flacher oder gewölbter ist, wird dann über den Zug der Schot und die Lage des Holepunktes gesteuert.</span>",
+    "ID" : "match-WPD!WPD_UUU.01708-p159-160",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Crux,Vic Fontaine,BS Thurner Hof",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Ananasrenette",
+    "foundries" : "connexor connexor/morpho connexor/syntax connexor/phrase base base/sentences base/paragraphs corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency treetagger treetagger/morpho xip xip/morpho xip/constituency xip/dependency opennlp opennlp/morpho",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_AAA.07202",
+    "snippet" : "<span class=\"context-left\">Die Früchte der Ananasrenette mit ihrem besonderem, sortentypischen Aroma bleiben eher klein. Sie reifen Mitte bis Ende Oktober und bleiben bei entsprechender Lagerung bis Februar genussreif. Der </span><span class=\"match\">Baum</span><span class=\"context-right\"> ist anfällig für Mehltau und Obstbaumkrebs und reagiert auf trockene Witterungsverhältnisse mit der Ausbildung sehr kleiner, wenig aromatischer Früchte.</span>",
+    "ID" : "match-WPD!WPD_AAA.07202-p78-79",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Feinschreiber,Triebtäter,Stefan Kühn",
+    "textClass" : "sport fussball",
+    "corpusID" : "WPD",
+    "title" : "Anita Kulcsár",
+    "foundries" : "xip xip/morpho xip/constituency xip/dependency mate mate/morpho mate/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 opennlp opennlp/morpho base base/sentences base/paragraphs connexor connexor/morpho connexor/syntax connexor/phrase treetagger treetagger/morpho",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_KKK.10701",
+    "snippet" : "<span class=\"context-left\">Anita Kulcsár war am Morgen des 19. Januar 2005 von ihrer Wohnung in Sukoró aus unterwegs zum Vormittagstraining nach Dunaújváros. Auf der Landstraße 6207 zwischen Velence und Pusztaszabolcs kam sie auf der glatten Fahrbahn ins Schleudern. Der Wagen kam von der Straße ab und prallte unkontrolliert gegen einen </span><span class=\"match\">Baum</span><span class=\"context-right\">. Sie starb sofort am Unfallort.</span>",
+    "ID" : "match-WPD!WPD_KKK.10701-p193-194",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Franz Xaver,Rosenzweig,Naddy",
+    "textClass" : "wissenschaft populaerwissenschaft",
+    "corpusID" : "WPD",
+    "title" : "Bussardartige",
+    "foundries" : "base base/sentences base/paragraphs xip xip/morpho xip/constituency xip/dependency mate mate/morpho opennlp opennlp/morpho treetagger treetagger/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 connexor connexor/morpho connexor/syntax connexor/phrase",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_BBB.15757",
+    "snippet" : "<span class=\"context-left\">Die Flugfähigkeit der Bussardartigen ist wesentlich schwerfälliger als die der wendigen Habichte oder Falken. Dafür ist ihr Körperbau besonders gut für lange Gleitflüge geeignet. Außerdem sind sie in der Wahl ihres Futters anpassungsfähig. In der Regel werden kleine bis mittlere Säugetiere, von manchen Arten (beispielsweise dem Seeadler (Haliaeetus)) Fische oder Wasservögel gejagt. Der südostasiatische Affenadler (Pithecophaga jefferyi) oder der südamerikanische Würgadler (Morphnus guianensis) jagen auch in </span><span class=\"match\">Bäumen</span><span class=\"context-right\"> lebende Affen und Vögel.</span>",
+    "ID" : "match-WPD!WPD_BBB.15757-p162-163",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Steschke,Asb,Paethon",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Kudzu (Pflanze)",
+    "foundries" : "base base/sentences base/paragraphs opennlp opennlp/morpho mate mate/morpho mate/dependency connexor connexor/morpho connexor/syntax connexor/phrase xip xip/morpho xip/constituency xip/dependency treetagger treetagger/morpho corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_KKK.10525",
+    "snippet" : "<span class=\"context-left\">Leider fand Kudzu im Südosten sehr gute Wachstumsbedingungen und ohne die natürlichen Feinde die in Japan vorkommen breitete er sich explosionsartig aus. Heute sind ca. 30.000 km² von Kudzu überwuchert und man wird der Plage, wegen der enormen Wachstumsgeschwindigkeit von bis zu 30cm am Tag, kaum noch Herr. Die Pflanze überwuchert in kürzester Zeit Häuser, </span><span class=\"match\">Bäume</span><span class=\"context-right\"> und alles was ihr im Weg steht. Sie kann (wenn sie nicht bekämpft wird) innerhalb weniger Monate ein Haus komplett überwuchern.</span>",
+    "ID" : "match-WPD!WPD_KKK.10525-p136-137",
+    "pubDate" : "2005-03-28"
+  }, {
+    "author" : "Filzstift,Alexander Sommer,TheK",
+    "textClass" : "freizeit-unterhaltung reisen",
+    "corpusID" : "WPD",
+    "title" : "Neuseeland",
+    "foundries" : "xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency connexor connexor/morpho connexor/syntax connexor/phrase treetagger treetagger/morpho base base/sentences base/paragraphs opennlp opennlp/morpho",
+    "tokenization" : "opennlp#tokens",
+    "field" : "tokens",
+    "startMore" : true,
+    "endMore" : true,
+    "docID" : "WPD_NNN.02848",
+    "snippet" : "<span class=\"context-left\">Als die Europäer ins Land kamen, waren etwa 70 % der Landesfläche bewaldet. Mittlerweile sind noch etwa 15 % des Landes von einheimischen Wäldern bedeckt, dazu kommen weitere etwa 5 % Fläche mit schnellwachsenden importierten </span><span class=\"match\">Bäumen</span><span class=\"context-right\"> wie Monterey Pine und Redwood für die neuseeländische Forstwirtschaft. Wesentliche Teile der ursprünglichen Wälder stehen unter Naturschutz, zu guten Teilen in Nationalparks und so genannten Forest Parks.</span>",
+    "ID" : "match-WPD!WPD_NNN.02848-p1139-1140",
+    "pubDate" : "2005-03-28"
+  } ],
+  "totalResults" : 4053,
+  "startIndex" : 0,
+  "itemsPerPage" : 25,
+  "benchmarkSearchResults" : "6.02 ms",
+  "benchmarkHitCounter" : "6.795 ms",
+  "error" : null,
+  "request" : {
+    "@context" : "http://ids-mannheim.de/ns/KorAP/json-ld/v0.1/context.jsonld",
+    "query" : {
+      "@type" : "korap:token",
+      "wrap" : {
+        "@type" : "korap:term",
+        "key" : "baum",
+        "layer" : "lemma",
+        "match" : "match:eq"
+      }
+    },
+    "collections" : [ {
+      "@type" : "korap:meta-filter",
+      "@value" : {
+        "@type" : "korap:term",
+        "@field" : "korap:field#corpusID",
+        "@value" : "WPD"
+      }
+    } ],
+    "meta" : {
+      "startPage" : 1,
+      "context" : "paragraph"
+    }
+  },
+  "context" : "p"
+}
diff --git a/lib/Korap/Plugin/KorapTagHelpers.pm b/lib/Korap/Plugin/KorapTagHelpers.pm
new file mode 100644
index 0000000..b54161c
--- /dev/null
+++ b/lib/Korap/Plugin/KorapTagHelpers.pm
@@ -0,0 +1,20 @@
+package Korap::Plugin::KorapTagHelpers;
+use Mojo::Base 'Mojolicious::Plugin';
+use Mojo::ByteStream 'b';
+use Mojo::Util qw/xml_escape/;
+
+sub register {
+  my ($plugin, $mojo) = @_;
+
+  $mojo->helper(
+    korap_tut_query => sub {
+      my ($c, $ql, $q) = @_;
+      $q = xml_escape $q;
+      b('<code class="query tutorial" onclick="top.useQuery(this)" ' .
+	  qq!data-query="$q" data-query-language="$ql"><pre>! .
+	    $q . '</pre></code>');
+    }
+  );
+};
+
+1;
diff --git a/lib/Korap/Search.pm b/lib/Korap/Search.pm
index 4773649..fd9e6d5 100644
--- a/lib/Korap/Search.pm
+++ b/lib/Korap/Search.pm
@@ -4,8 +4,10 @@
 # This action will render a template
 sub remote {
   my $c = shift;
+  $c->layout('default');
+  $c->title('KorAP');
 
-  if ($c->param('action') eq 'inspect') {
+  if ((scalar $c->param('action') // '') eq 'inspect') {
     my $api = $c->config('KorAP')->{api};
     my $url = Mojo::URL->new($api)->path('resource/query');
     $url->query({
@@ -20,29 +22,29 @@
     };
 
     $c->param(cutoff => 1);
-    return $c->render(template => 'query', layout => 'default', title => 'KorAP');
+    return $c->render(template => 'query');
+  }
+
+  elsif ($c->param('snippet')) {
+    $c->layout('snippet');
   };
 
-  # Render template "example/welcome.html.ep" with message
   $c->render(template => 'search');
 };
 
+
+
 sub info {
   my $c = shift;
   my $api = $c->config('KorAP')->{api};
   my $src = $c->stash('resource');
-  $src = 'VirtualCollection' if $src eq 'collection';
-  $src = 'Corpus' if $src eq 'corpus';
-
-  my $url = Mojo::URL->new($api)->path('resource/' . $src);
-  if (my $response = $c->ua->get($url)->success) {
-    $c->render(json => $c->notifications(json => $response->json));
-  };
+  $c->render(json => $c->notifications(json => $c->info_on($src)));
 };
 
+
 1;
 
 
 __END__
 
-[{"id":1,"name":"Wikipedia","description":"Die freie Enzyklopädie","owner":0,"created":1401193381119,"managed":true,"shared":false,"foundries":"base;corenlp;mate;mpt;opennlp;tt;xip","refCorpus":"","query":"[{\"@type\":\"korap:meta-filter\",\"@value\":{\"@type\":\"korap:term\",\"@field\":\"korap:field#corpusID\",\"@value\":\"WPD\"}}]","cache":false,"stats":"{\"documents\":196510,\"tokens\":51545081,\"sentences\":4116282,\"paragraphs\":2034752}"}]
+[{"shared":false,"id":1,"managed":true,"created":1401193381119,"stats":{"documents":196510,"tokens":51545081,"sentences":4116282,"paragraphs":2034752},"query":[{"@type":"korap:meta-filter","@value":{"@type":"korap:term","@field":"korap:field#corpusID","@value":"WPD"}}],"description":"Die freie Enzyklopädie","name":"Wikipedia","foundries":"base;corenlp;mate;mpt;opennlp;tt;xip"}]
diff --git a/lib/Korap/Tutorial.pm b/lib/Korap/Tutorial.pm
new file mode 100644
index 0000000..224190f
--- /dev/null
+++ b/lib/Korap/Tutorial.pm
@@ -0,0 +1,17 @@
+package Korap::Tutorial;
+use Mojo::Base 'Mojolicious::Controller';
+
+sub page {
+  my $c = shift;
+  $c->layout('snippet');
+  $c->title('KorAP');
+
+  my $page = $c->stash('tutorial');
+
+  $c->render(template => 'tutorial');
+};
+
+1;
+
+
+__END__
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..6a2a60a
--- /dev/null
+++ b/public/favicon.ico
Binary files differ
diff --git a/public/img/korap-logo-solo.svg b/public/img/korap-logo-solo.svg
new file mode 100644
index 0000000..e74b29a
--- /dev/null
+++ b/public/img/korap-logo-solo.svg
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.1"
+   width="292.90839"
+   height="104.8784"
+   transform="scale(.6)"
+   id="svg2">
+  <defs
+     id="defs4" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <path
+     d="m 272.6875,2.3470265 c -0.13853,0 -0.26847,0.028 -0.40625,0.031 -0.0633,9e-4 -0.1244,0 -0.1875,0 l -41.53125,0 -40,3e-4 -20,-3e-4 -11.9375,0 -10.84375,0 0,0.062 c -9.55779,0.3611 -17.1875,8.1974995 -17.1875,17.8436995 0,0.2871 0.0179,0.5599 0.0312,0.8438 l -0.0625,0 0,81.250004 40,0 0,-40.000004 20,0 0,40.000004 40,0 0,-40.000004 42.125,0 0.46875,0 0,-0.031 c 9.62803,-0.2482 17.35652,-8.0737 17.40625,-17.7499 1.6e-4,-0.031 0,-0.062 0,-0.094 l 0,-24.2501 c 0,-0.1254 0.003,-0.2502 0,-0.375 -0.19976,-9.7029 -8.12415,-17.5311995 -17.875,-17.5311995 z m -102.125,20.0312995 20,0 0,20 -20,0 z m 60,0 20,0 0,20 -20,0 z"
+     id="path6"
+     style="fill:#496000;fill-opacity:1;stroke:#ffffff;stroke-width:4.69999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+  <path
+     d="M 2.625,7.7150265 2.5,102.37833 l 40.0625,0 0,-42.812504 19.9375,42.812504 12,0 28.0625,0 14,0 40,0 0,-40.000004 40,0 0,-2.7188 c -3.6e-4,-0.01 3.8e-4,-0.021 0,-0.031 -0.3416,-9.4668 -8.05179,-17.0523 -17.5625,-17.2187 -5.5e-4,0 5.5e-4,-0.031 0,-0.031 l -0.3125,0 -22.125,0 -40,0 -41.9375,0 0,0.125 -0.0625,-0.125 28,-34.6632995 -39.9375,0 -20.0625,17.5694995 0,-17.5694995 -39.9375,0 z m 91.9375,54.6632995 20,0 0,20 -20,0 z"
+     id="path8"
+     style="fill:#ffffff;fill-opacity:1;stroke:#496000;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+</svg>
diff --git a/public/img/loading.gif b/public/img/loading.gif
new file mode 100644
index 0000000..c9aaeda
--- /dev/null
+++ b/public/img/loading.gif
Binary files differ
diff --git a/public/kwic-3.0.css b/public/kwic-3.0.css
index d8c7faf..0aac61e 100644
--- a/public/kwic-3.0.css
+++ b/public/kwic-3.0.css
@@ -1,5 +1,14 @@
 @charset "utf-8";
 
+/*
+  light orange: #f4eebb;
+  dark orange: #ffa500;
+  dark green: #496000;
+  light green: #7ba400;
+
+  Search for: [orth=erstens]
+*/
+
 ol {
   width: auto;
   overflow: hidden;
@@ -34,18 +43,18 @@
   background-color: #ddd;
 }
 
-ol > li > span,
-ol > li > span > span {
+ol > li > div.snippet > span,
+ol > li > div.snippet > span > span {
   white-space: no-wrap !important;
 }
 
-ol.free-aligned > li:not(.active) > span.left {
+ol.free-aligned > li:not(.active) > div.snippet > span.left {
   display: inline-block;
   text-align: right;
   width: 50.0046%;
 }
 
-ol.free-aligned > li:not(.active) > span.separator {
+ol.free-aligned > li:not(.active) > div.snippet > span.separator {
   width: 0px;
   height: 1em;
   margin-bottom: -2px;
@@ -56,11 +65,11 @@
   margin-right: 2px;
 }
 
-ol.free-aligned > li > span.right {
+ol.free-aligned > li > div.snippet > span.right {
   text-align: left;
 }
 
-ol.left-aligned > li > span.context-left {
+ol.left-aligned > li > div.snippet > span.context-left {
   display: inline-block;
   text-align: right;
   width: 50.001%;
@@ -70,19 +79,20 @@
   text-align: right;
 }
 
-ol.right-aligned > li:not(.active) > span.context-right {
+ol.right-aligned > li:not(.active) > div.snippet > span.context-right {
   display: inline-block;
   text-align: left;
   width: 49.9915%;
 }
 
-li > span {
+li > div.snippet > span {
   color: #666;
 }
 
 .match {
   font-weight: bold;
-  color: #333;
+  text-shadow: 1px 1px rgba(255, 255, 255, 0.9);
+  color: #111;
   padding-left: 4pt;
   padding-right: 2pt;
 }
@@ -113,26 +123,30 @@
 }
 
 /* active view */
-ol li.active {
+ol > li.active {
   text-align: left;
   width: auto;
   cursor: normal;
   white-space: wrap;
   height: auto;
-  padding: 5pt;
-  padding-left: 3em;
-  padding-bottom: 12px;
   border-width: 2px;
   background-color: #f4eebb;
   position: relative;
+  min-height: 68pt;
 }
 
-ol li.active > span {
-  line-height: 1.7em;
+ol > li.active > div.snippet {
+  margin: 5pt 10pt;
+  margin-right: 3em;
+  margin-bottom: 24pt;
+}
+
+ol > li.active > div.snippet > span {
+  line-height: 1.4em;
   width: auto;
 }
 
-ol li.active span.context-left {
+ol > li.active > div.snippet > span.context-left {
   margin-left: 0;
   display: inline;
   overflow: visible;
@@ -140,20 +154,22 @@
   width: auto;
 }
 
-
 /* Korap-Actions: */
 ol > li ul.action {
   display: none;
 }
 
-ol > li ul.action a {
+ol > li ul.action li {
+  cursor: pointer;
   color: white;
   text-decoration: none;
-  text-shadow: none;
 }
 
 ol > li.active ul.action {
   background-color: #ffa500;
+  font-size: 12pt;
+  color: white;
+  text-shadow: none;
   display: block;
   margin: 0;
   padding: 0;
@@ -163,6 +179,7 @@
   list-style-position: inline;
 }
 
+/*
 ol > li.active ul.action.right {
   position: absolute;
   right: 0;
@@ -170,20 +187,34 @@
   height: 1.2em;
 }
 
-ol > li.active ul.action.left {
-  position: absolute;
-  float: left;
-  padding: 0pt 3pt;
-  height: 100%;
-  width: 2em;;
-/*
-  margin: -5pt 2pt 2pt -5pt;
-*/
-  left: 0;
-  top: 0;
-}
-
 ol > li.active ul.action.right li {
   float: left;
   padding-left: 1em;
 }
+*/
+
+ol > li.active ul.action.right {
+  position: absolute;
+  float: right;
+  text-align: center;
+  padding: 0pt 3pt;
+  height: 100%;
+  width: 1.2em;;
+  right: 0;
+  top: 0;
+}
+
+ol > li:not(.active) p {
+  display: none;
+}
+
+ol > li.active p {
+  background-color: #ffa500;
+  color: white;
+  text-shadow: none;
+  padding: 3pt 10pt;
+  margin: 5pt 0pt 0pt 0pt;
+  position: absolute;
+  width: 100%;
+  bottom: 0;
+}
\ No newline at end of file
diff --git a/public/style.css b/public/style.css
index bfbeeb3..dff0bcb 100644
--- a/public/style.css
+++ b/public/style.css
@@ -95,7 +95,7 @@
   color: #c1002b;
 }
 
-code {
+code.query {
   background-color: #f4eebb;
   display: block;
   border-style: solid;
@@ -106,32 +106,27 @@
   text-shadow: 1px 1px rgba(255, 255, 255, 0.9);
   border-width: 2px;
   margin: 0;
+  margin-bottom: 5pt;
   cursor: pointer;
 }
 
-code:not(.active) {
-/*
-  height: 12pt;
-*/
-}
-
-code:not(.active) span {
+code.query.serial:not(.active) span {
   padding: 2pt;
 }
 
-code:not(.active) pre {
-  display: none;
-}
-
-code.active pre {
+code.query pre {
   display: block;
-  padding: 20px;
+  padding: 2px 5px;
+  margin: 0;
 }
 
-code.active span {
+code.query.serial:not(.active) pre {
   display: none;
 }
 
+code.query.serial.active span {
+  display: none;
+}
 
 #sidebar.active {
   margin-left: 0px;
@@ -153,17 +148,113 @@
   top: 0;
 }
 
+#sidebar > * {
+  opacity: 0;
+  transition-property: opacity;
+  transition-duration: .3s;
+}
+
+#sidebar.active > * {
+  opacity: 1;
+}
+
+#sidebar h2 {
+  font-size: 100%;
+  font-weight: bold;
+  text-align: center;
+  padding: 0;
+  margin: 0 0 5pt 0;
+}
+
+#sidebar ul {
+  list-style-type: none;
+  margin: 0;
+  font-size: 10pt;
+  text-indent: 0;
+  padding: 0;
+}
+
+#sidebar ul li {
+  padding: 4pt 10pt;
+}
+
+#sidebar ul li h3 {
+  font-weight: bold;
+  font-size: 100%;
+  padding: 0;
+  margin: 0;
+}
+
+#sidebar ul li.active h3 {
+  margin-bottom: 2pt;
+  padding-bottom: 2pt;
+  border-bottom: 1px solid black;
+}
+
+#sidebar ul li.active {
+  background-color: #7ba400;
+  text-shadow: 1px 1px rgba(0, 0, 0, 0.4);
+}
+
+dl.info {
+  font-size: 9pt;
+  padding: 0 10pt;
+}
+
+dl.info dt {
+  font-weight: bold;
+  float: left;
+}
+
+dl.info dd {
+  text-align: right;
+}
+
 #search {
   margin-left: 30px;
   margin-right: 15px;
   margin-bottom: 40px;
 }
 
-
+/*
 iframe {
   border-width: 0;
   border-top: 1px solid #ccc;
   border-bottom: 1px solid #ccc;
   height: 300px;
   width: 100%;
+}
+*/
+
+#tutorial {
+  position: fixed;
+  z-index: 9999;
+  top: 2%;
+  bottom: 2%;
+  left: 5%;
+  right: 5%;
+  background-color: #496000;
+  border-radius: 15px;
+  padding: 5px;
+}
+
+#tutorial > i {
+  font-size: 20pt;
+  color: #496000;
+  position: absolute;
+  z-index: 100;
+  top: 10pt;
+  right: 20pt;
+  cursor: pointer;
+}
+
+#tutorial iframe {
+  width: 100%;
+  min-height: 100%;
+  border-width: 0;
+  border-radius: 10px;
+  background-image: url('img/loading.gif');
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-color: white;
 }
\ No newline at end of file
diff --git a/templates/collections.html.ep b/templates/collections.html.ep
new file mode 100644
index 0000000..cab2ea2
--- /dev/null
+++ b/templates/collections.html.ep
@@ -0,0 +1,14 @@
+<h2>Virtual Collections</h2>
+<ul>
+% foreach my $vc (@{info_on 'collection'}) {
+<li class="active" title="<%= $vc->{description} // '' %>"><h3><%= $vc->{name} %></h3>
+% my $stats = $vc->{stats};
+  <dl class="info">
+    <dt>Documents</dt><dd><%= commify $stats->{documents} %></dd>
+    <dt>Paragraphs</dt><dd><%= commify $stats->{paragraphs} %></dd>
+    <dt>Sentences</dt><dd><%= commify $stats->{sentences} %></dd>
+    <dt>Tokens</dt><dd><%= commify $stats->{tokens} %></dd>
+  </dl>
+</li>
+% };
+</ul>
diff --git a/templates/exception.html.ep b/templates/exception.html.ep
new file mode 100644
index 0000000..8d3e656
--- /dev/null
+++ b/templates/exception.html.ep
@@ -0,0 +1 @@
+% notify('error' => '500: Server Error');
diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep
index 2ad80bd..97c53b4 100644
--- a/templates/layouts/default.html.ep
+++ b/templates/layouts/default.html.ep
@@ -9,30 +9,34 @@
 <meta charset="utf-8" />
   </head>
   <body>
-%= notifications 'Alertify'
+
+<div id="tutorial" style="display: none">
+  <i onclick="closeTutorial()" class="fa fa-toggle-up"></i>
+  <iframe src="about:blank" data-src="<%= url_for(session('tutorial') // 'tutorial') %>"></iframe>
+</div>
 
 <div id="top">
-%= image '/img/korap-logo.svg', style => 'position: absolute; z-index: 999'
+%#= image '/img/korap-logo.svg', style => 'position: absolute; z-index: 999'
+%= image '/img/korap-logo-solo.svg', style => 'position: absolute; z-index: 999'
 %= form_for url_for() => begin
-%= select_field ql => [[Poliqarp => 'poliqarp'], ['Cosmas II' => 'cosmas2']]
+%= select_field ql => [[Poliqarp => 'poliqarp'], ['Cosmas II' => 'cosmas2']], id => 'ql-field'
 <br />
-%= search_field 'q'
+%= search_field 'q', id => 'q-field'
 <button type="submit" name="action" value="ok"><i class="fa fa-search"></i></button>
 <button type="submit" name="action" value="inspect"><i class="fa fa-code"></i></button>
 % end
 
-% if (param('q')) {
 <div id="button-right">
+% if (param('q')) {
 <button type="button" onclick="$('#search > ol').toggleClass('left-aligned right-aligned'); $(this).children('i').toggleClass('fa-align-right fa-align-left')"><i class="fa fa-align-right"></i></button>
-</div>
 % }
+<button type="button" onclick="openTutorial()"><i class="fa fa-graduation-cap"></i></button>
+</div>
 
 </div>
 
 <div id="sidebar" style="padding-top: 90px">
-  <fieldset style="margin: 0 17px;">
-    <legend>Virtual Collections</legend>
-  </fieldset>
+%= include 'collections'
 </div>
 
 <div id="search">
@@ -40,10 +44,46 @@
 </div>
 
 %= javascript begin
-$("li,code,#sidebar").on("click", function () {
+
+$("ol > li:not(.active)").on("click", function () {
+  $(this).addClass('active');
+});
+
+function closeSnippet (o) {
+  $(o.parentNode.parentNode).removeClass('active');
+};
+
+function openTutorial (o) {
+  var tut = $("#tutorial");
+  tut.slideDown();
+  var iframe = tut.children("iframe");
+  var src = iframe.attr("data-src");
+  iframe.attr("src", src);
+};
+
+function closeTutorial (o) {
+  $("#tutorial").slideUp();
+};
+
+function useQuery (o) {
+  var q = o.getAttribute("data-query");
+  var ql = o.getAttribute("data-query-language");
+  $("#ql-field").val(ql);
+  $("#q-field").val(q);
+  closeTutorial();
+};
+
+/*
+function requestInfo
+*/
+
+$("code.query.serial,#sidebar").on("click", function () {
   $(this).toggleClass('active');
 });
+
+
 % end
 
+%= notifications 'Alertify'
   </body>
 </html>
diff --git a/templates/layouts/snippet.html.ep b/templates/layouts/snippet.html.ep
new file mode 100644
index 0000000..1c3ef1c
--- /dev/null
+++ b/templates/layouts/snippet.html.ep
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title><%= title %></title>
+%= stylesheet '/style.css'
+%= stylesheet '/kwic-3.0.css'
+%= stylesheet '/fontawesome/font-awesome.min.css'
+%= javascript '/jquery-2.0.0.min.js'
+<meta charset="utf-8" />
+  </head>
+  <body style="background-color:white">
+%= notifications 'Alertify'
+%= content
+%= javascript begin
+$("li,code,#sidebar").on("click", function () {
+  $(this).toggleClass('active');
+});
+% end
+  </body>
+</html>
diff --git a/templates/query.html.ep b/templates/query.html.ep
index 5d09324..6ef646f 100644
--- a/templates/query.html.ep
+++ b/templates/query.html.ep
@@ -1,8 +1,8 @@
 % use JSON::XS;
 
 % if (stash('search.query')) {
-<code><span>JSON-LD Query for <%= param 'q' %> (<%= param 'ql' %>)</span><pre>
-%  my $json = JSON::XS->new->pretty;
+<code class="query serial<% if (param('action') eq 'inspect') { %> active<% } %>"><span>JSON-LD Query for <%= param 'q' %> (<%= param 'ql' %>)</span><pre>
+%  my $json = JSON::XS->new->allow_blessed->pretty;
 %= $json->encode(stash('search.query'))
 </pre></span></code>
 % }
diff --git a/templates/search.html.ep b/templates/search.html.ep
index b8df8d3..8ed571b 100644
--- a/templates/search.html.ep
+++ b/templates/search.html.ep
@@ -1,17 +1,18 @@
-% layout 'default', title 'KorAP';
-
-
+% if (param 'q') {
 %= search begin
+
+% unless (param 'snippet') {
 <div style="clear: both">
-<p class="found"><span class="pagination">
+  <p class="found">
+    <span class="pagination">
 % my $url = url_with->query(['p' => '{page}']);
 % my $pages = (stash('search.totalResults') / (stash('search.itemsPerPage') || 1));
 % $pages = $pages < 0 ? 0 : $pages;
-</span>
+    </span>
 
-<div id="pagination">
+    <div id="pagination">
 %= pagination(stash('search.startPage'), $pages, $url)
-</div>
+    </div>
 
 %#= l('Found <span id="total-results">[_1]</span> [quant,_1,match]')
 %#= l('in [_1])
@@ -19,17 +20,32 @@
 % if (stash 'search.bm.hit') {
  in <%= stash 'search.bm.hit' %> (<%= stash 'search.bm.result' %>)
 % }
-</p>
+  </p>
 </div>
 
 %= include 'query'
+% };
 
 <ol class="left-aligned">
 %=  search_hits begin
   <li>
 %# ID, title, corpusID, author, pubDate, textClass
-<%== $_->{snippet} %>
+    <div class="snippet"><%== $_->{snippet} %></div>
+    <p><strong><%= $_->{title} %></strong><%= $_->{author} ? ' by ' . $_->{author}  : '' %>; published on <%= date_format $_->{pubDate} %> as <%= $_->{docID} %> (<%= $_->{corpusID} %>)</p>
+%#    as <%= $_->{ID} %>
+%#  textClass docID
+% foreach (grep { m!/morpho$! } split(/\s+/, $_->{foundries})) {
+%#  <%= $_ %>
+% };
+
+    <ul class="action right">
+      <li onmouseup="closeSnippet(this)" title="close"><i class="fa fa-toggle-up"></i></li>
+      <li title="Annotations"><i class="fa fa-info-circle"></i></li>
+      <li title="Tree Visualizations"><i class="fa fa-sitemap"></i></li>
+      <li title="Remember"><i class="fa fa-star-o"></i></li>
+    </ul>
   </li>
 %   end
 </ol>
 % end
+% }
diff --git a/templates/tutorial.html.ep b/templates/tutorial.html.ep
new file mode 100644
index 0000000..0c938d1
--- /dev/null
+++ b/templates/tutorial.html.ep
@@ -0,0 +1,27 @@
+<div style="padding: 20pt">
+
+<p>Links to Blog, FAQ, About, Contact ...</p>
+
+<h1>KorAP-Tutorial</h1>
+
+<ul>
+  <li>Introduction to KorAP</li>
+  <li>How to use Poliqarp+ QL?</li>
+  <li>How to use Cosmas-II QL?</li>
+  <li>How to use CQL?</li>
+</ul>
+
+<p>This is a Tutorial to KorAP. It may be maintained separately (as a Wiki?) and
+has some nice features - like embedded example queries - just click on the query below:</p>
+
+%= korap_tut_query poliqarp => '[base=baum]'
+
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+
+%= korap_tut_query cosmas2 => 'der /w5 Baum'
+
+<p>Suspendisse lectus leo, consectetur in tempor sit amet, placerat quis neque. Etiam luctus porttitor lorem, sed suscipit est rutrum non. Curabitur lobortis nisl a enim congue semper. Aenean commodo ultrices imperdiet. Vestibulum ut justo vel sapien venenatis tincidunt. Phasellus eget dolor sit amet ipsum dapibus condimentum vitae quis lectus. Aliquam ut massa in turpis dapibus convallis. Praesent elit lacus, vestibulum at malesuada et, ornare et est. Ut augue nunc, sodales ut euismod non, adipiscing vitae orci. Mauris ut placerat justo. Mauris in ultricies enim. Quisque nec est eleifend nulla ultrices egestas quis ut quam. Donec sollicitudin lectus a mauris pulvinar id aliquam urna cursus. Cras quis ligula sem, vel elementum mi. Phasellus non ullamcorper urna.</p>
+
+<p>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In euismod ultrices facilisis. Vestibulum porta sapien adipiscing augue congue id pretium lectus molestie. Proin quis dictum nisl. Morbi id quam sapien, sed vestibulum sem. Duis elementum rutrum mauris sed convallis. Proin vestibulum magna mi. Aenean tristique hendrerit magna, ac facilisis nulla hendrerit ut. Sed non tortor sodales quam auctor elementum. Donec hendrerit nunc eget elit pharetra pulvinar. Suspendisse id tempus tortor. Aenean luctus, elit commodo laoreet commodo, justo nisi consequat massa, sed vulputate quam urna quis eros. Donec vel.</p>
+
+</div>