Index: trunk/gsdl/perllib/mgppbuilder.pm
===================================================================
--- trunk/gsdl/perllib/mgppbuilder.pm	(revision 10158)
+++ trunk/gsdl/perllib/mgppbuilder.pm	(revision 10468)
@@ -26,4 +26,5 @@
 package mgppbuilder;
 
+use basebuilder;
 use classify;
 use cfgread;
@@ -33,18 +34,9 @@
 use FileHandle;
 
-
-BEGIN {
-    # set autoflush on for STDERR and STDOUT so that mgpp
-    # doesn't get out of sync with plugins
-    STDOUT->autoflush(1);
-    STDERR->autoflush(1);
-}
-
-END {
-    STDOUT->autoflush(0);
-    STDERR->autoflush(0);
-}
-
-our $maxdocsize = 12000;
+sub BEGIN {
+    @mgppbuilder::ISA = ('basebuilder');
+}
+
+
 
 our %level_map = ('document'=>'Doc',
@@ -107,4 +99,6 @@
 			  'Para'=>1);
 
+my $maxdocsize = $basebuilder::maxdocsize;
+
 sub new {
     my $class = shift(@_);
@@ -114,78 +108,8 @@
 	$outhandle, $no_text, $failhandle, $gli) = @_;
 
-    $outhandle = STDERR unless defined $outhandle;
-    $no_text = 0 unless defined $no_text;
-    
-    # create an mgppbuilder object
-    my $self = bless {'collection'=>$collection,
-		      'source_dir'=>$source_dir,
-		      'build_dir'=>$build_dir,
-		      'verbosity'=>$verbosity,
-		      'maxdocs'=>$maxdocs,
-		      'debug'=>$debug,
-		      'keepold'=>$keepold,
-		      'remove_empty_classifications'=>$remove_empty_classifications,
-		      'outhandle'=>$outhandle,
-		      'no_text'=>$no_text,
-		      'notbuilt'=>{},    # indexes not built
-		      'indexfieldmap'=>\%static_indexfield_map,
-		      'gli'=>$gli
-		  }, $class;
-
-    $self->{'gli'} = 0 unless defined $self->{'gli'};
-
-    # read in the collection configuration file
-    my $colcfgname = "$ENV{'GSDLCOLLECTDIR'}/etc/collect.cfg";
-    if (!-e $colcfgname) {
-	die "mgppbuilder::new - couldn't find collect.cfg for collection $collection\n";
-    }
-    $self->{'collect_cfg'} = &colcfg::read_collect_cfg ($colcfgname);
-
-    # sort out the indexes
-    #indexes are specified with spaces, but we put them into one index
-    my $indexes = $self->{'collect_cfg'}->{'indexes'};
-    $self->{'collect_cfg'}->{'indexes'} = [];
-    push (@{$self->{'collect_cfg'}->{'indexes'}}, join(',', @$indexes));
-	 
-    
-    # sort out subcollection indexes
-    if (defined $self->{'collect_cfg'}->{'indexsubcollections'}) {
-	my $indexes = $self->{'collect_cfg'}->{'indexes'};
-	$self->{'collect_cfg'}->{'indexes'} = [];
-	foreach my $subcollection (@{$self->{'collect_cfg'}->{'indexsubcollections'}}) {
-	    foreach my $index (@$indexes) {
-		push (@{$self->{'collect_cfg'}->{'indexes'}}, "$index:$subcollection");
-	    }
-	}
-    }
-
-    # sort out language subindexes
-    if (defined $self->{'collect_cfg'}->{'languages'}) {
-	my $indexes = $self->{'collect_cfg'}->{'indexes'};
-	$self->{'collect_cfg'}->{'indexes'} = [];
-	foreach my $language (@{$self->{'collect_cfg'}->{'languages'}}) {
-	    foreach my $index (@$indexes) {
-		if (defined ($self->{'collect_cfg'}->{'indexsubcollections'})) {
-		    push (@{$self->{'collect_cfg'}->{'indexes'}}, "$index:$language");
-		}
-		else { # add in an empty subcollection field
-		    push (@{$self->{'collect_cfg'}->{'indexes'}}, "$index\:\:$language");
-		   
-		}		
-	    }
-	}
-    }
-
-    # make sure that the same index isn't specified more than once
-    my %tmphash = ();
-    my @tmparray = @{$self->{'collect_cfg'}->{'indexes'}};
-    $self->{'collect_cfg'}->{'indexes'} = [];
-    foreach my $i (@tmparray) {
-	if (!defined ($tmphash{$i})) {
-	    push (@{$self->{'collect_cfg'}->{'indexes'}}, $i);
-	    $tmphash{$i} = 1;
-	}
-    }
-
+    my $self = new basebuilder (@_);
+    $self = bless $self, $class;
+
+    $self->{'indexfieldmap'} = \%static_indexfield_map;
 
     # get the levels (Section, Paragraph) for indexing and compression
