";
+ print $q->hidden(-name=>'key', -value=>"$R::key",-override=>'1');
+
+ print $q->start_table({-class=>'list', -border=>'0', -width=>'100%', -align=>'left', -cellpadding=>'3', -cellspacing=>'3'});
+ #Buttons
+ print $q->Tr();
+ print "
\n";
+ print $but->singlesubmit7("rel_edit","save_attrtpl","","");
+ print $but->singlesubmit7("rel_edit","remove_chk4attr","","margin-left:10px;");
+ #print $but->singlesubmit9("dummy","zurück","","ebutton","","");
+ print $q->span({-style=>'margin-left:5em; font-size:0.91em;'}, "$u_name / $tpl->{change}");
+ print " \n";
+
+ print $q->Tr();
+ print $q->td({-colspan=>'2'}," ");
+ print $q->Tr();
+ print $q->td({-class=>'tdescr'}, "Service Datenfeldname"),"\n";
+ print $q->td({-class=>'tdval'},$q->textfield(-class=>'etxt',-name=>"des", -override=>'1',-default=>"$des_name")),"\n";
+ if($key =~ /txt|int/){
+ print $q->Tr();
+ print $q->td({-class=>'tdescr'}, "Datentyp"),"\n";
+ print "\n";
+ if($R::key =~ /txt/){
+ print $but->radiobox("txt","key_typ","$checked_txt"),"Textzeile\n";
+ print $but->radiobox("txt_area","key_typ","$checked_txtarea"),"Textarea\n";
+ }elsif($R::key =~ /int/){
+ print $but->radiobox("int","key_typ","$checked_int"),"Dezimalzahl\n";
+ print $but->radiobox("int_checkbox","key_typ","$checked_intcheck"),"Checkbox\n";
+ }
+ print " \n";
+ }
+ print $q->Tr();
+ print $q->td({-class=>'tdescr'},"Sortierung"),"\n";
+ print $q->td({-class=>'tdval'},$q->textfield(-class=>'etxt', -name=>"asort", -default=>"$asort")),"\n";
+ #print $q->Tr();
+ #print $q->td({-class=>'tdescr'},"Text Vorauswahl"),"\n";
+ #my $pre_values = $q->unescapeHTML("$ctf->{$R::key}");
+ #print $q->td({-class=>'tdval'},$q->textarea(-id=>"prev", -class=>'etxt',-style=>"width:300px;",-rows=>"1", -name=>"pre_values",-default=>"$pre_values", -override=>'1')),"\n";
+ #print "";
+ #print $q->hidden(-name=>'cuid_glob', -value=>"$cuid_glob",-override=>'1');
+
+ #print $q->Tr();
+ #print $q->td({-class=>'tdescr',-colspan=>'2'},""),"\n";
+ #print $q->Tr();
+ #print $q->td({-class=>'tdescr',-colspan=>'2'},"Achtung, das löschen oder ändern verursacht Datenverlust."),"\n";
+
+ print $q->end_table;
+
+ print "";
+}
+1;
+
diff --git a/copri4/main/src/Tpl/AttributMatrix.pm b/copri4/main/src/Tpl/AttributMatrix.pm
new file mode 100644
index 0000000..aa08c1c
--- /dev/null
+++ b/copri4/main/src/Tpl/AttributMatrix.pm
@@ -0,0 +1,205 @@
+package AttributMatrix;
+#
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift;
+ my $mode = shift;
+ my $return = shift;
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $but = new Buttons;
+ my $dbt = new DBtank;
+
+ my %varenv = $cf->envonline();
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ if("$varenv{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $dbh = "";
+ my $lang = "de";
+ my %ib = $but->ibuttons_arch();
+
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+
+ my $tpl_master = $db->get_tpl("400");
+ my @tpl_masterorder = ();
+ my $node = {};
+
+ if($users_dms->{int08} == 2){
+print<
+
+ \$(function() {
+ function postValues() {
+ var data = \$("input[type='checkbox'], input[type='text'], input[type='hidden']").serialize();
+ \$.ajax({
+ url: '$varenv{wwwhost}/ajax_post',
+ type: 'POST',
+ async: true,
+ cache: false,
+ data: data,
+ });
+ }
+ \$("input[type='checkbox']").on( "click", postValues );
+ \$("input[type='text']").on( "change", postValues );
+
+ });
+
+EOF
+;
+ }
+
+ if($users_dms->{int08} >= 1){
+ @tpl_masterorder = split /,/,$tpl_master->{tpl_order};
+ my $pref = { template_id1 => 401,
+ template_id2 => 499,
+ fetch => "all",
+ keyfield => "main_id",
+ };
+ $node = $dbt->fetch_rel4tpl4nd($dbh,$pref);
+ }else{
+ $return = "failure::Abbruch. Keine Zugriffsberechtigung";
+ }
+
+
+ sub checkbox_style2() {
+ my ($sid_key,$dialog) = @_;
+ my $ck_style = "\n";
+ return $ck_style;
+ }
+
+ print "\n";
+
+ print $q->div({-class=>"copri_header",-style=>"background-color:#cccccc;"},"$path",$q->span("(shareetool Datenfeld Matrix)"));
+
+ print $q->start_form();
+ print $q->hidden(-name=>'mode', -override=>1, -value=>"supervisor");
+
+ #table header
+ print $q->start_table({-border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'0', -cellspacing=>'0'});
+ print $q->Tr();
+ if($users_dms->{int08} == 2){
+ #print $q->th({-style=>'text-align:right;padding:1px 3px;font-size:1em;'},"Datenfeld", $but->singlesubmit2("rel_edit","new_attrtpl_int","$ib{new_attrtpl_int}","background-color:silver;"), $but->singlesubmit2("rel_edit","new_attrtpl_txt","$ib{new_attrtpl_txt}","background-color:silver;")),"\n";
+ print $q->th({-style=>'text-align:right;padding:1px 3px;font-size:1em;'},"Datenfeld", $but->singlesubmit2glyph("rel_edit","new_attrtpl_int","$ib{new_attrtpl_int}","background-color:silver;")),"\n";
+ }else{
+ print $q->th({-style=>'text-align:right;padding:1px 3px;font-size:1em;'},""),"\n";
+ }
+ #foreach my $id (sort {$node->{$a}->{n_sort} <=> $node->{$b}->{n_sort}} keys (%$node)){
+ foreach my $id (sort {$node->{$a}->{node_name} cmp $node->{$b}->{node_name}} keys (%$node)){
+ if($node->{$id}->{template_id}){
+ if($node->{$id}->{main_id} == $node_meta->{main_id}){
+ print $q->hidden(-name=>'template_id',-override=>'1', -value=>"$node->{$id}->{template_id}");
+ print $q->th({-class=>'thmatrix',-nowrap=>1,-colspan=>2}, $q->b("$node->{$id}->{node_name}")),"\n";
+ }else{
+ if($users_dms->{int08} == 2){
+ my $uri_path = $dbt->recurse_node($dbh,$node->{$id}->{main_id});
+ print $q->th({-class=>'thmatrix',-nowrap=>1,-colspan=>2}, $q->a({-class=>"sortnav",-href=>"/$uri_path/supervisor",-title=>'aktivieren'}, "$node->{$id}->{node_name}")),"\n";
+ }else{
+ print $q->th({-class=>'thmatrix',-nowrap=>1,-colspan=>2},"$node->{$id}->{node_name}"),"\n";
+ }
+ }
+ }
+ }
+
+ #table content
+ my $j=0;
+ my $set_style;
+ my $checked="";
+ #tpl_id=400
+ foreach (@tpl_masterorder){
+ $j++;
+ $set_style = "background-color:#fcfdfb;";
+ $set_style = "background-color:#f4f1ee;" if($j %= 2);
+ print $q->Tr();
+ my ($m_key,$m_des,$m_size) = split /=/,$_;
+ if($m_key !~ /img|time|c_id|barcode|int04|owner/){#static
+ print $q->td({-class=>'tdtxtw', -style=>"$set_style"},$q->a({-class=>'sortnav',-href=>"/$viewsel[0]/$viewsel[1]/$viewsel[2]/supervisor?node2edit=edit_template\&tpl_id=$tpl_master->{tpl_id}\&key=$m_key", -title=>"edit ($j)"},"$m_des")),"\n";
+ }else{
+ print $q->td({-class=>'tdtxtw', -style=>"$set_style"},$q->a({-class=>'sortnav',-href=>"#", -title=>"static"},"$m_des")),"\n";
+ }
+ foreach my $id (sort {$node->{$a}->{node_name} cmp $node->{$b}->{node_name}} keys (%$node)){
+ my $cat_off="";
+ my $m_style="margin:auto;width:16px;height:16px;background-color:#cccccc;";
+ my $interval="";
+ #tpl_id > 400 and depends on node
+ if($node->{$id}->{tpl_order} =~ /$m_key=[a-z0-9-_ ]+=[a-z0-9-_]+=(\d+)/i){
+ $interval = $1;
+ }
+ my $service_type="";
+ if($node->{$id}->{tpl_order} =~ /$m_key=[a-z0-9-_ ]+=[a-z0-9-_]+=\d+=(\d+)/i){
+ $service_type = $1;
+ }
+
+ if($node->{$id}->{main_id} == $node_meta->{main_id}){
+ my $ck_style = &checkbox_style2($m_key,"attr");
+ print "$ck_style";
+ $checked="";
+ $checked="checked" if($node->{$id}->{tpl_order} =~ /$m_key/);
+ }else{
+ $cat_off=1;
+ $m_style="margin:auto;width:16px;height:16px;background-color:#717171;" if($node->{$id}->{tpl_order} =~ /$m_key/);
+ }
+ #my @tpl_node = split /,/,$node->{$id}->{tpl_order};
+ foreach (@tpl_masterorder){
+ my ($key,$des,$size) = split /=/,$_;
+ if($m_key eq $key){
+ if($cat_off){
+ my $itext = "";
+ my $ytext = "";
+ if($interval){
+ $itext = "$interval Tage Intervall";
+ $ytext = "";
+ $ytext = " | weich=1" if($service_type eq 1);
+ }
+ $ytext = " | hart=2" if($service_type eq 2);
+ print $q->td({-class=>'tdtxtc', -style=>"$set_style"},$q->div({-style=>"$m_style"},"")),"\n";
+ print $q->td({-class=>'tdtxtc', -style=>"$set_style text-align:left"},$q->div({-style=>""},"$itext $ytext")),"\n";
+ }else{
+ #print $q->td({-class=>'tdtxtc', -style=>"$set_style"},$q->div({ -class => "sq_attr$key" }," ")),"\n";
+ print $q->td({-class=>'tdtxtc', -style=>"$set_style"},$q->div({ -class => "sq_attr$key" }," ")),"\n";
+ print $q->td({-class=>'tdtxtc', -style=>"$set_style text-align:left;"}, $q->textfield(-class=>'etxt',-size=>'1',-name=>"interval_$key", -override=>'1',-default=>"$interval"), "Tage Intervall | Typ ", $q->textfield(-class=>'etxt',-size=>'1',-name=>"servicetype_$key", -override=>'1',-default=>"$service_type")),"\n";
+ }
+ }
+ }
+ }
+ }
+
+ print $q->end_table;
+ print $q->end_form;
+
+ print "
\n";
+ return $return;
+}
+1;
diff --git a/copri4/main/src/Tpl/BaseEdit.pm b/copri4/main/src/Tpl/BaseEdit.pm
new file mode 100644
index 0000000..bad5018
--- /dev/null
+++ b/copri4/main/src/Tpl/BaseEdit.pm
@@ -0,0 +1,608 @@
+package BaseEdit;
+#
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#use lib "/var/www/copri4/shareedms-primary/src";
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Date::Calc qw(:all);
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::Basework;
+use Mod::DBtank;
+use Mod::APIfunc;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift;
+ my $u_group = shift;
+ my $return = shift;
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $bw = new Basework;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+ my $but = new Buttons;
+ my %ib = $but->ibuttons();
+
+ my %varenv = $cf->envonline();
+ my $lang = "de";
+ my $dbh = "";
+ #print $dbt->{operator}->{$varenv{dbname}}->{oprefix};
+
+ my $rel_id = $1 if($R::rel_id && $R::rel_id =~ /(\d+)/);
+ my $u_id = $1 if($R::u_id && $R::u_id =~ /(\d+)/);
+ $u_id = $1 if($R::c_idadr && $R::c_idadr =~ /(\d+)/ && $R::base_edit eq "new_dmsusers");
+ my ($edit,$copy_key,$save_key,$relate_key,$move_key,$delete_key,$package_key);
+ my $tpl;
+ my @tpl_order;
+ my $edit_template;
+ my $bg_color = "grey";
+ my $ctrel = {};
+ if($node_meta->{ct_table} eq "content" && $node_meta->{tpl_id}){
+ my $ref = {
+ table => "$node_meta->{ct_table}",
+ fetch => "one",
+ template_id => "$node_meta->{tpl_id}",
+ rel_id => "$rel_id",
+ };
+ $ctrel = $dbt->fetch_record($dbh,$ref);
+ print $q->hidden(-name=>'c_id',-override=>'1', -value=>"$ctrel->{c_id}");
+ print $q->hidden(-name=>'rel_id',-override=>'1', -value=>"$ctrel->{rel_id}");
+
+ $bg_color = $varenv{background_color2};
+ $edit = "rel_edit";
+ #$relate_key = "relate_dialog4menu";
+ $move_key = "move_dialog4menu" if($node_meta->{tpl_id} == 205);#only Waren
+ #$copy_key = "copy_content";
+ $save_key = "save_content";
+ $edit_template = "$ctrel->{template_id}";
+ $tpl = $db->get_tpl($edit_template);
+ }elsif($node_meta->{ct_table} eq "contentadr" && $node_meta->{tpl_id}){
+ my $ref = {
+ table => "$node_meta->{ct_table}",
+ fetch => "one",
+ template_id => "$node_meta->{tpl_id}",
+ rel_id => "$rel_id",
+ };
+ $ctrel = $dbt->fetch_record($dbh,$ref);
+ print $q->hidden(-name=>'c_id',-override=>'1', -value=>"$ctrel->{c_id}");
+ print $q->hidden(-name=>'rel_id',-override=>'1', -value=>"$ctrel->{rel_id}");
+
+ $bg_color = $varenv{background_color2};
+ $edit = "base_edit";
+ $save_key = "save_adr";
+ $edit_template = "$ctrel->{template_id}" . "000";
+ $tpl = $db->get_tpl($edit_template);
+ }elsif($node_meta->{ct_table} eq "users" && $u_id){
+ my $ref = {
+ table => "$node_meta->{ct_table}",
+ fetch => "one",
+ u_id => "$u_id",
+ };
+ $ctrel = $dbt->fetch_tablerecord($dbh,$ref);
+ print $q->hidden(-name=>'u_id',-override=>'1', -value=>"$ctrel->{u_id}");
+
+ $bg_color = $varenv{background_color2};
+ $edit = "base_edit";
+ $save_key = "save_dmsusers";
+ $tpl = $db->get_tpl($node_meta->{tpl_id});
+ #print Dumper($node_meta->{tpl_id}) . "\n u_id:" . $u_id;
+ }else{
+ print $q->div("Es konnten keine Daten gefunden werden"),"\n";
+ return "failure::Error, no table selected";
+ }
+
+ my $u_name = $dbt->sys_username($dbh,$ctrel->{owner});
+
+ if(ref($ctrel) ne "HASH" && !$ctrel->{c_id} && !$ctrel->{u_id}){
+ print $q->div("error: no content available");
+ }
+
+ $ctrel->{mtime} = $lb->time4de($ctrel->{mtime},"1") if($ctrel->{mtime});
+ my $selsize="200px";
+ #$db->users_up("rel_id4edit",$ctrel->{rel_id},$users_dms->{u_id});
+
+ print $q->hidden(-name=>'parent_id',-override=>'1', -value=>"$node_meta->{parent_id}");
+ print $q->hidden(-name=>'main_id',-override=>'1', -value=>"$node_meta->{main_id}");
+ print $q->hidden(-name=>'template_id',-override=>'1', -value=>"$node_meta->{template_id}");
+ print $q->hidden(-name=>'offset',-override=>'1', -value=>"$R::offset");
+ print $q->hidden(-name=>'limit', -override=>'1', -value=>"$R::limit");
+ print $q->hidden(-name=>'relids', -override=>'1', -value=>"$R::relids");
+
+ my ($start_date,$start_time,$s_dd,$s_mo,$s_yy,$s_hh,$s_mi,$end_date,$end_time,$e_yy,$e_mo,$e_dd,$e_hh,$e_mi);
+ my $today = strftime("%d.%m.%Y",localtime(time));
+ my $start_datetime = $ctrel->{start_time};
+ my $end_datetime = $ctrel->{end_time};
+
+ if($start_datetime){
+ ($start_date,$start_time) = split(/ /,$start_datetime);
+ ($s_yy,$s_mo,$s_dd) = split(/-/,$start_date);
+ $start_date = "$s_dd-$s_mo-$s_yy";
+ ($s_hh,$s_mi) = split(/\:/,$start_time);
+ }
+ if($end_datetime){
+ ($end_date,$end_time) = split(/ /,$end_datetime);
+ ($e_yy,$e_mo,$e_dd) = split(/-/,$end_date);
+ $end_date = "$e_dd-$e_mo-$e_yy";
+ ($e_hh,$e_mi) = split(/\:/,$end_time);
+ }
+ ###
+
+ my $bike_nodes = {};
+ my $tariff_all = {};
+ if($varenv{systype} eq "sharee"){
+ my $node = { template_id => 205,#Leihrad_liste
+ parent_id => 200013,#Waren
+ fetch => "all",
+ keyfield => "main_id",
+ };
+ $bike_nodes = $dbt->fetch_rel4tpl4nd($dbh,$node);
+ $tariff_all = $db->collect_ct4rel("content","300026",$lang,"","","","","210");
+ }
+
+ print "\n";
+ #1. table submit
+ print $q->start_table({-class=>'list', -border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'3', -cellspacing=>'0'});
+ print $q->Tr();
+ print "
";
+ print $but->singlesubmit7("$edit","$save_key","$ib{$save_key}","margin:0 5px;");
+ print $but->singlesubmit7("rel_edit","$relate_key","$ib{$relate_key}","margin:0 5px;");
+ print $but->singlesubmit7("rel_edit","$move_key","$ib{$move_key}","margin:0 5px;");
+ print $but->singlesubmit7("rel_edit","$copy_key","$ib{$copy_key}","margin:0 5px;");
+ print $but->singlesubmit7("$edit","remove_chk4rel","$ib{remove_chk4rel}","margin:0 5px;");
+
+ #print $q->div({-style=>'position:fixed;bottom:2%;right:1%;z-index:10;font-size:13px;'}," (c_id: $ctrel->{c_id} | rel_id: $ctrel->{rel_id} | tpl_id: $ctrel->{template_id} / $edit_template)"),"\n" if($users_dms->{u_id} eq $varenv{superu_id});
+ print " \n";
+ print $q->td({-style=>"background-color:$bg_color;padding-right:10px;border-bottom: 1px solid silver;text-align:right;font-size:11px;"}, "$u_name / $ctrel->{mtime}");
+ print $q->end_table;
+
+
+ ###Terminal target
+ my $c_key = "c_id";
+ my $add_trans = "add_transpos";
+ if("$node_meta->{ct_table}" =~ /contentadr/){
+ $add_trans = "add_transadr";
+ $c_key = "c_idadr";
+ }
+
+ my $tpath = "";
+ my $top = 70;
+ if($node_meta->{tpl_id} == 202){
+ my $cttrans = $db->collect_ct4rel4nd("contenttrans","","$lang","","","","ct.int10","$ctrel->{c_id}","209,218","","rel_id","");
+ foreach my $id (sort { $cttrans->{$b}->{c_id} <=> $cttrans->{$a}->{c_id} } keys (%$cttrans)){
+ my $toppx = $top . "px";
+ print $q->div({-style=>"position:absolute;top:$toppx;right:20px;"}, " TXID $cttrans->{$id}->{txt16} ",$q->span({-style=>"background-color:$varenv{term_active_color}"},$q->a({-class=>"linknav",-href=>"/$dbt->{shareedms_conf}->{parent_node}/Faktura/$cttrans->{$id}->{node_name}?ct_trans=open\&c_id4trans=$cttrans->{$id}->{c_id}\&tpl_id4trans=$cttrans->{$id}->{template_id}\&kind_of_trans=$users_dms->{kind_of_trans}&owner=$users_dms->{u_id}",-title=>"Faktura Terminal öffnen"},"[ $cttrans->{$id}->{node_name} #$cttrans->{$id}->{ct_name} ]"))),"\n";
+ $top += 22;
+ }
+ }elsif($node_meta->{tpl_id} == 205){
+ my $day = strftime "%d", localtime;
+ my $month = strftime "%m", localtime;
+ my $year = strftime "%Y", localtime;
+ my ($nyear,$nmonth,$nday) = Add_Delta_YMD($year,$month,$day, 0,0,-28);
+ my $toppx = $top . "px";
+ print $q->div({-style=>"position:absolute;top:$toppx;right:20px;"}, $q->span({-style=>"background-color:$varenv{calendar_active_color}"},$q->a({-class=>"linknav",-href=>"/$dbt->{shareedms_conf}->{parent_node}/Mietjournal/?detail_search=1&barcode=$ctrel->{barcode}&start_date_time=$nday.$nmonth.$nyear",-title=>"Mietjournal der letzten 4 Wochen"},"[ Mietjournal zu Rad $dbt->{operator}->{$varenv{dbname}}->{oprefix}$ctrel->{barcode} ]"))),"\n";
+ $top += 22;
+ #}else{
+ #print $q->div({-style=>"position:absolute;top:$top;right:20px;"},"no valid users path definition: $tpath"),"\n";
+ }
+ ###
+
+#just for checking if ct_name or barcode still available
+if($varenv{orga} eq "dms"){
+print<
+ .ui-autocomplete {
+ text-align:left;
+ font-size:14px;
+ background:#eeeeee;
+ border:1px solid silver;
+ }
+
+
+
+EOF
+;
+}
+
+ #2. table content
+ print $q->start_table({-border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'3', -cellspacing=>'0'});
+ print "\n";
+
+ my $j=0;
+ @tpl_order = split /,/,$tpl->{tpl_order};
+
+ #2.1 sub-table
+ print "\n";
+ print $q->start_table({-border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'3', -cellspacing=>'0'});
+ $j++;
+ my @_service_valxx = ("","1","2","3","4");
+
+ foreach (@tpl_order){
+ my ($key,$des,$size,$postdes) = split /=/,$_;
+ my $seldes = $des;
+ $des .= " ($key)" if($users_dms->{u_id} eq $varenv{superu_id});
+
+ $ctrel->{$key} = $q->unescapeHTML("$ctrel->{$key}");
+ $ctrel->{$key} = $lb->newline($ctrel->{$key},"",1);
+ if($key =~ /c_id|ct_name|barcode|txt/ && $size eq "readonly"){
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>2},$q->textfield(-class=>'etxt', -style=>"width:15em;",-name=>"$key", -default=>"$ctrel->{$key}", -readonly=>1)),"\n";
+ }elsif($key eq "u_id" && $size eq "readonly"){
+ my $adref = {
+ table => "contentadr",
+ fetch => "one",
+ template_id => "202",
+ c_id => "$ctrel->{$key}",
+ };
+ my $ctadr = $dbt->fetch_record($dbh,$adref);
+
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"ID"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>2},$q->textfield(-class=>'etxt', -style=>"width:15em;",-name=>"$key", -default=>"$ctrel->{$key}", -readonly=>1)),"\n";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"Vorname Name"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>2},$q->textfield(-class=>'etxt', -style=>"width:15em;",-name=>"", -default=>"$ctadr->{txt01}", -readonly=>1)),"\n";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"eMail (Login)"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>2},$q->textfield(-class=>'etxt', -style=>"width:15em;",-name=>"", -default=>"$ctadr->{txt08}", -readonly=>1)),"\n";
+
+ }elsif($key eq "ct_name"){
+ #blank Teilenummer
+ my $ct_name = $ctrel->{$key};
+ if(($node_meta->{ct_table} eq "content") && ($tpl->{tpl_order} =~ /barcode/) && ("$ct_name" eq "$ctrel->{barcode}")){
+ $ct_name = "";
+ }
+ my $w = $size . "em";
+ my $oprefix = "";
+ $oprefix = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}-" if($node_meta->{tpl_id} == 224 || $node_meta->{tpl_id} == 228);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>2}, "$oprefix", $q->textfield(-class=>'etxt', -style=>"width:$w;",-name=>"$key", -override=>'1',-default=>"$ct_name")),"\n";
+ }
+ elsif($key eq "barcode"){
+ my $w = $size . "em";
+ my $oprefix = "";
+ $oprefix = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}" if($node_meta->{tpl_id} == 205);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>1}, "$oprefix", $q->textfield(-class=>'etxt',-style=>"width:$w;",-id=>"json_select",-name=>"$key",-value=>"$ctrel->{$key}", -override=>'1',-size=>"25",-maxlength=>50),"");
+ print $q->td({-class=>'content1_cms',-id=>'log'},""),"\n";
+ }
+ elsif($key =~ /int/ && $size =~ /\w\+\w/ && $postdes eq "reverse"){
+ my ($a,$b) = split /\+/,$size;
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>1},$but->radiobox2reverse("$key","$ctrel->{$key}","$a","$b")),"\n";
+ }
+ elsif($key =~ /int/ && $size =~ /\w\+\w/){
+ #if($users_dms->{u_id} eq $varenv{superu_id} || $des !~ /DMS/){#only superu_id can acivate DMS-Admin
+ if($users_dms->{u_id}){
+ my ($a,$b,$c) = split /\+/,$size;
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>1},$but->radiobox2("$key","$ctrel->{$key}","$a","$b","$c")),"\n";
+ }
+ }
+ elsif($key =~ /int/ && $size =~ /checkbox/){
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms', -colspan=>'1'}, $but->checkbox("1","$key","$ctrel->{$key}"), $postdes),"\n";
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"null");
+ }
+ elsif($key eq "int04"){
+ my $w = $size . "em";
+ my $oprefix = "";
+ $oprefix = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}" if($node_meta->{tpl_id} == 225 || $node_meta->{tpl_id} == 205);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>1}, "$oprefix", $q->textfield(-class=>'etxt',-style=>"width:$w;",-name=>"$key",-value=>"$ctrel->{$key}", -override=>'1',-size=>"25",-maxlength=>50),"");
+ }
+ elsif($key =~ /int12/ && "$size" eq "select" && $node_meta->{tpl_id} == 210){#Flotte bike_group (bikenode.main_id)
+ my @_valxx = ("");
+ foreach my $rid (sort { $bike_nodes->{$a}->{node_name} cmp $bike_nodes->{$b}->{node_name} } keys (%$bike_nodes)){
+ push (@_valxx, "$bike_nodes->{$rid}->{main_id}:$bike_nodes->{$rid}->{node_name} - $bike_nodes->{$rid}->{main_id}");
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-colspan=>'1'},"$des");
+ print $q->td({-class=>'content1_cms',-colspan=>'1'},$but->selector_class("$key","eselect","width:250px;",$ctrel->{$key},@_valxx));
+ }
+
+ elsif($key =~ /int21|int22/ && "$size" eq "select" && $node_meta->{tpl_id} == 228){#Bonus Tarif
+ my @_valxx = ("");
+ foreach my $rid (sort { $tariff_all->{$a}->{barcode} <=> $tariff_all->{$b}->{barcode} } keys (%$tariff_all)){
+ push (@_valxx, "$tariff_all->{$rid}->{barcode}:$tariff_all->{$rid}->{barcode} - $tariff_all->{$rid}->{txt01}");
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-colspan=>'1'},"$des");
+ print $q->td({-class=>'content1_cms',-colspan=>'1'},$but->selector_class("$key","eselect","width:350px;",$ctrel->{$key},@_valxx));
+ }
+ elsif($key =~ /int07/ && "$size" eq "select" && $node_meta->{tpl_id} == 225){#Station Service Tour
+ my $selsize="50px";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector("$key","$selsize",$ctrel->{$key},@_service_valxx));
+ }
+ elsif($key =~ /int10/ && "$size" eq "select" && ($node_meta->{tpl_id} == 205 || $node_meta->{tpl_id} == 225)){#bike_state
+ my @_lock_valxx = ();
+ while (my ($key, $value) = each %{ $dbt->{copri_conf}->{bike_state} }) {
+ push @_lock_valxx, "$key:$value";#[1:available] ...
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector_class("$key","eselect","",$ctrel->{$key},@_lock_valxx));
+ }
+ elsif($key =~ /int18/ && "$size" eq "select" && $node_meta->{tpl_id} == 210){#sharing_type
+ my @_lock_valxx = ();
+ while (my ($key, $value) = each %{ $dbt->{copri_conf}->{sharing_type} }) {
+ push @_lock_valxx, "$key:$value";#[0:private] ...
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector_class("$key","eselect","",$ctrel->{$key},@_lock_valxx));
+ }
+ elsif($key =~ /int20/ && "$size" eq "select" && $node_meta->{tpl_id} == 205){#lock_state locked/unlocked
+ my @_lock_valxx = ();
+ while (my ($key, $value) = each %{ $dbt->{copri_conf}->{lock_state} }) {
+ push @_lock_valxx, "$key:$value";#[2:unlocked]
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector_class("$key","eselect","",$ctrel->{$key},@_lock_valxx));
+ }
+ elsif($key =~ /int11/ && "$size" eq "select" && $node_meta->{tpl_id} == 205){#lock_system BC Ilockit usw
+ my @_lock_valxx = ();
+ while (my ($key, $value) = each %{ $dbt->{copri_conf}->{lock_system} }) {
+ push @_lock_valxx, "$key:$value";#[2:Ilockit]
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector_class("$key","eselect","",$ctrel->{$key},@_lock_valxx));
+ }
+ elsif($key =~ /int/ && "$size" eq "select"){
+ my @_valxx;
+ my $selsize="50px";
+
+ @_valxx = split(/\|/,$varenv{$seldes});
+ $ctrel->{$key} =~ s/\.00//;
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector("$key","$selsize",$ctrel->{$key},@_valxx));
+ }
+ elsif($key =~ /int/){
+ my $w = $size . "em";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>2},$q->textfield(-class=>'etxt', -style=>"width:$w;",-name=>"$key", -override=>'1', -default=>"$ctrel->{$key}"), $postdes),"\n";
+ }
+ elsif($key =~ /txt/ && "$size" eq "select" && "$des" =~ /Status|PiQuest|Zahlungsweise/){
+ my @_valxx;
+ my $selsize="150px";
+ @_valxx = split(/\|/,$varenv{$seldes}) if($varenv{$seldes});
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ if($des eq "PiQuest"){
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector("$key","$selsize","",@_valxx)," $ctrel->{$key}");
+ }else{
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector("$key","$selsize",$ctrel->{$key},@_valxx));
+ }
+ }
+ elsif($key =~ /txt/ && "$size" eq "select" && "$des" =~ /System|Ziel Datei/){
+ my @_valxx;
+ my $selsize="150px";
+ @_valxx = split(/\|/,$varenv{$seldes}) if($varenv{$seldes});
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector("$key","$selsize",$ctrel->{$key},@_valxx));
+ }
+ elsif($key =~ /txt/ && "$size" eq "select" && "$des" =~ /Land/){
+ my @_valxx;
+ my $selsize="150px";
+ my $country = $lb->country_code();
+ $ctrel->{$key} = "DE" if(!$ctrel->{$key});
+ foreach (sort { $country->{$a} cmp $country->{$b} } keys (%$country)){
+ push @_valxx, "$_:$country->{$_}";
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector("$key","$selsize",$ctrel->{$key},@_valxx));
+ }
+ elsif($node_meta->{tpl_id} == 205 && $key =~ /txt23/ && "$size" =~ /select/){#Service-Farbcode
+ my @_valxx = ("red","blue","green");
+ my @service_code = ("red","red","red","red","red","red");
+ @service_code = split(/\s/,$ctrel->{$key}) if($ctrel->{$key} =~ /\w+\s\w+\s\w+\s\w+\s\w+\s\w+/g);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-style=>'vertical-align:top;',-colspan=>'1'},"$des");
+ print " \n";
+ foreach(@service_code){
+ print $but->selector_color("$key","color:white;background-color:$_;width:60px;",$_,@_valxx);
+ }
+ print " \n";
+ }
+ elsif($key =~ /txt/ && "$size" =~ /select/){
+ if($size =~ /_multiple/){
+ if($key =~ /txt18/ && $node_meta->{tpl_id} eq "202"){ #service_tour alias user_tour
+ my $height = scalar(@_service_valxx);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-style=>'vertical-align:top;',-colspan=>'1'},"$des");
+ print $q->td({-class=>'content1_cms',-colspan=>'1'},$but->selector2("$key","50px;","$height",$ctrel->{$key},@_service_valxx));
+ }
+ elsif($key =~ /txt24/ && $node_meta->{tpl_id} == 225){ #sharee station_group (bikenode.main_ids)
+ my @_valxx = ("");
+ foreach my $rid (sort { $bike_nodes->{$a}->{node_name} cmp $bike_nodes->{$b}->{node_name} } keys (%$bike_nodes)){
+ push (@_valxx, "$bike_nodes->{$rid}->{main_id}:$bike_nodes->{$rid}->{node_name} - $bike_nodes->{$rid}->{main_id}");
+ }
+ my $height = scalar(@_valxx);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-style=>'vertical-align:top;',-colspan=>'1'},"$des");
+ print $q->td({-class=>'content1_cms',-colspan=>'1'},$but->selector2("$key","250px;","$height",$ctrel->{$key},@_valxx));
+ }
+ #sharee user_group Tarif-2.0 (tarif.c_ids)
+ elsif($key =~ /txt30/ && $varenv{dbname} ne "sharee_primary"){
+ my @_valxx = ("");
+ foreach my $rid (sort { $tariff_all->{$a}->{barcode} <=> $tariff_all->{$b}->{barcode} } keys (%$tariff_all)){
+ if($tariff_all->{$rid}->{ct_name}){
+ push (@_valxx, "$tariff_all->{$rid}->{barcode}:$tariff_all->{$rid}->{barcode} - $tariff_all->{$rid}->{txt01} - $tariff_all->{$rid}->{int12}");
+ }
+ }
+ my $height = scalar(@_valxx);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-style=>'vertical-align:top;',-colspan=>'1'},"$des");
+ print $q->td({-class=>'content1_cms',-colspan=>'1'},$but->selector2("$key","350px;","$height",$ctrel->{$key},@_valxx));
+ }
+ }else{
+ my @_valxx = ("");
+ @_valxx = split(/,/,$varenv{$seldes}) if($varenv{$seldes});
+ my $selsize = "80px";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$but->selector("$key","$selsize",$ctrel->{$key},@_valxx));
+ }
+ #print $q->hidden(-name=>"$key",-override=>1,-value=>"null");#2021-06-02 select works without empty null
+ }
+ elsif($key =~ /txt/ && $size =~ /area$/){
+ my $h= 1;# if($size =~ /area(\d+)/);
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-colspan=>1},"$des"),"\n";
+ print $q->td({-class=>'content1_cms', -colspan=>'3'},$q->textarea(-class=>"autos", -style=>'border: 1px solid silver;background-color:#ededed;',-rows=>"$h",-cols=>'35em;', -name=>"$key", -override=>'1',-default=>"$ctrel->{$key}")),"\n";
+ }
+ elsif($key =~ /txt/ && $size =~ /area(\d+)/){
+ #my $h= $1 if($size =~ /area(\d+)/);
+ my $h= "height:" . $1 . "em;";
+ my $w = "width:25em;";
+ $w= "width:" . $2 . "em;" if($size =~ /area(\d+)-(\d+)/);
+ print $q->Tr();
+ print $q->td({-style=>'padding:4px 0 0 0px;',-colspan=>1},""),"\n";
+ print $q->td({-style=>'padding:4px 0 0 0px;',-colspan=>3},"$des"),"\n";
+ print $q->Tr();
+ print $q->td({-style=>'padding:4px 0 0 0px;',-colspan=>1},""),"\n";
+ if($key eq "txt28" && $ctrel->{$key} =~ /SEPA-Lastschriftmandat/){
+ use URI::Encode qw(uri_encode uri_decode);
+ $ctrel->{txt28} = uri_decode($ctrel->{txt28});
+ $ctrel->{txt28} =~ s/\+/ /g;
+ print $q->td({-style=>'border:1px solid silver;'},$ctrel->{txt28}),"\n";
+ }else{
+ print $q->td({-class=>'content1_cms', -colspan=>'3'},$q->textarea(-id=>"$key", -class=>"autos", -style=>"border: 1px solid silver;background-color:#ededed;$h $w", -name=>"$key", -override=>'1',-default=>"$ctrel->{$key}")),"\n";
+ }
+ }
+ elsif($key =~ /txt02/ && $varenv{syshost} =~ /sharee/){
+ #nothing txt02=Datei aktiv=10=sharee-APP aktivierte Dokument
+ }
+ elsif($key =~ /txt15/ && $varenv{syshost} =~ /sharee/ && $node_meta->{tpl_id} == 202){
+ my $w = $size . "em";
+ my $record_bonus = {c_id => 0};
+ my $pref_cc = {
+ table => "content",
+ fetch => "one",
+ template_id => "228",
+ ct_name => "$ctrel->{txt15}",
+ };
+ $record_bonus = $dbt->fetch_record($dbh,$pref_cc);
+
+ my @tariff = ("$ctrel->{txt30}");
+ @tariff = split(/\s/,$ctrel->{txt30}) if($ctrel->{txt30} =~ /\s/);
+ foreach my $tf_id (@tariff){
+ $tf_id =~ s/\s//g;
+ #print "$record_bonus->{int22} == $tf_id ";
+ if($record_bonus->{int22} == $tf_id){
+ $postdes = "Tarif: $record_bonus->{int21} - $record_bonus->{int22} (public - bonus)";
+ $postdes .= $q->span({-style=>'color:red;padding-left:10px;'},"Fehler: Bonusnummer") if(!$ctrel->{$key});
+ }
+ }
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$q->textfield(-class=>'etxt', -style=>"width:$w;",-name=>"$key", -override=>'1', -default=>"$ctrel->{$key}"), $postdes),"\n";
+ }
+ #Operators or Operators Antrag
+ elsif($key =~ /txt17|txt19/){
+ if($varenv{dbname} eq "sharee_primary"){
+ my $w = $size . "em";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$q->textfield(-class=>'etxt', -style=>"width:$w;",-name=>"$key", -override=>'1', -default=>"$ctrel->{$key}"), $postdes),"\n";
+ }
+ }
+ elsif($key =~ /txt/){
+ my $w = $size . "em";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$q->textfield(-class=>'etxt', -style=>"width:$w;",-name=>"$key", -override=>'1', -default=>"$ctrel->{$key}"), $postdes),"\n";
+ }
+ elsif($key =~ /byte/){
+ my $K_int = unpack "H*", $ctrel->{$key};
+ #$K_int =~ s/(.)/sprintf( "%x", ord($1))/eg;
+ my $w = $size . "em";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms',-colspan=>1},"$des"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'2'},$q->textfield(-class=>'etxt', -style=>"width:$w;",-name=>"$key", -override=>'1', -default=>"$K_int"), $postdes),"\n";
+
+ }
+
+ if($key =~ /date_time/){
+ #print $q->hidden(-name=>'t_id', -override=>'1',-value=>"$times_id");
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"Datum Start"),"\n";
+ print $q->td({-class=>'content1_cms', -colspan=>'1'},$q->textfield(-id=>'datepicker1',-class=>'etxt',-name=>"start_date",-default=>"$start_date",-override=>'1',-size=>"10",-maxlength=>10)),"\n";
+ print $q->td({-class=>'content1_cms', -colspan=>'1'},"Ende", $q->textfield(-id=>'datepicker2',-class=>'etxt',-name=>"end_date",-default=>"$end_date",-override=>'1',-size=>"10",-maxlength=>10)),"\n";
+ print $q->Tr();
+ print $q->td({-class=>'left_italic_cms'},"Uhrzeit Start"),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'1'},
+ $q->textfield(-class=>'etxt',-name=>"s_hh", -override=>'1',-default=>"$s_hh",-size=>"2",-maxlength=>2),":",
+ $q->textfield(-class=>'etxt',-name=>"s_mi", -override=>'1',-default=>"$s_mi",-size=>"2",-maxlength=>2)),"\n";
+ print $q->td({-class=>'content1_cms',-colspan=>'1'},"Ende",
+ $q->textfield(-class=>'etxt',-name=>"e_hh", -override=>'1',-default=>"$e_hh",-size=>"2",-maxlength=>2),":",
+ $q->textfield(-class=>'etxt',-name=>"e_mi", -override=>'1',-default=>"$e_mi",-size=>"2",-maxlength=>2)),"\n";
+ }
+ }
+ print $q->end_table;
+ print "\n";
+ print " \n";
+
+ print $q->end_table;
+ #2.table ende
+
+ print $q->div($but->singlesubmit7("$edit","$save_key","$ib{$save_key}","margin:10px 20px;")),"\n";
+ my $debug = "";
+ #$debug = "(ct_table: $node_meta->{ct_table} | main_id: $node_meta->{main_id} | c_id: $ctrel->{c_id} | tpl_id: $tpl->{tpl_id} | rel_id: $ctrel->{rel_id})";
+ print $q->div({-style=>'z-index:10;font-size:13px;'},"$debug"),"\n" if($users_dms->{u_id} eq $varenv{superu_id});
+
+ print " ";
+}
+1;
diff --git a/copri4/main/src/Tpl/Calorin.pm b/copri4/main/src/Tpl/Calorin.pm
new file mode 100644
index 0000000..85142d9
--- /dev/null
+++ b/copri4/main/src/Tpl/Calorin.pm
@@ -0,0 +1,467 @@
+package Calorin;
+#
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use Calendar::Simple;
+use Date::Calc qw(:all);
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Callib;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Mod::APIfunc;
+use Mod::Pricing;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my ($node_meta,$users_dms,$u_group,$return) = @_;
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $but = new Buttons;
+ my $cb = new Callib;
+ my $db = new Libenzdb;
+ my $apif = new APIfunc;
+ my $dbt = new DBtank;
+ my $pri = new Pricing;
+
+ my $lang = "de";
+ #my $rel = $db->get_relation($main_id,$lang);
+ my $tpl = $db->get_tpl($node_meta->{template_id});
+ my @tpl_order = split /,/,$tpl->{tpl_order};
+ my %varenv = $cf->envonline();
+ my %ib = $but->ibuttons();
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+
+ $path =~ s/\/user|\/manager|\/admin//;
+ my $now_time = strftime "%Y-%m-%d %H:%M", localtime;
+
+ my $table = "contenttrans";
+ my $u_name = $q->escapeHTML("$R::u_name");
+ my $ctf = $db->get_content1("contentuser",$dbt->{shareedms_conf}->{parent_id});
+ my $dbh = "";
+
+ my $channel_map = $dbt->channel_map();
+ my $mapref = {};
+ my $ct_users = $dbt->users_map($dbh,$mapref);#get serviceAPP and DMS users from contentadr
+
+ my @_users = (":user");
+ foreach my $id (sort { $channel_map->{$a} cmp $channel_map->{$b} } keys (%$channel_map)){
+ push (@_users, "$id:$channel_map->{$id}");
+ if($channel_map->{$id} eq $R::s_owner){
+ #$searchref->{owner} = $id;
+ #$s_u_name = $channel_map->{$id};
+ }
+ }
+
+ if(1==1){
+ foreach my $ctu_id (sort { $ct_users->{$a}->{txt01} cmp $ct_users->{$b}->{txt01} } keys (%$ct_users)){
+ push (@_users, "$ct_users->{$ctu_id}->{c_id}:$ct_users->{$ctu_id}->{txt01}");
+ if($ct_users->{$ctu_id}->{ct_name} && ($ct_users->{$ctu_id}->{txt01} =~ /$R::s_owner/i)){
+ #$searchref->{owner} = $ct_users->{$ctu_id}->{c_id};
+ #$s_u_name = $ct_users->{$ctu_id}->{txt01};
+ }
+ }
+ }
+
+ my $bnode = { template_id => 205,#Leihrad_liste
+ parent_id => 200013,#Waren
+ fetch => "all",
+ keyfield => "main_id",
+ };
+ my $bike_nodes = $dbt->fetch_rel4tpl4nd($dbh,$bnode);
+
+ my $root_id = 100;
+ #alle nicht abgeschlossene mandanten-einträge ....
+ my $x_main_ids = "$root_id,";
+ my $tplids = "$node_meta->{template_id},";
+ $tplids .= "$ctf->{txt34}," if($ctf->{txt34});
+ $tplids .= "$ctf->{txt35}," if($ctf->{txt35});
+ $tplids .= "$ctf->{txt36}," if($ctf->{txt36});
+
+ #sollte ins ctf-System. Verkaufliste,Verleihliste
+ #incl. Verkauf/Verleih journal
+ $tplids .= "204,207,218,209";
+ $tplids =~ s/,$//;
+
+ $x_main_ids .= $db->collect_noderec($root_id,$lang,"nothing");
+ $x_main_ids =~ s/,$//;
+ my $ct4rel = $db->collect_ct4rel4nd($table,"$x_main_ids","$lang","","","","","","$tplids","","c_id","");
+ my @months = $cb->monthmap();
+
+ my $hh;my $mm;
+ my $day = strftime "%d", localtime;
+ my $day_today = $day;
+ my $mon = strftime "%m", localtime;
+ my $mon_today = $mon;
+ my $year = strftime "%Y", localtime;
+ my $year_today = $year;
+ ($year,$mon,$day,$hh,$mm) = $lb->split_date($users_dms->{cal_start}) if($users_dms->{cal_start});
+
+ print $q->end_form;
+ print $q->start_form();
+
+ print "\n";
+
+ my $start_date_time = $R::start_date_time;
+ my $end_date_time = $R::end_date_time;
+
+ $start_date_time = "01.$mon.$year" if(!$start_date_time);
+
+
+ my $c_date; my $start_chck=0;my $end_chck=0;my $message;
+ if($start_date_time){
+ ($start_date_time,$start_chck) = $lb->checkdate($start_date_time) if($start_date_time ne "%");
+ print $q->div({-style=>'background-color:white;color:red;'},"→ Datum Eingabefehler: $start_date_time <<<") if($end_chck);
+ }
+ if($end_date_time){
+ ($end_date_time,$end_chck) = $lb->checkdate($end_date_time) if($end_date_time ne "%");
+ print $q->div({-style=>'background-color:white;color:red;'},"→ Datum Eingabefehler: $end_date_time <<<") if($end_chck);
+ }
+
+ if(!$end_date_time){
+ my $days4month = Days_in_Month($year,$mon);
+ $end_date_time = "$days4month.$mon.$year";
+ $end_date_time = $cb->datetime_defaults($end_date_time,"dummy",$lang);
+ }
+
+
+ my $limit = $R::limit || $varenv{limit} * 2;#max. 160 * 2
+ my $offset = $R::offset || "0";
+ if($R::detail_search){
+ $limit = 10000;
+ $offset = 0;
+ }
+ #backward | forward
+ if($R::go eq "backward_list"){
+ $offset -= $limit if($offset >= $limit);
+ }elsif($R::go eq "forward_list"){
+ $offset += $limit;
+ }
+
+ my $cttpos;
+ $R::ct_ct_name =~ s/\#//;
+ my $search = {
+ #table => "contenttranspos",
+ table => "$node_meta->{ct_table}",
+ cttpos_id => $q->escapeHTML("$R::cttpos_id"),
+ txt06 => $q->escapeHTML("$R::txt06"),
+ txt08 => $q->escapeHTML("$R::txt08"),
+ int04 => $q->escapeHTML("$R::int04"),
+ int06 => $q->escapeHTML("$R::int06"),
+ int12 => $q->escapeHTML("$R::int12"),
+ int13 => $q->escapeHTML("$R::int13"),
+ cp_ct_name => $q->escapeHTML("$R::cp_ct_name"),
+ int10 => $q->escapeHTML("$R::int10"),
+ int20 => $q->escapeHTML("$R::int20"),
+ barcode => $q->escapeHTML("$R::barcode"),
+ ct_txt06 => $q->escapeHTML("$R::ct_txt06"),#PLZ
+ ct_ct_name => $q->escapeHTML("$R::ct_ct_name"),
+ owner => $q->escapeHTML("$R::owner"),
+ limit => $q->escapeHTML($limit),
+ offset => $q->escapeHTML($offset),
+ cal_sort_updown => $users_dms->{cal_sort_updown},
+ };
+ $search = { %$search,
+ start_date_time => "$start_date_time",
+ end_date_time => "$end_date_time",
+ } if(!$R::cttpos_id);
+
+ if(!$start_chck && !$end_chck){
+ if($node_meta->{ct_table} eq "contenttranspos"){
+ $cttpos = $dbt->collect_transpos($dbh,$search);
+ }elsif($node_meta->{ct_table} eq "contenttheftpos"){
+ $cttpos = $dbt->collect_theftpos($dbh,$search);
+ }
+ }
+
+ #2019-05-09 collect content to get content.txt10 for Räder Status
+ my $tpl_id_ware = "205";
+ my $ct4rel_ware = {};
+ $ct4rel_ware = $db->collect_cid("content",$lang,$tpl_id_ware,"","","","");
+
+ my $header_style = "";
+ $header_style = "border:2px solid #9f1f0e;" if($message);
+ print $q->div({-class=>"copri_header",-style=>"background-color:$tpl->{bg_color};"},"$path", $q->span({-style=>"padding:4px 10px;color:white;"},
+ " $months[$mon -1] $year",
+ $q->a({-class=>"linknav",-style=>"padding:0 0.5em;",-title=>"Monat zurück",-href=>"?cal_delta_start=0:-1:0"}," ← "),
+ $q->a({-class=>"linknav",-style=>"padding:0 0.5em;",-title=>"Monat aktuell",-href=>"?cal_today=1"}," • "),
+ $q->a({-class=>"linknav",-style=>"padding:0 0.5em;",-title=>"Monat vorwärts",-href=>"?cal_delta_start=0:1:0"}," → "),
+ "$message"
+ )),"\n";
+
+ my $sort_up = "up";
+ my $sort_down = "down";
+ $sort_up = "$sort_up " if($users_dms->{cal_sort_updown} eq "up");
+ $sort_down = "$sort_down " if($users_dms->{cal_sort_updown} eq "down");
+
+ print $q->div({-style=>'background-color:silver;height:10px;'},""),"\n";
+
+ my $hstyle = "border-right: solid thin gray;border-bottom: solid thin gray;";
+ my $search = "search";
+ my $edit="ct_trans";
+ my $new_key="new_transdate";
+
+ print $q->start_table({ -style=>"width:100%;", -border=>'0',-align=>'left', -cellpadding=>'1', -cellspacing=>'0'});
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;$hstyle;width:30px;padding:1px 10px;"},$but->singlesubmit1("detail_search","$search")),"\n";
+
+
+ #1. Search-fields
+ my $h=3;
+ print "
\n";
+ print $q->a({-class=>"sortnav",-href=>"?cal_sort_updown=up\&offset=$offset\&limit=$limit",-title=>'Aufsteigend sortieren'},"$sort_up"),"|",$q->a({-class=>"sortnav",-href=>"?cal_sort_updown=down\&offset=$offset\&limit=$limit",-title=>'Absteigend sortieren'},"$sort_down"),"\n";
+ foreach(@tpl_order){
+ #$h++;
+ my ($key,$des,$size) = split /=/,$_;
+ if($key =~ /time/){
+ $size="10px";
+ print $q->textfield(-id=>'datepicker1',-class=>'etxt',-name=>"start_$key",-default=>"$start_date_time",-size=>"$size",-maxlength=>20), "-", $q->textfield(-id=>'datepicker2',-class=>'etxt',-name=>"end_$key",-default=>"$end_date_time",-size=>"$size",-maxlength=>20),"\n";
+ }
+ elsif($key =~ /owner/){
+ print $but->selector_class("$key","eselect","width:80px;",$R::owner,@_users),"\n";
+ }
+ elsif($key =~ /int10/ && "$size" eq "select"){# && $node_meta->{tpl_id} == 205){#bike_state
+ my @_lock_valxx = (":$des");
+ while (my ($key, $value) = each %{ $dbt->{copri_conf}->{bike_state} }) {
+ push @_lock_valxx, "$key:$value";#[1:available] ...
+ }
+ print $but->selector_class("$key","eselect","",$R::int10,@_lock_valxx),"\n";
+ }
+ elsif($key =~ /int12/ && "$size" eq "select"){# && $node_meta->{tpl_id} == 210){#Flotte bike_group (bikenode.main_id)
+ my @_valxx = (":$des");
+ foreach my $rid (sort { $bike_nodes->{$a}->{node_name} cmp $bike_nodes->{$b}->{node_name} } keys (%$bike_nodes)){
+ push (@_valxx, "$bike_nodes->{$rid}->{main_id}:$bike_nodes->{$rid}->{node_name} ($bike_nodes->{$rid}->{main_id})");
+ }
+ print $but->selector_class("$key","eselect","width:100px;",$R::int12,@_valxx),"\n";
+ }
+ elsif($key =~ /int20/ && "$size" eq "select"){# && $node_meta->{tpl_id} == 205){#lock_state locked/unlocked
+ my @_lock_valxx = (":$des");
+ while (my ($key, $value) = each %{ $dbt->{copri_conf}->{lock_state} }) {
+ push @_lock_valxx, "$key:$value";#[2:unlocked]
+ }
+ print $but->selector_class("$key","eselect","width:100px;",$R::int20,@_lock_valxx),"\n";
+ }
+ else{
+ $size="9px" if($key =~ /int/);
+ if($key =~ /ct_name/){
+ print $q->textfield(-class=>'stxt2',-name=>"$key",-default=>"",-size=>"$size",-maxlength=>40, -placeholder=>"$des",-autofocus=>1),"\n";
+ }else{
+ print $q->textfield(-class=>'stxt2',-name=>"$key",-default=>"",-size=>"$size",-maxlength=>40, -placeholder=>"$des"),"\n";
+ }
+ }
+ }
+ print " \n";
+
+
+ my ($daymarker,$raster_mmpx,$day4month) = $lb->month_line($users_dms);
+
+ print $q->Tr();
+ print $q->td({-class=>'element',-style=>"height:1.5em;padding:0;border:0px solid green;",-colspan=>"$h",-nowrap=>"1"},"$day4month"),"\n";
+ ###
+
+ ###Calendar Content
+ my $nx;my $set_style="";my $kind;
+ my $scale_color = $node_meta->{bg_color};
+ my $edit="ct_trans";
+ my $save_key="save";
+ my $delete_key="delete";
+ my $itime;
+ my $start_time;
+ my $end_time;
+ my ($year_st,$mon_st,$day_st,$hh_st,$mm_st);
+ my ($year_en,$mon_en,$day_en,$hh_en,$mm_en);
+
+ my $nr=0;
+ my $i= $offset || 0;
+ $users_dms->{cal_sort_updown} = "down" if(!$users_dms->{cal_sort_updown});
+ foreach my $pid (sort {
+ if($users_dms->{cal_sort_updown} eq "down"){
+ $cttpos->{$b}->{end_time} cmp $cttpos->{$a}->{end_time}
+ }else{
+ $cttpos->{$a}->{end_time} cmp $cttpos->{$b}->{end_time}
+ }
+ } keys(%$cttpos)){
+
+ $nr++;
+ $i++;
+ $nx++;
+ $set_style = "background-color:#fcfdfb;";
+ $set_style = "background-color:#f4f1ee;" if($nx %= 2);
+ #$set_style = "background-color:$varenv{calendar_active_color}" if("$R::c_idpos" == "$cttpos->{$pid}->{c_id}");
+
+ my $trans_style = "padding:0 5px;border: 2px solid #f7ae37;";
+ my $stamm_style = "padding:0 5px;border: 2px solid #98c13b;";
+ my $ware_style = "padding:0 5px;border: 2px solid #dcd77f;";
+
+ my ($ct_name,$ct_txt00,$ct_txt01,$ct_phone,$c_id4trans,$tpl_id4trans,$u_name,$order_state22);
+ my $id = $cttpos->{$pid}->{ct_id};
+ if($ct4rel->{$id}->{c_id} == $cttpos->{$pid}->{ct_id}){
+ $ct_name = $ct4rel->{$id}->{ct_name};
+ $ct_txt00 = $ct4rel->{$id}->{txt00};
+ $ct_txt01 = $ct4rel->{$id}->{txt01};
+ $ct_phone = $ct4rel->{$id}->{txt07};
+ $order_state22 = $ct4rel->{$id}->{txt22};
+ $c_id4trans = $ct4rel->{$id}->{c_id};
+ $tpl_id4trans = $ct4rel->{$id}->{template_id};
+ $trans_style .= "background-color:#f7ae37;" if($ct4rel->{$id}->{c_id} == $users_dms->{c_id4trans});
+ }
+ ($year_st,$mon_st,$day_st,$hh_st,$mm_st) = $lb->split_date($cttpos->{$pid}->{start_time}) if($cttpos->{$pid}->{start_time});
+ ($year_en,$mon_en,$day_en,$hh_en,$mm_en) = $lb->split_date($cttpos->{$pid}->{end_time}) if($cttpos->{$pid}->{end_time});
+
+ if($year_st && $mon_st && $day_st && $hh_st && $mm_st && $year_en && $mon_en && $day_en && $hh_en && $mm_en){
+
+ #generate px for rent scale
+ my $start_nr = $year_st . $mon_st . $day_st . $hh_st . $mm_st;
+ my $end_nr = $year_en . $mon_en . $day_en . $hh_en . $mm_en;
+ my $day_stpx = 0;
+ my $rent_day_px = 0;
+ my $time_style;
+ if($start_nr <= $end_nr){
+ ($day_stpx,$rent_day_px) = $lb->rent_scale($users_dms,$year_st,$mon_st,$day_st,$hh_st,$mm_st,$year_en,$mon_en,$day_en,$hh_en,$mm_en);
+ }else{
+ $time_style="color:red;";
+ }
+
+ if($cttpos->{$pid}->{start_time}){
+ $itime = $lb->time4de($cttpos->{$pid}->{itime},1);
+ $start_time = $lb->time4de($cttpos->{$pid}->{start_time},1);
+ $end_time = $lb->time4de($cttpos->{$pid}->{end_time},1);
+ }
+
+ my $u_name = $cttpos->{$pid}->{owner};
+ my $u_name_end = $cttpos->{$pid}->{owner_end};
+ foreach my $ctu_id (keys (%$ct_users)){
+ if($channel_map->{$u_name}){
+ $u_name = $channel_map->{$u_name};
+ }elsif($cttpos->{$pid}->{owner} eq $ct_users->{$ctu_id}->{c_id}){
+ $u_name = $ct_users->{$ctu_id}->{txt01};
+ }
+ if($channel_map->{$u_name_end}){
+ $u_name_end = $channel_map->{$u_name_end};
+ }elsif($cttpos->{$pid}->{owner_end} eq $ct_users->{$ctu_id}->{c_id}){
+ $u_name_end = $ct_users->{$ctu_id}->{txt01};
+ }
+ }
+
+
+ #if($ct_name){
+ if(1==1){
+ print "\n";
+
+ my $pos_hash = $cttpos->{$pid};
+ my $pos_details = "";
+ foreach my $did (sort keys (%{$pos_hash})){
+ $pos_details .= $did . " = " . $pos_hash->{$did} . "" if($pos_hash->{$did});
+ }
+ my $pos_id = "";
+ my $user_device = "";
+ #if($users_dms->{u_id} == $dbt->{copri_conf}->{bike_state}->{superu_id}){
+ if($users_dms->{u_id} && $users_dms->{u_id} =~ /1842|5781|11765/){
+ $pos_id = $q->div({-class=>"popup",-onclick=>"toggle_box('$pid')"},"$cttpos->{$pid}->{c_id}", $q->span({-class=>"popuptext",-id=>"$pid"},"$pos_details"));
+ my $txt26 = $cttpos->{$pid}->{txt26};
+ my $txt21 = $cttpos->{$pid}->{txt21};
+ $txt26 = substr($cttpos->{$pid}->{txt26},0,20) . " ..." if(length($cttpos->{$pid}->{txt26}) > 20);
+ $txt21 = substr($cttpos->{$pid}->{txt21},0,50) . " ..." if(length($cttpos->{$pid}->{txt21}) > 50);
+ $user_device = "";
+ $user_device .= " → lock charge $cttpos->{$pid}->{int14} %" if($cttpos->{$pid}->{int14});
+ $user_device .= " → agent $txt26" if($txt26);
+ $user_device .= " → device $txt21" if($txt21);
+ }
+
+ my $bikenr = "$cttpos->{$pid}->{barcode}";
+ $bikenr = $q->a({-class=>"linknav3",-style=>"$stamm_style",-href=>"$script/$users_dms->{fullurl}/Waren/?detail_search=1&s_barcode=$cttpos->{$pid}->{barcode}",-title=>"Rad im Warenstamm"},"$cttpos->{$pid}->{barcode}") if($cttpos->{$pid}->{cc_id});
+ # (Flotte $cttpos->{$pid}->{int12})
+ #
+
+ my $status = "$dbt->{copri_conf}->{bike_state}->{$cttpos->{$pid}->{int10}}" || "state failure";
+ $status = "$dbt->{copri_conf}->{bike_state}->{$cttpos->{$pid}->{int10}} " if($cttpos->{$pid}->{int10} == 2 || $cttpos->{$pid}->{int10} == 3);
+ if($cttpos->{$pid}->{int10} ne $ct4rel_ware->{$cttpos->{$pid}->{cc_id}}->{int10}){
+ $status = "$dbt->{copri_conf}->{bike_state}->{$cttpos->{$pid}->{int10}} ";
+ }
+ my $lock_state = "lock failure" if(!$cttpos->{$pid}->{int20});
+ $lock_state = "locked" if($cttpos->{$pid}->{int20} == 1);
+ $lock_state = "unlocked " if($cttpos->{$pid}->{int20} == 2);
+ $lock_state = "locking in progress " if($cttpos->{$pid}->{int20} == 3);
+
+ my $track_info = "";
+ my $co2saving = "";
+ if($cttpos->{$pid}->{int26}){
+ $co2saving = $pri->co2calc($cttpos->{$pid});
+ $cttpos->{$pid}->{int26} =~ s/\./,/;
+ $track_info = "→ - $co2saving kg CO² ($cttpos->{$pid}->{int26} km)";
+ }
+
+ if($node_meta->{ct_table} eq "contenttranspos"){
+ my $start_station = "$cttpos->{$pid}->{int06}";
+ my $end_station = "$cttpos->{$pid}->{int04}";
+ $start_station = $q->a({-class=>"linknav3",-style=>"",-href=>"$script/$users_dms->{fullurl}/Waren/?detail_search=1&s_int04=$cttpos->{$pid}->{int06}",-title=>"Rad Warenstamm nach Station filtern"},"$cttpos->{$pid}->{int06}") if($ct4rel_ware->{$cttpos->{$pid}->{cc_id}}->{rel_id});
+ $end_station = $q->a({-class=>"linknav3",-style=>"",-href=>"$script/$users_dms->{fullurl}/Waren/?detail_search=1&s_int04=$cttpos->{$pid}->{int04}",-title=>"Rad Warenstamm nach Station filtern"},"$cttpos->{$pid}->{int04}") if($ct4rel_ware->{$cttpos->{$pid}->{cc_id}}->{rel_id});
+ my $kunde = $q->a({-class=>"linknav3",-style=>"$ware_style",-href=>"$script/$users_dms->{fullurl}/Kunden/?detail_search=1&s_c_id=$cttpos->{$pid}->{ca_id}",-title=>"Kunde im Kundenstamm"},"$cttpos->{$pid}->{txt08} ($cttpos->{$pid}->{ca_id})");#2021-05-24 saves kd name
+
+ print $q->div({-style=>'float:left;margin-left:1em;font-size:0.91em;'}, "$i) $start_time – $end_time → $kunde → Start Station $start_station → End Station $end_station → Rad $bikenr $status $lock_state $track_info → $u_name $pos_id"),"\n";
+ print $q->div({-style=>'float:left;margin-left:1em;font-size:0.91em;'}, "→ Faktura", $q->a({-class=>"linknav3",-style=>"$trans_style",-href=>"$script/$users_dms->{fullurl}/Faktura?ct_trans=open\&c_id4trans=$c_id4trans\&tpl_id4trans=$tpl_id4trans\&kind_of_trans=Faktura\&owner=$users_dms->{owner}",-title=>"Faktura Terminal öffnen"},"\#$ct_name")),"\n";
+ print $q->div({-style=>'float:left;margin-left:1em;font-size:0.91em;'}, "$user_device"),"\n";
+
+ }elsif($node_meta->{ct_table} eq "contenttheftpos"){
+ my $speed = 0;
+ if($cttpos->{$pid}->{int07} && $cttpos->{$pid}->{int07} > 0){
+ $speed = $cttpos->{$pid}->{int07} * 1.852;
+ $speed = $lb->round_half($speed);
+ }
+ my $event_type = "";
+ $event_type = "Diebstahlalarm" if($cttpos->{$pid}->{int01});
+ $event_type = "GPS $cttpos->{$pid}->{txt06} → speed $speed km/h → distance $cttpos->{$pid}->{int08} Meter" if($cttpos->{$pid}->{int02});
+ print $q->div({-style=>'float:left;margin-left:1em;font-size:0.91em;'}, "$i) $end_time → $event_type → Rad $bikenr → $u_name $pos_id"),"\n";
+
+ }
+
+ print $q->div({-style=>"position:absolute;margin-left:$daymarker;border-right: solid thin #86cb00;height:1.5em;"}," "),"\n" if("$mon" eq "$mon_today");
+ print $q->div({-style=>"position:static;margin-left:$day_stpx;width:$rent_day_px;height:1.5em;background-color:$scale_color;"}," "),"\n";
+ print " \n";
+ }
+ }
+ }
+
+ print $q->end_table;
+ ###
+
+ print "\n";
+
+ my $offset_nr = $offset + $nr;
+
+ #backward | forward
+ print $q->div({-style=>'float:left;padding:0.5em;'}, "Zeile: $offset - $offset_nr"),"\n";
+ print "\n";
+ print $q->a({-class=>"linknav",-href=>"?go=backward_list;offset=$offset;limit=$limit",-title=>''},"< zurück ... ") if($offset >= $limit);
+ print $q->a({-class=>"linknav",-href=>"?go=forward_list;offset=$offset;limit=$limit",-title=>''}," ... vorwärts >") if($nr >= $limit-10);
+ print "
\n";
+
+ print $q->end_form;
+}
+1;
+
diff --git a/copri4/main/src/Tpl/Liste3.pm b/copri4/main/src/Tpl/Liste3.pm
new file mode 100644
index 0000000..4b5de53
--- /dev/null
+++ b/copri4/main/src/Tpl/Liste3.pm
@@ -0,0 +1,1517 @@
+package Liste3;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#
+#uncomment for perl -cw src/Tpl/Liste3.pm
+#use lib qw(/var/www/copri4/main/src);
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use URI::Escape;
+use Encode;
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Date::Calc qw(:all);
+use Scalar::Util qw(looks_like_number);
+use Storable;
+use Mod::APIfunc;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift;
+ my $u_group = shift;
+ my $return = shift;
+
+ my $q = new CGI;
+ my @keywords = $q->param;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $but = new Buttons;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+
+ my %varenv = $cf->envonline();
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $lang = "de";
+ my $now_db = strftime("%d.%m.%Y %H:%M:%S",localtime(time));
+ my $dbh = "";
+ my $debug = 0;
+
+ $path =~ s/\/login|\/user|\/manager|\/admin|\/$//;
+ my $user_agent = $q->user_agent();
+ my $fullurl = $users_dms->{fullurl};
+ my $saved_query = $q->url(-query=>1);
+ my %ib = $but->ibuttons();
+ my $main_id = $node_meta->{main_id};
+ my $tpl_id = $node_meta->{template_id};
+ my $time = time;
+ my $today = strftime("%d.%m.%Y",localtime(time));
+ my $now_date = strftime("%Y-%m-%d",localtime(time));
+ #steht auch in Libenz
+ my @months = ("Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember");
+ my $mon = strftime "%m", localtime;
+ my $hh;my $mm;
+ my $day = strftime "%d", localtime;
+ my $mon = strftime "%m", localtime;
+ my $year = strftime "%Y", localtime;
+ ($year,$mon,$day,$hh,$mm) = $lb->split_date($users_dms->{cal_start}) if($users_dms->{cal_start});
+
+################### new from Callib for collect_pos() ################
+
+ my $start_date_time = $R::start_date_time;
+ my $end_date_time = $R::end_date_time;
+
+ $start_date_time = "01.$mon.$year" if(!$start_date_time);
+
+
+ my $days4month = Days_in_Month($year,$mon);
+ $end_date_time = "$days4month.$mon.$year" if(!$end_date_time);
+
+ my $c_date; my $start_chck=0;my $end_chck=0;my $message;
+ if($start_date_time){
+ ($start_date_time,$start_chck) = $lb->checkdate($start_date_time) if($start_date_time ne "%");
+ $message .= ">>> Datum Eingabefehler: $start_date_time <<<" if($start_chck);
+ }
+ if($end_date_time){
+ ($end_date_time,$end_chck) = $lb->checkdate($end_date_time) if($end_date_time ne "%");
+ $message .= ">>> Datum Eingabefehler: $end_date_time <<<" if($end_chck);
+ }
+
+ #sammle alle termine im definierten Zeitraum
+ my $search_startdt = $start_date_time;
+ my $search_enddt = $end_date_time;
+ #FIXME
+ $end_date_time .= " 23:59" if($end_date_time !~ / \d\:\d/);
+
+ if("$start_date_time" eq "01.$mon.$year"){
+ $search_startdt = "date \'$start_date_time\' - integer \'31\'"
+ }else{
+ $search_startdt = "\'$start_date_time\'"
+ }
+ if("$end_date_time" eq "$days4month.$mon.$year"){
+ $search_enddt = "date \'$end_date_time\' + integer \'31\'"
+ }else{
+ $search_enddt = "\'$end_date_time\'"
+ }
+
+ my $cttpos = {};
+ my $cttpos_trans = {};
+ my $cttpos_theft = {};
+ if(($node_meta->{ct_table} eq "content") && ($node_meta->{tpl_id} == 205) && (!$start_chck && !$end_chck)){
+ my $cttpos1 = $db->collect_postime("contenttranspos","$search_startdt","$search_enddt","$start_date_time","$end_date_time");
+ foreach my $key (keys %$cttpos1){
+ $cttpos_trans->{"trans_" . $key} = $cttpos1->{$key};
+ }
+ my $cttpos2 = $db->collect_postime("contenttheftpos","$search_startdt","$search_enddt","$start_date_time","$end_date_time");
+ foreach my $key (keys %$cttpos2){
+ $cttpos_theft->{"theft_" . $key} = $cttpos2->{$key};
+ }
+ }
+
+ $cttpos = { %$cttpos_trans, %$cttpos_theft };
+
+#####################################################################
+
+ my $table = $node_meta->{ct_table} || "content";
+
+ my $hashfile = "$varenv{logdir}/$users_dms->{u_id}-$table-searchhash";
+
+ if((!$users_dms->{ek_view}) && ($table eq "content")){
+ $node_meta->{tpl_order} =~ s/int01=EK €=5,//;
+ }
+ if($table eq "content"){
+ $node_meta->{tpl_order} =~ s/txt17=[\w\s=]+,//;
+ $node_meta->{tpl_order} =~ s/byte01=[\w\s=]+,//;
+ }
+ if($table eq "contentadr" && $varenv{dbname} ne "sharee_primary"){
+ $node_meta->{tpl_order} =~ s/txt17=[\w\s=]+,//;
+ $node_meta->{tpl_order} =~ s/txt19=[\w\s=]+,//;
+ }
+ $node_meta->{tpl_order} =~ s/c_id=raw=[\w\s=]+// if($users_dms->{u_id} != $dbt->{copri_conf}->{superu_id});
+
+ my @tpl_order = split /,/,$node_meta->{tpl_order};
+
+ my $scol = "c_id";
+ $scol = "txt01" if($path =~ /Waren/);
+ #table columne check for col_sort
+ if($users_dms->{col_sort} eq "node_name" && ($table eq "contenttver")){
+ $scol = "node_name";
+ }elsif($users_dms->{col_sort} eq "date_time" && ($table =~ /contenttver|contenttrans/)){
+ $scol = "end_time";
+ }elsif($users_dms->{col_sort}){
+ my $tinfo = $db->table_info($table);
+ foreach (keys(%$tinfo)){
+ $scol = "$users_dms->{col_sort}" if("$users_dms->{col_sort}" eq "$tinfo->{$_}->{attname}");
+ }
+ $db->users_up("col_sort","0",$users_dms->{owner}) if("$scol" ne "$users_dms->{col_sort}");
+ }
+
+ my $limit = $R::limit || $varenv{limit};
+ my $offset = $R::offset || "0";
+ if($node_meta->{int10} && $node_meta->{int10} < $varenv{limit}){
+ $offset = 0;
+ }
+
+
+ #backward | forward
+ if($R::go && $R::go eq "backward_list"){
+ $offset -= $limit if($offset >= $limit);
+ }elsif($R::go && $R::go eq "forward_list"){
+ $offset += $limit;
+ }
+
+ my ($daymarker,$raster_mmpx,$day4month) = $lb->month_line($users_dms);
+ my $rows = 0;
+ my $tpath = "";
+
+ #get Firma
+ my $ctf = $db->get_content1("contentuser","$dbt->{sharedms_conf}->{parent_id}");
+ #get Benutzer
+ my $ctb = $db->get_content1("contentuser","$users_dms->{owner}");
+
+
+ my ($umsatz,$edit,$new_key,$copy_key,$save_key,$delete_key,$c_id4csv);
+ my $ct4rel = {};
+ my $ct4rel_parts = {};
+ my $k=0;
+ my $message = "";
+
+ #print $q->end_form,"\n";
+ print "\n";
+
+ my $v_journal = $R::v_journal || "";
+ #if($path =~ /(\w+journal)/){
+ # $v_journal = "$1" ;
+ #}
+ if($node_meta->{main_id} == $dbt->{shareeconf_dms}->{invoicejournal}){
+ $v_journal = $node_meta->{node_name};
+ }
+
+ my $date = "";
+ my $start_chck = 0;
+ my $end_chck = 0;
+ my $last_year = "";
+ if($R::s_start_mtime){
+ ($date,$start_chck) = $lb->checkdate($R::s_start_mtime) if($R::s_start_mtime !~ "%");
+ $message .= ">>> Datum Eingabefehler: $date <<<" if($start_chck);
+ my ($c_dd,$c_mm,$c_yy) = split(/\./,$date);
+ $last_year = $c_yy if("$c_yy" eq "2011");
+ }
+ if($R::s_end_mtime){
+ ($date,$end_chck) = $lb->checkdate($R::s_end_mtime) if($R::s_end_mtime !~ "%");
+ $message .= ">>> Datum Eingabefehler: $date <<<" if($end_chck);
+ my ($c_dd,$c_mm,$c_yy) = split(/\./,$date);
+ }
+
+ my $searchref = {};
+
+ #Filter OPOS
+ if($path =~ /OPOS/){
+ $R::detail_search="suchen";
+ $searchref->{int14}=1;
+ $R::todo="Filter";
+ $message .= ">>> Offene Payone Posten (Fehlgeschlagene Geldeinzüge) <<<";
+ $offset=0;
+ $limit=10000;
+ }
+
+ if($path =~ /langzeit/){
+ $R::detail_search="suchen";
+ $searchref->{long_rent}="1 day";
+ $R::todo="Filter";
+ $message .= ">>> langzeit Mieten (größer 1 Tag) sollten vor Faktura überprüft werden <<<";
+ $offset=0;
+ $limit=10000;
+ }
+
+ if(!$v_journal && !$R::detail_search && -f $hashfile && ($path =~ /letzte Suche/ || ($limit > $varenv{limit} && !$ctb->{int04}))){
+ $R::todo="Filter";
+ $message .= ">>> es wurden die letzten Suchparameter oder Filter geladen <<<";
+ $offset=0;
+ $limit=10000;
+ }
+
+ my $opos = "";
+ if($node_meta->{node_name} eq "Tagesbericht"){
+ $offset=0;
+ $limit = "1000";
+ $R::detail_search="suchen";
+ $v_journal = $node_meta->{node_name};
+ $opos="null";
+ $tpl_id = 218;
+ }
+
+
+ my $max_timestamp = "";
+ $max_timestamp = "$1.$2.$3" if($ctf->{txt80} =~ /(\d{2})\.(\d{2})\.(\d{4})$/);
+ my $max_sum = $ctf->{int03} || "";
+ if($max_timestamp){
+ $limit = "2000";
+ $message .= ">>> Buchbare Rechnungspositionen laut Einstellungen bis Buchungsdatum: $max_timestamp <<<";
+
+ }
+ if($max_sum){
+ $message .= ">>> Buchbare Rechnungspositionen laut Einstellungen bis Verkaufssumme: $max_sum € <<<";
+ }
+ $message=$R::message if($R::message);
+
+ #CSV
+ my $export;
+ my $ck4ex = "@R::ck4ex" || "";
+ $export = "check4export" if($R::ck4ex);
+ if($export || $R::ck4ex){
+ $db->users_up("time4csv","$time",$users_dms->{u_id});
+ $users_dms = $db->select_users($users_dms->{u_id});
+ }
+
+ #path-line
+ my $redirect;
+ $redirect = "(redirected)" if($R::redirected);
+ #top of bootstrap
+ my $header_style = "";
+ $header_style = "border:2px solid #9f1f0e;" if($message);
+
+ if($node_meta->{tpl_id} == 205){
+ print $q->div({-class=>"copri_header",-style=>"background-color:$node_meta->{bg_color};"},"$path", $q->span({-style=>"padding:3px 10px;background-color:#86cbd7;color:white;"},
+ " $months[$mon -1] $year",
+ $q->a({-class=>"linknav",-style=>"padding:0 0.5em;",-title=>"Monat zurück",-href=>"?cal_delta_start=0:-1:0"}," ← "),
+ $q->a({-class=>"linknav",-style=>"padding:0 0.5em;",-title=>"Monat aktuell",-href=>"?cal_today=1"},"•"),
+ $q->a({-class=>"linknav",-style=>"padding:0 0.5em;",-title=>"Monat vorwärts",-href=>"?cal_delta_start=0:1:0"}," → "),
+ "$message"
+ )),"\n";
+ }else{
+ print $q->div({-class=>"copri_header",-style=>"background-color:$node_meta->{bg_color};"},"$path $redirect",$q->span({-style=>"$header_style"},"$message"));
+ }
+
+ print $q->start_form(-name=>'searchform');
+ print $q->hidden(-name=>'todo', -value=>"Mindermenge") if($R::todo && $R::todo =~ /Mindermenge/);
+ print $q->hidden(-name=>'todo', -value=>"Waren-Summe") if($R::todo && $R::todo =~ /Waren-Summe/);
+ print $q->hidden(-name=>'offset', -value=>"$offset");
+ print $q->hidden(-name=>'main_id', -value=>"$node_meta->{main_id}");
+ print $q->hidden(-name=>'kind_of_trans', -value=>"$node_meta->{node_name}");
+ print $q->hidden(-name=>'mode', -value=>"manager");
+ print $q->hidden(-name=>'owner', -value=>"$users_dms->{u_id}");
+ print $q->hidden(-name=>'template_id', -value=>"$node_meta->{template_id}");
+
+ my $tplids = "$tpl_id," || 0;
+ $tplids = "205,224,225,210,226,227,228,229" if(($table !~ /contentadr|contenttrans|contenttver|contentnel/) && !$export);
+ $tplids = 205 if($path =~ /Waren$/);#Defaults to only Verleih_list
+
+ #collect depends Reparatur_list (AWs) template
+ my $ct_aw; my $ct4aw;
+ if($v_journal){
+ $ct4aw = $db->collect_cid("content",$lang,"199");
+ foreach my $aw_id (keys (%$ct4aw)){
+ $ct_aw .= "$ct4aw->{$aw_id}->{c_id}|"
+ }
+ $ct_aw =~ s/\|$//;
+ }
+
+ my $s_ct_name = $q->escapeHTML($R::s_ct_name) || "";
+ my $s_barcode = $q->escapeHTML($R::s_barcode) || "";
+
+ #mandanten-modul abhängige rekursive suche
+ my $main_ids = "";
+ if($v_journal && $v_journal =~ /Verleihjournal|Verkaufsjournal/){
+ $main_ids = $dbt->{shareedms_conf}->{invoicejournal};
+ $tplids = 209;
+ }else{
+ $main_id = $dbt->{shareedms_conf}->{faktura} if($v_journal && $v_journal =~ /bericht/ || $R::todo);#starts at root
+ $main_ids = "$main_id,";
+ my $excluded = "journal";#case is defined
+ $excluded = "Storno" if($R::todo && $R::todo eq "Filter");
+ $main_ids .= $db->collect_noderec($main_id,$lang,"$excluded");
+ }
+ $main_ids =~ s/,$//;
+
+ if($v_journal){
+ $offset=0;
+ $limit=10000;
+ $umsatz = "AW";
+ }
+
+ #Waren-nodes für Umsatz-Auswertung
+ my $w_nodes = "";
+ my $verleih_nodes = "";
+
+ my $relnod = "";
+ $relnod = $db->collect_rel4nodes($main_ids,"","","rel_id");
+
+ #Faktura/Verkaufsjournal menue (ex. Verleihjournal)
+ my $j_exist = $db->get_node4multi("300011",$lang);
+
+ #nur für node_name in tabelle
+ my $nodes;
+ if($main_ids){
+ $nodes = $db->collect_node2($main_ids);
+ }else{
+ $lb->failure("Fehler! Es fehlen wichtige Einstellungen. ....journal-ID!");
+ }
+ my $kt_sum=0;
+ my $ct_name_set1;my $ct_name_set2;
+ my $ct_ids;my $ct_aw_ids; my $last_ab;
+
+ if($R::detail_search && $R::detail_search eq "suchen"){
+ $offset = 0;
+ $limit = 10000;
+ }
+
+ my $channel_map = $dbt->channel_map();
+ my $mapref = {};
+ my $ct_users = $dbt->users_map($dbh,$mapref);#get serviceAPP and DMS users from contentadr
+
+ my @_users = ("");
+ foreach my $id (sort { $channel_map->{$a} cmp $channel_map->{$b} } keys (%$channel_map)){
+ push (@_users, "$id:$channel_map->{$id}");
+ if($R::s_owner && $channel_map->{$id} eq $R::s_owner){
+ $searchref->{owner} = $id;
+ }
+ }
+ if(!$searchref->{owner}){
+ foreach my $ctu_id (sort { $ct_users->{$a}->{txt01} cmp $ct_users->{$b}->{txt01} } keys (%$ct_users)){
+ push (@_users, "$ct_users->{$ctu_id}->{c_id}:$ct_users->{$ctu_id}->{txt01}");
+ if($ct_users->{$ctu_id}->{ct_name} && ($R::s_owner && $ct_users->{$ctu_id}->{txt01} =~ /$R::s_owner/i) || ($ct_users->{$ctu_id}->{c_id} eq $searchref->{owner})){
+ $searchref->{owner} = $ct_users->{$ctu_id}->{c_id};
+ }
+ }
+ }
+
+ my $node = { template_id => 205,#Leihrad_liste
+ parent_id => 200013,#Waren
+ fetch => "all",
+ keyfield => "main_id",
+ };
+ my $bike_nodes = $dbt->fetch_rel4tpl4nd($dbh,$node);
+ my $tariff_all = $db->collect_ct4rel("content","300026",$lang,"","","","","210");
+
+ my $ctrel = {};
+ #only if permission read
+ if(($node_meta->{ct_table} eq "content" && $users_dms->{int01} >= 1) || ($node_meta->{ct_table} eq "contentadr" && $users_dms->{int02} >= 1) || ($node_meta->{ct_table} eq "contenttrans" && $users_dms->{int03} >= 1)){
+
+ my $c_id4trans = $R::c_id4trans || "";
+ #Take only c_id from users if
+ if($users_dms->{c_id4trans} && $R::ct_trans && (($R::ct_trans eq "add_transadr" && $R::c_idadr) || ($R::ct_trans eq "add_transpos" && $R::c_id) || $R::ct_trans eq "new_trans")){
+ $c_id4trans = $users_dms->{c_id4trans};
+ }
+
+ #only for adding to active transaction, disabled because of not browser tab save
+ #$ctrel = $db->get_ctrel("contenttrans","",$lang,"",$users_dms->{c_id4trans},$users_dms->{tpl_id4trans});
+
+ #without limit it will takes only one dataset
+ #if(($R::rel_id && $R::rel_id =~ /^\d+$/) || ($c_id4trans && $c_id4trans =~ /^\d+$/)){
+ if((($R::rel_id && $R::rel_id =~ /^\d+$/) || ($c_id4trans && $c_id4trans =~ /^\d+$/)) && ($limit > $varenv{limit})){
+ $ct4rel = $db->collect_cid($table,$lang,$tpl_id,$R::rel_id,$R::barcode,"c_id",$c_id4trans);
+ }
+
+ #Suchen
+ elsif(!$start_chck && !$end_chck){
+ #2020-12-01 changed to get last tablecontent, not only 1 by edit
+ #testing state
+ #if(!$start_chck && !$end_chck){
+ $rows = $db->count_content($table,"$main_ids","$tplids");
+
+ #collect search keys
+ foreach my $postkey (@keywords){
+ foreach(@tpl_order){
+ my ($key,$val,$size) = split /=/,$_;
+ if($postkey =~ /s_$key|s_start_$key|s_end_$key/){
+ my $val = $q->param($postkey);
+ $postkey =~ s/^s_//;
+ $searchref->{$postkey} = $val;
+ }
+ }
+ }
+
+ #trying to save hashref
+ if(!$v_journal && $R::detail_search && ref($searchref) eq "HASH"){
+ store $searchref, $hashfile;
+ }elsif(!$v_journal && !$R::detail_search && !$ctb->{int04} && -f $hashfile && ($path =~ /letzte Suche/ || $limit > $varenv{limit})){
+ $searchref = {};
+ $searchref = retrieve($hashfile);
+ }
+
+ #print Dumper($searchref);
+
+
+ #Because of pre counting sum_pos
+ if($node_meta->{node_name} eq "Faktura"){
+ if($v_journal && (!$R::detail_search || $R::s_start_mtime && $R::s_start_mtime =~ /letzt/)){
+ my $xtime = "date \'$today\' + integer \'7\'";#just time
+ $last_ab = $db->get_content6("contenttrans","state","Kassenbestand","int09","$dbt->{shareedms_conf}->{parent_id}","int12","$j_exist->{main_id}","close_time","$xtime","");
+ }
+ #
+ my $v_journalparts = $v_journal . "_parts";
+ $ct4rel_parts = $db->search_content3($searchref,$table,$dbt->{shareedms_conf}->{parent_id},$node_meta->{node_name},$users_dms->{u_id},$lang,"$main_ids","$tplids","$ct_ids",$v_journalparts,$time,$R::s_kontext,$scol,$users_dms->{sort_updown},$offset,$limit,$export,$R::todo,$ck4ex,$opos);
+
+ #collect invoice ids in kontext of parts
+ foreach my $cp_id (keys (%$ct4rel_parts)){
+ $ct_ids .= "$ct4rel_parts->{$cp_id}->{ct_id}," if($R::detail_search && ($R::s_kontext && $R::s_kontext eq "Waren" || $export eq "FiBu"));
+ #pre collect of trans for AW
+ if(($umsatz eq "AW") && "$ct_aw" && ($ct4rel_parts->{$cp_id}->{cc_id} =~ /$ct_aw/)){
+ $ct_aw_ids .= "$ct4rel_parts->{$cp_id}->{ct_id}|";#
+ }
+ }
+ }
+
+ $ct4rel = $db->search_content3($searchref,$table,$dbt->{shareedms_conf}->{parent_id},$node_meta->{node_name},$users_dms->{owner},$lang,"$main_ids","$tplids","$ct_ids",$v_journal,$time,$R::s_kontext,$scol,$users_dms->{sort_updown},$offset,$limit,$export,$R::todo,$ck4ex,$opos);
+ }#end $ct4rel collect
+ }else{
+ $return = "failure::Abbruch. Keine Zugriffsberechtigung";
+ }#end permission read
+
+ my $max_sum_pos = -10000;
+ my $max_op = ">=";
+ if($searchref->{int01} =~ /\d/){
+ $max_sum_pos = $searchref->{int01};
+ $max_sum_pos =~ s/\s//g;
+ $max_sum_pos =~ s/,/./g;
+ #$max_op = "==";
+ if($max_sum_pos =~ /(\<\=|\>\=|\<|\>|\=\=)(\d+)/){
+ $max_op = $1;
+ $max_sum_pos = $2;
+ }
+ }
+ print $q->div({-style=>'background-color:silver;height:10px;'}," "),"\n";
+ my $hstyle = "border-right: solid thin gray;border-bottom: solid thin gray;";
+ if($v_journal && $v_journal =~ /journal/){
+ my ($a_check,$b_check,$c_check,$d_check,$f_check,$g_check);
+ $a_check = "1" if($R::s_kontext && $R::s_kontext eq "Waren");
+ $umsatz="Summe der gefundenen Waren" if($R::s_kontext && $R::s_kontext eq "Waren");
+ $b_check = "1" if($R::s_kontext && $R::s_kontext eq "Beleg" || !$R::s_kontext);
+ my @_s_time_defaults = ("0,manuelle Eingabe in \"bearbeitet\"","7,1 Woche","14,2 Wochen","28,4 Wochen","365,1 Jahr");
+ #print $q->div({-style=>'float:left;background-color:silver;'},"
Suchzeitraum: ",$but->selector("selected_start_mtime","130px","$R::selected_start_mtime",@_s_time_defaults));
+ print "
\n";
+ print $q->span("Suchkontext: ",$but->radiobox("Beleg","s_kontext","$b_check"),"$node_meta->{node_name}/Kunde");
+ print $q->span($but->radiobox("Waren","s_kontext","$a_check"),"Waren/FiBu");
+ print "
\n";
+ }
+ print $q->hidden(-name=>'mandant_main_id', -value=>"$dbt->{shareedms_conf}->{parent_id}"),"\n";
+ print $q->hidden(-name=>'tpl_id4trans', -value=>"$node_meta->{tpl_id}"),"\n";
+
+ print $q->start_table({ -style=>'clear:both;', -border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'0', -cellspacing=>'0'}),"\n";
+ #1. Zeile mit Suchfelder und NEU-Anlage
+ #table-switch!!!
+ my $sb_style = "";
+ my $search = "search";
+ if($v_journal =~ /journal/){
+ $search = "search_export";
+ $sb_style= "font-size:0.61em;";
+ }
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-style=>"background-color:silver;$hstyle"},$but->singlesubmit1("detail_search","$search","","$sb_style;"),"\n");
+
+ $edit="rel_edit";
+ $new_key="new_content";
+ $save_key="save_content";
+ $delete_key="delete_content";
+ my $a_color = $node_meta->{bg_color} || "yellow";
+ if($table eq "contentadr"){
+ $edit="rel_edit";
+ $new_key="new_adr";
+ $save_key="save_adr";
+ $delete_key="delete_adr";
+ }
+ #contenttrans | contenttver via ct_trans
+ if($table eq "contenttrans"){
+ $edit="ct_trans";
+ $new_key="new_trans";
+ $delete_key="delete_trans";
+ }elsif($table eq "contenttver"){
+ $edit="ct_trans";
+ $new_key="new_tver";
+ $delete_key="delete_tver";
+ }
+ if($node_meta->{parent_id} >= "200000" && !$v_journal){
+ print $q->td({-style=>"width:25px;background-color:$a_color;$hstyle"}, $but->singlesubmit2glyph("$edit","$new_key","$ib{$new_key}","background-color:$a_color;"));
+ print $q->hidden(-name=>'open_set_main_id', -value=>"$node_meta->{main_id}") if($table =~ /contenttrans/);
+ }else{
+ print $q->td({-class=>'ebutton',-style=>"width:25px;background-color:$a_color;$hstyle"}," "),"\n";
+ }
+
+ #1. Search-fields
+ my $h=0;
+ my $s_val;
+ foreach(@tpl_order){
+ $h++;
+ my ($key,$val,$size) = split /=/,$_;
+ if($size =~ /area/){
+ $size = "10em";
+ }elsif($key =~ /int0|c_id/){
+ $size = "1em" if(!$size);
+ }
+
+ $s_val = $searchref->{$key};
+ #print "$key=$searchref->{$key}|";
+ if($key =~ /byte|node|txt|int|uri|ct_name|c_id|barcode|sort|public/){
+ if($table eq "content" && $tpl_id == 225 && $key eq "int04"){
+ print $q->td({-class=>"search_line"},$q->textfield(-class=>'stxt',-name=>"s_$key",-default=>"$s_val",-size=>"$size",-maxlength=>40, -autofocus=>1),"\n");
+ }elsif($table eq "content" && $key eq "barcode"){
+ print $q->td({-class=>"search_line"},$q->textfield(-class=>'stxt',-name=>"s_$key",-default=>"$s_val",-size=>"$size",-maxlength=>40, -autofocus=>1),"\n");
+ }elsif($table =~ /contentadr|contenttrans/ && $key eq "txt08"){
+ print $q->td({-class=>"search_line"},$q->textfield(-class=>'stxt',-name=>"s_$key",-default=>"$s_val",-size=>"$size",-maxlength=>40, -autofocus=>1),"\n");
+ }elsif($size =~ /select/ && $key =~ /int12|txt24/ && $tpl_id =~ /225|210/){#txt24=Flotten ID select
+ my @s_valxx = ("");
+ foreach my $rid (sort { $bike_nodes->{$a}->{node_name} cmp $bike_nodes->{$b}->{node_name} } keys (%$bike_nodes)){
+ push (@s_valxx, "$bike_nodes->{$rid}->{main_id}:$bike_nodes->{$rid}->{node_name} - $bike_nodes->{$rid}->{main_id}");
+ }
+ print $q->td({-class=>'search_line'},$but->selector_class("s_$key","","",$s_val,@s_valxx)),"\n";
+ }elsif($size =~ /select/ && $key =~ /int21|int22/ && $tpl_id == 228){#Bonusnummern
+ my @s_valxx = ("");
+ foreach my $rid (sort { $tariff_all->{$a}->{barcode} <=> $tariff_all->{$b}->{barcode} } keys (%$tariff_all)){
+ push (@s_valxx, "$tariff_all->{$rid}->{barcode}:$tariff_all->{$rid}->{barcode} - $tariff_all->{$rid}->{txt01}");
+ }
+ print $q->td({-class=>'search_line'},$but->selector_class("s_$key","","",$s_val,@s_valxx)),"\n";
+ }elsif($size =~ /select/ && $key !~ /txt23|txt24/){#txt23=color-code or txt24=Flotten ID select
+ my @s_valxx = ("");
+ my $s_hash = {};
+ $s_hash = $dbt->{copri_conf}->{lock_state} if($tpl_id == 205 && $key eq "int20");
+ $s_hash = $dbt->{copri_conf}->{bike_state} if($tpl_id == 205 && $key eq "int10");
+ $s_hash = $dbt->{copri_conf}->{station_state} if($tpl_id == 225 && $key eq "int10");
+ $s_hash = $dbt->{copri_conf}->{lock_system} if($tpl_id == 205 && $key eq "int11");
+ $s_hash = $dbt->{copri_conf}->{sharing_type} if($tpl_id == 210 && $key eq "int18");
+ $s_hash = { 1 => 1, 2 => 2, 3 => 3, 4 => 4 } if($tpl_id == 225 && $key eq "int07");
+ while (my ($key, $value) = each %{ $s_hash }) {
+ push @s_valxx, "$key:$value";#[2:unlocked]
+ }
+ print $q->td({-class=>'search_line'},$but->selector_class("s_$key","","",$s_val,@s_valxx)),"\n";
+ }else{
+ print $q->td({-class=>"search_line"},$q->textfield(-class=>'stxt',-name=>"s_$key",-default=>"$s_val",-size=>"$size",-maxlength=>40),"\n");
+ }
+ }elsif($key =~ /owner/){
+ print $q->td({-class=>'search_line'},$but->selector("s_$key","80px","$s_val",@_users)),"\n";
+ }elsif($key =~ /state/){
+ my @_states = split(/\|/,$varenv{Zahlungsweise});
+ my @_orderstates = split(/\|/,$varenv{order_state});
+ push (@_states,@_orderstates);
+ print $q->td({-class=>'search_line'},$but->selector("s_$key","80px","$s_val",@_states)),"\n";
+ }
+ my $s_mtime; my $e_mtime;
+ if($key eq "mtime"){
+ $s_mtime = $searchref->{start_mtime};
+ $e_mtime = $searchref->{end_mtime};
+ }
+ if($key eq "atime"){
+ $s_mtime = $searchref->{start_atime};
+ $e_mtime = $searchref->{end_atime};
+ }
+ if($key eq "bctime"){
+ $s_mtime = $searchref->{start_bctime};
+ $e_mtime = $searchref->{end_bctime};
+ }
+ if($key eq "date_time"){
+ $s_mtime = $searchref->{start_date_time};
+ $e_mtime = $searchref->{end_date_time};
+ }
+
+ print $q->td({-nowrap=>1,-class=>"search_line"},$q->textfield(-id=>'datepicker1',-class=>'stxt',-name=>"s_start_$key",-default=>"$s_mtime",-size=>"$size",-maxlength=>20)),"\n" if($key =~ /time/);
+ }
+
+
+ #2. Tableheader
+ print $q->Tr();
+ #permissions
+ if($users_dms->{int07} == 2){#only DMS-Account Admin
+ print $q->td({-style=>"background-color:silver;"},$q->checkbox(-name=>'toggle_all', -checked=>'', -value=>'off', -label=>'', -title=>'Alle auswählen', -onclick=>'CheckAll();')),"\n";
+ }else{
+ print $q->td({-style=>"background-color:silver;"}," "),"\n";
+ }
+ my $i=0;
+ $i += 2;
+ if($R::ck4ex){
+ print $q->th({-colspan=>2,-style=>'text-align:left;'},$q->a({-class=>'linknav3', href=>"$varenv{metahost}/pdf/$users_dms->{u_id}-$users_dms->{time4csv}.csv"},"CSV")," | ",$q->a({-class=>'linknav3', href=>"$varenv{metahost}/pdf/$users_dms->{u_id}-$users_dms->{time4csv}.xls"},"XLS")),"\n";
+ }else{
+ my $sort_up = "up";
+ my $sort_down = "down";
+ $sort_up = "
$sort_up " if($users_dms->{sort_updown} eq "up");
+ $sort_down = "
$sort_down " if($users_dms->{sort_updown} eq "down");
+
+ print $q->th($q->a({-class=>"sortnav",-href=>"?sort_updown=up\&offset=$offset\&limit=$limit",-title=>'Aufsteigend sortieren'},"$sort_up"),"|",$q->a({-class=>"sortnav",-href=>"?sort_updown=down\&offset=$offset\&limit=$limit",-title=>'Absteigend sortieren'},"$sort_down")),"\n";
+ print $q->th(""),"\n";
+ }
+ foreach (@tpl_order){
+ my ($key,$val,$size,$title) = split /=/,$_;
+ my $sort_title=" $title";
+ $val = "
$val " if($key eq $users_dms->{col_sort});
+ if($key =~ /byte|txt|time|node|int|uri|save|state|owner|c_id|ct_name|barcode|sort|public/){
+ $i++;
+ print $q->th($q->a({-class=>"sortnav",-href=>"?col_sort=$key\&offset=$offset\&limit=$limit",-title=>"$sort_title"},"$val")),"\n";
+ }
+ }
+
+ #TODO, chrome breaks timeline
+ #print $q->th(" "),"\n";
+ my $tdcal = scalar @tpl_order;
+ #$tdcal++;
+ #print "$tdcal xxxxxxxxx";
+ if($tpl_id == "205"){#205=Verleih
+ print $q->Tr();
+ print $q->td({-style=>'background-color:silver;'},""),"\n";
+ print $q->td({-class=>'tdtxt',-style=>'background-color:silver;',-colspan=>2},"$months[$mon -1] $year"),"\n";
+ print $q->td({-style=>"font-size:0.71em;padding:0;border:0px solid green;",-colspan=>"$tdcal",-nowrap=>"1"},"$day4month"),"\n";
+ }
+ #print $q->end_form,"\n";
+
+ my $sum_bar="0";my $sum_ec="0";my $sum_kredit="0";my $sum_abb="0";my $sum_ueb="0";my $sum_geka="0";my $sum_paypal="0";my $sum_SEPApayone="0";my $sum_CCpayone="0";my $sum_ausfall="0";my $sum_kasse="0";my $sum_start="0";my $close_time="";my $payment_time="";my $sum_waren;my $sum_verkauf;my $sum_kaution;my $sum_aw;my $sum_am;my $sum_park; my $sum_radd;my $sum_wst_ek=0; my $sum_wst_vk=0; my $sum_verleih;
+ my $nr=0;my $nx=0;
+ my $check_kaution=0;
+ my $rabatt_key; my $kost_key;
+
+ #BIG LOOP loop content table
+ foreach my $id (sort {
+ if($users_dms->{sort_updown} eq "down"){
+ if ($scol =~ /barcode|int/) {
+ $ct4rel->{$b}->{$scol} <=> $ct4rel->{$a}->{$scol}
+ }else{
+ lc($ct4rel->{$b}->{$scol}) cmp lc($ct4rel->{$a}->{$scol})
+ }
+ }else{
+ if ($scol =~ /barcode|int/) {
+ $ct4rel->{$a}->{$scol} <=> $ct4rel->{$b}->{$scol}
+ }else{
+ lc($ct4rel->{$a}->{$scol}) cmp lc($ct4rel->{$b}->{$scol})
+ }
+ }
+ } keys(%$ct4rel)){
+
+ my ($set_style,$set_style4nr,$sum_error);
+ my $ecol=0;
+
+ if($ct4rel->{$id}->{int01} > 0 && $ct4rel->{$id}->{int03} > 0){
+ $sum_wst_ek += $ct4rel->{$id}->{int01} * $ct4rel->{$id}->{int03};
+ }
+ if($ct4rel->{$id}->{int02} > 0 && $ct4rel->{$id}->{int03} > 0){
+ $sum_wst_vk += $ct4rel->{$id}->{int02} * $ct4rel->{$id}->{int03};
+ }
+
+ #AWs Faktor from Firma
+ if($table eq "content" && $ctf->{int02} != 0 && $ct4rel->{$id}->{int09} != 0){
+ $ct4rel->{$id}->{int02} = $ctf->{int02} * $ct4rel->{$id}->{int09};
+ $ct4rel->{$id}->{int02} = $lb->cashme($ct4rel->{$id}->{int02});
+ }
+
+ # check sum_pos and sum_buchen
+ my $sum_pos=0;
+ #if($v_journal && $ct4rel->{$id}->{state} ne "Kassenbestand"){
+ if($ct4rel->{$id}->{state} ne "Kassenbestand"){
+ foreach my $cpid (keys (%$ct4rel_parts)){
+ if(($ct4rel->{$id}->{c_id} eq $ct4rel_parts->{$cpid}->{ct_id}) && (looks_like_number($ct4rel_parts->{$cpid}->{int02}) && $ct4rel_parts->{$cpid}->{int02} != 0) && (looks_like_number($ct4rel_parts->{$cpid}->{int03}) && $ct4rel_parts->{$cpid}->{int03} != 0)){
+ if($ct4rel_parts->{$cpid}->{int07} != 0){
+ my $rabatt_eur = $ct4rel_parts->{$cpid}->{int07};
+ $rabatt_eur = $ct4rel_parts->{$cpid}->{int02} * $ct4rel_parts->{$cpid}->{int03} * $ct4rel_parts->{$cpid}->{int07}/100 if($ct4rel_parts->{$cpid}->{int08} != 1);#wenn int08 != 1 alias €
+ #$rabatt_eur = $lb->round($rabatt_eur);
+ $sum_pos += $ct4rel_parts->{$cpid}->{int02} * $ct4rel_parts->{$cpid}->{int03} - $rabatt_eur;
+ }else{
+ $sum_pos += $ct4rel_parts->{$cpid}->{int02} * $ct4rel_parts->{$cpid}->{int03};
+ }
+ }
+ }
+ my $sum_chk = $ct4rel->{$id}->{int01};
+ $sum_pos = $lb->round($sum_pos);
+ $sum_pos = $lb->cashme($sum_pos);
+ my $sum_chkdiff = $sum_chk - $sum_pos;#wegen $rabatt_eur kleine Rundungsfehler zulassen.
+ if($ct4rel->{$id}->{int01} && ($sum_pos ne $sum_chk) && ($sum_chkdiff > 0.02 || $sum_chkdiff < -0.02)){
+ $sum_error = "1";
+ }
+ $sum_error = "0" if($R::s_kontext && $R::s_kontext eq "Waren" || $R::node2edit || $R::ct_trans);
+ }
+
+
+ my $u_name = $ct4rel->{$id}->{owner};
+ foreach my $ctu_id (keys (%$ct_users)){
+ if($channel_map->{$u_name}){
+ $u_name = $channel_map->{$u_name};
+ }elsif($ct4rel->{$id}->{owner} eq $ct_users->{$ctu_id}->{c_id}){
+ $u_name = $ct_users->{$ctu_id}->{txt01};
+ }
+ }
+
+ #print $q->start_form(-name=>'listeform');
+
+ $sum_kasse = $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} eq "Kassenbestand");
+ $sum_start = $ct4rel->{$id}->{int02} if($ct4rel->{$id}->{state} eq "Kassenbestand");
+
+ if(eval($sum_pos . $max_op . $max_sum_pos) || $table ne "contenttrans"){
+ if(1==1){
+ $nr++;
+ $nx=$nr;
+ $close_time = $ct4rel->{$id}->{close_time} if($ct4rel->{$id}->{close_time});
+ $close_time = $lb->time4de($close_time,"1") if($close_time);
+ $payment_time = "";
+ if($ct4rel->{$id}->{payment_time}){
+ $payment_time = $ct4rel->{$id}->{payment_time};
+ $payment_time = $lb->time4de($payment_time,"1");
+ }
+ $sum_bar += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /^Bar/);
+ $sum_ec += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /EC/);
+ #$sum_kredit += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /Kredit/);
+ $sum_abb += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /Abbuchung/);
+ $sum_ueb += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /Überweisung/);
+ $sum_SEPApayone += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /SEPA.*payone|Zahlungseingang.*payone/);
+ $sum_CCpayone += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /Kreditkarte.*payone/);
+ $sum_ausfall += $ct4rel->{$id}->{int01} if($ct4rel->{$id}->{state} && $ct4rel->{$id}->{state} =~ /Zahlungsausfall/);
+ $c_id4csv .= "$ct4rel->{$id}->{c_id},";
+ $ct4rel->{$id}->{ct_name} = $q->unescapeHTML($ct4rel->{$id}->{ct_name}) || "";
+ $ct4rel->{$id}->{c_id} = $q->unescapeHTML($ct4rel->{$id}->{c_id}) || "";
+ $set_style = "background-color:#fcfdfb;";
+ $set_style = "background-color:#f4f1ee;" if($nx %= 2);
+ #$set_style = "background-color:#e4f1ee;" if($ct4rel->{$id}->{ct_name} eq $ct4rel->{$id}->{barcode});
+ my $ccc_id = $R::c_id || $R::c_id4trans || $users_dms->{c_id4trans};
+ $set_style = "background-color:$node_meta->{bg_color};" if(($R::rel_id && $R::rel_id eq $ct4rel->{$id}->{rel_id}) && !$R::empty_rel_id);
+ $set_style = "background-color:$node_meta->{bg_color};" if(($ccc_id && $ccc_id eq $ct4rel->{$id}->{content_id}) && ("$table" =~ /contenttrans/));
+ $set_style = "background-color:$node_meta->{bg_color};" if(($ccc_id && $ccc_id eq $ct4rel->{$id}->{content_id}) && ("$table" =~ /contenttver/));
+
+ #red
+ $set_style = "background-color:#d39c9c;" if($sum_error && $sum_error == 1 && $node_meta->{node_name} eq "Faktura");
+ $set_style4nr = $set_style;
+ my $m_id;
+ my $nodeline2;
+ my $nodeline_name2;
+ my $nodelist;
+
+
+ #Instanz Buttons-Logic
+ print $q->Tr(),"\n";
+ #checkboxes
+ #permissions
+ if($users_dms->{int07} == 2){#only DMS-Account Admin
+ print $q->td({-style=>"background-color:silver;"}, $q->checkbox(-name=>"ck4ex", -checked=>'', -value=>"$ct4rel->{$id}->{c_id}", -label=>'')),"\n";
+ }else{
+ print $q->td({-style=>"background-color:silver;"}," "),"\n";
+ }
+ #1.Spalte
+ if("$ct4rel->{$id}->{main_id}" eq "$node_meta->{main_id}" || "$ct4rel->{$id}->{main_id}" eq "$node_meta->{parent_id}"){
+ if($table =~ /content$|contentadr|contentnel/){
+ $ecol++;
+ print "
\n";
+ #2021-06-08 disabled because dms must be browser-tab save
+ if(1==2 && $table eq "content" && ($ct4rel->{$id}->{template_id} =~ /205|224|229/)){#bikes|Gutschein|Zubehör
+ print $q->a({-class=>"editnav",-href=>"$tpath?ct_trans=add_transpos\&mandant_main_id=$dbt->{shareedms_conf}->{parent_id}\&kind_of_trans=$users_dms->{kind_of_trans}\&c_id=$ct4rel->{$id}->{content_id}\&owner=$users_dms->{u_id}",-title=>"zum $users_dms->{kind_of_trans} \#$ctrel->{ct_name} $ctrel->{txt01} hinzufügen"}, $q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-512-copy.png", -style=>'height:1.3em;'}));
+ }
+ if($table eq "content" && ($ct4rel->{$id}->{template_id} =~ /205|225/)){
+ my $rnid = $ct4rel->{$id}->{rel_id};
+ my $node_names = "failure $rnid | $relnod->{$rnid}->{content_id} == $ct4rel->{$id}->{c_id}";
+ if($relnod->{$rnid}->{content_id} && $relnod->{$rnid}->{content_id} == $ct4rel->{$id}->{c_id}){
+ $node_names = $relnod->{$rnid}->{node_name};
+ }else{
+ my $subnode = $dbt->get_subrelnode($dbh,$node_meta->{main_id});
+ $node_names = $subnode->{node_name};
+ }
+ my $search_key = "s_barcode=$ct4rel->{$id}->{barcode}";#bike
+ $search_key = "s_int04=$ct4rel->{$id}->{int04}" if($ct4rel->{$id}->{template_id} == 225);#station
+ print $q->a({-class=>"editnav",-href=>"$path/$node_names?detail_search=1\&$search_key",-title=>"zur Liste der Rad $ct4rel->{$id}->{barcode} Servicearbeiten"}, $q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-440-wrench.png", -style=>'height:1em;'}));
+ }
+ ##
+ print " \n";
+ }elsif($users_dms->{u_id} > 0 && "$table" =~ /contenttrans|contenttver/){
+ print "
\n";
+ print " \n";
+ }else{
+ $ecol++;
+ print $q->td({-style=>"$set_style"}),"\n";
+ }
+ }elsif($ct4rel->{$id}->{content_id} && !$v_journal){
+ #2017-11-10 simple multi node_name directory view
+ $ecol++;
+ my $rnid = $ct4rel->{$id}->{rel_id};
+ my $node_names = "failure $rnid | $relnod->{$rnid}->{content_id} == $ct4rel->{$id}->{c_id}";
+ if($relnod->{$rnid}->{content_id} && $relnod->{$rnid}->{content_id} == $ct4rel->{$id}->{c_id}){
+ $node_names = $relnod->{$rnid}->{node_name};
+ }else{
+ my $subnode = $dbt->get_subrelnode($dbh,$node_meta->{main_id});
+ $node_names = $subnode->{node_name};
+ }
+
+ #node_names fails TODO
+ if(1==1 && $table eq "content" && ($ct4rel->{$id}->{template_id} =~ /205|225/)){
+ my $search_key = "s_barcode=$ct4rel->{$id}->{barcode}";#bike
+ $search_key = "s_int04=$ct4rel->{$id}->{int04}" if($ct4rel->{$id}->{template_id} == 225);#station
+ print $q->td({-class=>'tdtxt',-colspan=>1,-style=>"$set_style", -nowrap=>1}, $q->a({-class=>"editnav",-href=>"$path/$node_names?detail_search=1\&$search_key",-title=>"zur Liste der Rad $ct4rel->{$id}->{barcode} Servicearbeiten $ct4rel->{$id}->{main_id}"},"$node_names")), "\n";
+ }else{
+ print $q->td({-class=>'tdtxt',-colspan=>1,-style=>"$set_style", -nowrap=>1},"$node_names"),"\n";
+ }
+
+ }elsif("$table" =~ /contenttrans/ && $v_journal){
+ $ecol++;
+ print "
\n";
+ print $q->a({-class=>"editnav",-href=>"?ct_trans=open\&mode=manager\&c_id4trans=$ct4rel->{$id}->{c_id}\&tpl_id4trans=$ct4rel->{$id}->{template_id}\&kind_of_trans=$node_meta->{node_name}\&owner=$users_dms->{u_id}\&offset=$offset\&limit=$limit",-title=>"öffnen"}, $q->img({-src=>"$varenv{metahost}/img/actions/project-open.png"}));
+ print " \n";
+ }else{
+ $ecol++;
+ print $q->td({-class=>'element',-colspan=>1,-style=>"$set_style"},""),"\n";
+ }
+ $ecol++;
+
+ #2.Spalte
+ my $ny="";
+ if($table eq "contentadr" && ($ct4rel->{$id}->{int12} || !$ct4rel->{$id}->{int04} || !$ct4rel->{$id}->{int13})){
+ print $q->td({-class=>'tdicon',-style=>"$set_style color:red;"},"•","\n") if($ecol <= "2");
+ }elsif($table eq "contenttrans" && (($ct4rel->{$id}->{txt28} && $ct4rel->{$id}->{txt28} =~ /error/i) || ($ct4rel->{$id}->{int14} && $ct4rel->{$id}->{int14} == 1))){
+ print $q->td({-class=>'tdicon',-style=>"$set_style color:red;"},"•","\n") if($ecol <= "2");
+ }elsif($table eq "content" && $ct4rel->{$id}->{template_id} == 227){
+ my $dir_thumb = "$varenv{data}/$node_meta->{main_id}-thumb/$ct4rel->{$id}->{c_id}";
+ my @pics = $lb->read_dirfiles($dir_thumb,"\.JPG|\.PNG","file","");
+ my $dir_main = "$varenv{data}/$node_meta->{main_id}/$ct4rel->{$id}->{c_id}";
+ my @docs = $lb->read_dirfiles($dir_main,"\.HTML","file","");
+
+ print "
\n";
+
+ if( -d "$dir_thumb" && scalar(@pics) > 0){
+ foreach(@pics){
+ print $q->span($q->img({-style=>'max-width:75px;',-src=>"$varenv{metahost}/data/$node_meta->{main_id}-thumb/$ct4rel->{$id}->{c_id}/$_"},"$_")),"\n";
+ print $q->br(),"\n" if(scalar(@pics) > 1);
+ }
+ }
+ print " \n";
+
+ }else{
+ $ny = $nr if($path =~ /letzte Suche/);
+ print $q->td({-class=>'tdint',-style=>"$set_style color:grey;"},"$ny"),"\n" if($ecol <= "2");
+ }
+ #print $q->td("$ecol\n") if($ecol <= "2");
+ #my $ctimg = "000empty";
+ #my $ct_name4img = "$ct4rel->{$id}->{ct_name}.jpg";
+ #$ct_name4img =~ s/\s//g;
+ #my $title = "Foto nicht vorhanden";
+ #if(-f "$varenv{img4thumb}/$ct_name4img"){
+ # $ctimg = "$ct_name4img";
+ # $title="$ct4rel->{$id}->{ct_name}";
+ #}
+ #print $q->td({-class=>'element',-style=>"$set_style"},$q->a({-href=>"/img4ct/$ctimg",-rel=>'lightbox',-title=>"$title"},$q->img({-src=>"/img4thumb/$ctimg", -style=>'max-width:20px;border:1px solid silver;'})));
+
+
+ #Tablecontent (parameter)
+ $k=0;
+ foreach (@tpl_order){
+ $k++;
+ my ($key,$val,$size,$colorize) = split /=/,$_;
+ $rabatt_key = 1 if($key =~ /int07/);
+ $kost_key = 1 if($key =~ /node05|node08/);
+ my $txtstyle = "text-align:left;";
+ my $isize = "26";
+ if($key =~ /barcode|c_id|ct_name|int|state|sort|public/){
+ $txtstyle = "text-align:right;max-width:8em;";
+ $isize = "5";
+ $isize = "5" if($key =~ /int/);
+ }
+ $isize = $size if($size =~ /\d/);
+ $ct4rel->{$id}->{$key} = $lb->time4de($ct4rel->{$id}->{$key},"1") if($key =~ /time/);
+ $ct4rel->{$id}->{$key} = $q->unescapeHTML($ct4rel->{$id}->{$key});# if($key !~ /byte/);
+ my $br4text = $R::node2edit || "";
+ $ct4rel->{$id}->{$key} = $lb->newline($ct4rel->{$id}->{$key},"","$br4text");
+ $set_style4nr = $set_style;
+ $set_style4nr="background-color:#e3dbc9;" if(($key eq "barcode") || ($key eq "int04"));
+ #$set_style4nr="background-color:#e3dbc9;" if($key eq "barcode");
+ $ct4rel->{$id}->{$key} =~ s/\./,/ if($key =~ /int/);
+
+ if($key eq "c_id" && $val eq "raw"){
+
+ my $pos_hash = $ct4rel->{$id};
+ my $pos_details = "";
+ foreach my $did (sort keys (%{$pos_hash})){
+ my $teaser = "";
+ if($pos_hash->{$did}){
+ $teaser = substr($pos_hash->{$did},0,30);
+ }
+ $pos_details .= $did . " = " . $teaser . "";
+ }
+
+ my $pos_id = $q->div({-class=>"popup",-onclick=>"toggle_box('$id')"},"$ct4rel->{$id}->{c_id}", $q->span({-class=>"popuptext",-id=>"$id"},"$pos_details"));
+ print $q->td({-class=>'tdtxt',-style=>"font-weight:normal;$set_style4nr"},"$pos_id"),"\n";
+ }
+ elsif($key =~ /ct_name|c_id/ && $ct4rel->{$id}->{$key}){
+ if($table =~ /contenttrans|contenttver/){
+ print $q->td({-class=>'tdint',-style=>"font-weight:normal;$set_style4nr"},$q->a({-class=>"linknav3",-href=>"?ct_trans=open\&mode=manager\&c_id4trans=$ct4rel->{$id}->{c_id}\&tpl_id4trans=$ct4rel->{$id}->{template_id}\&kind_of_trans=$node_meta->{node_name}\&owner=$users_dms->{u_id}\&offset=$offset\&limit=$limit",-title=>"Terminal öffnen"},"$ct4rel->{$id}->{$key}"));
+ }elsif($table =~ /content$|contentadr|contentnel/){
+ if($varenv{wwwhost} =~ /regiox/ && $key =~ /ct_name/){
+ print $q->td({-class=>"tdtxt",-style=>"font-weight:normal;$set_style4nr"},"$ct4rel->{$id}->{$key}");
+ }else{
+ print $q->td({-class=>"tdint",-style=>"font-weight:normal;$set_style4nr"},$q->a({-class=>"linknav3",-href=>"?node2edit=editpart\&mode=manager\&rel_id=$ct4rel->{$id}->{rel_id}\&offset=$offset\&limit=$limit",-title=>"Terminal öffnen"},"$ct4rel->{$id}->{$key}")),"\n";
+ }
+ }elsif(($node_meta->{tpl_order} !~ /barcode/) || ("$ct4rel->{$id}->{$key}" ne "$ct4rel->{$id}->{barcode}")){
+ print $q->td({-class=>'tdint',-style=>"font-weight:bold;$set_style4nr"},"$ct4rel->{$id}->{$key}"),"\n";
+ }else{
+ print $q->td({-class=>'tdint',-style=>"font-weight:bold;$set_style4nr"},""),"\n";
+ }
+ }elsif($key =~ /txt01/ && $table =~ /contenttrans|contenttver/){
+ print $q->td({-class=>'tdtxt',-style=>"font-weight:normal;$set_style4nr"},$q->a({-class=>"linknav3",-href=>"?ct_trans=open\&mode=manager\&c_id4trans=$ct4rel->{$id}->{c_id}\&tpl_id4trans=$ct4rel->{$id}->{template_id}\&kind_of_trans=$node_meta->{node_name}\&owner=$users_dms->{u_id}\&offset=$offset\&limit=$limit",-title=>"Terminal öffnen"},"$ct4rel->{$id}->{$key}")),"\n";
+
+ }elsif($key =~ /txt01/ && $table =~ /content$|contentadr/){
+ my $txt01 = "---";
+ $txt01 = "$ct4rel->{$id}->{$key}" if($ct4rel->{$id}->{$key});
+ print $q->td({-class=>'tdtxt',-style=>"font-weight:normal;$set_style4nr"},$q->a({-class=>"linknav3",-href=>"?node2edit=editpart\&mode=manager\&rel_id=$ct4rel->{$id}->{rel_id}\&offset=$offset\&limit=$limit",-title=>"Terminal öffnen"},"$txt01")),"\n";
+ }elsif($key =~ /barcode/ && $table =~ /content$|contentadr/ && $ct4rel->{$id}->{template_id} != 225){
+ print $q->td({-class=>'tdint',-style=>"font-weight:normal;$set_style4nr"},$q->a({-class=>"linknav3",-href=>"?node2edit=editpart\&mode=manager\&rel_id=$ct4rel->{$id}->{rel_id}\&offset=$offset\&limit=$limit",-title=>"Terminal öffnen"},"$ct4rel->{$id}->{$key}")),"\n";
+ }elsif($key =~ /int04/ && $table eq "content" && $ct4rel->{$id}->{template_id} == 225){
+ print $q->td({-class=>'tdint',-style=>"font-weight:normal;$set_style4nr"},$q->a({-class=>"linknav3",-href=>"?node2edit=editpart\&mode=manager\&rel_id=$ct4rel->{$id}->{rel_id}\&offset=$offset\&limit=$limit",-title=>"Terminal öffnen"},"$ct4rel->{$id}->{$key}")),"\n";
+ }elsif($key =~ /int04/ && $table eq "content" && $ct4rel->{$id}->{template_id} == 205){
+ print $q->td({-class=>'tdint',-style=>"font-weight:normal;"},$q->a({-class=>"linknav3",-style=>"",-href=>"?detail_search=1&s_int04=$ct4rel->{$id}->{$key}",-title=>"Rad Warenstamm nach Station filtern"},"$ct4rel->{$id}->{$key}"));
+ }elsif($key =~ /date_time/){
+ $ct4rel->{$id}->{start_time} = $lb->time4de($ct4rel->{$id}->{start_time},"1") if($ct4rel->{$id}->{start_time});
+ $ct4rel->{$id}->{end_time} = $lb->time4de($ct4rel->{$id}->{end_time},"1") if($ct4rel->{$id}->{end_time});
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style", -nowrap=>1},"$ct4rel->{$id}->{start_time} - $ct4rel->{$id}->{end_time}"),"\n";
+ }elsif($key =~ /int01/ && $node_meta->{node_name} eq "Faktura"){
+ if($ct4rel->{$id}->{state} eq "Kassenbestand"){
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},$q->b("Tatsächl. $ct4rel->{$id}->{$key}")),"\n";
+ }else{
+ my $betrag = $ct4rel->{$id}->{$key} || "∑ $sum_pos";# pre counting
+ $betrag = $ct4rel->{$id}->{$key} if($v_journal);
+ $betrag =~ s/\./,/;
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},"$betrag"),"\n";
+ }
+ }elsif($key =~ /int02/ && $ct4rel->{$id}->{state} eq "Kassenbestand"){
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},$q->b("Anfangst. $ct4rel->{$id}->{$key}")),"\n";
+ }elsif($key =~ /int03/ && "$table" eq "contenttrans"){
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},""),"\n";
+ }elsif($key =~ /mtime/ && $ct4rel->{$id}->{close_time}){
+ my $close = "
$close_time TaAb.";
+ my $payment = "";
+ $payment = "
$payment_time ZaEi." if($payment_time);
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},"$ct4rel->{$id}->{$key} $close $payment"),"\n";
+ }elsif($key =~ /owner/){
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},"$u_name"),"\n";
+ }elsif($key =~ /state/){
+ my $order_state = "";
+ $order_state = "$ct4rel->{$id}->{txt22}" if($ct4rel->{$id}->{txt22});
+ $order_state = "$ct4rel->{$id}->{txt22},
" if($ct4rel->{$id}->{txt22} && $ct4rel->{$id}->{$key});
+ my $capture_state = "
$ct4rel->{$id}->{$key} ";
+ $capture_state = "
$ct4rel->{$id}->{$key} " if($ct4rel->{$id}->{$key} =~ /payone/ && $ct4rel->{$id}->{int14} == 1);
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},"$order_state $capture_state"),"\n";
+ }elsif($ct4rel->{$id}->{template_id} =~ /205|225/ && $key eq "int10"){#bike_state
+ my $colorize = "";
+ $colorize = "color:#c63e3e;" if($ct4rel->{$id}->{$key} == 2 || $ct4rel->{$id}->{$key} == 3);
+ $colorize = "color:#bd2424;" if($ct4rel->{$id}->{$key} == 4 || $ct4rel->{$id}->{$key} == 5 || $ct4rel->{$id}->{$key} == 6);
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style $colorize"},"$dbt->{copri_conf}->{bike_state}->{$ct4rel->{$id}->{$key}}"),"\n";
+ }elsif($ct4rel->{$id}->{template_id} == 205 && $key eq "int20"){#lock_state
+ my $colorize = "";
+ $colorize = "color:#c63e3e;" if($ct4rel->{$id}->{$key} == 2 || $ct4rel->{$id}->{$key} == 3);
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style $colorize"},"$dbt->{copri_conf}->{lock_state}->{$ct4rel->{$id}->{$key}}"),"\n";
+ }elsif($ct4rel->{$id}->{template_id} == 205 && $key eq "int11"){#lock_system
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$dbt->{copri_conf}->{lock_system}->{$ct4rel->{$id}->{$key}}"),"\n";
+ }elsif($ct4rel->{$id}->{template_id} == 210 && $key eq "int18"){#sharing_type
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$dbt->{copri_conf}->{sharing_type}->{$ct4rel->{$id}->{$key}}"),"\n";
+ }elsif($ct4rel->{$id}->{template_id} =~ /225|210/ && $key =~ /txt24|int12/){
+ my $flotten = "";
+ foreach my $rid (sort { $bike_nodes->{$a}->{node_name} cmp $bike_nodes->{$b}->{node_name} } keys (%$bike_nodes)){
+ $flotten .= "$bike_nodes->{$rid}->{node_name} - $bike_nodes->{$rid}->{main_id}
" if($ct4rel->{$id}->{$key} =~ /$bike_nodes->{$rid}->{main_id}/);
+ }
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$flotten"),"\n";
+ }elsif($ct4rel->{$id}->{template_id} == 228 && $key =~ /int21|int22/){
+ my $bonustarif = "";
+ foreach my $rid (sort { $tariff_all->{$a}->{barcode} <=> $tariff_all->{$b}->{barcode} } keys (%$tariff_all)){
+ $bonustarif .= "$tariff_all->{$rid}->{barcode} - $tariff_all->{$rid}->{txt01}
" if($ct4rel->{$id}->{$key} == $tariff_all->{$rid}->{barcode});
+ }
+
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$bonustarif"),"\n";
+
+ }elsif($key =~ /int|save|time|sort|public/){
+ if($key eq "int06" && $ct4rel->{$id}->{int06}){
+ $ct4rel->{$id}->{int06} =~ s/,.*//;
+ }
+
+ #if($colorize && $ct4rel->{$id}->{$key} == 1){
+ # print $q->td({-class=>'tdicon',-style=>"$txtstyle $set_style color:$colorize;"},"•"),"\n";
+ #}else{
+ print $q->td({-class=>'tdint',-style=>"$txtstyle $set_style"},"$ct4rel->{$id}->{$key}"),"\n";
+ #}
+ }elsif($key =~ /txt01/ && $v_journal){
+ my $txt01 = "$ct4rel->{$id}->{$key}";
+ $txt01 = "
$txt01 " if($ct4rel->{$id}->{state} eq "Kassenbestand");
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$txt01"),"\n";
+ }elsif($key =~ /txt03/ && $ct4rel->{$id}->{template_id} eq "227"){
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},$q->a({-style=>"color:black;",-href=>"$varenv{metahost}/site/$ct4rel->{$id}->{$key}", -target=>'_blank',-title=>'download',-type=>'application/octet-stream'}, $q->img({-src=>"$varenv{metahost}/glyphicons/file-any.png", -style=>'height:1.3em;'}),"$ct4rel->{$id}->{$key}")),"\n";
+ }elsif($key =~ /txt00/ && $v_journal){
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$ct4rel->{$id}->{$key}"),"\n";
+ }elsif($key =~ /txt08/ && $table eq "contentadr"){
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$ct4rel->{$id}->{$key}"),"\n";
+ #color code
+ }elsif($ct4rel->{$id}->{template_id} == 205 && $key eq "txt23"){
+ my @service_code = split(/\s/,$ct4rel->{$id}->{$key});
+ my $color_code = "";
+ foreach(@service_code){
+ $color_code .= "
";
+ }
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$color_code"),"\n";
+ #teaser shorts longtext
+ }elsif(($table eq "contentadr" && $key =~ /txt29/) || ($table eq "content" && $key =~ /txt04/) || ($table eq "contenttrans" && $key =~ /txt23/)){
+ my $teaser = "";
+ if($ct4rel->{$id}->{$key}){
+ $teaser = substr($ct4rel->{$id}->{$key},0,50) . " ...";
+ }
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style; min-width:200px;"},"$teaser"),"\n";
+
+ #default to anything else
+ }elsif($key =~ /ct_name|node|txt|uri/){
+ $txtstyle = "text-align:left;";
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$ct4rel->{$id}->{$key}"),"\n";
+ }elsif($key =~ /byte/){
+ #$ct4rel->{$id}->{$key} =~ s/\\x//;
+ my $K_int = $ct4rel->{$id}->{$key};
+ #$K_int =~ s/(.)/sprintf( "%x", ord($1))/eg;
+ my $K_int = unpack "H*", $ct4rel->{$id}->{$key};
+ $txtstyle = "text-align:left;";
+ print $q->td({-class=>'tdtxt',-style=>"$txtstyle $set_style"},"$K_int"),"\n";
+ }
+ }
+ }
+
+ #sub-table-row for rent Calendar
+ my $cal_count = 0;
+ foreach my $ctid (sort { $cttpos->{$b}->{end_time} cmp $cttpos->{$a}->{end_time} } keys (%$cttpos)){
+ if($ct4rel->{$id}->{c_id} == $cttpos->{$ctid}->{cc_id}){
+ $cal_count++;
+ if($cal_count <= 1){
+ my $scale_color = "#86cbd7;";
+ my $calement = "calement_86cbd7";
+ if($ct4rel->{$id}->{int13} == $cttpos->{$ctid}->{int13} && $cttpos->{$ctid}->{int10} == 7){
+ $scale_color = "#f0536e;";
+ $calement = "calement_f0536e";
+ }
+
+ my ($year_st,$mon_st,$day_st,$hh_st,$mm_st) = $lb->split_date($cttpos->{$ctid}->{start_time}) if($cttpos->{$ctid}->{start_time});
+ my ($year_en,$mon_en,$day_en,$hh_en,$mm_en) = $lb->split_date($cttpos->{$ctid}->{end_time}) if($cttpos->{$ctid}->{end_time});
+
+ if($year_st && $mon_st && $day_st && $hh_st && $mm_st && $year_en && $mon_en && $day_en && $hh_en && $mm_en){
+ #generate px for rent scale
+
+ my $start_nr = $year_st . $mon_st . $day_st . $hh_st . $mm_st;
+ my $end_nr = $year_en . $mon_en . $day_en . $hh_en . $mm_en;
+ my $day_stpx = 0;
+ my $rent_day_px = 0;
+ my $time_style;
+ if($start_nr <= $end_nr){
+ ($day_stpx,$rent_day_px) = $lb->rent_scale($users_dms,$year_st,$mon_st,$day_st,$hh_st,$mm_st,$year_en,$mon_en,$day_en,$hh_en,$mm_en);
+ }else{
+ $time_style="color:red;";
+ }
+ print $q->Tr();
+ print $q->td({-style=>'background-color:silver;'},""),"\n";
+ print $q->td({-class=>"$calement",-colspan=>2,-style=>"$set_style;"},""),"\n";
+ print "
\n";
+ #print $q->div({-style=>"position:absolute;margin-left:$daymarker;border-right: solid thin #86cb00;height:1.7em;"}," "),"\n";# if("$mon" eq "$mon_today");
+ my $calpath = "Mietjournal";
+ $calpath = "Alarmjournal" if($ct4rel->{$id}->{int13} == $cttpos->{$ctid}->{int13} && $cttpos->{$ctid}->{int10} == 7);
+ print $q->div({-style=>"position:static;margin-left:$day_stpx;width:$rent_day_px;background-color:$scale_color"},$q->a({-class=>"linknav3",-style=>"$time_style",-href=>"$script/$users_dms->{fullurl}/$calpath/?cttpos_id=$cttpos->{$ctid}->{c_id}",-title=>"Im $calpath öffnen"},"$hh_en:$mm_en")),"\n";
+ print " \n";
+ print $q->Tr();
+ print $q->td({-style=>'padding-top:1px;'},""),"\n";
+ }
+ }
+ }
+ }
+
+ #sub-table-row, Journal mit Teileansicht
+ if($v_journal){
+ my $o = "9";
+ $o = 8 if($varenv{wwwhost} =~ /cofi/);#because of extra col ID
+ $o++ if($rabatt_key); #Verkaufjournal mit Rabatt
+ $o++ if($kost_key); #Verkaufjournal mit Kostenstelle
+ my $m = $k - $o;
+ foreach my $cpid (sort { $ct4rel_parts->{$a}->{c_id} <=> $ct4rel_parts->{$b}->{c_id} } keys(%$ct4rel_parts)){
+ if($ct4rel->{$id}->{c_id} eq $ct4rel_parts->{$cpid}->{ct_id}){
+ my $pos_style="color:grey;$set_style";
+ my $sum_parts = $ct4rel_parts->{$cpid}->{int02} * $ct4rel_parts->{$cpid}->{int03};
+ if($ct4rel_parts->{$cpid}->{int07} != 0){
+ #my $rabatt_eur = $ct4rel_parts->{$cpid}->{int02} * $ct4rel_parts->{$cpid}->{int03} * $ct4rel_parts->{$cpid}->{int07}/100;
+ my $rabatt_eur = $ct4rel_parts->{$cpid}->{int07};
+ $rabatt_eur = $ct4rel_parts->{$cpid}->{int02} * $ct4rel_parts->{$cpid}->{int03} * $ct4rel_parts->{$cpid}->{int07}/100 if($ct4rel_parts->{$cpid}->{int08} != 1);#wenn int08 != 1 alias €
+ $sum_parts = $ct4rel_parts->{$cpid}->{int02} * $ct4rel_parts->{$cpid}->{int03} - $rabatt_eur;
+ }
+ $sum_parts = $lb->round($sum_parts);
+ $sum_parts = $lb->cashme($sum_parts);
+ $sum_waren += $sum_parts;
+ $sum_verkauf += $sum_parts if($ct4rel_parts->{$cpid}->{ct_name} ne "999");#999=Ausgaben, Fixme
+ $ctf->{txt31} =~ s/,/|/;
+ if($ct4rel->{$id}->{state} =~ /^Bar/ && $ct4rel_parts->{$cpid}->{int12} =~ /$ctf->{txt31}/){
+ $sum_kaution += $sum_parts;
+ $sum_bar -= $sum_parts;
+ }
+
+ #Umsatz Fkt.
+ #AW Material Summen
+ $ct_aw_ids =~ s/\|$//;
+ #if($umsatz eq "AW" && $ct4rel_parts->{$cpid}->{ct_name} eq $ctf->{txt51}){
+ if($umsatz eq "AW" && $ct4rel_parts->{$cpid}->{cc_id} =~ /$ct_aw/){
+ $sum_aw += $sum_parts;
+ $sum_verkauf -= $sum_parts;
+ #$pos_style .= "background-color:#a69100;";
+ }elsif($ct4rel_parts->{$cpid}->{ct_id} =~ /$ct_aw_ids/){
+ $sum_am += $sum_parts;
+ $sum_verkauf -= $sum_parts;
+ #$pos_style .= "background-color:#c69133;";
+ }
+
+ if($umsatz eq "Rad-Station_Verkauf"){
+ foreach my $nid (keys (%$w_nodes)){
+ if($ct4rel_parts->{$cpid}->{int12} eq $w_nodes->{$nid}->{main_id}){
+ if($w_nodes->{$nid}->{txt01} eq "Raddienst"){
+ $sum_radd += $sum_parts;
+ $sum_verkauf -= $sum_parts;
+ #$pos_style .= "background-color:#a69100;";
+ }elsif($w_nodes->{$nid}->{txt01} eq "Parkhaus"){
+ $sum_park += $sum_parts;
+ $sum_verkauf -= $sum_parts;
+ #$pos_style .= "background-color:#a69100;";
+ }
+ }
+ }
+ }
+ if($umsatz eq "Rad-Station_Verleih"){
+ #besser, anhand der Verleih-Kostenstelle
+ foreach my $nid (keys (%$verleih_nodes)){
+ if($ct4rel_parts->{$cpid}->{int12} eq $verleih_nodes->{$nid}->{main_id}){
+ $sum_verleih += $sum_parts;
+ #$pos_style .= "background-color:#a69100;";
+ }
+ }
+ }
+
+ my $parts_time = "";
+ if($ct4rel_parts->{$cpid}->{start_time} && $ct4rel_parts->{$cpid}->{end_time}){
+ $ct4rel_parts->{$cpid}->{start_time} = $lb->time4de($ct4rel_parts->{$cpid}->{start_time},"1");
+ $ct4rel_parts->{$cpid}->{end_time} = $lb->time4de($ct4rel_parts->{$cpid}->{end_time},"1");
+ $parts_time = "$ct4rel_parts->{$cpid}->{start_time} - $ct4rel_parts->{$cpid}->{end_time}";
+ }
+ print $q->Tr(),"\n";
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ #print $q->td({-colspan=>'2',-style=>"$pos_style"},"$ct4rel->{$id}->{c_id} | $ct4rel_parts->{$cpid}->{ct_id}\n");
+ print $q->td({-colspan=>'3',-style=>"$pos_style"},""),"\n";
+ print $q->td({-class=>'tdtxt',-style=>"$pos_style"},"$ct4rel_parts->{$cpid}->{txt00}"),"\n";
+ print $q->td({-colspan=>'1',-style=>"$pos_style"},""),"\n";
+ print $q->td({-class=>'tdtxt',-style=>"$pos_style"},"$ct4rel_parts->{$cpid}->{txt01}"),"\n";
+ print $q->td({-class=>'tdint',-style=>"$pos_style"},"$ct4rel_parts->{$cpid}->{ct_name}"),"\n";
+ print $q->td({-colspan=>"$m",-style=>"$pos_style"},""),"\n";
+ print $q->td({-class=>'tdint',-style=>"$pos_style"},"$ct4rel_parts->{$cpid}->{int03}"),"\n";
+ print $q->td({-class=>'tdint',-style=>"$pos_style"},"$ct4rel_parts->{$cpid}->{int02}"),"\n";
+ #Rabatt
+ if($rabatt_key && $ct4rel_parts->{$cpid}->{int07}){
+ $ct4rel_parts->{$cpid}->{int07} .= " €" if($ct4rel_parts->{$cpid}->{int08} == 1);#wenn int08 != 1 alias €;
+ $ct4rel_parts->{$cpid}->{int07} .= " %" if($ct4rel_parts->{$cpid}->{int08} != 1);#wenn int08 != 1 alias €;
+ print $q->td({-class=>'tdint',-style=>"$pos_style",-nowrap=>1},"$ct4rel_parts->{$cpid}->{int07}"),"\n";
+ }elsif($rabatt_key){
+ print $q->td({-class=>'tdint',-style=>"$pos_style",-nowrap=>1},""),"\n";
+ }
+ print $q->td({-class=>'tdint',-style=>"$pos_style"},"$sum_parts"),"\n";
+ print $q->td({-colspan=>'1',-style=>"$pos_style"},""),"\n";
+ }
+ }
+ }
+ }
+ }#journal offen ende
+
+
+ if($R::todo && $R::todo eq "Waren-Summe"){
+ my $m = 9;
+ $sum_wst_ek = $lb->round($sum_wst_ek);
+ $sum_wst_vk = $lb->round($sum_wst_vk);
+ $sum_wst_ek = $lb->cashme($sum_wst_ek,",");
+ $sum_wst_vk = $lb->cashme($sum_wst_vk,",");
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdtxt',-style=>'text-align:center;background-color:silver;',-colspan=>"$m"},"");
+ print $q->td({-class=>'tdsum',-colspan=>"2",-style=>'background-color:silver;'},"");
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ #print $q->td({-class=>'tdsum',-colspan=>"$m"},$q->span({-style=>'color:silver;font-weight:normal;'},"(Vorsicht! incl. Ausgaben)"),$q->span("Waren-Stamm Summe"));
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Waren-Stamm Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_wst_ek €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_wst_vk €");
+ }
+
+ #Kassenjournal alias Summe Bar und Kredit
+ if(($nr > 0) && ($v_journal || $R::v_abschluss) && (!$R::rel_id) && ("$R::s_kontext" ne "Waren")){
+ #if(($nr > 0) && ($v_journal || $R::v_abschluss || $close_time) && (!$R::rel_id)){
+#print "($nr > 0) && ($v_journal || $R::v_abschluss || $close_time) && (!$R::rel_id)";
+ $k="9" if(!$k);
+ my $m = $k;
+ $sum_bar = $lb->round($sum_bar);
+ $sum_bar = $lb->cashme($sum_bar);
+ $sum_ec = $lb->round($sum_ec);
+ $sum_ec = $lb->cashme($sum_ec);
+ #$sum_kredit = $lb->round($sum_kredit);
+ #$sum_kredit = $lb->cashme($sum_kredit);
+ $sum_abb = $lb->round($sum_abb);
+ $sum_abb = $lb->cashme($sum_abb);
+ $sum_ueb = $lb->round($sum_ueb);
+ $sum_ueb = $lb->cashme($sum_ueb);
+ $sum_geka = $lb->round($sum_geka);
+ $sum_geka = $lb->cashme($sum_geka);
+ $sum_paypal = $lb->round($sum_paypal);
+ $sum_paypal = $lb->cashme($sum_paypal);
+
+ $sum_SEPApayone = $lb->round($sum_SEPApayone);
+ $sum_SEPApayone = $lb->cashme($sum_SEPApayone);
+ $sum_CCpayone = $lb->round($sum_CCpayone);
+ $sum_CCpayone = $lb->cashme($sum_CCpayone);
+ $sum_ausfall = $lb->round($sum_ausfall);
+ $sum_ausfall = $lb->cashme($sum_ausfall);
+
+
+ $sum_waren = $lb->round($sum_waren);
+ $sum_waren = $lb->cashme($sum_waren);
+ $sum_kaution = $lb->cashme($sum_kaution);
+ $sum_start = $lb->cashme($sum_start);
+ $sum_kasse = $lb->cashme($sum_kasse);
+ $close_time = $R::s_mtime if($R::s_mtime);
+ my $summiert = "Gesamt Umsätze";
+ #my @_states = ("Bar","EC-Karte","Kreditkarte","Abbuchung","Überweisung");
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdtxt',-style=>'text-align:center;background-color:silver;',-colspan=>"$m"},"$summiert");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-style=>'background-color:silver;'},"");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-style=>'background-color:silver;'},"");
+
+
+ if(1==1){
+ if($sum_ec != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"EC-Karten Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_ec €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ #if($sum_kredit != "0"){
+ # print $q->Tr();
+ # print $q->td({-style=>"background-color:silver;"},""),"\n";
+ # print $q->td({-class=>'tdsum',-colspan=>"$m"},"Kreditkarten Summe");
+ # print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_kredit €");
+ #}
+ if($sum_abb != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Abbuchung Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_abb €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ if($sum_ueb != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Überweisung Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_ueb €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ if($sum_geka != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Geldkarte Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_geka €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ if($sum_paypal != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"PayPal Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_paypal €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ if($sum_SEPApayone != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"SEPA-Lastschrift (payone) Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_SEPApayone €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ if($sum_CCpayone != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Kreditkarte (payone) Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_CCpayone €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ if($sum_ausfall != "0"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Zahlungsausfall Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_ausfall €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m",-style=>'background-color:#eaeaec;'},"Bar Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1",-style=>'background-color:#eaeaec;'},"$sum_bar €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+
+ if($v_journal eq "Tagesbericht" || ($v_journal && $R::s_start_mtime !~ /\d+[\.|,]\d+[\.|,]\d+/)){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ $sum_start = "$ctf->{int01}" if($sum_start == "0");
+ my $sum_start_text = "(Kassenbestand Übernahme vom Vortag)" if(!$sum_start);
+ $sum_start = $last_ab->{int01} if(!$sum_start);
+ print $q->td({-class=>'tdsum',-colspan=>"$m",-style=>'background-color:#eaeaec;'},$q->span({-style=>'color:silver;font-weight:normal;'},"$sum_start_text"),"Anfangs Kassenbestand");
+ if($close_time){
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1",-style=>'background-color:#eaeaec;'},"$sum_start €");
+ }else{
+ print $q->td({-class=>'tdsum',-colspan=>"1",-style=>'background-color:#eaeaec;'}, $q->textfield(-class=>'etxt',-style=>'text-align:right;',-name=>"sum_start",-override=>'1',-default=>"$sum_start",-size=>"5",-maxlength=>10),"\n");
+ }
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m",-nowrap=>"1",-style=>'background-color:#eaeaec;'},"Tatsächlicher Kassenbestand");
+ $sum_kasse = "$varenv{sum_start}" if($sum_kasse == "0");
+ if($close_time){
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1",-style=>'background-color:#eaeaec;'},"$sum_kasse €");
+ }else{
+ print $q->td({-class=>'tdsum',-colspan=>"1",-style=>'background-color:#eaeaec;'},$q->textfield(-class=>'etxt',-style=>'text-align:right;',-name=>"sum_kasse",-override=>'1',-default=>"$sum_kasse",-size=>"5",-maxlength=>10),"\n");
+ }
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ my $sum_diff = $sum_kasse - $sum_start - $sum_bar;
+ $sum_diff = $lb->round($sum_diff);
+ $sum_diff = $lb->cashme($sum_diff);
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m",-style=>'background-color:#eaeaec;'},$q->span({-style=>'color:silver;font-weight:normal;'},"($sum_kasse - $sum_start - $sum_bar = $sum_diff)"),"Kassenbestand - Bar Summe = Differenz");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1",-style=>'background-color:#eaeaec;'},"$sum_diff €");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ ###
+
+ #AW 2020-01-29 disabled
+ if(1==2 && $umsatz && $node_meta->{node_name} eq "Faktura"){
+ my $sum_parts_all;
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdtxt',-style=>'text-align:center;background-color:silver;',-colspan=>"$m"},"Teil Umsätze");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-style=>'background-color:silver;'},"");
+
+ if("$R::s_kontext" eq "Waren"){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Suchkontext Waren. Die Umsatz Summe der durch Suchbegriffe gefundenen Artikel");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_waren €");
+ }
+
+ if($umsatz eq "Rad-Station_Verkauf"){
+ $sum_radd = $lb->cashme($sum_radd);
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Raddienst Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_radd €");
+ $sum_park = $lb->cashme($sum_park);
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Parkhaus Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_park €");
+ }
+
+ if($umsatz eq "Rad-Station_Verleih"){
+ $sum_verleih = $lb->cashme($sum_verleih);
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},$q->span({-style=>'color:silver;font-weight:normal;'},""),"Verleih Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_verleih €");
+ }
+
+ if($umsatz eq "AW"){
+ $sum_aw = $lb->round($sum_aw);
+ $sum_aw = $lb->cashme($sum_aw);
+ $sum_am = $lb->round($sum_am);
+ $sum_am = $lb->cashme($sum_am);
+ $sum_verkauf = $lb->round($sum_verkauf);
+ $sum_verkauf = $lb->cashme($sum_verkauf);
+ $sum_parts_all += $sum_aw;
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Arbeits-Werte Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_aw €");
+ $sum_parts_all += $sum_am;
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Arbeits-Material Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_am €");
+ $sum_parts_all += $sum_verkauf;
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Verkaufs-Material Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_verkauf €");
+ $sum_parts_all = $lb->cashme($sum_parts_all);
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"$m"},"Gesamt Summe");
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"$sum_parts_all €");
+ }
+ }
+
+ if($users_dms->{u_id}){
+ if($v_journal =~ /bericht/ && $j_exist->{main_id}){
+ print $q->Tr();
+ print $q->td({-style=>"background-color:silver;"},""),"\n";
+ print $q->td({-style=>"background-color:silver;",-class=>'tdsum',-colspan=>"$m"},"Tagesabschluss"),"\n";
+ print $q->td({-style=>"background-color:silver;",-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},$but->checkbox("1","close_trans","","Tagesbericht abschließen und in das Verkaufsjournal senden"),$but->singlesubmit("v_abschluss","Speichern")),"\n";
+ print $q->td({-class=>'tdsum',-colspan=>"1",-nowrap=>"1"},"");
+ }
+ }
+
+ }
+ }
+ print $q->end_table;
+
+ print $q->hidden(-name=>'tpl_id',-override=>'1', -value=>"$tpl_id");
+ print "
\n";
+ if($R::detail_search !~ /suchen/ && $rows > $limit && $nr > 0){
+ print $q->div({-style=>'float:left;padding:6px 0 0 20px;'},"Datensätze pro Seite:",$q->textfield(-style=>'height:16px;',-name=>"limit",-default=>"$limit",-size=>"3",-maxlength=>10)),"\n";
+ print $q->div({-style=>'float:left;padding:7px 0 0 10px;'},$but->singlesubmit3("detail_search","reload_search","$varenv{metahost}/img/refresh.png","height:15px;","Tabelle neu laden")),"\n";
+ }
+ print $q->end_form;
+
+ my $offset_nr = $offset + $nr;
+ my $counter = $node_meta->{int10} || $rows;
+ print $q->div({-style=>'float:left;padding:6px 0 0 10px;'},"Zeile: $offset - $offset_nr / $counter");
+
+ #backward | forward
+ print "
\n";
+ print $q->a({-class=>"linknav",-href=>"?go=backward_list;offset=$offset;limit=$limit",-title=>''},"< zurück ... ") if($offset >= $limit);
+ print $q->a({-class=>"linknav",-href=>"?go=forward_list;offset=$offset;limit=$limit",-title=>''}," ... vorwärts >") if($counter >= $limit-10); #if($rows > $limit && $nr > 0);
+ print "
\n";
+ print "
\n";
+ print $q->div({-style=>'padding:6px 0 6px 20px;text-decoration:underline;'}, "Symbol Legende"),"\n";
+ if($table eq "contentadr"){
+ print $q->div({-style=>'padding:0 20px;font-style:italic;'}, $q->span({-style=>'padding:0.1em 0.8em;',-style=>'color:red;'},"•"), "Der Verleih ist nicht freigeschaltet"),"\n";
+ }elsif($table eq "contenttrans"){
+ print $q->div({-style=>'padding:0 20px;font-style:italic;'}, $q->span({-style=>'padding:0.1em 0.8em;',-style=>'color:red;'},"•"), "payone error"),"\n";
+ }elsif($table eq "content"){
+ #print $q->div({-style=>'padding:0 20px;font-style:italic;'}, $q->span({-style=>'padding:0.1em 0.8em;'},$q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-512-copy.png", -style=>'height:1.3em;'})), "Artikel zur Rechnung hinzufügen ( Orange unterlegte Faktura Rechnung )"),"\n";
+ print $q->div({-style=>'padding:0 20px;font-style:italic;'}, $q->span({-style=>'padding:0.1em 0.8em;'},$q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-440-wrench.png", -style=>'height:1.3em;'})), "Service-Wartung"),"\n";
+ }
+ print $q->div({-style=>'padding:0.5em;'}, " "),"\n";
+
+ print "
";
+
+ if($varenv{wwwhost} !~ /regiox/ && $node_meta->{main_id} > 300000 && $rows =~ /\d/){
+ $db->updater("nodes","main_id",$node_meta->{main_id},"int10",$rows);
+ }
+
+ #letzte Suche
+ if(!$v_journal && $R::detail_search && ref($searchref) eq "HASH" && $nr =~ /\d/){
+ $db->updater("nodes","main_id","300023","int10",$nr);
+ }
+ #print Dumper($node_meta);
+ return $return;
+}
+1;
diff --git a/copri4/main/src/Tpl/MandantConf.pm b/copri4/main/src/Tpl/MandantConf.pm
new file mode 100644
index 0000000..4373ce6
--- /dev/null
+++ b/copri4/main/src/Tpl/MandantConf.pm
@@ -0,0 +1,139 @@
+package MandantConf;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#
+use strict;
+use warnings;
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift;
+ my $u_group = shift;
+ my $return = shift;
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+ my $but = new Buttons;
+ my %ib = $but->ibuttons();
+ my %varenv = $cf->envonline();
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ $path =~ s/\/user|\/manager|\/admin//;
+ my $lang = "de";
+ my $dbh = "";
+ my $rel = {};
+ my $ct = {};
+ if($node_meta->{ct_table} eq "contentuser"){
+ if(($node_meta->{node_name} eq "Firma") && ($users_dms->{u_id} eq $varenv{superu_id})){
+ $rel = $db->get_rel4tpl($node_meta->{main_id},$lang,"","201","","",">0");
+ $ct = $db->get_content1("contentuser",$rel->{content_id});
+ }elsif(($node_meta->{node_name} eq "System") && ($users_dms->{u_id} eq $varenv{superu_id})){
+ $rel = $db->get_rel4tpl($node_meta->{main_id},$lang,"","215","","",">0");
+ $ct = $db->get_content1("contentuser",$rel->{content_id});
+ }elsif($node_meta->{node_name} eq "Kontakt-Hotline" && $users_dms->{int08} >= 1){
+ $rel = $db->get_rel4tpl($node_meta->{main_id},$lang,"","197","","",">0");
+ $ct = $db->get_content1("contentuser",$rel->{content_id});
+ }else{
+ $return = "failure::Abbruch. Keine Zugriffsberechtigung";
+ }
+ }
+
+ my $tpl = $db->get_tpl($rel->{template_id});
+ my @tpl_order = split /,/,$tpl->{tpl_order};
+ my $u_name = $dbt->sys_username($dbh,$ct->{owner});
+ $ct->{mtime} = $lb->time4de($ct->{mtime},"1");
+
+ print "";
+ print $q->div({-class=>"copri_header",-style=>"background-color:#cccccc;"},"Pfad: $path");
+ print $q->div({-style=>'background-color:silver;height:10px;'},""),"\n";
+ print $q->start_form();
+
+ #Content
+ print $q->start_table({-border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'3', -cellspacing=>'0'});
+ print $q->Tr();
+ if($R::config2edit){
+ print "
";
+ print $q->hidden(-name=>'owner',-override=>'1', -value=>"$users_dms->{u_id}");
+ print $q->hidden(-name=>'c_id',-override=>'1', -value=>"$ct->{c_id}");
+ print $q->hidden(-name=>'rel_id',-override=>'1', -value=>"$rel->{rel_id}");
+ print $but->singlesubmit7("rel_edit","save_user","$ib{save}");
+ print " \n";
+ }else{
+ print "";
+ print $q->a({-class=>"editnav",-href=>"$script$path?config2edit=1",-title=>'bearbeiten'}, $q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-151-edit.png"}));
+ print " \n";
+ }
+ print $q->td({-style=>"background-color:white;padding-right:10px;border-bottom: 1px solid silver;text-align:right;font-size:12px;"}, "$u_name / $ct->{mtime}");
+
+ my $i=0;
+ foreach (@tpl_order){
+ $i++;
+ my ($key,$des,$size) = split /=/,$_;
+ $size = "60" if($key =~ /ct_name|txt/ && !$size);
+ $ct->{$key} = $q->unescapeHTML("$ct->{$key}");
+ $ct->{$key} = $lb->newline($ct->{$key});
+ my $value = "";
+ if($R::config2edit){
+ if($size eq "area"){
+ $value = "";
+ }elsif($size =~ /\w\+\w/){
+ my ($a,$b) = split /\+/,$size;
+ my $a_checked;
+ my $b_checked;
+ $a_checked = "checked" if($ct->{$key} eq "$a" || !$ct->{$key});
+ $b_checked = "checked" if($ct->{$key} eq "$b");
+ $value = "$a $b ";
+ }elsif($key =~ /txt|ct_name/){
+ $value = " ";
+ }elsif($key =~ /int/){
+ $value = " ";
+ }elsif($key =~ /img/){
+ $value = " ";
+ }
+ }else{
+ $value = "$ct->{$key}";
+ }
+ print $q->Tr();
+ if($key =~ /header/){
+ print $q->td({-class=>'tdval2',-colspan=>'2'},$q->b(" $des")),"\n";
+ }elsif($users_dms->{u_id} eq $varenv{superu_id}){
+ print $q->td({-class=>'tdescr2'},"$des ($key)"),"\n";
+ }else{
+ print $q->td({-class=>'tdescr2'},"$des"),"\n";
+ }
+ print $q->td({-class=>'tdval2'}, "$value"),"\n" if($key !~ /header/);
+ }
+ print $q->end_table;
+ print $q->end_form;
+ print "";
+
+ return $return;
+}
+1;
diff --git a/copri4/main/src/Tpl/SubListe.pm b/copri4/main/src/Tpl/SubListe.pm
new file mode 100644
index 0000000..504967f
--- /dev/null
+++ b/copri4/main/src/Tpl/SubListe.pm
@@ -0,0 +1,436 @@
+package SubListe;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#
+#uncomment for perl -cw src/Tpl/Liste3.pm
+#use lib qw(/var/www/copri4/shareedms-primary/src);
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI;
+use URI::Escape;
+use Encode;
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Mod::APIfunc;
+
+use Date::Calc qw(:all);
+use Storable;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift;
+ my $u_group = shift;
+ my $return = shift;
+
+ my $q = new CGI;
+ my @keywords = $q->param;
+ my $keycount = scalar(@keywords);
+ my $time = time;
+ my $now_db = strftime("%d.%m.%Y %H:%M:%S",localtime(time));
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+
+ my $but = new Buttons;
+ my %varenv = $cf->envonline();
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $lang = "de";
+ my $dbh = "";
+
+ my $parent_node4rel = $db->get_node4rel($node_meta->{parent_id},"","","null");
+ my %ib = $but->ibuttons();
+ my $tpl_order = $node_meta->{tpl_order};
+ if(1==2 && $node_meta->{tpl_id} >= 400 && $node_meta->{tpl_id} < 500){
+ $tpl_order =~ s/barcode=Rad/barcode=Rad,txt10=Station-log,txt09=Wartungsprotokoll=area/;
+ $tpl_order =~ s/int04=Station/int04=Station,txt09=Wartungsprotokoll=area/ if($node_meta->{tpl_id} == 403);
+ }
+ my @tpl_order = split /,/,$tpl_order;
+ my $message = "";
+ #$message = "Fehler: bitte Unter \"Servicetechnik\" die Datenklasse konfigurieren!" if(scalar(@tpl_order) < 1);
+ my $s_owner_id = "";
+ #my $s_u_name = "";
+
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+ my $depth = scalar(@viewsel);
+ my $view_base = $viewsel[1] || "nothing";#like Waren
+ my $node_mandant = $db->get_node("$view_base","$lang");
+
+ #TODO, build service path by pos.template_id or pos.barcode alis bike_id
+ #my $pref = { table => "content",
+ # table_pos => "contentpos",
+ #};
+ #my $template_group = $dbt->pos_template_group($dbh,$pref);
+ #my $subrelnode = $dbt->get_subrelnode($dbh,$crecord->{main_id},$template_id_pos);
+
+ my $searchref = {};
+ my $channel_map = $dbt->channel_map();
+
+ my $mapref = {};
+ my $ct_users = $dbt->users_map($dbh,$mapref);#get serviceAPP and DMS users from contentadr
+
+ my @_users = ("");
+ foreach my $id (sort { $channel_map->{$a} cmp $channel_map->{$b} } keys (%$channel_map)){
+ push (@_users, "$id:$channel_map->{$id}");
+ if($channel_map->{$id} eq $R::s_owner){
+ $searchref->{owner} = $id;
+ #$s_u_name = $channel_map->{$id};
+ }
+ }
+
+ foreach my $ctu_id (sort { $ct_users->{$a}->{txt01} cmp $ct_users->{$b}->{txt01} } keys (%$ct_users)){
+ push (@_users, "$ct_users->{$ctu_id}->{c_id}:$ct_users->{$ctu_id}->{txt01}");
+ if($ct_users->{$ctu_id}->{ct_name} && ($ct_users->{$ctu_id}->{txt01} =~ /$R::s_owner/i) || ($ct_users->{$ctu_id}->{c_id} eq $searchref->{owner})){
+ $searchref->{owner} = $ct_users->{$ctu_id}->{c_id};
+ #$s_u_name = $ct_users->{$ctu_id}->{txt01};
+ }
+ }
+
+ my $limit = $R::limit || $varenv{limit};
+ my $offset = $R::offset || "0";
+ if($node_meta->{int10} && $node_meta->{int10} < $varenv{limit}){
+ $offset = 0;
+ }
+ #backward | forward
+ if($R::go eq "backward_list"){
+ $offset -= $limit if($offset >= $limit);
+ }elsif($R::go eq "forward_list"){
+ $offset += $limit;
+ }
+
+ my $date; my $start_chck=0;my $end_chck=0;
+ my $last_year;
+ if($R::s_start_mtime){
+ ($date,$start_chck) = $lb->checkdate($R::s_start_mtime) if($R::s_start_mtime !~ "%");
+ $message .= ">>> Datum Eingabefehler: $date <<<" if($start_chck);
+ my ($c_dd,$c_mm,$c_yy) = split(/\./,$date);
+ $last_year = $c_yy if("$c_yy" eq "2011");
+ }
+ if($R::s_end_mtime){
+ ($date,$end_chck) = $lb->checkdate($R::s_end_mtime) if($R::s_end_mtime !~ "%");
+ $message .= ">>> Datum Eingabefehler: $date <<<" if($end_chck);
+ my ($c_dd,$c_mm,$c_yy) = split(/\./,$date);
+ }
+
+ #because of search we need parents
+ my $main_ids = $parent_node4rel->{main_id};
+ my $tpl_ids = $parent_node4rel->{template_id};
+
+ my $rows = 0;
+ my $scol = "mtime";
+ my $table = "content";
+ $searchref->{table_pos} = "contentpos";
+ if($node_meta->{tpl_id} > 600 && $node_meta->{tpl_id} < 700){
+ $table = "contentadr";
+ $searchref->{table_pos} = "contentadrpos";
+ $searchref->{template_id_pos} = "$node_meta->{tpl_id}";
+ }
+ if($node_meta->{tpl_id} == 198){
+ my $mandant_id = 100002;
+ $table = "contentadr";
+ $searchref->{table_pos} = "users";
+ #$searchref->{template_id_pos} = "$node_meta->{tpl_id}";
+ $main_ids = 200011;
+ $tpl_ids = 202;
+print<
+ .ui-autocomplete {
+ text-align:left;
+ background:#eeeeee;
+ border:1px solid silver;
+ }
+
+
+
+EOF
+;
+
+ }
+
+ #print Dumper($node_meta);
+ my $hashfile = "$varenv{logdir}/$users_dms->{u_id}-$searchref->{table_pos}-searchhash";
+ my $ct4rel = {};
+ if(!$start_chck && !$end_chck && $parent_node4rel ne "Servicetechnik" && $main_ids && $tpl_ids){
+ #$rows = $db->count_content($searchref->{table_pos},"$main_ids","$tpl_ids");
+
+ #collect search keys
+ foreach my $postkey (@keywords){
+ foreach(@tpl_order){
+ my ($key,$val,$size) = split /=/,$_;
+ if($postkey =~ /s_$key|s_start_$key|s_end_$key/){
+ my $val = $q->param($postkey);
+ $postkey =~ s/^s_//;
+ $searchref->{$postkey} = $val;
+ }
+ }
+ }
+
+ #trying to save hashref
+ if($R::detail_search && ref($searchref) eq "HASH"){
+ store $searchref, $hashfile;
+ }elsif($keycount > 0 && !$R::detail_search && -f $hashfile){
+ $searchref = {};
+ $searchref = retrieve($hashfile);
+ }
+ #print Dumper($searchref);
+ my $export = "";
+ my $todo = "";
+ my $ck4ex = "";
+ #only if permission read
+ if(($node_meta->{ct_table} eq "users" && $users_dms->{int07} >= 1) || ($node_meta->{ct_table} eq "contentadrpos" && $users_dms->{int02} >= 1) || ($node_meta->{ct_table} eq "contentpos" && $users_dms->{int01} >= 1)){
+ $ct4rel = $db->search_content3($searchref,$table,$node_mandant->{parent_id},"",$users_dms->{u_id},$lang,"$main_ids","$tpl_ids","","",$time,"",$scol,$users_dms->{sort_updown},$offset,$limit,$export,$todo,$ck4ex,"");
+ }else{
+ $return = "failure::Abbruch. Keine Zugriffsberechtigung";
+ }
+ }
+
+ print "\n";
+ if($varenv{syshost} ne "azn"){
+ my $header_style = "";
+ $header_style = "border:2px solid #9f1f0e;" if($message);
+ print $q->div({-class=>"copri_header",-style=>"background-color:$node_meta->{bg_color};"},"$path",$q->span({-style=>"$header_style"},"$message"));
+ }
+ print $q->div({-style=>'background-color:silver;height:10px;'},""),"\n";
+
+ print $q->start_form(-name=>'searchform'),"\n";
+ print $q->hidden(-name=>'offset', -value=>"$offset"),"\n";
+ print $q->hidden(-name=>'main_id', -value=>"$node_meta->{main_id}"),"\n";
+ print $q->hidden(-name=>'mode', -value=>"manager"),"\n";
+ print $q->hidden(-name=>'owner', -value=>"$users_dms->{u_id}"),"\n";
+ print $q->hidden(-name=>'template_id', -value=>"$node_meta->{template_id}"),"\n";
+
+ my $hstyle = "width:20px;background-color:$node_meta->{bg_color};border-right: solid thin gray;border-bottom: solid thin gray;";
+ print $q->start_table({ -style=>'clear:both;', -border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'0', -cellspacing=>'0'}),"\n";
+
+ #new_edit and search (disabled for DMS-Account)
+ if($node_meta->{tpl_id} != 198){
+ my $edit="rel_edit";
+ my $new_key="service_done";
+
+ my $search = "search";
+ print $q->Tr(),"\n";
+ print $q->td({-style=>"background-color:silver;$hstyle"},$but->singlesubmit1("detail_search","$search","","")),"\n";
+
+ #https://tinkwwp.copri4.de/APIjsonserver?request=service_done&bike=202&work_id=txt11&work_val=aaa&authcookie=1842_ad720ed63bd40039e4abe8a9ad7315e1_34567890
+ #disabled
+ if(1==2 && $node_meta->{tpl_id} >= 400 && $node_meta->{tpl_id} < 500){
+ print $q->td({-style=>"$hstyle"}, $but->singlesubmit2glyph("$edit","$new_key","$ib{$new_key}","background-color:$node_meta->{bg_color};")),"\n";
+ }else{
+ print $q->td({-style=>"$hstyle"}," "),"\n";
+ }
+
+ #1. Search-fields
+ my $s_val;
+ foreach(@tpl_order){
+ my ($key,$val,$size) = split /=/,$_;
+ $size = 15 if($size =~ /area/);
+ $size = 10 if($size =~ /time/);
+ $size = 2 if($size =~ /checkbox/);
+
+ $s_val = $searchref->{$key};
+ #print "$key=$searchref->{$key}|";
+ if($key =~ /node|txt|int|uri|ct_name|_id|barcode|sort|public/){
+ if($key =~ /barcode|int04/){
+ print $q->td({-class=>"search_line"},$q->textfield(-class=>'stxt',-name=>"s_$key",-size=>"4",-default=>"$s_val",-maxlength=>40, -autofocus=>1)),"\n";
+ }else{
+ print $q->td({-class=>"search_line"},$q->textfield(-class=>'stxt',-name=>"s_$key",-size=>"$size",-default=>"$s_val",-maxlength=>40)),"\n";
+ }
+ }elsif($key =~ /owner/){
+ print $q->td({-class=>'search_line'},$but->selector("s_$key","","$s_val",@_users)),"\n";
+ }
+ my $s_mtime; my $e_mtime;
+ if($key eq "mtime"){
+ $s_mtime = $searchref->{start_mtime};
+ $e_mtime = $searchref->{end_mtime};
+ }
+ if($key eq "date_time"){
+ $s_mtime = $searchref->{start_date_time};
+ $e_mtime = $searchref->{end_date_time};
+ }
+
+ print $q->td({-nowrap=>1,-class=>"search_line"},$q->textfield(-id=>'datepicker1',-class=>'etxt',-name=>"s_start_$key",-default=>"$s_mtime",-size=>"$size",-maxlength=>20),"-",$q->textfield(-id=>'datepicker2',-class=>'etxt',-name=>"s_end_$key",-default=>"$e_mtime",-size=>"$size", -maxlength=>20)),"\n" if($key =~ /time/);
+ }#end Search-fields
+ }
+
+ #2. Tableheader
+ print $q->Tr();
+ my $i=0;
+ if($node_meta->{tpl_id} == 198){
+ my $edit="base_edit";
+ my $new_key="new_dmsusers";
+
+ print "
\n";
+ print $but->singlesubmit2glyph("$edit","$new_key","$ib{$new_key}","background-color:$node_meta->{bg_color};"),"\n";
+ #print $q->hidden(-name=>'c_id4trans', -override=>'1', -value=>"$ctx->{c_id}"),"\n";
+ #from json_selectadr
+ print $q->hidden(-id=>'c_idadr', -name=>"c_idadr", -override=>'1'),"\n";
+ print $q->hidden(-id=>'vorname_name', -name=>"vorname_name", -override=>'1'),"\n";
+ print $q->textfield(-style=>'border:1px solid grey;height:25px;width:80%;',-id=>"json_selectadr",-name=>"json_selectadr", -placeholder=>'Neuer DMS-Account', -value=>""),"\n";
+
+ print " \n";
+ }else{
+ print $q->th({-style=>""}," "),"\n";
+ print $q->th({-style=>""}," "),"\n";
+ }
+ #my $sort_up = "up";
+ #my $sort_down = "down";
+ #$sort_up = "
$sort_up " if($users_dms->{sort_updown} eq "up");
+ #$sort_down = "
$sort_down " if($users_dms->{sort_updown} eq "down");
+ #print $q->th($q->a({-class=>"sortnav",-href=>"?sort_updown=up\&offset=$offset\&limit=$limit",-title=>'Aufsteigend sortieren'},"$sort_up"),"|",$q->a({-class=>"sortnav",-href=>"?sort_updown=down\&offset=$offset\&limit=$limit",-title=>'Absteigend sortieren'},"$sort_down")),"\n";
+
+ foreach (@tpl_order){
+ my ($key,$val,$size,$interval) = split /=/,$_;
+ my $divstyle = "";
+ if($size =~ /checkbox/){
+ $size = 2;
+ $divstyle = "width:20px;white-space:nowrap;overflow:hidden;";
+ }
+ my $sort_title="| $val";
+ $val = "
$val " if($key eq $users_dms->{col_sort});
+ $i++;
+ print $q->th({-style=>'padding:5px 0'},$q->div({-style=>"$divstyle"},$q->a({-class=>"sortnav",-href=>"?col_sort=$key\&offset=$offset\&limit=$limit",-title=>"$val"},"$val"))),"\n" if($key ne "u_id");
+ }#end Tableheader
+
+
+ #BIG LOOP loop content table
+ #if($users_dms->{sort_updown} eq "up"){
+ my $nr=0;
+ foreach my $id (sort {
+ if($users_dms->{sort_updown} eq "down"){
+ if ($scol =~ /barcode|int/) {
+ $ct4rel->{$b}->{$scol} <=> $ct4rel->{$a}->{$scol}
+ }else{
+ $ct4rel->{$b}->{$scol} cmp $ct4rel->{$a}->{$scol}
+ }
+ }else{
+ if ($scol =~ /barcode|int/) {
+ $ct4rel->{$a}->{$scol} <=> $ct4rel->{$b}->{$scol}
+ }else{
+ $ct4rel->{$a}->{$scol} cmp $ct4rel->{$b}->{$scol}
+ }
+ }
+ } keys(%$ct4rel)){
+
+ my $set_style = "";
+ $nr++;
+ #Tablecontent (parameter)
+ print $q->Tr(),"\n";
+
+ if($node_meta->{tpl_id} != 198){
+ print $q->td({-class=>'tdtxt',-style=>"$set_style"},""),"\n";
+ print $q->td({-class=>'tdint',-style=>"$set_style"},""),"\n";
+ }
+ my $k=0;
+ foreach (@tpl_order){
+ $k++;
+ my ($key,$val,$size) = split /=/,$_;
+ $size = 15 if($size =~ /area/);
+ $size = 2 if($size =~ /checkbox/);
+ my $tdclass = "tdtxt";
+ my $tdstyle = "text-align:left;";
+ if($size =~ /\w\+\w/){
+ $size = 5;
+ }elsif($key =~ /barcode|c_id|ct_name|int|state|sort|public/){
+ $tdclass = "tdint";
+ $tdstyle = "text-align:right;max-width:8em;$size px;";
+ }
+ $ct4rel->{$id}->{$key} = $lb->time4de($ct4rel->{$id}->{$key},"1") if($key =~ /time/);
+ $ct4rel->{$id}->{$key} = $q->unescapeHTML("$ct4rel->{$id}->{$key}");
+ $ct4rel->{$id}->{$key} = $lb->newline($ct4rel->{$id}->{$key},"","");
+ if($key eq "owner"){
+ my $u_name = $ct4rel->{$id}->{owner};
+ foreach my $ctu_id (keys (%$ct_users)){
+ if($channel_map->{$u_name}){
+ $u_name = $channel_map->{$u_name};
+ }elsif($ct4rel->{$id}->{owner} eq $ct_users->{$ctu_id}->{c_id}){
+ $u_name = $ct_users->{$ctu_id}->{txt01};
+ }
+ }
+
+ #$u_name = $ct_users->{$ct4rel->{$id}->{$key}}->{txt01} || $ct4rel->{$id}->{$key};
+ print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style"},"$u_name"),"\n";
+ }elsif($key eq "barcode" && $node_meta->{ct_table} eq "contentadrpos"){
+ print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style"},$q->a({-class=>"linknav3",-href=>"/$users_dms->{fullurl}/Waren/?detail_search=1\&s_barcode=$ct4rel->{$id}->{barcode}",-title=>"zum Rad "},"$ct4rel->{$id}->{barcode}")),"\n";
+ #print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style"},$q->a({-class=>"editnav",-href=>"/$users_dms->{fullurl}/Waren/?detail_search=1\&s_barcode=$ct4rel->{$id}->{barcode}",-title=>"zur Liste der Rad $ct4rel->{$id}->{barcode} Servicearbeiten"}, $q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-440-wrench.png", -style=>'height:1.3em;'}),"$ct4rel->{$id}->{barcode}")),"\n";
+
+ }elsif($key eq "u_id" && $node_meta->{ct_table} eq "users"){
+ my $adref = {
+ table => "contentadr",
+ fetch => "one",
+ template_id => "202",
+ c_id => "$ct4rel->{$id}->{$key}",
+ };
+ my $ctadr = $dbt->fetch_record($dbh,$adref);
+
+ print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style width:300px;"},$q->a({-class=>"linknav3",-href=>"?node2edit=editpart\&u_id=$ct4rel->{$id}->{u_id}",-title=>"edit"},"$ctadr->{txt01} - $ctadr->{txt08} ($ct4rel->{$id}->{$key})")),"\n";
+ }elsif($key eq "txt08" && $node_meta->{ct_table} eq "contentadrpos"){
+ my $subject = "sharee.bike feedback";
+ my $body = "Hallo $ct4rel->{$id}->{txt01},\%0A\%0Avielen Dank für Ihre Nachricht \"$ct4rel->{$id}->{txt02}\"";
+ print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style"},$q->a({-class=>"editnav",-href=>"mailto:$ct4rel->{$id}->{$key}?subject=$subject&body=$body"},$q->span({-class=>"bi bi-envelope"}," $ct4rel->{$id}->{$key}"))),"\n";
+ }elsif($key =~ /int0[1-8]/ && $node_meta->{ct_table} eq "users"){
+ print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style",-nowrap=>1},"$dbt->{copri_conf}->{permission}->{$ct4rel->{$id}->{$key}}"),"\n";
+ }elsif($key =~ /int09/ && $node_meta->{ct_table} eq "users"){
+ print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style",-nowrap=>1},"$dbt->{copri_conf}->{access}->{$ct4rel->{$id}->{$key}}"),"\n";
+ }else{
+ print $q->td({-class=>"$tdclass",-style=>"$tdstyle $set_style"},"$ct4rel->{$id}->{$key}"),"\n";
+ }
+ }
+ }
+
+ print $q->end_table;
+
+ my $offset_nr = $offset + $nr;
+ print $q->div({-style=>'float:left;padding:0.5em;'},"Zeile: $offset - $offset_nr");
+
+ #backward | forward
+ print "
\n";
+ print $q->a({-class=>"linknav",-href=>"?go=backward_list;offset=$offset;limit=$limit",-title=>''},"< zurück ... ") if($offset >= $limit);
+ print $q->a({-class=>"linknav",-href=>"?go=forward_list;offset=$offset;limit=$limit",-title=>''}," ... vorwärts >") if($nr >= $limit-10); #if($rows > $limit && $nr > 0);
+ print "
\n";
+
+ print $q->end_form,"\n";
+ print "
\n";
+ my $debug = "(ct_table: $node_meta->{ct_table} | main_id: $node_meta->{main_id} | template_id: $node_meta->{template_id})";
+ print $q->div({-style=>'position:fixed;bottom:1%;font-size:13px;'},"$debug"),"\n" if($users_dms->{u_id} eq $varenv{superu_id});
+
+ return $return;
+}
+
+1;
diff --git a/copri4/main/src/Tpl/TransPositionen.pm b/copri4/main/src/Tpl/TransPositionen.pm
new file mode 100644
index 0000000..e0d5cf9
--- /dev/null
+++ b/copri4/main/src/Tpl/TransPositionen.pm
@@ -0,0 +1,559 @@
+package TransPositionen;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use DateTime;
+use DateTime::Format::Pg;
+use Date::Calc::Object qw(:ALL);
+use Scalar::Util qw(looks_like_number);
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Mod::APIfunc;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $self=shift;
+ my ($node_meta,$users_dms,$set_main_id,$main_id,$rel_id,$c_id,$u_id,$lang,$return,$node_name) = @_;
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+ my $but = new Buttons;
+ my %varenv = $cf->envonline();
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $users = $db->select_users($u_id);
+ my %ib = $but->ibuttons();
+ my $today = strftime("%d.%m.%Y",localtime(time));
+ my $dbh = "";
+ my $channel_map = $dbt->channel_map();
+
+ my $mapref = {};
+ my $ct_users = $dbt->users_map($dbh,$mapref);#get serviceAPP and DMS users from contentadr
+
+ my $line_count2;
+ my $k=0;
+ my $spart_ct_name = $R::spart_ct_name || "";
+ my $c_idpos = $R::c_idpos || $R::pos_id || "";
+
+ my $ctf = $db->get_content1("contentuser",$dbt->{shareedms_conf}->{parent_id});
+ my $ctt = $db->get_content1("contenttrans",$c_id);
+
+ my $umst1619 = $lb->umst_breaking($ctt,"");
+
+ my $ctadr = $db->get_content1("contentadr",$ctt->{int10});
+ my $buchen_mtime = $lb->time4de($ctt->{mtime});
+ my $vibuchen_mtime = "";
+ $vibuchen_mtime = "Payone post " . $lb->time4de($ctt->{pay_time},1) . " . " if($ctt->{pay_time});
+
+ my $tpl = $db->get_tpl($ctf->{txt36});
+ my @tpl_order = split /,/,$tpl->{tpl_order};
+
+ my $txt20 = $R::txt20 || $ctt->{txt20} || "";#Leistungsdatum
+ my $int05 = $R::int05 || $ctt->{int05} || "";#manuell
+ my $max_timestamp = "210001012359";
+ if($ctf->{txt80} && $txt20 =~ /(\d{2})\.(\d{2})\.(\d{4})$/){
+ $max_timestamp = $3 . $2 . $1 . "2359";
+ }elsif($ctf->{txt80} =~ /(\d{2})\.(\d{2})\.(\d{4})$/){
+ $max_timestamp = $3 . $2 . $1 . "2359";
+ }
+ my $max_sum = $ctf->{int03} || "10000";
+ my $cttpos = { c_id => 0 };
+ my $rows = 0;
+ ($cttpos,$rows) = $db->collect_contentpos("contenttrans",$c_id) if($c_id);
+ my $tpath; #Terminal target-path
+ if($users->{transaction_uri} =~ /Verkauf|Verleih|Faktur/){
+ $tpath = "$users->{transaction_uri}";
+ }elsif("$users->{fullurl}"){
+ $tpath = "$script/$users->{fullurl}/$users->{kind_of_trans}";
+ }
+if($varenv{orga} eq "dms"){#obsolete after migrating lx-rad and mobile ...
+print<
+ .ui-autocomplete {
+ text-align:left;
+ font-size:14px;
+ background:#eeeeee;
+ border:1px solid silver;
+ }
+
+
+
+EOF
+;
+}
+#print $q->div({ -class=>"ui-widget"}, $q->label({ -for=>"birds"},"Birds: "),$q->input({ -id=>"birds"},"")),"\n";
+
+
+ print $q->start_table({-class=>'list', -border=>'0', -width=>'100%',-align=>'left', -cellpadding=>'3', -cellspacing=>'0'});
+
+
+ #my $action_sort = "itime";
+ #Parts Header
+ print $q->start_form(-name=>'spartform');
+ print $q->Tr(); $line_count2++;
+ print $q->th($but->singlesubmit("select_part","*"),"\n");
+ foreach (@tpl_order){
+ my ($key,$val) = split /=/,$_;
+ $k++ if($val);
+ if("$key" eq "ct_name"){
+ my $ctpos;
+ print $q->hidden(-name=>'c_id4trans', -override=>'1', -value=>"$c_id");
+ print $q->hidden(-id=>'c_id', -name=>"c_id", -override=>'1');
+ print $q->hidden(-id=>'spart_ct_name', -name=>"spart_ct_name", -override=>'1');
+ print $q->th($q->textfield(-class=>'etxt',-style=>'height:19px;width:140px;font-size:1.3em;text-align:right;',-id=>"json_select",-name=>"json_select",-value=>"", -override=>'1',-size=>"25",-maxlength=>50, -placeholder=>'Nummer'),"");
+ }
+ if($key =~ /int03/){
+ print $q->th("$val");
+ }elsif($key =~ /int|txt03/){
+ print $q->th("$val");
+ }elsif($key =~ /txt01/){
+
+ my $cal_button = "";
+ my $ter_button = "";
+ my $war_button = "";
+ print $q->th("Beschreibung"),"\n";
+
+ }elsif($key =~ /txt/){
+ print $q->th("$val");
+ }
+ }
+
+ $c_idpos = $1 if($return && $return =~ /pos_id=(\d+)/);
+ print $q->hidden(-name=>'trans2edit', -value=>"transpos", -override=>'1');
+ print $q->hidden(-name=>'offset', -override=>'1', -value=>"$R::offset") if($R::offset);
+ print $q->hidden(-name=>'limit', -override=>'1', -value=>"$R::limit") if($R::limit);
+ print $q->hidden(-name=>'relids', -override=>'1', -value=>"$R::relids") if($R::relids);
+ print $q->end_form,"\n";
+
+ print $q->start_form(-name=>'transposform'),"\n";
+
+ #Tablecontent (buttons and ct_name(primary key))
+ #my $scol = "c_id";#changed to itime because of Storno resorts
+ my $scol = "itime";
+ my $sum_parts0=0;
+ my $sum_parts7=0;
+ my $sum_parts19=0;
+ my $diff7 = 100 + 7;
+ my $diff19 = 100 + $umst1619;
+ my $sum_umst7=0;
+ my $sum_umst19=0;
+ my $i=0;
+ my $accounting_start;
+ my $accounting_end;
+
+ #foreach my $id (sort { $cttpos->{$b}->{$scol} <=> $cttpos->{$a}->{$scol} } keys(%$cttpos)){
+ foreach my $id (sort { $cttpos->{$b}->{$scol} cmp $cttpos->{$a}->{$scol} } keys(%$cttpos)){
+ my $set_style="";
+ my $gesamt="0";
+ my $occupied_style = "";
+ my $time_style = "";
+ #$occupied_style = "color:#ff1493" if($cttpos->{$id}->{txt10} =~ /occupied|requested|canceled/);
+ $occupied_style = "color:#ff1493" if($cttpos->{$id}->{int10} == 2 ||$cttpos->{$id}->{int10} == 3 || $cttpos->{$id}->{int10} == 6);
+
+ my $cttpos_timestamp = $1 . $2 . $3 . "0000" if($cttpos->{$id}->{itime} =~ /(\d+)\-(\d+)\-(\d+)/);
+ #max. Rechnungspositionen
+ if(($cttpos_timestamp <= $max_timestamp) && ($sum_parts19 <= $max_sum)){
+ $i++;
+ #print "$i (($id: $cttpos_timestamp <= $max_timestamp) && ($sum_parts19 <= $max_sum)) ";
+ if($i==1){
+ $accounting_end = "$3.$2.$1" if($cttpos->{$id}->{itime} =~ /(\d+)\-(\d+)\-(\d+)/);
+ }else{
+ $accounting_start = "$3.$2.$1" if($cttpos->{$id}->{itime} =~ /(\d+)\-(\d+)\-(\d+)/);
+ }
+ #print "$accounting_start - $accounting_end ";
+
+ my @line_txt01 = split(/\n/,$cttpos->{$id}->{txt01});
+ if($cttpos->{$id}->{int02} != 0){
+ $line_count2++;
+ #$line_count2 += scalar(@line_txt01);
+ }
+ my ($s_date,$s_dd,$s_mo,$s_yy,$s_hh,$s_mi,$e_date,$e_yy,$e_mo,$e_dd,$e_hh,$e_mi);
+ my $einzel = $cttpos->{$id}->{int02};
+ my $menge = $cttpos->{$id}->{int03} || 0;
+
+ #Make date and time
+ if($cttpos->{$id}->{start_time} && $cttpos->{$id}->{end_time}){
+ ($s_yy,$s_mo,$s_dd,$s_hh,$s_mi) = $lb->split_date($cttpos->{$id}->{start_time});
+ ($e_yy,$e_mo,$e_dd,$e_hh,$e_mi) = $lb->split_date($cttpos->{$id}->{end_time});
+ }
+
+
+ my $dt1 = DateTime->new(year => 2018, month => 3, day => 20);
+ my $dt0 = $dt1;
+ my $dt2 = $dt1;
+ $dt0 = DateTime::Format::Pg->parse_datetime($cttpos->{$id}->{start_time}) if($cttpos->{$id}->{start_time});
+ $dt2 = DateTime::Format::Pg->parse_datetime($cttpos->{$id}->{end_time}) if($cttpos->{$id}->{end_time});
+ #if($dt2 < $dt0){
+ #$time_style="color:red;";
+ #}
+
+ if(looks_like_number($einzel) && $einzel != 0 && looks_like_number($menge) && $menge != 0){
+ $gesamt = $einzel * $menge;
+
+ my $rabatt_val = $cttpos->{$id}->{int07} || "";
+ if($rabatt_val != 0){
+ my $rabatt_eur = $rabatt_val;
+ $rabatt_eur = $einzel * $menge * $rabatt_val/100 if($cttpos->{$id}->{int08} != 1);#wenn int08 != 1 alias €
+ $gesamt = $einzel * $menge - $rabatt_eur;
+ }
+ }
+
+ $gesamt = $lb->round($gesamt);
+ $gesamt = $lb->cashme($gesamt);
+ $ctf->{txt13} = $1 if($ctf->{txt13} =~ /(\d+)/);
+ if($node_name =~ /steuerfrei/){#dirty hack
+ $sum_parts0 += $gesamt;
+ }elsif("$cttpos->{$id}->{int05}" =~ /\d/){
+ $sum_parts0 += $gesamt if("$cttpos->{$id}->{int05}" == "0");
+ $sum_parts7 += $gesamt if("$cttpos->{$id}->{int05}" == "7");
+ #$sum_parts19 += $gesamt if("$cttpos->{$id}->{int05}" == "19");
+ $sum_parts19 += $gesamt if($cttpos->{$id}->{int05} >= 16);
+ }else{
+ #print "yyy $gesamt $ctf->{txt13} |";
+ $sum_parts0 += $gesamt if("$ctf->{txt13}" == "0");
+ $sum_parts7 += $gesamt if("$ctf->{txt13}" == "7");
+ $sum_parts19 += $gesamt if("$ctf->{txt13}" >= "16");
+ }
+
+ #1. Spalte
+ print $q->Tr(),"\n";
+ print "";
+ if(($c_idpos == $cttpos->{$id}->{c_id}) && ($R::trans2edit && $R::trans2edit =~ /transpos/)){
+ print $q->hidden(-name=>'c_idpos', -value=>"$cttpos->{$id}->{c_id}", -override=>'1');
+ print $q->hidden(-name=>'cc_id', -value=>"$cttpos->{$id}->{cc_id}", -override=>'1');
+ print $q->hidden(-name=>'c_id4trans', -override=>'1', -value=>"$c_id");
+ print $but->singlesubmit2("ct_trans","save_pos","$ib{save_pos}","","ebutton5"),
+ $but->singlesubmit2("ct_trans","delete_pos","$ib{delete_pos}"),"\n";
+ }elsif(!$ctt->{close_time}){
+ print $q->a({-class=>"editnav",-href=>"$tpath?trans2edit=transpos\&c_idpos=$cttpos->{$id}->{c_id}\&c_id4trans=$c_id\&owner=$users->{u_id}",-title=>"Datensatz bearbeiten"}, $q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-151-edit.png"})),"\n";
+ }
+ my $calpath = "Mietjournal";
+ print $q->a({-class=>"linknav3", -style=>"background-color:$varenv{calendar_active_color}",-href=>"$script/$users->{fullurl}/$calpath/?cttpos_id=$cttpos->{$id}->{c_id}",-title=>"Im $calpath öffnen"}," ID $cttpos->{$id}->{c_id}"),"\n";
+ print " \n";
+
+ #Tablecontent (parameter)
+ foreach (@tpl_order){
+ my ($key,$val,$inputsize) = split /=/,$_;
+ $cttpos->{$id}->{$key} = $q->unescapeHTML($cttpos->{$id}->{$key});
+ $cttpos->{$id}->{$key} = $lb->newline($cttpos->{$id}->{$key},"",$R::trans2edit) if($R::trans2edit);
+ my $ct_pos = "$cttpos->{$id}->{ct_name}";
+ my $txtstyle = "text-align:left;min-width:150px;";
+ my $isize = "30";
+ $isize = $inputsize if($inputsize);
+ if($key =~ /int|txt03/){ #für zahlen etwas kleiner
+ $txtstyle = "text-align:right;min-width:50px;";
+ $isize = "5";
+ }
+ if(($c_idpos == $cttpos->{$id}->{c_id}) && ($R::trans2edit && $R::trans2edit =~ /transpos/)){
+ if($key =~ /ct_name/){
+ print $q->td({-class=>'element',-style=>"$set_style text-align:right;"}, $q->textfield(-class=>'etxt',-style=>"text-align:right;min-width:120px;",-name=>"ct_name",-default=>"$ct_pos", -override=>'1',-size=>10,-readonly=>'1'),"\n");
+ }elsif($key =~ /int03/){
+ print $q->td({-colspan=>'1',-class=>'element',-style=>"$txtstyle $set_style"},$q->textfield(-class=>'etxt',-style=>"$txtstyle",-name=>"col_$key",-default=>"$menge", -override=>'1',-size=>"$isize",-maxlength=>10, -autofocus=>1),"\n");
+ }elsif($key =~ /int02/){
+ print $q->td({-class=>'element',-style=>"$txtstyle $set_style"},$q->textfield(-class=>'etxt',-style=>"$txtstyle",-name=>"col_$key",-default=>"$einzel", -override=>'1',-size=>"$isize",-maxlength=>100),"\n");
+ }elsif($key =~ /int07/){
+ print $q->td({-class=>'element',-style=>"$txtstyle $set_style",-nowrap=>'1'},$q->textfield(-class=>'etxt',-style=>"$txtstyle",-name=>"col_$key",-default=>"$cttpos->{$id}->{$key}", -override=>'1',-size=>"$isize",-maxlength=>100),$but->selector("int08","40px","$cttpos->{$id}->{int08}",("0.00:%","1.00:€"))),"\n";
+ }elsif($key =~ /int04/){
+ print $q->td({-class=>'element',-style=>'text-align:right;padding:0.1em 0.5em;',-nowrap=>"1"},"$gesamt €");
+ }elsif($key =~ /txt01/){
+ if($cttpos->{$id}->{int09} && $cttpos->{$id}->{$key} !~ /Manuell/){
+ $cttpos->{$id}->{$key} .= "\nManuell bearbeitet\n";
+ }
+ print "";
+ print $q->textarea(-class=>'autos',-style=>"border: 1px solid #ededed;background-color: #ededed;",-name=>"col_$key",-default=>"$cttpos->{$id}->{$key}", -override=>'1',-rows=>"1",-cols=>65)," \n";
+
+ if($cttpos->{$id}->{int09}){#2020-12-07 Verleihräder werden anhand der TarifNr als solches erkannt
+ print $q->span({-style=>"$txtstyle $set_style"},
+ "Tarif Nr.: ", $q->textfield(-class=>'etxt',-name=>"int09",-default=>"$cttpos->{$id}->{int09}",-size=>"5",-maxlength=>5),
+ "Tarif Text", $q->textfield(-class=>'etxt',-name=>"txt04",-default=>"$cttpos->{$id}->{txt04}",-size=>"30",-maxlength=>50))," \n";
+
+ print $q->span({-style=>"$txtstyle $set_style"},
+ "Endstation: ", $q->textfield(-class=>'etxt',-name=>"int04",-default=>"$cttpos->{$id}->{int04}",-size=>"5",-maxlength=>40),
+ "GPS: ", $q->textfield(-class=>'etxt',-name=>"txt06",-default=>"$cttpos->{$id}->{txt06}",-size=>"35",-maxlength=>40))," \n";
+
+ print $q->span({-style=>"$txtstyle $set_style"},"Mietzeit: ",
+ $q->textfield(-id=>'datepicker1',-class=>'etxt',-name=>"start_date",-default=>"$s_dd.$s_mo.$s_yy",-size=>"10",-maxlength=>10),
+ $q->textfield(-class=>'etxt',-name=>"s_hh",-default=>"$s_hh",-size=>"2",-maxlength=>2),":",
+ $q->textfield(-class=>'etxt',-name=>"s_mi",-default=>"$s_mi",-size=>"2",-maxlength=>2)," – ",
+ $q->textfield(-id=>'datepicker2',-class=>'etxt',-name=>"end_date",-default=>"$e_dd.$e_mo.$e_yy",-size=>"10",-maxlength=>10),
+ $q->textfield(-class=>'etxt',-name=>"e_hh",-default=>"$e_hh",-size=>"2",-maxlength=>2),":",
+ $q->textfield(-class=>'etxt',-name=>"e_mi",-default=>"$e_mi",-size=>"2",-maxlength=>2)),"\n";
+ }
+
+ print " \n";
+ }elsif($key =~ /txt/){
+ print $q->td({-class=>'element',-style=>"$txtstyle $set_style"},$q->textfield(-class=>'etxt',-style=>"$txtstyle",-name=>"col_$key",-default=>"$cttpos->{$id}->{$key}", -override=>'1',-size=>"$isize",-maxlength=>100),"\n");
+ #}elsif($key =~ /save/){
+ #print $q->td({-class=>'element',-style=>"$set_style"},$but->singlesubmit2("ct_trans","save_pos","$ib{save_pos}"));
+ }elsif($key =~ /int/){
+ print $q->td({-class=>'tdint',-nowrap=>"1"}," \n");
+ }
+ }else{
+ if($key =~ /ct_name/){
+ #print $q->td({-class=>'tdint',-style=>"min-width:60px;"},"$ct_pos");
+ my $stamm_style = "background-color:#98c13b;padding:2px;";
+ my $article = $cttpos->{$id}->{ct_name};
+ if($cttpos->{$id}->{int09}){
+ print $q->td({-class=>'tdint',-style=>"min-width:60px;padding-top:5px;"}, $q->a({-class=>"linknav3",-style=>"$stamm_style",-href=>"$script/$users->{fullurl}/Waren/?detail_search=1&s_barcode=$cttpos->{$id}->{barcode}",-title=>"Im Warenstamm"},"$article")),"\n";
+ }else{
+ print $q->td({-class=>'tdint'},"$article"),"\n";
+ }
+ }elsif($key =~ /int02/){
+ $einzel =~ s/\./,/;
+ print $q->td({-class=>'tdint'},"$einzel"),"\n";
+ }elsif($key =~ /int03/){
+ $menge =~ s/\./,/;
+ print $q->td({-colspan=>'1',-class=>'tdint'},"$menge"),"\n";
+ }elsif($key =~ /int04/){
+ $gesamt =~ s/\./,/;
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"$gesamt €"),"\n";
+ }elsif($key =~ /int02/){
+ print $q->td({-class=>'tdint'},"$einzel"),"\n";
+ }elsif($key =~ /int07/){
+ my $proz="";
+ $proz = "%" if($cttpos->{$id}->{$key} && $cttpos->{$id}->{$key} != 0);
+ $proz = "€" if($cttpos->{$id}->{$key} && $cttpos->{$id}->{$key} != 0 && $cttpos->{$id}->{int08} && $cttpos->{$id}->{int08} == 1);
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"$cttpos->{$id}->{$key} $proz"),"\n";
+ }elsif($key =~ /txt03/){
+ print $q->td({-class=>'tdint'},"$cttpos->{$id}->{$key}"),"\n";
+ }elsif($key =~ /txt01/){
+ $cttpos->{$id}->{$key} = $q->unescapeHTML("$cttpos->{$id}->{$key}");
+ $cttpos->{$id}->{$key} = $lb->newline($cttpos->{$id}->{$key},"","");
+ print "\n";
+ if($cttpos->{$id}->{barcode} && $cttpos->{$id}->{int09}){#bike with tariff-nr
+ my $u_name = $cttpos->{$id}->{owner};
+ my $u_name_end = $cttpos->{$id}->{owner_end};
+ foreach my $ctu_id (keys (%$ct_users)){
+ if($channel_map->{$u_name}){
+ $u_name = $channel_map->{$u_name};
+ }elsif($cttpos->{$id}->{owner} eq $ct_users->{$ctu_id}->{c_id}){
+ $u_name = $ct_users->{$ctu_id}->{txt01};
+ }
+ if($channel_map->{$u_name_end}){
+ $u_name_end = $channel_map->{$u_name_end};
+ }elsif($cttpos->{$id}->{owner_end} eq $ct_users->{$ctu_id}->{c_id}){
+ $u_name_end = $ct_users->{$ctu_id}->{txt01};
+ }
+ }
+ if($cttpos->{$id}->{itime} =~ /(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2})/){
+ print $q->span("$dbt->{copri_conf}->{bike_state}->{$cttpos->{$id}->{int10}} → $dbt->{copri_conf}->{lock_state}->{$cttpos->{$id}->{int20}} → $u_name / $u_name_end"),"\n";
+ print " \n";
+ }
+ }
+ if($cttpos->{$id}->{txt01} || $cttpos->{$id}->{int09}){
+ #$line_count2++;
+ $cttpos->{$id}->{txt01} =~ s/fixed/\fixed\<\/span\>/;
+ $cttpos->{$id}->{txt01} =~ s/defect/\defect\<\/span\>/;
+ my $bike="";
+ my $tariff = "";
+ $bike = "$cttpos->{$id}->{$key}" if($cttpos->{$id}->{$key});
+ $tariff = ", Tarif: $cttpos->{$id}->{int09} $cttpos->{$id}->{txt04}" if($cttpos->{$id}->{txt04});
+ print $q->span("$bike $tariff "),"\n";
+ }
+ if($cttpos->{$id}->{int06} || $cttpos->{$id}->{int04}){
+ print $q->span("Start/End Station: $cttpos->{$id}->{int06} / $cttpos->{$id}->{int04}, GPS: $cttpos->{$id}->{txt06}"),"\n";
+ }
+ if($cttpos->{$id}->{start_time}){
+ print " \n";
+ print $q->span({-style=>"$time_style"}, "Mietzeit: $s_dd.$s_mo.$s_yy $s_hh:$s_mi – $e_dd.$e_mo.$e_yy $e_hh:$e_mi"),"\n";
+ }
+ print " \n";
+ }elsif($key =~ /txt/){
+ print $q->td({-class=>'tdtxt'},"$cttpos->{$id}->{$key}");
+ }elsif($key =~ /int/){
+ print $q->td({-class=>'tdint',-nowrap=>"1"}," \n");
+ }
+ }
+ }
+ }
+ }#foreach end
+
+ if($sum_parts7 != "0"){
+ $sum_umst7 = $sum_parts7 / $diff7 * 7;
+ $sum_umst7 = $lb->round($sum_umst7);
+ }
+ if($sum_parts19 != "0"){
+ $sum_umst19 = $sum_parts19 / $diff19 * $umst1619;
+ $sum_umst19 = $lb->round($sum_umst19);
+ }
+ my $sum_netto7 = $sum_parts7 - $sum_umst7;
+ my $sum_netto19 = $sum_parts19 - $sum_umst19;
+ $sum_netto7 = $lb->cashme($sum_netto7);
+ $sum_netto19 = $lb->cashme($sum_netto19);
+ my $sum_nettoall = $sum_parts0 + $sum_netto7 + $sum_netto19;
+ $sum_nettoall = $lb->round($sum_nettoall);
+ $sum_nettoall = $lb->cashme($sum_nettoall,",");
+ my $sum_paid = $sum_parts0 + $sum_parts7 + $sum_parts19;
+ $sum_paid = $lb->round($sum_paid);
+ my $sum_preauth = $sum_paid || 0;
+ $sum_parts0 = $lb->cashme($sum_parts0,",");
+ $sum_parts7 = $lb->cashme($sum_parts7,",");
+ $sum_parts19 = $lb->cashme($sum_parts19,",");
+ $sum_umst7 = $lb->cashme($sum_umst7,",");
+ $sum_umst19 = $lb->round($sum_umst19);
+ $sum_umst19 = $lb->cashme($sum_umst19,",");
+ $sum_paid = $lb->cashme($sum_paid,",");
+
+ my $n="5";
+ my $m= 1 + $k - $n;
+ $m++ if($users->{kind_of_trans} =~ /Faktur|Verleih/);
+ print " \n";
+ print $q->start_table({-class=>'list',-style=>'border-top:1px;border-style:solid;border-color:black;', -border=>'0', -width=>'100%',-align=>'center', -cellpadding=>'3', -cellspacing=>'0'}),"\n";
+ print $q->Tr("\n");
+ print $q->td(" ");
+
+ #if($users->{kind_of_trans} ne "Einkauf" && $node_name !~ /steuerfrei/){
+ if($node_name !~ /steuerfrei/){
+ print $q->Tr("\n"); $line_count2++;
+ print $q->td({-class=>'tdint'},"Nettobetrag:");
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"$sum_nettoall €");
+
+ if($sum_parts0 != "0"){
+ print $q->Tr("\n");$line_count2++;
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"0% UmSt auf $sum_parts0 €:");
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"0,00 €");
+ }
+ if($sum_netto7 != "0"){
+ print $q->Tr("\n");$line_count2++;
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"7% UmSt auf $sum_netto7 €:");
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"$sum_umst7 €");
+ }
+ if($sum_netto19 != "0"){
+ print $q->Tr("\n");$line_count2++;
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"$umst1619% UmSt auf $sum_netto19 €:");
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"$sum_umst19 €");
+ }
+ }
+ my $summe = "Summe";
+ #$summe = "Nettosumme" if($users->{kind_of_trans} eq "Einkauf");
+ print $q->Tr("\n");$line_count2++;
+ print $q->td({-class=>'tdsum'},"$summe: ");
+ print $q->td({-class=>'tdint',-nowrap=>"1"},"$sum_paid € ");
+ print $q->hidden(-name=>'sum_paid', -override=>'1',-value=>"$sum_paid");
+
+ print $q->end_table;
+ print " ";
+ print " ";
+ print $q->end_table;
+
+ print $q->hidden(-name=>'owner', -override=>'1', -value=>"$users->{u_id}");
+ print $q->hidden(-name=>'offset', -override=>'1', -value=>"$R::offset") if($R::offset);
+ print $q->hidden(-name=>'c_id4trans', -override=>'1', -value=>"$c_id");
+ print $q->hidden(-name=>'offset', -override=>'1', -value=>"$R::offset") if($R::offset);
+ print $q->hidden(-name=>'limit', -override=>'1', -value=>"$R::limit") if($R::limit);
+ print $q->hidden(-name=>'relids', -override=>'1', -value=>"$R::relids") if($R::relids);
+
+ $set_main_id=$main_id if($main_id && $main_id > "300000");
+ print $q->hidden(-name=>'set_main_id', -value=>"$set_main_id", -override=>'1');
+
+
+ #if(!$ctt->{close_time} && $varenv{Zahlungsweise} && $users->{u_id} == $dbt->{copri_conf}->{superu_id}){
+ if($users_dms->{int03} == 2){
+ #only if user is also a primary DMS user with invoice rw
+ my $dbh_primary = $dbt->dbconnect_extern("sharee_primary");
+ my $users_dms_primary = { u_id => 0 };
+ $users_dms_primary = $dbt->select_users($dbh_primary,$users_dms->{u_id},"and int03=2");
+
+ if($users_dms_primary->{int03} == 2 && !$ctt->{close_time} && $varenv{Zahlungsweise}){
+ my @_paymentstate = split(/\|/,$varenv{Zahlungsweise});
+ push @_paymentstate, "";
+ my $kind_of_payment = "";
+ if($ctadr->{int03} == 1 && ($ctadr->{ct_name} =~ /PO-\d+/ || $ctadr->{ct_name} =~ /TM-\d+/)){
+ $kind_of_payment = "$_paymentstate[0]";
+ }else{
+ undef $_paymentstate[0];
+ }
+ if($ctadr->{int03} == 2 && length($ctadr->{ct_name}) >= 19){
+ $kind_of_payment = "$_paymentstate[1]";
+ }else{
+ undef $_paymentstate[1];
+ }
+ $kind_of_payment = "$ctt->{state}" if($ctt->{state});
+
+ print $q->hidden(-name=>'printer_id', -value=>"PDF - Normalpapier", -override=>'1');
+ my $send_invoice_checkbox = 1;
+ $send_invoice_checkbox = 0 if($ctt->{txt30});
+ print $q->div({-class=>'element',-style=>'float:right;'},
+ "buchen incl. drucken ",$but->checkbox("print_pdf","ct_trans","1","PDF drucken",""),
+ " eMail Versand ",$but->checkbox("1","send_invoice","$send_invoice_checkbox","eMail Rechnung",""),
+ $but->singlesubmit1("set_state","buchen"),
+ $but->selector("state","150px",$kind_of_payment,@_paymentstate),"\n") if($users->{kind_of_trans} =~ /Verkauf|Verleih|Faktur/);
+ }
+ }
+
+ my $praefix = "$ctt->{txt00}-$varenv{praefix}";
+ if($ctt->{state} && $ctt->{int01}){
+
+ $ctt->{int01} =~ s/\./,/;
+ my $style = "color:red;" if($ctt->{int01} ne $sum_paid);
+ my $opos = "";
+ $opos = "OPOS" if($ctt->{int14} eq "1");
+ print $q->div({-style=>"float:right;padding:0.71em;font-size:0.81em;$style"},"[$opos $vibuchen_mtime Gebucht $ctt->{int01} € \"$ctt->{state}\"]") if($ctt->{state});
+ }
+ print $q->end_form;
+ print $q->div({-style=>"clear:both;height:0.1px;"},""),"\n";
+ if($ctt->{txt30}){
+ print $q->div({-style=>"padding:0.5em;font-size:0.81em;width:98%;text-align:right;"}, "$ctt->{txt30}"),"\n";
+ }elsif( -f "$varenv{pdf}/$praefix-$ctt->{ct_name}.pdf" ){
+ print $q->start_form(),"\n";
+ print $q->hidden(-name=>'offset', -override=>'1', -value=>"$R::offset") if($R::offset);
+ print $q->hidden(-name=>'limit', -override=>'1', -value=>"$R::limit") if($R::limit);
+ print $q->hidden(-name=>'relids', -override=>'1', -value=>"$R::relids") if($R::relids);
+ print $q->div({-style=>"padding:0.5em;font-size:0.81em;width:98%;text-align:right;"}, "eMail wurde nicht versandt! Rechnung eMail ", $but->singlesubmit1("ct_trans","send_invoice_again","send_invoice_again")),"\n" if($users->{u_id} == $dbt->{copri_conf}->{superu_id});
+ print $q->end_form;
+ }
+
+ if( -f "$varenv{pdf}/$praefix-$ctt->{ct_name}.pdf" && $varenv{metahost}){
+ print $q->div({-style=>"padding:0.5em;font-size:0.81em;width:98%;text-align:right;"}, "Download: ", $q->a({-href=>"$varenv{metahost}/pdf/$praefix-$ctt->{ct_name}.pdf", -target=>'_blank'},"$praefix-$ctt->{ct_name}.pdf"));
+ }
+
+
+ if($ctt->{state} && $ctt->{state} =~ /payone/ && $ctt->{txt28} && $ctt->{txt28} =~ /error/i){
+ print $q->div({-style=>"clear:both;padding:0.5em;font-size:0.81em;width:98%;text-align:right;color:red;"}, "Payone error: $ctt->{txt28}"),"\n";
+ }elsif($ctt->{txt28} =~ /settleaccount=yes/i){
+ print $q->div({-style=>"clear:both;padding:0.5em;font-size:0.81em;width:98%;text-align:right;color:green;"}, "Payone SEPA-Lastschrifteinzug war erfolgreich"),"\n";
+ }
+
+ $db->updater("contenttrans","c_id","$c_id","txt20","$accounting_start - $accounting_end","","","","","no_time") if(!$int05 && $accounting_start && $accounting_end);
+ $db->updater("contenttrans","c_id","$c_id","int15","$sum_preauth","","","","","no_time") if($sum_preauth || $sum_preauth == 0);
+ return "$line_count2";
+}
+1;
diff --git a/copri4/main/src/scripts/Ilockauth.class b/copri4/main/src/scripts/Ilockauth.class
new file mode 100644
index 0000000..4a2ad72
Binary files /dev/null and b/copri4/main/src/scripts/Ilockauth.class differ
diff --git a/copri4/main/src/scripts/Ilockauth.java b/copri4/main/src/scripts/Ilockauth.java
new file mode 100644
index 0000000..0e05944
--- /dev/null
+++ b/copri4/main/src/scripts/Ilockauth.java
@@ -0,0 +1,47 @@
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.Arrays;
+
+
+
+public class Ilockauth {
+ public static void main( String args[] ) {
+ String db_id = args[0];
+ String bike_id = args[1];
+ Connection c = null;
+ Statement stmt = null;
+ try {
+ Class.forName("org.postgresql.Driver");
+ c = DriverManager
+ .getConnection("jdbc:postgresql://localhost:5432/" + db_id,
+ "postgres", "");
+ c.setAutoCommit(false);
+ //System.out.println("Opened database successfully");
+
+ stmt = c.createStatement();
+ ResultSet rs = stmt.executeQuery( "SELECT * FROM content where barcode=" + bike_id + ";" );
+ while ( rs.next() ) {
+
+ byte[] randomNum = new byte[16];
+
+ byte[] K_int = rs.getBytes("byte01");
+
+ //example by byte[]
+ //byte[] K_int = {(byte) 0xA7, (byte) 0x99, (byte) 0x91, 0x12, 0x49, (byte) 0xE0, (byte) 0xBA, (byte) 0xD5, (byte) 0xF2, 0x48, (byte) 0x8D, (byte) 0xC1, 0x7E, 0x28, 0x2D, (byte) 0xD0};
+
+ System.out.println( "K_int = " + Arrays.toString(K_int));
+ Ilockkeygen.generateKey(randomNum, K_int);
+
+ }
+ rs.close();
+ stmt.close();
+ c.close();
+ } catch ( Exception e ) {
+ System.err.println( e.getClass().getName()+": "+ e.getMessage() );
+ System.exit(0);
+ }
+ //System.out.println("Operation done successfully");
+ }
+}
diff --git a/copri4/main/src/scripts/Ilockit_CSV2DB.pl b/copri4/main/src/scripts/Ilockit_CSV2DB.pl
new file mode 100755
index 0000000..e89328b
--- /dev/null
+++ b/copri4/main/src/scripts/Ilockit_CSV2DB.pl
@@ -0,0 +1,143 @@
+#!/usr/bin/perl
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#For pdf pw files
+#"pdftotext -upw FksjxxxxxxfmC1h Teilrad_ISI_PLUS_BB01207.pdf"
+#:1,$ s/^\n//g
+#:1,$ s/\n/;/g
+#:1,$ s/;C2-/\rC2-/g
+#:1,$ s/;QR-/\rQR-/g
+#
+#
+#check if UTF-8
+#file Teilrad_ISI_PLUS_BB01207.txt
+#iconv -t utf-8 -f iso-8859-1 Ilockitkeys_110520.csv -o Ilockitkeys_110520_utf8.cs
+#
+#sudo su www-data -c "./src/scripts/Ilockit_CSV2DB.pl shareedms-fr01 Teilrad_ISI_GPS_BB01328.txt"
+#
+#do it twice to set hex-key and bike-nr!
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || exit 1;
+}
+
+use lib "/var/www/copri4/$syshost/src";
+
+my $csv_file = $ARGV[1] || "";
+
+use strict;
+use warnings;
+use POSIX;
+use DBI;
+use CGI ':standard';
+use Lib::Config;
+use Mod::DBtank;
+use Scalar::Util qw(looks_like_number);
+use Data::Dumper;
+
+my $q = new CGI;
+my $cf = new Config;
+my %varenv = $cf->envonline("$syshost");
+print "$varenv{wwwhost}\n";
+my $dbt = new DBtank;
+my $lang = "de";
+my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
+my $dbh = "";
+my $main_id = 300001;#TODO Mietrad Flotten ID
+my $template_id = 205;
+
+###
+#Start loop payone log and update userid ##################################
+####
+#reading CSV
+ my $dbh_csv = DBI->connect("DBI:CSV:");
+ $dbh_csv->{'csv_tables'}->{'ilockitcsv'} = {
+ 'eol' => "\n",
+ 'sep_char' => ";",
+ 'quote_char' => undef,
+ #'quote_char' => "\"",
+ 'escape_char' => undef,
+ 'file' => $csv_file,
+ 'col_names' => ["serialnr","ilockit_id","ilockit_key","c1","c2","c3","c4","c5","c6"]
+ };
+
+ my $sth = $dbh_csv->prepare("SELECT * FROM ilockitcsv where serialnr like 'C2-%'");
+ my $rc = $sth->execute();
+ my $csv = $sth->fetchall_hashref("serialnr");
+
+ my $i=0;
+ foreach my $id (sort { $csv->{$a}->{serialnr} cmp $csv->{$b}->{serialnr} } keys (%$csv)){
+ $i++;
+
+ if($csv->{$id}->{serialnr}){
+ $csv->{$id}->{ilockit_id} =~ s/\+/\-/;
+ $csv->{$id}->{c1} =~ s/Rot/red/;$csv->{$id}->{c1} =~ s/Blau/blue/;$csv->{$id}->{c1} =~ s/Gr.+n/green/;
+ $csv->{$id}->{c2} =~ s/Rot/red/;$csv->{$id}->{c2} =~ s/Blau/blue/;$csv->{$id}->{c2} =~ s/Gr.+n/green/;
+ $csv->{$id}->{c3} =~ s/Rot/red/;$csv->{$id}->{c3} =~ s/Blau/blue/;$csv->{$id}->{c3} =~ s/Gr.+n/green/;
+ $csv->{$id}->{c4} =~ s/Rot/red/;$csv->{$id}->{c4} =~ s/Blau/blue/;$csv->{$id}->{c4} =~ s/Gr.+n/green/;
+ $csv->{$id}->{c5} =~ s/Rot/red/;$csv->{$id}->{c5} =~ s/Blau/blue/;$csv->{$id}->{c5} =~ s/Gr.+n/green/;
+ $csv->{$id}->{c6} =~ s/Rot/red/;$csv->{$id}->{c6} =~ s/Blau/blue/;$csv->{$id}->{c6} =~ s/Gr.+n/green/;
+ print "$i) $csv->{$id}->{serialnr}|\n";
+
+ my $ct = &select_content($csv->{$id});
+
+ my $data = {
+ table => "content",
+ main_id => "$main_id",
+ template_id => "$template_id",
+ txt22 => "$csv->{$id}->{serialnr}",
+ txt18 => "$csv->{$id}->{ilockit_id}",
+ byte01 => "\\x$csv->{$id}->{ilockit_key}",
+ int04 => "0",#station Werkstatt
+ int10 => "5",#defect
+ int11 => "2",#Ilockit
+ int20 => "1",#locked
+ txt01 => "unverbaut", #Bezeichnung #TODO
+ txt04 => "aus Lieferung vom 29.11.2021", #Besonderheiten
+ txt15 => "", #Firmware
+ txt17 => "", #GUID from APP
+ txt23 => "$csv->{$id}->{c1} $csv->{$id}->{c2} $csv->{$id}->{c3} $csv->{$id}->{c4} $csv->{$id}->{c5} $csv->{$id}->{c6}",
+ mtime => "now()",
+ owner => "1842",
+ };
+
+ if(ref($ct) eq "HASH" && $ct->{c_id} && ref($data) eq "HASH" && $csv->{$id}->{serialnr}){
+ print "UPDATE $csv->{$id}->{serialnr} (c_id:$ct->{c_id})\n";
+ $data->{barcode} = $ct->{c_id} if(!$ct->{barcode});
+ $dbt->update_record($dbh,$data, { c_id => $ct->{c_id} });
+ print Dumper($data) . "\n";
+ }elsif(ref($data) eq "HASH" && $csv->{$id}->{serialnr}){
+ print "INSERT $csv->{$id}->{serialnr}\n";
+ $dbt->insert_contentoid($dbh,$data);
+ print Dumper($data) . "\n";
+ }else{
+ print "nothing todo\n";
+ }
+ }
+}
+
+#content check if still exists
+sub select_content{
+ my $ct_hash = shift;
+ my $fetch = {
+ table => "content",
+ main_id => "$main_id",
+ template_id => "$template_id",
+ fetch => "one",
+ };
+ if(ref($ct_hash) eq "HASH" && $ct_hash->{serialnr}){
+ $fetch = { %$fetch , txt22 => "=::$ct_hash->{serialnr}" };
+ #$fetch = { %$fetch , barcode => "<::100" };
+ #$fetch = { %$fetch , int10 => "!=::3" };
+ #$fetch = { %$fetch , int11 => "!=::2" };
+ }
+
+ my $ct = $dbt->fetch_record($dbh,$fetch);
+ return $ct;
+}
+
+
diff --git a/copri4/main/src/scripts/Ilockit_cloud.pl b/copri4/main/src/scripts/Ilockit_cloud.pl
new file mode 100755
index 0000000..d77bfa2
--- /dev/null
+++ b/copri4/main/src/scripts/Ilockit_cloud.pl
@@ -0,0 +1,377 @@
+#!/usr/bin/perl
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#get lock event for last 20 minutes
+#cronjob interval 15 minutes
+#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_events"
+#
+#Ilockit GPS cloud
+#
+#4. Get a list of positions
+#fetch_ >> https://tracking.ilockit.bike/api/positions?from=2021-05-31T07:44:10Z&to=2021-06-06T07:44:10Z&deviceId=4272
+
+#5. Get a list of Events
+#fetch_ >> https://tracking.ilockit.bike/api/reports/events?from=2021-05-31T07:44:10Z&to=2021-06-06T07:44:10Z&deviceId=4272
+
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || die;
+}
+
+use lib "/var/www/copri4/$syshost/src";
+use strict;
+use warnings;
+use POSIX;
+use CGI;
+use Lib::Config;
+use JSON;
+use LWP::UserAgent;
+use DateTime;
+use Time::Piece;
+
+my $cf = new Config;
+use Mod::DBtank;
+use Data::Dumper;
+
+my $q = new CGI;
+my $dbt = new DBtank;
+my %varenv = $cf->envonline($syshost);
+
+my $lang = "de";
+my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
+
+my $api_file = "/var/www/copri4/shareeconf/apikeys.cfg";
+my $aconf = Config::General->new($api_file);
+my %apikeyconf = $aconf->getall;
+#print "---> " . $apikeyconf{Ilockitcloud}->{username} . "\n";
+
+my $ua = LWP::UserAgent->new;
+$ua->agent("sharee APIclient");
+$ua->credentials( 'tracking.ilockit.bike:443', 'api', "$apikeyconf{Ilockitcloud}->{username}", "$apikeyconf{Ilockitcloud}->{passwd}");
+
+my $json = JSON->new->allow_nonref;
+my $response_in = {};
+my $dbh = "";
+my $owner = 183;
+
+my $todo = $ARGV[1];
+my $deviceId = $ARGV[2] || "";
+
+open(FILE,">>$varenv{logdir}/Ilockit_cloud.log");
+print FILE "\n\n*** $now_dt\n";
+
+#my $endpoint = "https://tracking.ilockit.bike/api/commands";
+#utc to localtime
+sub localizedtime {
+ my $date = shift;
+
+ $date =~ s/\..*$//;
+ my $time = Time::Piece->strptime($date, "%Y-%m-%dT%H:%M:%S");
+ print FILE "localizedtime GMT alias Zulu: " . $time->datetime . "\n";#GMT alias Zulu
+ $time = localtime($time->epoch);#epoch
+ print FILE "localizedtime localized date time: " . $time->datetime . "\n";#localized date time
+
+ return $time->datetime;
+}
+#print localizedtime("2021-06-11T11:58:09.000+0000") . " example\n";
+
+#localtime to utc
+#my $now = strftime "%Y-%m-%dT%H:%M:%S", localtime;
+#utctime($now);
+sub utctime {
+ my $date = shift;
+ my $latency = shift || 0;
+
+ $date =~ s/\..*$//;
+ $date =~ s/\+\d+$//;
+ print FILE "requested datetime: " . $date . "\n";
+
+ my $time = Time::Piece->strptime($date, "%Y-%m-%dT%H:%M:%S");
+ print FILE "localtime: " . $time->datetime . "\n";#localtime
+ my $utc_epoch = $time->epoch;
+ #$utc_epoch -= 2*60*60;# -2 std
+ #
+ #only -1 hour, because of deviceTime and serverTime differs
+ #'deviceTime' => '2021-10-14T08:19:35.000+0000',
+ #'serverTime' => '2021-10-14T07:19:37.000+0000',
+ $utc_epoch -= 1*60*60;# -1 std
+ $utc_epoch += $latency;
+ $time = gmtime($utc_epoch);#epoch
+ print FILE "utctime: " . $time->datetime . "\n";#utc zulu date time
+ #
+ return $time->datetime;
+}
+
+
+#get all device localy
+sub get_devicesONcontent_all {
+ my $deviceId = shift;
+ my $pref = {
+ table => "content",
+ fetch => "all",
+ keyfield => "int13",
+ template_id => "205",
+ int13 => ">::0",
+ };
+ my $record = $dbt->fetch_record($dbh,$pref);
+ return $record;
+}
+
+#get one device localy in contenttranspos to check if bike is locked
+sub get_devicesONcontenttranspos {
+ my $deviceId = shift;
+ my $pref = {
+ table => "contenttranspos",
+ fetch => "one",
+ int13 => "$deviceId",
+ #int20 => "1",#locked
+ };
+ my $record = $dbt->fetch_tablerecord($dbh,$pref);
+ return $record;
+}
+
+
+#get one device localy
+sub get_devicesONcontent {
+ my $deviceId = shift;
+ my $pref = {
+ table => "content",
+ fetch => "one",
+ template_id => "205",
+ int13 => "$deviceId",
+ };
+ my $record = $dbt->fetch_record($dbh,$pref);
+ return $record;
+}
+
+#get and check if theft exist in contenttranspos not older than 1 day
+sub get_devicesONcontenttheftpos {
+ my $key = shift;
+ my $id = shift;
+ my $pref = {
+ table => "contenttheftpos",
+ fetch => "one",
+ #mtime => ">::(now() - interval '1 day')",
+ $key => "$id",
+ };
+ my $record = $dbt->fetch_tablerecord($dbh,$pref);
+ return $record;
+}
+
+
+#per cronjob once a day to get and update content with cloud device id
+#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_devices"
+&get_devices if($todo eq "get_devices");
+sub get_devices {
+ my $endpoint = "https://tracking.ilockit.bike/api/devices";
+ my $rest = "";
+
+ my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
+ $response_in = decode_json($ret_json);
+
+ print FILE "ilockit get_devices response_in:" . Dumper($response_in);
+ #foreach my $result (@{ $response_in }) {
+ # if($result->{id}){
+ # print $result->{id} . "\n";
+ # print $result->{name} . "\n";
+ # }
+ #}
+
+ my $pref = {
+ table => "content",
+ fetch => "all",
+ keyfield => "barcode",
+ template_id => "205",
+ #int10 => "1",#1 = "available"
+ };
+ my $record = $dbt->fetch_record($dbh,$pref);
+ my $rows = 0;
+ if(1==1 && ref($response_in) eq "ARRAY"){
+ foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){
+ foreach my $resp (@{ $response_in }) {
+ #print "if($resp->{name} eq $record->{$id}->{txt18} && ($resp->{id} && $resp->{id} ne $record->{$id}->{int13}))\n";
+ if($resp->{name} eq $record->{$id}->{txt18} && ($resp->{id} && $resp->{id} ne $record->{$id}->{int13})){
+ my $update = {
+ table => "content",
+ mtime => "now()",
+ owner => "$owner",
+ int13 => "$resp->{id}",
+ };
+ $rows = $dbt->update_record($dbh,$update,$record->{$id});
+ print FILE "update_record content.int13=$resp->{id}" . $rows . "\n";
+ }
+ }
+ }
+ }
+
+}#end if($todo eq "get_devices"){
+
+
+#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_events 6572 20"
+&get_events if($todo eq "get_events");
+sub get_events {
+
+ #1. select all devices on content
+ my $record_cc = get_devicesONcontent_all();
+ my $today = DateTime->now( time_zone => "Europe/Berlin" );
+ $today .= "Z";
+ my $from_datetime = DateTime->now( time_zone => "Europe/Berlin" );
+ $from_datetime->subtract( days => 1 );
+ $from_datetime .= "Z";
+
+ my $endpoint = "https://tracking.ilockit.bike/api/reports/events";
+ #my $rest = "from=2021-05-31T07:44:10Z\&to=2021-06-06T07:44:10Z\&deviceId=4272";
+ #my $rest = "from=2021-06-11T07:44:10Z\&to=2021-06-11T12:44:10Z\&deviceId=$deviceId";
+ #
+ #2. loope cloud
+ foreach my $id (sort { $record_cc->{$a}->{barcode} <=> $record_cc->{$b}->{barcode} } keys (%$record_cc)){
+
+ my $rest = "from=$from_datetime\&to=$today\&deviceId=$record_cc->{$id}->{int13}";
+
+ my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
+ $response_in = decode_json($ret_json);
+ print FILE "ilockit get_events response_in:" . Dumper($response_in);
+
+
+ foreach my $resp (@{ $response_in }) {
+ #if($record_cc->{$id}->{int13} eq $resp->{deviceId} && $resp->{type} eq "deviceOnline"){
+ if($record_cc->{$id}->{int13} && $record_cc->{$id}->{int13} eq $resp->{deviceId} && ref($resp->{attributes}) eq "HASH" && $resp->{attributes}->{statusCode} && $resp->{attributes}->{statusCode} eq "alarm"){
+ my $theft_record = get_devicesONcontenttheftpos("int01",$resp->{id});
+ print FILE "id: $resp->{id}\n";
+ print FILE "deviceId: $resp->{deviceId}\n";
+ print FILE "type: $resp->{type}\n";
+ print FILE "statusCode: $resp->{attributes}->{statusCode}\n";
+ print FILE "serverTime: $resp->{serverTime}\n\n";
+ if(!$theft_record->{c_id}){
+ my $serverTime = localizedtime($resp->{serverTime});
+ my $insert = {
+ table => "contenttheftpos",
+ cc_id => "$record_cc->{$id}->{c_id}",
+ barcode => "$record_cc->{$id}->{barcode}",
+ int04 => "$record_cc->{$id}->{int04}",#end station
+ txt06 => "$record_cc->{$id}->{txt06}",#end gps
+ txt18 => "$record_cc->{$id}->{txt18}",
+ owner => $owner,
+ mtime => "now()",
+ int10 => "7",#theft alarm
+ int01 => "$resp->{id}",#keeps id for event_type
+ int13 => "$resp->{deviceId}",
+ start_time => "$serverTime",
+ end_time => "$serverTime",
+ };
+
+ my $c_id = $dbt->insert_contentoid($dbh,$insert);
+ print FILE "insert sub get_events:" . Dumper($insert);
+ }
+ }
+ }
+ }
+}#end if($todo eq "get_events"){
+
+
+#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_positions 6572"
+#2021-10-27, cron disabled, unspecific and not only alarm
+&get_positions if($todo eq "get_positions");
+sub get_positions {
+ #1. select all devices on content
+ my $record_cc = get_devicesONcontent_all();
+ my $today = DateTime->now( time_zone => "Europe/Berlin" );
+ $today .= "Z";
+ my $from_datetime = DateTime->now( time_zone => "Europe/Berlin" );
+ $from_datetime->subtract( days => 1 );
+ $from_datetime .= "Z";
+
+
+ my $endpoint = "https://tracking.ilockit.bike/api/positions";
+ #my $rest = "from=2021-06-11T07:44:10Z\&to=2021-06-11T12:44:10Z\&deviceId=$deviceId" if($deviceId);
+ #my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
+ #$response_in = decode_json($ret_json);
+ #print Dumper($response_in);
+
+ #2. loope cloud
+ foreach my $id (sort { $record_cc->{$a}->{barcode} <=> $record_cc->{$b}->{barcode} } keys (%$record_cc)){
+
+ my $ctpos = get_devicesONcontenttranspos("$record_cc->{$id}->{int13}");
+ if($ctpos->{int20} == 1){#if locked then get position in range of end_time to now
+ print FILE "record_pos.int13: $ctpos->{int13} --> lock_state:$ctpos->{int20}| end_time:$ctpos->{end_time}\n";
+
+ #get only positions until smartlock end_time is locked
+ if($ctpos->{int13} && $ctpos->{end_time} =~ /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/){
+ $ctpos->{end_time} =~ s/\..*$//;
+ my $end_time = $ctpos->{end_time};
+ $end_time =~ s/\s/T/;
+ $from_datetime = utctime($end_time,"0");
+ $from_datetime .= "Z";
+
+ #keep in mind, api-from maybe deviceTime (end_time-1) and position timestamp is serverTime+2
+ my $rest = "from=$from_datetime\&to=$today\&deviceId=$record_cc->{$id}->{int13}";
+ my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
+ $response_in = decode_json($ret_json);
+ print FILE "ilockit get_positions response_in:" . Dumper($response_in);
+
+ foreach my $resp (@{ $response_in }) {
+ if($record_cc->{$id}->{int13} eq $resp->{deviceId}){
+ my $theft_record = get_devicesONcontenttheftpos("int02",$resp->{id});
+ print FILE "id: $resp->{id}\n";
+ print FILE "deviceId: $resp->{deviceId}\n";
+ print FILE "serverTime: $resp->{serverTime}\n\n";
+ if(!$theft_record->{c_id}){
+ my $serverTime = localizedtime($resp->{serverTime});
+ my $insert = {
+ table => "contenttheftpos",
+ cc_id => "$record_cc->{$id}->{c_id}",
+ barcode => "$record_cc->{$id}->{barcode}",
+ txt06 => "$resp->{latitude}, $resp->{longitude}",
+ owner => $owner,
+ mtime => "now()",
+ int10 => "8",#gps position
+ int02 => "$resp->{id}",#keeps id for event_type
+ int07 => "$resp->{speed}",
+ int08 => "$resp->{attributes}->{distance}",
+ int09 => "$resp->{attributes}->{totalDistance}",
+ int13 => "$resp->{deviceId}",
+ start_time => "$serverTime",
+ end_time => "$serverTime",
+ };
+
+ my $c_id = $dbt->insert_contentoid($dbh,$insert);
+ print FILE "insert sub get_positions:" . Dumper($insert);
+ }
+ }
+ }
+ }
+ }
+ }
+
+}#end if($todo eq "get_positions"){
+
+
+#ilockit http request
+sub fetch_ilockit_cloud {
+ my $self = shift;
+ my $ilockitserver = shift || "";
+ my $rest = shift || "";
+ my $ilockit_request = "$ilockitserver?$rest";
+
+ print FILE "fetch_ >> " . $ilockit_request . "\n";
+
+ my $req = HTTP::Request->new(GET => "$ilockit_request");
+ #$req->content_type('application/x-www-form-urlencoded');
+ $req->content_type('application/json');
+ $req->content($rest);
+
+ my $res = $ua->request($req);
+ if ($res->is_success) {
+ #print $res->content;
+ return $res->content;
+ print $res->status_line, "\n";
+ }else {
+ print $res->status_line, "\n";
+ }
+}
+
+close(FILE);
+
diff --git a/copri4/main/src/scripts/Ilockit_trackingcloud.pl b/copri4/main/src/scripts/Ilockit_trackingcloud.pl
new file mode 100755
index 0000000..6978f27
--- /dev/null
+++ b/copri4/main/src/scripts/Ilockit_trackingcloud.pl
@@ -0,0 +1,214 @@
+#!/usr/bin/perl
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#get tracking by
+#Ilockit trips by Ilockit cloud
+#
+#sudo su www-data -c "./src/scripts/Ilockit_trackingcloud.pl shareedms-fr01 get_tripsum 155884"
+#
+#2021-07-20
+#GPS tracking
+#Unser System bieten für die Auswertung von Fahrtstrecken bereits Zusammenfassungen an. Hierfür können Sie einfach die folgenden Calls benutzen:
+#
+#GET /api/reports/summary?groupId=95& from=2021-07-17T18:30:00Z& to=2021-07-20T18:30:00Z - Gibt Ihnen eine Zusammenfassung aller Fahrstrecken für die Schlösser in der Gruppe zurück.
+#
+#GET /api/reports/trips?groupId=95& from=2020-07-17T18:30:00Z& to=2021-07-20T18:30:00Z - Gibt Ihnen einzelne Fahrtstrecken für die Schlösser in der Gruppe zurück.
+#
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || die;
+}
+
+use lib "/var/www/copri4/$syshost/src";
+use strict;
+use warnings;
+use POSIX;
+use CGI;
+use Lib::Config;
+use JSON;
+use LWP::UserAgent;
+use DateTime;
+use Time::Piece;
+use Mod::DBtank;
+use Data::Dumper;
+
+my $q = new CGI;
+my $dbt = new DBtank;
+my $cf = new Config;
+my %varenv = $cf->envonline($syshost);
+my $lang = "de";
+my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
+
+my $ua = LWP::UserAgent->new;
+$ua->agent("sharee APIclient");
+$ua->credentials( 'tracking.ilockit.bike:443', 'api', 'r.guempelein@sharee.bike', 'mohj2ooN');
+
+my $json = JSON->new->allow_nonref;
+my $response_in = {};
+my $dbh = "";
+my $owner = 183;
+
+my $todo = $ARGV[1];
+#my $deviceId = $ARGV[2] || "";
+my $pos_id = $ARGV[2] || "";
+
+open(FILE,">>$varenv{logdir}/Ilockit_tracking.log");
+print FILE "\n\n*** $now_dt\n";
+
+#utc to localtime
+sub localizedtime {
+ my $date = shift;
+
+ $date =~ s/\..*$//;
+ my $time = Time::Piece->strptime($date, "%Y-%m-%dT%H:%M:%S");
+ #print $time->datetime . "\n";#GMT alias Zulu
+ $time = localtime($time->epoch);#epoch
+ #print $time->datetime . "\n";#localized date time
+ #
+ return $time->datetime;
+}
+
+#localtime to utc
+#my $now = strftime "%Y-%m-%dT%H:%M:%S", localtime;
+#utctime($now);
+#exit;
+#
+sub utctime {
+ my $date = shift;
+ my $latency = shift || 0;
+
+ $date =~ s/\..*$//;
+ $date =~ s/\+\d+$//;
+ print FILE "requested datetime: " . $date . "\n";
+ my $time = Time::Piece->strptime($date, "%Y-%m-%dT%H:%M:%S");
+ print FILE "localtime: " . $time->datetime . "\n";#localtime
+ my $utc_epoch = $time->epoch;
+ #$utc_epoch -= 2*60*60;# -2 std (Sommerzeit)
+ $utc_epoch -= 1*60*60;# -1 std (Winterzeit)
+ $utc_epoch += $latency;
+ $time = gmtime($utc_epoch);#epoch
+ print FILE "utctime: " . $time->datetime . "\n";#utc zulu date time
+ #
+ return $time->datetime;
+}
+
+#get pos in contenttranspo
+sub get_pos {
+ my $id = shift;
+ my $pref = {
+ table => "contenttranspos",
+ fetch => "one",
+ c_id => "$id",
+ };
+ my $record = $dbt->fetch_tablerecord($dbh,$pref);
+ return $record;
+}
+
+
+
+if($todo eq "get_tripsum" && $pos_id){
+ print FILE "trying $todo && $pos_id" . "\n";
+ my $rows = &get_tripsum($pos_id);
+ print FILE "got rows $rows" . "\n";
+}else{
+ print FILE "failure: $todo && $pos_id" . "\n";
+}
+
+sub get_tripsum {
+ my $pos_id = shift;
+ my $ctpos = get_pos($pos_id);
+
+ #TEST
+ #$ctpos->{int13} = 8385;
+ #$ctpos->{start_time} = "2021-10-04 08:12:29";
+ #$ctpos->{end_time} = "2021-10-04 17:35:49";
+
+ #GET /api/reports/summary?groupId=95& from=2021-07-17T18:30:00Z& to=2021-07-20T18:30:00Z
+ my $endpoint = "https://tracking.ilockit.bike/api/reports/summary";
+
+ #GET /api/reports/trips?groupId=95& from=2020-07-17T18:30:00Z& to=2021-07-20T18:30:00Z
+ #my $endpoint = "https://tracking.ilockit.bike/api/reports/trips";
+ #my $rest = "groupId=95\&from=$oneday\&to=$today";
+ #my $rest = "deviceId=6574\&from=$oneday\&to=$today";
+ #
+ my $rows = 0;
+ if($ctpos->{int13}){
+ #start_time
+ $ctpos->{start_time} =~ s/\..*$//;
+ my $start_time = $ctpos->{start_time};
+ $start_time =~ s/\s/T/;
+ my $utc_start_time = utctime($start_time,"0");
+ $utc_start_time .= "Z";
+
+ #end_time
+ #my $end_time = strftime "%Y-%m-%dT%H:%M:%S", localtime;
+ $ctpos->{end_time} =~ s/\..*$//;
+ my $end_time = $ctpos->{end_time};
+ $end_time =~ s/\s/T/;
+ my $utc_end_time = utctime($end_time,"+300");#add 5 minutes, 300sec for latency
+ $utc_end_time .= "Z";
+
+ my $rest = "deviceId=$ctpos->{int13}\&from=$utc_start_time\&to=$utc_end_time";
+ #my $rest = "deviceId=$ctpos->{int13}\&from=2021-11-03T07:50:00Z\&to=2021-11-03T11:00:00Z";
+
+ my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
+ $response_in = decode_json($ret_json);
+ print FILE "ilockit get_tripsum response_in:" . Dumper($response_in) . "\n";
+
+ if(1==1){
+ my $update_pos = {
+ table => "contenttranspos",
+ owner => $owner,
+ mtime => "now()",
+ int26 => 0,
+ };
+ foreach my $resp (@{ $response_in }) {
+ if($ctpos->{int13} eq $resp->{deviceId}){
+ print FILE "device Id: $resp->{deviceId}" . "\n";
+ print FILE "distance: $resp->{distance}" . "\n";
+ if($resp->{distance}){
+ #my $distance = $resp->{distance} / 1000 * 1.60934; #distance in Meilen
+ my $distance = $resp->{distance} / 1000;
+ $distance = sprintf('%.2f', $distance);
+ $update_pos->{int26} = $distance;
+ }
+ }
+ }
+ $rows = $dbt->update_record($dbh,$update_pos,$ctpos) if($ctpos->{c_id} && $update_pos->{int26});
+ }
+ }else{
+ print FILE "failure: There is no contenttranspo deviceId int13: $ctpos->{int13}" . "\n";
+ }
+ return $rows;
+}#end if($todo eq "get_tripsum"){
+
+
+#ilockit http request
+sub fetch_ilockit_cloud {
+ my $self = shift;
+ my $ilockitserver = shift || "";
+ my $rest = shift || "";
+ my $ilockit_request = "$ilockitserver?$rest";
+
+ print FILE "fetch_ >> " . $ilockit_request . "\n";
+
+ my $req = HTTP::Request->new(GET => "$ilockit_request");
+ $req->content_type('application/json');
+ $req->content($rest);
+
+ my $res = $ua->request($req);
+ if ($res->is_success) {
+ #print $res->content;
+ return $res->content;
+ print $res->status_line, "\n";
+ }else {
+ print $res->status_line, "\n";
+ }
+}
+
+close(FILE);
+1;
diff --git a/copri4/main/src/scripts/Ilockkeygen.class b/copri4/main/src/scripts/Ilockkeygen.class
new file mode 100644
index 0000000..6477d52
Binary files /dev/null and b/copri4/main/src/scripts/Ilockkeygen.class differ
diff --git a/copri4/main/src/scripts/Ilockkeygen.java b/copri4/main/src/scripts/Ilockkeygen.java
new file mode 100644
index 0000000..b5cb00b
--- /dev/null
+++ b/copri4/main/src/scripts/Ilockkeygen.java
@@ -0,0 +1,102 @@
+/*
+import android.util.Log;
+*/
+import java.io.InputStream;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Created by Bjoern Kinberger on 04.10.18.
+ *
+ * This is a test class for the authentication process without a server
+ *
+ * Only use this for the development process, the key generation should be done on the server!
+ */
+public class Ilockkeygen {
+ //private static final String LOG_TAG = Ilockkeygen.class.getName();
+ public static byte[] sha1Value;
+
+
+ public static void generateKey(byte[] randomNum, byte[] internKey) {
+
+ //System.out.println( "K_int_byte = " + internKey );
+ //System.out.println("K_int_string = " + new String(internKey));
+ System.out.println("K_int = " + Arrays.toString(internKey));
+
+ byte[] filler = {0, 0, 0, 0};
+ Random random = new Random();
+
+ for (int i = 0; i < 16; i++) {
+ randomNum[i] = (byte) random.nextInt(255);
+ }
+
+ System.out.println("K_seed = " + Arrays.toString(randomNum));
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ try {
+ outputStream = new ByteArrayOutputStream();
+ outputStream.write(randomNum);
+ outputStream.write(internKey);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ byte tempoKey[] = outputStream.toByteArray();
+ System.out.println("K_temp = " + Arrays.toString(tempoKey));
+/*
+ Log.d(LOG_TAG, "onCreate: temp key " + Arrays.toString(tempoKey));
+*/
+ try {
+ sha1Value = SHA1(tempoKey);
+ } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ outputStream = new ByteArrayOutputStream();
+ outputStream.write(sha1Value);
+ outputStream.write(filler);
+ sha1Value = outputStream.toByteArray();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("K_a = " + Arrays.toString(sha1Value));
+/*
+ Log.d(LOG_TAG, "onCreate: 1. " + Arrays.toString(sha1Value));
+*/
+
+ try {
+ sha1Value = SHA1(sha1Value);
+ } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ outputStream = new ByteArrayOutputStream();
+ outputStream.write(sha1Value);
+ outputStream.write(filler);
+ sha1Value = outputStream.toByteArray();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ System.out.println("K_u = " + Arrays.toString(sha1Value));
+/*
+ Log.d(LOG_TAG, "onCreate: 2. " + Arrays.toString(sha1Value));
+*/
+ }
+
+ private static byte[] SHA1(byte[] tempoKey) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+ md.update(tempoKey);
+ return md.digest();
+ }
+}
+
diff --git a/copri4/main/src/scripts/Ilocktestauth.pl b/copri4/main/src/scripts/Ilocktestauth.pl
new file mode 100755
index 0000000..5467597
--- /dev/null
+++ b/copri4/main/src/scripts/Ilocktestauth.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+#
+#Autor ragu@gnu-systems.de
+#
+#Ilockit authentify test
+#
+#sudo su www-data -c "./src/scripts/Ilocktestauth.pl shareeapp_operator 1003"
+#
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || exit 1;
+}
+
+use lib "/var/www/copri4/$syshost/src";
+
+my $dbname = $ARGV[1] || "";
+my $bike = $ARGV[2] || "";
+
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use Lib::Config;
+use Data::Dumper;
+
+my $q = new CGI;
+my $cf = new Config;
+my %varenv = $cf->envonline("$syshost");
+my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
+
+
+my @K_select = `cd /var/www/copri4/$varenv{syshost}/src/scripts && export CLASSPATH='.:/usr/share/java:/usr/share/java/postgresql.jar' && java Ilockauth $dbname $bike`;
+ foreach(@K_select){
+ my ($K_key,$K_val) = split(/ = /, $_);
+ $K_val =~ s/\n//g;
+ print "$K_key: $K_val\n";
+ }
+
+my $receiver_usb = "abcd";
+if($receiver_usb =~ /(\w)(\w)$/){
+ my $a = ord($1);
+ my $b = ord($2);
+ print "$1|$2" . "\n";
+ print "$a|$b" . "\n";
+ my $receiver_id = sprintf( "%x", $a ) . sprintf( "%x", $b );
+ print $receiver_id . "\n";
+}
+
diff --git a/copri4/main/src/scripts/newsletter_post.pl b/copri4/main/src/scripts/newsletter_post.pl
new file mode 100755
index 0000000..45185cb
--- /dev/null
+++ b/copri4/main/src/scripts/newsletter_post.pl
@@ -0,0 +1,133 @@
+#!/usr/bin/perl -w
+
+#2021-03-17
+#redisgn because of BEGIN, use Net::SMTP; and executed in src/scripts
+#
+#sudo su www-data -c "./src/scripts/newsletter_post.pl 'shareedms-primary' 'send_cardexpire'"
+#
+#TODO, migrate it all to MailTransport.pm
+#
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || exit 1;
+}
+use lib "/var/www/copri4/$syshost/src";
+
+
+use strict;
+use warnings;
+use utf8;
+use Encode;
+use CGI ':standard';
+use DBI;
+use POSIX;
+use Email::MIME;
+use IO::All;
+use Email::MIME::CreateHTML;
+use Email::Sender::Simple qw(sendmail);
+use Net::SMTP;
+use Try::Tiny;
+use URI::Encode;
+my $uri_encode = URI::Encode->new( { encode_reserved => 1 } );
+use Data::Dumper;
+
+use Sys::Hostname;
+my $hostname = hostname;
+
+use Lib::Config;
+my $q = new CGI;
+my $cf = new Config;
+my %varenv = $cf->envonline("","$syshost");
+
+my $today = strftime("%d.%m.%Y %H:%M:%S",localtime(time));
+my $todo = $ARGV[1];
+
+open(EMA, ">> $varenv{logdir}/newsletter_post.log");
+print EMA "\n$today, start mailing\n";
+print EMA "'$todo\n";
+
+my $smtp_return = "";
+if($todo eq "send_cardexpire"){
+ my ($mail_to,$subject,$body,$signature) = send_cardexpire(\%varenv);
+ $smtp_return = transport(\%varenv,$mail_to,$subject,$body,$signature);
+}
+
+#----------------------------------------------------
+sub send_cardexpire {
+ my $varenv = shift;
+
+ my $mail_to = "ragu\@gnu-systems.de";
+ my $name = "test";
+
+ my $subject = "Fahrradmietsystem Konstanz";
+ my $body = <https://www.stadtwerke-konstanz.de/mobilitaet/rad-mietsystem ) haben Sie die Möglichkeit Ihre Daten zu überprüfen und ggf. zu erneuern.
+Kontaktieren Sie uns bitte falls Ihr Account für den Verleih nicht automatisch freigeschaltet wurde.
+
+Für weitere Fragen wenden Sie sich bitte an unsere Buchhaltung unter: buchhaltung\@fahrradspezialitaeten.com oder telefonisch 0761/5158912 (Mo, Mi, Fr 9-12 Uhr)
+
+EOF
+;
+ $body =~ s/\n/\ /g;
+
+ my $signature = "";
+
+ return ($mail_to,$subject,$body,$signature);
+}
+#---------------------------------------------------
+#
+sub transport {
+ my $varenv = shift;
+ my $mail_to = shift;
+ my $subject = shift;
+ my $body = shift;
+ my $signature = shift;
+
+ my $html = "$subject \n";
+ $html .= "$body
\n";
+ $html .= "$signature
\n";
+ $html .= "";
+
+ my $smtp = Net::SMTP->new($varenv->{mail_gateway},
+ Port => 465,
+ Hello => 'TeilRad',
+ Timeout => 30,
+ Debug => 0,
+ SSL => 1,
+ );
+ $smtp->auth($varenv->{sasl_username},$varenv->{sasl_password});
+ $smtp->mail($varenv->{mail_from});
+
+ if($hostname ne "$varenv->{live_hostname}"){
+ $mail_to = $varenv->{mail_testto};
+ $subject .= "* offline Test *";
+ }
+
+ if ($smtp->to($mail_to)) {
+ $smtp->data();
+ $smtp->datasend("To: $mail_to\n");
+ $smtp->datasend("Subject: $subject\nMIME-Version: 1.0\nContent-Type: text/html; charset=UTF-8 \n\n");
+ $smtp->datasend($html);
+ $smtp->dataend();
+ print EMA "$?\n";
+ } else {
+ print EMA $smtp->message();
+ }
+
+ sleep 1;
+ return $?;
+}
+#----------------------------------------------------
+
+print EMA "done mailing: $?\n";
+print EMA "\n\n";
+close EMA;
+
+1;
diff --git a/copri4/main/src/scripts/payone_cron.pl b/copri4/main/src/scripts/payone_cron.pl
new file mode 100755
index 0000000..05c9a0a
--- /dev/null
+++ b/copri4/main/src/scripts/payone_cron.pl
@@ -0,0 +1,245 @@
+#!/usr/bin/perl
+#
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#Capture payone payment by cron
+#
+ #> 1. auto-fixed RadBuchungen (bei service-fixed hat schon jemand die Buchung manuell bearbeitet, oder?)
+ #--> service fixed wird gesetzt wenn das Rad via COPRI terminiert wurde. D.h. das hat keine Aussage ob auch der RadBuchungs Datensatz bearbeitet wurde. Deshalb gilt hier die userid des Datensatz Bearbeiters als key ob Automatik angewandt werden kann.-->ok
+ #> 2. mit defect -->ok
+ #> 3. RadBuchungen länger als 1 Tag oder bei konrad > 9,- € und bei TINK > 15,- € -->ok if int03 <= 5
+ #> 4. Gesamtbetrag > 50,- € -->ok
+ #> 5. OPOS, also bereits fehlgeschlagene Einzüge -->ok
+ # 6. "Internas und Bearbeitungstatus" wenn definiert und nicht Buchungsfreigabe, txid renew
+#
+#payone_cron cron Intervall 0=disabled, 1=weekly, 2=monthly
+#
+#All with coded conditions
+#sudo su www-data -c "./src/scripts/payone_cron.pl tinkdms '' 1"
+
+#One invoice
+#sudo su www-data -c "./src/scripts/payone_cron.pl tinkdms ctt_id 1"
+#
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || exit 1;
+}
+
+use lib "/var/www/copri4/$syshost/src";
+
+my $ctt_id = $ARGV[1] || "";
+my $intervall = $ARGV[2] || "1";
+
+use strict;
+use warnings;
+use POSIX;
+use Lib::Config;
+use Mod::Libenz;
+use Mod::DBtank;
+use Mod::Payment;
+use Data::Dumper;
+use Scalar::Util qw(looks_like_number);
+
+my $cf = new Config;
+my %varenv = $cf->envonline("$syshost");
+my $lb = new Libenz;
+my $dbt = new DBtank;
+my $pay = new Payment;
+my $now_dt = strftime("%Y-%m-%d %H:%M:%S",localtime(time));
+my $owner = 179;#179=cron
+
+my $dbh = $dbt->dbconnect();
+
+ #get Firma in contentuser
+ my $fetchuser = {
+ table => "contentuser",
+ fetch => "one",
+ c_id => 100002,
+ };
+ my $ctf = $dbt->fetch_tablerecord($dbh,$fetchuser);
+
+ #collect open invoices
+ my $fetchtrans = {
+ table => "contenttrans",
+ fetch => "all",
+ keyfield => "c_id",
+ main_id => "300008",#Rechnung
+ template_id => "218",#Rechnung
+ state => "is::null",#never tried buchen
+ close_time => "",#invoice isn't closed
+ int14 => "is::null",#OPOS
+ owner => "!=::$owner",#not 179=cron, not still tried by payone_cron
+ };
+ $fetchtrans = { %$fetchtrans , c_id => $ctt_id } if($ctt_id && $ctt_id =~ /^\d+$/);
+ my $ct4rel = $dbt->fetch_record($dbh,$fetchtrans);
+
+ open(FILE,">>$varenv{logdir}/payone_cron.log");
+ print FILE "\n\n*** $now_dt\n";
+
+ my $max_sum = $ctf->{int03} || "10000";
+ my $max_timestamp = "210001012359";
+ my $scol = "mtime";
+ my $i=0;
+
+ #loop invoices
+ #foreach my $id (sort { $ct4rel->{$a}->{$scol} cmp $ct4rel->{$b}->{$scol} }keys (%$ct4rel)){
+ foreach my $id (sort { $ct4rel->{$b}->{$scol} cmp $ct4rel->{$a}->{$scol} }keys (%$ct4rel)){
+ $i++;
+
+ print FILE "\n$i)** loop $now_dt ---> payone_cron select invoice ct.c_id:$ct4rel->{$id}->{c_id}| ca.c_id:$ct4rel->{$id}->{int10}| ct.ct_name:$ct4rel->{$id}->{ct_name}| ct.mtime:$ct4rel->{$id}->{mtime}\n";
+ if($ct4rel->{$id}->{int10} && !$ct4rel->{$id}->{txt22} && $ct4rel->{$id}->{ct_name} =~ /---|^\d+$/){
+
+ my $umst1619 = $lb->umst_breaking($ct4rel->{$id},$now_dt);
+
+ #get Adresse from contentadr
+ my $fetchadr = {
+ table => "contentadr",
+ fetch => "one",
+ int16 => $intervall,
+ c_id => $ct4rel->{$id}->{int10},
+ };
+ my $ctadr = $dbt->fetch_tablerecord($dbh,$fetchadr);
+
+ #payone_cron cron Intervall 0=disabled, 1=weekly, 2=monthly
+ if($ctadr->{int16}){
+ #collect invoice positions
+ my $fetchpos = {
+ table => "contenttranspos",
+ fetch => "all",
+ keyfield => "c_id",
+ ct_id => $ct4rel->{$id}->{c_id},
+ };
+ my $cttpos = $dbt->fetch_tablerecord($dbh,$fetchpos);
+
+ my $scol = "itime";
+ my $sum_parts0=0;
+ my $sum_parts7=0;
+ my $sum_parts19=0;
+ my $sum_kaution=0;
+ my $diff7 = 100 + 7;
+ my $diff19 = 100 + $umst1619;
+ my $sum_umst7=0;
+ my $sum_umst19=0;
+ my $j=0;
+ my $accounting_start = "";
+ my $accounting_end = "";
+ my $k=0;
+ my $m=0;
+
+ my $capture_condition=1;#1=false
+
+ #loop invoice positions
+ foreach my $id (sort { $cttpos->{$b}->{$scol} cmp $cttpos->{$a}->{$scol} } keys(%$cttpos)){
+ if(($cttpos->{$id}->{int12} && $cttpos->{$id}->{int12} !~ /300005|300024/) || (($cttpos->{$id}->{int10} && $cttpos->{$id}->{int10} == 1) && ($cttpos->{$id}->{int03} && $cttpos->{$id}->{int03} <= 5) && ($cttpos->{$id}->{txt01} && $cttpos->{$id}->{txt01} !~ /fixed|defect/ || ($cttpos->{$id}->{owner_end} && $cttpos->{$id}->{owner_end} > 1000)))){
+ $j++;
+
+ my $cttpos_timestamp = $1 . $2 . $3 . "0000" if($cttpos->{$id}->{itime} =~ /(\d+)\-(\d+)\-(\d+)/);
+ #max. Rechnungspositionen
+ if(($cttpos_timestamp <= $max_timestamp) && ($sum_parts19 <= $max_sum)){
+ $k++;
+ #print "$i (($id: $cttpos_timestamp <= $max_timestamp) && ($sum_parts19 <= $max_sum)) ";
+ if($k==1){
+ $accounting_end = "$3.$2.$1" if($cttpos->{$id}->{itime} =~ /(\d+)\-(\d+)\-(\d+)/);
+ $accounting_start = $accounting_end;
+ }else{
+ $accounting_start = "$3.$2.$1" if($cttpos->{$id}->{itime} =~ /(\d+)\-(\d+)\-(\d+)/);
+ }
+
+ $capture_condition=0;
+ my $gesamt = 0;
+ my $einzel = $cttpos->{$id}->{int02};
+ my $menge = $cttpos->{$id}->{int03};
+ $gesamt = $einzel * $menge;
+
+ my $rabatt_val = $cttpos->{$id}->{int07} || 0;
+ my $rabatt_eur = 0;
+ my $proz_eur = $cttpos->{$id}->{int08} || 0;
+ if($rabatt_val != 0){
+ $rabatt_eur = $rabatt_val;
+ if($proz_eur != 1){#wenn int08 != 1 alias €
+ $rabatt_eur = $einzel * $menge * $rabatt_val/100;
+ }
+ $gesamt = $einzel * $menge - $rabatt_eur;
+ }
+ $m++ if($gesamt != 0);
+ print FILE "pos gesamt: $gesamt = $einzel * $menge - $rabatt_eur ($rabatt_val|$rabatt_eur)\n";
+
+ $gesamt = $lb->round($gesamt);
+ $gesamt = $lb->cashme($gesamt);
+ $ctf->{txt13} = $1 if($ctf->{txt13} =~ /(\d+)/);
+ if($ct4rel->{$id}->{node_name} && $ct4rel->{$id}->{node_name} =~ /steuerfrei/){
+ $sum_parts0 += $gesamt;
+ }elsif($cttpos->{$id}->{int05} && $cttpos->{$id}->{int05} =~ /\d/){
+ $sum_parts0 += $gesamt if($cttpos->{$id}->{int05} == 0);
+ $sum_parts7 += $gesamt if($cttpos->{$id}->{int05} == 7);
+ $sum_parts19 += $gesamt if($cttpos->{$id}->{int05} >= 16);
+ }else{
+ $sum_parts0 += $gesamt if($ctf->{txt13} == 0);
+ $sum_parts7 += $gesamt if($ctf->{txt13} == 7);
+ $sum_parts19 += $gesamt if($ctf->{txt13} >= 16);
+ }
+ }#end timestamp
+ }else{#end conditons
+ $capture_condition=1;
+ #print "LAST LINE\n";
+ last;
+ }
+ }#end loop invoice positions
+
+ my $sum_paid = $sum_parts0 + $sum_parts7 + $sum_parts19;
+ $sum_paid = $lb->round($sum_paid);
+ my $sum_preauth = $sum_paid || 0;
+ $sum_paid = $lb->cashme($sum_paid,"");
+ my $line_count2 = $m+4;
+
+ print FILE "---> payone_cron capture conditions c_id:$ct4rel->{$id}->{c_id}, capture_condition:$capture_condition, sum_paid:$sum_paid, sum_preauth:$sum_preauth, ($accounting_start - $accounting_end)\n";
+ if($capture_condition==0 && $sum_paid > 0 && $sum_paid <= 50){
+ my $update = {
+ table => "contenttrans",
+ int15 => "$sum_preauth",
+ txt20 => "$accounting_start - $accounting_end",
+ owner => "$owner",#cron
+ int04 => "14.$line_count2",
+ mtime => "now()",
+ };
+ my $record = { c_id => $ct4rel->{$id}->{c_id} };
+ my $rows = $dbt->update_record($dbh,$update,$record) if($record->{c_id} > 0);
+
+ my ($return,$return_text) = $pay->payone_capture(\%varenv,$ctf,$ctadr,$ct4rel->{$id},$sum_paid,$owner);
+ print FILE "---> Payment.pm Modul things: $return_text\nFinally log payone-return-post.log\n";
+
+ sleep 20;
+ }elsif($sum_paid > 0){
+ my $update = {
+ table => "contenttrans",
+ txt22 => "cronjob fail",#also defined in Config.pm
+ owner => "$owner",#cron
+ mtime => "now()",
+ };
+ my $record = { c_id => $ct4rel->{$id}->{c_id} };
+ my $rows = $dbt->update_record($dbh,$update,$record) if($record->{c_id} > 0);
+ print FILE "---> payone_cron c_id:$ct4rel->{$id}->{c_id} conditions fails\n";
+ }else{
+ print FILE "---> payone_cron c_id:$ct4rel->{$id}->{c_id} conditions fails at all, sum_paid: $sum_paid > 0\n";
+ }
+ }#end if $ctadr->{int16}
+ }else{
+ my $update = {
+ table => "contenttrans",
+ #txt22 => "cronjob fail",#disabled to keep fibu saved Bearbeitsungsstatus
+ owner => "$owner",#cron
+ mtime => "now()",
+ };
+ my $record = { c_id => $ct4rel->{$id}->{c_id} };
+ my $rows = $dbt->update_record($dbh,$update,$record) if($record->{c_id} > 0);
+
+ print FILE "---> payone_cron c_id:$ct4rel->{$id}->{c_id} Failure: no ct.int10 or order_stat ct.txt22:$ct4rel->{$id}->{txt22}\n";
+ }
+ }#end loop invoices
+
+ close(FILE);
+
diff --git a/copri4/main/src/scripts/payone_operatorsloop.pl b/copri4/main/src/scripts/payone_operatorsloop.pl
new file mode 100755
index 0000000..683dafa
--- /dev/null
+++ b/copri4/main/src/scripts/payone_operatorsloop.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#loops sharee operators for payone capture
+#only primary should do this
+#
+#sudo su www-data -c "./src/scripts/payone_operatorsloop.pl 1"
+#
+#defined by cronjob
+#weekly for $ARGV[0]=1
+#nonthly for $ARGV[0]=2
+#
+use lib "/var/www/copri4/shareedms-primary/src";
+
+use strict;
+use warnings;
+use POSIX;
+use Config::General;
+
+die if(!$ARGV[0] || ($ARGV[0] != 1 && $ARGV[0] != 2));
+
+my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
+my $conf = Config::General->new($globalconf_file);
+my %globalconf = $conf->getall;
+
+while (my ($key, $value) = each %{ $globalconf{"operator"} }) {
+ if(-d "/var/www/copri4/$value->{syshost}"){
+ `/var/www/copri4/shareedms-primary/src/scripts/payone_cron.pl $value->{syshost} '' $ARGV[0]`;
+ die if($? != 0);
+ }else{
+ print "/var/www/copri4/$value->{syshost} not available\n";
+ }
+}
diff --git a/copri4/main/src/scripts/payone_post_Payment.pl b/copri4/main/src/scripts/payone_post_Payment.pl
new file mode 100755
index 0000000..e520a6d
--- /dev/null
+++ b/copri4/main/src/scripts/payone_post_Payment.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+#
+#Autor ragu@gnu-systems.de
+#sharee payone POST
+#
+#managemandate
+#sudo su www-data -c "/var/www/copri4/shareeapp-primary/src/scripts/payone_post_Payment.pl shareeapp-fr01 managemandate contentadr 21250"
+#
+#captureSEPA
+#sudo su www-data -c "/var/www/copri4/shareeapp-primary/src/scripts/payone_post_Payment.pl shareeapp-fr01 preauthorizationSEPA contentadr 22027 28845"
+#sudo su www-data -c "/var/www/copri4/shareeapp-primary/src/scripts/payone_post_Payment.pl shareeapp-fr01 captureSEPA contenttrans '' 28845"
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || die 'syshost not defined';
+}
+
+use lib "/var/www/copri4/$syshost/src";
+
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use Lib::Config;
+use Mod::Libenzdb;
+use Mod::Payment;
+use Config::General;
+
+use Data::Dumper;
+use Sys::Hostname;
+my $hostname = hostname;
+
+my $q = new CGI;
+my $cf = new Config;
+my %varenv = $cf->envonline("$syshost");
+print "$varenv{dbname}\n";
+
+my $db = new Libenzdb;
+my $pay = new Payment;
+my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
+my $owner = 178;#payone API
+
+my $todo = $ARGV[1];
+my $table = $ARGV[2];
+my $ctadr_id = $ARGV[3];
+my $ctt_id = $ARGV[4];
+my $sequenz = $ARGV[5] || 0;
+my $set_time = $ARGV[6] || "";#no_time
+my $renewed = $ARGV[7] || "";#for requesting new txid via script loop_payone_capture.pl
+my $request_state = $ARGV[8] || "";#if request state=occupied , then never delete adr4xml
+
+my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
+my $conf = Config::General->new($globalconf_file);
+my %globalconf = $conf->getall;
+#print Dumper(\%globalconf);
+
+my $refpre = $globalconf{operator}{$varenv{dbname}}->{oprefix};#FR KN ...
+my $payone_conf = $globalconf{operator}{$varenv{dbname}}{payone_conf} || $globalconf{payone_conf};
+
+my $ctadr = { c_id => 0 };
+my $ctt = { c_id => 0 };
+$ctadr = $db->get_contentrow("contentadr",$ctadr_id,"","","","","","") if($ctadr_id);
+$ctt = $db->get_contentrow("contenttrans",$ctt_id,"","","","","","") if($ctt_id);
+
+#managemandate SEPA
+#1.
+#sudo su www-data -c "./src/scripts/payone_post.pl $varenv{syshost} managemandate contentadr $ctadr_id"
+if($todo eq "managemandate" && $table eq "contentadr" && $ctadr->{c_id} > 0){
+ $pay->managemandate_main(\%varenv,$ctadr,$ctt,$owner);
+}
+#preauthorizationSEPA
+#2.
+#sudo su www-data -c "./src/scripts/payone_post.pl $varenv{syshost} preauthorizationSEPA contentadr $ctadr_id $ctt_id"
+if($todo eq "preauthorizationSEPA" && $table eq "contentadr" && $ctadr->{c_id} > 0 && $ctt->{c_id} > 0){
+ $pay->preauthorizationSEPA_main(\%varenv,$ctadr,$ctt,$owner);
+}
+#captureSEPA
+#3.
+#sudo su www-data -c "./src/scripts/payone_post.pl $varenv{syshost} captureSEPA contenttrans '' $ctt_id"
+if($todo eq "captureSEPA" && $table eq "contenttrans" && $ctt->{c_id} > 0){
+ $pay->captureSEPA_main(\%varenv,$ctadr,$ctt,$owner);
+}
+#preauthorizationCC
+#1.PayoneCC creditcardcheck ajaxCall
+#2.
+#sudo su www-data -c "./src/scripts/payone_post.pl $varenv{syshost} preauthorizationCC contentadr $ctadr_id $ctt_id"
+if($todo eq "preauthorizationCC" && $table eq "contentadr" && $ctadr->{c_id} > 0 && $ctt->{c_id} > 0){
+ $pay->preauthorizationCC_main(\%varenv,$ctadr,$ctt,$owner);
+}
+#captureCC
+#3.
+#
+if($todo eq "captureCC" && $table eq "contenttrans" && $ctt->{c_id} > 0){
+ $pay->captureCC_main(\%varenv,$ctadr,$ctt,$owner);
+}
+
diff --git a/copri4/main/src/scripts/requested_timeout.pl b/copri4/main/src/scripts/requested_timeout.pl
new file mode 100755
index 0000000..8207c0b
--- /dev/null
+++ b/copri4/main/src/scripts/requested_timeout.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+#
+#Autor ragu@gnu-systems.de
+#
+#set availabel if requested > 15min
+#
+#sudo su www-data -c "./src/scripts/requested_timeout.pl shareedms-fr01"
+#
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || die;
+}
+
+use lib "/var/www/copri4/$syshost/src";
+
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use Lib::Config;
+use Mod::DBtank;
+use Data::Dumper;
+
+my $q = new CGI;
+my $cf = new Config;
+my %varenv = $cf->envonline("$syshost");
+my $dbt = new DBtank;
+my $lang = "de";
+my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
+my $dbh = "";
+
+#set available if requestes older than 15 minute
+my $return={};
+my $pref = {
+ table => "contenttranspos",
+ fetch => "all",
+ keyfield => "c_id",
+ #txt10 => "requested",
+ int10 => "2",
+ owner => "!=::199",#don't select LV api requested bikes
+ start_time => "<=::(now() - interval '15 minutes')",
+};
+my $record_cp = $dbt->fetch_tablerecord($dbh,$pref);
+
+my $update_cp = {
+ table => "contenttranspos",
+ #txt10 => "available",
+ int10 => "1",
+};
+my $update_cc = {
+ table => "content",
+ int10 => "1",
+};
+
+my $rows = 0;
+foreach my $id (sort { $record_cp->{$a}->{c_id} <=> $record_cp->{$b}->{c_id} } keys (%$record_cp)){
+ my $record = { c_id => 0 };
+ $record->{c_id} = $record_cp->{$id}->{c_id};
+ #contenttranspos
+ $rows = $dbt->update_record($dbh,$update_cp,$record);
+ if($rows > 0 && $record_cp->{$id}->{cc_id}){
+ $record->{c_id} = $record_cp->{$id}->{cc_id};
+ #content
+ $dbt->update_record($dbh,$update_cc,$record);
+ }
+}
+
+1;
diff --git a/copri4/main/src/scripts/sms_gtx_SMSTransport.pl b/copri4/main/src/scripts/sms_gtx_SMSTransport.pl
new file mode 100755
index 0000000..bd018c8
--- /dev/null
+++ b/copri4/main/src/scripts/sms_gtx_SMSTransport.pl
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+#
+#sudo su www-data -c "./src/scripts/sms_gtx_SMSTransport.pl shareeapp-operator '+491799xxxx72'"
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || die 'syshost not defined';
+}
+
+use lib "/var/www/copri4/$syshost/src";
+
+use strict;
+use warnings;
+use POSIX;
+use Mod::SMSTransport;
+
+my $smstrans = new SMSTransport;
+
+my $phone = $ARGV[1] || die 'phone not defined';
+my $adrhash = {
+ txt07 => $phone,
+ txt34 => "nureinlangertestdigest",
+};
+
+my $ret_json = $smstrans->sms_ack_digest($adrhash);
diff --git a/copri4/main/src/scripts/tests/index.pl b/copri4/main/src/scripts/tests/index.pl
new file mode 100755
index 0000000..a83742e
--- /dev/null
+++ b/copri4/main/src/scripts/tests/index.pl
@@ -0,0 +1,184 @@
+#!/usr/bin/perl
+#
+## SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use lib "/var/www/copri4/shareeweb-project/src";
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use CGI::Carp qw(fatalsToBrowser);
+use CGI::Cookie ();
+use DBI;
+use Lib::Config;
+use Mod::DBtank;
+
+my $q = new CGI();
+$q->import_names('R');
+my $cf = new Config;
+my $dbt = new DBtank;
+my %varenv = $cf->envonline();
+
+ my $coo = $q->cookie('domcookie') || $q->param('sessionid') || "";
+
+ if($q->param('sessionid') && $q->param('sessionid') ne $q->cookie('domcookie')){
+ $coo = $q->param('sessionid');
+ my $cookie = CGI::Cookie->new(-name => 'domcookie',-value => $coo);
+ print $q->header(-charset=>"utf-8", -cookie=>$cookie);
+ }else{
+ my $cookie = CGI::Cookie->new(-name => 'domcookie',-value => $coo);
+ print $q->header(-charset=>"utf-8", -cookie=>$cookie);
+ }
+
+ die "no configuration available" if(!$varenv{wwwhost});
+ my $lang = "de";
+ my $dyn_js = "
+ function onLoad() {
+ console.log('hallo');
+
+ if ('geolocation' in navigator) {
+ console.log('geon');
+ /* geolocation funktioniert */
+ } else {
+ console.log('geoff');
+ /* geolocation funktioniert NICHT */
+ }
+ \$( '#no_javascript' ).hide();
+ }
+ \n";
+
+ my $dyn_css = "";
+ my $local_style = "$varenv{metahost}/$dbt->{shareeapp_conf}->{local_style}";
+ my $jquery = "$varenv{metahost}/$dbt->{shareeapp_conf}->{jquery}";
+ my $js_bootstrap = "$varenv{metahost}/$dbt->{shareeapp_conf}->{js_bootstrap}";
+ my $style_bootstrap = "$varenv{metahost}/$dbt->{shareeapp_conf}->{style_bootstrap}";
+ if($varenv{wwwhost} =~ /shareedms/){
+ $local_style = "$varenv{metahost}/$dbt->{shareedms_conf}->{local_style}";
+ $jquery = "$varenv{metahost}/$dbt->{shareedms_conf}->{jquery}";
+ $js_bootstrap = "$varenv{metahost}/$dbt->{shareedms_conf}->{js_bootstrap}";
+ $style_bootstrap = "$varenv{metahost}/$dbt->{shareedms_conf}->{style_bootstrap}";
+ }
+
+
+ my $html5 = $q->start_html(
+ -title => "shareetest",
+ -lang => '',
+ -onload => "onLoad();",
+ -encoding => "utf-8",
+ -base => 'true',
+ -head => Link(
+ {
+ -rel => 'shortcut icon',
+ -type => 'image/x-icon',
+ -href => "/css/favicon.ico"
+ }
+ ),
+ -meta => {
+ 'viewport'=>"width=device-width,initial-scale=1,user-scalable=yes",
+ 'author' => "rainer guempelein",
+ 'publisher' => "",
+ 'copyright' => "",
+ },
+ -script=>[
+ {-language=>'JAVASCRIPT',
+ -src=>"$jquery"},
+ {-language=>'JAVASCRIPT',
+ -src=>"$varenv{metahost}/$dbt->{copri_conf}->{jquery_ui}"},
+ {-language=>'JAVASCRIPT',
+ -src=>"$varenv{metahost}/$dbt->{copri_conf}->{jquery_resize}"},
+ {-language=>'JAVASCRIPT',
+ -src=>"$varenv{metahost}/$dbt->{copri_conf}->{jsscript}"},
+ {-language=>'JAVASCRIPT',
+ -src=>"$varenv{metahost}/js/shareespecial.js"},
+ {-language=>'JAVASCRIPT',
+ -code=>"$dyn_js"}
+ ],
+ -STYLE=>{
+ -code=>"$dyn_css",
+ -src=>[
+ "$local_style",
+ "$style_bootstrap",
+ "$varenv{metahost}/$dbt->{copri_conf}->{style_bootstrap_icons}",
+ "$varenv{metahost}/$dbt->{copri_conf}->{style_jquery_ui}"
+ ],
+ -verbatim=>"\@import url(\"$local_style\");",
+ -media=>'screen'
+ }
+
+);
+
+ $html5 =~ s{}{}s;
+ $html5 =~ s{}{}s;
+ print $html5;
+
+##
+my $uri = "$dbt->{primary}->{sharee_primary}->{primaryApp}/APIjsonserver";
+print $q->div({-style=>'margin:15px;'},$q->a({-href=>"/src/scripts/tests/index.pl"},"[ index ]")),"\n";
+
+print $q->div({-style=>'margin:15px;'}," "),"\n";
+print $q->div({-style=>'margin:15px;'},"-------------- $uri --------------------"),"\n";
+my $authorization = "$uri?request=authorization&user_id=ragu\@gnu-systems.de&user_pw=mabel321&merchant_id=oiF2kahH&hw_id=g89g8o7goguzuzug";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$authorization"},"[ authorization ]---> $authorization")),"\n";
+
+my $authout = "$uri?request=authout&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$authout"},"[ authout ]---> $authout")),"\n";
+
+my $bikes_all = "$uri?request=bikes_all&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$bikes_all"},"[ bikes_all ]---> $bikes_all")),"\n";
+
+my $bikes_available = "$uri?request=bikes_available&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$bikes_available"},"[ bikes_available ]---> $bikes_available")),"\n";
+
+my $stations_all = "$uri?request=stations_all&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$stations_all"},"[ stations_all ]---> $stations_all")),"\n";
+
+my $stations_available = "$uri?request=stations_available&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$stations_available"},"[ stations_available ]---> $stations_available")),"\n";
+
+my $user_bikes_occupied = "$uri?request=user_bikes_occupied&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$user_bikes_occupied"},"[ user_bikes_occupied ]---> $user_bikes_occupied")),"\n";
+
+my $user_rentals_history = "$uri?request=user_rentals_history&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$user_rentals_history"},"[ user_rentals_history ]---> $user_rentals_history")),"\n";
+
+
+my $user_minianswer = "$uri?request=user_minianswer&q1=opt5&q2=opt4&q3=iuwehfiolbev&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$user_minianswer"},"[ user_minianswer ]---> $user_minianswer")),"\n";
+
+
+###
+print $q->div({-style=>'margin:15px;'}," "),"\n";
+my $uriop = "$dbt->{operator}->{sharee_operator}->{operatorApp}/APIjsonserver";
+print $q->div({-style=>'margin:15px;'},"-------------- $uriop --------------------"),"\n";
+my $booking_request = "$uriop?request=booking_request&bike=FR1003&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_request"},"[ booking_request ]---> $booking_request")),"\n";
+
+my $booking_update_cancel = "$uriop?request=booking_update&bike=FR1003&state=canceled&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_update_cancel"},"[ booking_update_cancel ]---> $booking_update_cancel")),"\n";
+
+my $booking_update_locking = "$uriop?request=booking_update&bike=FR1003&lock_state=locking&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_update_locking"},"[ booking_update_locking ]---> $booking_update_locking")),"\n";
+my $booking_update_locked = "$uriop?request=booking_update&bike=FR1003&lock_state=locked&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_update_locked"},"[ booking_update_locked ]---> $booking_update_locked")),"\n";
+my $booking_update_unlocked = "$uriop?request=booking_update&bike=FR1003&lock_state=unlocked&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_update_unlocked"},"[ booking_update_unlocked ]---> $booking_update_unlocked")),"\n";
+
+my $booking_update_oc_ul = "$uriop?request=booking_update&bike=FR1003&state=occupied&lock_state=unlocked&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_update_oc_ul"},"[ booking_update_oc_ul ]---> $booking_update_oc_ul")),"\n";
+
+my $booking_request_oc_ul = "$uriop?request=booking_request&bike=FR1003&state=occupied&lock_state=unlocked&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_request_oc_ul"},"[ booking_request_oc_ul ]---> $booking_request_oc_ul")),"\n";
+
+my $booking_update_av_lo = "$uriop?request=booking_update&bike=FR1003&state=available&lock_state=locked&latitude=47.927738&longitude=7.973855&gps_age=300&user_device_manufaturer=samsung)&user_device_model=SM-G398FN&user_device_platform=Android&user_device_version=10&user_device_id=90af86831c10374d&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$booking_update_av_lo"},"[ booking_update_av_lo ]---> $booking_update_av_lo")),"\n";
+
+my $user_feedback = "$uriop?request=user_feedback&bike=FR1003&bike_broken=1&message=testnachricht äöü&authcookie=$coo";
+print $q->div({-style=>'margin:15px;'},$q->a({-target=>'_blank', -href=>"$user_feedback"},"[ user_feedback ]---> $user_feedback")),"\n";
+
+print "\n";
+
+print $q->end_html;
+1;
diff --git a/copri4/main/src/scripts/velofaktur_client.pl b/copri4/main/src/scripts/velofaktur_client.pl
new file mode 100755
index 0000000..0cb5d4b
--- /dev/null
+++ b/copri4/main/src/scripts/velofaktur_client.pl
@@ -0,0 +1,220 @@
+#!/usr/bin/perl
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+# velofaktur per REST JSON Payload with Bearer Token
+#
+# Abrufen einer Liste mit Stationen, Anzahl Slots + Name
+# sudo su www-data -c "./src/scripts/velofaktur_client.pl shareedms-fr01 get_velo"
+#
+# bike ID Statusabfrage | Freigeben
+# sudo su www-data -c "./src/scripts/velofaktur_client.pl shareedms-fr01 post_velo 8 1 200008 Statusabfrage"
+# will be sent by booking_update $lock_state eq "unlocked"
+# sudo su www-data -c "./src/scripts/velofaktur_client.pl shareedms-fr01 post_velo 8 1 200008 Freigeben "$record_pos->{c_id}""
+#
+use vars qw($syshost);
+
+BEGIN {
+ $syshost = $ARGV[0] || die;
+}
+
+use lib "/var/www/copri4/$syshost/src";
+use strict;
+use warnings;
+use POSIX;
+use CGI;
+use JSON;
+use LWP::UserAgent;
+use DateTime;
+use Time::Piece;
+use Lib::Config;
+use Mod::DBtank;
+use Mod::Basework;
+use Data::Dumper;
+
+my $q = new CGI;
+my $cf = new Config;
+my $dbt = new DBtank;
+my $bw = new Basework;
+my $lang = "de";
+my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
+
+my $api_file = "/var/www/copri4/shareeconf/apikeys.cfg";
+my $aconf = Config::General->new($api_file);
+my %apikeyconf = $aconf->getall;
+#print $apikeyconf{velofaktur}->{bearer};
+
+my $ua = LWP::UserAgent->new;
+$ua->agent("sharee veloclient");
+my $size = $ua->max_size;
+my $bytes = 1000;
+$ua->max_size( $bytes );
+$ua->default_header( 'Authorization' => $apikeyconf{velofaktur}->{bearer} );
+
+my $json = JSON->new->allow_nonref;
+my %varenv = $cf->envonline($syshost);
+my $response_in = {};
+my $dbh = "";
+my $owner = 182;
+
+my $todo = $ARGV[1];
+my $Station = $ARGV[2] || "";
+my $Slot = $ARGV[3] || "";
+my $velo_id = $ARGV[4] || "";
+my $Befehl = $ARGV[5] || "";
+my $posc_id = $ARGV[6] || "";
+
+open(FILE,">>$varenv{logdir}/APIvelo.log");
+print FILE "\n*** $now_dt 'sharee veloclient' \n";
+
+&get_velo if($todo eq "get_velo");
+sub get_velo {
+
+ #my $endpoint = "https://shareeapp-primary.copri-bike.de/APIvelo";
+ my $endpoint = "https://cockpit.velofactur.de/api/portal/station";
+
+ my $rest_json = "";
+ my $ret_json = getvelo_cloud("","$endpoint",$rest_json);
+ eval {
+ $response_in = decode_json($ret_json);
+ print FILE "<--- velofactur response_in:\n" . Dumper($response_in);
+ };
+ if ($@){
+ print FILE "<--- failure get_velo raw response_in:\n" . Dumper($ret_json) . "\n";
+ warn $@;
+ }
+
+}
+
+#velofaktur http request
+sub getvelo_cloud {
+ my $self = shift;
+ my $veloserver = shift || "";
+ my $rest_json = shift || "";
+ my $velo_request = "$veloserver";
+
+ print FILE "===> GET2velo >> " . $velo_request . "\n" . $rest_json . "\n";
+
+ my $req = HTTP::Request->new(GET => "$velo_request");
+ $req->content_type('application/json');
+
+ $req->content($rest_json);
+
+ my $res = $ua->request($req);
+ if ($res->is_success) {
+ #print $res->content;
+ return $res->content;
+ print $res->status_line, "\n";
+ }else {
+ print $res->status_line, "\n";
+ }
+}
+#end if($todo eq "get_velo"){
+
+&post_velo($Station,$Slot,$velo_id,$Befehl,$posc_id) if($todo eq "post_velo");
+sub post_velo {
+ my $Station = shift;
+ my $Slot = shift;
+ my $velo_id = shift;
+ my $Befehl = shift;
+
+ #local TEST
+ #my $endpoint = "https://shareeapp-primary.copri-bike.de/APIvelo";
+ #LIVE
+ my $endpoint = "https://cockpit.velofactur.de/api/portal/befehl";
+
+
+ my %json;
+ $json{Station} = "$Station";
+ $json{Slot} = "$Slot";
+ $json{Id} = "$velo_id";
+ $json{Befehl} = "$Befehl";
+ my $rest_json = encode_json(\%json);
+
+ my $ret_json = post2velo_cloud("","$endpoint",$rest_json);
+ #
+ eval {
+ $response_in = decode_json($ret_json);
+ print FILE "<--- velofaktur response_in:\n" . Dumper($response_in);
+ print $ret_json . "\n";
+
+ my $record_cc = { c_id => 0 };
+ if($velo_id && $velo_id > 0){
+ my $pref_cc = {
+ table => "content",
+ fetch => "one",
+ template_id => "205",
+ int27 => $velo_id,
+ };
+
+ $record_cc = $dbt->fetch_record($dbh,$pref_cc);
+ my $update_cc = {
+ table => "content",
+ mtime => "now()",
+ owner => "$owner",
+ };
+ $update_cc->{txt25} = $response_in->{status} if($response_in->{status});
+ $dbt->update_record($dbh,$update_cc,$record_cc) if($record_cc->{c_id});
+ $bw->log("update content velofactur response Status for bike $velo_id $record_cc->{barcode} $response_in->{status}",$update_cc,"");
+ }
+
+ my $record_pos = { c_id => 0 };
+ if($posc_id && $posc_id > 0){
+ my $pref_pos = {
+ table => "contenttranspos",
+ fetch => "one",
+ c_id => $posc_id,
+ };
+
+ $record_pos = $dbt->fetch_record($dbh,$pref_pos);
+
+ my $update_pos = {
+ table => "contenttranspos",
+ mtime => "now()",
+ owner => "$owner",
+ };
+ $update_pos->{int27} = $velo_id if($velo_id);
+ $update_pos->{30} = $Station if($Station);
+ $update_pos->{31} = $Slot if($Slot);
+ $update_pos->{txt25} = $response_in->{status} if($response_in->{status});
+ $dbt->update_record($dbh,$update_pos,$record_pos) if($record_pos->{c_id});
+ $bw->log("update contenttranspos velofactur response Status for bike $velo_id $record_pos->{barcode} $response_in->{status}",$update_pos,"");
+ }
+
+
+ };
+ if ($@){
+ print FILE "<--- failure post_velo raw response_in:\n" . Dumper($ret_json) . "\n";
+ warn $@;
+ }
+
+}#end if($todo eq "post_velo"){
+
+
+#velofaktur http POST request
+sub post2velo_cloud {
+ my $self = shift;
+ my $veloserver = shift || "";
+ my $rest_json = shift || "";
+ my $velo_request = "$veloserver";
+
+ print FILE "===> POST2velo >> " . $velo_request . "\n" . $rest_json . "\n";
+
+ my $req = HTTP::Request->new(POST => "$velo_request");
+ $req->content_type('application/json');
+
+ $req->content($rest_json);
+
+ my $res = $ua->request($req);
+ if ($res->is_success) {
+ #print $res->content;
+ return $res->content;
+ print $res->status_line, "\n";
+ }else {
+ print $res->status_line, "\n";
+ }
+}
+
+close(FILE);
+
diff --git a/copri4/main/src/wkhtmltopdf-amd64 b/copri4/main/src/wkhtmltopdf-amd64
new file mode 120000
index 0000000..8f8a92e
--- /dev/null
+++ b/copri4/main/src/wkhtmltopdf-amd64
@@ -0,0 +1 @@
+/usr/bin/wkhtmltopdf
\ No newline at end of file
diff --git a/copri4/main/startup.pl b/copri4/main/startup.pl
new file mode 100755
index 0000000..1a6f9c9
--- /dev/null
+++ b/copri4/main/startup.pl
@@ -0,0 +1,2 @@
+use lib qw(/var/www/copri4/main/src);
+1;
diff --git a/copri4/mkaccess.sh b/copri4/mkaccess.sh
new file mode 100755
index 0000000..e349c0a
--- /dev/null
+++ b/copri4/mkaccess.sh
@@ -0,0 +1,93 @@
+#!/bin/bash
+
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+
+chgrp -R www-data *
+chmod go-w *
+chmod -R o-rwx *
+for i in $(find . -type d -and -name csv); do chmod -R ug+rwx $i;done
+for i in $(find . -type d -and -name data); do chmod -R ug+rwx $i;done
+for i in $(find . -type d -and -name ftp); do chmod -R ug+rwx $i;done
+for i in $(find . -type d -and -name cache); do chmod -R ug+rwx $i;done
+for i in $(find . -type d -and -name pdf); do chmod -R ug+rwx $i;done
+for i in $(find . -type d -and -name xml); do chmod -R ug+rwx $i;done
+for i in $(find . -type d -and -name site); do chmod -R ug+rwx $i;done
+for i in $(find . -type d -and -name apk); do chmod -R ug+rwx $i;done
+
+for i in $(find . -type d -and -name sql); do chmod -R go-rwx $i;done
+for i in $(find . -type d -and -name src); do chmod -R go-w $i;done
+for i in $(find . -type d -and -name img); do chmod -R go-w $i;done
+for i in $(find . -type d -and -name apache); do chmod -R go-w $i;done
+for i in $(find . -type d -and -name css); do chmod -R go-w $i;done
+for i in $(find . -type d -and -name js); do chmod -R go-w $i;done
+for i in $(find . -type f -and -iname README*); do chmod -R go-rwx $i;done
+for i in $(find . -type d -and -name docs); do chmod -R go-rwx $i;done
+for i in $(find . -type f -and -name .htaccess); do chmod -R go-wx $i;done
+for i in $(find . -type f -and -name startup.pl); do chmod -R go-w $i;done
+for i in $(find . -type f -and -name robots.txt); do chmod -R go-wx $i;done
+for i in $(find . -type d -and -name cronjobs); do chmod -R g-w $i/*;done
+for i in $(find . -type d -and -name cronjobs); do chmod -R o+r $i/*;done
+for i in $(find . -type d -and -name cronjobs); do chown -R root:root $i/*;done
+
+
+
+live_sharee="ginger" #sharee-primary and sharee-fr01 on ginger.copri.eu
+
+echo "You are on Server with hostname: $(hostname)";
+echo "";
+
+#sharee
+echo "KEEP in mind, SHAREE autoLinking is only done if $(hostname) == ${live_sharee}";
+echo "Checking payone links because of LIVE";
+if [[ $(hostname) == ${live_sharee} ]]
+then
+
+ #shareedms-operator
+ echo "";
+ for i in $(find . -type l -and -name shareedms-operator.conf); do rm $i;done
+ for i in $(find . -type f -and -name shareedms-operator_live.conf)
+ do (
+ echo $(dirname $(realpath $i));
+ cd $(dirname $(realpath $i));
+ ln -s $(basename $i) shareedms-operator.conf;
+ ls -al
+ )
+ done
+
+ #shareeapp-operator
+ echo "";
+ for i in $(find . -type l -and -name shareeapp-operator.conf); do rm $i;done
+ for i in $(find . -type f -and -name shareeapp-operator_live.conf)
+ do (
+ echo $(dirname $(realpath $i));
+ cd $(dirname $(realpath $i));
+ ln -s $(basename $i) shareeapp-operator.conf;
+ ls -al
+ )
+ done
+
+
+ #shareeweb-project
+ echo "";
+ for i in $(find . -type l -and -name shareeweb-project.conf); do rm $i;done
+ for i in $(find . -type f -and -name shareeweb-project_live.conf)
+ do (
+ echo $(dirname $(realpath $i));
+ cd $(dirname $(realpath $i));
+ ln -s $(basename $i) shareeweb-project.conf;
+ ls -al
+ )
+ done
+
+ #shareeconf/global.cfg
+ #sharee's
+ echo "";
+ for i in $(find . -type l -and -name global.cfg); do rm $i;done
+ ln -s /etc/shareeconf/global_live.cfg global.cfg;
+ ls -al
+
+fi
+
+
diff --git a/copri4/shareeapp-operator/apache/shareeapp-operator.conf b/copri4/shareeapp-operator/apache/shareeapp-operator.conf
new file mode 100644
index 0000000..db26787
--- /dev/null
+++ b/copri4/shareeapp-operator/apache/shareeapp-operator.conf
@@ -0,0 +1,112 @@
+
+ ServerName shareeapp-operator.copri-bike.de
+ ServerAlias shareeapp-operator1.copri-bike.de
+
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareeapp-operator
+
+ ErrorLog /var/log/apache2/shareeapp-operator-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareeapp-operator-access.log combined
+ ServerSignature Off
+ RewriteEngine on
+ RewriteCond %{SERVER_NAME} =shareeapp-operator.copri-bike.de
+ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
+
+
+
+
+ ServerName shareeapp-operator1.copri-bike.de
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareeapp-operator
+ AddHandler cgi-script .cgi .sh .pl
+
+
+ Options -Indexes +FollowSymLinks +ExecCGI
+ AllowOverride None
+
+
+
+ Header set Access-Control-Allow-Origin "copri-bike.de"
+
+
+
+ Options -Indexes +FollowSymLinks -ExecCGI
+ Order allow,deny
+ Allow from all
+
+
+
+ Options -Indexes +FollowSymLinks
+ Order allow,deny
+ Allow from all
+ ForceType application/octet-stream
+ Header set Content-Disposition attachment
+
+
+ ErrorLog /var/log/apache2/shareeapp-operator-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareeapp-operator-access.log combined
+ ServerSignature Off
+Include /etc/letsencrypt/options-ssl-apache.conf
+
+SSLCertificateFile /etc/letsencrypt/live/copri-bike.de-0003/fullchain.pem
+SSLCertificateKeyFile /etc/letsencrypt/live/copri-bike.de-0003/privkey.pem
+
+
+
+
+ ServerName shareeapp-operator.copri-bike.de
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareeapp-operator
+
+ PerlOptions +Parent
+ PerlRequire /var/www/copri4/shareeapp-operator/startup.pl
+
+
+ SetHandler perl-script
+ PerlResponseHandler Mod::Indexsharee
+ PerlInitHandler Apache2::Reload
+ PerlOptions +ParseHeaders +GlobalRequest
+ Options -ExecCGI +FollowSymLinks
+ Order allow,deny
+ Allow from all
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::APIvelo
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::APIjsonserver
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::FileOut
+
+
+
+ RewriteEngine On
+ RedirectMatch ^/$ /app/Anmelden
+ SSLProxyEngine On
+ RewriteCond %{REQUEST_URI} ^/(site|img|data|css|js|jquery)
+ RewriteRule ^(.*)$ https://shareeapp-operator1.copri-bike.de/$1 [P,L]
+
+
+ ErrorLog /var/log/apache2/shareeapp-operator-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareeapp-operator-access.log combined
+ ServerSignature Off
+Include /etc/letsencrypt/options-ssl-apache.conf
+SSLCertificateFile /etc/letsencrypt/live/copri-bike.de-0003/fullchain.pem
+SSLCertificateKeyFile /etc/letsencrypt/live/copri-bike.de-0003/privkey.pem
+
+
+
+
diff --git a/copri4/shareeapp-operator/css/bootstrap-icons-1.5.0 b/copri4/shareeapp-operator/css/bootstrap-icons-1.5.0
new file mode 120000
index 0000000..fc8bde9
--- /dev/null
+++ b/copri4/shareeapp-operator/css/bootstrap-icons-1.5.0
@@ -0,0 +1 @@
+../../main/css/bootstrap-icons-1.5.0
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/css/local_style1344.css b/copri4/shareeapp-operator/css/local_style1344.css
new file mode 100755
index 0000000..778cb38
--- /dev/null
+++ b/copri4/shareeapp-operator/css/local_style1344.css
@@ -0,0 +1,699 @@
+
+
+
diff --git a/copri4/shareeapp-operator/csv b/copri4/shareeapp-operator/csv
new file mode 120000
index 0000000..47f3d7b
--- /dev/null
+++ b/copri4/shareeapp-operator/csv
@@ -0,0 +1 @@
+../shareedms-operator/csv
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/glyphicons b/copri4/shareeapp-operator/glyphicons
new file mode 120000
index 0000000..7393fbd
--- /dev/null
+++ b/copri4/shareeapp-operator/glyphicons
@@ -0,0 +1 @@
+../main/glyphicons
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/img b/copri4/shareeapp-operator/img
new file mode 120000
index 0000000..39564ce
--- /dev/null
+++ b/copri4/shareeapp-operator/img
@@ -0,0 +1 @@
+../main/img
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/js b/copri4/shareeapp-operator/js
new file mode 120000
index 0000000..6b66a30
--- /dev/null
+++ b/copri4/shareeapp-operator/js
@@ -0,0 +1 @@
+../main/js
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/pdfinvoice b/copri4/shareeapp-operator/pdfinvoice
new file mode 120000
index 0000000..0d3af23
--- /dev/null
+++ b/copri4/shareeapp-operator/pdfinvoice
@@ -0,0 +1 @@
+../shareedms-operator/pdfinvoice
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/robots.txt b/copri4/shareeapp-operator/robots.txt
new file mode 100755
index 0000000..1f53798
--- /dev/null
+++ b/copri4/shareeapp-operator/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/copri4/shareeapp-operator/site b/copri4/shareeapp-operator/site
new file mode 120000
index 0000000..c8d8403
--- /dev/null
+++ b/copri4/shareeapp-operator/site
@@ -0,0 +1 @@
+../shareedms-operator/site
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/src/Lib/Config.pm b/copri4/shareeapp-operator/src/Lib/Config.pm
new file mode 100644
index 0000000..969dc5d
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Lib/Config.pm
@@ -0,0 +1,77 @@
+package Config;
+
+#Deprecated config file
+#Please use shareeconf/*
+
+use strict;
+use warnings;
+use CGI;
+use Config::General;
+my $q = new CGI;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+
+sub envonline(){
+ my $self = shift;
+
+ my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
+ my $conf = Config::General->new($globalconf_file);
+ my %globalconf = $conf->getall;
+
+ my $basedir = "$globalconf{copri_conf}->{basedir}/$globalconf{operator}{sharee_operator}->{dir_app}";
+ my $metahost = $globalconf{operator}{sharee_operator}->{operatorApp1};
+ my %varenv = (
+ dbname => $globalconf{operator}{sharee_operator}{database}->{dbname},
+ dbuser => $globalconf{operator}{sharee_operator}{database}->{user},
+ dbpassw => $globalconf{operator}{sharee_operator}{database}->{passwd},
+ dbhost => $globalconf{operator}{sharee_operator}{database}->{host},
+ syshost => $globalconf{operator}{sharee_operator}->{dir_app},
+ wwwhost => $globalconf{operator}{sharee_operator}->{operatorApp},
+ praefix => $globalconf{operator}{sharee_operator}{database}->{dbname},
+ systype => "sharee",#(azn)
+ mandant => $globalconf{shareeapp_conf}->{parent_node},
+ start => $globalconf{shareeapp_conf}->{start},
+ profile => $globalconf{shareeapp_conf}->{profile},
+ accounting_1 => $globalconf{shareeapp_conf}->{accounting_1},
+ accounting_1_5 => $globalconf{shareeapp_conf}->{accounting_1_5},
+ accounting_2 => $globalconf{shareeapp_conf}->{accounting_2},
+ accounting_3 => $globalconf{shareeapp_conf}->{accounting_3},
+
+ superu_id => $globalconf{copri_conf}->{superu_id},
+ debug => $globalconf{copri_conf}->{debug},
+ logdir => $globalconf{copri_conf}->{logdir},
+ live_hostname => $globalconf{primary}{sharee_primary}->{live_hostname},
+ metahost=>"$metahost",
+ orga => "",
+ style_font => "$metahost/img/OfficinaSansITCStd-Book.otf",
+ font_family => "OfficinaSansITCStd-Book,Arial",
+ background_image => "",
+ background_size => "cover",
+ background_color => "white",
+ background_color2 => "#c7c8ca",
+ background_align => "center",
+ background_repeat => "no-repeat",
+ font_size => "100.01%",
+ line_height => "1",
+ basedir => "$basedir",
+ pdf => "$basedir/pdf",
+ pdfinvoice => "$basedir/pdfinvoice",
+ data => "$basedir/data",
+ xmlfile => "$basedir/xml",
+ ftp_getfile => "ftp/SWK_codes/got_last.csv",
+ ftp_putfile => "ftp/SWK_return/konrad_code_protokoll.csv",
+ head_logo => "",
+ barcode => "",
+ printer => "PDF"
+ );
+ return %varenv;
+}
+
+1;
+
diff --git a/copri4/shareeapp-operator/src/Lib/Mlogic.pm b/copri4/shareeapp-operator/src/Lib/Mlogic.pm
new file mode 100644
index 0000000..22373e7
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Lib/Mlogic.pm
@@ -0,0 +1,100 @@
+package Mlogic;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use Mod::DBtank;
+
+use Data::Dumper;
+my $q = new CGI;
+my $dbt = new DBtank;
+
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $self = shift;
+ my ($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return) = @_;
+
+ my $session="";
+ my $session_and="";
+ if($R::sessionid && length($R::sessionid) > 20 && !$q->cookie(-name=>'domcookie')){
+ $session = "?sessionid=$R::sessionid";
+ $session_and = "&sessionid=$R::sessionid";
+ }
+ my $bgcolor1 = $dbt->{primary}->{$varenv->{dbname}}->{bgcolor1};
+
+ if($users_sharee->{c_id} && $R::sharee_edit ne "delete_account2" && ($users_sharee->{c_id} eq $varenv->{superu_id} || $dbt->{copri_conf}->{stage} eq "test")){
+ my $coo = $q->cookie('domcookie') || $q->param('sessionid') || "";
+ print $q->div({-style=>'text-align:right;height:25px;padding:6px 15px 6px 0px;background-color:white'},$q->a({-style=>"color:#$bgcolor1;", -href=>"$varenv->{metahost}/src/scripts/tests/index.pl?sessionid=$coo", -target=>'_blank'}," [ booking-test ] "),"$users_sharee->{txt08}",$q->a({-style=>"color:#$bgcolor1;", -href=>"logout_sharee$session"},"logout")),"\n";
+ }
+
+ print "\n";
+ print "
\n";
+ $self->tplselect($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ print "
\n";
+ print "
\n";
+ #print "\n";
+
+}
+
+#2021-05-05 changed to Mlogic
+sub tplselect(){
+ my $self = shift;
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $u_id = $users_dms->{u_id} || "";
+ my $sort = "";
+ my $lang = "de";
+ my $tpl_id = $node_meta->{tpl_id};
+
+ if($node_meta->{main_id}){
+ if($tpl_id == 2){
+ require "Tpl/Anmelden.pm";
+ &Anmelden::tpl($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+
+ }elsif($tpl_id == 302 || $tpl_id == 302008 || $tpl_id == 302004){#Adresse
+ require "Tpl/FormEdit.pm";
+ &FormEdit::tpl($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ }elsif($tpl_id == 308){
+ require "Tpl/PayoneSelect.pm";
+ &PayoneSelect::tpl($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ }elsif($tpl_id == 197){
+ require "Tpl/Contact.pm";
+ &Contact::tpl($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ }elsif($tpl_id == 1 || $tpl_id == 3){
+ require "Tpl/Listing.pm";
+ &Listing::tpl($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+
+ #require "Tpl/ModalboxDialog.pm";
+ #&ModalboxDialog::mobox2($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+
+ }
+ }
+ my $debug = "Mlogic --> (users_sharee->{c_id}: $users_sharee->{c_id} | ct_table: $node_meta->{ct_table} | parent_id: $node_meta->{parent_id} | main_id: $node_meta->{main_id} | tpl_id: $node_meta->{tpl_id} | u_id: $u_id | mode: $mode)";
+ print $q->div({-style=>'position:fixed;bottom:0%;right:2%;z-index:10;font-size:13px;'},"$debug"),"\n" if($users_sharee->{c_id} eq $varenv->{superu_id});
+
+ if($return && $return =~ /failure/){
+ require "Mod/Failure.pm";
+ &Failure::tpl("",$u_id,"","","","",$return);
+ }
+}
+
+1;
+
+
diff --git a/copri4/shareeapp-operator/src/Lib/PDFGenerator.pm b/copri4/shareeapp-operator/src/Lib/PDFGenerator.pm
new file mode 120000
index 0000000..1bebb95
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Lib/PDFGenerator.pm
@@ -0,0 +1 @@
+../../../main/src/Lib/PDFGenerator.pm
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/src/Lib/Printpreview.pm b/copri4/shareeapp-operator/src/Lib/Printpreview.pm
new file mode 120000
index 0000000..5485ff7
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Lib/Printpreview.pm
@@ -0,0 +1 @@
+../../../main/src/Lib/Printpreview.pm
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/src/Mod b/copri4/shareeapp-operator/src/Mod
new file mode 120000
index 0000000..d4b7ba5
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Mod
@@ -0,0 +1 @@
+../../main/src/Mod
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/src/Tpl/AccountSubmenu.pm b/copri4/shareeapp-operator/src/Tpl/AccountSubmenu.pm
new file mode 100644
index 0000000..3a0f04c
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/AccountSubmenu.pm
@@ -0,0 +1,165 @@
+package AccountSubmenu;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $self = shift;
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $but = new Buttons;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+
+ my $lang = "de";
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+
+ my $session="";
+ if($R::sessionid && length($R::sessionid) > 20){
+ $session = "?sessionid=$R::sessionid";
+ }
+
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+
+ #my $coo = $q->cookie(-name=>'domcookie') || $R::sessionid || "";
+ my $coo = $R::authcookie || $R::sessionid || "";
+ #my $merchant_id = "";
+ #$merchant_id = $coo if($coo && length($coo) <= 10);
+ #$merchant_id = $1 if($coo =~ /_(\w+)$/);
+
+ my $bgcolor1 = "009899";#sharee
+ #my $bgcolor1 = "e2001a";
+
+ $bgcolor1 = $dbt->{website}->{$varenv->{syshost}}->{bgcolor1} if($dbt->{website}->{$varenv->{syshost}}->{bgcolor1});
+
+ #$bgcolor1 = $dbt->{merchant_ids}->{$merchant_id}->{bgcolor1} if($merchant_id && $dbt->{merchant_ids}->{$merchant_id}->{bgcolor1});
+ $bgcolor1 = $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1} if($dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1});
+
+ #payable check
+ my $payable_check=0;
+ if(($users_sharee->{int03} == 1 && $users_sharee->{ct_name} =~ /\w{2}-\d+/) || ($users_sharee->{int03} == 2 && length($users_sharee->{ct_name}) >= 19)){
+ $payable_check=1;
+ }
+ my $node1 = $db->collect_node($node_meta->{parent_id},$lang,"1");
+
+ #if(!$R::confirm_success){
+ if(1==1){
+
+ #subMenue--------
+ print "\n";
+
+ #print "\n";
+ print "
\n";
+ foreach my $id1 (sort {$node1->{$a}->{n_sort} <=> $node1->{$b}->{n_sort}} keys (%$node1)){
+ #Creditcard test switch for payone (tinkwwp)
+ if($users_sharee->{c_id} && ($path =~ /$varenv->{mandant}\/$varenv->{profile}/ || $path =~ /$varenv->{mandant}\/Account/)){
+ my $mstyle_1="";
+ my $mstyle_1_5="";
+ my $mstyle_2="";
+ my $mstyle_3="";
+
+ if($node_meta->{main_id} == $node1->{$id1}->{main_id}){
+ $mstyle_1 .= "background-color: silver;" if("$node1->{$id1}->{node_name}" eq "$varenv->{accounting_1}");
+ $mstyle_1_5 .= "background-color: silver;" if("$node1->{$id1}->{node_name}" eq "$varenv->{accounting_1_5}");
+ $mstyle_2 .= "background-color: silver;" if("$node1->{$id1}->{node_name}" eq "$varenv->{accounting_2}");
+ $mstyle_3 .= "background-color: silver;" if("$node1->{$id1}->{node_name}" eq "$varenv->{accounting_3}");
+
+ #Konrad & TINK & sharee AGB
+ if(!$users_sharee->{int14} && !$users_sharee->{int15} && !$users_sharee->{txt30}){
+ print $q->li($q->a({-style=>"$mstyle_1",-title=>"$node1->{$id1}->{node_name}", -href=>"/$viewsel[0]/Account/$node1->{$id1}->{node_name}$session"}, "$node1->{$id1}->{node_name}")),"\n";
+ }
+ elsif(!$users_sharee->{int03}){
+ print $q->li($q->a({-style=>"$mstyle_1",-title=>"$varenv->{accounting_1}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_1}$session"}, $q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-265-vcard.png"}))),"\n";
+ print $q->li($q->a({-style=>"$mstyle_1_5",-title=>"$varenv->{accounting_1_5}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_1_5}$session"}, $q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-268-credit-card.png"}))),"\n";
+ }
+ #elsif($payable_check && $users_sharee->{int04}){
+ elsif($payable_check){
+ print $q->li($q->a({-style=>"$mstyle_1",-title=>"$varenv->{accounting_1}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_1}$session"}, $q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-265-vcard.png"}))),"\n";
+ print $q->li($q->a({-style=>"$mstyle_1_5",-title=>"$varenv->{accounting_1_5}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_1_5}$session"}, $q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-268-credit-card.png"}))),"\n";
+ print $q->li($q->a({-style=>"$mstyle_2",-title=>"$varenv->{accounting_2}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_2}$session"},$q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-326-wallet.png"}))),"\n";
+ print $q->li($q->a({-style=>"$mstyle_3",-title=>"$varenv->{accounting_3}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_3}$session"},$q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-530-list-alt.png"}))),"\n";
+ }
+ else{
+ print $q->li($q->a({-style=>"$mstyle_1",-title=>"$varenv->{accounting_1}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_1}$session"}, $q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-265-vcard.png"}))),"\n";
+ print $q->li($q->a({-style=>"$mstyle_1_5",-title=>"$varenv->{accounting_1_5}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_1_5}$session"}, $q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-268-credit-card.png"}))),"\n";
+ print $q->li($q->a({-style=>"$mstyle_2",-title=>"$varenv->{accounting_2}", -href=>"/$viewsel[0]/Account/$varenv->{accounting_2}$session"}, $q->img({-src=>"$varenv->{metahost}/glyphicons/glyphicons-326-wallet.png"}))),"\n";
+ }
+
+ }
+ }
+
+ }
+ print " \n";
+ #print "
\n";
+ #-----------------
+ }
+ print $q->div({-style=>'position:fixed;bottom:4%;right:2%;z-index:10;font-size:13px;'},"--> $varenv->{syshost} | $varenv->{merchant_id} | $bgcolor1 | template -> $node_meta->{tpl_name} | $users_sharee->{c_id}"),"\n" if($users_sharee->{c_id} eq $dbt->{copri_conf}->{superu_id} || $dbt->{copri_conf}->{stage} eq "test");
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/Anmelden.pm b/copri4/shareeapp-operator/src/Tpl/Anmelden.pm
new file mode 100644
index 0000000..80bb362
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/Anmelden.pm
@@ -0,0 +1,164 @@
+package Anmelden;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Mod::APIfunc;
+use Mod::Pricing;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+ my $but = new Buttons;
+ my $pri = new Pricing;
+
+ my $script = $q->script_name();
+ my $user_agent = $q->user_agent();
+
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ my $clientIP = $q->remote_addr();
+
+ #with meta_host,
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my %ib = $but->ibuttons_arch();
+ my $tpl = $db->get_tpl($node_meta->{tpl_id});
+ my @tpl_order = split /,/,$tpl->{tpl_order};
+ my $coo = $q->cookie(-name=>'domcookie') || "";
+
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+ my $bgcolor1 = "009899";#sharee
+ #my $bgcolor1 = "e2001a";
+
+ $bgcolor1 = $dbt->{website}->{$varenv->{syshost}}->{bgcolor1} if($dbt->{website}->{$varenv->{syshost}}->{bgcolor1});
+ $bgcolor1 = $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1} if($dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1});
+
+ print "\n";
+
+ if($viewsel[1] eq "Account"){
+ if($R::sharee_edit =~ /delete_account/){
+ my $dummy;
+ }elsif($R::sharee_edit =~ /password_forgotten/){
+ print $q->div({-class=>'content2'}, "Es wurde eine Nachricht mit zurueckgesetzten Passwort an
$R::email gesendet. Ersetzen Sie bitte das gesendete Passwort durch ein individuelles. Das neue Passwort muss min. 8 Zeichen mit 2 Zeichen ausserhalb des Alphabets beinhalten."),"\n";
+ }
+ }
+
+ print $q->start_multipart_form(-id=>'authform', -name=>'loginscreen'),"\n";
+ print $q->hidden(-name=>"sessionid",-override=>1,-value=>"$R::sessionid") if($R::sessionid);
+ print $q->hidden(-name=>"clientIP",-override=>1,-value=>"$clientIP");
+
+ print "
\n";
+
+ if($users_sharee->{c_id} && !$users_sharee->{int04} && $R::sharee_edit !~ /delete_account/){
+ print $q->div({-class=>'content1',-style=>'padding-top:1em;'}, "E-Mail Bestätigung"),"\n";
+ print $q->div({-class=>'content2'}, "Wir haben eine Nachricht an Ihre angegebene E-Mail Adresse versandt. Nach erfolgreicher Bestätigung können Sie unser Mietradsystem nutzen."),"\n";
+ print $q->div({-class=>'content2'},$q->a({-href=>"$varenv->{wwwhost}?sharee_edit=send_email"},"Senden wiederholen")),"\n";
+
+ #Account löschen
+ }elsif($viewsel[1] eq "Account" && $R::sharee_edit =~ /delete_account/){
+ if($R::sharee_edit eq "delete_account1" && $users_sharee->{c_id}){
+ #
+ my ($ctpos,$operator_hash) = $apif->user_rentals_history($q,$users_sharee);
+ my $ctpos_count = 0;
+ my $sum = 0;
+ foreach my $id (keys(%$ctpos)){
+ $ctpos_count++;
+ my $gesamt = 0;
+ my $rabatt = "";
+ ($gesamt,$rabatt) = $pri->price2calc($ctpos->{$id});
+ $sum += $gesamt;
+ }
+ $sum = $lb->round($sum);
+ if($ctpos_count > 0 && $sum > 0){
+ print $q->div({-class=>'content2'}, "Ihr Konto ist nicht ausgeglichen ($sum). Bitte kontaktieren Sie uns damit wir Ihre Rechnungstellung beschleunigen. Anschließend können Sie Ihren Account löschen. Danke für Ihr Verständnis"),"\n";
+ print $q->div({-style=>'margin-top:1em;'},$q->a({-class=>"btn btn-primary btn-lg btn-block",-href=>'javascript:history.back()'}, "zurück")),"\n";
+ }else{
+ print $q->div({-class=>'content2'}, "Wollen Sie wirklich Ihre Daten löschen?"),"\n";
+ print $q->div({-style=>'margin-top:1em;'},"
Ja "),"\n";
+ }
+ }elsif($R::sharee_edit eq "delete_account2" && $users_sharee->{c_id}){
+ my $rows = 0;
+ $rows = $dbt->update_operatorsloop($varenv->{dbname},$users_sharee->{c_id},"delete");#only operator
+ $rows += $dbt->delete_content("","contentadr",$users_sharee->{c_id});#final delete on primary
+ if($rows >= 1){
+ print $q->div({-class=>'content2'}, "Ihr Zugang wurde gelöscht.
Auf Wiedersehen."),"\n";
+ }else{
+ print $q->div({-class=>'content2'}, "Anscheinend ist hier etwas schief gelaufen.
Bitte kontaktieren Sie uns damit wir das Problem lösen können."),"\n";
+ }
+ }
+ #Passwort senden
+ }elsif($viewsel[1] eq "Account" && !$R::password_forgotten){
+ print $q->div({-class=>'content2'}, "Wir benötigen dazu Ihre registrierte E-Mail Adresse."),"\n";
+ print $q->label({-for=>'Email'},""),"\n";
+ print $q->textfield(-class=>'form-control', -name=>'email', -value=>'', -override=>1, -type=>'email',-class=>'form-control', -id=>'Email', -placeholder=>'E-Mail Adresse', -required=>1, -autofocus=>1),"\n";
+
+ print $q->hidden(-name=>'password_forgotten',-value=>"1");
+ print $q->div({-style=>'margin-top:1em;'},"
Passwort E-Mail senden "),"\n";
+
+ #Login
+ }elsif(!$R::password_forgotten){
+ if($R::conflict_failure){
+ print $q->div({-class=>'content2',-style=>'color:#c83434'},"Registrierungsfehler!"),"\n";
+ print $q->div({-class=>'content2'}, "Die Registrierung wurde abgebrochen weil bereits ein Account mit Ihrer e-Mail oder Telefonnr. existiert. Bitte kontaktieren Sie uns falls hier ein Missbrauch vorliegt. Falls Sie ein neues Passwort benötigen drücken Sie bitte:"),"\n";
+ print $q->div({-style=>'margin-top:1em;'},$q->a({-class=>"", -style=>"color:#$bgcolor1;font-size:1.1em;text-decoration:underline;", -role=>"button", -href=>"$varenv->{wwwhost}/$varenv->{mandant}/Account"}, "Passwort vergessen?")),"\n";
+ }
+ print $q->div({-class=>'content2'}, "Dein Zugang zum Lastenradmietsystem"),"\n";
+ print $q->div({-style=>'color:#c83434'},"Login verweigert. ",$q->a({-class=>"", -style=>"color:gray;", -role=>"button", -href=>"$varenv->{wwwhost}/$varenv->{mandant}/Account"}, "Passwort vergessen?")),"\n" if($R::failure);
+ print $q->div({-style=>'color:#c83434'},"Login verweigert. "),"\n" if($R::basicauthfailure);
+ print $q->label({-for=>'Email'},""),"\n";
+ print $q->textfield(-class=>'form-control', -name=>'user_id', -value=>'', -override=>1, -type=>'email',-class=>'form-control', -id=>'Email', -placeholder=>'E-Mail Adresse', -required=>1, -autofocus=>1),"\n";
+
+ print $q->label({-for=>'PW'},""),"\n";
+ print $q->password_field(-class=>'form-control', -name=>'user_pw', -value=>'', -override=>1, -type=>'password',-class=>'form-control', -id=>'txt04', -placeholder=>'Passwort', -required=>1),"\n";
+ print $q->div({-style=>'text-align:left;color:grey;'}, "
", "Passwort anzeigen"),"\n";
+
+
+ #js auth
+ # print $q->div({-style=>'margin-top:1em;'},"
Anmelden
"),"\n";
+ print $q->div({-style=>'margin-top:1em;'},"
Anmelden "),"\n";
+
+ print $q->div({-style=>'margin-top:1em;'},$q->a({-class=>"btn btn-default btn-lg btn-block", -style=>"color:#$bgcolor1;", -role=>"button", -href=>"$varenv->{wwwhost}/$varenv->{mandant}/Account/$varenv->{accounting_1}"}, "Registrieren")),"\n";
+ print $q->div({-class=>'content2'}, "Zur Information! Falls Sie bereits einen \"konrad\" oder \"TINK\" Account besitzen, können Sie mit Ihren bestehendem Account die Nutzung beider Mietradsysteme einstellen! Einfach dazu die entsprechende AGB bestätigen."),"\n" if($varenv->{wwwhost} =~ /tink|konrad/);
+
+ print $q->div({-style=>'margin-top:1em;'},$q->a({-class=>"", -style=>"color:#$bgcolor1;font-size:1.1em;text-decoration:underline;", -role=>"button", -href=>"$varenv->{wwwhost}/$varenv->{mandant}/Account"}, "Passwort vergessen?")),"\n";
+
+ }
+ print "
\n";
+
+ print $q->end_form,"\n";
+
+ print $q->div({-style=>'position:fixed;bottom:2%;right:2%;z-index:10;font-size:13px;'},"--> $varenv->{syshost} | $varenv->{merchant_id} | $bgcolor1 | $node_meta->{tpl_name} | $users_sharee->{c_id}"),"\n" if($users_sharee->{c_id} eq $dbt->{copri_conf}->{superu_id} || $dbt->{copri_conf}->{stage} eq "test");
+
+ print "
";
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/Contact.pm b/copri4/shareeapp-operator/src/Tpl/Contact.pm
new file mode 100644
index 0000000..648e23a
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/Contact.pm
@@ -0,0 +1,123 @@
+package Contact;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Encode;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $but = new Buttons;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+
+ my $lang = "de";
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if($varenv->{metahost}){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $user_agent = $q->user_agent();
+ my %ib = $but->ibuttons_arch();
+ my @tpl_order = split /,/,$node_meta->{tpl_order};
+ my $main_ids = $node_meta->{main_id};
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+
+ my $session="";
+ my $session_and="";
+ if(length($R::sessionid) > 20){
+ $session = "?sessionid=$R::sessionid";
+ $session_and = "&sessionid=$R::sessionid";
+ }
+
+ my $project = "all";
+ $project = "Bayern" if($varenv->{syshost} eq "shareeweb-bayern");
+ $project = "Konstanz" if($varenv->{syshost} eq "shareeweb-konstanz");
+
+ my $sort_updown = "up";
+ my $content2 = "content2_contact";
+ my $content_img = "pic-contact";
+ my $record_cc = { c_id => 0 };
+ my $pref_cc = {
+ table => "contentuser",
+ fetch => "one",
+ template_id => "197",
+ c_id => 1,
+ };
+
+
+ print "\n";
+ print $q->div({-class=>"$content2"},"Bei Fragen und Problemen bitte den örtlichen Betreiber kontaktieren"),"\n";
+
+ #BIG LOOP content table
+ #while (my ($mandant_conf, $value) = each %{ $dbt->{operator} }) {
+ foreach my $m_id (sort { $dbt->{operator}->{$b}->{oprefix} cmp $dbt->{operator}->{$a}->{oprefix} } keys(%{ $dbt->{operator} })) {
+ if($dbt->{operator}->{$m_id}->{project} eq $project || $project eq "all"){
+ print $q->div({-class=>"$content2"}," "),"\n";
+
+ my $sharee_operator = $dbt->{operator}->{$m_id}->{database}->{dbname};
+ my $dbh_operator = $dbt->dbconnect_extern($sharee_operator);
+ $record_cc = $dbt->fetch_record($dbh_operator,$pref_cc);
+ #print Dumper($node_meta->{tpl_order}) . "
\n";
+
+ foreach (@tpl_order){
+ my ($key,$des,$size) = split /=/,$_;
+ $record_cc->{$key} = $q->unescapeHTML("$record_cc->{$key}");
+ $record_cc->{$key} = $lb->newline($record_cc->{$key},"","");
+
+ if($key =~ /ct_name/){
+ print $q->div({-id=>"$record_cc->{c_id}",-class=>'content_title2'},"• $record_cc->{$key}"),"\n";
+ }elsif($key =~ /txt|int/ && $record_cc->{$key} && $key !~ /txt85/){
+ #phone tag
+ if($record_cc->{$key} =~ /\d+$/ && $des =~ /hotline|Telefon|phone/i){
+ $record_cc->{$key} =~ s/([\s0-9-\/]+)/\
$1\<\/a\>/;
+ }
+ #email tag with little coding against grabber
+ if($record_cc->{$key} =~ /(\w+\@[\w-]+\.\w+)/){
+ $record_cc->{$key} =~ s/(\w+\@[\w-]+\.\w+)/\ $1\<\/a\>/;
+ $record_cc->{$key} =~ s/\@/\&\#64\;/g;
+ }
+ $record_cc->{$key} =~ s/\\//g;
+ if($des =~ /hotline|e-Mail|zeiten/i){
+ print $q->div({-class=>"$content2"}, "$des: $record_cc->{$key}"),"\n";
+ print $q->div({-class=>"$content2"}," "),"\n" if($des =~ /e-Mail/i);
+ }else{
+ print $q->div({-class=>"$content2"}, "$record_cc->{$key}"),"\n";
+ }
+
+ }
+ }
+ }#end if
+ }
+ print " \n";
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/FormEdit.pm b/copri4/shareeapp-operator/src/Tpl/FormEdit.pm
new file mode 100644
index 0000000..450d848
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/FormEdit.pm
@@ -0,0 +1,633 @@
+package FormEdit;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use DateTime;
+use DateTime::Format::Pg;
+
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Mod::APIfunc;
+use Mod::Pricing;
+use Tpl::AccountSubmenu;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+ my $pri = new Pricing;
+ my $but = new Buttons;
+ my $submenu = new AccountSubmenu;
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $dbh = "";#$dbt->dbconnect();
+ my $user_agent = $q->user_agent();
+ my %ib = $but->ibuttons_arch();
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+ my $red = "red";
+
+ my $coo = $q->cookie(-name=>'domcookie') || $R::sessionid;
+ my $session="";
+ my $session_and="";
+ if($R::sessionid && length($R::sessionid) > 20 && !$q->cookie(-name=>'domcookie')){
+ $session = "?sessionid=$R::sessionid";
+ $session_and = "&sessionid=$R::sessionid";
+ }
+
+ my $bgcolor1 = "009899";#sharee
+ #my $bgcolor1 = "e2001a";
+
+ $bgcolor1 = $dbt->{website}->{$varenv->{syshost}}->{bgcolor1} if($dbt->{website}->{$varenv->{syshost}}->{bgcolor1});
+ $bgcolor1 = $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1} if($dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1});
+
+
+ my $ctrel = {};
+ $ctrel = $users_sharee if(ref($users_sharee) eq "HASH" && $users_sharee->{c_id});
+ #
+ #collect rentals on operators and get operator hash with dbname->uri_operator
+ #$q->param(-name=>'month',-value=>"18");#disabled because changing to not invoiced positions
+ my ($ctpos,$operator_hash) = $apif->user_rentals_history($q,$ctrel);
+ #print Dumper($ctpos);
+
+ my $ctpos_count=0;
+ foreach my $id (keys(%$ctpos)){
+ $ctpos_count++;
+ }
+
+ my $ctt_all = {};
+ #$ctt = $db->collect_content2("contenttrans","int10",$ctrel->{c_id}) if($ctrel->{c_id});
+ #
+ #loop operator hash to get invoices for each operator
+ foreach my $sharee_operator (keys (%$operator_hash)){
+ my $dbh_operator = $dbt->dbconnect_extern("$sharee_operator");
+ my $pref = {
+ table => "contenttrans",
+ fetch => "all",
+ int10 => "$ctrel->{c_id}",
+ keyfield => "c_id",
+ };
+
+ if($ctrel->{c_id}){
+ my $ctt = $dbt->fetch_tablerecord($dbh_operator,$pref);
+ foreach my $id (keys(%$ctt)){
+ $ctt->{$id}->{wwwhost} = "$operator_hash->{$sharee_operator}";
+ $ctt->{$id}->{praefix} = "$sharee_operator";
+ #print "$ctt->{$id}->{praefix}|";
+ }
+ $ctt_all = { %$ctt_all, %$ctt };
+ }
+ }
+
+ my $tpl_id = $node_meta->{tpl_id};
+ #$tpl_id = "302004" if($viewsel[1] =~ /Mieten/ && $ctrel->{c_id});
+ my $tpl = $db->get_tpl($tpl_id);
+ my $tpl01 = $tpl;#If nothing else, because of tpl_name Title in split_lates
+ my $tpl02 = "";
+ my @split_lates = ("$tpl->{tpl_order}");
+ my $template01 = "$tpl_id" . "001";
+ my $template02 = "$tpl_id" . "002";
+ if($tpl_id < 999){
+ $tpl01 = $db->get_tpl($template01);
+ $tpl02 = $db->get_tpl($template02);
+ @split_lates = ("$tpl01->{tpl_order}","$tpl02->{tpl_order}");
+ }
+ my $now_dt = strftime "%Y-%m-%d %H:%M", localtime;
+ my $start_date = strftime "%d.%m.%Y %H:%M", localtime;
+
+ my ($end_date,$end_time) = split(/ /,$now_dt);
+ my ($e_yy,$e_mo,$e_dd) = split(/-/,$end_date);
+ my ($e_hh,$e_mi) = split(/\:/,$end_time);
+
+ my $radID = $R::radID || "";
+
+ my $tink_agb_text;
+ $tink_agb_text = $db->get_content("2351","");
+ $tink_agb_text->{txt01} = $q->unescapeHTML($tink_agb_text->{txt01});
+ $tink_agb_text->{txt01} = $lb->newline($tink_agb_text->{txt01},"","0");
+
+ my $konrad_agb_text;
+ $konrad_agb_text = $db->get_content("3446","");
+ $konrad_agb_text->{txt01} = $q->unescapeHTML($konrad_agb_text->{txt01});
+ $konrad_agb_text->{txt01} = $lb->newline($konrad_agb_text->{txt01},"","0");
+
+ #TODO get and edit sharee AGB from Tarif content
+ my $sharee_agb_text;
+ $sharee_agb_text->{ct_name} = "AGB";
+ $sharee_agb_text->{txt01} = "";
+
+
+ print "\n";
+
+print <
+
+
+
+
+
+
$sharee_agb_text->{ct_name} $sharee_agb_text->{txt01}
+
+
+
+
+
+
+EOF
+;
+
+ my $debug=0;
+ $debug=1 if($users_sharee->{c_id} eq $dbt->{copri_conf}->{superu_id} || $dbt->{copri_conf}->{stage} eq "test");
+ my $debug_message = "";
+
+ my $payable_check=0;
+ if(($ctrel->{int03} == 1 && $ctrel->{ct_name} =~ /\w{2}-\d+/) || ($ctrel->{int03} == 2 && length($ctrel->{ct_name}) >= 19)){
+ $payable_check=1;
+ }
+
+ #subMenue--------
+ $submenu->tpl($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ #-----------------
+
+ my $catch_failure=0;
+ if(($R::failure && $R::failure =~ /\w+/) || ($ctrel->{txt31} && $ctrel->{txt31} =~ /\w/)){
+ $debug_message = "($R::failure || $ctrel->{txt31})" if($debug);
+ $catch_failure=1;
+ print $q->div({-class=>'content2', -style=>"clear:both;color:$red"}, "* Es liegt noch mindestens ein Fehler vor. $debug_message"),"\n";
+ }
+
+ #confirm code manage
+ if($catch_failure && (!$ctrel->{int04} && !$ctrel->{int13}) && ($tpl_id =~ /^2$|302004/) && ($path =~ /$varenv->{accounting_3}/)){
+ $debug_message = "$catch_failure && (!$ctrel->{int04} || !$ctrel->{int13}) && $tpl_id" if($debug);
+ print $q->div({-class=>'content2'}, "Erst nachdem Ihre Profildaten vollständig sind erhalten Sie die Bestätigung. $debug_message"),"\n";
+ }elsif((!$ctrel->{int04} || !$ctrel->{int13}) && ($tpl_id =~ /^2$|302004/) && ($path =~ /$varenv->{accounting_3}/)){
+ if(1==1){
+ $debug_message = "(!$ctrel->{int04} || !$ctrel->{int13}) && $tpl_id" if($debug);
+ print $q->div({-class=>'content_title3',-style=>'clear:both;'}, "Fasst geschafft $debug_message"),"\n";
+ print $q->div({-class=>'content2'}, "Es wurden Bestätigungs-Codes an Ihre e-Mail Adresse und per SMS an Ihre Telefonnr. versandt. Nach erfolgreicher Bestätigung können Sie unsere Mieträder nutzen. Bitte beachten Sie die Anweisungen."),"\n";
+ #}else{
+ #print $q->div({-class=>'content1',-style=>'padding-top:1em;clear:both;'}, "E-Mail Bestätigung"),"\n";
+ #print $q->div({-class=>'content2'}, "Wir haben einen Bestätigungscode an Ihre angegebene e-Mail Adresse versandt. Nach erfolgreicher Bestätigung können Sie sich einloggen und ein Leihrad mieten. Bitte beachten Sie die Anweisungen."),"\n";
+ }
+ print $q->start_form(-name=>'accountscreen', -action=>"/$varenv->{mandant}/Account/$varenv->{accounting_3}$session"),"\n";
+ print $q->hidden(-name=>"sessionid",-override=>1,-value=>"$R::sessionid");
+ my $required = "";
+ if(!$ctrel->{int04}){
+ my $des = "E-Mail Bestätigungscode";
+ my $key = "confirm_code";
+ my $label_des="* $des";
+ $label_des = "Bitte \"$des\" korrigieren " if($R::failure);
+ print $q->label({-for=>"$key", -style=>'padding-top:1em;'},"$label_des"),"\n";
+ print " \n";
+ print $q->div({-class=>'content2'}, "Falls Sie keinen e-Mail Bestätigungs Code erhalten haben, überprüfen Sie bitte Ihre bei der Registrierung angegebene e-Mail Adresse und/oder den Spam Bereich in Ihrem e-Mail Programm. Hier können Sie erneut einen ",$q->a({-style=>"color:#$bgcolor1;",-href=>"$varenv->{wwwhost}?sharee_edit=send_email$session_and"},"e-Mail Code anfordern")),"\n";
+ }else{
+ print $q->div({-class=>'content2', -style=>'color:gray;'}, "* E-Mail Bestätigungs-Code wurde bereits erfolgreich eingegeben."),"\n";
+ }
+ if(!$ctrel->{int13}){
+ my $des = "SMS Bestätigungscode";
+ my $key = "confirm_smscode";
+ my $label_des="* $des";
+ $label_des = "Bitte \"$des\" korrigieren " if($R::failure);
+ print $q->label({-for=>"$key", -style=>'padding-top:1em;'},"$label_des"),"\n";
+ print " \n";
+ print $q->div({-class=>'content2'}, "Falls Sie keinen SMS Bestätigungs Code erhalten haben, überprüfen Sie bitte Ihre bei der Registrierung angegebene mobile Telefonnummer. Hier können Sie erneut einen ",$q->a({-style=>"color:#$bgcolor1;",-href=>"$varenv->{wwwhost}?sharee_edit=send_sms$session_and"},"SMS Code anfordern")),"\n";
+ }else{
+ print $q->div({-class=>'content2', -style=>'color:gray;'}, "* SMS Bestätigungs-Code wurde bereits erfolgreich eingegeben."),"\n";
+ }
+
+ my $button_name = "Weiter";
+ print $q->div({-style=>'margin-top:2em;'},"$button_name "),"\n";
+ print $q->end_form,"\n";
+
+ }else{
+
+ my $postaction = "/$varenv->{mandant}/Account/$varenv->{accounting_2}";
+ if($ctrel->{c_id} && $path =~ /$varenv->{accounting_2}|$varenv->{accounting_3}|$varenv->{profile}/){
+ $postaction = "/$varenv->{mandant}/Account/$varenv->{accounting_3}";
+ }elsif($path =~ /$varenv->{accounting_1}/){
+ $postaction = "/$varenv->{mandant}/Account/$varenv->{accounting_1_5}";
+ }elsif($ctrel->{c_id} && $path =~ /$varenv->{accounting_1}/){
+ $postaction = "/$varenv->{mandant}/Account/$varenv->{accounting_2}";
+ }
+
+ print $q->start_form(-name=>'accountscreen', -action=>"$postaction$session"),"\n";
+ print $q->hidden(-name=>"sessionid",-override=>1,-value=>"$R::sessionid") if($R::sessionid);
+
+
+ print "\n";
+
+ my $i=0;
+ my @tpl_order;
+ foreach(@split_lates){
+ $i++;
+ if($i==1){
+ if($R::confirm_success){
+ print $q->div({-class=>'content_title3'},"Anmeldung bestätigt"),"\n";
+ }else{
+ print $q->div({-class=>'content_title3'},"$tpl01->{tpl_name}"),"\n";
+ }
+
+ if($path =~ /$varenv->{accounting_1}/){
+ print $q->div({-class=>'content2'}, "Damit Sie jederzeit und einfach ein Leihrad mieten können benötigen wir Anschrift und Zahlungsdaten."),"\n";
+ }
+ if($path =~ /$varenv->{accounting_2}/){
+ if($tpl_id == 302008){
+ print $q->div({-class=>'content2'}, "Wähle die Zahlungsart."),"\n";
+ }else{#old SEPA only style
+ print $q->div({-class=>'content2'}, "Durch das SEPA Mandat können wir die Leihrad Buchungen bequem einziehen."),"\n";
+ }
+ }
+
+ }
+ if($i==2){
+ print $q->div({-class=>'content_title3'},"$tpl02->{tpl_name}"),"\n";
+ print $q->div({-class=>'content2'}, "Das Login besteht aus Ihrer e-Mail Adresse und einem mindestens 8 stelligen Passwort."),"\n";
+
+ }
+ @tpl_order = split /,/,$_;
+ my $scol = "itime";
+ foreach (@tpl_order){
+ my ($key,$des,$size) = split /=/,$_;
+ $ctrel->{$key} = $q->unescapeHTML("$ctrel->{$key}");
+ $ctrel->{$key} = $lb->newline($ctrel->{$key},"","1");
+
+ #radID & timeCode from contenttranspos----------------
+ if($ctrel->{int03} && $path =~ /$varenv->{accounting_3}|$varenv->{profile}/){
+ if(1==1){
+ if($key =~ /ct_name/){
+ if($ctrel->{int12}){
+ print $q->div({-class=>'content2', -style=>'color:#c83434;'}, "Herzlich Willkommen. Wir mussten Ihren Zugang zu den Mieträdern sperren weil ein Problem mit Ihren Zahlungsdaten vorliegt. Bitte aktualisieren Sie Ihre Zahlungsdaten und kontaktieren Sie uns damit wir den Vorfall klären können."),"\n";
+ }else{
+ print $q->div({-class=>'content2'}, "Herzlich Willkommen. Sie können nach erfolgreicher Anmeldung unter dem Menue \"Fahrradstandortkarte\" ein Leihrad mieten."),"\n";
+ }
+ print $q->div({-class=>'content2'}, "Nach der Mietradnutzung haben Sie hier die Möglichkeit die Mietvorgänge einzusehen und gebuchte Rechnungen als PDF herunterzuladen."),"\n";
+ print $q->div({-class=>'content2'}, "Ihre Bonusnummer wurde akzeptiert. Bitte beachten Sie dass der Bonustarif im Kontext des Mietradbetreibers vergeben wird. Der Tarif wird bei der Mietrad Reservierung angezeigt."),"\n" if($R::success && $R::success eq "txt15");
+ print $q->div({-class=>'content2'}, "Aktuell liegen keine Buchungen vor."),"\n" if(!$ctpos_count);
+
+ }elsif($key =~ /barcode/ && $ctpos_count){
+
+ #print $q->div({-style=>'padding-top:1.5em;font-weight:bold;'},"Ihre Buchungsdaten der letzten 1 ½ Jahre im Überblick"),"\n";
+ print $q->div({-style=>'padding-top:1.5em;font-weight:bold;'},"Folgende Positionen liegen zur nächsten Abbuchung vor"),"\n";
+
+ my @tpl_posorder = ("txt01=Beschreibung","int04=Station","ct_name=(Rad) Nummer","int26=CO2","int02=Betrag");
+
+ my $j=0;
+ my $nx=0;
+ my $sum = 0;
+ print "
\n";
+ print $q->start_table({-style=>'margin:15px 0;', -border=>'0', -width=>'auto',-align=>'left', -cellpadding=>'3', -cellspacing=>'0'}),"\n";
+ print $q->Tr(),"\n";
+
+ foreach my $id (sort { lc($ctpos->{$b}->{$scol}) cmp lc($ctpos->{$a}->{$scol}) } keys(%$ctpos)){
+ $j++;
+ $nx++;
+
+ print $q->Tr(),"\n";
+ foreach (@tpl_posorder){
+ my ($key,$val) = split /=/,$_;
+
+ my $occupied_style = "background-color:#fcfdfb;";
+ $occupied_style = "background-color:#f4f1ee;" if($nx %= 2);
+ #$occupied_style = "color:#ff1493;" if($ctpos->{$id}->{txt10} =~ /occupied|requested/);
+ $occupied_style = "color:#ff1493;" if($ctpos->{$id}->{int10} == 2 || $ctpos->{$id}->{int10} == 3);
+
+ if($key eq "txt01"){
+ #print $q->td({-class=>'tdtxt', -style=>"$occupied_style"},"$ctpos->{$id}->{$key}");
+ print "
\n";
+ if($ctpos->{$id}->{txt01}){
+ $ctpos->{$id}->{$key} =~ s/\ /; /g;
+ print "$ctpos->{$id}->{$key} \n";
+ }
+ if($ctpos->{$id}->{start_time}){
+ $ctpos->{$id}->{start_time} = $lb->time4de($ctpos->{$id}->{start_time},"1");
+ $ctpos->{$id}->{end_time} = $lb->time4de($ctpos->{$id}->{end_time},"1");
+ print $q->span("→ $ctpos->{$id}->{start_time} ← $ctpos->{$id}->{end_time}");
+ }
+ print " \n";
+ }elsif($key =~ /int04/){
+ if($ctpos->{$id}->{int09}){#if Tarifnr then bike
+ #print $q->td({-class=>'tdint', -style=>"$occupied_style"},"Station $ctpos->{$id}->{$key}");
+ print "\n";
+ print $q->span("Station → $ctpos->{$id}->{txt12}$ctpos->{$id}->{int06} ← $ctpos->{$id}->{txt13}$ctpos->{$id}->{int04}");
+ print " \n";
+ }else{
+ print $q->td({-class=>'tdint', -style=>"$occupied_style"},"$ctpos->{$id}->{$key}");
+ }
+ }elsif($key =~ /ct_name/){
+ if($ctpos->{$id}->{int09}){#if Tarifnr then bike
+ print $q->td({-class=>'tdint', -style=>"$occupied_style"},"Rad $ctpos->{$id}->{$key}");
+ }else{
+ print $q->td({-class=>'tdint', -style=>"$occupied_style"},"$ctpos->{$id}->{$key}");
+ }
+ }elsif($key eq "int26"){
+ my $co2saving = "";
+ if($ctpos->{$id}->{int26}){
+ $co2saving = "Einsparung";
+ my $co2diff = $pri->co2calc($ctpos->{$id});
+ my $sprit_price = $pri->sprit2calc($ctpos->{$id});
+ $co2saving .= "$co2diff kg CO² ";
+ $co2saving .= "$sprit_price EUR ";
+ $ctpos->{$id}->{int26} =~ s/\./,/;
+ $co2saving .= "bei $ctpos->{$id}->{int26} KM";
+ }
+ print $q->td({-class=>'tdint', -style=>"$occupied_style", -nowrap=>1},"$co2saving");
+ }elsif($key eq "int02"){
+ my $gesamt = 0;
+ my $rabatt = "";
+ ($gesamt,$rabatt) = $pri->price2calc($ctpos->{$id});
+ $sum += $gesamt;
+ $gesamt = $lb->round($gesamt);
+ $gesamt = $lb->cashme($gesamt,",");
+ print $q->td({-class=>'tdint', -style=>"$occupied_style", -nowrap=>1},"$rabatt $gesamt €");
+ }
+ }
+ }
+ if($j==0){
+ print $q->Tr(),"\n";
+ print $q->td({-class=>'tdint'},"Keine Daten vorhanden");
+ }else{
+ $sum = $lb->round($sum);
+ $sum = $lb->cashme($sum,",");
+ print $q->Tr(),"\n";
+ print $q->td({-class=>'tdint', -colspan=>3},"");
+ print $q->td({-class=>'tdint'},"Gesamt");
+ print $q->td({-class=>'tdint'},$q->b("$sum €"));
+ }
+ print $q->end_table;
+ print "\n";
+
+ my $i=0;
+ my $dtext = "";
+ print "
\n";
+ foreach my $id (sort { $ctt_all->{$b}->{ct_name} cmp $ctt_all->{$a}->{ct_name} } keys(%$ctt_all)){
+
+ if($ctt_all->{$id}->{ct_name} =~ /\d/ && $coo){
+ $i++;
+ my $invoice_time = $ctt_all->{$id}->{invoice_time} || $ctt_all->{$id}->{mtime};
+ $invoice_time = $lb->time4de($invoice_time,0);
+ #$varenv->{praefix} only defined in sharee
+ my $webtarget = "_blank";
+ my $dtext = "";
+ if($varenv->{syshost} =~ /app/){
+ $webtarget = "_self";
+ $dtext = "(Der PDF download öffnet je nach System/Konfiguartion einen externen PDF-Viewer oder Webbrowser)";
+ }
+
+ if($i==1){
+ print $q->div({-id=>'Rechnungen',-style=>'font-weight:bold;'},"Ihre Rechnungen"),"\n";
+ print $q->div({-style=>'padding:0.5em;'},"$dtext"),"\n";
+ }
+ print $q->div({-style=>'font-size:1em;padding:0.5em;border:0px solid #cccccc;'},$q->a({-href=>"$ctt_all->{$id}->{wwwhost}/FileOut?file=Rechnung-$ctt_all->{$id}->{praefix}-$ctt_all->{$id}->{ct_name}.pdf&sessionid=$coo", -target=>"$webtarget" , -type=>'application/octet-stream', -style=>'text-decoration:underline;'}, $q->img({-src=>"$varenv->{metahost}/glyphicons/file-any.png", -style=>'width:30px;'}), "Rechnung $ctt_all->{$id}->{ct_name}.pdf"), " ($invoice_time)"),"\n";
+ }
+
+ }
+ print "
\n";
+ }
+ }
+ }
+ #------------------------------------------------------
+
+ my $label_des="* $des";
+ my $autofocus="";
+ if($key =~ /txt15|txt19/){
+ $label_des="$des";
+ }
+
+ #sharee Tarife
+ if(1==2 && $key =~ /txt30/){
+ #FIXME
+ print $q->div({-style=>'padding-top:10px;'}, "aktivierte Tarife: $ctrel->{$key}"),"\n" if($users_sharee->{txt08} =~ /gnu-systems|tux-edv/);
+ if(($R::failure && $R::failure =~ /^$key/) || ($ctrel->{txt31} && $ctrel->{txt31} =~ /$key/)){
+ $autofocus = "autofocus";
+ $label_des = "
Bitte \"$des\" bestätigen ";
+ }
+
+ my ($bike_group,$user_group,$tariff_all,$user_tour) = $apif->fetch_tariff($users_sharee,"");
+ my $required="";
+ my @tariff = ("$ctrel->{$key}");
+ @tariff = split(/\s/,$ctrel->{$key}) if($ctrel->{$key} =~ /\s/);
+ my $record_bonus = {c_id => 0};
+ foreach my $rid (sort { $tariff_all->{$a}->{barcode} <=> $tariff_all->{$b}->{barcode} } keys (%$tariff_all)){
+ print "xxxxxxxxxxxxx $tariff_all->{$rid}->{barcode} | $tariff_all->{$rid}->{int18}\n";
+ }#end foreach tariff_all
+
+ }elsif($key =~ /txt/ && $size eq "select" && $des eq "Land"){
+ my $country = $lb->country_code();
+ $ctrel->{$key} = "DE" if(!$ctrel->{$key});
+ my @_valxx;
+ foreach (sort { $country->{$a} cmp $country->{$b} } keys (%$country)){
+ push @_valxx, "$_:$country->{$_}";
+ }
+ print $q->label({-for=>"$key",-style=>'padding-top:15px;'},"$label_des"),"\n";
+ print $but->selector_class("$key","form-control","","$ctrel->{$key}",@_valxx);
+
+ }elsif($key =~ /txt/ && $size eq "select"){
+ my @_valxx = split(/,/,$varenv->{$des});
+ print $q->label({-for=>"$key",-style=>'padding-top:15px;'},"$label_des"),"\n";
+ print $but->selector_class("$key","form-control","","$ctrel->{$key}",@_valxx);
+
+ }elsif($key =~ /txt/ && !$R::confirm_success){
+ my $required="required";
+
+ #Gutschein
+ if($key =~ /txt16/ && $ctrel->{c_id}){
+ $required="";
+ $label_des = "
$des ";
+ }
+ if($key eq "txt07" && $R::failure && $R::failure =~ /conflict_txt07/){
+ $autofocus = "autofocus";
+ my ($failkey,$failval) = split(/=/,$R::failure);
+ $label_des = "
Achtung, es existiert bereits ein Account mit der Telefon Nr.: $failval ";
+ $ctrel->{$key} = $R::conflict_txt07;
+ }
+ elsif($key eq "txt08" && $R::failure && $R::failure =~ /conflict_txt08/){
+ $autofocus = "autofocus";
+ my ($failkey,$failval) = split(/=/,$R::failure);
+ $label_des = "
Achtung, es existiert bereits ein Account mit der e-Mail Adresse: $failval ";
+ $ctrel->{$key} = $R::conflict_txt08;
+ }
+ #elsif($key eq "txt04" && $R::failure && $R::failure =~ /pwlazy_txt04/){
+ # $autofocus = "autofocus";
+ # $label_des = "
Das Passwort ist zu kurz. ";
+ #}
+
+ elsif($key eq "txt15" && ($R::failure && $R::failure =~ /conflict_txt15/)){
+ $autofocus = "autofocus";
+ $label_des = "
Die Bonusnummer kann pro Registrierung nur einmal verwendet werden. So wird verhindert dass weitere Personen von den 30-Freiminuten widerrechtlich Gebrauch nehmen.
+Weitere Personen aus Ihrem Haushalt profitieren jedoch ebenfalls, falls Sie weitere Produkte (Gas, SeeConnect, Fähre- oder Bus-Zeitkarten) nutzen. Dann könnte sich die zweite Person mit der weiteren Nummer registrieren. ";
+ }
+ elsif($key eq "txt04" && $R::failure && $R::failure =~ /confirm_txt04/){
+ $autofocus = "autofocus";
+ $label_des = "
Die Passwort Wiederholung ist fehlerhaft. Bitte korrigieren Sie Ihre Eingabe. ";
+ }
+ elsif(($R::failure && $R::failure =~ /^$key/) || ($ctrel->{txt31} && $ctrel->{txt31} =~ /$key/)){
+ $autofocus = "autofocus";
+ $label_des = "
Bitte \"$des\" Angabe korrigieren ";
+ $label_des = "
Für das \"$des\" liegt ein Fehler vor. " if($key eq "txt04");
+ $label_des = "
Bitte SMS Telefon Nr. mit Ländercode, Beispiel: +49 170 12345678 " if($key eq "txt07");
+ $label_des = "
Die Bonusnummer ist leider nicht vorhanden. Bei nicht vorhandener Nummer das Feld bitte leer lassen. " if($key =~ /txt15/);
+ }
+ #if($R::success eq $key){
+ # $label_des = "
Das hat geklappt. Der \"$des\" wurde erfolgreich hinzugefügt, s.u.. ";
+ #}
+
+
+ if($key eq "txt04"){
+ my $pw = "xxxxxxxx";
+ $pw = "" if(!$ctrel->{c_id});
+ print $q->label({-for=>"$key", -style=>'padding-top:1.5em;'},"$label_des"),"\n";
+ print "
\n";
+ print $q->label({-for=>"confirm_$key"},"* Passwort wiederholen"),"\n";
+ print "
\n";
+ print $q->div({-style=>'text-align:left;color:grey;'}, "
", "Passwort anzeigen"),"\n" if($pw ne "xxxxxxxx");
+ }else{
+ #all other input textfields
+ $required = "";# if($key =~ /txt09|txt16/);
+ print $q->label({-for=>"$key", -style=>'padding-top:1.5em;'},"$label_des"),"\n";
+ print "
\n";
+ }
+
+ #all int checkboxes disabled because of AGB downunder
+ }elsif($key =~ /int/ && $size eq "checkbox"){
+ if(($R::failure && $R::failure =~ /^$key/) || ($ctrel->{txt31} && $ctrel->{txt31} =~ /$key/)){
+ $autofocus = "autofocus";
+ $label_des = "
Bitte \"$des\" bestätigen ";
+ }
+ my $required="";
+
+ #sharee AGB global new
+ if($key eq "int14" && $size eq "checkbox"){
+ $required="";
+ my $sharee_agb = "
$des \n";
+ print $q->label({-for=>"$key", -style=>'padding-top:20px;'},"$label_des"),"\n";
+ print $q->div({-id=>"$key"},$but->checkbox("1","$key","$ctrel->{$key}","","$required"), " $sharee_agb"),"\n";
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"null");
+ }
+
+ #look also Shareework.pm save_account ret value
+ elsif(1==2 && $key =~ /int15/){#Konrad AGB
+ $required=1 if($varenv->{wwwhost} =~ /konrad/);
+ my $konrad_agb = "
$des \n";
+ print $q->label({-for=>"$key", -style=>'padding-top:20px;'},"$label_des"),"\n";
+ print $q->div({-id=>"$key"},$but->checkbox("3429","$key","$ctrel->{$key}","","$required"), " $konrad_agb"),"\n";
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"0");
+ }elsif(1==2 && $key =~ /int14/){#TINK AGB
+ $required=1 if($varenv->{wwwhost} !~ /konrad/);
+ my $tink_agb = "
$des \n";
+ print $q->label({-for=>"$key", -style=>'padding-top:20px;'},"$label_des"),"\n";
+ print $q->div({-id=>"$key"},$but->checkbox("3428","$key","$ctrel->{$key}","","$required"), " $tink_agb"),"\n";
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"0");
+ }elsif(1==2 && $key =~ /int02/){#newsletter
+ if($varenv->{wwwhost} !~ /konrad/){
+ print $q->label({-for=>"$key", -style=>'padding-top:10px;'},""),"\n";
+ print $q->div({-id=>"$key"},$but->checkbox("1","$key","$ctrel->{$key}","","$required"), " $des"),"\n";
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"0");
+ }
+
+ }else{
+ print $q->label({-for=>"$key", -style=>'padding-top:10px;'},""),"\n";
+ print $q->div({-id=>"$key"},$but->checkbox("1","$key","$ctrel->{$key}","","$required"), " $des"),"\n";
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"0");
+ }
+
+ }elsif($key =~ /int/){
+ if(($R::failure && $R::failure =~ /^$key/) || ($ctrel->{txt31} && $ctrel->{txt31} =~ /$key/)){
+ $autofocus = "autofocus";
+ $label_des = "
Bitte \"$des\" bestätigen ";
+ print $q->label({-for=>"$key", -style=>'padding-top:10px;'},"$label_des"),"\n";
+ }
+
+ if($key =~ /int03/){
+
+ print $q->div({-class=>'content2'}, "
+ Es werden die Kreditkartendaten von VISA und MasterCard akzeptiert.
+ Die Beträge für die Leihvorgänge werden gesammelt und i.d.R. wöchentlich eingezogen. D.h. der Belastungszeitpunkt bei Bankeinzeig oder via Karte findet in den darauffolgenden Tagen statt.
+ Gutschriften werden verrechnet und Ihrem Konto gutgeschrieben.
+ Die Datenübetragung findet per SSL-Verschlüsselung statt.
+ Nach erfolgreicher Anmeldung können Sie unter Ihren Verleihdaten die Leihrad Buchungen und Rechnungen jederzeit einsehen.
+
+ "),"\n";
+
+ my $incasso="1";
+ my $creditcard="2";
+ my $checked_incasso;
+ my $checked_creditcard;
+ $checked_incasso=1 if($ctrel->{$key} == 1 || $ctrel->{$key} == 3);
+ $checked_creditcard=2 if($ctrel->{$key} == 2);
+ print $q->div({ -class=>'radio', -style=>'padding-top:20px;' },$but->radiobox_vertical("$key","$incasso","$checked_incasso",$q->img({-id=>"pic-payment" ,-style=>'height:50px;',-src=>"$varenv->{metahost}/img/payment-incasso2.png"}))),"\n";
+ print $q->div({ -class=>'radio', -style=>'padding-bottom:20px;' },$but->radiobox_vertical("$key","$creditcard","$checked_creditcard",$q->img({-id=>"pic-payment" ,-style=>'height:30px;', -src=>"$varenv->{metahost}/img/payment-creditcard2.png"}))),"\n";
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"null");
+ }
+ }
+
+ if($key eq "txt16" && $ctrel->{c_id} && !$R::confirm_success){
+ print $q->div({-style=>'margin-top:1em;'},"
Speichern "),"\n";
+ }
+
+ }
+ }
+
+ if(($R::failure && $R::failure =~ /\w+/ && $R::failure !~ /txt15|txt16/) || ($ctrel->{txt31} && $ctrel->{txt31} =~ /\w/)){
+ print $q->div({-class=>'content2', -style=>"color:$red"}, "* Eingabefehler.
Bitte überprüfen Sie Ihre Profildaten damit wir das Fahrradmietsystem freischalten können. Es liegt ein Eingabefehler vor."),"\n";
+ }
+
+ if($path !~ /$varenv->{accounting_3}|$varenv->{profile}/){
+ if($ctrel->{c_id}){
+ my $button_name = "Speichern";
+ $button_name = "Weiter" if($path =~ /$varenv->{accounting_1_5}|$varenv->{accounting_2}/);
+ print $q->hidden(-name=>"tinkc_id",-override=>1,-value=>"$ctrel->{c_id}");
+ print $q->div({-style=>'margin-top:1em;'},"
$button_name "),"\n";
+ if($path =~ /$varenv->{accounting_1}/){
+ print $q->div({-style=>'margin-top:2em;text-align:center;'},$q->a({-style=>"color:#$bgcolor1;font-size:1.2em;", -role=>"button", -href=>"/$viewsel[0]/Account?sharee_edit=delete_account1$session_and"}, "Daten löschen?")),"\n";# if($ctrel->{txt08});
+ }
+ }else{
+ print $q->div({-style=>'margin-top:1em;'},"
Weiter "),"\n";
+ }
+ }
+
+
+ }#ende e-Mail iif
+ print "
\n";
+ print $q->end_form,"\n";
+
+ print $q->div({-style=>'position:fixed;bottom:2%;right:2%;z-index:10;font-size:13px;'},"--> $varenv->{syshost} | $varenv->{merchant_id} | $bgcolor1 | template -> $node_meta->{tpl_name},$tpl_id ($template01,$template02) | $users_sharee->{c_id}"),"\n" if($users_sharee->{c_id} eq $dbt->{copri_conf}->{superu_id} || $dbt->{copri_conf}->{stage} eq "test");
+
+ print " ";
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/Karte.pm b/copri4/shareeapp-operator/src/Tpl/Karte.pm
new file mode 100644
index 0000000..670ff8f
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/Karte.pm
@@ -0,0 +1,100 @@
+package Karte;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use CGI ':standard';
+use Lib::Config;
+use Mod::DBtank;
+use Mod::APIfunc;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || { c_id => 0 };
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+
+ my $api_file = "/var/www/copri4/shareeconf/apikeys.cfg";
+ my $aconf = Config::General->new($api_file);
+ my %apikeyconf = $aconf->getall;
+ #print $apikeyconf{googlemap}->{google_key};
+
+ my $initMap = $dbt->{website}->{$varenv->{syshost}}->{initMap};
+ $initMap =~ s/\s//g;
+ my ($lat,$lng) = split(/,/,$initMap);
+
+ my $api_return = { authcookie => '' };
+ my $coo = $q->cookie(-name=>'domcookie') || $R::sessionid;
+ ($api_return,$users_sharee) = $apif->auth_verify($q,$coo,"");
+
+ require "Mod/KMLout.pm";
+ my $kmlfile = Mod::KMLout::kmlGenerator($api_return,$varenv,$users_sharee);
+
+ print "\n";
+
+ print "
\n";
+
+print<
+
+ function initMap() {
+ var map = new google.maps.Map(document.getElementById('map'), {
+ scrollwheel: false,
+ draggable: !("ontouchend" in document),
+ center: {lat: $lat, lng: $lng},
+ zoom: 8
+ });
+
+ var ctaLayer = new google.maps.KmlLayer({
+ position: map.getCenter(),
+ //preserveViewport: true,
+ //url: '$dbt->{primary}->{sharee_primary}->{primaryApp}/KMLout?kml=' + (new Date()).getTime() + '$users_sharee->{c_id}',
+ //url: '$varenv->{metahost}/xml/KMLout-3',
+ //url: '$varenv->{wwwhost}/?kml=' + (new Date()).getTime(),
+ url: '$varenv->{metahost}/xml/$kmlfile',
+ map: map
+ });
+ console.log('$varenv->{metahost}/xml/$kmlfile');
+
+ };
+
+
+
+
+EOF
+;
+
+print " \n";
+
+print $q->div({-class=>"content2_legende", -style=>'font-weight:bold;'}, "• Ist ein Lastenrad an einer Mietradstation verfügbar?"),"\n";
+print $q->div({-class=>"content2_legende"}, $q->img({-style=>'height:30px;', -src=>"$varenv->{metahost}/img/Open_Green.png"}), "Lastenrad verfügbar"),"\n";
+print $q->div({-class=>"content2_legende"}, $q->img({-style=>'height:30px;', -src=>"$varenv->{metahost}/img/Open_Red.png"}), "Lastenrad nicht verfügbar"),"\n";
+
+ #if($R::ask_radID && $R::ask_radID =~ /^\d+$/){
+ # require "Tpl/ModalboxDialog.pm";
+ # &ModalboxDialog::mobox2($tpl_name,$tpl_id,$parent_id,$main_id,$u_id,$u_group,$lang,$users_sharee,$bg_color1,$bg_color2,$R::ask_radID);
+ # }
+ #
+
+}
+1;
+
diff --git a/copri4/shareeapp-operator/src/Tpl/Listing.pm b/copri4/shareeapp-operator/src/Tpl/Listing.pm
new file mode 100644
index 0000000..22fe01b
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/Listing.pm
@@ -0,0 +1,179 @@
+package Listing;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use Encode;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $but = new Buttons;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+
+ my $lang = "de";
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $user_agent = $q->user_agent();
+ my %ib = $but->ibuttons_arch();
+ my @tpl_order = split /,/,$node_meta->{tpl_order};
+ my $main_ids = $node_meta->{main_id};
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+
+ my $session="";
+ my $session_and="";
+ if(length($R::sessionid) > 20){
+ $session = "?sessionid=$R::sessionid";
+ $session_and = "&sessionid=$R::sessionid";
+ }
+
+ my $ct4rel = {};
+ my $scol = "sort";
+ my $sort_updown = "up";
+ if($path =~ /NEWS/){
+ $scol = "date_time01";
+ $sort_updown = "down";
+ #$scol = "date_time01";
+ }
+
+ my $content2 = "content2";
+ my $content_img = "pic-float";
+ $ct4rel = $db->collect_ct4rel2("content",$main_ids,$lang,"","","","","",$users_dms->{u_id});
+
+ print "\n";
+
+ #Content sequential
+ #BIG LOOP content table
+ foreach my $id (sort {
+ if($sort_updown eq "down"){
+ if ($scol =~ /barcode|int|sort/) {
+ $ct4rel->{$b}->{$scol} <=> $ct4rel->{$a}->{$scol}
+ }else{
+ lc($ct4rel->{$b}->{$scol}) cmp lc($ct4rel->{$a}->{$scol})
+ }
+ }else{
+ if ($scol =~ /barcode|int|sort/) {
+ $ct4rel->{$a}->{$scol} <=> $ct4rel->{$b}->{$scol}
+ }else{
+ lc($ct4rel->{$a}->{$scol}) cmp lc($ct4rel->{$b}->{$scol})
+ }
+ }
+ } keys(%$ct4rel)){
+
+ my $j=0;
+ my $date_time;
+ my $uritxt_key;
+
+ foreach (@tpl_order){
+ my ($key,$des,$size) = split /=/,$_;
+ $ct4rel->{$id}->{$key} = $q->unescapeHTML("$ct4rel->{$id}->{$key}");
+ $ct4rel->{$id}->{$key} = $lb->newline($ct4rel->{$id}->{$key},"","");
+
+ my $datamain_id = $ct4rel->{$id}->{main_id};
+ my $dir_main = "$varenv->{data}/$datamain_id/$ct4rel->{$id}->{c_id}";
+ my $dir_thumb = "$varenv->{data}/$datamain_id-thumb/$ct4rel->{$id}->{c_id}";
+ my $dir_resize = "$varenv->{data}/$datamain_id-resize/$ct4rel->{$id}->{c_id}";
+
+
+ if($key =~ /img/ && $ct4rel->{$id}->{rel_id}){
+ #print "
\n";
+ if( -d "$dir_resize"){
+ my @pics = $lb->read_dirfiles($dir_resize,"\.JPG|\.JPEG|\.PNG","file");
+ foreach(@pics){
+ print $q->img({-id=>"$content_img" ,-src=>"$varenv->{metahost}/data/$datamain_id-resize/$ct4rel->{$id}->{c_id}/$_"}),"\n" if($_ =~ /\w/);
+ }
+ }
+ #print "
\n";
+ print $q->div({-style=>'clear:both;'},""),"\n";
+ }elsif($key =~ /pdf/){
+ if( -d "$dir_main"){
+ my @pdfs = $lb->read_dirfiles($dir_main,"\.JPG|\.JPEG|\.PNG","file","not");
+ foreach(@pdfs){
+ #print $q->div({-class=>"$content2"}, $q->a({-href=>"$varenv->{metahost}/data/$datamain_id/$ct4rel->{$id}->{c_id}/$_", -target=>'_blank',-title=>'Download',-type=>'application/octet-stream'}, $q->img({-src=>"$varenv->{metahost}/glyphicons/file-any.png", -style=>'width:50px;'}), "$_")),"\n";
+ print $q->div($q->a({-href=>"$varenv->{wwwhost}/FileOut?file=$datamain_id/$ct4rel->{$id}->{c_id}/$_$session_and", -target=>'_default', -title=>'Download',-type=>'application/octet-stream'}, $q->img({-src=>"$varenv->{metahost}/glyphicons/file-any.png", -style=>'width:50px;'}), "$_")),"\n";
+
+ }
+ }
+
+
+ }elsif($key =~ /date_time/ && $ct4rel->{$id}->{$key} =~ /\d{4}-\d{2}-\d{2}/){
+ $date_time = $lb->time4de("$ct4rel->{$id}->{$key}","","Date_to_Text_Long");
+ $date_time =~ s/^\w+,\s\w+//;
+ }elsif($key =~ /node_name/){
+ my $ct_users;
+ $ct_users = $db->get_owner($ct4rel->{$id}->{owner}) if($ct4rel->{$id}->{owner});
+ $ct4rel->{$id}->{mtime} = $lb->time4de($ct4rel->{$id}->{mtime},"1") if($ct4rel->{$id}->{mtime});
+ print $q->div({-class=>'content2_group'},"Absender: $ct_users->{u_name} | $ct4rel->{$id}->{mtime}"),"\n";
+ }elsif($key =~ /ct_name/){
+ my $debug;
+ if($users_dms->{u_id}){
+ print $q->div({-class=>'content_title2',-style=>"background-color:silver;padding:0.2em;"},$q->a({-class=>'editnav',-href=>"$path/manager?node2edit=edit_content\&rel_id=$ct4rel->{$id}->{rel_id}", -title=>"edit content"}, "$ct4rel->{$id}->{$key}"),$debug),"\n";
+ print $q->div({-class=>'content_title2'},"$date_time"),"\n" if($date_time);
+ }elsif(!$R::sharee_edit){
+ print $q->div({-class=>'content_title2'},"$date_time"),"\n" if($date_time);
+ print $q->div({-id=>"$ct4rel->{$id}->{c_id}",-class=>'content_title2'},"$ct4rel->{$id}->{$key}"),"\n" if($ct4rel->{$id}->{$key} =~ /[A-Za-z]/);
+ print $q->div({-style=>""},"$debug"),"\n";
+ }
+ }elsif($key =~ /uri(\d+)/ && $ct4rel->{$id}->{$key} =~ /http/){
+ $uritxt_key = "txt" . $1;
+ print $q->div({-class=>'content_direct2',-style=>'font-size:14px;'},$q->a({-href=>"$ct4rel->{$id}->{$key}"},"zum Projekt")),"\n";
+ }elsif($key =~ /txt|int/ && $ct4rel->{$id}->{$key} && "$key" ne "$uritxt_key"){
+ if($key =~ /txt/ && $size =~ /area(\d+)/ && $ct4rel->{$id}->{$key}){
+ #phone tag
+ if($ct4rel->{$id}->{$key} =~ /Telefon|Mobile/){
+ $ct4rel->{$id}->{$key} =~ s/([\s0-9-]+)/\
$1\<\/a\>/;
+ }
+ #email tag with little coding against grabber
+ if($ct4rel->{$id}->{$key} =~ /(\w+\@[\w-]+\.de)/){
+ $ct4rel->{$id}->{$key} =~ s/(\w+\@[\w-]+\.de)/\ $1\<\/a\>/;
+ $ct4rel->{$id}->{$key} =~ s/\@/\&\#64\;/g;
+ #$ct4rel->{$id}->{$key} =~ s/\.de/\&\#46\;de/g;
+ }
+ #Development
+ if($ct4rel->{$id}->{$key} =~ /(www\.GNU-Systems\.de)/){
+ $ct4rel->{$id}->{$key} =~ s/(www\.[\w-]+\.de)/\ $1\<\/a\>/g;
+ }
+ $ct4rel->{$id}->{$key} =~ s/\\//g;
+ print $q->div({-class=>"$content2"}, "$ct4rel->{$id}->{$key}"),"\n";
+ }elsif($ct4rel->{$id}->{$key} && $size !~ /checkbox/){
+ print $q->div({-class=>"$content2"}, "$ct4rel->{$id}->{$key}"),"\n";
+ }
+ }
+ }
+ print $q->div({-class=>"$content2"}," "),"\n";
+ }#end if
+ print " \n";
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/ModalboxDialog.pm b/copri4/shareeapp-operator/src/Tpl/ModalboxDialog.pm
new file mode 100644
index 0000000..8d8e7b9
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/ModalboxDialog.pm
@@ -0,0 +1,262 @@
+package ModalboxDialog;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+
+use CGI::Cookie ();
+use CGI ':standard';
+use DateTime;
+use DateTime::Format::Pg;
+use Lib::Config;
+use Mod::Buttons;
+use Mod::DBtank;
+use Mod::APIfunc;
+use Mod::Libenzdb;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+sub mobox2(){
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+ my $ask_radID = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $dbt = new DBtank;
+ my $apif = new APIfunc;
+
+ my $db = new Libenzdb;
+ my $but = new Buttons;
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $dbh = "";
+ my $bg_color = "white";
+ my $bg_color2 = $varenv->{brand_color} || "";
+
+ my $session="";
+ my $session_and="";
+ if(length($R::sessionid) > 20){
+ $session = "?sessionid=$R::sessionid";
+ $session_and = "&sessionid=$R::sessionid";
+ }
+
+ my $ctadr = $users_sharee if(ref($users_sharee) eq "HASH" && $users_sharee->{c_id});
+
+ my $main_ids;
+ my ($bike_group,$user_group,$tariff_content,$user_tour) = $apif->fetch_tariff($ctadr,"");
+ $main_ids = join(",",@{$bike_group});
+ $main_ids =~ s/[a-z_]+//ig;
+
+ my $title = "";
+ my $ct = {};
+ if($ask_radID){
+ my $pref_cc = {
+ table => "content",
+ fetch => "one",
+ main_id => "IN::($main_ids)",
+ barcode => $ask_radID,
+ int10 => 1,
+ };
+
+ $ct = $dbt->fetch_record($dbh,$pref_cc) if($ask_radID && $main_ids);
+ $title = "Fahrrad Buchungsbestätigung";
+ }
+
+ my $height = "250";
+ my $width = "400";
+
+print<
+ .ui-dialog .ui-dialog-content {
+ background: $bg_color;
+ }
+ .ui-dialog > .ui-widget-header {
+ color:$varenv->{color};
+ font-weight:normal;
+ border:1px solid $bg_color2;
+ background: $bg_color2;
+ }
+ .ui-widget-overlay {
+ background: #666 url("$varenv->{metahost}/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png") 50% 50% repeat;
+ opacity: .5;
+ filter: Alpha(Opacity=50);
+ }
+
+EOF
+;
+
+#int04 != 1 --> no mailACK
+#int13 != 1 --> no telACK
+#int01 != 3 --> no sync
+#int12 == 1 --> Vde
+
+ my $ctadr_int13 = 1;#default to activ
+ if($varenv->{telAck_startdate} && $ctadr->{mtime}){
+ my ($ty,$tm,$td) = split(/-/,$varenv->{telAck_startdate});
+ my $dt1telAck_start = DateTime->new(year => $ty, month => $tm, day => $td);
+ my $dt2mtime = DateTime::Format::Pg->parse_datetime($ctadr->{mtime});
+ #will be only evaluated if mtime never than global conf
+ if($ctadr->{owner} == 197 && $dt2mtime > $dt1telAck_start){
+ $ctadr_int13 = $ctadr->{int13};
+ }
+ }
+if($node_meta->{main_id} && $ctadr->{c_id} && ($ctadr->{int04} != 1 || $ctadr_int13 != 1 || $ctadr->{int12} || $ask_radID)){
+
+
+print<
+ \$(function() {
+ \$( "#dialog-form2" )
+ .css("background-color","$bg_color")
+ .dialog({
+ height: $height,
+ width: $width,
+ closeOnEscape: false,
+ modal: true
+ });
+ \$('.ui-widget-overlay').click(function() {
+ \$(".ui-dialog-titlebar-close").trigger('click');});
+
+ \$( "#btn_no1" ).click(function() {
+ \$( "#dialog-form2" ).dialog( "close" );
+ });
+ \$( "#btn_no2" ).click(function() {
+ \$( "#dialog-form2" ).dialog( "close" );
+ });
+
+ \$( "#btn_yes" ).click(function() {
+ window.location.href = '$varenv->{wwwhost}?radID=$ask_radID$session_and';
+ });
+
+ });
+
+EOF
+;
+
+ print "";
+
+
+ print $q->start_form(-name=>'modaldialog');
+ print $q->hidden(-name=>"sessionid",-override=>1,-value=>"$R::sessionid");
+
+ print "
\n";
+
+ if($ctadr->{int04} != 1 || $ctadr_int13 != 1){
+ my $required = "required";
+ if($ctadr->{int04} != 1){
+ my $des = "E-Mail Bestätigungscode";
+ my $key = "confirm_code";
+ my $label_des="* $des";
+ print $q->label({-for=>"$key", -style=>'padding-top:1em;'},"$label_des"),"\n";
+ print " \n";
+ }else{
+ print $q->div({-class=>'content2', -style=>'color:gray;'}, "* E-Mail Bestätigungscode wurde bereits erfolgreich eingegeben."),"\n";
+ }
+ if($ctadr_int13 != 1 && $varenv->{telAck_startdate}){
+ my $des = "SMS Bestätigungscode";
+ my $key = "confirm_smscode";
+ my $label_des="* $des";
+ print $q->label({-for=>"$key", -style=>'padding-top:1em;'},"$label_des"),"\n";
+ print " \n";
+ }elsif($varenv->{telAck_startdate}){
+ print $q->div({-class=>'content2', -style=>'color:gray;'}, "* SMS Bestätigungscode wurde bereits erfolgreich eingegeben."),"\n";
+ }
+ my $button_name = "Weiter";
+ print $q->div({-style=>'margin-top:1em;'},"$button_name "),"\n";
+
+ }elsif($ctadr->{int04} && $R::confirm_code){
+
+ my $des = "Danke! Die Bestätigung war erfolgreich.";
+ my $key = "nothing";
+ my $label_des="$des";
+ print $q->label({-for=>"$key", -style=>'padding-top:2.5em;'},"$label_des"),"\n";
+ print $q->div({-style=>'margin-top:2em;text-align:center;'},"Schließen "),"\n";
+
+
+ }elsif($ctadr->{int12} || $ctadr->{int01} != 3 || !$ct->{c_id}){
+ my $des = "Leider ist das Fahrradmietsystem für Ihren Account nicht freigeschaltet. Bitte überprüfen Sie Ihre Profildaten auf Vollständigkeit.";
+ $des = "Leider ist das Fahrradmietsystem für Ihren Account nicht freigeschaltet. Bitte kontaktieren Sie uns damit wir das Problem lösen und Ihren Account wieder freischalten können.." if($ctadr->{int12} == 2);
+ my $key = "nothing";
+ my $label_des="$des";
+ print $q->label({-for=>"$key", -style=>'padding-top:2.5em;'},"$label_des"),"\n";
+ print $q->div({-style=>'margin-top:2em;text-align:center;'},"Schließen "),"\n";
+
+
+
+ }elsif($ask_radID){
+
+ my $des = "Fahrrad Nr. $R::ask_radID kostenlos für 15 Min. reservieren?";
+ my $key = "radID";
+ my $label_des="$des";
+ print $q->label({-for=>"$key", -style=>'padding-top:2.5em;'},"$label_des"),"\n";
+ #print " \n";
+ #print $q->hidden(-name=>"$key",-override=>1,-value=>"$ask_radID");
+ print $q->div({-style=>'margin-top:2em;text-align:center;'},"Nein ","Ja "),"\n";
+
+ }
+
+ print "
\n";
+
+ print $q->end_form,"\n";
+ print "
\n";
+
+ }elsif($ask_radID){
+#If no Login
+print<
+ \$(function() {
+ \$( "#dialog-form2" )
+ .css("background-color","$bg_color")
+ .dialog({
+ height: $height,
+ width: $width,
+ closeOnEscape: false,
+ modal: true
+ });
+ \$('.ui-widget-overlay').click(function() {
+ \$(".ui-dialog-titlebar-close").trigger('click');});
+
+ \$( "#btn_no3" ).click(function() {
+ \$( "#dialog-form2" ).dialog( "close" );
+ });
+ \$( "#btn_anmelden" ).click(function() {
+ window.location.href = '$varenv->{wwwhost}/$varenv->{mandant}/Anmelden';
+ });
+
+ });
+
+EOF
+;
+ print "\n";
+
+ }
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/PayoneCCclient.pm b/copri4/shareeapp-operator/src/Tpl/PayoneCCclient.pm
new file mode 100644
index 0000000..69b3bd8
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/PayoneCCclient.pm
@@ -0,0 +1,266 @@
+package PayoneCCclient;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use CGI ':standard';
+use Config::General;
+use Mod::DBtank;
+
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $self = shift;
+ my $tpl_id = shift;
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $dbt = new DBtank;
+
+ my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
+ my $conf = Config::General->new($globalconf_file);
+ my %globalconf = $conf->getall;
+ my $payone_conf = $globalconf{payone_conf};
+
+ my $bgcolor1 = "009899";#sharee
+ #my $bgcolor1 = "e2001a";
+
+ $bgcolor1 = $dbt->{website}->{$varenv->{syshost}}->{bgcolor1} if($dbt->{website}->{$varenv->{syshost}}->{bgcolor1});
+ $bgcolor1 = $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1} if($dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1});
+
+ print "\n";
+
+
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/PayoneSEPA.pm b/copri4/shareeapp-operator/src/Tpl/PayoneSEPA.pm
new file mode 100644
index 0000000..351a8f1
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/PayoneSEPA.pm
@@ -0,0 +1,166 @@
+package PayoneSEPA;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Shareework;
+use Mod::DBtank;
+use Sys::Hostname;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $self = shift;
+ my $tpl_id = shift;
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $tk = new Shareework;
+ my $dbt = new DBtank;
+ my $but = new Buttons;
+ my $hostname = hostname;
+
+ $q->import_names('R');
+ my @keywords = $q->param;
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $now_dt = strftime "%Y-%m-%d %H:%M", localtime;
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+
+ my $coo = $q->cookie(-name=>'domcookie') || $R::sessionid;
+ my $ctadr = $users_sharee if(ref($users_sharee) eq "HASH" && $users_sharee->{c_id});
+
+ my $tpl = $dbt->get_tpl($tpl_id);
+ my @tpl_order = split /,/,$tpl->{tpl_order};
+
+ print $q->start_form(),"\n";
+ print $q->hidden(-name=>"sessionid",-override=>1,-value=>"$R::sessionid");
+ print $q->hidden(-name=>"tinkc_id",-override=>1,-value=>"$ctadr->{c_id}");
+ print $q->hidden(-name=>"request",-override=>1,-value=>"managemandate");
+
+ #Standard parameter
+ #foreach (keys (%$base_request)){
+ # print $q->hidden(-name=>"$_",-value=>"$base_request->{$_}"),"\n";
+ #}
+
+ print "\n";
+
+ print $q->div({-class=>'content_title3'},"Kontoverbindung"),"\n";
+ print $q->div({-class=>'content2'}, "Durch das SEPA Mandat können wir die Leihrad Buchungen bequem einziehen."),"\n";
+ #print $q->div({-class=>'content2'}, "Zur Validierung Ihrer Zahlungsdaten wird eine 1,- € Testbuchung vorgenommen. Wir werden nach erfolgreicher Abbuchung den Betrag als Mietgutschrift in Ihrem Account hinterlegen."),"\n";
+
+
+ foreach (@tpl_order){
+ my ($key,$des,$size) = split /=/,$_;
+ $ctadr->{$key} = $q->unescapeHTML("$ctadr->{$key}");
+
+ my $label_des="";
+ my $red = "#c83434";
+ my $required="required";
+ if($key eq "txt22"){
+ if($R::IBAN){
+ $label_des = "IBAN Fehler ";
+ $ctadr->{$key} = $R::IBAN;
+ }
+ if($R::failure eq $key){
+ $label_des = "Bitte \"$des\" Angabe korrigieren ";
+ }
+ print $q->label({-for=>"$key", -style=>'padding-top:1.5em;'},"$label_des"),"\n";
+ print " \n";
+
+ }elsif($key eq "txt23"){
+ print $q->label({-for=>"$key", -style=>'padding-top:1.5em;'},"$label_des"),"\n";
+ print " \n";
+
+ #------------------------
+ }elsif($key =~ /int03/ && $size eq "checkbox"){
+
+ if($ctadr->{$key} != 1){
+
+ my $int03 = "";
+ $int03 = $ctadr->{$key} if($ctadr->{$key} == 1);
+ print $q->div({-style=>'margin:10px 0;'},"Damit wir die SEPA-Lastschrift von Ihrem Konto einziehen können, benötigen wir von Ihnen ein SEPA-Lastschriftmandat. Das Mandat wird bei uns als PDF zu Ihren Zahldaten hinterlegt. Sie können nach der Anmeldung das Mandat als PDF herunterladen"),"\n";
+
+ if($ctadr->{txt27} !~ /active|pending/ && $R::failure eq $key){
+ $label_des = "Bitte \"$des\" bestätigen ";
+ print $q->label({-for=>"$key", -style=>'padding-top:10px;'},"$label_des"),"\n";
+ }
+
+ my $des = "Ich möchte das Mandat erteilen (elektronische Übermittlung)";
+ print $q->div({-id=>"$key"},$but->checkbox("1","$key","$int03","","$required"), " $des"),"\n";
+ #print $q->hidden(-name=>"$key",-override=>1,-value=>"3");
+
+ }else{
+
+ if($ctadr->{txt28} =~ /SEPA-Lastschriftmandat/){
+ print $q->div({-class=>'content2'}, ""),"\n";
+ $ctadr->{txt28} = $q->unescapeHTML("$ctadr->{txt28}");
+ use URI::Encode qw(uri_encode uri_decode);
+ $ctadr->{txt28} = uri_decode($ctadr->{txt28});
+ $ctadr->{txt28} =~ s/\+/ /g;
+ print $q->div({-style=>'padding:10px;margin:10px 0;border:1px solid silver;'},$ctadr->{txt28}),"\n";
+ }
+
+ #if payone fails/error
+ if($ctadr->{txt27} =~ /active|pending/){
+ #print $q->div({-style=>'padding:10px;margin:10px 0;border:1px solid silver;'}, "Das Mandat ist aktiviert"),"\n";
+ if($ctadr->{ct_name} && ($ctadr->{ct_name} =~ /PO-/ || $ctadr->{ct_name} =~ /TM-/) && $coo){
+ #print $q->div({-style=>'padding:10px;margin:10px 0;'}, "Download:", $q->a({-href=>"/PDFinvoice?session=$coo\&sepa=$ctadr->{ct_name}", -target=>'_blank'}, "SEPA-Lastschriftmandat.pdf")),"\n" if($coo);
+ #$varenv->{praefix} only defined in sharee
+ my $webtarget = "_blank";
+ my $dtext = "";
+ if($varenv->{syshost} =~ /app/){
+ $webtarget = "_self";
+ $dtext = " (Der PDF download öffnet je nach System/Konfiguartion einen externen PDF-Viewer oder Webbrowser)";
+ }
+ print $q->div({-style=>'padding:10px;margin:10px 0;'},$q->a({-href=>"$varenv->{wwwhost}/FileOut?file=SEPA-Lastschriftmandat-$varenv->{praefix}-$ctadr->{ct_name}.pdf", -target=>"$webtarget" , -type=>'application/octet-stream', -style=>'text-decoration:underline;font-size:1.1em;'}, $q->img({-src=>"$varenv->{metahost}/glyphicons/file-any.png", -style=>'width:30px;'}), "SEPA-Lastschriftmandat.pdf"),"$dtext"),"\n";
+ }else{
+ print $q->div({-style=>'padding:10px;margin:10px 0;border:1px solid silver;color:#c83434;'},"Es gibt ein Problem! Das SEPA Mandat konnte nicht eingeholt werden. Bitte wenden Sie sich bei Bedarf an den unter \"Kontakt\" hinterlegten Support."),"\n";
+ }
+ }elsif($ctadr->{txt22}){ #if IBAN but no mandat_status
+ print $q->div({-style=>'padding:10px;margin:10px 0;border:1px solid silver;color:#c83434;'}, "Fehler. Das Mandat ist nicht aktiv. "),"\n";
+
+ $ctadr->{txt28} = $q->unescapeHTML("$ctadr->{txt28}");
+ $ctadr->{txt28} = $lb->newline($ctadr->{txt28},"","0");
+
+ #print $q->div({-style=>'padding:10px;margin:10px 0;border:1px solid silver;color:#c83434;'}, "Fehlermeldung: $ctadr->{txt28}"),"\n" if($ctadr->{txt28} !~ /SEPA-Lastschriftmandat/);
+ }
+ print $q->hidden(-name=>"$key",-override=>1,-value=>"1");
+ }
+ }
+ #--------------------
+ }
+
+ print $q->div({-style=>'margin-top:1em;'},"Weiter "),"\n";
+
+
+ print "
\n";
+ print $q->end_form,"\n";
+}
+1;
diff --git a/copri4/shareeapp-operator/src/Tpl/PayoneSelect.pm b/copri4/shareeapp-operator/src/Tpl/PayoneSelect.pm
new file mode 100644
index 0000000..23da31f
--- /dev/null
+++ b/copri4/shareeapp-operator/src/Tpl/PayoneSelect.pm
@@ -0,0 +1,81 @@
+package PayoneSelect;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+use strict;
+use warnings;
+use POSIX;
+use CGI ':standard';
+use Lib::Config;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Tpl::AccountSubmenu;
+use Tpl::PayoneSEPA;
+use Tpl::PayoneCCclient;
+
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $node_meta = shift;
+ my $users_dms = shift || "";
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $users_sharee = shift || "";
+ my $return = shift || "";
+
+ my $q = new CGI;
+ my $cf = new Config;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $but = new Buttons;
+ my $submenu = new AccountSubmenu;
+ my $paySEPA = new PayoneSEPA;
+ my $payCC = new PayoneCCclient;
+
+ $q->import_names('R');
+ my @keywords = $q->param;
+
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ #with meta_host,
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $time = time;
+ my $now_dt = strftime "%Y-%m-%d %H:%M", localtime;
+
+ my %ib = $but->ibuttons_arch();
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+
+ my $ctrel = $users_sharee if(ref($users_sharee) eq "HASH" && $users_sharee->{c_id});
+ my $ctt = $db->collect_content2("contenttrans","int10",$ctrel->{c_id});
+ my $tpl = $db->get_tpl($node_meta->{tpl_id});
+
+ print "\n";
+
+ #subMenue--------
+ $submenu->tpl($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ #-----------------
+
+ #Selected Payment
+ if($ctrel->{int03} == 1 || $ctrel->{int03} == 3){
+ $paySEPA->tpl("309",$node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ }elsif($ctrel->{int03} == 2){
+ $payCC->tpl("310",$node_meta,$users_dms,$mode,$varenv,$users_sharee,$return);
+ }
+
+ print "
\n";
+
+}
+1;
diff --git a/copri4/shareeapp-operator/src/scripts b/copri4/shareeapp-operator/src/scripts
new file mode 120000
index 0000000..8705f56
--- /dev/null
+++ b/copri4/shareeapp-operator/src/scripts
@@ -0,0 +1 @@
+../../main/src/scripts
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/src/wkhtmltopdf-amd64 b/copri4/shareeapp-operator/src/wkhtmltopdf-amd64
new file mode 120000
index 0000000..2e6c34b
--- /dev/null
+++ b/copri4/shareeapp-operator/src/wkhtmltopdf-amd64
@@ -0,0 +1 @@
+../../main/src/wkhtmltopdf-amd64
\ No newline at end of file
diff --git a/copri4/shareeapp-operator/startup.pl b/copri4/shareeapp-operator/startup.pl
new file mode 100755
index 0000000..ed145fe
--- /dev/null
+++ b/copri4/shareeapp-operator/startup.pl
@@ -0,0 +1,2 @@
+use lib qw(/var/www/copri4/shareeapp-operator/src);
+1;
diff --git a/copri4/shareeapp-operator/xml b/copri4/shareeapp-operator/xml
new file mode 120000
index 0000000..ac9e2f3
--- /dev/null
+++ b/copri4/shareeapp-operator/xml
@@ -0,0 +1 @@
+../shareedms-operator/xml
\ No newline at end of file
diff --git a/copri4/shareeconf/apikeys.cfg b/copri4/shareeconf/apikeys.cfg
new file mode 120000
index 0000000..dc6515e
--- /dev/null
+++ b/copri4/shareeconf/apikeys.cfg
@@ -0,0 +1 @@
+/etc/shareeconf/apikeys.cfg
\ No newline at end of file
diff --git a/copri4/shareeconf/global.cfg b/copri4/shareeconf/global.cfg
new file mode 120000
index 0000000..a3e8ffd
--- /dev/null
+++ b/copri4/shareeconf/global.cfg
@@ -0,0 +1 @@
+/etc/shareeconf/global_devel.cfg
\ No newline at end of file
diff --git a/copri4/shareeconf/mailx.cfg b/copri4/shareeconf/mailx.cfg
new file mode 120000
index 0000000..b88542f
--- /dev/null
+++ b/copri4/shareeconf/mailx.cfg
@@ -0,0 +1 @@
+/etc/shareeconf/mailx.cfg
\ No newline at end of file
diff --git a/copri4/shareedms-operator/apache/shareedms-operator.conf b/copri4/shareedms-operator/apache/shareedms-operator.conf
new file mode 100644
index 0000000..682a7b5
--- /dev/null
+++ b/copri4/shareedms-operator/apache/shareedms-operator.conf
@@ -0,0 +1,113 @@
+
+ ServerName shareedms-operator.copri-bike.de
+ ServerAlias shareedms-operator1.copri-bike.de
+
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareedms-operator
+
+ ErrorLog /var/log/apache2/shareedms-operator-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareedms-operator-access.log combined
+ ServerSignature Off
+ RewriteEngine on
+ RewriteCond %{SERVER_NAME} =shareedms-operator.copri-bike.de
+ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
+
+
+
+
+
+ ServerName shareedms-operator1.copri-bike.de
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareedms-operator
+ AddHandler cgi-script .cgi .sh .pl
+
+
+ Options -Indexes +FollowSymLinks +ExecCGI
+ AllowOverride None
+
+
+
+ Header set Access-Control-Allow-Origin "*"
+
+
+
+ Options +Indexes +FollowSymLinks -ExecCGI
+ Order allow,deny
+ Allow from all
+
+
+
+ Options -Indexes +FollowSymLinks
+ Order allow,deny
+ Allow from all
+ ForceType application/octet-stream
+ Header set Content-Disposition attachment
+
+
+ ErrorLog /var/log/apache2/shareedms-operator-error.log
+ #LogLevel debug
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareedms-operator-access.log combined
+ ServerSignature Off
+
+ Include /etc/letsencrypt/options-ssl-apache.conf
+ SSLCertificateFile /etc/letsencrypt/live/copri-bike.de-0003/fullchain.pem
+ SSLCertificateKeyFile /etc/letsencrypt/live/copri-bike.de-0003/privkey.pem
+
+
+
+ ServerName shareedms-operator.copri-bike.de
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareedms-operator
+
+
+ PerlOptions +Parent
+ PerlRequire /var/www/copri4/shareedms-operator/startup.pl
+
+ SetHandler perl-script
+ PerlResponseHandler Mod::Indexsharee
+ PerlInitHandler Apache2::Reload
+ PerlOptions +ParseHeaders +GlobalRequest
+ Options -ExecCGI +FollowSymLinks
+ Order allow,deny
+ Allow from all
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::ajax_json
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::ajax_post
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::FileOut
+
+
+
+ RewriteEngine On
+ RedirectMatch ^/$ /DMS/Mietjournal
+ SSLProxyEngine On
+ RewriteCond %{REQUEST_URI} ^/(site|img|data|css|js|jquery)
+ RewriteRule ^(.*)$ https://shareedms-operator1.copri-bike.de/$1 [P,L]
+
+
+ ErrorLog /var/log/apache2/shareedms-operator-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareedms-operator-access.log combined
+ ServerSignature Off
+ Include /etc/letsencrypt/options-ssl-apache.conf
+
+ SSLCertificateFile /etc/letsencrypt/live/copri-bike.de-0003/fullchain.pem
+ SSLCertificateKeyFile /etc/letsencrypt/live/copri-bike.de-0003/privkey.pem
+
+
+
diff --git a/copri4/shareedms-operator/css/bootstrap-icons-1.5.0 b/copri4/shareedms-operator/css/bootstrap-icons-1.5.0
new file mode 120000
index 0000000..fc8bde9
--- /dev/null
+++ b/copri4/shareedms-operator/css/bootstrap-icons-1.5.0
@@ -0,0 +1 @@
+../../main/css/bootstrap-icons-1.5.0
\ No newline at end of file
diff --git a/copri4/shareedms-operator/css/favicon.ico b/copri4/shareedms-operator/css/favicon.ico
new file mode 120000
index 0000000..28b50e2
--- /dev/null
+++ b/copri4/shareedms-operator/css/favicon.ico
@@ -0,0 +1 @@
+../../main/css/favicon.ico
\ No newline at end of file
diff --git a/copri4/shareedms-operator/css/local_style_2.css b/copri4/shareedms-operator/css/local_style_2.css
new file mode 120000
index 0000000..bb065e7
--- /dev/null
+++ b/copri4/shareedms-operator/css/local_style_2.css
@@ -0,0 +1 @@
+../../main/css/local_style_2.css
\ No newline at end of file
diff --git a/copri4/shareedms-operator/glyphicons b/copri4/shareedms-operator/glyphicons
new file mode 120000
index 0000000..7393fbd
--- /dev/null
+++ b/copri4/shareedms-operator/glyphicons
@@ -0,0 +1 @@
+../main/glyphicons
\ No newline at end of file
diff --git a/copri4/shareedms-operator/img b/copri4/shareedms-operator/img
new file mode 120000
index 0000000..39564ce
--- /dev/null
+++ b/copri4/shareedms-operator/img
@@ -0,0 +1 @@
+../main/img
\ No newline at end of file
diff --git a/copri4/shareedms-operator/js b/copri4/shareedms-operator/js
new file mode 120000
index 0000000..6b66a30
--- /dev/null
+++ b/copri4/shareedms-operator/js
@@ -0,0 +1 @@
+../main/js
\ No newline at end of file
diff --git a/copri4/shareedms-operator/pdfinvoice b/copri4/shareedms-operator/pdfinvoice
new file mode 120000
index 0000000..6089659
--- /dev/null
+++ b/copri4/shareedms-operator/pdfinvoice
@@ -0,0 +1 @@
+pdf
\ No newline at end of file
diff --git a/copri4/shareedms-operator/robots.txt b/copri4/shareedms-operator/robots.txt
new file mode 100755
index 0000000..1f53798
--- /dev/null
+++ b/copri4/shareedms-operator/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/copri4/shareedms-operator/src/Lib/Config.pm b/copri4/shareedms-operator/src/Lib/Config.pm
new file mode 100644
index 0000000..3022f32
--- /dev/null
+++ b/copri4/shareedms-operator/src/Lib/Config.pm
@@ -0,0 +1,82 @@
+package Config;
+
+#Deprecated config file
+#Please use shareeconf/*
+
+use strict;
+use warnings;
+use CGI;
+use Config::General;
+my $q = new CGI;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+sub envonline(){
+ my $self = shift;
+
+ my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
+ my $conf = Config::General->new($globalconf_file);
+ my %globalconf = $conf->getall;
+
+ my $basedir = "$globalconf{copri_conf}->{basedir}/$globalconf{operator}{sharee_operator}->{dir_dms}";
+ my $metahost = $globalconf{operator}{sharee_operator}->{operatorDMS1};
+
+ my %varenv = (
+ dbname => $globalconf{operator}{sharee_operator}{database}->{dbname},
+ dbuser => $globalconf{operator}{sharee_operator}{database}->{user},
+ dbpassw => $globalconf{operator}{sharee_operator}{database}->{passwd},
+ dbhost => $globalconf{operator}{sharee_operator}{database}->{host},
+ syshost => $globalconf{operator}{sharee_operator}->{dir_app},
+ wwwhost => $globalconf{operator}{sharee_operator}->{operatorDMS},
+ praefix => $globalconf{operator}{sharee_operator}{database}->{dbname},
+ systype => "sharee",#(azn)
+ mandant => $globalconf{shareedms_conf}->{parent_node},
+ start => $globalconf{shareedms_conf}->{start},
+ profile => $globalconf{shareedms_conf}->{profile},
+
+ superu_id => $globalconf{copri_conf}->{superu_id},
+ debug => $globalconf{copri_conf}->{debug},
+ logdir => $globalconf{copri_conf}->{logdir},
+ live_hostname => $globalconf{primary}{sharee_primary}->{live_hostname},
+ metahost=>"$metahost",
+ orga => "dms",
+ term_active_color => "#$globalconf{shareedms_conf}->{term_active_color}",
+ background_image => "",
+ background_size => "cover",
+ background_color => "#5c5c5c",
+ background_color2 => "#a7a18f",
+ background_align => "center",
+ background_repeat => "no-repeat",
+ font_family => "Arial",
+ font_size => "100.01%",
+ line_height => "1",
+ basedir => "$basedir",
+ csv => "$basedir/csv",
+ pdf => "$basedir/pdf",
+ data => "$basedir/data",
+ xmlfile => "$basedir/xml",
+ ftp_getfile => "ftp/SWK_codes/got_last.csv",
+ ftp_putfile => "ftp/SWK_return/konrad_code_protokoll.csv",
+ map_activ => "",
+ min_width => "1100",
+ head_logo => "$metahost/img/sharee_bike_Logo.jpg",
+ barcode => "",
+ limit => "200",
+ waren_main_id => $globalconf{shareedms_conf}->{waren},
+ Zahlungsweise => "SEPA-Lastschrift (payone)|Kreditkarte (payone)|Zahlungseingang (payone txid)|Abbuchung|Bar|EC-Karte|Überweisung|Zahlungsausfall",
+ order_state => "|angerufen|eMail gesendet|in Arbeit|an FiBu delegiert|txid renewed|cronjob fail|payone Mahnung|COPRI Mahnung",
+ 'Ziel Datei' => "privacy.html|agb.html|impress.html|tariff_info.html|bike_info.html",
+ printer => "PDF"
+ );
+ return %varenv;
+
+}
+
+1;
+
+
diff --git a/copri4/shareedms-operator/src/Lib/Mlogic.pm b/copri4/shareedms-operator/src/Lib/Mlogic.pm
new file mode 100644
index 0000000..f71bfb6
--- /dev/null
+++ b/copri4/shareedms-operator/src/Lib/Mlogic.pm
@@ -0,0 +1,371 @@
+package Mlogic;
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# Copyright (c) Rainer Gümpelein, TeilRad GmbH
+#
+#
+use strict;
+use warnings;
+use CGI::Carp qw(fatalsToBrowser);
+use CGI ':standard';
+use Config::General;
+use Mod::Buttons;
+use Mod::Libenz;
+use Mod::Libenzdb;
+use Mod::DBtank;
+use POSIX;
+use Data::Dumper;
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless($self,$class);
+ return $self;
+}
+
+#Template
+sub tpl(){
+ my $self = shift;
+ my ($node_meta,$users_dms,$mode,$varenv,$users_sharee,$return) = @_;
+
+ my $q = new CGI;
+ my $lb = new Libenz;
+ my $db = new Libenzdb;
+ my $dbt = new DBtank;
+ my $but = new Buttons;
+ my %ib = $but->ibuttons();
+ my $script = $q->script_name();
+ my $path_info = $q->path_info();
+ my $path = $path_info;
+ if("$varenv->{metahost}"){
+ $path = "$script" . "$path_info";
+ $script="";
+ }
+ my $coo = $q->cookie(-name=>'domcookie');
+ my $debug = "";
+ my $lang = "de";
+ my @viewsel = split /\//,$1 if($path =~ /^\/(.*)/);
+ my $view_root = $viewsel[0] || "";
+ my $mandant = $db->get_node("$view_root","$lang");
+ my $parent_id = $node_meta->{parent_id};
+ my $main_id = $node_meta->{main_id};
+
+ my $title = "";
+ $title .= $dbt->{primary}->{$varenv->{dbname}}->{pprefix} if($dbt->{primary}->{$varenv->{dbname}}->{pprefix});
+ $title .= $dbt->{operator}->{$varenv->{dbname}}->{project} if($dbt->{operator}->{$varenv->{dbname}}->{project});
+ $title .= " " . $dbt->{operator}->{$varenv->{dbname}}->{oprefix} if($dbt->{operator}->{$varenv->{dbname}}->{oprefix});
+ $title .= $dbt->{website}->{$varenv->{syshost}}->{project} if($dbt->{website}->{$varenv->{syshost}}->{project});
+ $title .= " DEVEL $varenv->{dbname}" if($dbt->{copri_conf}->{stage} eq "test");
+
+
+ ###User Panel
+ if($users_dms->{u_id}){
+
+ ###header start
+ print "\n";
+ print "
\n";
+
+ #cleanup
+ if(!$mandant->{node_name} || "$mandant->{node_name}" ne "$users_dms->{fullurl}"){
+ $db->cleanup_users($users_dms->{owner}) if($users_dms->{owner});
+ }
+
+ if($users_dms->{c_id4trans} && $users_dms->{tpl_id4trans} && $users_dms->{kind_of_trans}){
+ my $table = "contenttrans";
+ if($users_dms->{kind_of_trans} =~ /Veranstaltung|Proje/){
+ $table = "contenttver";
+ }
+
+ my $limit = $R::limit || $varenv->{limit};
+ my $offset = $R::offset || "0";
+ if($R::go && $R::go eq "backward_list"){
+ $offset -= $limit if($offset >= $limit);
+ }elsif($R::go && $R::go eq "forward_list"){
+ $offset += $limit;
+ }
+ my $ctrel = $db->get_ctrel($table,"",$lang,"",$users_dms->{c_id4trans},$users_dms->{tpl_id4trans});
+ my $uri = "/$users_dms->{fullurl}/$users_dms->{kind_of_trans}";
+ print $q->div({-id=>'Headerlogin',-style=>"background-color:$varenv->{term_active_color};"},$q->a({-class=>'elinkbutton1',-title=>"$users_dms->{kind_of_trans} Terminal öffnen",-href=>"$uri?ct_trans=open\&c_id4trans=$users_dms->{c_id4trans}\&tpl_id4trans=$users_dms->{tpl_id4trans}\&kind_of_trans=$users_dms->{kind_of_trans}\&owner=$users_dms->{owner}\&offset=$offset\&limit=$limit\&relids=$R::relids\&no_redirect=1"}," $users_dms->{kind_of_trans} \#$ctrel->{ct_name} $ctrel->{txt01}", $q->span({-id=>"c_id4trans", -style=>"color:$varenv->{term_active_color}"}, "$users_dms->{c_id4trans}"))) if($ctrel->{ct_name});
+ }
+
+ print $q->div({-id=>'Headerlogin'},"$users_sharee->{txt08} ", $q->span({-id=>"owner", -style=>"color:silver"}, "($users_dms->{u_id})")),"\n";
+ print $q->div({-id=>'Headerlogin'},$q->a({-href=>"logout"},$q->img({-style=>'padding:0px 10px;',-src=>"$varenv->{metahost}/img/logout.svg"}))),"\n";
+ print "
";
+ print "
";
+ }
+ #end user panel
+ ###header end
+
+
+ #Mainlogin
+ if(!$users_dms->{u_id}){
+
+ print "\n";
+
+ print $q->start_multipart_form(-id=>'authform', -name=>'loginscreen'),"\n";
+ print $q->hidden(-name=>"sessionid",-override=>1,-value=>"$R::sessionid");
+
+ print "
\n";
+ #Login
+ print $q->div({-class=>'content2'}, "Zugang zum $title"),"\n";
+ print $q->div({-style=>'color:#c83434'},"Login failure"),"\n" if("$R::login_dms" eq "Login" && !$users_dms->{u_id});
+ print $q->label({-for=>'Userid'},""),"\n";
+ print $q->textfield(-class=>'form-control', -name=>'user_id', -value=>'', -override=>1, -type=>'email',-class=>'form-control', -id=>'Userid', -placeholder=>'NutzerIn', -required=>1, -autofocus=>1),"\n";
+ print $q->label({-for=>'PW'},""),"\n";
+ print $q->password_field(-class=>'form-control', -name=>'user_pw', -value=>'', -override=>1, -type=>'password',-class=>'form-control', -id=>'PW', -placeholder=>'Passwort', -required=>1),"\n";
+ print $q->div({-style=>'margin-top:1em;'},"Login "),"\n";
+
+ print "
\n";
+ print $q->end_form,"\n";
+ print "
";
+
+ exit 0;
+ }
+
+ if($users_dms->{u_id} && $main_id){
+ $return = $lb->return_feedback($return,$users_dms->{kind_of_trans},$users_dms->{owner}) if($return !~ /shareejson/);
+
+ if($main_id >= "100000"){
+ my $mstyle="";
+
+ ###Top Menu
+ #bootstrap menue
+ print "\n";
+ print "\n";
+ print "
\n";
+ print " \n";
+ print " \n";
+ print $q->div({-id=>'Headerlogo'},$q->a({-class=>'navbar-brand',-style=>"color:black;",-href=>"$varenv->{wwwhost}"}, $q->img({ -style=>"height:25px",-src=>"$varenv->{head_logo}"}), "c o p r i" ,$q->div({-style=>'font-size:0.71em;'}, "$title"))),"\n";
+ my $node = $db->collect_noderel($dbt->{shareedms_conf}->{parent_id},$lang,$users_dms->{u_id});
+
+ print "
\n";
+ print "
\n";
+ #print "\n";
+
+ foreach my $id (sort {$node->{$a}->{n_sort} <=> $node->{$b}->{n_sort}} keys (%$node)){
+ $node->{$id}->{node_path} = $node->{$id}->{node_name} if(!$node->{$id}->{node_path});
+ my $lmenu0 = "";
+ my $url = "";
+ my $mclass = "";
+ my $mstyle = "";
+ if("$node->{$id}->{node_name}" eq "$viewsel[1]"){
+ $mclass = "active";
+ $mstyle = "color:white;";
+ $parent_id = $node->{$id}->{parent_id};
+ $main_id = $node->{$id}->{main_id};
+ }
+ if($node->{$id}->{main_id} && $node->{$id}->{node_name} =~ /$dbt->{shareedms_conf}->{mod_active}/){
+ my $topath = "/$viewsel[0]/$node->{$id}->{node_path}";
+ #
+ #0. menue
+ my $aclass = "dropdown-item";
+ $aclass = "nav-link" if($node->{$id}->{node_name} =~ /Mietjourna|Alarmjournal/);
+ if($users_dms->{u_id} && ($users_dms->{int01} == 2 && $node_meta->{ct_table} =~ /content$/) || ($users_dms->{u_id} == $dbt->{copri_conf}->{superu_id})){
+ my $url = "$topath/maintainer?node2edit=edit_relation\&main_id=$node->{$id}->{main_id}";
+ $lmenu0 = $but->event_button("$topath","$node->{$id}->{node_name}","$node->{$id}->{main_id}","$aclass $mclass","","$users_dms->{u_id}","$url");
+ }else{
+ $lmenu0 = $but->lo_button("$topath","$node->{$id}->{node_name}","$node->{$id}->{main_id}","$aclass $mclass","","$users_dms->{u_id}");
+ }
+
+ #1. submenu
+ my $subs1=0;
+ my $node1 = $db->collect_noderel($node->{$id}->{main_id},$lang,$users_dms->{u_id});
+ foreach my $id1 (sort {$node1->{$a}->{n_sort} <=> $node1->{$b}->{n_sort}} keys (%$node1)){
+ $subs1=1 if($node1->{$id1}->{main_id});
+ }
+
+ #1. submenue
+ #if($subs1 && ($node->{$id}->{node_name} !~ /Einstellung/ || $users_dms->{u_group} =~ /maintainer/)){
+ if($subs1){
+ #if(ref($node1) eq "HASH"){
+ print "\n";#with integrated event_button
+ print " $node->{$id}->{node_name} \n";
+ print "\n";
+ print " \n";
+ #end submenu
+ #}elsif($node->{$id}->{node_name} !~ /Einstellung/ || $users_dms->{u_group} =~ /maintainer/){
+ }elsif(1==1){
+ print " $lmenu0 \n";
+ }
+ }
+ }
+ }#end foreach lmenue0
+ print " \n";
+ print " \n";
+ ###end bootstrap menue
+
+ #node_name=DMS
+ if($varenv->{dbname} eq "sharee_primary" && $main_id == "100002"){
+ my $big2menu="";
+ while (my ($key, $value) = each %{ $dbt->{operator} }) {
+ if($value->{operatorApp}){
+ $big2menu .= $but->lia_button("$value->{operatorDMS}","$key","","","","");
+ }
+ }
+ print $q->div({-style=>'width:100%;margin:0;padding-top:90px;color:white;'}, "sharee.bike Operatoren"),"\n";
+ print $q->div({-style=>'width:100%;margin:0;'}, $q->ul({-id=>'BigNavi'},$big2menu)),"\n";
+ }
+
+ print "\n";
+ #lefsitemenue disabled 2021-06.03
+ print "
\n";
+
+
+ $debug = "(c_id4trans:$users_dms->{c_id4trans} && tpl_id4trans:$users_dms->{tpl_id4trans} && kind_of_trans:$users_dms->{kind_of_trans}) $node_meta->{tpl_name},$node_meta->{tpl_id},$node_meta->{ct_table},$parent_id,$main_id, permissions: ($users_dms->{int01},$users_dms->{int02},$users_dms->{int03},$users_dms->{int07},$users_dms->{int08},$users_dms->{int09})" if($users_dms->{u_id} == $dbt->{copri_conf}->{superu_id});
+ print $q->div({-style=>'position:fixed;bottom:0%;right:1%;z-index:10;padding:2px;font-size:13px;'},"$debug",$q->a({-style=>'color:black;text-decoration: none;',-href=>'https://sharee.bike',-target=>'_blank'},"sharee.bike © TeilRad GmbH 2021")),"\n";
+
+
+#update c_id4trans on changing browser tab 2019-10-08
+#FIXME, we need all $R::c_id4trans,$R::tpl_id4trans,$R::kind_of_trans
+if(1==2 && $mode eq "manager"){
+print<
+
+function postc_id4trans(c_val,o_val) {
+ \$.ajax({
+ url: '$varenv->{wwwhost}/ajax_post',
+ type: 'POST',
+ async: true,
+ cache: false,
+ data: { c_id4trans: c_val, owner: o_val },
+ });
+}
+
+document.addEventListener('visibilitychange', function () {
+ if(document.visibilityState != 'hidden') {
+ var c_id4trans = document.getElementById("c_id4trans").innerText;
+ var owner = document.getElementById("owner").innerText;
+ if(c_id4trans){
+ postc_id4trans(c_id4trans,owner);
+ }
+ console.log("postc_id4trans:" + c_id4trans + " " + owner);
+ }
+}, false);
+
+
+
+EOF
+;
+}
+
+ $self->tplselect($node_meta,$users_dms,$mode,$varenv,$return);
+ print "\n";
+ }#end logedin environment
+
+}
+
+#2021-05-05 changed to Mlogic
+sub tplselect(){
+ my $self = shift;
+ my $node_meta = shift;
+ my $users_dms = shift;
+ my $mode = shift || "";
+ my $varenv = shift;
+ my $return = shift || "";
+
+ my $sort = "";
+ my $lang = "de";
+ my $tpl_name = $node_meta->{tpl_name};
+ my $tpl_id = $node_meta->{tpl_id};
+ my $ct_table = $node_meta->{ct_table};
+ my $parent_id = $node_meta->{parent_id};
+ my $main_id = $node_meta->{main_id};
+ my $u_id = $users_dms->{u_id};
+ #print Dumper($node_meta);
+ #exit;
+
+print <
+ \$(function(){
+ \$('.autos').autosize({append: '\\n'});
+ });
+
+EOF
+;
+
+ if($mode eq "supervisor" || $node_meta->{tpl_name} eq "AttributMatrix"){
+ $tpl_name = "AttributMatrix";
+ require "Tpl/AttributMatrix.pm";
+ $return = &AttributMatrix::tpl($node_meta,$users_dms,$mode,$return);
+ #}elsif($tpl_id && $tpl_id >= 400 && $tpl_id <= 699){#contentpos or contentadrpos
+ }elsif($node_meta->{ct_table} =~ /contentpos|contentadrpos|users$/){#contentpos or contentadrpos
+ require "Tpl/SubListe.pm";
+ $return = &SubListe::tpl($node_meta,$users_dms,$mode,$return);
+ }elsif($node_meta->{ct_table} =~ /content$|contentadr$|contenttrans$/){
+ require "Tpl/Liste3.pm";
+ $return = &Liste3::tpl($node_meta,$users_dms,$mode,$return);
+ }elsif($node_meta->{ct_table} eq "contentuser"){
+ require "Tpl/MandantConf.pm";
+ $return = &MandantConf::tpl($node_meta,$users_dms,$mode,$return);
+ #}elsif($tpl_name =~ /Statistik/){
+ #require "Tpl/Statistik.pm";
+ #&Statistik::tpl($main_id,$u_id,$lang,"","",$sort);
+ }elsif($node_meta->{ct_table} =~ /contenttranspos|contenttheftpos/){
+ require "Tpl/Calorin.pm";
+ &Calorin::tpl($node_meta,$users_dms,$mode,$return);
+ }
+##Modalbox things##
+ if($return !~ /failure/){
+ if(($R::ct_trans !~ /close/) && ($ct_table =~ /contenttrans/ || $R::kind_of_trans =~ /Faktur|Verleih/) && ($R::ct_trans || $R::trans2edit || $R::ctpos_activ || $R::select_part || $R::set_main_id)){
+ &Modalbox::mobox($node_meta,$users_dms,$mode,$return);
+ }elsif(($R::ct_trans !~ /close/) && ($ct_table =~ /content$|contentadr|contenttver|contentpos|users$/ && ($R::ct_trans || $R::rel_edit || $R::base_edit)) || ($R::node2edit && $R::node2edit =~ /edit/)){
+ &Modalbox3::mobox3($node_meta,$users_dms,$mode,$return) if($R::rel_edit !~ /delete|save/ && $R::ct_trans !~ /delete/ && $R::base_edit !~ /delete|save/ && !$R::service_id);
+ }
+ }
+
+ if($return =~ /failure/){
+ require "Mod/Failure.pm";
+ &Failure::tpl("",$u_id,"","","","",$return);
+ }
+}
+
+1;
+
+
diff --git a/copri4/shareedms-operator/src/Lib/PDFGenerator.pm b/copri4/shareedms-operator/src/Lib/PDFGenerator.pm
new file mode 120000
index 0000000..1bebb95
--- /dev/null
+++ b/copri4/shareedms-operator/src/Lib/PDFGenerator.pm
@@ -0,0 +1 @@
+../../../main/src/Lib/PDFGenerator.pm
\ No newline at end of file
diff --git a/copri4/shareedms-operator/src/Lib/Printpreview.pm b/copri4/shareedms-operator/src/Lib/Printpreview.pm
new file mode 120000
index 0000000..5485ff7
--- /dev/null
+++ b/copri4/shareedms-operator/src/Lib/Printpreview.pm
@@ -0,0 +1 @@
+../../../main/src/Lib/Printpreview.pm
\ No newline at end of file
diff --git a/copri4/shareedms-operator/src/Mod b/copri4/shareedms-operator/src/Mod
new file mode 120000
index 0000000..d4b7ba5
--- /dev/null
+++ b/copri4/shareedms-operator/src/Mod
@@ -0,0 +1 @@
+../../main/src/Mod
\ No newline at end of file
diff --git a/copri4/shareedms-operator/src/Tpl b/copri4/shareedms-operator/src/Tpl
new file mode 120000
index 0000000..61cf65a
--- /dev/null
+++ b/copri4/shareedms-operator/src/Tpl
@@ -0,0 +1 @@
+../../main/src/Tpl
\ No newline at end of file
diff --git a/copri4/shareedms-operator/src/scripts b/copri4/shareedms-operator/src/scripts
new file mode 120000
index 0000000..8705f56
--- /dev/null
+++ b/copri4/shareedms-operator/src/scripts
@@ -0,0 +1 @@
+../../main/src/scripts
\ No newline at end of file
diff --git a/copri4/shareedms-operator/src/wkhtmltopdf-amd64 b/copri4/shareedms-operator/src/wkhtmltopdf-amd64
new file mode 120000
index 0000000..2e6c34b
--- /dev/null
+++ b/copri4/shareedms-operator/src/wkhtmltopdf-amd64
@@ -0,0 +1 @@
+../../main/src/wkhtmltopdf-amd64
\ No newline at end of file
diff --git a/copri4/shareedms-operator/startup.pl b/copri4/shareedms-operator/startup.pl
new file mode 100755
index 0000000..74344fb
--- /dev/null
+++ b/copri4/shareedms-operator/startup.pl
@@ -0,0 +1,2 @@
+use lib qw(/var/www/copri4/shareedms-operator/src);
+1;
diff --git a/copri4/shareeweb-project/apache/index.html b/copri4/shareeweb-project/apache/index.html
new file mode 100644
index 0000000..d8964f8
--- /dev/null
+++ b/copri4/shareeweb-project/apache/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+ iFrame message passing test
+
+
+
+
+
+
+
Lastenrad Bayern
+
+
+
+
Registrieren
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/copri4/shareeweb-project/apache/shareeweb-operator.conf b/copri4/shareeweb-project/apache/shareeweb-operator.conf
new file mode 120000
index 0000000..3706f94
--- /dev/null
+++ b/copri4/shareeweb-project/apache/shareeweb-operator.conf
@@ -0,0 +1 @@
+shareeweb-operator_devel.conf
\ No newline at end of file
diff --git a/copri4/shareeweb-project/apache/shareeweb-operator_devel.conf b/copri4/shareeweb-project/apache/shareeweb-operator_devel.conf
new file mode 100644
index 0000000..45a41ec
--- /dev/null
+++ b/copri4/shareeweb-project/apache/shareeweb-operator_devel.conf
@@ -0,0 +1,114 @@
+
+ ServerName shareeweb-project.copri-bike.de
+ ServerAlias shareeweb-project1.copri-bike.de
+
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareeweb-project
+
+ ErrorLog /var/log/apache2/shareeweb-project-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareeweb-project-access.log combined
+ ServerSignature Off
+ RewriteEngine on
+ RewriteCond %{SERVER_NAME} =shareeweb-project.copri-bike.de
+ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
+
+
+
+
+ ServerName shareeweb-project1.copri-bike.de
+
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareeweb-project
+ AddHandler cgi-script .cgi .sh .pl
+
+
+ Options -Indexes +FollowSymLinks +ExecCGI
+ AllowOverride None
+
+
+
+ Header set Access-Control-Allow-Origin "copri-bike.de"
+
+
+
+ Options -Indexes +FollowSymLinks -ExecCGI
+ Order allow,deny
+ Allow from all
+
+
+
+ Options -Indexes +FollowSymLinks
+ Order allow,deny
+ Allow from all
+ ForceType application/octet-stream
+ Header set Content-Disposition attachment
+
+
+ ErrorLog /var/log/apache2/shareeweb-project-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareeweb-project-access.log combined
+ ServerSignature Off
+Include /etc/letsencrypt/options-ssl-apache.conf
+
+SSLCertificateFile /etc/letsencrypt/live/copri-bike.de-0003/fullchain.pem
+SSLCertificateKeyFile /etc/letsencrypt/live/copri-bike.de-0003/privkey.pem
+
+
+
+
+ ServerName shareeweb-project.copri-bike.de
+
+ ServerAdmin info@gnu-systems.de
+ DocumentRoot /var/www/copri4/shareeweb-project
+
+ PerlOptions +Parent
+ PerlRequire /var/www/copri4/shareeweb-project/startup.pl
+
+
+ SetHandler perl-script
+ PerlResponseHandler Mod::Indexsharee
+ PerlInitHandler Apache2::Reload
+ PerlOptions +ParseHeaders +GlobalRequest
+ Options -ExecCGI +FollowSymLinks
+ Order allow,deny
+ Allow from all
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::APIvelo
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::APIjsonserver
+
+
+
+ SetHandler perl-script
+ PerlInitHandler Apache2::Reload
+ PerlResponseHandler Mod::FileOut
+
+
+
+ RewriteEngine On
+ RedirectMatch ^/$ /frame/Karte
+ SSLProxyEngine On
+ RewriteCond %{REQUEST_URI} ^/(site|img|data|css|js|jquery)
+ RewriteRule ^(.*)$ https://shareeweb-project1.copri-bike.de/$1 [P,L]
+
+
+ ErrorLog /var/log/apache2/shareeweb-project-error.log
+ LogLevel info ssl:warn
+ CustomLog /var/log/apache2/shareeweb-project-access.log combined
+ ServerSignature Off
+Include /etc/letsencrypt/options-ssl-apache.conf
+SSLCertificateFile /etc/letsencrypt/live/copri-bike.de-0003/fullchain.pem
+SSLCertificateKeyFile /etc/letsencrypt/live/copri-bike.de-0003/privkey.pem
+
+
+
+
diff --git a/copri4/shareeweb-project/css b/copri4/shareeweb-project/css
new file mode 120000
index 0000000..7e8b615
--- /dev/null
+++ b/copri4/shareeweb-project/css
@@ -0,0 +1 @@
+../shareeapp-operator/css
\ No newline at end of file
diff --git a/copri4/shareeweb-project/glyphicons b/copri4/shareeweb-project/glyphicons
new file mode 120000
index 0000000..7393fbd
--- /dev/null
+++ b/copri4/shareeweb-project/glyphicons
@@ -0,0 +1 @@
+../main/glyphicons
\ No newline at end of file
diff --git a/copri4/shareeweb-project/img b/copri4/shareeweb-project/img
new file mode 120000
index 0000000..39564ce
--- /dev/null
+++ b/copri4/shareeweb-project/img
@@ -0,0 +1 @@
+../main/img
\ No newline at end of file
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/css/bootstrap.css b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/css/bootstrap.css
new file mode 100644
index 0000000..7caee93
--- /dev/null
+++ b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/css/bootstrap.css
@@ -0,0 +1,6760 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+html {
+ font-family: sans-serif;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+body {
+ margin: 0;
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+audio,
+canvas,
+progress,
+video {
+ display: inline-block;
+ vertical-align: baseline;
+}
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+[hidden],
+template {
+ display: none;
+}
+a {
+ background-color: transparent;
+}
+a:active,
+a:hover {
+ outline: 0;
+}
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+b,
+strong {
+ font-weight: bold;
+}
+dfn {
+ font-style: italic;
+}
+h1 {
+ margin: .67em 0;
+ font-size: 2em;
+}
+mark {
+ color: #000;
+ background: #ff0;
+}
+small {
+ font-size: 80%;
+}
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+sup {
+ top: -.5em;
+}
+sub {
+ bottom: -.25em;
+}
+img {
+ border: 0;
+}
+svg:not(:root) {
+ overflow: hidden;
+}
+figure {
+ margin: 1em 40px;
+}
+hr {
+ height: 0;
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+pre {
+ overflow: auto;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0;
+ font: inherit;
+ color: inherit;
+}
+button {
+ overflow: visible;
+}
+button,
+select {
+ text-transform: none;
+}
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button;
+ cursor: pointer;
+}
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+input {
+ line-height: normal;
+}
+input[type="checkbox"],
+input[type="radio"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+}
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+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-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+fieldset {
+ padding: .35em .625em .75em;
+ margin: 0 2px;
+ border: 1px solid #c0c0c0;
+}
+legend {
+ padding: 0;
+ border: 0;
+}
+textarea {
+ overflow: auto;
+}
+optgroup {
+ font-weight: bold;
+}
+table {
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+td,
+th {
+ padding: 0;
+}
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+@media print {
+ *,
+ *:before,
+ *:after {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+ }
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+ a[href^="#"]:after,
+ a[href^="javascript:"]: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;
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+ .navbar {
+ display: none;
+ }
+ .btn > .caret,
+ .dropup > .btn > .caret {
+ border-top-color: #000 !important;
+ }
+ .label {
+ border: 1px solid #000;
+ }
+ .table {
+ border-collapse: collapse !important;
+ }
+ .table td,
+ .table th {
+ background-color: #fff !important;
+ }
+ .table-bordered th,
+ .table-bordered td {
+ border: 1px solid #ddd !important;
+ }
+}
+@font-face {
+ font-family: 'Glyphicons Halflings';
+
+ src: url('../fonts/glyphicons-halflings-regular.eot');
+ src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: 'Glyphicons Halflings';
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1;
+
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.glyphicon-asterisk:before {
+ content: "\002a";
+}
+.glyphicon-plus:before {
+ content: "\002b";
+}
+.glyphicon-euro:before,
+.glyphicon-eur:before {
+ content: "\20ac";
+}
+.glyphicon-minus:before {
+ content: "\2212";
+}
+.glyphicon-cloud:before {
+ content: "\2601";
+}
+.glyphicon-envelope:before {
+ content: "\2709";
+}
+.glyphicon-pencil:before {
+ content: "\270f";
+}
+.glyphicon-glass:before {
+ content: "\e001";
+}
+.glyphicon-music:before {
+ content: "\e002";
+}
+.glyphicon-search:before {
+ content: "\e003";
+}
+.glyphicon-heart:before {
+ content: "\e005";
+}
+.glyphicon-star:before {
+ content: "\e006";
+}
+.glyphicon-star-empty:before {
+ content: "\e007";
+}
+.glyphicon-user:before {
+ content: "\e008";
+}
+.glyphicon-film:before {
+ content: "\e009";
+}
+.glyphicon-th-large:before {
+ content: "\e010";
+}
+.glyphicon-th:before {
+ content: "\e011";
+}
+.glyphicon-th-list:before {
+ content: "\e012";
+}
+.glyphicon-ok:before {
+ content: "\e013";
+}
+.glyphicon-remove:before {
+ content: "\e014";
+}
+.glyphicon-zoom-in:before {
+ content: "\e015";
+}
+.glyphicon-zoom-out:before {
+ content: "\e016";
+}
+.glyphicon-off:before {
+ content: "\e017";
+}
+.glyphicon-signal:before {
+ content: "\e018";
+}
+.glyphicon-cog:before {
+ content: "\e019";
+}
+.glyphicon-trash:before {
+ content: "\e020";
+}
+.glyphicon-home:before {
+ content: "\e021";
+}
+.glyphicon-file:before {
+ content: "\e022";
+}
+.glyphicon-time:before {
+ content: "\e023";
+}
+.glyphicon-road:before {
+ content: "\e024";
+}
+.glyphicon-download-alt:before {
+ content: "\e025";
+}
+.glyphicon-download:before {
+ content: "\e026";
+}
+.glyphicon-upload:before {
+ content: "\e027";
+}
+.glyphicon-inbox:before {
+ content: "\e028";
+}
+.glyphicon-play-circle:before {
+ content: "\e029";
+}
+.glyphicon-repeat:before {
+ content: "\e030";
+}
+.glyphicon-refresh:before {
+ content: "\e031";
+}
+.glyphicon-list-alt:before {
+ content: "\e032";
+}
+.glyphicon-lock:before {
+ content: "\e033";
+}
+.glyphicon-flag:before {
+ content: "\e034";
+}
+.glyphicon-headphones:before {
+ content: "\e036595";
+}
+.glyphicon-volume-off:before {
+ content: "\e036";
+}
+.glyphicon-volume-down:before {
+ content: "\e037";
+}
+.glyphicon-volume-up:before {
+ content: "\e038";
+}
+.glyphicon-qrcode:before {
+ content: "\e039";
+}
+.glyphicon-barcode:before {
+ content: "\e040";
+}
+.glyphicon-tag:before {
+ content: "\e041";
+}
+.glyphicon-tags:before {
+ content: "\e042";
+}
+.glyphicon-book:before {
+ content: "\e043";
+}
+.glyphicon-bookmark:before {
+ content: "\e044";
+}
+.glyphicon-print:before {
+ content: "\e045";
+}
+.glyphicon-camera:before {
+ content: "\e046";
+}
+.glyphicon-font:before {
+ content: "\e047";
+}
+.glyphicon-bold:before {
+ content: "\e048";
+}
+.glyphicon-italic:before {
+ content: "\e049";
+}
+.glyphicon-text-height:before {
+ content: "\e050";
+}
+.glyphicon-text-width:before {
+ content: "\e051";
+}
+.glyphicon-align-left:before {
+ content: "\e052";
+}
+.glyphicon-align-center:before {
+ content: "\e053";
+}
+.glyphicon-align-right:before {
+ content: "\e054";
+}
+.glyphicon-align-justify:before {
+ content: "\e055";
+}
+.glyphicon-list:before {
+ content: "\e056";
+}
+.glyphicon-indent-left:before {
+ content: "\e057";
+}
+.glyphicon-indent-right:before {
+ content: "\e058";
+}
+.glyphicon-facetime-video:before {
+ content: "\e059";
+}
+.glyphicon-picture:before {
+ content: "\e060";
+}
+.glyphicon-map-marker:before {
+ content: "\e062";
+}
+.glyphicon-adjust:before {
+ content: "\e063";
+}
+.glyphicon-tint:before {
+ content: "\e064";
+}
+.glyphicon-edit:before {
+ content: "\e065";
+}
+.glyphicon-share:before {
+ content: "\e066";
+}
+.glyphicon-check:before {
+ content: "\e067";
+}
+.glyphicon-move:before {
+ content: "\e068";
+}
+.glyphicon-step-backward:before {
+ content: "\e069";
+}
+.glyphicon-fast-backward:before {
+ content: "\e070";
+}
+.glyphicon-backward:before {
+ content: "\e071";
+}
+.glyphicon-play:before {
+ content: "\e072";
+}
+.glyphicon-pause:before {
+ content: "\e073";
+}
+.glyphicon-stop:before {
+ content: "\e074";
+}
+.glyphicon-forward:before {
+ content: "\e075";
+}
+.glyphicon-fast-forward:before {
+ content: "\e076";
+}
+.glyphicon-step-forward:before {
+ content: "\e077";
+}
+.glyphicon-eject:before {
+ content: "\e078";
+}
+.glyphicon-chevron-left:before {
+ content: "\e079";
+}
+.glyphicon-chevron-right:before {
+ content: "\e080";
+}
+.glyphicon-plus-sign:before {
+ content: "\e081";
+}
+.glyphicon-minus-sign:before {
+ content: "\e082";
+}
+.glyphicon-remove-sign:before {
+ content: "\e083";
+}
+.glyphicon-ok-sign:before {
+ content: "\e084";
+}
+.glyphicon-question-sign:before {
+ content: "\e085";
+}
+.glyphicon-info-sign:before {
+ content: "\e086";
+}
+.glyphicon-screenshot:before {
+ content: "\e087";
+}
+.glyphicon-remove-circle:before {
+ content: "\e088";
+}
+.glyphicon-ok-circle:before {
+ content: "\e089";
+}
+.glyphicon-ban-circle:before {
+ content: "\e090";
+}
+.glyphicon-arrow-left:before {
+ content: "\e091";
+}
+.glyphicon-arrow-right:before {
+ content: "\e092";
+}
+.glyphicon-arrow-up:before {
+ content: "\e093";
+}
+.glyphicon-arrow-down:before {
+ content: "\e094";
+}
+.glyphicon-share-alt:before {
+ content: "\e095";
+}
+.glyphicon-resize-full:before {
+ content: "\e096";
+}
+.glyphicon-resize-small:before {
+ content: "\e097";
+}
+.glyphicon-exclamation-sign:before {
+ content: "\e101";
+}
+.glyphicon-gift:before {
+ content: "\e102";
+}
+.glyphicon-leaf:before {
+ content: "\e103";
+}
+.glyphicon-fire:before {
+ content: "\e104";
+}
+.glyphicon-eye-open:before {
+ content: "\e105";
+}
+.glyphicon-eye-close:before {
+ content: "\e106";
+}
+.glyphicon-warning-sign:before {
+ content: "\e107";
+}
+.glyphicon-plane:before {
+ content: "\e108";
+}
+.glyphicon-calendar:before {
+ content: "\e109";
+}
+.glyphicon-random:before {
+ content: "\e110";
+}
+.glyphicon-comment:before {
+ content: "\e111";
+}
+.glyphicon-magnet:before {
+ content: "\e112";
+}
+.glyphicon-chevron-up:before {
+ content: "\e113";
+}
+.glyphicon-chevron-down:before {
+ content: "\e114";
+}
+.glyphicon-retweet:before {
+ content: "\e115";
+}
+.glyphicon-shopping-cart:before {
+ content: "\e116";
+}
+.glyphicon-folder-close:before {
+ content: "\e117";
+}
+.glyphicon-folder-open:before {
+ content: "\e118";
+}
+.glyphicon-resize-vertical:before {
+ content: "\e119";
+}
+.glyphicon-resize-horizontal:before {
+ content: "\e120";
+}
+.glyphicon-hdd:before {
+ content: "\e121";
+}
+.glyphicon-bullhorn:before {
+ content: "\e122";
+}
+.glyphicon-bell:before {
+ content: "\e123";
+}
+.glyphicon-certificate:before {
+ content: "\e124";
+}
+.glyphicon-thumbs-up:before {
+ content: "\e125";
+}
+.glyphicon-thumbs-down:before {
+ content: "\e126";
+}
+.glyphicon-hand-right:before {
+ content: "\e127";
+}
+.glyphicon-hand-left:before {
+ content: "\e128";
+}
+.glyphicon-hand-up:before {
+ content: "\e129";
+}
+.glyphicon-hand-down:before {
+ content: "\e130";
+}
+.glyphicon-circle-arrow-right:before {
+ content: "\e131";
+}
+.glyphicon-circle-arrow-left:before {
+ content: "\e132";
+}
+.glyphicon-circle-arrow-up:before {
+ content: "\e133";
+}
+.glyphicon-circle-arrow-down:before {
+ content: "\e134";
+}
+.glyphicon-globe:before {
+ content: "\e135";
+}
+.glyphicon-wrench:before {
+ content: "\e136";
+}
+.glyphicon-tasks:before {
+ content: "\e137";
+}
+.glyphicon-filter:before {
+ content: "\e138";
+}
+.glyphicon-briefcase:before {
+ content: "\e139";
+}
+.glyphicon-fullscreen:before {
+ content: "\e140";
+}
+.glyphicon-dashboard:before {
+ content: "\e141";
+}
+.glyphicon-paperclip:before {
+ content: "\e142";
+}
+.glyphicon-heart-empty:before {
+ content: "\e143";
+}
+.glyphicon-link:before {
+ content: "\e144";
+}
+.glyphicon-phone:before {
+ content: "\e145";
+}
+.glyphicon-pushpin:before {
+ content: "\e146";
+}
+.glyphicon-usd:before {
+ content: "\e148";
+}
+.glyphicon-gbp:before {
+ content: "\e149";
+}
+.glyphicon-sort:before {
+ content: "\e150";
+}
+.glyphicon-sort-by-alphabet:before {
+ content: "\e151";
+}
+.glyphicon-sort-by-alphabet-alt:before {
+ content: "\e152";
+}
+.glyphicon-sort-by-order:before {
+ content: "\e153";
+}
+.glyphicon-sort-by-order-alt:before {
+ content: "\e154";
+}
+.glyphicon-sort-by-attributes:before {
+ content: "\e155";
+}
+.glyphicon-sort-by-attributes-alt:before {
+ content: "\e156";
+}
+.glyphicon-unchecked:before {
+ content: "\e157";
+}
+.glyphicon-expand:before {
+ content: "\e158";
+}
+.glyphicon-collapse-down:before {
+ content: "\e159";
+}
+.glyphicon-collapse-up:before {
+ content: "\e160";
+}
+.glyphicon-log-in:before {
+ content: "\e161";
+}
+.glyphicon-flash:before {
+ content: "\e162";
+}
+.glyphicon-log-out:before {
+ content: "\e163";
+}
+.glyphicon-new-window:before {
+ content: "\e164";
+}
+.glyphicon-record:before {
+ content: "\e165";
+}
+.glyphicon-save:before {
+ content: "\e166";
+}
+.glyphicon-open:before {
+ content: "\e167";
+}
+.glyphicon-saved:before {
+ content: "\e168";
+}
+.glyphicon-import:before {
+ content: "\e169";
+}
+.glyphicon-export:before {
+ content: "\e170";
+}
+.glyphicon-send:before {
+ content: "\e171";
+}
+.glyphicon-floppy-disk:before {
+ content: "\e172";
+}
+.glyphicon-floppy-saved:before {
+ content: "\e173";
+}
+.glyphicon-floppy-remove:before {
+ content: "\e174";
+}
+.glyphicon-floppy-save:before {
+ content: "\e175";
+}
+.glyphicon-floppy-open:before {
+ content: "\e176";
+}
+.glyphicon-credit-card:before {
+ content: "\e177";
+}
+.glyphicon-transfer:before {
+ content: "\e178";
+}
+.glyphicon-cutlery:before {
+ content: "\e179";
+}
+.glyphicon-header:before {
+ content: "\e180";
+}
+.glyphicon-compressed:before {
+ content: "\e181";
+}
+.glyphicon-earphone:before {
+ content: "\e182";
+}
+.glyphicon-phone-alt:before {
+ content: "\e183";
+}
+.glyphicon-tower:before {
+ content: "\e184";
+}
+.glyphicon-stats:before {
+ content: "\e185";
+}
+.glyphicon-sd-video:before {
+ content: "\e186";
+}
+.glyphicon-hd-video:before {
+ content: "\e187";
+}
+.glyphicon-subtitles:before {
+ content: "\e188";
+}
+.glyphicon-sound-stereo:before {
+ content: "\e189";
+}
+.glyphicon-sound-dolby:before {
+ content: "\e190";
+}
+.glyphicon-sound-5-1:before {
+ content: "\e191";
+}
+.glyphicon-sound-6-1:before {
+ content: "\e192";
+}
+.glyphicon-sound-7-1:before {
+ content: "\e193";
+}
+.glyphicon-copyright-mark:before {
+ content: "\e194";
+}
+.glyphicon-registration-mark:before {
+ content: "\e195";
+}
+.glyphicon-cloud-download:before {
+ content: "\e197";
+}
+.glyphicon-cloud-upload:before {
+ content: "\e198";
+}
+.glyphicon-tree-conifer:before {
+ content: "\e199";
+}
+.glyphicon-tree-deciduous:before {
+ content: "\e200";
+}
+.glyphicon-cd:before {
+ content: "\e201";
+}
+.glyphicon-save-file:before {
+ content: "\e202";
+}
+.glyphicon-open-file:before {
+ content: "\e203";
+}
+.glyphicon-level-up:before {
+ content: "\e204";
+}
+.glyphicon-copy:before {
+ content: "\e205";
+}
+.glyphicon-paste:before {
+ content: "\e206";
+}
+.glyphicon-alert:before {
+ content: "\e209";
+}
+.glyphicon-equalizer:before {
+ content: "\e210";
+}
+.glyphicon-king:before {
+ content: "\e211";
+}
+.glyphicon-queen:before {
+ content: "\e212";
+}
+.glyphicon-pawn:before {
+ content: "\e213";
+}
+.glyphicon-bishop:before {
+ content: "\e214";
+}
+.glyphicon-knight:before {
+ content: "\e215";
+}
+.glyphicon-baby-formula:before {
+ content: "\e216";
+}
+.glyphicon-tent:before {
+ content: "\26fa";
+}
+.glyphicon-blackboard:before {
+ content: "\e218";
+}
+.glyphicon-bed:before {
+ content: "\e219";
+}
+.glyphicon-apple:before {
+ content: "\f8ff";
+}
+.glyphicon-erase:before {
+ content: "\e221";
+}
+.glyphicon-hourglass:before {
+ content: "\231b";
+}
+.glyphicon-lamp:before {
+ content: "\e223";
+}
+.glyphicon-duplicate:before {
+ content: "\e224";
+}
+.glyphicon-piggy-bank:before {
+ content: "\e225";
+}
+.glyphicon-scissors:before {
+ content: "\e226";
+}
+.glyphicon-bitcoin:before {
+ content: "\e227";
+}
+.glyphicon-btc:before {
+ content: "\e227";
+}
+.glyphicon-xbt:before {
+ content: "\e227";
+}
+.glyphicon-yen:before {
+ content: "\00a5";
+}
+.glyphicon-jpy:before {
+ content: "\00a5";
+}
+.glyphicon-ruble:before {
+ content: "\20bd";
+}
+.glyphicon-rub:before {
+ content: "\20bd";
+}
+.glyphicon-scale:before {
+ content: "\e230";
+}
+.glyphicon-ice-lolly:before {
+ content: "\e231";
+}
+.glyphicon-ice-lolly-tasted:before {
+ content: "\e232";
+}
+.glyphicon-education:before {
+ content: "\e233";
+}
+.glyphicon-option-horizontal:before {
+ content: "\e234";
+}
+.glyphicon-option-vertical:before {
+ content: "\e235";
+}
+.glyphicon-menu-hamburger:before {
+ content: "\e236";
+}
+.glyphicon-modal-window:before {
+ content: "\e237";
+}
+.glyphicon-oil:before {
+ content: "\e238";
+}
+.glyphicon-grain:before {
+ content: "\e239";
+}
+.glyphicon-sunglasses:before {
+ content: "\e240";
+}
+.glyphicon-text-size:before {
+ content: "\e241";
+}
+.glyphicon-text-color:before {
+ content: "\e242";
+}
+.glyphicon-text-background:before {
+ content: "\e243";
+}
+.glyphicon-object-align-top:before {
+ content: "\e244";
+}
+.glyphicon-object-align-bottom:before {
+ content: "\e245";
+}
+.glyphicon-object-align-horizontal:before {
+ content: "\e246";
+}
+.glyphicon-object-align-left:before {
+ content: "\e247";
+}
+.glyphicon-object-align-vertical:before {
+ content: "\e248";
+}
+.glyphicon-object-align-right:before {
+ content: "\e249";
+}
+.glyphicon-triangle-right:before {
+ content: "\e250";
+}
+.glyphicon-triangle-left:before {
+ content: "\e251";
+}
+.glyphicon-triangle-bottom:before {
+ content: "\e252";
+}
+.glyphicon-triangle-top:before {
+ content: "\e253";
+}
+.glyphicon-console:before {
+ content: "\e254";
+}
+.glyphicon-superscript:before {
+ content: "\e255";
+}
+.glyphicon-subscript:before {
+ content: "\e256";
+}
+.glyphicon-menu-left:before {
+ content: "\e257";
+}
+.glyphicon-menu-right:before {
+ content: "\e258";
+}
+.glyphicon-menu-down:before {
+ content: "\e259";
+}
+.glyphicon-menu-up:before {
+ content: "\e260";
+}
+* {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+*:before,
+*:after {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+html {
+ font-size: 10px;
+
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+body {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #008dd2;
+ background-color: #008dd2;
+}
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+a {
+ color: #008dd2;
+ text-decoration: none;
+}
+a:hover,
+a:focus {
+ color: #036595;
+ text-decoration: underline;
+}
+a:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+figure {
+ margin: 0;
+}
+img {
+ vertical-align: middle;
+}
+.img-responsive,
+.thumbnail > img,
+.thumbnail a > img,
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+.img-rounded {
+ border-radius: 0;
+}
+.img-thumbnail {
+ display: inline-block;
+ max-width: 100%;
+ height: auto;
+ padding: 4px;
+ line-height: 1.42857143;
+ background-color: #008dd2;
+ border: 1px solid #ddd;
+ border-radius: 0;
+ -webkit-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+ transition: all .2s ease-in-out;
+}
+.img-circle {
+ border-radius: 50%;
+}
+hr {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ border: 0;
+ border-top: 1px solid #008dd2;
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
+[role="button"] {
+ cursor: pointer;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6 {
+ font-family: inherit;
+ font-weight: 500;
+ line-height: 1.1;
+ color: inherit;
+}
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small,
+.h1 small,
+.h2 small,
+.h3 small,
+.h4 small,
+.h5 small,
+.h6 small,
+h1 .small,
+h2 .small,
+h3 .small,
+h4 .small,
+h5 .small,
+h6 .small,
+.h1 .small,
+.h2 .small,
+.h3 .small,
+.h4 .small,
+.h5 .small,
+.h6 .small {
+ font-weight: normal;
+ line-height: 1;
+ color: #008dd2;
+}
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3 {
+ margin-top: 20px;
+ margin-bottom: 10px;
+}
+h1 small,
+.h1 small,
+h2 small,
+.h2 small,
+h3 small,
+.h3 small,
+h1 .small,
+.h1 .small,
+h2 .small,
+.h2 .small,
+h3 .small,
+.h3 .small {
+ font-size: 65%;
+}
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+h4 small,
+.h4 small,
+h5 small,
+.h5 small,
+h6 small,
+.h6 small,
+h4 .small,
+.h4 .small,
+h5 .small,
+.h5 .small,
+h6 .small,
+.h6 .small {
+ font-size: 75%;
+}
+h1,
+.h1 {
+ font-size: 36px;
+}
+h2,
+.h2 {
+ font-size: 30px;
+}
+h3,
+.h3 {
+ font-size: 24px;
+}
+h4,
+.h4 {
+ font-size: 18px;
+}
+h5,
+.h5 {
+ font-size: 14px;
+}
+h6,
+.h6 {
+ font-size: 12px;
+}
+p {
+ margin: 0 0 10px;
+}
+.lead {
+ margin-bottom: 20px;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 1.4;
+}
+@media (min-width: 768px) {
+ .lead {
+ font-size: 21px;
+ }
+}
+small,
+.small {
+ font-size: 85%;
+}
+mark,
+.mark {
+ padding: .2em;
+ background-color: #fcf8e3;
+}
+.text-left {
+ text-align: left;
+}
+.text-right {
+ text-align: right;
+}
+.text-center {
+ text-align: center;
+}
+.text-justify {
+ text-align: justify;
+}
+.text-nowrap {
+ white-space: nowrap;
+}
+.text-lowercase {
+ text-transform: lowercase;
+}
+.text-uppercase {
+ text-transform: uppercase;
+}
+.text-capitalize {
+ text-transform: capitalize;
+}
+.text-muted {
+ color: #008dd2;
+}
+.text-primary {
+ color: #008dd2;
+}
+a.text-primary:hover,
+a.text-primary:focus {
+ color: #036595;
+}
+.text-success {
+ color: #3c763d;
+}
+a.text-success:hover,
+a.text-success:focus {
+ color: #2b542c;
+}
+.text-info {
+ color: #31708f;
+}
+a.text-info:hover,
+a.text-info:focus {
+ color: #245269;
+}
+.text-warning {
+ color: #8a6d3b;
+}
+a.text-warning:hover,
+a.text-warning:focus {
+ color: #66512c;
+}
+.text-danger {
+ color: #a94442;
+}
+a.text-danger:hover,
+a.text-danger:focus {
+ color: #843534;
+}
+.bg-primary {
+ color: #fff;
+ background-color: #008dd2;
+}
+a.bg-primary:hover,
+a.bg-primary:focus {
+ background-color: #036595;
+}
+.bg-success {
+ background-color: #dff0d8;
+}
+a.bg-success:hover,
+a.bg-success:focus {
+ background-color: #c1e2b3;
+}
+.bg-info {
+ background-color: #d9edf7;
+}
+a.bg-info:hover,
+a.bg-info:focus {
+ background-color: #afd9ee;
+}
+.bg-warning {
+ background-color: #fcf8e3;
+}
+a.bg-warning:hover,
+a.bg-warning:focus {
+ background-color: #f7ecb5;
+}
+.bg-danger {
+ background-color: #f2dede;
+}
+a.bg-danger:hover,
+a.bg-danger:focus {
+ background-color: #e4b9b9;
+}
+.page-header {
+ padding-bottom: 9px;
+ margin: 40px 0 20px;
+ border-bottom: 1px solid #008dd2;
+}
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: 10px;
+}
+ul ul,
+ol ul,
+ul ol,
+ol ol {
+ margin-bottom: 0;
+}
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline {
+ padding-left: 0;
+ margin-left: -5px;
+ list-style: none;
+}
+.list-inline > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
+}
+dl {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+dt,
+dd {
+ line-height: 1.42857143;
+}
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .dl-horizontal dd {
+ margin-left: 180px;
+ }
+}
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #008dd2;
+}
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+blockquote {
+ padding: 10px 20px;
+ margin: 0 0 20px;
+ font-size: 17.5px;
+ border-left: 5px solid #008dd2;
+}
+blockquote p:last-child,
+blockquote ul:last-child,
+blockquote ol:last-child {
+ margin-bottom: 0;
+}
+blockquote footer,
+blockquote small,
+blockquote .small {
+ display: block;
+ font-size: 80%;
+ line-height: 1.42857143;
+ color: #008dd2;
+}
+blockquote footer:before,
+blockquote small:before,
+blockquote .small:before {
+ content: '\2014 \00A0';
+}
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid #008dd2;
+ border-left: 0;
+}
+.blockquote-reverse footer:before,
+blockquote.pull-right footer:before,
+.blockquote-reverse small:before,
+blockquote.pull-right small:before,
+.blockquote-reverse .small:before,
+blockquote.pull-right .small:before {
+ content: '';
+}
+.blockquote-reverse footer:after,
+blockquote.pull-right footer:after,
+.blockquote-reverse small:after,
+blockquote.pull-right small:after,
+.blockquote-reverse .small:after,
+blockquote.pull-right .small:after {
+ content: '\00A0 \2014';
+}
+address {
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 1.42857143;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
+}
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #c7254e;
+ background-color: #f9f2f4;
+ border-radius: 0;
+}
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: #fff;
+ background-color: #ccc;
+ border-radius: 0;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+}
+kbd kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: bold;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 1.42857143;
+ color: #008dd2;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border-radius: 0;
+}
+pre code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+}
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+.container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+@media (min-width: 768px) {
+ .container {
+ width: 750px;
+ }
+}
+@media (min-width: 992px) {
+ .container {
+ width: 970px;
+ }
+}
+@media (min-width: 1200px) {
+ .container {
+ width: 1170px;
+ }
+}
+.container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+.row {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
+ position: relative;
+ min-height: 1px;
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
+ float: left;
+}
+.col-xs-12 {
+ width: 100%;
+}
+.col-xs-11 {
+ width: 91.66666667%;
+}
+.col-xs-10 {
+ width: 83.33333333%;
+}
+.col-xs-9 {
+ width: 75%;
+}
+.col-xs-8 {
+ width: 66.66666667%;
+}
+.col-xs-7 {
+ width: 58.33333333%;
+}
+.col-xs-6 {
+ width: 50%;
+}
+.col-xs-5 {
+ width: 41.66666667%;
+}
+.col-xs-4 {
+ width: 33.33333333%;
+}
+.col-xs-3 {
+ width: 25%;
+}
+.col-xs-2 {
+ width: 16.66666667%;
+}
+.col-xs-1 {
+ width: 8.33333333%;
+}
+.col-xs-pull-12 {
+ right: 100%;
+}
+.col-xs-pull-11 {
+ right: 91.66666667%;
+}
+.col-xs-pull-10 {
+ right: 83.33333333%;
+}
+.col-xs-pull-9 {
+ right: 75%;
+}
+.col-xs-pull-8 {
+ right: 66.66666667%;
+}
+.col-xs-pull-7 {
+ right: 58.33333333%;
+}
+.col-xs-pull-6 {
+ right: 50%;
+}
+.col-xs-pull-5 {
+ right: 41.66666667%;
+}
+.col-xs-pull-4 {
+ right: 33.33333333%;
+}
+.col-xs-pull-3 {
+ right: 25%;
+}
+.col-xs-pull-2 {
+ right: 16.66666667%;
+}
+.col-xs-pull-1 {
+ right: 8.33333333%;
+}
+.col-xs-pull-0 {
+ right: auto;
+}
+.col-xs-push-12 {
+ left: 100%;
+}
+.col-xs-push-11 {
+ left: 91.66666667%;
+}
+.col-xs-push-10 {
+ left: 83.33333333%;
+}
+.col-xs-push-9 {
+ left: 75%;
+}
+.col-xs-push-8 {
+ left: 66.66666667%;
+}
+.col-xs-push-7 {
+ left: 58.33333333%;
+}
+.col-xs-push-6 {
+ left: 50%;
+}
+.col-xs-push-5 {
+ left: 41.66666667%;
+}
+.col-xs-push-4 {
+ left: 33.33333333%;
+}
+.col-xs-push-3 {
+ left: 25%;
+}
+.col-xs-push-2 {
+ left: 16.66666667%;
+}
+.col-xs-push-1 {
+ left: 8.33333333%;
+}
+.col-xs-push-0 {
+ left: auto;
+}
+.col-xs-offset-12 {
+ margin-left: 100%;
+}
+.col-xs-offset-11 {
+ margin-left: 91.66666667%;
+}
+.col-xs-offset-10 {
+ margin-left: 83.33333333%;
+}
+.col-xs-offset-9 {
+ margin-left: 75%;
+}
+.col-xs-offset-8 {
+ margin-left: 66.66666667%;
+}
+.col-xs-offset-7 {
+ margin-left: 58.33333333%;
+}
+.col-xs-offset-6 {
+ margin-left: 50%;
+}
+.col-xs-offset-5 {
+ margin-left: 41.66666667%;
+}
+.col-xs-offset-4 {
+ margin-left: 33.33333333%;
+}
+.col-xs-offset-3 {
+ margin-left: 25%;
+}
+.col-xs-offset-2 {
+ margin-left: 16.66666667%;
+}
+.col-xs-offset-1 {
+ margin-left: 8.33333333%;
+}
+.col-xs-offset-0 {
+ margin-left: 0;
+}
+@media (min-width: 768px) {
+ .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
+ float: left;
+ }
+ .col-sm-12 {
+ width: 100%;
+ }
+ .col-sm-11 {
+ width: 91.66666667%;
+ }
+ .col-sm-10 {
+ width: 83.33333333%;
+ }
+ .col-sm-9 {
+ width: 75%;
+ }
+ .col-sm-8 {
+ width: 66.66666667%;
+ }
+ .col-sm-7 {
+ width: 58.33333333%;
+ }
+ .col-sm-6 {
+ width: 50%;
+ }
+ .col-sm-5 {
+ width: 41.66666667%;
+ }
+ .col-sm-4 {
+ width: 33.33333333%;
+ }
+ .col-sm-3 {
+ width: 25%;
+ }
+ .col-sm-2 {
+ width: 16.66666667%;
+ }
+ .col-sm-1 {
+ width: 8.33333333%;
+ }
+ .col-sm-pull-12 {
+ right: 100%;
+ }
+ .col-sm-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-sm-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-sm-pull-9 {
+ right: 75%;
+ }
+ .col-sm-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-sm-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-sm-pull-6 {
+ right: 50%;
+ }
+ .col-sm-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-sm-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-sm-pull-3 {
+ right: 25%;
+ }
+ .col-sm-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-sm-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-sm-pull-0 {
+ right: auto;
+ }
+ .col-sm-push-12 {
+ left: 100%;
+ }
+ .col-sm-push-11 {
+ left: 91.66666667%;
+ }
+ .col-sm-push-10 {
+ left: 83.33333333%;
+ }
+ .col-sm-push-9 {
+ left: 75%;
+ }
+ .col-sm-push-8 {
+ left: 66.66666667%;
+ }
+ .col-sm-push-7 {
+ left: 58.33333333%;
+ }
+ .col-sm-push-6 {
+ left: 50%;
+ }
+ .col-sm-push-5 {
+ left: 41.66666667%;
+ }
+ .col-sm-push-4 {
+ left: 33.33333333%;
+ }
+ .col-sm-push-3 {
+ left: 25%;
+ }
+ .col-sm-push-2 {
+ left: 16.66666667%;
+ }
+ .col-sm-push-1 {
+ left: 8.33333333%;
+ }
+ .col-sm-push-0 {
+ left: auto;
+ }
+ .col-sm-offset-12 {
+ margin-left: 100%;
+ }
+ .col-sm-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-sm-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-sm-offset-9 {
+ margin-left: 75%;
+ }
+ .col-sm-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-sm-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-sm-offset-6 {
+ margin-left: 50%;
+ }
+ .col-sm-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-sm-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-sm-offset-3 {
+ margin-left: 25%;
+ }
+ .col-sm-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-sm-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-sm-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 992px) {
+ .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
+ float: left;
+ }
+ .col-md-12 {
+ width: 100%;
+ }
+ .col-md-11 {
+ width: 91.66666667%;
+ }
+ .col-md-10 {
+ width: 83.33333333%;
+ }
+ .col-md-9 {
+ width: 75%;
+ }
+ .col-md-8 {
+ width: 66.66666667%;
+ }
+ .col-md-7 {
+ width: 58.33333333%;
+ }
+ .col-md-6 {
+ width: 50%;
+ }
+ .col-md-5 {
+ width: 41.66666667%;
+ }
+ .col-md-4 {
+ width: 33.33333333%;
+ }
+ .col-md-3 {
+ width: 25%;
+ }
+ .col-md-2 {
+ width: 16.66666667%;
+ }
+ .col-md-1 {
+ width: 8.33333333%;
+ }
+ .col-md-pull-12 {
+ right: 100%;
+ }
+ .col-md-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-md-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-md-pull-9 {
+ right: 75%;
+ }
+ .col-md-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-md-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-md-pull-6 {
+ right: 50%;
+ }
+ .col-md-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-md-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-md-pull-3 {
+ right: 25%;
+ }
+ .col-md-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-md-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-md-pull-0 {
+ right: auto;
+ }
+ .col-md-push-12 {
+ left: 100%;
+ }
+ .col-md-push-11 {
+ left: 91.66666667%;
+ }
+ .col-md-push-10 {
+ left: 83.33333333%;
+ }
+ .col-md-push-9 {
+ left: 75%;
+ }
+ .col-md-push-8 {
+ left: 66.66666667%;
+ }
+ .col-md-push-7 {
+ left: 58.33333333%;
+ }
+ .col-md-push-6 {
+ left: 50%;
+ }
+ .col-md-push-5 {
+ left: 41.66666667%;
+ }
+ .col-md-push-4 {
+ left: 33.33333333%;
+ }
+ .col-md-push-3 {
+ left: 25%;
+ }
+ .col-md-push-2 {
+ left: 16.66666667%;
+ }
+ .col-md-push-1 {
+ left: 8.33333333%;
+ }
+ .col-md-push-0 {
+ left: auto;
+ }
+ .col-md-offset-12 {
+ margin-left: 100%;
+ }
+ .col-md-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-md-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-md-offset-9 {
+ margin-left: 75%;
+ }
+ .col-md-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-md-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-md-offset-6 {
+ margin-left: 50%;
+ }
+ .col-md-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-md-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-md-offset-3 {
+ margin-left: 25%;
+ }
+ .col-md-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-md-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-md-offset-0 {
+ margin-left: 0;
+ }
+}
+@media (min-width: 1200px) {
+ .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
+ float: left;
+ }
+ .col-lg-12 {
+ width: 100%;
+ }
+ .col-lg-11 {
+ width: 91.66666667%;
+ }
+ .col-lg-10 {
+ width: 83.33333333%;
+ }
+ .col-lg-9 {
+ width: 75%;
+ }
+ .col-lg-8 {
+ width: 66.66666667%;
+ }
+ .col-lg-7 {
+ width: 58.33333333%;
+ }
+ .col-lg-6 {
+ width: 50%;
+ }
+ .col-lg-5 {
+ width: 41.66666667%;
+ }
+ .col-lg-4 {
+ width: 33.33333333%;
+ }
+ .col-lg-3 {
+ width: 25%;
+ }
+ .col-lg-2 {
+ width: 16.66666667%;
+ }
+ .col-lg-1 {
+ width: 8.33333333%;
+ }
+ .col-lg-pull-12 {
+ right: 100%;
+ }
+ .col-lg-pull-11 {
+ right: 91.66666667%;
+ }
+ .col-lg-pull-10 {
+ right: 83.33333333%;
+ }
+ .col-lg-pull-9 {
+ right: 75%;
+ }
+ .col-lg-pull-8 {
+ right: 66.66666667%;
+ }
+ .col-lg-pull-7 {
+ right: 58.33333333%;
+ }
+ .col-lg-pull-6 {
+ right: 50%;
+ }
+ .col-lg-pull-5 {
+ right: 41.66666667%;
+ }
+ .col-lg-pull-4 {
+ right: 33.33333333%;
+ }
+ .col-lg-pull-3 {
+ right: 25%;
+ }
+ .col-lg-pull-2 {
+ right: 16.66666667%;
+ }
+ .col-lg-pull-1 {
+ right: 8.33333333%;
+ }
+ .col-lg-pull-0 {
+ right: auto;
+ }
+ .col-lg-push-12 {
+ left: 100%;
+ }
+ .col-lg-push-11 {
+ left: 91.66666667%;
+ }
+ .col-lg-push-10 {
+ left: 83.33333333%;
+ }
+ .col-lg-push-9 {
+ left: 75%;
+ }
+ .col-lg-push-8 {
+ left: 66.66666667%;
+ }
+ .col-lg-push-7 {
+ left: 58.33333333%;
+ }
+ .col-lg-push-6 {
+ left: 50%;
+ }
+ .col-lg-push-5 {
+ left: 41.66666667%;
+ }
+ .col-lg-push-4 {
+ left: 33.33333333%;
+ }
+ .col-lg-push-3 {
+ left: 25%;
+ }
+ .col-lg-push-2 {
+ left: 16.66666667%;
+ }
+ .col-lg-push-1 {
+ left: 8.33333333%;
+ }
+ .col-lg-push-0 {
+ left: auto;
+ }
+ .col-lg-offset-12 {
+ margin-left: 100%;
+ }
+ .col-lg-offset-11 {
+ margin-left: 91.66666667%;
+ }
+ .col-lg-offset-10 {
+ margin-left: 83.33333333%;
+ }
+ .col-lg-offset-9 {
+ margin-left: 75%;
+ }
+ .col-lg-offset-8 {
+ margin-left: 66.66666667%;
+ }
+ .col-lg-offset-7 {
+ margin-left: 58.33333333%;
+ }
+ .col-lg-offset-6 {
+ margin-left: 50%;
+ }
+ .col-lg-offset-5 {
+ margin-left: 41.66666667%;
+ }
+ .col-lg-offset-4 {
+ margin-left: 33.33333333%;
+ }
+ .col-lg-offset-3 {
+ margin-left: 25%;
+ }
+ .col-lg-offset-2 {
+ margin-left: 16.66666667%;
+ }
+ .col-lg-offset-1 {
+ margin-left: 8.33333333%;
+ }
+ .col-lg-offset-0 {
+ margin-left: 0;
+ }
+}
+table {
+ background-color: transparent;
+}
+caption {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ color: #008dd2;
+ text-align: left;
+}
+th {
+ text-align: left;
+}
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 20px;
+}
+.table > thead > tr > th,
+.table > tbody > tr > th,
+.table > tfoot > tr > th,
+.table > thead > tr > td,
+.table > tbody > tr > td,
+.table > tfoot > tr > td {
+ padding: 8px;
+ line-height: 1.42857143;
+ vertical-align: top;
+ border-top: 1px solid #008dd2;
+}
+.table > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid #008dd2;
+}
+.table > caption + thead > tr:first-child > th,
+.table > colgroup + thead > tr:first-child > th,
+.table > thead:first-child > tr:first-child > th,
+.table > caption + thead > tr:first-child > td,
+.table > colgroup + thead > tr:first-child > td,
+.table > thead:first-child > tr:first-child > td {
+ border-top: 0;
+}
+.table > tbody + tbody {
+ border-top: 2px solid #008dd2;
+}
+.table .table {
+ background-color: #008dd2;
+}
+.table-condensed > thead > tr > th,
+.table-condensed > tbody > tr > th,
+.table-condensed > tfoot > tr > th,
+.table-condensed > thead > tr > td,
+.table-condensed > tbody > tr > td,
+.table-condensed > tfoot > tr > td {
+ padding: 5px;
+}
+.table-bordered {
+ border: 1px solid #008dd2;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > tbody > tr > th,
+.table-bordered > tfoot > tr > th,
+.table-bordered > thead > tr > td,
+.table-bordered > tbody > tr > td,
+.table-bordered > tfoot > tr > td {
+ border: 1px solid #008dd2;
+}
+.table-bordered > thead > tr > th,
+.table-bordered > thead > tr > td {
+ border-bottom-width: 2px;
+}
+.table-striped > tbody > tr:nth-of-type(odd) {
+ background-color: #f9f9f9;
+}
+.table-hover > tbody > tr:hover {
+ background-color: #f5f5f5;
+}
+table col[class*="col-"] {
+ position: static;
+ display: table-column;
+ float: none;
+}
+table td[class*="col-"],
+table th[class*="col-"] {
+ position: static;
+ display: table-cell;
+ float: none;
+}
+.table > thead > tr > td.active,
+.table > tbody > tr > td.active,
+.table > tfoot > tr > td.active,
+.table > thead > tr > th.active,
+.table > tbody > tr > th.active,
+.table > tfoot > tr > th.active,
+.table > thead > tr.active > td,
+.table > tbody > tr.active > td,
+.table > tfoot > tr.active > td,
+.table > thead > tr.active > th,
+.table > tbody > tr.active > th,
+.table > tfoot > tr.active > th {
+ background-color: #f5f5f5;
+}
+.table-hover > tbody > tr > td.active:hover,
+.table-hover > tbody > tr > th.active:hover,
+.table-hover > tbody > tr.active:hover > td,
+.table-hover > tbody > tr:hover > .active,
+.table-hover > tbody > tr.active:hover > th {
+ background-color: #e8e8e8;
+}
+.table > thead > tr > td.success,
+.table > tbody > tr > td.success,
+.table > tfoot > tr > td.success,
+.table > thead > tr > th.success,
+.table > tbody > tr > th.success,
+.table > tfoot > tr > th.success,
+.table > thead > tr.success > td,
+.table > tbody > tr.success > td,
+.table > tfoot > tr.success > td,
+.table > thead > tr.success > th,
+.table > tbody > tr.success > th,
+.table > tfoot > tr.success > th {
+ background-color: #dff0d8;
+}
+.table-hover > tbody > tr > td.success:hover,
+.table-hover > tbody > tr > th.success:hover,
+.table-hover > tbody > tr.success:hover > td,
+.table-hover > tbody > tr:hover > .success,
+.table-hover > tbody > tr.success:hover > th {
+ background-color: #d0e9c6;
+}
+.table > thead > tr > td.info,
+.table > tbody > tr > td.info,
+.table > tfoot > tr > td.info,
+.table > thead > tr > th.info,
+.table > tbody > tr > th.info,
+.table > tfoot > tr > th.info,
+.table > thead > tr.info > td,
+.table > tbody > tr.info > td,
+.table > tfoot > tr.info > td,
+.table > thead > tr.info > th,
+.table > tbody > tr.info > th,
+.table > tfoot > tr.info > th {
+ background-color: #d9edf7;
+}
+.table-hover > tbody > tr > td.info:hover,
+.table-hover > tbody > tr > th.info:hover,
+.table-hover > tbody > tr.info:hover > td,
+.table-hover > tbody > tr:hover > .info,
+.table-hover > tbody > tr.info:hover > th {
+ background-color: #c4e3f3;
+}
+.table > thead > tr > td.warning,
+.table > tbody > tr > td.warning,
+.table > tfoot > tr > td.warning,
+.table > thead > tr > th.warning,
+.table > tbody > tr > th.warning,
+.table > tfoot > tr > th.warning,
+.table > thead > tr.warning > td,
+.table > tbody > tr.warning > td,
+.table > tfoot > tr.warning > td,
+.table > thead > tr.warning > th,
+.table > tbody > tr.warning > th,
+.table > tfoot > tr.warning > th {
+ background-color: #fcf8e3;
+}
+.table-hover > tbody > tr > td.warning:hover,
+.table-hover > tbody > tr > th.warning:hover,
+.table-hover > tbody > tr.warning:hover > td,
+.table-hover > tbody > tr:hover > .warning,
+.table-hover > tbody > tr.warning:hover > th {
+ background-color: #faf2cc;
+}
+.table > thead > tr > td.danger,
+.table > tbody > tr > td.danger,
+.table > tfoot > tr > td.danger,
+.table > thead > tr > th.danger,
+.table > tbody > tr > th.danger,
+.table > tfoot > tr > th.danger,
+.table > thead > tr.danger > td,
+.table > tbody > tr.danger > td,
+.table > tfoot > tr.danger > td,
+.table > thead > tr.danger > th,
+.table > tbody > tr.danger > th,
+.table > tfoot > tr.danger > th {
+ background-color: #f2dede;
+}
+.table-hover > tbody > tr > td.danger:hover,
+.table-hover > tbody > tr > th.danger:hover,
+.table-hover > tbody > tr.danger:hover > td,
+.table-hover > tbody > tr:hover > .danger,
+.table-hover > tbody > tr.danger:hover > th {
+ background-color: #ebcccc;
+}
+.table-responsive {
+ min-height: .01%;
+ overflow-x: auto;
+}
+@media screen and (max-width: 767px) {
+ .table-responsive {
+ width: 100%;
+ margin-bottom: 15px;
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid #008dd2;
+ }
+ .table-responsive > .table {
+ margin-bottom: 0;
+ }
+ .table-responsive > .table > thead > tr > th,
+ .table-responsive > .table > tbody > tr > th,
+ .table-responsive > .table > tfoot > tr > th,
+ .table-responsive > .table > thead > tr > td,
+ .table-responsive > .table > tbody > tr > td,
+ .table-responsive > .table > tfoot > tr > td {
+ white-space: nowrap;
+ }
+ .table-responsive > .table-bordered {
+ border: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:first-child,
+ .table-responsive > .table-bordered > tbody > tr > th:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+ .table-responsive > .table-bordered > thead > tr > td:first-child,
+ .table-responsive > .table-bordered > tbody > tr > td:first-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+ }
+ .table-responsive > .table-bordered > thead > tr > th:last-child,
+ .table-responsive > .table-bordered > tbody > tr > th:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+ .table-responsive > .table-bordered > thead > tr > td:last-child,
+ .table-responsive > .table-bordered > tbody > tr > td:last-child,
+ .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+ }
+ .table-responsive > .table-bordered > tbody > tr:last-child > th,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > th,
+ .table-responsive > .table-bordered > tbody > tr:last-child > td,
+ .table-responsive > .table-bordered > tfoot > tr:last-child > td {
+ border-bottom: 0;
+ }
+}
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: inherit;
+ color: #008dd2;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+label {
+ display: inline-block;
+ max-width: 100%;
+ margin-bottom: 5px;
+ font-weight: normal;
+}
+input[type="search"] {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ line-height: normal;
+}
+input[type="file"] {
+ display: block;
+}
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+select[multiple],
+select[size] {
+ height: auto;
+}
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+output {
+ display: block;
+ padding-top: 7px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #008dd2;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ line-height: 1.42857143;
+ color: #000000;
+ background-color: #fff;
+ background-image: none;
+ border: 1px solid #ccc;
+ border-radius: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
+ -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+ transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+.form-control:focus {
+ border-color: #66afe9;
+ outline: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
+}
+.form-control::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+.form-control:-ms-input-placeholder {
+ color: #999;
+}
+.form-control::-webkit-input-placeholder {
+ color: #999;
+}
+.form-control::-ms-expand {
+ background-color: transparent;
+ border: 0;
+}
+.form-control[disabled],
+.form-control[readonly],
+fieldset[disabled] .form-control {
+ background-color: #008dd2;
+ opacity: 1;
+}
+.form-control[disabled],
+fieldset[disabled] .form-control {
+ cursor: not-allowed;
+}
+textarea.form-control {
+ height: auto;
+}
+input[type="search"] {
+ -webkit-appearance: none;
+}
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"].form-control,
+ input[type="time"].form-control,
+ input[type="datetime-local"].form-control,
+ input[type="month"].form-control {
+ line-height: 34px;
+ }
+ input[type="date"].input-sm,
+ input[type="time"].input-sm,
+ input[type="datetime-local"].input-sm,
+ input[type="month"].input-sm,
+ .input-group-sm input[type="date"],
+ .input-group-sm input[type="time"],
+ .input-group-sm input[type="datetime-local"],
+ .input-group-sm input[type="month"] {
+ line-height: 30px;
+ }
+ input[type="date"].input-lg,
+ input[type="time"].input-lg,
+ input[type="datetime-local"].input-lg,
+ input[type="month"].input-lg,
+ .input-group-lg input[type="date"],
+ .input-group-lg input[type="time"],
+ .input-group-lg input[type="datetime-local"],
+ .input-group-lg input[type="month"] {
+ line-height: 46px;
+ }
+}
+.form-group {
+ margin-bottom: 15px;
+}
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.radio label,
+.checkbox label {
+ min-height: 20px;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ cursor: pointer;
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px;
+}
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px;
+}
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: normal;
+ vertical-align: middle;
+ cursor: pointer;
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px;
+}
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"].disabled,
+input[type="checkbox"].disabled,
+fieldset[disabled] input[type="radio"],
+fieldset[disabled] input[type="checkbox"] {
+ cursor: not-allowed;
+}
+.radio-inline.disabled,
+.checkbox-inline.disabled,
+fieldset[disabled] .radio-inline,
+fieldset[disabled] .checkbox-inline {
+ cursor: not-allowed;
+}
+.radio.disabled label,
+.checkbox.disabled label,
+fieldset[disabled] .radio label,
+fieldset[disabled] .checkbox label {
+ cursor: not-allowed;
+}
+.form-control-static {
+ min-height: 34px;
+ padding-top: 7px;
+ padding-bottom: 7px;
+ margin-bottom: 0;
+}
+.form-control-static.input-lg,
+.form-control-static.input-sm {
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-sm {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 0;
+}
+select.input-sm {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-sm,
+select[multiple].input-sm {
+ height: auto;
+}
+.form-group-sm .form-control {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 0;
+}
+.form-group-sm select.form-control {
+ height: 30px;
+ line-height: 30px;
+}
+.form-group-sm textarea.form-control,
+.form-group-sm select[multiple].form-control {
+ height: auto;
+}
+.form-group-sm .form-control-static {
+ height: 30px;
+ min-height: 32px;
+ padding: 6px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.input-lg {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 0;
+}
+select.input-lg {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-lg,
+select[multiple].input-lg {
+ height: auto;
+}
+.form-group-lg .form-control {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 0;
+}
+.form-group-lg select.form-control {
+ height: 46px;
+ line-height: 46px;
+}
+.form-group-lg textarea.form-control,
+.form-group-lg select[multiple].form-control {
+ height: auto;
+}
+.form-group-lg .form-control-static {
+ height: 46px;
+ min-height: 38px;
+ padding: 11px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.has-feedback {
+ position: relative;
+}
+.has-feedback .form-control {
+ padding-right: 42.5px;
+}
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ display: block;
+ width: 34px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ pointer-events: none;
+}
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+ width: 46px;
+ height: 46px;
+ line-height: 46px;
+}
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+.has-success .help-block,
+.has-success .control-label,
+.has-success .radio,
+.has-success .checkbox,
+.has-success .radio-inline,
+.has-success .checkbox-inline,
+.has-success.radio label,
+.has-success.checkbox label,
+.has-success.radio-inline label,
+.has-success.checkbox-inline label {
+ color: #3c763d;
+}
+.has-success .form-control {
+ border-color: #3c763d;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-success .form-control:focus {
+ border-color: #2b542c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
+}
+.has-success .input-group-addon {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #3c763d;
+}
+.has-success .form-control-feedback {
+ color: #3c763d;
+}
+.has-warning .help-block,
+.has-warning .control-label,
+.has-warning .radio,
+.has-warning .checkbox,
+.has-warning .radio-inline,
+.has-warning .checkbox-inline,
+.has-warning.radio label,
+.has-warning.checkbox label,
+.has-warning.radio-inline label,
+.has-warning.checkbox-inline label {
+ color: #8a6d3b;
+}
+.has-warning .form-control {
+ border-color: #8a6d3b;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-warning .form-control:focus {
+ border-color: #66512c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
+}
+.has-warning .input-group-addon {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #8a6d3b;
+}
+.has-warning .form-control-feedback {
+ color: #8a6d3b;
+}
+.has-error .help-block,
+.has-error .control-label,
+.has-error .radio,
+.has-error .checkbox,
+.has-error .radio-inline,
+.has-error .checkbox-inline,
+.has-error.radio label,
+.has-error.checkbox label,
+.has-error.radio-inline label,
+.has-error.checkbox-inline label {
+ color: #a94442;
+}
+.has-error .form-control {
+ border-color: #a94442;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
+}
+.has-error .form-control:focus {
+ border-color: #843534;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
+}
+.has-error .input-group-addon {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #a94442;
+}
+.has-error .form-control-feedback {
+ color: #a94442;
+}
+.has-feedback label ~ .form-control-feedback {
+ top: 25px;
+}
+.has-feedback label.sr-only ~ .form-control-feedback {
+ top: 0;
+}
+.help-block {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: #21a7ff;
+}
+@media (min-width: 768px) {
+ .form-inline .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .form-inline .form-control-static {
+ display: inline-block;
+ }
+ .form-inline .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .form-inline .input-group .input-group-addon,
+ .form-inline .input-group .input-group-btn,
+ .form-inline .input-group .form-control {
+ width: auto;
+ }
+ .form-inline .input-group > .form-control {
+ width: 100%;
+ }
+ .form-inline .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio,
+ .form-inline .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .form-inline .radio label,
+ .form-inline .checkbox label {
+ padding-left: 0;
+ }
+ .form-inline .radio input[type="radio"],
+ .form-inline .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .form-inline .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox,
+.form-horizontal .radio-inline,
+.form-horizontal .checkbox-inline {
+ padding-top: 7px;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.form-horizontal .radio,
+.form-horizontal .checkbox {
+ min-height: 27px;
+}
+.form-horizontal .form-group {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .control-label {
+ padding-top: 7px;
+ margin-bottom: 0;
+ text-align: right;
+ }
+}
+.form-horizontal .has-feedback .form-control-feedback {
+ right: 15px;
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-lg .control-label {
+ padding-top: 11px;
+ font-size: 18px;
+ }
+}
+@media (min-width: 768px) {
+ .form-horizontal .form-group-sm .control-label {
+ padding-top: 6px;
+ font-size: 12px;
+ }
+}
+.btn {
+ display: inline-block;
+ padding: 6px 12px;
+ margin-bottom: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 0;
+}
+.btn:focus,
+.btn:active:focus,
+.btn.active:focus,
+.btn.focus,
+.btn:active.focus,
+.btn.active.focus {
+ outline: thin dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.btn:hover,
+.btn:focus,
+.btn.focus {
+ color: #ccc;
+ text-decoration: none;
+}
+.btn:active,
+.btn.active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn.disabled,
+.btn[disabled],
+fieldset[disabled] .btn {
+ cursor: not-allowed;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ opacity: .65;
+}
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+.btn-default {
+ color: #ccc;
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default:focus,
+.btn-default.focus {
+ color: #ccc;
+ background-color: #e6e6e6;
+ border-color: #8c8c8c;
+}
+.btn-default:hover {
+ color: #ccc;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ color: #ccc;
+ background-color: #e6e6e6;
+ border-color: #adadad;
+}
+.btn-default:active:hover,
+.btn-default.active:hover,
+.open > .dropdown-toggle.btn-default:hover,
+.btn-default:active:focus,
+.btn-default.active:focus,
+.open > .dropdown-toggle.btn-default:focus,
+.btn-default:active.focus,
+.btn-default.active.focus,
+.open > .dropdown-toggle.btn-default.focus {
+ color: #ccc;
+ background-color: #d4d4d4;
+ border-color: #8c8c8c;
+}
+.btn-default:active,
+.btn-default.active,
+.open > .dropdown-toggle.btn-default {
+ background-image: none;
+}
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus {
+ background-color: #fff;
+ border-color: #ccc;
+}
+.btn-default .badge {
+ color: #fff;
+ background-color: #ccc;
+}
+.btn-primary {
+ color: #fff;
+ background-color: #008dd2;
+ border-color: #008dd2;
+}
+.btn-primary:focus,
+.btn-primary.focus {
+ color: #fff;
+ background-color: #036595;
+ border-color: #000508;
+}
+.btn-primary:hover {
+ color: #fff;
+ background-color: #036595;
+ border-color: #036595;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ color: #fff;
+ background-color: #036595;
+ border-color: #036595;
+}
+.btn-primary:active:hover,
+.btn-primary.active:hover,
+.open > .dropdown-toggle.btn-primary:hover,
+.btn-primary:active:focus,
+.btn-primary.active:focus,
+.open > .dropdown-toggle.btn-primary:focus,
+.btn-primary:active.focus,
+.btn-primary.active.focus,
+.open > .dropdown-toggle.btn-primary.focus {
+ color: #fff;
+ background-color: #036595;
+ border-color: #000508;
+}
+.btn-primary:active,
+.btn-primary.active,
+.open > .dropdown-toggle.btn-primary {
+ background-image: none;
+}
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus {
+ background-color: #008dd2;
+ border-color: #008dd2;
+}
+.btn-primary .badge {
+ color: #008dd2;
+ background-color: #fff;
+}
+.btn-success {
+ color: #fff;
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success:focus,
+.btn-success.focus {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #255625;
+}
+.btn-success:hover {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ color: #fff;
+ background-color: #449d44;
+ border-color: #398439;
+}
+.btn-success:active:hover,
+.btn-success.active:hover,
+.open > .dropdown-toggle.btn-success:hover,
+.btn-success:active:focus,
+.btn-success.active:focus,
+.open > .dropdown-toggle.btn-success:focus,
+.btn-success:active.focus,
+.btn-success.active.focus,
+.open > .dropdown-toggle.btn-success.focus {
+ color: #fff;
+ background-color: #398439;
+ border-color: #255625;
+}
+.btn-success:active,
+.btn-success.active,
+.open > .dropdown-toggle.btn-success {
+ background-image: none;
+}
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus {
+ background-color: #5cb85c;
+ border-color: #4cae4c;
+}
+.btn-success .badge {
+ color: #5cb85c;
+ background-color: #fff;
+}
+.btn-info {
+ color: #fff;
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info:focus,
+.btn-info.focus {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #1b6d85;
+}
+.btn-info:hover {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ color: #fff;
+ background-color: #31b0d5;
+ border-color: #269abc;
+}
+.btn-info:active:hover,
+.btn-info.active:hover,
+.open > .dropdown-toggle.btn-info:hover,
+.btn-info:active:focus,
+.btn-info.active:focus,
+.open > .dropdown-toggle.btn-info:focus,
+.btn-info:active.focus,
+.btn-info.active.focus,
+.open > .dropdown-toggle.btn-info.focus {
+ color: #fff;
+ background-color: #269abc;
+ border-color: #1b6d85;
+}
+.btn-info:active,
+.btn-info.active,
+.open > .dropdown-toggle.btn-info {
+ background-image: none;
+}
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus {
+ background-color: #5bc0de;
+ border-color: #46b8da;
+}
+.btn-info .badge {
+ color: #5bc0de;
+ background-color: #fff;
+}
+.btn-warning {
+ color: #fff;
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning:focus,
+.btn-warning.focus {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #985f0d;
+}
+.btn-warning:hover {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ color: #fff;
+ background-color: #ec971f;
+ border-color: #d58512;
+}
+.btn-warning:active:hover,
+.btn-warning.active:hover,
+.open > .dropdown-toggle.btn-warning:hover,
+.btn-warning:active:focus,
+.btn-warning.active:focus,
+.open > .dropdown-toggle.btn-warning:focus,
+.btn-warning:active.focus,
+.btn-warning.active.focus,
+.open > .dropdown-toggle.btn-warning.focus {
+ color: #fff;
+ background-color: #d58512;
+ border-color: #985f0d;
+}
+.btn-warning:active,
+.btn-warning.active,
+.open > .dropdown-toggle.btn-warning {
+ background-image: none;
+}
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus {
+ background-color: #f0ad4e;
+ border-color: #eea236;
+}
+.btn-warning .badge {
+ color: #f0ad4e;
+ background-color: #fff;
+}
+.btn-danger {
+ color: #fff;
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger:focus,
+.btn-danger.focus {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #761c19;
+}
+.btn-danger:hover {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ color: #fff;
+ background-color: #c9302c;
+ border-color: #ac2925;
+}
+.btn-danger:active:hover,
+.btn-danger.active:hover,
+.open > .dropdown-toggle.btn-danger:hover,
+.btn-danger:active:focus,
+.btn-danger.active:focus,
+.open > .dropdown-toggle.btn-danger:focus,
+.btn-danger:active.focus,
+.btn-danger.active.focus,
+.open > .dropdown-toggle.btn-danger.focus {
+ color: #fff;
+ background-color: #ac2925;
+ border-color: #761c19;
+}
+.btn-danger:active,
+.btn-danger.active,
+.open > .dropdown-toggle.btn-danger {
+ background-image: none;
+}
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus {
+ background-color: #d9534f;
+ border-color: #d43f3a;
+}
+.btn-danger .badge {
+ color: #d9534f;
+ background-color: #fff;
+}
+.btn-link {
+ font-weight: normal;
+ color: #008dd2;
+ border-radius: 0;
+}
+.btn-link,
+.btn-link:active,
+.btn-link.active,
+.btn-link[disabled],
+fieldset[disabled] .btn-link {
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-link,
+.btn-link:hover,
+.btn-link:focus,
+.btn-link:active {
+ border-color: transparent;
+}
+.btn-link:hover,
+.btn-link:focus {
+ color: #036595;
+ text-decoration: underline;
+ background-color: transparent;
+}
+.btn-link[disabled]:hover,
+fieldset[disabled] .btn-link:hover,
+.btn-link[disabled]:focus,
+fieldset[disabled] .btn-link:focus {
+ color: #008dd2;
+ text-decoration: none;
+}
+.btn-lg,
+.btn-group-lg > .btn {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 0;
+}
+.btn-sm,
+.btn-group-sm > .btn {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 0;
+}
+.btn-xs,
+.btn-group-xs > .btn {
+ padding: 1px 5px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 0;
+}
+.btn-block {
+ display: block;
+ width: 100%;
+}
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity .15s linear;
+ -o-transition: opacity .15s linear;
+ transition: opacity .15s linear;
+}
+.fade.in {
+ opacity: 1;
+}
+.collapse {
+ display: none;
+}
+.collapse.in {
+ display: block;
+}
+tr.collapse.in {
+ display: table-row;
+}
+tbody.collapse.in {
+ display: table-row-group;
+}
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: .35s;
+ -o-transition-duration: .35s;
+ transition-duration: .35s;
+ -webkit-transition-property: height, visibility;
+ -o-transition-property: height, visibility;
+ transition-property: height, visibility;
+}
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: 4px dashed;
+ border-top: 4px solid \9;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+}
+.dropup,
+.dropdown {
+ position: relative;
+}
+.dropdown-toggle:focus {
+ outline: 0;
+}
+.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;
+ font-size: 14px;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .15);
+ border-radius: 0;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu .divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.42857143;
+ color: #008dd2;
+ white-space: nowrap;
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ color: #008dd2;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #fff;
+ text-decoration: none;
+ background-color: #008dd2;
+ outline: 0;
+}
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #008dd2;
+}
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
+.open > .dropdown-menu {
+ display: block;
+}
+.open > a {
+ outline: 0;
+}
+.dropdown-menu-right {
+ right: 0;
+ left: auto;
+}
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ color: #008dd2;
+ white-space: nowrap;
+}
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990;
+}
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: 4px dashed;
+ border-bottom: 4px solid \9;
+}
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+}
+@media (min-width: 768px) {
+ .navbar-right .dropdown-menu {
+ right: 0;
+ left: auto;
+ }
+ .navbar-right .dropdown-menu-left {
+ right: auto;
+ left: 0;
+ }
+}
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+}
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+ position: relative;
+ float: left;
+}
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group-vertical > .btn:focus,
+.btn-group > .btn:active,
+.btn-group-vertical > .btn:active,
+.btn-group > .btn.active,
+.btn-group-vertical > .btn.active {
+ z-index: 2;
+}
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+ margin-left: -1px;
+}
+.btn-toolbar {
+ margin-left: -5px;
+}
+.btn-toolbar .btn,
+.btn-toolbar .btn-group,
+.btn-toolbar .input-group {
+ float: left;
+}
+.btn-toolbar > .btn,
+.btn-toolbar > .btn-group,
+.btn-toolbar > .input-group {
+ margin-left: 5px;
+}
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+.btn-group > .btn:first-child {
+ margin-left: 0;
+}
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px;
+}
+.btn-group.open .dropdown-toggle {
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
+}
+.btn-group.open .dropdown-toggle.btn-link {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn .caret {
+ margin-left: 0;
+}
+.btn-lg .caret {
+ border-width: 5px 5px 0;
+ border-bottom-width: 0;
+}
+.dropup .btn-lg .caret {
+ border-width: 0 5px 5px;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group,
+.btn-group-vertical > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+}
+.btn-group-vertical > .btn-group > .btn {
+ float: none;
+}
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+}
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+}
+.btn-group-justified > .btn,
+.btn-group-justified > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%;
+}
+.btn-group-justified > .btn-group .btn {
+ width: 100%;
+}
+.btn-group-justified > .btn-group .dropdown-menu {
+ left: auto;
+}
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+.input-group {
+ position: relative;
+ display: table;
+ border-collapse: separate;
+}
+.input-group[class*="col-"] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0;
+}
+.input-group .form-control {
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+}
+.input-group .form-control:focus {
+ z-index: 3;
+}
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 0;
+}
+select.input-group-lg > .form-control,
+select.input-group-lg > .input-group-addon,
+select.input-group-lg > .input-group-btn > .btn {
+ height: 46px;
+ line-height: 46px;
+}
+textarea.input-group-lg > .form-control,
+textarea.input-group-lg > .input-group-addon,
+textarea.input-group-lg > .input-group-btn > .btn,
+select[multiple].input-group-lg > .form-control,
+select[multiple].input-group-lg > .input-group-addon,
+select[multiple].input-group-lg > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 0;
+}
+select.input-group-sm > .form-control,
+select.input-group-sm > .input-group-addon,
+select.input-group-sm > .input-group-btn > .btn {
+ height: 30px;
+ line-height: 30px;
+}
+textarea.input-group-sm > .form-control,
+textarea.input-group-sm > .input-group-addon,
+textarea.input-group-sm > .input-group-btn > .btn,
+select[multiple].input-group-sm > .form-control,
+select[multiple].input-group-sm > .input-group-addon,
+select[multiple].input-group-sm > .input-group-btn > .btn {
+ height: auto;
+}
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+}
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+ border-radius: 0;
+}
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+.input-group-addon {
+ padding: 6px 12px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 1;
+ color: #008dd2;
+ text-align: center;
+ background-color: #008dd2;
+ border: 1px solid #ccc;
+ border-radius: 0;
+}
+.input-group-addon.input-sm {
+ padding: 5px 10px;
+ font-size: 12px;
+ border-radius: 0;
+}
+.input-group-addon.input-lg {
+ padding: 10px 16px;
+ font-size: 18px;
+ border-radius: 0;
+}
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+ margin-top: 0;
+}
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group-addon:first-child {
+ border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.input-group-addon:last-child {
+ border-left: 0;
+}
+.input-group-btn {
+ position: relative;
+ font-size: 0;
+ white-space: nowrap;
+}
+.input-group-btn > .btn {
+ position: relative;
+}
+.input-group-btn > .btn + .btn {
+ margin-left: -1px;
+}
+.input-group-btn > .btn:hover,
+.input-group-btn > .btn:focus,
+.input-group-btn > .btn:active {
+ z-index: 2;
+}
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group {
+ margin-right: -1px;
+}
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group {
+ z-index: 2;
+ margin-left: -1px;
+}
+.nav {
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+.nav > li {
+ position: relative;
+ display: block;
+}
+.nav > li > a {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+}
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #008dd2;
+}
+.nav > li.disabled > a {
+ color: #008dd2;
+}
+.nav > li.disabled > a:hover,
+.nav > li.disabled > a:focus {
+ color: #008dd2;
+ text-decoration: none;
+ cursor: not-allowed;
+ background-color: transparent;
+}
+.nav .open > a,
+.nav .open > a:hover,
+.nav .open > a:focus {
+ background-color: #008dd2;
+ border-color: #008dd2;
+}
+.nav .nav-divider {
+ height: 1px;
+ margin: 9px 0;
+ overflow: hidden;
+ background-color: #e5e5e5;
+}
+.nav > li > a > img {
+ max-width: none;
+}
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+.nav-tabs > li {
+ float: left;
+ margin-bottom: -1px;
+}
+.nav-tabs > li > a {
+ margin-right: 2px;
+ line-height: 1.42857143;
+ border: 1px solid transparent;
+ border-radius: 0 0 0 0;
+}
+.nav-tabs > li > a:hover {
+ border-color: #008dd2 #008dd2 #ddd;
+}
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus {
+ color: #008dd2;
+ cursor: default;
+ background-color: #008dd2;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+.nav-tabs.nav-justified {
+ width: 100%;
+ border-bottom: 0;
+}
+.nav-tabs.nav-justified > li {
+ float: none;
+}
+.nav-tabs.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-tabs.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-tabs.nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs.nav-justified > li > a {
+ margin-right: 0;
+ border-radius: 0;
+}
+.nav-tabs.nav-justified > .active > a,
+.nav-tabs.nav-justified > .active > a:hover,
+.nav-tabs.nav-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs.nav-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 0 0 0 0;
+ }
+ .nav-tabs.nav-justified > .active > a,
+ .nav-tabs.nav-justified > .active > a:hover,
+ .nav-tabs.nav-justified > .active > a:focus {
+ border-bottom-color: #008dd2;
+ }
+}
+.nav-pills > li {
+ float: left;
+}
+.nav-pills > li > a {
+ border-radius: 0;
+}
+.nav-pills > li + li {
+ margin-left: 2px;
+}
+.nav-pills > li.active > a,
+.nav-pills > li.active > a:hover,
+.nav-pills > li.active > a:focus {
+ color: #fff;
+ background-color: #008dd2;
+}
+.nav-stacked > li {
+ float: none;
+}
+.nav-stacked > li + li {
+ margin-top: 2px;
+ margin-left: 0;
+}
+.nav-justified {
+ width: 100%;
+}
+.nav-justified > li {
+ float: none;
+}
+.nav-justified > li > a {
+ margin-bottom: 5px;
+ text-align: center;
+}
+.nav-justified > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+}
+@media (min-width: 768px) {
+ .nav-justified > li {
+ display: table-cell;
+ width: 1%;
+ }
+ .nav-justified > li > a {
+ margin-bottom: 0;
+ }
+}
+.nav-tabs-justified {
+ border-bottom: 0;
+}
+.nav-tabs-justified > li > a {
+ margin-right: 0;
+ border-radius: 0;
+}
+.nav-tabs-justified > .active > a,
+.nav-tabs-justified > .active > a:hover,
+.nav-tabs-justified > .active > a:focus {
+ border: 1px solid #ddd;
+}
+@media (min-width: 768px) {
+ .nav-tabs-justified > li > a {
+ border-bottom: 1px solid #ddd;
+ border-radius: 0 0 0 0;
+ }
+ .nav-tabs-justified > .active > a,
+ .nav-tabs-justified > .active > a:hover,
+ .nav-tabs-justified > .active > a:focus {
+ border-bottom-color: #008dd2;
+ }
+}
+.tab-content > .tab-pane {
+ display: none;
+}
+.tab-content > .active {
+ display: block;
+}
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar {
+ position: relative;
+ min-height: 70px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+}
+@media (min-width: 768px) {
+ .navbar {
+ border-radius: 0;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-header {
+ float: left;
+ }
+}
+.navbar-collapse {
+ padding-right: 15px;
+ padding-left: 15px;
+ overflow-x: visible;
+ -webkit-overflow-scrolling: touch;
+ border-top: 1px solid transparent;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+}
+.navbar-collapse.in {
+ overflow-y: auto;
+}
+@media (min-width: 768px) {
+ .navbar-collapse {
+ width: auto;
+ border-top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-collapse.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0;
+ overflow: visible !important;
+ }
+ .navbar-collapse.in {
+ overflow-y: visible;
+ }
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-static-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+.navbar-fixed-top .navbar-collapse,
+.navbar-fixed-bottom .navbar-collapse {
+ max-height: 340px;
+}
+@media (max-device-width: 480px) and (orientation: landscape) {
+ .navbar-fixed-top .navbar-collapse,
+ .navbar-fixed-bottom .navbar-collapse {
+ max-height: 200px;
+ }
+}
+.container > .navbar-header,
+.container-fluid > .navbar-header,
+.container > .navbar-collapse,
+.container-fluid > .navbar-collapse {
+ margin-right: -15px;
+ margin-left: -15px;
+}
+@media (min-width: 768px) {
+ .container > .navbar-header,
+ .container-fluid > .navbar-header,
+ .container > .navbar-collapse,
+ .container-fluid > .navbar-collapse {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+.navbar-static-top {
+ z-index: 1000;
+ border-width: 0 0 1px;
+}
+@media (min-width: 768px) {
+ .navbar-static-top {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+@media (min-width: 768px) {
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ border-radius: 0;
+ }
+}
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0;
+ border-width: 1px 0 0;
+}
+.navbar-brand {
+ float: left;
+ height: 70px;
+ padding: 25px 15px;
+ font-size: 18px;
+ line-height: 20px;
+}
+.navbar-brand:hover,
+.navbar-brand:focus {
+ text-decoration: none;
+}
+.navbar-brand > img {
+ display: block;
+}
+@media (min-width: 768px) {
+ .navbar > .container .navbar-brand,
+ .navbar > .container-fluid .navbar-brand {
+ margin-left: -15px;
+ }
+}
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-top: 18px;
+ margin-right: 15px;
+ margin-bottom: 18px;
+ background-color: transparent;
+ background-image: none;
+ border: 1px solid transparent;
+ border-radius: 0;
+}
+.navbar-toggle:focus {
+ outline: 0;
+}
+.navbar-toggle .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+}
+.navbar-toggle .icon-bar + .icon-bar {
+ margin-top: 4px;
+}
+@media (min-width: 768px) {
+ .navbar-toggle {
+ display: none;
+ }
+}
+.navbar-nav {
+ margin: 12.5px -15px;
+}
+.navbar-nav > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: 20px;
+}
+@media (max-width: 767px) {
+ .navbar-nav .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+ .navbar-nav .open .dropdown-menu > li > a,
+ .navbar-nav .open .dropdown-menu .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a {
+ line-height: 20px;
+ }
+ .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-nav .open .dropdown-menu > li > a:focus {
+ background-image: none;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-nav {
+ float: left;
+ margin: 0;
+ }
+ .navbar-nav > li {
+ float: left;
+ }
+ .navbar-nav > li > a {
+ padding-top: 25px;
+ padding-bottom: 25px;
+ }
+}
+.navbar-form {
+ padding: 10px 15px;
+ margin-top: 18px;
+ margin-right: -15px;
+ margin-bottom: 18px;
+ margin-left: -15px;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ -webkit-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);
+}
+@media (min-width: 768px) {
+ .navbar-form .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control {
+ display: inline-block;
+ width: auto;
+ vertical-align: middle;
+ }
+ .navbar-form .form-control-static {
+ display: inline-block;
+ }
+ .navbar-form .input-group {
+ display: inline-table;
+ vertical-align: middle;
+ }
+ .navbar-form .input-group .input-group-addon,
+ .navbar-form .input-group .input-group-btn,
+ .navbar-form .input-group .form-control {
+ width: auto;
+ }
+ .navbar-form .input-group > .form-control {
+ width: 100%;
+ }
+ .navbar-form .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio,
+ .navbar-form .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+ .navbar-form .radio label,
+ .navbar-form .checkbox label {
+ padding-left: 0;
+ }
+ .navbar-form .radio input[type="radio"],
+ .navbar-form .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+ .navbar-form .has-feedback .form-control-feedback {
+ top: 0;
+ }
+}
+@media (max-width: 767px) {
+ .navbar-form .form-group {
+ margin-bottom: 5px;
+ }
+ .navbar-form .form-group:last-child {
+ margin-bottom: 0;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-form {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ }
+}
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.navbar-btn {
+ margin-top: 18px;
+ margin-bottom: 18px;
+}
+.navbar-btn.btn-sm {
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+.navbar-btn.btn-xs {
+ margin-top: 24px;
+ margin-bottom: 24px;
+}
+.navbar-text {
+ margin-top: 25px;
+ margin-bottom: 25px;
+}
+@media (min-width: 768px) {
+ .navbar-text {
+ float: left;
+ margin-right: 15px;
+ margin-left: 15px;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-left {
+ float: left !important;
+ }
+ .navbar-right {
+ float: right !important;
+ margin-right: -15px;
+ }
+ .navbar-right ~ .navbar-right {
+ margin-right: 0;
+ }
+}
+.navbar-default {
+ background-color: #008dd2;
+ border-color: #008dd2;
+}
+.navbar-default .navbar-brand {
+ color: #fff;
+}
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #e6e6e6;
+ background-color: transparent;
+}
+.navbar-default .navbar-text {
+ color: #fff;
+}
+.navbar-default .navbar-nav > li > a {
+ color: #fff;
+}
+.navbar-default .navbar-nav > li > a:hover,
+.navbar-default .navbar-nav > li > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+.navbar-default .navbar-nav > .active > a,
+.navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+ color: #ccc;
+ background-color: #008dd2;
+}
+.navbar-default .navbar-nav > .disabled > a,
+.navbar-default .navbar-nav > .disabled > a:hover,
+.navbar-default .navbar-nav > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+}
+.navbar-default .navbar-toggle {
+ border-color: #ddd;
+}
+.navbar-default .navbar-toggle:hover,
+.navbar-default .navbar-toggle:focus {
+ background-color: #ddd;
+}
+.navbar-default .navbar-toggle .icon-bar {
+ background-color: #888;
+}
+.navbar-default .navbar-collapse,
+.navbar-default .navbar-form {
+ border-color: #008dd2;
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .open > a:hover,
+.navbar-default .navbar-nav > .open > a:focus {
+ color: #ccc;
+ background-color: #008dd2;
+}
+@media (max-width: 767px) {
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #fff;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #ccc;
+ background-color: #008dd2;
+ }
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #ccc;
+ background-color: transparent;
+ }
+}
+.navbar-default .navbar-link {
+ color: #fff;
+}
+.navbar-default .navbar-link:hover {
+ color: #ccc;
+}
+.navbar-default .btn-link {
+ color: #fff;
+}
+.navbar-default .btn-link:hover,
+.navbar-default .btn-link:focus {
+ color: #ccc;
+}
+.navbar-default .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-default .btn-link:hover,
+.navbar-default .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-default .btn-link:focus {
+ color: #ccc;
+}
+.navbar-inverse {
+ background-color: #222;
+ border-color: #080808;
+}
+.navbar-inverse .navbar-brand {
+ color: #008fee;
+}
+.navbar-inverse .navbar-brand:hover,
+.navbar-inverse .navbar-brand:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-text {
+ color: #008fee;
+}
+.navbar-inverse .navbar-nav > li > a {
+ color: #008fee;
+}
+.navbar-inverse .navbar-nav > li > a:hover,
+.navbar-inverse .navbar-nav > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-nav > .active > a,
+.navbar-inverse .navbar-nav > .active > a:hover,
+.navbar-inverse .navbar-nav > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+.navbar-inverse .navbar-nav > .disabled > a,
+.navbar-inverse .navbar-nav > .disabled > a:hover,
+.navbar-inverse .navbar-nav > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+}
+.navbar-inverse .navbar-toggle {
+ border-color: #ccc;
+}
+.navbar-inverse .navbar-toggle:hover,
+.navbar-inverse .navbar-toggle:focus {
+ background-color: #ccc;
+}
+.navbar-inverse .navbar-toggle .icon-bar {
+ background-color: #fff;
+}
+.navbar-inverse .navbar-collapse,
+.navbar-inverse .navbar-form {
+ border-color: #101010;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .open > a:hover,
+.navbar-inverse .navbar-nav > .open > a:focus {
+ color: #fff;
+ background-color: #080808;
+}
+@media (max-width: 767px) {
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
+ border-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
+ color: #008fee;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
+ color: #fff;
+ background-color: transparent;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
+ color: #fff;
+ background-color: #080808;
+ }
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,
+ .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
+ color: #444;
+ background-color: transparent;
+ }
+}
+.navbar-inverse .navbar-link {
+ color: #008fee;
+}
+.navbar-inverse .navbar-link:hover {
+ color: #fff;
+}
+.navbar-inverse .btn-link {
+ color: #008fee;
+}
+.navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link:focus {
+ color: #fff;
+}
+.navbar-inverse .btn-link[disabled]:hover,
+fieldset[disabled] .navbar-inverse .btn-link:hover,
+.navbar-inverse .btn-link[disabled]:focus,
+fieldset[disabled] .navbar-inverse .btn-link:focus {
+ color: #444;
+}
+.breadcrumb {
+ padding: 8px 15px;
+ margin-bottom: 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ border-radius: 0;
+}
+.breadcrumb > li {
+ display: inline-block;
+}
+.breadcrumb > li + li:before {
+ padding: 0 5px;
+ color: #ccc;
+ content: "/\00a0";
+}
+.breadcrumb > .active {
+ color: #008dd2;
+}
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: 20px 0;
+ border-radius: 0;
+}
+.pagination > li {
+ display: inline;
+}
+.pagination > li > a,
+.pagination > li > span {
+ position: relative;
+ float: left;
+ padding: 6px 12px;
+ margin-left: -1px;
+ line-height: 1.42857143;
+ color: #008dd2;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.pagination > li:first-child > a,
+.pagination > li:first-child > span {
+ margin-left: 0;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.pagination > li:last-child > a,
+.pagination > li:last-child > span {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.pagination > li > a:hover,
+.pagination > li > span:hover,
+.pagination > li > a:focus,
+.pagination > li > span:focus {
+ z-index: 2;
+ color: #036595;
+ background-color: #008dd2;
+ border-color: #ddd;
+}
+.pagination > .active > a,
+.pagination > .active > span,
+.pagination > .active > a:hover,
+.pagination > .active > span:hover,
+.pagination > .active > a:focus,
+.pagination > .active > span:focus {
+ z-index: 3;
+ color: #fff;
+ cursor: default;
+ background-color: #008dd2;
+ border-color: #008dd2;
+}
+.pagination > .disabled > span,
+.pagination > .disabled > span:hover,
+.pagination > .disabled > span:focus,
+.pagination > .disabled > a,
+.pagination > .disabled > a:hover,
+.pagination > .disabled > a:focus {
+ color: #008dd2;
+ cursor: not-allowed;
+ background-color: #fff;
+ border-color: #ddd;
+}
+.pagination-lg > li > a,
+.pagination-lg > li > span {
+ padding: 10px 16px;
+ font-size: 18px;
+ line-height: 1.3333333;
+}
+.pagination-lg > li:first-child > a,
+.pagination-lg > li:first-child > span {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.pagination-lg > li:last-child > a,
+.pagination-lg > li:last-child > span {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.pagination-sm > li > a,
+.pagination-sm > li > span {
+ padding: 5px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+}
+.pagination-sm > li:first-child > a,
+.pagination-sm > li:first-child > span {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.pagination-sm > li:last-child > a,
+.pagination-sm > li:last-child > span {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.pager {
+ padding-left: 0;
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+}
+.pager li {
+ display: inline;
+}
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 15px;
+}
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #008dd2;
+}
+.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: #008dd2;
+ cursor: not-allowed;
+ background-color: #fff;
+}
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+}
+a.label:hover,
+a.label:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.label:empty {
+ display: none;
+}
+.btn .label {
+ position: relative;
+ top: -1px;
+}
+.label-default {
+ background-color: #008dd2;
+}
+.label-default[href]:hover,
+.label-default[href]:focus {
+ background-color: #036595;
+}
+.label-primary {
+ background-color: #008dd2;
+}
+.label-primary[href]:hover,
+.label-primary[href]:focus {
+ background-color: #036595;
+}
+.label-success {
+ background-color: #5cb85c;
+}
+.label-success[href]:hover,
+.label-success[href]:focus {
+ background-color: #449d44;
+}
+.label-info {
+ background-color: #5bc0de;
+}
+.label-info[href]:hover,
+.label-info[href]:focus {
+ background-color: #31b0d5;
+}
+.label-warning {
+ background-color: #f0ad4e;
+}
+.label-warning[href]:hover,
+.label-warning[href]:focus {
+ background-color: #ec971f;
+}
+.label-danger {
+ background-color: #d9534f;
+}
+.label-danger[href]:hover,
+.label-danger[href]:focus {
+ background-color: #c9302c;
+}
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: 12px;
+ font-weight: bold;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: #008dd2;
+ border-radius: 10px;
+}
+.badge:empty {
+ display: none;
+}
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+.btn-xs .badge,
+.btn-group-xs > .btn .badge {
+ top: 0;
+ padding: 1px 5px;
+}
+a.badge:hover,
+a.badge:focus {
+ color: #fff;
+ text-decoration: none;
+ cursor: pointer;
+}
+.list-group-item.active > .badge,
+.nav-pills > .active > a > .badge {
+ color: #008dd2;
+ background-color: #fff;
+}
+.list-group-item > .badge {
+ float: right;
+}
+.list-group-item > .badge + .badge {
+ margin-right: 5px;
+}
+.nav-pills > li > a > .badge {
+ margin-left: 3px;
+}
+.jumbotron {
+ padding-top: 30px;
+ padding-bottom: 30px;
+ margin-bottom: 30px;
+ color: inherit;
+ background-color: #008dd2;
+}
+.jumbotron h1,
+.jumbotron .h1 {
+ color: inherit;
+}
+.jumbotron p {
+ margin-bottom: 15px;
+ font-size: 21px;
+ font-weight: 200;
+}
+.jumbotron > hr {
+ border-top-color: #036595;
+}
+.container .jumbotron,
+.container-fluid .jumbotron {
+ padding-right: 15px;
+ padding-left: 15px;
+ border-radius: 0;
+}
+.jumbotron .container {
+ max-width: 100%;
+}
+@media screen and (min-width: 768px) {
+ .jumbotron {
+ padding-top: 48px;
+ padding-bottom: 48px;
+ }
+ .container .jumbotron,
+ .container-fluid .jumbotron {
+ padding-right: 60px;
+ padding-left: 60px;
+ }
+ .jumbotron h1,
+ .jumbotron .h1 {
+ font-size: 63px;
+ }
+}
+.thumbnail {
+ display: block;
+ padding: 4px;
+ margin-bottom: 20px;
+ line-height: 1.42857143;
+ background-color: #008dd2;
+ border: 1px solid #ddd;
+ border-radius: 0;
+ -webkit-transition: border .2s ease-in-out;
+ -o-transition: border .2s ease-in-out;
+ transition: border .2s ease-in-out;
+}
+.thumbnail > img,
+.thumbnail a > img {
+ margin-right: auto;
+ margin-left: auto;
+}
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: #008dd2;
+}
+.thumbnail .caption {
+ padding: 9px;
+ color: #008dd2;
+}
+.alert {
+ padding: 15px;
+ margin-bottom: 20px;
+ border: 1px solid transparent;
+ border-radius: 0;
+}
+.alert h4 {
+ margin-top: 0;
+ color: inherit;
+}
+.alert .alert-link {
+ font-weight: bold;
+}
+.alert > p,
+.alert > ul {
+ margin-bottom: 0;
+}
+.alert > p + p {
+ margin-top: 5px;
+}
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: 35px;
+}
+.alert-dismissable .close,
+.alert-dismissible .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+}
+.alert-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.alert-success hr {
+ border-top-color: #c9e2b3;
+}
+.alert-success .alert-link {
+ color: #2b542c;
+}
+.alert-info {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.alert-info hr {
+ border-top-color: #a6e1ec;
+}
+.alert-info .alert-link {
+ color: #245269;
+}
+.alert-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.alert-warning hr {
+ border-top-color: #f7e1b5;
+}
+.alert-warning .alert-link {
+ color: #66512c;
+}
+.alert-danger {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.alert-danger hr {
+ border-top-color: #e4b9c0;
+}
+.alert-danger .alert-link {
+ color: #843534;
+}
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f5f5f5;
+ border-radius: 0;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
+}
+.progress-bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ line-height: 20px;
+ color: #fff;
+ text-align: center;
+ background-color: #008dd2;
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
+ -webkit-transition: width .6s ease;
+ -o-transition: width .6s ease;
+ transition: width .6s ease;
+}
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+.progress.active .progress-bar,
+.progress-bar.active {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+.progress-bar-success {
+ background-color: #5cb85c;
+}
+.progress-striped .progress-bar-success {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-info {
+ background-color: #5bc0de;
+}
+.progress-striped .progress-bar-info {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-warning {
+ background-color: #f0ad4e;
+}
+.progress-striped .progress-bar-warning {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.progress-bar-danger {
+ background-color: #d9534f;
+}
+.progress-striped .progress-bar-danger {
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
+}
+.media {
+ margin-top: 15px;
+}
+.media:first-child {
+ margin-top: 0;
+}
+.media,
+.media-body {
+ overflow: hidden;
+ zoom: 1;
+}
+.media-body {
+ width: 10000px;
+}
+.media-object {
+ display: block;
+}
+.media-object.img-thumbnail {
+ max-width: none;
+}
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+.media-middle {
+ vertical-align: middle;
+}
+.media-bottom {
+ vertical-align: bottom;
+}
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
+.list-group {
+ padding-left: 0;
+ margin-bottom: 20px;
+}
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+}
+.list-group-item:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.list-group-item:last-child {
+ margin-bottom: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+a.list-group-item,
+button.list-group-item {
+ color: #fff;
+}
+a.list-group-item .list-group-item-heading,
+button.list-group-item .list-group-item-heading {
+ color: #ccc;
+}
+a.list-group-item:hover,
+button.list-group-item:hover,
+a.list-group-item:focus,
+button.list-group-item:focus {
+ color: #fff;
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+button.list-group-item {
+ width: 100%;
+ text-align: left;
+}
+.list-group-item.disabled,
+.list-group-item.disabled:hover,
+.list-group-item.disabled:focus {
+ color: #008dd2;
+ cursor: not-allowed;
+ background-color: #008dd2;
+}
+.list-group-item.disabled .list-group-item-heading,
+.list-group-item.disabled:hover .list-group-item-heading,
+.list-group-item.disabled:focus .list-group-item-heading {
+ color: inherit;
+}
+.list-group-item.disabled .list-group-item-text,
+.list-group-item.disabled:hover .list-group-item-text,
+.list-group-item.disabled:focus .list-group-item-text {
+ color: #008dd2;
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ z-index: 2;
+ color: #fff;
+ background-color: #008dd2;
+ border-color: #008dd2;
+}
+.list-group-item.active .list-group-item-heading,
+.list-group-item.active:hover .list-group-item-heading,
+.list-group-item.active:focus .list-group-item-heading,
+.list-group-item.active .list-group-item-heading > small,
+.list-group-item.active:hover .list-group-item-heading > small,
+.list-group-item.active:focus .list-group-item-heading > small,
+.list-group-item.active .list-group-item-heading > .small,
+.list-group-item.active:hover .list-group-item-heading > .small,
+.list-group-item.active:focus .list-group-item-heading > .small {
+ color: inherit;
+}
+.list-group-item.active .list-group-item-text,
+.list-group-item.active:hover .list-group-item-text,
+.list-group-item.active:focus .list-group-item-text {
+ color: #6ec5ff;
+}
+.list-group-item-success {
+ color: #3c763d;
+ background-color: #dff0d8;
+}
+a.list-group-item-success,
+button.list-group-item-success {
+ color: #3c763d;
+}
+a.list-group-item-success .list-group-item-heading,
+button.list-group-item-success .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-success:hover,
+button.list-group-item-success:hover,
+a.list-group-item-success:focus,
+button.list-group-item-success:focus {
+ color: #3c763d;
+ background-color: #d0e9c6;
+}
+a.list-group-item-success.active,
+button.list-group-item-success.active,
+a.list-group-item-success.active:hover,
+button.list-group-item-success.active:hover,
+a.list-group-item-success.active:focus,
+button.list-group-item-success.active:focus {
+ color: #fff;
+ background-color: #3c763d;
+ border-color: #3c763d;
+}
+.list-group-item-info {
+ color: #31708f;
+ background-color: #d9edf7;
+}
+a.list-group-item-info,
+button.list-group-item-info {
+ color: #31708f;
+}
+a.list-group-item-info .list-group-item-heading,
+button.list-group-item-info .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-info:hover,
+button.list-group-item-info:hover,
+a.list-group-item-info:focus,
+button.list-group-item-info:focus {
+ color: #31708f;
+ background-color: #c4e3f3;
+}
+a.list-group-item-info.active,
+button.list-group-item-info.active,
+a.list-group-item-info.active:hover,
+button.list-group-item-info.active:hover,
+a.list-group-item-info.active:focus,
+button.list-group-item-info.active:focus {
+ color: #fff;
+ background-color: #31708f;
+ border-color: #31708f;
+}
+.list-group-item-warning {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+}
+a.list-group-item-warning,
+button.list-group-item-warning {
+ color: #8a6d3b;
+}
+a.list-group-item-warning .list-group-item-heading,
+button.list-group-item-warning .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-warning:hover,
+button.list-group-item-warning:hover,
+a.list-group-item-warning:focus,
+button.list-group-item-warning:focus {
+ color: #8a6d3b;
+ background-color: #faf2cc;
+}
+a.list-group-item-warning.active,
+button.list-group-item-warning.active,
+a.list-group-item-warning.active:hover,
+button.list-group-item-warning.active:hover,
+a.list-group-item-warning.active:focus,
+button.list-group-item-warning.active:focus {
+ color: #fff;
+ background-color: #8a6d3b;
+ border-color: #8a6d3b;
+}
+.list-group-item-danger {
+ color: #a94442;
+ background-color: #f2dede;
+}
+a.list-group-item-danger,
+button.list-group-item-danger {
+ color: #a94442;
+}
+a.list-group-item-danger .list-group-item-heading,
+button.list-group-item-danger .list-group-item-heading {
+ color: inherit;
+}
+a.list-group-item-danger:hover,
+button.list-group-item-danger:hover,
+a.list-group-item-danger:focus,
+button.list-group-item-danger:focus {
+ color: #a94442;
+ background-color: #ebcccc;
+}
+a.list-group-item-danger.active,
+button.list-group-item-danger.active,
+a.list-group-item-danger.active:hover,
+button.list-group-item-danger.active:hover,
+a.list-group-item-danger.active:focus,
+button.list-group-item-danger.active:focus {
+ color: #fff;
+ background-color: #a94442;
+ border-color: #a94442;
+}
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
+.panel {
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid transparent;
+ border-radius: 0;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+}
+.panel-body {
+ padding: 15px;
+}
+.panel-heading {
+ padding: 10px 15px;
+ border-bottom: 1px solid transparent;
+ border-top-left-radius: -1px;
+ border-top-right-radius: -1px;
+}
+.panel-heading > .dropdown .dropdown-toggle {
+ color: inherit;
+}
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: 16px;
+ color: inherit;
+}
+.panel-title > a,
+.panel-title > small,
+.panel-title > .small,
+.panel-title > small > a,
+.panel-title > .small > a {
+ color: inherit;
+}
+.panel-footer {
+ padding: 10px 15px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ border-bottom-right-radius: -1px;
+ border-bottom-left-radius: -1px;
+}
+.panel > .list-group,
+.panel > .panel-collapse > .list-group {
+ margin-bottom: 0;
+}
+.panel > .list-group .list-group-item,
+.panel > .panel-collapse > .list-group .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+}
+.panel > .list-group:first-child .list-group-item:first-child,
+.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {
+ border-top: 0;
+ border-top-left-radius: -1px;
+ border-top-right-radius: -1px;
+}
+.panel > .list-group:last-child .list-group-item:last-child,
+.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: -1px;
+ border-bottom-left-radius: -1px;
+}
+.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.panel-heading + .list-group .list-group-item:first-child {
+ border-top-width: 0;
+}
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+.panel > .table,
+.panel > .table-responsive > .table,
+.panel > .panel-collapse > .table {
+ margin-bottom: 0;
+}
+.panel > .table caption,
+.panel > .table-responsive > .table caption,
+.panel > .panel-collapse > .table caption {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+.panel > .table:first-child,
+.panel > .table-responsive:first-child > .table:first-child {
+ border-top-left-radius: -1px;
+ border-top-right-radius: -1px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {
+ border-top-left-radius: -1px;
+ border-top-right-radius: -1px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
+ border-top-left-radius: -1px;
+}
+.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
+.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
+.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
+.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
+ border-top-right-radius: -1px;
+}
+.panel > .table:last-child,
+.panel > .table-responsive:last-child > .table:last-child {
+ border-bottom-right-radius: -1px;
+ border-bottom-left-radius: -1px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {
+ border-bottom-right-radius: -1px;
+ border-bottom-left-radius: -1px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
+ border-bottom-left-radius: -1px;
+}
+.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
+.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
+.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
+.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
+ border-bottom-right-radius: -1px;
+}
+.panel > .panel-body + .table,
+.panel > .panel-body + .table-responsive,
+.panel > .table + .panel-body,
+.panel > .table-responsive + .panel-body {
+ border-top: 1px solid #008dd2;
+}
+.panel > .table > tbody:first-child > tr:first-child th,
+.panel > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+}
+.panel > .table-bordered,
+.panel > .table-responsive > .table-bordered {
+ border: 0;
+}
+.panel > .table-bordered > thead > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
+.panel > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
+.panel > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
+.panel > .table-bordered > thead > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
+.panel > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
+.panel > .table-bordered > tfoot > tr > td:first-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
+ border-left: 0;
+}
+.panel > .table-bordered > thead > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
+.panel > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
+.panel > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
+.panel > .table-bordered > thead > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
+.panel > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
+.panel > .table-bordered > tfoot > tr > td:last-child,
+.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
+ border-right: 0;
+}
+.panel > .table-bordered > thead > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
+.panel > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
+.panel > .table-bordered > thead > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
+.panel > .table-bordered > tbody > tr:first-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
+ border-bottom: 0;
+}
+.panel > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
+.panel > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
+.panel > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
+.panel > .table-bordered > tfoot > tr:last-child > th,
+.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
+ border-bottom: 0;
+}
+.panel > .table-responsive {
+ margin-bottom: 0;
+ border: 0;
+}
+.panel-group {
+ margin-bottom: 20px;
+}
+.panel-group .panel {
+ margin-bottom: 0;
+ border-radius: 0;
+}
+.panel-group .panel + .panel {
+ margin-top: 5px;
+}
+.panel-group .panel-heading {
+ border-bottom: 0;
+}
+.panel-group .panel-heading + .panel-collapse > .panel-body,
+.panel-group .panel-heading + .panel-collapse > .list-group {
+ border-top: 1px solid #ddd;
+}
+.panel-group .panel-footer {
+ border-top: 0;
+}
+.panel-group .panel-footer + .panel-collapse .panel-body {
+ border-bottom: 1px solid #ddd;
+}
+.panel-default {
+ border-color: #ddd;
+}
+.panel-default > .panel-heading {
+ color: #008dd2;
+ background-color: #f5f5f5;
+ border-color: #ddd;
+}
+.panel-default > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ddd;
+}
+.panel-default > .panel-heading .badge {
+ color: #f5f5f5;
+ background-color: #008dd2;
+}
+.panel-default > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ddd;
+}
+.panel-primary {
+ border-color: #008dd2;
+}
+.panel-primary > .panel-heading {
+ color: #fff;
+ background-color: #008dd2;
+ border-color: #008dd2;
+}
+.panel-primary > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #008dd2;
+}
+.panel-primary > .panel-heading .badge {
+ color: #008dd2;
+ background-color: #fff;
+}
+.panel-primary > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #008dd2;
+}
+.panel-success {
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading {
+ color: #3c763d;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+.panel-success > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #d6e9c6;
+}
+.panel-success > .panel-heading .badge {
+ color: #dff0d8;
+ background-color: #3c763d;
+}
+.panel-success > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #d6e9c6;
+}
+.panel-info {
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading {
+ color: #31708f;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+.panel-info > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #bce8f1;
+}
+.panel-info > .panel-heading .badge {
+ color: #d9edf7;
+ background-color: #31708f;
+}
+.panel-info > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #bce8f1;
+}
+.panel-warning {
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading {
+ color: #8a6d3b;
+ background-color: #fcf8e3;
+ border-color: #faebcc;
+}
+.panel-warning > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #faebcc;
+}
+.panel-warning > .panel-heading .badge {
+ color: #fcf8e3;
+ background-color: #8a6d3b;
+}
+.panel-warning > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #faebcc;
+}
+.panel-danger {
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading {
+ color: #a94442;
+ background-color: #f2dede;
+ border-color: #ebccd1;
+}
+.panel-danger > .panel-heading + .panel-collapse > .panel-body {
+ border-top-color: #ebccd1;
+}
+.panel-danger > .panel-heading .badge {
+ color: #f2dede;
+ background-color: #a94442;
+}
+.panel-danger > .panel-footer + .panel-collapse > .panel-body {
+ border-bottom-color: #ebccd1;
+}
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+}
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ border-radius: 0;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
+}
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15);
+}
+.well-lg {
+ padding: 24px;
+ border-radius: 0;
+}
+.well-sm {
+ padding: 9px;
+ border-radius: 0;
+}
+.close {
+ float: right;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 1;
+ color: #000;
+ text-shadow: 0 1px 0 #fff;
+ filter: alpha(opacity=20);
+ opacity: .2;
+}
+.close:hover,
+.close:focus {
+ color: #000;
+ text-decoration: none;
+ cursor: pointer;
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+button.close {
+ -webkit-appearance: none;
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+}
+.modal-open {
+ overflow: hidden;
+}
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1050;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+ outline: 0;
+}
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform .3s ease-out;
+ -o-transition: -o-transform .3s ease-out;
+ transition: transform .3s ease-out;
+ -webkit-transform: translate(0, -25%);
+ -ms-transform: translate(0, -25%);
+ -o-transform: translate(0, -25%);
+ transform: translate(0, -25%);
+}
+.modal.in .modal-dialog {
+ -webkit-transform: translate(0, 0);
+ -ms-transform: translate(0, 0);
+ -o-transform: translate(0, 0);
+ transform: translate(0, 0);
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+.modal-content {
+ position: relative;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 0;
+ outline: 0;
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
+}
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000;
+}
+.modal-backdrop.fade {
+ filter: alpha(opacity=0);
+ opacity: 0;
+}
+.modal-backdrop.in {
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.modal-header {
+ padding: 15px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.modal-header .close {
+ margin-top: -2px;
+}
+.modal-title {
+ margin: 0;
+ line-height: 1.42857143;
+}
+.modal-body {
+ position: relative;
+ padding: 15px;
+}
+.modal-footer {
+ padding: 15px;
+ text-align: right;
+ border-top: 1px solid #e5e5e5;
+}
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+@media (min-width: 768px) {
+ .modal-dialog {
+ width: 600px;
+ margin: 30px auto;
+ }
+ .modal-content {
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
+ }
+ .modal-sm {
+ width: 300px;
+ }
+}
+@media (min-width: 992px) {
+ .modal-lg {
+ width: 900px;
+ }
+}
+.tooltip {
+ position: absolute;
+ z-index: 1070;
+ display: block;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ filter: alpha(opacity=0);
+ opacity: 0;
+
+ line-break: auto;
+}
+.tooltip.in {
+ filter: alpha(opacity=90);
+ opacity: .9;
+}
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px;
+}
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px;
+}
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px;
+}
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px;
+}
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 0;
+}
+.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: #000;
+}
+.tooltip.top-left .tooltip-arrow {
+ right: 5px;
+ bottom: 0;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.top-right .tooltip-arrow {
+ bottom: 0;
+ left: 5px;
+ margin-bottom: -5px;
+ border-width: 5px 5px 0;
+ border-top-color: #000;
+}
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-width: 5px 5px 5px 0;
+ border-right-color: #000;
+}
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-width: 5px 0 5px 5px;
+ border-left-color: #000;
+}
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-left .tooltip-arrow {
+ top: 0;
+ right: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.tooltip.bottom-right .tooltip-arrow {
+ top: 0;
+ left: 5px;
+ margin-top: -5px;
+ border-width: 0 5px 5px;
+ border-bottom-color: #000;
+}
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.42857143;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, .2);
+ border-radius: 0;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
+
+ line-break: auto;
+}
+.popover.top {
+ margin-top: -10px;
+}
+.popover.right {
+ margin-left: 10px;
+}
+.popover.bottom {
+ margin-top: 10px;
+}
+.popover.left {
+ margin-left: -10px;
+}
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ border-radius: -1px -1px 0 0;
+}
+.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 {
+ content: "";
+ border-width: 10px;
+}
+.popover.top > .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, .25);
+ border-bottom-width: 0;
+}
+.popover.top > .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-color: #fff;
+ border-bottom-width: 0;
+}
+.popover.right > .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, .25);
+ border-left-width: 0;
+}
+.popover.right > .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ content: " ";
+ border-right-color: #fff;
+ border-left-width: 0;
+}
+.popover.bottom > .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-width: 0;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, .25);
+}
+.popover.bottom > .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: #fff;
+}
+.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, .25);
+}
+.popover.left > .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: #fff;
+}
+.carousel {
+ position: relative;
+}
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: .6s ease-in-out left;
+ -o-transition: .6s ease-in-out left;
+ transition: .6s ease-in-out left;
+}
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ line-height: 1;
+}
+@media all and (transform-3d), (-webkit-transform-3d) {
+ .carousel-inner > .item {
+ -webkit-transition: -webkit-transform .6s ease-in-out;
+ -o-transition: -o-transform .6s ease-in-out;
+ transition: transform .6s ease-in-out;
+
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-perspective: 1000px;
+ perspective: 1000px;
+ }
+ .carousel-inner > .item.next,
+ .carousel-inner > .item.active.right {
+ left: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+ .carousel-inner > .item.prev,
+ .carousel-inner > .item.active.left {
+ left: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+ .carousel-inner > .item.next.left,
+ .carousel-inner > .item.prev.right,
+ .carousel-inner > .item.active {
+ left: 0;
+ -webkit-transform: translate3d(0, 0, 0);
+ transform: translate3d(0, 0, 0);
+ }
+}
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+.carousel-inner > .active {
+ left: 0;
+}
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+.carousel-inner > .next {
+ left: 100%;
+}
+.carousel-inner > .prev {
+ left: -100%;
+}
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+.carousel-inner > .active.left {
+ left: -100%;
+}
+.carousel-inner > .active.right {
+ left: 100%;
+}
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 15%;
+ font-size: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+ background-color: rgba(0, 0, 0, 0);
+ filter: alpha(opacity=50);
+ opacity: .5;
+}
+.carousel-control.left {
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control.right {
+ right: 0;
+ left: auto;
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
+ background-repeat: repeat-x;
+}
+.carousel-control:hover,
+.carousel-control:focus {
+ color: #fff;
+ text-decoration: none;
+ filter: alpha(opacity=90);
+ outline: 0;
+ opacity: .9;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-left,
+.carousel-control .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+ margin-top: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+}
+.carousel-control .icon-next,
+.carousel-control .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+}
+.carousel-control .icon-prev,
+.carousel-control .icon-next {
+ width: 20px;
+ height: 20px;
+ font-family: serif;
+ line-height: 1;
+}
+.carousel-control .icon-prev:before {
+ content: '\2039';
+}
+.carousel-control .icon-next:before {
+ content: '\203a';
+}
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none;
+}
+.carousel-indicators li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #000 \9;
+ background-color: rgba(0, 0, 0, 0);
+ border: 1px solid #fff;
+ border-radius: 10px;
+}
+.carousel-indicators .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: #fff;
+}
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
+}
+.carousel-caption .btn {
+ text-shadow: none;
+}
+@media screen and (min-width: 768px) {
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-prev,
+ .carousel-control .icon-next {
+ width: 30px;
+ height: 30px;
+ margin-top: -10px;
+ font-size: 30px;
+ }
+ .carousel-control .glyphicon-chevron-left,
+ .carousel-control .icon-prev {
+ margin-left: -10px;
+ }
+ .carousel-control .glyphicon-chevron-right,
+ .carousel-control .icon-next {
+ margin-right: -10px;
+ }
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px;
+ }
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
+.clearfix:before,
+.clearfix:after,
+.dl-horizontal dd:before,
+.dl-horizontal dd:after,
+.container:before,
+.container:after,
+.container-fluid:before,
+.container-fluid:after,
+.row:before,
+.row:after,
+.form-horizontal .form-group:before,
+.form-horizontal .form-group:after,
+.btn-toolbar:before,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:before,
+.btn-group-vertical > .btn-group:after,
+.nav:before,
+.nav:after,
+.navbar:before,
+.navbar:after,
+.navbar-header:before,
+.navbar-header:after,
+.navbar-collapse:before,
+.navbar-collapse:after,
+.pager:before,
+.pager:after,
+.panel-body:before,
+.panel-body:after,
+.modal-header:before,
+.modal-header:after,
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ content: " ";
+}
+.clearfix:after,
+.dl-horizontal dd:after,
+.container:after,
+.container-fluid:after,
+.row:after,
+.form-horizontal .form-group:after,
+.btn-toolbar:after,
+.btn-group-vertical > .btn-group:after,
+.nav:after,
+.navbar:after,
+.navbar-header:after,
+.navbar-collapse:after,
+.pager:after,
+.panel-body:after,
+.modal-header:after,
+.modal-footer:after {
+ clear: both;
+}
+.center-block {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+.hidden {
+ display: none !important;
+}
+.affix {
+ position: fixed;
+}
+@-ms-viewport {
+ width: device-width;
+}
+.visible-xs,
+.visible-sm,
+.visible-md,
+.visible-lg {
+ display: none !important;
+}
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+@media (max-width: 767px) {
+ .visible-xs {
+ display: block !important;
+ }
+ table.visible-xs {
+ display: table !important;
+ }
+ tr.visible-xs {
+ display: table-row !important;
+ }
+ th.visible-xs,
+ td.visible-xs {
+ display: table-cell !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-block {
+ display: block !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline {
+ display: inline !important;
+ }
+}
+@media (max-width: 767px) {
+ .visible-xs-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm {
+ display: block !important;
+ }
+ table.visible-sm {
+ display: table !important;
+ }
+ tr.visible-sm {
+ display: table-row !important;
+ }
+ th.visible-sm,
+ td.visible-sm {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-block {
+ display: block !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .visible-sm-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md {
+ display: block !important;
+ }
+ table.visible-md {
+ display: table !important;
+ }
+ tr.visible-md {
+ display: table-row !important;
+ }
+ th.visible-md,
+ td.visible-md {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-block {
+ display: block !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .visible-md-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg {
+ display: block !important;
+ }
+ table.visible-lg {
+ display: table !important;
+ }
+ tr.visible-lg {
+ display: table-row !important;
+ }
+ th.visible-lg,
+ td.visible-lg {
+ display: table-cell !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-block {
+ display: block !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline {
+ display: inline !important;
+ }
+}
+@media (min-width: 1200px) {
+ .visible-lg-inline-block {
+ display: inline-block !important;
+ }
+}
+@media (max-width: 767px) {
+ .hidden-xs {
+ display: none !important;
+ }
+}
+@media (min-width: 768px) and (max-width: 991px) {
+ .hidden-sm {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) and (max-width: 1199px) {
+ .hidden-md {
+ display: none !important;
+ }
+}
+@media (min-width: 1200px) {
+ .hidden-lg {
+ display: none !important;
+ }
+}
+.visible-print {
+ display: none !important;
+}
+@media print {
+ .visible-print {
+ display: block !important;
+ }
+ table.visible-print {
+ display: table !important;
+ }
+ tr.visible-print {
+ display: table-row !important;
+ }
+ th.visible-print,
+ td.visible-print {
+ display: table-cell !important;
+ }
+}
+.visible-print-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-block {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+}
+@media print {
+ .visible-print-inline-block {
+ display: inline-block !important;
+ }
+}
+@media print {
+ .hidden-print {
+ display: none !important;
+ }
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.eot b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 0000000..b93a495
Binary files /dev/null and b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.eot differ
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.svg b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..94fb549
--- /dev/null
+++ b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,288 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.ttf b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 0000000..1413fc6
Binary files /dev/null and b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.woff b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 0000000..9e61285
Binary files /dev/null and b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.woff differ
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.woff2 b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.woff2
new file mode 100644
index 0000000..64539b5
Binary files /dev/null and b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/fonts/glyphicons-halflings-regular.woff2 differ
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/bootstrap.js b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/bootstrap.js
new file mode 100644
index 0000000..d47d640
--- /dev/null
+++ b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/bootstrap.js
@@ -0,0 +1,2363 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+
+if (typeof jQuery === 'undefined') {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery')
+}
+
++function ($) {
+ 'use strict';
+ var version = $.fn.jquery.split(' ')[0].split('.')
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')
+ }
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.6
+ * http://getbootstrap.com/javascript/#transitions
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
+ // ============================================================
+
+ function transitionEnd() {
+ var el = document.createElement('bootstrap')
+
+ var transEndEventNames = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
+ }
+
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ return { end: transEndEventNames[name] }
+ }
+ }
+
+ return false // explicit for ie8 ( ._.)
+ }
+
+ // http://blog.alexmaccaw.com/css-transitions
+ $.fn.emulateTransitionEnd = function (duration) {
+ var called = false
+ var $el = this
+ $(this).one('bsTransitionEnd', function () { called = true })
+ var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
+ setTimeout(callback, duration)
+ return this
+ }
+
+ $(function () {
+ $.support.transition = transitionEnd()
+
+ if (!$.support.transition) return
+
+ $.event.special.bsTransitionEnd = {
+ bindType: $.support.transition.end,
+ delegateType: $.support.transition.end,
+ handle: function (e) {
+ if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
+ }
+ }
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: alert.js v3.3.6
+ * http://getbootstrap.com/javascript/#alerts
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // ALERT CLASS DEFINITION
+ // ======================
+
+ var dismiss = '[data-dismiss="alert"]'
+ var Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ }
+
+ Alert.VERSION = '3.3.6'
+
+ Alert.TRANSITION_DURATION = 150
+
+ Alert.prototype.close = function (e) {
+ var $this = $(this)
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = $(selector)
+
+ if (e) e.preventDefault()
+
+ if (!$parent.length) {
+ $parent = $this.closest('.alert')
+ }
+
+ $parent.trigger(e = $.Event('close.bs.alert'))
+
+ if (e.isDefaultPrevented()) return
+
+ $parent.removeClass('in')
+
+ function removeElement() {
+ // detach from parent, fire event then clean up data
+ $parent.detach().trigger('closed.bs.alert').remove()
+ }
+
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent
+ .one('bsTransitionEnd', removeElement)
+ .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
+ removeElement()
+ }
+
+
+ // ALERT PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.alert')
+
+ if (!data) $this.data('bs.alert', (data = new Alert(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.alert
+
+ $.fn.alert = Plugin
+ $.fn.alert.Constructor = Alert
+
+
+ // ALERT NO CONFLICT
+ // =================
+
+ $.fn.alert.noConflict = function () {
+ $.fn.alert = old
+ return this
+ }
+
+
+ // ALERT DATA-API
+ // ==============
+
+ $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: button.js v3.3.6
+ * http://getbootstrap.com/javascript/#buttons
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // BUTTON PUBLIC CLASS DEFINITION
+ // ==============================
+
+ var Button = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Button.DEFAULTS, options)
+ this.isLoading = false
+ }
+
+ Button.VERSION = '3.3.6'
+
+ Button.DEFAULTS = {
+ loadingText: 'loading...'
+ }
+
+ Button.prototype.setState = function (state) {
+ var d = 'disabled'
+ var $el = this.$element
+ var val = $el.is('input') ? 'val' : 'html'
+ var data = $el.data()
+
+ state += 'Text'
+
+ if (data.resetText == null) $el.data('resetText', $el[val]())
+
+ // push to event loop to allow forms to submit
+ setTimeout($.proxy(function () {
+ $el[val](data[state] == null ? this.options[state] : data[state])
+
+ if (state == 'loadingText') {
+ this.isLoading = true
+ $el.addClass(d).attr(d, d)
+ } else if (this.isLoading) {
+ this.isLoading = false
+ $el.removeClass(d).removeAttr(d)
+ }
+ }, this), 0)
+ }
+
+ Button.prototype.toggle = function () {
+ var changed = true
+ var $parent = this.$element.closest('[data-toggle="buttons"]')
+
+ if ($parent.length) {
+ var $input = this.$element.find('input')
+ if ($input.prop('type') == 'radio') {
+ if ($input.prop('checked')) changed = false
+ $parent.find('.active').removeClass('active')
+ this.$element.addClass('active')
+ } else if ($input.prop('type') == 'checkbox') {
+ if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
+ this.$element.toggleClass('active')
+ }
+ $input.prop('checked', this.$element.hasClass('active'))
+ if (changed) $input.trigger('change')
+ } else {
+ this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
+ this.$element.toggleClass('active')
+ }
+ }
+
+
+ // BUTTON PLUGIN DEFINITION
+ // ========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.button')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.button', (data = new Button(this, options)))
+
+ if (option == 'toggle') data.toggle()
+ else if (option) data.setState(option)
+ })
+ }
+
+ var old = $.fn.button
+
+ $.fn.button = Plugin
+ $.fn.button.Constructor = Button
+
+
+ // BUTTON NO CONFLICT
+ // ==================
+
+ $.fn.button.noConflict = function () {
+ $.fn.button = old
+ return this
+ }
+
+
+ // BUTTON DATA-API
+ // ===============
+
+ $(document)
+ .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ var $btn = $(e.target)
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
+ Plugin.call($btn, 'toggle')
+ if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
+ })
+ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: carousel.js v3.3.6
+ * http://getbootstrap.com/javascript/#carousel
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // CAROUSEL CLASS DEFINITION
+ // =========================
+
+ var Carousel = function (element, options) {
+ this.$element = $(element)
+ this.$indicators = this.$element.find('.carousel-indicators')
+ this.options = options
+ this.paused = null
+ this.sliding = null
+ this.interval = null
+ this.$active = null
+ this.$items = null
+
+ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
+
+ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+ }
+
+ Carousel.VERSION = '3.3.6'
+
+ Carousel.TRANSITION_DURATION = 600
+
+ Carousel.DEFAULTS = {
+ interval: 5000,
+ pause: 'hover',
+ wrap: true,
+ keyboard: true
+ }
+
+ Carousel.prototype.keydown = function (e) {
+ if (/input|textarea/i.test(e.target.tagName)) return
+ switch (e.which) {
+ case 37: this.prev(); break
+ case 39: this.next(); break
+ default: return
+ }
+
+ e.preventDefault()
+ }
+
+ Carousel.prototype.cycle = function (e) {
+ e || (this.paused = false)
+
+ this.interval && clearInterval(this.interval)
+
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+
+ return this
+ }
+
+ Carousel.prototype.getItemIndex = function (item) {
+ this.$items = item.parent().children('.item')
+ return this.$items.index(item || this.$active)
+ }
+
+ Carousel.prototype.getItemForDirection = function (direction, active) {
+ var activeIndex = this.getItemIndex(active)
+ var willWrap = (direction == 'prev' && activeIndex === 0)
+ || (direction == 'next' && activeIndex == (this.$items.length - 1))
+ if (willWrap && !this.options.wrap) return active
+ var delta = direction == 'prev' ? -1 : 1
+ var itemIndex = (activeIndex + delta) % this.$items.length
+ return this.$items.eq(itemIndex)
+ }
+
+ Carousel.prototype.to = function (pos) {
+ var that = this
+ var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
+
+ if (pos > (this.$items.length - 1) || pos < 0) return
+
+ if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
+ if (activeIndex == pos) return this.pause().cycle()
+
+ return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
+ }
+
+ Carousel.prototype.pause = function (e) {
+ e || (this.paused = true)
+
+ if (this.$element.find('.next, .prev').length && $.support.transition) {
+ this.$element.trigger($.support.transition.end)
+ this.cycle(true)
+ }
+
+ this.interval = clearInterval(this.interval)
+
+ return this
+ }
+
+ Carousel.prototype.next = function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
+
+ Carousel.prototype.prev = function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ Carousel.prototype.slide = function (type, next) {
+ var $active = this.$element.find('.item.active')
+ var $next = next || this.getItemForDirection(type, $active)
+ var isCycling = this.interval
+ var direction = type == 'next' ? 'left' : 'right'
+ var that = this
+
+ if ($next.hasClass('active')) return (this.sliding = false)
+
+ var relatedTarget = $next[0]
+ var slideEvent = $.Event('slide.bs.carousel', {
+ relatedTarget: relatedTarget,
+ direction: direction
+ })
+ this.$element.trigger(slideEvent)
+ if (slideEvent.isDefaultPrevented()) return
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ if (this.$indicators.length) {
+ this.$indicators.find('.active').removeClass('active')
+ var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
+ $nextIndicator && $nextIndicator.addClass('active')
+ }
+
+ var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ $active
+ .one('bsTransitionEnd', function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () {
+ that.$element.trigger(slidEvent)
+ }, 0)
+ })
+ .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
+ } else {
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger(slidEvent)
+ }
+
+ isCycling && this.cycle()
+
+ return this
+ }
+
+
+ // CAROUSEL PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.carousel')
+ var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
+ var action = typeof option == 'string' ? option : options.slide
+
+ if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (action) data[action]()
+ else if (options.interval) data.pause().cycle()
+ })
+ }
+
+ var old = $.fn.carousel
+
+ $.fn.carousel = Plugin
+ $.fn.carousel.Constructor = Carousel
+
+
+ // CAROUSEL NO CONFLICT
+ // ====================
+
+ $.fn.carousel.noConflict = function () {
+ $.fn.carousel = old
+ return this
+ }
+
+
+ // CAROUSEL DATA-API
+ // =================
+
+ var clickHandler = function (e) {
+ var href
+ var $this = $(this)
+ var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
+ if (!$target.hasClass('carousel')) return
+ var options = $.extend({}, $target.data(), $this.data())
+ var slideIndex = $this.attr('data-slide-to')
+ if (slideIndex) options.interval = false
+
+ Plugin.call($target, options)
+
+ if (slideIndex) {
+ $target.data('bs.carousel').to(slideIndex)
+ }
+
+ e.preventDefault()
+ }
+
+ $(document)
+ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
+ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
+
+ $(window).on('load', function () {
+ $('[data-ride="carousel"]').each(function () {
+ var $carousel = $(this)
+ Plugin.call($carousel, $carousel.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: collapse.js v3.3.6
+ * http://getbootstrap.com/javascript/#collapse
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // COLLAPSE PUBLIC CLASS DEFINITION
+ // ================================
+
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, Collapse.DEFAULTS, options)
+ this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
+ '[data-toggle="collapse"][data-target="#' + element.id + '"]')
+ this.transitioning = null
+
+ if (this.options.parent) {
+ this.$parent = this.getParent()
+ } else {
+ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
+ }
+
+ if (this.options.toggle) this.toggle()
+ }
+
+ Collapse.VERSION = '3.3.6'
+
+ Collapse.TRANSITION_DURATION = 350
+
+ Collapse.DEFAULTS = {
+ toggle: true
+ }
+
+ Collapse.prototype.dimension = function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
+
+ Collapse.prototype.show = function () {
+ if (this.transitioning || this.$element.hasClass('in')) return
+
+ var activesData
+ var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
+
+ if (actives && actives.length) {
+ activesData = actives.data('bs.collapse')
+ if (activesData && activesData.transitioning) return
+ }
+
+ var startEvent = $.Event('show.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ if (actives && actives.length) {
+ Plugin.call(actives, 'hide')
+ activesData || actives.data('bs.collapse', null)
+ }
+
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ .addClass('collapsing')[dimension](0)
+ .attr('aria-expanded', true)
+
+ this.$trigger
+ .removeClass('collapsed')
+ .attr('aria-expanded', true)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse in')[dimension]('')
+ this.transitioning = 0
+ this.$element
+ .trigger('shown.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
+
+ this.$element
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
+ }
+
+ Collapse.prototype.hide = function () {
+ if (this.transitioning || !this.$element.hasClass('in')) return
+
+ var startEvent = $.Event('hide.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ var dimension = this.dimension()
+
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
+
+ this.$element
+ .addClass('collapsing')
+ .removeClass('collapse in')
+ .attr('aria-expanded', false)
+
+ this.$trigger
+ .addClass('collapsed')
+ .attr('aria-expanded', false)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.transitioning = 0
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse')
+ .trigger('hidden.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ this.$element
+ [dimension](0)
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+ }
+
+ Collapse.prototype.toggle = function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ Collapse.prototype.getParent = function () {
+ return $(this.options.parent)
+ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
+ .each($.proxy(function (i, element) {
+ var $element = $(element)
+ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
+ }, this))
+ .end()
+ }
+
+ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
+ var isOpen = $element.hasClass('in')
+
+ $element.attr('aria-expanded', isOpen)
+ $trigger
+ .toggleClass('collapsed', !isOpen)
+ .attr('aria-expanded', isOpen)
+ }
+
+ function getTargetFromTrigger($trigger) {
+ var href
+ var target = $trigger.attr('data-target')
+ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+
+ return $(target)
+ }
+
+
+ // COLLAPSE PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.collapse')
+ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
+ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.collapse
+
+ $.fn.collapse = Plugin
+ $.fn.collapse.Constructor = Collapse
+
+
+ // COLLAPSE NO CONFLICT
+ // ====================
+
+ $.fn.collapse.noConflict = function () {
+ $.fn.collapse = old
+ return this
+ }
+
+
+ // COLLAPSE DATA-API
+ // =================
+
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
+ var $this = $(this)
+
+ if (!$this.attr('data-target')) e.preventDefault()
+
+ var $target = getTargetFromTrigger($this)
+ var data = $target.data('bs.collapse')
+ var option = data ? 'toggle' : $this.data()
+
+ Plugin.call($target, option)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.3.6
+ * http://getbootstrap.com/javascript/#dropdowns
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // DROPDOWN CLASS DEFINITION
+ // =========================
+
+ var backdrop = '.dropdown-backdrop'
+ var toggle = '[data-toggle="dropdown"]'
+ var Dropdown = function (element) {
+ $(element).on('click.bs.dropdown', this.toggle)
+ }
+
+ Dropdown.VERSION = '3.3.6'
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ var $parent = selector && $(selector)
+
+ return $parent && $parent.length ? $parent : $this.parent()
+ }
+
+ function clearMenus(e) {
+ if (e && e.which === 3) return
+ $(backdrop).remove()
+ $(toggle).each(function () {
+ var $this = $(this)
+ var $parent = getParent($this)
+ var relatedTarget = { relatedTarget: this }
+
+ if (!$parent.hasClass('open')) return
+
+ if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
+
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this.attr('aria-expanded', 'false')
+ $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
+ })
+ }
+
+ Dropdown.prototype.toggle = function (e) {
+ var $this = $(this)
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+ // if mobile we use a backdrop because click events don't delegate
+ $(document.createElement('div'))
+ .addClass('dropdown-backdrop')
+ .insertAfter($(this))
+ .on('click', clearMenus)
+ }
+
+ var relatedTarget = { relatedTarget: this }
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this
+ .trigger('focus')
+ .attr('aria-expanded', 'true')
+
+ $parent
+ .toggleClass('open')
+ .trigger($.Event('shown.bs.dropdown', relatedTarget))
+ }
+
+ return false
+ }
+
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
+
+ var $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ var $parent = getParent($this)
+ var isActive = $parent.hasClass('open')
+
+ if (!isActive && e.which != 27 || isActive && e.which == 27) {
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
+ return $this.trigger('click')
+ }
+
+ var desc = ' li:not(.disabled):visible a'
+ var $items = $parent.find('.dropdown-menu' + desc)
+
+ if (!$items.length) return
+
+ var index = $items.index(e.target)
+
+ if (e.which == 38 && index > 0) index-- // up
+ if (e.which == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items.eq(index).trigger('focus')
+ }
+
+
+ // DROPDOWN PLUGIN DEFINITION
+ // ==========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.dropdown')
+
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ var old = $.fn.dropdown
+
+ $.fn.dropdown = Plugin
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ // DROPDOWN NO CONFLICT
+ // ====================
+
+ $.fn.dropdown.noConflict = function () {
+ $.fn.dropdown = old
+ return this
+ }
+
+
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
+ // ===================================
+
+ $(document)
+ .on('click.bs.dropdown.data-api', clearMenus)
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
+ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.6
+ * http://getbootstrap.com/javascript/#modals
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // MODAL CLASS DEFINITION
+ // ======================
+
+ var Modal = function (element, options) {
+ this.options = options
+ this.$body = $(document.body)
+ this.$element = $(element)
+ this.$dialog = this.$element.find('.modal-dialog')
+ this.$backdrop = null
+ this.isShown = null
+ this.originalBodyPad = null
+ this.scrollbarWidth = 0
+ this.ignoreBackdropClick = false
+
+ if (this.options.remote) {
+ this.$element
+ .find('.modal-content')
+ .load(this.options.remote, $.proxy(function () {
+ this.$element.trigger('loaded.bs.modal')
+ }, this))
+ }
+ }
+
+ Modal.VERSION = '3.3.6'
+
+ Modal.TRANSITION_DURATION = 300
+ Modal.BACKDROP_TRANSITION_DURATION = 150
+
+ Modal.DEFAULTS = {
+ backdrop: true,
+ keyboard: true,
+ show: true
+ }
+
+ Modal.prototype.toggle = function (_relatedTarget) {
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
+ }
+
+ Modal.prototype.show = function (_relatedTarget) {
+ var that = this
+ var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = true
+
+ this.checkScrollbar()
+ this.setScrollbar()
+ this.$body.addClass('modal-open')
+
+ this.escape()
+ this.resize()
+
+ this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
+
+ this.$dialog.on('mousedown.dismiss.bs.modal', function () {
+ that.$element.one('mouseup.dismiss.bs.modal', function (e) {
+ if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
+ })
+ })
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(that.$body) // don't move modals dom position
+ }
+
+ that.$element
+ .show()
+ .scrollTop(0)
+
+ that.adjustDialog()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element.addClass('in')
+
+ that.enforceFocus()
+
+ var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
+
+ transition ?
+ that.$dialog // wait for modal to slide in
+ .one('bsTransitionEnd', function () {
+ that.$element.trigger('focus').trigger(e)
+ })
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ that.$element.trigger('focus').trigger(e)
+ })
+ }
+
+ Modal.prototype.hide = function (e) {
+ if (e) e.preventDefault()
+
+ e = $.Event('hide.bs.modal')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ this.escape()
+ this.resize()
+
+ $(document).off('focusin.bs.modal')
+
+ this.$element
+ .removeClass('in')
+ .off('click.dismiss.bs.modal')
+ .off('mouseup.dismiss.bs.modal')
+
+ this.$dialog.off('mousedown.dismiss.bs.modal')
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$element
+ .one('bsTransitionEnd', $.proxy(this.hideModal, this))
+ .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
+ this.hideModal()
+ }
+
+ Modal.prototype.enforceFocus = function () {
+ $(document)
+ .off('focusin.bs.modal') // guard against infinite focus loop
+ .on('focusin.bs.modal', $.proxy(function (e) {
+ if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
+ this.$element.trigger('focus')
+ }
+ }, this))
+ }
+
+ Modal.prototype.escape = function () {
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
+ }
+ }
+
+ Modal.prototype.resize = function () {
+ if (this.isShown) {
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
+ } else {
+ $(window).off('resize.bs.modal')
+ }
+ }
+
+ Modal.prototype.hideModal = function () {
+ var that = this
+ this.$element.hide()
+ this.backdrop(function () {
+ that.$body.removeClass('modal-open')
+ that.resetAdjustments()
+ that.resetScrollbar()
+ that.$element.trigger('hidden.bs.modal')
+ })
+ }
+
+ Modal.prototype.removeBackdrop = function () {
+ this.$backdrop && this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ Modal.prototype.backdrop = function (callback) {
+ var that = this
+ var animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $(document.createElement('div'))
+ .addClass('modal-backdrop ' + animate)
+ .appendTo(this.$body)
+
+ this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
+ if (this.ignoreBackdropClick) {
+ this.ignoreBackdropClick = false
+ return
+ }
+ if (e.target !== e.currentTarget) return
+ this.options.backdrop == 'static'
+ ? this.$element[0].focus()
+ : this.hide()
+ }, this))
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ if (!callback) return
+
+ doAnimate ?
+ this.$backdrop
+ .one('bsTransitionEnd', callback)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ var callbackRemove = function () {
+ that.removeBackdrop()
+ callback && callback()
+ }
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.$backdrop
+ .one('bsTransitionEnd', callbackRemove)
+ .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+ // these following methods are used to handle overflowing modals
+
+ Modal.prototype.handleUpdate = function () {
+ this.adjustDialog()
+ }
+
+ Modal.prototype.adjustDialog = function () {
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
+
+ this.$element.css({
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
+ })
+ }
+
+ Modal.prototype.resetAdjustments = function () {
+ this.$element.css({
+ paddingLeft: '',
+ paddingRight: ''
+ })
+ }
+
+ Modal.prototype.checkScrollbar = function () {
+ var fullWindowWidth = window.innerWidth
+ if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
+ var documentElementRect = document.documentElement.getBoundingClientRect()
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
+ }
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
+ this.scrollbarWidth = this.measureScrollbar()
+ }
+
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+ this.originalBodyPad = document.body.style.paddingRight || ''
+ if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
+ }
+
+ Modal.prototype.resetScrollbar = function () {
+ this.$body.css('padding-right', this.originalBodyPad)
+ }
+
+ Modal.prototype.measureScrollbar = function () { // thx walsh
+ var scrollDiv = document.createElement('div')
+ scrollDiv.className = 'modal-scrollbar-measure'
+ this.$body.append(scrollDiv)
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
+ this.$body[0].removeChild(scrollDiv)
+ return scrollbarWidth
+ }
+
+
+ // MODAL PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option, _relatedTarget) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.modal')
+ var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
+
+ if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option](_relatedTarget)
+ else if (options.show) data.show(_relatedTarget)
+ })
+ }
+
+ var old = $.fn.modal
+
+ $.fn.modal = Plugin
+ $.fn.modal.Constructor = Modal
+
+
+ // MODAL NO CONFLICT
+ // =================
+
+ $.fn.modal.noConflict = function () {
+ $.fn.modal = old
+ return this
+ }
+
+
+ // MODAL DATA-API
+ // ==============
+
+ $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ var href = $this.attr('href')
+ var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
+ var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
+
+ if ($this.is('a')) e.preventDefault()
+
+ $target.one('show.bs.modal', function (showEvent) {
+ if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
+ $target.one('hidden.bs.modal', function () {
+ $this.is(':visible') && $this.trigger('focus')
+ })
+ })
+ Plugin.call($target, option, this)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tooltip.js v3.3.6
+ * http://getbootstrap.com/javascript/#tooltip
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TOOLTIP PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Tooltip = function (element, options) {
+ this.type = null
+ this.options = null
+ this.enabled = null
+ this.timeout = null
+ this.hoverState = null
+ this.$element = null
+ this.inState = null
+
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.VERSION = '3.3.6'
+
+ Tooltip.TRANSITION_DURATION = 150
+
+ Tooltip.DEFAULTS = {
+ animation: true,
+ placement: 'top',
+ selector: false,
+ template: '',
+ trigger: 'hover focus',
+ title: '',
+ delay: 0,
+ html: false,
+ container: false,
+ viewport: {
+ selector: 'body',
+ padding: 0
+ }
+ }
+
+ Tooltip.prototype.init = function (type, element, options) {
+ this.enabled = true
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
+ this.inState = { click: false, hover: false, focus: false }
+
+ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
+ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
+ }
+
+ var triggers = this.options.trigger.split(' ')
+
+ for (var i = triggers.length; i--;) {
+ var trigger = triggers[i]
+
+ if (trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (trigger != 'manual') {
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
+
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ Tooltip.prototype.getDefaults = function () {
+ return Tooltip.DEFAULTS
+ }
+
+ Tooltip.prototype.getOptions = function (options) {
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay,
+ hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ Tooltip.prototype.getDelegateOptions = function () {
+ var options = {}
+ var defaults = this.getDefaults()
+
+ this._options && $.each(this._options, function (key, value) {
+ if (defaults[key] != value) options[key] = value
+ })
+
+ return options
+ }
+
+ Tooltip.prototype.enter = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
+ }
+
+ if (self.tip().hasClass('in') || self.hoverState == 'in') {
+ self.hoverState = 'in'
+ return
+ }
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'in'
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ Tooltip.prototype.isInStateTrue = function () {
+ for (var key in this.inState) {
+ if (this.inState[key]) return true
+ }
+
+ return false
+ }
+
+ Tooltip.prototype.leave = function (obj) {
+ var self = obj instanceof this.constructor ?
+ obj : $(obj.currentTarget).data('bs.' + this.type)
+
+ if (!self) {
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
+ $(obj.currentTarget).data('bs.' + this.type, self)
+ }
+
+ if (obj instanceof $.Event) {
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
+ }
+
+ if (self.isInStateTrue()) return
+
+ clearTimeout(self.timeout)
+
+ self.hoverState = 'out'
+
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.timeout = setTimeout(function () {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ Tooltip.prototype.show = function () {
+ var e = $.Event('show.bs.' + this.type)
+
+ if (this.hasContent() && this.enabled) {
+ this.$element.trigger(e)
+
+ var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
+ if (e.isDefaultPrevented() || !inDom) return
+ var that = this
+
+ var $tip = this.tip()
+
+ var tipId = this.getUID(this.type)
+
+ this.setContent()
+ $tip.attr('id', tipId)
+ this.$element.attr('aria-describedby', tipId)
+
+ if (this.options.animation) $tip.addClass('fade')
+
+ var placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ var autoToken = /\s?auto?\s?/i
+ var autoPlace = autoToken.test(placement)
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
+
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+ .addClass(placement)
+ .data('bs.' + this.type, this)
+
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
+ this.$element.trigger('inserted.bs.' + this.type)
+
+ var pos = this.getPosition()
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (autoPlace) {
+ var orgPlacement = placement
+ var viewportDim = this.getPosition(this.$viewport)
+
+ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
+ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
+ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
+ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
+ placement
+
+ $tip
+ .removeClass(orgPlacement)
+ .addClass(placement)
+ }
+
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+
+ this.applyPlacement(calculatedOffset, placement)
+
+ var complete = function () {
+ var prevHoverState = that.hoverState
+ that.$element.trigger('shown.bs.' + that.type)
+ that.hoverState = null
+
+ if (prevHoverState == 'out') that.leave(that)
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+ }
+ }
+
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
+ var $tip = this.tip()
+ var width = $tip[0].offsetWidth
+ var height = $tip[0].offsetHeight
+
+ // manually read margins because getBoundingClientRect includes difference
+ var marginTop = parseInt($tip.css('margin-top'), 10)
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
+
+ // we must check for NaN for ie 8/9
+ if (isNaN(marginTop)) marginTop = 0
+ if (isNaN(marginLeft)) marginLeft = 0
+
+ offset.top += marginTop
+ offset.left += marginLeft
+
+ // $.fn.offset doesn't round pixel values
+ // so we use setOffset directly with our own function B-0
+ $.offset.setOffset($tip[0], $.extend({
+ using: function (props) {
+ $tip.css({
+ top: Math.round(props.top),
+ left: Math.round(props.left)
+ })
+ }
+ }, offset), 0)
+
+ $tip.addClass('in')
+
+ // check to see if placing tip in new offset caused the tip to resize itself
+ var actualWidth = $tip[0].offsetWidth
+ var actualHeight = $tip[0].offsetHeight
+
+ if (placement == 'top' && actualHeight != height) {
+ offset.top = offset.top + height - actualHeight
+ }
+
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
+
+ if (delta.left) offset.left += delta.left
+ else offset.top += delta.top
+
+ var isVertical = /top|bottom/.test(placement)
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
+
+ $tip.offset(offset)
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+ }
+
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
+ this.arrow()
+ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+ .css(isVertical ? 'top' : 'left', '')
+ }
+
+ Tooltip.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ Tooltip.prototype.hide = function (callback) {
+ var that = this
+ var $tip = $(this.$tip)
+ var e = $.Event('hide.bs.' + this.type)
+
+ function complete() {
+ if (that.hoverState != 'in') $tip.detach()
+ that.$element
+ .removeAttr('aria-describedby')
+ .trigger('hidden.bs.' + that.type)
+ callback && callback()
+ }
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $tip.removeClass('in')
+
+ $.support.transition && $tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ complete()
+
+ this.hoverState = null
+
+ return this
+ }
+
+ Tooltip.prototype.fixTitle = function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
+ }
+ }
+
+ Tooltip.prototype.hasContent = function () {
+ return this.getTitle()
+ }
+
+ Tooltip.prototype.getPosition = function ($element) {
+ $element = $element || this.$element
+
+ var el = $element[0]
+ var isBody = el.tagName == 'BODY'
+
+ var elRect = el.getBoundingClientRect()
+ if (elRect.width == null) {
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
+ }
+ var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
+ }
+
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
+
+ }
+
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
+ var delta = { top: 0, left: 0 }
+ if (!this.$viewport) return delta
+
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
+ var viewportDimensions = this.getPosition(this.$viewport)
+
+ if (/right|left/.test(placement)) {
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
+ delta.top = viewportDimensions.top - topEdgeOffset
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
+ }
+ } else {
+ var leftEdgeOffset = pos.left - viewportPadding
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
+ delta.left = viewportDimensions.left - leftEdgeOffset
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
+ }
+ }
+
+ return delta
+ }
+
+ Tooltip.prototype.getTitle = function () {
+ var title
+ var $e = this.$element
+ var o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ Tooltip.prototype.getUID = function (prefix) {
+ do prefix += ~~(Math.random() * 1000000)
+ while (document.getElementById(prefix))
+ return prefix
+ }
+
+ Tooltip.prototype.tip = function () {
+ if (!this.$tip) {
+ this.$tip = $(this.options.template)
+ if (this.$tip.length != 1) {
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
+ }
+ }
+ return this.$tip
+ }
+
+ Tooltip.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
+ }
+
+ Tooltip.prototype.enable = function () {
+ this.enabled = true
+ }
+
+ Tooltip.prototype.disable = function () {
+ this.enabled = false
+ }
+
+ Tooltip.prototype.toggleEnabled = function () {
+ this.enabled = !this.enabled
+ }
+
+ Tooltip.prototype.toggle = function (e) {
+ var self = this
+ if (e) {
+ self = $(e.currentTarget).data('bs.' + this.type)
+ if (!self) {
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
+ $(e.currentTarget).data('bs.' + this.type, self)
+ }
+ }
+
+ if (e) {
+ self.inState.click = !self.inState.click
+ if (self.isInStateTrue()) self.enter(self)
+ else self.leave(self)
+ } else {
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
+ }
+ }
+
+ Tooltip.prototype.destroy = function () {
+ var that = this
+ clearTimeout(this.timeout)
+ this.hide(function () {
+ that.$element.off('.' + that.type).removeData('bs.' + that.type)
+ if (that.$tip) {
+ that.$tip.detach()
+ }
+ that.$tip = null
+ that.$arrow = null
+ that.$viewport = null
+ })
+ }
+
+
+ // TOOLTIP PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tooltip')
+ var options = typeof option == 'object' && option
+
+ if (!data && /destroy|hide/.test(option)) return
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tooltip
+
+ $.fn.tooltip = Plugin
+ $.fn.tooltip.Constructor = Tooltip
+
+
+ // TOOLTIP NO CONFLICT
+ // ===================
+
+ $.fn.tooltip.noConflict = function () {
+ $.fn.tooltip = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: popover.js v3.3.6
+ * http://getbootstrap.com/javascript/#popovers
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // POPOVER PUBLIC CLASS DEFINITION
+ // ===============================
+
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ }
+
+ if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
+
+ Popover.VERSION = '3.3.6'
+
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: ''
+ })
+
+
+ // NOTE: POPOVER EXTENDS tooltip.js
+ // ================================
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
+
+ Popover.prototype.constructor = Popover
+
+ Popover.prototype.getDefaults = function () {
+ return Popover.DEFAULTS
+ }
+
+ Popover.prototype.setContent = function () {
+ var $tip = this.tip()
+ var title = this.getTitle()
+ var content = this.getContent()
+
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+ $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
+ this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
+ ](content)
+
+ $tip.removeClass('fade top bottom left right in')
+
+ // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
+ // this manually by checking the contents.
+ if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
+ }
+
+ Popover.prototype.hasContent = function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ Popover.prototype.getContent = function () {
+ var $e = this.$element
+ var o = this.options
+
+ return $e.attr('data-content')
+ || (typeof o.content == 'function' ?
+ o.content.call($e[0]) :
+ o.content)
+ }
+
+ Popover.prototype.arrow = function () {
+ return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
+ }
+
+
+ // POPOVER PLUGIN DEFINITION
+ // =========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.popover')
+ var options = typeof option == 'object' && option
+
+ if (!data && /destroy|hide/.test(option)) return
+ if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.popover
+
+ $.fn.popover = Plugin
+ $.fn.popover.Constructor = Popover
+
+
+ // POPOVER NO CONFLICT
+ // ===================
+
+ $.fn.popover.noConflict = function () {
+ $.fn.popover = old
+ return this
+ }
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: scrollspy.js v3.3.6
+ * http://getbootstrap.com/javascript/#scrollspy
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // SCROLLSPY CLASS DEFINITION
+ // ==========================
+
+ function ScrollSpy(element, options) {
+ this.$body = $(document.body)
+ this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
+ this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
+ this.selector = (this.options.target || '') + ' .nav li > a'
+ this.offsets = []
+ this.targets = []
+ this.activeTarget = null
+ this.scrollHeight = 0
+
+ this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
+ this.refresh()
+ this.process()
+ }
+
+ ScrollSpy.VERSION = '3.3.6'
+
+ ScrollSpy.DEFAULTS = {
+ offset: 10
+ }
+
+ ScrollSpy.prototype.getScrollHeight = function () {
+ return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
+ }
+
+ ScrollSpy.prototype.refresh = function () {
+ var that = this
+ var offsetMethod = 'offset'
+ var offsetBase = 0
+
+ this.offsets = []
+ this.targets = []
+ this.scrollHeight = this.getScrollHeight()
+
+ if (!$.isWindow(this.$scrollElement[0])) {
+ offsetMethod = 'position'
+ offsetBase = this.$scrollElement.scrollTop()
+ }
+
+ this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ var href = $el.data('target') || $el.attr('href')
+ var $href = /^#./.test(href) && $(href)
+
+ return ($href
+ && $href.length
+ && $href.is(':visible')
+ && [[$href[offsetMethod]().top + offsetBase, href]]) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ that.offsets.push(this[0])
+ that.targets.push(this[1])
+ })
+ }
+
+ ScrollSpy.prototype.process = function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ var scrollHeight = this.getScrollHeight()
+ var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
+ var offsets = this.offsets
+ var targets = this.targets
+ var activeTarget = this.activeTarget
+ var i
+
+ if (this.scrollHeight != scrollHeight) {
+ this.refresh()
+ }
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
+ }
+
+ if (activeTarget && scrollTop < offsets[0]) {
+ this.activeTarget = null
+ return this.clear()
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
+ && this.activate(targets[i])
+ }
+ }
+
+ ScrollSpy.prototype.activate = function (target) {
+ this.activeTarget = target
+
+ this.clear()
+
+ var selector = this.selector +
+ '[data-target="' + target + '"],' +
+ this.selector + '[href="' + target + '"]'
+
+ var active = $(selector)
+ .parents('li')
+ .addClass('active')
+
+ if (active.parent('.dropdown-menu').length) {
+ active = active
+ .closest('li.dropdown')
+ .addClass('active')
+ }
+
+ active.trigger('activate.bs.scrollspy')
+ }
+
+ ScrollSpy.prototype.clear = function () {
+ $(this.selector)
+ .parentsUntil(this.options.target, '.active')
+ .removeClass('active')
+ }
+
+
+ // SCROLLSPY PLUGIN DEFINITION
+ // ===========================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.scrollspy')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.scrollspy
+
+ $.fn.scrollspy = Plugin
+ $.fn.scrollspy.Constructor = ScrollSpy
+
+
+ // SCROLLSPY NO CONFLICT
+ // =====================
+
+ $.fn.scrollspy.noConflict = function () {
+ $.fn.scrollspy = old
+ return this
+ }
+
+
+ // SCROLLSPY DATA-API
+ // ==================
+
+ $(window).on('load.bs.scrollspy.data-api', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ Plugin.call($spy, $spy.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: tab.js v3.3.6
+ * http://getbootstrap.com/javascript/#tabs
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // TAB CLASS DEFINITION
+ // ====================
+
+ var Tab = function (element) {
+ // jscs:disable requireDollarBeforejQueryAssignment
+ this.element = $(element)
+ // jscs:enable requireDollarBeforejQueryAssignment
+ }
+
+ Tab.VERSION = '3.3.6'
+
+ Tab.TRANSITION_DURATION = 150
+
+ Tab.prototype.show = function () {
+ var $this = this.element
+ var $ul = $this.closest('ul:not(.dropdown-menu)')
+ var selector = $this.data('target')
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
+ }
+
+ if ($this.parent('li').hasClass('active')) return
+
+ var $previous = $ul.find('.active:last a')
+ var hideEvent = $.Event('hide.bs.tab', {
+ relatedTarget: $this[0]
+ })
+ var showEvent = $.Event('show.bs.tab', {
+ relatedTarget: $previous[0]
+ })
+
+ $previous.trigger(hideEvent)
+ $this.trigger(showEvent)
+
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
+
+ var $target = $(selector)
+
+ this.activate($this.closest('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $previous.trigger({
+ type: 'hidden.bs.tab',
+ relatedTarget: $this[0]
+ })
+ $this.trigger({
+ type: 'shown.bs.tab',
+ relatedTarget: $previous[0]
+ })
+ })
+ }
+
+ Tab.prototype.activate = function (element, container, callback) {
+ var $active = container.find('> .active')
+ var transition = callback
+ && $.support.transition
+ && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', false)
+
+ element
+ .addClass('active')
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if (element.parent('.dropdown-menu').length) {
+ element
+ .closest('li.dropdown')
+ .addClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+ }
+
+ callback && callback()
+ }
+
+ $active.length && transition ?
+ $active
+ .one('bsTransitionEnd', next)
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+ next()
+
+ $active.removeClass('in')
+ }
+
+
+ // TAB PLUGIN DEFINITION
+ // =====================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.tab')
+
+ if (!data) $this.data('bs.tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.tab
+
+ $.fn.tab = Plugin
+ $.fn.tab.Constructor = Tab
+
+
+ // TAB NO CONFLICT
+ // ===============
+
+ $.fn.tab.noConflict = function () {
+ $.fn.tab = old
+ return this
+ }
+
+
+ // TAB DATA-API
+ // ============
+
+ var clickHandler = function (e) {
+ e.preventDefault()
+ Plugin.call($(this), 'show')
+ }
+
+ $(document)
+ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
+ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.6
+ * http://getbootstrap.com/javascript/#affix
+ * ========================================================================
+ * Copyright 2011-2015 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * ======================================================================== */
+
+
++function ($) {
+ 'use strict';
+
+ // AFFIX CLASS DEFINITION
+ // ======================
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, Affix.DEFAULTS, options)
+
+ this.$target = $(this.options.target)
+ .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
+
+ this.$element = $(element)
+ this.affixed = null
+ this.unpin = null
+ this.pinnedOffset = null
+
+ this.checkPosition()
+ }
+
+ Affix.VERSION = '3.3.6'
+
+ Affix.RESET = 'affix affix-top affix-bottom'
+
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ }
+
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ var targetHeight = this.$target.height()
+
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
+ }
+
+ var initializing = this.affixed == null
+ var colliderTop = initializing ? scrollTop : position.top
+ var colliderHeight = initializing ? targetHeight : height
+
+ if (offsetTop != null && scrollTop <= offsetTop) return 'top'
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+
+ return false
+ }
+
+ Affix.prototype.getPinnedOffset = function () {
+ if (this.pinnedOffset) return this.pinnedOffset
+ this.$element.removeClass(Affix.RESET).addClass('affix')
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ return (this.pinnedOffset = position.top - scrollTop)
+ }
+
+ Affix.prototype.checkPositionWithEventLoop = function () {
+ setTimeout($.proxy(this.checkPosition, this), 1)
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
+
+ var height = this.$element.height()
+ var offset = this.options.offset
+ var offsetTop = offset.top
+ var offsetBottom = offset.bottom
+ var scrollHeight = Math.max($(document).height(), $(document.body).height())
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
+
+ var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
+
+ if (this.affixed != affix) {
+ if (this.unpin != null) this.$element.css('top', '')
+
+ var affixType = 'affix' + (affix ? '-' + affix : '')
+ var e = $.Event(affixType + '.bs.affix')
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
+
+ this.$element
+ .removeClass(Affix.RESET)
+ .addClass(affixType)
+ .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
+
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - height - offsetBottom
+ })
+ }
+ }
+
+
+ // AFFIX PLUGIN DEFINITION
+ // =======================
+
+ function Plugin(option) {
+ return this.each(function () {
+ var $this = $(this)
+ var data = $this.data('bs.affix')
+ var options = typeof option == 'object' && option
+
+ if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ var old = $.fn.affix
+
+ $.fn.affix = Plugin
+ $.fn.affix.Constructor = Affix
+
+
+ // AFFIX NO CONFLICT
+ // =================
+
+ $.fn.affix.noConflict = function () {
+ $.fn.affix = old
+ return this
+ }
+
+
+ // AFFIX DATA-API
+ // ==============
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ var data = $spy.data()
+
+ data.offset = data.offset || {}
+
+ if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
+ if (data.offsetTop != null) data.offset.top = data.offsetTop
+
+ Plugin.call($spy, data)
+ })
+ })
+
+}(jQuery);
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/bootstrap.min.js b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/bootstrap.min.js
new file mode 100644
index 0000000..12ae598
--- /dev/null
+++ b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.6 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/npm.js b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/npm.js
new file mode 100644
index 0000000..bf6aa80
--- /dev/null
+++ b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/js/npm.js
@@ -0,0 +1,13 @@
+// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
+require('../../js/transition.js')
+require('../../js/alert.js')
+require('../../js/button.js')
+require('../../js/carousel.js')
+require('../../js/collapse.js')
+require('../../js/dropdown.js')
+require('../../js/modal.js')
+require('../../js/tooltip.js')
+require('../../js/popover.js')
+require('../../js/scrollspy.js')
+require('../../js/tab.js')
+require('../../js/affix.js')
\ No newline at end of file
diff --git a/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/variables.less b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/variables.less
new file mode 100644
index 0000000..2b815d7
--- /dev/null
+++ b/copri4/shareeweb-project/js/bootstrap-3.3.6-dist/variables.less
@@ -0,0 +1,870 @@
+//
+// Variables
+// --------------------------------------------------
+
+
+//== Colors
+//
+//## Gray and brand colors for use across Bootstrap.
+
+@gray-base: #0061a1;
+@gray-darker: #0061a1;
+@gray-dark: #0061a1;
+@gray: #0061a1;
+@gray-light: #0061a1;
+@gray-lighter: #0061a1;
+
+@brand-primary: #0061a1;
+@brand-success: #5cb85c;
+@brand-info: #5bc0de;
+@brand-warning: #f0ad4e;
+@brand-danger: #d9534f;
+
+
+//== Scaffolding
+//
+//## Settings for some of the most global styles.
+
+//** Background color for ``.
+@body-bg: #0061a1;
+//** Global text color on ``.
+@text-color: @gray-dark;
+
+//** Global textual link color.
+@link-color: @brand-primary;
+//** Link hover color set via `darken()` function.
+@link-hover-color: darken(@link-color, 15%);
+//** Link hover decoration.
+@link-hover-decoration: underline;
+
+
+//== Typography
+//
+//## Font, line-height, and color for body text, headings, and more.
+
+@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif;
+@font-family-serif: Georgia, "Times New Roman", Times, serif;
+//** Default monospace fonts for ``, ``, and ``.
+@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
+@font-family-base: @font-family-sans-serif;
+
+@font-size-base: 14px;
+@font-size-large: ceil((@font-size-base * 1.25)); // ~18px
+@font-size-small: ceil((@font-size-base * 0.85)); // ~12px
+
+@font-size-h1: floor((@font-size-base * 2.6)); // ~36px
+@font-size-h2: floor((@font-size-base * 2.15)); // ~30px
+@font-size-h3: ceil((@font-size-base * 1.7)); // ~24px
+@font-size-h4: ceil((@font-size-base * 1.25)); // ~18px
+@font-size-h5: @font-size-base;
+@font-size-h6: ceil((@font-size-base * 0.85)); // ~12px
+
+//** Unit-less `line-height` for use in components like buttons.
+@line-height-base: 1.428571429; // 20/14
+//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
+@line-height-computed: floor((@font-size-base * @line-height-base)); // ~20px
+
+//** By default, this inherits from the ``.
+@headings-font-family: inherit;
+@headings-font-weight: 500;
+@headings-line-height: 1.1;
+@headings-color: inherit;
+
+
+//== Iconography
+//
+//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
+
+//** Load fonts from this directory.
+@icon-font-path: "../fonts/";
+//** File name for all font files.
+@icon-font-name: "glyphicons-halflings-regular";
+//** Element ID within SVG icon file.
+@icon-font-svg-id: "glyphicons_halflingsregular";
+
+
+//== Components
+//
+//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
+
+@padding-base-vertical: 6px;
+@padding-base-horizontal: 12px;
+
+@padding-large-vertical: 10px;
+@padding-large-horizontal: 16px;
+
+@padding-small-vertical: 5px;
+@padding-small-horizontal: 10px;
+
+@padding-xs-vertical: 1px;
+@padding-xs-horizontal: 5px;
+
+@line-height-large: 1.3333333; // extra decimals for Win 8.1 Chrome
+@line-height-small: 1.5;
+
+@border-radius-base: 0px;
+@border-radius-large: 0px;
+@border-radius-small: 0px;
+
+//** Global color for active items (e.g., navs or dropdowns).
+@component-active-color: #fff;
+//** Global background color for active items (e.g., navs or dropdowns).
+@component-active-bg: @brand-primary;
+
+//** Width of the `border` for generating carets that indicator dropdowns.
+@caret-width-base: 4px;
+//** Carets increase slightly in size for larger components.
+@caret-width-large: 5px;
+
+
+//== Tables
+//
+//## Customizes the `.table` component with basic values, each used across all table variations.
+
+//** Padding for ``s and ` `s.
+@table-cell-padding: 8px;
+//** Padding for cells in `.table-condensed`.
+@table-condensed-cell-padding: 5px;
+
+//** Default background color used for all tables.
+@table-bg: transparent;
+//** Background color used for `.table-striped`.
+@table-bg-accent: #f9f9f9;
+//** Background color used for `.table-hover`.
+@table-bg-hover: #f5f5f5;
+@table-bg-active: @table-bg-hover;
+
+//** Border color for table and cell borders.
+@table-border-color: #0061a1;
+
+
+//== Buttons
+//
+//## For each of Bootstrap's buttons, define text, background and border color.
+
+@btn-font-weight: normal;
+
+@btn-default-color: #cccccc;
+@btn-default-bg: #fff;
+@btn-default-border: #ccc;
+
+@btn-primary-color: #fff;
+@btn-primary-bg: @brand-primary;
+@btn-primary-border: darken(@btn-primary-bg, 5%);
+
+@btn-success-color: #fff;
+@btn-success-bg: @brand-success;
+@btn-success-border: darken(@btn-success-bg, 5%);
+
+@btn-info-color: #fff;
+@btn-info-bg: @brand-info;
+@btn-info-border: darken(@btn-info-bg, 5%);
+
+@btn-warning-color: #fff;
+@btn-warning-bg: @brand-warning;
+@btn-warning-border: darken(@btn-warning-bg, 5%);
+
+@btn-danger-color: #fff;
+@btn-danger-bg: @brand-danger;
+@btn-danger-border: darken(@btn-danger-bg, 5%);
+
+@btn-link-disabled-color: @gray-light;
+
+// Allows for customizing button radius independently from global border radius
+@btn-border-radius-base: @border-radius-base;
+@btn-border-radius-large: @border-radius-large;
+@btn-border-radius-small: @border-radius-small;
+
+
+//== Forms
+//
+//##
+
+//** ` ` background color
+@input-bg: #fff;
+//** ` ` background color
+@input-bg-disabled: @gray-lighter;
+
+//** Text color for ` `s
+@input-color: @gray;
+//** ` ` border color
+@input-border: #ccc;
+
+// TODO: Rename `@input-border-radius` to `@input-border-radius-base` in v4
+//** Default `.form-control` border radius
+// This has no effect on ``s in some browsers, due to the limited stylability of ``s in CSS.
+@input-border-radius: @border-radius-base;
+//** Large `.form-control` border radius
+@input-border-radius-large: @border-radius-large;
+//** Small `.form-control` border radius
+@input-border-radius-small: @border-radius-small;
+
+//** Border color for inputs on focus
+@input-border-focus: #66afe9;
+
+//** Placeholder text color
+@input-color-placeholder: #999;
+
+//** Default `.form-control` height
+@input-height-base: (@line-height-computed + (@padding-base-vertical * 2) + 2);
+//** Large `.form-control` height
+@input-height-large: (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
+//** Small `.form-control` height
+@input-height-small: (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
+
+//** `.form-group` margin
+@form-group-margin-bottom: 15px;
+
+@legend-color: @gray-dark;
+@legend-border-color: #e5e5e5;
+
+//** Background color for textual input addons
+@input-group-addon-bg: @gray-lighter;
+//** Border color for textual input addons
+@input-group-addon-border-color: @input-border;
+
+//** Disabled cursor for form controls and buttons.
+@cursor-disabled: not-allowed;
+
+
+//== Dropdowns
+//
+//## Dropdown menu container and contents.
+
+//** Background for the dropdown menu.
+@dropdown-bg: #fff;
+//** Dropdown menu `border-color`.
+@dropdown-border: rgba(0,0,0,.15);
+//** Dropdown menu `border-color` **for IE8**.
+@dropdown-fallback-border: #ccc;
+//** Divider color for between dropdown items.
+@dropdown-divider-bg: #e5e5e5;
+
+//** Dropdown link text color.
+@dropdown-link-color: @gray-dark;
+//** Hover color for dropdown links.
+@dropdown-link-hover-color: darken(@gray-dark, 5%);
+//** Hover background for dropdown links.
+@dropdown-link-hover-bg: #f5f5f5;
+
+//** Active dropdown menu item text color.
+@dropdown-link-active-color: @component-active-color;
+//** Active dropdown menu item background color.
+@dropdown-link-active-bg: @component-active-bg;
+
+//** Disabled dropdown menu item background color.
+@dropdown-link-disabled-color: @gray-light;
+
+//** Text color for headers within dropdown menus.
+@dropdown-header-color: @gray-light;
+
+//** Deprecated `@dropdown-caret-color` as of v3.1.0
+@dropdown-caret-color: #000;
+
+
+//-- Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+//
+// Note: These variables are not generated into the Customizer.
+
+@zindex-navbar: 1000;
+@zindex-dropdown: 1000;
+@zindex-popover: 1060;
+@zindex-tooltip: 1070;
+@zindex-navbar-fixed: 1030;
+@zindex-modal-background: 1040;
+@zindex-modal: 1050;
+
+
+//== Media queries breakpoints
+//
+//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
+
+// Extra small screen / phone
+//** Deprecated `@screen-xs` as of v3.0.1
+@screen-xs: 480px;
+//** Deprecated `@screen-xs-min` as of v3.2.0
+@screen-xs-min: @screen-xs;
+//** Deprecated `@screen-phone` as of v3.0.1
+@screen-phone: @screen-xs-min;
+
+// Small screen / tablet
+//** Deprecated `@screen-sm` as of v3.0.1
+@screen-sm: 768px;
+@screen-sm-min: @screen-sm;
+//** Deprecated `@screen-tablet` as of v3.0.1
+@screen-tablet: @screen-sm-min;
+
+// Medium screen / desktop
+//** Deprecated `@screen-md` as of v3.0.1
+@screen-md: 992px;
+@screen-md-min: @screen-md;
+//** Deprecated `@screen-desktop` as of v3.0.1
+@screen-desktop: @screen-md-min;
+
+// Large screen / wide desktop
+//** Deprecated `@screen-lg` as of v3.0.1
+@screen-lg: 1200px;
+@screen-lg-min: @screen-lg;
+//** Deprecated `@screen-lg-desktop` as of v3.0.1
+@screen-lg-desktop: @screen-lg-min;
+
+// So media queries don't overlap when required, provide a maximum
+@screen-xs-max: (@screen-sm-min - 1);
+@screen-sm-max: (@screen-md-min - 1);
+@screen-md-max: (@screen-lg-min - 1);
+
+
+//== Grid system
+//
+//## Define your custom responsive grid.
+
+//** Number of columns in the grid.
+@grid-columns: 12;
+//** Padding between columns. Gets divided in half for the left and right.
+@grid-gutter-width: 30px;
+// Navbar collapse
+//** Point at which the navbar becomes uncollapsed.
+@grid-float-breakpoint: @screen-sm-min;
+//** Point at which the navbar begins collapsing.
+@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
+
+
+//== Container sizes
+//
+//## Define the maximum width of `.container` for different screen sizes.
+
+// Small screen / tablet
+@container-tablet: (720px + @grid-gutter-width);
+//** For `@screen-sm-min` and up.
+@container-sm: @container-tablet;
+
+// Medium screen / desktop
+@container-desktop: (940px + @grid-gutter-width);
+//** For `@screen-md-min` and up.
+@container-md: @container-desktop;
+
+// Large screen / wide desktop
+@container-large-desktop: (1140px + @grid-gutter-width);
+//** For `@screen-lg-min` and up.
+@container-lg: @container-large-desktop;
+
+
+//== Navbar
+//
+//##
+
+// Basics of a navbar
+@navbar-height: 70px;
+@navbar-margin-bottom: @line-height-computed;
+@navbar-border-radius: @border-radius-base;
+@navbar-padding-horizontal: floor((@grid-gutter-width / 2));
+@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);
+@navbar-collapse-max-height: 340px;
+
+@navbar-default-color: #ffffff;
+@navbar-default-bg: #0061a1;
+@navbar-default-border: #0061a1;
+
+// Navbar links
+@navbar-default-link-color: #ffffff;
+@navbar-default-link-hover-color: #cccccc;
+@navbar-default-link-hover-bg: transparent;
+@navbar-default-link-active-color: #cccccc;
+//@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%);
+@navbar-default-link-active-bg: @navbar-default-bg;
+@navbar-default-link-disabled-color: #ccc;
+@navbar-default-link-disabled-bg: transparent;
+
+// Navbar brand label
+@navbar-default-brand-color: @navbar-default-link-color;
+@navbar-default-brand-hover-color: darken(@navbar-default-brand-color, 10%);
+@navbar-default-brand-hover-bg: transparent;
+
+// Navbar toggle
+@navbar-default-toggle-hover-bg: #ddd;
+@navbar-default-toggle-icon-bar-bg: #888;
+@navbar-default-toggle-border-color: #ddd;
+
+
+//=== Inverted navbar
+// Reset inverted navbar basics
+@navbar-inverse-color: lighten(@gray-light, 15%);
+@navbar-inverse-bg: #222;
+@navbar-inverse-border: darken(@navbar-inverse-bg, 10%);
+
+// Inverted navbar links
+@navbar-inverse-link-color: lighten(@gray-light, 15%);
+@navbar-inverse-link-hover-color: #fff;
+@navbar-inverse-link-hover-bg: transparent;
+@navbar-inverse-link-active-color: @navbar-inverse-link-hover-color;
+@navbar-inverse-link-active-bg: darken(@navbar-inverse-bg, 10%);
+@navbar-inverse-link-disabled-color: #444;
+@navbar-inverse-link-disabled-bg: transparent;
+
+// Inverted navbar brand label
+@navbar-inverse-brand-color: @navbar-inverse-link-color;
+@navbar-inverse-brand-hover-color: #fff;
+@navbar-inverse-brand-hover-bg: transparent;
+
+// Inverted navbar toggle
+@navbar-inverse-toggle-hover-bg: #cccccc;
+@navbar-inverse-toggle-icon-bar-bg: #fff;
+@navbar-inverse-toggle-border-color: #cccccc;
+
+
+//== Navs
+//
+//##
+
+//=== Shared nav styles
+@nav-link-padding: 10px 15px;
+@nav-link-hover-bg: @gray-lighter;
+
+@nav-disabled-link-color: @gray-light;
+@nav-disabled-link-hover-color: @gray-light;
+
+//== Tabs
+@nav-tabs-border-color: #ddd;
+
+@nav-tabs-link-hover-border-color: @gray-lighter;
+
+@nav-tabs-active-link-hover-bg: @body-bg;
+@nav-tabs-active-link-hover-color: @gray;
+@nav-tabs-active-link-hover-border-color: #ddd;
+
+@nav-tabs-justified-link-border-color: #ddd;
+@nav-tabs-justified-active-link-border-color: @body-bg;
+
+//== Pills
+@nav-pills-border-radius: @border-radius-base;
+@nav-pills-active-link-hover-bg: @component-active-bg;
+@nav-pills-active-link-hover-color: @component-active-color;
+
+
+//== Pagination
+//
+//##
+
+@pagination-color: @link-color;
+@pagination-bg: #fff;
+@pagination-border: #ddd;
+
+@pagination-hover-color: @link-hover-color;
+@pagination-hover-bg: @gray-lighter;
+@pagination-hover-border: #ddd;
+
+@pagination-active-color: #fff;
+@pagination-active-bg: @brand-primary;
+@pagination-active-border: @brand-primary;
+
+@pagination-disabled-color: @gray-light;
+@pagination-disabled-bg: #fff;
+@pagination-disabled-border: #ddd;
+
+
+//== Pager
+//
+//##
+
+@pager-bg: @pagination-bg;
+@pager-border: @pagination-border;
+@pager-border-radius: 15px;
+
+@pager-hover-bg: @pagination-hover-bg;
+
+@pager-active-bg: @pagination-active-bg;
+@pager-active-color: @pagination-active-color;
+
+@pager-disabled-color: @pagination-disabled-color;
+
+
+//== Jumbotron
+//
+//##
+
+@jumbotron-padding: 30px;
+@jumbotron-color: inherit;
+@jumbotron-bg: @gray-lighter;
+@jumbotron-heading-color: inherit;
+@jumbotron-font-size: ceil((@font-size-base * 1.5));
+@jumbotron-heading-font-size: ceil((@font-size-base * 4.5));
+
+
+//== Form states and alerts
+//
+//## Define colors for form feedback states and, by default, alerts.
+
+@state-success-text: #3c763d;
+@state-success-bg: #dff0d8;
+@state-success-border: darken(spin(@state-success-bg, -10), 5%);
+
+@state-info-text: #31708f;
+@state-info-bg: #d9edf7;
+@state-info-border: darken(spin(@state-info-bg, -10), 7%);
+
+@state-warning-text: #8a6d3b;
+@state-warning-bg: #fcf8e3;
+@state-warning-border: darken(spin(@state-warning-bg, -10), 5%);
+
+@state-danger-text: #a94442;
+@state-danger-bg: #f2dede;
+@state-danger-border: darken(spin(@state-danger-bg, -10), 5%);
+
+
+//== Tooltips
+//
+//##
+
+//** Tooltip max width
+@tooltip-max-width: 200px;
+//** Tooltip text color
+@tooltip-color: #fff;
+//** Tooltip background color
+@tooltip-bg: #000;
+@tooltip-opacity: .9;
+
+//** Tooltip arrow width
+@tooltip-arrow-width: 5px;
+//** Tooltip arrow color
+@tooltip-arrow-color: @tooltip-bg;
+
+
+//== Popovers
+//
+//##
+
+//** Popover body background color
+@popover-bg: #fff;
+//** Popover maximum width
+@popover-max-width: 276px;
+//** Popover border color
+@popover-border-color: rgba(0,0,0,.2);
+//** Popover fallback border color
+@popover-fallback-border-color: #ccc;
+
+//** Popover title background color
+@popover-title-bg: darken(@popover-bg, 3%);
+
+//** Popover arrow width
+@popover-arrow-width: 10px;
+//** Popover arrow color
+@popover-arrow-color: @popover-bg;
+
+//** Popover outer arrow width
+@popover-arrow-outer-width: (@popover-arrow-width + 1);
+//** Popover outer arrow color
+@popover-arrow-outer-color: fadein(@popover-border-color, 5%);
+//** Popover outer arrow fallback color
+@popover-arrow-outer-fallback-color: darken(@popover-fallback-border-color, 20%);
+
+
+//== Labels
+//
+//##
+
+//** Default label background color
+@label-default-bg: @gray-light;
+//** Primary label background color
+@label-primary-bg: @brand-primary;
+//** Success label background color
+@label-success-bg: @brand-success;
+//** Info label background color
+@label-info-bg: @brand-info;
+//** Warning label background color
+@label-warning-bg: @brand-warning;
+//** Danger label background color
+@label-danger-bg: @brand-danger;
+
+//** Default label text color
+@label-color: #fff;
+//** Default text color of a linked label
+@label-link-hover-color: #fff;
+
+
+//== Modals
+//
+//##
+
+//** Padding applied to the modal body
+@modal-inner-padding: 15px;
+
+//** Padding applied to the modal title
+@modal-title-padding: 15px;
+//** Modal title line-height
+@modal-title-line-height: @line-height-base;
+
+//** Background color of modal content area
+@modal-content-bg: #fff;
+//** Modal content border color
+@modal-content-border-color: rgba(0,0,0,.2);
+//** Modal content border color **for IE8**
+@modal-content-fallback-border-color: #999;
+
+//** Modal backdrop background color
+@modal-backdrop-bg: #000;
+//** Modal backdrop opacity
+@modal-backdrop-opacity: .5;
+//** Modal header border color
+@modal-header-border-color: #e5e5e5;
+//** Modal footer border color
+@modal-footer-border-color: @modal-header-border-color;
+
+@modal-lg: 900px;
+@modal-md: 600px;
+@modal-sm: 300px;
+
+
+//== Alerts
+//
+//## Define alert colors, border radius, and padding.
+
+@alert-padding: 15px;
+@alert-border-radius: @border-radius-base;
+@alert-link-font-weight: bold;
+
+@alert-success-bg: @state-success-bg;
+@alert-success-text: @state-success-text;
+@alert-success-border: @state-success-border;
+
+@alert-info-bg: @state-info-bg;
+@alert-info-text: @state-info-text;
+@alert-info-border: @state-info-border;
+
+@alert-warning-bg: @state-warning-bg;
+@alert-warning-text: @state-warning-text;
+@alert-warning-border: @state-warning-border;
+
+@alert-danger-bg: @state-danger-bg;
+@alert-danger-text: @state-danger-text;
+@alert-danger-border: @state-danger-border;
+
+
+//== Progress bars
+//
+//##
+
+//** Background color of the whole progress component
+@progress-bg: #f5f5f5;
+//** Progress bar text color
+@progress-bar-color: #fff;
+//** Variable for setting rounded corners on progress bar.
+@progress-border-radius: @border-radius-base;
+
+//** Default progress bar color
+@progress-bar-bg: @brand-primary;
+//** Success progress bar color
+@progress-bar-success-bg: @brand-success;
+//** Warning progress bar color
+@progress-bar-warning-bg: @brand-warning;
+//** Danger progress bar color
+@progress-bar-danger-bg: @brand-danger;
+//** Info progress bar color
+@progress-bar-info-bg: @brand-info;
+
+
+//== List group
+//
+//##
+
+//** Background color on `.list-group-item`
+@list-group-bg: #fff;
+//** `.list-group-item` border color
+@list-group-border: #ddd;
+//** List group border radius
+@list-group-border-radius: @border-radius-base;
+
+//** Background color of single list items on hover
+@list-group-hover-bg: #f5f5f5;
+//** Text color of active list items
+@list-group-active-color: @component-active-color;
+//** Background color of active list items
+@list-group-active-bg: @component-active-bg;
+//** Border color of active list elements
+@list-group-active-border: @list-group-active-bg;
+//** Text color for content within active list items
+@list-group-active-text-color: lighten(@list-group-active-bg, 40%);
+
+//** Text color of disabled list items
+@list-group-disabled-color: @gray-light;
+//** Background color of disabled list items
+@list-group-disabled-bg: @gray-lighter;
+//** Text color for content within disabled list items
+@list-group-disabled-text-color: @list-group-disabled-color;
+
+@list-group-link-color: #ffffff;
+@list-group-link-hover-color: @list-group-link-color;
+@list-group-link-heading-color: #cccccc;
+
+
+//== Panels
+//
+//##
+
+@panel-bg: #fff;
+@panel-body-padding: 15px;
+@panel-heading-padding: 10px 15px;
+@panel-footer-padding: @panel-heading-padding;
+@panel-border-radius: @border-radius-base;
+
+//** Border color for elements within panels
+@panel-inner-border: #ddd;
+@panel-footer-bg: #f5f5f5;
+
+@panel-default-text: @gray-dark;
+@panel-default-border: #ddd;
+@panel-default-heading-bg: #f5f5f5;
+
+@panel-primary-text: #fff;
+@panel-primary-border: @brand-primary;
+@panel-primary-heading-bg: @brand-primary;
+
+@panel-success-text: @state-success-text;
+@panel-success-border: @state-success-border;
+@panel-success-heading-bg: @state-success-bg;
+
+@panel-info-text: @state-info-text;
+@panel-info-border: @state-info-border;
+@panel-info-heading-bg: @state-info-bg;
+
+@panel-warning-text: @state-warning-text;
+@panel-warning-border: @state-warning-border;
+@panel-warning-heading-bg: @state-warning-bg;
+
+@panel-danger-text: @state-danger-text;
+@panel-danger-border: @state-danger-border;
+@panel-danger-heading-bg: @state-danger-bg;
+
+
+//== Thumbnails
+//
+//##
+
+//** Padding around the thumbnail image
+@thumbnail-padding: 4px;
+//** Thumbnail background color
+@thumbnail-bg: @body-bg;
+//** Thumbnail border color
+@thumbnail-border: #ddd;
+//** Thumbnail border radius
+@thumbnail-border-radius: @border-radius-base;
+
+//** Custom text color for thumbnail captions
+@thumbnail-caption-color: @text-color;
+//** Padding around the thumbnail caption
+@thumbnail-caption-padding: 9px;
+
+
+//== Wells
+//
+//##
+
+@well-bg: #f5f5f5;
+@well-border: darken(@well-bg, 7%);
+
+
+//== Badges
+//
+//##
+
+@badge-color: #fff;
+//** Linked badge text color on hover
+@badge-link-hover-color: #fff;
+@badge-bg: @gray-light;
+
+//** Badge text color in active nav link
+@badge-active-color: @link-color;
+//** Badge background color in active nav link
+@badge-active-bg: #fff;
+
+@badge-font-weight: bold;
+@badge-line-height: 1;
+@badge-border-radius: 10px;
+
+
+//== Breadcrumbs
+//
+//##
+
+@breadcrumb-padding-vertical: 8px;
+@breadcrumb-padding-horizontal: 15px;
+//** Breadcrumb background color
+@breadcrumb-bg: #f5f5f5;
+//** Breadcrumb text color
+@breadcrumb-color: #ccc;
+//** Text color of current page in the breadcrumb
+@breadcrumb-active-color: @gray-light;
+//** Textual separator for between breadcrumb elements
+@breadcrumb-separator: "/";
+
+
+//== Carousel
+//
+//##
+
+@carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6);
+
+@carousel-control-color: #fff;
+@carousel-control-width: 15%;
+@carousel-control-opacity: .5;
+@carousel-control-font-size: 20px;
+
+@carousel-indicator-active-bg: #fff;
+@carousel-indicator-border-color: #fff;
+
+@carousel-caption-color: #fff;
+
+
+//== Close
+//
+//##
+
+@close-font-weight: bold;
+@close-color: #000;
+@close-text-shadow: 0 1px 0 #fff;
+
+
+//== Code
+//
+//##
+
+@code-color: #c7254e;
+@code-bg: #f9f2f4;
+
+@kbd-color: #fff;
+@kbd-bg: #cccccc;
+
+@pre-bg: #f5f5f5;
+@pre-color: @gray-dark;
+@pre-border-color: #ccc;
+@pre-scrollable-max-height: 340px;
+
+
+//== Type
+//
+//##
+
+//** Horizontal offset for forms and lists.
+@component-offset-horizontal: 180px;
+//** Text muted color
+@text-muted: @gray-light;
+//** Abbreviations and acronyms border color
+@abbr-border-color: @gray-light;
+//** Headings small color
+@headings-small-color: @gray-light;
+//** Blockquote small color
+@blockquote-small-color: @gray-light;
+//** Blockquote font size
+@blockquote-font-size: (@font-size-base * 1.25);
+//** Blockquote border color
+@blockquote-border-color: @gray-lighter;
+//** Page header border color
+@page-header-border-color: @gray-lighter;
+//** Width of horizontal description list titles
+@dl-horizontal-offset: @component-offset-horizontal;
+//** Point at which .dl-horizontal becomes horizontal
+@dl-horizontal-breakpoint: @grid-float-breakpoint;
+//** Horizontal line color.
+@hr-border: @gray-lighter;
diff --git a/copri4/shareeweb-project/js/iframeResizer.contentWindow.min.js b/copri4/shareeweb-project/js/iframeResizer.contentWindow.min.js
new file mode 100644
index 0000000..a25e581
--- /dev/null
+++ b/copri4/shareeweb-project/js/iframeResizer.contentWindow.min.js
@@ -0,0 +1,10 @@
+/*! iFrame Resizer (iframeSizer.contentWindow.min.js) - v4.3.2 - 2021-04-26
+ * Desc: Include this file in any page being loaded into an iframe
+ * to force the iframe to resize to the content size.
+ * Requires: iframeResizer.min.js on host page.
+ * Copyright: (c) 2021 David J. Bradshaw - dave@bradshaw.net
+ * License: MIT
+ */
+
+!function(c){if("undefined"!=typeof window){var i=!0,o=10,r="",a=0,u="",s=null,d="",l=!1,f={resize:1,click:1},m=128,h=!0,g=1,n="bodyOffset",p=n,v=!0,y="",w={},b=32,T=null,E=!1,O=!1,S="[iFrameSizer]",M=S.length,I="",N={max:1,min:1,bodyScroll:1,documentElementScroll:1},A="child",C=!0,z=window.parent,k="*",R=0,x=!1,e=null,L=16,F=1,t="scroll",P=t,D=window,j=function(){re("onMessage function not defined")},q=function(){},H=function(){},W={height:function(){return re("Custom height calculation function not defined"),document.documentElement.offsetHeight},width:function(){return re("Custom width calculation function not defined"),document.body.scrollWidth}},B={},J=!1;try{var U=Object.create({},{passive:{get:function(){J=!0}}});window.addEventListener("test",ee,U),window.removeEventListener("test",ee,U)}catch(e){}var V,X,Y,K,Q,G,Z={bodyOffset:function(){return document.body.offsetHeight+pe("marginTop")+pe("marginBottom")},offset:function(){return Z.bodyOffset()},bodyScroll:function(){return document.body.scrollHeight},custom:function(){return W.height()},documentElementOffset:function(){return document.documentElement.offsetHeight},documentElementScroll:function(){return document.documentElement.scrollHeight},max:function(){return Math.max.apply(null,ye(Z))},min:function(){return Math.min.apply(null,ye(Z))},grow:function(){return Z.max()},lowestElement:function(){return Math.max(Z.bodyOffset()||Z.documentElementOffset(),ve("bottom",be()))},taggedElement:function(){return we("bottom","data-iframe-height")}},$={bodyScroll:function(){return document.body.scrollWidth},bodyOffset:function(){return document.body.offsetWidth},custom:function(){return W.width()},documentElementScroll:function(){return document.documentElement.scrollWidth},documentElementOffset:function(){return document.documentElement.offsetWidth},scroll:function(){return Math.max($.bodyScroll(),$.documentElementScroll())},max:function(){return Math.max.apply(null,ye($))},min:function(){return Math.min.apply(null,ye($))},rightMostElement:function(){return ve("right",be())},taggedElement:function(){return we("right","data-iframe-width")}},_=(V=Te,Q=null,G=0,function(){var e=Date.now(),t=L-(e-(G=G||e));return X=this,Y=arguments,t<=0||LF[s]["max"+e])throw new Error("Value for min"+e+" can not be greater than max"+e)}s in F&&"iFrameResizer"in i?N(s,"Ignored iFrame, already setup."):(o(e),function(){switch(T(s,"IFrame scrolling "+(F[s]&&F[s].scrolling?"enabled":"disabled")+" for "+s),i.style.overflow=!1===(F[s]&&F[s].scrolling)?"hidden":"auto",F[s]&&F[s].scrolling){case"omit":break;case!0:i.scrolling="yes";break;case!1:i.scrolling="no";break;default:i.scrolling=F[s]?F[s].scrolling:"no"}}(),c("Height"),c("Width"),d("maxHeight"),d("minHeight"),d("maxWidth"),d("minWidth"),"number"!=typeof(F[s]&&F[s].bodyMargin)&&"0"!==(F[s]&&F[s].bodyMargin)||(F[s].bodyMarginV1=F[s].bodyMargin,F[s].bodyMargin=F[s].bodyMargin+"px"),n(q(s)),F[s]&&(F[s].iframe.iFrameResizer={close:C.bind(null,F[s].iframe),removeListeners:p.bind(null,F[s].iframe),resize:B.bind(null,"Window resize","resize",F[s].iframe),moveToAnchor:function(e){B("Move to anchor","moveToAnchor:"+e,F[s].iframe,s)},sendMessage:function(e){B("Send Message","message:"+(e=JSON.stringify(e)),F[s].iframe,s)}}))}function c(e,n){null===t&&(t=setTimeout(function(){t=null,e()},n))}function n(){"hidden"!==document.visibilityState&&(T("document","Trigger event: Visiblity change"),c(function(){w("Tab Visable","resize")},16))}function w(t,i){Object.keys(F).forEach(function(e){var n;F[n=e]&&"parent"===F[n].resizeFrom&&F[n].autoResize&&!F[n].firstRun&&B(t,i,F[e].iframe,e)})}function b(){O(window,"message",e),O(window,"resize",function(){var e;T("window","Trigger event: "+(e="resize")),c(function(){w("Window "+e,"resize")},16)}),O(document,"visibilitychange",n),O(document,"-webkit-visibilitychange",n)}function y(){function i(e,n){n&&(function(){if(!n.tagName)throw new TypeError("Object is not a valid DOM element");if("IFRAME"!==n.tagName.toUpperCase())throw new TypeError("Expected