if($folder == "base") {
	$serverpath = ".";
} else {
	$serverpath = "..";
}
// SPECIFY PATHS TO SMARTY RESOURCES
$smartypath_template_dir = realpath("$serverpath/templates");
$smartypath_compile_dir = realpath("$serverpath/include/smarty/templates_c");
$smartypath_cache_dir = realpath("$serverpath/include/smarty/cache");
$smartypath_config_dir = realpath("$serverpath/include/smarty/configs");
// INITIATE SMARTY CLASS
require("$serverpath/include/smarty/Smarty.class.php");
$smarty = new Smarty();
// ASSIGN SMARTY TEMPLATE DIRECTORY PATHS
$smarty->template_dir = $smartypath_template_dir;
$smarty->compile_dir = $smartypath_compile_dir;
$smarty->cache_dir = $smartypath_cache_dir;
$smarty->config_dir = $smartypath_config_dir;
?>
$database_host = 'localhost';
$database_username = 'de5z6k1_db39127_';
$database_password = 'vbxud?FkJGUn1xg4';
$database_name = 'de5z6k1_db39127_slackengine';
?>
//  THIS CLASS CONTAINS DATABASE-RELATED METHODS
//  IT IS USED TO CONNECT TO THE DATABASE, RUN QUERIES, AND REPORT ERRORS
//  CURRENTLY MySQL IS THE DATABASE TYPE, EVENTUALLY ADD SUPPORT FOR OTHER DATABASE TYPES
//  METHODS IN THIS CLASS:
//    se_database()
//    database_connect()
//    database_select()
//    database_query()
//    database_fetch_array()
//    database_fetch_assoc()
//    database_num_rows()
//    database_affected_rows()
//    database_set_charset()
//    database_real_escape_string()
//    database_insert_id()
//    database_error()
//    database_close()
class se_database {
	// INITIALIZE VARIABLES
	var $database_connection;		// VARIABLE REPRESENTING DATABASE LINK IDENTIFIER
	var $log_stats;				// VARIABLE DETERMINING WHETHER QUERY INFO SHOULD BE LOGGED
	var $query_stats;			// ARRAY CONTAINING RELEVANT INFORMATION ABOUT QUERIES RUN
	// THIS METHOD CONNECTS TO THE SERVER AND SELECTS THE DATABASE
	// INPUT: $database_host REPRESENTING THE DATABASE HOST
	//	  $database_username REPRESENTING THE DATABASE USERNAME
	//	  $database_password REPRESENTING THE DATABASE PASSWORD
	//	  $database_name REPRESENTING THE DATABASE NAME
	// OUTPUT: 
	function se_database($database_host, $database_username, $database_password, $database_name) {
	  $this->database_connection = $this->database_connect($database_host, $database_username, $database_password) or die($this->database_error());
	  $this->database_select($database_name) or die($this->database_error());
	
	  $this->log_stats = 1;
	  $this->query_stats = Array();
	} // END se_database() METHOD
	// THIS METHOD CONNECTS TO A DATABASE SERVER
	// INPUT: $database_host REPRESENTING THE DATABASE HOST
	//	  $database_username REPRESENTING THE DATABASE USERNAME
	//	  $database_password REPRESENTING THE DATABASE PASSWORD
	// OUTPUT: RETURNS A DATABASE LINK IDENTIFIER
	function database_connect($database_host, $database_username, $database_password) {
	  return mysql_connect($database_host, $database_username, $database_password, TRUE);
	} // END database_connect() METHOD
	// THIS METHOD SELECTS A DATABASE
	// INPUT: $database_name REPRESENTING THE DATABASE NAME
	// OUTPUT: RETURNS OUTPUT FOR DATABASE SELECTION
	function database_select($database_name) {
	  return mysql_select_db($database_name, $this->database_connection);
	} // END database_select() METHOD
	// THIS METHOD QUERIES A DATABASE
	// INPUT: $database_query REPRESENTING THE DATABASE QUERY TO RUN
	// OUTPUT: RETURNS A DATABASE QUERY RESULT RESOURCE
	function database_query($database_query) {
	
	  $query_timer_start = getmicrotime();
	  $query_result = mysql_query($database_query, $this->database_connection); 
	  
	  if($this->log_stats != 0) {
	    $query_time = round(getmicrotime()-$query_timer_start, 5);
	    $this->query_stats[] = Array('query' => $database_query,
					'time' => $query_time);
	  }
	  return $query_result;
	} // END database_query() METHOD
	// THIS METHOD FETCHES A ROW AS A NUMERIC ARRAY
	// INPUT: $database_result REPRESENTING A DATABASE QUERY RESULT RESOURCE
	// OUTPUT: RETURNS A NUMERIC ARRAY FOR A DATABASE ROW
	function database_fetch_array($database_result) {
	  return mysql_fetch_array($database_result);
	} // END database_fetch_array() METHOD
	// THIS METHOD FETCHES A ROW AS AN ASSOCIATIVE ARRAY
	// INPUT: $database_result REPRESENTING A DATABASE QUERY RESULT RESOURCE
	// OUTPUT: RETURNS AN ASSOCIATIVE ARRAY FOR A DATABASE ROW
	function database_fetch_assoc($database_result) {
	  return mysql_fetch_assoc($database_result);
	} // END database_fetch_assoc() METHOD
	// THIS METHOD RETURNS THE NUMBER OF ROWS IN A RESULT
	// INPUT: $database_result REPRESENTING A DATABASE QUERY RESULT RESOURCE
	// OUTPUT: RETURNS THE NUMBER OF ROWS IN A RESULT
	function database_num_rows($database_result) {
	  return mysql_num_rows($database_result);
	} // END database_num_rows() METHOD
	// THIS METHOD RETURNS THE NUMBER OF ROWS IN A RESULT
	// INPUT: $database_result REPRESENTING A DATABASE QUERY RESULT RESOURCE
	// OUTPUT: RETURNS THE NUMBER OF ROWS IN A RESULT
	function database_affected_rows() {
	  return mysql_affected_rows($this->database_connection);
	} // END database_affected_rows() METHOD 
	// THIS METHOD SETS THE CLIENT CHARACTER SET FOR THE CURRENT CONNECTION
	// INPUT: $charset REPRESENTING A VALID CHARACTER SET NAME
	// OUTPUT: 
	function database_set_charset($charset) {
	  if(function_exists('mysql_set_charset') === TRUE) {
	    return mysql_set_charset($charset, $this->database_connection);
	  } else {
	    return $this->database_query('SET NAMES "'.$charset.'"');
	  }
	} // END database_set_charset() METHOD 
	// THIS METHOD ESCAPES SPECIAL CHARACTERS IN A STRING FOR USE IN AN SQL STATEMENT
	// INPUT: $unescaped_string REPRESENTING THE STRING TO ESCAPE
	// OUTPUT: 
	function database_real_escape_string($unescaped_string) {
	  return mysql_real_escape_string($unescaped_string, $this->database_connection);
	} // END database_real_escape_string() METHOD 
	// THIS METHOD RETURNS THE ID GENERATED FROM THE PREVIOUS INSERT OPERATION
	// INPUT: 
	// OUTPUT: RETURNS THE ID GENERATED FROM THE PREVIOUS INSERT OPERATION
	function database_insert_id() {
	  return mysql_insert_id($this->database_connection);
	} // END database_insert_id() METHOD
	// THIS METHOD RETURNS THE DATABASE ERROR
	// INPUT: 
	// OUTPUT: 
	function database_error() {
	  return mysql_error($this->database_connection);
	} // END database_error() METHOD
	// THIS METHOD CLOSES A CONNECTION TO THE DATABASE SERVER
	// INPUT: 
	// OUTPUT: 
	function database_close() {
	  mysql_close($this->database_connection);
	} // END database_close() METHOD
}
?>
//  THIS CLASS CONTAINS DATE/TIME-RELATED METHODS.
//  IT IS USED TO FORMAT TIMESTAMPS
//  METHODS IN THIS CLASS:
//    cdate()
//    untimezone()
//    timezone()
//    time_since()
//    age()
class se_datetime {
	// INITIALIZE VARIABLES
	var $is_error;			// DETERMINES WHETHER THERE IS AN ERROR OR NOT
	// THIS METHOD SETS INITIAL VARS SUCH AS PRELOADING LANG VARS
	// INPUT:  
	// OUTPUT: 
	function se_datetime() {
	  SE_Language::_preload_multi(773, 774, 775, 776, 777, 778, 779);
	} // END se_datetime() METHOD
	// THIS METHOD RETURNS A FORMATTED DATE (MULTILANGUAGE)
	// INPUT: $format REPRESENTING A DATE FORMAT BASED ON THE PHP DATE() FUNCTION FORMAT
	//	  $time (OPTIONAL) REPRESENTING A TIMESTAMP
	// OUTPUT: A STRING REPRESENTING A FORMATTED DATE BASED ON THE GIVEN TIMESTAMP
	function cdate($format, $time = "") {
	  global $multi_language;
	  if($time == "") { $time = time(); }
	  if(!$multi_language) {
	    return date($format, $time);
	  } else {
	    $date_letters = Array("a", "A", "B", "c", "D", "d", "F", "m", "M", "I", "i", "g", "h", "H", "G", "j", "l", "L", "n", "O", "r", "S", "s", "t", "U", "W", "w", "Y", "y", "z", "Z", "T");
	    $strftime_letters = Array("%p", "%p", "", "", "%a", "%d", "%B", "%m", "%b", "", "%M", "%I", "%I", "%H", "%H", "%e", "%A", "", "%m", "", "", "", "%S", "", "", "%V", "%w", "%Y", "%y", "%j", "", "%Z");
	    $new_format = str_replace($date_letters, $strftime_letters, $format);
	    return strftime($new_format, $time);
	  }
	} // END cdate() METHOD
	// THIS METHOD RETURNS A TIMESTAMP IN THE SERVER TIMEZONE
	// INPUT: $time REPRESENTING A TIMESTAMP IN USER'S TIME
	//	  $timezone REPRESENTING A TIMEZONE
	// OUTPUT: A TIMESTAMP IN THE SERVER TIMEZONE
	function untimezone($time, $timezone) {
	  switch($timezone) {
	    case -12: $new_time = $time + 43200; break;
	    case -11: $new_time = $time + 39600; break;
	    case -10: $new_time = $time + 33000; break;
	    case -9: $new_time = $time + 32400; break;
	    case -8: $new_time = $time + 28800; break;
	    case -7: $new_time = $time + 25200; break;
	    case -6: $new_time = $time + 21600; break;
	    case -5: $new_time = $time + 18000; break;
	    case -4: $new_time = $time + 14400; break;
	    case -3.3: $new_time = $time + 11880; break;
	    case -3: $new_time = $time + 10800; break;
	    case -2: $new_time = $time + 7200; break;
	    case -1: $new_time = $time + 3600; break;
	    case 0: $new_time = $time; break;
  	    case 1: $new_time = $time - 3600; break;
  	    case 2: $new_time = $time - 7200; break;
  	    case 3: $new_time = $time - 10800; break;
  	    case 3.3: $new_time = $time - 11880; break;
  	    case 4: $new_time = $time - 14400; break;
  	    case 4.3: $new_time = $time - 15480; break;
  	    case 5: $new_time = $time - 18000; break;
  	    case 5.5: $new_time = $time - 19800; break;
  	    case 6: $new_time = $time - 21600; break;
  	    case 7: $new_time = $time - 25200; break;
  	    case 8: $new_time = $time - 28800; break;
  	    case 9: $new_time = $time - 32400; break;
  	    case 9.3: $new_time = $time - 33480; break;
  	    case 10: $new_time = $time - 33000; break;
  	    case 11: $new_time = $time - 39600; break;
  	    case 12: $new_time = $time - 43200; break;
	  }
	  $new_time = $new_time+(date("Z")-(date("I")*3600));
	  return $new_time;
  
	} // END untimezone() METHOD
	// THIS METHOD RETURNS A TIMESTAMP IN THE CORRECT TIMEZONE
	// INPUT: $time REPRESENTING A TIMESTAMP IN SERVER TIME
	//	  $timezone REPRESENTING A TIMEZONE
	// OUTPUT: A TIMESTAMP IN THE CORRECT TIMEZONE
	function timezone($time, $timezone) {
	  $time = $time-(date("Z")-(date("I")*3600));
	  switch($timezone) {
	    case -12: $new_time = $time - 43200; break;
	    case -11: $new_time = $time - 39600; break;
	    case -10: $new_time = $time - 33000; break;
	    case -9: $new_time = $time - 32400; break;
	    case -8: $new_time = $time - 28800; break;
	    case -7: $new_time = $time - 25200; break;
	    case -6: $new_time = $time - 21600; break;
	    case -5: $new_time = $time - 18000; break;
	    case -4: $new_time = $time - 14400; break;
	    case -3.3: $new_time = $time - 11880; break;
	    case -3: $new_time = $time - 10800; break;
	    case -2: $new_time = $time - 7200; break;
	    case -1: $new_time = $time - 3600; break;
	    case 0: $new_time = $time; break;
  	    case 1: $new_time = $time + 3600; break;
  	    case 2: $new_time = $time + 7200; break;
  	    case 3: $new_time = $time + 10800; break;
  	    case 3.3: $new_time = $time + 11880; break;
  	    case 4: $new_time = $time + 14400; break;
  	    case 4.3: $new_time = $time + 15480; break;
  	    case 5: $new_time = $time + 18000; break;
  	    case 5.5: $new_time = $time + 19800; break;
  	    case 6: $new_time = $time + 21600; break;
  	    case 7: $new_time = $time + 25200; break;
  	    case 8: $new_time = $time + 28800; break;
  	    case 9: $new_time = $time + 32400; break;
  	    case 9.3: $new_time = $time + 33480; break;
  	    case 10: $new_time = $time + 33000; break;
  	    case 11: $new_time = $time + 39600; break;
  	    case 12: $new_time = $time + 43200; break;
	  }
	  return $new_time;
  
	} // END timezone() METHOD
	// THIS METHOD RETURNS A STRING SPECIFYING THE TIME SINCE THE SPECIFIED TIMESTAMP
	// INPUT: $time REPRESENTING A TIMESTAMP
	// OUTPUT: A STRING SPECIFYING THE TIME SINCE THE SPECIFIED TIMESTAMP
	function time_since($time) {
	  $now = time();
	  $now_day = date("j", $now);
	  $now_month = date("n", $now);
	  $now_year = date("Y", $now);
	  $time_day = date("j", $time);
	  $time_month = date("n", $time);
	  $time_year = date("Y", $time);
	  $time_since = "";
	  $lang_var = 0;
	  switch(TRUE) {
	  
	    case ($now-$time < 60):
	      // RETURNS SECONDS
	      $seconds = $now-$time;
	      $time_since = $seconds;
	      $lang_var = 773;
	      break;
	    case ($now-$time < 3600):
	      // RETURNS MINUTES
	      $minutes = round(($now-$time)/60);
	      $time_since = $minutes;
	      $lang_var = 774;
	      break;
	    case ($now-$time < 86400):
	      // RETURNS HOURS
	      $hours = round(($now-$time)/3600);
	      $time_since = $hours;
	      $lang_var = 775;
	      break;
	    case ($now-$time < 1209600):
	      // RETURNS DAYS
	      $days = round(($now-$time)/86400);
	      $time_since = $days;
	      $lang_var = 776;
	      break;
	    case (mktime(0, 0, 0, $now_month-1, $now_day, $now_year) < mktime(0, 0, 0, $time_month, $time_day, $time_year)):
	      // RETURNS WEEKS
	      $weeks = round(($now-$time)/604800);
	      $time_since = $weeks;
	      $lang_var = 777;
	      break;
	    case (mktime(0, 0, 0, $now_month, $now_day, $now_year-1) < mktime(0, 0, 0, $time_month, $time_day, $time_year)):
	      // RETURNS MONTHS
	      if($now_year == $time_year) { $subtract = 0; } else { $subtract = 12; }
	      $months = round($now_month-$time_month+$subtract);
	      $time_since = $months;
	      $lang_var = 778;
	      break;
	    default:
	      // RETURNS YEARS
	      if($now_month < $time_month) { 
	        $subtract = 1; 
	      } elseif($now_month == $time_month) {
	        if($now_day < $time_day) { $subtract = 1; } else { $subtract = 0; }
	      } else { 
	        $subtract = 0; 
	      }
	      $years = $now_year-$time_year-$subtract;
	      $time_since = $years;
	      $lang_var = 779;
	      if($years == 0) { $time_since = ""; $lang_var = 0; }
	      break;
	  }
	  return Array($lang_var, $time_since);
  
	} // END time_since() METHOD
	// THIS METHOD RETURNS AN AGE BASED ON A GIVEN MYSQL DATE
	// INPUT: $time REPRESENTING A MYSQL-FORMAT DATE (YYYY-MM-DD)
	// OUTPUT: AN INTEGER REPRESENTING AN AGE BASED ON THE DATE
	function age($time) {
	  $now = time();
	  $now_day = date("d", $now);
	  $now_month = date("m", $now);
	  $now_year = date("Y", $now);
	  $time_day = substr($time, 8, 2);
	  $time_month = substr($time, 5, 2);
	  $time_year = substr($time, 0, 4);
	  // RETURNS YEARS
	  if($now_month < $time_month) { 
	    $subtract = 1; 
	  } elseif($now_month == $time_month) {
	    if($now_day < $time_day) {
	      $subtract = 1;
	    } else {
	      $subtract = 0;
	    }
	  } else { 
	    $subtract = 0; 
	  }
	  $years = $now_year-$time_year-$subtract;
	  return $years;
  
	} // END age() METHOD
}
?>
//  THIS CLASS CONTAINS COMMENT-RELATED METHODS 
//  IT IS USED FOR ALL COMMENTING (INCLUDING PLUGINS)
//  METHODS IN THIS CLASS:
//    se_comment()
//    comment_total()
//    comment_list()
//    comment_post()
//    comment_edit()
//    comment_delete()
//    comment_delete_selected()
class se_comment {
	// INITIALIZE VARIABLES
	var $is_error;			// DETERMINES WHETHER THERE IS AN ERROR OR NOT
	var $comment_type;		// CONTAINS THE PREFIX CORRESPONDING TO THE COMMENT TYPE (EX: PROFILE FOR SE_PROFILECOMMENTS)
	var $comment_identifier;	// CONTAINS THE IDENTIFYING COLUMN IN THE TABLE (EX: USER_ID FOR SE_PROFILECOMMENTS)
	var $comment_identifying_value;	// CONTAINS THE VALUE TO MATCH TO THE IDENTIFIER
	// THIS METHOD SETS INITIAL VARS
	// INPUT: $type REPRESENTING THE PREFIX CORRESPONDING TO THE COMMENT TYPE
	//	  $identifier REPRESENTING THE IDENTIFYING COLUMN IN THE TABLE
	// OUTPUT: 
	function se_comment($type, $identifier, $identifying_value) {
	  $this->comment_type = $type;
	  $this->comment_identifier = $identifier;
	  $this->comment_identifying_value = $identifying_value;
	} // END se_comment() METHOD
	// THIS METHOD RETURNS THE TOTAL NUMBER OF COMMENTS
	// INPUT:
	// OUTPUT: AN INTEGER REPRESENTING THE NUMBER OF COMMENTS
	function comment_total() {
	  global $database;
	  $comment_query = "SELECT ".$this->comment_type."comment_id FROM se_".$this->comment_type."comments WHERE ".$this->comment_type."comment_".$this->comment_identifier."='".$this->comment_identifying_value."'";
	  $comments_total = $database->database_num_rows($database->database_query($comment_query));
	  return $comments_total;
	} // END comment_total() METHOD
	// THIS METHOD RETURNS AN ARRAY CONTAINING COMMENT INFO
	// INPUT: $start REPRESENTING THE COMMENT TO START WITH
	//	  $limit REPRESENTING THE NUMBER OF COMMENTS TO RETURN
	// OUTPUT: AN ARRAY OF COMMENTS
	function comment_list($start, $limit) {
	  global $database, $setting, $user;
	  $comment_array = Array();
	  $comment_query = "SELECT 
				se_".$this->comment_type."comments.*, 
				se_users.user_id, 
				se_users.user_username, 
				se_users.user_fname,
				se_users.user_lname,
				se_users.user_photo,
			CASE
			  WHEN ((se_users.user_privacy & @SE_PRIVACY_REGISTERED) AND {$user->user_exists}<>0)
			    THEN FALSE
			  WHEN ((se_users.user_privacy & @SE_PRIVACY_ANONYMOUS) AND {$user->user_exists}=0)
			    THEN FALSE
			  WHEN ((se_users.user_privacy & @SE_PRIVACY_SELF) AND se_users.user_id={$user->user_info[user_id]})
			    THEN FALSE
			  WHEN ((se_users.user_privacy & @SE_PRIVACY_FRIEND) AND (SELECT TRUE FROM se_friends WHERE friend_user_id1=se_users.user_id AND friend_user_id2={$user->user_info[user_id]} AND friend_status='1' LIMIT 1))
			    THEN FALSE
			  WHEN ((se_users.user_privacy & @SE_PRIVACY_SUBNET) AND se_users.user_subnet_id={$user->user_info[user_subnet_id]})
			    THEN FALSE
			  WHEN ((se_users.user_privacy & @SE_PRIVACY_FRIEND2) AND se_users.user_subnet_id={$user->user_info[user_subnet_id]} AND (SELECT TRUE FROM se_friends AS friends_primary LEFT JOIN se_friends AS friends_secondary ON friends_primary.friend_user_id2=friends_secondary.friend_user_id1 WHERE friends_primary.friend_user_id1=se_users.user_id AND friends_secondary.friend_user_id2={$user->user_info[user_id]} LIMIT 1))
			    THEN FALSE
			  ELSE TRUE
			END
			AS is_profile_private
			FROM 
				se_".$this->comment_type."comments 
			LEFT JOIN 
				se_users 
			ON 
				se_".$this->comment_type."comments.".$this->comment_type."comment_authoruser_id=se_users.user_id 
			WHERE 
				".$this->comment_type."comment_".$this->comment_identifier."='".$this->comment_identifying_value."' 
			ORDER BY ".$this->comment_type."comment_id DESC 
			LIMIT $start, $limit";
	  $comments = $database->database_query($comment_query);
	  while($comment_info = $database->database_fetch_assoc($comments)) {
	    // CREATE AN OBJECT FOR AUTHOR
	    $author = new se_user();
	    if($comment_info[user_id] != $comment_info[$this->comment_type.'comment_authoruser_id']) {
	      $author->user_exists = 0;
	    } else {
	      $author->user_exists = 1;
	      $author->user_info[user_id] = $comment_info[user_id];
	      $author->user_info[user_username] = $comment_info[user_username];
	      $author->user_info[user_fname] = $comment_info[user_fname];
	      $author->user_info[user_lname] = $comment_info[user_lname];
	      $author->user_info[user_photo] = $comment_info[user_photo];
	      $author->user_displayname();
	    }
	    // SET COMMENT ARRAY
	    $comment_array[] = Array('comment_id' => $comment_info[$this->comment_type.'comment_id'],
					'comment_authoruser_id' =>$comment_info[$this->comment_type.'comment_authoruser_id'],
					'comment_author' => $author,
					'comment_date' => $comment_info[$this->comment_type.'comment_date'],
					'comment_body' => $comment_info[$this->comment_type.'comment_body'],
					'comment_author_private' => $comment_info[is_profile_private]);
	  }
	  return $comment_array;
	} // END comment_list() METHOD
	// THIS METHOD POSTS A COMMENT
	// INPUT: $comment_body REPRESENTING THE COMMENT BODY BEING POSTED
	//	  $comment_secure REPRESENTING THE SECURITY CODE VALUE (IF APPLICABLE)
	//	  $object_title (OPTIONAL) REPRESENTING THE COMMENTED OBJECT'S TITLE
	//	  $object_owner (OPTIONAL) REPRESENTING THE OWNER OF THE OBJECT (ex 'user')
	//	  $object_owner_id (OPTIONAL) REPRESENTING THE OWNER OF THE OBJECT'S ID
	//	  $object_privacy (OPTIONAL) REPRESENTING THE PRIVACY OF THE OBJECT
	// OUTPUT: AN ARRAY CONTAINING ALL THE SAVED COMMENT DATA
	function comment_post($comment_body, $comment_secure, $object_title = "", $object_owner = "", $object_owner_id = 0, $object_privacy = "") {
	  global $database, $user, $owner, $setting, $actions, $notify, $url;
	  $comment_date = time();
	  // RETRIEVE AND CHECK SECURITY CODE IF NECESSARY
	  if($setting[setting_comment_code] != 0) {
	    session_start();
	    $code = $_SESSION['code'];
	    if($code == "") { $code = randomcode(); }
	    if($comment_secure != $code) { $this->is_error = 1; }
	  }
	  // MAKE SURE COMMENT BODY IS NOT EMPTY - ADD BREAKS AND CENSOR
	  $comment_body = str_replace("\r\n", "
", cleanHTML(censor($comment_body), $setting[setting_comment_html], Array("style")));
	  $comment_body = preg_replace('/(
){3,}/is', '
', $comment_body);
	  $comment_body = str_replace("'", "\'", $comment_body);
	  if(trim($comment_body) == "") { $this->is_error = 1; $comment_body = ""; }
	  // ADD COMMENT IF NO ERROR
	  if($this->is_error == 0) {
	    $database->database_query("INSERT INTO se_".$this->comment_type."comments (".$this->comment_type."comment_".$this->comment_identifier.", ".$this->comment_type."comment_authoruser_id, ".$this->comment_type."comment_date, ".$this->comment_type."comment_body) VALUES ('".$this->comment_identifying_value."', '".$user->user_info[user_id]."', '$comment_date', '$comment_body')");
	    // INSERT ACTION IF USER EXISTS
	    if($user->user_exists != 0) {
	      $commenter = $user->user_displayname;
	      $comment_body_encoded = $comment_body;
	      if(strlen(strip_tags($comment_body_encoded)) > 250) { $comment_body_encoded = cleanHTML(chopHTML($comment_body_encoded, 0, 240), $setting[setting_comment_html])."..."; }
	      $comment_body_encoded = str_replace(Array("
", "
"), " ", $comment_body_encoded);
	      $actions->actions_add($user, $this->comment_type."comment", Array($user->user_info[user_username], $user->user_displayname, $owner->user_info[user_username], $owner->user_displayname, $comment_body_encoded, $this->comment_identifying_value, $object_title), Array(), 0, false, $object_owner, $object_owner_id, $object_privacy);
	    } else {
	      SE_Language::_preload(835);
	      SE_Language::load();
	      $commenter = SE_Language::_get(835);
	    }
	    // SEND PROFILE COMMENT NOTIFICATION IF COMMENTER IS NOT OWNER
	    if($owner->user_info[user_id] != $user->user_info[user_id]) { 
	      $notifytype = $notify->notify_add($owner->user_info[user_id], $this->comment_type."comment", $this->comment_identifying_value, Array($owner->user_info[user_username], $this->comment_identifying_value), Array($object_title));
	      $object_url = $url->url_base.vsprintf($notifytype[notifytype_url], Array($owner->user_info[user_username], $this->comment_identifying_value));
	      $owner->user_settings();
	      if($owner->usersetting_info['usersetting_notify_'.$this->comment_type.'comment']) { send_systememail($this->comment_type."comment", $owner->user_info[user_email], Array($owner->user_displayname, $commenter, "$object_url")); }
	    }
	  }
	  return Array('comment_body' => $comment_body, 'comment_date' => $comment_date);
	} // END comment_post() METHOD
	// THIS METHOD EDITS A COMMENT
	// INPUT: $comment_id REPRESENTING THE ID FOR THE COMMENT BEING EDITED
	//	  $comment_body REPRESENTING THE COMMENT BODY BEING EDITED
	// OUTPUT:
	function comment_edit($comment_id, $comment_body) {
	  global $database, $user, $setting;
	  // MAKE SURE COMMENT BODY IS NOT EMPTY - ADD BREAKS AND CENSOR
	  $comment_body = str_replace("\r\n", "
", cleanHTML(censor($comment_body), $setting[setting_comment_html]));
	  $comment_body = preg_replace('/(
){3,}/is', '
', $comment_body);
	  $comment_body = str_replace("'", "\'", $comment_body);
	  // EDIT COMMENT IF NO ERROR
	  if(trim($comment_body) != "") {
	    $database->database_query("UPDATE se_".$this->comment_type."comments SET ".$this->comment_type."comment_body='$comment_body' WHERE ".$this->comment_type."comment_".$this->comment_identifier."='".$this->comment_identifying_value."' AND ".$this->comment_type."comment_id=$comment_id AND ".$this->comment_type."comment_authoruser_id='".$user->user_info[user_id]."'");
	  }
	} // END comment_edit() METHOD
	// THIS METHOD DELETES A SINGLE COMMENT
	// INPUT: $comment_id REPRESENTING THE ID OF THE COMMENT TO DELETE
	// OUTPUT: 
	function comment_delete($comment_id) {
	  global $database;
	  $database->database_query("DELETE FROM se_".$this->comment_type."comments WHERE ".$this->comment_type."comment_".$this->comment_identifier."='".$this->comment_identifying_value."' AND ".$this->comment_type."comment_id=$comment_id");
	  
	} // END comment_delete() METHOD
	// THIS METHOD DELETES MANY COMMENTS BASED ON WHAT HAS BEEN POSTED
	// INPUT: $start REPRESENTING THE COMMENT TO START WITH
	//	  $limit REPRESENTING THE NUMBER OF COMMENTS TO RETURN
	// OUTPUT: 
	function comment_delete_selected($start, $limit) {
	  global $database;
	  $delete_query = "";
	  $comment_query = "SELECT se_".$this->comment_type."comments.".$this->comment_type."comment_id FROM se_".$this->comment_type."comments WHERE ".$this->comment_type."comment_".$this->comment_identifier."='".$this->comment_identifying_value."' ORDER BY ".$this->comment_type."comment_id DESC LIMIT $start, $limit";
	  $comments = $database->database_query($comment_query);
	  while($comment_info = $database->database_fetch_assoc($comments)) {
	    $var = "comment_".$comment_info[$this->comment_type.'comment_id'];
	    if($_POST[$var] == 1) {
	      if($delete_query != "") { $delete_query .= " OR "; }
	      $delete_query .= $this->comment_type."comment_id='".$comment_info[$this->comment_type.'comment_id']."'";
	    }
	  }
	  if($delete_query != "") { $database->database_query("DELETE FROM se_".$this->comment_type."comments WHERE $delete_query"); }
	} // END comment_delete_selected() METHOD
}
?>
//  THIS CLASS CONTAINS UPLOAD-RELATED METHODS.
//  IT IS USED DURING THE UPLOAD OF A FILE.
//  METHODS IN THIS CLASS:
//    new_upload()
//    upload_file()
//    upload_photo()
//    upload_thumb()
//    image_resize_on()
//    ConvertBMP2GD()
//    imagecreatefrombmp()
class se_upload {
	// INITIALIZE VARIABLES
	var $is_error = 0;		// DETERMINES WHETHER THERE IS AN ERROR OR NOT, CONTAINS RELEVANT ERROR CODE
	var $file_name;			// CONTAINS NAME OF UPLOADED FILE
	var $file_type;			// CONTAINS UPLOADED FILE MIME TYPE
	var $file_size;			// CONTAINS UPLOADED FILE SIZE
	var $file_tempname;		// CONTAINS TEMP NAME OF UPLOADED FILE
	var $file_error;		// CONTAINS UPLOADED FILE ERROR
	var $file_ext;			// CONTAINS UPLOADED FILE EXTENSION
	var $file_width;		// CONTAINS UPLOADED IMAGE WIDTH
	var $file_height;		// CONTAINS UPLOADED IMAGE HEIGHT
	var $is_image;			// DETERMINES WHETHER FILE IS AN IMAGE OR NOT
	var $file_maxwidth;		// CONTAINS THE MAXIMUM WIDTH OF AN UPLOADED IMAGE
	var $file_maxheight;		// CONTAINS THE MAXIMUM HEIGHT OF AN UPLOADED IMAGE
	// THIS METHOD SETS INITIAL VARS SUCH AS FILE NAME
	// INPUT: $file REPRESENTING THE NAME OF THE FILE INPUT
	//	  $file_maxsize REPRESENTING THE MAXIMUM ALLOWED FILESIZE
	//	  $file_exts REPRESENTING AN ARRAY OF LOWERCASE ALLOWABLE EXTENSIONS
	//	  $file_types REPRESENTING AN ARRAY OF LOWERCASE ALLOWABLE MIME TYPES
	//	  $file_maxwidth (OPTIONAL) REPRESENTING THE MAXIMUM WIDTH OF THE UPLOADED PHOTO
	//	  $file_maxheight (OPTIONAL) REPRESENTING THE MAXIMUM HEIGHT OF THE UPLOADED PHOTO
	// OUTPUT: 
	function new_upload($file, $file_maxsize, $file_exts, $file_types, $file_maxwidth = "", $file_maxheight = "") {
	  // GET FILE VARS
	  $this->file_name = $_FILES[$file]['name'];
	  $this->file_type = strtolower($_FILES[$file]['type']);
	  $this->file_size = $_FILES[$file]['size'];
	  $this->file_tempname = $_FILES[$file]['tmp_name'];
	  $this->file_error = $_FILES[$file]['error'];
	  $this->file_ext = strtolower(str_replace(".", "", strrchr($this->file_name, "."))); 
	  $file_dimensions = @getimagesize($this->file_tempname);
	  $this->file_width = $file_dimensions[0];
	  $this->file_height = $file_dimensions[1];
	  if($file_maxwidth == "") { $file_maxwidth = $this->file_width; }
	  if($file_maxheight == "") { $file_maxheight = $this->file_height; }
	  $this->file_maxwidth = $file_maxwidth;
	  $this->file_maxheight = $file_maxheight;
	  // ENSURE THE FILE IS AN UPLOADED FILE
	  if(!is_uploaded_file($this->file_tempname)) { $this->is_error = 718; }
	  // CHECK THAT FILESIZE IS LESS THAN GIVEN FILE MAXSIZE
	  if($this->file_size > $file_maxsize) { $this->is_error = 719; }
	  // CHECK EXTENSION OF FILE TO MAKE SURE ITS ALLOWED
	  if(!in_array($this->file_ext, $file_exts)) { $this->is_error = 720; }
	  // CHECK MIME TYPE OF FILE TO MAKE SURE ITS ALLOWED
	  if(!in_array($this->file_type, $file_types)) { $this->is_error = 720; }
	  // DETERMINE IF FILE IS A PHOTO (AND IF GD CAN BE USED) - DO NOT COUNT GIFs AS IMAGES, OTHERWISE ANIMATION WON'T WORK!!
	  if($file_dimensions !== FALSE && in_array($this->file_ext, Array('jpg', 'jpeg', 'png', 'bmp', 'gif')) !== FALSE) {
	    $this->is_image = 1;
	    // ENSURE THE UPLOADED FILE IS NOT LARGER THAN MAX WIDTH AND HEIGHT IF GD IS NOT AVAILABLE
	    if(!$this->image_resize_on()) {
	      $this->is_image = 0;
	      if($this->file_width > $this->file_maxwidth || $this->file_height > $this->file_maxheight) { $this->is_error = 721; }
	    }
	    // IF THIS IS A GIF, RESIZE ONLY IF IT IS GREATER THAN THE MAX WIDTH/HEIGHT, OTHERWISE SIMPLY MOVE
	    if($this->file_ext == 'gif' && $this->file_width <= $this->file_maxwidth && $this->file_height <= $this->file_maxheight) {
	      $this->is_image = 0;
	    }
	  } else {
	    $this->is_image = 0;
	  }
	} // END new_upload() METHOD
	// THIS METHOD UPLOADS A FILE
	// INPUT: $file_dest REPRESENTS THE DESTINATION OF THE UPLOADED FILE
	// OUTPUT: BOOLEAN INDICATING WHETHER UPLOAD SUCCEEDED OR FAILED
	function upload_file($file_dest) { 
	  // TRY MOVING UPLOADED FILE, RETURN ERROR UPON FAILURE
          if(!move_uploaded_file($this->file_tempname, $file_dest)) { 
	    $this->is_error = 718; 
	    return false;
	  } else {
	    chmod($file_dest, 0777);
	    return true;
	  }
	} // END upload_file() METHOD
	// THIS METHOD UPLOADS A PHOTO
	// INPUT: $photo_dest REPRESENTS THE DESTINATION OF THE UPLOADED PHOTO
	//	  $file_maxwidth (OPTIONAL) REPRESENTING THE MAXIMUM WIDTH OF THE UPLOADED PHOTO
	//	  $file_maxheight (OPTIONAL) REPRESENTING THE MAXIMUM HEIGHT OF THE UPLOADED PHOTO
	// OUTPUT: BOOLEAN INDICATING WHETHER UPLOAD SUCCEEDED OR FAILED
	function upload_photo($photo_dest, $file_maxwidth = "", $file_maxheight = "") { 
	  
	  // SET MAX WIDTH AND HEIGHT
	  if($file_maxwidth == "") { $file_maxwidth = $this->file_maxwidth; }
	  if($file_maxheight == "") { $file_maxheight = $this->file_maxheight; }
	  // CHECK IF DIMENSIONS ARE LARGER THAN ADMIN SPECIFIED SETTINGS
	  // AND SET DESIRED WIDTH AND HEIGHT
	  if($this->file_width > $file_maxwidth || $this->file_height > $file_maxheight) { 
	    if($this->file_height > $file_maxheight) {
	      $width = ($this->file_width)*$file_maxheight/($this->file_height);
	      $height = $file_maxheight;
	    }
	    if($this->file_width > $file_maxwidth) {
	      $height = ($this->file_height)*$file_maxwidth/($this->file_width);
	      $width = $file_maxwidth;
	    }
	  } else {
	    $width = $this->file_width;
	    $height = $this->file_height;
	  }
	  // RESIZE IMAGE AND PUT IN USER DIRECTORY
	  switch($this->file_ext) {
	    case "gif":
	      $file = imagecreatetruecolor($width, $height);
	      $new = imagecreatefromgif($this->file_tempname);
	      $kek=imagecolorallocate($file, 255, 255, 255);
	      imagefill($file,0,0,$kek);
	      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height);
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	    case "bmp":
	      $file = imagecreatetruecolor($width, $height);
	      $new = $this->imagecreatefrombmp($this->file_tempname);
	      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
	      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height); 
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	    case "jpeg":
	    case "jpg":
	      $file = imagecreatetruecolor($width, $height);
	      $new = imagecreatefromjpeg($this->file_tempname);
	      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
	      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height);
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	    case "png":
	      $file = imagecreatetruecolor($width, $height);
	      $new = imagecreatefrompng($this->file_tempname);
	      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
	      imagecopyresampled($file, $new, 0, 0, 0, 0, $width, $height, $this->file_width, $this->file_height); 
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	  } 
	  chmod($photo_dest, 0777);
	  return true;
	} // END upload_photo() METHOD
	// THIS METHOD CREATES A SQUARE THUMBNAIL
	// INPUT: $photo_dest REPRESENTS THE DESTINATION OF THE UPLOADED PHOTO
	//	  $file_maxdim (OPTIONAL) REPRESENTING THE MAXIMUM WIDTH AND HEIGHT OF THE UPLOADED PHOTO
	// OUTPUT: BOOLEAN INDICATING WHETHER UPLOAD SUCCEEDED OR FAILED
	function upload_thumb($photo_dest, $file_maxdim = "60") { 
	  
	  // SET DESIRED WIDTH AND HEIGHT
	  $width = $this->file_width;
	  $height = $this->file_height;
	  if($width > $height) { 
	    $x = ceil(($width - $height) / 2);
	    $width = $height;
	  } elseif($width < $height) {
	    $y = ceil(($height - $width) / 2);
	    $height = $width;
	  }
	  // RESIZE IMAGE AND PUT IN USER DIRECTORY
	  switch($this->file_ext) {
	    case "gif":
	      $file = imagecreatetruecolor($file_maxdim, $file_maxdim);
	      $new = imagecreatefromgif($this->file_tempname);
	      $kek=imagecolorallocate($file, 255, 255, 255);
	      imagefill($file,0,0,$kek);
	      imagecopyresampled($file, $new, 0, 0, $x, $y, $file_maxdim, $file_maxdim, $width, $height);
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	    case "bmp":
	      $file = imagecreatetruecolor($file_maxdim, $file_maxdim);
	      $new = $this->imagecreatefrombmp($this->file_tempname);
	      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
	      imagecopyresampled($file, $new, 0, 0, $x, $y, $file_maxdim, $file_maxdim, $width, $height); 
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	    case "jpeg":
	    case "jpg":
	      $file = imagecreatetruecolor($file_maxdim, $file_maxdim);
	      $new = imagecreatefromjpeg($this->file_tempname);
	      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
	      imagecopyresampled($file, $new, 0, 0, $x, $y, $file_maxdim, $file_maxdim, $width, $height);
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	    case "png":
	      $file = imagecreatetruecolor($file_maxdim, $file_maxdim);
	      $new = imagecreatefrompng($this->file_tempname);
	      for($i=0; $i<256; $i++) { imagecolorallocate($file, $i, $i, $i); }
	      imagecopyresampled($file, $new, 0, 0, $x, $y, $file_maxdim, $file_maxdim, $width, $height); 
	      imagejpeg($file, $photo_dest, 100);
	      ImageDestroy($new);
	      ImageDestroy($file);
	      break;
	  } 
	  chmod($photo_dest, 0777);
	  return true;
	} // END upload_thumb() METHOD
	// THIS METHOD CHECKS FOR NECESSARY IMAGE RESIZING SUPPORT
	// INPUT: 
	// OUTPUT: BOOLEAN INDICATING WHETHER GD CAN BE USED TO RESIZE IMAGES 
	function image_resize_on() {
	  // CHECK IF GD LIBRARY IS INSTALLED
	  if( !is_callable('gd_info') ) return FALSE;
	
	  $gd_info = gd_info();
	  preg_match('/\d/', $gd_info['GD Version'], $match);
	  $gd_ver = $match[0];
	  if($gd_ver >= 2 && $gd_info['GIF Read Support'] == TRUE && $gd_info['JPG Support'] == TRUE && $gd_info['PNG Support'] == TRUE) {
	    return true;
	  } else {
	    return false;
	  }
	} // END image_resize_on() METHOD
	// THIS METHOD CONVERTS BMP TO GD
	// INPUT: $src REPRESENTING THE SOURCE OF THE BMP
	//	  $dest (OPTIONAL) REPRESENTING THE DESTINATION OF THE GD
	// OUTPUT: BOOLEAN INDICATING WHETHER THE CONVERSION SUCCEEDED OR FAILED
	function ConvertBMP2GD($src, $dest = false) {
	  if(!($src_f = fopen($src, "rb"))) {
	    return false;
	  }
	  if(!($dest_f = fopen($dest, "wb"))) {
	    return false;
	  }
	  $header = unpack("vtype/Vsize/v2reserved/Voffset", fread($src_f, 14));
	  $info = unpack("Vsize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vncolor/Vimportant", fread($src_f, 40));
	  extract($info);
	  extract($header);
	  if($type != 0x4D42) {  // signature "BM"
	    return false;
	  }
	  $palette_size = $offset - 54;
	  $ncolor = $palette_size / 4;
	  $gd_header = "";
	  // true-color vs. palette
	  $gd_header .= ($palette_size == 0) ? "\xFF\xFE" : "\xFF\xFF"; 
	  $gd_header .= pack("n2", $width, $height);
	  $gd_header .= ($palette_size == 0) ? "\x01" : "\x00";
	  if($palette_size) {
	    $gd_header .= pack("n", $ncolor);
	  }
	  // no transparency
	  $gd_header .= "\xFF\xFF\xFF\xFF";     
	
	  fwrite($dest_f, $gd_header);
	
	  if($palette_size) {
	    $palette = fread($src_f, $palette_size);
	    $gd_palette = "";
	    $j = 0;
	    while($j < $palette_size) {
	      $b = $palette{$j++};
	      $g = $palette{$j++};
	      $r = $palette{$j++};
	      $a = $palette{$j++};
	      $gd_palette .= "$r$g$b$a";
	    }
	    $gd_palette .= str_repeat("\x00\x00\x00\x00", 256 - $ncolor);
	    fwrite($dest_f, $gd_palette);
	  }
	
	  $scan_line_size = (($bits * $width) + 7) >> 3;
	  $scan_line_align = ($scan_line_size & 0x03) ? 4 - ($scan_line_size & 0x03) : 0;
	
	  for($i = 0, $l = $height - 1; $i < $height; $i++, $l--) {
	    // BMP stores scan lines starting from bottom
	    fseek($src_f, $offset + (($scan_line_size + $scan_line_align) * $l));
	    $scan_line = fread($src_f, $scan_line_size);
	    if($bits == 24) {
	      $gd_scan_line = "";
	      $j = 0;
	      while($j < $scan_line_size) {
	        $b = $scan_line{$j++};
	        $g = $scan_line{$j++};
	        $r = $scan_line{$j++};
	        $gd_scan_line .= "\x00$r$g$b";
	      }
	    } elseif($bits == 8) {
	      $gd_scan_line = $scan_line;
	    } elseif($bits == 4) {
	      $gd_scan_line = "";
	      $j = 0;
	      while($j < $scan_line_size) {
	        $byte = ord($scan_line{$j++});
	        $p1 = chr($byte >> 4);
	        $p2 = chr($byte & 0x0F);
	        $gd_scan_line .= "$p1$p2";
	      } 
	      $gd_scan_line = substr($gd_scan_line, 0, $width);
	    } elseif($bits == 1) {
	      $gd_scan_line = "";
	      $j = 0;
	      while($j < $scan_line_size) {
	        $byte = ord($scan_line{$j++});
	        $p1 = chr((int) (($byte & 0x80) != 0));
	        $p2 = chr((int) (($byte & 0x40) != 0));
	        $p3 = chr((int) (($byte & 0x20) != 0));
	        $p4 = chr((int) (($byte & 0x10) != 0)); 
	        $p5 = chr((int) (($byte & 0x08) != 0));
	        $p6 = chr((int) (($byte & 0x04) != 0));
	        $p7 = chr((int) (($byte & 0x02) != 0));
	        $p8 = chr((int) (($byte & 0x01) != 0));
	        $gd_scan_line .= "$p1$p2$p3$p4$p5$p6$p7$p8";
	      } 
	      $gd_scan_line = substr($gd_scan_line, 0, $width);
	    }
	    
	    fwrite($dest_f, $gd_scan_line);
	  }
	
	  fclose($src_f);
	  fclose($dest_f);
	
	  return true;
	
	} // END ConvertBMP2GD() METHOD
	
	// THIS METHOD CREATES IMAGE FROM BMP FUNCTION
	// INPUT: $filename REPRESENTING THE NAME OF THE FILE TO BE USED FOR CREATION
	// OUTPUT: BOOLEAN INDICATING WHETHER THE CREATION SUCCEEDED OR FAILED
	function imagecreatefrombmp($filename) {
	
	  $tmp_name = tempnam("/tmp", "GD");
	  if($this->ConvertBMP2GD($filename, $tmp_name)) {
	    $img = imagecreatefromgd($tmp_name);
	    unlink($tmp_name);
	    return $img;
	  } else {
	    return false;
	  }
	} //END imagecreatefrombmp() METHOD
}
?>
//  THIS CLASS CONTAINS URL-RELATED METHODS.
//  IT IS USED TO RETURN THE CURRENT URL AND CREATE NEW URLS
//  METHODS IN THIS CLASS:
//    se_url()
//    url_create()
//    url_current()
//    url_userdir()
//    url_encode()
class se_url {
	// INITIALIZE VARIABLES
	var $is_error;			// DETERMINES WHETHER THERE IS AN ERROR OR NOT
	var $url_base;			// CONTAINS THE BASE URL TO WHICH FILENAMES CAN BE APPENDED
	var $convert_urls;		// CONTAINS THE URL CONVERSIONS
	// THIS METHOD SETS THE BASE URL TO WHICH FILENAMES CAN BE APPENDED
	// INPUT:
	// OUTPUT: A STRING REPRESENTING A PATH TO WHICH FILENAMES CAN BE APPENDED TO CREATE URLs
	function se_url() {
	  global $database;
	  $server_array = explode("/", $_SERVER['PHP_SELF']);
	  $server_array_mod = array_pop($server_array);
	  if($server_array[count($server_array)-1] == "admin") { $server_array_mod = array_pop($server_array); }
	  $server_info = implode("/", $server_array);
	  $this->url_base = "http://".$_SERVER['HTTP_HOST'].$server_info."/";
	  $se_urls = $database->database_query("SELECT url_file, url_regular, url_subdirectory FROM se_urls");
	  while($se_url_info = $database->database_fetch_assoc($se_urls)) {
	    $this->convert_urls[$se_url_info[url_file]] = Array('url_regular' => $se_url_info[url_regular],
								'url_subdirectory' => $se_url_info[url_subdirectory]);
	  }
	  $this->convert_urls['profile'] = Array('url_regular' => 'profile.php?user=$user',
						'url_subdirectory' => '$user/');
	} // END se_url() METHOD
	// THIS METHOD CREATES A FULL URL TO A GIVEN PAGE
	// INPUT: $file REPRESENTING THE PAGE TO CREATE THE URL FOR
	//	  $user REPRESENTING THE USERNAME OF THE USER
	//	  THERE ARE FURTHER OPTIONAL PARAMETERS TO ALLOW FOR ADDITIONAL REPLACEMENTS
	// OUTPUT: A STRING REPRESENTING A URL
	function url_create($file, $user) {
	  global $setting;
	  $url_conversion = $this->convert_urls[$file];
	  
	  if($setting[setting_url] == 1) {
	    $new_url = $url_conversion[url_subdirectory];
	  } else {
	    $new_url = $url_conversion[url_regular];
	  }
	  $num_args = func_num_args();
	  $search = Array('$user');
	  $replace = Array($user);
	  for($a=2;$a<$num_args;$a++) {
	    $search[] = '$id'.($a-1);
	    $replace[] = func_get_arg($a);
	  }
	  $new_url = str_replace($search, $replace, $new_url);
	  return $this->url_base.$new_url;
  
	} // END url_create() METHOD
	// THIS METHOD RETURNS THE URL TO THE CURRENT PAGE
	// INPUT: 
	// OUTPUT: A STRING REPRESENTING THE URL TO THE CURRENT PAGE
	function url_current() {
	  $current_url_domain = $_SERVER['HTTP_HOST'];
	  $current_url_path = $_SERVER['SCRIPT_NAME'];
	  $current_url_querystring = $_SERVER['QUERY_STRING'];
	  $current_url = "http://".$current_url_domain.$current_url_path;
	  if($current_url_querystring != "") {  $current_url .= "?".$current_url_querystring; }
	  $current_url = urlencode($current_url);
	  return $current_url;
	} // END url_current() METHOD
	// THIS METHOD RETURNS THE PATH TO THE GIVEN USER'S DIRECTORY
	// INPUT: $user_id REPRESENTING A USER'S USER_ID
	// OUTPUT: A STRING REPRESENTING THE RELATIVE PATH TO THE USER'S DIRECTORY
	function url_userdir($user_id) {
	  $subdir = $user_id+999-(($user_id-1)%1000);
	  $userdir = "./uploads_user/$subdir/$user_id/";
	  return $userdir;
	} // END url_userdir() METHOD
	// THIS METHOD RETURNS A URLENCODED VERSION OF THE GIVEN STRING
	// INPUT: $url REPRESENTING ANY STRING
	// OUTPUT: A STRING REPRESENTING A URLENCODED VERSION OF THE GIVEN STRING
	function url_encode($url) {
	  return urlencode($url);
	} // END url_encode() METHOD
}
?>
//  THIS CLASS CONTAINS MISC METHODS TO BE AVAILABLE TO SMARTY
//  METHODS IN THIS CLASS:
//    photo_size()
class se_misc {
	// THIS METHOD RETURNS WIDTH OR HEIGHT, PROPORTIONALLY, BASED ON GIVEN MAX WIDTH AND MAX HEIGHT
	// INPUT: $photo REPRESENTING THE PATH TO THE PHOTO
	//	  $max_width REPRESENTING THE MAXIMUM WIDTH IN PIXELS
	//	  $max_height REPRESENTING THE MAXIMUM HEIGHT IN PIXELS
	//	  $return_value (OPTIONAL) REPRESENTING THE VALUE TO RETURN (CAN BE "w" FOR WIDTH OR "h" FOR HEIGHT)
	// OUTPUT: A WIDTH OR HEIGHT IN PIXELS THAT SCALES THE PHOTO BASED ON A MAX WIDTH AND HEIGHT
	function photo_size($photo, $max_width, $max_height, $return_value = "w") {
	  $dimensions = @getimagesize($photo);
	  $width = $dimensions[0];
	  $height = $dimensions[1];
	  if($width > $max_width | $height > $max_height) { 
	    if($width > $max_width) {
	      $height = $height*$max_width/$width;
	      $width = $max_width;
	    }
	    if($height > $max_height) {
	      $width = $width*$max_height/$height;
	      $height = $max_height;
	    }
	  }
	  if($return_value == "w") { $image_dimension = $width; } else { $image_dimension = $height; }
	
	  return round($image_dimension, 2);
	} // END photo_size() METHOD
}
?>
//  THIS CLASS IS USED TO DISPLAY AND MANAGE AD CAMPAIGN BANNERS
//  METHODS IN THIS CLASS:
//    se_ads()
//    ad_display()
class se_ads {
	var $ad_top; 			// VARIABLE REPRESENTING PAGE TOP BANNER HTML
	var $ad_belowmenu; 		// VARIABLE REPRESENTING BELOW MENU BANNER HTML
	var $ad_left; 			// VARIABLE REPRESENTING LEFT SIDE BANNER HTML
	var $ad_right; 			// VARIABLE REPRESENTING RIGHT SIDE BANNER HTML
	var $ad_bottom; 		// VARIABLE REPRESENTING PAGE BOTTOM BANNER HTML
	var $ad_feed;	 		// VARIABLE REPRESENTING ACTIVITY FEED BANNER HTML
	var $ad_custom;			// VARIABLE REPRESENTING AN ARRAY OF CUSTOM BANNER HTML
	// THIS METHOD IS USED TO DETERMINE WHAT ADS SHOULD BE SHOWN ON THE PAGE
	// THIS ONLY INCLUDES AD CAMPAIGNS THAT HAVE BEEN GIVEN A POSITION BY THE ADMIN
	// OUTPUT: AD BANNER HTML (IF AVAILABLE) FOR PAGE TOP, BELOW MENU, LEFT, RIGHT, AND BOTTOM
	function se_ads() {
	  global $database, $datetime, $setting, $user, $page;
	
	  // DON'T RETRIEVE ADS ON HIDDEN PAGE
	  if($page == "ad") return;
	  // GET CURRENT TIME IN ADMINS TIMEZONE
	  $nowtime = time();
	  // BEGIN BUILDING AD QUERY 
	  $ad_querystring = "SELECT ad_id, ad_position, ad_html FROM se_ads WHERE ad_date_start<'$nowtime' AND (ad_date_end>'$nowtime' OR ad_date_end='0')";
	  // MAKE SURE AD IS NOT PAUSED
	  $ad_querystring .= " AND ad_paused!='1'";
	  // MAKE SURE AD HAS NOT REACHED ITS VIEW LIMIT
	  $ad_querystring .= " AND (ad_limit_views=0 OR ad_limit_views>ad_total_views)";
	  // MAKE SURE AD HAS NOT REACHED ITS CLICK LIMIT
	  $ad_querystring .= " AND (ad_limit_clicks=0 OR ad_limit_clicks>ad_total_clicks)";
	  // MAKE SURE AD HAS NOT REACHED ITS CTR LIMIT
          $ad_querystring .= " AND (ad_limit_ctr=0 OR ad_limit_ctr<(ad_total_clicks/(ad_total_views+1))*100)";
	  // IF VIEWER IS NOT LOGGED-IN, ONLY SHOW PUBLIC AD CAMPAIGNS
          if($user->user_exists == 0) {
	    $ad_querystring .= " AND ad_public='1'";
	  // IF VIEWER IS LOGGED-IN, ONLY SHOW AD IF VIEWER'S LEVEL AND SUBNETS MATCH
	  } else { 
	    $level_id = $user->level_info[level_id];
	    $subnet_id = $user->subnet_info[subnet_id];
	    $ad_querystring .= " AND (ad_levels LIKE '%,$level_id,%' AND ad_subnets LIKE '%,$subnet_id,%')";
	  }
	  // RANDOMIZE QUERY RESULTS
	  $ad_querystring .= " ORDER BY RAND()";
	  // DETERMINE WHICH ADS SHOULD BE SHOWN
	  $ad_query = $database->database_query($ad_querystring);
	  // PREPARE STAT UPDATE QUERY
	  $stats_string = "";
	  // SET AD HTML FOR EACH POSITION
	  while($ad_info = $database->database_fetch_assoc($ad_query)) {
	    // CONVERT TO HTML AND ADD CLICK-TRACKING JAVASCRIPT
	    $ad_info[ad_html] = htmlspecialchars_decode($ad_info[ad_html], ENT_QUOTES);
	    $ad_info[ad_html] = "