@@ -212,59 +136,4 @@
     }
 
-    print $outhandle "doclevel = ". $self->{'doc_level'}."\n";
-    # get the list of plugins for this collection
-
-    #build up the extra global options for the plugins
-    my @global_opts = ();
-    if (defined $self->{'collect_cfg'}->{'separate_cjk'} && $self->{'collect_cfg'}->{'separate_cjk'} =~ /^true$/i) {
-	push @global_opts, "-separate_cjk";
-    }
-
-    my $plugins = [];
-    if (defined $self->{'collect_cfg'}->{'plugin'}) {
-	$plugins = $self->{'collect_cfg'}->{'plugin'};
-    }
-    
-    # load all the plugins
-    $self->{'pluginfo'} = &plugin::load_plugins ($plugins, $verbosity, $outhandle, \@global_opts);
-    if (scalar(@{$self->{'pluginfo'}}) == 0) {
-	print $outhandle "No plugins were loaded.\n";
-	die "\n";
-    }
-
-    # get the list of classifiers for this collection
-    my $classifiers = [];
-    if (defined $self->{'collect_cfg'}->{'classify'}) {
-	$classifiers = $self->{'collect_cfg'}->{'classify'};
-    }
-    
-    # load all the classifiers
-    $self->{'classifiers'} = &classify::load_classifiers ($classifiers, $build_dir, $outhandle);
-
-    # load up any dontgdbm fields
-    $self->{'dontgdbm'} = {};
-    if (defined ($self->{'collect_cfg'}->{'dontgdbm'})) {
-	foreach my $dg (@{$self->{'collect_cfg'}->{'dontgdbm'}}) {
-	    $self->{'dontgdbm'}->{$dg} = 1;
-	}
-    }
-
-    # load up the document processor for building
-    # if a buildproc class has been created for this collection, use it
-    # otherwise, use the mgpp buildproc
-    my ($buildprocdir, $buildproctype);
-    if (-e "$ENV{'GSDLCOLLECTDIR'}/perllib/${collection}buildproc.pm") {
-	$buildprocdir = "$ENV{'GSDLCOLLECTDIR'}/perllib";
-	$buildproctype = "${collection}buildproc";
-    } else {
-	$buildprocdir = "$ENV{'GSDLHOME'}/perllib";
-	$buildproctype = "mgppbuildproc";
-    }
-    require "$buildprocdir/$buildproctype.pm";
-
-    eval("\$self->{'buildproc'} = new $buildproctype(\$collection, " .
-	 "\$source_dir, \$build_dir, \$keepold, \$verbosity, \$outhandle)");
-    die "$@" if $@;
-
     $self->{'buildtype'} = "mgpp";
 
@@ -272,24 +141,18 @@
 }
 
-sub init {
-    my $self = shift (@_);
-
-    if (!$self->{'debug'} && !$self->{'keepold'}) {
-	# remove any old builds
-	&util::rm_r($self->{'build_dir'});
-	&util::mk_all_dir($self->{'build_dir'});
-        
-	# make the text directory
-	my $textdir = "$self->{'build_dir'}/text";
-	&util::mk_all_dir($textdir);
-    }
-}
-
-sub set_strip_html {
-    my $self = shift (@_);
-    my ($strip) = @_;
-    
-    $self->{'strip_html'} = $strip;
-    $self->{'buildproc'}->set_strip_html($strip);
+sub generate_index_list {
+    my $self  = shift (@_);
+    
+    # sort out the indexes
+    #indexes are specified with spaces, but we put them into one index
+    my $indexes = $self->{'collect_cfg'}->{'indexes'};
+    $self->{'collect_cfg'}->{'indexes'} = [];
+    push (@{$self->{'collect_cfg'}->{'indexes'}}, join(',', @$indexes));
+}
+
+sub default_buildproc {
+    my $self  = shift (@_);
+
+    return "mgppbuildproc";
 }
 
@@ -423,53 +286,10 @@
 }
 
