Index: /trunk/htdocs2/Classes/Astro/Angle.php
===================================================================
--- /trunk/htdocs2/Classes/Astro/Angle.php	(revision 298)
+++ /trunk/htdocs2/Classes/Astro/Angle.php	(revision 298)
@@ -0,0 +1,99 @@
+<?php
+
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/StringUtils.php';
+
+
+
+class Angle
+{
+  public function __construct( Angle $s_angle = null )
+  {
+    if( $s_angle != null )
+      $this->radians = $s_angle->ToRadians();
+    else
+      $this->radians = 0.0;
+  }
+
+  public function ToRadians() { return $this->radians; }
+  public function FromRadians( $s_radians ) { $this->radians = $s_radians; }
+  
+  public function ToDegrees() { return ($this->radians / M_PI * 180.0); }
+  public function FromDegrees( $s_degrees ) { $this->radians = $s_degrees / 180.0 * M_PI; }
+  
+  public function FromHMS( $s_hours, $s_mins, $s_secs )
+  {
+    $this->FromDegrees( $s_hours * 15.0 + $s_mins * 0.25 + $s_secs * 0.25 / 60.0 );
+//     $this->radians = ((($s_hours * 15.0) + ($s_mins * 0.25) + ($s_sec * (0.25 / 60.0))) / 180.0) * M_PI;
+  }
+  public function ToHMS( &$hours, &$mins, &$secs )
+  {
+    $degrees = $this->ToDegrees();
+    $hours = floor( ($degrees * 24.0) / 360.0);
+    $hours_remainder = (( $degrees * 24.0) / 360.0 ) - $hours;
+    $mins = floor( $hours_remainder * 60.0 );
+    $mins_remainder = ($hours_remainder * 60.0) - $mins;
+    $secs = $mins_remainder * 60;
+  }
+
+  public function FromHMSString( $s_hms )
+  {
+    $hours = strword( $s_hms, 0, ':' );
+    $mins = strword( $s_hms, 1, ':' );
+    $secs = strword( $s_hms, 2, ':' );
+
+    $this->FromHMS( $hours, $mins, $secs );
+  }
+  
+  public function ToHMSString()
+  {
+    $hours = 0;
+    $mins = 0;
+    $secs = 0;
+    $this->ToHMS( $hours, $mins, $secs );
+    
+    return sprintf("%02d:%02d:%02d", $hours, $mins, $secs );
+  }
+  
+  public function FromDMS( $s_degrees, $s_mins, $s_secs )
+  {
+    $degrees = $s_degrees;
+    $degrees += $s_mins / 60.0;
+    $degrees += $s_secs / 3600.0;
+    $this->FromDegrees( $degrees );
+  }
+  
+  public function FromDMSString( $dms_string )
+  {
+    $degrees = strword( $dms_string, 0, ':' );
+    $mins = strword( $dms_string, 1, ':' );
+    $secs = strword( $dms_string, 2, ':' );
+    $this->FromDMS( $degrees, $mins, $secs );
+  }
+  
+  public function ToDMS( &$degrees, &$mins, &$secs )
+  {
+    $degrees = $this->ToDegrees();
+    $remainder = $degrees - floor($degrees);
+    $mins = floor( $remainder * 60.0 );
+    $remainder = ($remainder * 60.0) - $mins;
+    $secs = $remainder * 60.0;
+    $degrees = floor($degrees);
+  }
+  public function ToDMSString()
+  {
+    $degrees;
+    $mins;
+    $secs;
+    $this->ToDMS( $degrees, $mins, $secs );
+
+    return sprintf("%02d:%02d:%06.3f", $degrees, $mins, $secs );
+  }
+  
+  private $radians;
+
+};
+
+?>
Index: /trunk/htdocs2/Classes/Astro/Band.php
===================================================================
--- /trunk/htdocs2/Classes/Astro/Band.php	(revision 298)
+++ /trunk/htdocs2/Classes/Astro/Band.php	(revision 298)
@@ -0,0 +1,60 @@
+<?php
+
+
+
+class Band
+{
+  // PUBLIC
+
+  public function __construct( $s_name = '', $s_description = '', $s_lower_bound = '', $s_upper_bound = '')
+  {
+    $this->SetName($s_name);
+    $this->SetDescription($s_description);
+    $this->SetLowerBound($s_lower_bound);
+    $this->SetUpperBound($s_upper_bound);
+
+    if( !Band::$static_setup )
+      Band::SetupStaticData();
+  }
+
+  public function GetName() { return $this->name; }
+  public function SetName( $s_name ) { $this->name = $s_name; }
+
+  public function GetDescription() { return $this->description; }
+  public function SetDescription( $s_description ) { $this->description = $s_description; }
+
+  public function GetLowerBound() { return $this->lower_bound; }
+  public function SetLowerBound( $s_lower_bound ) { $this->lower_bound = $s_lower_bound; }
+
+  public function GetUpperBound() { return $this->upper_bound; }
+  public function SetUpperBound( $s_upper_bound ) { $this->upper_bound = $s_upper_bound; }
+
+  // PRIVATE
+
+  private $name;
+  private $description;
+  private $lower_bound;
+  private $upper_bound;
+
+  // STATIC
+
+  private static $static_setup = false;
+  public static $valid_bands = Array();
+
+  public static function SetupStaticData()
+  {
+    Band::$static_setup = true;
+
+    Band::$valid_bands[] = new Band( '70cm', '(~0.44 GHz)', 0.0, 500.0 );
+    Band::$valid_bands[] = new Band( '50cm', '(~0.66 GHz)', 600.0, 700.0 );
+    Band::$valid_bands[] = new Band( '20/18cm', '(1.2-1.8 GHz)', 1199.99, 1800.01 );
+    Band::$valid_bands[] = new Band( '13cm', '(2.0-2.5 GHz)', 1999.99, 2500.01 );
+    Band::$valid_bands[] = new Band( '10cm', '(2.6-3.6 GHz)', 2599.99, 3600.01 );
+    Band::$valid_bands[] = new Band( '6cm', '(4.5-5.1 GHz)', 4499.99, 5100.01 );
+    Band::$valid_bands[] = new Band( '5cm', '(5.9-6.8 GHz)', 5899.99, 6800.01 );
+    Band::$valid_bands[] = new Band( '3cm', '(8.1-8.6 GHz)', 8099.99, 8600.01);
+    Band::$valid_bands[] = new Band( '1.3cm', '(21.-24. GHZ)', 20999.99, 24000.01 );
+  }
+};
+
+?>
Index: /trunk/htdocs2/Classes/Astro/MJD.php
===================================================================
--- /trunk/htdocs2/Classes/Astro/MJD.php	(revision 298)
+++ /trunk/htdocs2/Classes/Astro/MJD.php	(revision 298)
@@ -0,0 +1,98 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Utils/StringUtils.php';
+require_once 'Classes/General/Date.php';
+
+
+class MJD
+{
+  // PUBLIC
+
+  public function __construct( $mjd = '' )
+  {
+    $this->day = '';
+    $this->frac_day = '';
+    $this->FromString( $mjd );
+  }
+  
+  public function FromString( $mjd )
+  {
+    if( $mjd != '' )
+    {
+      $this->day = strword( $mjd, 0, '.' );
+      $this->frac_day = strword( $mjd, 1, '.' );
+    }
+  }
+
+  public function ToString()
+  {
+    return $this->day . '.' . $this->frac_day;
+  }
+
+  // From http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html
+  public function ToDate()
+  {
+    $jdval = floatval($this->ToString()) + 2400000.5;
+    $z = $jdval + 0.5;
+	
+    $w = floor(($z - 1867216.25)/36524.25);
+    $x = floor($w/4);
+    $a = floor($z+1+$w-$x);
+    $b = floor($a + 1524);
+    $c = floor(($b-122.1)/365.25);
+    $d = floor(365.25*$c);
+    $e = floor(($b-$d)/30.6001);
+    $f = floor(30.6001 * $e);
+	
+    $day = $b-$d-$f;
+    $month = $e-1;
+    if ($month > 12) {
+      $month = $e - 13;
+    }
+	
+    if ($month == 1 || $month == 2) {
+      $year = $c - 4715;
+    }
+    else {
+      $year = $c - 4716;
+    }
+    
+    
+    $gregorian = new Date( $day . '/' . $month . '/' . $year );
+    
+    return $gregorian;
+  }
+  
+  public function FromDate( $gregorian )
+  {
+    $year = intval($gregorian->GetYear());
+    $month = intval($gregorian->GetMonthOfYear());
+    $day = intval($gregorian->GetDayOfMonth());
+    
+    if ($month == 1 || $month == 2) {
+      $year = $year - 1;
+      $month += 12;
+    }
+	
+    $a = floor($year/100);
+	
+    $b = floor($a/4);
+    $c = 2 - $a + $b;
+    $e = floor(365.25 * ($year + 4716));
+    $f = floor(30.6001 * ($month + 1));
+    $jd = $c+$day+$e+$f - 1524.5;
+	
+    $this->FromString( $jd - 2400000.5);
+  }
+
+  // PRIVATE
+
+  private $day;
+  private $frac_day;
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Astro/SkyCoord.php
===================================================================
--- /trunk/htdocs2/Classes/Astro/SkyCoord.php	(revision 298)
+++ /trunk/htdocs2/Classes/Astro/SkyCoord.php	(revision 298)
@@ -0,0 +1,70 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Utils/StringUtils.php';
+require_once 'Classes/Astro/Angle.php';
+
+
+
+/**
+ * This class represents a coordinate in the sky, as right ascention and declanation.
+ **/
+
+class SkyCoord
+{
+  public function __construct( SkyCoord $s_coords  = null )
+  {
+    $s_ra = null;
+    $s_dec = null;
+    if( $s_coords != null )
+    {
+      $s_ra = $s_coords->GetRA();
+      $s_dec = $s_coords->GetDEC();
+    }
+
+    $this->ra = new Angle( $s_ra );
+    $this->dec = new Angle( $s_dec );
+  }
+  
+  public function GetRA() { return $this->ra; }
+  public function GetDEC() { return $this->dec; }
+  
+  public function SetRA( $s_ra ) { $this->ra = $s_ra; }
+  public function SetDEC( $s_dec ) { $this->dec = $s_dec; }
+
+  public function GetRAHour() { return strword( $this->ra->ToHMSString(), 0, ':' ); }
+  public function GetRAMin() { return strword( $this->ra->ToHMSString(), 1, ':' ); }
+  public function GetRASec() { return strword( $this->ra->ToHMSString(), 2, ':' ); }
+
+  public function GetDECDeg() { return strword( $this->dec->ToDMSString(), 0, ':' ); }
+  public function GetDECMin() { return strword( $this->dec->ToDMSString(), 1, ':' ); }
+  public function GetDECSec() { return strword( $this->dec->ToDMSString(), 2, ':' ); }
+
+  public function FromHMSDMSString( $coord_string )
+  {
+    $ra = strword( $coord_string, 0 );
+    $dec = strword( $coord_string, 1 );
+
+    $this->ra->FromHMSString( $ra );
+    $this->dec->FromDMSString( $dec );
+  }
+
+  public function ToHMSDMSString() 
+  {
+    if( $this->ra == null || $this->dec == null )
+      return '';
+
+    return $this->ra->ToHMSString() . ' ' . $this->dec->ToDMSString();
+  }
+  
+  private $ra;
+  private $dec;
+};
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/General/Date.php
===================================================================
--- /trunk/htdocs2/Classes/General/Date.php	(revision 298)
+++ /trunk/htdocs2/Classes/General/Date.php	(revision 298)
@@ -0,0 +1,112 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Utils/StringUtils.php';
+require_once GREEN_ZONE_DIR . 'Utils/GZ_Exception.php';
+
+
+
+class Date
+{
+  public function __construct( $s_dmy = null)
+  {
+    if( $s_dmy == null )
+    {
+      $this->day_of_month = null;
+      $this->month_of_year = null;
+      $this->year = null;
+    }
+    else
+      $this->FromDMYString( $s_dmy );
+  }
+  
+  public function IsUnset()
+  { 
+      if( $this->year != null ) 
+	 return false; 
+        return true; 
+  }
+
+  public function FromDMYString( $date_string )
+  {
+    // TODO add some checking to ensure that we have a properly formed string
+    // and throw an exception if we don't
+        
+    $separator = '';
+    if( strpos( $date_string, '/' ) !== false )
+      $separator = '/';
+    else if( strpos( $date_string, '-' ) !== false )
+      $separator = '-';
+    else
+      throw( new GZ_Exception( 'Date::FromDMYString unknown separator string' ) );
+
+    $this->SetDayOfMonth( strword( $date_string, 0, $separator ) );
+    $this->SetMonthOfYear( strword( $date_string, 1, $separator ) );
+    $this->SetYear( strword( $date_string, 2, $separator ) );
+  }
+  public function FromYMDString( $date_string )
+  {
+    // TODO add some checking to ensure that we have a properly formed string
+    // and throw an exception if we don't
+        
+        $separator = '';
+    if( strpos( $date_string, '/' ) !== false )
+      $separator = '/';
+    else if( strpos( $date_string, '-' ) !== false )
+      $separator = '-';
+    else
+      throw( new GZ_Exception( 'Date::FromDMYString unknown separator string' ) );
+
+    $this->SetDayOfMonth( strword( $date_string, 2, $separator ) );
+    $this->SetMonthOfYear( strword( $date_string, 1, $separator ) );
+    $this->SetYear( strword( $date_string, 0, $separator ) );
+  }
+
+  public function ToDMYString( $separator = '/' ) 
+  {
+    return $this->GetDayOfMonth() . $separator . $this->GetMonthOfYear() . $separator . $this->GetYear();
+  }
+  public function ToDMYString2( $separator = '/') 
+  {
+    return $this->GetDayOfMonth() . $separator . $this->GetMonthOfYearTxt() . $separator . $this->GetYear();
+  }
+  public function ToYMDStringDashed( $separator = '/' )
+  {
+    return $this->GetYear() . $separator . sprintf( '%02d', $this->GetMonthOfYear()) . $separator . sprintf('%02d',$this->GetDayOfMonth());
+  }
+
+  public function GetDayOfMonth() { return $this->day_of_month; }
+  public function SetDayOfMonth( $s_day_of_month ) { $this->day_of_month = $s_day_of_month; }
+
+  public function GetMonthOfYear() { return $this->month_of_year; }
+  public function GetMonthOfYearTxt() { return Date::$months_in_year[intval($this->month_of_year)-1]; }
+  public function SetMonthOfYear( $s_month_of_year )
+  {
+    if( is_numeric( $s_month_of_year ) )
+      $this->month_of_year = $s_month_of_year;
+    else
+    {
+      for( $ind = 0; $ind < count( Date::$months_in_year ); $ind ++ )
+	if( Date::$months_in_year[$ind] == $s_month_of_year )
+	  $this->month_of_year = $ind + 1;
+    }
+  }
+
+  public function GetYear() { return $this->year; }
+  public function SetYear( $s_year ) { $this->year = $s_year; }
+
+  private $day_of_month;
+  private $month_of_year;
+  private $year;
+  public static $arrays_setup = false;
+  public static $days_in_month = Array( 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 );
+  public static $months_in_year = Array( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );
+};
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/General/DateRange.php
===================================================================
--- /trunk/htdocs2/Classes/General/DateRange.php	(revision 298)
+++ /trunk/htdocs2/Classes/General/DateRange.php	(revision 298)
@@ -0,0 +1,35 @@
+<?php
+
+
+
+require_once 'Classes/General/Date.php';
+
+
+
+/**
+ * This class represents a range of dates, from date to date
+ **/
+
+class DateRange
+{
+  public function __construct( $s_from_dmy = '', $s_to_dmy = '' )
+  {
+    $this->from_date = new Date( $s_from_dmy );
+    $this->to_date = new Date( $s_to_dmy );
+  }
+
+  public function SetFromDate( $s_from_date ) { $this->from_date = $s_from_date; }
+  public function GetFromDate() { return $this->from_date; }
+
+  public function SetToDate( $s_to_date ) { $this->to_date = $s_to_date; }
+  public function GetToDate() { return $this->to_date; }
+
+  private $from_date;
+  private $to_date;
+};
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/General/Dir.php
===================================================================
--- /trunk/htdocs2/Classes/General/Dir.php	(revision 298)
+++ /trunk/htdocs2/Classes/General/Dir.php	(revision 298)
@@ -0,0 +1,57 @@
+<?php
+
+
+
+/**
+ * This class represents a directory, it needs you to give it the path
+ * you can get it to
+ * - list the files under that directory
+ * - check that it exists and is a directory
+ * - make the directory, if the parent directory exists
+ **/
+
+class Dir
+{
+  // PUBLIC
+
+  public function __construct( $s_path = '' ) { $this->SetPath( $s_path ); }
+
+  public function SetPath( $s_path ) { $this->path = $s_path; }
+  public function GetPath() { return $this->path; }
+
+  public function Create() { mkdir( $this->path ); }
+  public function Remove() { rmdir( $this->path ); }
+
+  public function IsDir() { return is_dir($this->path); }
+
+  public function ListFiles()
+  {
+    $file_list = Array();
+
+    $dirhandler = opendir( $this->path );
+    if( $dirhandler !== false )
+    {
+      while( ( $next_file = readdir( $dirhandler ) ) !== false )
+      {
+	$file_list[] = $next_file;
+      }
+      closedir( $dirhandler );
+    }
+
+    return $file_list;
+  }
+
+  // PRIVATE
+
+  private $path;
+};
+
+
+
+
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/General/File.php
===================================================================
--- /trunk/htdocs2/Classes/General/File.php	(revision 298)
+++ /trunk/htdocs2/Classes/General/File.php	(revision 298)
@@ -0,0 +1,55 @@
+<?php
+
+
+
+/**
+ * This simple class represents a path/filename pair. Not a very usefull class
+ * but it does ensure both components are initialized to '' and we can get
+ * either component on its own or both together.
+ **/
+
+class File
+{
+  // PUBLIC
+
+    public function __construct( $s_path = '', $s_file = '' )
+    {
+      $this->path = $s_path;
+      $this->filename = $s_file;
+    }
+
+    public function SetFilename( $s_filename ) { $this->filename = $s_filename; }
+    public function SetPath( $s_path ) { $this->path = $s_path; }
+
+    public function GetFilename() { return $this->filename; }
+    public function GetPath() { return $this->path; }
+
+    public function GetFullPath() { return "$this->path/$this->filename"; }
+    public function SetFullPath( $s_full_path )
+    {
+      $this->path = substr( $s_full_path, 0, strrpos( $s_full_path, '/' ) );
+      $this->filename = substr( $s_full_path, strrpos( $s_full_path, '/' ) + 1 );
+    }
+
+    public function IsDir() { return is_dir( $this->GetFullPath() ); }
+    public function IsFile() { return is_file( $this->GetFullPath() ); }
+    public function IsLink() { return is_link( $this->GetFullPath() ); }
+
+    public function Exists() { return file_exists( $this->GetFullPath() ); }
+
+    public function Create() { touch( $this->GetFullPath() ); }
+
+    public function Remove() { unlink( $this->GetFullPath() ); }
+    
+    public function GetFileSize() { return filesize( $this->GetFullPath() ); }
+
+  // PRIVATE
+
+    private $filename;
+    private $path;
+};
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/General/Pair.php
===================================================================
--- /trunk/htdocs2/Classes/General/Pair.php	(revision 298)
+++ /trunk/htdocs2/Classes/General/Pair.php	(revision 298)
@@ -0,0 +1,18 @@
+<?php
+
+class Pair
+{
+  // PUBLIC
+
+  public function __construct( $s_first = 0, $s_second = 0 ) 
+  {
+    $this->first = $s_first;
+    $this->second = $s_second;
+  }
+
+  // PRIVATE
+
+  public $first;
+  public $second;
+};
+?>
Index: /trunk/htdocs2/Classes/General/TarBuilder.php
===================================================================
--- /trunk/htdocs2/Classes/General/TarBuilder.php	(revision 298)
+++ /trunk/htdocs2/Classes/General/TarBuilder.php	(revision 298)
@@ -0,0 +1,63 @@
+<?php
+
+
+
+require_once 'Classes/General/File.php';
+
+
+
+/**
+ * This class is a tar file builder. Though the actual work of
+ * building the tar file is done by execing tar. We use this
+ * algorithm by giving it a data directory to compress the files
+ * from, the names of all the files under that path we want to
+ * add to the tar file, and the name and path to the tar file
+ * we want to create.
+ **/
+class TarBuilder
+{
+  // PUBLIC
+
+    public function __construct()
+    {
+      $this->tar_file = new File();
+      $this->filenames = Array();
+      $this->src_dir = '';
+    }
+
+    public function SetSrcDir( $s_src_dir ) { $this->src_dir = $s_src_dir; }
+    public function AddFile( $new_file ) { $this->filenames[] = $new_file; }
+    public function SetTarFile( File $s_tar_file ) { $this->tar_file = $s_tar_file; }
+
+    public function GetTarFile() { return $this->tar_file; }
+
+    //! Call exec to run tar and create our tarfile.
+    public function Execute()
+    {
+      $web_dir = getcwd();
+      chdir( $this->src_dir );
+
+      $command = 'tar --dereference -cf ' . $this->tar_file->GetFullPath() . ' ';
+
+      foreach( $this->filenames as $next_filename )
+	$command .= $next_filename . ' ';
+
+      $ret_val = '';
+      $output_array = Array();
+      $last_line = exec( $command, $output_array, $ret_val );
+
+      // TODO throw an exception if the exec failed in some way
+      // TODO throw an exception if no tar file was created.
+
+      chdir( $web_dir );
+    }
+
+  // PRIVATE
+
+    private $tar_file;
+    private $src_dir;
+    private $filenames;
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/General/UserData.php
===================================================================
--- /trunk/htdocs2/Classes/General/UserData.php	(revision 298)
+++ /trunk/htdocs2/Classes/General/UserData.php	(revision 298)
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * Written by David Smith
+ * nopeer@gmail.com
+ *
+ * For ATNF CSIRO
+ *
+ * This class represents the user data we wish to store in _SESSION.
+ * This includes;
+ * - The users email address
+ * - The method of authenticate used 'anonymous' or 'opal'
+ */
+
+class UserData
+{
+  // PUBLIC
+
+  public function __construct()
+  {
+    $this->auth_type = '';
+    $this->email = '';
+    $this->RestoreFromSession();
+  }
+
+  public function __destruct()
+  {
+    $this->SaveToSession();
+  }
+
+  public function SetAuthType( $s_auth_type ) { $this->auth_type = $s_auth_type; }
+  public function GetAuthType() { return $this->auth_type; }
+
+  public function SetEmail( $s_email ) { $this->email = $s_email; }
+  public function GetEmail() { return $this->email; }
+
+  public function RemoveFromSession()
+  {
+    global $_SESSION;
+
+    unset( $_SESSION['userdata_email'] );
+    unset( $_SESSION['userdata_auth_type'] );
+
+    $this->email = '';
+    $this->auth_type = '';
+  }
+
+  // PRIVATE
+
+  private $auth_type;
+  private $email;
+
+  private function SaveToSession()
+  {
+    global $_SESSION;
+
+    if( $this->auth_type != '' )
+    {
+      $_SESSION['userdata_auth_type'] = $this->auth_type;
+      $_SESSION['userdata_email'] = $this->email;
+    }
+  }
+
+  private function RestoreFromSession()
+  {
+    global $_SESSION;
+
+    if( isset( $_SESSION['userdata_auth_type'] ) )
+      $this->auth_type = $_SESSION['userdata_auth_type'];
+
+    if( isset( $_SESSION['userdata_email'] ) )
+      $this->email = $_SESSION['userdata_email'];
+  }
+};
+
+?>
Index: /trunk/htdocs2/Classes/Interfaces/CalInterface.php
===================================================================
--- /trunk/htdocs2/Classes/Interfaces/CalInterface.php	(revision 298)
+++ /trunk/htdocs2/Classes/Interfaces/CalInterface.php	(revision 298)
@@ -0,0 +1,24 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/GZ_DataMapper.php';
+
+
+
+class CalInterface extends GZ_DataMapper
+{
+  public function __construct()
+  {
+    parent::__construct();
+    
+    $this->MakeMapping( 'primary_key', 'GetFileID' );
+    $this->MakeMapping( 'file_id', 'GetFileID' );
+    $this->MakeMapping( 'rajd', 'GetRA', 'ToHMS' );
+    $this->MakeMapping( 'decjd', 'GetDEC', 'ToDMS' );
+    $this->MakeMapping( 'MJD', 'GetMJD', 'ToString' );
+
+  }
+};
+
+?>
Index: /trunk/htdocs2/Classes/Interfaces/ObsInterface.php
===================================================================
--- /trunk/htdocs2/Classes/Interfaces/ObsInterface.php	(revision 298)
+++ /trunk/htdocs2/Classes/Interfaces/ObsInterface.php	(revision 298)
@@ -0,0 +1,35 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/GZ_DataMapper.php';
+
+
+
+class ObsInterface extends GZ_DataMapper
+{
+  public function __construct()
+  {
+    parent::__construct();
+    
+    $this->MakeMapping( 'primary_key', 'GetFileID' );
+    $this->MakeMapping( 'file_id', 'GetFileID' );
+    $this->MakeMapping( 'src_name', 'GetPulsarName' );
+    $this->MakeMapping( 'rajd', 'GetRAJD', 'ToHMSString' );
+    $this->MakeMapping( 'decjd', 'GetDECJD', 'ToDMSString' );
+    $this->MakeMapping( 'distance', 'GetDistance' );
+    $this->MakeMapping( 'project_id', 'GetProjectID' );
+    $this->MakeMapping( 'filename', 'GetFile', 'GetFilename' );
+    $this->MakeMapping( 'data_type', 'GetDataType' );
+    $this->MakeMapping( 'mjd', 'GetMJD', 'ToString' );
+    $this->MakeMapping( 'date', 'GetDate', 'ToDMYString2' );
+    $this->MakeMapping( 'ut', 'GetUT' );
+    $this->MakeMapping( 'obsfreq', 'GetObsFreq' );
+    $this->MakeMapping( 'bw', 'GetBW' );
+    $this->MakeMapping( 'scanlen', 'GetScanLen' );
+    $this->MakeMapping( 'child_interface', 'GetChildInterface' );
+    $this->MakeMapping( 'child_data', 'GetCalibrations' );
+  }
+};
+
+?>
Index: /trunk/htdocs2/Classes/Model/Calibration.php
===================================================================
--- /trunk/htdocs2/Classes/Model/Calibration.php	(revision 298)
+++ /trunk/htdocs2/Classes/Model/Calibration.php	(revision 298)
@@ -0,0 +1,81 @@
+<?php
+
+
+
+require_once 'Classes/Astro/SkyCoord.php';
+
+
+
+/**
+ * @class Calibration
+ *
+ * This class represents a calibration, it contains an array whith the contents of
+ * an entry in the cals table of the database that corresponds to this calibration.
+ **/
+class Calibration
+{
+  public $is_calibration = true;
+  
+  
+  
+  // PUBLIC
+      
+  public function __construct()
+  {
+    $this->coordinates = new SkyCoord();
+    $this->file_id = null;
+    $this->mjd = null;
+  }
+  
+  /**
+   * This function extracts the parameters for this object from the 
+   * database record given.
+   **/
+
+  public function FromRecord( $record )
+  {
+    $this->coordinates = new SkyCoord();
+    
+    $ra_angle = new Angle();
+    $ra_angle->FromDegrees( $record['rajd'] );
+    
+    $dec_angle = new Angle();
+    $dec_angle->FromDegrees( $record['decjd'] );
+    
+    $new_coords = new SkyCoord();
+    $new_coords->SetRA( $ra_angle );
+    $new_coords->SetDEC( $dec_angle );
+    
+    $this->SetCoordinates( $new_coords );
+    
+    $this->mjd = new MJD();
+    $this->mjd->FromString( $record['MJD'] );
+  }
+  
+  public function SetFileID( $s_file_id ) { $this->file_id = $s_file_id; }
+  public function GetFileID() { return $this->file_id; }
+  
+  public function SetCoordinates( $s_coordinates ) { $this->coordinates = $s_coordinates; }
+  public function GetCoordinates() { return $this>coordinates; }
+  
+  public function GetRA() { if( $this->coordinates == null ) return ull; return $this->GetCoordinates()->GetRA(); }
+  public function GetDEC() { return $this->GetCoordiantes()->GetDEC(); }
+  
+  public function SetMJD( $s_mjd ) { $this->mjd = $s_mjd; }
+  public function GetMJD() { return $this->mjd; }
+  
+  
+
+  
+  // PRIVATE
+      
+  private $file_id;
+  private $coordinates;
+  private $mjd;
+};
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/Model/Observation.php
===================================================================
--- /trunk/htdocs2/Classes/Model/Observation.php	(revision 298)
+++ /trunk/htdocs2/Classes/Model/Observation.php	(revision 298)
@@ -0,0 +1,149 @@
+<?php
+
+
+
+require_once 'Classes/General/File.php';
+require_once 'Classes/Model/Calibration.php';
+require_once 'Classes/Interfaces/CalInterface.php';
+
+
+
+class Observation
+{
+  public $is_calibration = false;
+  
+  public function __construct()
+  {
+    $this->file_id = null;
+    $this->rajd = null;
+    $this->decjd = null;
+    $this->distance = null;
+    $this->pulsar_name = null;
+    $this->mjd = null;
+    $this->data_type = null;
+    $this->date = null;
+    $this->file = null;
+    $this->ut = null;
+    $this->bw = null;
+    $this->obs_freq = null;
+    $this->scal_len = null;
+    $this->calibrations = Array();
+  }
+
+  /**
+   * This function extracts the parameters for this object from the 
+   * database record given.
+   **/
+
+  public function FromRecord( $record )
+  {
+    $this->SetPulsarName( $record['src_name'] );
+    $this->SetFileID( $record['file_id'] );
+    $this->SetDistance( $record['distance'] );
+    
+    $ra = new Angle();
+    $ra->FromDegrees( $record['rajd'] );
+    $this->SetRAJD( $ra );
+    
+    $dec = new Angle();
+    $dec->FromDegrees( $record['decjd'] );
+    $this->SetDECJD( $dec );
+    
+    $mjd = new MJD();
+    $mjd->FromString( $record['MJD'] );
+    $this->SetMJD( $mjd );
+    
+    $this->SetBW( $record['bw'] );
+    
+    $this->SetObsFreq( $record['obsfreq'] );
+    
+    $this->SetScanLen( $record['scanlen'] );
+    
+    $this->SetProjectID( $record['project_id'] );
+    
+    $this->file = new File();
+    $this->file->SetPath( $record['data_loc'] );
+    $this->file->SetFilename( $record['filename'] );
+    
+    $date = new Date();
+    $date->FromDMYString( $record['date'] );
+    $this->SetDate( $date );
+    
+    $this->SetUT( $record['ut'] );
+    
+    $this->SetDataType( $record['data_type'] );
+  }
+
+  public function GetFileID() { return $this->file_id; }
+  public function SetFileID( $s_file_id ) { $this->file_id = $s_file_id; }
+  
+  public function GetPulsarName() { return $this->pulsar_name; }
+  public function SetPulsarName( $s_pulsar_name ) { $this->pulsar_name = $s_pulsar_name; }
+  
+  public function GetDistance() { return $this->distance; }
+  public function SetDistance( $s_distance ) { $this->distance = $s_distance; }
+  
+  public function GetRAJD() { return $this->rajd; }
+  public function SetRAJD( $s_rajd ) { $this->rajd = $s_rajd; }
+  
+  public function GetDECJD() { return $this->decjd; }
+  public function SetDECJD( $s_decjd ) { $this->decjd = $s_decjd; }
+  
+  public function GetMJD() { return $this->mjd; }
+  public function SetMJD( $s_mjd ) { $this->mjd = $s_mjd; }
+  
+  public function GetProjectID() { return $this->project_id; }
+  public function SetProjectID( $s_project_id ) { $this->project_id = $s_project_id; }
+  
+  public function GetDataType() { return $this->data_type; }
+  public function SetDataType( $s_data_type ) { $this->data_type = $s_data_type; }
+  
+  public function GetFile() { return $this->file; }
+  public function SetFile( $s_file ) { $this->file = $s_file; }
+  
+  public function GetDate() { return $this->date; }
+  public function SetDate( $s_date ) { $this->date = $s_date; }
+  
+  public function GetUT() { return $this->ut; }
+  public function SetUT( $s_ut ) { $this->ut = $s_ut; }
+  
+  public function SetBW( $s_bw ) { $this->bw = $s_bw; }
+  public function GetBW() { return $this->bw; }
+  
+  public function SetObsFreq( $s_obs_freq ){ $this->obs_freq = $s_obs_freq; }
+  public function GetObsFreq() { return $this->obs_freq; }
+  
+  public function SetScanLen( $s_scan_len ) { $this->scan_len = $s_scan_len; }
+  public function GetScanLen() { return $this->scan_len; }
+  
+  public function SetCalibrations( $s_calibrations ) { $this->calibrations = $s_calibrations; }
+  public function GetCalibrations() { return $this->calibrations; }
+  
+  public function GetChildInterface() { return new CalInterface(); }
+  public function GetChildren() { return $this->GetCalibrations(); }
+  
+  // PRIVATE
+
+  private $file_id;
+  private $rajd;
+  private $decjd;
+  private $pulsar_name;
+  private $mjd;
+  private $project_id;
+  private $file;
+  private $data_type;
+  private $ut;
+  private $date;
+  private $bw;
+  private $obs_freq;
+  private $scan_len;
+  private $calibrations;
+
+  // STATIC
+
+  public static $valid_data_types = Array( 'DFB', 'WBC', 'CPSR2', 'FB_1BIT' );
+}
+
+
+
+?>
Index: /trunk/htdocs2/Classes/Pulsar/Archive.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/Archive.php	(revision 298)
+++ /trunk/htdocs2/Classes/Pulsar/Archive.php	(revision 298)
@@ -0,0 +1,22 @@
+<?php
+
+
+
+require_once 'Classes/General/File.php';
+
+
+/**
+ * @class Archive
+ * 
+ * This class represents a PSRFITS file on disc.
+ **/
+class Archive extends File
+{
+  public function __construct()
+  {
+    parent::__construct();
+  }
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Pulsar/ArchiveScruncher.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/ArchiveScruncher.php	(revision 298)
+++ /trunk/htdocs2/Classes/Pulsar/ArchiveScruncher.php	(revision 298)
@@ -0,0 +1,157 @@
+<?php
+
+
+
+require_once 'Classes/General/File.php';
+require_once 'Utils/strutils.php';
+require_once 'Classes/Pulsar/ScrunchingParameters.php';
+
+
+
+/**
+ * This class represents an archive scrunching algorithm, though
+ * the actual scrunching is performed by executing psrsh. You give
+ * this algorithm
+ * <ul>
+ *  <li> the archive filename </li>
+ *  <li> the directory to save the new scrunched file into </li>
+ *  <li> the scrunching parameters </li>
+ * </ul>
+ **/
+
+class ArchiveScruncher
+{
+  /// PUBLIC
+
+    public function __construct()
+    {
+      $this->src_file = new File();  // This is a File class representing the source archive
+      $this->dest_file = new File(); // This is a File class representing the destination archive
+      $this->parameters = null;
+    }
+
+    public function SetSrcFile( File $s_src_file ) { $this->src_file = $s_src_file; }
+    public function SetDestFile( File $s_dest_file ) { $this->dest_file = $s_dest_file; }
+    
+    public function SetParameters( $s_parameters ) { $this->parameters = $s_parameters; }
+    public function GetParameters() { return $this->parameters; }
+
+    /**
+     * This is the algorithms execute method, determine the destination filename from the
+     * source filename and scrunching parameters, create a script for psrsh to perform the
+     * scrunching and to output the file, then exec psrsh with that script.
+     **/
+
+    public function Execute()
+    {
+      // TODO throw an exception if not scrunching needs to be done
+      //       if( !$this->NeedsScrunching() )
+      //       {
+      //       }
+      
+//       $this->dest_file->SetFilename( $this->CreateScrunchedFilename( $this->src_file->GetFilename(name) ) );
+    
+      $script_file = $this->CreateScrunchingScript();
+    
+      $psrcmd = FIX_LD_LIB . PSRSH_CMD . " $script_file " . $this->src_file->GetFullPath();
+//       echo 'psrcmd is ' . $psrcmd . ' <br> ';
+    
+      $output_array = Array();
+      $retval = '';
+      $last_line = exec( $psrcmd, $output_array, $retval );
+    
+      // TODO throw an exception if we didn't produce an output file
+      if( !file_exists( $this->dest_file->GetFullPath() ) )
+      {
+	echo 'psrsh doesn\'t seem to have created the file we want <br>';
+	echo $this->dest_file->GetFullPath() . '<br>';
+	exit;
+      }
+    }
+    
+   /**
+    * Guess how much disk space the resulting scrunched file will take up
+    **/
+
+    public function GuessScrunchedFileSize()
+    {
+
+    }
+
+  /// PRIVATE
+
+    private $src_file;
+    private $dest_file;
+    private $parameters;
+
+
+    /**
+     * Return true if atleast one scrunching parameter is set, false otherwise.
+     **/
+
+    private function NeedsScrunching()
+    {
+      return ( $this->parameters->GetPScrunch() === false &&
+	  $this->parameters->GetTScrunch() == '' &&
+	  $this->parameters->GetFScrunch() == '' );
+    }
+
+    /**
+     * Create a temporary file and write into it the instructions for psrsh
+     * to perform to scrunch the file appropriately and write it out to the
+     * target directory.
+     **/
+
+    private function CreateScrunchingScript()
+    {
+      if( $this->parameters->GetFScrunch() != '' )
+	$psrscript .= "fscrunch_by $this->fscrunch \n";
+      if( $this->parameters->GetTScrunch() != '' )
+	$psrscript .= "tscrunch_by $this->tscrunch \n";
+      if( $this->parameters->GetPScrunch() !== false )
+	$psrscript .= "pscrunch \n";
+      $psrscript .= 'unload ' . $this->dest_file->GetFullPath() . "\n";
+
+      $script_filename = tempnam(TEMP_DIR, '');
+
+    // TODO remove this chmod command, its for debugging only
+	exec( 'chmod 666 ' . $script_filename );
+
+      $outfile = fopen( $script_filename, 'r+' );
+      // TODO throw an exception if we can't open the tempfile
+      // if( $outfile === false )
+      fwrite( $outfile, $psrscript );
+      fclose( $outfile );
+
+      return $script_filename;
+    }
+    
+    
+    /**
+     * Call vap to determine the parameters for an archive, nsub,nchan,nbin,npol
+     **/
+    
+    private function DetermineSubintParams( $filename, &$nsub, &$nchan, &$nbin, &$npol )
+    {
+      $cmd = FIX_LD_LIB . VAP_CMD . ' -c nbin,nchan,npol,nsub ' . $filename;
+      $all_lines = Array();
+      $retval = '';
+      
+      $last_line = exec( $cmd, $all_lines, $retval );
+      
+      $vap_response = eatwhite( $last_line );
+      $nbin = strword( $vap_response, 1 );
+      $nchan = strword( $vap_response, 2 );
+      $npol = strword( $vap_response, 3 );
+      $nsub = strword( $vap_response, 4 );
+      
+//       echo "$filename is (nsub,nchan,nbin,npol) ($nsub,$nchan,$nbin,$npol) <br>";
+    } 
+    
+
+
+
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Pulsar/CPSR2Combiner.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/CPSR2Combiner.php	(revision 298)
+++ /trunk/htdocs2/Classes/Pulsar/CPSR2Combiner.php	(revision 298)
@@ -0,0 +1,63 @@
+<?php
+
+
+
+require_once 'constants.php';
+require_once 'File.php';
+require_once 'Dir.php';
+
+
+/**
+ * This class represents an algorithm to take a cspr2 observation, which is a directory
+ * containing several archive files, and combining them into a single observation file.
+ * It calls psradd to perform the actual work of combining the files.
+ *
+ * Usage
+ *  $src_dir = new Dir( 'path to cpsr2 data directory' );
+ *  $dest_file = new File( 'target data dir', 'target filename' );
+ *  $combiner = new CPSR2Combiner();
+ *  $combiner->SetSrcDir( $src_dir );
+ *  $combiner->SetDestFile( $dest_file );
+ *  $combiner->Execute();
+ **/
+
+class CPSR2Combiner
+{
+  public __construct()
+  {
+    $this->src_dir = new Dir();
+    $this->dest_file = new File();
+  }
+
+  public SetSrcDir( $s_src_dir ) { $this->src_dir = $s_src_dir; }
+  public SetDestFile( $s_dest_file ) { $this->dest_file = $s_dest_file; }
+
+  public Execute()
+  {
+    // Get a list of all the .cfb files from the src directory
+    $src_files = $src_dir->ListFiles();
+    $src_files_str = ' ';
+    foreach( $src_files as $next_filename )
+      $src_files_str .= $src_dir->GetPath() . '/' . $next_filename;
+
+    $psradd_cmd = FIX_LD_LIB . PSRADD_CMD . ' -f ' . $dest_file->GetFullPath() . $src_files_str;
+    $retval = '';
+    $all_lines = Array();
+
+    echo 'execing command ' . $psradd_cmd . ' <br> ';
+    exec( $psradd_cmd, $all_lines, $retval );
+
+    // TODO throw an exception if the psradd call failed or if the file wasn't created
+    if( !$dest_file->Exists() )
+    {
+      echo 'failed to psradd files together <br>';
+      exit;
+    }
+  }
+
+  private $src_dir;
+  private $dest_file;
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Pulsar/ObservationData.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/ObservationData.php	(revision 298)
+++ /trunk/htdocs2/Classes/Pulsar/ObservationData.php	(revision 298)
@@ -0,0 +1,127 @@
+<?php
+
+
+
+require_once 'Classes/Pulsar/ScrunchingParameters.php';
+require_once 'Classes/Pulsar/CPSR2Combiner.php';
+
+
+
+/**
+ * @class ObservationData
+ * 
+ * This class represents the data from a single observation, on disk
+ * this is one or more archives. We use this interface to create a standard
+ * way of querying to see how large the file will be with or without
+ * scrunching.
+ **/
+class ObservationData
+{
+  // PUBLIC
+      
+  public function __construct()
+  {
+    $this->archives = Array();
+    $this->scrunching_parameters = null;
+    $this->path = null;
+  }
+  
+  public function SetScrunchingParameters( $s_scr_prameters ) { $this->scrunching_parameters = $_scr_parameters; }
+  public function GetScrunchingParameters() { return $this->scrunching_parameters; }
+  
+  public function SetPath( $s_path ) { $this->path = $s_path; $this->ExamineObservation(); }
+  public function GetPath() { return $this->path; }
+  
+  //! Make an estimate of the size the downloadable file will be
+  public function EstimateDownloadableSize()
+  {
+    /*
+     * if we have a single file
+     *   return the size of that file
+     * otherwise
+     *   estimate what the file size will be after psradding them together
+     **/
+    $file_size = 0;
+    
+    if( count( $this->archives ) == 1 )
+    {
+      $file_size = $this->archives[0]->GetFileSize();
+    }
+    else
+    {
+      foreach( $this->archives as $next_archive )
+      {
+        $next_size = $next_archive->GetFileSize();
+        // TODO guess the data size from the archive parameters npol,nbin,nchan,nsub
+        $file_size += $next_size;
+      }
+    }
+    
+    return $file_size;
+  }
+
+  public function MakeDownloadableFile( $target_file )
+  {
+   /*
+    * if we have multiple files
+    *   psradd the files into one
+    *
+    * if we are scrunching
+    *   create the scrunched file in the data dir
+    * otherwise
+    *   create a link to the file
+    *
+    * return a file object pointing to the created file
+    */
+   
+   if( $this->path->IsDir() )
+   {
+     $combiner = new CPSR2Combiner();
+     $combiner->SetSrcDir( $this->path );
+     $combiner->SetDestFile( $target_file );
+     $combiner->Execute();
+   }
+   else
+   {
+     $pre_scr_file->SetPath( $this->archives[0]->GetPath() );
+     $pre_scr_file->SetFilename( $this->archives[0]->GetFilename() );
+   }
+  }
+  
+  // PRIVATE
+  
+  private $archives;
+  private $scrunching_parameters;
+  private $path;
+  
+  private function ExamineObservation()
+  {
+    /*
+     * if the path is pointing to a directory
+     *   for each file in the directory
+     *     create a new archive object for that file
+     * otherwise
+     *   create a new archive object and point it at that file
+     */
+    if( $this->path == null )
+        throw new GZ_Exception( 'No path set', 'ObservationData::ExamineObservation' );
+    
+    if( $this->path->IsDir() )
+    {
+      $dir_path = $this->path->GetFullPath();
+      $dir = new Dir( $dir_path );
+      foreach( $dir->ListFiles() as $next_filename )
+      {
+        $new_archive = new Archive( $dir_path, $next_filename);
+        $this->archives[] = $new_archive;
+      }
+    }
+    else
+    {
+      $new_archive = new Archive( $this->path );
+      $this->archives[] = $new_archive;
+    }
+  }
+};
+
+?>
Index: /trunk/htdocs2/Classes/Pulsar/PulsarCatalog.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/PulsarCatalog.php	(revision 298)
+++ /trunk/htdocs2/Classes/Pulsar/PulsarCatalog.php	(revision 298)
@@ -0,0 +1,52 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/StringUtils.php';
+require_once 'Classes/Astro/SkyCoord.php';
+
+
+
+class PulsarCatalog
+{
+  // PUBLIC
+      
+  public function __construct()
+  {
+    
+  }
+  
+  //! Return a SkyCoord for the pulsar given
+  public function GetCoordsForPulsar( $src_name )
+  {
+    $psrcat_cmd = '/pulsar/psr/linux/bin/psrcat -nohead -nonumber -o short -c "RAJD DECJD" ' . $src_name;
+
+    $all_lines = Array();
+    $ret_val = '';
+    $last_line = exec( $psrcat_cmd, $all_lines, $ret_val );
+    
+    // TODO throw exceptions if exec failed
+
+    $last_line = trim( $last_line );
+    
+    $ra_degrees = strword( $last_line, 0 );
+    $last_line = AdvanceStringTo( $last_line, $ra_degrees );
+    $dec_degrees = trim( $last_line );
+    
+    $ra_angle = new Angle();
+    $ra_angle->FromDegrees( $ra_degrees );
+    $dec_angle = new Angle();
+    $dec_angle->FromDegrees( $dec_degrees );
+  
+    $coords = new SkyCoord();
+    $coords->SetRA( $ra_angle );
+    $coords->SetDEC( $dec_angle );
+    
+    return $coords;
+  }
+  
+  // PRIVATE
+      
+};
+
+?>
Index: /trunk/htdocs2/Classes/Pulsar/ScrunchingParameters.php
===================================================================
--- /trunk/htdocs2/Classes/Pulsar/ScrunchingParameters.php	(revision 298)
+++ /trunk/htdocs2/Classes/Pulsar/ScrunchingParameters.php	(revision 298)
@@ -0,0 +1,45 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/GZ_Exception.php';
+
+
+
+class ScrunchingParameters
+{
+  // PUBLIC
+      
+  public function __construct()
+  {
+    $this->pscrunch = null;          // polarization scrunching is either on or off
+    $this->tscrunch = null;          // this is the number of subints to scrunch together
+    $this->fscrunch = null;          // this is the number of channels to scrunch together
+  }
+  
+  public function PScrunch() { $this->pscrunch = true; }
+  public function TScrunch( $value ) { $this->tscrunch = $value; }
+  public function FScrunch( $value ) { $this->fscrunch = $value; }
+  
+  public function GetPScrunch() { return $this->CheckParameter('pscrunch'); }
+  public function GetTScrunch() { return $this->CheckParameter('tscrunch'); }
+  public function GetFScrunch() { return $this->CheckParameter('fscrunch'); }
+  
+  // PRIVATE
+      
+  private $pscrunch;
+  private $tscrunch;
+  private $fscrunch;
+  
+  //! Retrieve a parameter, throw an exception if it hasn't been set yet.
+  private function CheckParameter( $param )
+  {
+    eval( '$value = $this->' . $param . ';' );
+    if( $value == null )
+      throw new GZ_Exception( 'Failed Parameter Check',
+                              'ScrunchingParameters::CheckParameter' );
+    return $param;
+  }
+};
+
+?>
Index: /trunk/htdocs2/Classes/Queries/CalQuery.php
===================================================================
--- /trunk/htdocs2/Classes/Queries/CalQuery.php	(revision 298)
+++ /trunk/htdocs2/Classes/Queries/CalQuery.php	(revision 298)
@@ -0,0 +1,69 @@
+<?php
+
+
+
+require_once 'Classes/Astro/MJD.php';
+
+
+
+/**
+ * This class represents the algorithm for performing a calibration query
+ * Usage:
+ * $searcher = new CalQuery();
+ * $searcher->SetStartTime( $start_mjd );
+ * $searcher->SetEndTiem( $end_mjd );
+ * $searcher->Execute();
+ * $calibrations = $searcher->GetCalibrations();
+ **/
+
+class CalQuery
+{
+  // PUBLIC
+  
+  public function __construct()
+  {
+    $this->start_mjd = new MJD();
+    $this->end_mjd = new MJD();
+    $this->results = Array();
+  }
+  
+  public function SetStartTime( MJD $s_start_time ) { $this->start_time = $s_start_time; }
+  public function SetEndTime( MJD $s_end_time ) { $this->end_time = $s_end_time; }
+  
+  public function Execute( MysqlDB $db )
+  {
+    $select_sql = ' SELECT * FROM cals WHERE MJD < ' . $this->end_time->ToString();
+    $select_sql .= ' AND MJD > ' . $this->start_time->ToString();
+    
+                  //echo 'executing cal query ' . $select_sql . ' <br> ';
+                  
+    $db->DoQuery( $select_sql );
+    
+    if( $db->FetchNumRows() > 0 )
+      $this->ExtractResults( $db->GetLastResult() );
+  }
+  
+  public function GetCalibrations() { return $this->results; }
+  
+  // PRIVATE
+  
+  private $start_mjd;
+  private $end_mjd;
+  private $results;
+  
+  private function ExtractResults( $array_data )
+  {
+    foreach( $array_data as $next_record )
+    {
+      $new_calibration = new Calibration();
+      $new_calibration->FromRecord( $next_record );
+      $this->results[] = $new_calibration;
+    }
+  }
+};
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/Queries/ConeQuery.php
===================================================================
--- /trunk/htdocs2/Classes/Queries/ConeQuery.php	(revision 298)
+++ /trunk/htdocs2/Classes/Queries/ConeQuery.php	(revision 298)
@@ -0,0 +1,129 @@
+<?php
+
+
+
+require_once 'Classes/Astro/MJD.php';
+
+
+class ConeQuery
+{
+  // PUBLIC
+      
+  public function __construct()
+  {
+    $this->parameters = '';
+    $this->sql = '';
+    $this->cone_string = '';
+    $this->results = null;
+  }
+  
+  public function SetParameters( $s_parameters ) { $this->parameters = $s_parameters; }
+
+  public function Execute( $db )
+  {
+//     echo 'performing cone query';
+    if( $this->parameters == '' )
+      throw Exception( 'attempted to perform query without parameters' );
+    
+    $this->results = Array();
+    
+    $this->BuildQueryString('observations');
+    $db->DoQuery( $this->sql );
+    $this->ExtractResultSet( $db->GetLastResult() );
+  }
+  
+  public function GetResults(){  return $this->results; }
+  
+  // PRIVATE
+      
+  private $parameters;
+  private $results;
+  private $sql;
+  private $cone_string;
+  
+    //! Convert the result set array to an array of observations
+  private function ExtractResultSet( $result_set )
+  {
+    foreach( $result_set as $next_row )
+    {
+      $new_obs = new Observation();
+      $new_obs->FromRecord( $next_row );
+      $this->results[] = $new_obs;
+    }
+  }
+  
+  private function BuildConeString()
+  {
+    $psr_rajd = $this->parameters->GetCoordinates()->GetRA()->ToDegrees();
+    $psr_decjd = $this->parameters->GetCoordinates()->GetDEC()->ToDegrees();
+    
+    $this->cone_string = "degrees( acos(cos(radians(rajd-$psr_rajd)) *
+					cos(radians(decjd)) *
+					cos(radians($psr_decjd)) +
+					sin(radians(decjd)) *
+					sin(radians($psr_decjd))
+                                        )
+                                 )";
+  }
+  
+  private function BuildSelectString()
+  {
+    $this->sql .= ' SELECT *,' . $this->cone_string . ' AS distance ';
+  }
+  
+  private function BuildFromString()
+  {
+    $this->sql .= ' FROM  observations ';
+  }
+  
+  private function BuildWhereString()
+  {
+    $this->sql .= ' WHERE 1=1 ';
+
+    $radius = $this->parameters->GetSearchRadius();
+    
+    if( $radius == '' )
+      $radius = 1;
+    
+    $this->sql .= " AND ( (($this->cone_string - 0.25*(bmaj+bmin)) < ($radius/60.)) ) ";
+    
+    $project_id = $this->parameters->GetProjectID();
+    if( $project_id != '')
+      $this->sql .= " AND project_id = '$project_id' ";
+    
+    $date_range = $this->parameters->GetDateRange();
+    $from_mjd = new MJD();
+    $from_mjd->FromDate( $date_range->GetFromDate() );
+    $to_mjd = new MJD();
+    $to_mjd->FromDate( $date_range->GetToDate() );
+    $this->sql .= ' AND MJD >= ' . $from_mjd->ToString();
+    $this->sql .= ' AND MJD <= ' . $to_mjd->ToString();
+  }
+  
+  private function BuildLimitString()
+  {
+//     $this->sql .= ' LIMIT 1 ';
+  }
+  
+  private function BuildOrderString()
+  {
+    $this->sql .= ' ORDER BY file_id DESC ';
+  }
+  
+  private function BuildQueryString()
+  {
+    $this->BuildConeString();
+    $this->BuildSelectString();
+    $this->BuildFromString();
+    $this->BuildWhereString();
+    $this->BuildOrderString();
+    $this->BuildLimitString();
+    
+//     echo 'the query built was ' . $this->sql .' <br> ';
+  }
+};
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/Queries/ConeQueryParameters.php
===================================================================
--- /trunk/htdocs2/Classes/Queries/ConeQueryParameters.php	(revision 298)
+++ /trunk/htdocs2/Classes/Queries/ConeQueryParameters.php	(revision 298)
@@ -0,0 +1,103 @@
+<?php
+
+
+
+require_once 'Classes/General/DateRange.php';
+require_once 'Classes/Astro/SkyCoord.php';
+
+
+
+/**
+ * This class represents the parameters used in a cone query search.
+ **/
+
+class ConeQueryParameters
+{
+  // PUBLIC
+
+  public function __construct()
+  {
+    $this->date_range = new DateRange();
+//     $this->pulsar_name = '';
+    $this->project_id = '';
+    $this->coordinates = new SkyCoord();
+    $this->search_radius = 30;
+    $this->obs_mode = '';
+    $this->data_type = '';
+    $this->bandnames = Array();
+    $this->cals_timeframe = 0;
+
+    if( !ConeQueryParameters::$static_setup )
+      $this->SetupStaticData();
+  }
+
+  public function SetDateRange( $s_date_range ) { $this->date_range = $s_date_range; }
+  public function GetDateRange() { return $this->date_range; }
+
+//   public function SetPulsarName( $s_pulsar_name ) { $this->pulsar_name = $s_pulsar_name; }
+//   public function GetPulsarName() { return $this->pulsar_name; }
+
+  public function SetProjectID( $s_project_id ) { $this->project_id = $s_project_id; }
+  public function GetProjectID() { return $this->project_id; }
+
+  public function SetCoordinates( $s_coordinates ) { $this->coordinates = $s_coordinates; }
+  public function GetCoordinates() { return $this->coordinates; }
+
+  public function SetSearchRadius( $s_search_radius ) { $this->search_radius = $s_search_radius; }
+  public function GetSearchRadius() { return $this->search_radius; }
+
+  public function SetObsMode( $s_obs_mode ) { $this->obs_mode = $s_obs_mode; }
+  public function GetObsMode() { return $this->obs_mode; }
+
+  public function SetDataType( $s_data_type ) { $this->data_type = $s_data_type; }
+  public function GetDataType() { return $this->data_type; }
+
+  public function SetCalsTimeframe( $s_cals_timeframe ) { $this->cals_timeframe = $s_cals_timeframe; }
+  public function GetCalsTimeframe() { return $this->cals_timeframe; }
+
+  public function SetBands( $s_bands ) 
+  {
+    if( is_array( $s_bands ) )
+    {
+      $this->bands = $s_bands;
+    }
+  }
+  public function GetBands() { return $this->bands; }
+  public function AddBand( $s_band ) { $this->bands[] = $s_band; }
+  
+  public function AreValid()
+  {
+    return true;
+  }
+
+  // PRIVATE
+
+  private $date_range;
+//   private $pulsar_name;
+  private $project_id;
+  private $coordinates;
+  private $search_radius;
+  private $obs_mode;
+  private $data_type;
+  private $bands;
+  private $order_column;
+  private $order_direction;
+  private $cals_timeframe;
+
+  // STATIC
+
+  private function SetupStaticData()
+  {
+    // TODO query the database for a list of valid data types
+    ConeQueryParameters::$static_setup = true;
+  }
+
+  static public $static_setup = false;
+  static public $valid_obs_modes = Array( 'Any', 'Only Timing', 'Only Search Data' );
+
+};
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/Queries/DateRangeQuery.php
===================================================================
--- /trunk/htdocs2/Classes/Queries/DateRangeQuery.php	(revision 298)
+++ /trunk/htdocs2/Classes/Queries/DateRangeQuery.php	(revision 298)
@@ -0,0 +1,49 @@
+<?php
+
+
+
+
+require_once 'Classes/Astro/MJD.php';
+
+
+
+class DateRangeQuery
+{
+  public function __construct()
+  {
+    $this->date_range = new DateRange();
+  }
+
+  public function Execute( $db )
+  {
+    $select_sql = ' SELECT min(MJD) as min, max(MJD) as max ' .
+	          ' FROM observations ';
+    
+    $db->DoQuery( $select_sql );
+    
+    $db->EnsureNumRows( 'equals', 1 );
+    
+    $row = $db->GetLastResult();
+    $min_mjd = new MJD( $row[0]['min'] );
+    $max_mjd = new MJD( $row[0]['max'] );
+    
+    $range = new DateRange();
+    $range->SetFromDate( $min_mjd->ToDate() );
+    $range->SetToDate( $max_mjd->ToDate() );
+    
+    return $range;
+  }
+
+  public function GetDateRange()
+  {
+    return $date_range;
+  }
+
+  private $date_range;
+};
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Classes/Tests/TestAngle.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestAngle.php	(revision 298)
+++ /trunk/htdocs2/Classes/Tests/TestAngle.php	(revision 298)
@@ -0,0 +1,97 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/Astro/Angle.php';
+
+
+
+class TestAngle extends BaseTest
+{
+  public function TestIt()
+  {
+    $a0 = new Angle();
+    $a0->FromRadians( M_PI/2.0 );
+    $a1 = new Angle( $a0 );
+    
+    $this->PerformTest( 'Testing constructor with value',
+			( $a1->ToRadians() == (M_PI/2.0) ),
+			'Failed to construct with given value' );
+    
+    $a1->FromRadians( pi() );
+    $this->PerformTest( 'Testing basic getter/setter methods ',
+			( $a1->ToRadians() == M_PI ),
+			'Failed to retrieve radians as set' );
+    
+    $this->PerformTest( 'Testing retreiving as degrees',
+			( $a1->ToDegrees() == 180.0 ),
+			'Failed to retreive as degrees' );
+    
+    $this->PerformTest( 'Testing retreiving as hms string',
+			( $a1->ToHMSString() == '12:00:00' ),
+			'Failed to retreive as hms string' . $a1->ToHMSString() );
+    
+    $this->TestDegToHMS( 171.1, 11, 24, 24 );
+    $this->TestDegToHMS( 170, 11, 20, 0 );
+    $this->TestDegToHMS( 180, 12, 0, 0 );
+    $this->TestDegToHMS( 180.01, 12, 0, 2.4 );
+    $this->TestDegToHMS( 179.99, 11, 59, 57.6 );
+    
+    $this->TestDegToDMS( 179.99, 179, 59, 24.0 );
+    
+    $this->TestFromDMSString( 179.99, '179:59:24' );
+    $this->TestFromDMSString( 180.00, '180:00:00' );
+    $this->TestFromDMSString( 30.0, '29:59:59' );
+  }
+  
+  private function TestDegToHMS( $degrees, $hours_expected, $mins_expected, $secs_expected )
+  {
+    $a1 = new Angle();
+    
+    $a1->FromDegrees( $degrees );
+    
+    $hours = 1;
+    $mins = 2;
+    $secs = 3.0;
+    
+    $hms_string = $a1->ToHMS( $hours, $mins, $secs );
+    $secs = round( $secs, 3 );
+    $this->PerformTest( 'Testing Degrees To HMS conversion ' . $degrees,
+			( $hours == $hours_expected && $mins == $mins_expected && $secs == $secs_expected ),
+			'Failed to retreive hms by values ' . "$hours:$mins:$secs " .
+			' should be ' . "$hours_expected:$mins_expected:$secs_expected" );
+  }
+  
+  private function TestDegToDMS( $degrees, $degrees_expected, $mins_expected, $secs_expected )
+  {
+    $a1 = new Angle();
+    
+    $a1->FromDegrees( $degrees );
+    
+    $degrees_returned = 1;
+    $mins = 2;
+    $secs = 3.0;
+    
+    $hms_string = $a1->ToDMS( $degrees_returned, $mins, $secs );
+    $secs = round( $secs, 3 );
+    $this->PerformTest( 'Testing Degrees To DMS conversion ' . $degrees,
+			( $degrees_returned == $degrees_expected && $mins == $mins_expected && $secs == $secs_expected ),
+			'Failed to retreive hms by values ' . "$degrees_returned:$mins:$secs " .
+			    ' should be ' . "$degrees_expected:$mins_expected:$secs_expected" );
+  }
+  
+  private function TestFromDMSString( $degrees_expected, $dms_string )
+  {
+    $angle = new Angle();
+    
+    $angle->FromDMSString( $dms_string );
+    $degrees_returned = round( $angle->ToDegrees(), 2 );
+    $this->PerformTest( 'Testing From DMS ',
+			( $degrees_returned == $degrees_expected ),
+			" Failed to retreive degress from a dms got $degrees_returned expected $degrees_expected" );
+  }
+};
+
+?>
Index: /trunk/htdocs2/Classes/Tests/TestDate.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestDate.php	(revision 298)
+++ /trunk/htdocs2/Classes/Tests/TestDate.php	(revision 298)
@@ -0,0 +1,48 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/General/Date.php';
+
+
+
+class TestDate extends BaseTest
+{
+  function TestIt()
+  {
+    $day = '1';
+    $month = '2';
+    $year = '2008';
+  
+    $d1 = new Date();
+    $d1->SetDayOfMonth( $day );
+  
+    $this->PerformTest( 'Testing day getter/setter',
+		( $day == $d1->GetDayOfMonth() ),
+		'Failed to retrieve the day we set' );
+  
+    $d1->SetMonthOfYear( $month );
+    $this->PerformTest( 'Testing month getter/setter',
+		( $month == $d1->GetMonthOfYear() ),
+		'Failed to retrieve the month we set' );
+  
+    $d1->SetYear( $year );
+    $this->PerformTest( 'Testing year getter/setter',
+		( $year == $d1->GetYear() ),
+		'Failed to retrieve the year we set' );
+  
+    $d1->FromDMYString( '12/12/1212' );
+    $this->PerformTest( 'Testing DMY getter/setter',
+		( $d1->ToDMYString() == '12/12/1212' ),
+		'The date set and retrieved do not match' . $d1->ToDMYString() );
+    
+    $this->PerformTest( 'Testing DMY getter 2 (month is string)',
+                        ( $d1->ToDMYString2() == '12/Dec/1212' ),
+                          'Failed to retrieve date with text month ' . $d1->ToDMYString2() );
+  }
+}
+
+
+?>
Index: /trunk/htdocs2/Classes/Tests/TestDateRange.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestDateRange.php	(revision 298)
+++ /trunk/htdocs2/Classes/Tests/TestDateRange.php	(revision 298)
@@ -0,0 +1,37 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/General/DateRange.php';
+
+
+class TestDateRange extends BaseTest
+{
+  public function TestIt()
+  {
+  // test the from date setter/getter
+  // test the to date setter/getter
+
+  $from_date = new Date();
+  $from_date->FromDMYString( '12/12/1212' );
+
+  $date_range = new DateRange();
+  $date_range->SetFromdate( $from_date );
+  $this->PerformTest( 'Testing from date getter/setter',
+	       ( $date_range->GetFromDate()->ToDMYString() == '12/12/1212' ),
+	       'From date retrieved does not match from date set' );
+
+  $to_date = new Date();
+  $to_date->FromDMYString( '11/11/1111' );
+
+  $date_range->SetToDate( $to_date );
+  $this->PerformTest( 'Testing to date getter/seetter',
+	       ( $date_range->GetToDate()->ToDMYString() == '11/11/1111' ),
+	       'To date retrieved does not match to date set' );
+  }
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Tests/TestDir.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestDir.php	(revision 298)
+++ /trunk/htdocs2/Classes/Tests/TestDir.php	(revision 298)
@@ -0,0 +1,79 @@
+<?php
+
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/General/Dir.php';
+require_once 'Classes/General/File.php';
+
+
+
+class TestDir extends BaseTest
+{
+  public function TestIt()
+  {
+    // get a temporary filename
+    // test that there is no dir with that name
+    // create a directory using that tmpfile name
+    // test that the new directory exists as a directory
+    // create a test file in the directory
+    // test that the test file was created correctly
+    // get the list of files in the directory
+    // test that the list simply contains the test file
+    // delete the test file
+    // remove the directory
+    // test that the directory no longer exists
+  
+    $tmp_file = new File();
+    $tmp_file->SetFullPath( tempnam('','') );
+    $tmp_file->Remove();
+    
+    $dir = new Dir();
+    $dir->SetPath( $tmp_file->GetFullPath() );
+    
+    $this->PerformTest( 'Testing temp file doesnt exist',
+		( !$tmp_file->Exists() ),
+		'The file created by tempnam still exists' );
+    
+    $this->PerformTest( 'Testing temp dir does not exist',
+		( !$dir->IsDir() ),
+		'The test directory exists for some reason ' . $dir->GetPath() );
+    
+    $dir->Create();
+    
+    $this->PerformTest( 'Test that we created the directory successfully',
+		( $dir->IsDir() ),
+		'Failed to create the directory ' . $dir->GetPath() );
+    
+    $test_file = new File( $dir->GetPath(), 'testing' );
+    $test_file->Create();
+    $this->PerformTest( 'Testing we can create a file in the new directory',
+		( $test_file->Exists() ),
+		'Failed to create file called testing in directory' . $dir->GetPath() );
+    
+    $all_files = $dir->ListFiles();
+    $this->PerformTest( 'Testing we have the correct number of files from the directory',
+		( count($all_files) == 3 ),
+		'Wrong number of files listed in directory ' . count($all_files) );
+    
+    $this->PerformTest( 'Testing the file we want is listed correctly',
+		( $all_files[1] == 'testing' ),
+		'The file "testing" is not there' );
+    
+    $test_file->Remove();
+    $this->PerformTest( 'testing we removed the test file successfully',
+		( !$test_file->Exists() ),
+		'Failed to remove the test file from out test directory' );
+    
+    $dir->Remove();
+    
+    $this->PerformTest( 'Test that we can remove the directoroy',
+		( !$dir->IsDir() ),
+		'Failed to remove the directory ' . $dir->GetPath() );
+  }
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Tests/TestFile.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestFile.php	(revision 298)
+++ /trunk/htdocs2/Classes/Tests/TestFile.php	(revision 298)
@@ -0,0 +1,71 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/General/File.php';
+
+
+
+class TestFile extends BaseTest
+{
+  public function TestIt()
+  {
+    $tmp_name = tempnam( '', 'FileTest');
+    $tmp_dir = substr( $tmp_name, 0, strrpos( $tmp_name, '/' ) );
+    $tmp_file = substr( $tmp_name, strrpos( $tmp_name, '/' ) + 1 );
+
+    $f1 = new File();
+
+    $f1->SetPath( $tmp_dir );
+    $this->PerformTest( 'Testing path Getter/Setters',
+		 ($f1->GetPath() == $tmp_dir),
+		 'Path retreived does not match path entered' );
+
+    $f1->SetFilename( $tmp_file );
+    $this->PerformTest( 'Testing filename Getter/Setter',
+		 ($f1->GetFilename() == $tmp_file ),
+		 'Filename retreived does not match filenamed entered' );
+
+    $this->PerformTest( 'Testing GetFullPath function',
+		 ($f1->GetFullPath() == $tmp_name),
+		 'Full path returned does not match the path and filename set' );
+  
+    $f1->SetFullPath( $tmp_name );
+    $this->PerformTest( 'Testing SetFullPath breaks up correctly',
+		 ($f1->GetPath() == $tmp_dir),
+		 'The path was not extracted from the full path correctly' );
+
+    $this->PerformTest( 'Testing SetFullPath separates filename correctly',
+		 ($f1->GetFilename() == $tmp_file),
+		 'The filename was not extracted from the full path correctly' );
+  
+    $this->PerformTest( 'Testing tempnam created the file',
+		 ($f1->Exists()),
+		 'The file specified doesnt exist' . $f1->GetFullPath() );
+
+    $this->PerformTest( 'Testing directory test',
+		 (!$f1->IsDir()),
+		 'The file specified is a directory ???' );
+
+    $this->PerformTest( 'Testing link test',
+		 (!$f1->IsLink()),
+		 'The file specified is a link ???' );
+
+    $f1->Remove();
+
+    $this->PerformTest( 'Testing file deletion',
+		 ( !$f1->Exists() ),
+		 'The file still exists' . $f1->GetFullPath() );
+
+    $f1->Create();
+
+    $this->PerformTest( 'Testing file creation',
+		 ( $f1->Exists() ),
+		 'The file wasnt created' . $f1->GetFullPath() );
+  }
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Tests/TestMJD.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestMJD.php	(revision 298)
+++ /trunk/htdocs2/Classes/Tests/TestMJD.php	(revision 298)
@@ -0,0 +1,30 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/Astro/MJD.php';
+
+
+
+class TestMJD extends BaseTest
+{
+  public function TestIt()
+  {
+    $target_date = new Date();
+    $target_date->FromYMDString( '2008-01-01' );
+    echo $target_date->ToDMYString() . ' <br> ';
+    $target_mjd = new MJD();
+    $target_mjd->FromDate( $target_date );
+    echo $target_mjd->ToString() , ' <br> ';
+    $new_value = $target_mjd->ToString() - 365;
+    $adjusted_mjd = new MJD();
+    $adjusted_mjd->FromString( $new_value );
+    $adjusted_date = $adjusted_mjd->ToDate();
+    echo $adjusted_date->ToDMYString() . ' <br> ';
+  }
+};
+
+
+?>
Index: /trunk/htdocs2/Classes/Tests/TestSkyCoord.php
===================================================================
--- /trunk/htdocs2/Classes/Tests/TestSkyCoord.php	(revision 298)
+++ /trunk/htdocs2/Classes/Tests/TestSkyCoord.php	(revision 298)
@@ -0,0 +1,27 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Tests/BaseTest.php';
+require_once 'Classes/Astro/SkyCoord.php';
+
+
+
+class TestSkyCoord extends BaseTest
+{
+  public function TestIt()
+  {
+    $coord_string = '01:02:30 04:05:06.000';
+
+    $c1 = new SkyCoord();
+    $c1->FromHMSDMSString( $coord_string );
+
+    $this->PerformTest( 'Testing SkyCoord SetHMSDMS/GetHMSDMS ',
+		 ( $coord_string == $c1->ToHMSDMSString() ),
+		 'Result read from GetHMSDMS does not match string given in SetHMSDMS ' .
+                      $c1->ToHMSDMSString() );
+  }
+}
+
+?>
Index: /trunk/htdocs2/Forms/ATNFFooterView.php
===================================================================
--- /trunk/htdocs2/Forms/ATNFFooterView.php	(revision 298)
+++ /trunk/htdocs2/Forms/ATNFFooterView.php	(revision 298)
@@ -0,0 +1,22 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+
+
+
+class ATNFFooterView extends GZ_BaseForm
+{
+  function Display()
+  {
+    $smarty = $this->gz->CreateSmarty();
+    $smarty->display( 'footer.tpl' );
+  }
+  
+  function ProcessActions()
+  {
+  }
+};
+
+?>
Index: /trunk/htdocs2/Forms/ATNFHeaderView.php
===================================================================
--- /trunk/htdocs2/Forms/ATNFHeaderView.php	(revision 298)
+++ /trunk/htdocs2/Forms/ATNFHeaderView.php	(revision 298)
@@ -0,0 +1,22 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+
+
+
+class ATNFHeaderView extends GZ_BaseForm
+{
+  function Display()
+  {
+    $smarty = $this->gz->CreateSmarty();
+    $smarty->display( 'header.tpl' );
+  }
+
+  function ProcessActions()
+  {
+  }
+};
+
+?>
Index: /trunk/htdocs2/Forms/ArchivePage.php
===================================================================
--- /trunk/htdocs2/Forms/ArchivePage.php	(revision 298)
+++ /trunk/htdocs2/Forms/ArchivePage.php	(revision 298)
@@ -0,0 +1,158 @@
+<?php
+/**
+ * Written by David Smith
+ * nopeer@gmail.com
+ *
+ * For ATNF CSIRO
+ *
+ * This is the entry point for the web site. It will switch between several forms
+ * - LoginForm
+ * - QueryForm
+ * - QueryResultsForm
+ * - CartForm
+ * Based on feedback from page processing.
+ **/
+
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+require_once 'Forms/LoginForm.php';
+require_once 'Forms/QueryForm.php';
+require_once 'Forms/QueryResultsForm.php';
+require_once 'Forms/CartForm.php';
+require_once 'Forms/ATNFHeaderView.php';
+require_once 'Forms/ATNFFooterView.php';
+require_once 'Forms/ArchivePageHeader.php';
+require_once 'Forms/ArchivePageFooter.php';
+
+
+
+
+class ArchivePage extends GZ_BaseForm
+{
+  // PUBLIC
+  
+  function __construct( $set_gz )
+  {
+    global $_SESSION;
+    
+    parent::__construct( $set_gz );
+
+    try
+    {
+      $this->login_form = new LoginForm( $set_gz );
+      
+      if( isset( $_SESSION['active_form'] ) && $_SESSION['active_form'] != '' )
+        $this->CreateForm( $_SESSION['active_form'] );
+      else
+        $this->active_form = $this->login_form;
+      
+      $this->processing_error = null;
+    }
+    catch( GZ_Exception $e )
+    {
+      $this->processing_error = $e;
+    }
+  }
+
+  function Display()
+  {
+    // Output the HTML header
+    $html_header = new ArchivePageHeader( $this->gz );
+    $html_header->Display();
+    
+    if( $this->processing_error == null )
+    {
+      try
+      {
+        // Draw the header with the links to other ATNF resources
+        $header = new ATNFHeaderView( $this->gz );
+        $header->Display();
+    
+        $this->active_form->Display();
+        
+        // Draw the footer with links to other ATNF resources
+        $footer = new ATNFFooterView( $this->gz );
+        $footer->Display();
+      }
+      catch( GZ_Exception $e )
+      {
+        $this->processing_error = $e;
+      }
+    }
+    
+    if( $this->processing_error != null )
+    {
+      echo '<br><br>';
+      echo 'Caught the following exception <br>';
+      echo 'Message: ' .$this->processing_error->getMessage() . '<br>';
+      echo 'Method: ' . $this->processing_error->getMethod() . '<br>';
+      echo 'Code: ' . $this->processing_error->getCode() . ' <br>';
+      $this->gz->LogMessage( 'me', $this->processing_error->getMessage(),
+                         $this->processing_error->getMethod(),
+                         $this->processing_error->getCode(),
+                         '' ); 
+    }
+
+    
+    $html_footer = new ArchivePageFooter( $this->gz );
+    $html_footer->Display();
+  }
+  
+  private function CreateForm( $form_name )
+  {
+    global $_SESSION;
+    
+    // TODO add code to check we are asking for a valid form class.
+    if( $form_name == '' )
+	$this->active_form = $this->login_form;
+    else
+    {
+      eval( '$this->active_form = new ' . $form_name . '( $this->gz );' );
+      $_SESSION['active_form'] = $form_name;
+    }
+  }
+  
+  public function ReadForm()
+  {
+    $this->login_form->ReadForm();
+    $this->active_form->ReadForm();
+  }
+
+  function ProcessActions()
+  {
+    try
+    {
+      $this->login_form->ProcessActions();
+  
+      if( $this->login_form->LoggedIn() )
+      {
+        $proc_result = 'working';
+        while( $proc_result != '' )
+        {
+          $proc_result = $this->active_form->ProcessActions();
+          if( $proc_result != '' )
+            $this->CreateForm( $proc_result );
+        }
+      }
+      else
+      {
+        $this->active_form = $this->login_form;
+      }
+    }
+    catch( GZ_Exception $e )
+    {
+      $this->processing_error = $e;
+    }
+  }
+
+  // PRIVATE
+      
+  private $processing_error;
+  private $login_form;
+  private $active_form;
+
+};
+
+?>
Index: /trunk/htdocs2/Forms/ArchivePageFooter.php
===================================================================
--- /trunk/htdocs2/Forms/ArchivePageFooter.php	(revision 298)
+++ /trunk/htdocs2/Forms/ArchivePageFooter.php	(revision 298)
@@ -0,0 +1,20 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+
+
+
+class ArchivePageFooter extends GZ_BaseForm
+{
+  function Display()
+  {
+    $smarty = $this->gz->CreateSmarty();
+    $smarty->display( 'ArchivePageFooter.tpl' ); 
+  }
+};
+
+
+
+?>
Index: /trunk/htdocs2/Forms/ArchivePageHeader.php
===================================================================
--- /trunk/htdocs2/Forms/ArchivePageHeader.php	(revision 298)
+++ /trunk/htdocs2/Forms/ArchivePageHeader.php	(revision 298)
@@ -0,0 +1,20 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+
+
+
+class ArchivePageHeader extends GZ_BaseForm
+{
+  function Display()
+  {
+    $smarty = $this->gz->CreateSmarty();
+    $smarty->display( 'ArchivePageHeader.tpl' ); 
+  }
+};
+
+
+
+?>
Index: /trunk/htdocs2/Forms/CartForm.php
===================================================================
--- /trunk/htdocs2/Forms/CartForm.php	(revision 298)
+++ /trunk/htdocs2/Forms/CartForm.php	(revision 298)
@@ -0,0 +1,160 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+require_once 'Forms/ObservationsTable.php';
+require_once 'Classes/Interfaces/ObsInterface.php';
+
+
+
+
+class CartForm extends GZ_BaseForm
+{
+  public function __construct( $s_gz )
+  {
+    parent::__construct( $s_gz );
+    
+    
+    $this->LoadCart();
+    
+    $this->SetupObservationsTable();
+    
+    $this->SetupPaginator();
+  }
+  
+
+  
+  public function Display()
+  {
+    $smarty = $this->gz->CreateSmarty();
+    
+    $this->gz->smarty_assign( $smarty, 'cart_size', count( $this->cart_contents ) );
+    $smarty->display( 'CartFormHeader.tpl' );
+    
+    if( count( $this->cart_contents ) > 0 )
+    {
+      $this->paginator->Display();
+      $this->obs_table->Display();
+    }
+    
+    $smarty->display( 'CartFormFooter.tpl' );
+  }
+  
+  public function ReadForm()
+  {
+    $this->obs_table->ReadForm();
+    $this->paginator->ReadForm();
+  }
+  
+  public function ProcessActions()
+  {
+    $next_form = '';
+    
+    $this->obs_table->ProcessActions();
+    $this->paginator->ProcessActions();
+    
+    if( $this->ActionIs( 'BackToResults' ) )
+      $next_form = 'QueryResultsForm';
+    
+    else if( $this->ActionIs( 'Download' ) )
+    {
+      $method = $this->GetPostString( 'DownloadMethod' );
+      if( $method == 'RemoveFromCart' )
+	$this->DeleteSelected();
+      else if( $method == 'DownloadObsOnly' )
+	$this->DownloadObservations();
+      else if( $method == 'DownloadCalsOnly' )
+	$this->DownloadCalibrations();
+      else if( $method == 'DownloadObsAndCals' )
+	$this->DownloadObsAndCals();
+    }
+    	  
+    return $next_form;
+  }
+  
+  // PRIVATE
+      
+  private $cart_contents;
+  private $obs_table;
+  private $paginator;
+  
+  private function SetupPaginator()
+  {
+    $table_pager = new GZ_Pager();
+    $table_pager->SetTarget( $this->obs_table );
+    $table_pager->SetItemsPerPage( 15 );
+    
+    $this->paginator = new GZ_Paginator( $this->gz, 'CartFormPaginator' );
+    $this->paginator->AddPager( $table_pager );
+  }
+  
+  private function SetupObservationsTable()
+  {
+    $this->obs_table = new ObservationsTable( $this->gz, 'tabQueryResults' );
+    
+    $this->obs_table->SetColumnHeadings( Array( 'distance', 'filename', 'src_name', 'project_id', 
+					 'rajd', 'decjd', 'data_type', 'obsfreq', 'bw',
+					 'scanlen', 'date', 'ut' ) );
+    
+    $this->obs_table->SetData( $this->cart_contents );
+  }
+  
+  private function DownloadObservations()
+  {
+    echo 'downloading observations <br> ';
+    echo 'there are ' . count( $this->obs_table->GetSelectedIDs() ) . ' items selected <br> ';
+  }
+  
+  private function DownloadCalibrations()
+  {
+    echo 'downloaing calibrations <br> ';
+  }
+  
+  private function DownloadObsAndCals()
+  {
+    echo 'downloading observations and cals <br> ';
+  }
+  
+  private function DeleteSelected()
+  {
+    $new_cart_contents = Array();
+    
+    $selected_ids = $this->obs_table->GetSelectedIDs();
+    if( count( $selected_ids ) > 0 )
+    {
+      $mapper = new ObsInterface();
+      foreach( $this->cart_contents as $next_cart_item )
+      {
+        $mapper->SetInstance( $next_cart_item );
+	if( !in_array( $mapper->GetValue( 'primary_key' ), $selected_ids ) )
+	  $new_cart_contents[] = $next_cart_item;
+      }
+      $this->cart_contents = $new_cart_contents;
+      $this->SaveCart();
+      $this->obs_table->SetData( $new_cart_contents );
+      $this->paginator->Paginate();
+    }
+  }
+  
+  private function SaveCart()
+  {
+    global $_SESSION;
+    
+    $_SESSION['cart_contents'] = $this->cart_contents;
+  }
+  
+  private function LoadCart()
+  {
+    global $_SESSION;
+    
+    $this->cart_contents = Array();
+    if( isset( $_SESSION['cart_contents'] ) )
+      $this->cart_contents = $_SESSION['cart_contents'];
+  }
+  
+};
+
+
+?>
Index: /trunk/htdocs2/Forms/DisplayParametersView.php
===================================================================
--- /trunk/htdocs2/Forms/DisplayParametersView.php	(revision 298)
+++ /trunk/htdocs2/Forms/DisplayParametersView.php	(revision 298)
@@ -0,0 +1,30 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . '/forms/GZ_BaseForm.php';
+
+
+
+class DisplayParametersView extends GZ_BaseForm
+{
+  public function __construct( $set_gz )
+  {
+    parent::__construct( $set_gz );
+  }
+
+  public function Display()
+  {
+    $smarty = $this->gz->CreateSmarty();
+    
+    $smarty->Display( 'DisplayParametersView.tpl' );
+  }
+
+  public function ProcessActions()
+  {
+    return '';
+  }
+};
+
+
+?>
Index: /trunk/htdocs2/Forms/LoginForm.php
===================================================================
--- /trunk/htdocs2/Forms/LoginForm.php	(revision 298)
+++ /trunk/htdocs2/Forms/LoginForm.php	(revision 298)
@@ -0,0 +1,125 @@
+<?php
+
+
+
+/**
+ * Written by David Smith
+ * nopeer@gmail.com
+ *
+ * For ATNF CSIRO
+ *
+ * This form presents a login dialog.
+ */
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+require_once 'Classes/General/UserData.php';
+
+
+
+
+class LoginForm extends GZ_BaseForm
+{
+  var $failure;
+  var $user_data;
+
+  function __construct( $set_gz )
+  {
+    parent::__construct( $set_gz );
+
+    $this->failure = false;
+
+    $this->user_data = new UserData();
+  }
+
+
+  function LoggedIn()
+  {
+    $logged_in = false;
+    
+    if( $this->user_data != '' )
+    {
+      $method = $this->user_data->GetAuthType();
+      if( $method == 'anonymous' || $method == 'opal' )
+	$logged_in = true;
+    }
+    
+    return $logged_in;
+  }
+
+
+  function Login()
+  {
+    global $_SESSION;
+
+    if( $this->GetPostString('authenticateType') == 'anon' )
+    {
+      if( !is_string( $this->GetPostString('email') ) ||
+          strlen( $this->GetPostString('email') ) < 4 ||
+          strpos( $this->GetPostString('email'), '@' ) === false ||
+          strpos( $this->GetPostString('email'), '.' ) === false )
+        throw new GZ_Exception( 'Enter a valid email address', 'LoginForm::Login' );
+
+      if( $this->user_data == '' )
+        $this->user_data = new UserData();
+    
+      $this->user_data->SetEmail( $this->GetPostString( 'email' ) );
+      $this->user_data->SetAuthType( 'anonymous' );
+    }
+
+    // TODO add opal login code here
+  }
+
+
+
+  function Logout()
+  {
+    global $_SESSION;
+
+    if( $this->user_data != '' )
+      $this->user_data->RemoveFromSession();
+    foreach( $_SESSION as $name => $value )
+      unset( $_SESSION[$name] );
+  }
+
+
+
+  function Display()
+  {
+    global $_SERVER;
+
+    $smarty = $this->gz->CreateSmarty();
+
+    $logged_in = $this->LoggedIn();
+    $proprietary_period = 12;
+    $self = $_SERVER['PHP_SELF'];
+
+    $this->gz->smarty_assign( $smarty, 'logged_in', $logged_in );
+    $this->gz->smarty_assign( $smarty, 'proprietary_period', $propietary_period );
+    $this->gz->smarty_assign( $smarty, 'self', $self );
+
+    $smarty->Display( 'LoginForm.tpl' );
+  }
+
+
+  function ProcessActions()
+  {
+    if( $this->ActionIs( 'Login' ) )
+      $this->Login();
+    else if( $this->ActionIs( 'Logout' ) )
+      $this->Logout();
+
+    if( $this->LoggedIn() )
+      return 'QueryForm';
+    else
+      return '';
+  }
+};
+
+
+
+
+
+
+?>
Index: /trunk/htdocs2/Forms/ObservationsTable.php
===================================================================
--- /trunk/htdocs2/Forms/ObservationsTable.php	(revision 298)
+++ /trunk/htdocs2/Forms/ObservationsTable.php	(revision 298)
@@ -0,0 +1,25 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Forms/GZ_Table.php';
+require_once 'Classes/Interfaces/ObsInterface.php';
+
+
+
+
+class ObservationsTable extends GZ_Table
+{
+  public function __construct( $s_gz, $s_html_id )
+  {
+    parent::__construct( $s_gz, $s_html_id );
+    
+    $this->SetDataMapper( new ObsInterface() );
+  }
+
+
+};
+
+
+?>
Index: /trunk/htdocs2/Forms/QueryForm.php
===================================================================
--- /trunk/htdocs2/Forms/QueryForm.php	(revision 298)
+++ /trunk/htdocs2/Forms/QueryForm.php	(revision 298)
@@ -0,0 +1,94 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+require_once 'Classes/General/UserData.php';
+require_once 'Classes/General/DateRange.php';
+require_once 'Classes/Astro/Band.php';
+require_once 'Classes/Astro/MJD.php';
+require_once 'Classes/Model/Observation.php';
+require_once 'Forms/QueryFormParameters.php';
+require_once 'Classes/Queries/DateRangeQuery.php';
+require_once 'Classes/Pulsar/PulsarCatalog.php';
+
+
+
+
+class QueryForm extends GZ_BaseForm
+{
+  // PUBLIC
+
+  public function __construct( $set_gz )
+  {
+    global $_SESSION;
+    
+    parent::__construct( $set_gz );
+
+    isset( $_SESSION['last_query'] ) ? $this->parameters = $_SESSION['last_query'] : $this->parameters = new QueryFormParameters();
+  }
+
+  public function Display()
+  {
+    global $_SERVER;
+    
+    $smarty = $this->gz->CreateSmarty();
+
+    $self = $_SERVER['PHP_SELF'];
+    $self = '';
+    $this->gz->smarty_assign( $smarty, 'self', $self );
+
+    $this->gz->smarty_assign( $smarty, 'parameters', $this->parameters );
+    $this->gz->smarty_assign( $smarty, 'coordinates', $this->parameters->GetCoordinates() );
+    $this->gz->smarty_assign( $smarty, 'cals_window', $this->parameters->GetCalsWindow() );
+
+    $dates_query = new DateRangeQuery();
+    $full_date_range = $dates_query->Execute( $this->gz );
+    
+    $from_date = $this->parameters->GetDateRange()->GetFromDate();
+    $to_date = $this->parameters->GetDateRange()->GetToDate();
+    if( $from_date->IsUnset() )
+      $from_date = $full_date_range->GetFromDate();
+    if( $to_date->IsUnset() )
+      $to_date = $full_date_range->GetToDate();
+    
+    $this->gz->smarty_assign( $smarty, 'from_date',  $from_date );
+    $this->gz->smarty_assign( $smarty, 'to_date', $to_date );
+
+    $this->gz->smarty_assign( $smarty, 'from_date_limit', $full_date_range->GetFromDate() );
+    $this->gz->smarty_assign( $smarty, 'to_date_limit', $full_date_range->GetToDate() );
+    
+    $known_years = Array();
+    for( $y = $full_date_range->GetFromDate()->GetYear(); $y < $full_date_range->GetToDate()->GetYear() + 1; $y ++ )
+      $known_years[] = $y;
+    $this->gz->smarty_assign( $smarty, 'known_years', $known_years );
+
+    $this->gz->smarty_assign( $smarty, 'days_in_month', Date::$days_in_month );
+    $this->gz->smarty_assign( $smarty, 'months_in_year', Date::$months_in_year );
+
+    $this->gz->smarty_assign( $smarty, 'valid_bands', Band::$valid_bands );
+    $this->gz->smarty_assign( $smarty, 'bands', $this->parameters->GetBands() );
+    $this->gz->smarty_assign( $smarty, 'valid_data_types', Observation::$valid_data_types );
+
+    $smarty->Display( 'QueryForm.tpl' );
+  }
+
+  public function ProcessActions()
+  {
+    if( $this->ActionIs( 'ConeQuery' ) )
+    {
+      $this->parameters->ReadForm( $this->gz->_POST );
+      if( $this->parameters->AreValid() )
+	return 'QueryResultsForm';
+    }
+    return '';
+  }
+
+  // PRIVATE
+
+  private $parameters;
+};
+
+
+
+?>
Index: /trunk/htdocs2/Forms/QueryFormParameters.php
===================================================================
--- /trunk/htdocs2/Forms/QueryFormParameters.php	(revision 298)
+++ /trunk/htdocs2/Forms/QueryFormParameters.php	(revision 298)
@@ -0,0 +1,83 @@
+<?php
+
+
+
+require_once 'Classes/Queries/ConeQueryParameters.php';
+
+
+
+class QueryFormParameters extends ConeQueryParameters
+{
+  // PUBLIC
+
+  public function __construct()
+  {
+    parent::__construct();
+
+    $this->pulsar_name = '';
+    $this->cals_window = 30;
+  }
+
+  public function GetPulsarName() { return $this->pulsar_name; }
+  public function SetPulsarName( $s_pulsar_name ) { $this->pulsar_name = $s_pulsar_name; }
+  
+  public function GetCalsWindow() { return $this->cals_window; }
+  public function SetCalsWindow( $s_cals_window ) { $this->cals_window = $s_cals_window; }
+  
+  public function ReadForm( $form_data )
+  {
+    // Read in the coordinates
+	
+    $ra = new Angle();
+    $dec = new Angle();
+    $ra->FromHMS( $form_data['ra_hour'], $form_data['ra_min'], $form_data['ra_sec'] );
+    $dec->FromDMS( $form_data['dec_deg'], $form_data['dec_min'], $form_data['dec_sec'] );
+    $coords = new SkyCoord();
+    $coords->SetRA( $ra );
+    $coords->SetDEC( $dec );
+    $this->SetCoordinates( $coords );
+    
+    $this->SetPulsarName( $form_data['pulsar_name'] );
+    
+    if( $form_data['add_cals'] == 'on' )
+      $this->SetCalsWindow( $form_data['cals_window'] );
+    else
+      $this->SetCalsWindow( null );
+    
+    $this->SetProjectID( $form_data['project_id'] );
+    
+    $this->SetProjectID( $form_data['project_id'] );
+
+    $this->SetSearchRadius( $form_data['search_radius'] );
+    
+    $this->SetDateRange( new DateRange( $form_data['from_day'] . '/' . $form_data['from_month'] . '/' . $form_data['from_year'],
+				       $form_data['to_day'] . '/' . $form_data['to_month'] . '/' . $form_data['to_year'] ) );
+    
+    $this->SetObsMode( $form_data['obs_mode'] );
+    
+    $this->SetDataType( $form_data['data_type'] );
+
+    if( is_array( $form_data['bands'] ) )
+    {
+      foreach( $form_data['bands']  as $next_bandname )
+      {
+	if( $next_bandname == 'Any' )
+	{
+	  $this->bands = Band::$valid_bands;
+	  break;
+	}
+	else
+	  foreach( Band::$valid_bands as $next_valid_band )
+	    if( $next_bandname == $next_valid_band->GetName() )
+	      $this->bands[] = $next_valid_band;
+      }
+    }
+  }
+
+  // PRIVATE
+
+  private $pulsar_name;
+  private $cals_window;
+};
+
+?>
Index: /trunk/htdocs2/Forms/QueryResultsForm.php
===================================================================
--- /trunk/htdocs2/Forms/QueryResultsForm.php	(revision 298)
+++ /trunk/htdocs2/Forms/QueryResultsForm.php	(revision 298)
@@ -0,0 +1,329 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+require_once GREEN_ZONE_DIR . 'Forms/GZ_Paginator.php';
+require_once 'Forms/QueryFormParameters.php';
+require_once 'Forms/ObservationsTable.php';
+require_once 'Classes/Model/Observation.php';
+require_once 'Classes/Queries/ConeQuery.php';
+require_once 'Classes/Queries/CalQuery.php';
+require_once 'Classes/General/Pair.php';
+require_once 'Classes/Pulsar/PulsarCatalog.php';
+require_once 'Classes/General/UserData.php';
+
+
+
+/**
+ * @class QueryResultsForm
+ * 
+ * This form uses a GZ_Table to display the results from the last query performd.
+ * It also presents some controls and responds to the following user actions
+ * - ConeQuery (Perform the actual query using the posted form data)
+ * - NewQuery  (Return to the query form)
+ * - ShowCart  (Switch to the cart form)
+ * - AddToCart (Add all the selected observations to the cart session data.
+ **/
+
+class QueryResultsForm extends GZ_BaseForm
+{
+  // PUBLIC
+
+  public function __construct( $set_gz )
+  {
+    global $_SESSION;
+    
+    parent::__construct( $set_gz );
+
+    $this->last_result_set = Array();
+    $this->last_query = null;
+    
+    isset( $_SESSION['last_results'] ) ?
+	$this->last_result_set = $_SESSION['last_results'] : $this->last_result_set = Array();
+    
+    isset( $_SESSION['cart_contents'] ) ?
+	$this->cart_contents = $_SESSION['cart_contents'] : $this->cart_contents = Array();
+    
+    $this->SetupObservationsTable();
+    
+    $this->SetupPaginator();
+    
+    $this->download_size = 0.0;
+    
+    $this->date_range_adjusted = false;
+  }
+  
+  public function Display()
+  {
+    $smarty = $this->gz->CreateSmarty();
+    $this->gz->smarty_assign( $smarty, 'cart_size', count( $this->cart_contents ) );
+    $this->gz->smarty_assign( $smarty, 'download_size', $this->download_size );
+    
+    $adjusted_from_date = null;
+    $adjusted_to_date = null;
+    if( $this->date_range_adjusted )
+    {
+      $adjusted_from_date = $this->parameters->GetDateRange()->GetFromDate()->ToDMYString();
+      $adjusted_to_date = $this->parameters->GetDateRange()->GetToDate()->ToDMYString();
+    }
+    $this->gz->smarty_assign( $smarty, 'adjusted_from_date', $adjusted_from_date );
+    $this->gz->smarty_assign( $smarty, 'adjusted_to_date', $adjusted_to_date );
+    
+    $smarty->display( 'QueryResultsFormHeader.tpl' );
+
+    if( $this->last_result_set != '' )
+    {
+      $this->paginator->Display();
+      $this->obs_table->Display();
+    }
+    
+    $smarty->display( 'QueryResultsFormFooter.tpl' );
+  }
+
+  public function ReadForm()
+  {
+    $this->obs_table->ReadForm();
+    $this->paginator->ReadForm();
+  }
+  
+  public function ProcessActions()
+  {
+    $next_form = '';
+    
+    $this->obs_table->SetData( $this->last_result_set );
+    
+
+    
+    if( $this->ActionIs( 'ConeQuery' ) )
+    {
+      $this->ProcessConeQuery();
+      $this->obs_table->SetData( $this->last_result_set );
+      $this->paginator->ProcessActions();
+    }
+    else if( $this->ActionIs( 'NewQuery' ) )
+      $next_form = 'QueryForm';
+    else if( $this->ActionIs( 'ShowCart' ) )
+      $next_form = 'CartForm';
+    else if( $this->ActionIs( 'PerformAction' ) )
+    {
+      $action = $this->GetPostString( 'Action' );
+      if( $action == 'AddToCart' )
+        $this->AddToCart();
+      else if( $action == 'ViewProfiles' )
+        $this->ViewProfiles();
+      else if( $action == 'ViewProfilesAndCals' )
+        $this->ViewProfilesAndCals();
+    }
+
+    $this->obs_table->ProcessActions();
+    $this->paginator->ProcessActions();
+
+    
+    return $next_form;
+  }
+
+  // PRIVATE
+
+  private $last_result_set;
+  private $query_failure_msg;
+  private $parameters;
+  private $cart_contents;
+  private $obs_table;
+  private $pager;
+  private $download_size;
+  private $date_range_adjusted;
+  
+  
+  private function SetupObservationsTable()
+  {
+    $this->obs_table = new ObservationsTable( $this->gz, 'tabQueryResults' );
+    
+    $this->obs_table->SetColumnHeadings( Array( 'distance', 'filename', 'src_name', 'project_id', 
+					 'rajd', 'decjd', 'data_type', 'obsfreq', 'bw',
+					 'scanlen', 'date', 'ut', 'mjd' ) );
+    
+    $this->obs_table->SetData( $this->last_result_set );
+  }
+  
+  private function SetupPaginator()
+  {
+    $table_pager = new GZ_Pager();
+    $table_pager->SetTarget( $this->obs_table );
+    $table_pager->SetItemsPerPage( 15 );
+    
+    $this->paginator = new GZ_Paginator( $this->gz, 'QueryResultsFormPaginator' );
+    $this->paginator->AddPager( $table_pager );
+  }
+
+  private function PerformQuery()
+  {
+    // If we were given a pulsar name, set the rajd and decjd to that pulsar
+	
+    $query = new ConeQuery();
+    if( $this->parameters->GetPulsarName() != '' )
+    {
+      $catalog = new PulsarCatalog();
+      $coords = $catalog->GetCoordsForPulsar( $this->parameters->GetPulsarName() );
+      $this->parameters->SetCoordinates( $coords );
+    }
+    
+    // If the user is anonymous, drop the to_limit on the date range down by 18 months
+    $this->AdjustDateRange();
+    
+    
+    $query->SetParameters( $this->parameters );
+    $query->Execute( $this->gz );
+    $this->last_result_set = $query->GetResults();
+  }
+  
+  private function ProcessConeQuery()
+  {
+    global $_SESSION;
+    
+    $this->parameters = new QueryFormParameters();
+    $this->parameters->ReadForm( $this->gz->_POST );
+
+    $pulsar_name = $this->parameters->GetPulsarName();
+    if( $pulsar_name != '' )
+    {
+      $catalog = new PulsarCatalog();
+      $coordinates = $catalog->GetCoordsForPulsar( $pulsar_name );
+      $this->parameters->SetCoordinates( $coordinates );
+    }
+
+    $this->PerformQuery();
+    
+    // if we have a time window from which we want cals
+    // for each observation
+    //    calculate the time window as start and end mjds
+    //    create a cal query
+    //    give it the start and end mjd times
+    //    perform the cal query
+    //    if we have any cal results
+    //      add those cal results to the observation
+        
+    if( $this->parameters->GetCalsWindow() != null )
+    {
+      for( $obs = 0; $obs < count( $this->last_result_set ); $obs ++ )
+      {
+        $obs_time = $this->last_result_set[$obs]->GetMJD();
+        // determine a min as a fraction of a day
+        $half_min = 0.5 / (24.0 * 60.0);
+        
+        $min_mjd = new MJD();
+        $min_mjd->FromString( $obs_time->ToString() - $this->parameters->GetCalsWindow() * $half_min );
+        
+        $max_mjd = new MJD();
+        $max_mjd->FromString( $obs_time->ToString() + $this->parameters->GetCalsWindow() * $half_min );
+        
+        $cal_query = new CalQuery();
+        $cal_query->SetStartTime( $min_mjd );
+        $cal_query->SetEndTime( $max_mjd );
+        $cal_query->Execute( $this->gz );
+        $cals = $cal_query->GetCalibrations();
+        
+        $this->last_result_set[$obs]->SetCalibrations( $cals );
+      }
+    }
+    else
+    {
+      echo 'we dont want any cals <br>';
+    }
+      
+    $_SESSION['last_query'] = $this->parameters;
+    $_SESSION['last_results'] = $this->last_result_set;
+  }
+  
+  private function AddToCart()
+  {
+    global $_SESSION;
+    
+    $this->obs_table->ProcessActions();
+    $selected_ids = $this->obs_table->GetSelectedIDs();
+      
+    $cart_ids = Array();
+    foreach( $this->cart_contents as $next_cart_item )
+      $cart_ids[] = $next_cart_item->GetFileID();
+      
+    foreach( $this->last_result_set as $next_result )
+    {
+      $next_id = $next_result->GetFileID();
+      if( in_array( $next_id, $selected_ids ) &&
+	  !in_array( $next_id, $cart_ids ) )
+      {
+	$this->cart_contents[] = $next_result;
+      }
+    }
+    $_SESSION['cart_contents'] = $this->cart_contents;
+  }
+  
+  private function ViewProfiles( )
+  {
+  }
+  
+  private function ViewProfilesAndCals()
+  {
+  }
+  
+  private function AdjustDateRange()
+  {
+    $user_data = new UserData();
+    
+    $auth_type = $user_data->GetAuthType();
+    if( $auth_type == 'anonymous' )
+    {
+      // get the mjd for now
+	  
+      $now_date = new Date();
+      $now_date->FromDMYString( date( 'd/m/Y' ) );
+      $now_mjd = new MJD();
+      $now_mjd->FromDate( $now_date );
+	  
+       // get the mjd the user has chosen as their to value
+	   
+      $user_date_range = $this->parameters->GetDateRange();
+      $user_to_date = $user_date_range->GetToDate();
+      $user_to_mjd = new MJD();
+      $user_to_mjd->FromDate( $user_to_date );
+      
+      // if the user has selected a higher mjd
+      //   correct it
+      //   save it back to the search parameters
+      if( $user_to_mjd->ToString() > $now_mjd->ToString() - 547 )
+      {
+	$user_to_mjd->FromString( $user_to_mjd->ToString() - 547 );
+	$user_to_date = $user_to_mjd->ToDate();
+	
+	$user_date_range->SetToDate( $user_to_date );
+	
+	$this->date_range_adjusted = true;
+      }
+      
+      
+      
+      
+      
+      
+      
+      
+      
+
+//       
+
+//       $chosen_mjd_value = $chosen_mjd->ToString();
+//       
+//       if( $chosen_mjd_value > $user_to_mjd_value )
+//       {
+// 	$new_max_mjd = new MJD();
+// 	$new_max_mjd->FromString( $user_max_mjd );
+// 
+// 	$new_date_range = new DateRange();
+// 	$new_date_range->SetFromDate( $current_range->GetFromDate() );
+// 	$new_date_range->SetToDate( $new_max_mjd->ToDate() );
+//       }
+    }
+  }
+};
+
+?>
Index: /trunk/htdocs2/GreenZone/Forms/GZ_BaseForm.php
===================================================================
--- /trunk/htdocs2/GreenZone/Forms/GZ_BaseForm.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Forms/GZ_BaseForm.php	(revision 298)
@@ -0,0 +1,234 @@
+<?php 
+
+
+/**
+ * (c) David Smith 2008 ATNF CSIRO
+ * nopeer@gmail.com
+ **/
+
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/StringUtils.php';
+
+
+
+
+class GZ_BaseForm
+{
+  var $gz;
+
+
+
+  /**
+   * Constructor
+   *
+   *   DOES     - stores the pointer to the green zone
+   *   RECEIVES - A green zone
+   *   RETURNS  - Nothing
+   *   THROWS   - Nothing
+   **/
+
+  function __construct( $set_gz )
+  {
+    $this->gz = $set_gz;
+  }
+
+
+
+  /**
+   * Display
+   *
+   *    DOES     - Nothing
+   *    RECEIVES - Nothing
+   *    RETURNS  - An empty string
+   *    THROWS   - Nothing
+   **/
+  
+  function Display()
+  {
+    return '';
+  }
+
+
+
+  /**
+   * Read in form data and alter state, but don't respond to any RealAction commands
+   *
+   *   DOES     - Nothing
+   *   RECEIVES - Nothing
+   *   RETURNS  - An empty string
+   *   THROWS   - Nothing
+   **/
+
+  function ReadForm()
+  {
+  }
+  
+  /**
+   * Process any RealAction events, and return the name of a new form if applicable
+   *
+   *   DOES     - Nothing
+   *   RECEIVES - Nothing
+   *   RETURNS  - An empty string
+   *   THROWS   - Nothing
+   **/
+  
+  function ProcessActions()
+  {
+    return '';
+  }
+
+
+
+  /**
+   * ActionIs
+   *
+   *   DOES     - Returns true if the action post variable begins with the action string given
+   *   RECEIVES - The string to check against
+   *   RETURNS  - True if th eaction matches, false otherwise
+   *   THROWS   - Nothing
+   *   TODO     - Nothing
+   **/
+
+  function ActionIs( $action_string )
+  {
+    $matches = false;
+
+    foreach( Array( $this->gz->_POST, $this->gz->_GET ) as $cmd_source )
+    {
+      if( isset( $cmd_source['RealAction'] ) )
+      {
+	if( StartsWith( $cmd_source['RealAction'], $action_string ) )
+	{
+	  $matches = true;
+	}
+      }
+    }
+
+    return $matches;
+  }
+
+
+
+  /**
+   * GetActionData
+   *
+   *   DOES     - Get anything in the action post variable after the action command, usually an id
+   *   RECEIVES - Nothing
+   *   RETURNS  - Any data out of the action post variable after the first space
+   *   THROWS   - An exception if the action psot variable is not set
+   *   TODO     - Nothing
+   **/
+
+  function GetActionData( )
+  {
+    if( isset( $this->gz->_POST['RealAction'] ) )
+    {
+      return AdvanceStringTo( $this->gz->_POST['RealAction'], '_' );
+    }
+    if( isset( $this->gz->_GET['RealAction'] ) )
+    {
+      return AdvanceStringTo( $this->gz->_GET['RealAction'], '_' );
+    }
+    throw( new GZ_Exception( 'No Action Set', 'GetActionData' ) );
+  }
+
+
+
+
+  /**
+   * CheckPostString
+   *
+   *   DOES     - Retreives a string from post data
+   *   RECEIVES - The variable name
+   *   RETURNS  - Returns the post variable or false if unset, empty string, or not string
+   *   THROWS   - Nothing
+   *   TODO     - Nothing
+   **/
+
+  function GetPostString( $target_var )
+  {
+    if( !isset( $this->gz->_POST[$target_var] ) )
+      {
+	return false;
+      }
+    else if( '' == $this->gz->_POST[$target_var] )
+      {
+	return false;
+      }
+    else if( !is_string( $this->gz->_POST[$target_var] ) )
+      {
+	return false;
+      }
+    else
+      {
+	return $this->gz->_POST[$target_var];
+      }
+  }
+
+
+
+  /**
+   * GetPostNum
+   *
+   *   DOES     - Retreives a number from post data
+   *   RECEIVES - The variable name
+   *   RETURNS  - Returns the post variable or false if unset or not a number
+   *   THROWS   - Nothing
+   *   TODO     - Nothing
+   **/
+
+  function GetPostNum( $target_var )
+  {
+    if( !isset( $this->gz->_POST[$target_var] ) )
+      {
+	return false;
+      }
+    else if( !is_numeric( $this->gz->_POST[$target_var] ) )
+      {
+	return false;
+      }
+    else
+      {
+	return $this->gz->_POST[$target_var];
+      }
+  }
+
+
+
+  /**
+   * GetPostArray
+   *
+   *   DOES     - Retreives an array from post data, or throws an exception if unset or not an array
+   *   RECEIVES - The variable name
+   *   RETURNS  - Returns the post variable
+   *   THROWS   - A CybergamingException if the variable is unset or not an array
+   *   TODO     - Nothing
+   **/
+
+  function GetPostArray( $target_var )
+  {
+    if( !isset( $this->gz->_POST[$target_var] ) )
+      {
+	throw( new GZ_Exception( 'Variable ' . $target_var . ' not set', 'GZ_BaseForm::GetPostArray' ) ); 
+      }
+    else if( !is_array( $this->gz->_POST[$target_var] ) )
+      {
+	throw( new GZ_Exception( 'Variable ' . $target_var . ' should be an array', 'GZ_BaseForm::GetPostArray' ) );
+      }
+    else
+      {
+	return $this->gz->_POST[$target_var];
+      }
+  }
+};
+
+
+
+
+
+
+
+
+?>
Index: /trunk/htdocs2/GreenZone/Forms/GZ_Pager.php
===================================================================
--- /trunk/htdocs2/GreenZone/Forms/GZ_Pager.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Forms/GZ_Pager.php	(revision 298)
@@ -0,0 +1,42 @@
+<?php
+
+
+
+class GZ_Pager
+{
+  // PUBLIC
+      
+  public function __construct()
+  {
+    $this->items_per_page = 1;
+  }
+  
+  public function SetItemsPerPage( $s_items_per_page ) { $this->items_per_page = $s_items_per_page; }
+   
+  public function GetNumPages()
+  {
+    $num_items = $this->target->GetNumItems();
+    $this->num_pages = ceil( $num_items / $this->items_per_page );
+    
+    return $this->num_pages; 
+  }
+  
+  public function SetTarget( $s_target ) { $this->target = $s_target; }
+  
+  public function SetPage( $page_num ) 
+  {
+    $range = new Pair();
+    $range->first = $this->items_per_page * ($page_num-1);
+    $range->second = ($this->items_per_page * $page_num) - 1;
+    
+    $this->target->SetRange( $range );
+  }
+  
+  // PRIVATE
+      
+  private $items_per_page;
+  private $num_pages;
+  private $target;
+};
+
+?>
Index: /trunk/htdocs2/GreenZone/Forms/GZ_Paginator.php
===================================================================
--- /trunk/htdocs2/GreenZone/Forms/GZ_Paginator.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Forms/GZ_Paginator.php	(revision 298)
@@ -0,0 +1,108 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+require_once GREEN_ZONE_DIR . 'Forms/GZ_Pager.php';
+
+
+
+class GZ_Paginator extends GZ_BaseForm
+{
+  // PUBLIC
+      
+  public function __construct( $s_gz, $s_html_id )
+  {
+    global $_SESSION;
+    
+    parent::__construct( $s_gz );
+    
+    $this->pagers = Array();
+    $this->total_pages = 1;
+    $this->current_page = 1;
+    $this->html_id = $s_html_id;
+  }
+  
+  public function AddPager( $new_pager ) { $this->pagers[] = $new_pager; }
+  
+  public function Display()
+  {
+    echo '<font size=4>';
+    // draw the paginator controls
+    for( $ind = 1; $ind <= $this->total_pages; $ind ++ )
+    {
+      if( $ind == $this->current_page )
+	echo " <b>$ind</b>";
+      else
+	echo " <a href=?page=$ind>$ind</a>";
+    }
+    echo '<br><br>';
+    echo '</font>';
+  }
+  
+  public function CheckCurrentPage()
+  {
+    if( $this->current_page > $this->total_pages )
+      $this->current_page = $this->total_pages;
+    if( $this->current_page < 1 )
+      $this->current_page = 1;
+  }
+  
+  public function DeterminePageRange()
+  {
+    // check all the pagers to determine the maximum page range
+
+    $this->total_pages = 0;
+    foreach( $this->pagers as $next_pager )
+    {
+      $next_num_pages = $next_pager->GetNumPages();
+      if( $next_num_pages > $this->total_pages )
+	$this->total_pages = $next_num_pages;
+    }
+  }
+  
+  public function Paginate()
+  {
+    $this->DeterminePageRange();
+    
+    $this->CheckCurrentPage();
+    
+    foreach( $this->pagers as $next_pager )
+      $next_pager->SetPage( $this->current_page );
+  }
+  
+  public function SetPage( $s_page )
+  {
+    global $_SESSION;
+    echo 'setting page to ' . $s_page . ' <br>';
+    $this->current_page = $s_page;
+    
+    $this->CheckCurrentPage();
+    
+    $_SESSION[ $this->html_id . 'CurrentPage' ] = $this->current_page;
+  }
+  
+  public function ReadForm()
+  {
+    if( isset( $_SESSION[ $this->html_id . 'CurrentPage' ] ) )
+      $this->current_page = $_SESSION[ $this->html_id . 'CurrentPage' ];
+
+    if( isset( $this->gz->_GET['page'] ) )
+      $this->current_page = $this->gz->_GET['page'];
+  }
+  
+  public function ProcessActions()
+  {
+    $this->Paginate();
+    
+    return '';
+  }
+  
+  // PRIVATE
+  
+  private $pagers;
+  private $total_pages;
+  private $current_page;
+};
+
+?>
Index: /trunk/htdocs2/GreenZone/Forms/GZ_Table.php
===================================================================
--- /trunk/htdocs2/GreenZone/Forms/GZ_Table.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Forms/GZ_Table.php	(revision 298)
@@ -0,0 +1,179 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once 'Classes/General/Pair.php';
+require_once GREEN_ZONE_DIR . 'Forms/GZ_BaseForm.php';
+require_once GREEN_ZONE_DIR . 'Utils/GZ_DataMapper.php';
+
+
+
+class GZ_Table extends GZ_BaseForm
+{
+  // PUBLIC
+
+  //! Constructor
+  public function __construct( $s_gz, $s_html_id )
+  {
+    parent::__construct( $s_gz );
+    
+    $this->data_set = Array();
+    $this->headings = Array();
+    $this->show_range = new Pair();
+    $this->show_columns = Array();
+    $this->selected_ids = Array();
+    $this->data_mapper = null;
+    $this->html_id = $s_html_id;
+    $this->html_selections_id = $s_html_id . 'Selections';
+  }
+  
+  //! Return the ids for the rows that the user has selected.
+  public function GetSelectedIDs() { return $this->selected_ids; }
+  
+  //! Set the ids to show as selected
+  public function SetSelectedIDs( $s_selected_ids ) { $this->selected_ids = $s_selected_ids; }
+  
+  //! Set all the entries as selected
+  public function SelectAll()
+  {
+    if( $this->data_mapper == null )
+      throw new GZ_Exception( 'No mapper set for table', 'GZ_Table::SelectAll' );
+
+    $this->selected_ids = Array();
+    foreach( $this->data_set as $next_item )
+    {
+      $this->data_mapper->SetInstance( $next_item );
+      $this->selected_ids[] = $this->data_mapper->GetValue( 'primary_key' );
+    }
+  }
+  
+  //! Set the column headings
+  public function SetColumnHeadings( $s_headings ) { $this->headings = $s_headings; }
+  
+  //! Get the column headings
+  public function GetColumnHeadings() { return $this->headings; }
+  
+  //! Set the range of items to show
+  public function SetRange( Pair $s_range ) { $this->show_range = $s_range; }
+  
+  //! Set the data set to display
+  public function SetData( $s_data_set ) { $this->data_set = $s_data_set; }
+  
+  //! Get the number of items in the data set
+  public function GetNumItems() { return count( $this->data_set ); }
+  
+  //! Set the mapper to use to get fields from the data, must contain a primary_key mapping
+  public function SetDataMapper( $s_data_mapper ) { $this->data_mapper = $s_data_mapper; }
+  
+  /**
+   * Render the html for this table to output.
+   **/
+  public function Display()
+  {
+    // If our range is outside the data set, move it to something more sensible
+	
+    if( $this->show_range->first > count( $this->data_set ) - 1)
+      $this->show_range->first = 0;
+    if( $this->show_range->second > count( $this->data_set ) - 1 )
+      $this->show_range->second = count( $this->data_set ) - 1;
+
+    // grab just the rows that are in range
+    
+    $display_data = $this->DataToArray();
+    
+    // Setup some class variables
+    // TODO make these settable by members
+    
+    $td_class = 'result_row';
+    $tr_class = 'QueryResultsTR';
+    $thr_class = 'QueryResultsHeaderTR';
+
+
+    $smarty = $this->gz->CreateSmarty();
+
+    $this->gz->smarty_assign( $smarty, 'selected_ids', $this->selected_ids );
+    $this->gz->smarty_assign( $smarty, 'data_set', $display_data );
+    $this->gz->smarty_assign( $smarty, 'headings', $this->headings );
+    $this->gz->smarty_assign( $smarty, 'td_class', $td_class );
+    $this->gz->smarty_assign( $smarty, 'tr_class', $tr_class );
+    $this->gz->smarty_assign( $smarty, 'thr_class', $thr_class );
+    $this->gz->smarty_assign( $smarty, 'html_id', $this->html_id );
+    $this->gz->smarty_assign( $smarty, 'html_selections_id', $this->html_selections_id );
+
+    $smarty->display( 'GZ_Table.tpl' );
+  }
+  
+  public function ReadForm()
+  {
+    // read the array of selected ids from the post data
+
+    $this->selected_ids = Array();
+    if( isset( $this->gz->_POST[$this->html_selections_id] ) )
+      $this->selected_ids = $this->gz->_POST[$this->html_selections_id];
+  }
+  
+  public function ProcessActions()
+  {
+    if( $this->ActionIs( $this->html_id . 'SelectAll' ) )
+      $this->SelectAll();
+
+    return '';
+  }
+  
+  // PRIVATE
+
+  private $data_set;
+  private $data_mapper;
+  private $show_range;
+  private $order_column_name;
+  private $order_column_direction;
+  private $show_columns;
+  private $html_id;
+  private $html_selections_id;
+  private $selected_ids;
+  
+
+  //! This function returns an array with the data ready for display
+  public function DataToArray()
+  {
+    $converted_rows = Array();
+    
+    for( $ind = $this->show_range->first; $ind <= $this->show_range->second; $ind ++ )
+    {
+      $next_observation = $this->data_set[$ind];
+      
+      $this->data_mapper->SetInstance( $next_observation );
+
+      $new_row = Array();
+      $new_row['id'] = $this->data_mapper->GetValue('primary_key');
+      $new_row['cells'] = Array();
+      foreach( $this->GetColumnHeadings() as $next_col_name )
+      {
+        $next_value = $this->data_mapper->GetValue( $next_col_name );
+        $new_row['cells'][] = $next_value;
+      }
+
+      $new_row['children'] = Array();
+      $children = $next_observation->GetChildren();
+      $child_interface = $next_observation->GetChildInterface();
+      foreach( $children as $next_child )
+      {
+        $child_interface->SetInstance( $next_child );
+        foreach( $this->GetColumnHeadings() as $next_child_col_name )
+        {
+          //$next_value = $child_interface->GetValue( $next_child_col_name );
+          //echo 'next value is ' . $next_value . '<br>';
+          $new_row['children'][] = $child_interface->GetValue( 'rajd'  );
+          //$new_row['children'][] = 'testing';
+        }
+      }
+      
+      $converted_rows[] = $new_row;
+    }
+    
+    return $converted_rows;
+  }
+};
+
+?>
Index: /trunk/htdocs2/GreenZone/Tests/BaseTest.php
===================================================================
--- /trunk/htdocs2/GreenZone/Tests/BaseTest.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Tests/BaseTest.php	(revision 298)
@@ -0,0 +1,48 @@
+<?
+
+/**
+ * TODO document
+ **/
+
+class BaseTest
+{
+  public function __construct()
+  {
+  }
+
+  public function TestIt()
+  {
+    echo 'Test function not implemented<br>';
+  }
+
+  /**
+  * This function creates a string to display either success in green or failure in red
+  * based on the boolean value given.
+  * Usage
+  *   echo 'Performing test ... ' . ResultString( $a == TestClass->GetValue(), "strings don't match" );
+  **/
+
+  function ResultString( $success, $err_description )
+  {
+    $result_string = '';
+
+    if( $success )
+      $result_string = '<B style="color: green;"> SUCCESS </B>';
+    else
+    {
+      $result_string = '<B style="color: red;"> FAILED </B>';
+      $result_string .= "<ul><li> $err_description </li></ul>";
+    }
+
+    return $result_string;
+  }
+
+
+
+  function PerformTest( $desc, $success, $err_description )
+  {
+    echo $desc . ' ... ' . $this->ResultString( $success, $err_description ) . ' <br> ';
+  }
+};
+
+?>
Index: /trunk/htdocs2/GreenZone/Utils/GZ_DataMapper.php
===================================================================
--- /trunk/htdocs2/GreenZone/Utils/GZ_DataMapper.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Utils/GZ_DataMapper.php	(revision 298)
@@ -0,0 +1,72 @@
+<?php
+
+
+
+/**
+ * class GZ_DataMapper
+ *
+ * This class provides an object that can extract data from another class
+ * by providing a mapping from a text name, to the getter function and
+ * data conversion functions
+ **/
+class GZ_DataMapper
+{
+  // PUBLIC
+      
+  public function __construct()
+  {
+    $this->mappings = Array();
+  }
+  
+  public function MakeMapping( $name, $access_method, $conversion_function = null )
+  {
+    $new_mapping = Array();
+    $new_mapping['name'] = $name;
+    $new_mapping['access_method'] = $access_method;
+    $new_mapping['conversion_function'] = $conversion_function;
+
+    $this->AddMapping( $new_mapping );
+  }
+  
+  public function AddMapping( $new_mapping )
+  {
+    $this->mappings[] = $new_mapping;
+  }
+  
+  public function SetInstance( $s_instance ) { $this->instance = $s_instance; }
+  public function GetInstance() { return $this->instance; }
+  
+  public function GetValue( $name )
+  {
+    $data_value = null;
+    
+    if( $this->instance == null )
+      throw new GZ_Exception( 'Instance not set', 'GZ_DataMapper::GetValue' );
+    
+    foreach( $this->mappings as $next_mapping )
+    {
+      if( $next_mapping['name'] == $name )
+      {
+
+        $extract_cmd = '$data_value = $this->instance->' . $next_mapping['access_method'] . '();';
+
+        eval( $extract_cmd );
+
+        if( $next_mapping['conversion_function'] != null )
+          eval( '$data_value = $data_value->' . $next_mapping['conversion_function'] . '();' );
+        break;
+      }
+    }
+    
+    return $data_value;
+  }
+  
+  // PRIVATE
+      
+  private $instance;
+  private $mappings;
+};
+
+
+
+?>
Index: /trunk/htdocs2/GreenZone/Utils/GZ_Exception.php
===================================================================
--- /trunk/htdocs2/GreenZone/Utils/GZ_Exception.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Utils/GZ_Exception.php	(revision 298)
@@ -0,0 +1,48 @@
+<?php
+
+
+
+
+define( 'INVALID_PARAM', 100 );
+define( 'FAILED_CALL', 101 );
+define( 'QUERY_FAILED', 102 );
+define( 'NO_ROWS', 103 );
+define( 'OUT_OF_RANGE', 104 );
+define( 'DISCONNECTED', 105 );
+
+
+
+
+
+/**
+ * This class extends phps basic exception class to include
+ * details of the method that called the exception and a code
+ * for identifying the type of exception.
+ * code that is unaware of the extra field will operate as though it
+ * were a normal exception.
+ **/
+
+class GZ_Exception extends Exception
+{
+  // PUBLIC
+      
+  public function __construct( $s_message = null, $s_method = null, $s_code = null)
+  {
+    parent::__construct();
+    
+    $this->message = $s_message;
+    $this->method = $s_method;
+    $this->code = $s_code;
+  }
+
+  
+  public function getMethod()
+  {
+    return $this->method;
+  }
+  
+  // PRIVATE
+      
+  private $method;
+};
+?>
Index: /trunk/htdocs2/GreenZone/Utils/GZ_Logger.php
===================================================================
--- /trunk/htdocs2/GreenZone/Utils/GZ_Logger.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Utils/GZ_Logger.php	(revision 298)
@@ -0,0 +1,68 @@
+<?php
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/GZ_Exception.php';
+
+
+
+/**
+ * @class GZ_Logger
+ * 
+ * This class simply stores the path to the log file and receives
+ * calls to log new messages to that file
+ **/
+class GZ_Logger
+{
+  // PUBLIC
+      
+  public function __construct( $s_logfilename = null )
+  {
+    $this->SetLogFilename( $s_logfilename );
+  }
+  
+  public function SetLogFilename( $s_logfilename ) { $this->log_filename = $s_logfilename; }
+  
+  public function LogMessage( $username, $action, $param1, $param2, $param3 )
+  {
+    $date = date("n Y");
+
+    list($month, $year) = split(' ', $date);
+
+    $string = "\"" . date('d-m-y') . "\"\t\"" .
+        date( 'h:i:s') . "\"\t\"" .
+        $username . "\"\t\"" .
+        $action . "\"\t\"" .
+        $param1 . "\"\t\"" .
+        $param2 . "\"\t\"" .
+        $param3 . "\"\n";
+
+    if (!file_exists($this>log_filename)) {
+      touch($this->log_filename);
+    }
+
+    if (is_writable($this->log_filename)) {
+      if (!$handle = fopen($this->log_filename, "a+")) {
+	      //echo "Cannot open log file ($filename)<br>\n";
+      }
+      else {
+
+        if (fwrite($handle, $string) === FALSE) {
+		//echo "Cannot write to log file $file<br>\n";
+        }
+
+        fclose($handle);
+      }
+    }
+    else {
+      //echo "Cannot write to log file ($filename)<br>\n";
+    }
+  }
+  
+  // PRIVATE
+      
+  private $log_filename;
+};
+
+
+?>
Index: /trunk/htdocs2/GreenZone/Utils/GreenZone.php
===================================================================
--- /trunk/htdocs2/GreenZone/Utils/GreenZone.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Utils/GreenZone.php	(revision 298)
@@ -0,0 +1,373 @@
+<?php 
+
+  /**
+   * (c) David Smith, 2008
+   * nopeer@gmail.com
+   *
+   *
+   * THE PROBLEM
+   *
+   *     The most basic form of attack on a system, is with escape sequence data
+   *     being sent using the normal methods of input such as _GET and _POST.
+   *
+   *     Escape sequence functions such as mysql_real_escape_string give us
+   *     the ability to prevent bad/maliscious data from breaking/compromising
+   *     systems. 
+   *
+   *     How these functions are used depends upon your design. In the worst
+   *     case you can call mysql_real_escape_string on each string as you add it
+   *     to a mysql_query call. This is both repetitious and pointless as you only
+   *     have to miss it once to compromise your system. A better design, will
+   *     have queries encapsulated in a function or class and you can make your
+   *     call to the escape function once. However this requires that you pass
+   *     each argument for the query separately. Which in most cases would
+   *     rquire a function with a variable number of parameters.
+   *
+   *     The best approach is to escape all
+   *     strings as they are received, eg calling mysql_real_escape string on
+   *     every string under the _GET and _POST arrays and storing them under a
+   *     new array. Any later use of _GET or _POST in code can be detected with
+   *     a simple grep.
+   *
+   *     One of the biggest headaches with all of this is knowing what state a
+   *     string is in. If you escape a string twice, you have introduced unwanted data.
+   *         eg a ' becomes \' and then \\\'
+   *
+   *     If you send an escaped string to the database, then retrieve it it will
+   *     no longer be escaped. You are constantly having to figure out what state
+   *     a string is in before you use it.
+   *
+   * THE SOLUTION
+   *
+   *     The best way to solve these problems is by establishing a policy. As always
+   *     it is up to the programmer to follow/ignore a policy. The policy that I have
+   *     chosen is to create a GREEN ZONE within my programs. Every string inside that
+   *     zone is to be properly escaped at all times. To facilitate this, I have constructed
+   *     this class to create a GREEN WALL. All data entering and leaving the GREEN ZONE
+   *     must pass through the GREEN WALL. The wall will ensure that all data is properly
+   *     escaped when entering the zone, and escaped or not escaped when leaving depending
+   *     on where it is going ( output to browser should not be escaped, output to database
+   *     should be ).
+   *
+   *     The choice as to wether code should be escaped or not escaped within the zone
+   *     is arbitrary, I could have chosen to have all strings not escaped within the zone.
+   *     Which would be like building a zone around the database. But databases are not
+   *     the only problems. php functions like eval, are also susceptible to escape sequence
+   *     attacks, therefore all calls to eval etc would have to pass through the wall also.
+   *     So it is better, to have the zone pretty much encompass the whole php program. Which
+   *     is what this class attempts to acheive.
+   *
+   *     Since I use postgres or mysql databases and smarty for outputting. The GreenWall
+   *     that I have constructed encapsulates these interfaces. Where possible I have made
+   *     the interfaces identical, so that programmers don't have to learn too much in order
+   *     to work with the green wall.
+   *
+   *     smarty = new Smarty();           becomes      smarty = new GreenWall->NewSmarty();
+   *     smarty->display( 'my.tpl' );                  smarty->display( 'my.tpl' );  
+   *
+   *     mysql_query( ... );              becomes      GreenWall->mysql_query( ... );
+   *     mysql_fetch_row( ... );
+   *
+   *     One last note, there is a difference between addslashes and mysql_real_escape_string,
+   *     you can read about one definite example here http://shiflett.org/archive/184
+   **/
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/MysqlDB.php';
+
+
+
+
+class GreenZone extends MysqlDB
+{
+  public $_GET;
+  public $_POST;
+
+  /**
+   * Constructor
+   *
+   *    DOES     - sets up the database aspect and stores the get and post data in new arrays
+   *    RECEIVES - Nothing
+   *    RETURNS  - Nothing
+   *    THROWS   - Nothing
+   **/
+
+  function __construct()
+  {
+    parent::__construct();
+    
+    global $_POST;
+    global $_GET;
+
+    if( !get_magic_quotes_gpc() )
+    {
+      $this->_GET = $this->SecureArray( $_GET );
+      $this->_POST = $this->SecureArray( $_POST );
+    }
+    else
+    {
+      $this->_GET = $_GET;
+      $this->_POST = $_POST;
+    }
+      
+    $log = null;
+  }
+
+
+  function get( $target )
+  {
+    return $this->_GET[$target];
+  }
+
+  function post( $target )
+  {
+    return $this->_POST[$target];
+  }
+
+
+  /**
+   * SecureArray 
+   *
+   *    DOES     - This function converts all strings in an array using mysql_real_escape_string.
+   *               It will also branch down to arrays in arrays.
+   *    RECEIVES - The array to secure
+   *    RETURNS  - A copy of the array that is secured
+   *    THROWS   - Nothing
+   **/
+  
+  function SecureArray( $source_array )
+  {
+    $result_array = array();
+    
+    if( is_array( $source_array ) )
+      {
+	foreach( $source_array as $source_name => $source_value )
+	  {
+	    if( is_array( $source_value ) )
+	      {
+		$result_array[ $source_name ] = SecureArray( $source_value );
+	      }
+	    else if( is_string( $source_value ) )
+	      {
+		$result_array[ $source_name ] = mysql_real_escape_string( $source_value );
+	      }
+	    else
+	      {
+		$result_array[ $source_name ] = $source_value;
+	      }
+	  }
+      }
+    
+    return $result_array;
+  }
+
+
+
+  /**
+   * ReleaseArray - remove the slashes from all the strings under an array.
+   **/
+
+  function ReleaseArray( $source_array )
+  {
+    $result_array = array();
+    
+    if( is_array( $source_array ) )
+      {
+	foreach( $source_array as $source_name => $source_value )
+	  {
+	    if( is_array( $source_value ) )
+	      {
+		$result_array[ $source_name ] = $this->ReleaseArray( $source_value );
+	      }
+	    else if( is_string( $source_value ) )
+	      {
+		$result_array[ $source_name ] = stripslashes( $source_value );
+	      }
+	    else
+	      {
+		$result_array[ $source_name ] = $source_value;
+	      }
+	  }
+      }
+    
+    return $result_array;
+  }
+
+
+
+
+
+
+
+  /**
+   * Wrapper for mysql_fetch_array
+   **/
+
+  function mysql_fetch_array( $result_set, $result_type = MYSQL_BOTH )
+  {
+    // Call fetch array to get the result set
+    // if we received a row as a result.
+    //     for each element in the row
+    //         if the element is a string
+    //             escape the string.
+    // return the row
+
+    $row = mysql_fetch_array( $result_set, $result_type );
+
+    if( $row !== FALSE )
+      {
+	foreach( $row as $next_name => $next_value )
+	  {
+	    if( is_string( $next_value ) )
+	      {
+		$row[ $next_name ] = mysql_real_escape_string( $next_value );
+	      }
+	  }
+      }
+
+    return $row;
+  }
+
+
+
+  /**
+   * smarty_assign - Wrapper for smarty->assign
+   **/
+
+  function smarty_assign( $smarty_object, $template_varname, $value )
+  {
+    $adjusted_value = '';
+
+    if( is_string( $value ) )
+      {
+	$adjusted_value = stripslashes( $value );
+      }
+    else if ( is_array( $value ) )
+      {
+	$adjusted_value = $this->ReleaseArray( $value );
+      }
+    else
+      {
+	$adjusted_value = $value;
+      }
+
+    $smarty_object->assign( $template_varname, $adjusted_value );
+  }
+
+
+
+  /**
+   * EnsureSecure
+   *
+   *    DOES     - Checks this projects code that violates the green zone.
+   *    RECEIVES - Nothing
+   *    RETURNS  - Nothing
+   *    THROWS   - A GreenZoneException "Green Zone insecure"
+   *    TODO     - implement this
+   **/
+
+  function EnsureSecure()
+  {
+    // echo 'No real checking yet, so thumbs up <br>';
+  }
+
+
+
+
+
+  /**
+   * CreateSmarty 
+   *
+   *    DOES     - This function creates a smarty object. Its just here so we can encapsulate
+   *               the calls to configure it.
+   *    RECEIVES - Nothing
+   *    RETURNS  - A new smarty object with its compile and template directories set.
+   *    THROWS   - Nothing
+   **/
+  
+  function CreateSmarty()
+  {
+    $smarty = new Smarty();
+
+    $smarty->template_dir = SMARTY_TEMPLATES_DIR;
+    $smarty->compile_dir = SMARTY_COMPILE_DIR;
+    
+    return $smarty;
+  }
+
+
+
+
+  /**
+   * ValidPassword
+   *
+   *    DOES     - Checks that the value given is a string greater than 7 characters.
+   *    RECEIVES - The password to test
+   *    RETURNS  - true or false, valid or invalid
+   *    THROWS   - Nothing
+   **/
+  
+  function ValidPassword( $target_password )
+  {
+    if( !is_string( $target_password ) )
+      {
+	SetLastError( 'Password needs to be a string' );
+	return false;
+      }
+    else if( strlen( $target_password ) < 8 )
+      {
+	SetLastError( 'Password must be atleast 8 characters' );
+	return false;
+    }
+    
+    return true;
+  }
+
+
+/**
+ * SetupLogFile
+ * 
+ *    DOES     - Creates a GZ_Logger object to handle logging requests
+ *    RECEIVES - The path to the log file
+ *    RETURNS  - Nothing
+ *    THROWS   - Nothing, an exception will be called when you try to write
+ *               an error to the file if its not writeable
+ **/
+  
+  public function SetupLogFile( $log_filename )
+  {
+    $this->log = new GZ_Logger( $log_filename );
+  }
+
+
+  
+  /**
+  * LogMessage
+  * 
+  *    DOES     - Write a message to the logfile
+  *    RECEIVES - An identifyer for the user, the main message, and some variable parameters
+  *    RETURNS  - Nothing
+  *    THROWS   - The GZ_Logger will throw an exception if it can't write to the log file
+  **/
+  
+  public function LogMessage( $user, $message, $param1, $param2, $param3 )
+  {
+    $this->log->LogMessage( $user, $message, $param1, $param2, $param3 );
+  }
+
+
+// PRIVATE
+    
+  private $log;
+
+
+};
+
+
+
+
+
+
+
+?>
Index: /trunk/htdocs2/GreenZone/Utils/MysqlDB.php
===================================================================
--- /trunk/htdocs2/GreenZone/Utils/MysqlDB.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Utils/MysqlDB.php	(revision 298)
@@ -0,0 +1,438 @@
+<?php
+
+
+
+/**
+ * Written by David Smith 2006-2008
+ * nopeer@gmail.com
+ **/
+
+
+
+require_once GREEN_ZONE_DIR . 'Utils/GZ_Exception.php';
+
+
+
+
+
+/**
+ * @class MysqlDBException
+ * @brief Simply an exception
+ **/
+
+class MysqlDBException extends GZ_Exception
+{
+};
+
+
+/**
+ * @class MysqlDB
+ *
+ * This class encapsulates a mysql database connection.
+ **/
+
+class MysqlDB
+{
+  var $link;
+  var $last_result;
+  var $last_query;
+  var $debug;
+  var $last_dataset;
+  var $last_dataset_index;
+
+
+
+  //! Constructor. Initialize defaults.
+
+  function __construct()
+  {
+    $this->link = null;
+    $this->last_query = null;
+    $this->last_result = null;
+    $this->last_dataset = Array();
+    $this->debug = 0;
+  }
+
+
+
+
+  //! Destructor. close the connection if it exists
+
+  function __destruct()
+  {
+    if( $this->link != null )
+      mysql_close( $this->link );
+  }
+
+
+  /**
+   * @brief                 Connects to the database using the values given
+   * @param target_host     The server with the mysql server
+   * @param target_user     The user to login to the database as
+   * @param target_password The password for the database user
+   * @param target_db       The database we want to open on the server
+   * @throws e              Throw an exception if we failed to connect to the server or couldn't
+   *                        select the database we wanted
+   **/
+
+  function connect( $target_host, $target_user, $target_password, $target_db )
+  {
+    if( ( $this->link = mysql_connect( $target_host, $target_user, $target_password ) ) === false )
+        throw new MysqlDBException( 'Failed to connect to host', 'MysqlDB::connect', FAILED_CALL );
+
+    if( mysql_select_db( $target_db, $this->link ) === false )
+        throw new MysqlDBException( 'Failed to select database ' . $target_db, 'MysqlDB::connect', FAILED_CALL );
+  }
+
+
+
+  /**
+   *    @brief     Makes sure we are connected to the remote host
+   *    @throws e  An exception if we are not connected to a remote host.
+   **/
+
+  function EnsureConnected()
+  {
+    if( !$this->link )
+        throw new MysqlDBException( 'Not connected to database', 'MysqlDB::EnsureConnected', DISCONNECTED );
+  }
+
+
+
+  /**
+    *    @brief       Performs a query using the sql given
+    *    @param sql   The query in SQL
+    *    @return      Nothing
+    *    @throws e    QUERY_FAILED, FAILED_CALL
+    *
+    *    Perform the sql query given, don't throw an exception if there are no rows returned,
+    *    simply set last_dataset as an empty array. Throw an exception for any other error.
+    **/
+
+  function DoQuery( $sql )
+  {
+    if( $this->debug )
+      echo 'DoQuery( ' . $sql . ') <br>';
+
+    $this->EnsureConnected();
+
+    $this->last_query = $sql;
+    if( ( $this->last_result = mysql_query( $sql ) ) === false )
+      throw new MysqlDBException( 'Query Failed: ' . $sql . ' : ' . mysql_error(), 'MysqlDB::DoQuery', QUERY_FAILED );
+
+    if( $this->last_result !== true )
+    {
+      $new_dataset = Array();
+
+      $num_records = $this->FetchNumRows();
+
+      for( $ind = 0; $ind < $num_records; $ind ++ )
+      {
+        if( ( $new_row = mysql_fetch_array( $this->last_result, MYSQL_ASSOC ) ) === false )
+          throw( new MysqlDBException( 'Failed to fetch row ' . $this->last_query, 'MysqlDB::DoQuery', 5 ) );
+
+        $new_dataset[] = $new_row;
+      }
+      $this->last_dataset = $new_dataset;
+      $this->last_dataset_index = 0;
+    }
+  }
+
+
+
+
+
+
+  /**
+   * @brief             Checks that the correct number of rows have been returned
+   * @param comparison  The comparison to perform {equals, lessthan or greaterthan}
+   * @param num         The value to compare against
+   * @throws e          Throw an exception if the condition is not met.
+   **/
+
+  function EnsureNumRows( $comparison, $num )
+  {
+    $this->EnsureConnected();
+
+    $num_rows = mysql_num_rows( $this->last_result );
+
+    if( $comparison != 'equals' && $comparison != 'lessthan' && $comparison != 'greaterthan' )
+      throw new MysqlDBException( 'Unknown comparison ' . $comparison, 'MysqlDB::EnsureNumRows', INVALID_PARAM );
+
+    if( $comparison == 'equals' && $num != $num_rows )
+      throw new MysqlDBException( 'num rows failed equality' . $this->last_query, 'MysqlDB::EnsureNumRows', OUT_OF_RANGE );
+    else if( $comparison == 'lessthan' && $num_rows >= $num )
+      throw new MysqlDBException( 'num rows failed < comparison' . $this->last_query, 'MysqlDB::EnsureNumRows', OUT_OF_RANGE );
+    else if( $comparison == 'greaterthan' && $num_rows <= $num )
+      throw new MysqlDBException( 'num rows failed > comparison' . $this->last_query, 'MysqlDB::EnsureNumRows', OUT_OF_RANGE );
+  }
+
+
+
+  /**
+   *    @brief    Fetch the number or rows that were returned by the last result.
+   *    @returns  The number of rows in the last result
+   **/
+
+  function FetchNumRows()
+  {
+    $this->EnsureConnected();
+
+    $num_rows = mysql_num_rows( $this->last_result );
+
+    return $num_rows;
+  }
+
+
+
+  /**
+   *    @brief    Fetch the next row from the result of the last query
+   *    @returns  An associative array containing the record fetched
+   *    @throws e An exception if we have gone beyond the number of rows returned
+   **/
+
+  function FetchRowAsArray()
+  {
+    if( $this->last_dataset_index >= $this->FetchNumRows() )
+      throw new MysqlDBException( 'fetching row out of range', 'MysqlDB::FetchRowAsArray', OUT_OF_RANGE );
+
+    return $this->last_dataset[ $this->last_dataset_index ++ ];
+  }
+
+
+
+  /**
+   *    @brief     - Gets the id of the tuple inserted during the last insert query.
+   *    RECEIVES - Nothing.
+   *    @returns  - The last insert id.
+   *    @throws   - An excpetion for any sql errors encountered.
+   **/
+
+  function GetInsertID()
+  {
+    $this->EnsureConnected();
+
+    if( ( $id = mysql_insert_id( $this->link ) ) === false )
+      throw new MysqlDBException( 'Unable to retreive insert id', 'MysqlDB::EnsureConnected', FAILED_CALL );
+
+    return $id;
+  }
+
+
+
+  /**
+    *   @brief     - Retreives the tuples from the last result and returns them in an array
+    *   @returns  - An array of tuples containing the last result
+    *   @throws   - Any database exception.
+    **/
+
+  function GetLastResult()
+  {
+    return $this->last_dataset;
+  }
+
+
+
+
+
+  /**
+   * @brief             Selects all the rows from the table given that have fields matching the pairs in the array
+   * @param table_name  The name of the table to select from
+   * @param field_specs An associative array of fields to form the WHERE clause from
+   * @returns           An array of tuples from the table
+   * @throws e          Any database exception
+   * @example e         $row = SelectByFields( 'users', Array( 'name' => 'nopeer' ) );
+   **/
+
+  function SelectByFields( $table_name, $field_specs )
+  {
+    $select_sql = ' SELECT * FROM ' . $table_name . ' WHERE ';
+
+    $first = true;
+    foreach( $field_specs as $next_field => $next_value )
+    {
+      if( !$first )
+        $select_sql .= ' AND ';
+      $select_sql .= $next_field . ' = ';
+      if( !is_numeric( $next_value ) )
+        $select_sql .= '\'';
+
+      $select_sql .= $next_value;
+
+      if( !is_numeric( $next_value ) )
+        $select_sql .= '\'';
+
+      $first = false;
+    }
+
+    if( $this->debug )
+      echo $select_sql . ' <br> ';
+
+    $this->DoQuery( $select_sql );
+
+    return $this->GetLastResult();
+  }
+
+
+
+  /**
+   *   @brief   Sets the set_fields on any record with matching match_fields int table table_name
+   *   @param   table_name   Name of the sql table
+   *   @param   set_fields   The fields to set
+   *   @param   match_fields An array of fields to use in a WHERE clause
+   *   @throws  e            Any database exception.
+   *   @todo                 Nothing
+   **/
+
+  function SetFieldsByFields( $table_name, $set_fields, $match_fields )
+  {
+    if( count( $set_fields ) < 2 || count( $match_fields ) < 2 )
+      throw( new MysqlDBException( 'SetFieldsByFields: Need atleast 2 args to set fields and 2 to match fields.', 
+                              'MysqlDB::SetFieldsByFields', OUT_OF_RANGE ) );
+
+    $update_sql = ' UPDATE ' . $table_name . ' SET ';
+
+    for( $i = 0; $i < count( $set_fields ); $i += 2 )
+    {
+      if( 0 != $i )
+        $update_sql .= ', ';
+
+      $update_sql .= $set_fields[$i] . ' = ';
+      if( !is_numeric( $set_fields[$i+1] ) )
+        $update_sql .= '\'';
+
+      $update_sql .= $set_fields[$i+1];
+      if( !is_numeric( $set_fields[$i+1] ) )
+        $update_sql .= '\'';
+    }
+
+    $update_sql .= ' WHERE ';
+
+    for( $i = 0; $i < count( $match_fields ); $i += 2 )
+    {
+      if( $i != 0 )
+        $update_sql .= ' AND ';
+      $update_sql .= $match_fields[$i] . ' = ';
+
+      if( !is_numeric( $match_fields[$i+1] ) )
+        $update_sql .= '\'';
+
+      $update_sql .= $match_fields[$i+1];
+
+      if( !is_numeric( $match_fields[$i+1] ) )
+        $update_sql .= '\'';
+    }
+
+    if( $this->debug )
+      echo $update_sql;
+
+    $this->DoQuery( $update_sql );
+  }
+
+
+
+  /**
+   *   @brief   Inserts a new record into the table given with the field values given
+   *   @param   table_name  The table to insert the fields into
+   *   @param   field_specs An array(not associative) of field/value pairs to create the new record from.
+   *   @throws  e           Any database exception.
+   *   @example usage       InsertWithFields( 'users', Array( 'name', 'dave', 'email', 'nopeer@gmail.com' ) );
+   **/
+
+  function InsertWithFields( $table_name, $field_specs )
+  {
+    $insert_sql = ' INSERT INTO ' . $table_name . ' ( ';
+
+    for( $i = 0; $i < count( $field_specs ); $i += 2 )
+    {
+      if( $i != 0 )
+        $insert_sql .= ', ';
+
+      $insert_sql .= $field_specs[$i];
+    }
+
+    $insert_sql .= ' ) VALUES ( ';
+
+    for( $i = 1; $i < count( $field_specs ); $i += 2 )
+    {
+      if( $i != 1 )
+        $insert_sql .= ', ';
+
+      $insert_sql .= '\'' . $field_specs[$i] . '\'';
+    }
+    $insert_sql .= ' ) ';
+
+    if( $this->debug )
+      echo $insert_sql . '<br>';
+
+    $this->DoQuery( $insert_sql );
+  }
+
+
+
+  /**
+   *   @brief   Insert the given associative array as a new record into the table
+   *   @param   table_name  The table to insert the new row into
+   *   @param   tuple       An associative array representing the record
+   *   @throws  e           Any database exception.
+   *   @example usage       InsertTupleUsingAssoc( 'users', Array( 'name' => 'dave', 'email' => 'nopeer@gmail.com' ) );
+   **/
+
+  function InsertTupleUsingAssoc( $table_name, $tuple )
+  {
+    $insert_sql = ' INSERT INTO ' . $table_name . ' ( ';
+
+    $num_fields = count( $tuple );
+    $ind = 1;
+    foreach( $tuple as $next_name => $next_value )
+    {
+      $insert_sql .= $next_name . ' ';
+      if( $ind < $num_fields )
+        $insert_sql .= ', ';
+      $ind ++;
+    }
+    $insert_sql .= ' ) VALUES ( ';
+
+    $ind = 1;
+    foreach( $tuple as $next_name => $next_value )
+    {
+      if( is_string( $next_value ) || $next_value == null )
+        $insert_sql .= '"' . $next_value . '" ';
+      else
+        $insert_sql .= $next_value;
+      if( $ind < $num_fields )
+        $insert_sql .= ', ';
+      $ind ++;
+    }
+    $insert_sql .= ' ) ';
+
+    if( $this->debug )
+      echo $insert_sql . '<br>';
+
+    $this->DoQuery( $insert_sql );
+  }
+
+  //! turn on debugging
+
+  function Debug()
+  {
+    $this->debug = 1;
+  }
+
+  //! turn off debugging
+
+  function EndDebug()
+  {
+    $this->debug = 0;
+  }
+
+};
+
+
+
+
+
+
+
+
+?>
Index: /trunk/htdocs2/GreenZone/Utils/StringUtils.php
===================================================================
--- /trunk/htdocs2/GreenZone/Utils/StringUtils.php	(revision 298)
+++ /trunk/htdocs2/GreenZone/Utils/StringUtils.php	(revision 298)
@@ -0,0 +1,204 @@
+<?php 
+
+/**
+ * Written by David Smith
+ * nopeer@gmail.com
+ *
+ * I have found these string functions to be generally usefull.
+ **/
+
+
+
+
+/**
+ * This function advances the string to just after the target string given.
+ **/
+
+function AdvanceStringTo( $source_string, $target_string )
+{
+  if( strpos( $source_string, $target_string ) === FALSE )
+    return FALSE;
+  else
+    return substr( $source_string, strpos( $source_string, $target_string ) + strlen( $target_string ) );
+}
+
+
+
+/**
+ * This function returns the contents of the source string between the next occurance of the
+ * two tags given. If advance is set to true, the advance the string to after the second tag.
+ **/
+
+function NextStringBetween( &$source_string, $first_tag, $second_tag, $advance = FALSE )
+{
+  $start_pos = strpos( $source_string, $first_tag );
+  if( $start_pos === FALSE )
+    return FALSE;
+  
+  $start_pos += strlen( $first_tag );
+  $end_pos = strpos( $source_string, $second_tag, $start_pos );
+  if( $end_pos === FALSE )
+    return FALSE;
+
+  $result = substr( $source_string, $start_pos, $end_pos - $start_pos );
+
+  if( $result !== FALSE && $advance )
+    {
+      $full_tag = $first_tag . $result . $second_tag;
+      $source_string = substr( $source_string, strpos( $source_string, $full_tag ) + strlen( $full_tag ) );
+    }
+
+  return $result;
+}
+
+
+
+
+
+/**
+ * This function returns the substring of the string given up to
+ * the start of the second string given. If the second string is
+ * not within the first, it will return the entire string.
+ **/
+
+function GetStringUpTo( $source, $delimiter )
+{
+  $length = strpos( $source, $delimiter );
+  if( $length === FALSE )
+    $length = strlen( $source );
+
+  return substr( $source, 0, $length );
+}
+
+
+
+/**
+ * StartsWith
+ *
+ *    DOES     - tells you if the first string starts with the second
+ *    RECEIVES - a source and search string
+ *    RETURNS  - true if the first string starts with the second string
+ *    THROWS   - Nothing
+ **/
+
+function StartsWith( $source, $search )
+{
+  if( substr( $source, 0, strlen( $search ) ) == $search )
+    {
+      return true;
+    }
+
+  return false;
+}
+
+
+
+
+/**
+ * MakeCurrency
+ *
+ * DOES		- converts a string to have 2 decinal places.
+ **/
+
+function MakeCurrency( &$src_string )
+{
+  if( is_numeric( $src_string ) )
+  {
+	  $src_string = '$' . number_format( $src_string, 2 );
+  }
+}
+
+
+
+
+ /**
+ * @brief     Add a string to a filename before its extension
+ * @example e AddPreExtension( "testing.txt", "_this" ) will return "testing_this.txt"
+ * @example f AddPreExtension( "testing", "_this" ) will return "testing_this"
+ * @example g AddPreExtension( "can.we.test.txt", "_this" ) will return "can.we.test_this.txt"
+ **/
+
+function AddPreExtension( $str, $pre_ext )
+{
+  $result = $str . $pre_ext;
+
+  if( strpos( $str, '.' ) !== false )
+  {
+    $last_dot = strrpos( $str, '.' );
+    $result = substr( $str, 0, $last_dot - 1);
+    $ext = substr( $str, $last_dot );
+
+    $result .= $pre_ext;
+    $result .= $ext;
+  }
+
+  return $result;
+}
+
+
+/**
+  * remove extra whitespace, if we have more than one consecutive delimiter
+  * character, then reduce it to 1.
+  *
+  *  note we are not in a run of delim characters
+  *  for each character in the line
+  *    if this is a delim character
+  *      if we are not in a run
+  *        note that we are now in a run
+  *        put the character in the output line
+  *    otherwise
+  *      put the character in the output line
+  *      note that we are no longer in a run
+  **/
+function eatwhite( $line, $delim = ' ' )
+{
+  $out = '';
+  $run = false;
+  for( $i = 0; $i < strlen($line); $i ++ )
+  {
+    if( $line[$i] == $delim )
+    {
+      if( !$run )
+      {
+	$run = true;
+	$out .= $delim;
+      }
+    }
+    else
+    {
+      $run = false;
+      $out .= $line[$i];
+    }
+  }
+  return $out;
+}
+
+/**
+  * Get the nth word from a line of text, words are delimited by delim
+  * default is space.
+  *
+  *  set the position of the current word to 0
+  *  count from zero to n-1
+  *    set the position of the current word to the next delimiter + 1
+  *  if there are no more delimiters after the current word
+  *    return from the current word to the end of string
+  *  otherwise
+  *    return from the current word to the next delimiter - 1
+  **/
+
+function strword( $line, $n, $delim = ' ' )
+{
+  $current = 0;
+  for( $i = 0; $i < $n; $i ++ )
+    $current = strpos( $line, $delim, $current ) + 1;
+
+  $next = strpos( $line, $delim, $current );
+  if( $next === false )
+    return substr( $line, $current );
+  else
+  {
+    return substr( $line, $current, $next - $current );
+  }
+}
+
+?>
Index: /trunk/htdocs2/GreenZone/templates/GZ_Table.tpl
===================================================================
--- /trunk/htdocs2/GreenZone/templates/GZ_Table.tpl	(revision 298)
+++ /trunk/htdocs2/GreenZone/templates/GZ_Table.tpl	(revision 298)
@@ -0,0 +1,27 @@
+<table id="{$html_id}" class="{$table_class}">
+  <tr class="{$thr_class}">
+    <th><button name=RealAction value={$html_id}SelectAll>Select All</button></th>
+    {section name=h loop=$headings}
+      <th class={$th_class}> {$headings[h]} </th>
+    {/section}
+  </tr>
+  {section name=r loop=$data_set}
+    <tr class={$tr_class}>
+      <td>
+        <input type=checkbox name={$html_selections_id}[] value="{$data_set[r].id}"
+          {section name=i loop=$selected_ids} 
+            {if $selected_ids[i] == $data_set[r].id} CHECKED {/if}
+          {/section}
+        >
+      </td>
+      {section name=cell loop=$data_set[r].cells}
+        <td class="{$td_class}"> 
+          {$data_set[r].cells[cell]}
+          {section name=child loop=$data_set[r].children}
+              <br> {$data_set[r].children[child]}
+          {/section} 
+        </td>
+      {/section}
+    </tr>
+  {/section}
+</table>
Index: /trunk/htdocs2/TestClass.php
===================================================================
--- /trunk/htdocs2/TestClass.php	(revision 298)
+++ /trunk/htdocs2/TestClass.php	(revision 298)
@@ -0,0 +1,16 @@
+<?php
+
+
+
+/**
+    * This file will take the "class" argument from the url line and open 
+ **/
+
+$class = $_GET['class'];
+$subdir = $_GET['subdir'];
+
+require_once './Classes/' . $subdir . '/' . $class . '.php';
+
+eval( 'Test' . $class . '();' );
+
+?>
Index: /trunk/htdocs2/TestClasses.php
===================================================================
--- /trunk/htdocs2/TestClasses.php	(revision 298)
+++ /trunk/htdocs2/TestClasses.php	(revision 298)
@@ -0,0 +1,60 @@
+<?php
+
+
+
+require_once 'config.php';
+require_once GREEN_ZONE_DIR . 'Utils/StringUtils.php';
+
+
+
+/**
+ * This file will test all the classes it can find
+ **/
+
+// get all the names of all the functional classes (exclude test classes)
+
+$all_lines = Array();
+$ret_val = '';
+exec( 'find ./Classes/ -name "*.php" | grep -v Classes/Tests/', $all_lines, $ret_val );
+
+$class_names = Array();
+foreach( $all_lines as $next_filename )
+{
+  $class_names[] = strword( strword( $next_filename, 3, '/' ), 0, '.' );
+}
+
+// get the names of all the classes that we have tests for
+
+$all_lines = Array();
+exec( 'find ./Classes/Tests/ -name "*.php"', $all_lines, $ret_val );
+
+$test_class_names = Array();
+foreach( $all_lines as $next_filename )
+{
+  require_once $next_filename;
+  $test_class_names[] = AdvanceStringTo( strword( strword( $next_filename, 3, '/' ), 0, '.' ), 'Test' );
+}
+
+// output the list of untested classes
+
+echo '<H3> The following classes have no associated tests </H3>';
+foreach( $class_names as $class )
+{
+  if( !in_array( $class, $test_class_names ) )
+    echo $class . '<br>';
+}
+
+// Now iterate through all the actual tests
+
+echo '<H3> Perform all the tests we have </H3>';
+
+foreach( $test_class_names as $next_class )
+{
+  echo '<b>' . $next_class . '</b><br><br>';
+  eval( '$test = new Test' . $next_class . '();' );
+  $test->TestIt();
+  echo '<br>';
+}
+
+
+?>
Index: /trunk/htdocs2/config.php
===================================================================
--- /trunk/htdocs2/config.php	(revision 298)
+++ /trunk/htdocs2/config.php	(revision 298)
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Written by David Smith
+ * nopeer@gmail.com
+ *
+ * For ATNF CSIRO
+ *
+ * This file defines some basic configuration parameters
+ * - use the DEBUG constant for debugging output, set to 0 on production server
+ * - Where smarty is and the directories it uses for templates and compiling
+ * - The database parameters username,password etc
+ **/
+
+
+
+
+define( 'DEBUG', '1' );
+
+define( 'SMARTY_DIR', './smarty/libs/' );
+define( 'SMARTY_TEMPLATES_DIR', './templates/' );
+define( 'SMARTY_COMPILE_DIR', './templates_c/' );
+
+require_once SMARTY_DIR . 'Smarty.class.php';
+
+define ( 'DB_HOST', 'localhost' );
+define ( 'DB_USER', 'pulsar' );
+define ( 'DB_PASSWD', 'lighthouse' );
+define ( 'DB_NAME', 'psrchive' );
+
+define ( 'GREEN_ZONE_DIR', './GreenZone/' );
+
+define( 'PSRHOME', '/usr/local/work/psrhome' );
+define( 'FIX_LD_LIB', 'env PSRHOME=' . PSRHOME . ' ' );
+define( 'PAV_CMD', PSRHOME . '/bin/pav' );
+define( 'PSRCAT_CMD', PSRHOME, '/bin/psrcat' );
+define( 'VAP_CMD', PSRHOME . '/bin/vap' );
+define( 'PSRADD_CMD', '/bin/psradd' );
+define( 'PSRSH_CMD', '/bin/psrsh' );
+
+
+?>
Index: /trunk/htdocs2/index.php
===================================================================
--- /trunk/htdocs2/index.php	(revision 298)
+++ /trunk/htdocs2/index.php	(revision 298)
@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * Written by David Smith
+ * nopeer@gmail.com
+ *
+ * For ATNF CSIRO
+ *
+ **/
+
+
+// NOTE, we need to include the definitions of all the classes that we might be storing in session
+// date before we start the session. Clearly something has changed and php must now be instantiated
+// these classes when the session starts, as opposed to when we request them (which im sure used to
+// be the case).
+require_once 'Forms/QueryFormParameters.php';
+require_once 'Classes/Model/Observation.php';
+require_once 'Classes/Astro/MJD.php';
+require_once 'Classes/General/Date.php';
+
+
+
+
+session_start();
+
+
+
+require_once './config.php';
+require_once GREEN_ZONE_DIR . 'Utils/GreenZone.php';
+require_once GREEN_ZONE_DIR . 'Utils/GZ_Logger.php';
+require_once 'Forms/ArchivePage.php';
+require_once 'Classes/Astro/Band.php';
+
+
+
+try
+{
+  list($month, $year) = split(' ', date( 'n Y' ));
+  
+  $gz = new GreenZone();
+  $gz->SetupLogFile( './logs/' . $year . $month . '.log' );
+  $gz->connect( DB_HOST, DB_USER, DB_PASSWD, DB_NAME );
+  $gz->EnsureSecure();
+
+  // add code here to setup static variables
+  Band::SetupStaticData();
+
+  $page = new ArchivePage( $gz );
+  $page->ReadForm();
+  $page->ProcessActions();
+  $page->Display();
+  $page = NULL;
+}
+catch( Exception $e )
+{
+  // TODO make better error handling output
+  echo 'The following unhandled exception was encountered: ' . $e->getMessage() . '<BR>';
+}
+
+
+session_write_close();
+
+?>
Index: /trunk/htdocs2/pulsar_archive_guide.html
===================================================================
--- /trunk/htdocs2/pulsar_archive_guide.html	(revision 298)
+++ /trunk/htdocs2/pulsar_archive_guide.html	(revision 298)
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html>
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="styles/standard.css" />
+<link rel="stylesheet" type="text/css" href="styles/atnf.css" />
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8759-1" />
+<meta name="DC.Creator" lang="en" content="personalName=Whiting,Matthew" />
+<meta name="ATNF.Maintainer" content="contactName=Webmaster,the" />
+<meta name="DC.Title.alt" lang="en" content="" />
+<meta name="DC.Subject" lang="en" content="pulsar" />
+<meta name="DC.Description" lang="en" content="Provides a user's guide to the Pulsar Data Archive." />
+<meta name="DC.Date.created" scheme="ISO8601" content="2002-12-12" />
+<meta name="ATNF.Site" content="Marsfield" />
+<meta name="ATNF.AccessPermission" content="Public" />
+<meta name="ATNF.MetaVersion" content="1.0" />
+</head>
+<title>ATNF Pulsar Data Archive: Users Guide</title>
+<body>
+<?php
+include_once("header.html");
+include_once("constants.php");
+?>
+
+<div class="bodycontents">
+
+<table class="top_menu" border="0px" frame="void">
+  <tr class="top_menu">
+    <td class="top_menu"  align="left" width="30%">
+      <a href="index.php">Return to Query page</a>
+    </td>
+  </tr>
+</table>
+    
+<h1>ATNF Pulsar Data Archive: Users Guide</h1>
+
+<center><i>This page is still under construction!</i></center>
+
+<h2>Introduction</h2>
+
+<p>The ATNF Pulsar Data Archive exists to allow astronomers access to
+observations of pulsars made with the Parkes radio telescope in the
+last two decades.</p>
+
+<p>The data comes either from the Parkes Southern Pulsar Survey (the
+"70cm Survey", Manchester et al. 1996, MN 279, 1235), or from 
+observations of known pulsars with one of the Parkes instruments (WBC,
+DFB, CPSR2). We hope to make available data from the Multibeam Survey
+at some point in the near future.</p>
+
+<h2>Using the archive</h2>
+
+<h3>Overview</h3>
+
+<p>The Pulsar Data Archive provides a means for accessing observational
+data. Queries are made according to position on the sky and can be
+filtered by parameters such as data type and date.</p>
+
+<p>To download data, selections are made from the query results. These
+are stored in a "cart" from which they can be downloaded as a tar
+file. </p>
+
+<h3>Data access and availability</h3>
+
+<p>ATNF pulsar data has a <?php echo PROPRIETRY_PERIOD_MONTH; ?> month
+proprietary period. All data older than this is publicly available,
+but access to proprietary data is restricted to those involved in the
+project under which the data was taken.</p>
+
+<p>To manage the access to data, we have two forms of access to the
+archive. Anonymous access allows access only to the non-proprietary
+data. Proprietary data from a project you were involved in is obtained
+by logging in with your email and OPAL password, with the same OPAL
+account you use for proposals. This will then verify that you were
+involved in the project (by use of the Project ID), and allow you
+access.</p>
+
+<p><b>Note (Feb 18):</b> At present, the use of OPAL authentication
+has not been enabled, and anonymous access is the only option (unless
+you obtained a login for the testing version of the archive). This
+will be rectified in the very near future.</p>
+
+<h3>How to make queries</h3>
+
+<p>The data is queried primarily on positional information. The user
+gives either a pulsar name or a RA/Dec position, plus a search
+radius. The pulsar name takes precedence over the RA/Dec position
+given, so to search by RA/Dec, make sure the pulsar name field is
+empty.</p>
+
+<p>The search-by-name searches for files that either have the given
+pulsar name in their "src_name" field, or have an RA/Dec position
+within the given search radius of the pulsar. The pulsar's position is
+taken from the <a
+href="http://www.atnf.csiro.au/research/pulsar/psrcat/">ATNF Pulsar
+Catalogue</a>.</p>
+
+<p><b>Important:</b> When doing the position search, the beam size of
+the telescope is taken into account. For a given observation, there is
+a primary beam size, and if the primary beam intersects the search
+circle (i.e. the circle on the sky centred at the query position with
+radius equal to the search radius), then the observation is
+accepted.</p> 
+
+<h3>Query options</h3>
+
+<p>The query can be refined according to a number of parameters:
+<ul>
+  <li> Time: A time range for the observations can be specified. The
+  default values for this are given by the extent of the archive
+  (ie. the default "from" date is the earliest observation, and the
+  default "to" date is the latest).
+  <li> Obs Mode: The query can be restricted to only survey data (just
+  the 70cm survey for the moment), or only timing data
+  (ie. observations of a particular pulsar). The default is both
+  types.
+  <li> Data Type: One of the different instruments (WBC, DFB, CPSR2,
+  FB_1BIT) can be selected. The default is all of them.
+  <li> Frequency range: Multiple frequency bands can be selected from
+  the list.
+</ul></p>
+
+<p>The list of options on the left hand side shows the possible
+parameters that can be returned with your query. Note that not all
+fields will have values for all observations.</p>
+
+<p>The list can be ordered according to a limited range of these
+parameters: distance (from the query position - the default), date of
+observation, frequency, and filename.</p>
+
+<p>Finally, it is possible to search for calibration observations that
+were taken within a given time period of the science observations. To
+do so, check the box under "DISPLAY OTHER DATA" and set the time limit
+in which to search for Cals (the default is 30 minutes).</p>
+
+<h3>Navigating around the archive</h3>
+
+<p>The first page returned when you submit your query is the list of the
+first (up to) 20 observations. Only 20 observations are displayed at a
+time. You can move through the list by clicking on the page numbers
+above or below the table.</p>
+
+<p>Note that a limit of 1000 results is returned for the query -- if you
+are getting more than this, perhaps you can afford to narrow your
+search!</p>
+
+<p>In the top right, you will find information on the number of files and
+total size of the cart, as well as a navigation icon. When the Query
+Results page is displayed, the icon shown is that of the cart.
+Alternatively, when the list of cart items is displayed, the icon
+shown is that of the results table. Clicking on the icon takes you to
+the page depicted.</p>
+
+<center>
+<table cellpadding="0" cellspacing="0" border="0" width="200px"
+  cellhalign="center" frame="void">
+  <tbody>
+    <tr>
+      <td align="center">
+	<img alt="Cart icon" border="0" title="Cart icon" src="/images/cart_30px_white.png"></img>
+      </td>
+     <td align="center">
+       <img alt="Table icon" border="0" title="Table icon" src="/images/table_30px_white.png"></img>
+     </td>
+   </tr>
+   <tr>
+   <td align="center">
+     Cart Icon
+   </td>
+   <td align="center">
+     Table Icon
+   </td>
+  </tr>
+ </tbody>
+</table>
+</center>
+
+<h3>Viewing profiles of pulsars</h3>
+
+<p>For some types of data, it is possible to view a pre-scrunched pulse
+profile. To do so, select the observations using the check boxes in
+the table, and select "View selected profiles" from the drop-down
+menu. This will display profile plots for all selected observations,
+unless they are unable to be pre-scrunched (for instance, survey
+observations).</p>
+
+<p>To return to the results table, click the table icon at top right.</p>
+
+<h3>Downloading data</h3>
+
+<p>Since there can be a large number of query results, spread over many
+pages, we have implemented the observation cart to act as a staging
+post for downloading data. Desired data is first saved to the cart
+using the drop-down menu, by selecting its check box. From the cart
+page, the drop-down menu offers the option of downloading either just
+the data or the data plus any cals that have been found. The data is
+returned in a tar file that can be saved to a local disk.</p>
+
+<h3>Caveats</h3>
+
+<p>The archive is still in a developmental stage, albeit a fairly
+complete one. The main area that needs some work is that many fields
+for a lot of the data files are not filled in. This will be rectified
+in the near future, but be aware that not all information will be
+present. Also note that not all fields <i>can</i> be filled in for
+each data file: e.g. survey data cannot have a period defined.</p>
+
+<h2>Acknowledgments</h2>
+
+</div>
+
+<?php include_once("footer.html"); ?>
+</body>
+</html>
+
+
Index: /trunk/htdocs2/scripts/expandable.js
===================================================================
--- /trunk/htdocs2/scripts/expandable.js	(revision 298)
+++ /trunk/htdocs2/scripts/expandable.js	(revision 298)
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+function toggleInstructions()
+{
+  var div = document.getElementById( "divInstructions" ) ;
+  if ( div.style.display == 'none' || div.style.display == '' )
+  div.style.display = "block" ;
+  else div.style.display = "none" ;
+}
Index: /trunk/htdocs2/smarty/BUGS
===================================================================
--- /trunk/htdocs2/smarty/BUGS	(revision 298)
+++ /trunk/htdocs2/smarty/BUGS	(revision 298)
@@ -0,0 +1,7 @@
+Smarty is supported only in PHP 4.0.6 or later.
+
+Smarty versions previous to 2.0 require the PEAR libraries. Be sure to include
+the path to the PEAR libraries in your php include_path. Config_file.class.php
+uses the PEAR library for its error handling routines. PEAR comes with the PHP
+distribution. Unix users check /usr/local/lib/php, windows users check
+C:/php/pear.
Index: /trunk/htdocs2/smarty/COPYING.lib
===================================================================
--- /trunk/htdocs2/smarty/COPYING.lib	(revision 298)
+++ /trunk/htdocs2/smarty/COPYING.lib	(revision 298)
@@ -0,0 +1,466 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
Index: /trunk/htdocs2/smarty/ChangeLog
===================================================================
--- /trunk/htdocs2/smarty/ChangeLog	(revision 298)
+++ /trunk/htdocs2/smarty/ChangeLog	(revision 298)
@@ -0,0 +1,8667 @@
+2007-03-06  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      fix html_select_date separator when parts are missing (thanks to kayk for
+      the patch)
+
+2007-03-06  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      bumped version number
+
+    * NEWS:
+      added release headline
+
+    * libs/internals/core.write_compiled_include.php:
+      fixed detection of non-cached block when writing compiled includes
+
+2007-03-01  Danilo Buerger  <danilo@blizzz.org>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      Applied boots clean up patch and removed commented out code.
+      Updated NEWS file
+
+2007-02-27  Danilo Buerger  <danilo@blizzz.org>
+
+    * NEWS
+      docs/en/designers/language-modifiers/language-modifier-date-format.xml
+      libs/internals/core.write_file.php
+      libs/plugins/modifier.date_format.php:
+      Updated smarty_core_write_file() and smarty_modifier_date_format() to speed
+      up Windows detection.
+      Emulated more parameters for Windows in smarty_modifier_date_format() and
+      fixed some old ones.
+      Updated the docs to tell what parameters are emulated on Windows.
+      Updated NEWS file.
+
+    * NEWS:
+      Updated NEWS file to reflect changes commited in the last revision
+
+2007-02-27  Monte Ohrt  <monte@ohrt.com>
+
+    * docs/en/appendixes/troubleshooting.xml:
+      fix typo
+
+2007-02-27  Danilo Buerger  <danilo@blizzz.org>
+
+    * libs/Smarty_Compiler.class.php:
+      Modified _(push|pop)_cacheable_state() to embedd alternate syntax. See this
+      bug report: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=10502
+
+2007-02-26  Peter 'Mash' Morgan  <pm@daffodil.uk.com>
+
+    * docs/en/designers/language-custom-functions/language-function-html-options.xml:
+      Fix incorrect var name
+
+2007-02-23  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/Smarty_Compiler.class.php:
+      escape creating of language=php from interleaving
+
+    * libs/Smarty_Compiler.class.php:
+      add removed line back in
+
+    * libs/Smarty_Compiler.class.php:
+      fix up last patch, remove unnecessary lines
+
+    * libs/Smarty_Compiler.class.php:
+      fix situation when no compiled tags are present
+
+    * libs/Smarty_Compiler.class.php:
+      fix problem with php open tags generated from tag interleaving
+
+2007-02-06  boots  <jayboots@yahoo.com>
+
+    * docs/en/programmers/advanced-features/template-resources.xml:
+      Correct default template handler function example.
+
+2007-01-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/modifier.truncate.php:
+      fixed handling of $etc in the truncate modifier when $etc is longer
+      than $length.
+      
+      thanks to Sylvinus!
+
+2007-01-10  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/plugins/modifier.date_format.php
+      libs/plugins/modifier.date_format.php:
+      fix handling of %I with mysql timestamps
+      
+      Thanks to Danilo Buerger
+
+    * NEWS
+      libs/internals/core.write_file.php:
+      Better recognize Windows filesystems to reduce warnings
+
+    * NEWS
+      libs/plugins/modifier.date_format.php:
+      Emulate %R in the date_format modifier on Windows
+      
+      Thanks to Danilo Buerger
+
+2006-12-10  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/getting-started.xml:
+      fix build
+
+    * docs/fr/language-snippets.ent
+      docs/fr/designers/language-builtin-functions/language-function-include-php.xml
+      docs/fr/designers/language-modifiers/language-modifier-truncate.xml
+      docs/fr/designers/language-variables/language-variables-smarty.xml:
+      sync with EN
+
+2006-12-02  Peter 'Mash' Morgan  <pm@daffodil.uk.com>
+
+    * docs/en/designers/language-builtin-functions/language-function-include-php.xml:
+      Tidy example, speeling andd add links
+
+    * docs/en/getting-started.xml:
+      Add/correct entities
+
+    * docs/entities/global.ent:
+      Fix entities (strange)
+
+2006-12-01  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update dev version numbers
+
+2006-12-01  boots  <jayboots@yahoo.com>
+
+    * (Smarty_2_6_16)
+      NEWS:
+      Fixed replacement bug introduced in trimwhitespaces output filter that
+      was introduced in the last release.
+      
+      Thanks to Spuerhund from the forums.
+
+    * (Smarty_2_6_16)
+      libs/plugins/outputfilter.trimwhitespace.php:
+      Fixed replacement bug introduced by last changes.
+      
+      Thanks to Spuerhund from the forums.
+
+2006-11-30  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      docs/en/designers/language-modifiers/language-modifier-truncate.xml
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update dev version numbers, fix manual typo
+
+2006-11-22  George Miroshnikov  <support@infinity.com.ua>
+
+    * docs/ru/getting-started.xml
+      docs/ru/language-snippets.ent:
+      sync with EN
+
+    * docs/en/getting-started.xml:
+      replaced hardcoded path separator with PATH_SEPARATOR constant
+
+2006-11-20  boots  <jayboots@yahoo.com>
+
+    * libs/plugins/modifier.debug_print_var.php:
+      fix depth formatting of arrays and objects in modifier debug_print_var
+
+2006-11-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/en/designers/language-variables/language-variables-smarty.xml:
+      fixed typo. thanks jonez.
+
+2006-11-08  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/internals/core.write_file.php:
+      change file writing semantics in smarty_core_write_file()
+      
+      This avoids unlink() unless rename() fails or a Windows system is detected
+      
+      see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=6956
+      
+      Thanks to c960657 from the forums.
+
+2006-11-07  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/debug.tpl:
+      update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug
+      output and apply a Smarty based color scheme
+      
+      see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=7178
+      
+      thanks to cybot from the forums!
+
+    * NEWS
+      libs/plugins/modifier.debug_print_var.php:
+      enhance reporting precision of debug_print_var modifier
+      
+      see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=9281
+      
+      thanks to cybot from the forums
+
+2006-11-01  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      make html_select_date work consistently with 0000-00-00 00:00:00 and
+      0000-00-00 inputs
+      
+      Thanks to cybot from forums
+
+2006-10-16  George Miroshnikov  <support@infinity.com.ua>
+
+    * docs/en/language-snippets.ent:
+      minor typo fix - &$class doesn't make sense.
+
+2006-10-14  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/designers/language-basic-syntax.xml
+      docs/fr/designers/language-builtin-functions.xml
+      docs/fr/designers/language-basic-syntax/language-syntax-attributes.xml
+      docs/fr/designers/language-basic-syntax/language-syntax-comments.xml
+      docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml
+      docs/fr/designers/language-builtin-functions/language-function-capture.xml
+      docs/fr/designers/language-builtin-functions/language-function-php.xml
+      docs/fr/designers/language-builtin-functions/language-function-section.xml
+      docs/fr/designers/language-custom-functions/language-function-popup-init.xml
+      docs/fr/designers/language-modifiers/language-modifier-escape.xml
+      docs/fr/programmers/api-functions/api-display.xml
+      docs/fr/programmers/plugins/plugins-inserts.xml:
+      sync with EN
+
+2006-10-14  Fernando Correa da Conceição  <fernando_conceicao@yahoo.com.br>
+
+    * docs/pt_BR/programmers/api-variables/variable-error-reporting.xml:
+      New Translation
+
+    * docs/pt_BR/designers/language-basic-syntax/language-escaping.xml
+      docs/pt_BR/designers/language-basic-syntax/language-syntax-variables.xml:
+      New Translations
+
+    * docs/pt_BR/translation.xml:
+      Used in revcheck
+
+    * docs/pt_BR/getting-started.xml
+      docs/pt_BR/language-snippets.ent
+      docs/pt_BR/make_chm_index.html
+      docs/pt_BR/preface.xml
+      docs/pt_BR/appendixes/resources.xml
+      docs/pt_BR/appendixes/troubleshooting.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-capitalize.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-cat.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-count-characters.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-count-paragraphs.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-count-sentences.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-count-words.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-date-format.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-default.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-escape.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-indent.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-lower.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-nl2br.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-regex-replace.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-replace.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-spacify.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-string-format.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-strip-tags.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-strip.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-truncate.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-upper.xml
+      docs/pt_BR/designers/language-modifiers/language-modifier-wordwrap.xml
+      docs/pt_BR/designers/language-variables/language-assigned-variables.xml
+      docs/pt_BR/designers/language-variables/language-config-variables.xml
+      docs/pt_BR/designers/language-variables/language-variables-smarty.xml
+      docs/pt_BR/programmers/advanced-features.xml
+      docs/pt_BR/programmers/api-functions.xml
+      docs/pt_BR/programmers/api-variables.xml
+      docs/pt_BR/programmers/caching.xml
+      docs/pt_BR/programmers/plugins.xml
+      docs/pt_BR/programmers/smarty-constants.xml
+      docs/pt_BR/programmers/advanced-features/advanced-features-objects.xml
+      docs/pt_BR/programmers/advanced-features/advanced-features-outputfilters.xml
+      docs/pt_BR/programmers/advanced-features/advanced-features-postfilters.xml
+      docs/pt_BR/programmers/advanced-features/advanced-features-prefilters.xml
+      docs/pt_BR/programmers/advanced-features/section-template-cache-handler-func.xml
+      docs/pt_BR/programmers/advanced-features/template-resources.xml
+      docs/pt_BR/programmers/api-functions/api-append-by-ref.xml
+      docs/pt_BR/programmers/api-functions/api-append.xml
+      docs/pt_BR/programmers/api-functions/api-assign-by-ref.xml
+      docs/pt_BR/programmers/api-functions/api-assign.xml
+      docs/pt_BR/programmers/api-functions/api-clear-all-assign.xml
+      docs/pt_BR/programmers/api-functions/api-clear-all-cache.xml
+      docs/pt_BR/programmers/api-functions/api-clear-assign.xml
+      docs/pt_BR/programmers/api-functions/api-clear-cache.xml
+      docs/pt_BR/programmers/api-functions/api-clear-compiled-tpl.xml
+      docs/pt_BR/programmers/api-functions/api-clear-config.xml
+      docs/pt_BR/programmers/api-functions/api-config-load.xml
+      docs/pt_BR/programmers/api-functions/api-display.xml
+      docs/pt_BR/programmers/api-functions/api-fetch.xml
+      docs/pt_BR/programmers/api-functions/api-get-config-vars.xml
+      docs/pt_BR/programmers/api-functions/api-get-registered-object.xml
+      docs/pt_BR/programmers/api-functions/api-get-template-vars.xml
+      docs/pt_BR/programmers/api-functions/api-is-cached.xml
+      docs/pt_BR/programmers/api-functions/api-load-filter.xml
+      docs/pt_BR/programmers/api-functions/api-register-block.xml
+      docs/pt_BR/programmers/api-functions/api-register-compiler-function.xml
+      docs/pt_BR/programmers/api-functions/api-register-function.xml
+      docs/pt_BR/programmers/api-functions/api-register-modifier.xml
+      docs/pt_BR/programmers/api-functions/api-register-object.xml
+      docs/pt_BR/programmers/api-functions/api-register-outputfilter.xml
+      docs/pt_BR/programmers/api-functions/api-register-postfilter.xml
+      docs/pt_BR/programmers/api-functions/api-register-prefilter.xml
+      docs/pt_BR/programmers/api-functions/api-register-resource.xml
+      docs/pt_BR/programmers/api-functions/api-template-exists.xml
+      docs/pt_BR/programmers/api-functions/api-trigger-error.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-block.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-compiler-function.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-function.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-modifier.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-object.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-outputfilter.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-postfilter.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-prefilter.xml
+      docs/pt_BR/programmers/api-functions/api-unregister-resource.xml
+      docs/pt_BR/programmers/api-variables/variable-autoload-filters.xml
+      docs/pt_BR/programmers/api-variables/variable-cache-dir.xml
+      docs/pt_BR/programmers/api-variables/variable-cache-handler-func.xml
+      docs/pt_BR/programmers/api-variables/variable-cache-lifetime.xml
+      docs/pt_BR/programmers/api-variables/variable-cache-modified-check.xml
+      docs/pt_BR/programmers/api-variables/variable-caching.xml
+      docs/pt_BR/programmers/api-variables/variable-compile-check.xml
+      docs/pt_BR/programmers/api-variables/variable-compile-dir.xml
+      docs/pt_BR/programmers/api-variables/variable-compile-id.xml
+      docs/pt_BR/programmers/api-variables/variable-compiler-class.xml
+      docs/pt_BR/programmers/api-variables/variable-config-booleanize.xml
+      docs/pt_BR/programmers/api-variables/variable-config-dir.xml
+      docs/pt_BR/programmers/api-variables/variable-config-fix-newlines.xml
+      docs/pt_BR/programmers/api-variables/variable-config-overwrite.xml
+      docs/pt_BR/programmers/api-variables/variable-config-read-hidden.xml
+      docs/pt_BR/programmers/api-variables/variable-debug-tpl.xml
+      docs/pt_BR/programmers/api-variables/variable-debugging-ctrl.xml
+      docs/pt_BR/programmers/api-variables/variable-debugging.xml
+      docs/pt_BR/programmers/api-variables/variable-default-modifiers.xml
+      docs/pt_BR/programmers/api-variables/variable-default-resource-type.xml
+      docs/pt_BR/programmers/api-variables/variable-default-template-handler-func.xml
+      docs/pt_BR/programmers/api-variables/variable-force-compile.xml
+      docs/pt_BR/programmers/api-variables/variable-global-assign.xml
+      docs/pt_BR/programmers/api-variables/variable-left-delimiter.xml
+      docs/pt_BR/programmers/api-variables/variable-php-handling.xml
+      docs/pt_BR/programmers/api-variables/variable-plugins-dir.xml
+      docs/pt_BR/programmers/api-variables/variable-request-use-auto-globals.xml
+      docs/pt_BR/programmers/api-variables/variable-request-vars-order.xml
+      docs/pt_BR/programmers/api-variables/variable-right-delimiter.xml
+      docs/pt_BR/programmers/api-variables/variable-secure-dir.xml
+      docs/pt_BR/programmers/api-variables/variable-security-settings.xml
+      docs/pt_BR/programmers/api-variables/variable-security.xml
+      docs/pt_BR/programmers/api-variables/variable-template-dir.xml
+      docs/pt_BR/programmers/api-variables/variable-trusted-dir.xml
+      docs/pt_BR/programmers/api-variables/variable-undefined.xml
+      docs/pt_BR/programmers/api-variables/variable-use-sub-dirs.xml
+      docs/pt_BR/programmers/caching/caching-cacheable.xml
+      docs/pt_BR/programmers/caching/caching-groups.xml
+      docs/pt_BR/programmers/caching/caching-multiple-caches.xml
+      docs/pt_BR/programmers/caching/caching-setting-up.xml
+      docs/pt_BR/programmers/plugins/plugins-block-functions.xml
+      docs/pt_BR/programmers/plugins/plugins-compiler-functions.xml
+      docs/pt_BR/programmers/plugins/plugins-functions.xml
+      docs/pt_BR/programmers/plugins/plugins-howto.xml
+      docs/pt_BR/programmers/plugins/plugins-inserts.xml
+      docs/pt_BR/programmers/plugins/plugins-modifiers.xml
+      docs/pt_BR/programmers/plugins/plugins-naming-conventions.xml
+      docs/pt_BR/programmers/plugins/plugins-outputfilters.xml
+      docs/pt_BR/programmers/plugins/plugins-prefilters-postfilters.xml
+      docs/pt_BR/programmers/plugins/plugins-resources.xml
+      docs/pt_BR/programmers/plugins/plugins-writing.xml:
+      Big update. Revision tag for all files. Some updates. Now I can update it
+
+2006-10-09  Peter 'Mash' Morgan  <pm@daffodil.uk.com>
+
+    * docs/en/getting-started.xml
+      docs/en/designers/language-basic-syntax.xml
+      docs/en/designers/language-custom-functions/language-function-popup-init.xml
+      docs/en/designers/language-modifiers/language-modifier-escape.xml
+      docs/en/programmers/api-functions/api-display.xml
+      docs/en/programmers/plugins/plugins-inserts.xml:
+      Minor changes and corrections
+
+    * docs/en/designers/language-basic-syntax.xml
+      docs/en/designers/language-builtin-functions.xml
+      docs/en/designers/language-basic-syntax/language-syntax-attributes.xml
+      docs/en/designers/language-basic-syntax/language-syntax-comments.xml
+      docs/en/designers/language-basic-syntax/language-syntax-quotes.xml
+      docs/en/designers/language-modifiers/language-modifier-escape.xml:
+      Minor formatting and error correction
+
+    * docs/en/designers/language-builtin-functions/language-function-capture.xml
+      docs/en/designers/language-builtin-functions/language-function-php.xml
+      docs/en/designers/language-builtin-functions/language-function-section.xml:
+      minor formatting and changes
+
+    * docs/en/getting-started.xml:
+      Tidied up formatting so more readable, tidied up the install to the paths
+      are more clear (ta jj)
+
+2006-10-09  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/designers/language-builtin-functions/language-function-section.xml:
+      sync with EN
+
+2006-10-08  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/designers/language-builtin-functions/language-function-php.xml
+      docs/fr/designers/language-modifiers/language-modifier-escape.xml
+      docs/fr/designers/language-variables/language-variables-smarty.xml
+      docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml:
+      fix build
+
+    * docs/fr/designers/language-builtin-functions/language-function-strip.xml
+      docs/fr/programmers/caching.xml
+      docs/fr/programmers/smarty-constants.xml
+      docs/fr/programmers/api-variables/variable-autoload-filters.xml
+      docs/fr/programmers/api-variables/variable-cache-dir.xml
+      docs/fr/programmers/api-variables/variable-cache-handler-func.xml
+      docs/fr/programmers/api-variables/variable-cache-lifetime.xml
+      docs/fr/programmers/api-variables/variable-cache-modified-check.xml
+      docs/fr/programmers/api-variables/variable-caching.xml
+      docs/fr/programmers/api-variables/variable-compile-check.xml
+      docs/fr/programmers/api-variables/variable-compile-dir.xml
+      docs/fr/programmers/api-variables/variable-compile-id.xml
+      docs/fr/programmers/api-variables/variable-compiler-class.xml
+      docs/fr/programmers/api-variables/variable-config-booleanize.xml
+      docs/fr/programmers/api-variables/variable-config-dir.xml
+      docs/fr/programmers/api-variables/variable-config-fix-newlines.xml
+      docs/fr/programmers/api-variables/variable-config-overwrite.xml
+      docs/fr/programmers/api-variables/variable-config-read-hidden.xml
+      docs/fr/programmers/api-variables/variable-debug-tpl.xml
+      docs/fr/programmers/api-variables/variable-debugging-ctrl.xml
+      docs/fr/programmers/api-variables/variable-debugging.xml
+      docs/fr/programmers/api-variables/variable-default-modifiers.xml
+      docs/fr/programmers/api-variables/variable-default-resource-type.xml
+      docs/fr/programmers/api-variables/variable-default-template-handler-func.xml
+      docs/fr/programmers/api-variables/variable-error-reporting.xml
+      docs/fr/programmers/api-variables/variable-force-compile.xml
+      docs/fr/programmers/api-variables/variable-left-delimiter.xml
+      docs/fr/programmers/api-variables/variable-php-handling.xml
+      docs/fr/programmers/api-variables/variable-plugins-dir.xml
+      docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml
+      docs/fr/programmers/api-variables/variable-request-vars-order.xml
+      docs/fr/programmers/api-variables/variable-right-delimiter.xml
+      docs/fr/programmers/api-variables/variable-secure-dir.xml
+      docs/fr/programmers/api-variables/variable-security-settings.xml
+      docs/fr/programmers/api-variables/variable-security.xml
+      docs/fr/programmers/api-variables/variable-template-dir.xml
+      docs/fr/programmers/api-variables/variable-trusted-dir.xml
+      docs/fr/programmers/api-variables/variable-use-sub-dirs.xml
+      docs/fr/programmers/caching/caching-cacheable.xml
+      docs/fr/programmers/caching/caching-groups.xml
+      docs/fr/programmers/caching/caching-multiple-caches.xml
+      docs/fr/programmers/caching/caching-setting-up.xml
+      docs/fr/programmers/plugins/plugins-block-functions.xml
+      docs/fr/programmers/plugins/plugins-compiler-functions.xml
+      docs/fr/programmers/plugins/plugins-functions.xml
+      docs/fr/programmers/plugins/plugins-inserts.xml
+      docs/fr/programmers/plugins/plugins-modifiers.xml
+      docs/fr/programmers/plugins/plugins-naming-conventions.xml
+      docs/fr/programmers/plugins/plugins-outputfilters.xml
+      docs/fr/programmers/plugins/plugins-prefilters-postfilters.xml
+      docs/fr/programmers/plugins/plugins-resources.xml
+      docs/fr/programmers/plugins/plugins-writing.xml:
+      sync with EN
+
+2006-10-07  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/programmers/advanced-features/advanced-features-objects.xml
+      docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml
+      docs/fr/programmers/advanced-features/advanced-features-postfilters.xml
+      docs/fr/programmers/advanced-features/advanced-features-prefilters.xml
+      docs/fr/programmers/advanced-features/section-template-cache-handler-func.xml
+      docs/fr/programmers/advanced-features/template-resources.xml
+      docs/fr/programmers/api-functions/api-append-by-ref.xml
+      docs/fr/programmers/api-functions/api-append.xml
+      docs/fr/programmers/api-functions/api-assign-by-ref.xml
+      docs/fr/programmers/api-functions/api-assign.xml
+      docs/fr/programmers/api-functions/api-clear-all-assign.xml
+      docs/fr/programmers/api-functions/api-clear-all-cache.xml
+      docs/fr/programmers/api-functions/api-clear-assign.xml
+      docs/fr/programmers/api-functions/api-clear-cache.xml
+      docs/fr/programmers/api-functions/api-clear-compiled-tpl.xml
+      docs/fr/programmers/api-functions/api-clear-config.xml
+      docs/fr/programmers/api-functions/api-config-load.xml
+      docs/fr/programmers/api-functions/api-display.xml
+      docs/fr/programmers/api-functions/api-fetch.xml
+      docs/fr/programmers/api-functions/api-get-config-vars.xml
+      docs/fr/programmers/api-functions/api-get-registered-object.xml
+      docs/fr/programmers/api-functions/api-get-template-vars.xml
+      docs/fr/programmers/api-functions/api-is-cached.xml
+      docs/fr/programmers/api-functions/api-load-filter.xml
+      docs/fr/programmers/api-functions/api-register-block.xml
+      docs/fr/programmers/api-functions/api-register-compiler-function.xml
+      docs/fr/programmers/api-functions/api-register-function.xml
+      docs/fr/programmers/api-functions/api-register-modifier.xml
+      docs/fr/programmers/api-functions/api-register-object.xml
+      docs/fr/programmers/api-functions/api-register-outputfilter.xml
+      docs/fr/programmers/api-functions/api-register-postfilter.xml
+      docs/fr/programmers/api-functions/api-register-prefilter.xml
+      docs/fr/programmers/api-functions/api-register-resource.xml
+      docs/fr/programmers/api-functions/api-template-exists.xml
+      docs/fr/programmers/api-functions/api-trigger-error.xml
+      docs/fr/programmers/api-functions/api-unregister-block.xml
+      docs/fr/programmers/api-functions/api-unregister-compiler-function.xml
+      docs/fr/programmers/api-functions/api-unregister-function.xml
+      docs/fr/programmers/api-functions/api-unregister-modifier.xml
+      docs/fr/programmers/api-functions/api-unregister-object.xml
+      docs/fr/programmers/api-functions/api-unregister-outputfilter.xml
+      docs/fr/programmers/api-functions/api-unregister-postfilter.xml
+      docs/fr/programmers/api-functions/api-unregister-prefilter.xml
+      docs/fr/programmers/api-functions/api-unregister-resource.xml:
+      sync with EN
+
+2006-10-03  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/designers/language-custom-functions/language-function-html-select-time.xml
+      docs/fr/designers/language-custom-functions/language-function-html-table.xml
+      docs/fr/designers/language-custom-functions/language-function-mailto.xml
+      docs/fr/designers/language-custom-functions/language-function-math.xml
+      docs/fr/designers/language-custom-functions/language-function-popup-init.xml
+      docs/fr/designers/language-custom-functions/language-function-popup.xml
+      docs/fr/designers/language-custom-functions/language-function-textformat.xml
+      docs/fr/designers/language-modifiers/language-modifier-capitalize.xml
+      docs/fr/designers/language-modifiers/language-modifier-cat.xml
+      docs/fr/designers/language-modifiers/language-modifier-count-characters.xml
+      docs/fr/designers/language-modifiers/language-modifier-count-paragraphs.xml
+      docs/fr/designers/language-modifiers/language-modifier-count-sentences.xml
+      docs/fr/designers/language-modifiers/language-modifier-count-words.xml
+      docs/fr/designers/language-modifiers/language-modifier-date-format.xml
+      docs/fr/designers/language-modifiers/language-modifier-default.xml
+      docs/fr/designers/language-modifiers/language-modifier-escape.xml
+      docs/fr/designers/language-modifiers/language-modifier-indent.xml
+      docs/fr/designers/language-modifiers/language-modifier-lower.xml
+      docs/fr/designers/language-modifiers/language-modifier-nl2br.xml
+      docs/fr/designers/language-modifiers/language-modifier-regex-replace.xml
+      docs/fr/designers/language-modifiers/language-modifier-replace.xml
+      docs/fr/designers/language-modifiers/language-modifier-spacify.xml
+      docs/fr/designers/language-modifiers/language-modifier-string-format.xml
+      docs/fr/designers/language-modifiers/language-modifier-strip-tags.xml
+      docs/fr/designers/language-modifiers/language-modifier-strip.xml
+      docs/fr/designers/language-modifiers/language-modifier-truncate.xml
+      docs/fr/designers/language-modifiers/language-modifier-upper.xml
+      docs/fr/designers/language-modifiers/language-modifier-wordwrap.xml
+      docs/fr/designers/language-variables/language-assigned-variables.xml
+      docs/fr/designers/language-variables/language-config-variables.xml
+      docs/fr/designers/language-variables/language-variables-smarty.xml:
+      sync with EN
+
+2006-10-01  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/designers/language-builtin-functions/language-function-include-php.xml
+      docs/fr/designers/language-builtin-functions/language-function-include.xml
+      docs/fr/designers/language-builtin-functions/language-function-insert.xml
+      docs/fr/designers/language-builtin-functions/language-function-ldelim.xml
+      docs/fr/designers/language-builtin-functions/language-function-literal.xml
+      docs/fr/designers/language-builtin-functions/language-function-php.xml
+      docs/fr/designers/language-custom-functions/language-function-assign.xml
+      docs/fr/designers/language-custom-functions/language-function-counter.xml
+      docs/fr/designers/language-custom-functions/language-function-cycle.xml
+      docs/fr/designers/language-custom-functions/language-function-debug.xml
+      docs/fr/designers/language-custom-functions/language-function-eval.xml
+      docs/fr/designers/language-custom-functions/language-function-fetch.xml
+      docs/fr/designers/language-custom-functions/language-function-html-checkboxes.xml
+      docs/fr/designers/language-custom-functions/language-function-html-image.xml
+      docs/fr/designers/language-custom-functions/language-function-html-options.xml
+      docs/fr/designers/language-custom-functions/language-function-html-radios.xml
+      docs/fr/designers/language-custom-functions/language-function-html-select-date.xml:
+      sync with EN
+
+2006-09-30  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/getting-started.xml:
+      fix build
+
+    * docs/fr/designers/chapter-debugging-console.xml
+      docs/fr/designers/config-files.xml
+      docs/fr/designers/language-builtin-functions.xml
+      docs/fr/designers/language-modifiers.xml
+      docs/fr/designers/language-variables.xml
+      docs/fr/designers/language-basic-syntax/language-escaping.xml
+      docs/fr/designers/language-basic-syntax/language-math.xml
+      docs/fr/designers/language-basic-syntax/language-syntax-comments.xml
+      docs/fr/designers/language-basic-syntax/language-syntax-functions.xml
+      docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml
+      docs/fr/designers/language-basic-syntax/language-syntax-variables.xml
+      docs/fr/designers/language-builtin-functions/language-function-capture.xml
+      docs/fr/designers/language-builtin-functions/language-function-config-load.xml
+      docs/fr/designers/language-builtin-functions/language-function-foreach.xml
+      docs/fr/designers/language-builtin-functions/language-function-if.xml:
+      sync with EN
+
+    * docs/fr/getting-started.xml
+      docs/fr/language-snippets.ent
+      docs/fr/appendixes/resources.xml
+      docs/fr/appendixes/tips.xml
+      docs/fr/appendixes/troubleshooting.xml:
+      sync with EN
+
+2006-09-27  Peter 'Mash' Morgan  <pm@daffodil.uk.com>
+
+    * docs/en/designers/language-builtin-functions/language-function-section.xml:
+      Minor tweaks and corrections
+
+    * docs/en/getting-started.xml
+      docs/en/designers/chapter-debugging-console.xml
+      docs/en/designers/language-basic-syntax/language-syntax-comments.xml
+      docs/en/designers/language-custom-functions/language-function-html-image.xml
+      docs/en/designers/language-custom-functions/language-function-html-options.xml
+      docs/en/designers/language-custom-functions/language-function-html-radios.xml
+      docs/en/designers/language-custom-functions/language-function-html-select-date.xml
+      docs/en/designers/language-custom-functions/language-function-html-select-time.xml
+      docs/en/designers/language-custom-functions/language-function-html-table.xml
+      docs/en/designers/language-custom-functions/language-function-mailto.xml
+      docs/en/designers/language-custom-functions/language-function-popup-init.xml
+      docs/en/designers/language-custom-functions/language-function-textformat.xml
+      docs/en/designers/language-variables/language-config-variables.xml
+      docs/en/designers/language-variables/language-variables-smarty.xml:
+      Add literal tags to html, general formatting
+
+    * docs/en/getting-started.xml
+      docs/en/appendixes/resources.xml
+      docs/en/appendixes/tips.xml
+      docs/en/appendixes/troubleshooting.xml
+      docs/en/designers/config-files.xml
+      docs/en/programmers/caching.xml
+      docs/en/programmers/smarty-constants.xml
+      docs/en/programmers/advanced-features/advanced-features-objects.xml
+      docs/en/programmers/advanced-features/advanced-features-outputfilters.xml
+      docs/en/programmers/advanced-features/advanced-features-postfilters.xml
+      docs/en/programmers/advanced-features/advanced-features-prefilters.xml
+      docs/en/programmers/advanced-features/section-template-cache-handler-func.xml
+      docs/en/programmers/advanced-features/template-resources.xml
+      docs/en/programmers/api-variables/variable-autoload-filters.xml
+      docs/en/programmers/api-variables/variable-cache-dir.xml
+      docs/en/programmers/api-variables/variable-cache-handler-func.xml
+      docs/en/programmers/api-variables/variable-cache-lifetime.xml
+      docs/en/programmers/api-variables/variable-cache-modified-check.xml
+      docs/en/programmers/api-variables/variable-caching.xml
+      docs/en/programmers/api-variables/variable-compile-check.xml
+      docs/en/programmers/api-variables/variable-compile-dir.xml
+      docs/en/programmers/api-variables/variable-compile-id.xml
+      docs/en/programmers/api-variables/variable-config-booleanize.xml
+      docs/en/programmers/api-variables/variable-config-dir.xml
+      docs/en/programmers/api-variables/variable-config-fix-newlines.xml
+      docs/en/programmers/api-variables/variable-config-overwrite.xml
+      docs/en/programmers/api-variables/variable-config-read-hidden.xml
+      docs/en/programmers/api-variables/variable-debug-tpl.xml
+      docs/en/programmers/api-variables/variable-debugging-ctrl.xml
+      docs/en/programmers/api-variables/variable-debugging.xml
+      docs/en/programmers/api-variables/variable-default-modifiers.xml
+      docs/en/programmers/api-variables/variable-default-resource-type.xml
+      docs/en/programmers/api-variables/variable-error-reporting.xml
+      docs/en/programmers/api-variables/variable-force-compile.xml
+      docs/en/programmers/api-variables/variable-left-delimiter.xml
+      docs/en/programmers/api-variables/variable-php-handling.xml
+      docs/en/programmers/api-variables/variable-plugins-dir.xml
+      docs/en/programmers/api-variables/variable-request-use-auto-globals.xml
+      docs/en/programmers/api-variables/variable-request-vars-order.xml
+      docs/en/programmers/api-variables/variable-right-delimiter.xml
+      docs/en/programmers/api-variables/variable-secure-dir.xml
+      docs/en/programmers/api-variables/variable-security-settings.xml
+      docs/en/programmers/api-variables/variable-security.xml
+      docs/en/programmers/api-variables/variable-template-dir.xml
+      docs/en/programmers/api-variables/variable-trusted-dir.xml
+      docs/en/programmers/api-variables/variable-use-sub-dirs.xml
+      docs/en/programmers/caching/caching-cacheable.xml
+      docs/en/programmers/caching/caching-groups.xml
+      docs/en/programmers/caching/caching-multiple-caches.xml
+      docs/en/programmers/caching/caching-setting-up.xml:
+      Tidy up of formatting
+
+    * docs/entities/global.ent:
+      Adding some more resources
+
+    * docs/en/programmers/plugins/plugins-block-functions.xml
+      docs/en/programmers/plugins/plugins-compiler-functions.xml
+      docs/en/programmers/plugins/plugins-functions.xml
+      docs/en/programmers/plugins/plugins-inserts.xml
+      docs/en/programmers/plugins/plugins-modifiers.xml
+      docs/en/programmers/plugins/plugins-naming-conventions.xml
+      docs/en/programmers/plugins/plugins-outputfilters.xml
+      docs/en/programmers/plugins/plugins-prefilters-postfilters.xml
+      docs/en/programmers/plugins/plugins-resources.xml
+      docs/en/programmers/plugins/plugins-writing.xml:
+      Tidy up some formatting
+
+2006-09-26  Peter 'Mash' Morgan  <pm@daffodil.uk.com>
+
+    * docs/en/programmers/api-functions/api-append-by-ref.xml
+      docs/en/programmers/api-functions/api-append.xml
+      docs/en/programmers/api-functions/api-assign-by-ref.xml
+      docs/en/programmers/api-functions/api-assign.xml
+      docs/en/programmers/api-functions/api-clear-all-assign.xml
+      docs/en/programmers/api-functions/api-clear-all-cache.xml
+      docs/en/programmers/api-functions/api-clear-assign.xml
+      docs/en/programmers/api-functions/api-clear-cache.xml
+      docs/en/programmers/api-functions/api-clear-compiled-tpl.xml
+      docs/en/programmers/api-functions/api-clear-config.xml
+      docs/en/programmers/api-functions/api-config-load.xml
+      docs/en/programmers/api-functions/api-display.xml
+      docs/en/programmers/api-functions/api-fetch.xml
+      docs/en/programmers/api-functions/api-get-config-vars.xml
+      docs/en/programmers/api-functions/api-get-registered-object.xml
+      docs/en/programmers/api-functions/api-get-template-vars.xml
+      docs/en/programmers/api-functions/api-is-cached.xml
+      docs/en/programmers/api-functions/api-load-filter.xml
+      docs/en/programmers/api-functions/api-register-block.xml
+      docs/en/programmers/api-functions/api-register-compiler-function.xml
+      docs/en/programmers/api-functions/api-register-function.xml
+      docs/en/programmers/api-functions/api-register-modifier.xml
+      docs/en/programmers/api-functions/api-register-object.xml
+      docs/en/programmers/api-functions/api-register-outputfilter.xml
+      docs/en/programmers/api-functions/api-register-postfilter.xml
+      docs/en/programmers/api-functions/api-register-prefilter.xml
+      docs/en/programmers/api-functions/api-register-resource.xml
+      docs/en/programmers/api-functions/api-template-exists.xml
+      docs/en/programmers/api-functions/api-trigger-error.xml
+      docs/en/programmers/api-functions/api-unregister-block.xml
+      docs/en/programmers/api-functions/api-unregister-compiler-function.xml
+      docs/en/programmers/api-functions/api-unregister-function.xml
+      docs/en/programmers/api-functions/api-unregister-modifier.xml
+      docs/en/programmers/api-functions/api-unregister-object.xml
+      docs/en/programmers/api-functions/api-unregister-outputfilter.xml
+      docs/en/programmers/api-functions/api-unregister-postfilter.xml
+      docs/en/programmers/api-functions/api-unregister-prefilter.xml
+      docs/en/programmers/api-functions/api-unregister-resource.xml:
+      Tidy up formatting and examples
+
+    * docs/en/language-snippets.ent:
+      Moved recurring para for register_*
+
+    * docs/en/designers/language-modifiers.xml:
+      Spelling on modifiers
+
+    * docs/en/designers/language-builtin-functions.xml
+      docs/en/designers/language-modifiers.xml
+      docs/en/designers/language-custom-functions/language-function-html-options.xml
+      docs/en/designers/language-modifiers/language-modifier-capitalize.xml
+      docs/en/designers/language-modifiers/language-modifier-cat.xml
+      docs/en/designers/language-modifiers/language-modifier-count-characters.xml
+      docs/en/designers/language-modifiers/language-modifier-count-paragraphs.xml
+      docs/en/designers/language-modifiers/language-modifier-count-sentences.xml
+      docs/en/designers/language-modifiers/language-modifier-count-words.xml
+      docs/en/designers/language-modifiers/language-modifier-date-format.xml
+      docs/en/designers/language-modifiers/language-modifier-default.xml
+      docs/en/designers/language-modifiers/language-modifier-escape.xml
+      docs/en/designers/language-modifiers/language-modifier-indent.xml
+      docs/en/designers/language-modifiers/language-modifier-lower.xml
+      docs/en/designers/language-modifiers/language-modifier-nl2br.xml
+      docs/en/designers/language-modifiers/language-modifier-regex-replace.xml
+      docs/en/designers/language-modifiers/language-modifier-replace.xml
+      docs/en/designers/language-modifiers/language-modifier-spacify.xml
+      docs/en/designers/language-modifiers/language-modifier-string-format.xml
+      docs/en/designers/language-modifiers/language-modifier-strip-tags.xml
+      docs/en/designers/language-modifiers/language-modifier-strip.xml
+      docs/en/designers/language-modifiers/language-modifier-truncate.xml
+      docs/en/designers/language-modifiers/language-modifier-upper.xml
+      docs/en/designers/language-modifiers/language-modifier-wordwrap.xml:
+      Tidying up some markup
+
+    * docs/en/designers/language-variables.xml:
+      typo
+
+    * docs/en/designers/language-variables.xml
+      docs/en/designers/language-variables/language-assigned-variables.xml
+      docs/en/designers/language-variables/language-config-variables.xml
+      docs/en/designers/language-variables/language-variables-smarty.xml:
+      Tidy up formatting on variables
+
+    * docs/en/designers/language-basic-syntax/language-escaping.xml
+      docs/en/designers/language-basic-syntax/language-math.xml
+      docs/en/designers/language-basic-syntax/language-syntax-comments.xml
+      docs/en/designers/language-basic-syntax/language-syntax-functions.xml
+      docs/en/designers/language-basic-syntax/language-syntax-quotes.xml
+      docs/en/designers/language-basic-syntax/language-syntax-variables.xml:
+      Formatting of the basic-syntax dir
+
+    * docs/en/designers/language-custom-functions/language-function-assign.xml
+      docs/en/designers/language-custom-functions/language-function-counter.xml
+      docs/en/designers/language-custom-functions/language-function-cycle.xml
+      docs/en/designers/language-custom-functions/language-function-debug.xml
+      docs/en/designers/language-custom-functions/language-function-eval.xml
+      docs/en/designers/language-custom-functions/language-function-fetch.xml
+      docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml
+      docs/en/designers/language-custom-functions/language-function-html-image.xml
+      docs/en/designers/language-custom-functions/language-function-html-options.xml
+      docs/en/designers/language-custom-functions/language-function-html-radios.xml
+      docs/en/designers/language-custom-functions/language-function-html-select-date.xml
+      docs/en/designers/language-custom-functions/language-function-html-select-time.xml
+      docs/en/designers/language-custom-functions/language-function-html-table.xml
+      docs/en/designers/language-custom-functions/language-function-mailto.xml
+      docs/en/designers/language-custom-functions/language-function-math.xml
+      docs/en/designers/language-custom-functions/language-function-popup-init.xml
+      docs/en/designers/language-custom-functions/language-function-popup.xml
+      docs/en/designers/language-custom-functions/language-function-textformat.xml:
+      More formatting and cleaning up examples
+
+2006-09-25  Peter 'Mash' Morgan  <pm@daffodil.uk.com>
+
+    * docs/en/designers/language-builtin-functions/language-function-foreach.xml
+      docs/en/designers/language-builtin-functions/language-function-section.xml:
+      Doh! removing tabs
+
+    * docs/en/designers/language-builtin-functions/language-function-capture.xml
+      docs/en/designers/language-builtin-functions/language-function-config-load.xml
+      docs/en/designers/language-builtin-functions/language-function-foreach.xml
+      docs/en/designers/language-builtin-functions/language-function-if.xml
+      docs/en/designers/language-builtin-functions/language-function-include-php.xml
+      docs/en/designers/language-builtin-functions/language-function-include.xml
+      docs/en/designers/language-builtin-functions/language-function-insert.xml
+      docs/en/designers/language-builtin-functions/language-function-ldelim.xml
+      docs/en/designers/language-builtin-functions/language-function-literal.xml
+      docs/en/designers/language-builtin-functions/language-function-php.xml
+      docs/en/designers/language-builtin-functions/language-function-section.xml
+      docs/en/designers/language-builtin-functions/language-function-strip.xml:
+      A lot of formatting, tagging and tidy up. Some consistency at last
+
+    * docs/en/designers/language-builtin-functions/language-function-section.xml:
+      Major tidy up
+
+    * docs/en/designers/language-builtin-functions/language-function-foreach.xml:
+      Major tidy up, added index property and some examples
+
+2006-09-03  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/designers/language-custom-functions/language-function-popup-init.xml
+      docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml
+      docs/fr/programmers/advanced-features/advanced-features-postfilters.xml
+      docs/fr/programmers/advanced-features/advanced-features-prefilters.xml:
+      sync with EN
+
+2006-09-01  George Miroshnikov  <support@infinity.com.ua>
+
+    * docs/ru/programmers/api-functions/api-append-by-ref.xml
+      docs/ru/programmers/api-functions/api-append.xml
+      docs/ru/programmers/api-functions/api-assign-by-ref.xml
+      docs/ru/programmers/api-functions/api-assign.xml
+      docs/ru/programmers/api-functions/api-clear-all-assign.xml
+      docs/ru/programmers/api-functions/api-clear-all-cache.xml
+      docs/ru/programmers/api-functions/api-clear-assign.xml
+      docs/ru/programmers/api-functions/api-clear-cache.xml
+      docs/ru/programmers/api-functions/api-clear-compiled-tpl.xml
+      docs/ru/programmers/api-functions/api-clear-config.xml
+      docs/ru/programmers/api-functions/api-config-load.xml
+      docs/ru/programmers/api-functions/api-display.xml:
+      sync with EN
+
+2006-08-25  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed wrong handling of name attribute in {insert}
+      thanks to Ivan Kravets for reporting this
+
+    * libs/Smarty_Compiler.class.php:
+      fixed typo
+
+2006-08-21  George Miroshnikov  <support@infinity.com.ua>
+
+    * docs/ru/designers/language-custom-functions/language-function-popup-init.xml
+      docs/ru/programmers/advanced-features/advanced-features-objects.xml
+      docs/ru/programmers/advanced-features/advanced-features-outputfilters.xml
+      docs/ru/programmers/advanced-features/advanced-features-postfilters.xml
+      docs/ru/programmers/advanced-features/advanced-features-prefilters.xml
+      docs/ru/programmers/advanced-features/section-template-cache-handler-func.xml
+      docs/ru/programmers/advanced-features/template-resources.xml:
+      sync with EN
+
+    * docs/en/programmers/advanced-features/advanced-features-prefilters.xml:
+      another missing dot
+
+    * docs/en/programmers/advanced-features/advanced-features-postfilters.xml:
+      missing dot
+
+    * docs/en/programmers/advanced-features/advanced-features-outputfilters.xml:
+      missing comma
+
+2006-08-19  Peter 'Mash' Morgan  <pmm@daffodil.uk.com>
+
+    * docs/en/designers/language-custom-functions/language-function-popup-init.xml:
+      avoid dupes and added remote paths
+
+2006-08-06  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/designers/language-custom-functions/language-function-html-table.xml
+      docs/fr/designers/language-custom-functions/language-function-mailto.xml:
+      sync with EN
+
+2006-08-03  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix false replacement of "$t" inside double quotes
+      thanks to checat for reporting this
+
+2006-07-20  George Miroshnikov  <support@infinity.com.ua>
+
+    * docs/ru/designers/language-custom-functions/language-function-html-table.xml
+      docs/ru/designers/language-custom-functions/language-function-mailto.xml:
+      incrementing EN-Revision
+
+    * docs/ru/designers/language-custom-functions/language-function-assign.xml
+      docs/ru/designers/language-custom-functions/language-function-eval.xml
+      docs/ru/designers/language-custom-functions/language-function-fetch.xml
+      docs/ru/designers/language-custom-functions/language-function-html-checkboxes.xml
+      docs/ru/designers/language-custom-functions/language-function-html-image.xml
+      docs/ru/designers/language-custom-functions/language-function-html-options.xml
+      docs/ru/designers/language-custom-functions/language-function-html-radios.xml
+      docs/ru/designers/language-custom-functions/language-function-html-table.xml
+      docs/ru/designers/language-custom-functions/language-function-mailto.xml
+      docs/ru/designers/language-custom-functions/language-function-popup-init.xml
+      docs/ru/designers/language-custom-functions/language-function-popup.xml
+      docs/ru/designers/language-modifiers/language-modifier-date-format.xml
+      docs/ru/designers/language-modifiers/language-modifier-default.xml
+      docs/ru/designers/language-modifiers/language-modifier-escape.xml
+      docs/ru/designers/language-modifiers/language-modifier-indent.xml
+      docs/ru/designers/language-modifiers/language-modifier-lower.xml
+      docs/ru/designers/language-modifiers/language-modifier-nl2br.xml
+      docs/ru/designers/language-modifiers/language-modifier-strip.xml
+      docs/ru/designers/language-modifiers/language-modifier-truncate.xml
+      docs/ru/designers/language-modifiers/language-modifier-upper.xml
+      docs/ru/designers/language-modifiers/language-modifier-wordwrap.xml
+      docs/ru/designers/language-variables/language-variables-smarty.xml:
+      sync with EN
+
+    * docs/en/designers/language-custom-functions/language-function-mailto.xml:
+      typo
+
+2006-07-10  boots  <jayboots@yahoo.com>
+
+    * libs/plugins/function.html_table.php:
+      fixed email address in comments
+
+    * NEWS
+      libs/plugins/function.html_table.php:
+      html_table: fixed th/tr output, added hdir support for column
+      headings,update docs to reflect new features
+
+2006-07-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_table.php:
+      fix occasional notices on undefined variables
+
+2006-07-08  boots  <jayboots@yahoo.com>
+
+    * libs/plugins/function.html_table.php:
+      Added ability to specify column headings in {html_table}
+      
+      Added th_attrs attribute which works similary to td_attr and tr_attr but
+      for TH elements. Changes the cols attribute to allow mixed values; a
+      numeric still specifies the number of columns to render but now an array
+      of values can be used to specify TH column values. The number of columns
+      is determine from the size of the array. Further, a comma-separated
+      string of column names can be used which is internally coverted to an
+      array and used as if it was specified as a normal array.
+      
+      Thanks for lynlyn for the feature request.
+
+2006-06-23  boots  <jayboots@yahoo.com>
+
+    * libs/plugins/outputfilter.trimwhitespace.php:
+      fix comments in outputfilter.trimwhitespace
+
+    * NEWS
+      libs/plugins/outputfilter.trimwhitespace.php:
+      fixed ordering of replacements in trimwhitespace output filter
+      
+      Thanks to Getty from IRC for reporting this.
+
+2006-06-20  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/plugins/function.mailto.php:
+      update mailto function plugin to work around a firefox/thunderbird escaping
+      bug
+      
+      Thanks to elijahlofgren from the forums for reporting this and providing
+      the necessary patch
+
+    * NEWS
+      libs/plugins/modifier.date_format.php:
+      emulate %l in the date_format modifier on windows
+      
+      thanks to Gibberish from the forums for reporting this
+
+2006-06-14  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/plugins/modifier.capitalize.php:
+      Fix handling of apostrophes in the capitalize modifier.
+      
+      Thanks to asmecher from the forums for reporting this and providing a
+      partial solution.
+
+2006-05-28  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers
+
+2006-05-25  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      un-hide hidden xml open tags
+
+2006-05-09  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      separate handling of comment blocks from "special blocks"
+
+    * NEWS
+      libs/plugins/function.popup_init.php:
+      reverted {popup_init} as proposed change to insertion behviour was not BC
+
+2006-05-04  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/plugins/function.popup_init.php:
+      changed {popup_init} to only emit code once during a request
+      
+      Thanks to TGKnIght from forums
+
+2006-04-22  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix handling of block-methods of registered objects
+      thanks to El Hombre Gris
+
+2006-04-04  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/function.html_select_date.php:
+      fix typo
+
+2006-03-09  Monte Ohrt  <monte@ohrt.com>
+
+    * (Smarty_2_6_13)
+      NEWS:
+      update for release
+
+2006-03-08  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/modifier.regex_replace.php:
+      remove delim quote
+
+    * libs/plugins/modifier.regex_replace.php:
+      fix delimiter issue
+
+2006-03-03  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/modifier.regex_replace.php:
+      use preg_replace to cover any space chars
+
+    * libs/plugins/modifier.regex_replace.php:
+      fix problem with allowing "e" modifier
+
+2006-01-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      removed possiblity for E_NOTICE on an undefined variable in
+      Smarty_Compiler::_compile_if_tag() - thanks to sbeh
+
+2006-01-18  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers
+
+    * (Smarty_2_6_12)
+      NEWS:
+      commit 2.6.12 release
+
+2006-01-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed use of references $cache_attrs and $repeat in Smarty_Compiler.
+      
+      php does not allow to pass an assigned by reference to a function. since
+      php-5.1.2
+      the reference to the lval gets lost when passing an assignment.
+
+2005-12-31  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      fixed incompatible use of fread() in Smarty::_read_file()
+      it choke on php-5.1.1 and later.
+      thanks to andig for pointing this out.
+
+2005-12-21  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      Fix improper tokenization of certain inline math expressions.
+      
+      Thanks to gerard at forums for reporting this.
+
+2005-12-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.math.php:
+      fixed problem with math in certain LC_NUMERIC locales.
+      thanks to wiebren for providing problem+solution.
+
+2005-12-14  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS:
+      fixed iso-latin1 special chars
+
+2005-12-14  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers
+
+    * (Smarty_2_6_11)
+      NEWS:
+      commit NEWS file for 2.6.11
+
+2005-12-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/de/getting-started.xml:
+      sync with en
+
+2005-11-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed code generation of non-cacheable blocks to play well with php's
+      "Alternative syntax" used for example in compiled {if}..{else}..{/if}
+      blocks.
+      
+      (see: http://php.net/manual/en/control-structures.alternative-syntax.php
+      on "Alternative syntax")
+      
+      thanks to kihara from the forum.
+
+2005-11-26  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS:
+      fixed handling of multiple identical calls to {insert}.
+      
+      the function was called multiple times, but all inserts where replaced
+      by the results of the first call to the insert function.
+
+    * libs/plugins/compiler.assign.php
+      libs/plugins/function.config_load.php:
+      added credits
+
+    * libs/plugins/function.popup.php:
+      added "closeclick" from
+      http://www.bosrup.com/web/overlib/?Command_Reference
+
+2005-11-23  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/plugins/modifier.escape.php:
+      replace {} string access with equivalent substr() to avoid E_STRICT
+      warnings in PHP 5.1
+
+2005-11-09  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/Smarty.class.php:
+      return valid reference in get_config_vars() when given var is non-existant
+
+2005-10-11  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/block.textformat.php
+      libs/plugins/compiler.assign.php
+      libs/plugins/function.assign_debug_info.php
+      libs/plugins/function.config_load.php
+      libs/plugins/function.counter.php
+      libs/plugins/function.eval.php
+      libs/plugins/function.fetch.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_select_date.php
+      libs/plugins/function.html_select_time.php
+      libs/plugins/function.math.php
+      libs/plugins/function.popup.php
+      libs/plugins/function.popup_init.php
+      libs/plugins/modifier.capitalize.php
+      libs/plugins/modifier.count_characters.php
+      libs/plugins/modifier.count_paragraphs.php
+      libs/plugins/modifier.count_sentences.php
+      libs/plugins/modifier.count_words.php
+      libs/plugins/modifier.date_format.php
+      libs/plugins/modifier.debug_print_var.php
+      libs/plugins/modifier.default.php
+      libs/plugins/modifier.escape.php
+      libs/plugins/modifier.indent.php
+      libs/plugins/modifier.lower.php
+      libs/plugins/modifier.regex_replace.php
+      libs/plugins/modifier.replace.php
+      libs/plugins/modifier.spacify.php
+      libs/plugins/modifier.string_format.php
+      libs/plugins/modifier.strip_tags.php
+      libs/plugins/modifier.truncate.php
+      libs/plugins/modifier.upper.php
+      libs/plugins/modifier.wordwrap.php
+      libs/plugins/shared.escape_special_chars.php
+      libs/plugins/shared.make_timestamp.php:
+      Added author title to plugins where they don't exist. I put my name where I
+      was the original or co-author. If there needs to be more credit given
+      somewhere, speak up!
+
+2005-10-10  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/plugins/function.html_image.php:
+      add path_prefix to html_image, fix incorrect secure_dir error when image
+      file is missing
+
+2005-10-04  Monte Ohrt  <monte@ohrt.com>
+
+    * demo/templates/index.tpl:
+      remove popup example, update section var syntax
+
+2005-09-16  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/de/getting-started.xml:
+      more fixes
+
+    * docs/de/getting-started.xml:
+      fix php bug #34520: broken example display (de only)
+
+2005-08-30  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/modifier.escape.php:
+      change default charset from utf8 to iso-8859-1
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      add char_set param
+
+2005-08-17  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS:
+      fix notice in debug security check
+
+    * libs/Smarty.class.php:
+      fix typo
+
+    * NEWS
+      libs/Smarty.class.php:
+      return valid reference in get_template_vars() when given var is
+      non-existant
+
+2005-08-12  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      add "urlpathinfo" escape type to escape modifier. (apache does not like %2F
+      in the PATH_INFO)
+
+2005-08-05  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers
+
+2005-08-04  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS:
+      update secure_dir notes
+
+    * NEWS:
+      allow debug.tpl to work from arbitrary dir
+
+2005-08-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed proper escaping for literal strings passed to
+      Smarty_Compiler::_expand_quoted_text() by
+      Smarty_Compiler::_parse_var_props()
+
+2005-07-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/shared.make_timestamp.php:
+      removed ambiguity for numeric values passed to smarty_make_timestamp().
+      numeric values are *always* treated as timestamps now.
+
+2005-07-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php:
+      removed E_NOTICE from Config_File::get()
+
+    * libs/Smarty.class.php:
+      removed E_NOTICE
+
+2005-07-10  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/getting-started.xml:
+      sync with EN
+
+2005-07-08  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS:
+      correct username in NEWS file
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      added passthru attribute feature to html_select_date
+
+2005-07-03  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/language-snippets.ent
+      docs/fr/preface.xml:
+      sync with EN
+
+2005-06-16  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/de/preface.xml
+      docs/de/preface.xml:
+      sync with en
+
+2005-06-13  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/plugins/modifier.truncate.php:
+      add "middle" parameter to truncate modifier
+
+2005-06-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/de/livedocs.ent:
+      added german livedocs.ent
+
+    * docs/de/language-snippets.ent
+      docs/de/preface.xml:
+      sync with en
+
+2005-06-09  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/de/bookinfo.xml
+      docs/de/getting-started.xml
+      docs/de/getting-started.xml:
+      sync with en
+
+2005-05-24  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/getting-started.xml
+      docs/fr/language-snippets.ent:
+      sync with EN
+
+2005-05-20  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/function.html_radios.php:
+      fix allowable label id characters
+
+2005-05-06  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/plugins/function.html_radios.php:
+      make form input label ids optional (monte)
+
+2005-05-02  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      add error message for empty if/elseif statements
+
+2005-04-15  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/plugins/function.html_radios.php:
+      cast selected value to string for comparison in html_radios
+
+2005-04-07  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      added xhtml compliance to html_select_date's year_as_text-feature
+      thanks to Mark West
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      fixed handling of selected month html_select_date
+      thanks to Yuri Weseman for providing problem+solution
+
+2005-04-07  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/configure.in:
+      sync configure and file-entities scripts with phpdoc, for better
+      windows/cygwin support
+
+2005-03-31  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers
+
+    * (Smarty_2_6_9)
+      NEWS:
+      update NEWS file
+
+2005-03-30  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.math.php:
+      re-enabled hex-constant. i hope in a sane way this time.
+
+2005-03-30  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/function.math.php:
+      fix function testing logic
+
+    * libs/Smarty_Compiler.class.php:
+      disable variable func calls completely
+
+    * libs/Smarty_Compiler.class.php:
+      disallow variable func calls when security is enabled
+
+2005-03-22  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      bumped version-number to 2.6.9-dev
+      added headline of 2.6.6 release to NEWS file
+
+2005-03-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * (Smarty_2_6_8)
+      NEWS:
+      maybe even better this way. thanks monte :)
+
+    * NEWS:
+      little more clear news-entry
+
+2005-03-21  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS:
+      update NEWS with e-modifier removal
+
+    * (Smarty_2_6_8)
+      libs/plugins/modifier.regex_replace.php:
+      remove e-modifier
+
+2005-03-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      objects don't get casted to arrays anymore in {foreach}
+
+2005-02-26  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      add "null" as a valid token for {if} when security is enabled
+
+2005-02-25  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS
+      libs/plugins/function.mailto.php:
+      add javascript_charcode option to mailto
+
+2005-02-24  Monte Ohrt  <monte@ohrt.com>
+
+    * NEWS:
+      update NEWS file
+
+    * QUICK_START
+      libs/plugins/function.html_radios.php:
+      add label ids to html_radios
+
+2005-02-10  Monte Ohrt  <monte@ohrt.com>
+
+    * QUICK_START:
+      update with directory structure
+
+2005-02-10  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/Makefile.in:
+      fix chm generation
+
+2005-02-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed too agressive {strip} around delimiters inside strip-blocks
+
+2005-02-10  Monte Ohrt  <monte@ohrt.com>
+
+    * QUICK_START:
+      fix a couple errors
+
+2005-02-10  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/Makefile.in
+      docs/README:
+      commiting the new tools to make the CHM manual.
+
+2005-02-09  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed handling of strip-tags with non-default delimiters
+
+2005-02-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_radios.php:
+      fixed syntax error. shame on me.
+
+2005-02-03  Monte Ohrt  <monte@ohrt.com>
+
+    * QUICK_START:
+      fix example
+
+    * QUICK_START:
+      initial commit
+
+    * RELEASE_NOTES
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers in cvs
+
+    * (Smarty_2_6_7)
+      NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      commit version numbers for new release
+
+2005-02-03  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * (Smarty_2_6_7)
+      libs/plugins/function.html_image.php:
+      fixed comment (thanks to CirTap)
+
+2005-02-01  Monte Ohrt  <monte@ohrt.com>
+
+    * libs/plugins/function.html_image.php:
+      remove border tag
+
+2005-02-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      fixed serialization of values containing newlines (like _cache_attrs)
+      in core_write_cache_file()
+      
+      bumped version to 2.6.6-dev-3 to indicate that the fileformat of cache
+      has changed
+
+2005-01-30  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed handling of hashed opening php-tags inside strip-blocks
+      (reported by titi_rafa)
+
+2005-01-30  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/fr/language-snippets.ent:
+      fix build
+
+2005-01-28  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      escape:url now uses the (RFC 1738 compliant) rawurlencode()
+
+2005-01-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      replaced ? true : false and removed intermediate $_cookie_var in the
+      handling of the SMARTY_DEBUG-cookie
+
+2005-01-22  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/bookinfo.xml:
+      update EN-Revision tag
+
+2005-01-21  Monte Ohrt  <monte@ohrt.com>
+
+    * README
+      RELEASE_NOTES
+      docs/de/bookinfo.xml
+      docs/fr/bookinfo.xml
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/plugins/function.cycle.php
+      libs/plugins/function.debug.php
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_image.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/function.html_table.php
+      libs/plugins/function.mailto.php
+      libs/plugins/modifier.cat.php
+      libs/plugins/modifier.nl2br.php
+      libs/plugins/modifier.strip.php
+      libs/plugins/outputfilter.trimwhitespace.php:
+      de-spammify e-mails
+
+    * README
+      RELEASE_NOTES
+      docs/de/bookinfo.xml
+      docs/fr/bookinfo.xml
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/plugins/function.cycle.php
+      libs/plugins/function.debug.php
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_image.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/function.html_table.php
+      libs/plugins/function.mailto.php
+      libs/plugins/modifier.cat.php
+      libs/plugins/modifier.nl2br.php
+      libs/plugins/modifier.strip.php
+      libs/plugins/outputfilter.trimwhitespace.php:
+      update copyright notices, e-mail addresses
+
+2005-01-06  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      reduced the code that is generated on a {foreach}-block that has a
+      name.
+      
+      instead of pre-computing all foreach-properties (like first, last,
+      show) on each iteration, they are computed on demand as soon as
+      {$smarty.foreach.*}-variables are used.
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      slight optimization in the compilation of $smarty.const.FOO .
+      
+      more complex consts like $smarty.const.$name still compile to
+      constant($this->_tpl_vars['name'])
+
+2005-01-05  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      make block functions and registered objects' block methods use a
+      local variable for block_content instead of $this->_block_content
+      
+      it's not necessary to have $smarty->_block_content accessible.
+
+2005-01-04  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/bookinfo.xml:
+      sync with EN
+
+2005-01-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      Happy new year from germany.
+
+2004-12-28  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php:
+      fix _read_file comments
+
+2004-12-26  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/getting-started.xml
+      docs/fr/preface.xml:
+      typo
+
+    * docs/fr/language-defs.ent
+      docs/fr/language-snippets.ent
+      docs/fr/livedocs.ent:
+      sync with EN & typo
+
+2004-12-21  Yannick Torres  <yannick.torres@keliglia.com>
+
+    * docs/fr/bookinfo.xml
+      docs/fr/getting-started.xml
+      docs/fr/translation.xml:
+      sync with EN
+
+2004-12-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed escaping of template-filenames in the generated code that loads
+      needed plugins
+
+2004-12-15  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/function.popup.php:
+      fix invalid HTML issue with popup
+
+2004-12-06  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/plugins/function.popup.php:
+      - fixed {popup} to properly handle inarray and function parameters and
+      added support for mouseoff and followmouse options
+
+2004-11-21  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/fr/livedocs.ent:
+      add livedocs specific entities files
+
+2004-11-16  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_radios.php:
+      cleaned up typecasting
+
+2004-11-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_options.php:
+      fixed semantically misleading check for $options (use isset() instead
+      of is_array() because it is always an array).
+      
+      thanks to albert almeida.
+
+2004-11-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      removed unused code
+
+2004-10-25  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/fr/bookinfo.xml
+      docs/fr/getting-started.xml:
+      sync with en
+
+2004-10-13  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      update header
+
+2004-10-02  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS:
+      fixed nocache-handling with nested includes. there was a logical error
+      in the replacement of internal nocache-tags to dynamic content that
+      lead to false results with deeply nested includes or with
+      nocache-blocks inside nocache-blocks.
+      
+      many thanks to Lars Jankowfsky for providing big help on reproducing
+      and tracking down this bug!
+
+2004-10-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      - better header for compiled includes (more in line with compiled
+      templates)
+      
+      - reuse cache_serials if a file is compiled more than once in one
+        process (force_compile)
+      
+      - don't print nocache-delimiters wenn already inside
+      process_cached_inserts()
+
+2004-09-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      switched from @count() to !empty() . this was pointed out a few times
+      by a few people with buggy error-handlers
+
+    * libs/Smarty_Compiler.class.php:
+      added some property declarations
+
+2004-09-28  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      bumped up version number to reflect incompatibility in tempfiles of
+      'core' vs. 'internals'
+
+2004-09-24  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_select_date.php:
+      fixed $start_year when no value for the year in $time is given.
+
+2004-09-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_table.php:
+      fixed handling of "inner"-attribute
+
+    * libs/Smarty_Compiler.class.php:
+      fixed handling of object derefence inside backticks
+
+2004-09-20  Monte Ohrt  <monte@ispi.net>
+
+    * libs/debug.tpl:
+      add <head></head> tags
+
+2004-09-18  boots  <jayboots@yahoo.com>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/plugins/function.config_load.php
+      libs/plugins/function.debug.php
+      libs/plugins/function.fetch.php
+      libs/plugins/function.html_image.php:
+      Fixed \\r\\n line endings mistakenly introduced in last commit. d'oh.
+
+2004-09-16  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.assemble_plugin_filepath.php
+      libs/core/core.assign_smarty_interface.php
+      libs/core/core.create_dir_structure.php
+      libs/core/core.display_debug_console.php
+      libs/core/core.get_include_path.php
+      libs/core/core.get_microtime.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.is_secure.php
+      libs/core/core.is_trusted.php
+      libs/core/core.load_plugins.php
+      libs/core/core.load_resource_plugin.php
+      libs/core/core.process_cached_inserts.php
+      libs/core/core.process_compiled_include.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.rm_auto.php
+      libs/core/core.rmdir.php
+      libs/core/core.run_insert_handler.php
+      libs/core/core.smarty_include_php.php
+      libs/core/core.write_cache_file.php
+      libs/core/core.write_compiled_include.php
+      libs/core/core.write_compiled_resource.php
+      libs/core/core.write_file.php
+      libs/plugins/function.config_load.php
+      libs/plugins/function.debug.php
+      libs/plugins/function.fetch.php
+      libs/plugins/function.html_image.php:
+      Moved /libs/core to /libs/internals and created new constant,
+      SMARTY_CORE_DIR which defaults to SMARTY_DIR/internals. This should help
+      CVS and rsynch users butupgrades will require changes and this may affect
+      3rd party plugins that use the /core dir.
+
+2004-09-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      moved $this->_num_const_regexp out of $this->_var_regexp and added it
+      to the places that affect $this->_var_regexp
+      
+      this should fix some problems parsing plugin-names endings with digits
+
+2004-09-14  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update files to 2.6.6-dev
+
+2004-09-13  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS:
+      fixed typo
+
+2004-09-13  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_6_5)
+      NEWS:
+      update NEWS file with parsing correction note
+
+2004-09-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.debug.php:
+      removed notice from {debug}
+      thanks to Peter Billen for pointing this one out!
+
+2004-09-11  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      fix more object calling syntax issues
+
+2004-09-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      added $smarty->security_settings['ALLOW_CONSTANTS']
+      including test-cases for them
+
+2004-09-09  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      break down regex to digestable chunks, fix multiple param problem with
+      method calls,
+      add object method testing to unit_test cases
+
+    * libs/Smarty_Compiler.class.php:
+      update code comment with more examples
+
+    * libs/Smarty_Compiler.class.php:
+      allow objects in arbitrary param positions
+
+    * libs/Smarty_Compiler.class.php:
+      fix object parameter regex, allow one level of object indirection
+
+    * libs/Smarty_Compiler.class.php:
+      fix compile problem with numeric constants and math operator matching
+
+2004-09-07  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update files to 2.6.5-dev
+
+    * (Smarty_2_6_4)
+      NEWS:
+      update NEWS file with 2.6.4 header
+
+2004-08-31  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      fix preg_quote
+
+    * libs/Smarty_Compiler.class.php:
+      fix math in object params, clean up some regex on the way, change
+      preg_ delimiters to ~ to avoid character clashes with ! and %
+
+2004-08-30  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      add $smarty.ldelim and $smarty.rdelim to smarty special var
+
+2004-08-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/core/core.write_file.php:
+      tempnam() seems to be borken on many installation.
+      
+      now we try tempnam first and if that fails we generate our own
+      temp-filename with uniqid()
+
+2004-08-23  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/modifier.capitalize.php:
+      dont use constant, use static var instead
+
+    * libs/plugins/modifier.capitalize.php:
+      implement optional param to capitalize for digit behavior
+
+    * libs/plugins/modifier.capitalize.php:
+      another commit to capitalize, taking special chars into account
+
+2004-08-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      cleaned up attribute-handling in Smarty_Compiler::_compile_foreach_start()
+
+2004-08-23  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/function.html_select_date.php
+      libs/plugins/modifier.capitalize.php:
+      fix capitalize modifier to not rely on buggy ucwords() func
+
+2004-08-20  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/function.html_select_date.php:
+      update version
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      make time param work with negative timestamps, force year range to include
+      given date unless explicitly set
+
+2004-08-19  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/function.fetch.php:
+      fix bug with fetch, passing user/pass in url did not work
+
+2004-08-13  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed handling of {foreachelse} and {sectionelse} that got borked with
+      the latest commit (v 1.330)
+
+2004-08-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed occasional wrong error messages on mismatched tags when
+      {else}, {elseif}, {foreachelse} or {sectionelse} is involved
+      
+      thanks to Ooypunk for pointing me on this
+
+2004-08-12  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/.cvsignore
+      docs/Makefile.in
+      docs/configure.in:
+      enable russian PDF builds
+
+2004-07-30  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/configure.in:
+      typo
+
+    * docs/Makefile.in
+      docs/README
+      docs/configure.in:
+      add make test_xml
+      this is usefull to detect XML problems
+
+2004-07-29  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/configure.in:
+      avoid warnings in head
+
+    * docs/.cvsignore
+      docs/Makefile.in
+      docs/README
+      docs/configure.in:
+      build pdf files
+      just type make pdf
+
+2004-07-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed handling of methods arguments.
+      
+      thanks to Manfred Wischin for finding this one and providing the
+      conceptual fix.
+
+2004-07-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_radios.php:
+      there was little flaw in smarty_function_html_radios() and
+      smarty_function_html_checkboxes():
+      
+      the newly introduced assign-attribute was still added to the
+      tag-output as an extra-attribute.
+      
+      fixed.
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.load_plugins.php
+      libs/core/core.load_resource_plugin.php
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_image.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/function.html_select_date.php
+      libs/plugins/function.html_select_time.php
+      libs/plugins/modifier.date_format.php:
+      backed out renaming of _get_plugin_filepath() to get_plugin_filepath()
+      
+      we'll stick to _get_plugin_filepath() and look for a more viable
+      solution to be exposed to plugin-writers.
+
+2004-07-20  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php
+      libs/core/core.is_trusted.php
+      libs/plugins/compiler.assign.php:
+      Some fixes on PhpDocumentor comments. Thanks go to Ruben Vermeersch.
+
+2004-07-16  andreas halter  <phpcvs@andreashalter.ch>
+
+    * docs/de/bookinfo.xml
+      docs/de/getting-started.xml
+      docs/de/language-defs.ent
+      docs/de/language-snippets.ent
+      docs/de/preface.xml:
+      - updated for 2.6.3
+      - updates for new build system
+      - added missing files
+      - corrections from users
+      - revcheck comments for all files
+      - big up to didou and nuno, brilliant work
+      - make test: ok
+      - make: ok
+
+2004-07-16  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/de/getting-started.xml:
+      fix the revision tracking tag
+      the revision number might not be right. just check it, please
+
+2004-07-16  andreas halter  <phpcvs@andreashalter.ch>
+
+    * docs/de/getting-started.xml:
+      - updated version (incl revcheck comment) for revcheck testing
+
+2004-07-14  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php:
+      replace " with ' where literal strings are quoted (ever so slight speedup)
+
+2004-07-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/modifier.date_format.php:
+      changed call from $smarty->_get_plugin_filepath() to
+      $smarty->get_plugin_filepath()
+
+    * libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_image.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/function.html_select_date.php
+      libs/plugins/function.html_select_time.php:
+      renamed calls to $smarty->_get_plugin_filepath() to
+      $smarty->get_plugin_filepath()
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.load_plugins.php
+      libs/core/core.load_resource_plugin.php:
+      renamed Smarty::_get_plugin_filepath() to Smarty::get_plugin_filepath()
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/core/core.write_compiled_include.php
+      libs/core/core.write_compiled_resource.php
+      libs/core/core.write_file.php:
+      removed touch() call. changing the timestamp of the compiled-template
+      to the source template's may be irritating for certain
+      source-code-caches. now a newly compiled template gets the current
+      time as timestamp.
+
+2004-07-02  gerald croes  <gerald@phpside.org>
+
+    * docs/fr/getting-started.xml
+      docs/fr/preface.xml:
+      Fixed missing tags to be able to make doc again
+
+    * docs/fr/preface.xml:
+      added the "is a good thing [TM]" as in en docs
+
+    * docs/fr/getting-started.xml:
+      added ctags, updated screen => programm listing.
+      added the technical note founded on the en doc
+
+2004-07-02  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/function.mailto.php:
+      add assign attribute to html_checkboxes and html_radios
+
+2004-07-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      removed use of get_include_filepath() inside
+      get_auto_filename(). thanks go to c960657
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      enhanced error-reporting for {foreach}
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed handling of digits inside tagnames. this problem slipped into
+      the regexps by adding support for numeric contants next to string
+      constants as variables.
+
+2004-06-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed escaping of backslashes in Smarty_Compiler::_quote_replace()
+
+2004-06-23  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/modifier.date_format.php:
+      display date_format %e, %T and %D as expected for windows
+
+2004-06-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      changed version-number to 2.6.4-dev
+
+2004-06-16  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_6_3)
+      NEWS:
+      update NEWS file with version number
+
+2004-06-09  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      added escapement of '</' to javascript escaping
+
+2004-06-08  gerald croes  <gerald@phpside.org>
+
+    * docs/fr/translation.xml:
+      Add other translators.
+
+2004-06-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      made the correct value of "use_sub_dirs" available to the compiler.
+      (not worth a NEWS-entry, i think)
+
+2004-06-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.fetch.php:
+      fix: proper initialistaion of $content.
+      thanks to Dmitry Koteroff for pointing this out.
+
+2004-05-29  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/fr/translation.xml:
+      oups :)
+
+    * docs/fr/translation.xml:
+      added translation file
+
+2004-05-28  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/Makefile.in:
+      clean also file-entities.php
+
+2004-05-28  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.mailto.php:
+      added obfuscation of protocol-string in {mailto} when using
+      hex-encoding (thanks to bharat)
+
+2004-05-26  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      enhanced auto-generated filenames for templates_c and cache
+      
+      incremented Smarty::_version because the tempfiles' structure changed
+      a little
+
+2004-05-23  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/fr/bookinfo.xml
+      docs/fr/getting-started.xml
+      docs/fr/preface.xml:
+      WS and added revcheck
+
+2004-05-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed typo in error-messages
+
+    * docs/de/language-snippets.ent
+      docs/fr/language-snippets.ent:
+      added empty language-snippets.ent to fix "make web"
+
+2004-05-12  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      add 'nonstd' escape modifier
+
+2004-05-07  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/block.textformat.php:
+      update textformat to not output wrap chars after last para
+
+2004-05-06  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/core/core.write_file.php:
+      use tempnam() instead of unqid() to create better temporary files in
+      smarty_core_write_file().
+      
+      (thanks to xces for finding this race-condition and his work on
+      fixing it)
+
+2004-05-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      added check if for file_exists() to Smarty::_read_file()
+
+2004-04-30  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      add 'mail' attribute to escape modifier
+
+2004-04-20  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/manual.xml.in:
+      added the language-snippets.ent file and started using entities for notes
+      under en/programmers/api-functions
+
+2004-04-18  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/de/getting-started.xml
+      docs/fr/getting-started.xml:
+      new global entity for zend and php-accelerator
+
+    * docs/fr/bookinfo.xml
+      docs/fr/getting-started.xml
+      docs/fr/preface.xml:
+      added myself as translator and added vim comments and xml tags
+
+2004-04-16  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS:
+      added entry for numeric constants
+
+    * libs/Smarty_Compiler.class.php:
+      removed unused 2nd param in call to _parse_var()
+
+    * libs/Smarty_Compiler.class.php:
+      added explanation for $this->_num_const_regexp
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      added escape type "decentity" to smarty_modifier_escape()
+
+    * libs/Smarty_Compiler.class.php:
+      enabled numerical constants be parsed as statements.
+      (like {10} or {10|@range:12} )
+
+    * libs/Smarty_Compiler.class.php:
+      removed unused $smarty_compiler->_dvar_num_var_regexp
+
+    * libs/Smarty.class.php:
+      reverted Stuff
+
+    * libs/debug.tpl
+      libs/core/core.assemble_plugin_filepath.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.write_file.php
+      libs/plugins/function.eval.php
+      libs/plugins/function.popup.php
+      libs/plugins/modifier.escape.php
+      libs/plugins/shared.make_timestamp.php:
+      reverted stuff
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/debug.tpl
+      libs/core/core.assemble_plugin_filepath.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.write_file.php
+      libs/plugins/function.eval.php
+      libs/plugins/function.popup.php
+      libs/plugins/modifier.escape.php
+      libs/plugins/shared.make_timestamp.php:
+      Smarty_Compiler.class.php
+
+2004-04-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/core/core.write_compiled_include.php:
+      made smarty_core_write_compiled_include() php5-aware
+      
+      if someone knows a better way than patching the source with the
+      tokenizer, please stand up!
+
+2004-04-14  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/Makefile.in:
+      remove file-entities.ent also
+
+    * docs/.cvsignore
+      docs/Makefile.in
+      docs/README:
+      allow make revcheck
+
+2004-04-13  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/configure.in:
+      do not need inipath
+
+2004-04-13  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/TODO:
+      done
+
+    * docs/configure.in
+      docs/manual.xml.in:
+      now the files entites are generated dynamically
+
+2004-04-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php:
+      removed unused functionality to load a subset of lines from a file in
+      Smarty::_read_file()
+      
+      additionally removed a warning that is emitted since php-4.3.5 when
+      fread() is called on an empty file (with filesize()==0). thanks to
+      Andreas Streichardt who pointed this out.
+
+    * NEWS
+      libs/core/core.is_secure.php:
+      smarty_core_is_secure() only checks the file for readability now, not
+      the directory where is in.
+
+    * libs/Smarty.class.php:
+      removed unused security_setting 'ALLOW_CONSTANTS'
+
+2004-04-07  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.assign_debug_info.php
+      libs/plugins/function.cycle.php
+      libs/plugins/function.mailto.php:
+      removed trailing spaces
+
+    * libs/Smarty.class.php:
+      removed unused $smarty->_error_msg
+
+2004-04-04  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/configure.in:
+      fixing my crap
+      put build_date back on-line
+
+2004-04-03  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/Makefile.in
+      docs/configure.in
+      docs/manual.xml.in:
+      trying to fix ru problems
+
+2004-03-30  Monte Ohrt  <monte@ispi.net>
+
+    * libs/core/core.display_debug_console.php:
+      fix problem with debug_tpl path and security
+
+    * NEWS
+      libs/core/core.display_debug_console.php:
+      fix problem displaying debug console when $default_resource_type is not
+      "file:"
+
+2004-03-29  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/TODO:
+      and finally, add a TODO here
+
+    * docs/de/bookinfo.xml
+      docs/de/manual.sgml
+      docs/fr/bookinfo.xml
+      docs/fr/manual.xml:
+      translate bookinfo.xml and put back the translators
+
+2004-03-28  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/manual.xml.in:
+      add global.ent and define some general entities
+
+    * docs/de/bookinfo.xml
+      docs/de/getting-started.xml
+      docs/de/language-defs.ent
+      docs/de/preface.xml:
+      add new de files
+
+    * docs/de/appendixes.sgml
+      docs/de/designers.sgml
+      docs/de/getting-started.sgml
+      docs/de/html-common.dsl
+      docs/de/preface.sgml
+      docs/de/programmers.sgml:
+      drop old de files
+
+    * docs/fr/bookinfo.xml
+      docs/fr/getting-started.xml
+      docs/fr/manual.xml
+      docs/fr/preface.xml:
+      add ommited files
+
+    * docs/fr/language-defs.ent:
+      split the french dir
+
+    * docs/fr/appendixes.sgml
+      docs/fr/designers.sgml
+      docs/fr/getting-started.sgml
+      docs/fr/html-common.dsl
+      docs/fr/manual.sgml
+      docs/fr/preface.sgml
+      docs/fr/programmers.sgml:
+      drop old french files
+
+    * docs/manual.xml.in:
+      let's put the new build system
+
+2004-03-26  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/de/common.dsl
+      docs/de/html.dsl
+      docs/fr/common.dsl
+      docs/fr/html.dsl
+      docs/fr/php.dsl:
+      not needed anymore
+
+2004-03-24  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/Makefile.in:
+      updated stylesheets
+      highlight PHP automatically
+
+    * docs/Makefile.in
+      docs/html.dsl:
+      remove unneeded file
+
+2004-03-23  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/version.ent.in:
+      remove this also
+
+    * docs/getting-started.sgml:
+      remove this one too
+
+    * docs/appendixes.sgml
+      docs/common.dsl
+      docs/designers.sgml
+      docs/html-common.dsl
+      docs/manual.sgml
+      docs/php.dsl
+      docs/preface.sgml
+      docs/programmers.sgml:
+      removing uneeded files
+
+    * docs/.cvsignore:
+      commiting missing files for docbook
+
+    * docs/.cvsignore
+      docs/Makefile.in
+      docs/configure.in
+      docs/manual.xml.in:
+      bundling docbook 4
+      now make and make web works
+
+2004-03-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.config_load.php:
+      unrolled call to the is_compiled()-check to be able to supply the
+      correct resource_base_path for config_load. this avoids errors when
+      config-files are accessed where security is enabled.
+      
+      thanks to shuther for pointing out this bug.
+
+2004-03-20  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/manual.xml.in:
+      fix build date
+
+2004-03-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.is_secure.php:
+      removed merging of $smarty->template_dir into $smarty->secure_dir
+      
+      the resource_base_path is considerd secure instead. this change should
+      have absolutely no impact on smarty's security's behaviour
+
+2004-03-18  Nuno Lopes  <nunoplopes@sapo.pt>
+
+    * docs/configure.in:
+      correcting non-existent var
+
+    * docs/.cvsignore
+      docs/Makefile.in
+      docs/configure.in
+      docs/manual.xml.in
+      docs/version.ent.in:
+      generate build date
+
+    * docs/.cvsignore
+      docs/Makefile.in
+      docs/README
+      docs/configure.in
+      docs/manual.xml.in:
+      new build/test system
+
+2004-03-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      moved setting of a default resource_base_path from
+      Smarty::_parse_resource_name() to Smarty::_fetch_resource_info()
+      
+      this shouldn't affect anything, since all calls to
+      _parse_resource_name() that are not done from within
+      _fetch_resource_info() all pass their own resource_base_path
+
+2004-03-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      removed '.' from the list of default resource_base_paths in
+      _parse_resource_name()
+      
+      this should only affect _parse_resource_name() for templates, not for
+      php-resources and not for config_files. the latter pass two their own
+      resource_base_path.
+
+2004-03-16  Mehdi Achour  <didou@keliglia.com>
+
+    * docs/appendixes.sgml
+      docs/getting-started.sgml
+      docs/preface.sgml:
+      adding editor comments
+
+    * docs/appendixes.sgml
+      docs/getting-started.sgml:
+      cleaning words spacing, killing tabulations, using roles for
+      programlisting..
+
+2004-03-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      simplified Smarty::clear_all_cache();
+
+2004-03-12  boots  <jayboots@yahoo.com>
+
+    * docs/programmers.sgml:
+      Updated is_cached prototype to indicate proper return type. (thanks to
+      Geoffrey Hoffman)
+
+2004-03-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.assemble_plugin_filepath.php:
+      fixed little bug that prevented plugins filepaths that are found in
+      php's include_path (and not in one of the plugins_dirs) from being
+      cached in the internal plugins-filepath-cache
+
+2004-03-01  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+      update include_php docs:wq
+      :q
+
+    * docs/appendixes.sgml:
+      update componentized template example to something useful
+
+2004-02-24  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      _parse_resource_name() returned true on non-existant absolute
+      paths. This caused a warning on _fetch_resource_info() when used in
+      conjunction with template_exists(). It should be fixed now without
+      negative effects.
+
+2004-02-24  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+      one more typo
+
+    * docs/designers.sgml:
+      fix typo
+
+2004-02-24  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/core/core.is_secure.php:
+      smarty_resource_*_secure got &$smarty passed errornously as 3rd
+      parameter and not as 2nd. this is fixed.
+
+2004-02-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS:
+      fix handling of integer values like width and delay im
+      smarty_function_popup()
+
+    * libs/plugins/function.popup.php:
+      fixed handling of integer-attributes
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      updated version to 2.6.3-dev
+
+2004-02-22  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_select_date.php:
+      removed notice on html_select_date with the month_empty-attribute
+
+    * libs/plugins/function.mailto.php:
+      removed 2 notices of undefined vars (thanks Cit)
+
+2004-02-17  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      add header
+
+    * (Smarty_2_6_2)
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      change some info in headers, remove fluff
+
+2004-02-13  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      correctly handle partially empty dates (like "2004--" or "-12-").
+
+    * docs/programmers.sgml:
+      learned something about <note> and sgml and applied this to the
+      use.sub.dirs-section :)
+
+    * docs/designers.sgml:
+      changed attribute-name "checked" to "selected" in the docs for
+      html_radios and html_checkboxes. "checked" is deprecated for ages
+      AFAIK and selected is recommended for consistency with {html_options}
+
+    * docs/programmers.sgml:
+      added note about use_sub_dirs and Smarty-2.6.2 .
+      fixed markup for section about clear_compiled_tpl() .
+
+2004-02-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Config_File.class.php:
+      YES and NO should not be booleanized inside triple-quotes in a
+      config-file. this behaviour changed by accident in 2.6.1 and is now
+      reverted to pre-2.6.1 behaviour
+
+2004-02-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Config_File.class.php:
+      fixed slurping of a the next line following a triple-quoted value in a
+      config-file
+
+2004-02-07  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php:
+      avoid @-operator for handling empty lines in Config_File.class.php
+
+    * libs/Smarty_Compiler.class.php:
+      removed two notices from Smarty_Compiler::_parse_is_expr()
+      (thanks shuther!)
+
+    * NEWS
+      libs/Smarty.class.php:
+      changed default for use_sub_dirs to false
+
+    * libs/plugins/function.mailto.php:
+      removed notice of undefined variable. (thanks shuther!)
+
+2004-01-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      added file and line-number-information to error-messages regarding
+      assigned objects an an error messages regarding modifiers with
+      security.
+
+2004-01-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      removed use of temporary var $_params in compiled code of block-plugins
+
+    * NEWS
+      libs/plugins/function.popup.php:
+      fixed quoting of values in smarty_function_popup()
+
+2004-01-25  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/programmers.sgml:
+      documented parameters of Smarty::clear_compiled_tpl()
+
+    * libs/Smarty_Compiler.class.php:
+      Smarty_Compiler::_syntax_error() uses Smarty::_trigger_fatal_error() now
+      instead of the trigger_error()-function
+
+    * libs/Smarty.class.php:
+      Smarty::_trigger_fatal_error() uses Smarty::trigger_error() now,
+      instead of the native trigger_error()-function
+
+    * libs/Smarty_Compiler.class.php:
+      unrecognized custom-functions trigger an error at compile now, not at
+      display-time.
+
+2004-01-23  Monte Ohrt  <monte@ispi.net>
+
+    * docs/getting-started.sgml:
+      reword a paragraph
+
+2004-01-22  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.config_load.php:
+      removed emission of unnecessary notices for unavailable config-files
+      in config_load()
+
+    * NEWS
+      libs/Config_File.class.php:
+      fixed handling of hidden sections in Config_File
+
+2004-01-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.config_load.php:
+      added handling of resources for {config_load}
+
+2004-01-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_table.php:
+      fixed bug when using arrays with tr_attr and td_attr in {html_table}
+
+2004-01-16  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      add unit testing
+
+    * NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers, add initial unit test directory
+
+    * (Smarty_2_6_1)
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers for 2.6.1 release
+
+2004-01-16  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * (Smarty_2_6_1)
+      NEWS
+      docs/programmers.sgml
+      libs/Smarty.class.php:
+      renamed $smarty->tpl_rror_reporting to $smarty->error_reporting
+      "tpl_" is a bit redundant here (it's a TemPLate-engine overall :)
+
+2004-01-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_image.php:
+      forgot to remove duplicate is_secure()-check
+
+    * NEWS
+      libs/plugins/function.html_image.php:
+      fix: $smarty->security is now correctly handled
+      
+      minor optimizations:
+         core/core.is_secure.php is only included when needed
+         $dpi_default is only determined when needed
+
+2004-01-14  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/appendixes.sgml
+      docs/programmers.sgml:
+      removed suggestions to use extract() from the manual
+
+    * docs/designers.sgml:
+      fixed typo
+
+2004-01-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      mention SCRIPT_NAME below {$smarty} reserved variable because it got
+      lost in the docs for $smarty->global_assign
+
+    * docs/designers.sgml:
+      added docs for {$smarty.version} special variable
+
+    * docs/programmers.sgml:
+      removed docs for $global_assign
+
+    * docs/programmers.sgml:
+      added docs for tpl_error_reporting
+
+    * docs/designers.sgml:
+      added docs for year_empty-, month_empty- and day_emtpy-attributes of
+      html_select_date. maybe an example is needed to better explain empty
+      values in YYY-MM-DD.
+
+2004-01-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed handling of {php}-tags
+
+2004-01-10  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+      fix html_checkboxes examples
+
+2004-01-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/core/core.assemble_plugin_filepath.php:
+      added caching of requested paths to smarty_core_assemble_plugin_filepath()
+
+    * NEWS:
+      fix handling of comments inside {php}- and {literal}-blocks
+
+    * libs/Smarty_Compiler.class.php:
+      fixed handling of comments inside {php} and {literal}
+
+2004-01-06  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Config_File.class.php:
+      fixed bug handling triple-quotes in config-files
+
+    * libs/Config_File.class.php:
+      fixed bugs with triple-quotes in config-files
+      thanks BRDude for finding them testing!
+
+2004-01-02  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      removed unnecessary param in call to _fetch_resource_info()
+
+2003-12-30  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      oops! removed tabs.
+
+2003-12-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      made $SCRIPT_NAME available again
+      changes default for request_use_auto_global to prefer autoglobals
+
+    * libs/Smarty.class.php:
+      removed tabs and trailing spaces
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      readded default_modifiers. who removed that?
+
+2003-12-23  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      add portuguese docs
+
+2003-12-22  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+      fix counter example
+
+2003-12-19  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php:
+      add debug console persistance feature
+
+2003-12-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/block.textformat.php
+      libs/plugins/function.html_table.php
+      libs/plugins/function.popup.php:
+      removed extract(). enhanced parameter parsing.
+
+    * libs/plugins/function.counter.php
+      libs/plugins/function.fetch.php
+      libs/plugins/function.popup_init.php
+      libs/plugins/modifier.capitalize.php
+      libs/plugins/modifier.cat.php
+      libs/plugins/modifier.date_format.php
+      libs/plugins/modifier.debug_print_var.php
+      libs/plugins/modifier.escape.php
+      libs/plugins/modifier.indent.php
+      libs/plugins/modifier.lower.php
+      libs/plugins/modifier.nl2br.php
+      libs/plugins/modifier.strip.php
+      libs/plugins/modifier.upper.php
+      libs/plugins/modifier.wordwrap.php
+      libs/plugins/outputfilter.trimwhitespace.php
+      libs/plugins/shared.escape_special_chars.php:
+      removed tabs. fixed indentiation.
+
+    * libs/plugins/modifier.truncate.php:
+      removed tabs
+
+    * libs/plugins/function.counter.php
+      libs/plugins/function.cycle.php:
+      removed extract() from parameter-parsing
+
+2003-12-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_select_date.php:
+      fix plugin-name in error message
+
+    * libs/plugins/function.html_select_time.php:
+      remove extract-call from {html_select_time}
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      allow single-digit days and months without smarty_make_timestamp()
+      this makes dates like "1968-11-6" work correctly since no strtotime()
+      is involved
+      
+      add warning when unknown parameter is passed
+
+2003-12-16  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      fix headers sent erroneously with cache_modified_check and fetch()
+
+2003-12-12  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/function.config_load.php:
+      move set_path() call below the conditional bracket
+
+    * NEWS
+      libs/plugins/function.config_load.php:
+      fix config_load filepath bug
+
+2003-12-12  boots  <jayboots@yahoo.com>
+
+    * docs/designers.sgml:
+      Updated language.function.if with additional annotation and to fix error
+      that broke docs build process
+
+2003-12-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      little optimization for "is odd" and "is even"
+
+2003-12-11  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix 'is even by' and 'is odd by' logic
+
+2003-12-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      update example-output of {mailto}
+
+    * libs/plugins/function.mailto.php:
+      removed extract-call -> cleaner parameter-handling
+
+    * libs/plugins/function.mailto.php:
+      fixed indentiation
+
+    * TODO:
+      removed two done topics
+
+2003-12-11  boots  <jayboots@yahoo.com>
+
+    * docs/designers.sgml:
+      Updated language.function.if to describe qualifiers (thanks andre)
+
+2003-12-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_select_date.php:
+      added day_empty, month_empty, year_empty and all_empty attributes
+      to pass an undefined date use {html_select_date time="--" ...}
+
+    * libs/plugins/function.html_select_date.php:
+      removed extract()-call
+
+    * libs/plugins/function.html_select_date.php:
+      fixed indetiation
+
+2003-12-10  boots  <jayboots@yahoo.com>
+
+    * NEWS
+      docs/designers.sgml:
+      Added table to language.function.if to describe qualifiers
+
+2003-12-09  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_options.php:
+      strict comparason didn't work in all cases. use type-casting now.
+
+    * NEWS
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_options.php:
+      fix bug when comparing array-keys to "selected" in html_options and
+      html_checkboxes
+      
+      in_array() uses "strict" comparason now.
+
+    * libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_radios.php:
+      removed tabs, fixed indentiation
+
+2003-12-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      add better checks for correctly nested tags when compiling
+
+2003-12-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/plugins/function.html_image.php:
+      fix: check $smarty->request_use_auto_globals at the last occurences of
+           HTTP_*_VARS
+
+2003-12-03  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      remove $global_assign property from Smarty and $global_assign-handling
+      from the constructor. the only visible change is, that $SCRIPT_NAME is
+      not available in the tempates anymore. $smarty.server.SCRIPT_NAME has
+      to be used from now.
+
+2003-12-03  boots  <jayboots@yahoo.com>
+
+    * docs/designers.sgml:
+      Fixed example for count_characters
+
+2003-12-01  boots  <jayboots@yahoo.com>
+
+    * docs/designers.sgml:
+      Added section "Escaping Smarty Parsing" under Basic Syntax.
+
+2003-12-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.create_dir_structure.php:
+      thought again about my latest commit and backed it out.
+
+    * libs/core/core.create_dir_structure.php:
+      fix root-dir-handling on windows filepath
+
+2003-11-29  boots  <jayboots@yahoo.com>
+
+    * libs/plugins/function.config_load.php:
+      really make the fixes the last patch was supposed to do
+
+    * libs/plugins/function.config_load.php:
+      removed tabs and killed trailing white-space
+
+    * libs/plugins/function.config_load.php:
+      changed $smarty->_syntax_error to $smarty->trigger_error
+
+2003-11-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/modifier.debug_print_var.php:
+      remove warning in debug_print_var on php-resources
+
+    * README:
+      fix version number
+
+2003-11-26  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      raise max_level for $smarty.config... to 3 to allow arrays of config-vars
+
+2003-11-25  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      changed version-tag to indicate incompatibility to older compiled
+      templates
+
+2003-11-24  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/compiler.assign.php
+      libs/plugins/function.assign.php:
+      move function.assign.php to compiler.assign.php
+
+    * libs/core/core.get_include_path.php:
+      silence occasional warnings of open_basedir- and
+      safe_mode-restrictions in core.get_include_path.php
+
+2003-11-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.write_compiled_resource.php
+      libs/core/core.write_file.php:
+      avoid touch()-ing of recently unlinked files by touch()-ing the
+      tempfile before rename instead of touch()-ing the resulting file after
+      rename.
+
+    * NEWS
+      libs/Smarty.class.php:
+      add property $tpl_error_reporting
+
+2003-11-22  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.assign.php:
+      remove use of extract() in smarty_function_assign()
+
+    * NEWS
+      libs/Smarty.class.php:
+      remove property $undefined. "null" is used literally instead
+
+2003-11-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      remove two E_NOTICES
+
+2003-11-20  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      change version to 2.6.1-dev
+
+2003-11-19  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_6_0)
+      NEWS:
+      update NEWS file
+
+    * (Smarty_2_6_0)
+      docs/designers.sgml
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      change version numbers to 2.6.0
+
+2003-11-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml
+      docs/de/designers.sgml
+      docs/fr/designers.sgml:
+      fix examples of escape-modifier (in docs, docs/de and docs/fr !)
+
+2003-11-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      move Smarty::quote_replace() to Smarty_Compiler::_quote_replace()
+
+    * libs/Smarty.class.php:
+      removed extract-calls from _include()- and _eval()-wrappers
+      variables passed with {include_php} have to accessed as members of $params
+      now
+
+2003-11-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      fixed typo
+
+2003-11-13  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php:
+      fix occasional notice
+
+2003-11-13  andreas halter  <phpcvs@andreashalter.ch>
+
+    * docs/de/designers.sgml:
+      - added cat modifier, thanks messju :-)
+
+2003-11-13  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_6_0-RC3)
+      NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      commit RC3 tags
+
+2003-11-13  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix handling of $var.key inside []
+
+    * libs/Smarty.class.php:
+      fix unnecessary loading of core.load_resource_plugin.php
+
+    * (Smarty_2_6_0-RC3)
+      docs/fr/designers.sgml:
+      fixed example of html_table
+
+2003-11-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/core/core.process_cached_inserts.php:
+      fix handling of assign inside {insert}-tags
+
+2003-11-06  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.read_cache_file.php:
+      added $exp_time-parameter
+
+    * docs/programmers.sgml:
+      added $exp_time to cache_handler_func-example
+
+    * libs/Smarty.class.php
+      libs/core/core.write_cache_file.php:
+      added $exp_time-parameter of clear_cache() and clear_all_cache() to
+      cache_handler_func.
+
+2003-11-05  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Config_File.class.php:
+      fix handling if [...] inside triple-quotes in config-files
+
+2003-11-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      fixed little bug in _parse_resource_name() (jlgunter, messju)
+
+2003-11-03  andreas halter  <phpcvs@andreashalter.ch>
+
+    * docs/designers.sgml
+      docs/de/designers.sgml
+      docs/fr/designers.sgml:
+      - changed Smarty.php.class occurences to Smarty.class.php
+
+2003-10-29  boots  <jayboots@yahoo.com>
+
+    * docs/appendixes.sgml
+      docs/designers.sgml
+      docs/manual.sgml
+      docs/programmers.sgml
+      docs/de/appendixes.sgml
+      docs/de/designers.sgml
+      docs/de/programmers.sgml
+      docs/fr/appendixes.sgml
+      docs/fr/designers.sgml
+      docs/fr/getting-started.sgml
+      docs/fr/manual.sgml
+      docs/fr/preface.sgml
+      docs/fr/programmers.sgml:
+      Fixes to documentation syntax so that all content can be processed used
+      xsltproc docbook-xsl tools. In particular, fixes unescaped entities,
+      broken tags, unquoted attributes.
+
+2003-10-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix handling of simple-math-operators inside modifiers
+
+2003-10-25  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      removed unused property _output_type
+      removed unused param $tag_attrs of _parse_var_props()
+      cleaned up alignment of class-properties
+
+2003-10-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      removed notice in php-tag handling in Smarty_Compiler::_compile_file()
+
+    * libs/Smarty_Compiler.class.php:
+      removed two occasional E_NOTICES from
+      Smarty_Compiler::_compile_include_php_tag()
+
+    * NEWS
+      libs/core/core.create_dir_structure.php:
+      fix handling of trailing-slashes in open_basedir in
+      smarty_core_create_dir_structure()
+
+2003-10-20  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      elements inside `` are bracketed now inside the compiled-tpl. this
+      fixes some issues with simple-math inside backticks.
+
+2003-10-16  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+      update overlib docs, no working examples
+
+2003-10-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/core/core.is_secure.php:
+      move check for template_dir in secure_dir-array into core.is_secure.php
+      
+      this makes template_exists() work correctly with security=true even if
+      template_dir is not inside the secure_dir-array
+
+2003-10-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/shared.make_timestamp.php:
+      tightened check for YYYYMMDDHHMMSS-format. thanks konstantin for
+      pointing this out.
+      
+      removed a few tabs.
+
+    * libs/Smarty_Compiler.class.php:
+      fix precedence of simple-math-operators before modifiers.
+      thanks dominik!
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.assemble_plugin_filepath.php
+      libs/core/core.assign_smarty_interface.php
+      libs/core/core.create_dir_structure.php
+      libs/core/core.display_debug_console.php
+      libs/core/core.get_include_path.php
+      libs/core/core.get_microtime.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.is_secure.php
+      libs/core/core.is_trusted.php
+      libs/core/core.load_plugins.php
+      libs/core/core.load_resource_plugin.php
+      libs/core/core.process_cached_inserts.php
+      libs/core/core.process_compiled_include.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.rm_auto.php
+      libs/core/core.rmdir.php
+      libs/core/core.run_insert_handler.php
+      libs/core/core.smarty_include_php.php
+      libs/core/core.write_compiled_include.php
+      libs/core/core.write_compiled_resource.php
+      libs/core/core.write_file.php:
+      removed tabs from the main and the core/*.php files
+
+2003-10-08  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_6_0-RC2)
+      NEWS
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      update version numbers to RC2
+
+2003-09-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml
+      docs/de/designers.sgml:
+      fixed description of cycle's advance-attribute
+
+2003-09-16  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      apply modifiers only once to section-loop and foreach-from attributes
+
+2003-09-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.write_cache_paths_file.php:
+      backed out _smarty_cached_paths-file-handling
+
+    * libs/Smarty.class.php
+      libs/core/core.rm_auto.php:
+      fixed clear_compiled_tpl with explicit $tpl_file given
+      fixed return value of smarty_core_rm_auto() + Smarty::_unlink()
+
+    * libs/Smarty.class.php:
+      little fix in _get_auto_filename()
+
+2003-09-14  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/core/core.assemble_auto_filename.php:
+      removed auto-filenames from path-cache. merged assemble_auto_filename
+      back into Smarty::_get_auto_filename()
+
+2003-09-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed quoting of modifier parameters
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.load_plugins.php
+      libs/core/core.load_resource_plugin.php:
+      remove Smarty::_plugin_implementation_exists() - use php's native
+      is_callable()
+
+2003-09-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      silenced two notices acces HTTP_SERVER_VARS
+
+2003-09-10  andreas halter  <phpcvs@andreashalter.ch>
+
+    * docs/de/designers.sgml
+      docs/de/getting-started.sgml
+      docs/de/programmers.sgml:
+      - minor fixes (2 rep), slight wording changes
+      - jade transform problem fixed
+
+2003-09-08  andreas halter  <phpcvs@andreashalter.ch>
+
+    * docs/de/designers.sgml
+      docs/de/getting-started.sgml
+      docs/de/manual.sgml
+      docs/de/preface.sgml
+      docs/de/programmers.sgml:
+      all updated for 2.6.0 release, translated everything from 2_5_0 branch to
+      20030908
+
+2003-09-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      proper checking for files in  _fetch_resource_info()
+
+2003-09-02  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      ignore {strip}/{/strip) inside {strip}-blocks
+
+    * libs/plugins/function.mailto.php:
+      fixed 2 notices in smarty_function_mailto()
+
+2003-09-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      re-include cache_paths on multiple calls to fetch() to avoid
+      inconsistencies
+      at multiple calls to fetch() in one script
+
+    * libs/Smarty_Compiler.class.php:
+      fixed handling of \r in {strip}
+      renamed $_trailing_lf to $_additional_newline
+
+    * libs/Smarty_Compiler.class.php:
+      the weekly fix for {strip} :)
+
+    * docs/designers.sgml:
+      fixed example for simple math.
+
+2003-08-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.assign_smarty_interface.php
+      libs/core/core.display_debug_console.php
+      libs/plugins/function.assign.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_table.php:
+      fixed PHPDocumentor-comments (thanks Konstantin)
+
+    * libs/core/core.rmdir.php:
+      made rmdir a bit more optimistic. especially it now removes
+      directories correctly that where created accidently by "safe_mode=On
+      && $use_sub_dirs=true"
+
+2003-08-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed removal of leading/trailing newlines in {strip}-blocks
+
+2003-08-25  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * INSTALL:
+      added note emphasizing the introduction of "libs/" with 2.5.0
+
+    * NEWS
+      libs/plugins/modifier.escape.php:
+      fixed proper escaping of " and ' with escape:javascript
+
+2003-08-22  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/core/core.assemble_plugin_filepath.php:
+      fixed bug in traversal of $smarty->plugins_dir-array in
+      smarty_core_assemble_plugin_filepath(). the first matching plugin in
+      the path should be used, not the last one.
+
+    * libs/core/core.read_cache_file.php:
+      discard $_cache_info when the cache should be regenerated
+
+2003-08-20  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php
+      libs/plugins/block.strip.php:
+      reverted {strip} from a block-plugin back into the compiler
+
+    * docs/programmers.sgml:
+      fixed examples for register_function() and register_block()
+
+    * libs/Smarty.class.php:
+      made template_exists() quiet when the template does not exist (thanks
+      to konstatin for pointing this out)
+
+2003-08-18  Monte Ohrt  <monte@ispi.net>
+
+    * docs/getting-started.sgml:
+      fix example title
+
+    * docs/README
+      docs/getting-started.sgml:
+      change installation wording confusion
+
+2003-08-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/core/core.read_cache_file.php:
+      fixed unnecessary load of source in template_exists() and the
+      compile-check of smarty_core_read_cache_file()
+
+    * libs/Smarty_Compiler.class.php:
+      allow section-, array- and object-dereference in $smarty-references
+
+2003-08-15  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      added parameter-descriptions for count_characters (thanks Konstantin
+      A. Pelepelin)
+      
+      fixed docs for {html_checkboxes}
+
+2003-08-14  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/core/core.read_cache_file.php:
+      fixed timestamp-check of config-files in smarty_core_read_cache_file()
+
+    * libs/Smarty.class.php:
+      fixed typecasting for arrays in _parse_resource_name()
+
+    * NEWS
+      libs/plugins/function.config_load.php:
+      fixes in config_load:
+      - handling of section-attribute
+      - reusing the same config-file multiple times
+      - serialization of config-data for php<4.2.0 (no var_export)
+      
+      many thanks to atu for pointing this out and for testing
+
+2003-08-13  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/core/core.smarty_include_php.php:
+      fixed problem with vars as attributes in {include_php}
+
+2003-08-13  Monte Ohrt  <monte@ispi.net>
+
+    * docs/README:
+      commit README file for documentation compiling
+
+2003-08-13  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/debug.tpl
+      libs/plugins/modifier.debug_print_var.php:
+      removed '\r' from debug_print_vars' output
+      properly escape vars in javascript-version of debug.tpl
+
+2003-08-11  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_6_0_RC1)
+      NEWS
+      docs/designers.sgml
+      docs/html.dsl
+      docs/php.dsl
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      get ready for 2.6.0-RC1 release
+
+2003-08-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      fixed status-header for cache_modified_check under cgi-sapi
+
+2003-08-09  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.is_secure.php
+      libs/core/core.is_trusted.php:
+      synced secure_dir-checking with trusted_dir-checking
+
+    * libs/core/core.is_secure.php:
+      tightenend path checking in smarty_core_is_secure()
+
+2003-08-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      fix: proper nesting of $smarty->_cache_including flag in cascaded
+      cached/not-cached/fetched/inserted/foo-templates
+
+    * libs/debug.tpl:
+      better escaping for $_debug_tpls[templates].filenames
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      removed redundant $smarty from Smarty::_smarty_include()
+
+    * libs/debug.tpl:
+      proper escaping of filenames in debug-console (thanks to prossel).
+
+2003-08-07  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/programmers.sgml:
+      added docs for block-methods of registered objects
+
+    * docs/programmers.sgml:
+      fixed typo in example for registered objects
+
+    * docs/designers.sgml:
+      fixed exampls of html_image and html_checkboxes
+
+    * libs/plugins/function.debug.php:
+      fixed {debug} and removed tabs in function.debug.php
+
+    * docs/programmers.sgml:
+      fixed example for register_object
+
+    * docs/designers.sgml
+      docs/programmers.sgml:
+      updated docs for capture, html_table, html_image and register_object
+
+2003-08-07  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      docs/programmers.sgml:
+      add math and default_resource_type to docs
+
+    * docs/getting-started.sgml:
+      add core to example, add tech note
+
+2003-08-07  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/manual.sgml
+      docs/fr/manual.sgml:
+      upd copyright in the docs
+
+2003-08-07  Monte Ohrt  <monte@ispi.net>
+
+    * docs/getting-started.sgml:
+      added core directory to install instructions
+
+2003-08-07  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml
+      docs/programmers.sgml:
+      added docs for php-functions as modifiers
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      better caching of attributes for $cacheable=false-plugins
+
+    * docs/programmers.sgml:
+      added section "caching.cacheable" to the docs, explaining the usage of
+      the $cacheable-flag of the register_(block|compiler|function)-functions
+
+    * libs/Smarty_Compiler.class.php:
+      fixed output of custom-functions with cached attributes
+
+    * docs/programmers.sgml:
+      docs update on callbacks to the register_*-functions
+
+2003-08-06  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.process_compiled_include.php:
+      added optional parameter $cache_attrs to register_function() and
+      register_block(). $cache_attrs is an array containing attribute- names
+      that should be cached on calls to functions that have $cacheable set
+      to false.
+
+    * libs/Smarty.class.php:
+      fixed bug in _run_mod_handler
+
+    * libs/Smarty_Compiler.class.php:
+      fixed bug with autoload-handling of modifiers. thanks ándre.
+
+2003-08-05  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      updated copyright notice
+
+    * libs/Smarty.class.php
+      libs/core/core.load_plugins.php:
+      fixed bug that occurred when using the same not-cacheable plugin in
+      multiple includes
+
+    * docs/programmers.sgml:
+      docs-update for plugins.writing
+
+2003-08-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml
+      docs/programmers.sgml:
+      updated docs for register_block_function(), block-functions,
+      $request_use_auto_globals and html_checkboxes
+
+2003-07-31  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      enabled registration of class-methods as callbacks for the
+      register_*-functions
+      
+      use: array('classname', 'method_name')) as callback
+
+2003-07-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      modifiers are resolved at compile-time now. _run_mod_handler() is
+      still used for modifiers with map_array=true (== no preceeding '@')
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.smarty_include.php:
+      moved _smarty_include() back into Smarty.class.php
+
+    * libs/Smarty.class.php
+      libs/core/core.load_plugins.php:
+      prevent unnecessary calls to _read_file() in _is_compiled()
+      converted method-call to internal function-call in
+      smarty_core_load_plugins()
+
+2003-07-28  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      quote smarty-header properly to prevent resource-names from escaping from
+      the comment
+
+2003-07-25  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.create_dir_structure.php:
+      weakend race-condition and removed bogus error-message caused by that
+      in smarty_core_create_dir_structure().
+
+2003-07-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/core/core.display_debug_console.php
+      libs/core/core.fetch_resource_info.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.parse_resource_name.php
+      libs/core/core.process_cached_inserts.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.run_insert_handler.php
+      libs/core/core.smarty_include.php
+      libs/core/core.smarty_include_php.php
+      libs/plugins/function.eval.php:
+      moved  _fetch_resource_info and _parse_resource_name back into
+      Smarty.class.php
+      renamed smarty_include and smarty_eval wrappers to _include and _eval
+
+2003-07-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.process_compiled_include.php
+      libs/core/core.read_cache_file.php:
+      improved checking of compiled_include against cached-template with
+      non-cached-chunks
+
+    * libs/core/core.write_compiled_include.php:
+      fixed too short open-tag
+
+    * libs/plugins/function.eval.php:
+      fixed assign parameter for eval (must have gotton lost on its way to 2.5.0)
+      cleaned up indentiation
+
+2003-07-03  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      resurrected $foo->$bar syntax
+
+    * libs/Smarty_Compiler.class.php:
+      i'm so stupid. kick me.
+
+    * libs/Smarty_Compiler.class.php:
+      fixed initialisation of $this->_plugins in compile_block_tag()
+
+2003-07-03  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Config_File.class.php:
+      add preg_quote delimiter
+
+2003-07-03  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      applied fix for {$var1->p1|modifier:$var2->p2}-syntax - thanks Dominik
+
+2003-07-02  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed duplicate generation of arg-list in _compile_block_tag()
+
+    * libs/Smarty_Compiler.class.php:
+      fixed off-by-one-error in nocache-tag-handling
+
+2003-06-30  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      backed out errornously committed support for $foo->$bar
+
+    * libs/core/core.write_file.php:
+      fixed indentiation, silenced occasional warning
+
+    * libs/plugins/function.html_image.php:
+      match first character of file-attribute against "/" instead of
+      DIRECTORY_SEPARATOR since it is a url-path and not a file-path.
+
+    * libs/Smarty_Compiler.class.php
+      libs/core/core.write_file.php
+      libs/plugins/function.html_image.php:
+      libs/plugins/function.html_image.php
+
+    * libs/Smarty_Compiler.class.php:
+      re-fixed cacheable_state-handling
+
+    * libs/core/core.display_debug_console.php
+      libs/core/core.process_cached_inserts.php
+      libs/core/core.process_compiled_include.php
+      libs/core/core.run_insert_handler.php:
+      extincting $this out of smarty_core_*-functions
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      fixed handling of nocache-state
+
+2003-06-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/core/core.smarty_include.php
+      libs/core/core.smarty_include_php.php
+      libs/plugins/function.eval.php:
+      removed $this from smarty_include and smarty_include_php
+      added cleaner handling of $this to {eval}
+
+    * libs/core/core.load_resource_plugin.php:
+      fixed inlude_once-call
+
+    * docs/de/designers.sgml
+      docs/fr/designers.sgml:
+      fixed examples of html_radios and html_checkboxes in german and french docs
+
+2003-06-25  Monte Ohrt  <monte@ispi.net>
+
+    * libs/core/core.assemble_auto_filename.php
+      libs/core/core.write_cache_paths_file.php:
+      fix typo, fix write_cache_paths logic
+
+    * libs/Smarty.class.php
+      libs/core/core.assemble_auto_filename.php:
+      fix SMARTY_COMPILE_DIR_SEP problem, make local var
+
+2003-06-24  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php
+      libs/core/core.assemble_auto_filename.php
+      libs/core/core.write_cache_paths_file.php:
+      fixed cache_paths bug, simplified filename assembly logic
+
+2003-06-24  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.html_image.php:
+      added parsing of forgotton param "basedir"
+
+    * libs/Smarty_Compiler.class.php:
+      fixed $smarty.get-reference
+
+    * libs/plugins/block.textformat.php:
+      removed warning
+
+    * libs/Smarty_Compiler.class.php:
+      fixed value of _cacheable_state on compiler-startup
+
+2003-06-23  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.write_cache_paths_file.php:
+      make cache_path per resource, fix a couple directory path issues
+
+2003-06-23  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      removed warning when compiling empty template
+
+    * libs/core/core.write_compiled_include.php:
+      fixed bug in write_compiled_include
+
+    * libs/core/core.assemble_plugin_filepath.php:
+      fixed warning
+
+2003-06-22  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.eval.php:
+      fixed propagation of $this into evald code in smarty_function_eval()
+
+    * libs/core/core.write_cache_paths_file.php
+      libs/core/core.write_compiled_include.php:
+      fix in compiled-include-handling
+
+    * libs/core/core.assemble_auto_filename.php
+      libs/core/core.assemble_plugin_filepath.php
+      libs/core/core.assign_smarty_interface.php
+      libs/core/core.create_dir_structure.php
+      libs/core/core.fetch_resource_info.php
+      libs/core/core.get_include_path.php
+      libs/core/core.get_microtime.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.is_secure.php
+      libs/core/core.is_trusted.php
+      libs/core/core.load_plugins.php
+      libs/core/core.load_resource_plugin.php
+      libs/core/core.parse_resource_name.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.rm_auto.php
+      libs/core/core.rmdir.php
+      libs/core/core.write_cache_file.php
+      libs/core/core.write_cache_paths_file.php
+      libs/core/core.write_compiled_include.php
+      libs/core/core.write_compiled_resource.php
+      libs/core/core.write_file.php
+      libs/plugins/modifier.date_format.php:
+      started moving from $this to $smarty in core.*.php
+
+2003-06-21  Monte Ohrt  <monte@ispi.net>
+
+    * libs/core/core.create_dir_structure.php
+      libs/core/core.write_file.php
+      libs/plugins/function.config_load.php:
+      fix more dir paths
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/core/core.assemble_auto_filename.php
+      libs/core/core.assemble_plugin_filepath.php
+      libs/core/core.fetch_resource_info.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.parse_resource_name.php
+      libs/core/core.process_cached_inserts.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.rm_auto.php
+      libs/core/core.rmdir.php
+      libs/core/core.run_insert_handler.php
+      libs/core/core.smarty_include.php
+      libs/core/core.smarty_include_php.php
+      libs/core/core.write_cache_file.php
+      libs/core/core.write_cache_paths_file.php
+      libs/core/core.write_compiled_include.php
+      libs/core/core.write_compiled_resource.php
+      libs/core/core.write_file.php
+      libs/plugins/function.config_load.php
+      libs/plugins/function.fetch.php
+      libs/plugins/function.html_image.php:
+      fix filepaths to core files to use DIRECTORY_SEPARATOR
+
+2003-06-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed {plugin|modifier} syntax
+
+    * libs/Smarty.class.php
+      libs/core/core.write_compiled_include.php:
+      fixed compiled include handling
+
+2003-06-21  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.assemble_auto_filename.php
+      libs/core/core.assemble_plugin_filepath.php
+      libs/core/core.write_cache_paths_file.php:
+      added filepath caching
+
+2003-06-20  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      update more varnames
+
+    * libs/Smarty.class.php
+      libs/core/core.display_debug_console.php
+      libs/core/core.fetch_file_info.php
+      libs/core/core.fetch_resource_info.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.parse_file_path.php
+      libs/core/core.parse_resource_name.php
+      libs/core/core.process_cached_inserts.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.run_insert_handler.php
+      libs/core/core.smarty_include.php
+      libs/core/core.smarty_include_php.php
+      libs/core/core.write_compiled_resource.php
+      libs/core/core.write_compiled_template.php
+      libs/plugins/function.config_load.php:
+      refactored var naming to better reflect "resource" instead of "file" where
+      appropriate
+
+2003-06-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      updated version-number to 2.5.0-cvs
+
+    * libs/core/core.write_cache_file.php:
+      omit is-cache_dir-writable-check if a cache_handler_function is in use
+
+    * libs/core/core.smarty_include_php.php:
+      fixed comments in smarty_include_php
+
+2003-06-19  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.display_debug_console.php
+      libs/core/core.smarty_include.php
+      libs/plugins/function.eval.php:
+      split up _compile_template to _compile_file and _compile_source, fix eval
+      function
+      VS: ----------------------------------------------------------------------
+
+    * libs/plugins/function.config_load.php:
+      fix logic for _is_compiled()
+
+2003-06-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      added optional assign-attribute to {capture}-tag
+
+    * NEWS
+      libs/Smarty.class.php:
+      added $cacheable-parameter to register_compiler_function()
+
+2003-06-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.load_plugins.php
+      libs/core/core.process_compiled_include.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.write_cache_file.php
+      libs/core/core.write_compiled_include.php:
+      added $cacheable-parameter to register_function() and register_block()
+
+    * libs/Smarty.class.php:
+      append '.php' to all compiled templates regardless of the settings of
+      $use_sub_dirs
+
+    * libs/Smarty.class.php
+      libs/core/core.read_cache_file.php:
+      fixed $file_path-parameters  passed to smarty_core_fetch_file_info()
+
+2003-06-17  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      fix name
+
+    * libs/Smarty_Compiler.class.php:
+      change varnames to follow coding methods
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      add math patch to core
+
+2003-06-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/core/core.smarty_include.php:
+      switched _process_template() to _is_compiled()-logic
+
+2003-06-17  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php:
+      fix _is_compiled logic
+
+    * NEWS:
+      update news file
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      fix _run_mod_handler routine
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.display_debug_console.php
+      libs/core/core.fetch_file_info.php
+      libs/core/core.parse_file_path.php
+      libs/core/core.write_compiled_template.php
+      libs/plugins/function.config_load.php:
+      fix path problems, rename some varibles from "template" to "file"
+
+2003-06-16  Monte Ohrt  <monte@ispi.net>
+
+    * libs/core/core.fetch_file_info.php
+      libs/core/core.fetch_template_info.php:
+      rename file, commit
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.parse_file_path.php
+      libs/core/core.read_cache_file.php
+      libs/plugins/block.strip.php
+      libs/plugins/block.textformat.php
+      libs/plugins/compiler.config_load.php
+      libs/plugins/function.config_load.php
+      libs/plugins/function.eval.php
+      libs/plugins/function.fetch.php
+      libs/plugins/function.html_image.php:
+      fix config_load, compile fetched arrays to compile_dir, switch display
+      back to runtime. clean up var names and function names,  split up compile
+      testing and compiling to separate funcs, rename some template_* functions
+      to
+      file_* functions and update logic so they can be used for file resources
+      other than templates.
+
+2003-06-16  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed little bug in _compile_custom_tag()
+
+2003-06-16  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/core/core.assign_smarty_interface.php
+      libs/core/core.create_dir_structure.php
+      libs/core/core.display_debug_console.php
+      libs/core/core.fetch_template_info.php
+      libs/core/core.get_include_path.php
+      libs/core/core.get_microtime.php
+      libs/core/core.get_php_resource.php
+      libs/core/core.is_secure.php
+      libs/core/core.is_trusted.php
+      libs/core/core.load_plugins.php
+      libs/core/core.load_resource_plugin.php
+      libs/core/core.parse_file_path.php
+      libs/core/core.process_cached_inserts.php
+      libs/core/core.read_cache_file.php
+      libs/core/core.rm_auto.php
+      libs/core/core.rmdir.php
+      libs/core/core.run_insert_handler.php
+      libs/core/core.smarty_include.php
+      libs/core/core.smarty_include_php.php
+      libs/core/core.write_cache_file.php
+      libs/core/core.write_compiled_template.php
+      libs/core/core.write_file.php
+      libs/plugins/core.assign_smarty_interface.php
+      libs/plugins/core.create_dir_structure.php
+      libs/plugins/core.display_debug_console.php
+      libs/plugins/core.fetch_template_info.php
+      libs/plugins/core.get_include_path.php
+      libs/plugins/core.get_microtime.php
+      libs/plugins/core.get_php_resource.php
+      libs/plugins/core.is_secure.php
+      libs/plugins/core.is_trusted.php
+      libs/plugins/core.load_plugins.php
+      libs/plugins/core.load_resource_plugin.php
+      libs/plugins/core.parse_file_path.php
+      libs/plugins/core.process_cached_inserts.php
+      libs/plugins/core.read_cache_file.php
+      libs/plugins/core.rm_auto.php
+      libs/plugins/core.rmdir.php
+      libs/plugins/core.run_insert_handler.php
+      libs/plugins/core.smarty_include.php
+      libs/plugins/core.smarty_include_php.php
+      libs/plugins/core.write_cache_file.php
+      libs/plugins/core.write_compiled_template.php
+      libs/plugins/core.write_file.php:
+      move core files into their own directory under SMARTY_DIR,
+      remove abstraction function _execute_core_function
+
+    * libs/Smarty_Compiler.class.php:
+      fix newline handling for template for all template tags
+
+2003-06-11  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/compiler.config_load.php:
+      add compiler function to cvs repository
+
+2003-06-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      added config-option "request_use_auto_globals" to make auto-globals be
+      used as request vars instead of HTTP_*_VARS
+
+2003-06-11  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/plugins/function.config_load.php:
+      make config vars compile statically
+
+2003-06-11  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      backed out newlines patch
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      removed newlines in compiled templates after closing tags
+
+2003-06-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/de/designers.sgml:
+      fixed german note on html_image and disk-access
+
+2003-06-10  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/core.parse_file_path.php:
+      fix bug with resource_type resolving
+
+2003-06-09  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+      replace example with more practical one
+
+2003-06-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      added block-methods for registered objects
+
+2003-06-07  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/programmers.sgml:
+      fixed bug in documentation for $smarty->default_modifiers
+
+2003-06-06  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/core.parse_file_path.php:
+      fix problem with new default_resource_type changes
+
+    * NEWS:
+      update NEWS file info
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/plugins/core.parse_file_path.php:
+      add default_resource_type, ignore 1 char resource names
+
+    * NEWS
+      libs/Config_File.class.php:
+      fix bug where config file starts with hidden section
+
+2003-06-04  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty.class.php:
+      -** empty log message ***
+
+2003-06-03  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/function.html_image.php:
+      fix example in code comments
+
+2003-06-03  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.counter.php:
+      fixed behaviour of start=... for {counter}
+
+2003-06-02  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.counter.php:
+      fixed assign for {counter}
+
+2003-05-30  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/core.write_cache_file.php
+      libs/plugins/core.write_compiled_template.php:
+      add discrete error checking pertaining to $cache_dir
+      and $compile_dir, their existance and writability
+
+2003-05-28  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_table.php:
+      added params vdir, hdir and inner to html_table to allow looping over
+      the data in various directions
+
+2003-05-28  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/core.compile_template.php
+      libs/plugins/core.display_debug_console.php:
+      fix problem with security and debug.tpl file
+
+2003-05-23  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      upd NEWS file
+
+    * libs/Smarty_Compiler.class.php:
+      allow spaces in literal tags
+
+2003-05-22  Monte Ohrt  <monte@ispi.net>
+
+    * docs/fr/programmers.sgml:
+      fix special chars
+
+2003-05-19  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      speed up compiled templates, hardcode plugin filepaths instead of
+      recalculate at runtime
+
+2003-05-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      fixed example of {html_image}
+
+    * docs/designers.sgml:
+      fixed typo
+
+2003-05-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/plugins/core.read_cache_file.php
+      libs/plugins/core.smarty_include.php
+      libs/plugins/function.config_load.php:
+      fixed multiple redundant occurrences for 'config' and 'template' in
+      $smarty->_cache_info
+
+2003-05-10  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/core.create_dir_structure.php:
+      refurbished create_dir_structure to use '/' internally
+
+    * libs/plugins/core.create_dir_structure.php:
+      fixed windows absolute-paths in smarty_core_create_dir_structure()
+
+    * libs/plugins/core.create_dir_structure.php:
+      fixed error-message
+
+2003-05-09  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      fixed warning due to missing param to _execute_core_function()
+
+    * libs/Smarty_Compiler.class.php:
+      fixed quoting in _compile_include_php
+
+    * libs/Smarty_Compiler.class.php:
+      fixed quoting of "file"-parameter in _compile_include_tag()
+
+2003-05-08  Monte Ohrt  <monte@ispi.net>
+
+    * docs/programmers.sgml:
+      fix typo
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/plugins/core.compile_template.php
+      libs/plugins/core.create_dir_structure.php
+      libs/plugins/core.fetch_template_info.php
+      libs/plugins/core.get_include_path.php
+      libs/plugins/core.get_microtime.php
+      libs/plugins/core.get_php_resource.php
+      libs/plugins/core.is_secure.php
+      libs/plugins/core.is_trusted.php
+      libs/plugins/core.load_plugins.php
+      libs/plugins/core.load_resource_plugin.php
+      libs/plugins/core.parse_file_path.php
+      libs/plugins/core.process_cached_inserts.php
+      libs/plugins/core.read_cache_file.php
+      libs/plugins/core.rm_auto.php
+      libs/plugins/core.rmdir.php
+      libs/plugins/core.run_insert_handler.php
+      libs/plugins/core.smarty_include.php
+      libs/plugins/core.smarty_include_php.php
+      libs/plugins/core.write_cache_file.php
+      libs/plugins/core.write_compiled_template.php
+      libs/plugins/core.write_file.php
+      libs/plugins/function.config_load.php
+      libs/plugins/function.fetch.php
+      libs/plugins/function.html_image.php:
+      abstract more private functions to plugin directory
+
+    * libs/Config_File.class.php:
+      only add DIRECTORY_SEPARATOR if it isn't already present
+
+    * libs/Config_File.class.php:
+      fix directory separator code, use DIRECTORY_SEPARATOR
+
+2003-05-08  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      fixed example of html_checkboxes
+
+    * NEWS
+      libs/Smarty.class.php:
+      fixed bug in _create_dir_structure() when used with
+      open_basedir-restriction and relative paths
+
+    * docs/designers.sgml:
+      fixed example for html_radios
+
+2003-05-07  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php
+      libs/plugins/core.assign_smarty_interface.php
+      libs/plugins/core.display_debug_console.php
+      libs/plugins/function.display_debug_console.php:
+      abstracted display_debug_console and assign_smarty_interface to plugin dir
+      as a test
+
+    * libs/Smarty.class.php
+      libs/plugins/function.display_debug_console.php:
+      correct misc varnames, abstract debug console display to plugin function
+
+    * libs/plugins/modifier.escape.php:
+      fix typo
+
+2003-05-05  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      add % to math
+
+    * libs/Smarty.class.php:
+      clean up comments, formatting
+
+    * NEWS
+      libs/Smarty.class.php:
+      keep DIR_SEP for 3rd party compatability
+
+    * NEWS
+      libs/Smarty.class.php:
+      remove DIR_SEP, use DIRECTORY_SEPARATOR exclusively
+
+    * libs/Smarty_Compiler.class.php:
+      remove ++ and -- math operators on template vars
+
+2003-05-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty_Compiler.class.php:
+      removed unused parameter $quote from Smarty_Compiler::_parse_attrs()
+
+    * libs/plugins/function.html_image.php:
+      fixed DIR_SEP in html_image-plugin
+
+2003-05-04  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty.class.php:
+      rename DIR_SEP to SMARTY_DIR_SEP to avoid varname collisions
+
+2003-05-04  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_image.php:
+      changed "link" to "href" in html_image. "link" is still working but
+      deprecated
+      html_image always renders an alt-tag now (default alt="")
+      cleaned up indentiation of function.html_image.php
+
+2003-05-03  Monte Ohrt  <monte@ispi.net>
+
+    * libs/debug.tpl:
+      fix typo
+
+2003-05-02  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.counter.php:
+      fixed assign attribute for multiple counters
+
+2003-05-02  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      allow math on negative number
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      added simple math operators to variables
+
+2003-05-02  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      fixed typos
+
+2003-04-30  Monte Ohrt  <monte@ispi.net>
+
+    * docs/fr/appendixes.sgml
+      docs/fr/common.dsl
+      docs/fr/designers.sgml
+      docs/fr/getting-started.sgml
+      docs/fr/html-common.dsl
+      docs/fr/html.dsl
+      docs/fr/manual.sgml
+      docs/fr/php.dsl
+      docs/fr/preface.sgml
+      docs/fr/programmers.sgml:
+      add frech docs to cvs repository
+
+2003-04-29  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      reverted patch for case-insensitive tag-names
+
+2003-04-28  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/programmers.sgml:
+      reverted back to humerous redundancy in the docs :). although we all
+      know we are here to generate template-based output, and not to have
+      fun ;-)
+
+    * docs/getting-started.sgml:
+      fixed default user and group for max os x installation
+
+    * libs/Smarty.class.php:
+      made $function[2] and $function[3] options for register_resource
+
+    * libs/Smarty.class.php:
+      fixed issue with object-callback when fetching a php-resource
+
+    * NEWS
+      libs/Smarty.class.php:
+      enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted') as
+      callback for register_resource()
+      
+      enabled array(&$obj, 'method') as callback for
+      $default_template_handler_func
+
+2003-04-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml
+      docs/programmers.sgml:
+      fixed some typos, thank to mehdi
+
+    * libs/plugins/function.counter.php:
+      prevent assign from overruling print-attribute in function.counter.php
+
+    * libs/plugins/function.counter.php:
+      fixed problem with counter and assign
+
+    * libs/Smarty.class.php:
+      fixed notice in  _load_plugins()
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      made plugin-names case-insensitive. this affects
+      compiler/block/custom-functions and modifers.
+
+2003-04-26  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      remove unnecessary close/open tags from compiled templates
+
+2003-04-26  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      added documentation for foreach.property.*
+
+2003-04-24  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * docs/designers.sgml:
+      fixed example table_attr and tr_attr in html_table-example
+
+2003-04-21  Greg Beaver  <greg@chiaraquartet.net>
+
+    * libs/Smarty.class.php:
+      fixed small bug in doc comments
+
+2003-04-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_image.php:
+      fixed errornous creation of '//' in image_path in html_image
+
+2003-04-21  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/modifier.debug_print_var.php:
+      fix htmlspecialchars() conflict
+
+    * NEWS
+      libs/plugins/modifier.debug_print_var.php:
+      fix escapement of special chars in key values of debug console
+
+    * NEWS
+      libs/plugins/function.config_load.php:
+      fixed debug timing logic for config_load
+
+    * docs/designers.sgml:
+      fix example text
+
+
+2003-04-20  Greg Beaver <cellog@users.sourceforge.net>
+    * plugins/*
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      Config_File.class.php:
+      updated all doc comments to phpDocumentor format (whew!)
+
+2003-04-06  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/plugins/function.math.php:
+      allowed "_" in the name of variable-parameters to {math}-function
+
+2003-04-04  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      docs/designers.sgml
+      libs/Smarty_Compiler.class.php:
+      change backtic syntax from $`foo` to `$foo`
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      recognize $foo[][] syntax in embedded quotes without backticks
+
+2003-04-03  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      name=123 is passed as an integer (not a string) to plugins now
+
+2003-04-01  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      added CVS $Id: ChangeLog,v 1.459 2007/03/07 01:31:23 changelog Exp $
+
+2003-03-31  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      added missing compile_id inside Smarty_Compiler
+
+    * libs/Smarty_Compiler.class.php:
+      fixed flaw when generating an error for missing postfilter
+
+2003-03-31  Monte Ohrt  <monte@ispi.net>
+
+    * docs/getting-started.sgml
+      docs/programmers.sgml:
+      fix typos
+
+2003-03-27  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/modifier.debug_print_var.php:
+      $length is now propagated to sub-values in debug_print_var
+
+2003-03-26  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      update header
+
+    * RELEASE_NOTES:
+      commit changes to release notes
+
+    * (Smarty_2_5_0_RC2)
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      committing RC2
+
+2003-03-24  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      made clear_cache() ignore compile_id when clearing cache_groups
+
+    * libs/plugins/function.popup.php:
+      made onmouseout XHTML-compatible in function.popup.php
+
+2003-03-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      applied new var-names to fetch()
+
+    * NEWS
+      libs/Smarty.class.php:
+      renamed $localvars to $_localvars in cache-file-handling-functions,
+      added _get_auto_id()-function
+
+2003-03-21  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/function.mailto.php
+      libs/plugins/function.popup.php:
+      update functions for XHTML compatability
+
+2003-03-21  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * libs/Smarty.class.php:
+      fixed wrong $auto_id in _read_cache_file()
+
+    * NEWS
+      libs/Smarty.class.php:
+      swapped compile_id and cache_id in read_cache_file and write_cache_file
+
+    * libs/Smarty.class.php:
+      reverted patch for ignoring compile-id back to -r1.364, due to problems
+
+    * NEWS
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_radios.php:
+      html_radios and html_checkboxes accept "selected" instead of "checked"
+      optionally now
+
+    * NEWS
+      libs/Smarty.class.php:
+      swapped compile_id and cache_id for cache-file-handling again
+
+2003-03-20  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      fix notice when no parameter is passed to default
+
+2003-03-20  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      removed notice of undefined var in _rm_auto()
+
+2003-03-19  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/function.html_table.php:
+      fix a few error messages, follow consistancy format plugin_name: errormsg
+
+    * libs/plugins/function.html_radios.php:
+      update error messages
+
+    * NEWS
+      libs/plugins/function.html_radios.php:
+      add a warning when an array is passed as the 'checked' value of html_radios
+
+2003-03-19  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fixed errormessage in _compile_smarty_ref()
+
+    * NEWS
+      docs/designers.sgml:
+      updated docs for html_image
+
+2003-03-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/Smarty.class.php:
+      cleaned up calls to readdir()
+
+    * libs/plugins/function.html_options.php:
+      fixed label for optgroup in html_options
+
+2003-03-18  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix (newly introduced) bug with passing multiple modifiers to a parameter
+
+2003-03-18  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      docs/designers.sgml:
+      updated docs for html_checkboxes, html_options and html_radios
+
+    * libs/plugins/function.html_options.php:
+      fixed wrong default-"name" in function.html_options.php
+
+    * NEWS
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_radios.php:
+      renamed "checkbox" and "radios" to "options" in {html_checkboxes} and
+      {html_radios}
+
+    * libs/plugins/outputfilter.trimwhitespace.php:
+      tried to optimize re-replacement in outputfilter.trimwhitespace.php a
+      little
+
+    * libs/plugins/outputfilter.trimwhitespace.php:
+      fixed greedy str_replace in outputfilter.trimwhitespace.php
+
+    * NEWS
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_radios.php:
+      html_options, html_checkboxes and html_radios now pass-thru all unknown
+      paramters
+
+2003-03-17  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/function.html_options.php:
+      html_options passthru all unknown paramters now
+
+2003-03-17  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/function.html_image.php:
+      Fix link bug in html_image function, also make output XHTML compatible
+
+    * libs/Smarty_Compiler.class.php:
+      fix issue of embedded var and escaped double quotes
+
+2003-03-15  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      back out "@" logic, apply only to default modifier special case
+
+    * libs/Smarty_Compiler.class.php:
+      fix @ logic, only use upon an echo
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      append "@" to template var echoes to supress possible notices
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      append "@" to _run_mod_handler to supress warnings
+
+2003-03-14  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix problem with escaped double quotes
+
+    * NEWS
+      libs/plugins/function.html_radios.php:
+      fixed html_options to not return an array
+
+2003-03-12  Messju Mohr  <messju@lammfellpuschen.de>
+
+    * NEWS
+      libs/plugins/modifier.truncate.php:
+      fixed length in modifier.truncate.php
+
+    * NEWS
+      libs/plugins/outputfilter.trimwhitespace.php:
+      fixed handling of '$'-signs in trimwhitespace outputfilter (messju)
+
+2003-03-12  Monte Ohrt  <monte@ispi.net>
+
+    * docs/programmers.sgml:
+      update technical explanation of assign_by_ref and append_by_ref
+
+2003-03-11  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/Smarty.class.php:
+      fix config file recompiling code
+
+2003-03-07  Monte Ohrt  <monte@ispi.net>
+
+    * libs/plugins/function.html_image.php:
+      change E_USER_ERROR to E_USER_NOTICE
+
+    * libs/plugins/function.html_image.php:
+      suppress warning in html_image
+
+    * NEWS
+      libs/plugins/function.html_image.php:
+      update changes to html_image
+
+2003-03-06  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      docs/de/appendixes.sgml
+      docs/de/common.dsl
+      docs/de/designers.sgml
+      docs/de/getting-started.sgml
+      docs/de/html-common.dsl
+      docs/de/html.dsl
+      docs/de/manual.sgml
+      docs/de/preface.sgml
+      docs/de/programmers.sgml:
+      add german docs to dist
+
+    * NEWS:
+      update news file
+
+    * libs/plugins/function.html_image.php:
+      fix width/height parameter index
+
+    * NEWS
+      libs/Smarty.class.php:
+      get rid of unsetting name and script attributes to insert tags
+
+2003-03-05  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      RELEASE_NOTES:
+      update NEWS file
+
+    * libs/plugins/modifier.string_format.php:
+      fix argument order, erroneously swapped a while back
+
+    * (Smarty_2_5_0_RC1)
+      NEWS
+      README
+      RELEASE_NOTES
+      libs/Config_File.class.php
+      libs/Smarty.class.php
+      libs/Smarty_Compiler.class.php:
+      commit final changes for 2.5.0-RC1
+
+2003-03-04  Monte Ohrt  <monte@ispi.net>
+
+    * docs/programmers.sgml:
+      remove $show_info_header and $show_info_include property vars from docs
+
+2003-03-03  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/function.popup.php:
+      fixed PHP notice
+
+2003-02-28  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty_Compiler.class.php:
+      simplify smarty.const.foo and smarty.const.$foo logic
+
+    * libs/Smarty_Compiler.class.php:
+      only allow $foo syntax in embedded quotes, unless escaped with backticks
+      then allow any dollar var
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      fix "once" var compiling to work with new attr compiling methods for
+      include_php
+
+    * FAQ
+      NEWS
+      README
+      docs/designers.sgml
+      docs/getting-started.sgml
+      libs/Smarty_Compiler.class.php
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_image.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/function.html_select_date.php
+      libs/plugins/function.html_select_time.php
+      libs/plugins/function.html_table.php:
+      fix $smarty.const.foo compiling, clean up double quoted strings,
+      allow full dollar var syntax in quotes again
+
+2003-02-27  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      docs/programmers.sgml
+      libs/Smarty_Compiler.class.php:
+      update docs, fix smarty var compiling, allow any $smarty.*.$foo syntax,
+      add $`foobar` for embedded variables
+
+    * libs/plugins/function.html_image.php:
+      update functionality
+
+2003-02-26  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      libs/plugins/modifier.nl2br.php:
+      add nl2br modifier
+
+    * libs/plugins/function.html_image.php:
+      add link parameter
+
+2003-02-24  Monte Ohrt  <monte@ispi.net>
+
+    * libs/Smarty.class.php
+      libs/plugins/function.html_image.php:
+      fix rename problem in windows, unlink first
+
+    * libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_image.php
+      libs/plugins/function.html_options.php
+      libs/plugins/function.html_radios.php
+      libs/plugins/shared.escape_special_chars.php:
+      update functions with separate escape_special_chars routine
+
+    * NEWS
+      libs/plugins/function.html_checkboxes.php
+      libs/plugins/function.html_radios.php:
+      commit checkboxes, update radios
+
+    * NEWS
+      libs/Smarty.class.php
+      libs/plugins/function.html_image.php:
+      fix bug with get_registered_object
+
+    * NEWS
+      libs/plugins/modifier.cat.php:
+      added cat modifier to distribution
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      added << >> <> support to IF statements
+
+    * libs/plugins/function.html_radios.php:
+      apply patch to initial html_radios function
+
+    * NEWS
+      libs/Smarty.class.php:
+      fix _assign_smarty_interface to not overwrite keys other than 'request'
+
+    * NEWS
+      libs/plugins/function.html_radios.php:
+      added html_radios to distribution
+
+    * NEWS
+      libs/plugins/modifier.string_format.php:
+      fixed arg order of string_format
+
+    * NEWS
+      libs/Smarty.class.php:
+      use tmp file for file writes, avoid race condition
+
+    * NEWS
+      libs/Smarty_Compiler.class.php:
+      add $smarty.config.foo var, handle embedded smarty var correctly
+
+    * NEWS
+      libs/plugins/function.fetch.php:
+      silence warnings in fetch plugin
+
+2003-02-21  Monte Ohrt  <monte@ispi.net>
+
+    * INSTALL:
+      update wording
+
+    * INSTALL:
+      update install instructions
+
+    * AUTHORS
+      BUGS
+      CREDITS
+      QUICKSTART
+      README
+      RESOURCES
+      TESTIMONIALS:
+      remove some files already in docs or elsewhere
+
+    * demo/index.php:
+      add templates_c to repository
+
+    * index.php:
+      move demo files to demo directory
+
+    * Config_File.class.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      debug.tpl:
+      moved lib files under libs directory
+
+2003-02-20  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php:
+      add get_config_vars() method, update get_template_vars() functionality
+
+    * NEWS
+      Smarty.class.php:
+      fix minor logic in _fetch_template_info()
+
+    * NEWS
+      Smarty.class.php:
+      support merging appended vars
+
+    * NEWS
+      Smarty.class.php:
+      fix cache groups behavior with compile_id set
+
+2003-02-19  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+      back out third parameter, extend functionality of append
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      update imbedded vars, allow special $smarty vars
+
+    * plugins/function.html_table.php:
+      add plugin html_table
+
+    * NEWS
+      Smarty.class.php:
+      support appending key=>val pairs
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      change embedded variable logic to only recognize $foo and $foo[0][bar]
+      syntax
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      allow null as function attribute value
+
+2003-02-18  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      support foo->bar[index] syntax
+
+    * Smarty_Compiler.class.php:
+      allow $foo->bar[0] syntax
+
+2003-02-17  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/modifier.escape.php:
+      fix syntax error from previous commit
+
+    * NEWS
+      Smarty.class.php:
+      add error msgs to get_registered_object
+
+    * Smarty.class.php:
+      add function for getting reference to registered object
+
+    * Smarty_Compiler.class.php:
+      back out patches for object and objref calls on $smarty var
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      treat unrecognized param attribute syntax as a string
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      support $smarty.const.$foo syntax
+
+    * NEWS
+      debug.tpl
+      plugins/modifier.count_words.php
+      plugins/modifier.escape.php:
+      fix E_NOTICE messages
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      add @ and === to if tokens, few param cleanups
+
+2003-02-16  Greg Beaver  <greg@chiaraquartet.net>
+
+    * ChangeLog
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      many more phpdoc comment upgrades
+
+2003-02-15  Greg Beaver <cellog@sourceforge.net>
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      continue cleaning of phpdoc comments.  All that is needed is the
+      addition of @return tags and perhaps a bit more verbose comments
+      and they are finished.
+
+2003-02-14  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php:
+      enable config_load error messages
+
+    * NEWS
+      plugins/function.html_options.php:
+      fix html_options to not escape already escaped entities
+
+    * NEWS
+      Smarty.class.php:
+      send Last-Modified header on cache creation, misc tab/spacing cleanup
+
+2003-02-13  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      docs/designers.sgml:
+      allow dash in plain text
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      check strict syntax of function attributes
+
+2003-02-12  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      dropped support for modifiers on object parameters,
+      added support for objects as modifier parameters
+
+    * NEWS
+      Smarty_Compiler.class.php
+      docs/designers.sgml:
+      fix bug with decimal numbers in if statements, misc doc updates
+
+2003-02-11  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_4_2)
+      Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      update version numbers
+
+2003-02-10  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      add support for $foo->$bar syntax
+
+    * NEWS:
+      update NEWS file
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      support full var syntax in quoted text, fix problem with const var access,
+      clean up some more regex code, fix object problem with no properties
+
+2003-02-06  Monte Ohrt  <monte@ispi.net>
+
+    * (Smarty_2_4_1)
+      Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      committed 2.4.1 changes
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      ignore case in IF statements
+
+2003-02-05  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      treat undefined constants as null
+
+    * NEWS
+      Smarty.class.php:
+      fix problem with inserts and nested fetches
+
+    * Smarty_Compiler.class.php:
+      fix "if" regex for math tokens
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs/getting-started.sgml:
+      added support for extracting params to include_php
+
+2003-02-04  Monte Ohrt  <monte@ispi.net>
+
+    * RELEASE_NOTES:
+      reformat text
+
+2003-02-03  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      update news file
+
+2003-02-03  Greg Beaver  <greg@chiaraquartet.net>
+
+    * ChangeLog
+      Smarty.class.php:
+      begin fixing phpdoc comments in Smarty.class.php
+
+    * ChangeLog
+      Config_File.class.php:
+      fixed phpdoc comments
+
+2003-02-03  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      allow $foo->bar[$x].foo syntax
+
+    * Smarty_Compiler.class.php
+      index.php
+      configs/test.conf
+      templates/index.tpl:
+      fix accidental commit
+
+    * index.php
+      configs/test.conf
+      templates/index.tpl:
+      allow $foo->bar[$j].blah type of syntax
+
+2003-02-02  Greg Beaver  <cellog@php.net>
+
+    * Smarty.class.php
+      begin fixing of phpdoc comments
+
+    * Config_File.class.php
+      fix phpdoc comments, add phpDocumentor docblock templates
+
+2003-02-02  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      docs/html.dsl
+      docs/php.dsl:
+      fix version number
+
+    * (Smarty_2_4_0)
+      Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs/appendixes.sgml
+      docs/designers.sgml
+      docs/programmers.sgml:
+      update Smarty version numbers
+
+2003-01-30  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty_Compiler.class.php
+      TODO:
+      fix order of php tag comparisons
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      fix known php tag handling problems
+
+2003-01-29  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php:
+      change comments to phpdoc style
+
+2003-01-28  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      docs/programmers.sgml:
+      make separate var for compiler file
+
+    * plugins/function.fetch.php:
+      fix error call
+
+2003-01-25  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php:
+      add support for restriction to registered methods
+
+    * plugins/outputfilter.trimwhitespace.php:
+      update with textarea support
+
+2003-01-24  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      fix compiling problem with {foreach} tags
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php:
+      put objects in own array, add object param format support, change
+      object syntax from foo.bar to foo->bar
+
+2003-01-23  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      add support for object registration
+
+2003-01-22  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+      add file & line number of calling error to error message
+
+2003-01-21  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      put php style object syntax back in
+
+2003-01-20  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+      move security settings to fetch function for template_dir
+
+    * NEWS
+      Smarty.class.php:
+      fix debug template and security, add template_dir to secure_dir at runtime
+
+2003-01-17  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      added new object support without new template syntax
+
+2003-01-15  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      fix if statement syntax for negative integers, fix issue with directories
+      named '0'
+
+2003-01-08  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      plugins/function.counter.php
+      plugins/function.cycle.php
+      plugins/function.debug.php
+      plugins/function.eval.php
+      plugins/function.fetch.php
+      plugins/function.html_options.php
+      plugins/function.html_select_date.php
+      plugins/function.html_select_time.php
+      plugins/function.mailto.php
+      plugins/function.math.php
+      plugins/function.popup.php
+      plugins/function.popup_init.php:
+      update plugins to return values instead of echo, fix config file cache
+      to include global config variables in cache file
+
+    * Smarty_Compiler.class.php:
+      fix bug with >= tests in if statements, comment out full object support
+
+2003-01-06  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      docs/html.dsl
+      plugins/modifier.escape.php:
+      add javascript escape parameter to escape modifier
+
+2003-01-02  Monte Ohrt  <monte@ispi.net>
+
+    * templates/header.tpl:
+      move the title into head where it should be
+
+2002-12-24  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      added correct line numbers to smarty syntax error messages
+
+    * docs/programmers.sgml:
+      update append documentation, make more clear on its function
+
+    * Smarty_Compiler.class.php:
+      fix modifier matching regexp
+
+2002-12-23  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      support nested function calls in IF statements
+
+2002-12-20  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      few more fixes, spaces around function parameters
+
+    * Smarty_Compiler.class.php:
+      fix misc syntax issues with {if} tags
+
+2002-12-20  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      fix misc syntax issues with {if} tags
+
+2002-12-19  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      commit updates, passes all smoke tests
+
+    * NEWS:
+      update NEWS file
+
+    * Smarty_Compiler.class.php:
+      fixed literal string not in quotes as parameters
+
+    * NEWS
+      Smarty_Compiler.class.php:
+      fix misc syntax issues, add ability to pass modifiers to functions
+
+2002-12-18  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      update NEWS
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      update compiler code, clean up regex, add new syntax features
+
+2002-12-16  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS:
+      update NEWS file
+
+    * Smarty_Compiler.class.php:
+      commit updates for objects
+
+2002-12-14  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php:
+      fix bug with compiling config files with caching on
+
+2002-12-13  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      fix problem with matching single quoted strings
+
+    * Smarty_Compiler.class.php:
+      update embedded variable logic, get rid of ."" at end of output
+
+    * NEWS
+      docs/designers.sgml
+      plugins/function.html_select_date.php:
+      add day_value_format to html_select_date
+
+2002-12-12  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/modifier.debug_print_var.php:
+      fix bug, double escaped values in display
+
+    * Smarty.class.php:
+      move debug test back into fetch()
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      plugins/outputfilter.trimwhitespace.php:
+      assigned vars are no longer in global name space, few debug cleanups
+
+2002-12-11  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.popup.php:
+      fix error in newline code
+
+    * plugins/function.popup.php:
+      fix popup to allow newlines in text data
+
+2002-12-10  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+      fix plugin error logic
+
+    * docs/designers.sgml
+      docs/programmers.sgml:
+      edit examples, make more verbose
+
+    * NEWS
+      plugins/function.html_options.php:
+      escape html entities in the option values and output
+
+    * NEWS
+      plugins/function.html_options.php:
+      fixed bug with label of html_options
+
+2002-12-09  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+      add support for var_export()
+
+    * Config_File.class.php
+      Smarty.class.php:
+      clean up code, respect force_compile and compile_check flags
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs/designers.sgml
+      plugins/function.mailto.php:
+      add caching feature to config loading, document update, add mailto plugin
+
+2002-12-08  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.fetch.php:
+      fix query part of URL
+
+2002-12-05  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+      fix typos
+
+2002-11-22  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php:
+      patch for warning message
+
+2002-11-21  Monte Ohrt  <monte@ispi.net>
+
+    * RELEASE_NOTES
+      Smarty.class.php:
+      get rid of testing for a set value with assign function, just set to
+      whatever is passed into the template
+
+    * docs/programmers.sgml:
+      fix typo
+
+2002-11-19  Monte Ohrt  <monte@ispi.net>
+
+    * Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+      commit changes, ready for 2.3.1 release
+
+2002-11-01  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.html_options.php:
+    added label attribute to all option outputs, cover w3c spec.
+
+    * NEWS: update NEWS file
+
+    * docs/designers.sgml: update docs for optgroup output
+
+    * plugins/function.html_options.php:
+    make html_options work with optgroup, make func modular and recursive.
+
+2002-10-29  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php: set mtime on compile files so they match source files
+
+2002-10-18  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php: added proper support for open_basedir setting
+
+    * docs/designers.sgml: clear up docs on index, iteration and rownum
+
+2002-10-16  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/modifier.default.php: fix warning message in default modifier
+
+2002-09-25  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      plugins/modifier.strip.php
+      NEWS: added strip variable modifier
+
+2002-09-24  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty_Compiler.class.php:
+    Fix to be able to use $smarty.x variables as arrays.
+
+2002-09-23  Monte Ohrt  <monte@ispi.net>
+
+    * Config_File.class.php:
+    add support for mac/dos formatted config files (fix newlines)
+
+    * docs/programmers.sgml: add optional tags to clear_cache parameters
+
+    * docs/designers.sgml:
+    fix error with include_php description, add $this to description
+
+2002-09-20  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      docs/getting-started.sgml: fixed errors with example setup docs
+
+2002-09-16  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/block.textformat.php
+      docs/designers.sgml
+      NEWS: add textformat block function
+
+2002-09-10  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+    add assign attribute to cycle function documentation
+
+    * docs/designers.sgml
+      docs/programmers.sgml: fix typos
+
+2002-09-09  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.debug.php
+      templates/header.tpl:
+    fix header in debug template, fix typo in header.tpl example
+
+2002-08-15  mohrt  <mohrt@pb1.pair.com>
+
+    * docs/programmers.sgml: fix typos
+
+2002-08-08  mohrt  <mohrt@pb1.pair.com>
+
+    * RELEASE_NOTES
+      Smarty.class.php:
+    supress warnings from unlink() and is_dir(), let error handler deal with it
+
+2002-08-07  mohrt  <mohrt@pb1.pair.com>
+
+    * docs/appendixes.sgml
+      docs/designers.sgml
+      docs/programmers.sgml
+      Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php: update files with new version numbers
+
+2002-08-02  mohrt  <mohrt@pb1.pair.com>
+
+    * NEWS: update NEWS file with credits
+
+    * NEWS
+      Smarty.class.php: added assign_by_ref() and append_by_ref() functions
+
+2002-08-01  mohrt  <mohrt@pb1.pair.com>
+
+    * TODO
+      NEWS
+      Smarty.class.php:
+    changed default warning type for plugin errors from E_USER_WARNING to E_USER_ERROR
+
+2002-07-29  mohrt  <mohrt@pb1.pair.com>
+
+    * plugins/function.html_select_time.php
+      docs/designers.sgml
+      NEWS: added paramters to html_select_time plugin
+
+2002-07-25  Andrei Zmievski  <andrei@pb1.pair.com>
+
+    * TODO: *** empty log message ***
+
+2002-07-24  mohrt  <mohrt@pb1.pair.com>
+
+    * QUICKSTART: update QUICKSTART guide
+
+    * NEWS
+      debug.tpl
+      plugins/modifier.debug_print_var.php:
+    update debug console to show objects, fix warning in debug.tpl
+
+2002-07-23  mohrt  <mohrt@pb1.pair.com>
+
+    * docs/programmers.sgml: fix load_filter examples
+
+    * Config_File.class.php
+      NEWS: fix error when there are no sections in config file
+
+2002-07-19  mohrt  <mohrt@pb1.pair.com>
+
+    * docs/getting-started.sgml: fix error in install guide
+
+2002-07-18  mohrt  <mohrt@pb1.pair.com>
+
+    * Smarty_Compiler.class.php:
+    correct the expression match for smarty:nodefaults
+
+2002-07-17  mohrt  <mohrt@pb1.pair.com>
+
+    * Smarty_Compiler.class.php: fix default modifier to work with config vars
+
+    * Smarty_Compiler.class.php: got args to strstr backwards...
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    change default modifiers to array instead of string
+
+    * Smarty_Compiler.class.php
+      docs/designers.sgml
+      Smarty.class.php: add default modifier logic, minor doc updates
+
+    * NEWS
+      Smarty.class.php
+      plugins/function.popup_init.php:
+    make popup_init xhtml compliant, minor variable name changes for consistancy
+
+2002-07-16  mohrt  <mohrt@pb1.pair.com>
+
+    * NEWS: update NEWS file
+
+    * plugins/function.debug.php
+      Smarty.class.php
+      debug.tpl
+      NEWS:
+    fix problem with filenames on windows, add ability to supply expire time in seconds when clearing cache or compiled files
+
+2002-07-15  mohrt  <mohrt@pb1.pair.com>
+
+    * Smarty.class.php:
+    fixed problem with insert tags when loading function from script attribute
+    and caching enabled (Monte)
+
+2002-07-14  mohrt  <mohrt@pb1.pair.com>
+
+    * NEWS
+      Smarty.class.php: fix bug with debug_tpl file path for Windows
+
+2002-07-12  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: fix append function with array/string issue
+
+2002-07-11  Monte Ohrt  <monte@ispi.net>
+
+    * RELEASE_NOTES: update release notes
+
+    * NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      Config_File.class.php: update files to 2.2.0 tags, get ready for release
+
+2002-07-09  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php: make debug.tpl work with any delimiter
+
+    * NEWS
+      Smarty.class.php:
+    change tests in append and assign to != '' instead of empty(), which is more accurate
+
+2002-07-08  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml: minor doc update
+
+    * Smarty.class.php:
+    cast var as an array, simplify and get rid of PHP warning messages
+
+2002-07-03  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: one more N
+
+    * Smarty.class.php:
+    prepend "N" to filenames to avoid possible OS issues with dir names starting with "-"
+
+    * Smarty.class.php: only set $debug_tpl in constructor if empty
+
+    * Smarty.class.php
+      docs/designers.sgml
+      docs/getting-started.sgml
+      docs/programmers.sgml:
+    make use_sub_dirs go back to crc32 for subdir separation
+
+2002-06-29  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.eval.php: do nothing if $val is empty
+
+    * TODO
+      plugins/function.eval.php
+      plugins/function.popup_init.php:
+    add zindex to popup init, fix error message for eval.
+
+2002-06-27  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+    only loop through relative paths for PHP include_path, remove $_relative variable
+
+    * Smarty_Compiler.class.php: added {$smarty.version} variable
+
+2002-06-26  Monte Ohrt  <monte@ispi.net>
+
+    * docs/appendixes.sgml
+      docs/designers.sgml
+      docs/getting-started.sgml
+      docs/programmers.sgml
+      Smarty.class.php:
+    update plugin loading logic, look in SMARTY_DIR, then cwd. If all fail, then retry all with include_path
+
+    * templates/header.tpl
+      Smarty.class.php: update get_include_path, get _path_array only once
+
+    * Smarty.class.php: fix get_include_path function for windows
+
+    * Smarty.class.php: update plugin search logic
+
+    * Smarty.class.php: only search include_path if relative path
+
+    * plugins/function.html_select_date.php
+      plugins/function.html_select_time.php
+      plugins/modifier.date_format.php
+      Smarty_Compiler.class.php
+      NEWS
+      Smarty.class.php: allow plugins_dir to be an array of directories
+
+2002-06-25  Monte Ohrt  <monte@ispi.net>
+
+    * docs/programmers.sgml
+      docs/getting-started.sgml: update installation docs
+
+    * debug.tpl
+      docs/getting-started.sgml
+      templates/debug.tpl
+      NEWS
+      Smarty.class.php: move debug.tpl to SMARTY_DIR, add to constructor
+
+2002-06-24  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.assign_debug_info.php
+      NEWS: fixed warning message in function.assign_debug_info
+
+    * Smarty.class.php: update include_path fixes
+
+    * NEWS:
+    fixed $template_dir, $compile_dir, $cache_dir, $config_dir to respect include_path
+
+2002-06-23  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/shared.make_timestamp.php:
+    update timestamp plugin to work when passed a timestamp
+
+2002-06-19  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update NEWS file
+
+    * plugins/modifier.date_format.php
+      docs/designers.sgml:
+    update date_format, allow optional 2nd paramater as default date if passed date is empty. update docs.
+
+    * plugins/modifier.date_format.php:
+    fix date_format modifier, return nothing if given empty string
+
+2002-06-18  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      plugins/function.cycle.php:
+    gave $reset a default value in cycle function
+
+    * plugins/function.html_select_date.php
+      plugins/shared.make_timestamp.php
+      NEWS:
+    corrected warnings in html_select_time function, made make timestamp always return a timestamp
+
+2002-06-17  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: swapped around cache_id and compile_id order
+
+2002-06-14  Monte Ohrt  <monte@ispi.net>
+
+    * docs/programmers.sgml
+      plugins/function.popup_init.php
+      Smarty.class.php:
+    change directory delimiter to "^" for cache and compile files
+
+2002-06-13  Andrei Zmievski  <andrei@php.net>
+
+    * TODO: done.
+
+    * Smarty_Compiler.class.php:
+    Optimize the calculation of section 'total' property.
+
+2002-06-11  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php:
+    added support for subdir exclusion, deletion by full or partial cache_id and compile_id, change file format to urlencoded values instead of crc32
+
+2002-06-07  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: fix bug with last_modified_check code
+
+    * NEWS
+      Smarty.class.php:
+    updated $GLOBALS refererence for HTTP_IF_MODIFIED_SINCE
+
+2002-06-06  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      overlib.js:
+    remove overlib.js file from distribution, update plugin and docs
+
+2002-06-05  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      NEWS
+      Smarty.class.php: fix 304 Not Modified, don't send content
+
+2002-06-03  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.cycle.php: update version number
+
+    * plugins/function.cycle.php
+      NEWS:
+    fixed cycle function to respect delimiter setting after initial setting
+
+    * Smarty.class.php
+      NEWS:
+    update $GLOBALS references to work properly with track_globals settings
+
+    * plugins/function.math.php: fixed bug with call $assign
+
+    * docs/appendixes.sgml
+      docs/designers.sgml
+      plugins/function.html_options.php
+      plugins/function.html_select_time.php
+      NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    optimized for loops with count() function calls
+
+2002-06-01  Andrei Zmievski  <andrei@php.net>
+
+    * TODO: *** empty log message ***
+
+2002-05-21  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update NEWS file
+
+    * plugins/function.html_select_date.php
+      RESOURCES
+      docs/designers.sgml
+      Config_File.class.php:
+    update html_select_date with month_value_format attribute for controlling the format of the month values.
+
+2002-05-17  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty_Compiler.class.php:
+    Made it possible to use simple variables inside [] for indexing.
+
+2002-05-16  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      docs/getting-started.sgml
+      NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      TESTIMONIALS: add "once" attribute to php_include, update docs
+
+2002-05-09  Andrei Zmievski  <andrei@ispi.net>
+
+    * NEWS
+      TODO: *** empty log message ***
+
+2002-05-07  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.cycle.php: remove \n from cycle function
+
+    * docs/designers.sgml
+      plugins/function.cycle.php
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      NEWS:
+    update cycle function to handle array as input, update files to 2.1.1
+
+2002-05-06  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.fetch.php:
+    update fetch function with more error checking
+
+2002-05-03  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      plugins/function.counter.php:
+    update counter to use name instead of id (id still works though)
+
+    * plugins/function.cycle.php
+      docs/designers.sgml: rename id to name for cycle function
+
+    * plugins/function.cycle.php:
+    update cycle function to allow blank values parameter after initialized
+
+    * plugins/function.cycle.php: fix syntax error
+
+2002-05-02  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.cycle.php: ugh, another typo
+
+    * plugins/function.cycle.php: update comments
+
+    * docs/designers.sgml
+      plugins/function.cycle.php
+      NEWS: added function cycle
+
+    * FAQ
+      Smarty.class.php: fix register_outputfilter function
+
+2002-05-01  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml
+      NEWS
+      Smarty.class.php: fixed bug with resource testing and include_path
+
+2002-04-30  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php: update files for 2.1.0 release
+
+2002-04-30  Andrei Zmievski  <andrei@ispi.net>
+
+    * plugins/function.fetch.php
+      docs/programmers.sgml
+      Smarty.class.php: Fix.
+
+2002-04-29  Andrei Zmievski  <andrei@ispi.net>
+
+    * docs/programmers.sgml
+      docs/designers.sgml: A whole bunch of docs.
+
+2002-04-26  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      QUICKSTART
+      docs/programmers.sgml: update FAQ, QUICKSTART, small doc syntax fix
+
+2002-04-24  Monte Ohrt  <monte@ispi.net>
+
+    * docs/programmers.sgml
+      templates/debug.tpl
+      Smarty.class.php: changed doc structure a bit
+
+2002-04-16  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Add register/unregister API for output filters.
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      TODO:
+    Changed the way filters are loaded, which now has to be done explicitly,
+    either through load_filter() API or by filling in $autoload_filters variable.
+    Also renamed internal variable to avoid namespace pollution.
+
+2002-04-15  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php:
+    Fixed _get_php_resource() to take include_path into account.
+
+2002-04-15  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml:
+    update docs, get modifiers and functions into index for easy access
+
+    * docs/programmers.sgml
+      NEWS
+      Smarty.class.php: update caching documentation
+
+2002-04-15  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty.class.php: Only turn down error notices if $debugging is false.
+
+2002-04-15  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update NEWS file
+
+    * plugins/function.html_select_date.php:
+    fixed logic so this works right when field_separator = "/"
+
+    * plugins/function.html_select_date.php:
+    fix regular expression for matching date
+
+2002-04-13  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml: updated html_select_date docs to reflect changes
+
+    * NEWS
+      plugins/function.html_select_date.php:
+    added YYYY-MM-DD support to html_select_date
+
+2002-04-12  Andrei Zmievski  <andrei@php.net>
+
+    * TESTIMONIALS: New entry.
+
+2002-04-12  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/modifier.strip_tags.php: back out changes to strip_tags
+
+    * docs/programmers.sgml: update docs regarding cache_lifetime
+
+    * plugins/modifier.strip_tags.php
+      Smarty.class.php:
+    update cache_lifetime logic: -1 = never expire, 0 = always expire
+
+2002-04-11  Andrei Zmievski  <andrei@php.net>
+
+    * BUGS
+      FAQ
+      INSTALL
+      NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs/getting-started.sgml:
+    Fixed directory separtor issue. Requiring PHP 4.0.6 now.
+
+    * NEWS
+      Smarty_Compiler.class.php:
+    Added ability to use simple variables for array indices or object properties.
+
+    * TESTIMONIALS: Another one.
+
+    * TESTIMONIALS: Adding one from Mark P.
+
+2002-04-05  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php
+      NEWS
+      Smarty.class.php: Make it possible to unregister pre/postfilter plugins.
+
+2002-04-05  Monte Ohrt  <monte@ispi.net>
+
+    * INSTALL: Remove addons file from INSTALL instructions
+
+2002-04-04  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml: update doc error
+
+    * docs/designers.sgml
+      plugins/modifier.escape.php
+      NEWS
+      Smarty.class.php: added htmlall attribute to escape modifier
+
+2002-04-03  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Fixed undefined offset warning in {if} tag.
+
+    * Smarty.class.php
+      NEWS: Added template_exists() API.
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      NEWS:
+    - Added $smarty.template variable.
+    - Fixed {include_php} tag when dynamic values were used for 'file' attribute.
+
+    * Config_File.class.php: Separator setting fix.
+
+2002-03-28  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      README: add digest address
+
+    * FAQ
+      README
+      Smarty.class.php: update mailing list addresses
+
+2002-03-28  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * plugins/function.html_select_date.php
+      plugins/function.html_select_time.php
+      plugins/modifier.date_format.php:
+    Fix for when plugins directory is not the default one.
+
+2002-03-28  Andrei Zmievski  <andrei@ispi.net>
+
+    * NEWS: *** empty log message ***
+
+    * plugins/function.html_select_date.php
+      plugins/function.html_select_time.php
+      plugins/modifier.date_format.php:
+    Fix for when plugins directory is not the default one.
+
+2002-03-27  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ: update FAQ page
+
+2002-03-26  Andrei Zmievski  <andrei@ispi.net>
+
+    * CREDITS
+      NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      TODO: Block functions changes.
+
+    * Config_File.class.php: *** empty log message ***
+
+2002-03-25  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php: Initial implementation of block functions.
+
+2002-03-22  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml: fix documentation error in capture
+
+2002-03-22  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: *** empty log message ***
+
+    * Smarty.class.php: Turn off notices.
+
+2002-03-21  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Make _current_file available to prefilters.
+
+    * NEWS
+      Smarty.class.php:
+    Made is possible to assign variables in pre/postfilters.
+
+2002-03-20  Andrei Zmievski  <andrei@php.net>
+
+    * plugins/function.html_select_date.php: Fixed +/- functionality.
+
+    * NEWS: *** empty log message ***
+
+2002-03-20  Monte Ohrt  <monte@ispi.net>
+
+    * Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.class.php
+      Smarty_Compiler.class.php: update version numbers
+
+    * plugins/function.html_select_date.php
+      plugins/function.html_select_time.php
+      plugins/modifier.date_format.php:
+    move .make_timestamp.php to shared.make_timestamp.php
+
+    * NEWS
+      Smarty.class.php
+      docs/designers.sgml
+      plugins/function.fetch.php
+      plugins/function.html_select_date.php:
+    update file generation, replace crc32() '-' with 'N'
+
+2002-03-20  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: *** empty log message ***
+
+2002-03-19  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php:
+    Fix plugin behavior for inserts with script attribute.
+
+    * NEWS: *** empty log message ***
+
+    * Smarty_Compiler.class.php: Fix bug with $smarty.cookies.
+
+    * TESTIMONIALS: *** empty log message ***
+
+2002-03-15  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      docs/designers.sgml: update Changelog
+
+    * plugins/modifier.indent.php
+      plugins/modifier.wordwrap.php: add wordwrap and indent to repository
+
+2002-03-14  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+    remove show_info_include and show_info_header functions
+
+2002-03-13  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.fetch.php: update fetch function
+
+    * plugins/function.fetch.php: update fetch function with new parameters
+
+2002-03-12  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml: update doc tables
+
+    * docs/designers.sgml: update docs columns
+
+    * docs/getting-started.sgml
+      docs/appendixes.sgml: update docs
+
+    * TESTIMONIALS
+      docs/appendixes.sgml: update syntax error in docs, add to testimonials
+
+2002-03-04  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      README: update FAQ, README with digest mode info
+
+2002-03-02  Monte Ohrt  <monte@ispi.net>
+
+    * QUICKSTART: update quickstart
+
+    * Smarty.class.php:
+    change behavior so cache_lifetime = 0 never expires (instead of always regenerate)
+
+2002-03-01  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml: update doc example
+
+2002-03-01  Andrei Zmievski  <andrei@php.net>
+
+    * CREDITS
+      RELEASE_NOTES
+      TODO
+      NEWS: *** empty log message ***
+
+2002-03-01  Monte Ohrt  <monte@ispi.net>
+
+    * docs/appendixes.sgml
+      docs/designers.sgml
+      docs/getting-started.sgml
+      docs/programmers.sgml: update document id tags
+
+    * docs.sgml: remove docs.sgml
+
+    * RESOURCES
+      Smarty.class.php: update resources
+
+2002-02-28  Andrei Zmievski  <andrei@php.net>
+
+    * TESTIMONIALS
+      docs/appendixes.sgml
+      docs/designers.sgml
+      docs/programmers.sgml: *** empty log message ***
+
+2002-02-27  Andrei Zmievski  <andrei@php.net>
+
+    * plugins/function.eval.php
+      docs/designers.sgml: *** empty log message ***
+
+2002-02-27  Monte Ohrt  <monte@ispi.net>
+
+    * plugins/function.eval.php: added eval function to plugin dir
+
+2002-02-27  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+2002-02-27  Monte Ohrt  <monte@ispi.net>
+
+    * docs/designers.sgml: fix syntax error
+
+    * docs/appendixes.sgml
+      docs/designers.sgml
+      docs/getting-started.sgml
+      docs/programmers.sgml: convert technical notes to docbook format
+
+    * NEWS
+      docs/designers.sgml: added "eval" plugin docs
+
+2002-02-26  Andrei Zmievski  <andrei@php.net>
+
+    * docs/programmers.sgml
+      docs/designers.sgml
+      docs/appendixes.sgml
+      docs/getting-started.sgml
+      docs/html-common.dsl
+      docs/.cvsignore: *** empty log message ***
+
+    * docs/appendixes.sgml
+      docs/common.dsl
+      docs/designers.sgml
+      docs/getting-started.sgml
+      docs/html-common.dsl
+      docs/html.dsl
+      docs/manual.sgml
+      docs/preface.sgml
+      docs/programmers.sgml: Split up docs.
+
+2002-02-25  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml: *** empty log message ***
+
+2002-02-22  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: update docs
+
+2002-02-22  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml
+      AUTHORS
+      NEWS: *** empty log message ***
+
+2002-02-21  Monte Ohrt  <monte@ispi.net>
+
+    * Config_File.class.php
+      NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml: update misc changes
+
+2002-02-21  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml: *** empty log message ***
+
+2002-02-20  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: misc updates
+
+2002-02-20  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml: *** empty log message ***
+
+    * Smarty.class.php
+      plugins/function.assign.php
+      plugins/function.assign_debug_info.php
+      plugins/function.counter.php
+      plugins/function.fetch.php
+      plugins/function.math.php
+      plugins/function.popup.php
+      plugins/function.popup_init.php
+      plugins/modifier.escape.php: Fixup some naming.
+
+2002-02-20  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: update docs
+
+2002-02-20  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml: *** empty log message ***
+
+2002-02-20  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      docs.sgml
+      plugins/modifier.escape.php:
+    removed global vars from fetch function, added attrs to escape modifier
+
+    * docs.sgml: add plugin chapter outline
+
+2002-02-19  Monte Ohrt  <monte@ispi.net>
+
+    * README
+      RELEASE_NOTES
+      RESOURCES
+      Smarty.class.php
+      docs.sgml
+      BUGS
+      FAQ
+      INSTALL
+      QUICKSTART: update docs
+
+2002-02-19  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml: Updated resources docs.
+
+    * README: *** empty log message ***
+
+    * docs.sgml: Updated description of {$smarty} variable.
+
+    * BUGS
+      FAQ
+      INSTALL
+      QUICKSTART
+      RELEASE_NOTES
+      docs.sgml: Remove PEAR notes.
+
+2002-02-18  Andrei Zmievski  <andrei@php.net>
+
+    * Config_File.class.php
+      NEWS: Removed dependency on PEAR.
+
+2002-02-18  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      docs.sgml
+      plugins/function.popup_init.php: add src attribute to popup_init
+
+2002-02-15  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php
+      plugins/modifier.debug_print_var.php
+      NEWS
+      Smarty.class.php: Performance enhancements.
+
+2002-02-06  Andrei Zmievski  <andrei@php.net>
+
+    * plugins/function.html_options.php:
+    Fix html_options output to be XHTML compatible.
+
+2002-02-05  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php: Fix up plugin inclusion.
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      TODO
+      plugins/function.html_select_date.php
+      plugins/function.html_select_time.php
+      plugins/modifier.date_format.php: Fix plugin directory access.
+
+2002-02-04  Andrei Zmievski  <andrei@php.net>
+
+    * .cvsignore
+      Smarty_Compiler.class.php: *** empty log message ***
+
+2002-01-31  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      TODO
+      plugins/function.assign.php
+      plugins/function.assign_debug_info.php
+      plugins/function.counter.php
+      plugins/function.fetch.php
+      plugins/function.html_options.php
+      plugins/function.html_select_date.php
+      plugins/function.html_select_time.php
+      plugins/function.math.php
+      plugins/function.popup.php
+      plugins/function.popup_init.php
+      plugins/modifier.capitalize.php
+      plugins/modifier.count_characters.php
+      plugins/modifier.count_paragraphs.php
+      plugins/modifier.count_sentences.php
+      plugins/modifier.count_words.php
+      plugins/modifier.date_format.php
+      plugins/modifier.debug_print_var.php
+      plugins/modifier.default.php
+      plugins/modifier.escape.php
+      plugins/modifier.lower.php
+      plugins/modifier.regex_replace.php
+      plugins/modifier.replace.php
+      plugins/modifier.spacify.php
+      plugins/modifier.string_format.php
+      plugins/modifier.strip_tags.php
+      plugins/modifier.truncate.php
+      plugins/modifier.upper.php
+      plugins/shared.make_timestamp.php
+      templates/index.tpl
+      AUTHORS
+      CREDITS
+      Config_File.class.php
+      README: Implemented plugin architecture.
+
+    * NEWS: *** empty log message ***
+
+2002-01-30  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml: added modifiers wordwrap and indent
+
+2002-01-28  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      docs.sgml:
+    add support for is-modified-since headers, adjust a doc example
+
+2002-01-24  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: cleanup formatting
+
+    * NEWS
+      Smarty.class.php
+      docs.sgml: update ChangeLog, remove insert_tag_check parameter
+
+2002-01-24  Andrei Zmievski  <andrei@php.net>
+
+    * plugins/standard.plugin.php: *** empty log message ***
+
+2002-01-24  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: fix syntax error
+
+    * Smarty.class.php: removed unneccesary test from fetch()
+
+2002-01-23  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php: update overlib fixes
+
+    * NEWS: update changelog
+
+    * FAQ
+      NEWS
+      RESOURCES
+      Smarty.addons.php: updated overlib fixes
+
+2001-12-31  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: Fixed compile_id problem.
+
+2001-12-28  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    fixed problem with using assigned var with include_php filepath
+
+2001-12-21  Monte Ohrt  <monte@ispi.net>
+
+    * RESOURCES: update RESOURCES
+
+2001-12-20  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      README: update FAQ
+
+2001-12-18  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      docs.sgml
+      Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php: update version numbers
+
+2001-12-18  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: Fixed clear_cache().
+
+2001-12-14  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.addons.php:
+    fixed bug in smarty_make_timestamp introduced in PHP 4.1.0
+
+2001-12-13  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php
+      docs.sgml: update default function args, fix cached insert debug timing
+
+2001-12-12  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: fix syntax error in documentation
+
+    * Smarty.class.php: update default template handling functionality
+
+2001-12-11  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php: update file fetching logic
+
+2001-12-11  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: Added 'script' attribute to {insert..}.
+
+2001-12-10  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php: added default template function handler
+
+    * Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php: update version numbers in files to 1.5.1
+
+2001-12-10  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: Removed error message from the _read_file() method.
+
+    * Smarty.class.php: Fix check for compile and cache IDs.
+
+2001-12-06  Monte Ohrt  <monte@ispi.net>
+
+    * QUICKSTART: fix spelling error in QUICKSTART
+
+    * docs.sgml: fixed spelling errors in documenation
+
+    * Smarty_Compiler.class.php
+      docs.sgml
+      Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php: commit 1.5.0 release
+
+    * RESOURCES
+      docs.sgml: added RESOURCES file
+
+2001-12-05  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Refactor.
+
+2001-12-05  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty_Compiler.class.php
+      docs.sgml: added assign to include and php_include
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml: *** empty log message ***
+
+2001-12-04  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty_Compiler.class.php: Formatting.
+
+2001-12-04  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      NEWS
+      Smarty.class.php: update ChangeLog
+
+2001-12-04  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: Formatting.
+
+2001-12-04  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: removed SMARTY_DIR setting in constructor
+
+    * Smarty.class.php: fix Smarty.class.php indention error
+
+    * Smarty.class.php: update trusted logic
+
+2001-12-03  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php:
+    fix up is_secure, is_trusted, make _parse_tpl_path function
+
+    * Smarty.class.php: fix problem with testing SMARTY_DIR as empty
+
+    * NEWS
+      docs.sgml: update documentation, change log
+
+    * Smarty.class.php:
+    update constructor to check for SMARTY_DIR before assigning
+
+2001-12-03  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: *** empty log message ***
+
+2001-12-03  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      INSTALL
+      RELEASE_NOTES: update a few files
+
+    * NEWS
+      QUICKSTART
+      Smarty.class.php
+      docs.sgml: added trusted_dir functionality, cleaned up secure_dir logic
+
+2001-12-03  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * NEWS
+      Smarty.class.php: - Introduced $compile_id class variable.
+    - Fixed a situation where if $cache_id and $compile_id were both null
+      they were passed to auto functions as empty string instead of null.
+
+2001-11-30  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php:
+    change variable names in fetch() fuction to smarty_* to avoid namespace conflicts
+
+    * NEWS
+      Smarty.class.php: fixed bug in _rm_auto with catenated null values
+
+2001-11-29  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty_Compiler.class.php: Added $smarty.section.* syntax.
+
+    * Smarty_Compiler.class.php: Made 'name' attribute optional for {foreach}.
+
+2001-11-29  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      index.php: remove assign "now" in index.tpl
+
+2001-11-29  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php: Fix formatting.
+
+2001-11-28  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.class.php
+      docs.sgml:
+    removed return statements from _read_cache_file (how did they get in there?)
+
+2001-11-27  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml
+      NEWS
+      Smarty.addons.php
+      Smarty.class.php:
+    fixed bugs and added assign attribute to several functions
+
+2001-11-27  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: Some rewording.
+
+    * Smarty_Compiler.class.php: Fix $smarty.capture access.
+
+    * TODO: *** empty log message ***
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    Made {config_load ..} merge globals from each config file only once per scope.
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php: - Added {foreach ...}.
+    - Made certain $smarty.* references handled at compilation time.
+
+2001-11-26  Monte Ohrt  <monte@ispi.net>
+
+    * Config_File.class.php
+      NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml: commit cache handler functionality
+
+2001-11-20  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.addons.php
+      Smarty_Compiler.class.php: Various fixes and additions.
+
+    * NEWS
+      index.php: *** empty log message ***
+
+2001-11-05  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: changed _read_file parameter from $end to $lines
+
+    * NEWS
+      Smarty.class.php: fixed is_cache, make cache reading more efficient
+
+2001-11-02  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      NEWS: update FAQ with mailing list Reply-To header FAQ
+
+    * NEWS
+      Smarty.class.php
+      index.php: supress fopen errors, return false if cache file won't load
+
+2001-11-01  Monte Ohrt  <monte@ispi.net>
+
+    * QUICKSTART
+      docs.sgml
+      index.php: update QUICKSTART guide with index key example
+
+    * Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml: commit all updates for 1.4.6
+
+2001-11-01  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+2001-10-30  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php: fix assign function problem with empty value passed
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      templates/debug.tpl:
+    fixed bug in assign function when passing an empty value
+
+2001-10-26  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php
+      Smarty.class.php
+      index.php: fix minor typo in debug code
+
+2001-10-26  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Typo.
+
+2001-10-26  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php:
+    update debug console output, handle html encoding correctly
+
+2001-10-26  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      templates/debug.tpl: Debug formatting.
+
+    * Smarty.class.php: Disable rmdir warning.
+
+2001-10-26  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php
+      Smarty.class.php
+      templates/debug.tpl: update debugging to expand array variables
+
+    * Smarty.class.php
+      docs.sgml:
+    update docs for fetching only timestamp with custom template source functions
+
+    * Smarty.addons.php: fix debug console error
+
+2001-10-26  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml: Typos.
+
+    * Smarty.addons.php: Cleanup whitespace.
+
+    * Smarty_Compiler.class.php: Clean up whitespace.
+
+    * Smarty.class.php: Cleaning up code, formatting mostly.
+
+    * NEWS: *** empty log message ***
+
+2001-10-25  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      docs.sgml: update documentation to current version
+
+    * NEWS
+      Smarty.addons.php:
+    updated fetch to give proper warning when fetching unreadable or nonexistant files
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    fixed problem with newline at the end of compiled templates
+
+    * NEWS
+      Smarty.class.php: recompile cache if config file gets modified too.
+
+    * NEWS
+      Smarty.class.php:
+    added feature to regenerate cache if compile_check is enabled and an
+    involved template is modified
+
+2001-10-23  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: fix indent for insert tags in debug console
+
+    * templates/debug.tpl: update debug.tpl file format
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      templates/debug.tpl:
+    update execution time debugging, move into include list
+
+2001-10-10  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    fixed up execution time output in debug console
+
+2001-10-09  Andrei Zmievski  <andrei@php.net>
+
+    * Config_File.class.php
+      NEWS
+      Smarty.class.php
+      TODO: Added support for hidden config vars.
+
+2001-10-04  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      templates/debug.tpl: added execution times to debug console
+
+2001-10-02  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Add space.
+
+2001-10-01  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Fix reference to compile_id.
+
+2001-09-28  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php: Added postfilter functions.
+
+2001-09-26  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      docs.sgml: Rename to clear_compiled_tpl().
+
+2001-09-25  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty_Compiler.class.php:
+    Fixed line number reporting when removing comments.
+
+2001-09-20  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      RELEASE_NOTES
+      Smarty.addons.php: made html_options output xhtml compatible
+
+2001-09-19  Monte Ohrt  <monte@ispi.net>
+
+    * Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      templates/debug.tpl: updated version numbers
+
+2001-09-16  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      NEWS
+      docs.sgml: fix doc error with insert function
+
+2001-09-06  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+2001-08-31  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update ChangeLog
+
+    * overlib.js
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml:
+    update overlib to 3.50, adjust addon code so that the overlib.js file isn't modified
+
+2001-08-31  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: - compile_id changes
+
+    * NEWS
+      Smarty.addons.php: - compile_id support
+    - new options for html_select_date
+
+2001-08-23  Andrei Zmievski  <andrei@php.net>
+
+    * TODO: *** empty log message ***
+
+2001-08-10  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    Modified to pass Smarty object as second parameter to insert functions.
+    Also moved _smarty_mod_handler() and _smarty_insert_handler() into the class.
+
+    * NEWS
+      Smarty_Compiler.class.php:
+    Passing Smarty as second parameter to prefilter functions.
+
+2001-08-09  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+2001-08-09  Monte Ohrt  <monte@ispi.net>
+
+    * templates/index.tpl
+      Smarty.class.php: add smarty.now variable to template
+
+2001-08-06  Monte Ohrt  <monte@ispi.net>
+
+    * templates/index.tpl: change config_load section back to setup
+
+2001-08-06  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php: Optimize a bit.
+
+2001-08-04  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: update capture documentation
+
+2001-08-03  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      NEWS
+      Smarty.class.php:
+    fix bug with URL controlled debugging, works now (Monte)
+
+2001-08-01  Andrei Zmievski  <andrei@php.net>
+
+    * Config_File.class.php: *** empty log message ***
+
+    * Smarty_Compiler.class.php
+      Smarty.class.php: - Fixed some E_NOTICE stuff in compiler.
+    - Generalized assign_smarty_interface() a bit.
+
+2001-07-24  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty_Compiler.class.php
+      TODO: See ChangeLog for details.
+
+2001-07-20  Andrei Zmievski  <andrei@php.net>
+
+    * Config_File.class.php: Booleanize case-insensitively.
+
+2001-07-17  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update ChangeLog
+
+    * Smarty.class.php
+      docs.sgml: put SMARTY_DIR on Config_File require
+
+2001-07-11  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml
+      FAQ
+      NEWS
+      Smarty.class.php:
+    updated security to not include insecure docs, only warning
+
+2001-07-10  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Adding 'sizeof' as an allowed {if} function.
+
+2001-07-06  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+2001-07-06  Monte Ohrt  <monte@ispi.net>
+
+    * Config_File.class.php
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php: update version number to 1.4.4
+
+    * NEWS
+      Smarty.addons.php
+      Smarty_Compiler.class.php
+      docs.sgml
+      templates/header.tpl
+      templates/index.tpl: update documenatation, template examples
+
+2001-07-03  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: Implemented access to request vars via $smarty var.
+
+    * NEWS
+      Smarty_Compiler.class.php:
+    Fixed a bug with parsing function arguments in {if} tags.
+
+2001-06-30  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update ChangeLog
+
+2001-06-29  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php
+      Smarty.class.php
+      docs.sgml
+      overlib.js:
+    moved overlib to separate file, added SMARTY_DIR, documented. added much documentation
+
+2001-06-29  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      RELEASE_NOTES
+      TODO: *** empty log message ***
+
+2001-06-29  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml
+      index.php
+      templates/debug.tpl
+      templates/header.tpl
+      templates/index.tpl: update release notes
+
+2001-06-27  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: *** empty log message ***
+
+    * NEWS
+      Smarty_Compiler.class.php: Implemented 'step' section attribute.
+
+    * Smarty_Compiler.class.php: Negative values of 'max' will mean no max.
+
+    * AUTHORS
+      NEWS: *** empty log message ***
+
+2001-06-26  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      index.php: Added 'max' and 'start' section attributes.
+    Added 'total' and 'iteration' section properties.
+
+2001-06-25  Andrei Zmievski  <andrei@php.net>
+
+    * Config_File.class.php
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php: Update version numbers.
+
+2001-06-23  Andrei Zmievski  <andrei@php.net>
+
+    * TODO: *** empty log message ***
+
+2001-06-21  Andrei Zmievski  <andrei@php.net>
+
+    * Config_File.class.php
+      NEWS: Fixed booleanization bug.
+
+2001-06-20  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml:
+    update documents to reflect changes to cached content & debugging
+
+2001-06-20  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      Smarty.class.php: Remove debug output for cached and fetched cases.
+
+2001-06-20  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: update include_info to false
+
+    * Smarty.class.php
+      docs.sgml
+      index.php
+      templates/footer.tpl:
+    moved debug logic into Smarty completely, created flags for it
+
+2001-06-19  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      Smarty.class.php
+      templates/debug.tpl: *** empty log message ***
+
+    * NEWS
+      Smarty.class.php: Remove unneeded debug functions.
+
+2001-06-19  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml
+      templates/debug.tpl
+      templates/footer.tpl: commit updates, add debug template
+
+2001-06-19  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      TODO:
+    Moved config loading code inside main class, the compiled template now
+    simply calls that method.
+
+2001-06-15  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      templates/index.tpl: * moved config array into class itself
+    * added 'scope' attribute for config_load
+
+    * Smarty_Compiler.class.php
+      Smarty.addons.php
+      Smarty.class.php: Finishing up secure mode.
+
+2001-06-15  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update ChangeLog
+
+    * Smarty_Compiler.class.php: cleaned up logic of if statement security
+
+    * Smarty_Compiler.class.php: update if logic to cover more situations
+
+    * Smarty_Compiler.class.php
+      docs.sgml: update if statement security feature
+
+2001-06-14  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      Smarty.class.php: *** empty log message ***
+
+    * NEWS
+      Smarty_Compiler.class.php:
+    Fixed a bug with quoted strings inside if statements.
+
+2001-06-13  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php
+      Smarty.class.php: added secure_dir array for multiple secure directories
+
+    * Smarty.addons.php: update fetch funtion to respect security setting
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml: update documentation, changelog
+
+    * Smarty.addons.php
+      Smarty.class.php: moved _extract setting to assign functions
+
+    * Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    added assign/unassign custom functions, ability to re-extract tpl_vars
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml
+      index.php: commit security features
+
+2001-06-11  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Version variable typo.
+
+2001-06-05  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php:
+    Create config object in fetch() or just set the config path if it already
+    exists.
+
+2001-06-04  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: *** empty log message ***
+
+    * NEWS
+      Smarty_Compiler.class.php:
+    Fixed a problem with $<number> inside strip tags.
+
+2001-05-31  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Config_File.class.php: Allow empty config_path.
+
+2001-05-29  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      docs.sgml
+      NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php: update version numbers
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml: moved version variable to internal variable
+
+2001-05-22  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php:
+    Moved $_smarty_sections and $_smarty_conf_obj into Smarty class.
+
+2001-05-18  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update ChangeLog
+
+    * FAQ
+      QUICKSTART: update FAQ, QUICKSTART for windows include_path setup
+
+    * configs/test.conf: added configs directory to cvs
+
+2001-05-18  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Use compiler_class for including the file.
+
+2001-05-18  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: fix typo
+
+2001-05-16  Monte Ohrt  <monte@ispi.net>
+
+    * README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php: update files to version 1.4.1
+
+    * NEWS: update ChangeLog
+
+2001-05-15  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * index.php: forget that!
+
+    * NEWS
+      Smarty_Compiler.class.php
+      index.php: Fixed a few E_NOTICE warnings.
+
+2001-05-09  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml: update dates versions
+
+2001-05-09  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty.class.php:
+    Use absolute paths when requiring/including Smart components.
+
+    * NEWS: *** empty log message ***
+
+    * Smarty.class.php: Use write mode instead of append.
+
+2001-05-02  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty_Compiler.class.php: Fix indexing by section properties.
+
+2001-05-02  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update changelog
+
+    * Smarty.class.php: remove period from syntax error
+
+2001-05-02  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Double-quote the attribute values by default.
+
+2001-04-30  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      NEWS: added simple {capture} logic
+
+2001-04-30  Andrei Zmievski  <andrei@php.net>
+
+    * TODO: *** empty log message ***
+
+    * Smarty_Compiler.class.php
+      Smarty.class.php: Fix passing config vars to included files.
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php: Fix inclusion again.
+
+2001-04-30  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      RELEASE_NOTES
+      Smarty.class.php
+      misc/fix_vars.php
+      NEWS: update paths for windows (c:)
+
+2001-04-28  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php: Fix passing variables to included files.
+
+    * templates/index.tpl: *** empty log message ***
+
+2001-04-27  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Fix includes.
+
+2001-04-26  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php
+      docs.sgml
+      Smarty.class.php: Formatting mostly.
+
+    * Smarty_Compiler.class.php
+      Config_File.class.php: *** empty log message ***
+
+2001-04-26  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      docs.sgml
+      FAQ
+      NEWS
+      QUICKSTART
+      RELEASE_NOTES
+      Smarty.class.php: update docs with new changes
+
+2001-04-26  Andrei Zmievski  <andrei@php.net>
+
+    * RELEASE_NOTES: *** empty log message ***
+
+    * docs.sgml
+      templates/index.tpl
+      NEWS
+      Smarty_Compiler.class.php: Added ability to reference object properties.
+
+2001-04-25  Andrei Zmievski  <andrei@php.net>
+
+    * README
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml
+      AUTHORS
+      Config_File.class.php
+      CREDITS
+      RELEASE_NOTES
+      NEWS: *** empty log message ***
+
+    * docs.sgml: Docs on new parameter to custom functions.
+
+    * NEWS: *** empty log message ***
+
+    * Smarty_Compiler.class.php:
+    Changing the way tpl vars are referenced and passing smarty object
+    to custom functions.
+
+    * RELEASE_NOTES
+      docs.sgml: Fixing docs a bit.
+
+2001-04-24  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml: Docs for $compiler_class and compiler functions.
+
+    * templates/index.tpl: *** empty log message ***
+
+    * Smarty_Compiler.class.php: Remove debugging.
+
+2001-04-24  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: update compiler function docs
+
+2001-04-24  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      templates/index.tpl: Added compiler function support.
+
+2001-04-24  Monte Ohrt  <monte@ispi.net>
+
+    * RELEASE_NOTES
+      Smarty.class.php:
+    update notes, change show_info_header to false by default
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml
+      CREDITS
+      FAQ
+      NEWS
+      README
+      RELEASE_NOTES: update documenation, bug fixes
+
+2001-04-24  Andrei Zmievski  <andrei@php.net>
+
+    * misc/fix_vars.php: Hopefully fix for sure.
+
+2001-04-23  Monte Ohrt  <monte@ispi.net>
+
+    * misc/fix_vars.php: uncomment copy/unlink
+
+2001-04-23  Andrei Zmievski  <andrei@php.net>
+
+    * misc/fix_vars.php: Do it more thoroughly.
+
+    * misc/fix_vars.php: check for }
+
+2001-04-22  Andrei Zmievski  <andrei@php.net>
+
+    * misc/fix_vars.php: Fix variable parsing.
+
+2001-04-20  Monte Ohrt  <monte@ispi.net>
+
+    * misc/fix_vars.php: fix problem with 4.0.5-dev and preg_replace_callback
+
+2001-04-19  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      docs.sgml
+      misc/fix_vars.php
+      NEWS
+      RELEASE_NOTES
+      Smarty.class.php: update notes/documentation
+
+    * NEWS
+      README
+      RELEASE_NOTES
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml: update files for 1.4.0 release
+
+2001-04-16  Andrei Zmievski  <andrei@php.net>
+
+    * misc/fix_vars.php: Added fix_vars.php script.
+
+2001-04-16  Monte Ohrt  <monte@ispi.net>
+
+    * QUICKSTART
+      RELEASE_NOTES
+      docs.sgml
+      templates/index.tpl:
+    update RELEASE_NOTES & scripts with new section var syntax
+
+2001-04-13  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: * Implement new variable format parser.
+    * Optimizing config load a bit.
+
+2001-04-13  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      NEWS
+      RELEASE_NOTES
+      Smarty.class.php:
+    added $check_cached_insert_tags to speed up cached pages if
+          {insert ...} is not used (Monte)
+
+2001-04-12  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      RELEASE_NOTES: *** empty log message ***
+
+    * Smarty_Compiler.class.php: Remove redundant functions.
+
+    * Smarty.class.php: Formatting.
+
+2001-04-12  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: update file: parsing
+
+    * Smarty.class.php
+      docs.sgml: update documentation
+
+2001-04-12  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      TODO: *** empty log message ***
+
+2001-04-11  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      QUICKSTART
+      RELEASE_NOTES: added RELEASE_NOTES file to cvs
+
+    * NEWS
+      docs.sgml: update ChangeLog, update documentation
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      templates/index.tpl:
+    update Smarty to compile at run-time. added ability to get files from
+    absolute paths, added work around for LOCK_EX and windows, changed a few
+    file permissions to be more secure.
+
+2001-03-29  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.addons.php:
+    allow arbitrary date strings instead of just timestamps
+
+2001-03-28  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      docs.sgml
+      FAQ
+      NEWS
+      README
+      Smarty.addons.php:
+    update version in class, update docs for count_ and new vars
+
+    * templates/index.tpl
+      docs.sgml: update docs, example template
+
+2001-03-28  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Some variable renaming.
+
+2001-03-23  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php
+      NEWS: Fixed nested include infinite repeat bug.
+
+2001-03-23  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: fix version number
+
+    * Smarty.class.php
+      NEWS: added optional HTML header to output
+
+2001-03-22  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Fixed inclusion of dynamic files.
+
+2001-03-16  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty_Compiler.class.php: Fixing the config_load scoping.
+
+    * Smarty_Compiler.class.php: making config variables global for now.
+
+2001-03-15  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty_Compiler.class.php:
+    * Includes are now always done via generated function call to protect
+      namespace.
+    * config_load now always uses global config object to improve
+      performance.
+
+2001-03-13  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: update math documentation with format attribute
+
+2001-03-11  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml
+      NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php: update math function with format attribute
+
+2001-03-10  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php: *** empty log message ***
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php: Added html_select_time custom function.
+
+2001-03-08  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php
+      NEWS
+      README
+      Smarty.addons.php: rename 1.3.1b to 1.3.1pl1
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php: update version numbers, changelog
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php:
+    moved _syntax_error to Smarty_Compiler.class.php
+
+    * Smarty.class.php
+      docs.sgml:
+    missing _syntax_error function recovered. fixed minor syntax in docs
+
+2001-03-07  Monte Ohrt  <monte@ispi.net>
+
+    * QUICKSTART
+      README
+      Smarty.addons.php
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      BUGS
+      INSTALL
+      NEWS: update everything to 1.3.1
+
+2001-03-03  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty_Compiler.class.php
+      Smarty.class.php: fixed bug with cached insert tags
+
+2001-03-02  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      Smarty_Compiler.class.php:
+    fix cache fuctions with separated compiled class
+
+    * FAQ
+      NEWS
+      docs.sgml: update changelog
+
+2001-03-02  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty_Compiler.class.php: Added 'first' and 'last' section properties.
+
+2001-03-02  Monte Ohrt  <monte@ispi.net>
+
+    * TODO: remove compiling separation TODO
+
+    * Smarty_Compiler.class.php
+      Smarty.addons.php
+      Smarty.class.php: update function headers
+
+    * templates/index.tpl
+      NEWS
+      Smarty.class.php
+      Smarty_Compiler.class.php
+      index.php: split out compiling code for faster execution
+
+    * Smarty.class.php: fixed a few warning messages
+
+    * Smarty.addons.php
+      Smarty.class.php
+      docs.sgml
+      NEWS: added fetch, unregister mod/fun, updated docs
+
+2001-03-01  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php: added "int" to available list
+
+    * docs.sgml
+      FAQ
+      Smarty.class.php: update FAQ, add math functions & update documetation
+
+    * index.php
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml: fixed literal tags and other optional delimiters
+
+2001-02-26  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php:
+    Added index_prev, index_next section properties and ability to
+    index by them.
+
+    * NEWS
+      Smarty.addons.php
+      Smarty.class.php: Reverting the plugins patch - needs more thought.
+
+    * Smarty.class.php: Fixing plugin loading.
+
+2001-02-23  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      Smarty.class.php
+      plugins/standard.plugin.php
+      NEWS: Added plugin functionality.
+
+2001-02-22  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml
+      templates/index.tpl
+      NEWS
+      README
+      Smarty.class.php: fixed issue with php tags executed in literal blocks
+
+2001-02-21  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update changelog for LGPL change
+
+    * Smarty.class.php
+      docs.sgml
+      README
+      Smarty.addons.php: updated version numbers to 1.3.0
+
+    * NEWS
+      templates/index.tpl: update changelog, rearrange index.tpl file
+
+2001-02-21  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: *** empty log message ***
+
+2001-02-21  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: update parameters for is_cached and fetch
+
+2001-02-21  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: *** empty log message ***
+
+2001-02-21  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS
+      Smarty.addons.php
+      docs.sgml: update docs, remove header function from addons
+
+2001-02-20  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      NEWS: update changelog
+
+    * TODO: update todo
+
+    * TODO: update todo list
+
+    * Smarty.class.php: update php tag handling logic
+
+2001-02-19  Monte Ohrt  <monte@ispi.net>
+
+    * index.php
+      Config_File.class.php
+      FAQ
+      Smarty.class.php
+      docs.sgml: fixed <?php tag at beginning of files, updated docs
+
+2001-02-19  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php: *** empty log message ***
+
+2001-02-13  Andrei Zmievski  <andrei@php.net>
+
+    * TODO: *** empty log message ***
+
+2001-02-12  Andrei Zmievski  <andrei@php.net>
+
+    * templates/index.tpl
+      Smarty.class.php: *** empty log message ***
+
+2001-02-10  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: remove  unneeded preg_match
+
+    * Smarty.class.php: remove comment
+
+    * Smarty.class.php: updated php escape to handle <script language="php">
+
+    * NEWS
+      Smarty.class.php: fix php tag escapement logic
+
+    * NEWS: commit changelog
+
+    * docs.sgml: update header docs
+
+    * docs.sgml
+      Smarty.addons.php
+      Smarty.class.php: added header custom function
+
+2001-02-09  Monte Ohrt  <monte@ispi.net>
+
+    * index.php
+      templates/header.tpl
+      templates/index.tpl
+      INSTALL
+      QUICKSTART
+      docs.sgml: update documentation, add examples to test script.
+
+2001-02-08  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: *** empty log message ***
+
+2001-02-08  Monte Ohrt  <monte@ispi.net>
+
+    * COPYING.lib: added COPYING.lib
+
+    * COPYING
+      Config_File.class.php
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml: changed license to LGPL for commercial use
+
+    * docs.sgml
+      Smarty.class.php: fix clear_assign syntax error
+
+2001-02-07  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: added ability to pass array to clear_assign
+
+    * index.php
+      templates/index.tpl
+      docs.sgml:
+    update documentation, remove tests from index file and template
+
+2001-02-07  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php: Adding file locking.
+
+    * templates/index.tpl
+      Smarty.addons.php
+      Smarty.class.php
+      index.php: More cache work.
+
+2001-02-06  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml
+      Smarty.class.php:
+    change register_ function names, update documents with tables
+
+2001-02-06  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      templates/index.tpl: Reworking and optimizing the cache system.
+
+    * Smarty.class.php: Restoring ?> in patterns.
+
+2001-02-05  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      docs.sgml: update cache directory creation logic
+
+2001-02-05  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Removing once-only subpattern for now..
+
+    * Smarty.class.php: Fix modifier arg parsing.
+
+2001-02-02  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      Smarty.class.php
+      templates/index.tpl: See changelog.
+
+2001-02-01  Andrei Zmievski  <andrei@php.net>
+
+    * README: *** empty log message ***
+
+    * Smarty.class.php: Use 'echo' instead of 'print'.
+
+    * Smarty.addons.php: *** empty log message ***
+
+2001-02-01  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: rearranged variables at top of script
+
+2001-02-01  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Retabbing.
+
+    * templates/index.tpl
+      Smarty.class.php
+      index.php: *** empty log message ***
+
+2001-02-01  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: update caching logic
+
+    * Smarty.class.php: fixed clear_all_cache bugs
+
+    * Smarty.class.php: fix .cache check
+
+    * docs.sgml
+      FAQ
+      Smarty.class.php: update .che to .cache
+
+    * FAQ
+      Smarty.class.php
+      docs.sgml: updated docs for caching, added clear_all_cache() directive
+
+2001-01-31  Monte Ohrt  <monte@ispi.net>
+
+    * index.php
+      templates/index.tpl
+      docs.sgml: upated docs for date_format and html_options
+
+2001-01-31  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty.addons.php
+      index.php: Added ability to pass 'options' attribute to html_options.
+
+    * Smarty.addons.php
+      Smarty.class.php
+      docs.sgml
+      index.php
+      templates/index.tpl
+      Config_File.class.php
+      NEWS
+      README: Reworking, simplifying, and speeding up cache implementation.
+    Fixing the infelicity where you couldn't have '|' and ':' inside
+    quoted modifier arguments.
+
+2001-01-31  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php
+      index.php
+      templates/index.tpl: removed DEBUG lines
+
+2001-01-30  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: changed default expire to 3600
+
+    * Config_File.class.php
+      NEWS
+      README
+      Smarty.addons.php
+      Smarty.class.php: updated version numbers
+
+    * docs.sgml
+      NEWS
+      Smarty.class.php:
+    added caching, force compile, force cache, misc performance updates
+
+2001-01-30  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS: *** empty log message ***
+
+    * Smarty.class.php
+      templates/index.tpl: Remove debug message.
+
+    * Smarty.class.php
+      templates/index.tpl: Fixing the compile directory mayhem...
+
+    * Smarty.class.php:
+    Fix problem with {strip} around {section} and {include}
+
+    * Smarty.addons.php: *** empty log message ***
+
+2001-01-29  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      NEWS
+      README
+      Smarty.class.php: fixed PHP_VERSION check, misc doc updates
+
+    * index.php
+      Config_File.class.php
+      NEWS
+      QUICKSTART
+      README
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml: updated for 1.2.1 compile_dir changes, misc doc updates
+
+2001-01-26  Monte Ohrt  <monte@ispi.net>
+
+    * BUGS
+      README: update BUGS and README files
+
+    * FAQ: updated FAQ
+
+    * Config_File.class.php
+      FAQ
+      NEWS
+      README
+      Smarty.addons.php
+      docs.sgml
+      templates/index.tpl
+      AUTHORS: update again
+
+2001-01-26  Andrei Zmievski  <andrei@php.net>
+
+    * docs.sgml
+      NEWS
+      README
+      Smarty.class.php
+      templates/index.tpl: *** empty log message ***
+
+    * Smarty.class.php
+      index.php
+      templates/index.tpl: Added ability to index by key.
+
+2001-01-25  Monte Ohrt  <monte@ispi.net>
+
+    * NEWS: update changelog
+
+    * README
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml
+      AUTHORS: updated versions to 1.1.0
+
+    * docs.sgml
+      templates/index.tpl
+      Config_File.class.php
+      Smarty.addons.php
+      Smarty.class.php: update copyright notice
+
+    * Config_File.class.php
+      Smarty.addons.php
+      Smarty.class.php
+      docs.sgml: added misc info
+
+2001-01-24  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.addons.php
+      index.php
+      templates/index.tpl
+      Config_File.class.php: initial commit
+
+2001-01-23  Monte Ohrt  <monte@ispi.net>
+
+    * docs.sgml: fix typo
+
+2001-01-22  Monte Ohrt  <monte@ispi.net>
+
+    * doc.sgm
+      docs.sgml: updated docs, renamed file
+
+    * FAQ: updated FAQ
+
+    * NEWS
+      README: updated Changelog and Readme
+
+    * doc.sgm: updated doc.sgm error
+
+    * AUTHORS
+      COPYING
+      INSTALL
+      NEWS
+      QUICKSTART: misc doc changes, added AUTHORS, COPYING
+
+2001-01-22  Andrei Zmievski  <andrei@php.net>
+
+    * NEWS
+      templates/index.tpl: *** empty log message ***
+
+    * Smarty.class.php
+      templates/index.tpl:
+    Fixed bug that wouldn't let you do specify non-array values for 'loop'
+    attribute.
+
+2001-01-22  Monte Ohrt  <monte@ispi.net>
+
+    * QUICKSTART: updated QUICKSTART
+
+    * BUGS
+      FAQ
+      INSTALL
+      README
+      doc.sgm: added BUGS and INSTALL, updated docs, FAQ, README
+
+2001-01-21  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ
+      doc.sgm: updates to FAQ and docs
+
+2001-01-19  Monte Ohrt  <monte@ispi.net>
+
+    * FAQ: initial commit of FAQ
+
+    * QUICKSTART
+      README
+      doc.sgm
+      index.php:
+    updated README, doc.sgm with preg_replace() parameter issue. also removed "./" from index.php file
+
+    * NEWS: initial commit of changelog
+
+    * doc.sgm
+      QUICKSTART: update quickstart text
+
+2001-01-19  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Fix the compiled template check.
+
+2001-01-18  Andrei Zmievski  <andrei@php.net>
+
+    * doc.sgm: *** empty log message ***
+
+2001-01-18  Monte Ohrt  <monte@ispi.net>
+
+    * index.php
+      templates/index.tpl
+      QUICKSTART
+      Smarty.addons.php
+      Smarty.class.php
+      doc.sgm: update changes
+
+2001-01-18  Andrei Zmievski  <andrei@php.net>
+
+    * QUICKSTART
+      Smarty.addons.php: *** empty log message ***
+
+2001-01-18  Monte Ohrt  <monte@ispi.net>
+
+    * QUICKSTART
+      doc.sgm: add QUICKSTART, update docs for default modifier
+
+    * Smarty.addons.php
+      Smarty.class.php: added default modifier
+
+    * README
+      Smarty.addons.php
+      Smarty.class.php
+      doc.sgm
+      templates/index.tpl: added dislaimers
+
+2001-01-18  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: *** empty log message ***
+
+2001-01-16  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      templates/index.tpl: Implement 'div by'.
+
+2001-01-12  Monte Ohrt  <monte@ispi.net>
+
+    * doc.sgm: update docs
+
+    * doc.sgm: doc changes
+
+    * doc.sgm: update docs
+
+2001-01-12  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      doc.sgm: *** empty log message ***
+
+    * Smarty.class.php: Fix template traversal.
+
+2001-01-11  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: *** empty log message ***
+
+2001-01-09  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      Smarty.class.php: *** empty log message ***
+
+2001-01-09  Monte Ohrt  <monte@ispi.net>
+
+    * doc.sgm: update manual
+
+2001-01-05  Monte Ohrt  <monte@ispi.net>
+
+    * doc.sgm
+      Smarty.addons.php: commit changes
+
+2001-01-04  Monte Ohrt  <monte@ispi.net>
+
+    * doc.sgm
+      templates/index.tpl
+      Smarty.class.php: update changes
+
+    * index.php
+      Smarty.addons.php
+      doc.sgm: add documentation
+
+2001-01-02  Monte Ohrt  <monte@ispi.net>
+
+    * index.php
+      templates/index.tpl
+      Smarty.addons.php
+      Smarty.class.php: prepend insert_ to insert tag functions
+
+    * Smarty.class.php
+      index.php
+      templates/index.tpl: remove caching logic
+
+    * README
+      Smarty.class.php
+      index.php
+      templates/index.tpl: update changes
+
+2000-12-27  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      templates/header.tpl
+      templates/index.tpl
+      Smarty.addons.php: *** empty log message ***
+
+2000-12-21  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php: Fix access to template variables.
+
+    * Smarty.class.php
+      templates/header.tpl:
+    Added support for passing variables to included files.
+
+2000-12-20  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php:
+    Added support for inserting results of function processing a template.
+
+2000-12-18  Monte Ohrt  <monte@ispi.net>
+
+    * Smarty.class.php: added string_format function
+
+    * Smarty.addons.php: update format to string_format
+
+    * README
+      Smarty.addons.php
+      Smarty.class.php: added format addon function
+
+2000-12-13  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      Smarty.class.php: Fix sectionelse.
+
+2000-12-07  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.addons.php
+      Smarty.class.php
+      templates/index.tpl: *** empty log message ***
+
+2000-12-04  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      templates/index.tpl
+      Smarty.addons.php: *** empty log message ***
+
+2000-11-27  Andrei Zmievski  <andrei@php.net>
+
+    * templates/index.tpl
+      Smarty.class.php: *** empty log message ***
+
+2000-11-22  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      templates/index.tpl: *** empty log message ***
+
+2000-11-21  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      templates/index.tpl
+      Smarty.addons.php: *** empty log message ***
+
+2000-11-20  Andrei Zmievski  <andrei@php.net>
+
+    * templates/index.tpl
+      Smarty.class.php
+      Smarty.addons.php
+      index.php: *** empty log message ***
+
+    * Smarty.class.php
+      index.php
+      templates/index.tpl: Made sections work mostly.
+
+2000-11-19  Andrei Zmievski  <andrei@php.net>
+
+    * index.php
+      templates/index.tpl: *** empty log message ***
+
+2000-11-17  Andrei Zmievski  <andrei@php.net>
+
+    * Smarty.class.php
+      Smarty.addons.php: *** empty log message ***
+
+2000-11-15  Monte Ohrt  <monte@ispi.net>
+
+    * index.php
+      templates/footer.tpl
+      templates/header.tpl
+      templates/index.tpl: added template files to cvs dir
+
+    * README
+      Smarty.class.php: commit changes
+
+2000-08-08  Monte Ohrt  <monte@ispi.net>
+
+    * README
+      Smarty.class.php: update include path bug
+
+    * README: add README file
+
+    * Smarty.class.php: New file.
+
+    * Smarty.class.php: initial import
+
Index: /trunk/htdocs2/smarty/FAQ
===================================================================
--- /trunk/htdocs2/smarty/FAQ	(revision 298)
+++ /trunk/htdocs2/smarty/FAQ	(revision 298)
@@ -0,0 +1,284 @@
+QUESTION INDEX
+--------------
+
+GENERAL
+
+Q: What is Smarty?
+Q: What's the difference between Smarty and other template engines?
+Q: What do you mean "Compiled PHP Scripts" ?
+Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
+Q: Why does smarty have a built in cache? Wouldn't it be better to handle this
+   in a separate class?
+Q: Is Smarty faster than <insert other PHP template engine>?
+Q: How can I be sure to get the best performance from Smarty?
+Q: Do you have a mailing list?
+Q: Can you change the mailing list so reply-to sends to the list and not the
+   user?
+
+TROUBLESHOOTING
+
+Q: Smarty doesn't work.
+Q: I get the following error when running Smarty:
+   Warning:  Smarty error: problem creating directory "templates_c/239/239105369"
+   in /path/to/Smarty.class.php on line 542
+Q: I get the following error when running Smarty:
+   Warning: Wrong parameter count for preg_replace() in
+   Smarty.class.php on line 371
+Q: I get this error when passing variables to {include}:
+   Fatal error: Call to undefined function: get_defined_vars() in
+   /path/to/Smarty/templates_c/index.tpl.php on line 8
+Q: I get PHP errors in my {if} tag logic.
+Q: I'm changing my php code and/or templates, and my results are not getting
+   updated.
+Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
+   also zero length.
+Q: The template goes into an infinite loop when I include included templates
+   that pass local variables
+Q: Javascript is causing Smarty errors in my templates.
+Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
+
+MISC
+
+Q: Can I use Macromedia's Dreamweaver to edit my templates?
+Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
+   HREF link. How do I get around this?
+
+HOWTO
+
+Q: How do I generate different cache files per template based on arguments
+   passed to the page?
+Q: How do I pass a template variable as a parameter? {function param={$varname}}
+   does not work.
+Q: How do I include cached template(s) within a non-cached template?
+
+
+GENERAL
+-------
+
+Q: What is Smarty?
+A: Smarty is a template engine for PHP... but be aware this isn't just another
+   PHP template engine. It's much more than that.
+
+Q: What's the difference between Smarty and other template engines?
+A: Most other template engines for PHP provide basic variable substitution and
+   dynamic block functionality. Smarty takes a step further to be a "smart"
+   template engine, adding features such as configuration files, template
+   functions, variable modifiers (see the docs!) and making all of this
+   functionality as easy as possible to use for both programmers and template
+   designers. Smarty also compiles the templates into PHP scripts, eliminating
+   the need to parse the templates on every invocation, making Smarty extremely
+   scalable and manageable for large application needs.
+
+Q: What do you mean "Compiled PHP Scripts" ?
+A: Smarty reads the template files and creates PHP scripts from them. Once
+   these PHP scripts are created, Smarty executes these, never having to parse
+   the template files again. If you change a template file, Smarty will
+   recreate the PHP script for it. All this is done automatically by Smarty.
+   Template designers never need to mess with the generated PHP scripts or even
+   know of their existance. (NOTE: you can turn off this compile checking step
+   in Smarty for increased performance.)
+
+Q: Why can't I just use PHPA (http://php-accelerator.co.uk) or Zend Cache?
+A: You certainly can, and we highly recommend it! What PHPA does is caches
+   compiled bytecode of your PHP scripts in shared memory or in a file. This
+   speeds up server response and saves the compilation step. Smarty creates PHP
+   scripts, which PHPA will cache nicely. Now, Smarty's built-in cache is
+   something completely different. It caches the _output_ of the template
+   contents. For example, if you have a template that requires several database
+   queries, Smarty can cache this output, saving the need to call the database
+   every time. Smarty and PHPA (or Zend Cache) complement each other nicely. If
+   performance is of the utmost importance, we would recommend using one of
+   these with any PHP application, using Smarty or not. As you can see in the
+   benchmarks, Smartys performance _really_ excels in combination with a PHP
+   accelerator.
+
+Q: Why does Smarty have a built in cache? Wouldn't it be better to handle this
+   in a separate class?
+A: Smarty's caching functionality is tightly integrated with the template
+   engine, making it quite a bit more flexible than a simple caching wrapper.
+   For instance, you can cache select portions of a template page. Let's say
+   you have a polling box on your site. With Smarty, you can leave the poll
+   dynamic and cache the rest of the page. You can also pass templates
+   multiple cache ids, meaning that a template can have several caches
+   depending on URL, cookies, etc.
+
+Q: Is Smarty faster than <insert other PHP template engine>?
+A: See the benchmark page for some performance comparisons. Smarty's approach
+   to templates is a bit different from some languages: it compiles templates
+   into PHP scripts instead of parsing them on each invocation. This usually
+   results in great performance gains, especially with complex templates.
+   Coupled with the built-in caching of Smarty templates, the performance is
+   outstanding.
+
+Q: How can I be sure to get the best performance from Smarty?
+A: Be sure you set $compile_check=false once your templates are initially
+   compiled. This will skip the unneeded step of testing if the template has
+   changed since it was last compiled. If you have complex pages that don't
+   change too often, turn on the caching engine and adjust your application so
+   it doesn't do unnecessary work (like db calls) if a cached page is
+   available. See the documentation for examples.
+   
+Q: Do you have a mailing list?
+A:  We have a few mailing lists. "general" for you to share your ideas or ask
+	questions, "dev" for those interested in the development efforts of Smarty,
+	and "cvs" for those that would like to track the updates made in the cvs
+	repository.
+
+    send a blank e-mail message to:
+      smarty-general-subscribe@lists.php.net (subscribe to the general list)
+      smarty-general-unsubscribe@lists.php.net (unsubscribe from the general list)
+      smarty-general-digest-subscribe@lists.php.net (subscribe to digest)
+      smarty-general-digest-unsubscribe@lists.php.net (unsubscribe from digest)
+      smarty-dev-subscribe@lists.php.net (subscribe to the dev list)
+      smarty-dev-unsubscribe@lists.php.net (unsubscribe from the dev list)
+      smarty-cvs-subscribe@lists.php.net (subscribe to the cvs list)
+      smarty-cvs-unsubscribe@lists.php.net (unsubscribe from the cvs list)
+    You can also browse the mailing list archives at
+    http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
+
+
+
+Q: Can you change the mailing list so Reply-To sends to the list and not the
+   user?
+A: Yes we could, but no we won't. Use "Reply-All" in your e-mail client to send
+   to the list. http://www.unicom.com/pw/reply-to-harmful.html
+
+TROUBLESHOOTING
+---------------
+
+Q: Smarty doesn't work.
+A: You must be using PHP 4.0.6 or later if you use any version of Smarty
+   past 2.0.1. Read the BUGS file for more info.
+
+Q: I get the following error when running Smarty:
+   Warning:  Smarty error: problem creating directory "templates_c/239/239105369"
+   in /path/to/Smarty.class.php on line 542
+A: Your web server user does not have permission to write to the templates_c
+   directory, or is unable to create the templates_c directory. Be sure the
+   templates_c directory exists in the location defined in Smarty.class.php,
+   and the web server user can write to it. If you do not know the web server
+   user, chmod 777 the templates_c directory, reload the page, then check the
+   file ownership of the files created in templates_c. Or, you can check the
+   httpd.conf (usually in /usr/local/apache/conf) file for this setting:
+   User nobody
+   Group nobody
+
+Q: I get the following error when running Smarty: Warning: Wrong parameter
+   count for preg_replace() in Smarty.class.php on line 371
+A: preg_replace had a parameter added in PHP 4.0.2 that Smarty
+   requires. Upgrade to at least 4.0.6 to fix all known PHP issues with
+   Smarty.
+
+Q: I get this error when passing variables to {include}:
+   Fatal error: Call to undefined function: get_defined_vars() in
+   /path/to/Smarty/templates_c/index.tpl.php on line 8
+A: get_defined_vars() was added to PHP 4.0.4. If you plan on passing
+   variables to included templates, you will need PHP 4.0.6 or later.
+
+Q: I get PHP errors in my {if} tag logic.
+A: All conditional qualifiers must be separated by spaces. This syntax will not
+   work: {if $name=="Wilma"} You must instead do this: {if $name == "Wilma"}.
+   The reason for this is syntax ambiguity. Both "==" and "eq" are equivalent
+   in the template parser, so something like {if $nameeq"Wilma"} wouldn't be
+   parsable by the tokenizer.
+
+Q: I'm changing my php code and/or templates, and my results are not getting
+   updated.
+A: This may be the result of your compile or cache settings. If you are
+   changing your php code, your templates will not necessarily get recompiled
+   to reflect the changes. Use $force_compile during develpment to avoid these
+   situations. Also turn off caching during development when you aren't
+   specifically testing it. You can also remove everything from your
+   compile_dir and cache_dir and reload the page to be sure everything gets
+   regenerated.
+
+Q: I'm running Windows 2000 and I get blank content. My compiled PHP files are
+   also zero length.
+A: There seems to be a problem with some W2k machines and exclusive file
+   locking. Comment out the flock() call in _write_file to get around this,
+   although be aware this could possibly cause a problem with simultaneous
+   writes to a file, especially with caching turned on. NOTE: As of Smarty
+   1.4.0, a workaround was put in place that should solve this.
+
+Q: The template goes into an infinite loop when I include included templates
+   that pass local variables
+A: This was fixed in 1.3.2 (new global attribute)
+
+Q: Javascript is causing Smarty errors in my templates.
+A: Surround your javascript with {literal}{/literal} tags. See the docs.
+
+Q: I get "SAFE MODE Restriction in effect. ..."-errors when running smarty.
+A: Use $smarty->use_sub_dirs = false when running php in safe mode.
+
+MISC
+----
+
+Q: Can I use Macromedia's Dreamweaver to edit my templates?
+A: Certainly. You might want to change your tag delimiters from {} to something
+   that resembles valid HTML, like <!--{ }--> or <{ }> or something similar.
+   This way the editor won't view the template tags as errors.
+
+Q: Dreamweaver is urlencoding the template delimiters when they are in a SRC or
+   HREF link. How do I get around this?
+A: In Edit - Properties - Rewrite HTML you can specify if Dreamweaver should
+   change special letters to %-equivalent or not. The default is on which
+   produces this error.
+
+HOWTO
+-----
+   
+Q: How do I generate different cache files per template based on arguments
+   passed to the page?
+A: Use your $REQUEST_URI as the cache_id when fetching the page:
+
+   global $REQUEST_URI; // if not already present
+   $smarty->display('index.tpl',$REQUEST_URI);
+
+   This will create a separate cache file for each unique URL when you call
+   index.tpl. See the documentation for display() and fetch()
+
+Q: How do I pass a template variable as a parameter? {function param={$varname}}
+   does not work.
+A: {function param=$varname} (You cannot nest template delimiters.)
+
+Q: How do I include cached template(s) within a non-cached template?
+A: One way to do it:
+
+   $smarty->caching = true;
+   $tpl1 = $smarty->fetch("internal1.tpl");
+   $tpl2 = $smarty->fetch("internal2.tpl");
+   $tpl3 = $smarty->fetch("internal3.tpl");
+
+   $smarty->assign("tpl1_contents",$tpl1);
+   $smarty->assign("tpl2_contents",$tpl2);
+   $smarty->assign("tpl3_contents",$tpl3);
+
+   $smarty->caching = false;
+   $smarty->display('index.tpl');
+
+   index.tpl
+   ---------
+
+   <table>
+           <tr>
+                   <td>{$tpl1_contents}</td>
+                   <td>{$tpl2_contents}</td>
+                   <td>{$tpl3_contents}</td>
+           </tr>
+   </table>
+
+
+
+
+   Another approach:
+
+   You could write a custom insert function to fetch your internal
+   templates:
+
+   <table>
+           <tr>
+                   <td>{insert name=fetch_tpl tpl="internal1.tpl"}</td>
+                   <td>{insert name=fetch_tpl tpl="internal2.tpl"}</td>
+                   <td>{insert name=fetch_tpl tpl="internal3.tpl"}</td>
+           </tr>
+   </table>
Index: /trunk/htdocs2/smarty/INSTALL
===================================================================
--- /trunk/htdocs2/smarty/INSTALL	(revision 298)
+++ /trunk/htdocs2/smarty/INSTALL	(revision 298)
@@ -0,0 +1,29 @@
+REQUIREMENTS:
+
+Smarty requires PHP 4.0.6 or later.
+See the on-line documentation for complete install instructions.
+
+INSTALLATION (quick):
+
+* copy the files under the libs/ directory to a directory that is in your PHP
+  include_path, or set the SMARTY_DIR constant and put them in this directory.
+  (if you upgrade from versions before 2.5.0 be aware that up to Smarty 2.4.2
+  all necessary files where in the distribution's root directory, but are now
+  in libs/.)
+
+* for each application using Smarty, create a "templates", "configs", and a
+  "templates_c" directory, be sure to set the appropriate directory settings in
+  Smarty for them. If they are located in the same directory as your
+  application, they shouldn't need to be modified. Be sure the "templates_c"
+  directory is writable by your web server user (usually nobody). chown
+  nobody:nobody templates_c; chmod 700 templates_c You can also chmod 777 this
+  directory, but be aware of security issues for multi-user systems. If you are
+  using Smarty's built-in caching, create a "cache" directory and also chown
+  nobody:nobody.
+
+* setup your php and template files. A good working example is in the on-line
+  documentation.
+
+* TECHNICAL NOTE: If you do not have access to the php.ini file, you can change
+  non-server settings (such as your include_path) with the ini_set() command.
+  example: ini_set("include_path",".:/usr/local/lib/php");
Index: /trunk/htdocs2/smarty/NEWS
===================================================================
--- /trunk/htdocs2/smarty/NEWS	(revision 298)
+++ /trunk/htdocs2/smarty/NEWS	(revision 298)
@@ -0,0 +1,1013 @@
+Version 2.6.18 (Mar 7th, 2007)
+------------------------------
+
+- fix html_select_date separator when parts are missing (hayk,
+  monte)
+- fix broken detection of non-cached blocks introduced in 2.6.17
+  (messju)
+
+Version 2.6.17 (Mar 5th, 2007)
+------------------------------
+
+- fix php handling (monte, boots, danilo)
+- fix handling of plugin tags directly followed by an else tag (Fahr, danilo)
+- fix handling of $etc in the truncate modifier when $etc is longer
+  than $length (Sylvinus, messju)
+- fix handling of %I with mysql timestamps in the date_format modifier
+  (danilo, boots)
+- update smarty_core_write_file() and smarty_modifier_date_format() to better
+  recognize Windows (boots, danilo)
+- emulate %h, %n, %r, %R, %t in the date_format modifier on Windows 
+  (danilo, boots)
+
+Version 2.6.16 (Dec 1st, 2006)
+------------------------------
+
+- fixed replacement bug in trimwhitespace output filter that was introduced
+  in the last release (Spuerhund, boots)
+
+Version 2.6.15 (Nov 30th, 2006)
+-------------------------------
+
+- change file writing semantics in smarty_core_write_file() to unlink() only
+  when rename() fails or a Windows system is detected (c960657, boots) 
+- update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug
+  output and apply a Smarty based color scheme (cybot, boots)
+- enhance reporting precision of debug_print_var modifier (cybot, boots) 
+- make html_select_date work consistently with 0000-00-00 00:00:00 and
+  0000-00-00 inputs (cybot, boots)
+- fix wrong handling of insert's name attribute. (messju)
+- fix false replacement of "$t" inside double quotes (checat, messju)
+- added support for column headings and caption element to html_table and
+  updated the output to use thead/tbody elements (boots)
+- fixed ordering of replacements in trimwhitespace output filter (Getty, boots)
+- update mailto function plugin to work around a firefox/thunderbird
+  escaping bug (elijahlofgren, boots)
+- emulate %l in the date_format modifier on windows (boots) 
+- fix handling of apostrophes in capitalize modifier (Alec Smecher, boots)
+
+Version 2.6.14 (May 28th, 2006)
+-------------------------------
+
+- fix compiler bug allowing php tags in secure templates
+  (boots,monte)
+- un-hide hidden xml open tags (boots)
+- fix handling of block-methods of registered objects (El Hombre Gris,
+  messju)
+
+Version 2.6.13 (March 9th, 2006)
+--------------------------------
+
+ - update regex_replace, removing possible use of "e" modifier
+
+Version 2.6.12 (Jan 18th, 2006)
+-------------------------------
+
+ - fix improper use of references in the compiler handling cached
+   attributes and in compiled code handling block plugins (messju)
+ - make Smarty::_read_file() work on latest php (messju)
+ - fixed improper tokenization of certain inline math expressions (boots)
+
+Version 2.6.11 (Dec 14, 2005)
+-----------------------------
+
+ - fixed code generation of non-cacheable blocks to play well with php's
+   "Alternative syntax for control structures" (kihara, messju)
+ - fix handling of multiple identical inserts in one display()-call (messju)
+ - replace {} string access with equivalent substr() to avoid E_STRICT
+   warnings in PHP 5.1 (boots)
+ - return valid reference in get_config_vars() when given var is
+   non-existant (Thomas Schulz, boots)
+ - plugin html_image: fix incorrect secure_dir error when
+   file doesn't exist (monte)
+ - plugin html_image: add path_prefix param (monte)
+ - add char_set parameter to escape modifier (Loading, monte)
+ - fix notice in debug security check (Drakla, monte)
+ - return valid reference in get_template_vars() when given var is
+   non-existant (monte)
+ - add escape type "urlpathinfo" to escape modifier (monte)
+
+Version 2.6.10 (Aug 5, 2005)
+----------------------------
+
+  - allow secure_dir to be a filename, not just
+    a directory name (monte)
+  - set debug.tpl as a secure_dir, not the entire
+    SMARTY_DIR (monte)
+  - fix proper escaping for literal strings in
+    Smarty_Compiler::_parse_var_props() (boots, messju)
+  - remove ambiguity for numeric values passed to smarty_make_timestamp()
+    (and thus the date_format modifier). numeric values are treated as
+    timestamps now. (andreas, messju)
+  - add passthru attribute feature to html_select_date (Sedgar,
+    monte)
+  - add "middle" parameter to truncate (monte)
+  - make form input label ids optional (monte)
+  - add error message for empty if/elseif statements (eykanal,
+    monte)
+  - cast selected value to string for comparison in html_radios
+    (Exeption, monte)
+  - updated html_select_date's year_as_text-feature to be xhtml compliant
+    (Mark West, messju)
+  - fix handling of selected month html_select_date (Yuri Weseman, messju)
+
+Version 2.6.9 (Mar 31, 2005)
+----------------------------
+
+  - disallow variable function calls in {if} statements (messju, monte)
+  - disallow variable function calls in {math} equations (messju, monte)
+
+Version 2.6.8 (Mar 21, 2005)
+----------------------------
+
+  - remove e-modifier from regex_replace modifier (messju)
+  - remove cast of object to array in foreach's from-attribute (messju)
+  - add "null" as a valid token for {if} when security is enabled (messju)
+  - add javascript_charcode encoding option to mailto function
+    (monte)
+  - add ids to html_radios labels (monte, menulis)
+  - fix handling of strip-tags with non-default delimiters (Mark West, messju)
+
+Version 2.6.7 (Feb 3, 2005)
+---------------------------
+
+  - fix handling of hashed opening php-tags inside strip-blocks (messju)
+  - removed border tag from html_image function (monte)
+  - change escape:url use rawurlencode() instead of urlencode() (messju)
+  - make $smarty.const.FOO compile to "FOO", and not to "constant('foo')".
+    this is less code and a little faster execution. note that undefined
+    constants are now displayed as the constant's name. (messju)
+  - make block functions and registered objects' block methods use a
+    local variable for block_content instead of a property of $smarty (messju)
+  - fix escaping in the generated code that calls smarty_core_load_plugins
+    (jes5199, messju)
+  - fix invalid HTML issue with popup (Stefanos Harhalakis,
+    Monte)
+  - fixed {popup} to properly handle inarray and function parameters and added
+    support for mouseoff and followmouse options (boots)
+
+Version 2.6.6 (Oct 13, 2004)
+----------------------------
+
+  - fixed nocache-handling with nested includes (Lars Jankowfsky, messju)
+  - moved /libs/core to /libs/internals (boots)
+  - fixed more parsing problems (messju)
+
+Version 2.6.5 (Sept 13, 2004)
+-----------------------------
+
+  - fixed some parsing problems with object calls introduced
+    in 2.6.4 (Monte)
+  - add $smarty->security_settings['ALLOW_CONSTANTS']. note: this
+    defaults to false which means you have to allow them explicitly
+    in your secured templates from now on! (messju)
+
+Version 2.6.4 (Sept 7, 2004)
+----------------------------
+
+  - add $smarty.ldelim and $smarty.rdelim to smarty special var (Monte)
+  - fall back to old uniqid()-behaviour when tempnam() fails in
+    core.write_file.php (messju)
+  - fix capitalize modifier, don't rely on buggy ucwords (Monte)
+  - make html_select_date work with negative timestamps, also
+    force year range to include given date unless explicitly
+    set (Garo, Monte)
+  - fix bug with {fetch}, passing user/pass in url did not work
+    (Monte)
+  - fix occasional wrong error messages on mismatched tags when
+    {else}, {elseif}, {foreachelse} or {sectionelse} is involved (messju)
+  - fix handling of methods arguments (messju, Manfred Wischin)
+  - remove touch() call that made the compiled-template's timestamp the
+    same as the source-template's one. (messju)
+  - add assign attribute to html_checkboxes and html_radios
+    (pcg, Monte)
+  - remove non-xhtml conformant tag from mailto function
+    (tacker, Monte)
+  - handle date_format codes %e, %T and %D for windows (tip,
+    Monte)
+  - fix unnecessary call to smarty_core_get_include_path() inside
+    Smarty::_get_auto_filename() (c960657, messju)
+  - add error-messages when anything else than an identifier is passed
+    to foreach's key- or item-attribute (messju)
+  - fix handling of digits inside tagnames (messju)
+  - fix escaping of backslashes in Smarty_Compiler::_quote_replace() (messju)
+
+Version 2.6.3 (June 16, 2004)
+-----------------------------
+
+  - added escapement of '</' to '<\/' in escape:javascript
+    modifier (c960657, Monte)
+  - added obfuscation of protocol-string in {mailto} when using hex-
+    encoding (bharat, messju)
+  - enhanced auto-generated filenames for templates_c and cache (messju)
+  - add 'nonstd' to escape modifier for escaping non-std chars,
+    such as ms doc quote (Monte)
+  - adjusted textformat to not output wrap chars after last para
+    (Monte)
+  - use tempnam() instead of unqid() to create better temporary files in
+    smarty_core_write_file() (xces, messju)
+  - add 'mail' to escape modifier for safe display of e-mail
+    addresses (Monte)
+  - add cycle function attribute "reset" to english docs (Monte)
+  - enhanced support of numeric constants as variable-expressions (messju)
+  - add case decentity to smarty_modifier_escape() (Konstantin A. Pelepelin,
+    messju)
+  - make smarty_core_write_compiled_include() php5-aware (messju)
+  - removed unused functionality to load a subset of lines from a file (messju)
+  - fix is_secure() should only check if a file is_readable, not if
+    the directory where it is in is readable (sagi, messju)
+  - fix problem displaying debug console when $default_resource_type
+    is not "file:" (c960657, Monte)
+  - fix permission handling with security and config_load (messju)
+  - removed '.' from the list of default template locations in
+    _parse_resource_name() (messju)
+  - fix avoid warning with template_exists() on an absolute paths (messju)
+  - fix parameters passed to resource's secure()-function (messju)
+  - fix handling of integer values like width and delay im
+    smarty_function_popup() (messju)
+
+Version 2.6.2 (Feb 17, 2004)
+----------------------------
+
+  - fix allow empty years, months and days in html_select_date's
+    time-attribute (messju)
+  - fix YES and NO should not be booleanized inside triple-quotes in a
+    config-file (messju)
+  - fix accidently slurped line following a triple-quoted value in a
+    config-file (messju)
+  - change default for use_sub_dirs to false (messju)
+  - fix quoting of values in smarty_function_popup() (messju)
+  - fix handling of hidden sections in Config_File (messju)
+  - add handling of resources for {config_load} (messju)
+  - fix bug when using arrays with tr_attr and td_attr in {html_table} (messju)
+  - add unit testing to cvs core (Monte)
+
+Version 2.6.1 (Jan 16, 2004)
+----------------------------
+
+  - rename $smarty->tpl_error_reporting to $smarty->error_reporting
+    (messju)
+  - fix interpretation of $smarty->security in {html_image} (messju)
+  - add caching of requested paths to _assemble_plugin_filepath() (messju)
+  - fix handling of comments inside {php}- and {literal}-blocks (messju)
+  - fix bug handling triple-quotes in config-files (BRDude, messju)
+  - change default of request_use_auto_globals to true - $_SERVER is
+    now preferred over $HTTP_SERVER_VARS (messju)
+  - re-add support for $SCRIPT_NAME (messju)
+  - reactivate $smarty->default_modifiers (messju)
+  - add cookie persistance to debug console (Monte)
+  - allow single-digit days and months without smarty_make_timestamp()
+    in html_select_date (messju)
+  - fix headers sent erroneously with cache_modified_check and fetch()
+    (wphilips, messju)
+  - fix config_file path bug (Marc Cabadas, Monte)
+  - fix 'is even by' and 'is odd by' logic (Monte)
+  - add day_empty, month_empty, year_empty and all_empty attributes to
+    html_select_date (messju)
+  - add table of explanation for {if} qualifiers in docs (boots)
+  - fix bug when comparing array-keys to "selected" in html_options
+    and html_checkboxes (messju)
+  - add better checks for correctly nested tags when compiling (messju)
+  - remove {$SCRIPT_NAME}. use {$smarty.server.SCRIPT_NAME} instead (messju)
+  - remove $global_assign. assign global variables explicitly instead (messju)
+  - fix example for count_characters in docs (boots)
+  - add section new basic syntax section "Escaping Smarty Parsing" in docs (boots)
+  - fix error handler call in config_load (boots)
+  - remove warning in debug_print_var on php-resources (messju)
+  - move function.assign.php to compiler.assign.php (messju)
+  - add property $tpl_error_reporting (messju)
+  - remove property $undefined. "null" is used literally instead (messju)
+
+Version 2.6.0 (Nov 19, 2003)
+----------------------------
+
+  - move Smarty::quote_replace() to Smarty_Compiler::_quote_replace() (messju)
+  - remove import of of attributes of {include_php} to php's namespace.
+    use $params[name] instead (messju)
+
+Version 2.6.0-RC3 (Nov 13, 2003)
+--------------------------------
+
+  - fix handling of $var.key inside [] (messju)
+  - fix handling of assign inside {insert}-tags (messju)
+  - fix handling if [...] inside triple-quotes in config-files (messju)
+  - fix handling of simple-math-operators inside modifiers (Dominik, messju)
+  - fix handling of trailing-slashes in open_basedir in
+    smarty_core_create_dir_structure() (packman, messju)
+
+Version 2.6.0-RC2 (Oct 8, 2003)
+-------------------------------
+
+  - apply modifiers only once to section-loop and foreach-from attrs (messju)
+  - remove use of _smarty_cached_paths-files (messju)
+  - remove Smarty::_plugin_implementation_exists() - use is_callable() (messju)
+  - ignore {strip}/{/strip) inside {strip}-blocks (messju)
+  - fixed removal of leading/trailing newlines in {strip}-blocks (messju)
+  - fixed proper escaping of " and ' with escape:javascript (messju)
+  - fixed bug in traversal of $smarty->plugins_dir-array. now the
+    first matching plugin is taken (messju)
+  - moved {strip} back into the compiler (messju)
+  - fixed config_load: handling of section-attribute and use of
+    multiple config-files in one template (atu, messju)
+
+Version 2.6.0-RC1 (August 11, 2003)
+-----------------------------------
+
+  - fixed status-header for cache_modified_check under cgi-sapi (messju)
+  - added optional parameter $cache_attrs to register_function() and
+    register_block(). $cache_attrs is an array containing attribute-
+    names that should be cached on calls to functions that have
+    $cacheable set to false. (messju)
+  - enabled registration of class-methods as callbacks for the register_*-
+    functions (use: array('classname', 'method_name')) as callback) (messju)
+  - added filepath caching (Monte)
+  - added optional assign-attribute to {capture}-tag (messju)
+  - added $cacheable-parameter to register_compiler_function() (messju)
+  - added $cacheable-parameter with default=true to register_function()
+    and register_block() (messju)
+  - add math speedup to core (Dominik, Monte)
+  - fix newlines for tags without template output (Monte)
+  - added config-option "request_use_auto_globals" to make auto-globals be
+    used as request vars instead of HTTP_*_VARS (messju)
+  - speed up config_load, simplify compiling (Monte)
+  - added block-methods for registered objects (Bharat Mediratta, messju)
+  - ignore one char resource names like c:foo.tpl (Monte)
+  - added default_resource_type feature (Monte)
+  - fix bug where config file starts with hidden section (boots, Monte)
+  - add discrete error checking pertaining to $cache_dir
+    and $compile_dir, their existance and writability (Monte)
+  - fixed behaviour of start=... for {counter} (messju)
+  - fixed assign for {counter} (messju)
+  - added params vdir, hdir and inner to html_table to allow looping
+    over the data in various directions (messju)
+  - allow spaces in literal tags (Paul Lockaby, Monte)
+  - speed up compiled templates, hardcode plugin filepaths
+    instead of dynamically calculate at runtime. (Monte)
+  - abstract many core components from Smarty.class.php,
+    speeding up core class instantiation (Monte)
+  - fixed bug in _create_dir_structure() when used with open_basedir-
+    restriction and relative paths (messju)
+  - use DIRECTORY_SEPARATOR exclusively, keep DIR_SEP for BC (Monte)
+  - changed "link" to "href" in html_image. "link" is still working
+    but deprecated (messju)
+  - html_image always renders an alt-tag now (default alt="") (messju)
+  - fixed assign attribute for multiple counters (messju)
+  - added simple math operators to variables (Monte)
+  - enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted')
+    as callback for register_resource() (messju);
+  - enabled array(&$obj, 'method') as callback for
+    $default_template_handler_func (messju)
+  - remove unnecessary close/open tags from compiled templates
+    (Monte)
+  - fixed errornous creation of '//' in image_path in html_image (messju)
+  - fix escapement of special chars for key vals in debug
+    console (Monte)
+  - fixed debug timing logic for config_load (Tom Sommer, Monte)
+  - all in-code doc comments converted to phpDocumentor format (Greg)
+  - moved strip from smarty core to plugin (Monte)
+  - moved config_load from smarty core to plugin (Monte)
+  - added &$repeat-parameter to block-functions (messju)
+  - enabled hex-constants in function.math.php (messju)
+  - enabled hex-constants (0x...) as function-attributes, inside if-statements
+    and as modifier-parameters (messju)
+  - fixed bug with passing $smarty as reference in Smarty.compiler.class
+    (messju)
+  - corrected output with {strip} and PHP tag newlines (Monte)
+  - added possibility to register function-callbacks as "array(&$obj, 'method)"
+    this affects register_function(), -block, -compiler_function, -modifier,
+    -prefilter, -postfilter, -outputfilter-functions() and $cache_handler_func
+    (messju)
+  - added <labels> to html_checkboxes and html_radios (Philippe, messju)
+  - added "labels"-options to turn off labels in html_checkboxes and _radios
+    (messju)
+
+Version 2.5.0 (April 11, 2003)
+------------------------------
+
+   - fixed bug with default modifier when passing integer 0
+     (Monte)
+   - change backtic syntax from $`foo` to `$foo` (Monte)
+   - recognize $foo[][] syntax inside embedded quotes without
+     backtics (Monte)
+   - name=123 is passed as an integer (not a string) to plugins now (messju)
+   - $length is now propagated to sub-values in debug_print_var (messju)
+
+Version 2.5.0-RC2 (March 26, 2003)
+----------------------------------
+
+    - made clear_cache() ignore compile_id, when clearing cache-groups (this
+      is when no $tpl_file is supplied) (messju)
+    - made onmouseout XHTML-compliant in function.popup.php (messju)
+    - applied local-var-naming-scheme to fetch() (messju)
+    - renamed $localvars to $_localvars in cache-file-handling-functions,
+      added _get_auto_id()-function (messju)
+    - swapped compile_id and cache_id in read_cache_file and write_cache_file
+      (messju)
+    - reverted patch for cache-file-handling (messju)
+    - made html_radios and html_checkboxes accept "selected" instead
+      of "checked" optionally. (messju)
+    - made compile_id ignored in clear_cache, made order of
+      auto_file_name $cache_id.$compile_id again, applied the the new
+      variable-naming-scheme for cache_file_handing functions (messju)
+    - removed notice of undefined var in _rm_auto() (messju)
+    - added warning message when an array is passed as
+      the "checked" value of html_radios (Monte)
+    - fixed errormessage in _compile_smarty_ref() (messju)
+    - updated docs for html_image "name" -> "file" (messju)
+    - fixed bug with html_options-optgroups (Nichlas Löfdahl, messju)
+    - cleaned up calls to readdir() (messju)
+    - fixed bug with passing multiple modifiers to a parameter
+      (Monte)
+    - updated docs for html_checkboxes, html_options and html_radios (messju)
+    - fixed wrong default "name" attribute for html_options (messju)
+    - html_checkboxes now expect the options as attribute "options" instead
+      of "checkboxes. html_radios expect "options" instead of "radios".
+      cleaned up indentiation (messju)
+    - fixed too greedy str_replace in trimwhitespace outputfilter (messju)
+    - html_checkboxes and html_radios passthru all unknown paramters now
+      additionally their output is now XHTML compliant (messju)
+    - html_options passthru all unknown paramters now (messju)
+    - fix link functionality of html_image, also make
+      output XHTML compatible (Hinrich Donner, Monte)
+    - append "@" to default modifier vars/args
+      supress possible warnings (Monte)
+    - fix problem with escaped double quotes (Monte)
+    - fix html_radios to not return an array (Monte)
+    - fixed length in modifier.truncate.php (messju)
+    - fixed handling of '$'-signs in trimwhitespace outputfilter (messju)
+    - fix bug that makes config files recompile every time
+      (Nagger, Monte)
+    - add dpi functionality to html_image, change "name"
+      parameter to "file" (Thomas Shulz, Monte)
+    - fix height/width parameter index in html_image (Gerard,
+      Monte)
+    - get rid of unsetting name and script attributes
+      to insert tag (Thomas Schulz, Monte)
+    - changed argument order of string_format modifier back,
+      was right in the first place (Monte)
+
+Version 2.5.0-RC1 (March 5, 2003)
+---------------------------------
+
+    - fixed notice in popup function (Nagger, Monte)
+    - fix "once" var compiling for include_php (Monte)
+    - added nl2br modifier to distribution (Monte)
+    - added html_image to distribution (Monte)
+    - added cat modifier to distribution (Monte)
+    - added html_table to distribution (Monte)
+    - added << >> <> support to if statments (SMK, Monte)
+    - fix _assign_smarty_interface to not overwrite keys
+      other than 'request' (Jerome Poudevigne, Monte)
+    - added html_checkboxes to distribution (Christopher Kvarme, Monte)
+    - added html_radios to distribution (Christopher Kvarme, Monte)
+    - fixed string_format modifier args (wrong order) (Paul
+      Lockaby, Monte)
+    - use tmp file for file writes, avoid file lock race (Monte)
+    - support syntax "$`smarty.config.foo`.tpl" for embedded
+      vars in quotes, and allow full dollar var syntax (Monte)
+    - add $smarty.config.varname variable for accessing config vars (Paul
+      Lockaby, Monte)
+    - silence PHP warnings in function.fetch.php (Eduardo,
+      Monte)
+    - added get_config_vars(), same basic functionality as
+      get_template_vars() (Monte)
+    - update get_template_vars() to be able to get
+      individual vars (Monte)
+    - fix minor logic in _fetch_template_info (Dennis Gearon,
+      Monte)
+    - fix cache groups with compile_id set (Monte)
+    - add support for merging appended vars (messju, Monte)
+    - allow null as function attribute value
+      (André Rabold, Monte)
+    - support $foo->bar[index] syntax (Monte)
+    - add get_registered_object function (messju, Monte)
+    - treat unrecognized param attribute syntax as string (Monte)
+    - support $smarty.const.$foo syntax (messju, Monte)
+    - remove E_NOTICE warnings from debug.tpl,
+      escape modifier (Kanstantin, Monte)
+    - don't count non-ascii chars in count_words modifier
+      (Kanstantin, Monte)
+    - clean up param calls to _parse_var and _parse_attrs (Monte)
+    - define $template_source var, elude possible warning
+      (Monte)
+    - fix syntax problem with evaluating PHP constants (Monte)
+    - add @ and === as valid if statement tokens (Monte)
+    - enable error messages for config_load errors,
+      use $this->config_class for loading class name (Monte)
+    - fix html_options to not escape already escaped entities (Monte)
+    - send Last-Modified header on cache creation (Monte)
+    - check strict syntax of function attributes (Monte)
+    - dropped support for modifers on object parameters,
+      added support for objects as modifier parameters (Monte)
+    - fixed bug with decimal numbers in if statements (Monte)
+
+Version 2.4.2 (Feb 11, 2003)
+----------------------------
+    - support embedded variables in objects (Monte)
+    - fix bug with objects with no properties (M Mohr, Monte)
+    - support full dollar var syntax in quoted text (Monte)
+    - fixed bug in $smarty.const.FOO introduced in 2.4.1 (M
+      Mohr, Monte)
+
+Version 2.4.1 (Feb 6, 2003)
+---------------------------
+
+    - ignore case in IF statements (Rainer Collet, Monte)
+    - treat undefined constants as null (Ferdinand Beyer, Monte)
+    - fix problem with inserts and nested fetches
+      (Rainer Collet, Monte)
+    - added support for passing params to include_php
+      (Tim Riley, Monte)
+    - added support for math operators in if statements (Monte)
+    - added support for $foo->bar[$x].blah syntax (Monte)
+
+Version 2.4.0 (Feb 2, 2003)
+---------------------------
+
+    - fix known problems with php tag handling in templates
+      (recursion, echoing xml tags) (Monte)
+    - add support for object registration (Monte)
+    - add debug template to secure_dir, add template_dir
+      to secure_dir by default (Ferdinand Beyer, Monte)
+    - added support for assigned object access (Monte)
+    - fixed bug with directories named '0' (Frank Bauer, Monte)
+    - add javascript parameter to escape modifier (Monte)
+    - added calling function line numbers to syntax error
+      messages in compiler (Monte)
+    - added support for modifiers to function calls (Monte)
+    - support return value for custom functions
+      instead of echoing (but echo still works) (Monte)
+    - added direct access to constants
+      via $smarty.const.FOO (Monte)
+    - added support for passing modifiers
+      to static values (Monte)
+    - fix up regex code in compiler, more accurate and
+      maintainable (Monte)
+    - added day_value_format to html_select_date (Marcus
+      Bointon, Monte)
+    - assigned variables are no longer in global
+      namespace, saving extract() calls and speeding
+      up fetch() and display() linearly with no. of
+      assigned variables (Monte)
+    - added trimwhitespace output filter to dist. (Monte)
+    - fix popup function to allow newlines in text (Monte)
+    - escape html entities in html_options (Monte)
+    - fixed bug with label for html_options (Monte)
+    - added config_load API function (Monte)
+    - added caching to config file loading (Monte)
+    - added "extra" parameter to mailto function (Monte,
+      Massimiliano Perantoni)
+    - added mailto plugin to dist.  (Monte)
+
+Version 2.3.1 (Nov 19, 2002)
+----------------------------
+
+    - added optgroup support to html_options (Monte, Robert
+      Amos)
+    - set mtime on compile files so they match source
+      files (Monte, Peter Bowen)
+    - added proper support for open_basedir setting
+      (Monte, Alessandro Astarita)
+    - added strip variable modifier, updated docs (Monte)
+    - fixed access to $smarty.x variables as arrays. (Andrei)
+    - fixed errors with example setup docs (Monte, Matthew
+      Hagerty)
+    - added textformat block function (Monte)
+
+Version 2.3.0 (Aug 7, 2002)
+---------------------------
+
+    - added assign_by_ref() and append_by_ref() functions
+      (Bob Silva, Monte)
+    - changed default warning type for plugin errors from
+      E_USER_WARNING to E_USER_ERROR (Monte)
+    - added $all_extra, $hour_extra, $minute_extra,
+      $second_extra and $meridian_extra parameters to
+      html_select_time function (Rainer Collet, Monte)
+    - update debug console to print objects (Simon Willison,
+      Monte)
+    - fix Config_File class to not error when there are no
+      sections (Peter Kmet, Monte)
+    - add default modifier logic (Monte)
+    - updated popup_init to be xhtml compliant (Tom Oram, Monte)
+    - fix filename bug with windows (Gary Loescher, Monte)
+    - add ability to supply expire time in seconds when clearing
+      cache or compile files (Monte)
+    - add {debug} plugin to distribution (Monte)
+    - fixed bug with insert tags, loading from "script" attribute
+      when caching is enabled (Monte)
+    - fix bug with debug_tpl file path with Windows (.SMK., Monte)
+    - fix append() function with string/array problem (Monte)
+
+Version 2.2.0 (July 11, 2002)
+-----------------------------
+
+    - make debug.tpl work with any delimiter (Monte)
+    - change logic in assign() and append() to test var names
+      against != '' instead of empty() (Monte)
+    - fix PHP notice in append() function (Monte)
+    - allow $plugins_dir to be an array of directories
+      (Andreas Kossmeier, Monte)
+    - move debug.tpl to SMARTY_DIR, add to constructor (Monte)
+    - fixed warning message in function.assign_debug_info (Monte)
+    - fixed $template_dir, $compile_dir, $cache_dir, $config_dir,
+      $plugin_dir to respect include_path (Monte)
+    - fixed warning message with output filter array (Monte)
+    - add optional 2nd parameter to date_format, used as
+      the default date if the passed date is empty (Monte)
+    - gave $reset a default value in cycle plugin (Monte)
+    - fixed warnings with html_select_date and timestamp
+      functions (Monte)
+    - added support for sub directory exlusion format (Monte)
+    - added support for grouping by cache_id, compile_id
+      and segments thereof (Monte)
+    - changed cache and compile files to human readable
+      format (Monte)
+    - remove overlib.js file from distribution (Monte)
+    - fixed bug with 304 Not Modified response sending
+      content (Monte)
+    - fixed cycle function to respect delimiter after
+      initial setting (Monte)
+    - update $GLOBALS references to work properly with
+      track_globals settings (Michal Prinke, Monte)
+    - fixed bug in math function with call to assign
+      (Grigory V. Kareev, Monte)
+    - optimized for loops with count() function calls (Monte)
+    - add month_value_format attribute to html_select_date
+      plugin (Gary Loescher, Monte)
+    - made it possible to use simple variables inside [] for
+      indexing. (Andrei)
+    - added "once" attribute to {include_php}. (Monte)
+
+Version 2.1.1
+-------------
+    - added cycle function. (Monte)
+    - fixed bug with resource testing, and include_path. (Monte)
+    - fixed a bug with register_outputfilter function. (Monte)
+
+Version 2.1.0
+-------------
+
+    - introduced output filters. (Andrei)
+    - changed the way filters are loaded, added load_filter()
+      API function and $autoload_filters variable. (Andrei)
+    - added caching logic for expire times per cache file
+      (Norbert Rocher, Monte)
+    - fixed html_select_date when field separator is "/"
+      (Roberto Berto, Monte)
+    - added YYYY-MM-DD format support to html_select_date
+      (Jan Rosier, Monte)
+    - fixed cache_lifetime logic bug, also made -1 = never
+      expire (Monte)
+    - fixed directory separator issue for Windows. (Andrei)
+    - added ability to use simple variables as array indices or
+      object properties. (Andrei)
+    - added ability to unregister pre/postfilters plugins at
+      runtime. (Andrei)
+    - added 'htmlall' attribute to escape modifier. (Monte)
+    - added template_exists() API function. (Andrei)
+    - fixed a problem with using dynamic values for 'file'
+      attribute of {include_php} tag. (Andrei)
+    - added $smarty.template variable. (Andrei)
+    - fixed several plugins that would not work if the plugin
+      directory was not the default one. (Andrei)
+    - implemented support for block functions. (Andrei)
+    - made it possible to assign variables in pre/postfilter
+      plugins. (Andrei)
+
+Version 2.0.1
+-------------
+    - rename plugin .make_timestamp.php to shared.make_timestamp.php.
+      (Monte)
+    - changed crc32() generated values, replace '-' with 'N'. (Monte)
+    - added support for +/- N syntax in html_select_date year values.
+      (Monte)
+    - fixed behavior of inserts with script attribute. (Andrei)
+    - fixed bug with $smarty.cookies and $smarty.server. (Andrei)
+    - wordwrap and indent are missing from 2.0 release, now fixed.
+      (Monte)
+    - removed show_info_header and show_info_include variables. (Monte)
+
+Version 2.0.0
+-------------
+    - added "eval" function plugin for evaluating variables as
+      templates. (Monte)
+    - removed $tpl_file_ext class variable, no longer used. (Monte)
+    - added "hex" and "hexentity" escape types to escape modifier.
+      (Monte)
+    - removed dependency on PEAR. (Andrei)
+    - update popup_init to accept src attribute. (Monte, Duncan Forrest)
+    - implemented several optimizations, speeding up Smarty
+      significantly in most cases. (Andrei,Monte)
+    - implemented plugin architecture. (Andrei)
+    - added wordwrap and indent modifiers. (Monte)
+    - added support for 'If-Modified-Since' headers for cached content.
+      (Monte)
+    - removed insert_tag_check class variable, no longer needed. (Monte)
+    - optimized cache fetches by scanning for insert tags only if they
+      exist. (Monte)
+    - fixed bugs in overlib. (Monte, Duncan Forrest)
+    - fixed a problem with compile_id usage. (Andrei)
+    - fixed problem with using assigned vars with {include_php ...}
+      filepath. (Monte)
+
+Version 1.5.2
+-------------
+    - added Smarty object as fifth argument for template resource functions.
+      (Monte)
+    - fixed a bug with incorrectly combined cache and compile id in
+      clear_cache(). (Andrei)
+    - fixed bug in smarty_make_timestamp introduced in PHP 4.1.0. (Monte)
+    - fixed bug with cached insert debug timing. (Monte)
+    - added 'script' attribute to {insert..} which specifies the script that
+      the insert function can be found in. (Andrei)
+    - added default template function handler. (Monte)
+
+Version 1.5.1
+-------------
+    - removed error message from the generic _read_file() method, the caller
+      should take care of that. (Andrei)
+    - fixed a bug with incorrectly combined cache and compile id. (Andrei)
+
+Version 1.5.0
+-------------
+    - added include_php built-in function, documented. (Monte)
+    - added trusted_dir functionality, documented. (Monte)
+    - consolidated secure_dir tests to one function. (Monte)
+    - prepended _smarty_ to variable names in fetch() class function to avoid
+      namespace conflicts. (Monte)
+    - introduced $compile_id class variable that can be used to set persistent
+      compile identifier across multiple display calls, documented. (Andrei)
+    - fixed bug with concatenated null cache and compile identifiers. (Andrei)
+    - added $smarty.section.* syntax for accessing section properties,
+      documented. (Andrei)
+    - added custom cache handling function ability, documented. (Monte)
+    - added assign attribute to include, include_php, insert, fetch, math, and
+      counter functions, documented. (Monte)
+    - fixed bug with fetch testing for local file when http address. (Monte)
+    - fixed bug with counter and skipval setting. (Monte)
+    - made {config_load ...} merge globals from each config file only once per
+      scope, thus avoiding several problems. (Andrei)
+    - added {foreach ...} tag that can be used to iterate through
+      non-sequential and associative arrays, documented. (Andrei)
+    - speeded up section property access a bit. (Andrei)
+    - removed $smarty variable from storage used by normal template variables,
+      to prevent any problems. (Andrei)
+    - fixed a bug that could cause parse error with quotes inside literal
+      blocks. (Andrei, Alexander Belonosov)
+    - added 'field_array' attribute to html_select_time function, documented.
+      (Andrei, Michael Caplan)
+    - documented {section} "max" attribute. (Monte)
+    - fixed notice message in Smarty_Compiler.class.php. (Monte)
+    - fixed bug with clear_cache introduced in 1.4.6, third parameter should
+      default to null. (Monte)
+    - updated Config_File class to support '\' path separator in OS/2. (Monte,
+      Francesco Cipriani)
+    - removed secure_ext setting (not used). (Monte)
+    - made cache reading process more efficient. (Monte)
+    - fixed bug, is_cached() now supports new 1.4.6 caching behavior. (Monte)
+    - update FAQ with mailing list Reply-To header FAQ. (Monte)
+    - supress error messages for fopen(), fix cache to regenerate if cache
+      file is not available (i.e. cluster race condition). (Monte)
+    - added index key example to QUICKSTART guide. (Monte)
+
+Version 1.4.6
+-------------
+    - fixed bug with {assign ...} when passing an empty value. (Monte)
+    - add more warning message fixes. (Monte, Tara Johnson)
+    - documentation updates. (Monte)
+    - update fetch function to give proper warning when fetching a non-readable
+      or non-existant file. (Monte)
+    - fixed problem with newline at the end of included templates (Monte, Andrei)
+    - added feature to regenerate cache if compile_check is enabled and an
+      involved template or config file gets modified. (Monte)
+    - added DEBUG execution times to included files: REQUIRES updated debug.tpl
+      file! (Monte)
+    - added support for hidden config variables that cannot be read by
+      templates. (Andrei)
+    - added execution time to DEBUG console, total and inserts. (Monte)
+    - fixed bug where DEBUG console would not appear with cached content. (Monte)
+    - added support for postfilter functions that are applied to compiled
+      template right after compilation. (Andrei)
+    - fixed the name of clear_compile_tpl() API function to clear_compiled_tpl.
+      (Andrei)
+    - added fix for removing comments so that the line numbers are reported
+      correctly in case of errors. (patch from Anders Janson)
+    - made html_options output xhtml compatible code. (Monte, Arnaud Limbourg)
+
+Version 1.4.5
+-------------
+    - update FAQ with index of questions at the top
+    - update overlib to 3.50, adjust addon code so that the overlib.js
+      file isn't modified, and not using the mini one. (Monte)
+    - added many more options to html_select_date. (Alexander Skwar, Andrei)
+    - added support for generating different compiled templates from the same
+      source template. (Hans-Peter Oeri, Andrei)
+    - modified Smarty to pass itself to insert functions as the second
+      parameter. (Andrei)
+    - modified Smarty to pass itself to prefilter functions as the second
+      parameter. (Andrei)
+    - fixed syntax error when including a non-existant template with security
+      enabled. (Monte)
+    - fixed comments handling to allow commenting out template blocks. (Andrei)
+    - implemented named capture buffers, with results accessible via
+      $smarty.capture.<name>. (Andrei)
+    - added ability to index arrays directly by numbers. (Andrei)
+    - fixed bug with SMARTY_DIR not prepended to Config_File include. (Monte)
+
+Version 1.4.4
+-------------
+    - fixed problem with including insecure templates with security enabled.
+      (Monte)
+    - numerous documentation updates. (Monte)
+    - added ENT_QUOTES to escapement of html. (Monte, Sam Beckwith)
+    - implemented access to request variables via auto-assigned $smarty
+      template variable. (Andrei)
+    - fixed a bug with parsing function arguments inside {if} tags if a comma
+      was present. (Andrei)
+    - updated debug console with config file vars. (Monte)
+    - added SMARTY_DIR constant as an alternative to relying on include_path.
+      (Monte)
+    - added popup_init and popup functions (requires overlib.js). (Monte)
+    - updated debug console with config file vars. (Monte)
+    - added debugging url control. (Monte)
+    - added 'quotes' type to escape modifier. (Monte, Mike Krus)
+    - added 'total' and 'iteration' section properties. (Andrei)
+    - added 'start', 'max', and 'step' section attributes/properties. (Andrei)
+    - fixed a bug with security checking of functions inside {if} tags.
+      (Andrei)
+    - fixed a bug in Config_File that would incorrectly booleanize values that
+      weren't really booleans. (Andrei)
+
+Version 1.4.3
+-------------
+    - added regex_replace modifier, documented. (Monte)
+    - added debugging console feature and custom function assign_debug_info,
+      documented. (Monte)
+    - added 'scope' attribute for {config_load}, 'global' is now deprecated but
+      is still supported. (Andrei)
+    - reduced template symbol table pollution by moving config array into the
+      class itself. (Andrei)
+    - fixed a bug with passing quoted arguments to modifiers inside {if}
+      statements. (Andrei, Sam Beckwith)
+    - added security features for third party template editing, documented
+      (Monte)
+    - added assign custom function, documented. (Monte)
+    - fixed bug with template header using version instead of _version. (Monte)
+    - fixed a problem with putting $ followed by numbers inside {strip} and
+      {/strip} tags. (Andrei)
+    - fixed Config_File class to allow empty config paths (defaults to current
+      directory). (Andrei)
+
+Version 1.4.2
+-------------
+    - move $version to internal variable, remove from docs. (Monte)
+    - cleaned up compiled templates global scope by moving some variables into
+      the class itself. (Andrei)
+    - fixed a bug that would not allow referring to a section in the including
+      file from the included file. (Andrei)
+    - configs directory missing from 1.4.1 release, added back in. (Monte)
+    - added windows include_path setup instructions to FAQ & QUICKSTART.
+      (Monte)
+
+Version 1.4.1
+-------------
+    - fix LOCK_EX logic for all windows platforms (Monte)
+    - fixed indexing by section properties with the new syntax. (Andrei)
+    - updated Smarty to use absolute paths when requiring/including Smarty
+      components. (Andrei, John Lim)
+
+Version 1.4.0
+-------------
+    - added {capture}{/capture} function, documented (Monte)
+    - added {counter} function, documented (Monte)
+
+Version 1.4.0b2
+---------------
+    - fixed issue in Config_File.class with referencing blank sections (Andrei)
+    - fixed problem with passing variables to included files (Andrei)
+    - fixed resource path recognition for windows (Monte)
+
+Version 1.4.0b1
+---------------
+    - added "componentized templates" tip into documentation (Monte)
+    - added {php}{/php} tags for embedding php code into templates (Monte)
+    - changed default value of $show_info_header to false (Monte)
+    - implemented '->' syntax for accessing properties of objects passed to the
+      template. (Andrei)
+    - allowed custom functions to receive Smarty object as the second
+      parameter; this can be used to dynamically change template variables, for
+      example. (Andrei)
+    - added custom compiler functions support, register_compiler_function() and
+      unregister_compiler_function() API functions. (Andrei, Ivo Jansch).
+    - updated GLOBAL_ASSIGN to take SCRIPT_NAME from HTTP_SERVER_VARS
+      instead of global variable. You can also assign several variables
+      in one shot with an array. (Monte, Roman Neuhauser)
+    - added template prefilters, register_prefilter() and
+      unregister_prefilter() API functions. (Monte)
+    - added RELEASE_NOTES file to distribution. (Monte)
+    - moved CREDITS out of manual into its own file. (Monte)
+    - added register_resource() and unregister_resource() API functions. (Monte)
+    - changed the syntax of indexing template variables, thus supporting
+      structures of arbitrary complexity; supplied fix_vars.php script to fix
+      old syntax. (Andrei)
+    - added $insert_tag_check to speed up cached pages if {insert ...} is not
+      used. (Monte)
+    - added $compiler_class variable to allow specifying a different compiler
+      class. (Andrei)
+    - changed Smarty to compile templates at runtime, allowing for arbitrary
+      template resources. (Monte)
+    - added fix for LOCK_EX under Windows and changed a couple of file
+      permissions for security. (Monte, Fernando Nunes)
+    - allow arbitrary date strings to date_format, html_select_date and
+      html_select_time (Monte)
+
+Version 1.3.2
+-------------
+    - fixed a bug that caused some nested includes to loop infinitely. (Andrei)
+    - added optional HTML header to output. (Monte)
+    - significantly improved config_load performance. (Andrei)
+    - added format attribute to math function. (Monte)
+    - added html_select_time custom function. (Andrei)
+    - fixed minor PHP warning when attempting to unset an unset variable
+      (Monte)
+    - added count_characters, count_words, count_sentences, count_paragraphs
+      modifiers (Monte)
+
+Version 1.3.1pl1
+--------------
+    - bug fix, recovered missing _syntax_error function (Monte)
+
+Version 1.3.1
+-------------
+    - document first, last, index_prev, index_next (Monte)
+    - added 'first' and 'last' section properties. (Andrei)
+    - split out compiling code to separate class for faster template execution
+      time (Monte)
+    - fixed a couple of minor PHP warnings (Monte)
+    - added and documented unregister_modifier() and unregister_function() API
+      calls. (Monte)
+    - added and documented 'fetch' and 'math' functions. (Monte)
+    - added ability to index looped variables by section properties, e.g.
+      $foo.index_prev/bar. (Andrei)
+    - added index_prev and index_next section properties. (Andrei)
+    - fixed issue with php executing in literal blocks. (Monte)
+
+Version 1.3.0
+-------------
+    - moved license from GPL to LGPL (Monte)
+    - implemented workaround for PHP "feature" that eats carriage returns
+      if the PHP tag is at the end of the line. (Andrei)
+    - removed $allow_php, added $php_handling logic (Monte)
+    - added file locking to prevent reader/writer problem. (Andrei)
+    - made Smarty catch unimplemented modifiers and custom functions and output
+      error messages during compilation instead of failing during run time.
+      (Andrei)
+    - removed short-tags at the top of the smarty scripts (Monte)
+    - added register_function() and register_modifier() API calls to make
+      registering stuff easier. (Andrei)
+    - added template results caching capability. (Monte, Andrei)
+    - added optional 'options' attribute to html_options custom function
+      that allows passing associative arrays for values/output. (Andrei)
+    - modifier arguments can now contain '|' and ':' characters inside quoted
+      strings. (Andrei)
+
+Version 1.2.2
+-------------
+    - fixed bug that would not respect nested template directories and would
+      put all compiled files into top-level one. (Andrei)
+    - fixed bug using $PHP_VERSION instead of environment var PHP_VERSION.
+      (Monte)
+    - a couple small warning fixes. (Monte)
+
+Version 1.2.1
+-------------
+    - added $compile_dir, removed $compile_dir_ext, simplified usage. (Monte)
+    - added tips & tricks chapter to documentation. (Monte)
+    - misc documentation updates. (Monte)
+
+Version 1.2.0
+-------------
+    - updated documentation (Monte)
+    - added file and line number information to syntax error messages. (Andrei)
+    - added ability to index template vars by a key. (Andrei)
+
+Version 1.1.0
+-------------
+    - misc documentation changes, official stable release
+
+Version 1.0b
+------------
+    - fixed the bug that prevented using non-array values for 'loop' attribute.
+      (Andrei)
+    - many misc documentation changes & additions (Monte)
+
+Version 1.0a
+------------
+    - fixed bug that caused templates to recompile every time (Monte)
+
+Version 1.0
+------------
+    - initial release
+
+/* vim: set et tw=64 ft=changelog: */
Index: /trunk/htdocs2/smarty/QUICK_START
===================================================================
--- /trunk/htdocs2/smarty/QUICK_START	(revision 298)
+++ /trunk/htdocs2/smarty/QUICK_START	(revision 298)
@@ -0,0 +1,103 @@
+This is a simple guide to get Smarty setup and running quickly. The online
+documentation includes a very thorough explanation of a Smarty installation.
+This guide is meant to be a quick and painless way of getting Smarty working,
+and nothing more. The guide assumes you are familiar with the UNIX system
+environment. Windows users will need to make adjustments where necessary.
+
+INSTALL SMARTY LIBRARY FILES
+
+Copy the Smarty library files to your system. In our example, we place them in
+/usr/local/lib/php/Smarty/
+
+$> cd YOUR_DOWNLOAD_DIRECTORY
+$> gtar -ztvf Smarty-2.6.7.tar.gz
+$> mkdir /usr/local/lib/php/Smarty
+$> cp -r Smarty-2.6.7/libs/* /usr/local/lib/php/Smarty
+
+You should now have the following file structure:
+
+/usr/local/lib/php/Smarty/
+                          Config_File.class.php
+                          debug.tpl
+                          internals/
+                          plugins/
+                          Smarty.class.php
+                          Smarty_Compiler.class.php
+
+
+SETUP SMARTY DIRECTORIES
+
+You will need four directories setup for Smarty to work. These files are for
+templates, compiled templates, cached templates and config files. You may or
+may not use caching or config files, but it is a good idea to set them up
+anyways. It is also recommended to place them outside of the web server
+document root. The web server PHP user will need write access to the cache and
+compile directories as well.
+
+In our example, the document root is /web/www.domain.com/docs and the
+web server username is "nobody". We will keep our Smarty files under
+/web/www.domain.com/smarty
+
+$> cd /web/www.domain.com
+$> mkdir smarty
+$> mkdir smarty/templates
+$> mkdir smarty/templates_c
+$> mkdir smarty/cache
+$> mkdir smarty/configs
+$> chown nobody:nobody smarty/templates_c
+$> chown nobody:nobody smarty/cache
+$> chmod 775 smarty/templates_c
+$> chmod 775 smarty/cache
+
+
+SETUP SMARTY PHP SCRIPTS
+
+Now we setup our application in the document root:
+
+$> cd /web/www.domain.com/docs
+$> mkdir myapp
+$> cd myapp
+$> vi index.php
+
+Edit the index.php file to look like the following:
+
+<?php
+
+// put full path to Smarty.class.php
+require('/usr/local/lib/php/Smarty/Smarty.class.php');
+$smarty = new Smarty();
+
+$smarty->template_dir = '/web/www.domain.com/smarty/templates';
+$smarty->compile_dir = '/web/www.domain.com/smarty/templates_c';
+$smarty->cache_dir = '/web/www.domain.com/smarty/cache';
+$smarty->config_dir = '/web/www.domain.com/smarty/configs';
+
+$smarty->assign('name', 'Ned');
+$smarty->display('index.tpl');
+
+?>
+
+
+SETUP SMARTY TEMPLATE
+
+$> vi /web/www.domain.com/smarty/templates/index.tpl
+
+Edit the index.tpl file with the following:
+
+<html>
+<head>
+<title>Smarty</title>
+</head>
+<body>
+Hello, {$name}!
+</body>
+</html>
+
+
+
+Now go to your new application through the web browser,
+http://www.domain.com/myapp/index.php in our example. You should see the text
+"Hello Ned!" in your browser.
+
+Once you get this far, you can continue on to the Smarty Crash Course to learn
+a few more simple things, or on to the documentation to learn it all.
Index: /trunk/htdocs2/smarty/README
===================================================================
--- /trunk/htdocs2/smarty/README	(revision 298)
+++ /trunk/htdocs2/smarty/README	(revision 298)
@@ -0,0 +1,80 @@
+NAME:
+
+    Smarty - the PHP compiling template engine
+
+VERSION: 2.6.0
+
+AUTHORS:
+    
+    Monte Ohrt <monte at ohrt dot com>
+    Andrei Zmievski <andrei@php.net>
+
+MAILING LISTS:
+
+    We have a few mailing lists. "general" for you to share your ideas or ask
+	questions, "dev" for those interested in the development efforts of Smarty,
+	and "cvs" for those that would like to track the updates made in the cvs
+	repository.
+
+    send a blank e-mail message to:
+      smarty-general-subscribe@lists.php.net (subscribe to the general list)
+      smarty-general-unsubscribe@lists.php.net (unsubscribe from the general list)
+      smarty-general-digest-subscribe@lists.php.net (subscribe to digest)
+      smarty-general-digest-unsubscribe@lists.php.net (unsubscribe from digest)
+      smarty-dev-subscribe@lists.php.net (subscribe to the dev list)
+      smarty-dev-unsubscribe@lists.php.net (unsubscribe from the dev list)
+      smarty-cvs-subscribe@lists.php.net (subscribe to the cvs list)
+      smarty-cvs-unsubscribe@lists.php.net (unsubscribe from the cvs list)
+    You can also browse the mailing list archives at
+    http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
+
+SYNOPSIS:
+
+    require("Smarty.class.php");
+
+    $smarty = new Smarty;
+
+    $smarty->assign("Title","My Homepage");
+    $smarty->assign("Names",array("John","Gary","Gregg","James"));
+
+    $smarty->display("index.tpl");
+
+
+DESCRIPTION:
+
+    What is Smarty?
+
+    Smarty is a template engine for PHP. Many other template engines for PHP
+    provide basic variable substitution and dynamic block functionality.
+    Smarty takes a step further to be a "smart" template engine, adding
+    features such as configuration files, template functions, and variable
+    modifiers, and making all of this functionality as easy as possible to
+    use for both programmers and template designers. Smarty also converts
+    the templates into PHP scripts, eliminating the need to parse the
+    templates on every invocation. This makes Smarty extremely scalable and
+    manageable for large application needs.
+
+    Some of Smarty's features:
+
+    * it is extremely fast
+    * no template parsing overhead, only compiles once.
+	* it is smart about recompiling only the template files that have
+	  changed.
+    * the template language is remarkably extensible via the plugin
+      architecture.
+    * configurable template delimiter tag syntax, so you can use
+      {}, {{}}, <!--{}-->, or whatever you like.
+    * built-in caching of template output.
+    * arbitrary template sources (filesystem, databases, etc.)
+    * template if/elseif/else/endif constructs are passed to the PHP parser,
+      so the if syntax can be as simple or as complex as you like.
+    * unlimited nesting of sections, conditionals, etc. allowed
+    * it is possible to embed PHP code right in your template files,
+      although not recommended and doubtfully needed since the engine
+      is so customizable.
+    * and many more.
+
+COPYRIGHT:
+    Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved.
+    This software is released under the GNU Lesser General Public License.
+    Please read the disclaimer at the top of the Smarty.class.php file.
Index: /trunk/htdocs2/smarty/RELEASE_NOTES
===================================================================
--- /trunk/htdocs2/smarty/RELEASE_NOTES	(revision 298)
+++ /trunk/htdocs2/smarty/RELEASE_NOTES	(revision 298)
@@ -0,0 +1,428 @@
+2.6.7
+-----
+
+Those using Smarty with security enabled: a hole was found that allowed PHP code to be executed from within a template file. This has been fixed and you are engouraged to upgrade immediately. Note that this hole does NOT affect the security of your web server or PHP applications, only the ability for someone editing a template to execute PHP code. Other changes in this release can be found in the NEWS file.
+
+2.5.0
+-----
+
+Very minor adjustments since RC2, see the NEWS file for details.
+
+2.5.0-RC2
+---------
+
+Many fixes since the RC1 release. This one is as close to production quality as
+they come, so this will be the last release before 2.5.0. The SGML documentation
+files have also been removed from the tarball. If you want them, get them from
+the CVS repository.
+
+2.5.0-RC1
+---------
+
+Release Candidate 1. All $smarty vars can now be dynamic, such as
+$smarty.get.$foo. A new class function get_function_object() gets you a
+reference to an assigned object, useful within your own custom functions.
+append() can now merge as well as append with a third optional attribute. A new
+class function get_config_vars() was added, and get_template_vars() can now be
+used to get individual vars. Full variable syntax is now supported within
+double quotes via a backtick (`) syntax. Files created by smarty are now
+written to a tmp file then renamed to avoid file lock retention. html_radios,
+html_checkboxes, html_table, html_image, nl2br functions added, see the NEWS
+file for full details.
+
+2.4.2
+-----
+Another point release. Added support for dynamic object reference syntax
+($foo->$bar), support for full variable syntax within quotes ("$foo[0].bar"),
+and other minor fixes. See the NEWS file for full details.
+
+2.4.1
+-----
+
+This is basically a point release, cleaning up a few things caught
+in the 2.4.0 release. See the NEWS file for full details.
+
+2.4.0
+-----
+
+Smarty now supports the ability to access objects within the templates. Two
+methods are available, one which closely follows Smartys conventions, and
+another that follows more traditional object syntax for those familiar with
+PHP.
+
+The internal compiling engine has also undergone some major work. The regex
+parsing was rewritten to be much more strict, more secure and more
+maintainable. Config files are now compiled, which can speed up pages quite a
+bit that use config files extensively. Assigned variables are no longer
+extracted to PHP namespace, saving an extract call for every template. There is
+now support for applying modifiers to static values and functions. You can now
+access constants with $smarty.const.VAR.  See the NEWS file for complete
+changes.
+ 
+2.3.1
+-----
+
+The mtime on compiled files will now match the source files, in the case where
+the source file may not get the current timestamp, recompiling will still work
+as expected. Proper support for open_basedir has been added, so Smarty should
+work correctly in safe mode. Added a few new features such as textformat block
+function, strip variable modifier and optgroup support for html_options. Also
+other minor bug fixes, see the Change Log.
+
+2.3.0
+-----
+
+Smarty now has a {debug} template function that brings up the debugging console
+right where {debug} is called, regardless of $debugging settings. This works a
+little different than turning on $debugging in the sense that it shows all the
+template variables available at the time {debug} is called, including local
+scope vars. It does not show the templates names however, since this
+executed during runtime of the template.
+
+You can now supply an expire time when clearing cache or compile files. This is
+mostly useful for removing stale files via the API.
+
+Plugins now stop execution upon error, instead of outputting a warning and
+continuing.
+
+Two new API functions, assign_by_ref() and append_by_ref() were added. They
+allow assigning template variables by reference. This can make a significant
+performance gain, especially if you are assigning large arrays of data. PHP 5.0
+will do this implicitly, so these functions are basically workarounds.
+
+Several misc bug fixes, see the Change Log for information.
+
+
+2.2.0
+-----
+
+Smarty now allows an array of paths for the $plugin_dir class variable. The
+directories will be searched in the order they are given, so for efficiency keep
+the most-used plugins at the top. Also, absolute paths to the plugin directories are
+more efficient than relying on the PHP include_path.
+
+Cache files can now be grouped with the cache_id. See the documentation under
+the new "Caching" section for details. compile_id also respects the same
+grouping syntax. The cache/compile file structure changed, so be sure to clear
+out all your cache and compile files when upgrading Smarty. Also if you are
+using PHP-accelerator, restart apache. I've seen some quirky things happen if
+the phpa files do not get cleared (known issue with phpa and parent
+class-member changes, so just clear 'em.)
+
+Smarty now correctly respects the PHP include_path for $template_dir, $compile_dir,
+$cache_dir, $config_dir and $plugin_dir. Be aware that relying on the
+include_path is an overhead, try to use absolute pathnames when possible
+(or relative to working directory.)
+
+Documentation has been updated and rearranged a bit. Most notably, the
+installation instructions are completely revamped, and a new Caching section
+explains Smarty's caching in detail along with the new grouping functionality.
+
+Many misc. bug fixes and enhancements, see the full ChangeLog (NEWS file) for
+details.
+
+2.1.1
+-----
+
+There was a bug with template paths and the include_path, this has been fixed.
+Also register_outputfilter() did not work, this is fixed. A new template
+function named "cycle" has been added to the distribution, nice for cycling
+through a list (or array) of values.
+
+2.1.0
+-----
+
+This release has quite a few new features and fixes. Most notable are the
+introduction of block functions, so you can write plugins that work on a block
+of text with {func}{/func} notation. Also output filters were added, so you can
+apply a function against the output of your templates. This differs from the 
+postfilter function, which works on the compiled template at compile time, and
+output filters work on the template output at runtime.
+
+Many other features and bug fixes are noted in the NEWS file.
+
+
+2.0.1
+-----
+
+This is a point release, fixing a few bugs and cleaning things up. A plugin
+was renamed, the dash "-" was removed from compiled template and cached file
+names. If you're upgrading, you might want to clear them out first.  See the
+ChangeLog for details.
+
+2.0.0
+-----
+
+This release is a huge milestone for Smarty. Most notable new things are a
+plugin architecture, removal of PEAR dependency, and optimizations that
+drastically improve the performance of Smarty in most cases.
+
+The plugin architecture allows modifiers, custom functions, compiler functions,
+prefilters, postfilters, resources, and insert functions to be added by
+simply dropping a file into the plugins directory. Once dropped in, they are
+automatically registered by the template engine. This makes user-contributed
+plugins easy to manage, as well as the internal workings of Smarty easy to
+control and customize. This new architecture depends on the __FILE__ constant,
+which contains the full path to the executing script. Some older versions of
+PHP incorrectly gave the script name and not the full filesystem path. Be sure
+your version of PHP populates __FILE__ correctly. If you use custom template
+resource functions, the format of these changed with the plugin architecture.
+Be sure to update your functions accordingly. See the template resource section
+of the documentation.
+
+The PEAR dependancy was removed from Smarty. The Config_File class that comes
+with Smarty was actually what needed PEAR for error handling which Smarty didn't
+use, but now everything is self-contained.
+
+Performance improvements are graphed on the benchmark page, you will see that
+overall performance has been sped up by as much as 80% in some cases.
+
+Smarty-cached pages now support If-Modified-Since headers, meaning that if a
+cached template page has not changed since the last request, a "304 Not
+Modified" header will be sent instead of resending the same page. This is
+disabled by default, change the setting of $cache_modified_check.
+
+
+1.5.2
+-----
+
+Mostly bug fixes, added a default template resource handler.
+
+
+1.5.1
+-----
+
+Critical bug fix release. If you use caching, you'll need to upgrade.
+
+
+1.5.0
+-----
+
+Several feature enhancements were made to this version, most notably the
+{foreach ...} command which is an alternative to {section ...} with an easier
+syntax for looping through a single array of values. Several functions were
+enhanced so that the output can be automatically assigned to a template
+variable instead of displayed (assign attribute). Cache files can now be
+controlled with a custom function as an alternative to the built-in file based
+method. Many code cleanups and bug fixed went into this release as well.
+
+
+1.4.6
+-----
+
+The behavior with caching and compile_check has been slightly enhanced. If
+caching is enabled AND compile_check is enabled, the cache will immediately get
+regenerated if _any_ involved template or config file is updated. This imposes
+a slight performance hit because it must check all the files for changes, so be
+sure to run live sites with caching enabled and compile_check disabled for best
+performance. If you update a template or config file, simply turn on
+compile_check, load the page, then turn it back off. This will update the cache
+file with the new content. This is accomplished by maintaining a list of
+included/loaded templates and config files at the beginning of the cache file.
+Therefore it is advisable to remove all cache files after upgrading to 1.4.6
+(although not absolutely necessary, old cache files will regenerate)
+
+The debug console now has script timing and array values printed. You MUST
+update your debug.tpl file with this version of Smarty. Also, the new debug.tpl
+will not work with older versions of Smarty.
+
+
+1.4.5
+-----
+
+Mostly bug fixes and minor improvements. Added compile id for separate compiled
+versions of the same script. The directory format and filename convention for
+the files in templates_c has changed, so you may want to remove all of the
+existing ones before you upgrade.
+
+
+1.4.4
+-----
+
+A few bug fixes, new section looping attributes and properties, debugging
+console function for control via URL, and overLib integration and access
+to request variables from within the template.
+
+
+1.4.3
+-----
+
+This release has a few bug fixes and several enhancements. Smarty now supports
+template security for third-party template editing. These features disallow the
+ability for someone to execute commands or PHP code from the template language.
+Smarty also now has a built-in debugging console, which is a javascript pop-up
+window that displays all the included template names and assigned variables.
+
+
+1.4.2
+-----
+
+This was mostly one bug fix with variable scoping within included templates
+and a few documentation changes and updates. See the ChangeLog file for full
+details.
+
+
+1.4.1
+-----
+
+It seems that the EX_LOCK logic from the previous release didn't fix all the
+problems with windows platforms. Hopefully this one does. It basically
+disables file locking on windows, so there is a potential that two programs
+could write over the same file at the same time, fyi.
+
+The reset is minor bug fixes, please refer to the ChangeLog file.
+
+
+1.4.0
+-----
+
+IMPORTANT NOTICE
+
+Smarty now has a new syntax for accessing elements within section loops. The
+new syntax is easier to use and nicely handles data structures of any
+complexity. Consequently, this breaks the old syntax.
+
+Here is an example of the syntax change:
+
+old syntax:
+{$sec1/sec2/sec3/customer.phone}
+
+new syntax:
+{$customer[$sec1][$sec2][$sec3].phone}
+
+The section names used to come first, followed by the variable name. Now the
+variable name always comes first, followed by the section names in brackets.
+You can access variable indexes anywhere, depending on how you passed the
+variables in.
+
+To fix your current templates, we have provided a script that will adjust the
+syntax for you. Located in misc/fix_vars.php, run this script from the the
+command line, giving each template as an argument. Be sure to use absolute
+pathnames, or pathnames relative to the executing script. Probably the easiest
+way to do this is to copy the fix_vars.php script into your template directory
+and run 'php -q fix_vars.php *.tpl' Be sure you have proper write permission,
+and backup your scripts first to be safe! The examples in the 1.4.0
+documentation have been updated to reflect the changes.
+
+cd /path/to/templates
+cp /path/to/fix_vars.php .
+find . -name "*.tpl" -exec php -q ./fix_vars.php {} \;
+
+NEW AND IMPROVED COMPILATION PROCESS
+
+Smarty 1.4.0 also has a new compilation process. Instead of compiling all the
+templates up front, it now compiles them at runtime. This has several
+advantages. First of all, there is no longer a need to have a single template
+directory. You can now have arbitrary template sources, such as multiple
+directories or even database calls. This also speeds the performance of Smarty
+when $compile_check is enabled, since it is only checking the template that is
+being executed instead of everything found in the template directory. The
+$tpl_file_ext is no longer needed, but kept for backward compatability.
+Templates can now be named anything you like with any extension.
+
+MINOR FIXES
+
+A workaround for LOCK_EX on Windows systems was added, and changed a couple of
+file permissions for better security on public servers.
+
+$show_info_header is now defaulted to false instead of true. This header causes
+problems when displaying content other than HTML, so now you must explicitly
+set this flag to true to show the header information (or change the default in
+your copy of Smarty.)
+
+Documentation is written in docbook format. I updated the docbook -> HTML
+generating software & style-sheets, and consequently the examples are no longer
+in a different background color. If anyone wants to contribute a better
+stylesheet or help with documentation, drop me a line. <monte at ohrt dot com>
+
+CHANGES/ENHANCEMENTS/UPDATES
+
+date_format, html_select_date and html_select_time used to require a unix
+timestamp as the format of the date passed into the template. Smarty is now a
+bit smarter at this. It will take a unix timestamp, a mysql timestamp, or any
+date string that is parsable by strtotime, such as 10/01/2001 or 2001-10-01,
+etc. Just give some formats a try and see what works.
+
+Smarty now has template prefilters, meaning that you can run your templates
+through custom functions before they are compiled. This is good for things like
+removing unwanted comments, keeping an eye on words or functionality people are
+putting in templates, translating XML -> HTML, etc. See the register_prefilter
+documentation for more info.
+
+Another addition are the so-called compiler functions. These are custom
+functions registered by the user that are executed at compilation time of the
+template. They can be used to inject PHP code or time-sensitive static content
+into the compiled template.
+
+The run-time custom functions are now passed the Smarty object as the second
+parameter. This can be used, for example, to assign or clear template variables
+from inside the custom function.
+
+clear_compile_dir() was added for clearing out compiled versions of your
+templates. Not something normally needed, but you may have a need for this if
+you have $compile_check set to false and you periodically update templates via
+some automated process. As of 1.4.0, uncompiled templates _always_ get
+compiled regardless of $compile_check setting, although they won't be checked
+for recompile if $compile_check is set to false.
+
+You can now refer to properties of objects assigned from PHP by using the '->'
+symbol and specifying the property name after it, e.g. $foo->bar.
+
+{php}{/php} tags were added to embed php into the templates. Not normally
+needed, but some circumstances may call for it. Check out the "componentized
+templates" tip in the documentation for an example.
+
+{capture}{/capture} and {counter} functions were added. See the documentation
+for a complete description and examples.
+
+UPGRADE NOTES
+
+The format of the files created in the $compile_dir are now a bit different.
+The compiled template filename is the template resource name url-encoded.
+Therefore, all compiled files are now in the top directory of $compile_dir.
+This was done to make way for arbitrary template resources. Each compiled
+template also has a header that states what template resource was used to
+create it. From a unix command prompt, you can use "head -2 *" to see the first
+two lines of each file.
+
+When upgrading to 1.4.0, you will want to clear out all your old files in the
+$compile_dir. If you have $compile_check set to false and the compiled template
+does not yet exist, it will compile it regardless of this setting. This way you
+can clear out the $compile_dir and not worry about setting $compile_check to
+true to get the inital compilation under way.
+
+
+1.3.2
+-----
+
+Smarty now has (an optional) header prepended to the output of the Smarty
+templates. This displays the Smarty version and the date/time when the page was
+generated. This is useful for debugging your cache routines, and purely
+informational so there is evidence that the page was generated by Smarty. Set
+$show_info_header to false to disable it.
+
+{config_load ...} performance was tuned by placing the loaded variables into a
+global array, so basically a config file is read from the file system and
+placed into a php array structure only once, no matter how many times it is
+called in any of the templates. The scope of the loaded variables has changed a
+bit as well. Variables loaded by config_load used to be treated as global
+variables, meaning that parent templates (templates that included the current
+template) could see them. Now the default behavior is such that loaded
+variables are only visible by the current template and child templates (all
+templates included after the {config_load ...} is called.) To mimic the
+original behavior, provide the attribute "global=yes" like so: {config_load
+file="mystuff.conf" global=yes}. Now when you load in mystuff.conf, the
+variables will be visible to parent templates (merged with any existing config
+variables.)
+
+A formatting attribute was added to the {math ...} function, adding the ability
+to control the format of the output. Use the same formatting syntax as the PHP
+function sprintf().
+
+{html_select_time ...} was added, a custom function that works much like
+{html_select_date ...} except it displays time elements instead of dates.
+
+A few custom modifiers were added: count_characters, count_words,
+count_sentences, count_paragraphs. All pretty self-explanatory.
+
+/* vim: set et: */
Index: /trunk/htdocs2/smarty/TODO
===================================================================
--- /trunk/htdocs2/smarty/TODO	(revision 298)
+++ /trunk/htdocs2/smarty/TODO	(revision 298)
@@ -0,0 +1,10 @@
+* handle asp style tags in $php_handler
+* fix all E_NOTICE warnings
+* make simple math easier
+* caching all but parts of the template
+* change plugins so $smarty variable always comes first
+* get cache ttl with function call
+FIX: make inserts use normal functions before plugins
+UPD: change it so that if template comes from some resource,
+     that resource stays as the default, no need to specify it
+     in includes.
Index: /trunk/htdocs2/smarty/demo/configs/test.conf
===================================================================
--- /trunk/htdocs2/smarty/demo/configs/test.conf	(revision 298)
+++ /trunk/htdocs2/smarty/demo/configs/test.conf	(revision 298)
@@ -0,0 +1,5 @@
+title = Welcome to Smarty!
+cutoff_size = 40
+
+[setup]
+bold = true
Index: /trunk/htdocs2/smarty/demo/index.php
===================================================================
--- /trunk/htdocs2/smarty/demo/index.php	(revision 298)
+++ /trunk/htdocs2/smarty/demo/index.php	(revision 298)
@@ -0,0 +1,25 @@
+<?php
+
+require '../libs/Smarty.class.php';
+
+$smarty = new Smarty;
+
+$smarty->compile_check = true;
+$smarty->debugging = true;
+
+$smarty->assign("Name","Fred Irving Johnathan Bradley Peppergill");
+$smarty->assign("FirstName",array("John","Mary","James","Henry"));
+$smarty->assign("LastName",array("Doe","Smith","Johnson","Case"));
+$smarty->assign("Class",array(array("A","B","C","D"), array("E", "F", "G", "H"),
+	  array("I", "J", "K", "L"), array("M", "N", "O", "P")));
+
+$smarty->assign("contacts", array(array("phone" => "1", "fax" => "2", "cell" => "3"),
+	  array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234")));
+
+$smarty->assign("option_values", array("NY","NE","KS","IA","OK","TX"));
+$smarty->assign("option_output", array("New York","Nebraska","Kansas","Iowa","Oklahoma","Texas"));
+$smarty->assign("option_selected", "NE");
+
+$smarty->display('index.tpl');
+
+?>
Index: /trunk/htdocs2/smarty/demo/templates/footer.tpl
===================================================================
--- /trunk/htdocs2/smarty/demo/templates/footer.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/demo/templates/footer.tpl	(revision 298)
@@ -0,0 +1,2 @@
+</BODY>
+</HTML>
Index: /trunk/htdocs2/smarty/demo/templates/header.tpl
===================================================================
--- /trunk/htdocs2/smarty/demo/templates/header.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/demo/templates/header.tpl	(revision 298)
@@ -0,0 +1,6 @@
+<HTML>
+<HEAD>
+{popup_init src="/javascripts/overlib.js"}
+<TITLE>{$title} - {$Name}</TITLE>
+</HEAD>
+<BODY bgcolor="#ffffff">
Index: /trunk/htdocs2/smarty/demo/templates/index.tpl
===================================================================
--- /trunk/htdocs2/smarty/demo/templates/index.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/demo/templates/index.tpl	(revision 298)
@@ -0,0 +1,81 @@
+{config_load file=test.conf section="setup"}
+{include file="header.tpl" title=foo}
+
+<PRE>
+
+{* bold and title are read from the config file *}
+{if #bold#}<b>{/if}
+{* capitalize the first letters of each word of the title *}
+Title: {#title#|capitalize}
+{if #bold#}</b>{/if}
+
+The current date and time is {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}
+
+The value of global assigned variable $SCRIPT_NAME is {$SCRIPT_NAME}
+
+Example of accessing server environment variable SERVER_NAME: {$smarty.server.SERVER_NAME}
+
+The value of {ldelim}$Name{rdelim} is <b>{$Name}</b>
+
+variable modifier example of {ldelim}$Name|upper{rdelim}
+
+<b>{$Name|upper}</b>
+
+
+An example of a section loop:
+
+{section name=outer loop=$FirstName}
+{if $smarty.section.outer.index is odd by 2}
+	{$smarty.section.outer.rownum} . {$FirstName[outer]} {$LastName[outer]}
+{else}
+	{$smarty.section.outer.rownum} * {$FirstName[outer]} {$LastName[outer]}
+{/if}
+{sectionelse}
+	none
+{/section}
+
+An example of section looped key values:
+
+{section name=sec1 loop=$contacts}
+	phone: {$contacts[sec1].phone}<br>
+	fax: {$contacts[sec1].fax}<br>
+	cell: {$contacts[sec1].cell}<br>
+{/section}
+<p>
+
+testing strip tags
+{strip}
+<table border=0>
+	<tr>
+		<td>
+			<A HREF="{$SCRIPT_NAME}">
+			<font color="red">This is a  test     </font>
+			</A>
+		</td>
+	</tr>
+</table>
+{/strip}
+
+</PRE>
+
+This is an example of the html_select_date function:
+
+<form>
+{html_select_date start_year=1998 end_year=2010}
+</form>
+
+This is an example of the html_select_time function:
+
+<form>
+{html_select_time use_24_hours=false}
+</form>
+
+This is an example of the html_options function:
+
+<form>
+<select name=states>
+{html_options values=$option_values selected=$option_selected output=$option_output}
+</select>
+</form>
+
+{include file="footer.tpl"}
Index: /trunk/htdocs2/smarty/libs/Config_File.class.php
===================================================================
--- /trunk/htdocs2/smarty/libs/Config_File.class.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/Config_File.class.php	(revision 298)
@@ -0,0 +1,389 @@
+<?php
+
+/**
+ * Config_File class.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @link http://smarty.php.net/
+ * @version 2.6.18
+ * @copyright Copyright: 2001-2005 New Digital Group, Inc.
+ * @author Andrei Zmievski <andrei@php.net>
+ * @access public
+ * @package Smarty
+ */
+
+/* $Id: Config_File.class.php,v 1.88 2007/03/06 10:40:06 messju Exp $ */
+
+/**
+ * Config file reading class
+ * @package Smarty
+ */
+class Config_File {
+    /**#@+
+     * Options
+     * @var boolean
+     */
+    /**
+     * Controls whether variables with the same name overwrite each other.
+     */
+    var $overwrite        =    true;
+
+    /**
+     * Controls whether config values of on/true/yes and off/false/no get
+     * converted to boolean values automatically.
+     */
+    var $booleanize        =    true;
+
+    /**
+     * Controls whether hidden config sections/vars are read from the file.
+     */
+    var $read_hidden     =    true;
+
+    /**
+     * Controls whether or not to fix mac or dos formatted newlines.
+     * If set to true, \r or \r\n will be changed to \n.
+     */
+    var $fix_newlines =    true;
+    /**#@-*/
+
+    /** @access private */
+    var $_config_path    = "";
+    var $_config_data    = array();
+    /**#@-*/
+
+    /**
+     * Constructs a new config file class.
+     *
+     * @param string $config_path (optional) path to the config files
+     */
+    function Config_File($config_path = NULL)
+    {
+        if (isset($config_path))
+            $this->set_path($config_path);
+    }
+
+
+    /**
+     * Set the path where configuration files can be found.
+     *
+     * @param string $config_path path to the config files
+     */
+    function set_path($config_path)
+    {
+        if (!empty($config_path)) {
+            if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
+                $this->_trigger_error_msg("Bad config file path '$config_path'");
+                return;
+            }
+            if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
+                $config_path .= DIRECTORY_SEPARATOR;
+            }
+
+            $this->_config_path = $config_path;
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the file, section, and variable name.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @param string $var_name (optional) variable to get info for
+     * @return string|array a value or array of values
+     */
+    function get($file_name, $section_name = NULL, $var_name = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else {
+            $file_name = $this->_config_path . $file_name;
+            if (!isset($this->_config_data[$file_name]))
+                $this->load_file($file_name, false);
+        }
+
+        if (!empty($var_name)) {
+            if (empty($section_name)) {
+                return $this->_config_data[$file_name]["vars"][$var_name];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
+                    return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
+                else
+                    return array();
+            }
+        } else {
+            if (empty($section_name)) {
+                return (array)$this->_config_data[$file_name]["vars"];
+            } else {
+                if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
+                    return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
+                else
+                    return array();
+            }
+        }
+    }
+
+
+    /**
+     * Retrieves config info based on the key.
+     *
+     * @param $file_name string config key (filename/section/var)
+     * @return string|array same as get()
+     * @uses get() retrieves information from config file and returns it
+     */
+    function &get_key($config_key)
+    {
+        list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
+        $result = &$this->get($file_name, $section_name, $var_name);
+        return $result;
+    }
+
+    /**
+     * Get all loaded config file names.
+     *
+     * @return array an array of loaded config file names
+     */
+    function get_file_names()
+    {
+        return array_keys($this->_config_data);
+    }
+
+
+    /**
+     * Get all section names from a loaded file.
+     *
+     * @param string $file_name config file to get section names from
+     * @return array an array of section names from the specified file
+     */
+    function get_section_names($file_name)
+    {
+        $file_name = $this->_config_path . $file_name;
+        if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        return array_keys($this->_config_data[$file_name]["sections"]);
+    }
+
+
+    /**
+     * Get all global or section variable names.
+     *
+     * @param string $file_name config file to get info for
+     * @param string $section_name (optional) section to get info for
+     * @return array an array of variables names from the specified file/section
+     */
+    function get_var_names($file_name, $section = NULL)
+    {
+        if (empty($file_name)) {
+            $this->_trigger_error_msg('Empty config file name');
+            return;
+        } else if (!isset($this->_config_data[$file_name])) {
+            $this->_trigger_error_msg("Unknown config file '$file_name'");
+            return;
+        }
+
+        if (empty($section))
+            return array_keys($this->_config_data[$file_name]["vars"]);
+        else
+            return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
+    }
+
+
+    /**
+     * Clear loaded config data for a certain file or all files.
+     *
+     * @param string $file_name file to clear config data for
+     */
+    function clear($file_name = NULL)
+    {
+        if ($file_name === NULL)
+            $this->_config_data = array();
+        else if (isset($this->_config_data[$file_name]))
+            $this->_config_data[$file_name] = array();
+    }
+
+
+    /**
+     * Load a configuration file manually.
+     *
+     * @param string $file_name file name to load
+     * @param boolean $prepend_path whether current config path should be
+     *                              prepended to the filename
+     */
+    function load_file($file_name, $prepend_path = true)
+    {
+        if ($prepend_path && $this->_config_path != "")
+            $config_file = $this->_config_path . $file_name;
+        else
+            $config_file = $file_name;
+
+        ini_set('track_errors', true);
+        $fp = @fopen($config_file, "r");
+        if (!is_resource($fp)) {
+            $this->_trigger_error_msg("Could not open config file '$config_file'");
+            return false;
+        }
+
+        $contents = ($size = filesize($config_file)) ? fread($fp, $size) : '';
+        fclose($fp);
+
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * Store the contents of a file manually.
+     *
+     * @param string $config_file file name of the related contents
+     * @param string $contents the file-contents to parse
+     */
+    function set_file_contents($config_file, $contents)
+    {
+        $this->_config_data[$config_file] = $this->parse_contents($contents);
+        return true;
+    }
+
+    /**
+     * parse the source of a configuration file manually.
+     *
+     * @param string $contents the file-contents to parse
+     */
+    function parse_contents($contents)
+    {
+        if($this->fix_newlines) {
+            // fix mac/dos formatted newlines
+            $contents = preg_replace('!\r\n?!', "\n", $contents);
+        }
+
+        $config_data = array();
+        $config_data['sections'] = array();
+        $config_data['vars'] = array();
+
+        /* reference to fill with data */
+        $vars =& $config_data['vars'];
+
+        /* parse file line by line */
+        preg_match_all('!^.*\r?\n?!m', $contents, $match);
+        $lines = $match[0];
+        for ($i=0, $count=count($lines); $i<$count; $i++) {
+            $line = $lines[$i];
+            if (empty($line)) continue;
+
+            if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
+                /* section found */
+                if (substr($match[1], 0, 1) == '.') {
+                    /* hidden section */
+                    if ($this->read_hidden) {
+                        $section_name = substr($match[1], 1);
+                    } else {
+                        /* break reference to $vars to ignore hidden section */
+                        unset($vars);
+                        $vars = array();
+                        continue;
+                    }
+                } else {                    
+                    $section_name = $match[1];
+                }
+                if (!isset($config_data['sections'][$section_name]))
+                    $config_data['sections'][$section_name] = array('vars' => array());
+                $vars =& $config_data['sections'][$section_name]['vars'];
+                continue;
+            }
+
+            if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
+                /* variable found */
+                $var_name = rtrim($match[1]);
+                if (strpos($match[2], '"""') === 0) {
+                    /* handle multiline-value */
+                    $lines[$i] = substr($match[2], 3);
+                    $var_value = '';
+                    while ($i<$count) {
+                        if (($pos = strpos($lines[$i], '"""')) === false) {
+                            $var_value .= $lines[$i++];
+                        } else {
+                            /* end of multiline-value */
+                            $var_value .= substr($lines[$i], 0, $pos);
+                            break;
+                        }
+                    }
+                    $booleanize = false;
+
+                } else {
+                    /* handle simple value */
+                    $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
+                    $booleanize = $this->booleanize;
+
+                }
+                $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
+            }
+            /* else unparsable line / means it is a comment / means ignore it */
+        }
+        return $config_data;
+    }
+
+    /**#@+ @access private */
+    /**
+     * @param array &$container
+     * @param string $var_name
+     * @param mixed $var_value
+     * @param boolean $booleanize determines whether $var_value is converted to
+     *                            to true/false
+     */
+    function _set_config_var(&$container, $var_name, $var_value, $booleanize)
+    {
+        if (substr($var_name, 0, 1) == '.') {
+            if (!$this->read_hidden)
+                return;
+            else
+                $var_name = substr($var_name, 1);
+        }
+
+        if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
+            $this->_trigger_error_msg("Bad variable name '$var_name'");
+            return;
+        }
+
+        if ($booleanize) {
+            if (preg_match("/^(on|true|yes)$/i", $var_value))
+                $var_value = true;
+            else if (preg_match("/^(off|false|no)$/i", $var_value))
+                $var_value = false;
+        }
+
+        if (!isset($container[$var_name]) || $this->overwrite)
+            $container[$var_name] = $var_value;
+        else {
+            settype($container[$var_name], 'array');
+            $container[$var_name][] = $var_value;
+        }
+    }
+
+    /**
+     * @uses trigger_error() creates a PHP warning/error
+     * @param string $error_msg
+     * @param integer $error_type one of
+     */
+    function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Config_File error: $error_msg", $error_type);
+    }
+    /**#@-*/
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/Smarty.class.php
===================================================================
--- /trunk/htdocs2/smarty/libs/Smarty.class.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/Smarty.class.php	(revision 298)
@@ -0,0 +1,1944 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-general-subscribe@lists.php.net
+ *
+ * @link http://smarty.php.net/
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @package Smarty
+ * @version 2.6.18
+ */
+
+/* $Id: Smarty.class.php,v 1.528 2007/03/06 10:40:06 messju Exp $ */
+
+/**
+ * DIR_SEP isn't used anymore, but third party apps might
+ */
+if(!defined('DIR_SEP')) {
+    define('DIR_SEP', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * if not defined, include_path will be used. Sets SMARTY_DIR only if user
+ * application has not already defined it.
+ */
+
+if (!defined('SMARTY_DIR')) {
+    define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+
+if (!defined('SMARTY_CORE_DIR')) {
+    define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
+}
+
+define('SMARTY_PHP_PASSTHRU',   0);
+define('SMARTY_PHP_QUOTE',      1);
+define('SMARTY_PHP_REMOVE',     2);
+define('SMARTY_PHP_ALLOW',      3);
+
+/**
+ * @package Smarty
+ */
+class Smarty
+{
+    /**#@+
+     * Smarty Configuration Section
+     */
+
+    /**
+     * The name of the directory where templates are located.
+     *
+     * @var string
+     */
+    var $template_dir    =  'templates';
+
+    /**
+     * The directory where compiled templates are located.
+     *
+     * @var string
+     */
+    var $compile_dir     =  'templates_c';
+
+    /**
+     * The directory where config files are located.
+     *
+     * @var string
+     */
+    var $config_dir      =  'configs';
+
+    /**
+     * An array of directories searched for plugins.
+     *
+     * @var array
+     */
+    var $plugins_dir     =  array('plugins');
+
+    /**
+     * If debugging is enabled, a debug console window will display
+     * when the page loads (make sure your browser allows unrequested
+     * popup windows)
+     *
+     * @var boolean
+     */
+    var $debugging       =  false;
+
+    /**
+     * When set, smarty does uses this value as error_reporting-level.
+     *
+     * @var boolean
+     */
+    var $error_reporting  =  null;
+
+    /**
+     * This is the path to the debug console template. If not set,
+     * the default one will be used.
+     *
+     * @var string
+     */
+    var $debug_tpl       =  '';
+
+    /**
+     * This determines if debugging is enable-able from the browser.
+     * <ul>
+     *  <li>NONE => no debugging control allowed</li>
+     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+     * </ul>
+     * @link http://www.foo.dom/index.php?SMARTY_DEBUG
+     * @var string
+     */
+    var $debugging_ctrl  =  'NONE';
+
+    /**
+     * This tells Smarty whether to check for recompiling or not. Recompiling
+     * does not need to happen unless a template or config file is changed.
+     * Typically you enable this during development, and disable for
+     * production.
+     *
+     * @var boolean
+     */
+    var $compile_check   =  true;
+
+    /**
+     * This forces templates to compile every time. Useful for development
+     * or debugging.
+     *
+     * @var boolean
+     */
+    var $force_compile   =  false;
+
+    /**
+     * This enables template caching.
+     * <ul>
+     *  <li>0 = no caching</li>
+     *  <li>1 = use class cache_lifetime value</li>
+     *  <li>2 = use cache_lifetime in cache file</li>
+     * </ul>
+     * @var integer
+     */
+    var $caching         =  0;
+
+    /**
+     * The name of the directory for cache files.
+     *
+     * @var string
+     */
+    var $cache_dir       =  'cache';
+
+    /**
+     * This is the number of seconds cached content will persist.
+     * <ul>
+     *  <li>0 = always regenerate cache</li>
+     *  <li>-1 = never expires</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $cache_lifetime  =  3600;
+
+    /**
+     * Only used when $caching is enabled. If true, then If-Modified-Since headers
+     * are respected with cached content, and appropriate HTTP headers are sent.
+     * This way repeated hits to a cached page do not send the entire page to the
+     * client every time.
+     *
+     * @var boolean
+     */
+    var $cache_modified_check = false;
+
+    /**
+     * This determines how Smarty handles "<?php ... ?>" tags in templates.
+     * possible values:
+     * <ul>
+     *  <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
+     *  <li>SMARTY_PHP_QUOTE    -> escape tags as entities</li>
+     *  <li>SMARTY_PHP_REMOVE   -> remove php tags</li>
+     *  <li>SMARTY_PHP_ALLOW    -> execute php tags</li>
+     * </ul>
+     *
+     * @var integer
+     */
+    var $php_handling    =  SMARTY_PHP_PASSTHRU;
+
+    /**
+     * This enables template security. When enabled, many things are restricted
+     * in the templates that normally would go unchecked. This is useful when
+     * untrusted parties are editing templates and you want a reasonable level
+     * of security. (no direct execution of PHP in templates for example)
+     *
+     * @var boolean
+     */
+    var $security       =   false;
+
+    /**
+     * This is the list of template directories that are considered secure. This
+     * is used only if {@link $security} is enabled. One directory per array
+     * element.  {@link $template_dir} is in this list implicitly.
+     *
+     * @var array
+     */
+    var $secure_dir     =   array();
+
+    /**
+     * These are the security settings for Smarty. They are used only when
+     * {@link $security} is enabled.
+     *
+     * @var array
+     */
+    var $security_settings  = array(
+                                    'PHP_HANDLING'    => false,
+                                    'IF_FUNCS'        => array('array', 'list',
+                                                               'isset', 'empty',
+                                                               'count', 'sizeof',
+                                                               'in_array', 'is_array',
+                                                               'true', 'false', 'null'),
+                                    'INCLUDE_ANY'     => false,
+                                    'PHP_TAGS'        => false,
+                                    'MODIFIER_FUNCS'  => array('count'),
+                                    'ALLOW_CONSTANTS'  => false
+                                   );
+
+    /**
+     * This is an array of directories where trusted php scripts reside.
+     * {@link $security} is disabled during their inclusion/execution.
+     *
+     * @var array
+     */
+    var $trusted_dir        = array();
+
+    /**
+     * The left delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $left_delimiter  =  '{';
+
+    /**
+     * The right delimiter used for the template tags.
+     *
+     * @var string
+     */
+    var $right_delimiter =  '}';
+
+    /**
+     * The order in which request variables are registered, similar to
+     * variables_order in php.ini E = Environment, G = GET, P = POST,
+     * C = Cookies, S = Server
+     *
+     * @var string
+     */
+    var $request_vars_order    = 'EGPCS';
+
+    /**
+     * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
+     * are uses as request-vars or $_*[]-vars. note: if
+     * request_use_auto_globals is true, then $request_vars_order has
+     * no effect, but the php-ini-value "gpc_order"
+     *
+     * @var boolean
+     */
+    var $request_use_auto_globals      = true;
+
+    /**
+     * Set this if you want different sets of compiled files for the same
+     * templates. This is useful for things like different languages.
+     * Instead of creating separate sets of templates per language, you
+     * set different compile_ids like 'en' and 'de'.
+     *
+     * @var string
+     */
+    var $compile_id            = null;
+
+    /**
+     * This tells Smarty whether or not to use sub dirs in the cache/ and
+     * templates_c/ directories. sub directories better organized, but
+     * may not work well with PHP safe mode enabled.
+     *
+     * @var boolean
+     *
+     */
+    var $use_sub_dirs          = false;
+
+    /**
+     * This is a list of the modifiers to apply to all template variables.
+     * Put each modifier in a separate array element in the order you want
+     * them applied. example: <code>array('escape:"htmlall"');</code>
+     *
+     * @var array
+     */
+    var $default_modifiers        = array();
+
+    /**
+     * This is the resource type to be used when not specified
+     * at the beginning of the resource path. examples:
+     * $smarty->display('file:index.tpl');
+     * $smarty->display('db:index.tpl');
+     * $smarty->display('index.tpl'); // will use default resource type
+     * {include file="file:index.tpl"}
+     * {include file="db:index.tpl"}
+     * {include file="index.tpl"} {* will use default resource type *}
+     *
+     * @var array
+     */
+    var $default_resource_type    = 'file';
+
+    /**
+     * The function used for cache file handling. If not set, built-in caching is used.
+     *
+     * @var null|string function name
+     */
+    var $cache_handler_func   = null;
+
+    /**
+     * This indicates which filters are automatically loaded into Smarty.
+     *
+     * @var array array of filter names
+     */
+    var $autoload_filters = array();
+
+    /**#@+
+     * @var boolean
+     */
+    /**
+     * This tells if config file vars of the same name overwrite each other or not.
+     * if disabled, same name variables are accumulated in an array.
+     */
+    var $config_overwrite = true;
+
+    /**
+     * This tells whether or not to automatically booleanize config file variables.
+     * If enabled, then the strings "on", "true", and "yes" are treated as boolean
+     * true, and "off", "false" and "no" are treated as boolean false.
+     */
+    var $config_booleanize = true;
+
+    /**
+     * This tells whether hidden sections [.foobar] are readable from the
+     * tempalates or not. Normally you would never allow this since that is
+     * the point behind hidden sections: the application can access them, but
+     * the templates cannot.
+     */
+    var $config_read_hidden = false;
+
+    /**
+     * This tells whether or not automatically fix newlines in config files.
+     * It basically converts \r (mac) or \r\n (dos) to \n
+     */
+    var $config_fix_newlines = true;
+    /**#@-*/
+
+    /**
+     * If a template cannot be found, this PHP function will be executed.
+     * Useful for creating templates on-the-fly or other special action.
+     *
+     * @var string function name
+     */
+    var $default_template_handler_func = '';
+
+    /**
+     * The file that contains the compiler class. This can a full
+     * pathname, or relative to the php_include path.
+     *
+     * @var string
+     */
+    var $compiler_file        =    'Smarty_Compiler.class.php';
+
+    /**
+     * The class used for compiling templates.
+     *
+     * @var string
+     */
+    var $compiler_class        =   'Smarty_Compiler';
+
+    /**
+     * The class used to load config vars.
+     *
+     * @var string
+     */
+    var $config_class          =   'Config_File';
+
+/**#@+
+ * END Smarty Configuration Section
+ * There should be no need to touch anything below this line.
+ * @access private
+ */
+    /**
+     * where assigned template vars are kept
+     *
+     * @var array
+     */
+    var $_tpl_vars             = array();
+
+    /**
+     * stores run-time $smarty.* vars
+     *
+     * @var null|array
+     */
+    var $_smarty_vars          = null;
+
+    /**
+     * keeps track of sections
+     *
+     * @var array
+     */
+    var $_sections             = array();
+
+    /**
+     * keeps track of foreach blocks
+     *
+     * @var array
+     */
+    var $_foreach              = array();
+
+    /**
+     * keeps track of tag hierarchy
+     *
+     * @var array
+     */
+    var $_tag_stack            = array();
+
+    /**
+     * configuration object
+     *
+     * @var Config_file
+     */
+    var $_conf_obj             = null;
+
+    /**
+     * loaded configuration settings
+     *
+     * @var array
+     */
+    var $_config               = array(array('vars'  => array(), 'files' => array()));
+
+    /**
+     * md5 checksum of the string 'Smarty'
+     *
+     * @var string
+     */
+    var $_smarty_md5           = 'f8d698aea36fcbead2b9d5359ffca76f';
+
+    /**
+     * Smarty version number
+     *
+     * @var string
+     */
+    var $_version              = '2.6.18';
+
+    /**
+     * current template inclusion depth
+     *
+     * @var integer
+     */
+    var $_inclusion_depth      = 0;
+
+    /**
+     * for different compiled templates
+     *
+     * @var string
+     */
+    var $_compile_id           = null;
+
+    /**
+     * text in URL to enable debug mode
+     *
+     * @var string
+     */
+    var $_smarty_debug_id      = 'SMARTY_DEBUG';
+
+    /**
+     * debugging information for debug console
+     *
+     * @var array
+     */
+    var $_smarty_debug_info    = array();
+
+    /**
+     * info that makes up a cache file
+     *
+     * @var array
+     */
+    var $_cache_info           = array();
+
+    /**
+     * default file permissions
+     *
+     * @var integer
+     */
+    var $_file_perms           = 0644;
+
+    /**
+     * default dir permissions
+     *
+     * @var integer
+     */
+    var $_dir_perms               = 0771;
+
+    /**
+     * registered objects
+     *
+     * @var array
+     */
+    var $_reg_objects           = array();
+
+    /**
+     * table keeping track of plugins
+     *
+     * @var array
+     */
+    var $_plugins              = array(
+                                       'modifier'      => array(),
+                                       'function'      => array(),
+                                       'block'         => array(),
+                                       'compiler'      => array(),
+                                       'prefilter'     => array(),
+                                       'postfilter'    => array(),
+                                       'outputfilter'  => array(),
+                                       'resource'      => array(),
+                                       'insert'        => array());
+
+
+    /**
+     * cache serials
+     *
+     * @var array
+     */
+    var $_cache_serials = array();
+
+    /**
+     * name of optional cache include file
+     *
+     * @var string
+     */
+    var $_cache_include = null;
+
+    /**
+     * indicate if the current code is used in a compiled
+     * include
+     *
+     * @var string
+     */
+    var $_cache_including = false;
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty()
+    {
+      $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
+                    : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
+    }
+
+    /**
+     * assigns values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to assign
+     */
+    function assign($tpl_var, $value = null)
+    {
+        if (is_array($tpl_var)){
+            foreach ($tpl_var as $key => $val) {
+                if ($key != '') {
+                    $this->_tpl_vars[$key] = $val;
+                }
+            }
+        } else {
+            if ($tpl_var != '')
+                $this->_tpl_vars[$tpl_var] = $value;
+        }
+    }
+
+    /**
+     * assigns values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to assign
+     */
+    function assign_by_ref($tpl_var, &$value)
+    {
+        if ($tpl_var != '')
+            $this->_tpl_vars[$tpl_var] = &$value;
+    }
+
+    /**
+     * appends values to template variables
+     *
+     * @param array|string $tpl_var the template variable name(s)
+     * @param mixed $value the value to append
+     */
+    function append($tpl_var, $value=null, $merge=false)
+    {
+        if (is_array($tpl_var)) {
+            // $tpl_var is an array, ignore $value
+            foreach ($tpl_var as $_key => $_val) {
+                if ($_key != '') {
+                    if(!@is_array($this->_tpl_vars[$_key])) {
+                        settype($this->_tpl_vars[$_key],'array');
+                    }
+                    if($merge && is_array($_val)) {
+                        foreach($_val as $_mkey => $_mval) {
+                            $this->_tpl_vars[$_key][$_mkey] = $_mval;
+                        }
+                    } else {
+                        $this->_tpl_vars[$_key][] = $_val;
+                    }
+                }
+            }
+        } else {
+            if ($tpl_var != '' && isset($value)) {
+                if(!@is_array($this->_tpl_vars[$tpl_var])) {
+                    settype($this->_tpl_vars[$tpl_var],'array');
+                }
+                if($merge && is_array($value)) {
+                    foreach($value as $_mkey => $_mval) {
+                        $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
+                    }
+                } else {
+                    $this->_tpl_vars[$tpl_var][] = $value;
+                }
+            }
+        }
+    }
+
+    /**
+     * appends values to template variables by reference
+     *
+     * @param string $tpl_var the template variable name
+     * @param mixed $value the referenced value to append
+     */
+    function append_by_ref($tpl_var, &$value, $merge=false)
+    {
+        if ($tpl_var != '' && isset($value)) {
+            if(!@is_array($this->_tpl_vars[$tpl_var])) {
+             settype($this->_tpl_vars[$tpl_var],'array');
+            }
+            if ($merge && is_array($value)) {
+                foreach($value as $_key => $_val) {
+                    $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
+                }
+            } else {
+                $this->_tpl_vars[$tpl_var][] = &$value;
+            }
+        }
+    }
+
+
+    /**
+     * clear the given assigned template variable.
+     *
+     * @param string $tpl_var the template variable to clear
+     */
+    function clear_assign($tpl_var)
+    {
+        if (is_array($tpl_var))
+            foreach ($tpl_var as $curr_var)
+                unset($this->_tpl_vars[$curr_var]);
+        else
+            unset($this->_tpl_vars[$tpl_var]);
+    }
+
+
+    /**
+     * Registers custom function to be used in templates
+     *
+     * @param string $function the name of the template function
+     * @param string $function_impl the name of the PHP function to register
+     */
+    function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['function'][$function] =
+            array($function_impl, null, null, false, $cacheable, $cache_attrs);
+
+    }
+
+    /**
+     * Unregisters custom function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_function($function)
+    {
+        unset($this->_plugins['function'][$function]);
+    }
+
+    /**
+     * Registers object to be used in templates
+     *
+     * @param string $object name of template object
+     * @param object &$object_impl the referenced PHP object to register
+     * @param null|array $allowed list of allowed methods (empty = all)
+     * @param boolean $smarty_args smarty argument format, else traditional
+     * @param null|array $block_functs list of methods that are block format
+     */
+    function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+    {
+        settype($allowed, 'array');
+        settype($smarty_args, 'boolean');
+        $this->_reg_objects[$object] =
+            array(&$object_impl, $allowed, $smarty_args, $block_methods);
+    }
+
+    /**
+     * Unregisters object
+     *
+     * @param string $object name of template object
+     */
+    function unregister_object($object)
+    {
+        unset($this->_reg_objects[$object]);
+    }
+
+
+    /**
+     * Registers block function to be used in templates
+     *
+     * @param string $block name of template block
+     * @param string $block_impl PHP function to register
+     */
+    function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+    {
+        $this->_plugins['block'][$block] =
+            array($block_impl, null, null, false, $cacheable, $cache_attrs);
+    }
+
+    /**
+     * Unregisters block function
+     *
+     * @param string $block name of template function
+     */
+    function unregister_block($block)
+    {
+        unset($this->_plugins['block'][$block]);
+    }
+
+    /**
+     * Registers compiler function
+     *
+     * @param string $function name of template function
+     * @param string $function_impl name of PHP function to register
+     */
+    function register_compiler_function($function, $function_impl, $cacheable=true)
+    {
+        $this->_plugins['compiler'][$function] =
+            array($function_impl, null, null, false, $cacheable);
+    }
+
+    /**
+     * Unregisters compiler function
+     *
+     * @param string $function name of template function
+     */
+    function unregister_compiler_function($function)
+    {
+        unset($this->_plugins['compiler'][$function]);
+    }
+
+    /**
+     * Registers modifier to be used in templates
+     *
+     * @param string $modifier name of template modifier
+     * @param string $modifier_impl name of PHP function to register
+     */
+    function register_modifier($modifier, $modifier_impl)
+    {
+        $this->_plugins['modifier'][$modifier] =
+            array($modifier_impl, null, null, false);
+    }
+
+    /**
+     * Unregisters modifier
+     *
+     * @param string $modifier name of template modifier
+     */
+    function unregister_modifier($modifier)
+    {
+        unset($this->_plugins['modifier'][$modifier]);
+    }
+
+    /**
+     * Registers a resource to fetch a template
+     *
+     * @param string $type name of resource
+     * @param array $functions array of functions to handle resource
+     */
+    function register_resource($type, $functions)
+    {
+        if (count($functions)==4) {
+            $this->_plugins['resource'][$type] =
+                array($functions, false);
+
+        } elseif (count($functions)==5) {
+            $this->_plugins['resource'][$type] =
+                array(array(array(&$functions[0], $functions[1])
+                            ,array(&$functions[0], $functions[2])
+                            ,array(&$functions[0], $functions[3])
+                            ,array(&$functions[0], $functions[4]))
+                      ,false);
+
+        } else {
+            $this->trigger_error("malformed function-list for '$type' in register_resource");
+
+        }
+    }
+
+    /**
+     * Unregisters a resource
+     *
+     * @param string $type name of resource
+     */
+    function unregister_resource($type)
+    {
+        unset($this->_plugins['resource'][$type]);
+    }
+
+    /**
+     * Registers a prefilter function to apply
+     * to a template before compiling
+     *
+     * @param string $function name of PHP function to register
+     */
+    function register_prefilter($function)
+    {
+    $_name = (is_array($function)) ? $function[1] : $function;
+        $this->_plugins['prefilter'][$_name]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a prefilter function
+     *
+     * @param string $function name of PHP function
+     */
+    function unregister_prefilter($function)
+    {
+        unset($this->_plugins['prefilter'][$function]);
+    }
+
+    /**
+     * Registers a postfilter function to apply
+     * to a compiled template after compilation
+     *
+     * @param string $function name of PHP function to register
+     */
+    function register_postfilter($function)
+    {
+    $_name = (is_array($function)) ? $function[1] : $function;
+        $this->_plugins['postfilter'][$_name]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters a postfilter function
+     *
+     * @param string $function name of PHP function
+     */
+    function unregister_postfilter($function)
+    {
+        unset($this->_plugins['postfilter'][$function]);
+    }
+
+    /**
+     * Registers an output filter function to apply
+     * to a template output
+     *
+     * @param string $function name of PHP function
+     */
+    function register_outputfilter($function)
+    {
+    $_name = (is_array($function)) ? $function[1] : $function;
+        $this->_plugins['outputfilter'][$_name]
+            = array($function, null, null, false);
+    }
+
+    /**
+     * Unregisters an outputfilter function
+     *
+     * @param string $function name of PHP function
+     */
+    function unregister_outputfilter($function)
+    {
+        unset($this->_plugins['outputfilter'][$function]);
+    }
+
+    /**
+     * load a filter of specified type and name
+     *
+     * @param string $type filter type
+     * @param string $name filter name
+     */
+    function load_filter($type, $name)
+    {
+        switch ($type) {
+            case 'output':
+                $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
+                require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                smarty_core_load_plugins($_params, $this);
+                break;
+
+            case 'pre':
+            case 'post':
+                if (!isset($this->_plugins[$type . 'filter'][$name]))
+                    $this->_plugins[$type . 'filter'][$name] = false;
+                break;
+        }
+    }
+
+    /**
+     * clear cached content for the given template and cache id
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id name of cache_id
+     * @param string $compile_id name of compile_id
+     * @param string $exp_time expiration time
+     * @return boolean
+     */
+    function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+    {
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        if (!isset($tpl_file))
+            $compile_id = null;
+
+        $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
+
+        if (!empty($this->cache_handler_func)) {
+            return call_user_func_array($this->cache_handler_func,
+                                  array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
+        } else {
+            $_params = array('auto_base' => $this->cache_dir,
+                            'auto_source' => $tpl_file,
+                            'auto_id' => $_auto_id,
+                            'exp_time' => $exp_time);
+            require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+            return smarty_core_rm_auto($_params, $this);
+        }
+
+    }
+
+
+    /**
+     * clear the entire contents of cache (all templates)
+     *
+     * @param string $exp_time expire time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_all_cache($exp_time = null)
+    {
+        return $this->clear_cache(null, null, null, $exp_time);
+    }
+
+
+    /**
+     * test to see if valid cache exists for this template
+     *
+     * @param string $tpl_file name of template file
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|false results of {@link _read_cache_file()}
+     */
+    function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+    {
+        if (!$this->caching)
+            return false;
+
+        if (!isset($compile_id))
+            $compile_id = $this->compile_id;
+
+        $_params = array(
+            'tpl_file' => $tpl_file,
+            'cache_id' => $cache_id,
+            'compile_id' => $compile_id
+        );
+        require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+        return smarty_core_read_cache_file($_params, $this);
+    }
+
+
+    /**
+     * clear all the assigned template variables.
+     *
+     */
+    function clear_all_assign()
+    {
+        $this->_tpl_vars = array();
+    }
+
+    /**
+     * clears compiled version of specified template resource,
+     * or all compiled template files if one is not specified.
+     * This function is for advanced use only, not normally needed.
+     *
+     * @param string $tpl_file
+     * @param string $compile_id
+     * @param string $exp_time
+     * @return boolean results of {@link smarty_core_rm_auto()}
+     */
+    function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+    {
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+        $_params = array('auto_base' => $this->compile_dir,
+                        'auto_source' => $tpl_file,
+                        'auto_id' => $compile_id,
+                        'exp_time' => $exp_time,
+                        'extensions' => array('.inc', '.php'));
+        require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
+        return smarty_core_rm_auto($_params, $this);
+    }
+
+    /**
+     * Checks whether requested template exists.
+     *
+     * @param string $tpl_file
+     * @return boolean
+     */
+    function template_exists($tpl_file)
+    {
+        $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
+        return $this->_fetch_resource_info($_params);
+    }
+
+    /**
+     * Returns an array containing template variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_template_vars($name=null)
+    {
+        if(!isset($name)) {
+            return $this->_tpl_vars;
+        } elseif(isset($this->_tpl_vars[$name])) {
+            return $this->_tpl_vars[$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;   
+        }
+    }
+
+    /**
+     * Returns an array containing config variables
+     *
+     * @param string $name
+     * @param string $type
+     * @return array
+     */
+    function &get_config_vars($name=null)
+    {
+        if(!isset($name) && is_array($this->_config[0])) {
+            return $this->_config[0]['vars'];
+        } else if(isset($this->_config[0]['vars'][$name])) {
+            return $this->_config[0]['vars'][$name];
+        } else {
+            // var non-existant, return valid reference
+            $_tmp = null;
+            return $_tmp;
+        }
+    }
+
+    /**
+     * trigger Smarty error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     */
+    function trigger_error($error_msg, $error_type = E_USER_WARNING)
+    {
+        trigger_error("Smarty error: $error_msg", $error_type);
+    }
+
+
+    /**
+     * executes & displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     */
+    function display($resource_name, $cache_id = null, $compile_id = null)
+    {
+        $this->fetch($resource_name, $cache_id, $compile_id, true);
+    }
+
+    /**
+     * executes & returns or displays the template results
+     *
+     * @param string $resource_name
+     * @param string $cache_id
+     * @param string $compile_id
+     * @param boolean $display
+     */
+    function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
+    {
+        static $_cache_info = array();
+        
+        $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
+               ? $this->error_reporting : error_reporting() & ~E_NOTICE);
+
+        if (!$this->debugging && $this->debugging_ctrl == 'URL') {
+            $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
+            if (@strstr($_query_string, $this->_smarty_debug_id)) {
+                if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
+                    // enable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', true);
+                    $this->debugging = true;
+                } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
+                    // disable debugging for this browser session
+                    @setcookie('SMARTY_DEBUG', false);
+                    $this->debugging = false;
+                } else {
+                    // enable debugging for this page
+                    $this->debugging = true;
+                }
+            } else {
+                $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
+            }
+        }
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $_debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                'filename'  => $resource_name,
+                                                'depth'     => 0);
+            $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        if (!isset($compile_id)) {
+            $compile_id = $this->compile_id;
+        }
+
+        $this->_compile_id = $compile_id;
+        $this->_inclusion_depth = 0;
+
+        if ($this->caching) {
+            // save old cache_info, initialize cache_info
+            array_push($_cache_info, $this->_cache_info);
+            $this->_cache_info = array();
+            $_params = array(
+                'tpl_file' => $resource_name,
+                'cache_id' => $cache_id,
+                'compile_id' => $compile_id,
+                'results' => null
+            );
+            require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
+            if (smarty_core_read_cache_file($_params, $this)) {
+                $_smarty_results = $_params['results'];
+                if (!empty($this->_cache_info['insert_tags'])) {
+                    $_params = array('plugins' => $this->_cache_info['insert_tags']);
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+                    $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+                }
+                if (!empty($this->_cache_info['cache_serials'])) {
+                    $_params = array('results' => $_smarty_results);
+                    require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
+                    $_smarty_results = smarty_core_process_compiled_include($_params, $this);
+                }
+
+
+                if ($display) {
+                    if ($this->debugging)
+                    {
+                        // capture time for debugging info
+                        $_params = array();
+                        require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                        $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
+                        require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                        $_smarty_results .= smarty_core_display_debug_console($_params, $this);
+                    }
+                    if ($this->cache_modified_check) {
+                        $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+                        $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+                        $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
+                        if (@count($this->_cache_info['insert_tags']) == 0
+                            && !$this->_cache_serials
+                            && $_gmt_mtime == $_last_modified_date) {
+                            if (php_sapi_name()=='cgi')
+                                header('Status: 304 Not Modified');
+                            else
+                                header('HTTP/1.1 304 Not Modified');
+
+                        } else {
+                            header('Last-Modified: '.$_gmt_mtime);
+                            echo $_smarty_results;
+                        }
+                    } else {
+                            echo $_smarty_results;
+                    }
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return true;
+                } else {
+                    error_reporting($_smarty_old_error_level);
+                    // restore initial cache_info
+                    $this->_cache_info = array_pop($_cache_info);
+                    return $_smarty_results;
+                }
+            } else {
+                $this->_cache_info['template'][$resource_name] = true;
+                if ($this->cache_modified_check && $display) {
+                    header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
+                }
+            }
+        }
+
+        // load filters that are marked as autoload
+        if (count($this->autoload_filters)) {
+            foreach ($this->autoload_filters as $_filter_type => $_filters) {
+                foreach ($_filters as $_filter) {
+                    $this->load_filter($_filter_type, $_filter);
+                }
+            }
+        }
+
+        $_smarty_compile_path = $this->_get_compile_path($resource_name);
+
+        // if we just need to display the results, don't perform output
+        // buffering - for speed
+        $_cache_including = $this->_cache_including;
+        $this->_cache_including = false;
+        if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+        } else {
+            ob_start();
+            if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+                    || $this->_compile_resource($resource_name, $_smarty_compile_path))
+            {
+                include($_smarty_compile_path);
+            }
+            $_smarty_results = ob_get_contents();
+            ob_end_clean();
+
+            foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
+                $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
+            }
+        }
+
+        if ($this->caching) {
+            $_params = array('tpl_file' => $resource_name,
+                        'cache_id' => $cache_id,
+                        'compile_id' => $compile_id,
+                        'results' => $_smarty_results);
+            require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
+            smarty_core_write_cache_file($_params, $this);
+            require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
+            $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+
+            if ($this->_cache_serials) {
+                // strip nocache-tags from output
+                $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
+                                                ,''
+                                                ,$_smarty_results);
+            }
+            // restore initial cache_info
+            $this->_cache_info = array_pop($_cache_info);
+        }
+        $this->_cache_including = $_cache_including;
+
+        if ($display) {
+            if (isset($_smarty_results)) { echo $_smarty_results; }
+            if ($this->debugging) {
+                // capture time for debugging info
+                $_params = array();
+                require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+                $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
+                require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+                echo smarty_core_display_debug_console($_params, $this);
+            }
+            error_reporting($_smarty_old_error_level);
+            return;
+        } else {
+            error_reporting($_smarty_old_error_level);
+            if (isset($_smarty_results)) { return $_smarty_results; }
+        }
+    }
+
+    /**
+     * load configuration values
+     *
+     * @param string $file
+     * @param string $section
+     * @param string $scope
+     */
+    function config_load($file, $section = null, $scope = 'global')
+    {
+        require_once($this->_get_plugin_filepath('function', 'config_load'));
+        smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
+    }
+
+    /**
+     * return a reference to a registered object
+     *
+     * @param string $name
+     * @return object
+     */
+    function &get_registered_object($name) {
+        if (!isset($this->_reg_objects[$name]))
+        $this->_trigger_fatal_error("'$name' is not a registered object");
+
+        if (!is_object($this->_reg_objects[$name][0]))
+        $this->_trigger_fatal_error("registered '$name' is not an object");
+
+        return $this->_reg_objects[$name][0];
+    }
+
+    /**
+     * clear configuration values
+     *
+     * @param string $var
+     */
+    function clear_config($var = null)
+    {
+        if(!isset($var)) {
+            // clear all values
+            $this->_config = array(array('vars'  => array(),
+                                         'files' => array()));
+        } else {
+            unset($this->_config[0]['vars'][$var]);
+        }
+    }
+
+    /**
+     * get filepath of requested plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @return string|false
+     */
+    function _get_plugin_filepath($type, $name)
+    {
+        $_params = array('type' => $type, 'name' => $name);
+        require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
+        return smarty_core_assemble_plugin_filepath($_params, $this);
+    }
+
+   /**
+     * test if resource needs compiling
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _is_compiled($resource_name, $compile_path)
+    {
+        if (!$this->force_compile && file_exists($compile_path)) {
+            if (!$this->compile_check) {
+                // no need to check compiled file
+                return true;
+            } else {
+                // get file source and timestamp
+                $_params = array('resource_name' => $resource_name, 'get_source'=>false);
+                if (!$this->_fetch_resource_info($_params)) {
+                    return false;
+                }
+                if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
+                    // template not expired, no recompile
+                    return true;
+                } else {
+                    // compile template
+                    return false;
+                }
+            }
+        } else {
+            // compiled template does not exist, or forced compile
+            return false;
+        }
+    }
+
+   /**
+     * compile the template
+     *
+     * @param string $resource_name
+     * @param string $compile_path
+     * @return boolean
+     */
+    function _compile_resource($resource_name, $compile_path)
+    {
+
+        $_params = array('resource_name' => $resource_name);
+        if (!$this->_fetch_resource_info($_params)) {
+            return false;
+        }
+
+        $_source_content = $_params['source_content'];
+        $_cache_include    = substr($compile_path, 0, -4).'.inc';
+
+        if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
+            // if a _cache_serial was set, we also have to write an include-file:
+            if ($this->_cache_include_info) {
+                require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
+                smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)),  $this);
+            }
+
+            $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $this);
+
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+   /**
+     * compile the given source
+     *
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return boolean
+     */
+    function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
+    {
+        if (file_exists(SMARTY_DIR . $this->compiler_file)) {
+            require_once(SMARTY_DIR . $this->compiler_file);
+        } else {
+            // use include_path
+            require_once($this->compiler_file);
+        }
+
+
+        $smarty_compiler = new $this->compiler_class;
+
+        $smarty_compiler->template_dir      = $this->template_dir;
+        $smarty_compiler->compile_dir       = $this->compile_dir;
+        $smarty_compiler->plugins_dir       = $this->plugins_dir;
+        $smarty_compiler->config_dir        = $this->config_dir;
+        $smarty_compiler->force_compile     = $this->force_compile;
+        $smarty_compiler->caching           = $this->caching;
+        $smarty_compiler->php_handling      = $this->php_handling;
+        $smarty_compiler->left_delimiter    = $this->left_delimiter;
+        $smarty_compiler->right_delimiter   = $this->right_delimiter;
+        $smarty_compiler->_version          = $this->_version;
+        $smarty_compiler->security          = $this->security;
+        $smarty_compiler->secure_dir        = $this->secure_dir;
+        $smarty_compiler->security_settings = $this->security_settings;
+        $smarty_compiler->trusted_dir       = $this->trusted_dir;
+        $smarty_compiler->use_sub_dirs      = $this->use_sub_dirs;
+        $smarty_compiler->_reg_objects      = &$this->_reg_objects;
+        $smarty_compiler->_plugins          = &$this->_plugins;
+        $smarty_compiler->_tpl_vars         = &$this->_tpl_vars;
+        $smarty_compiler->default_modifiers = $this->default_modifiers;
+        $smarty_compiler->compile_id        = $this->_compile_id;
+        $smarty_compiler->_config            = $this->_config;
+        $smarty_compiler->request_use_auto_globals  = $this->request_use_auto_globals;
+
+        if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
+            $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
+        }
+        $smarty_compiler->_cache_include = $cache_include_path;
+
+
+        $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
+
+        if ($smarty_compiler->_cache_serial) {
+            $this->_cache_include_info = array(
+                'cache_serial'=>$smarty_compiler->_cache_serial
+                ,'plugins_code'=>$smarty_compiler->_plugins_code
+                ,'include_file_path' => $cache_include_path);
+
+        } else {
+            $this->_cache_include_info = null;
+
+        }
+
+        return $_results;
+    }
+
+    /**
+     * Get the compile path for this resource
+     *
+     * @param string $resource_name
+     * @return string results of {@link _get_auto_filename()}
+     */
+    function _get_compile_path($resource_name)
+    {
+        return $this->_get_auto_filename($this->compile_dir, $resource_name,
+                                         $this->_compile_id) . '.php';
+    }
+
+    /**
+     * fetch the template info. Gets timestamp, and source
+     * if get_source is true
+     *
+     * sets $source_content to the source of the template, and
+     * $resource_timestamp to its time stamp
+     * @param string $resource_name
+     * @param string $source_content
+     * @param integer $resource_timestamp
+     * @param boolean $get_source
+     * @param boolean $quiet
+     * @return boolean
+     */
+
+    function _fetch_resource_info(&$params)
+    {
+        if(!isset($params['get_source'])) { $params['get_source'] = true; }
+        if(!isset($params['quiet'])) { $params['quiet'] = false; }
+
+        $_return = false;
+        $_params = array('resource_name' => $params['resource_name']) ;
+        if (isset($params['resource_base_path']))
+            $_params['resource_base_path'] = $params['resource_base_path'];
+        else
+            $_params['resource_base_path'] = $this->template_dir;
+
+        if ($this->_parse_resource_name($_params)) {
+            $_resource_type = $_params['resource_type'];
+            $_resource_name = $_params['resource_name'];
+            switch ($_resource_type) {
+                case 'file':
+                    if ($params['get_source']) {
+                        $params['source_content'] = $this->_read_file($_resource_name);
+                    }
+                    $params['resource_timestamp'] = filemtime($_resource_name);
+                    $_return = is_file($_resource_name);
+                    break;
+
+                default:
+                    // call resource functions to fetch the template source and timestamp
+                    if ($params['get_source']) {
+                        $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                            call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
+                                                 array($_resource_name, &$params['source_content'], &$this));
+                    } else {
+                        $_source_return = true;
+                    }
+
+                    $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
+                        call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
+                                             array($_resource_name, &$params['resource_timestamp'], &$this));
+
+                    $_return = $_source_return && $_timestamp_return;
+                    break;
+            }
+        }
+
+        if (!$_return) {
+            // see if we can get a template with the default template handler
+            if (!empty($this->default_template_handler_func)) {
+                if (!is_callable($this->default_template_handler_func)) {
+                    $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
+                } else {
+                    $_return = call_user_func_array(
+                        $this->default_template_handler_func,
+                        array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
+                }
+            }
+        }
+
+        if (!$_return) {
+            if (!$params['quiet']) {
+                $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
+            }
+        } else if ($_return && $this->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+            if (!smarty_core_is_secure($_params, $this)) {
+                if (!$params['quiet'])
+                    $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
+                $params['source_content'] = null;
+                $params['resource_timestamp'] = null;
+                return false;
+            }
+        }
+        return $_return;
+    }
+
+
+    /**
+     * parse out the type and name from the resource
+     *
+     * @param string $resource_base_path
+     * @param string $resource_name
+     * @param string $resource_type
+     * @param string $resource_name
+     * @return boolean
+     */
+
+    function _parse_resource_name(&$params)
+    {
+
+        // split tpl_path by the first colon
+        $_resource_name_parts = explode(':', $params['resource_name'], 2);
+
+        if (count($_resource_name_parts) == 1) {
+            // no resource type given
+            $params['resource_type'] = $this->default_resource_type;
+            $params['resource_name'] = $_resource_name_parts[0];
+        } else {
+            if(strlen($_resource_name_parts[0]) == 1) {
+                // 1 char is not resource type, but part of filepath
+                $params['resource_type'] = $this->default_resource_type;
+                $params['resource_name'] = $params['resource_name'];
+            } else {
+                $params['resource_type'] = $_resource_name_parts[0];
+                $params['resource_name'] = $_resource_name_parts[1];
+            }
+        }
+
+        if ($params['resource_type'] == 'file') {
+            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
+                // relative pathname to $params['resource_base_path']
+                // use the first directory where the file is found
+                foreach ((array)$params['resource_base_path'] as $_curr_path) {
+                    $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
+                    if (file_exists($_fullpath) && is_file($_fullpath)) {
+                        $params['resource_name'] = $_fullpath;
+                        return true;
+                    }
+                    // didn't find the file, try include_path
+                    $_params = array('file_path' => $_fullpath);
+                    require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                    if(smarty_core_get_include_path($_params, $this)) {
+                        $params['resource_name'] = $_params['new_file_path'];
+                        return true;
+                    }
+                }
+                return false;
+            } else {
+                /* absolute path */
+                return file_exists($params['resource_name']);
+            }
+        } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
+            $_params = array('type' => $params['resource_type']);
+            require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
+            smarty_core_load_resource_plugin($_params, $this);
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Handle modifiers
+     *
+     * @param string|null $modifier_name
+     * @param array|null $map_array
+     * @return string result of modifiers
+     */
+    function _run_mod_handler()
+    {
+        $_args = func_get_args();
+        list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
+        list($_func_name, $_tpl_file, $_tpl_line) =
+            $this->_plugins['modifier'][$_modifier_name];
+
+        $_var = $_args[0];
+        foreach ($_var as $_key => $_val) {
+            $_args[0] = $_val;
+            $_var[$_key] = call_user_func_array($_func_name, $_args);
+        }
+        return $_var;
+    }
+
+    /**
+     * Remove starting and ending quotes from the string
+     *
+     * @param string $string
+     * @return string
+     */
+    function _dequote($string)
+    {
+        if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
+            substr($string, -1) == substr($string, 0, 1))
+            return substr($string, 1, -1);
+        else
+            return $string;
+    }
+
+
+    /**
+     * read in a file
+     *
+     * @param string $filename
+     * @return string
+     */
+    function _read_file($filename)
+    {
+        if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) {
+            $contents = '';
+            while (!feof($fd)) {
+                $contents .= fread($fd, 8192);
+            }
+            fclose($fd);
+            return $contents;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * get a concrete filename for automagically created content
+     *
+     * @param string $auto_base
+     * @param string $auto_source
+     * @param string $auto_id
+     * @return string
+     * @staticvar string|null
+     * @staticvar string|null
+     */
+    function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
+    {
+        $_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
+        $_return = $auto_base . DIRECTORY_SEPARATOR;
+
+        if(isset($auto_id)) {
+            // make auto_id safe for directory names
+            $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
+            // split into separate directories
+            $_return .= $auto_id . $_compile_dir_sep;
+        }
+
+        if(isset($auto_source)) {
+            // make source name safe for filename
+            $_filename = urlencode(basename($auto_source));
+            $_crc32 = sprintf('%08X', crc32($auto_source));
+            // prepend %% to avoid name conflicts with
+            // with $params['auto_id'] names
+            $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
+                      substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
+            $_return .= '%%' . $_crc32 . '%%' . $_filename;
+        }
+
+        return $_return;
+    }
+
+    /**
+     * unlink a file, possibly using expiration time
+     *
+     * @param string $resource
+     * @param integer $exp_time
+     */
+    function _unlink($resource, $exp_time = null)
+    {
+        if(isset($exp_time)) {
+            if(time() - @filemtime($resource) >= $exp_time) {
+                return @unlink($resource);
+            }
+        } else {
+            return @unlink($resource);
+        }
+    }
+
+    /**
+     * returns an auto_id for auto-file-functions
+     *
+     * @param string $cache_id
+     * @param string $compile_id
+     * @return string|null
+     */
+    function _get_auto_id($cache_id=null, $compile_id=null) {
+    if (isset($cache_id))
+        return (isset($compile_id)) ? $cache_id . '|' . $compile_id  : $cache_id;
+    elseif(isset($compile_id))
+        return $compile_id;
+    else
+        return null;
+    }
+
+    /**
+     * trigger Smarty plugin error
+     *
+     * @param string $error_msg
+     * @param string $tpl_file
+     * @param integer $tpl_line
+     * @param string $file
+     * @param integer $line
+     * @param integer $error_type
+     */
+    function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
+            $file = null, $line = null, $error_type = E_USER_ERROR)
+    {
+        if(isset($file) && isset($line)) {
+            $info = ' ('.basename($file).", line $line)";
+        } else {
+            $info = '';
+        }
+        if (isset($tpl_line) && isset($tpl_file)) {
+            $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
+        } else {
+            $this->trigger_error($error_msg . $info, $error_type);
+        }
+    }
+
+
+    /**
+     * callback function for preg_replace, to call a non-cacheable block
+     * @return string
+     */
+    function _process_compiled_include_callback($match) {
+        $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
+        ob_start();
+        $_func($this);
+        $_ret = ob_get_contents();
+        ob_end_clean();
+        return $_ret;
+    }
+
+
+    /**
+     * called for included templates
+     *
+     * @param string $_smarty_include_tpl_file
+     * @param string $_smarty_include_vars
+     */
+
+    // $_smarty_include_tpl_file, $_smarty_include_vars
+
+    function _smarty_include($params)
+    {
+        if ($this->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $debug_start_time = smarty_core_get_microtime($_params, $this);
+            $this->_smarty_debug_info[] = array('type'      => 'template',
+                                                  'filename'  => $params['smarty_include_tpl_file'],
+                                                  'depth'     => ++$this->_inclusion_depth);
+            $included_tpls_idx = count($this->_smarty_debug_info) - 1;
+        }
+
+        $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
+
+        // config vars are treated as local, so push a copy of the
+        // current ones onto the front of the stack
+        array_unshift($this->_config, $this->_config[0]);
+
+        $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
+
+
+        if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
+            || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
+        {
+            include($_smarty_compile_path);
+        }
+
+        // pop the local vars off the front of the stack
+        array_shift($this->_config);
+
+        $this->_inclusion_depth--;
+
+        if ($this->debugging) {
+            // capture time for debugging info
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
+        }
+
+        if ($this->caching) {
+            $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
+        }
+    }
+
+
+    /**
+     * get or set an array of cached attributes for function that is
+     * not cacheable
+     * @return array
+     */
+    function &_smarty_cache_attrs($cache_serial, $count) {
+        $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
+
+        if ($this->_cache_including) {
+            /* return next set of cache_attrs */
+            $_return = current($_cache_attrs);
+            next($_cache_attrs);
+            return $_return;
+
+        } else {
+            /* add a reference to a new set of cache_attrs */
+            $_cache_attrs[] = array();
+            return $_cache_attrs[count($_cache_attrs)-1];
+
+        }
+
+    }
+
+
+    /**
+     * wrapper for include() retaining $this
+     * @return mixed
+     */
+    function _include($filename, $once=false, $params=null)
+    {
+        if ($once) {
+            return include_once($filename);
+        } else {
+            return include($filename);
+        }
+    }
+
+
+    /**
+     * wrapper for eval() retaining $this
+     * @return mixed
+     */
+    function _eval($code, $params=null)
+    {
+        return eval($code);
+    }
+    /**#@-*/
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/Smarty_Compiler.class.php
===================================================================
--- /trunk/htdocs2/smarty/libs/Smarty_Compiler.class.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/Smarty_Compiler.class.php	(revision 298)
@@ -0,0 +1,2327 @@
+<?php
+
+/**
+ * Project:     Smarty: the PHP compiling template engine
+ * File:        Smarty_Compiler.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @link http://smarty.php.net/
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @version 2.6.18
+ * @copyright 2001-2005 New Digital Group, Inc.
+ * @package Smarty
+ */
+
+/* $Id: Smarty_Compiler.class.php,v 1.395 2007/03/06 10:40:06 messju Exp $ */
+
+/**
+ * Template compiling class
+ * @package Smarty
+ */
+class Smarty_Compiler extends Smarty {
+
+    // internal vars
+    /**#@+
+     * @access private
+     */
+    var $_folded_blocks         =   array();    // keeps folded template blocks
+    var $_current_file          =   null;       // the current template being compiled
+    var $_current_line_no       =   1;          // line number for error messages
+    var $_capture_stack         =   array();    // keeps track of nested capture buffers
+    var $_plugin_info           =   array();    // keeps track of plugins to load
+    var $_init_smarty_vars      =   false;
+    var $_permitted_tokens      =   array('true','false','yes','no','on','off','null');
+    var $_db_qstr_regexp        =   null;        // regexps are setup in the constructor
+    var $_si_qstr_regexp        =   null;
+    var $_qstr_regexp           =   null;
+    var $_func_regexp           =   null;
+    var $_reg_obj_regexp        =   null;
+    var $_var_bracket_regexp    =   null;
+    var $_num_const_regexp      =   null;
+    var $_dvar_guts_regexp      =   null;
+    var $_dvar_regexp           =   null;
+    var $_cvar_regexp           =   null;
+    var $_svar_regexp           =   null;
+    var $_avar_regexp           =   null;
+    var $_mod_regexp            =   null;
+    var $_var_regexp            =   null;
+    var $_parenth_param_regexp  =   null;
+    var $_func_call_regexp      =   null;
+    var $_obj_ext_regexp        =   null;
+    var $_obj_start_regexp      =   null;
+    var $_obj_params_regexp     =   null;
+    var $_obj_call_regexp       =   null;
+    var $_cacheable_state       =   0;
+    var $_cache_attrs_count     =   0;
+    var $_nocache_count         =   0;
+    var $_cache_serial          =   null;
+    var $_cache_include         =   null;
+
+    var $_strip_depth           =   0;
+    var $_additional_newline    =   "\n";
+
+    /**#@-*/
+    /**
+     * The class constructor.
+     */
+    function Smarty_Compiler()
+    {
+        // matches double quoted strings:
+        // "foobar"
+        // "foo\"bar"
+        $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
+
+        // matches single quoted strings:
+        // 'foobar'
+        // 'foo\'bar'
+        $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
+
+        // matches single or double quoted strings
+        $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
+
+        // matches bracket portion of vars
+        // [0]
+        // [foo]
+        // [$bar]
+        $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
+
+        // matches numerical constants
+        // 30
+        // -12
+        // 13.22
+        $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)';
+
+        // matches $ vars (not objects):
+        // $foo
+        // $foo.bar
+        // $foo.bar.foobar
+        // $foo[0]
+        // $foo[$bar]
+        // $foo[5][blah]
+        // $foo[5].bar[$foobar][4]
+        $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))';
+        $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
+        $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
+                . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?';
+        $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
+
+        // matches config vars:
+        // #foo#
+        // #foobar123_foo#
+        $this->_cvar_regexp = '\#\w+\#';
+
+        // matches section vars:
+        // %foo.bar%
+        $this->_svar_regexp = '\%\w+\.\w+\%';
+
+        // matches all valid variables (no quotes, no modifiers)
+        $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
+           . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
+
+        // matches valid variable syntax:
+        // $foo
+        // $foo
+        // #foo#
+        // #foo#
+        // "text"
+        // "text"
+        $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
+
+        // matches valid object call (one level of object nesting allowed in parameters):
+        // $foo->bar
+        // $foo->bar()
+        // $foo->bar("text")
+        // $foo->bar($foo, $bar, "text")
+        // $foo->bar($foo, "foo")
+        // $foo->bar->foo()
+        // $foo->bar->foo->bar()
+        // $foo->bar($foo->bar)
+        // $foo->bar($foo->bar())
+        // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar))
+        $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
+        $this->_obj_restricted_param_regexp = '(?:'
+                . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')'
+                . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)';
+        $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)';
+        $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp
+                . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)';
+        $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
+        $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)';
+        
+        // matches valid modifier syntax:
+        // |foo
+        // |@foo
+        // |foo:"bar"
+        // |foo:$bar
+        // |foo:"bar":$foobar
+        // |foo|bar
+        // |foo:$foo->bar
+        $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|'
+           . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
+
+        // matches valid function name:
+        // foo123
+        // _foo_bar
+        $this->_func_regexp = '[a-zA-Z_]\w*';
+
+        // matches valid registered object:
+        // foo->bar
+        $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
+
+        // matches valid parameter values:
+        // true
+        // $foo
+        // $foo|bar
+        // #foo#
+        // #foo#|bar
+        // "text"
+        // "text"|bar
+        // $foo->bar
+        $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
+           . $this->_var_regexp . '|' . $this->_num_const_regexp  . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
+
+        // matches valid parenthesised function parameters:
+        //
+        // "text"
+        //    $foo, $bar, "text"
+        // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
+        $this->_parenth_param_regexp = '(?:\((?:\w+|'
+                . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+                . $this->_param_regexp . ')))*)?\))';
+
+        // matches valid function call:
+        // foo()
+        // foo_bar($foo)
+        // _foo_bar($foo,"bar")
+        // foo123($foo,$foo->bar(),"foo")
+        $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
+           . $this->_parenth_param_regexp . '))';
+    }
+
+    /**
+     * compile a resource
+     *
+     * sets $compiled_content to the compiled source
+     * @param string $resource_name
+     * @param string $source_content
+     * @param string $compiled_content
+     * @return true
+     */
+    function _compile_file($resource_name, $source_content, &$compiled_content)
+    {
+
+        if ($this->security) {
+            // do not allow php syntax to be executed unless specified
+            if ($this->php_handling == SMARTY_PHP_ALLOW &&
+                !$this->security_settings['PHP_HANDLING']) {
+                $this->php_handling = SMARTY_PHP_PASSTHRU;
+            }
+        }
+
+        $this->_load_filters();
+
+        $this->_current_file = $resource_name;
+        $this->_current_line_no = 1;
+        $ldq = preg_quote($this->left_delimiter, '~');
+        $rdq = preg_quote($this->right_delimiter, '~');
+
+        // run template source through prefilter functions
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) continue;
+                if ($prefilter[3] || is_callable($prefilter[0])) {
+                    $source_content = call_user_func_array($prefilter[0],
+                                                            array($source_content, &$this));
+                    $this->_plugins['prefilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        /* fetch all special blocks */
+        $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s";
+
+        preg_match_all($search, $source_content, $match,  PREG_SET_ORDER);
+        $this->_folded_blocks = $match;
+        reset($this->_folded_blocks);
+
+        /* replace special blocks by "{php}" */
+        $source_content = preg_replace($search.'e', "'"
+                                       . $this->_quote_replace($this->left_delimiter) . 'php'
+                                       . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
+                                       . $this->_quote_replace($this->right_delimiter)
+                                       . "'"
+                                       , $source_content);
+
+        /* Gather all template tags. */
+        preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match);
+        $template_tags = $_match[1];
+        /* Split content by template tags to obtain non-template content. */
+        $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content);
+
+        /* loop through text blocks */
+        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
+            /* match anything resembling php tags */
+            if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
+                /* replace tags with placeholders to prevent recursive replacements */
+                $sp_match[1] = array_unique($sp_match[1]);
+                usort($sp_match[1], '_smarty_sort_length');
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
+                }
+                /* process each one */
+                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
+                        /* echo php contents */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
+                        /* quote php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
+                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
+                        /* remove php tags */
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
+                    } else {
+                        /* SMARTY_PHP_ALLOW, but echo non php starting tags */
+                        $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
+                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
+                    }
+                }
+            }
+        }
+        
+        /* Compile the template tags into PHP code. */
+        $compiled_tags = array();
+        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
+            $this->_current_line_no += substr_count($text_blocks[$i], "\n");
+            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
+            $this->_current_line_no += substr_count($template_tags[$i], "\n");
+        }
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = end($this->_tag_stack);
+            $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
+            return;
+        }
+
+        /* Reformat $text_blocks between 'strip' and '/strip' tags,
+           removing spaces, tabs and newlines. */
+        $strip = false;
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '{strip}') {
+                $compiled_tags[$i] = '';
+                $strip = true;
+                /* remove leading whitespaces */
+                $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]);
+            }
+            if ($strip) {
+                /* strip all $text_blocks before the next '/strip' */
+                for ($j = $i + 1; $j < $for_max; $j++) {
+                    /* remove leading and trailing whitespaces of each line */
+                    $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]);
+                    if ($compiled_tags[$j] == '{/strip}') {                       
+                        /* remove trailing whitespaces from the last text_block */
+                        $text_blocks[$j] = rtrim($text_blocks[$j]);
+                    }
+                    $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>";
+                    if ($compiled_tags[$j] == '{/strip}') {
+                        $compiled_tags[$j] = "\n"; /* slurped by php, but necessary
+                                    if a newline is following the closing strip-tag */
+                        $strip = false;
+                        $i = $j;
+                        break;
+                    }
+                }
+            }
+        }
+        $compiled_content = '';
+        
+        $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
+        
+        /* Interleave the compiled contents and text blocks to get the final result. */
+        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+            if ($compiled_tags[$i] == '') {
+                // tag result empty, remove first newline from following text block
+                $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]);
+            }
+            // replace legit PHP tags with placeholder
+            $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
+            $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
+            
+            $compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
+        }
+        $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
+
+        // escape php tags created by interleaving
+        $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
+        $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
+
+        // recover legit tags
+        $compiled_content = str_replace($tag_guard, '<?', $compiled_content); 
+        
+        // remove \n from the end of the file, if any
+        if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) {
+            $compiled_content = substr($compiled_content, 0, -1);
+        }
+
+        if (!empty($this->_cache_serial)) {
+            $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
+        }
+
+        // run compiled template through postfilter functions
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) continue;
+                if ($postfilter[3] || is_callable($postfilter[0])) {
+                    $compiled_content = call_user_func_array($postfilter[0],
+                                                              array($compiled_content, &$this));
+                    $this->_plugins['postfilter'][$filter_name][3] = true;
+                } else {
+                    $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
+                }
+            }
+        }
+
+        // put header at the top of the compiled template
+        $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+        $template_header .= "         compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
+
+        /* Emit code to load needed plugins. */
+        $this->_plugins_code = '';
+        if (count($this->_plugin_info)) {
+            $_plugins_params = "array('plugins' => array(";
+            foreach ($this->_plugin_info as $plugin_type => $plugins) {
+                foreach ($plugins as $plugin_name => $plugin_info) {
+                    $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], ";
+                    $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
+                }
+            }
+            $_plugins_params .= '))';
+            $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
+            $template_header .= $plugins_code;
+            $this->_plugin_info = array();
+            $this->_plugins_code = $plugins_code;
+        }
+
+        if ($this->_init_smarty_vars) {
+            $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
+            $this->_init_smarty_vars = false;
+        }
+
+        $compiled_content = $template_header . $compiled_content;
+        return true;
+    }
+
+    /**
+     * Compile a template tag
+     *
+     * @param string $template_tag
+     * @return string
+     */
+    function _compile_tag($template_tag)
+    {
+        /* Matched comment. */
+        if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
+            return '';
+        
+        /* Split tag into two three parts: command, command modifiers and the arguments. */
+        if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp
+                . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
+                      (?:\s+(.*))?$
+                    ~xs', $template_tag, $match)) {
+            $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        $tag_command = $match[1];
+        $tag_modifier = isset($match[2]) ? $match[2] : null;
+        $tag_args = isset($match[3]) ? $match[3] : null;
+
+        if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) {
+            /* tag name is a variable or object */
+            $_return = $this->_parse_var_props($tag_command . $tag_modifier);
+            return "<?php echo $_return; ?>" . $this->_additional_newline;
+        }
+
+        /* If the tag name is a registered object, we process it. */
+        if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) {
+            return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
+        }
+
+        switch ($tag_command) {
+            case 'include':
+                return $this->_compile_include_tag($tag_args);
+
+            case 'include_php':
+                return $this->_compile_include_php_tag($tag_args);
+
+            case 'if':
+                $this->_push_tag('if');
+                return $this->_compile_if_tag($tag_args);
+
+            case 'else':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__);
+                else
+                    $this->_push_tag('else');
+                return '<?php else: ?>';
+
+            case 'elseif':
+                list($_open_tag) = end($this->_tag_stack);
+                if ($_open_tag != 'if' && $_open_tag != 'elseif')
+                    $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
+                if ($_open_tag == 'if')
+                    $this->_push_tag('elseif');
+                return $this->_compile_if_tag($tag_args, true);
+
+            case '/if':
+                $this->_pop_tag('if');
+                return '<?php endif; ?>';
+
+            case 'capture':
+                return $this->_compile_capture_tag(true, $tag_args);
+
+            case '/capture':
+                return $this->_compile_capture_tag(false);
+
+            case 'ldelim':
+                return $this->left_delimiter;
+
+            case 'rdelim':
+                return $this->right_delimiter;
+
+            case 'section':
+                $this->_push_tag('section');
+                return $this->_compile_section_start($tag_args);
+
+            case 'sectionelse':
+                $this->_push_tag('sectionelse');
+                return "<?php endfor; else: ?>";
+                break;
+
+            case '/section':
+                $_open_tag = $this->_pop_tag('section');
+                if ($_open_tag == 'sectionelse')
+                    return "<?php endif; ?>";
+                else
+                    return "<?php endfor; endif; ?>";
+
+            case 'foreach':
+                $this->_push_tag('foreach');
+                return $this->_compile_foreach_start($tag_args);
+                break;
+
+            case 'foreachelse':
+                $this->_push_tag('foreachelse');
+                return "<?php endforeach; else: ?>";
+
+            case '/foreach':
+                $_open_tag = $this->_pop_tag('foreach');
+                if ($_open_tag == 'foreachelse')
+                    return "<?php endif; unset(\$_from); ?>";
+                else
+                    return "<?php endforeach; endif; unset(\$_from); ?>";
+                break;
+
+            case 'strip':
+            case '/strip':
+                if (substr($tag_command, 0, 1)=='/') {
+                    $this->_pop_tag('strip');
+                    if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
+                        $this->_additional_newline = "\n";
+                        return '{' . $tag_command . '}';
+                    }
+                } else {
+                    $this->_push_tag('strip');
+                    if ($this->_strip_depth++==0) { /* outermost opening {strip} */
+                        $this->_additional_newline = "";
+                        return '{' . $tag_command . '}';
+                    }
+                }
+                return '';
+
+            case 'php':
+                /* handle folded tags replaced by {php} */
+                list(, $block) = each($this->_folded_blocks);
+                $this->_current_line_no += substr_count($block[0], "\n");
+                /* the number of matched elements in the regexp in _compile_file()
+                   determins the type of folded tag that was found */
+                switch (count($block)) {
+                    case 2: /* comment */
+                        return '';
+
+                    case 3: /* literal */
+                        return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
+
+                    case 4: /* php */
+                        if ($this->security && !$this->security_settings['PHP_TAGS']) {
+                            $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
+                            return;
+                        }
+                        return '<?php ' . $block[3] .' ?>';
+                }
+                break;
+
+            case 'insert':
+                return $this->_compile_insert_tag($tag_args);
+
+            default:
+                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
+                    return $output;
+                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;
+                } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+                    return $output;                    
+                } else {
+                    $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+
+        }
+    }
+
+
+    /**
+     * compile the custom compiler tag
+     *
+     * sets $output to the compiled custom compiler tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_compiler_tag($tag_command, $tag_args, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the compiler function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['compiler'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['compiler'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "compiler function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_compiler_' . $tag_command;
+            if (!is_callable($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
+            }
+        }
+
+        /*
+         * True return value means that we either found a plugin or a
+         * dynamically registered function. False means that we didn't and the
+         * compiler should now emit code to load custom function plugin for this
+         * tag.
+         */
+        if ($found) {
+            if ($have_function) {
+                $output = call_user_func_array($plugin_func, array($tag_args, &$this));
+                if($output != '') {
+                $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
+                                   . $output
+                                   . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
+                }
+            } else {
+                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * compile block function tag
+     *
+     * sets $output to compiled block function tag
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @param string $output
+     * @return boolean
+     */
+    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else
+            $start_tag = true;
+
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the block function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['block'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['block'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "block function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_block_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /*
+         * Even though we've located the plugin function, compilation
+         * happens only once, so the plugin will still need to be loaded
+         * at runtime for future requests.
+         */
+        $this->_add_plugin('block', $tag_command);
+
+        if ($start_tag)
+            $this->_push_tag($tag_command);
+        else
+            $this->_pop_tag($tag_command);
+
+        if ($start_tag) {
+            $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
+            $attrs = $this->_parse_attrs($tag_args);
+            $_cache_attrs='';
+            $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs);
+            $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
+            $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);';
+            $output .= 'while ($_block_repeat) { ob_start(); ?>';
+        } else {
+            $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); ';
+            $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
+            if ($tag_modifier != '') {
+                $this->_parse_modifiers($_out_tag_text, $tag_modifier);
+            }
+            $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } ';
+            $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
+        }
+
+        return true;
+    }
+
+
+    /**
+     * compile custom function tag
+     *
+     * @param string $tag_command
+     * @param string $tag_args
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
+    {
+        $found = false;
+        $have_function = true;
+
+        /*
+         * First we check if the custom function has already been registered
+         * or loaded from a plugin file.
+         */
+        if (isset($this->_plugins['function'][$tag_command])) {
+            $found = true;
+            $plugin_func = $this->_plugins['function'][$tag_command][0];
+            if (!is_callable($plugin_func)) {
+                $message = "custom function '$tag_command' is not implemented";
+                $have_function = false;
+            }
+        }
+        /*
+         * Otherwise we need to load plugin file and look for the function
+         * inside it.
+         */
+        else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
+            $found = true;
+
+            include_once $plugin_file;
+
+            $plugin_func = 'smarty_function_' . $tag_command;
+            if (!function_exists($plugin_func)) {
+                $message = "plugin function $plugin_func() not found in $plugin_file\n";
+                $have_function = false;
+            } else {
+                $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
+
+            }
+        }
+
+        if (!$found) {
+            return false;
+        } else if (!$have_function) {
+            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+            return true;
+        }
+
+        /* declare plugin to be loaded on display of the template that
+           we compile right now */
+        $this->_add_plugin('function', $tag_command);
+
+        $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
+        $attrs = $this->_parse_attrs($tag_args);
+        $_cache_attrs = '';
+        $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs);
+
+        $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
+        if($tag_modifier != '') {
+            $this->_parse_modifiers($output, $tag_modifier);
+        }
+
+        if($output != '') {
+            $output =  '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
+                . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
+        }
+
+        return true;
+    }
+
+    /**
+     * compile a registered object tag
+     *
+     * @param string $tag_command
+     * @param array $attrs
+     * @param string $tag_modifier
+     * @return string
+     */
+    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
+    {
+        if (substr($tag_command, 0, 1) == '/') {
+            $start_tag = false;
+            $tag_command = substr($tag_command, 1);
+        } else {
+            $start_tag = true;
+        }
+
+        list($object, $obj_comp) = explode('->', $tag_command);
+
+        $arg_list = array();
+        if(count($attrs)) {
+            $_assign_var = false;
+            foreach ($attrs as $arg_name => $arg_value) {
+                if($arg_name == 'assign') {
+                    $_assign_var = $arg_value;
+                    unset($attrs['assign']);
+                    continue;
+                }
+                if (is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        if($this->_reg_objects[$object][2]) {
+            // smarty object argument format
+            $args = "array(".implode(',', (array)$arg_list)."), \$this";
+        } else {
+            // traditional argument format
+            $args = implode(',', array_values($attrs));
+            if (empty($args)) {
+                $args = 'null';
+            }
+        }
+
+        $prefix = '';
+        $postfix = '';
+        $newline = '';
+        if(!is_object($this->_reg_objects[$object][0])) {
+            $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
+            $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+        } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
+            // method
+            if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
+                // block method
+                if ($start_tag) {
+                    $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
+                    $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); ";
+                    $prefix .= "while (\$_block_repeat) { ob_start();";
+                    $return = null;
+                    $postfix = '';
+                } else {
+                    $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;";
+                    $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)";
+                    $postfix = "} array_pop(\$this->_tag_stack);";
+                }
+            } else {
+                // non-block method
+                $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
+            }
+        } else {
+            // property
+            $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
+        }
+
+        if($return != null) {
+            if($tag_modifier != '') {
+                $this->_parse_modifiers($return, $tag_modifier);
+            }
+
+            if(!empty($_assign_var)) {
+                $output = "\$this->assign('" . $this->_dequote($_assign_var) ."',  $return);";
+            } else {
+                $output = 'echo ' . $return . ';';
+                $newline = $this->_additional_newline;
+            }
+        } else {
+            $output = '';
+        }
+
+        return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
+    }
+
+    /**
+     * Compile {insert ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_insert_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $name = $this->_dequote($attrs['name']);
+
+        if (empty($name)) {
+            return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        
+        if (!preg_match('~^\w+$~', $name)) {
+            return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (!empty($attrs['script'])) {
+            $delayed_loading = true;
+        } else {
+            $delayed_loading = false;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $this->_add_plugin('insert', $name, $delayed_loading);
+
+        $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if ($arg_name == 'file') {
+                $include_file = $arg_value;
+                continue;
+            } else if ($arg_name == 'assign') {
+                $assign_var = $arg_value;
+                continue;
+            }
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            $arg_list[] = "'$arg_name' => $arg_value";
+        }
+
+        $output = '<?php ';
+
+        if (isset($assign_var)) {
+            $output .= "ob_start();\n";
+        }
+
+        $output .=
+            "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
+
+
+        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
+        $output .= "\$this->_smarty_include($_params);\n" .
+        "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
+        "unset(\$_smarty_tpl_vars);\n";
+
+        if (isset($assign_var)) {
+            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
+        }
+
+        $output .= ' ?>';
+
+        return $output;
+
+    }
+
+    /**
+     * Compile {include ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_include_php_tag($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if (empty($attrs['file'])) {
+            $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
+        $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
+
+        $arg_list = array();
+        foreach($attrs as $arg_name => $arg_value) {
+            if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
+                if(is_bool($arg_value))
+                    $arg_value = $arg_value ? 'true' : 'false';
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+
+        $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
+
+        return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
+    }
+
+
+    /**
+     * Compile {section ...} tag
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_section_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        $output = '<?php ';
+        $section_name = $attrs['name'];
+        if (empty($section_name)) {
+            $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $output .= "unset(\$this->_sections[$section_name]);\n";
+        $section_props = "\$this->_sections[$section_name]";
+
+        foreach ($attrs as $attr_name => $attr_value) {
+            switch ($attr_name) {
+                case 'loop':
+                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
+                    break;
+
+                case 'show':
+                    if (is_bool($attr_value))
+                        $show_attr_value = $attr_value ? 'true' : 'false';
+                    else
+                        $show_attr_value = "(bool)$attr_value";
+                    $output .= "{$section_props}['show'] = $show_attr_value;\n";
+                    break;
+
+                case 'name':
+                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+                    break;
+
+                case 'max':
+                case 'start':
+                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
+                    break;
+
+                case 'step':
+                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
+                    break;
+
+                default:
+                    $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+        }
+
+        if (!isset($attrs['show']))
+            $output .= "{$section_props}['show'] = true;\n";
+
+        if (!isset($attrs['loop']))
+            $output .= "{$section_props}['loop'] = 1;\n";
+
+        if (!isset($attrs['max']))
+            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+        else
+            $output .= "if ({$section_props}['max'] < 0)\n" .
+                       "    {$section_props}['max'] = {$section_props}['loop'];\n";
+
+        if (!isset($attrs['step']))
+            $output .= "{$section_props}['step'] = 1;\n";
+
+        if (!isset($attrs['start']))
+            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+        else {
+            $output .= "if ({$section_props}['start'] < 0)\n" .
+                       "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
+                       "else\n" .
+                       "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+        }
+
+        $output .= "if ({$section_props}['show']) {\n";
+        if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
+            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";
+        } else {
+            $output .= "    {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+        }
+        $output .= "    if ({$section_props}['total'] == 0)\n" .
+                   "        {$section_props}['show'] = false;\n" .
+                   "} else\n" .
+                   "    {$section_props}['total'] = 0;\n";
+
+        $output .= "if ({$section_props}['show']):\n";
+        $output .= "
+            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+                 {$section_props}['iteration'] <= {$section_props}['total'];
+                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";
+        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+        $output .= "?>";
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {foreach ...} tag.
+     *
+     * @param string $tag_args
+     * @return string
+     */
+    function _compile_foreach_start($tag_args)
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+        $arg_list = array();
+
+        if (empty($attrs['from'])) {
+            return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $from = $attrs['from'];
+
+        if (empty($attrs['item'])) {
+            return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
+        }
+        $item = $this->_dequote($attrs['item']);
+        if (!preg_match('~^\w+$~', $item)) {
+            return $this->_syntax_error("'foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (isset($attrs['key'])) {
+            $key  = $this->_dequote($attrs['key']);
+            if (!preg_match('~^\w+$~', $key)) {
+                return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
+            }
+            $key_part = "\$this->_tpl_vars['$key'] => ";
+        } else {
+            $key = null;
+            $key_part = '';
+        }
+
+        if (isset($attrs['name'])) {
+            $name = $attrs['name'];
+        } else {
+            $name = null;
+        }
+
+        $output = '<?php ';
+        $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }";
+        if (isset($name)) {
+            $foreach_props = "\$this->_foreach[$name]";
+            $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n";
+            $output .= "if ({$foreach_props}['total'] > 0):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+            $output .= "        {$foreach_props}['iteration']++;\n";
+        } else {
+            $output .= "if (count(\$_from)):\n";
+            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+        }
+        $output .= '?>';
+
+        return $output;
+    }
+
+
+    /**
+     * Compile {capture} .. {/capture} tags
+     *
+     * @param boolean $start true if this is the {capture} tag
+     * @param string $tag_args
+     * @return string
+     */
+
+    function _compile_capture_tag($start, $tag_args = '')
+    {
+        $attrs = $this->_parse_attrs($tag_args);
+
+        if ($start) {
+            if (isset($attrs['name']))
+                $buffer = $attrs['name'];
+            else
+                $buffer = "'default'";
+
+            if (isset($attrs['assign']))
+                $assign = $attrs['assign'];
+            else
+                $assign = null;
+            $output = "<?php ob_start(); ?>";
+            $this->_capture_stack[] = array($buffer, $assign);
+        } else {
+            list($buffer, $assign) = array_pop($this->_capture_stack);
+            $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
+            if (isset($assign)) {
+                $output .= " \$this->assign($assign, ob_get_contents());";
+            }
+            $output .= "ob_end_clean(); ?>";
+        }
+
+        return $output;
+    }
+
+    /**
+     * Compile {if ...} tag
+     *
+     * @param string $tag_args
+     * @param boolean $elseif if true, uses elseif instead of if
+     * @return string
+     */
+    function _compile_if_tag($tag_args, $elseif = false)
+    {
+
+        /* Tokenize args for 'if' tag. */
+        preg_match_all('~(?>
+                ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
+                ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)?    | # var or quoted string
+                \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@    | # valid non-word token
+                \b\w+\b                                                        | # valid word token
+                \S+                                                           # anything else
+                )~x', $tag_args, $match);
+
+        $tokens = $match[0];
+
+        if(empty($tokens)) {
+            $_error_msg = $elseif ? "'elseif'" : "'if'";
+            $_error_msg .= ' statement requires arguments'; 
+            $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__);
+        }
+            
+                
+        // make sure we have balanced parenthesis
+        $token_count = array_count_values($tokens);
+        if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
+            $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        $is_arg_stack = array();
+
+        for ($i = 0; $i < count($tokens); $i++) {
+
+            $token = &$tokens[$i];
+
+            switch (strtolower($token)) {
+                case '!':
+                case '%':
+                case '!==':
+                case '==':
+                case '===':
+                case '>':
+                case '<':
+                case '!=':
+                case '<>':
+                case '<<':
+                case '>>':
+                case '<=':
+                case '>=':
+                case '&&':
+                case '||':
+                case '|':
+                case '^':
+                case '&':
+                case '~':
+                case ')':
+                case ',':
+                case '+':
+                case '-':
+                case '*':
+                case '/':
+                case '@':
+                    break;
+
+                case 'eq':
+                    $token = '==';
+                    break;
+
+                case 'ne':
+                case 'neq':
+                    $token = '!=';
+                    break;
+
+                case 'lt':
+                    $token = '<';
+                    break;
+
+                case 'le':
+                case 'lte':
+                    $token = '<=';
+                    break;
+
+                case 'gt':
+                    $token = '>';
+                    break;
+
+                case 'ge':
+                case 'gte':
+                    $token = '>=';
+                    break;
+
+                case 'and':
+                    $token = '&&';
+                    break;
+
+                case 'or':
+                    $token = '||';
+                    break;
+
+                case 'not':
+                    $token = '!';
+                    break;
+
+                case 'mod':
+                    $token = '%';
+                    break;
+
+                case '(':
+                    array_push($is_arg_stack, $i);
+                    break;
+
+                case 'is':
+                    /* If last token was a ')', we operate on the parenthesized
+                       expression. The start of the expression is on the stack.
+                       Otherwise, we operate on the last encountered token. */
+                    if ($tokens[$i-1] == ')')
+                        $is_arg_start = array_pop($is_arg_stack);
+                    else
+                        $is_arg_start = $i-1;
+                    /* Construct the argument for 'is' expression, so it knows
+                       what to operate on. */
+                    $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
+
+                    /* Pass all tokens from next one until the end to the
+                       'is' expression parsing function. The function will
+                       return modified tokens, where the first one is the result
+                       of the 'is' expression and the rest are the tokens it
+                       didn't touch. */
+                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
+
+                    /* Replace the old tokens with the new ones. */
+                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
+
+                    /* Adjust argument start so that it won't change from the
+                       current position for the next iteration. */
+                    $i = $is_arg_start;
+                    break;
+
+                default:
+                    if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) {
+                            // function call
+                            if($this->security &&
+                               !in_array($token, $this->security_settings['IF_FUNCS'])) {
+                                $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
+                            }
+                    } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
+                        // variable function call
+                        $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);                      
+                    } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
+                        // object or variable
+                        $token = $this->_parse_var_props($token);
+                    } elseif(is_numeric($token)) {
+                        // number, skip it
+                    } else {
+                        $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    }
+                    break;
+            }
+        }
+
+        if ($elseif)
+            return '<?php elseif ('.implode(' ', $tokens).'): ?>';
+        else
+            return '<?php if ('.implode(' ', $tokens).'): ?>';
+    }
+
+
+    function _compile_arg_list($type, $name, $attrs, &$cache_code) {
+        $arg_list = array();
+
+        if (isset($type) && isset($name)
+            && isset($this->_plugins[$type])
+            && isset($this->_plugins[$type][$name])
+            && empty($this->_plugins[$type][$name][4])
+            && is_array($this->_plugins[$type][$name][5])
+            ) {
+            /* we have a list of parameters that should be cached */
+            $_cache_attrs = $this->_plugins[$type][$name][5];
+            $_count = $this->_cache_attrs_count++;
+            $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
+
+        } else {
+            /* no parameters are cached */
+            $_cache_attrs = null;
+        }
+
+        foreach ($attrs as $arg_name => $arg_value) {
+            if (is_bool($arg_value))
+                $arg_value = $arg_value ? 'true' : 'false';
+            if (is_null($arg_value))
+                $arg_value = 'null';
+            if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
+                $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
+            } else {
+                $arg_list[] = "'$arg_name' => $arg_value";
+            }
+        }
+        return $arg_list;
+    }
+
+    /**
+     * Parse is expression
+     *
+     * @param string $is_arg
+     * @param array $tokens
+     * @return array
+     */
+    function _parse_is_expr($is_arg, $tokens)
+    {
+        $expr_end = 0;
+        $negate_expr = false;
+
+        if (($first_token = array_shift($tokens)) == 'not') {
+            $negate_expr = true;
+            $expr_type = array_shift($tokens);
+        } else
+            $expr_type = $first_token;
+
+        switch ($expr_type) {
+            case 'even':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "!(1 & $is_arg)";
+                break;
+
+            case 'odd':
+                if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+                } else
+                    $expr = "(1 & $is_arg)";
+                break;
+
+            case 'div':
+                if (@$tokens[$expr_end] == 'by') {
+                    $expr_end++;
+                    $expr_arg = $tokens[$expr_end++];
+                    $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
+                } else {
+                    $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
+                }
+                break;
+
+            default:
+                $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if ($negate_expr) {
+            $expr = "!($expr)";
+        }
+
+        array_splice($tokens, 0, $expr_end, $expr);
+
+        return $tokens;
+    }
+
+
+    /**
+     * Parse attribute string
+     *
+     * @param string $tag_args
+     * @return array
+     */
+    function _parse_attrs($tag_args)
+    {
+
+        /* Tokenize tag attributes. */
+        preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
+                         )+ |
+                         [=]
+                        ~x', $tag_args, $match);
+        $tokens       = $match[0];
+
+        $attrs = array();
+        /* Parse state:
+            0 - expecting attribute name
+            1 - expecting '='
+            2 - expecting attribute value (not '=') */
+        $state = 0;
+
+        foreach ($tokens as $token) {
+            switch ($state) {
+                case 0:
+                    /* If the token is a valid identifier, we set attribute name
+                       and go to state 1. */
+                    if (preg_match('~^\w+$~', $token)) {
+                        $attr_name = $token;
+                        $state = 1;
+                    } else
+                        $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 1:
+                    /* If the token is '=', then we go to state 2. */
+                    if ($token == '=') {
+                        $state = 2;
+                    } else
+                        $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+
+                case 2:
+                    /* If token is not '=', we set the attribute value and go to
+                       state 0. */
+                    if ($token != '=') {
+                        /* We booleanize the token if it's a non-quoted possible
+                           boolean value. */
+                        if (preg_match('~^(on|yes|true)$~', $token)) {
+                            $token = 'true';
+                        } else if (preg_match('~^(off|no|false)$~', $token)) {
+                            $token = 'false';
+                        } else if ($token == 'null') {
+                            $token = 'null';
+                        } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
+                            /* treat integer literally */
+                        } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
+                            /* treat as a string, double-quote it escaping quotes */
+                            $token = '"'.addslashes($token).'"';
+                        }
+
+                        $attrs[$attr_name] = $token;
+                        $state = 0;
+                    } else
+                        $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
+                    break;
+            }
+            $last_token = $token;
+        }
+
+        if($state != 0) {
+            if($state == 1) {
+                $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+            } else {
+                $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        $this->_parse_vars_props($attrs);
+
+        return $attrs;
+    }
+
+    /**
+     * compile multiple variables and section properties tokens into
+     * PHP code
+     *
+     * @param array $tokens
+     */
+    function _parse_vars_props(&$tokens)
+    {
+        foreach($tokens as $key => $val) {
+            $tokens[$key] = $this->_parse_var_props($val);
+        }
+    }
+
+    /**
+     * compile single variable and section properties token into
+     * PHP code
+     *
+     * @param string $val
+     * @param string $tag_attrs
+     * @return string
+     */
+    function _parse_var_props($val)
+    {
+        $val = trim($val);
+
+        if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) {
+            // $ variable or object
+            $return = $this->_parse_var($match[1]);
+            $modifiers = $match[2];
+            if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) {
+                $_default_mod_string = implode('|',(array)$this->default_modifiers);
+                $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
+            }
+            $this->_parse_modifiers($return, $modifiers);
+            return $return;
+        } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // double quoted text
+                preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                $return = $this->_expand_quoted_text($match[1]);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($return, $match[2]);
+                }
+                return $return;
+            }
+        elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // numerical constant
+                preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // single quoted text
+                preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match);
+                if($match[2] != '') {
+                    $this->_parse_modifiers($match[1], $match[2]);
+                    return $match[1];
+                }
+            }
+        elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // config var
+                return $this->_parse_conf_var($val);
+            }
+        elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) {
+                // section var
+                return $this->_parse_section_prop($val);
+            }
+        elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
+            // literal string
+            return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
+        }
+        return $val;
+    }
+
+    /**
+     * expand quoted text with embedded variables
+     *
+     * @param string $var_expr
+     * @return string
+     */
+    function _expand_quoted_text($var_expr)
+    {
+        // if contains unescaped $, expand it
+        if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
+            $_match = $_match[0];
+            $_replace = array();
+            foreach($_match as $_var) {
+                $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
+            }
+            $var_expr = strtr($var_expr, $_replace);
+            $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
+        } else {
+            $_return = $var_expr;
+        }
+        // replace double quoted literal string with single quotes
+        $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return);
+        return $_return;
+    }
+
+    /**
+     * parse variable expression into PHP code
+     *
+     * @param string $var_expr
+     * @param string $output
+     * @return string
+     */
+    function _parse_var($var_expr)
+    {
+        $_has_math = false;
+        $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+        if(count($_math_vars) > 1) {
+            $_first_var = "";
+            $_complete_var = "";
+            $_output = "";
+            // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
+            foreach($_math_vars as $_k => $_math_var) {
+                $_math_var = $_math_vars[$_k];
+
+                if(!empty($_math_var) || is_numeric($_math_var)) {
+                    // hit a math operator, so process the stuff which came before it
+                    if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) {
+                        $_has_math = true;
+                        if(!empty($_complete_var) || is_numeric($_complete_var)) {
+                            $_output .= $this->_parse_var($_complete_var);
+                        }
+
+                        // just output the math operator to php
+                        $_output .= $_math_var;
+
+                        if(empty($_first_var))
+                            $_first_var = $_complete_var;
+
+                        $_complete_var = "";
+                    } else {
+                        $_complete_var .= $_math_var;
+                    }
+                }
+            }
+            if($_has_math) {
+                if(!empty($_complete_var) || is_numeric($_complete_var))
+                    $_output .= $this->_parse_var($_complete_var);
+
+                // get the modifiers working (only the last var from math + modifier is left)
+                $var_expr = $_complete_var;
+            }
+        }
+
+        // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
+        if(is_numeric(substr($var_expr, 0, 1)))
+            $_var_ref = $var_expr;
+        else
+            $_var_ref = substr($var_expr, 1);
+        
+        if(!$_has_math) {
+            
+            // get [foo] and .foo and ->foo and (...) pieces
+            preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match);
+                        
+            $_indexes = $match[0];
+            $_var_name = array_shift($_indexes);
+
+            /* Handle $smarty.* variable references as a special case. */
+            if ($_var_name == 'smarty') {
+                /*
+                 * If the reference could be compiled, use the compiled output;
+                 * otherwise, fall back on the $smarty variable generated at
+                 * run-time.
+                 */
+                if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
+                    $_output = $smarty_ref;
+                } else {
+                    $_var_name = substr(array_shift($_indexes), 1);
+                    $_output = "\$this->_smarty_vars['$_var_name']";
+                }
+            } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) {
+                // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
+                if(count($_indexes) > 0)
+                {
+                    $_var_name .= implode("", $_indexes);
+                    $_indexes = array();
+                }
+                $_output = $_var_name;
+            } else {
+                $_output = "\$this->_tpl_vars['$_var_name']";
+            }
+
+            foreach ($_indexes as $_index) {
+                if (substr($_index, 0, 1) == '[') {
+                    $_index = substr($_index, 1, -1);
+                    if (is_numeric($_index)) {
+                        $_output .= "[$_index]";
+                    } elseif (substr($_index, 0, 1) == '$') {
+                        if (strpos($_index, '.') !== false) {
+                            $_output .= '[' . $this->_parse_var($_index) . ']';
+                        } else {
+                            $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
+                        }
+                    } else {
+                        $_var_parts = explode('.', $_index);
+                        $_var_section = $_var_parts[0];
+                        $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
+                        $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
+                    }
+                } else if (substr($_index, 0, 1) == '.') {
+                    if (substr($_index, 1, 1) == '$')
+                        $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
+                    else
+                        $_output .= "['" . substr($_index, 1) . "']";
+                } else if (substr($_index,0,2) == '->') {
+                    if(substr($_index,2,2) == '__') {
+                        $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif($this->security && substr($_index, 2, 1) == '_') {
+                        $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                    } elseif (substr($_index, 2, 1) == '$') {
+                        if ($this->security) {
+                            $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+                        } else {
+                            $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
+                        }
+                    } else {
+                        $_output .= $_index;
+                    }
+                } elseif (substr($_index, 0, 1) == '(') {
+                    $_index = $this->_parse_parenth_args($_index);
+                    $_output .= $_index;
+                } else {
+                    $_output .= $_index;
+                }
+            }
+        }
+
+        return $_output;
+    }
+
+    /**
+     * parse arguments in function call parenthesis
+     *
+     * @param string $parenth_args
+     * @return string
+     */
+    function _parse_parenth_args($parenth_args)
+    {
+        preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match);
+        $orig_vals = $match = $match[0];
+        $this->_parse_vars_props($match);
+        $replace = array();
+        for ($i = 0, $count = count($match); $i < $count; $i++) {
+            $replace[$orig_vals[$i]] = $match[$i];
+        }
+        return strtr($parenth_args, $replace);
+    }
+
+    /**
+     * parse configuration variable expression into PHP code
+     *
+     * @param string $conf_var_expr
+     */
+    function _parse_conf_var($conf_var_expr)
+    {
+        $parts = explode('|', $conf_var_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        $var_name = substr($var_ref, 1, -1);
+
+        $output = "\$this->_config[0]['vars']['$var_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+    /**
+     * parse section property expression into PHP code
+     *
+     * @param string $section_prop_expr
+     * @return string
+     */
+    function _parse_section_prop($section_prop_expr)
+    {
+        $parts = explode('|', $section_prop_expr, 2);
+        $var_ref = $parts[0];
+        $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+        preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
+        $section_name = $match[1];
+        $prop_name = $match[2];
+
+        $output = "\$this->_sections['$section_name']['$prop_name']";
+
+        $this->_parse_modifiers($output, $modifiers);
+
+        return $output;
+    }
+
+
+    /**
+     * parse modifier chain into PHP code
+     *
+     * sets $output to parsed modified chain
+     * @param string $output
+     * @param string $modifier_string
+     */
+    function _parse_modifiers(&$output, $modifier_string)
+    {
+        preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match);
+        list(, $_modifiers, $modifier_arg_strings) = $_match;
+
+        for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
+            $_modifier_name = $_modifiers[$_i];
+
+            if($_modifier_name == 'smarty') {
+                // skip smarty modifier
+                continue;
+            }
+
+            preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match);
+            $_modifier_args = $_match[1];
+
+            if (substr($_modifier_name, 0, 1) == '@') {
+                $_map_array = false;
+                $_modifier_name = substr($_modifier_name, 1);
+            } else {
+                $_map_array = true;
+            }
+
+            if (empty($this->_plugins['modifier'][$_modifier_name])
+                && !$this->_get_plugin_filepath('modifier', $_modifier_name)
+                && function_exists($_modifier_name)) {
+                if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
+                    $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+                } else {
+                    $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name,  null, null, false);
+                }
+            }
+            $this->_add_plugin('modifier', $_modifier_name);
+
+            $this->_parse_vars_props($_modifier_args);
+
+            if($_modifier_name == 'default') {
+                // supress notifications of default modifier vars and args
+                if(substr($output, 0, 1) == '$') {
+                    $output = '@' . $output;
+                }
+                if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') {
+                    $_modifier_args[0] = '@' . $_modifier_args[0];
+                }
+            }
+            if (count($_modifier_args) > 0)
+                $_modifier_args = ', '.implode(', ', $_modifier_args);
+            else
+                $_modifier_args = '';
+
+            if ($_map_array) {
+                $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
+
+            } else {
+
+                $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
+
+            }
+        }
+    }
+
+
+    /**
+     * add plugin
+     *
+     * @param string $type
+     * @param string $name
+     * @param boolean? $delayed_loading
+     */
+    function _add_plugin($type, $name, $delayed_loading = null)
+    {
+        if (!isset($this->_plugin_info[$type])) {
+            $this->_plugin_info[$type] = array();
+        }
+        if (!isset($this->_plugin_info[$type][$name])) {
+            $this->_plugin_info[$type][$name] = array($this->_current_file,
+                                                      $this->_current_line_no,
+                                                      $delayed_loading);
+        }
+    }
+
+
+    /**
+     * Compiles references of type $smarty.foo
+     *
+     * @param string $indexes
+     * @return string
+     */
+    function _compile_smarty_ref(&$indexes)
+    {
+        /* Extract the reference name. */
+        $_ref = substr($indexes[0], 1);
+        foreach($indexes as $_index_no=>$_index) {
+            if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) {
+                $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+            }
+        }
+
+        switch ($_ref) {
+            case 'now':
+                $compiled_ref = 'time()';
+                $_max_index = 1;
+                break;
+
+            case 'foreach':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $_propname = substr($indexes[1], 1);
+                $_max_index = 1;
+                switch ($_propname) {
+                    case 'index':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)";
+                        break;
+                        
+                    case 'first':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)";
+                        break;
+
+                    case 'last':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])";
+                        break;
+                        
+                    case 'show':
+                        array_shift($indexes);
+                        $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)";
+                        break;
+                        
+                    default:
+                        unset($_max_index);
+                        $compiled_ref = "\$this->_foreach[$_var]";
+                }
+                break;
+
+            case 'section':
+                array_shift($indexes);
+                $_var = $this->_parse_var_props(substr($indexes[0], 1));
+                $compiled_ref = "\$this->_sections[$_var]";
+                break;
+
+            case 'get':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']";
+                break;
+
+            case 'post':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']";
+                break;
+
+            case 'cookies':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']";
+                break;
+
+            case 'env':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']";
+                break;
+
+            case 'server':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']";
+                break;
+
+            case 'session':
+                $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']";
+                break;
+
+            /*
+             * These cases are handled either at run-time or elsewhere in the
+             * compiler.
+             */
+            case 'request':
+                if ($this->request_use_auto_globals) {
+                    $compiled_ref = '$_REQUEST';
+                    break;
+                } else {
+                    $this->_init_smarty_vars = true;
+                }
+                return null;
+
+            case 'capture':
+                return null;
+
+            case 'template':
+                $compiled_ref = "'$this->_current_file'";
+                $_max_index = 1;
+                break;
+
+            case 'version':
+                $compiled_ref = "'$this->_version'";
+                $_max_index = 1;
+                break;
+
+            case 'const':
+                if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) {
+                    $this->_syntax_error("(secure mode) constants not permitted",
+                                         E_USER_WARNING, __FILE__, __LINE__);
+                    return;
+                }
+                array_shift($indexes);
+                if (preg_match('!^\.\w+$!', $indexes[0])) {
+                    $compiled_ref = '@' . substr($indexes[0], 1);
+                } else {
+                    $_val = $this->_parse_var_props(substr($indexes[0], 1));
+                    $compiled_ref = '@constant(' . $_val . ')';
+                }
+                $_max_index = 1;
+                break;
+
+            case 'config':
+                $compiled_ref = "\$this->_config[0]['vars']";
+                $_max_index = 3;
+                break;
+
+            case 'ldelim':
+                $compiled_ref = "'$this->left_delimiter'";
+                break;
+
+            case 'rdelim':
+                $compiled_ref = "'$this->right_delimiter'";
+                break;
+                
+            default:
+                $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
+                break;
+        }
+
+        if (isset($_max_index) && count($indexes) > $_max_index) {
+            $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        array_shift($indexes);
+        return $compiled_ref;
+    }
+
+    /**
+     * compiles call to plugin of type $type with name $name
+     * returns a string containing the function-name or method call
+     * without the paramter-list that would have follow to make the
+     * call valid php-syntax
+     *
+     * @param string $type
+     * @param string $name
+     * @return string
+     */
+    function _compile_plugin_call($type, $name) {
+        if (isset($this->_plugins[$type][$name])) {
+            /* plugin loaded */
+            if (is_array($this->_plugins[$type][$name][0])) {
+                return ((is_object($this->_plugins[$type][$name][0][0])) ?
+                        "\$this->_plugins['$type']['$name'][0][0]->"    /* method callback */
+                        : (string)($this->_plugins[$type][$name][0][0]).'::'    /* class callback */
+                       ). $this->_plugins[$type][$name][0][1];
+
+            } else {
+                /* function callback */
+                return $this->_plugins[$type][$name][0];
+
+            }
+        } else {
+            /* plugin not loaded -> auto-loadable-plugin */
+            return 'smarty_'.$type.'_'.$name;
+
+        }
+    }
+
+    /**
+     * load pre- and post-filters
+     */
+    function _load_filters()
+    {
+        if (count($this->_plugins['prefilter']) > 0) {
+            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+                if ($prefilter === false) {
+                    unset($this->_plugins['prefilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+        if (count($this->_plugins['postfilter']) > 0) {
+            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+                if ($postfilter === false) {
+                    unset($this->_plugins['postfilter'][$filter_name]);
+                    $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
+                    require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
+                    smarty_core_load_plugins($_params, $this);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Quote subpattern references
+     *
+     * @param string $string
+     * @return string
+     */
+    function _quote_replace($string)
+    {
+        return strtr($string, array('\\' => '\\\\', '$' => '\\$'));
+    }
+
+    /**
+     * display Smarty syntax error
+     *
+     * @param string $error_msg
+     * @param integer $error_type
+     * @param string $file
+     * @param integer $line
+     */
+    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
+    {
+        $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
+    }
+
+
+    /**
+     * check if the compilation changes from cacheable to
+     * non-cacheable state with the beginning of the current
+     * plugin. return php-code to reflect the transition.
+     * @return string
+     */
+    function _push_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || 0<$this->_cacheable_state++) return '';
+        if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
+        $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
+            . $this->_cache_serial . '#' . $this->_nocache_count
+            . '}\'; endif;';
+        return $_ret;
+    }
+
+
+    /**
+     * check if the compilation changes from non-cacheable to
+     * cacheable state with the end of the current plugin return
+     * php-code to reflect the transition.
+     * @return string
+     */
+    function _pop_cacheable_state($type, $name) {
+        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+        if ($_cacheable
+            || --$this->_cacheable_state>0) return '';
+        return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
+            . $this->_cache_serial . '#' . ($this->_nocache_count++)
+            . '}\'; endif;';
+    }
+
+
+    /**
+     * push opening tag-name, file-name and line-number on the tag-stack
+     * @param string the opening tag's name
+     */
+    function _push_tag($open_tag)
+    {
+        array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
+    }
+
+    /**
+     * pop closing tag-name
+     * raise an error if this stack-top doesn't match with the closing tag
+     * @param string the closing tag's name
+     * @return string the opening tag's name
+     */
+    function _pop_tag($close_tag)
+    {
+        $message = '';
+        if (count($this->_tag_stack)>0) {
+            list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
+            if ($close_tag == $_open_tag) {
+                return $_open_tag;
+            }
+            if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
+                return $this->_pop_tag($close_tag);
+            }
+            if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
+                $this->_pop_tag($close_tag);
+                return $_open_tag;
+            }
+            if ($_open_tag == 'else' || $_open_tag == 'elseif') {
+                $_open_tag = 'if';
+            } elseif ($_open_tag == 'sectionelse') {
+                $_open_tag = 'section';
+            } elseif ($_open_tag == 'foreachelse') {
+                $_open_tag = 'foreach';
+            }
+            $message = " expected {/$_open_tag} (opened line $_line_no).";
+        }
+        $this->_syntax_error("mismatched tag {/$close_tag}.$message",
+                             E_USER_ERROR, __FILE__, __LINE__);
+    }
+
+}
+
+/**
+ * compare to values by their string length
+ *
+ * @access private
+ * @param string $a
+ * @param string $b
+ * @return 0|-1|1
+ */
+function _smarty_sort_length($a, $b)
+{
+    if($a == $b)
+        return 0;
+
+    if(strlen($a) == strlen($b))
+        return ($a > $b) ? -1 : 1;
+
+    return (strlen($a) > strlen($b)) ? -1 : 1;
+}
+
+
+/* vim: set et: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/debug.tpl
===================================================================
--- /trunk/htdocs2/smarty/libs/debug.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/libs/debug.tpl	(revision 298)
@@ -0,0 +1,157 @@
+{* Smarty *}
+{* debug.tpl, last updated version 2.1.0 *}
+{assign_debug_info}
+{capture assign=debug_output}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+    <title>Smarty Debug Console</title>
+{literal}
+<style type="text/css">
+/* <![CDATA[ */
+body, h1, h2, td, th, p {
+    font-family: sans-serif;
+    font-weight: normal;
+    font-size: 0.9em;
+    margin: 1px;
+    padding: 0;
+}
+
+h1 {
+    margin: 0;
+    text-align: left;
+    padding: 2px;
+    background-color: #f0c040;
+    color:  black;
+    font-weight: bold;
+    font-size: 1.2em;
+ }
+
+h2 {
+    background-color: #9B410E;
+    color: white;
+    text-align: left;
+    font-weight: bold;
+    padding: 2px;
+    border-top: 1px solid black;
+}
+
+body {
+    background: black; 
+}
+
+p, table, div {
+    background: #f0ead8;
+} 
+
+p {
+    margin: 0;
+    font-style: italic;
+    text-align: center;
+}
+
+table {
+    width: 100%;
+}
+
+th, td {
+    font-family: monospace;
+    vertical-align: top;
+    text-align: left;
+    width: 50%;
+}
+
+td {
+    color: green;
+}
+
+.odd {
+    background-color: #eeeeee;
+}
+
+.even {
+    background-color: #fafafa;
+}
+
+.exectime {
+    font-size: 0.8em;
+    font-style: italic;
+}
+
+#table_assigned_vars th {
+    color: blue;
+}
+
+#table_config_vars th {
+    color: maroon;
+}
+/* ]]> */
+</style>
+{/literal}
+</head>
+<body>
+
+<h1>Smarty Debug Console</h1>
+
+<h2>included templates &amp; config files (load time in seconds)</h2>
+
+<div>
+{section name=templates loop=$_debug_tpls}
+    {section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
+    <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
+        {$_debug_tpls[templates].filename|escape:html}</font>
+    {if isset($_debug_tpls[templates].exec_time)}
+        <span class="exectime">
+        ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
+        {if %templates.index% eq 0}(total){/if}
+        </span>
+    {/if}
+    <br />
+{sectionelse}
+    <p>no templates included</p>
+{/section}
+</div>
+
+<h2>assigned template variables</h2>
+
+<table id="table_assigned_vars">
+    {section name=vars loop=$_debug_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
+            <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no template variables assigned</p></td></tr>
+    {/section}
+</table>
+
+<h2>assigned config file variables (outer template scope)</h2>
+
+<table id="table_config_vars">
+    {section name=config_vars loop=$_debug_config_keys}
+        <tr class="{cycle values="odd,even"}">
+            <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
+            <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
+    {sectionelse}
+        <tr><td><p>no config vars assigned</p></td></tr>
+    {/section}
+</table>
+</body>
+</html>
+{/capture}
+{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
+    {$debug_output}
+{else}
+<script type="text/javascript">
+// <![CDATA[
+    if ( self.name == '' ) {ldelim}
+       var title = 'Console';
+    {rdelim}
+    else {ldelim}
+       var title = 'Console_' + self.name;
+    {rdelim}
+    _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
+    _smarty_console.document.write('{$debug_output|escape:'javascript'}');
+    _smarty_console.document.close();
+// ]]>
+</script>
+{/if}
Index: /trunk/htdocs2/smarty/libs/internals/core.assemble_plugin_filepath.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.assemble_plugin_filepath.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.assemble_plugin_filepath.php	(revision 298)
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * assemble filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+function smarty_core_assemble_plugin_filepath($params, &$smarty)
+{
+    static $_filepaths_cache = array();
+
+    $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
+    if (isset($_filepaths_cache[$_plugin_filename])) {
+        return $_filepaths_cache[$_plugin_filename];
+    }
+    $_return = false;
+
+    foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
+
+        $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+        // see if path is relative
+        if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
+            $_relative_paths[] = $_plugin_dir;
+            // relative path, see if it is in the SMARTY_DIR
+            if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
+                $_return = SMARTY_DIR . $_plugin_filepath;
+                break;
+            }
+        }
+        // try relative to cwd (or absolute)
+        if (@is_readable($_plugin_filepath)) {
+            $_return = $_plugin_filepath;
+            break;
+        }
+    }
+
+    if($_return === false) {
+        // still not found, try PHP include_path
+        if(isset($_relative_paths)) {
+            foreach ((array)$_relative_paths as $_plugin_dir) {
+
+                $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+                $_params = array('file_path' => $_plugin_filepath);
+                require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+                if(smarty_core_get_include_path($_params, $smarty)) {
+                    $_return = $_params['new_file_path'];
+                    break;
+                }
+            }
+        }
+    }
+    $_filepaths_cache[$_plugin_filename] = $_return;
+    return $_return;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.assign_smarty_interface.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.assign_smarty_interface.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.assign_smarty_interface.php	(revision 298)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty assign_smarty_interface core plugin
+ *
+ * Type:     core<br>
+ * Name:     assign_smarty_interface<br>
+ * Purpose:  assign the $smarty interface variable
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_assign_smarty_interface($params, &$smarty)
+{
+        if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
+            return;
+        }
+
+        $_globals_map = array('g'  => 'HTTP_GET_VARS',
+                             'p'  => 'HTTP_POST_VARS',
+                             'c'  => 'HTTP_COOKIE_VARS',
+                             's'  => 'HTTP_SERVER_VARS',
+                             'e'  => 'HTTP_ENV_VARS');
+
+        $_smarty_vars_request  = array();
+
+        foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
+            if (isset($_globals_map[$_c])) {
+                $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
+            }
+        }
+        $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
+
+        $smarty->_smarty_vars['request'] = $_smarty_vars_request;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.create_dir_structure.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.create_dir_structure.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.create_dir_structure.php	(revision 298)
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * create full directory structure
+ *
+ * @param string $dir
+ */
+
+// $dir
+
+function smarty_core_create_dir_structure($params, &$smarty)
+{
+    if (!file_exists($params['dir'])) {
+        $_open_basedir_ini = ini_get('open_basedir');
+
+        if (DIRECTORY_SEPARATOR=='/') {
+            /* unix-style paths */
+            $_dir = $params['dir'];
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/';
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(':', $_open_basedir_ini);
+            }
+
+        } else {
+            /* other-style paths */
+            $_dir = str_replace('\\','/', $params['dir']);
+            $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+            if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
+                /* leading "//" for network volume, or "[letter]:/" for full path */
+                $_new_dir = $_root_dir[1];
+                /* remove drive-letter from _dir_parts */
+                if (isset($_root_dir[3])) array_shift($_dir_parts);
+
+            } else {
+                $_new_dir = str_replace('\\', '/', getcwd()).'/';
+
+            }
+
+            if($_use_open_basedir = !empty($_open_basedir_ini)) {
+                $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
+            }
+
+        }
+
+        /* all paths use "/" only from here */
+        foreach ($_dir_parts as $_dir_part) {
+            $_new_dir .= $_dir_part;
+
+            if ($_use_open_basedir) {
+                // do not attempt to test or make directories outside of open_basedir
+                $_make_new_dir = false;
+                foreach ($_open_basedirs as $_open_basedir) {
+                    if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
+                        $_make_new_dir = true;
+                        break;
+                    }
+                }
+            } else {
+                $_make_new_dir = true;
+            }
+
+            if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
+                $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
+                return false;
+            }
+            $_new_dir .= '/';
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.display_debug_console.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.display_debug_console.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.display_debug_console.php	(revision 298)
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty debug_console function plugin
+ *
+ * Type:     core<br>
+ * Name:     display_debug_console<br>
+ * Purpose:  display the javascript debug console window
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_display_debug_console($params, &$smarty)
+{
+    // we must force compile the debug template in case the environment
+    // changed between separate applications.
+
+    if(empty($smarty->debug_tpl)) {
+        // set path to debug template from SMARTY_DIR
+        $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
+        if($smarty->security && is_file($smarty->debug_tpl)) {
+            $smarty->secure_dir[] = realpath($smarty->debug_tpl);
+        }
+        $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
+    }
+
+    $_ldelim_orig = $smarty->left_delimiter;
+    $_rdelim_orig = $smarty->right_delimiter;
+
+    $smarty->left_delimiter = '{';
+    $smarty->right_delimiter = '}';
+
+    $_compile_id_orig = $smarty->_compile_id;
+    $smarty->_compile_id = null;
+
+    $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
+    if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
+    {
+        ob_start();
+        $smarty->_include($_compile_path);
+        $_results = ob_get_contents();
+        ob_end_clean();
+    } else {
+        $_results = '';
+    }
+
+    $smarty->_compile_id = $_compile_id_orig;
+
+    $smarty->left_delimiter = $_ldelim_orig;
+    $smarty->right_delimiter = $_rdelim_orig;
+
+    return $_results;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.get_include_path.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.get_include_path.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.get_include_path.php	(revision 298)
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get path to file from include_path
+ *
+ * @param string $file_path
+ * @param string $new_file_path
+ * @return boolean
+ * @staticvar array|null
+ */
+
+//  $file_path, &$new_file_path
+
+function smarty_core_get_include_path(&$params, &$smarty)
+{
+    static $_path_array = null;
+
+    if(!isset($_path_array)) {
+        $_ini_include_path = ini_get('include_path');
+
+        if(strstr($_ini_include_path,';')) {
+            // windows pathnames
+            $_path_array = explode(';',$_ini_include_path);
+        } else {
+            $_path_array = explode(':',$_ini_include_path);
+        }
+    }
+    foreach ($_path_array as $_include_path) {
+        if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
+               $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
+            return true;
+        }
+    }
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.get_microtime.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.get_microtime.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.get_microtime.php	(revision 298)
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get seconds and microseconds
+ * @return double
+ */
+function smarty_core_get_microtime($params, &$smarty)
+{
+    $mtime = microtime();
+    $mtime = explode(" ", $mtime);
+    $mtime = (double)($mtime[1]) + (double)($mtime[0]);
+    return ($mtime);
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.get_php_resource.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.get_php_resource.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.get_php_resource.php	(revision 298)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Retrieves PHP script resource
+ *
+ * sets $php_resource to the returned resource
+ * @param string $resource
+ * @param string $resource_type
+ * @param  $php_resource
+ * @return boolean
+ */
+
+function smarty_core_get_php_resource(&$params, &$smarty)
+{
+
+    $params['resource_base_path'] = $smarty->trusted_dir;
+    $smarty->_parse_resource_name($params, $smarty);
+
+    /*
+     * Find out if the resource exists.
+     */
+
+    if ($params['resource_type'] == 'file') {
+        $_readable = false;
+        if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
+            $_readable = true;
+        } else {
+            // test for file in include_path
+            $_params = array('file_path' => $params['resource_name']);
+            require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
+            if(smarty_core_get_include_path($_params, $smarty)) {
+                $_include_path = $_params['new_file_path'];
+                $_readable = true;
+            }
+        }
+    } else if ($params['resource_type'] != 'file') {
+        $_template_source = null;
+        $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
+            && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
+                                    array($params['resource_name'], &$_template_source, &$smarty));
+    }
+
+    /*
+     * Set the error function, depending on which class calls us.
+     */
+    if (method_exists($smarty, '_syntax_error')) {
+        $_error_funcc = '_syntax_error';
+    } else {
+        $_error_funcc = 'trigger_error';
+    }
+
+    if ($_readable) {
+        if ($smarty->security) {
+            require_once(SMARTY_CORE_DIR . 'core.is_trusted.php');
+            if (!smarty_core_is_trusted($params, $smarty)) {
+                $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
+                return false;
+            }
+        }
+    } else {
+        $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
+        return false;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $params['php_resource'] = $params['resource_name'];
+    } else {
+        $params['php_resource'] = $_template_source;
+    }
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.is_secure.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.is_secure.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.is_secure.php	(revision 298)
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is secure or not.
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+//  $resource_type, $resource_name
+
+function smarty_core_is_secure($params, &$smarty)
+{
+    if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
+        return true;
+    }
+
+    if ($params['resource_type'] == 'file') {
+        $_rp = realpath($params['resource_name']);
+        if (isset($params['resource_base_path'])) {
+            foreach ((array)$params['resource_base_path'] as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false &&
+                     strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                     substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                    return true;
+                }
+            }
+        }
+        if (!empty($smarty->secure_dir)) {
+            foreach ((array)$smarty->secure_dir as $curr_dir) {
+                if ( ($_cd = realpath($curr_dir)) !== false) {
+                    if($_cd == $_rp) {
+                        return true;
+                    } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
+                        substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
+                        return true;
+                    }
+                }
+            }
+        }
+    } else {
+        // resource is not on local file system
+        return call_user_func_array(
+            $smarty->_plugins['resource'][$params['resource_type']][0][2],
+            array($params['resource_name'], &$smarty));
+    }
+
+    return false;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.is_trusted.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.is_trusted.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.is_trusted.php	(revision 298)
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is trusted or not
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ // $resource_type, $resource_name
+
+function smarty_core_is_trusted($params, &$smarty)
+{
+    $_smarty_trusted = false;
+    if ($params['resource_type'] == 'file') {
+        if (!empty($smarty->trusted_dir)) {
+            $_rp = realpath($params['resource_name']);
+            foreach ((array)$smarty->trusted_dir as $curr_dir) {
+                if (!empty($curr_dir) && is_readable ($curr_dir)) {
+                    $_cd = realpath($curr_dir);
+                    if (strncmp($_rp, $_cd, strlen($_cd)) == 0
+                        && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
+                        $_smarty_trusted = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+    } else {
+        // resource is not on local file system
+        $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
+                                                array($params['resource_name'], $smarty));
+    }
+
+    return $_smarty_trusted;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.load_plugins.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.load_plugins.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.load_plugins.php	(revision 298)
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Load requested plugins
+ *
+ * @param array $plugins
+ */
+
+// $plugins
+
+function smarty_core_load_plugins($params, &$smarty)
+{
+
+    foreach ($params['plugins'] as $_plugin_info) {
+        list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
+        $_plugin = &$smarty->_plugins[$_type][$_name];
+
+        /*
+         * We do not load plugin more than once for each instance of Smarty.
+         * The following code checks for that. The plugin can also be
+         * registered dynamically at runtime, in which case template file
+         * and line number will be unknown, so we fill them in.
+         *
+         * The final element of the info array is a flag that indicates
+         * whether the dynamically registered plugin function has been
+         * checked for existence yet or not.
+         */
+        if (isset($_plugin)) {
+            if (empty($_plugin[3])) {
+                if (!is_callable($_plugin[0])) {
+                    $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                } else {
+                    $_plugin[1] = $_tpl_file;
+                    $_plugin[2] = $_tpl_line;
+                    $_plugin[3] = true;
+                    if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
+                }
+            }
+            continue;
+        } else if ($_type == 'insert') {
+            /*
+             * For backwards compatibility, we check for insert functions in
+             * the symbol table before trying to load them as a plugin.
+             */
+            $_plugin_func = 'insert_' . $_name;
+            if (function_exists($_plugin_func)) {
+                $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
+                continue;
+            }
+        }
+
+        $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
+
+        if (! $_found = ($_plugin_file != false)) {
+            $_message = "could not load plugin file '$_type.$_name.php'\n";
+        }
+
+        /*
+         * If plugin file is found, it -must- provide the properly named
+         * plugin function. In case it doesn't, simply output the error and
+         * do not fall back on any other method.
+         */
+        if ($_found) {
+            include_once $_plugin_file;
+
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+                continue;
+            }
+        }
+        /*
+         * In case of insert plugins, their code may be loaded later via
+         * 'script' attribute.
+         */
+        else if ($_type == 'insert' && $_delayed_loading) {
+            $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+            $_found = true;
+        }
+
+        /*
+         * Plugin specific processing and error checking.
+         */
+        if (!$_found) {
+            if ($_type == 'modifier') {
+                /*
+                 * In case modifier falls back on using PHP functions
+                 * directly, we only allow those specified in the security
+                 * context.
+                 */
+                if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
+                    $_message = "(secure mode) modifier '$_name' is not allowed";
+                } else {
+                    if (!function_exists($_name)) {
+                        $_message = "modifier '$_name' is not implemented";
+                    } else {
+                        $_plugin_func = $_name;
+                        $_found = true;
+                    }
+                }
+            } else if ($_type == 'function') {
+                /*
+                 * This is a catch-all situation.
+                 */
+                $_message = "unknown tag - '$_name'";
+            }
+        }
+
+        if ($_found) {
+            $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
+        } else {
+            // output error
+            $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.load_resource_plugin.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.load_resource_plugin.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.load_resource_plugin.php	(revision 298)
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * load a resource plugin
+ *
+ * @param string $type
+ */
+
+// $type
+
+function smarty_core_load_resource_plugin($params, &$smarty)
+{
+    /*
+     * Resource plugins are not quite like the other ones, so they are
+     * handled differently. The first element of plugin info is the array of
+     * functions provided by the plugin, the second one indicates whether
+     * all of them exist or not.
+     */
+
+    $_plugin = &$smarty->_plugins['resource'][$params['type']];
+    if (isset($_plugin)) {
+        if (!$_plugin[1] && count($_plugin[0])) {
+            $_plugin[1] = true;
+            foreach ($_plugin[0] as $_plugin_func) {
+                if (!is_callable($_plugin_func)) {
+                    $_plugin[1] = false;
+                    break;
+                }
+            }
+        }
+
+        if (!$_plugin[1]) {
+            $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
+        }
+
+        return;
+    }
+
+    $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
+    $_found = ($_plugin_file != false);
+
+    if ($_found) {            /*
+         * If the plugin file is found, it -must- provide the properly named
+         * plugin functions.
+         */
+        include_once($_plugin_file);
+
+        /*
+         * Locate functions that we require the plugin to provide.
+         */
+        $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
+        $_resource_funcs = array();
+        foreach ($_resource_ops as $_op) {
+            $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
+            if (!function_exists($_plugin_func)) {
+                $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
+                return;
+            } else {
+                $_resource_funcs[] = $_plugin_func;
+            }
+        }
+
+        $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.process_cached_inserts.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.process_cached_inserts.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.process_cached_inserts.php	(revision 298)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace cached inserts with the actual results
+ *
+ * @param string $results
+ * @return string
+ */
+function smarty_core_process_cached_inserts($params, &$smarty)
+{
+    preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
+                   $params['results'], $match);
+    list($cached_inserts, $insert_args) = $match;
+
+    for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $debug_start_time = smarty_core_get_microtime($_params, $smarty);
+        }
+
+        $args = unserialize($insert_args[$i]);
+        $name = $args['name'];
+
+        if (isset($args['script'])) {
+            $_params = array('resource_name' => $smarty->_dequote($args['script']));
+            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+            if(!smarty_core_get_php_resource($_params, $smarty)) {
+                return false;
+            }
+            $resource_type = $_params['resource_type'];
+            $php_resource = $_params['php_resource'];
+
+
+            if ($resource_type == 'file') {
+                $smarty->_include($php_resource, true);
+            } else {
+                $smarty->_eval($php_resource);
+            }
+        }
+
+        $function_name = $smarty->_plugins['insert'][$name][0];
+        if (empty($args['assign'])) {
+            $replace = $function_name($args, $smarty);
+        } else {
+            $smarty->assign($args['assign'], $function_name($args, $smarty));
+            $replace = '';
+        }
+
+        $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i]));
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
+                                                'filename'  => 'insert_'.$name,
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
+        }
+    }
+
+    return $params['results'];
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.process_compiled_include.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.process_compiled_include.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.process_compiled_include.php	(revision 298)
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace nocache-tags by results of the corresponding non-cacheable
+ * functions and return it
+ *
+ * @param string $compiled_tpl
+ * @param string $cached_source
+ * @return string
+ */
+
+function smarty_core_process_compiled_include($params, &$smarty)
+{
+    $_cache_including = $smarty->_cache_including;
+    $smarty->_cache_including = true;
+
+    $_return = $params['results'];
+
+    foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
+        $smarty->_include($_include_file_path, true);
+    }
+
+    foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) {
+        $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
+                                         array(&$smarty, '_process_compiled_include_callback'),
+                                         $_return);
+    }
+    $smarty->_cache_including = $_cache_including;
+    return $_return;
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.read_cache_file.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.read_cache_file.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.read_cache_file.php	(revision 298)
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * read a cache file, determine if it needs to be
+ * regenerated or not
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return boolean
+ */
+
+//  $tpl_file, $cache_id, $compile_id, &$results
+
+function smarty_core_read_cache_file(&$params, &$smarty)
+{
+    static  $content_cache = array();
+
+    if ($smarty->force_compile) {
+        // force compile enabled, always regenerate
+        return false;
+    }
+
+    if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
+        list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
+        return true;
+    }
+
+    if (!empty($smarty->cache_handler_func)) {
+        // use cache_handler function
+        call_user_func_array($smarty->cache_handler_func,
+                             array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+    } else {
+        // use local cache file
+        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+        $params['results'] = $smarty->_read_file($_cache_file);
+    }
+
+    if (empty($params['results'])) {
+        // nothing to parse (error?), regenerate cache
+        return false;
+    }
+
+    $_contents = $params['results'];
+    $_info_start = strpos($_contents, "\n") + 1;
+    $_info_len = (int)substr($_contents, 0, $_info_start - 1);
+    $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len));
+    $params['results'] = substr($_contents, $_info_start + $_info_len);
+
+    if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
+        // caching by expiration time
+        if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
+            // cache expired, regenerate
+            return false;
+        }
+    } else {
+        // caching by lifetime
+        if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
+            // cache expired, regenerate
+            return false;
+        }
+    }
+
+    if ($smarty->compile_check) {
+        $_params = array('get_source' => false, 'quiet'=>true);
+        foreach (array_keys($_cache_info['template']) as $_template_dep) {
+            $_params['resource_name'] = $_template_dep;
+            if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+                // template file has changed, regenerate cache
+                return false;
+            }
+        }
+
+        if (isset($_cache_info['config'])) {
+            $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
+            foreach (array_keys($_cache_info['config']) as $_config_dep) {
+                $_params['resource_name'] = $_config_dep;
+                if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+                    // config file has changed, regenerate cache
+                    return false;
+                }
+            }
+        }
+    }
+
+    $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
+
+    $smarty->_cache_info = $_cache_info;
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.rm_auto.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.rm_auto.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.rm_auto.php	(revision 298)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete an automagically created file by name and id
+ *
+ * @param string $auto_base
+ * @param string $auto_source
+ * @param string $auto_id
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
+
+function smarty_core_rm_auto($params, &$smarty)
+{
+    if (!@is_dir($params['auto_base']))
+      return false;
+
+    if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
+        $_params = array(
+            'dirname' => $params['auto_base'],
+            'level' => 0,
+            'exp_time' => $params['exp_time']
+        );
+        require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+        $_res = smarty_core_rmdir($_params, $smarty);
+    } else {
+        $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
+
+        if(isset($params['auto_source'])) {
+            if (isset($params['extensions'])) {
+                $_res = false;
+                foreach ((array)$params['extensions'] as $_extension)
+                    $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
+            } else {
+                $_res = $smarty->_unlink($_tname, $params['exp_time']);
+            }
+        } elseif ($smarty->use_sub_dirs) {
+            $_params = array(
+                'dirname' => $_tname,
+                'level' => 1,
+                'exp_time' => $params['exp_time']
+            );
+            require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
+            $_res = smarty_core_rmdir($_params, $smarty);
+        } else {
+            // remove matching file names
+            $_handle = opendir($params['auto_base']);
+            $_res = true;
+            while (false !== ($_filename = readdir($_handle))) {
+                if($_filename == '.' || $_filename == '..') {
+                    continue;
+                } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
+                    $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
+                }
+            }
+        }
+    }
+
+    return $_res;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.rmdir.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.rmdir.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.rmdir.php	(revision 298)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete a dir recursively (level=0 -> keep root)
+ * WARNING: no tests, it will try to remove what you tell it!
+ *
+ * @param string $dirname
+ * @param integer $level
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+//  $dirname, $level = 1, $exp_time = null
+
+function smarty_core_rmdir($params, &$smarty)
+{
+   if(!isset($params['level'])) { $params['level'] = 1; }
+   if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
+
+   if($_handle = @opendir($params['dirname'])) {
+
+        while (false !== ($_entry = readdir($_handle))) {
+            if ($_entry != '.' && $_entry != '..') {
+                if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
+                    $_params = array(
+                        'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
+                        'level' => $params['level'] + 1,
+                        'exp_time' => $params['exp_time']
+                    );
+                    smarty_core_rmdir($_params, $smarty);
+                }
+                else {
+                    $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
+                }
+            }
+        }
+        closedir($_handle);
+   }
+
+   if ($params['level']) {
+       return @rmdir($params['dirname']);
+   }
+   return (bool)$_handle;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.run_insert_handler.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.run_insert_handler.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.run_insert_handler.php	(revision 298)
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Handle insert tags
+ *
+ * @param array $args
+ * @return string
+ */
+function smarty_core_run_insert_handler($params, &$smarty)
+{
+
+    require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+    if ($smarty->debugging) {
+        $_params = array();
+        $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+    }
+
+    if ($smarty->caching) {
+        $_arg_string = serialize($params['args']);
+        $_name = $params['args']['name'];
+        if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
+            $smarty->_cache_info['insert_tags'][$_name] = array('insert',
+                                                             $_name,
+                                                             $smarty->_plugins['insert'][$_name][1],
+                                                             $smarty->_plugins['insert'][$_name][2],
+                                                             !empty($params['args']['script']) ? true : false);
+        }
+        return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
+    } else {
+        if (isset($params['args']['script'])) {
+            $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
+            require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+            if(!smarty_core_get_php_resource($_params, $smarty)) {
+                return false;
+            }
+
+            if ($_params['resource_type'] == 'file') {
+                $smarty->_include($_params['php_resource'], true);
+            } else {
+                $smarty->_eval($_params['php_resource']);
+            }
+            unset($params['args']['script']);
+        }
+
+        $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
+        $_content = $_funcname($params['args'], $smarty);
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'insert',
+                                                'filename'  => 'insert_'.$params['args']['name'],
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+        }
+
+        if (!empty($params['args']["assign"])) {
+            $smarty->assign($params['args']["assign"], $_content);
+        } else {
+            return $_content;
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.smarty_include_php.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.smarty_include_php.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.smarty_include_php.php	(revision 298)
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * called for included php files within templates
+ *
+ * @param string $smarty_file
+ * @param string $smarty_assign variable to assign the included template's
+ *               output into
+ * @param boolean $smarty_once uses include_once if this is true
+ * @param array $smarty_include_vars associative array of vars from
+ *              {include file="blah" var=$var}
+ */
+
+//  $file, $assign, $once, $_smarty_include_vars
+
+function smarty_core_smarty_include_php($params, &$smarty)
+{
+    $_params = array('resource_name' => $params['smarty_file']);
+    require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php');
+    smarty_core_get_php_resource($_params, $smarty);
+    $_smarty_resource_type = $_params['resource_type'];
+    $_smarty_php_resource = $_params['php_resource'];
+
+    if (!empty($params['smarty_assign'])) {
+        ob_start();
+        if ($_smarty_resource_type == 'file') {
+            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+        } else {
+            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+        }
+        $smarty->assign($params['smarty_assign'], ob_get_contents());
+        ob_end_clean();
+    } else {
+        if ($_smarty_resource_type == 'file') {
+            $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+        } else {
+            $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+        }
+    }
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.write_cache_file.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.write_cache_file.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.write_cache_file.php	(revision 298)
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Prepend the cache information to the cache file
+ * and write it
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return true|null
+ */
+
+ // $tpl_file, $cache_id, $compile_id, $results
+
+function smarty_core_write_cache_file($params, &$smarty)
+{
+
+    // put timestamp in cache header
+    $smarty->_cache_info['timestamp'] = time();
+    if ($smarty->cache_lifetime > -1){
+        // expiration set
+        $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
+    } else {
+        // cache will never expire
+        $smarty->_cache_info['expires'] = -1;
+    }
+
+    // collapse nocache.../nocache-tags
+    if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) {
+        // remove everything between every pair of outermost noache.../nocache-tags
+        // and replace it by a single nocache-tag
+        // this new nocache-tag will be replaced by dynamic contents in
+        // smarty_core_process_compiled_includes() on a cache-read
+        
+        $match_count = count($match[0]);
+        $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE);
+        
+        $level = 0;
+        $j = 0;
+        for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) {
+            if ($results[$i] == $match[0][$j]) {
+                // nocache tag
+                if ($match[1][$j]) { // closing tag
+                    $level--;
+                    unset($results[$i]);
+                } else { // opening tag
+                    if ($level++ > 0) unset($results[$i]);
+                }
+                $j++;
+            } elseif ($level > 0) {
+                unset($results[$i]);
+            }
+        }
+        $params['results'] = implode('', $results);
+    }
+    $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
+
+    // prepend the cache header info into cache file
+    $_cache_info = serialize($smarty->_cache_info);
+    $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results'];
+
+    if (!empty($smarty->cache_handler_func)) {
+        // use cache_handler function
+        call_user_func_array($smarty->cache_handler_func,
+                             array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+    } else {
+        // use local cache file
+
+        if(!@is_writable($smarty->cache_dir)) {
+            // cache_dir not writable, see if it exists
+            if(!@is_dir($smarty->cache_dir)) {
+                $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+                return false;
+            }
+            $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
+            return false;
+        }
+
+        $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+        $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+        $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
+        require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+        smarty_core_write_file($_params, $smarty);
+        return true;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.write_compiled_include.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.write_compiled_include.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.write_compiled_include.php	(revision 298)
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Extract non-cacheable parts out of compiled template and write it
+ *
+ * @param string $compile_path
+ * @param string $template_compiled
+ * @return boolean
+ */
+
+function smarty_core_write_compiled_include($params, &$smarty)
+{
+    $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
+    $_tag_end   = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
+
+    preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
+                   $params['compiled_content'], $_match_source, PREG_SET_ORDER);
+    
+    // no nocache-parts found: done
+    if (count($_match_source)==0) return;
+
+    // convert the matched php-code to functions
+    $_include_compiled =  "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+    $_include_compiled .= "         compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n";
+
+    $_compile_path = $params['include_file_path'];
+
+    $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
+    $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
+
+    $_include_compiled .= $params['plugins_code'];
+    $_include_compiled .= "<?php";
+
+    $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this';
+    for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
+        $_match =& $_match_source[$_i];
+        $source = $_match[4];
+        if ($this_varname == '_smarty') {
+            /* rename $this to $_smarty in the sourcecode */
+            $tokens = token_get_all('<?php ' . $_match[4]);
+
+            /* remove trailing <?php */
+            $open_tag = '';
+            while ($tokens) {
+                $token = array_shift($tokens);
+                if (is_array($token)) {
+                    $open_tag .= $token[1];
+                } else {
+                    $open_tag .= $token;
+                }
+                if ($open_tag == '<?php ') break;
+            }
+
+            for ($i=0, $count = count($tokens); $i < $count; $i++) {
+                if (is_array($tokens[$i])) {
+                    if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
+                        $tokens[$i] = '$' . $this_varname;
+                    } else {
+                        $tokens[$i] = $tokens[$i][1];
+                    }                   
+                }
+            }
+            $source = implode('', $tokens);
+        }
+
+        /* add function to compiled include */
+        $_include_compiled .= "
+function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname)
+{
+$source
+}
+
+";
+    }
+    $_include_compiled .= "\n\n?>\n";
+
+    $_params = array('filename' => $_compile_path,
+                     'contents' => $_include_compiled, 'create_dirs' => true);
+
+    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+    smarty_core_write_file($_params, $smarty);
+    return true;
+}
+
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.write_compiled_resource.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.write_compiled_resource.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.write_compiled_resource.php	(revision 298)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write the compiled resource
+ *
+ * @param string $compile_path
+ * @param string $compiled_content
+ * @return true
+ */
+function smarty_core_write_compiled_resource($params, &$smarty)
+{
+    if(!@is_writable($smarty->compile_dir)) {
+        // compile_dir not writable, see if it exists
+        if(!@is_dir($smarty->compile_dir)) {
+            $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+            return false;
+        }
+        $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
+        return false;
+    }
+
+    $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
+    require_once(SMARTY_CORE_DIR . 'core.write_file.php');
+    smarty_core_write_file($_params, $smarty);
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/internals/core.write_file.php
===================================================================
--- /trunk/htdocs2/smarty/libs/internals/core.write_file.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/internals/core.write_file.php	(revision 298)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write out a file to disk
+ *
+ * @param string $filename
+ * @param string $contents
+ * @param boolean $create_dirs
+ * @return boolean
+ */
+function smarty_core_write_file($params, &$smarty)
+{
+    $_dirname = dirname($params['filename']);
+
+    if ($params['create_dirs']) {
+        $_params = array('dir' => $_dirname);
+        require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php');
+        smarty_core_create_dir_structure($_params, $smarty);
+    }
+
+    // write to tmp file, then rename it to avoid file locking race condition
+    $_tmp_file = tempnam($_dirname, 'wrt');
+
+    if (!($fd = @fopen($_tmp_file, 'wb'))) {
+        $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt');
+        if (!($fd = @fopen($_tmp_file, 'wb'))) {
+            $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
+            return false;
+        }
+    }
+
+    fwrite($fd, $params['contents']);
+    fclose($fd);
+
+    if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
+        // On platforms and filesystems that cannot overwrite with rename() 
+        // delete the file before renaming it -- because windows always suffers
+        // this, it is short-circuited to avoid the initial rename() attempt
+        @unlink($params['filename']);
+        @rename($_tmp_file, $params['filename']);
+    }
+    @chmod($params['filename'], $smarty->_file_perms);
+
+    return true;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/block.textformat.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/block.textformat.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/block.textformat.php	(revision 298)
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {textformat}{/textformat} block plugin
+ *
+ * Type:     block function<br>
+ * Name:     textformat<br>
+ * Purpose:  format text a certain way with preset styles
+ *           or custom wrap/indent settings<br>
+ * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
+ *       (Smarty online manual)
+ * @param array
+ * <pre>
+ * Params:   style: string (email)
+ *           indent: integer (0)
+ *           wrap: integer (80)
+ *           wrap_char string ("\n")
+ *           indent_char: string (" ")
+ *           wrap_boundary: boolean (true)
+ * </pre>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param string contents of the block
+ * @param Smarty clever simulation of a method
+ * @return string string $content re-formatted
+ */
+function smarty_block_textformat($params, $content, &$smarty)
+{
+    if (is_null($content)) {
+        return;
+    }
+
+    $style = null;
+    $indent = 0;
+    $indent_first = 0;
+    $indent_char = ' ';
+    $wrap = 80;
+    $wrap_char = "\n";
+    $wrap_cut = false;
+    $assign = null;
+    
+    foreach ($params as $_key => $_val) {
+        switch ($_key) {
+            case 'style':
+            case 'indent_char':
+            case 'wrap_char':
+            case 'assign':
+                $$_key = (string)$_val;
+                break;
+
+            case 'indent':
+            case 'indent_first':
+            case 'wrap':
+                $$_key = (int)$_val;
+                break;
+
+            case 'wrap_cut':
+                $$_key = (bool)$_val;
+                break;
+
+            default:
+                $smarty->trigger_error("textformat: unknown attribute '$_key'");
+        }
+    }
+
+    if ($style == 'email') {
+        $wrap = 72;
+    }
+
+    // split into paragraphs
+    $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
+    $_output = '';
+
+    for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
+        if ($_paragraphs[$_x] == '') {
+            continue;
+        }
+        // convert mult. spaces & special chars to single space
+        $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
+        // indent first line
+        if($indent_first > 0) {
+            $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
+        }
+        // wordwrap sentences
+        $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
+        // indent lines
+        if($indent > 0) {
+            $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
+        }
+    }
+    $_output = implode($wrap_char . $wrap_char, $_paragraphs);
+
+    return $assign ? $smarty->assign($assign, $_output) : $_output;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/compiler.assign.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/compiler.assign.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/compiler.assign.php	(revision 298)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign} compiler function plugin
+ *
+ * Type:     compiler function<br>
+ * Name:     assign<br>
+ * Purpose:  assign a value to a template variable
+ * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com> (initial author)
+ * @auther messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
+ * @param string containing var-attribute and value-attribute
+ * @param Smarty_Compiler
+ */
+function smarty_compiler_assign($tag_attrs, &$compiler)
+{
+    $_params = $compiler->_parse_attrs($tag_attrs);
+
+    if (!isset($_params['var'])) {
+        $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
+        return;
+    }
+
+    if (!isset($_params['value'])) {
+        $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
+        return;
+    }
+
+    return "\$this->assign({$_params['var']}, {$_params['value']});";
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.assign_debug_info.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.assign_debug_info.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.assign_debug_info.php	(revision 298)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign_debug_info} function plugin
+ *
+ * Type:     function<br>
+ * Name:     assign_debug_info<br>
+ * Purpose:  assign debug info to the template<br>
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
+ *              {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
+ * @param Smarty
+ */
+function smarty_function_assign_debug_info($params, &$smarty)
+{
+    $assigned_vars = $smarty->_tpl_vars;
+    ksort($assigned_vars);
+    if (@is_array($smarty->_config[0])) {
+        $config_vars = $smarty->_config[0];
+        ksort($config_vars);
+        $smarty->assign("_debug_config_keys", array_keys($config_vars));
+        $smarty->assign("_debug_config_vals", array_values($config_vars));
+    }
+    
+    $included_templates = $smarty->_smarty_debug_info;
+    
+    $smarty->assign("_debug_keys", array_keys($assigned_vars));
+    $smarty->assign("_debug_vals", array_values($assigned_vars));
+    
+    $smarty->assign("_debug_tpls", $included_templates);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.config_load.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.config_load.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.config_load.php	(revision 298)
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {config_load} function plugin
+ *
+ * Type:     function<br>
+ * Name:     config_load<br>
+ * Purpose:  load config file vars
+ * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
+ * @param array Format:
+ * <pre>
+ * array('file' => required config file name,
+ *       'section' => optional config file section to load
+ *       'scope' => local/parent/global
+ *       'global' => overrides scope, setting to parent if true)
+ * </pre>
+ * @param Smarty
+ */
+function smarty_function_config_load($params, &$smarty)
+{
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+        }
+
+        $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
+        $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
+        $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
+        $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
+
+        if (!isset($_file) || strlen($_file) == 0) {
+            $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
+        }
+
+        if (isset($_scope)) {
+            if ($_scope != 'local' &&
+                $_scope != 'parent' &&
+                $_scope != 'global') {
+                $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
+            }
+        } else {
+            if ($_global) {
+                $_scope = 'parent';
+            } else {
+                $_scope = 'local';
+            }
+        }
+
+        $_params = array('resource_name' => $_file,
+                         'resource_base_path' => $smarty->config_dir,
+                         'get_source' => false);
+        $smarty->_parse_resource_name($_params);
+        $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
+        if (isset($_section))
+            $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
+        else
+            $_compile_file = $smarty->_get_compile_path($_file_path);
+
+        if($smarty->force_compile || !file_exists($_compile_file)) {
+            $_compile = true;
+        } elseif ($smarty->compile_check) {
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             'get_source' => false);
+            $_compile = $smarty->_fetch_resource_info($_params) &&
+                $_params['resource_timestamp'] > filemtime($_compile_file);
+        } else {
+            $_compile = false;
+        }
+
+        if($_compile) {
+            // compile config file
+            if(!is_object($smarty->_conf_obj)) {
+                require_once SMARTY_DIR . $smarty->config_class . '.class.php';
+                $smarty->_conf_obj = new $smarty->config_class();
+                $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
+                $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
+                $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
+                $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
+            }
+
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             $_params['get_source'] = true);
+            if (!$smarty->_fetch_resource_info($_params)) {
+                return;
+            }
+            $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
+            $_config_vars = array_merge($smarty->_conf_obj->get($_file),
+                    $smarty->_conf_obj->get($_file, $_section));
+            if(function_exists('var_export')) {
+                $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
+            } else {
+                $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
+            }
+            $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $smarty);
+        } else {
+            include($_compile_file);
+        }
+
+        if ($smarty->caching) {
+            $smarty->_cache_info['config'][$_file] = true;
+        }
+
+        $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
+        $smarty->_config[0]['files'][$_file] = true;
+
+        if ($_scope == 'parent') {
+                $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
+                $smarty->_config[1]['files'][$_file] = true;
+        } else if ($_scope == 'global') {
+            for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
+                $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
+                $smarty->_config[$i]['files'][$_file] = true;
+            }
+        }
+
+        if ($smarty->debugging) {
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
+            $smarty->_smarty_debug_info[] = array('type'      => 'config',
+                                                'filename'  => $_file.' ['.$_section.'] '.$_scope,
+                                                'depth'     => $smarty->_inclusion_depth,
+                                                'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+        }
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.counter.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.counter.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.counter.php	(revision 298)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {counter} function plugin
+ *
+ * Type:     function<br>
+ * Name:     counter<br>
+ * Purpose:  print out a counter value
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
+ *       (Smarty online manual)
+ * @param array parameters
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_counter($params, &$smarty)
+{
+    static $counters = array();
+
+    $name = (isset($params['name'])) ? $params['name'] : 'default';
+    if (!isset($counters[$name])) {
+        $counters[$name] = array(
+            'start'=>1,
+            'skip'=>1,
+            'direction'=>'up',
+            'count'=>1
+            );
+    }
+    $counter =& $counters[$name];
+
+    if (isset($params['start'])) {
+        $counter['start'] = $counter['count'] = (int)$params['start'];
+    }
+
+    if (!empty($params['assign'])) {
+        $counter['assign'] = $params['assign'];
+    }
+
+    if (isset($counter['assign'])) {
+        $smarty->assign($counter['assign'], $counter['count']);
+    }
+    
+    if (isset($params['print'])) {
+        $print = (bool)$params['print'];
+    } else {
+        $print = empty($counter['assign']);
+    }
+
+    if ($print) {
+        $retval = $counter['count'];
+    } else {
+        $retval = null;
+    }
+
+    if (isset($params['skip'])) {
+        $counter['skip'] = $params['skip'];
+    }
+    
+    if (isset($params['direction'])) {
+        $counter['direction'] = $params['direction'];
+    }
+
+    if ($counter['direction'] == "down")
+        $counter['count'] -= $counter['skip'];
+    else
+        $counter['count'] += $counter['skip'];
+    
+    return $retval;
+    
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.cycle.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.cycle.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.cycle.php	(revision 298)
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {cycle} function plugin
+ *
+ * Type:     function<br>
+ * Name:     cycle<br>
+ * Date:     May 3, 2002<br>
+ * Purpose:  cycle through given values<br>
+ * Input:
+ *         - name = name of cycle (optional)
+ *         - values = comma separated list of values to cycle,
+ *                    or an array of values to cycle
+ *                    (this can be left out for subsequent calls)
+ *         - reset = boolean - resets given var to true
+ *         - print = boolean - print var or not. default is true
+ *         - advance = boolean - whether or not to advance the cycle
+ *         - delimiter = the value delimiter, default is ","
+ *         - assign = boolean, assigns to template var instead of
+ *                    printed.
+ *
+ * Examples:<br>
+ * <pre>
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Mark Priatel <mpriatel@rogers.com>
+ * @author credit to Gerard <gerard@interfold.com>
+ * @author credit to Jason Sweat <jsweat_php@yahoo.com>
+ * @version  1.3
+ * @param array
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_cycle($params, &$smarty)
+{
+    static $cycle_vars;
+    
+    $name = (empty($params['name'])) ? 'default' : $params['name'];
+    $print = (isset($params['print'])) ? (bool)$params['print'] : true;
+    $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
+    $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
+            
+    if (!in_array('values', array_keys($params))) {
+        if(!isset($cycle_vars[$name]['values'])) {
+            $smarty->trigger_error("cycle: missing 'values' parameter");
+            return;
+        }
+    } else {
+        if(isset($cycle_vars[$name]['values'])
+            && $cycle_vars[$name]['values'] != $params['values'] ) {
+            $cycle_vars[$name]['index'] = 0;
+        }
+        $cycle_vars[$name]['values'] = $params['values'];
+    }
+
+    $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
+    
+    if(is_array($cycle_vars[$name]['values'])) {
+        $cycle_array = $cycle_vars[$name]['values'];
+    } else {
+        $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
+    }
+    
+    if(!isset($cycle_vars[$name]['index']) || $reset ) {
+        $cycle_vars[$name]['index'] = 0;
+    }
+    
+    if (isset($params['assign'])) {
+        $print = false;
+        $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
+    }
+        
+    if($print) {
+        $retval = $cycle_array[$cycle_vars[$name]['index']];
+    } else {
+        $retval = null;
+    }
+
+    if($advance) {
+        if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
+            $cycle_vars[$name]['index'] = 0;
+        } else {
+            $cycle_vars[$name]['index']++;
+        }
+    }
+    
+    return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.debug.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.debug.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.debug.php	(revision 298)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {debug} function plugin
+ *
+ * Type:     function<br>
+ * Name:     debug<br>
+ * Date:     July 1, 2002<br>
+ * Purpose:  popup debug window
+ * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
+ *       (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version  1.0
+ * @param array
+ * @param Smarty
+ * @return string output from {@link Smarty::_generate_debug_output()}
+ */
+function smarty_function_debug($params, &$smarty)
+{
+    if (isset($params['output'])) {
+        $smarty->assign('_smarty_debug_output', $params['output']);
+    }
+    require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
+    return smarty_core_display_debug_console(null, $smarty);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.eval.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.eval.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.eval.php	(revision 298)
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {eval} function plugin
+ *
+ * Type:     function<br>
+ * Name:     eval<br>
+ * Purpose:  evaluate a template variable as a template<br>
+ * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ */
+function smarty_function_eval($params, &$smarty)
+{
+
+    if (!isset($params['var'])) {
+        $smarty->trigger_error("eval: missing 'var' parameter");
+        return;
+    }
+
+    if($params['var'] == '') {
+        return;
+    }
+
+    $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
+
+    ob_start();
+    $smarty->_eval('?>' . $_var_compiled);
+    $_contents = ob_get_contents();
+    ob_end_clean();
+
+    if (!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_contents);
+    } else {
+        return $_contents;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.fetch.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.fetch.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.fetch.php	(revision 298)
@@ -0,0 +1,221 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {fetch} plugin
+ *
+ * Type:     function<br>
+ * Name:     fetch<br>
+ * Purpose:  fetch file, web or ftp data and display results
+ * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
+ *       (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string|null if the assign parameter is passed, Smarty assigns the
+ *                     result to a template variable
+ */
+function smarty_function_fetch($params, &$smarty)
+{
+    if (empty($params['file'])) {
+        $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
+        return;
+    }
+
+    $content = '';
+    if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
+        $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
+        require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
+        if(!smarty_core_is_secure($_params, $smarty)) {
+            $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
+            return;
+        }
+        
+        // fetch the file
+        if($fp = @fopen($params['file'],'r')) {
+            while(!feof($fp)) {
+                $content .= fgets ($fp,4096);
+            }
+            fclose($fp);
+        } else {
+            $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
+            return;
+        }
+    } else {
+        // not a local file
+        if(preg_match('!^http://!i',$params['file'])) {
+            // http fetch
+            if($uri_parts = parse_url($params['file'])) {
+                // set defaults
+                $host = $server_name = $uri_parts['host'];
+                $timeout = 30;
+                $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
+                $agent = "Smarty Template Engine ".$smarty->_version;
+                $referer = "";
+                $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
+                $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
+                $_is_proxy = false;
+                if(empty($uri_parts['port'])) {
+                    $port = 80;
+                } else {
+                    $port = $uri_parts['port'];
+                }
+                if(!empty($uri_parts['user'])) {
+                    $user = $uri_parts['user'];
+                }
+                if(!empty($uri_parts['pass'])) {
+                    $pass = $uri_parts['pass'];
+                }
+                // loop through parameters, setup headers
+                foreach($params as $param_key => $param_value) {
+                    switch($param_key) {
+                        case "file":
+                        case "assign":
+                        case "assign_headers":
+                            break;
+                        case "user":
+                            if(!empty($param_value)) {
+                                $user = $param_value;
+                            }
+                            break;
+                        case "pass":
+                            if(!empty($param_value)) {
+                                $pass = $param_value;
+                            }
+                            break;
+                        case "accept":
+                            if(!empty($param_value)) {
+                                $accept = $param_value;
+                            }
+                            break;
+                        case "header":
+                            if(!empty($param_value)) {
+                                if(!preg_match('![\w\d-]+: .+!',$param_value)) {
+                                    $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
+                                    return;
+                                } else {
+                                    $extra_headers[] = $param_value;
+                                }
+                            }
+                            break;
+                        case "proxy_host":
+                            if(!empty($param_value)) {
+                                $proxy_host = $param_value;
+                            }
+                            break;
+                        case "proxy_port":
+                            if(!preg_match('!\D!', $param_value)) {
+                                $proxy_port = (int) $param_value;
+                            } else {
+                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+                                return;
+                            }
+                            break;
+                        case "agent":
+                            if(!empty($param_value)) {
+                                $agent = $param_value;
+                            }
+                            break;
+                        case "referer":
+                            if(!empty($param_value)) {
+                                $referer = $param_value;
+                            }
+                            break;
+                        case "timeout":
+                            if(!preg_match('!\D!', $param_value)) {
+                                $timeout = (int) $param_value;
+                            } else {
+                                $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+                                return;
+                            }
+                            break;
+                        default:
+                            $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
+                            return;
+                    }
+                }
+                if(!empty($proxy_host) && !empty($proxy_port)) {
+                    $_is_proxy = true;
+                    $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
+                } else {
+                    $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
+                }
+
+                if(!$fp) {
+                    $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
+                    return;
+                } else {
+                    if($_is_proxy) {
+                        fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
+                    } else {
+                        fputs($fp, "GET $uri HTTP/1.0\r\n");
+                    }
+                    if(!empty($host)) {
+                        fputs($fp, "Host: $host\r\n");
+                    }
+                    if(!empty($accept)) {
+                        fputs($fp, "Accept: $accept\r\n");
+                    }
+                    if(!empty($agent)) {
+                        fputs($fp, "User-Agent: $agent\r\n");
+                    }
+                    if(!empty($referer)) {
+                        fputs($fp, "Referer: $referer\r\n");
+                    }
+                    if(isset($extra_headers) && is_array($extra_headers)) {
+                        foreach($extra_headers as $curr_header) {
+                            fputs($fp, $curr_header."\r\n");
+                        }
+                    }
+                    if(!empty($user) && !empty($pass)) {
+                        fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
+                    }
+
+                    fputs($fp, "\r\n");
+                    while(!feof($fp)) {
+                        $content .= fgets($fp,4096);
+                    }
+                    fclose($fp);
+                    $csplit = split("\r\n\r\n",$content,2);
+
+                    $content = $csplit[1];
+
+                    if(!empty($params['assign_headers'])) {
+                        $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
+                    }
+                }
+            } else {
+                $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
+                return;
+            }
+        } else {
+            // ftp fetch
+            if($fp = @fopen($params['file'],'r')) {
+                while(!feof($fp)) {
+                    $content .= fgets ($fp,4096);
+                }
+                fclose($fp);
+            } else {
+                $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
+                return;
+            }
+        }
+
+    }
+
+
+    if (!empty($params['assign'])) {
+        $smarty->assign($params['assign'],$content);
+    } else {
+        return $content;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.html_checkboxes.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.html_checkboxes.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.html_checkboxes.php	(revision 298)
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_checkboxes} function plugin
+ *
+ * File:       function.html_checkboxes.php<br>
+ * Type:       function<br>
+ * Name:       html_checkboxes<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of checkbox input types<br>
+ * Input:<br>
+ *           - name       (optional) - string default "checkbox"
+ *           - values     (required) - array
+ *           - options    (optional) - associative array
+ *           - checked    (optional) - array default not set
+ *           - separator  (optional) - ie <br> or &nbsp;
+ *           - output     (optional) - the output next to each checkbox
+ *           - assign     (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
+ * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ *      (Smarty online manual)
+ * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version    1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_checkboxes($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+    $name = 'checkbox';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $output = null;
+
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = $_val;
+                break;
+
+            case 'labels':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'checked':
+            case 'selected':
+                $selected = array_map('strval', array_values((array)$_val));
+                break;
+
+            case 'checkboxes':
+                $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    settype($selected, 'array');
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+
+
+    } else {
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
+
+}
+
+function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
+    $_output = '';
+    if ($labels) $_output .= '<label>';
+    $_output .= '<input type="checkbox" name="'
+        . smarty_function_escape_special_chars($name) . '[]" value="'
+        . smarty_function_escape_special_chars($value) . '"';
+
+    if (in_array((string)$value, $selected)) {
+        $_output .= ' checked="checked"';
+    }
+    $_output .= $extra . ' />' . $output;
+    if ($labels) $_output .= '</label>';
+    $_output .=  $separator;
+
+    return $_output;
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.html_image.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.html_image.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.html_image.php	(revision 298)
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_image} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_image<br>
+ * Date:     Feb 24, 2003<br>
+ * Purpose:  format HTML tags for the image<br>
+ * Input:<br>
+ *         - file = file (and path) of image (required)
+ *         - height = image height (optional, default actual height)
+ *         - width = image width (optional, default actual width)
+ *         - basedir = base directory for absolute paths, default
+ *                     is environment variable DOCUMENT_ROOT
+ *         - path_prefix = prefix for path output (optional, default empty)
+ *
+ * Examples: {html_image file="/images/masthead.gif"}
+ * Output:   <img src="/images/masthead.gif" width=400 height=23>
+ * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
+ *      (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author credits to Duda <duda@big.hu> - wrote first image function
+ *           in repository, helped with lots of functionality
+ * @version  1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_image($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    
+    $alt = '';
+    $file = '';
+    $height = '';
+    $width = '';
+    $extra = '';
+    $prefix = '';
+    $suffix = '';
+    $path_prefix = '';
+    $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+    $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'file':
+            case 'height':
+            case 'width':
+            case 'dpi':
+            case 'path_prefix':
+            case 'basedir':
+                $$_key = $_val;
+                break;
+
+            case 'alt':
+                if(!is_array($_val)) {
+                    $$_key = smarty_function_escape_special_chars($_val);
+                } else {
+                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+
+            case 'link':
+            case 'href':
+                $prefix = '<a href="' . $_val . '">';
+                $suffix = '</a>';
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (empty($file)) {
+        $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
+        return;
+    }
+
+    if (substr($file,0,1) == '/') {
+        $_image_path = $basedir . $file;
+    } else {
+        $_image_path = $file;
+    }
+    
+    if(!isset($params['width']) || !isset($params['height'])) {
+        if(!$_image_data = @getimagesize($_image_path)) {
+            if(!file_exists($_image_path)) {
+                $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
+                return;
+            } else if(!is_readable($_image_path)) {
+                $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
+                return;
+            } else {
+                $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
+                return;
+            }
+        }
+        if ($smarty->security &&
+            ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
+            (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
+            (!smarty_core_is_secure($_params, $smarty)) ) {
+            $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
+        }        
+        
+        if(!isset($params['width'])) {
+            $width = $_image_data[0];
+        }
+        if(!isset($params['height'])) {
+            $height = $_image_data[1];
+        }
+
+    }
+
+    if(isset($params['dpi'])) {
+        if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
+            $dpi_default = 72;
+        } else {
+            $dpi_default = 96;
+        }
+        $_resize = $dpi_default/$params['dpi'];
+        $width = round($width * $_resize);
+        $height = round($height * $_resize);
+    }
+
+    return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.html_options.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.html_options.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.html_options.php	(revision 298)
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_options} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_options<br>
+ * Input:<br>
+ *           - name       (optional) - string default "select"
+ *           - values     (required if no options supplied) - array
+ *           - options    (required if no values supplied) - associative array
+ *           - selected   (optional) - string default not set
+ *           - output     (required if not options supplied) - array
+ * Purpose:  Prints the list of <option> tags generated from
+ *           the passed parameters
+ * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
+ *      (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_options($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    
+    $name = null;
+    $values = null;
+    $options = null;
+    $selected = array();
+    $output = null;
+    
+    $extra = '';
+    
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+                $$_key = (string)$_val;
+                break;
+            
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+                
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'selected':
+                $$_key = array_map('strval', array_values((array)$_val));
+                break;
+                
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = '';
+
+    if (isset($options)) {
+        
+        foreach ($options as $_key=>$_val)
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+
+    } else {
+        
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+        }
+
+    }
+
+    if(!empty($name)) {
+        $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
+    }
+
+    return $_html_result;
+
+}
+
+function smarty_function_html_options_optoutput($key, $value, $selected) {
+    if(!is_array($value)) {
+        $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
+            smarty_function_escape_special_chars($key) . '"';
+        if (in_array((string)$key, $selected))
+            $_html_result .= ' selected="selected"';
+        $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
+    } else {
+        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
+    }
+    return $_html_result;
+}
+
+function smarty_function_html_options_optgroup($key, $values, $selected) {
+    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
+    foreach ($values as $key => $value) {
+        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
+    }
+    $optgroup_html .= "</optgroup>\n";
+    return $optgroup_html;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.html_radios.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.html_radios.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.html_radios.php	(revision 298)
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_radios} function plugin
+ *
+ * File:       function.html_radios.php<br>
+ * Type:       function<br>
+ * Name:       html_radios<br>
+ * Date:       24.Feb.2003<br>
+ * Purpose:    Prints out a list of radio input types<br>
+ * Input:<br>
+ *           - name       (optional) - string default "radio"
+ *           - values     (required) - array
+ *           - options    (optional) - associative array
+ *           - checked    (optional) - array default not set
+ *           - separator  (optional) - ie <br> or &nbsp;
+ *           - output     (optional) - the output next to each radio button
+ *           - assign     (optional) - assign the output as an array to this variable
+ * Examples:
+ * <pre>
+ * {html_radios values=$ids output=$names}
+ * {html_radios values=$ids name='box' separator='<br>' output=$names}
+ * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ *      (Smarty online manual)
+ * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte at ohrt dot com>
+ * @version    1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_radios($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+   
+    $name = 'radio';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $label_ids = false;
+    $output = null;
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = (string)$_val;
+                break;
+
+            case 'checked':
+            case 'selected':
+                if(is_array($_val)) {
+                    $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+                } else {
+                    $selected = (string)$_val;
+                }
+                break;
+
+            case 'labels':
+            case 'label_ids':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'radios':
+                $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+
+    } else {
+
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
+
+}
+
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
+    $_output = '';
+    if ($labels) {
+      if($label_ids) {
+          $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
+          $_output .= '<label for="' . $_id . '">';
+      } else {
+          $_output .= '<label>';           
+      }
+   }
+   $_output .= '<input type="radio" name="'
+        . smarty_function_escape_special_chars($name) . '" value="'
+        . smarty_function_escape_special_chars($value) . '"';
+
+   if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
+
+    if ((string)$value==$selected) {
+        $_output .= ' checked="checked"';
+    }
+    $_output .= $extra . ' />' . $output;
+    if ($labels) $_output .= '</label>';
+    $_output .=  $separator;
+
+    return $_output;
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.html_select_date.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.html_select_date.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.html_select_date.php	(revision 298)
@@ -0,0 +1,331 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {html_select_date} plugin
+ *
+ * Type:     function<br>
+ * Name:     html_select_date<br>
+ * Purpose:  Prints the dropdowns for date selection.
+ *
+ * ChangeLog:<br>
+ *           - 1.0 initial release
+ *           - 1.1 added support for +/- N syntax for begin
+ *                and end year values. (Monte)
+ *           - 1.2 added support for yyyy-mm-dd syntax for
+ *                time value. (Jan Rosier)
+ *           - 1.3 added support for choosing format for
+ *                month values (Gary Loescher)
+ *           - 1.3.1 added support for choosing format for
+ *                day values (Marcus Bointon)
+ *           - 1.3.2 support negative timestamps, force year
+ *             dropdown to include given date unless explicitly set (Monte)
+ *           - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
+ *             of 0000-00-00 dates (cybot, boots)
+ * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
+ *      (Smarty online manual)
+ * @version 1.3.4
+ * @author Andrei Zmievski
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_select_date($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+    /* Default values. */
+    $prefix          = "Date_";
+    $start_year      = strftime("%Y");
+    $end_year        = $start_year;
+    $display_days    = true;
+    $display_months  = true;
+    $display_years   = true;
+    $month_format    = "%B";
+    /* Write months as numbers by default  GL */
+    $month_value_format = "%m";
+    $day_format      = "%02d";
+    /* Write day values using this format MB */
+    $day_value_format = "%d";
+    $year_as_text    = false;
+    /* Display years in reverse order? Ie. 2000,1999,.... */
+    $reverse_years   = false;
+    /* Should the select boxes be part of an array when returned from PHP?
+       e.g. setting it to "birthday", would create "birthday[Day]",
+       "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
+    $field_array     = null;
+    /* <select size>'s of the different <select> tags.
+       If not set, uses default dropdown. */
+    $day_size        = null;
+    $month_size      = null;
+    $year_size       = null;
+    /* Unparsed attributes common to *ALL* the <select>/<input> tags.
+       An example might be in the template: all_extra ='class ="foo"'. */
+    $all_extra       = null;
+    /* Separate attributes for the tags. */
+    $day_extra       = null;
+    $month_extra     = null;
+    $year_extra      = null;
+    /* Order in which to display the fields.
+       "D" -> day, "M" -> month, "Y" -> year. */
+    $field_order     = 'MDY';
+    /* String printed between the different fields. */
+    $field_separator = "\n";
+    $time = time();
+    $all_empty       = null;
+    $day_empty       = null;
+    $month_empty     = null;
+    $year_empty      = null;
+    $extra_attrs     = '';
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'prefix':
+            case 'time':
+            case 'start_year':
+            case 'end_year':
+            case 'month_format':
+            case 'day_format':
+            case 'day_value_format':
+            case 'field_array':
+            case 'day_size':
+            case 'month_size':
+            case 'year_size':
+            case 'all_extra':
+            case 'day_extra':
+            case 'month_extra':
+            case 'year_extra':
+            case 'field_order':
+            case 'field_separator':
+            case 'month_value_format':
+            case 'month_empty':
+            case 'day_empty':
+            case 'year_empty':
+                $$_key = (string)$_value;
+                break;
+
+            case 'all_empty':
+                $$_key = (string)$_value;
+                $day_empty = $month_empty = $year_empty = $all_empty;
+                break;
+
+            case 'display_days':
+            case 'display_months':
+            case 'display_years':
+            case 'year_as_text':
+            case 'reverse_years':
+                $$_key = (bool)$_value;
+                break;
+
+            default:
+                if(!is_array($_value)) {
+                    $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
+                } else {
+                    $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (preg_match('!^-\d+$!', $time)) {
+        // negative timestamp, use date()
+        $time = date('Y-m-d', $time);
+    }
+    // If $time is not in format yyyy-mm-dd
+    if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
+        $time = $found[1];
+    } else {
+        // use smarty_make_timestamp to get an unix timestamp and
+        // strftime to make yyyy-mm-dd
+        $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
+    }
+    // Now split this in pieces, which later can be used to set the select
+    $time = explode("-", $time);
+
+    // make syntax "+N" or "-N" work with start_year and end_year
+    if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
+        if ($match[1] == '+') {
+            $end_year = strftime('%Y') + $match[2];
+        } else {
+            $end_year = strftime('%Y') - $match[2];
+        }
+    }
+    if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
+        if ($match[1] == '+') {
+            $start_year = strftime('%Y') + $match[2];
+        } else {
+            $start_year = strftime('%Y') - $match[2];
+        }
+    }
+    if (strlen($time[0]) > 0) {
+        if ($start_year > $time[0] && !isset($params['start_year'])) {
+            // force start year to include given date if not explicitly set
+            $start_year = $time[0];
+        }
+        if($end_year < $time[0] && !isset($params['end_year'])) {
+            // force end year to include given date if not explicitly set
+            $end_year = $time[0];
+        }
+    }
+
+    $field_order = strtoupper($field_order);
+
+    $html_result = $month_result = $day_result = $year_result = "";
+
+    $field_separator_count = -1;
+    if ($display_months) {
+    	$field_separator_count++;
+        $month_names = array();
+        $month_values = array();
+        if(isset($month_empty)) {
+            $month_names[''] = $month_empty;
+            $month_values[''] = '';
+        }
+        for ($i = 1; $i <= 12; $i++) {
+            $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
+            $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
+        }
+
+        $month_result .= '<select name=';
+        if (null !== $field_array){
+            $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
+        } else {
+            $month_result .= '"' . $prefix . 'Month"';
+        }
+        if (null !== $month_size){
+            $month_result .= ' size="' . $month_size . '"';
+        }
+        if (null !== $month_extra){
+            $month_result .= ' ' . $month_extra;
+        }
+        if (null !== $all_extra){
+            $month_result .= ' ' . $all_extra;
+        }
+        $month_result .= $extra_attrs . '>'."\n";
+
+        $month_result .= smarty_function_html_options(array('output'     => $month_names,
+                                                            'values'     => $month_values,
+                                                            'selected'   => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
+                                                            'print_result' => false),
+                                                      $smarty);
+        $month_result .= '</select>';
+    }
+
+    if ($display_days) {
+    	$field_separator_count++;
+        $days = array();
+        if (isset($day_empty)) {
+            $days[''] = $day_empty;
+            $day_values[''] = '';
+        }
+        for ($i = 1; $i <= 31; $i++) {
+            $days[] = sprintf($day_format, $i);
+            $day_values[] = sprintf($day_value_format, $i);
+        }
+
+        $day_result .= '<select name=';
+        if (null !== $field_array){
+            $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
+        } else {
+            $day_result .= '"' . $prefix . 'Day"';
+        }
+        if (null !== $day_size){
+            $day_result .= ' size="' . $day_size . '"';
+        }
+        if (null !== $all_extra){
+            $day_result .= ' ' . $all_extra;
+        }
+        if (null !== $day_extra){
+            $day_result .= ' ' . $day_extra;
+        }
+        $day_result .= $extra_attrs . '>'."\n";
+        $day_result .= smarty_function_html_options(array('output'     => $days,
+                                                          'values'     => $day_values,
+                                                          'selected'   => $time[2],
+                                                          'print_result' => false),
+                                                    $smarty);
+        $day_result .= '</select>';
+    }
+
+    if ($display_years) {
+    	$field_separator_count++;
+        if (null !== $field_array){
+            $year_name = $field_array . '[' . $prefix . 'Year]';
+        } else {
+            $year_name = $prefix . 'Year';
+        }
+        if ($year_as_text) {
+            $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
+            if (null !== $all_extra){
+                $year_result .= ' ' . $all_extra;
+            }
+            if (null !== $year_extra){
+                $year_result .= ' ' . $year_extra;
+            }
+            $year_result .= ' />';
+        } else {
+            $years = range((int)$start_year, (int)$end_year);
+            if ($reverse_years) {
+                rsort($years, SORT_NUMERIC);
+            } else {
+                sort($years, SORT_NUMERIC);
+            }
+            $yearvals = $years;
+            if(isset($year_empty)) {
+                array_unshift($years, $year_empty);
+                array_unshift($yearvals, '');
+            }
+            $year_result .= '<select name="' . $year_name . '"';
+            if (null !== $year_size){
+                $year_result .= ' size="' . $year_size . '"';
+            }
+            if (null !== $all_extra){
+                $year_result .= ' ' . $all_extra;
+            }
+            if (null !== $year_extra){
+                $year_result .= ' ' . $year_extra;
+            }
+            $year_result .= $extra_attrs . '>'."\n";
+            $year_result .= smarty_function_html_options(array('output' => $years,
+                                                               'values' => $yearvals,
+                                                               'selected'   => $time[0],
+                                                               'print_result' => false),
+                                                         $smarty);
+            $year_result .= '</select>';
+        }
+    }
+
+    // Loop thru the field_order field
+    for ($i = 0; $i <= 2; $i++){
+        $c = substr($field_order, $i, 1);
+        switch ($c){
+            case 'D':
+                $html_result .= $day_result;
+                break;
+
+            case 'M':
+                $html_result .= $month_result;
+                break;
+
+            case 'Y':
+                $html_result .= $year_result;
+                break;
+        }
+        // Add the field seperator
+        if($i < $field_separator_count) {
+            $html_result .= $field_separator;
+        }
+    }
+
+    return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.html_select_time.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.html_select_time.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.html_select_time.php	(revision 298)
@@ -0,0 +1,194 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_select_time} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_select_time<br>
+ * Purpose:  Prints the dropdowns for time selection
+ * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
+ *          (Smarty online manual)
+ * @author Roberto Berto <roberto@berto.net>
+ * @credits Monte Ohrt <monte AT ohrt DOT com>
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_make_timestamp()
+ */
+function smarty_function_html_select_time($params, &$smarty)
+{
+    require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+    require_once $smarty->_get_plugin_filepath('function','html_options');
+    /* Default values. */
+    $prefix             = "Time_";
+    $time               = time();
+    $display_hours      = true;
+    $display_minutes    = true;
+    $display_seconds    = true;
+    $display_meridian   = true;
+    $use_24_hours       = true;
+    $minute_interval    = 1;
+    $second_interval    = 1;
+    /* Should the select boxes be part of an array when returned from PHP?
+       e.g. setting it to "birthday", would create "birthday[Hour]",
+       "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
+       Can be combined with prefix. */
+    $field_array        = null;
+    $all_extra          = null;
+    $hour_extra         = null;
+    $minute_extra       = null;
+    $second_extra       = null;
+    $meridian_extra     = null;
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'prefix':
+            case 'time':
+            case 'field_array':
+            case 'all_extra':
+            case 'hour_extra':
+            case 'minute_extra':
+            case 'second_extra':
+            case 'meridian_extra':
+                $$_key = (string)$_value;
+                break;
+
+            case 'display_hours':
+            case 'display_minutes':
+            case 'display_seconds':
+            case 'display_meridian':
+            case 'use_24_hours':
+                $$_key = (bool)$_value;
+                break;
+
+            case 'minute_interval':
+            case 'second_interval':
+                $$_key = (int)$_value;
+                break;
+
+            default:
+                $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
+        }
+    }
+
+    $time = smarty_make_timestamp($time);
+
+    $html_result = '';
+
+    if ($display_hours) {
+        $hours       = $use_24_hours ? range(0, 23) : range(1, 12);
+        $hour_fmt = $use_24_hours ? '%H' : '%I';
+        for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
+            $hours[$i] = sprintf('%02d', $hours[$i]);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Hour"';
+        }
+        if (null !== $hour_extra){
+            $html_result .= ' ' . $hour_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        $html_result .= smarty_function_html_options(array('output'          => $hours,
+                                                           'values'          => $hours,
+                                                           'selected'      => strftime($hour_fmt, $time),
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_minutes) {
+        $all_minutes = range(0, 59);
+        for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
+            $minutes[] = sprintf('%02d', $all_minutes[$i]);
+        $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Minute"';
+        }
+        if (null !== $minute_extra){
+            $html_result .= ' ' . $minute_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => $minutes,
+                                                           'values'          => $minutes,
+                                                           'selected'      => $selected,
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_seconds) {
+        $all_seconds = range(0, 59);
+        for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
+            $seconds[] = sprintf('%02d', $all_seconds[$i]);
+        $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Second"';
+        }
+        
+        if (null !== $second_extra){
+            $html_result .= ' ' . $second_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => $seconds,
+                                                           'values'          => $seconds,
+                                                           'selected'      => $selected,
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    if ($display_meridian && !$use_24_hours) {
+        $html_result .= '<select name=';
+        if (null !== $field_array) {
+            $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
+        } else {
+            $html_result .= '"' . $prefix . 'Meridian"';
+        }
+        
+        if (null !== $meridian_extra){
+            $html_result .= ' ' . $meridian_extra;
+        }
+        if (null !== $all_extra){
+            $html_result .= ' ' . $all_extra;
+        }
+        $html_result .= '>'."\n";
+        
+        $html_result .= smarty_function_html_options(array('output'          => array('AM', 'PM'),
+                                                           'values'          => array('am', 'pm'),
+                                                           'selected'      => strtolower(strftime('%p', $time)),
+                                                           'print_result' => false),
+                                                     $smarty);
+        $html_result .= "</select>\n";
+    }
+
+    return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.html_table.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.html_table.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.html_table.php	(revision 298)
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_table} function plugin
+ *
+ * Type:     function<br>
+ * Name:     html_table<br>
+ * Date:     Feb 17, 2003<br>
+ * Purpose:  make an html table from an array of data<br>
+ * Input:<br>
+ *         - loop = array to loop through
+ *         - cols = number of columns, comma separated list of column names
+ *                  or array of column names
+ *         - rows = number of rows
+ *         - table_attr = table attributes
+ *         - th_attr = table heading attributes (arrays are cycled)
+ *         - tr_attr = table row attributes (arrays are cycled)
+ *         - td_attr = table cell attributes (arrays are cycled)
+ *         - trailpad = value to pad trailing cells with
+ *         - caption = text for caption element 
+ *         - vdir = vertical direction (default: "down", means top-to-bottom)
+ *         - hdir = horizontal direction (default: "right", means left-to-right)
+ *         - inner = inner loop (default "cols": print $loop line by line,
+ *                   $loop will be printed column by column otherwise)
+ *
+ *
+ * Examples:
+ * <pre>
+ * {table loop=$data}
+ * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
+ * {table loop=$data cols="first,second,third" tr_attr=$colors}
+ * </pre>
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
+ * @author credit to boots <boots dot smarty at yahoo dot com>
+ * @version  1.1
+ * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
+ *          (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_table($params, &$smarty)
+{
+    $table_attr = 'border="1"';
+    $tr_attr = '';
+    $th_attr = '';
+    $td_attr = '';
+    $cols = $cols_count = 3;
+    $rows = 3;
+    $trailpad = '&nbsp;';
+    $vdir = 'down';
+    $hdir = 'right';
+    $inner = 'cols';
+    $caption = '';
+
+    if (!isset($params['loop'])) {
+        $smarty->trigger_error("html_table: missing 'loop' parameter");
+        return;
+    }
+
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'loop':
+                $$_key = (array)$_value;
+                break;
+
+            case 'cols':
+                if (is_array($_value) && !empty($_value)) {
+                    $cols = $_value;
+                    $cols_count = count($_value);
+                } elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
+                    $cols = explode(',', $_value);
+                    $cols_count = count($cols);
+                } elseif (!empty($_value)) {
+                    $cols_count = (int)$_value;
+                } else {
+                    $cols_count = $cols;
+                }
+                break;
+
+            case 'rows':
+                $$_key = (int)$_value;
+                break;
+
+            case 'table_attr':
+            case 'trailpad':
+            case 'hdir':
+            case 'vdir':
+            case 'inner':
+            case 'caption':
+                $$_key = (string)$_value;
+                break;
+
+            case 'tr_attr':
+            case 'td_attr':
+            case 'th_attr':
+                $$_key = $_value;
+                break;
+        }
+    }
+
+    $loop_count = count($loop);
+    if (empty($params['rows'])) {
+        /* no rows specified */
+        $rows = ceil($loop_count/$cols_count);
+    } elseif (empty($params['cols'])) {
+        if (!empty($params['rows'])) {
+            /* no cols specified, but rows */
+            $cols_count = ceil($loop_count/$rows);
+        }
+    }
+
+    $output = "<table $table_attr>\n";
+
+    if (!empty($caption)) {
+        $output .= '<caption>' . $caption . "</caption>\n";
+    }
+
+    if (is_array($cols)) {
+        $cols = ($hdir == 'right') ? $cols : array_reverse($cols);
+        $output .= "<thead><tr>\n";
+
+        for ($r=0; $r<$cols_count; $r++) {
+            $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
+            $output .= $cols[$r];
+            $output .= "</th>\n";
+        }
+        $output .= "</tr></thead>\n";
+    }
+
+    $output .= "<tbody>\n";
+    for ($r=0; $r<$rows; $r++) {
+        $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
+        $rx =  ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
+
+        for ($c=0; $c<$cols_count; $c++) {
+            $x =  ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
+            if ($inner!='cols') {
+                /* shuffle x to loop over rows*/
+                $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
+            }
+
+            if ($x<$loop_count) {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
+            } else {
+                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
+            }
+        }
+        $output .= "</tr>\n";
+    }
+    $output .= "</tbody>\n";
+    $output .= "</table>\n";
+    
+    return $output;
+}
+
+function smarty_function_html_table_cycle($name, $var, $no) {
+    if(!is_array($var)) {
+        $ret = $var;
+    } else {
+        $ret = $var[$no % count($var)];
+    }
+    
+    return ($ret) ? ' '.$ret : '';
+}
+
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.mailto.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.mailto.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.mailto.php	(revision 298)
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {mailto} function plugin
+ *
+ * Type:     function<br>
+ * Name:     mailto<br>
+ * Date:     May 21, 2002
+ * Purpose:  automate mailto address link creation, and optionally
+ *           encode them.<br>
+ * Input:<br>
+ *         - address = e-mail address
+ *         - text = (optional) text to display, default is address
+ *         - encode = (optional) can be one of:
+ *                * none : no encoding (default)
+ *                * javascript : encode with javascript
+ *                * javascript_charcode : encode with javascript charcode
+ *                * hex : encode with hexidecimal (no javascript)
+ *         - cc = (optional) address(es) to carbon copy
+ *         - bcc = (optional) address(es) to blind carbon copy
+ *         - subject = (optional) e-mail subject
+ *         - newsgroups = (optional) newsgroup(s) to post to
+ *         - followupto = (optional) address(es) to follow up to
+ *         - extra = (optional) extra tags for the href link
+ *
+ * Examples:
+ * <pre>
+ * {mailto address="me@domain.com"}
+ * {mailto address="me@domain.com" encode="javascript"}
+ * {mailto address="me@domain.com" encode="hex"}
+ * {mailto address="me@domain.com" subject="Hello to you!"}
+ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
+ * {mailto address="me@domain.com" extra='class="mailto"'}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
+ *          (Smarty online manual)
+ * @version  1.2
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
+ * @param    array
+ * @param    Smarty
+ * @return   string
+ */
+function smarty_function_mailto($params, &$smarty)
+{
+    $extra = '';
+
+    if (empty($params['address'])) {
+        $smarty->trigger_error("mailto: missing 'address' parameter");
+        return;
+    } else {
+        $address = $params['address'];
+    }
+
+    $text = $address;
+
+    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+    // so, don't encode it.
+    $search = array('%40', '%2C');
+    $replace  = array('@', ',');
+    $mail_parms = array();
+    foreach ($params as $var=>$value) {
+        switch ($var) {
+            case 'cc':
+            case 'bcc':
+            case 'followupto':
+                if (!empty($value))
+                    $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
+                break;
+                
+            case 'subject':
+            case 'newsgroups':
+                $mail_parms[] = $var.'='.rawurlencode($value);
+                break;
+
+            case 'extra':
+            case 'text':
+                $$var = $value;
+
+            default:
+        }
+    }
+
+    $mail_parm_vals = '';
+    for ($i=0; $i<count($mail_parms); $i++) {
+        $mail_parm_vals .= (0==$i) ? '?' : '&';
+        $mail_parm_vals .= $mail_parms[$i];
+    }
+    $address .= $mail_parm_vals;
+
+    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
+    if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
+        $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
+        return;
+    }
+
+    if ($encode == 'javascript' ) {
+        $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
+
+        $js_encode = '';
+        for ($x=0; $x < strlen($string); $x++) {
+            $js_encode .= '%' . bin2hex($string[$x]);
+        }
+
+        return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
+
+    } elseif ($encode == 'javascript_charcode' ) {
+        $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+        for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
+            $ord[] = ord($string[$x]);   
+        }
+
+        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
+        $_ret .= "<!--\n";
+        $_ret .= "{document.write(String.fromCharCode(";
+        $_ret .= implode(',',$ord);
+        $_ret .= "))";
+        $_ret .= "}\n";
+        $_ret .= "//-->\n";
+        $_ret .= "</script>\n";
+        
+        return $_ret;
+        
+        
+    } elseif ($encode == 'hex') {
+
+        preg_match('!^(.*)(\?.*)$!',$address,$match);
+        if(!empty($match[2])) {
+            $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
+            return;
+        }
+        $address_encode = '';
+        for ($x=0; $x < strlen($address); $x++) {
+            if(preg_match('!\w!',$address[$x])) {
+                $address_encode .= '%' . bin2hex($address[$x]);
+            } else {
+                $address_encode .= $address[$x];
+            }
+        }
+        $text_encode = '';
+        for ($x=0; $x < strlen($text); $x++) {
+            $text_encode .= '&#x' . bin2hex($text[$x]).';';
+        }
+
+        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
+        return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
+
+    } else {
+        // no encoding
+        return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+    }
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.math.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.math.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.math.php	(revision 298)
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {math} function plugin
+ *
+ * Type:     function<br>
+ * Name:     math<br>
+ * Purpose:  handle math computations in template<br>
+ * @link http://smarty.php.net/manual/en/language.function.math.php {math}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_math($params, &$smarty)
+{
+    // be sure equation parameter is present
+    if (empty($params['equation'])) {
+        $smarty->trigger_error("math: missing equation parameter");
+        return;
+    }
+
+    $equation = $params['equation'];
+
+    // make sure parenthesis are balanced
+    if (substr_count($equation,"(") != substr_count($equation,")")) {
+        $smarty->trigger_error("math: unbalanced parenthesis");
+        return;
+    }
+
+    // match all vars in equation, make sure all are passed
+    preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
+    $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
+                           'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
+    
+    foreach($match[1] as $curr_var) {
+        if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
+            $smarty->trigger_error("math: function call $curr_var not allowed");
+            return;
+        }
+    }
+
+    foreach($params as $key => $val) {
+        if ($key != "equation" && $key != "format" && $key != "assign") {
+            // make sure value is not empty
+            if (strlen($val)==0) {
+                $smarty->trigger_error("math: parameter $key is empty");
+                return;
+            }
+            if (!is_numeric($val)) {
+                $smarty->trigger_error("math: parameter $key: is not numeric");
+                return;
+            }
+            $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
+        }
+    }
+
+    eval("\$smarty_math_result = ".$equation.";");
+
+    if (empty($params['format'])) {
+        if (empty($params['assign'])) {
+            return $smarty_math_result;
+        } else {
+            $smarty->assign($params['assign'],$smarty_math_result);
+        }
+    } else {
+        if (empty($params['assign'])){
+            printf($params['format'],$smarty_math_result);
+        } else {
+            $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
+        }
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.popup.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.popup.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.popup.php	(revision 298)
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup} function plugin
+ *
+ * Type:     function<br>
+ * Name:     popup<br>
+ * Purpose:  make text pop up in windows via overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup($params, &$smarty)
+{
+    $append = '';
+    foreach ($params as $_key=>$_value) {
+        switch ($_key) {
+            case 'text':
+            case 'trigger':
+            case 'function':
+            case 'inarray':
+                $$_key = (string)$_value;
+                if ($_key == 'function' || $_key == 'inarray')
+                    $append .= ',' . strtoupper($_key) . ",'$_value'";
+                break;
+
+            case 'caption':
+            case 'closetext':
+            case 'status':
+                $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
+                break;
+
+            case 'fgcolor':
+            case 'bgcolor':
+            case 'textcolor':
+            case 'capcolor':
+            case 'closecolor':
+            case 'textfont':
+            case 'captionfont':
+            case 'closefont':
+            case 'fgbackground':
+            case 'bgbackground':
+            case 'caparray':
+            case 'capicon':
+            case 'background':
+            case 'frame':
+                $append .= ',' . strtoupper($_key) . ",'$_value'";
+                break;
+
+            case 'textsize':
+            case 'captionsize':
+            case 'closesize':
+            case 'width':
+            case 'height':
+            case 'border':
+            case 'offsetx':
+            case 'offsety':
+            case 'snapx':
+            case 'snapy':
+            case 'fixx':
+            case 'fixy':
+            case 'padx':
+            case 'pady':
+            case 'timeout':
+            case 'delay':
+                $append .= ',' . strtoupper($_key) . ",$_value";
+                break;
+
+            case 'sticky':
+            case 'left':
+            case 'right':
+            case 'center':
+            case 'above':
+            case 'below':
+            case 'noclose':
+            case 'autostatus':
+            case 'autostatuscap':
+            case 'fullhtml':
+            case 'hauto':
+            case 'vauto':
+            case 'mouseoff':
+            case 'followmouse':
+            case 'closeclick':
+                if ($_value) $append .= ',' . strtoupper($_key);
+                break;
+
+            default:
+                $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
+        }
+    }
+
+    if (empty($text) && !isset($inarray) && empty($function)) {
+        $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
+        return false;
+    }
+
+    if (empty($trigger)) { $trigger = "onmouseover"; }
+
+    $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
+    $retval .= $append . ');"';
+    if ($trigger == 'onmouseover')
+       $retval .= ' onmouseout="nd();"';
+
+
+    return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/function.popup_init.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/function.popup_init.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/function.popup_init.php	(revision 298)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup_init} function plugin
+ *
+ * Type:     function<br>
+ * Name:     popup_init<br>
+ * Purpose:  initialize overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup_init($params, &$smarty)
+{
+    $zindex = 1000;
+    
+    if (!empty($params['zindex'])) {
+        $zindex = $params['zindex'];
+    }
+    
+    if (!empty($params['src'])) {
+        return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
+         . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
+    } else {
+        $smarty->trigger_error("popup_init: missing src parameter");
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.capitalize.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.capitalize.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.capitalize.php	(revision 298)
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty capitalize modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     capitalize<br>
+ * Purpose:  capitalize words in the string
+ * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
+ *      capitalize (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_capitalize($string, $uc_digits = false)
+{
+    smarty_modifier_capitalize_ucfirst(null, $uc_digits);
+    return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
+}
+
+function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
+{
+    static $_uc_digits = false;
+    
+    if(isset($uc_digits)) {
+        $_uc_digits = $uc_digits;
+        return;
+    }
+    
+    if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
+        return ucfirst($string[0]);
+    else
+        return $string[0];
+}
+
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.cat.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.cat.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.cat.php	(revision 298)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty cat modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     cat<br>
+ * Date:     Feb 24, 2003
+ * Purpose:  catenate a value to a variable
+ * Input:    string to catenate
+ * Example:  {$var|cat:"foo"}
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ *          (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version 1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_cat($string, $cat)
+{
+    return $string . $cat;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.count_characters.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.count_characters.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.count_characters.php	(revision 298)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_characters modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_characteres<br>
+ * Purpose:  count the number of characters in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
+ *          count_characters (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean include whitespace in the character count
+ * @return integer
+ */
+function smarty_modifier_count_characters($string, $include_spaces = false)
+{
+    if ($include_spaces)
+       return(strlen($string));
+
+    return preg_match_all("/[^\s]/",$string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.count_paragraphs.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.count_paragraphs.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.count_paragraphs.php	(revision 298)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_paragraphs<br>
+ * Purpose:  count the number of paragraphs in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_paragraphs (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_paragraphs($string)
+{
+    // count \r or \n characters
+    return count(preg_split('/[\r\n]+/', $string));
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.count_sentences.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.count_sentences.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.count_sentences.php	(revision 298)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_sentences modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_sentences
+ * Purpose:  count the number of sentences in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ *          count_sentences (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_sentences($string)
+{
+    // find periods with a word before but not after.
+    return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.count_words.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.count_words.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.count_words.php	(revision 298)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_words modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     count_words<br>
+ * Purpose:  count the number of words in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
+ *          count_words (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_words($string)
+{
+    // split text by ' ',\r,\n,\f,\t
+    $split_array = preg_split('/\s+/',$string);
+    // count matches that contain alphanumerics
+    $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
+
+    return count($word_count);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.date_format.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.date_format.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.date_format.php	(revision 298)
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Include the {@link shared.make_timestamp.php} plugin
+ */
+require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
+/**
+ * Smarty date_format modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     date_format<br>
+ * Purpose:  format datestamps via strftime<br>
+ * Input:<br>
+ *         - string: input date string
+ *         - format: strftime format for output
+ *         - default_date: default date if $string is empty
+ * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
+ *          date_format (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string|void
+ * @uses smarty_make_timestamp()
+ */
+function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
+{
+    if ($string != '') {
+        $timestamp = smarty_make_timestamp($string);
+    } elseif ($default_date != '') {
+        $timestamp = smarty_make_timestamp($default_date);
+    } else {
+        return;
+    }
+    if (DIRECTORY_SEPARATOR == '\\') {
+        $_win_from = array('%D',       '%h', '%n', '%r',          '%R',    '%t', '%T');
+        $_win_to   = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
+        if (strpos($format, '%e') !== false) {
+            $_win_from[] = '%e';
+            $_win_to[]   = sprintf('%\' 2d', date('j', $timestamp));
+        }
+        if (strpos($format, '%l') !== false) {
+            $_win_from[] = '%l';
+            $_win_to[]   = sprintf('%\' 2d', date('h', $timestamp));
+        }
+        $format = str_replace($_win_from, $_win_to, $format);
+    }
+    return strftime($format, $timestamp);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.debug_print_var.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.debug_print_var.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.debug_print_var.php	(revision 298)
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty debug_print_var modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     debug_print_var<br>
+ * Purpose:  formats variable contents for display in the console
+ * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
+ *          debug_print_var (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param array|object
+ * @param integer
+ * @param integer
+ * @return string
+ */
+function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
+{
+    $_replace = array(
+        "\n" => '<i>\n</i>',
+        "\r" => '<i>\r</i>',
+        "\t" => '<i>\t</i>'
+    );
+
+    switch (gettype($var)) {
+        case 'array' :
+            $results = '<b>Array (' . count($var) . ')</b>';
+            foreach ($var as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                    . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
+                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                    $depth--;
+            }
+            break;
+        case 'object' :
+            $object_vars = get_object_vars($var);
+            $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
+            foreach ($object_vars as $curr_key => $curr_val) {
+                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
+                    . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
+                    . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
+                    $depth--;
+            }
+            break;
+        case 'boolean' :
+        case 'NULL' :
+        case 'resource' :
+            if (true === $var) {
+                $results = 'true';
+            } elseif (false === $var) {
+                $results = 'false';
+            } elseif (null === $var) {
+                $results = 'null';
+            } else {
+                $results = htmlspecialchars((string) $var);
+            }
+            $results = '<i>' . $results . '</i>';
+            break;
+        case 'integer' :
+        case 'float' :
+            $results = htmlspecialchars((string) $var);
+            break;
+        case 'string' :
+            $results = strtr($var, $_replace);
+            if (strlen($var) > $length ) {
+                $results = substr($var, 0, $length - 3) . '...';
+            }
+            $results = htmlspecialchars('"' . $results . '"');
+            break;
+        case 'unknown type' :
+        default :
+            $results = strtr((string) $var, $_replace);
+            if (strlen($results) > $length ) {
+                $results = substr($results, 0, $length - 3) . '...';
+            }
+            $results = htmlspecialchars($results);
+    }
+
+    return $results;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.default.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.default.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.default.php	(revision 298)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty default modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     default<br>
+ * Purpose:  designate default value for empty variables
+ * @link http://smarty.php.net/manual/en/language.modifier.default.php
+ *          default (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_default($string, $default = '')
+{
+    if (!isset($string) || $string === '')
+        return $default;
+    else
+        return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.escape.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.escape.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.escape.php	(revision 298)
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     escape<br>
+ * Purpose:  Escape the string according to escapement type
+ * @link http://smarty.php.net/manual/en/language.modifier.escape.php
+ *          escape (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param html|htmlall|url|quotes|hex|hexentity|javascript
+ * @return string
+ */
+function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
+{
+    switch ($esc_type) {
+        case 'html':
+            return htmlspecialchars($string, ENT_QUOTES, $char_set);
+
+        case 'htmlall':
+            return htmlentities($string, ENT_QUOTES, $char_set);
+
+        case 'url':
+            return rawurlencode($string);
+
+        case 'urlpathinfo':
+            return str_replace('%2F','/',rawurlencode($string));
+            
+        case 'quotes':
+            // escape unescaped single quotes
+            return preg_replace("%(?<!\\\\)'%", "\\'", $string);
+
+        case 'hex':
+            // escape every character into hex
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '%' . bin2hex($string[$x]);
+            }
+            return $return;
+            
+        case 'hexentity':
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '&#x' . bin2hex($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'decentity':
+            $return = '';
+            for ($x=0; $x < strlen($string); $x++) {
+                $return .= '&#' . ord($string[$x]) . ';';
+            }
+            return $return;
+
+        case 'javascript':
+            // escape quotes and backslashes, newlines, etc.
+            return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
+            
+        case 'mail':
+            // safe way to display e-mail address on a web page
+            return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
+            
+        case 'nonstd':
+           // escape non-standard chars, such as ms document quotes
+           $_res = '';
+           for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
+               $_ord = ord(substr($string, $_i, 1));
+               // non-standard char, escape it
+               if($_ord >= 126){
+                   $_res .= '&#' . $_ord . ';';
+               }
+               else {
+                   $_res .= substr($string, $_i, 1);
+               }
+           }
+           return $_res;
+
+        default:
+            return $string;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.indent.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.indent.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.indent.php	(revision 298)
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty indent modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     indent<br>
+ * Purpose:  indent lines of text
+ * @link http://smarty.php.net/manual/en/language.modifier.indent.php
+ *          indent (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @return string
+ */
+function smarty_modifier_indent($string,$chars=4,$char=" ")
+{
+    return preg_replace('!^!m',str_repeat($char,$chars),$string);
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.lower.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.lower.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.lower.php	(revision 298)
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty lower modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     lower<br>
+ * Purpose:  convert string to lowercase
+ * @link http://smarty.php.net/manual/en/language.modifier.lower.php
+ *          lower (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_lower($string)
+{
+    return strtolower($string);
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.nl2br.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.nl2br.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.nl2br.php	(revision 298)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty plugin
+ *
+ * Type:     modifier<br>
+ * Name:     nl2br<br>
+ * Date:     Feb 26, 2003
+ * Purpose:  convert \r\n, \r or \n to <<br>>
+ * Input:<br>
+ *         - contents = contents to replace
+ *         - preceed_test = if true, includes preceeding break tags
+ *           in replacement
+ * Example:  {$text|nl2br}
+ * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
+ *          nl2br (Smarty online manual)
+ * @version  1.0
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_nl2br($string)
+{
+    return nl2br($string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.regex_replace.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.regex_replace.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.regex_replace.php	(revision 298)
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty regex_replace modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     regex_replace<br>
+ * Purpose:  regular expression search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ *          regex_replace (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string|array
+ * @param string|array
+ * @return string
+ */
+function smarty_modifier_regex_replace($string, $search, $replace)
+{
+    if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
+        /* remove eval-modifier from $search */
+        $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
+    }
+       
+    return preg_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.replace.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.replace.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.replace.php	(revision 298)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty replace modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     replace<br>
+ * Purpose:  simple search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.replace.php
+ *          replace (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_replace($string, $search, $replace)
+{
+    return str_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.spacify.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.spacify.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.spacify.php	(revision 298)
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty spacify modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     spacify<br>
+ * Purpose:  add spaces between characters in a string
+ * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
+ *          spacify (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_spacify($string, $spacify_char = ' ')
+{
+    return implode($spacify_char,
+                   preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.string_format.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.string_format.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.string_format.php	(revision 298)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty string_format modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     string_format<br>
+ * Purpose:  format strings via sprintf
+ * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
+ *          string_format (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_string_format($string, $format)
+{
+    return sprintf($format, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.strip.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.strip.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.strip.php	(revision 298)
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip<br>
+ * Purpose:  Replace all repeated spaces, newlines, tabs
+ *           with a single space or supplied replacement string.<br>
+ * Example:  {$var|strip} {$var|strip:"&nbsp;"}
+ * Date:     September 25th, 2002
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.php
+ *          strip (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @version  1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_strip($text, $replace = ' ')
+{
+    return preg_replace('!\s+!', $replace, $text);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.strip_tags.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.strip_tags.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.strip_tags.php	(revision 298)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip_tags modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     strip_tags<br>
+ * Purpose:  strip html tags from text
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
+ *          strip_tags (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_strip_tags($string, $replace_with_space = true)
+{
+    if ($replace_with_space)
+        return preg_replace('!<[^>]*?>!', ' ', $string);
+    else
+        return strip_tags($string);
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.truncate.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.truncate.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.truncate.php	(revision 298)
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty truncate modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     truncate<br>
+ * Purpose:  Truncate a string to a certain length if necessary,
+ *           optionally splitting in the middle of a word, and
+ *           appending the $etc string or inserting $etc into the middle.
+ * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
+ *          truncate (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_truncate($string, $length = 80, $etc = '...',
+                                  $break_words = false, $middle = false)
+{
+    if ($length == 0)
+        return '';
+
+    if (strlen($string) > $length) {
+        $length -= min($length, strlen($etc));
+        if (!$break_words && !$middle) {
+            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
+        }
+        if(!$middle) {
+            return substr($string, 0, $length) . $etc;
+        } else {
+            return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
+        }
+    } else {
+        return $string;
+    }
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.upper.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.upper.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.upper.php	(revision 298)
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty upper modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     upper<br>
+ * Purpose:  convert string to uppercase
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php
+ *          upper (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_modifier_upper($string)
+{
+    return strtoupper($string);
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/modifier.wordwrap.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/modifier.wordwrap.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/modifier.wordwrap.php	(revision 298)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty wordwrap modifier plugin
+ *
+ * Type:     modifier<br>
+ * Name:     wordwrap<br>
+ * Purpose:  wrap a string of text at a given length
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
+ *          wordwrap (Smarty online manual)
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
+{
+    return wordwrap($string,$length,$break,$cut);
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/outputfilter.trimwhitespace.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/outputfilter.trimwhitespace.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/outputfilter.trimwhitespace.php	(revision 298)
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty trimwhitespace outputfilter plugin
+ *
+ * File:     outputfilter.trimwhitespace.php<br>
+ * Type:     outputfilter<br>
+ * Name:     trimwhitespace<br>
+ * Date:     Jan 25, 2003<br>
+ * Purpose:  trim leading white space and blank lines from
+ *           template source after it gets interpreted, cleaning
+ *           up code and saving bandwidth. Does not affect
+ *           <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
+ * Install:  Drop into the plugin directory, call
+ *           <code>$smarty->load_filter('output','trimwhitespace');</code>
+ *           from application.
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
+ * @version  1.3
+ * @param string
+ * @param Smarty
+ */
+function smarty_outputfilter_trimwhitespace($source, &$smarty)
+{
+    // Pull out the script blocks
+    preg_match_all("!<script[^>]+>.*?</script>!is", $source, $match);
+    $_script_blocks = $match[0];
+    $source = preg_replace("!<script[^>]+>.*?</script>!is",
+                           '@@@SMARTY:TRIM:SCRIPT@@@', $source);
+
+    // Pull out the pre blocks
+    preg_match_all("!<pre>.*?</pre>!is", $source, $match);
+    $_pre_blocks = $match[0];
+    $source = preg_replace("!<pre>.*?</pre>!is",
+                           '@@@SMARTY:TRIM:PRE@@@', $source);
+
+    // Pull out the textarea blocks
+    preg_match_all("!<textarea[^>]+>.*?</textarea>!is", $source, $match);
+    $_textarea_blocks = $match[0];
+    $source = preg_replace("!<textarea[^>]+>.*?</textarea>!is",
+                           '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
+
+    // remove all leading spaces, tabs and carriage returns NOT
+    // preceeded by a php close tag.
+    $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
+
+    // replace textarea blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
+
+    // replace pre blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
+
+    // replace script blocks
+    smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
+
+    return $source;
+}
+
+function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
+    $_len = strlen($search_str);
+    $_pos = 0;
+    for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
+        if (($_pos=strpos($subject, $search_str, $_pos))!==false)
+            $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
+        else
+            break;
+
+}
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/shared.escape_special_chars.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/shared.escape_special_chars.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/shared.escape_special_chars.php	(revision 298)
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * escape_special_chars common function
+ *
+ * Function: smarty_function_escape_special_chars<br>
+ * Purpose:  used by other smarty functions to escape
+ *           special chars except for already escaped ones
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_function_escape_special_chars($string)
+{
+    if(!is_array($string)) {
+        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
+        $string = htmlspecialchars($string);
+        $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
+    }
+    return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/libs/plugins/shared.make_timestamp.php
===================================================================
--- /trunk/htdocs2/smarty/libs/plugins/shared.make_timestamp.php	(revision 298)
+++ /trunk/htdocs2/smarty/libs/plugins/shared.make_timestamp.php	(revision 298)
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Function: smarty_make_timestamp<br>
+ * Purpose:  used by other smarty functions to make a timestamp
+ *           from a string.
+ * @author   Monte Ohrt <monte at ohrt dot com>
+ * @param string
+ * @return string
+ */
+function smarty_make_timestamp($string)
+{
+    if(empty($string)) {
+        // use "now":
+        $time = time();
+
+    } elseif (preg_match('/^\d{14}$/', $string)) {
+        // it is mysql timestamp format of YYYYMMDDHHMMSS?            
+        $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
+                       substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
+        
+    } elseif (is_numeric($string)) {
+        // it is a numeric string, we handle it as timestamp
+        $time = (int)$string;
+        
+    } else {
+        // strtotime should handle it
+        $time = strtotime($string);
+        if ($time == -1 || $time === false) {
+            // strtotime() was not able to parse $string, use "now":
+            $time = time();
+        }
+    }
+    return $time;
+
+}
+
+/* vim: set expandtab: */
+
+?>
Index: /trunk/htdocs2/smarty/misc/smarty_icon.README
===================================================================
--- /trunk/htdocs2/smarty/misc/smarty_icon.README	(revision 298)
+++ /trunk/htdocs2/smarty/misc/smarty_icon.README	(revision 298)
@@ -0,0 +1,6 @@
+Feel free to put the smarty icon on your site.
+You can cut-and-paste the following code, be sure
+to adjust the path to the image:
+
+<a href="http://smarty.php.net/">
+<img src="smarty_icon.gif" border="0" height="31" width="88" /></a>
Index: /trunk/htdocs2/smarty/unit_test/README
===================================================================
--- /trunk/htdocs2/smarty/unit_test/README	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/README	(revision 298)
@@ -0,0 +1,32 @@
+Smarty Unit Testing
+-------------------
+
+Smarty unit tests require the PEAR PHPUnit
+package to be installed. See if you have that
+installed with the following command:
+
+$> pear list
+
+If you don't see PHPUnit, install with this:
+
+$> pear install PHPUnit
+
+Edit the config.php file,
+be sure everything is defined correctly.
+
+Be sure the following directories are present:
+
+templates
+configs
+templates_c (writable)
+cache (writable)
+
+Then run from the command line:
+php -q smarty_unit_test.php
+
+Or from the web browser:
+http://www.your_domain.com/path/to/smarty_unit_test_gui.php
+
+This will run a unit test for every component
+of Smarty and dump the results. All should pass
+with flying colors. :)
Index: /trunk/htdocs2/smarty/unit_test/config.php
===================================================================
--- /trunk/htdocs2/smarty/unit_test/config.php	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/config.php	(revision 298)
@@ -0,0 +1,5 @@
+<?php
+
+define('SMARTY_DIR', '../libs/');
+
+?>
Index: /trunk/htdocs2/smarty/unit_test/configs/globals_double_quotes.conf
===================================================================
--- /trunk/htdocs2/smarty/unit_test/configs/globals_double_quotes.conf	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/configs/globals_double_quotes.conf	(revision 298)
@@ -0,0 +1,1 @@
+foo = "bar"
Index: /trunk/htdocs2/smarty/unit_test/configs/globals_single_quotes.conf
===================================================================
--- /trunk/htdocs2/smarty/unit_test/configs/globals_single_quotes.conf	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/configs/globals_single_quotes.conf	(revision 298)
@@ -0,0 +1,1 @@
+foo = 'bar'
Index: /trunk/htdocs2/smarty/unit_test/smarty_unit_test.php
===================================================================
--- /trunk/htdocs2/smarty/unit_test/smarty_unit_test.php	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/smarty_unit_test.php	(revision 298)
@@ -0,0 +1,10 @@
+<?php
+
+require_once 'test_cases.php';
+require_once 'PHPUnit.php';
+
+$suite = new PHPUnit_TestSuite("SmartyTest");
+$result = PHPUnit::run($suite);
+
+echo $result -> toString();
+?>
Index: /trunk/htdocs2/smarty/unit_test/smarty_unit_test_gui.php
===================================================================
--- /trunk/htdocs2/smarty/unit_test/smarty_unit_test_gui.php	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/smarty_unit_test_gui.php	(revision 298)
@@ -0,0 +1,10 @@
+<?php
+
+require_once 'test_cases.php';
+require_once 'PHPUnit.php';
+
+$suite = new PHPUnit_TestSuite("SmartyTest");
+$result = PHPUnit::run($suite);
+
+echo $result -> toHTML();
+?>
Index: /trunk/htdocs2/smarty/unit_test/templates/assign_var.tpl
===================================================================
--- /trunk/htdocs2/smarty/unit_test/templates/assign_var.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/templates/assign_var.tpl	(revision 298)
@@ -0,0 +1,1 @@
+{$foo}
Index: /trunk/htdocs2/smarty/unit_test/templates/constant.tpl
===================================================================
--- /trunk/htdocs2/smarty/unit_test/templates/constant.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/templates/constant.tpl	(revision 298)
@@ -0,0 +1,1 @@
+{$smarty.const.TEST_CONSTANT}
Index: /trunk/htdocs2/smarty/unit_test/templates/index.tpl
===================================================================
--- /trunk/htdocs2/smarty/unit_test/templates/index.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/templates/index.tpl	(revision 298)
@@ -0,0 +1,1 @@
+TEST STRING
Index: /trunk/htdocs2/smarty/unit_test/templates/parse_math.tpl
===================================================================
--- /trunk/htdocs2/smarty/unit_test/templates/parse_math.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/templates/parse_math.tpl	(revision 298)
@@ -0,0 +1,12 @@
+{foreach name=loop from=$items item=i}
+{$smarty.foreach.loop.iteration+2}
+{$smarty.foreach.loop.iteration+$flt}
+{$smarty.foreach.loop.iteration+$obj->six()}
+{$smarty.foreach.loop.iteration+$obj->ten}
+{/foreach}
+{$obj->ten+$flt}
+{$obj->ten*$flt}
+{$obj->six()+$obj->ten}
+{$obj->ten+$obj->ten}
+{$obj->six()+$flt}
+{$obj->six()+$items.0}
Index: /trunk/htdocs2/smarty/unit_test/templates/parse_obj_meth.tpl
===================================================================
--- /trunk/htdocs2/smarty/unit_test/templates/parse_obj_meth.tpl	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/templates/parse_obj_meth.tpl	(revision 298)
@@ -0,0 +1,8 @@
+{$obj->meth($foo, 2.5)}
+{$obj->meth(2.5, $foo)}
+{$obj->meth(2.5)}
+{$obj->meth($obj->val, "foo")}
+{$obj->meth("foo", $obj->val)}
+{$obj->meth("foo", $foo)}
+{$obj->meth($obj->arr.one, 2)}
+{$obj->meth($obj->meth("foo", $foo))}
Index: /trunk/htdocs2/smarty/unit_test/test_cases.php
===================================================================
--- /trunk/htdocs2/smarty/unit_test/test_cases.php	(revision 298)
+++ /trunk/htdocs2/smarty/unit_test/test_cases.php	(revision 298)
@@ -0,0 +1,450 @@
+<?php
+
+require_once './config.php';
+require_once SMARTY_DIR . 'Smarty.class.php';
+require_once 'PHPUnit.php';
+
+class Obj {
+    var $val = 'val';
+    var $arr = array('one' => 'one', 'two' => 2);
+    var $ten = 10;
+
+    function meth($a="a", $b="b") {
+        return "$a:$b";
+    }
+
+    function six() {
+        return 6;
+    }
+}
+
+    
+class SmartyTest extends PHPUnit_TestCase {   
+    // contains the object handle of the string class
+    var $abc;
+    // contains the last triggered error's errorlevel
+    var $errorlevel;
+
+    // constructor of the test suite
+    function SmartyTest($name) {
+       $this->PHPUnit_TestCase($name);
+    }
+
+    // called before the test functions will be executed    
+    // this function is defined in PHPUnit_TestCase and overwritten 
+    // here
+    function setUp() {
+        // create a new instance of String with the
+        // string 'abc'
+        $this->smarty = new Smarty;
+    }
+    // called after the test functions are executed    
+    // this function is defined in PHPUnit_TestCase and overwritten 
+    // here    
+    function tearDown() {
+        // delete your instance
+        unset($this->smarty);
+    }
+    
+    // dummy errorhandler for functions that are supposed to call trigger_error()
+    function error_handler($errorlevel) {
+        if ($errorlevel) $this->errorlevel = $errorlevel;
+    }
+
+    /* DIRECTORY TESTS */
+    
+    // test that template_dir exists
+    function test_template_dir_exists() {
+        $this->assertTrue(file_exists($this->smarty->template_dir));                       
+    }
+    // test that template_dir is a directory
+    function test_template_dir_is_dir() {
+        $this->assertTrue(is_dir($this->smarty->template_dir));                       
+    }
+    // test that template_dir is readable
+    function test_template_dir_is_readable() {
+        $this->assertTrue(is_readable($this->smarty->template_dir));                       
+    }
+    // test that config_dir exists
+    function test_config_dir_exists() {
+        $this->assertTrue(file_exists($this->smarty->config_dir));                       
+    }
+    // test that config_dir is a directory
+    function test_config_dir_is_dir() {
+        $this->assertTrue(is_dir($this->smarty->config_dir));                       
+    }
+    // test that config_dir is readable
+    function test_config_dir_is_readable() {
+        $this->assertTrue(is_readable($this->smarty->config_dir));                       
+    }
+    // test that compile_dir exists
+    function test_compile_dir_exists() {
+        $this->assertTrue(file_exists($this->smarty->compile_dir));                       
+    }
+    // test that compile_dir is a directory
+    function test_compile_dir_is_dir() {
+        $this->assertTrue(is_dir($this->smarty->compile_dir));                       
+    }
+    // test that compile_dir is readable
+    function test_compile_dir_is_readable() {
+        $this->assertTrue(is_readable($this->smarty->compile_dir));                       
+    }
+    // test that compile_dir is writable
+    function test_compile_dir_is_writable() {
+        $this->assertTrue(is_writable($this->smarty->compile_dir));                       
+    }
+    // test that cache_dir exists
+    function test_cache_dir_exists() {
+        $this->assertTrue(file_exists($this->smarty->cache_dir));                       
+    }
+    // test that cache_dir is a directory
+    function test_cache_dir_is_dir() {
+        $this->assertTrue(is_dir($this->smarty->cache_dir));                       
+    }
+    // test that cache_dir is readable
+    function test_cache_dir_is_readable() {
+        $this->assertTrue(is_readable($this->smarty->cache_dir));                       
+    }
+    // test that cache_dir is writable
+    function test_cache_dir_is_writable() {
+        $this->assertTrue(is_writable($this->smarty->cache_dir));                       
+    }
+
+    /* METHOD EXISTS TESTS */
+    function test_assign_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'assign'));
+    }
+    function test_assign_by_ref_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'assign_by_ref'));
+    }
+    function test_append_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'append'));
+    }
+    function test_append_by_ref_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'append_by_ref'));
+    }
+    function test_clear_assign_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'clear_assign'));
+    }
+    function test_register_function_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_function'));
+    }
+    function test_unregister_function_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_function'));
+    }
+    function test_register_object_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_object'));
+    }
+    function test_unregister_object_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_object'));
+    }
+    function test_register_block_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_block'));
+    }
+    function test_unregister_block_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_block'));
+    }
+    function test_register_compiler_function_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_compiler_function'));
+    }
+    function test_unregister_compiler_function_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_compiler_function'));
+    }
+    function test_register_modifier_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_modifier'));
+    }
+    function test_unregister_modifier_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_modifier'));
+    }
+    function test_register_resource_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_resource'));
+    }
+    function test_unregister_resource_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_resource'));
+    }
+    function test_register_prefilter_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_prefilter'));
+    }
+    function test_unregister_prefilter_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_prefilter'));
+    }
+    function test_register_postfilter_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_postfilter'));
+    }
+    function test_unregister_postfilter_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_postfilter'));
+    }
+    function test_register_outputfilter_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'register_outputfilter'));
+    }
+    function test_unregister_outputfilter_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'unregister_outputfilter'));
+    }
+    function test_load_filter_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'load_filter'));
+    }
+    function test_clear_cache_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'clear_cache'));
+    }
+    function test_clear_all_cache_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'clear_all_cache'));
+    }
+    function test_is_cached_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'is_cached'));
+    }
+    function test_clear_all_assign_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'clear_all_assign'));
+    }
+    function test_clear_compiled_tpl_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'clear_compiled_tpl'));
+    }
+    function test_template_exists_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'template_exists'));
+    }
+    function test_get_template_vars_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'get_template_vars'));
+    }
+    function test_get_config_vars_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'get_config_vars'));
+    }
+    function test_trigger_error_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'trigger_error'));
+    }
+    function test_display_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'display'));
+    }
+    function test_fetch_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'fetch'));
+    }
+    function test_config_load_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'config_load'));
+    }
+    function test_get_registered_object_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'get_registered_object'));
+    }
+    function test_clear_config_method_exists() {
+        $this->assertTrue(method_exists($this->smarty, 'clear_config'));
+    }
+    function test_get_plugin_filepath() {
+        $this->assertTrue(method_exists($this->smarty, '_get_plugin_filepath'));
+    }
+
+    
+    function test_clear_compiled_tpl() {
+        $this->assertTrue($this->smarty->clear_compiled_tpl());
+    }
+    
+    /* DISPLAY TESTS */
+    
+    // test that display() executes properly
+    function test_call_to_display() {
+        ob_start();
+        $this->smarty->display('index.tpl');
+        $output = ob_get_contents();
+        ob_end_clean();
+        $this->assertEquals($output, 'TEST STRING');
+    }
+
+    /* FETCH TESTS */
+
+    // test that fetch() executes properly
+    function test_call_to_fetch() {
+        $this->assertEquals($this->smarty->fetch('index.tpl'), 'TEST STRING');
+    }
+    
+    /* ASSIGN TESTS */
+
+    // test assigning a simple template variable
+    function test_assign_var() {
+        $this->smarty->assign('foo', 'bar');
+        $this->assertEquals($this->smarty->fetch('assign_var.tpl'), 'bar');
+    }
+
+    /* PARSING TESTS */
+    
+    // test assigning and calling an object
+    function test_parse_obj_meth() {
+        $obj  = new Obj();
+        $this->smarty->assign('obj', $obj);
+        $this->smarty->assign('foo', 'foo');
+        $this->assertEquals('foo:2.5
+2.5:foo
+2.5:b
+val:foo
+foo:val
+foo:foo
+one:2
+foo:foo:b', $this->smarty->fetch('parse_obj_meth.tpl'));
+    }
+    
+    // test assigning and calling an object
+    function test_parse_math() {
+        $obj  = new Obj();
+        $this->smarty->assign('obj', $obj);
+        $this->smarty->assign('flt', 2.5);
+        $this->smarty->assign('items', array(1, 2));
+        $this->assertEquals('3
+3.5
+7
+11
+4
+4.5
+8
+12
+12.5
+25
+16
+20
+8.5
+7', $this->smarty->fetch('parse_math.tpl'));
+    }
+    
+    /* CONFIG FILE TESTS */
+
+    // test assigning a double quoted global variable
+    function test_config_load_globals_double_quotes() {
+        // load the global var
+        $this->smarty->config_load('globals_double_quotes.conf');
+        // test that it is assigned
+        $this->assertEquals($this->smarty->_config[0]['vars']['foo'], 'bar');
+    }
+
+    // test assigning a single quoted global variable
+    function test_config_load_globals_single_quotes() {
+        // load the global var
+        $this->smarty->config_load('globals_single_quotes.conf');
+        // test that it is assigned
+        $this->assertEquals($this->smarty->_config[0]['vars']['foo'], 'bar');
+    }
+
+    // test loading and running modifier.escape.php
+    function test_escape_modifier_get_plugins_filepath() {
+        $filepath = $this->smarty->_get_plugin_filepath('modifier', 'escape');
+        $this->assertTrue($filepath);
+    }
+
+    function test_escape_modifier_include_file() {
+        $filepath = $this->smarty->_get_plugin_filepath('modifier', 'escape');
+        $this->assertTrue(include($filepath));
+    }
+
+    function test_escape_modifier_function_exists() {
+        $this->assertTrue(function_exists('smarty_modifier_escape'));
+    }
+
+    function test_escape_modifier_escape_default() {
+        $string = smarty_modifier_escape("<html><body></body></html>");
+        $this->assertEquals('&lt;html&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;',
+                            $string);
+    }
+
+    function test_escape_modifier_escape_html() {
+        $string = smarty_modifier_escape("<html><body></body></html>", 'html');
+        $this->assertEquals('&lt;html&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;',
+                            $string);
+    }
+
+    function test_escape_modifier_escape_htmlall() {
+        $string = smarty_modifier_escape("<html><body></body></html>", 'htmlall');
+        $this->assertEquals('&lt;html&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;',
+                            $string);
+    }
+
+    function test_escape_modifier_escape_url() {
+        $string = smarty_modifier_escape("http://test.com?foo=bar", 'url');
+        $this->assertEquals('http%3A%2F%2Ftest.com%3Ffoo%3Dbar', $string);
+    }
+
+    function test_escape_modifier_escape_quotes() {
+        $string = smarty_modifier_escape("'\\'\\''", 'quotes');
+        $this->assertEquals("\\'\\'\\'\\'", $string);
+    }
+
+    function test_escape_modifier_escape_hex() {
+        $string = smarty_modifier_escape("abcd", 'hex');
+        $this->assertEquals('%61%62%63%64', $string);
+    }
+
+    function test_escape_modifier_escape_hexentity() {
+        $string = smarty_modifier_escape("ABCD", 'hexentity');
+        $this->assertEquals('&#x41;&#x42;&#x43;&#x44;', $string);
+    }
+
+    function test_escape_modifier_escape_javascript() {
+        $string = smarty_modifier_escape("\r\n\\", 'javascript');
+        $this->assertEquals('\\r\\n\\\\', $string);
+    }
+
+
+    function test_core_is_secure_file_exists() {
+        $file = SMARTY_CORE_DIR . 'core.is_secure.php';
+        $this->assertTrue(file_exists($file));
+    }
+
+    function test_core_is_secure_file_include() {
+        $file = SMARTY_CORE_DIR . 'core.is_secure.php';
+        $this->assertTrue(include($file));
+    }
+
+    function test_core_is_secure_function_exists() {
+        $this->assertTrue(function_exists('smarty_core_is_secure'));
+    }
+
+    function test_core_is_secure_function_is_secure_true() {
+        $security = $this->smarty->security;
+        $this->smarty->security = true;
+
+        /* check if index.tpl is secure (should be true) */
+        $params = array('resource_type' => 'file',
+                        'resource_base_path' => dirname(__FILE__) . '/templates',
+                        'resource_name' => dirname(__FILE__) . '/templates/index.tpl');
+        $this->assertTrue(smarty_core_is_secure($params, $this->smarty));
+        $this->smarty->security = $security;
+    }
+
+    function test_core_is_secure_function_is_secure_false() {
+        $security = $this->smarty->security;
+        $this->smarty->security = true;
+        /* check if test_cases.php is secure (should be false) */
+        $params = array('resource_type' => 'file',
+                        'resource_base_path' => dirname(__FILE__) . '/templates',
+                        'resource_name' => __FILE__);
+        $this->assertFalse(smarty_core_is_secure($params, $this->smarty));
+        $this->smarty->security = $security;
+
+    }
+
+    // test constants and security
+    function test_core_is_secure_function_smarty_var_const() {
+        define('TEST_CONSTANT', 'test constant');
+        $this->assertEquals('test constant', $this->smarty->fetch('constant.tpl',
+                                                             null, 'var_const'));
+    }
+
+    function test_core_is_secure_function_smarty_var_const_allowed() {
+        $security = $this->smarty->security;
+        $security_settings = $this->smarty->security_settings;
+        $this->smarty->security_settings['ALLOW_CONSTANTS'] = true;
+        $this->smarty->security = true;
+        $this->assertEquals('test constant', $this->smarty->fetch('constant.tpl',
+                                                     null, 'var_const_allowed'));
+        $this->smarty->security_settings = $security_settings;
+        $this->smarty->security = $security;   
+    }
+
+    function test_core_is_secure_function_smarty_var_const_not_allowed() {
+        $security = $this->smarty->security;
+        $this->smarty->security = true;
+        /* catch errors: */
+        $this->errorlevel = null;
+        set_error_handler(array(&$this, 'error_handler'));
+        $this->smarty->fetch('constant.tpl', null, 'var_const_not_allowed');
+        restore_error_handler();
+
+        $this->assertEquals( $this->errorlevel, E_USER_WARNING);
+        $this->smarty->security = $security;
+    }
+
+}
+
+?>
Index: /trunk/htdocs2/styles/atnf.css
===================================================================
--- /trunk/htdocs2/styles/atnf.css	(revision 298)
+++ /trunk/htdocs2/styles/atnf.css	(revision 298)
@@ -0,0 +1,77 @@
+/* ATNF Template CSS */
+
+html, body { padding: 0; margin: 0; }
+body { font-family: verdana, sans-serif; font-size: 90% }
+
+#imgEpping { border: 0; width: 70px; height: 61px; }
+#imgATNF { border: 0; width: 220px; height: 61px; }
+#imgCSIRO { float: right; border: 0; width: 42px; height: 50px; }
+
+#divTitleBar { 
+	height: 61px; 
+	background-image: url(http://www.atnf.csiro.au/images/starback3.jpg); 
+}
+
+div.site-links {
+	float: right;
+}
+
+div.site-links a, div.site-links a:visited {
+	text-decoration: none;
+	font-size: small;
+	color: white;
+	margin-right: 0.5em;
+}
+
+div.site-links a:hover { color: #ff6600; }
+div.site-links a:active { color: #ccccff; }
+
+.navbar { 
+	background-color: #ccccff; 
+	padding: 0.1em 0 0.1em 0; 
+	text-align: center; 
+	border-top: solid 1px #ccccff;
+	border-bottom: solid 1px #9999ff;
+}
+
+.navbar a {
+	font-size: small;
+	margin-right: 0.5em;
+}
+
+
+.navbar a , .navbar a:visited {
+	color:  #3333cc;
+	text-decoration: none;
+}
+
+.navbar a:active {
+	color: #ff6600;
+}
+
+div.navbar a:hover {
+	text-decoration: underline;
+	color: #333399;
+}
+
+div#header {
+	border-bottom: solid 1px black;
+}
+
+div#footer {
+	font-size: small;
+	margin-top: 2em;
+}
+
+div#footer .bottom-matter { margin-left: 1em; margin-bottom: 0.5em; }
+
+#last-modified { font-style: italic }
+
+div.bodycontents { margin: 1em; }
+
+div.error {
+	margin: 1em;
+	background-color: rgb(250,250,250);
+}
+
+abbr, acronym { cursor: help; }
Index: /trunk/htdocs2/styles/query.css
===================================================================
--- /trunk/htdocs2/styles/query.css	(revision 298)
+++ /trunk/htdocs2/styles/query.css	(revision 298)
@@ -0,0 +1,81 @@
+form div { margin: 1em 0 1em 0; }
+
+label {
+	font-weight: bold;
+}
+
+fieldset label { font-weight: normal }
+
+fieldset { 
+	border: 1px solid;
+	border-top-width: 2px;
+	border-color: rgb(230,230,230);
+	border-top-color: #ABB8C7;
+	padding: 0 1px 1px 1px;
+	background-color: #F4F4F4;
+	margin-left: 0px;
+	width: auto;
+	margin-right: 0px;
+	vertical-align: top;
+}
+
+fieldset fieldset {
+	border-bottom: none;
+	border-left: none;
+	border-right: none;
+	margin-right: auto;
+	margin-left: 0;
+	vertical-align: top;
+}
+
+#list {
+  max-height: 250px;
+  overflow: auto;
+}
+
+fieldset#flsPosition fieldset, fieldset#flsObsDate fieldset { 
+	display: inline; 
+}
+
+form#frmSearch { margin-left: 1em; }
+input, button { border: 1px solid gray; }
+
+button.calendar { font-size: 60%; }
+
+div.bodycontents div label { display: block; }
+/*div.bodycontents div input { width: 1em; }*/
+
+fieldset#flsObsDate div { display: inline; margin-right: 1em; }
+fieldset#flsObsDate div label { display: inline; }
+fieldset#flsObsDate input { width: 10em; }
+
+hr { display: none; }
+
+legend {
+	color: white;
+	border: solid #8F8FB3;
+	border-width: 1px;
+	padding: 0.3em;
+	margin-bottom: 1em;
+	background-color: #ADADD9;
+	font-weight: bold;
+	letter-spacing: 0.2em;
+	font-size: smaller;
+	margin-top: 1em;
+}
+
+
+select#selBand { width: 15em; }
+
+span.date { font-weight: bold; }
+
+div#divInstructions { display: block; }
+div#divInstructions dl { margin-left: 1em; }
+div#divInstructions dl.top { background-color: lemonchiffon; border: 1px solid orange; padding: 1em; margin-right: 2em; font-size: 90%; border-radius: 1em; }
+div#divInstructions dt { font-weight: bolder; margin-bottom: 0.1em; }
+div#divInstructions dd { margin-bottom: 0.5em; }
+
+div#divScrunching {background-color: lemonchiffon; border: 1px solid orange; padding: 1em; margin-right: 2em; font-size: 90%; border-radius: 1em; }
+
+* html legend { font-size: 8pt; margin-top: 0 }
+
Index: /trunk/htdocs2/styles/results.css
===================================================================
--- /trunk/htdocs2/styles/results.css	(revision 298)
+++ /trunk/htdocs2/styles/results.css	(revision 298)
@@ -0,0 +1,170 @@
+td.mosaic-positions { text-align: left ! important; }
+
+.disabled { color: gray; }
+
+span.mosaic-tag { margin-left: 1em; font-style: italic; font-size: 80%; vertical-align: middle; }
+
+span#spaBundle { margin-right: 1em; }
+
+#spaBundle label { margin-right: 0.5em; }
+
+body { padding: 0; margin: 0}
+
+a { text-decoration: none; }
+a:hover { text-decoration: underline }
+
+table {
+	border: 1px solid gray;
+	border-collapse: collapse;
+}
+
+col {
+	border-right: 1px solid gray;
+	border-left: 1px solid gray;
+}
+
+ul {
+	margin: 0;
+}
+
+tr.extra-detail {
+	display: none;				
+}
+
+tr.extra-detail td {
+	padding: 0;
+}
+
+table.source-summary {
+	width: 100%;
+	font-size: 90%;
+	border: 0;
+	margin: 0 auto 0 0; 
+}
+
+td.ra, td.dec { font-family: monospace; font-size: 110%; }
+
+table.source-summary td {
+	text-align: right;
+	padding: 0.1em 0.5em 0.1em 0.1em;
+}
+
+table.source-summary col.scan-details { width: 100%; }
+
+table.scan-summary col.first { border-left: 0; }
+table.scan-summary col.last { border-right: 0; }
+
+col#colSources {
+	width: 100%;
+}
+
+td.size {
+	text-align: right; 
+}
+
+col#colRestricted, td.restricted, td.not-restricted {
+	text-align: center;
+}
+
+.glyph {
+	font-family: "Arial Unicode MS";
+}
+
+span.glyph {
+	cursor: pointer;
+}
+
+input {
+	margin-left: auto;
+	margin-right: auto;
+}
+
+td.observer {
+	white-space: nowrap;
+}
+
+td.restricted {
+	color: indianred;
+}
+
+td.not-restricted {
+	color: darkgreen;
+}
+
+tbody.odd {
+	background-color: rgb(240, 240, 240);
+}
+
+tbody.odd.selected, tbody.selected-odd {
+	background-color: rgb(210, 170, 170);
+}
+
+tbody.even.selected, tbody.selected-even {
+	background-color: rgb(220, 190, 190);
+}
+
+.file-headings { white-space: nowrap; }
+.file-headings th { padding: 0.2em; } 
+
+label#labChkAll { margin-left: 0.5em; }
+
+table#tabQueryResults {width: auto; margin-bottom: 1em; border-left: 0; border-right: 0; 
+/*margin-left: -1em; margin-right: -1em; */
+}
+
+acronym, abbr { cursor: help; }
+
+td.file-download, td.date { white-space: nowrap }
+td.file-download input, #chkSelectAll { margin: 0 0.5em 0 0.5em; }
+
+#tdFooter { font-size: 80%; }
+
+.accesskey { text-decoration: underline; }
+
+tr.observers ul, td.sources ul { padding-left: 0 }
+tr.observers ul li, td.sources ul li, td.sources ul { display: inline; }
+tr.observers ul li:after, td.sources ul li:after { content: ", ";}
+tr.observers ul li.last:after, td.sources ul li.last:after { content: ""; }
+
+colgroup.right-ascension { border-left: 0; }
+colgroup.scan-details { border-right: 0; }
+
+colgroup.right-ascension, colgroup.declination, colgroup.source-name { vertical-align: middle }
+
+div#divUsage {
+	display: none;
+}
+
+div#divUsage li {
+	margin-top: 0.2em;
+	margin-bottom: 0.2em;
+}
+
+div#divUsage ul.top var, div#divUsage ul.top code {
+	font-size: 110%;
+}
+
+div#divUsage ul.top, p.note { background-color: lemonchiffon; font-size: 90%; margin-left: 2em; padding: 1em 1em 1em 2em; border: 1px solid orange; }
+
+p.note { font-style: italic; padding-top : 0.5em; padding-bottom: 0.5em;}
+
+tr.observers td { width: 100%; }
+tr.observers th { padding-left: 0.5em; padding-right: 0.5em; }
+tr.observers td, tr.observers th { padding-top: 0.2em; padding-bottom: 0.2em; }
+
+.page-info { text-align: right; margin-top: 1em; margin-bottom: 1em; font-size: 90%; }
+
+span.na, span.no-sources { color: rgb(60, 60, 60); font-size: 80%; font-style: italic; }
+
+div#divDownloadSize { font-size: 85%; color: rgb(20,20,20); margin-bottom: 0.5em }
+
+/* Internet explorer adjustments */
+
+* html td, * html th { border: solid gray 1px; }
+* html td.sources ul li { margin-right: 0.5em; }
+* html tr.observers ul li { margin-right: 1em; margin-left: 0.5em; }
+* html col#colSources { width: auto; }
+* html div#divUsage ul { margin-left: 1em; }
+* html tr, * html tbody, * html col, * html colgroup { border: 0; }
+* html table#tabQueryResults { width: 100%; }
+
Index: /trunk/htdocs2/styles/style.css
===================================================================
--- /trunk/htdocs2/styles/style.css	(revision 298)
+++ /trunk/htdocs2/styles/style.css	(revision 298)
@@ -0,0 +1,188 @@
+/* Body */
+/*
+.commenthidden {display:none}
+
+.commentshown {display:inline}
+
+body.front_page {background-image: url('../images/space.png');
+      background-attachment: fixed;
+      font-size: 90%; font-family: verdana, sans-serif;}
+
+body.atoa {font-size: 90%; font-family: verdana, sans-serif;}
+
+p.nav {position:relative; left:100px}
+
+abbr, acronym { cursor: help; }
+
+*/
+/*body.atoa {font-size: 90%; font-family: verdana, sans-serif;*/ /*background-color: #264096;*/ /*}*/
+/* Table */
+
+
+th {
+	font-size: 80%; 
+	color: white; 
+	background-color: #ADADD9;
+	border: 1px solid gray; 
+}
+
+table.registration {
+	border: none;
+}
+
+table.front_page {
+   background-image:url('../images/space.png');
+   position:absolute;
+	 left:0px;
+	 top:0px
+}
+
+/*
+table.login {
+   position:absolute;
+	 left:380px;
+	 top:120px;
+	 border: 1px solid gray; 
+}
+*/
+
+table.top_menu { 
+	border: 0px; 
+	width: 100%;
+}
+
+table.noborder {
+	border: 0px;
+}
+
+tr.top_menu { 
+	border:0px; 
+}
+
+td.result_row {
+	vertical-align:top; 
+	font-size: 80%; 
+	font-family: verdana, sans-serif;
+	padding: 0.2em 0.3em 0.2em 0.3em;
+	border: 1px solid gray;
+}
+
+tr.form_field {
+	border: 1px solid gray;
+}
+
+
+td.form_field {
+	vertical-align:top; 
+	font-size: 80%; 
+	font-family: verdana, sans-serif;
+	padding: 0.2em 0.3em 0.2em 0.3em;
+	border: none;
+}
+
+td.top_menu {
+	border:0px; 
+	font-size: 80%; 
+	font-family: verdana, sans-serif;
+}
+
+td.top_menu_heading {
+	border:0px; 
+	font-size: 80%; 
+	font-family: verdana, sans-serif;
+	color: white
+}
+
+/* div */
+div.tabArea {
+  font-size: 80%;
+  font-weight: bold;
+}
+
+/* The border area */
+div.tabMain {
+  background-color: #CCFFFF;
+  border: 1px solid #000000;
+  padding: 1em;
+  position: relative;
+  z-index: 101;
+}
+
+
+div.tabIframeWrapper {
+	width: 100%;
+}
+
+/* The main region within tab area */
+iframe.tabContent {
+  background-color: #CCFFFF;
+  
+  border: 0px solid #000000;
+	width: 100%;
+	height: 80%;
+}
+
+/* Hyperlink */
+a.tab {
+  background-color: white;
+  border: 1px solid #000000;
+  border-bottom-width: 0px;
+  padding: 2px 1em 2px 1em;
+  text-decoration: none;
+  position: relative;
+  text-decoration: none;
+  top: -1px;
+  z-index: 100;
+}
+
+/* Non-active tab */
+a.tab, a.tab:visited {
+  background-color: #DDDDDD;
+  color: #808080;
+}
+
+a.tab:hover {
+  background-color: #d0d0d0;
+  color: #606060;
+}
+
+a.tab.activeTab {
+  z-index: 102;
+}
+
+
+a.tab.activeTab, a.tab.activeTab:hover, a.tab.activeTab:visited {
+  background-color: #CCFFFF;
+  color: #000000;
+}
+
+
+a.top_menu {font-size: 100%}
+
+
+/* Image */
+/*
+.bl {background: url(../images/bl.gif) 0 100% no-repeat #E68200; width:100%}
+.br {background: url(../images/br.gif) 100% 100% no-repeat; width:100%}
+.tl {background: url(../images/tl.gif) 0 0% no-repeat; width:100%}
+.tr {background: url(../images/tr.gif) 100% 0 no-repeat; width:100%}
+*/
+
+img.front_page {
+   position:absolute;
+	 left:0px;
+	 top:0px
+}
+
+/* Form */
+
+/*input { font-size: 80% }*/
+
+
+/* Exception message box */
+
+div.exception_box
+{
+  background: rgb( 255, 200, 200 );
+  border: 2px solid rgb( 255, 150, 150 );
+}
Index: /trunk/htdocs2/templates/ArchivePageFooter.tpl
===================================================================
--- /trunk/htdocs2/templates/ArchivePageFooter.tpl	(revision 298)
+++ /trunk/htdocs2/templates/ArchivePageFooter.tpl	(revision 298)
@@ -0,0 +1,5 @@
+
+
+
+</body>
+</html>
Index: /trunk/htdocs2/templates/ArchivePageHeader.tpl
===================================================================
--- /trunk/htdocs2/templates/ArchivePageHeader.tpl	(revision 298)
+++ /trunk/htdocs2/templates/ArchivePageHeader.tpl	(revision 298)
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+
+<html>
+
+<head>
+<link rel="stylesheet" type="text/css" href="styles/opal.css" />
+<link rel="stylesheet" type="text/css" href="styles/style.css" />
+<link rel="stylesheet" type="text/css" href="styles/query.css" />
+<link rel="stylesheet" type="text/css" href="styles/results.css" />
+<link rel="stylesheet" type="text/css" href="styles/atnf.css" />
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8759-1" />
+<meta name="DC.Creator" lang="en" content="personalName=Smith,David" />
+<meta name="ATNF.Maintainer" content="contactName=Webmaster,the" />
+<meta name="DC.Title.alt" lang="en" content="" />
+<meta name="DC.Subject" lang="en" content="pulsar" />
+<meta name="DC.Description" lang="en" content="Searches the data archives at the ATNF" />
+<meta name="DC.Date.created" scheme="ISO8601" content="2002-12-12" />
+<meta name="ATNF.Site" content="Marsfield" />
+<meta name="ATNF.AccessPermission" content="Public" />
+<meta name="ATNF.MetaVersion" content="1.0" />
+<script type="text/javascript" src="scripts/expandable.js"></script>
+</head>
Index: /trunk/htdocs2/templates/CartFormFooter.tpl
===================================================================
--- /trunk/htdocs2/templates/CartFormFooter.tpl	(revision 298)
+++ /trunk/htdocs2/templates/CartFormFooter.tpl	(revision 298)
@@ -0,0 +1,7 @@
+
+
+
+</center>
+</form>
+
+
Index: /trunk/htdocs2/templates/CartFormHeader.tpl
===================================================================
--- /trunk/htdocs2/templates/CartFormHeader.tpl	(revision 298)
+++ /trunk/htdocs2/templates/CartFormHeader.tpl	(revision 298)
@@ -0,0 +1,25 @@
+<form name=cart method=post>
+<h2> Observations Cart </h2>
+<br><br>
+<center>
+<table border=0 width=100% style="border: 0px;">
+<tr><td width=30%>
+<a href=?RealAction=Logout> Logout </a> &nbsp | &nbsp
+<a href=?RealAction=BackToResults> Return to results </a> &nbsp | &nbsp
+<a href=?RealAction=NewQuery> New Query </a>
+
+</td><td width=50%>
+
+<select name=DownloadMethod>
+  <option value=""> ----- Select an Action ----- </option>
+  <option value=RemoveFromCart> Remove Selected From Cart </option>
+  <option value=DownloadObsOnly> Download Selected Observations </option>
+  <option value=DownloadCalsOnly> Download Selected Calibrations </option>
+  <option value=DownloadObsAndCals> Download Selected Obs and Cals </option>
+</select>
+<button name=RealAction value=Download > Download </button>
+</td><td width=30%>
+</td></tr>
+</table>
+<br>
+<br>
Index: /trunk/htdocs2/templates/DisplayParametersView.tpl
===================================================================
--- /trunk/htdocs2/templates/DisplayParametersView.tpl	(revision 298)
+++ /trunk/htdocs2/templates/DisplayParametersView.tpl	(revision 298)
@@ -0,0 +1,30 @@
+
+
+<table BORDER=none>
+<tr>
+  <td valign="top" class="form_field" rowspan="1">
+
+  <fieldset>
+    <legend>DISPLAY PARAMETERS</legend>
+      <input 
+        type="checkbox" 
+        name="all_params" 
+        id="all_params" 
+        onClick="checkAll('all_params', 'data_archive_form', 'params[]')"  
+      />Select all
+      <span class="commenthidden" id="params">
+        <div id="list">
+          {section name=f loop=$fields}
+            <input onClick='updateSelectAll({$fields[f].Field},"all_params")' 
+              type=checkbox
+              name="params[]"
+              value="{$fields[f].Field}"
+              id="{$fields[f].Field}"
+            />
+          {/section}
+        </div>
+      </span>
+    </fieldset>
+  </td>
+</tr>
+</table>
Index: /trunk/htdocs2/templates/GZ_Table.tpl
===================================================================
--- /trunk/htdocs2/templates/GZ_Table.tpl	(revision 298)
+++ /trunk/htdocs2/templates/GZ_Table.tpl	(revision 298)
@@ -0,0 +1,1 @@
+link ../GreenZone/templates/GZ_Table.tpl
Index: /trunk/htdocs2/templates/LoginForm.tpl
===================================================================
--- /trunk/htdocs2/templates/LoginForm.tpl	(revision 298)
+++ /trunk/htdocs2/templates/LoginForm.tpl	(revision 298)
@@ -0,0 +1,53 @@
+
+
+<body class="front_page">
+
+<div class="bodycontents">
+
+<h1>The ATNF Pulsar Data Archive</h1>
+
+<p>The ATNF Pulsar Data Archive provides access to pulsar observations
+made with the Parkes radio Telescope. Data older than <b>
+{$proprietary_period} months</b> is
+publicly available, and can be accessed by simply providing your email
+address. More recent data is proprietry, and can only be accessed by
+those who were involved in the proposal. We plan to do this via the
+<a href="http://opal.atnf.csiro.au">OPAL system</a>, but this is
+currently not enabled. In the interim, those who have previously
+obtained a login for the Data Archive can use that option below
+(making sure to check the "Data Archive login" button!). </p>
+
+<p>A <a href="pulsar_archive_guide.html">Users Guide</a> to the archive is available.</p> 
+
+<form action="{$self}" method="POST">
+<table width="700" style="border: 0px;">
+
+<tr>
+<td><input type="radio" name="authenticateType" checked value="anon">Non-proprietry access<br> 
+<table class="login" width="500" style="border: 0px;"> 
+<tr>
+<td class="form_field">Email: </td>
+<td><input type="text" name="email"></td>
+</tr>
+</table>
+<br>
+</td>
+</tr>
+
+<tr>
+
+<td><input type="radio" name="authenticateType" value="opal">Data Archive login<br>
+<table class="login" width="500" style="border: 0px;">
+<tr><td class="form_field">Username: </td><td><input type="text" name="opalEmail"></td></tr>
+<tr><td class="form_field">Password: </td><td><input type="password" name="opalPassword"></td></tr>
+</table>
+<br>
+</td>
+</tr>
+
+<tr>
+<td><input type="submit" value="Login" name="RealAction"><input type="reset" value="Reset"></td>
+</tr>
+</table>
+
+</form>
Index: /trunk/htdocs2/templates/QueryForm.tpl
===================================================================
--- /trunk/htdocs2/templates/QueryForm.tpl	(revision 298)
+++ /trunk/htdocs2/templates/QueryForm.tpl	(revision 298)
@@ -0,0 +1,317 @@
+
+
+
+<body class="atoa">
+<div class="bodycontents">
+
+<h1>ATNF Pulsar Data Archive</h1>
+
+<p>This archive provides access to pulsar observations taken at the Parkes radio telescope between the dates of 
+<b> {$from_date_limit->ToDMYString2()} </b> and <b> {$to_date_limit->ToDMYString2()} </b>.</p>
+
+<p>See the Users Guide link for more details. </p>
+
+<table width="700" style="border: 0px;">
+<tr align="center">
+<td>
+<a class="top_menu" href="{$self}?RealAction=Logout">Logout</a>
+<!--a href="login?_action=logout">Logout</a-->
+
+</td>
+<td>
+<a href="#" onClick="toggleInstructions();return false;">Instructions</a>
+</td>
+<td size="30">
+&nbsp;
+</td>
+<td>
+<a href="pulsar_archive_guide.html">Users Guide</a>
+</td>
+</tr>
+
+</table>
+
+<div id="divInstructions" style="display:none" >
+<dl class="top">
+<h2>Instructions</h2>
+<i>To hide, click "Instructions" again. </i>
+<dt> Display Parameters </dt>
+<dd> Check the fields you want shown in the results table. Suggested columns are checked by default</dd>
+<dd> The results can be ordered by one of the parameters in the "Order By" drop-down list</dd>
+<dt> Coordinates </dt>
+<dd> The sky position can be specified by a Pulsar name or a RA/Dec position. 
+The pulsar name takes precedence. The search radius must be given. </dd> 
+<dt> Filter Options </dt>
+<dd> Results can be limited to observations just from a particular project - use the Project ID box</dd>
+<dd> The date range can be specified - the defaults are the range of dates in the archive.</dd>
+<dd> Either timing data (particular pulsar) or survey data can be specified. Or both! </dd> 
+<dd> The type of instrument can be specified. Default is any type.</dd>
+<dd> More than one frequency band can be specified.
+<dt> Display Other </dt>
+<dd> Calibraton observations taken within a given time period of the queried observations can also be shown and downloaded. Check the box to do so, and specify the time interval. </dd> 
+</dl>
+</div>
+
+
+
+
+
+
+
+
+
+
+
+<form action="index.php?view=QueryForm" method="POST" name="data_archive_form" id="data_archive_form">
+<input type="hidden" name="state" value="results">
+
+
+
+
+<table class="noborder" cellpadding=0>
+
+    <tr><td colspan=3>
+	<br>
+	<center><input type="submit" value="ConeQuery" name="RealAction" style="float: center;"> &nbsp;
+	<input type="reset" value="reset" name="reset_button" style="float: center;"></center>
+	<br>
+    </td></tr>
+    
+    <tr>
+<td>	
+<table cellspacing=0 cellpadding=0 style="border: 0px;">
+<tr>
+  <td>
+    <fieldset id="flsPosition">
+      <legend>POSITION REQUIREMENTS</legend>
+
+      <!-- Pulsar Name -->
+      <fieldset>
+        <legend>Pulsar Name</legend>
+        <input type="text" name="pulsar_name" size="20" value="{$parameters->GetPulsarName()}">
+        <br>
+
+        <p>Note that search-by-name takes precedence over search-by-RA/Dec.</p>
+      </fieldset>
+
+      <br>
+
+      <fieldset>
+	<legend>Right Ascension (J2000)</legend>
+		
+		<input type="text" id="txtRAHour" name="ra_hour" size="3" tabindex="1" 
+                        value="{$coordinates->GetRAHour()}"/>
+		<label for="txtRAHour" class="coordinate"><abbr title="hours"><sup>h</sup></abbr></label>
+
+					     
+		    <input type="text" id="txtRAMinute" name="ra_min" size="3" tabindex="1" value="{$coordinates->GetRAMin()}"/>
+		<label for="txtRAMinute" class="coordinate"><abbr title="minutes"><sup>m</sup></abbr></label>
+		
+		    <input type="text" id="txtRASecond" name="ra_sec" size="6" tabindex="1" value="{$coordinates->GetRASec()}"/>
+		<label for="txtRASecond" class="coordinate"><abbr title="seconds"><sup>s</sup></abbr></label>
+		</fieldset>
+	
+	        <fieldset>
+		<legend>Declination (J2000)</legend>
+
+		
+		    <input type="text" id="txtDecDegree" name="dec_deg" size="3" tabindex="1" value="{$coordinates->GetDECDeg()}"/>
+		<label for="txtDecDegree" class="coordinate"><abbr title="degrees">&deg;</abbr></label>
+		
+		    <input type="text" id="txtDecMinute" name="dec_min" size="3" tabindex="1" value="{$coordinates->GetDECMin()}"/>
+		<label for="txtDecMinute" class="coordinate"><abbr title="minutes">&prime;</abbr></label>
+		
+		    <input type="text" id="txtDecSecond" name="dec_sec" size="6" tabindex="1" value="{$coordinates->GetDECSec()}"/>
+		<label for="txtDecSecond" class="coordinate"><abbr title="seconds">&Prime;</abbr></label>
+	        </fieldset>
+
+                <br>
+
+                <br>
+	</fieldset>
+
+        <fieldset id="flsSearchRadius">
+	<legend>SEARCH WINDOW [arcmin]</legend>
+	<input type="text" name="search_radius" size="20" tabindex="1" value="{$parameters->GetSearchRadius()}"/>
+        </fieldset>
+        
+
+
+
+
+        </td></tr>
+</table>
+</td>
+<td>
+<table style="border: 0px;" cellpadding=5>
+
+
+
+<!-- filter options -->
+
+        <tr><td>
+        <br>
+
+
+
+        
+	<fieldset id="flsObsDate">
+				
+		<legend>FILTER OPTIONS</legend>
+<br>
+        <fieldset id="flsProjectID">
+	<legend>PROJECT ID</legend>
+	<input type="text" name="project_id" size="20" tabindex="1" value="{$parameters->GetProjectID()}"/>
+        </fieldset>
+<!--        <br>-->
+		<!-- Date range -->
+		<fieldset>
+
+			<legend>Date Range</legend>
+			
+			  &nbsp From:
+			    <select name="from_day">
+                              {section name=d loop=$days_in_month}
+                                <option value="{$days_in_month[d]}" 
+                                  {if $from_date->GetDayOfMonth() == $days_in_month[d]} selected {/if}
+                                >{$days_in_month[d]}</option>
+                              {/section}
+			    </select> 
+
+			    <select name="from_month">
+			      {section name=m loop=$months_in_year}
+				<option value="{$months_in_year[m]}"
+			      {if $from_date->GetMonthOfYearTxt() == $months_in_year[m]} selected {/if}
+				  >
+				  {$months_in_year[m]}
+				</option>
+			      {/section}
+			    </select> 
+			    
+			    <select name="from_year">
+                              {section name=y loop=$known_years}
+				<option value="{$known_years[y]}"
+                                  {if $from_date->GetYear() == $known_years[y]} selected {/if}
+				  >
+                                  {$known_years[y]}
+				</option>
+                              {/section}
+			    </select> 
+                          <br><br>To: 
+			    <select name="to_day">
+                              {section name=d loop=$days_in_month}
+                                <option value="{$days_in_month[d]}" 
+                                  {if $to_date->GetDayOfMonth() == $days_in_month[d]} selected {/if}
+                                >{$days_in_month[d]}</option>
+                              {/section}
+			    </select> 
+
+			    <select name="to_month">
+			      {section name=m loop=$months_in_year}
+				<option value="{$months_in_year[m]}"
+			      {if $to_date->GetMonthOfYearTxt() == $months_in_year[m]} selected {/if}
+				  >
+				  {$months_in_year[m]}
+				</option>
+			      {/section}
+			    </select> 
+			    
+			    <select name="to_year">
+                              {section name=y loop=$known_years}
+				<option value="{$known_years[y]}"
+                                  {if $to_date->GetYear() == $known_years[y]} selected {/if}
+				  >
+                                  {$known_years[y]}
+				</option>
+                              {/section}
+			    </select> 
+		</fieldset>
+
+ 
+<br>
+		<!-- Obs Mode -->
+		<fieldset>
+		  <legend>Obs Mode</legend>
+
+		  <select name="obs_mode" onchange="ObsModeChanged()" id="ObsModeList">
+		    <option value="any" {if $parameters->GetObsMode() == "any"}selected{/if} > Any </option>
+		    <option value="timing" {if $parameters->GetObsMode() == "timing"}selected{/if}> Only timing data </option>
+		    <option value="search" {if $parameters->GetObsMode() == "search"}selected{/if}> Only search data </option>
+                  </select>
+		</fieldset>
+
+		<!-- Data Type -->
+		<fieldset>
+			<legend>Data Type</legend>
+
+			<select name="data_type">
+				<option value="Any" selected> Any </option>
+				{section name=t loop=$valid_data_types}
+				  <option value="{$valid_data_types[t]}"
+				    {if $parameters->GetDataType() == $valid_data_types[t]} selected {/if}>
+				  {$valid_data_types[t]}
+				  </option>
+				{/section}
+			</select> 
+		</fieldset>	
+
+		<!-- Frequency band -->
+
+                <fieldset>
+			<legend>Band Name</legend> 
+			    <select id="selBand" name="bands[]" multiple="multiple" size="5">
+			    
+<option value="Any">Any</option>
+{section name=b loop=$valid_bands}
+  <option value="{$valid_bands[b]->GetName()}"
+    {section name=mb loop=$bands}
+      {if $bands[mb]->GetName() == $valid_bands[b]->GetName()} selected {/if}
+    {/section}
+    >{$valid_bands[b]->GetName()}&nbsp{$valid_bands[b]->GetDescription()}
+  </option>
+{/section}
+</select>
+
+     </fieldset>
+     
+     
+
+       </fieldset>
+       
+        <fieldset id="flsCalsWindow">
+          <legend> Display Other Data </legend>
+          <input type="checkbox" name="add_cals"
+            {if $parameters->GetCalsWindow() != null} CHECKED {/if}
+          />
+          Get cals within
+          <input type="text" name="cals_window" size="20" tabindex="2" value="{$parameters->GetCalsWindow()}"/>
+          mins
+        </fieldset>
+        
+        
+        </td></tr>
+        </table>
+	<br>
+	</td>
+	</tr>	
+
+
+<!-- end filter options -->
+
+
+
+
+
+
+
+</table>
+</td>
+	
+	</tr>
+	</table>
+
+
+
+</form>
+<div style="min-height: 20px; max-height: 1000px;"> </div>
+
Index: /trunk/htdocs2/templates/QueryResultsFormFooter.tpl
===================================================================
--- /trunk/htdocs2/templates/QueryResultsFormFooter.tpl	(revision 298)
+++ /trunk/htdocs2/templates/QueryResultsFormFooter.tpl	(revision 298)
@@ -0,0 +1,6 @@
+
+
+
+</center>
+
+</form>
Index: /trunk/htdocs2/templates/QueryResultsFormHeader.tpl
===================================================================
--- /trunk/htdocs2/templates/QueryResultsFormHeader.tpl	(revision 298)
+++ /trunk/htdocs2/templates/QueryResultsFormHeader.tpl	(revision 298)
@@ -0,0 +1,40 @@
+<h2> Query Results </h2>
+
+<br><br>
+<form name=QueryResultForm method=post action="">
+<center>
+<table border="0" border=0 style="border: 0px;" width=100%>
+  <tr>
+    <td width="25%">
+      <a href=?RealAction=Logout> Logout </a> &nbsp | &nbsp
+      <a href=?RealAction=NewQuery> New Query </a>
+    </td>
+    <td width="50%" align=center>
+      <select name=Action>
+        <option value=""> ----- Select an action ----- </option>
+        <option value="AddToCart"> Add observations to cart </option>
+        <option value=""> ----- Profile viewing options ----- </option>
+        <option value="ViewProfiles"> View selected profiles </option>
+        <option value="ViewProfilesAndCals"> View selected profiles with cals </option>
+      </select>
+      <input type="submit" name="RealAction" value="PerformAction"/>
+    </td>
+    <td width="25%" align=right>
+
+      Cart size: <a href=?RealAction=ShowCart>{$cart_size} item/s </a>
+      <b>({$download_size} MB)</b>
+      <a href=?RealAction=ShowCart> view observation cart </a>
+    </td>
+  </tr>
+</table>
+
+<br>
+<br>
+
+{if $adjusted_from_date != null}
+  
+  You're date range has been adjusted to <b> {$adjusted_from_date} </b> To <b> {$adjusted_to_date} </b>.
+{/if}
+
+<br>
+
Index: /trunk/htdocs2/templates/footer.tpl
===================================================================
--- /trunk/htdocs2/templates/footer.tpl	(revision 298)
+++ /trunk/htdocs2/templates/footer.tpl	(revision 298)
@@ -0,0 +1,43 @@
+
+
+                                                                                                                        
+
+
+<div style="position: fixed; bottom: 0px; width: 100%;">
+  <center>
+	<div class="bottom-matter">
+	    <!--
+		<div id="last-modified">Last modified: </div>
+		-->
+		
+		<div>
+			&#169; Copyright CSIRO Australia 2004. 
+			<a href="http://www.csiro.au/index.asp?type=aboutCSIRO&amp;xml=mrcopyright&amp;style=generic">CSIRO Media Release information</a>, 
+			<a href="http://www.csiro.au/index.asp?type=aboutCSIRO&amp;xml=disclaimer&amp;style=generic">Legal Notice and Disclaimer</a>, 
+			<a href="http://www.csiro.au/index.asp?type=aboutCSIRO&amp;xml=privacy&amp;stylesheet=generic">Privacy Statement</a>.			
+		</div>
+	</div>
+
+	
+ 	<div class="navbar">
+		<a href="http://www.atnf.csiro.au/">Home</a>
+		<a href="http://www.atnf.csiro.au/the_atnf/">The ATNF</a>
+		<a href="http://www.atnf.csiro.au/news/">News</a>
+		<a href="http://www.atnf.csiro.au/whats_on/">What's On</a>
+		<a href="http://www.atnf.csiro.au/observers/">Observers</a>
+
+		<a href="http://www.atnf.csiro.au/research/">Research</a>
+		<a href="http://www.atnf.csiro.au/technology/">Technology</a>
+		<a href="http://outreach.atnf.csiro.au/">Outreach</a>
+		<a href="http://www.atnf.csiro.au/resources/">Resources</a>
+		<a href="http://www.atnf.csiro.au/contact/">Contact</a>
+		<a href="http://www.atnf.csiro.au/search/">Search</a>
+
+		<a href="http://www.atnf.csiro.au/internal/"><em>Internal</em></a>
+	</div>
+  </center>
+</div>
+
+
+                                                                                                                       
+
Index: /trunk/htdocs2/templates/header.tpl
===================================================================
--- /trunk/htdocs2/templates/header.tpl	(revision 298)
+++ /trunk/htdocs2/templates/header.tpl	(revision 298)
@@ -0,0 +1,42 @@
+<table cellpadding="0" cellspacing="0" border="0" valign="top" width="100%">
+
+<div id="header">
+
+<div id="divTitleBar">
+  <a href="http://www.csiro.au/"><img id="imgCSIRO" src="http://www.atnf.csiro.au/images/csiro_logo_white.gif" alt="CSIRO" /></a>
+  
+<div class="site-links">
+  <a href="http://www.parkes.atnf.csiro.au/" class="site_link">Parkes</a>&nbsp;&nbsp;
+  <a href="http://www.narrabri.atnf.csiro.au/"  class="site_link">Narrabri</a>&nbsp;&nbsp;
+  <a href="http://www.narrabri.atnf.csiro.au/mopra/" class="site_link">Mopra</a>&nbsp;&nbsp;
+  <a href="http://www.atnf.csiro.au/vlbi/" class="site_link">VLBI</a>&nbsp;&nbsp;
+  <a href="http://www.atnf.csiro.au/projects/askap/" class="site_link">ASKAP</a>&nbsp;&nbsp;
+  <a href="http://www.atnf.csiro.au/projects/ska/" class="site_link">SKA</a>&nbsp;&nbsp;
+  <a href="http://www.atnf.csiro.au/projects/mnrf/" class="site_link">MNRF</a>
+</div>
+
+<img id="imgEpping" src="http://www.atnf.csiro.au/images/top_left_epping.gif" alt="One of the ATCA Dishes" />
+<a href="/"><img id="imgATNF" src="http://www.atnf.csiro.au/images/atnf_title_big.gif" alt="Australia Telescope National Facility" /></a>
+
+</div>
+
+<div class="navbar">
+  <a href="http://www.atnf.csiro.au/">Home</a>
+  <a href="http://www.atnf.csiro.au/the_atnf/">The ATNF</a>
+  <a href="http://www.atnf.csiro.au/news/">News</a>
+  <a href="http://www.atnf.csiro.au/whats_on/">What's On</a>
+  <a href="http://www.atnf.csiro.au/observers/">Observers</a>
+  
+  <a href="http://www.atnf.csiro.au/research/">Research</a>
+  <a href="http://www.atnf.csiro.au/technology/">Technology</a>
+  <a href="http://outreach.atnf.csiro.au/">Outreach</a>
+  <a href="http://www.atnf.csiro.au/resources/">Resources</a>
+  <a href="http://www.atnf.csiro.au/contact/">Contact</a>
+  <a href="http://www.atnf.csiro.au/search/">Search</a>
+  
+  <a href="http://www.atnf.csiro.au/internal/"><em>Internal</em></a>
+</div>
+
+</div>
+
+</table>
