Diff for /loncom/homework/structuretags.pm between versions 1.512.2.10 and 1.531

version 1.512.2.10, 2015/04/21 22:48:46 version 1.531, 2015/03/07 23:13:09
Line 270  sub homework_js { Line 270  sub homework_js {
         $jstimeout = 1000 * $timeout;          $jstimeout = 1000 * $timeout;
     }      }
     return &Apache::loncommon::resize_textarea_js().      return &Apache::loncommon::resize_textarea_js().
                   &Apache::loncommon::colorfuleditor_js().
            &setmode_javascript().             &setmode_javascript().
  <<"JS";   <<"JS";
 <script type="text/javascript">  <script type="text/javascript">
Line 286  function setSubmittedPart (part,prefix) Line 287  function setSubmittedPart (part,prefix)
     }      }
 }  }
   
 function disableAutoComplete (id) {  
     var field = document.getElementById(id);  
     if (field != null && field != undefined){  
         if ('autocomplete' in field) {  
             field.autocomplete = "off";  
         } else {  
             field.setAttribute("autocomplete", "off");  
         }  
     }  
 }  
   
 function image_response_click (which, e) {  function image_response_click (which, e) {
     init_geometry();      init_geometry();
     if (!e) { e = window.event; } //IE      if (!e) { e = window.event; } //IE
Line 316  var keypresshandled = 0; Line 306  var keypresshandled = 0;
 var postsubmit = '$postsubmit';  var postsubmit = '$postsubmit';
   
 \$(document).ready(function(){  \$(document).ready(function(){
   if (postsubmit != 'off') {    if (postsubmit != 'off') {    
     \$(document).keypress(function(event){      \$(document).keypress(function(event){
         var keycode = (event.keyCode ? event.keyCode : event.which);          var keycode = (event.keyCode ? event.keyCode : event.which);
         if ((keycode == '13') && (keypresshandled == 0)) {          if ((keycode == '13') && (keypresshandled == 0)) {
Line 776  sub problem_edit_buttons { Line 766  sub problem_edit_buttons {
    return $result;     return $result;
 }  }
   
   sub insert_menu_datastructure {
   
    my $template_menu = &template_dropdown_datastructure();
    my $responseblock_menu = &responseblock_dropdown_datastructure();
    my $conditional_scripting = &conditional_scripting_datastructure();
    my $misc = &misc_datastructure();
   
    my @menu = ($template_menu, $responseblock_menu, $conditional_scripting, $misc);
    return \@menu;
   
   }
   
   sub template_dropdown_datastructure {
       # gathering the all templates and their path, title, category and help topic
       my @templates = &Apache::lonhomework::get_template_list('problem');
       # template category => title
       my %tmplthash = ();
       # template title => path
       my %tmpltcontent = ();
   
       foreach my $template (@templates){
           # put in hash if the template is not empty
           unless ($template->[1] eq ''){
               push(@{$tmplthash{$template->[2]}}, $template->[1]);
               push(@{$tmpltcontent{$template->[1]}},$template->[0]);
           }
       }
   
    my $catList = [];
       foreach my $cat (sort keys %tmplthash) {
    my $catItems = [];
           foreach my $title (sort @{$tmplthash{$cat}}) {
               my $path = $tmpltcontent{$title}->[0];
               my $code;
               open(FH, "<$path");
               while(<FH>){
                   $code.= $_ unless $_ =~ /(<problem>)|(<\/problem>)/;
               }
               close(FH);
   
    if ($code ne '') {
    my $href = 'javascript:insertText(\'' . &convert_for_js(&HTML::Entities::encode($code)) . '\')';
    my $currItem = [$href, $title, undef];
    push @{$catItems}, $currItem;
    }
           }
    push @{$catList}, [$catItems, $cat, undef];
       }
   
    my $templDropdown = [$catList, &mt("Complete Problem Templates"), undef];
       return $templDropdown;
   }
   
   sub responseblock_dropdown_datastructure {
   
    my $mathCat = [
    [
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_formularesponse())) . "\')", &mt("Formula Response"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_functionplotresponse())) . "\')", &mt("Function Plot Response"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_mathresponse())) . "\')", &mt("Math Response"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_numericalresponse())) . "\')", &mt("Numerical Response"), undef]
    ], 
    &mt("Math"), 
    undef
    ];
   
    my $miscCat = [
    [
               ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_imageresponse())) . "\')", &mt("Click on Image"), undef],
               ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_customresponse())) . "\')", &mt("Custom Response"), undef],
               ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_externalresponse())) . "\')", &mt("External Response"), undef],
               ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_matchresponse())) . "\')", &mt("Match Response"), undef],
               ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_radiobuttonresponse())) . "\')", &mt("One out of N Statement"), undef],
               ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_optionresponse())) . "\')", &mt("Optionresponse"), undef], 
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_rankresponse())) . "\')", &mt("Rank Values"), undef]
    ],
    &mt("Misc"),
    undef
    ];
   
    my $chemCat = [
    [
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_reactionresponse())) . "\')", &mt("Chemical Reaction"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicresponse())) . "\')", &mt("Organic Structure"), undef]
    ],
    &mt("Chemical"),
    undef
    ];
   
    my $textCat = [
    [
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_stringresponse())) . "\')", &mt("String Response"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_essayresponse())) . "\')", &mt("Essay"), undef]
    ],
    &mt("Text"),
    undef
    ];
   
    my $cats = [[$mathCat, $miscCat, $chemCat, $textCat], &mt("Response Types"), undef];
    return $cats;
   }
   
   
   sub conditional_scripting_datastructure {
   # TODO: corresponding routines should be used for the javascript:insertText parts
   # instead of the placeholder routine default_xml_tag with the tags
   # e.g. &default_xml_tag("postanswerdate") should be replaced with a routine which
   # returns the corresponding content for this case
   
   #TODO translated is currently temporarily here, another solution should be found where the
   # needed string can be retrieved
   
    my $translatedTag = '
   <translated>
       <lang which="en"></lang>
       <lang which="default"></lang>
   </translated>';
   
    my $cat = [
    [
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode($translatedTag)) . "\')", &mt("Translated Tag"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("block"))) . "\')", &mt("Conditional Block"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("postanswerdate"))) . "\')", &mt("After Answer Block"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("preduedate"))) . "\')", &mt("Before Due Date Block"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("solved"))) . "\')", &mt("Block For After Solved"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("notsolved"))) . "\')", &mt("Block For When Not Solved"), undef]
    ],
    &mt("Contitional Scripting"),
    undef
    ];
   
    return $cat;
   }
   
   sub misc_datastructure {
   
    my $graphicalCat = [
    [
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_img())) . "\')", &mt("Image"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::lonplot::insert_gnuplot())) . "\')", &mt("GNU Plot"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicstructure())) . "\')", &mt("Organic Structure"), undef]
    ],
    "Graphical",
    undef
    ];
   
    my $advancedCat = [
    [
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_script())) . "\')", &mt("Script Block"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("allow"))) . "\')", &mt("File Dependencies"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("import"))) . "\')", &mt("Import a File"), undef],
    ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::londefdef::insert_meta())) . "\')", &mt("Custom Metadata"), undef]
    ],
    "advanced",
    undef
    ];
   
    my $cats = [[$graphicalCat, $advancedCat], &mt("misc"), undef];
    return $cats;
   }
   
   # helper routine for the datastructure building subroutines
   sub default_xml_tag {
    my ($tag) = @_;
    return "\n<$tag></$tag>";
   }
   
   
   sub helpmenu_datastructure {
   
    my $width = 500;
    my $height = 600;
   
    my $helpers = [
    ['Problem_LON-CAPA_Functions', &mt('Script Functions')],
    ['Greek_Symbols', &mt('Greek Symbols')],
     ['Other_Symbols', &mt('Other Symbols')],
    ['Authoring_Output_Tags', &mt('Output Tags')],
    ['Authoring_Multilingual_Problems', 
    &mt('How to create problems in different languages')]
    ];
   
    my $help_structure = [];
   
    foreach my $count (0..(scalar(@{$helpers})-1)) {
    my $filename = $helpers->[$count]->[0];
    my $title = $helpers->[$count]->[1];
    my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename.hlp',$width,$height,'yes');");
    push @{$help_structure}, [$href, $title, undef];
    }
   
    return $help_structure;
   }
   
   # we need substitution to not break javascript code
   sub convert_for_js {
       my $return = shift;
           $return =~ s|script|ESCAPEDSCRIPT|g;
           $return =~ s|\\|\\\\|g;
           $return =~ s|\n|\\r\\n|g;
           $return =~ s|'|\\'|g;
    $return =~ s|&#39;|\\&#39;|g;
       return $return;
   }
   
 sub problem_edit_header {  sub problem_edit_header {
     return '<input type="hidden" name="submitted" value="edit" />'.      my ($mode)=@_;
       my $return = '<input type="hidden" name="submitted" value="edit" />'.
  &remember_problem_state('edit').'   &remember_problem_state('edit').'
 <div class="LC_edit_problem_header">          <div class="LC_edit_problem_header">
 <div class="LC_edit_problem_header_title">          <div class="LC_edit_problem_header_title">
 '.&mt('Problem Editing').&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'          '.&mt('Problem Editing').$mode.&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'
 </div>'.          </div><div class="LC_edit_actionbar" id="actionbar">'.
 '<input type="hidden" name="problemmode" value="saveedit" />'.          '<input type="hidden" name="problemmode" value="saveedit" />'.
 &problem_edit_buttons().'          &problem_edit_buttons();
 <hr style="clear:both;" />  
 '.&Apache::lonxml::message_location().'      $return.='<hr style="clear:both;visibility:hidden;" />
 </div>      </div></div>'
 '.      .&Apache::lonxml::message_location();
        '<table id="LC_edit_problem_colorful" border="0" width="100%"><tr><td bgcolor="#F8F8F8">';      $return .= '<link rel="stylesheet" href="/adm/codemirror/codemirror-combined.css" />
       <script type="text/javascript" src="/adm/codemirror/codemirror-compressed-colorful.js"></script>';
   
       $return .= '<script type="text/javascript" src="/adm/jQuery/addons/jquery-scrolltofixed.js"></script>
           <script type="text/javascript">
               // unless internet explorer
               if (!(window.navigator.appName == "Microsoft Internet Explorer" && (document.documentMode || document.compatMode))){
                   $(document).ready(
                       function() {
                           $(\'.LC_edit_actionbar\').scrollToFixed(
                               {
                                   fixed: function(){
                                       $(this).find(\'.LC_edit_actionbar\').css(\'height\', \'31px\');
                                   }
                               }
                           );
                       }
                   );
               }
           </script>
           <table id="LC_edit_problem_colorful" border="0" width="100%"><tr><td bgcolor="#F8F8F8">';
       return $return;
 }  }
   
 sub problem_edit_footer {  sub problem_edit_footer {
       my $resource = $env{'request.ambiguous'};
     return '</td></tr></table><br />      return '</td></tr></table><br />
 <div class="LC_edit_problem_footer">  <div class="LC_edit_problem_footer">
   <hr />'.    <hr />'.
 &problem_edit_buttons().'  &problem_edit_buttons().'
   <hr style="clear:both;" />    <hr style="clear:both;" />
     <script type="text/javascript">
         restoreState("'.$resource.'");
         restoreScrollPosition("'.$resource.'");
     </script>
 </div>  </div>
 '.  '.
     "\n</form>\n".&Apache::loncommon::end_page();      "\n</form>\n".&Apache::loncommon::end_page();
Line 862  sub problem_web_to_edit_header { Line 1084  sub problem_web_to_edit_header {
 ".&mt("Problem Type:")."  ".&mt("Problem Type:")."
 <select name='problemtype'>  <select name='problemtype'>
   <option value=''></option>    <option value=''></option>
   ".&option('exam'   ,'problemtype').&mt("Exam Problem")."</option>    ".&option('exam'   ,'problemtype').&mt("Bubblesheet Exam Problem")."</option>
   ".&option('problem','problemtype').&mt("Homework Problem")."</option>    ".&option('problem','problemtype').&mt("Homework Problem")."</option>
   ".&option('survey' ,'problemtype').&mt("Survey Question")."</option>    ".&option('survey' ,'problemtype').&mt("Survey Question")."</option>
   ".&option('surveycred' ,'problemtype').&mt("Survey Question (with credit)")."</option>    ".&option('surveycred' ,'problemtype').&mt("Survey Question (with credit)")."</option>
Line 982  sub initialize_storage { Line 1204  sub initialize_storage {
  }   }
  %Apache::lonhomework::history=   %Apache::lonhomework::history=
     &Apache::lonnet::tmprestore($namespace,'',$domain,$name);      &Apache::lonnet::tmprestore($namespace,'',$domain,$name);
  my ($temp)=keys(%Apache::lonhomework::history);   my ($temp)=keys(%Apache::lonhomework::history) ;
  &Apache::lonxml::debug("Return message of $temp");   &Apache::lonxml::debug("Return message of $temp");
     } else {      } else {
  %Apache::lonhomework::history=   %Apache::lonhomework::history=
Line 1005  sub initialize_storage { Line 1227  sub initialize_storage {
         &check_correctness_changes() is called in two circumstances          &check_correctness_changes() is called in two circumstances
         in which the results hash is to be stored permanently, for          in which the results hash is to be stored permanently, for
         grading triggered by a student's submission, where feedback on          grading triggered by a student's submission, where feedback on
         correctness is to be provided to the student.          correctness is to be provided to the student. 
   
         1. Immediately prior to storing the results hash          1. Immediately prior to storing the results hash
   
         To handle the case where a student's submission (and award) were          To handle the case where a student's submission (and award) were 
         stored after history was retrieved in &initialize_storage(), e.g.,          stored after history was retrieved in &initialize_storage(), e.g.,
         if a student submitted answers in quick succession (e.g., from          if a student submitted answers in quick succession (e.g., from 
         multiple tabs).  &Apache::inputtags::hidealldata() is called for          multiple tabs).  &Apache::inputtags::hidealldata() is called for
         any parts with out-of-order storage (i.e., correct then incorrect,          any parts with out-of-order storage (i.e., correct then incorrect,
         where awarded >= 1 when correct).          where awarded >= 1 when correct).
Line 1021  sub initialize_storage { Line 1243  sub initialize_storage {
         To handle the case where lond on the student's homeserver returns          To handle the case where lond on the student's homeserver returns
         delay:N -- where N is the number of transactions between the last          delay:N -- where N is the number of transactions between the last
         retrieved in &initialize_storage() and the last stored immediately          retrieved in &initialize_storage() and the last stored immediately
         before permanent storage of the current transaction via          before permanent storage of the current transaction via 
         lond::store_handler().  &Apache::grades::makehidden() is called          lond::store_handler().  &Apache::grades::makehidden() is called  
         for any parts with out-of-order storage (i.e., correct then incorrect,          for any parts with out-of-order storage (i.e., correct then incorrect,
         where awarded >= 1 when correct).          where awarded >= 1 when correct).
   
  Will call &store_aggregates() to increment totals for attempts,    Will call &store_aggregates() to increment totals for attempts, 
  students, and corrects, if running user has student role.          students, and corrects, if running user has student role.
   
 =cut  =cut
   
   
Line 1149  sub finalize_storage { Line 1371  sub finalize_storage {
 =item check_correctness_changes()  =item check_correctness_changes()
   
         For all parts for which current results contain a solved status          For all parts for which current results contain a solved status
         of "incorrect_attempted", check if there was a transaction in which          of "incorrect_attempted", check if there was a transaction in which  
         solved was set to "correct_by_student" in the time since the last          solved was set to "correct_by_student" in the time since the last 
         transaction (retrieved when &initialize_storage() was called i.e.,          transaction (retrieved when &initialize_storage() was called i.e., 
         when &start_problem() was called), unless:          when &start_problem() was called), unless:
         (a) questiontype parameter is set to survey or anonymous survey (+/- credit)          (a) questiontype parameter is set to survey or anonymous survey (+/- credit)
         (b) problemstatus is set to no or no_feedback_ever          (b) problemstatus is set to no or no_feedback_ever
         If such a transaction exists, and did not occur after "reset status"          If such a transaction exists, and did not occur after "reset status" 
         by a user with grading privileges, then the current transaction is an          by a user with grading privileges, then the current transaction is an
         example of an out-of-order transaction (i.e., incorrect occurring after          example of an out-of-order transaction (i.e., incorrect occurring after
         correct).  Accordingly, the current transaction should be hidden.          correct).  Accordingly, the current transaction should be hidden.
Line 1283  sub checkout_msg { Line 1505  sub checkout_msg {
  'resource'=>'The resource needs to be checked out',   'resource'=>'The resource needs to be checked out',
  'id_expln'=>'As a resource gets checked out, a unique timestamped ID is given to it, and a permanent record is left in the system.',   'id_expln'=>'As a resource gets checked out, a unique timestamped ID is given to it, and a permanent record is left in the system.',
                 'warning'=>'Checking out resources is subject to course policies, and may exclude future credit even if done erroneously.',                  'warning'=>'Checking out resources is subject to course policies, and may exclude future credit even if done erroneously.',
                 'checkout'=>'Check out Exam for Viewing',                  'checkout'=>'Check out Bubblesheet Exam for Viewing',
  'checkout?'=>'Check out Exam?');   'checkout?'=>'Check out Bubblesheet Exam?');
     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});      my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
     return (<<ENDCHECKOUT);      return (<<ENDCHECKOUT);
 <h2>$lt{'resource'}</h2>  <h2>$lt{'resource'}</h2>
Line 1361  sub init_problem_globals { Line 1583  sub init_problem_globals {
     @Apache::inputtags::importlist = ();      @Apache::inputtags::importlist = ();
     @Apache::inputtags::previous=();      @Apache::inputtags::previous=();
     @Apache::inputtags::previous_version=();      @Apache::inputtags::previous_version=();
     $Apache::inputtags::leniency='';  
     $Apache::structuretags::printanswer='No';      $Apache::structuretags::printanswer='No';
     @Apache::structuretags::whileconds=();      @Apache::structuretags::whileconds=();
     @Apache::structuretags::whilebody=();      @Apache::structuretags::whilebody=();
Line 1377  sub reset_problem_globals { Line 1598  sub reset_problem_globals {
     undef(%Apache::lonhomework::history);      undef(%Apache::lonhomework::history);
     undef(%Apache::lonhomework::results);      undef(%Apache::lonhomework::results);
     undef($Apache::inputtags::part);      undef($Apache::inputtags::part);
     undef($Apache::inputtags::leniency);  
     if ($type eq 'Task') {      if ($type eq 'Task') {
         undef($Apache::inputtags::slot_name);          undef($Apache::inputtags::slot_name);
     } elsif ($type eq 'problem') {      } elsif ($type eq 'problem') {
Line 2581  sub start_part { Line 2801  sub start_part {
     my $id= &Apache::lonxml::get_id($parstack,$safeeval);      my $id= &Apache::lonxml::get_id($parstack,$safeeval);
     $Apache::inputtags::part=$id;      $Apache::inputtags::part=$id;
     push(@Apache::inputtags::partlist,$id);      push(@Apache::inputtags::partlist,$id);
     $Apache::inputtags::leniency='';  
     @Apache::inputtags::response=();      @Apache::inputtags::response=();
     @Apache::inputtags::previous=();      @Apache::inputtags::previous=();
     @Apache::inputtags::previous_version=();      @Apache::inputtags::previous_version=();
Line 2747  sub end_part { Line 2966  sub end_part {
     }      }
     pop @Apache::inputtags::status;      pop @Apache::inputtags::status;
     $Apache::inputtags::part='';      $Apache::inputtags::part='';
     $Apache::inputtags::leniency='';  
     $Apache::lonhomework::type = $Apache::lonhomework::default_type;      $Apache::lonhomework::type = $Apache::lonhomework::default_type;
     return $result;      return $result;
 }  }
Line 2855  sub start_problemtype { Line 3073  sub start_problemtype {
     ['hide','Hide']]      ['hide','Hide']]
    ,$token);     ,$token);
  $result .=&Apache::edit::checked_arg('When used as type(s):','for',   $result .=&Apache::edit::checked_arg('When used as type(s):','for',
      [ ['exam','Exam/Quiz Problem'],       [ ['exam','Bubblesheet Exam/Quiz Problem'],
        ['survey','Survey'],         ['survey','Survey'],
                                                ['surveycred','Survey (with credit)'],                                                 ['surveycred','Survey (with credit)'],
                                                ['anonsurvey','Anonymous Survey'],                                                 ['anonsurvey','Anonymous Survey'],
Line 2898  sub end_startouttext { Line 3116  sub end_startouttext {
     if ($target eq 'edit') {      if ($target eq 'edit') {
  my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;   my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;
  $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);   $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);
  $result.=&Apache::edit::start_table($token)."<tr><td>".&mt('Text Block')."</td>"          $result.=&Apache::edit::start_table($token)."<tr><td>".&Apache::loncommon::insert_folding_button()
                    ." ".&mt('Text Block')."</td>"
                  .'<td><span class="LC_nobreak">'.&mt('Delete?').' '                   .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
                  .&Apache::edit::deletelist($target,$token)                   .&Apache::edit::deletelist($target,$token)
                  .'</span></td>'                   .'</span></td>'

Removed from v.1.512.2.10  
changed lines
  Added in v.1.531


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>