-sub want_built {
-    my $self = shift (@_);
-    my ($index) = @_;
-
-    if (defined ($self->{'collect_cfg'}->{'dontbuild'})) {
-	foreach my $checkstr (@{$self->{'collect_cfg'}->{'dontbuild'}}) {
-	    if ($index =~ /^$checkstr$/) {
-		#push (@{$self->{'notbuilt'}}, $self->{'index_mapping'}->{$index});
-		$self->{'notbuilt'}->{$index} = 1;
-		return 0;
-	    }
-	}
-    }
-
-    return 1;
-}
-
-sub build_indexes {
-    my $self = shift (@_);
-    my ($indexname) = @_;
-    my $outhandle = $self->{'outhandle'};
-
-    my $indexes = [];
-    if (defined $indexname && $indexname =~ /\w/) {
-	push @$indexes, $indexname;
-    } else {
-	$indexes = $self->{'collect_cfg'}->{'indexes'};
-    }
-
-    # create the mapping between the index descriptions 
-    # and their directory names (includes subcolls and langs)
-    $self->{'index_mapping'} = $self->create_index_mapping ($indexes);
-
-    # build each of the indexes
-    foreach my $index (@$indexes) {
-	if ($self->want_built($index)) {
-	    print $outhandle "\n*** building index $index in subdirectory " . 
-		"$self->{'index_mapping'}->{$index}\n" if ($self->{'verbosity'} >= 1);
-	    print STDERR "<Stage name='Index' source='$index'>\n" if $self->{'gli'};
-	    $self->build_index($index);
-	} else {
-	    print $outhandle "\n*** ignoring index $index\n" if ($self->{'verbosity'} >= 1);
-	}
-    }
-
+
+sub build_indexes_extra {
+    my $self = shift(@_);
     #define the final field lists
     $self->make_final_field_list();
-
-}
+}    
 
 # creates directory names for each of the index descriptions
@@ -545,27 +365,4 @@
 }
 
-# returns a processed version of a field.
-# if the field has only one component the processed
-# version will contain the first character and next consonant
-# of that componant - otherwise it will contain the first 
-# character of the first two components 
-sub process_field {
-    my $self = shift (@_);
-    my ($field) = @_;
- 
-    return "" unless (defined ($field) && $field =~ /\w/);
-
-    my @components = split /,/, $field;
-    if (scalar @components >= 2) {
-	splice (@components, 2);
-	map {s/^(.).*$/$1/;} @components;
-	return join("", @components);
-    } else {
-	my ($a, $b) = $field =~ /^(.).*?([bcdfghjklmnpqrstvwxyz])/i;
-	($a, $b) = $field =~ /^(.)(.)/ unless defined $a && defined $b;
-	return "$a$b";
-    }
-}
-
 sub make_unique {
     my $self = shift (@_);
@@ -583,19 +380,4 @@
 }	
 
-sub get_next_version {
-    my $self = shift (@_);
-    my ($nameref) = @_;
-    my $num=0;
-    if ($$nameref =~ /(\d\d)$/) {
-	$num = $1; $num ++;
-	$$nameref =~ s/\d\d$/$num/;
-    } elsif ($$nameref =~ /(\d)$/) {
-	$num = $1;
-	if ($num == 9) {$$nameref =~ s/\d$/10/;}
-	else {$num ++; $$nameref =~ s/\d$/$num/;}
-    } else {
-	$$nameref =~ s/.$/0/;
-    }
-}
 
 sub build_index {
@@ -812,59 +594,8 @@
 }   
 
-sub make_infodatabase {
-    my $self = shift (@_);
-    my $outhandle = $self->{'outhandle'};
-
-
-    my $textdir = &util::filename_cat($self->{'build_dir'}, "text");
-    my $assocdir = &util::filename_cat($self->{'build_dir'}, "assoc");
-    &util::mk_all_dir ($textdir);
-    &util::mk_all_dir ($assocdir);
-
-    # get db name
-    my $dbext = ".bdb";
-    $dbext = ".ldb" if &util::is_little_endian();
-    my $fulldbname = &util::filename_cat ($textdir, "$self->{'collection'}$dbext");
-    $fulldbname =~ s/\//\\/g if ($ENV{'GSDLOS'} =~ /^windows$/i);
-
-    my $exedir = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}";
-    my $exe = &util::get_os_exe ();
-    my $txt2db_exe = &util::filename_cat($exedir, "txt2db$exe");
-
-    # define the indexed field mapping if not already done so (ie if infodb called separately from build_index)
-    if (!defined $self->{'build_cfg'}) {
-	$self->read_final_field_list();
-    }
-    print $outhandle "\n*** creating the info database and processing associated files\n" 
-	if ($self->{'verbosity'} >= 1);
-    print STDERR "<Stage name='CreateInfoData'>\n" if $self->{'gli'};
-
-    # init all the classifiers
-    &classify::init_classifiers ($self->{'classifiers'});
-
-    # set up the document processor
-    my ($handle);
-    if ($self->{'debug'}) {
-	$handle = STDOUT;
-    } else {
-	if (!-e "$txt2db_exe" || !open (PIPEOUT, "| txt2db$exe \"$fulldbname\"")) {
-	    print STDERR "<FatalError name='NoRunText2DB'/>\n</Stage>\n" if $self->{'gli'};
-	    die "mgppbuilder::make_infodatabase - couldn't run $txt2db_exe\n";
-	}
-	$handle = mgppbuilder::PIPEOUT;
-    }
-
-    $self->{'buildproc'}->set_output_handle ($handle);
-    $self->{'buildproc'}->set_mode ('infodb');
-    $self->{'buildproc'}->set_assocdir ($assocdir);
-    $self->{'buildproc'}->set_dontgdbm ($self->{'dontgdbm'});
-    $self->{'buildproc'}->set_classifiers ($self->{'classifiers'});
-    $self->{'buildproc'}->set_indexing_text (0);
-    $self->{'buildproc'}->set_store_text(1);
-    #$self->{'buildproc'}->set_indexfieldmap ($self->{'indexfieldmap'});
-
-    # make_infodatabase does not support incremental build 
-    # => full reset needed
-    $self->{'buildproc'}->zero_reset(); 
+
+sub output_collection_meta {
+    my $self = shift(@_);
+    my ($handle) = @_;
 
     # do the collection info
@@ -873,9 +604,10 @@
     # first do the collection meta stuff - everything without a dot
     my $collmetadefined = 0;
+    my $metadata_entry;
     if (defined $self->{'collect_cfg'}->{'collectionmeta'}) {
 	$collmetadefined = 1;
 	foreach my $cmeta (keys (%{$self->{'collect_cfg'}->{'collectionmeta'}})) {
 	    next if ($cmeta =~ /^\./); # for now, ignore ones with dots
-	    my ($metadata_entry) = $self->create_language_db_map($cmeta, $cmeta);
+	    $metadata_entry = $self->create_language_db_map($cmeta, $cmeta);
 	    #write the entry to the file
 	    print $handle $metadata_entry;
@@ -896,5 +628,5 @@
 	$collmeta = ".$longfield";
 	if ($collmetadefined && defined $self->{'collect_cfg'}->{'collectionmeta'}->{$collmeta}) {
-	    my $metadata_entry = $self->create_language_db_map($collmeta, $shortfield);
+	    $metadata_entry = $self->create_language_db_map($collmeta, $shortfield);
 	    $field_entry .= $metadata_entry;
 	} else { #use the metadata names, or the text macros for allfields and textonly
@@ -917,5 +649,5 @@
 	my $levelid = $level_map{$level}; # find the actual value we used in the index
 	if ($collmetadefined && defined $self->{'collect_cfg'}->{'collectionmeta'}->{$collmeta}) {
-	    my $metadata_entry = $self->create_language_db_map($collmeta, $levelid);
+	    $metadata_entry = $self->create_language_db_map($collmeta, $levelid);
 	    $level_entry .= $metadata_entry;
 	} else {
@@ -955,28 +687,7 @@
     # end the collection entry
     print $handle "\n" . ('-' x 70) . "\n";        
-    
-    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
-		   "", {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
-
-    # output classification information
-    &classify::output_classify_info ($self->{'classifiers'}, $handle,
-				     $self->{'remove_empty_classifications'}, 
-				     $self->{'gli'});
-
-    #output doclist
-    my @doclist = $self->{'buildproc'}->get_doc_list();
-    my $docs = join (";",@doclist);
-    print $handle "[browselist]\n";
-    print $handle "<hastxt>0\n";
-    print $handle "<childtype>VList\n";
-    print $handle "<numleafdocs>" . ($#doclist+1) . "\n";
-    print $handle "<thistype>Invisible\n";
-    print $handle "<contains>$docs";
-    print $handle "\n" . ('-' x 70) . "\n";
-    close ($handle) if !$self->{'debug'};
-
-    print STDERR "</Stage>\n" if $self->{'gli'};
-}
-
+
+
+}
 sub create_language_db_map {
     my $self = shift (@_);
@@ -1020,7 +731,4 @@
     
 }
-sub collect_specific {
-    my $self = shift (@_);
-}
 
 # at the end of building, we have an indexfieldmap with all the mappings,
@@ -1047,5 +755,6 @@
     # those again.
 
-    foreach my $field (@{$self->{'collect_cfg'}->{'indexes'}}) {
+    my $field;
+    foreach $field (@{$self->{'collect_cfg'}->{'indexes'}}) {
 	# remove subcoll stuff
 	my $parts = $field;
@@ -1061,5 +770,5 @@
     
     #add all fields bit 
-    foreach my $field (@specifiedfieldorder) {
+    foreach $field (@specifiedfieldorder) {
 	if ($field eq "metadata") {
 	    foreach my $newfield (keys %{$self->{'buildproc'}->{'indexfields'}}) {
@@ -1114,7 +823,7 @@
 
     my $buildcfg = &colcfg::read_build_cfg( $buildconfigfile);
-
+    my $field;
     if (defined $buildcfg->{'indexfields'}) {
-	foreach my $field (@{$buildcfg->{'indexfields'}}) {
+	foreach $field (@{$buildcfg->{'indexfields'}}) {
 	    push (@indexfields, "$field");
 	}
@@ -1122,5 +831,5 @@
 
     if (defined $buildcfg->{'indexfieldmap'}) {
-	foreach my $field (@{$buildcfg->{'indexfieldmap'}}) {
+	foreach $field (@{$buildcfg->{'indexfieldmap'}}) {
 	    push (@indexfieldmap, "$field");
 	    my ($f, $v) = $field =~ /^(.*)\-\>(.*)$/;
@@ -1133,25 +842,22 @@
 }
 
-sub make_auxiliary_files {
+
+sub write_cfg_file {
+    my $self = shift(@_);
+    my ($build_cfg) = @_;
+
+    # write out the build information
+    &cfgread::write_cfg_file("$self->{'build_dir'}/build.cfg", $build_cfg,
+			     '^(builddate|buildtype|numdocs|numsections|numbytes|textlevel|indexstem|maxnumeric)$', 
+                             '^(indexmap|subcollectionmap|languagemap|indexfieldmap|notbuilt|indexfields|indexlevels|levelmap)$');
+
+}
+
+sub build_cfg_extra {
     my $self = shift (@_);
-    my ($index);
-    
-    my $build_cfg = {};
-    # this already includes indexfieldmap and indexfields
-    if (defined $self->{'build_cfg'}) {
-	$build_cfg = $self->{'build_cfg'};
-    }
-    
-    my $outhandle =  $self->{'outhandle'};
-    print $outhandle "\n*** creating auxiliary files \n" if ($self->{'verbosity'} >= 1);
-    print STDERR "<Stage name='CreatingAuxilary'>\n" if $self->{'gli'};
-
-    # get the text directory
-    &util::mk_all_dir ($self->{'build_dir'});
-
-    # store the build date
-    $build_cfg->{'builddate'} = time;
-    $build_cfg->{'buildtype'} = $self->{'buildtype'};
-    $build_cfg->{'indexstem'} = $self->{'collection'};
+    my ($build_cfg) = @_;
+
+    $build_cfg->{'numsections'} = $self->{'buildproc'}->get_num_sections();
+    
     # store the level info
     my @indexlevels = ();
@@ -1169,93 +875,5 @@
 	$build_cfg->{'textlevel'} = $level_map{'document'};
     }
-    # store the number of documents and number of bytes
-    $build_cfg->{'numdocs'} = $self->{'buildproc'}->get_num_docs();
-    $build_cfg->{'numsections'} = $self->{'buildproc'}->get_num_sections();
-    $build_cfg->{'numbytes'} = $self->{'buildproc'}->get_num_bytes();
-
-    # store the mapping between the index names and the directory names
-    my @indexmap = ();
-    foreach my $index (@{$self->{'index_mapping'}->{'indexmaporder'}}) {
-	if (not defined ($self->{'notbuilt'}->{$index})) {
-	    push (@indexmap, "$index\-\>$self->{'index_mapping'}->{'indexmap'}->{$index}");
-	}
-    }
-    $build_cfg->{'indexmap'} = \@indexmap;
-
-    my @subcollectionmap = ();
-    foreach my $subcollection (@{$self->{'index_mapping'}->{'subcollectionmaporder'}}) {
-	push (@subcollectionmap, "$subcollection\-\>" .
-	      $self->{'index_mapping'}->{'subcollectionmap'}->{$subcollection});
-    }
-    $build_cfg->{'subcollectionmap'} = \@subcollectionmap if scalar (@subcollectionmap);
-
-    my @languagemap = ();
-    foreach my $language (@{$self->{'index_mapping'}->{'languagemaporder'}}) {
-	push (@languagemap, "$language\-\>" .
-	      $self->{'index_mapping'}->{'languagemap'}->{$language});
-    }
-    $build_cfg->{'languagemap'} = \@languagemap if scalar (@languagemap);
-
-    my @notbuilt = ();
-    foreach my $nb (keys %{$self->{'notbuilt'}}) {
-	push (@notbuilt, $nb);
-    }
-    $build_cfg->{'notbuilt'} = \@notbuilt if scalar (@notbuilt);
-
-    # write out the build information
-    &cfgread::write_cfg_file("$self->{'build_dir'}/build.cfg", $build_cfg,
-			     '^(builddate|buildtype|numdocs|numsections|numbytes|textlevel|indexstem)$', 
-                             '^(indexmap|subcollectionmap|languagemap|indexfieldmap|notbuilt|indexfields|indexlevels|levelmap)$');
-
-    print STDERR "</Stage>\n" if $self->{'gli'};
-}
-
-sub deinit {
-    my $self = shift (@_);
-    
-    &plugin::deinit($self->{'pluginfo'},$self->{'buildproc'});
-}
-
-sub print_stats {
-    my $self = shift (@_);
-
-    my $outhandle = $self->{'outhandle'};
-    my $indexing_text = $self->{'buildproc'}->get_indexing_text();
-    my $index = $self->{'buildproc'}->get_index();
-    my $num_bytes = $self->{'buildproc'}->get_num_bytes();
-    my $num_processed_bytes = $self->{'buildproc'}->get_num_processed_bytes();
-
-    if ($indexing_text) {
-	print $outhandle "Stats (Creating index $index)\n";
-    } else {
-	print $outhandle "Stats (Compressing text from $index)\n";
-    }
-    print $outhandle "Total bytes in collection: $num_bytes\n";
-    print $outhandle "Total bytes in $index: $num_processed_bytes\n";
-
-    if ($num_processed_bytes < 50 && ($indexing_text || !$self->{'no_text'})) {
-	
-	if ($self->{'keepold'}) {
-	    if ($num_processed_bytes == 0) {
-		if ($indexing_text) {
-		    print $outhandle "No additional text was added to $index\n";
-		} elsif (!$self->{'no_text'}) {
-		    print $outhandle "No additional text was compressed\n";
-		}	
-	    }	
-	}
-	else {
-	    print $outhandle "***************\n";
-	    if ($indexing_text) {
-		print $outhandle "WARNING: There is very little or no text to process for $index\n";
-	    } elsif (!$self->{'no_text'}) {
-		print $outhandle "WARNING: There is very little or no text to compress\n";
-	    }	   
-	    print $outhandle "         Was this your intention?\n";
-	    print $outhandle "***************\n";
-	}
-
-    }
-
+   
 }
 
