From 67755abf252f38dea557485de7d72e6d29320a8a Mon Sep 17 00:00:00 2001 From: "Paul S. Owen" Date: Wed, 11 Feb 2004 18:28:24 +0000 Subject: [PATCH] Profile, prefs, feedback git-svn-id: file:///svn/phpbb/trunk@4827 89ea8834-ac86-4346-8a33-228a782c2dd0 --- phpBB/adm/admin_users.php | 412 ++++++++++++++++++++++++++++++----- phpBB/adm/admin_viewlogs.php | 2 +- phpBB/adm/editor.js | 306 ++++++++++++++++++++++++++ phpBB/adm/subSilver.css | 2 + phpBB/common.php | 1 + 5 files changed, 664 insertions(+), 59 deletions(-) create mode 100644 phpBB/adm/editor.js diff --git a/phpBB/adm/admin_users.php b/phpBB/adm/admin_users.php index b0a8f89fdb..dad6a47bee 100644 --- a/phpBB/adm/admin_users.php +++ b/phpBB/adm/admin_users.php @@ -36,6 +36,7 @@ include($phpbb_root_path.'includes/functions_profile_fields.'.$phpEx); // $mode = request_var('mode', ''); $action = request_var('action', 'overview'); +$start = request_var('start', 0); $username = request_var('username', ''); $user_id = request_var('u', 0); $ip = request_var('ip', ''); @@ -47,6 +48,7 @@ $quicktools = request_var('quicktools', ''); $submit = (isset($_POST['update'])) ? true : false; $confirm = (isset($_POST['confirm'])) ? true : false; $cancel = (isset($_POST['cancel'])) ? true : false; +$preview = (isset($_POST['preview'])) ? true : false; $error = array(); @@ -119,7 +121,7 @@ adm_page_header($user->lang['MANAGE']); // // User has submitted a form, process it // -if ($submit) +if ($submit || $preview) { switch ($action) { @@ -473,6 +475,16 @@ if ($submit) break; + case 'feedback': + + if ($message = request_var('message', '')) + { + add_log('user', $user_id, 'LOG_USER_GENERAL', $message); + trigger_error("ADDED"); + } + + break; + case 'profile': $var_ary = array( @@ -672,9 +684,120 @@ if ($submit) break; case 'avatar': + + $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && is_writeable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false; + + $var_ary = array( + 'uploadurl' => (string) '', + 'remotelink' => (string) '', + 'width' => (string) '', + 'height' => (string) '', + ); + + foreach ($var_ary as $var => $default) + { + $data[$var] = request_var($var, $default); + } + + $var_ary = array( + 'uploadurl' => array('string', true, 5, 255), + 'remotelink' => array('string', true, 5, 255), + 'width' => array('string', true, 1, 3), + 'height' => array('string', true, 1, 3), + ); + + $error = validate_data($data, $var_ary); + + if (!sizeof($error)) + { + $data['user_id'] = $user_id; + + if ((!empty($_FILES['uploadfile']['tmp_name']) || $data['uploadurl']) && $can_upload) + { + list($type, $filename, $width, $height) = avatar_upload($data, $error); + } + else if ($data['remotelink']) + { + list($type, $filename, $width, $height) = avatar_remote($data, $error); + } + else if ($delete) + { + $type = $filename = $width = $height = ''; + } + } + + if (!sizeof($error)) + { + // Do we actually have any data to update? + if (sizeof($data)) + { + $sql_ary = array( + 'user_avatar' => $filename, + 'user_avatar_type' => $type, + 'user_avatar_width' => $width, + 'user_avatar_height' => $height, + ); + + echo $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE user_id = $user_id"; + $db->sql_query($sql); + + // Delete old avatar if present + if ($user_avatar && $filename != $user_avatar) + { + avatar_delete($user_avatar); + } + } + + trigger_error($message); + } + + extract($data); + unset($data); + break; - case 'signature': + case 'sig': + + $var_ary = array( + 'enable_html' => (bool) $config['allow_html'], + 'enable_bbcode' => (bool) $config['allow_bbcode'], + 'enable_smilies' => (bool) $config['allow_smilies'], + 'enable_urls' => true, + 'signature' => (string) $user_sig, + + ); + + foreach ($var_ary as $var => $default) + { + $$var = request_var($var, $default); + } + + if (!$preview) + { + include($phpbb_root_path . 'includes/message_parser.'.$phpEx); + + $message_parser = new parse_message(); + + $message_parser->message = $signature; + $message_parser->parse($enable_html, $enable_bbcode, $enable_urls, $enable_smilies); + + $sql_ary = array( + 'user_sig' => (string) $message_parser->message, + 'user_sig_bbcode_uid' => (string) $message_parser->bbcode_uid, + 'user_sig_bbcode_bitfield' => (int) $message_parser->bbcode_bitfield + ); + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE user_id = $user_id"; + $db->sql_query($sql); + + $message = $user->lang['PROFILE_UPDATED'] . '

' . sprintf($user->lang['RETURN_UCP'], "", ''); + trigger_error($message); + } + break; case 'groups': @@ -706,11 +829,41 @@ if ($username || $user_id) ?> + + +

lang['USER_ADMIN']; ?>

lang['USER_ADMIN_EXPLAIN']; ?>

-
"> +">
@@ -830,67 +983,84 @@ if ($username || $user_id) break; - - - - - case 'feedback': - if ($submit) + $st = request_var('st', 0); + $sk = request_var('sk', 't'); + $sd = request_var('sd', 'd'); + + $limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 364 => $user->lang['1_YEAR']); + $sort_by_text = array('u' => $user->lang['SORT_USERNAME'], 't' => $user->lang['SORT_DATE'], 'i' => $user->lang['SORT_IP'], 'o' => $user->lang['SORT_ACTION']); + $sort_by_sql = array('u' => 'l.user_id', 't' => 'l.log_time', 'i' => 'l.log_ip', 'o' => 'l.log_operation'); + + $s_limit_days = $s_sort_key = $s_sort_dir = ''; + gen_sort_selects($limit_days, $sort_by_text, $st, $sk, $sd, $s_limit_days, $s_sort_key, $s_sort_dir); + + // Define where and sort sql for use in displaying logs + $sql_where = ($st) ? (time() - ($st * 86400)) : 0; + $sql_sort = $sort_by_sql[$sk] . ' ' . (($sd == 'd') ? 'DESC' : 'ASC'); + + $log_data = array(); + $log_count = 0; + view_log('user', $log_data, $log_count, $config['posts_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort); + + $pagination = generate_pagination("admin_users.$phpEx$SID&action=$action&u=$user_id&st=$st&sk=$sk&sd=$sd", $total_reports, $config['posts_per_page'], $start); + + if ($log_count) { - - } - -?> - - - -sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - $total_reports = $row['total_reports']; - - if ($total_reports) - { - $pagination = generate_pagination("admin_users.$phpEx$SID&action=$action&u=$user_id&st=$sort_days&sk=$sort_key&sd=$sort_dir", $total_reports, $config['posts_per_page'], $start); - - $sql = 'SELECT u.username, n.* - FROM ' . USERS_NOTES_TABLE . ' n, ' . USERS_TABLE . " u - WHERE n.user_id = $user_id - AND u.user_id = n.reporter_id - ORDER BY n.report_log DESC, n.report_date DESC"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) + for($i = 0; $i < sizeof($log_data); $i++) { $row_class = ($row_class == 'row1') ? 'row2' : 'row1'; ?> - + + sql_freeresult($result); } else { ?> - + + + + +
lang['SELECT_FORM']; ?>:
Report by: on format_date($row['report_date']); ?>
Report by: on format_date($log_data[$i]['time']); ?>
No reports exist for this userNo reports exist for this user
lang['DISPLAY_LOG']; ?>:   lang['SORT_BY']; ?>:  
+ + + + + + + +

lang['ADD_FEEDBACK']; ?>

+ +

lang['ADD_FEEDBACK_EXPLAIN']; ?>

+ + + + diff --git a/phpBB/adm/admin_viewlogs.php b/phpBB/adm/admin_viewlogs.php index e42bee398a..ece903bb5b 100644 --- a/phpBB/adm/admin_viewlogs.php +++ b/phpBB/adm/admin_viewlogs.php @@ -140,7 +140,7 @@ if ($mode == 'mod') // $log_data = array(); $log_count = 0; -view_log($mode, $log_data, $log_count, $config['topics_per_page'], $start, $forum_id, 0, $sql_where, $sql_sort); +view_log($mode, $log_data, $log_count, $config['topics_per_page'], $start, $forum_id, 0, 0, $sql_where, $sql_sort); if ($log_count) { diff --git a/phpBB/adm/editor.js b/phpBB/adm/editor.js new file mode 100644 index 0000000000..a54a31db38 --- /dev/null +++ b/phpBB/adm/editor.js @@ -0,0 +1,306 @@ +// bbCode control by subBlue design [ www.subBlue.com ] +// Includes unixsafe colour palette selector by SHS` + +// Startup variables +var imageTag = false; +var theSelection = false; + +// Check for Browser & Platform for PC & IE specific bits +// More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html +var clientPC = navigator.userAgent.toLowerCase(); // Get client info +var clientVer = parseInt(navigator.appVersion); // Get browser version + +var is_ie = ((clientPC.indexOf("msie") != -1) && (clientPC.indexOf("opera") == -1)); +var is_nav = ((clientPC.indexOf('mozilla')!=-1) && (clientPC.indexOf('spoofer')==-1) + && (clientPC.indexOf('compatible') == -1) && (clientPC.indexOf('opera')==-1) + && (clientPC.indexOf('webtv')==-1) && (clientPC.indexOf('hotjava')==-1)); + +var is_win = ((clientPC.indexOf("win")!=-1) || (clientPC.indexOf("16bit") != -1)); +var is_mac = (clientPC.indexOf("mac")!=-1); + +// Shows the help messages in the helpline window +function helpline(help) { + document.forms[form_name].helpbox.value = eval(help + "_help"); +} + +// Replacement for arrayname.length property +function getarraysize(thearray) { + for (i = 0; i < thearray.length; i++) { + if ((thearray[i] == "undefined") || (thearray[i] == "") || (thearray[i] == null)) + return i; + } + return thearray.length; +} + +// Replacement for arrayname.push(value) not implemented in IE until version 5.5 +// Appends element to the array +function arraypush(thearray,value) { + thearray[ getarraysize(thearray) ] = value; +} + +// Replacement for arrayname.pop() not implemented in IE until version 5.5 +// Removes and returns the last element of an array +function arraypop(thearray) { + thearraysize = getarraysize(thearray); + retval = thearray[thearraysize - 1]; + delete thearray[thearraysize - 1]; + return retval; +} + +function emoticon(text) { + text = ' ' + text + ' '; + if (document.forms[form_name].elements[text_name].createTextRange && document.forms[form_name].elements[text_name].caretPos) { + var caretPos = document.forms[form_name].elements[text_name].caretPos; + + caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == ' ' ? caretPos.text + text + ' ' : caretPos.text + text; + document.forms[form_name].elements[text_name].focus(); + } else { + var selStart = document.forms[form_name].elements[text_name].selectionStart; + var selEnd = document.forms[form_name].elements[text_name].selectionEnd; + + mozWrap(document.forms[form_name].elements[text_name], text, '') + document.forms[form_name].elements[text_name].focus(); + document.forms[form_name].elements[text_name].selectionStart = selStart + text.length; + document.forms[form_name].elements[text_name].selectionEnd = selEnd + text.length; + } +} + +function bbfontstyle(bbopen, bbclose) { + if ((clientVer >= 4) && is_ie && is_win) { + theSelection = document.selection.createRange().text; + if (!theSelection) { + insert_text(bbopen + bbclose); + document.forms[form_name].elements[text_name].focus(); + return; + } + document.selection.createRange().text = bbopen + theSelection + bbclose; + document.forms[form_name].elements[text_name].focus(); + return; + } else { + insert_text(bbopen + bbclose); + document.forms[form_name].elements[text_name].focus(); + return; + } + storeCaret(document.forms[form_name].elements[text_name]); +} + +function insert_text(text) { + if (document.forms[form_name].elements[text_name].createTextRange && document.forms[form_name].elements[text_name].caretPos) { + var caretPos = document.forms[form_name].elements[text_name].caretPos; + caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == ' ' ? caretPos.text + text + ' ' : caretPos.text + text; + } else { + var selStart = document.forms[form_name].elements[text_name].selectionStart; + var selEnd = document.forms[form_name].elements[text_name].selectionEnd; + + mozWrap(document.forms[form_name].elements[text_name], text, '') + document.forms[form_name].elements[text_name].selectionStart = selStart + text.length; + document.forms[form_name].elements[text_name].selectionEnd = selEnd + text.length; + } +} + +function attach_inline() { + insert_text('[attachment=' + document.forms[form_name].elements['attachments'].value + ']' + document.forms[form_name].elements['attachments'].options[document.forms[form_name].elements['attachments'].selectedIndex].text + '[/attachment]'); +} + +function bbstyle(bbnumber) { + + donotinsert = false; + theSelection = false; + bblast = 0; + document.forms[form_name].elements[text_name].focus(); + + if (bbnumber == -1) { // Close all open tags & default button names + while (bbcode[0]) { + butnumber = arraypop(bbcode) - 1; + document.forms[form_name].elements[text_name].value += bbtags[butnumber + 1]; + buttext = eval('document.forms[form_name].addbbcode' + butnumber + '.value'); + if (buttext != "[*]") + { + eval('document.forms[form_name].addbbcode' + butnumber + '.value ="' + buttext.substr(0,(buttext.length - 1)) + '"'); + } + } + document.forms[form_name].addbbcode10.value = "List"; + bbtags[10] = "[list]"; + document.forms[form_name].addbbcode12.value = "List="; + bbtags[12] = "[list=]"; + imageTag = false; // All tags are closed including image tags :D + document.forms[form_name].elements[text_name].focus(); + return; + } + + if ((clientVer >= 4) && is_ie && is_win) + { + theSelection = document.selection.createRange().text; // Get text selection + if (theSelection) { + // Add tags around selection + document.selection.createRange().text = bbtags[bbnumber] + theSelection + bbtags[bbnumber+1]; + document.forms[form_name].elements[text_name].focus(); + theSelection = ''; + return; + } + } + else if (document.forms[form_name].elements[text_name].selectionEnd && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) + { + mozWrap(document.forms[form_name].elements[text_name], bbtags[bbnumber], bbtags[bbnumber+1]); + document.forms[form_name].elements[text_name].focus(); + theSelection = ''; + return; + } + + // Find last occurance of an open tag the same as the one just clicked + for (i = 0; i < bbcode.length; i++) { + if (bbcode[i] == bbnumber+1) { + bblast = i; + donotinsert = true; + } + } + + if ((bbnumber == 10) && (bbtags[10] != "[*]")) + { + if (donotinsert) + { + document.forms[form_name].addbbcode12.value = "List="; + tmp_help = o_help; + o_help = e_help; + e_help = tmp_help; + bbtags[12] = "[list=]"; + } + else + { + document.forms[form_name].addbbcode12.value = "[*]"; + tmp_help = o_help; + o_help = e_help; + e_help = tmp_help; + bbtags[12] = "[*]"; + } + } + + if ((bbnumber == 12) && (bbtags[12] != "[*]")) + { + if (donotinsert) + { + document.forms[form_name].addbbcode10.value = "List"; + tmp_help = l_help; + l_help = e_help; + e_help = tmp_help; + bbtags[10] = "[list]"; + } + else + { + document.forms[form_name].addbbcode10.value = "[*]"; + tmp_help = l_help; + l_help = e_help; + e_help = tmp_help; + bbtags[10] = "[*]"; + } + } + + if (donotinsert) { // Close all open tags up to the one just clicked & default button names + while (bbcode[bblast]) { + butnumber = arraypop(bbcode) - 1; + if (bbtags[butnumber] != "[*]") + { + insert_text(bbtags[butnumber + 1]); + } + else + { + insert_text(bbtags[butnumber]); + } + buttext = eval('document.forms[form_name].addbbcode' + butnumber + '.value'); + if (bbtags[butnumber] != "[*]") + { + eval('document.forms[form_name].addbbcode' + butnumber + '.value ="' + buttext.substr(0,(buttext.length - 1)) + '"'); + } + imageTag = false; + } + document.forms[form_name].elements[text_name].focus(); + return; + } else { // Open tags + + if (imageTag && (bbnumber != 14)) { // Close image tag before adding another + insert_text(bbtags[15]); + + lastValue = arraypop(bbcode) - 1; // Remove the close image tag from the list + document.forms[form_name].addbbcode14.value = "Img"; // Return button back to normal state + imageTag = false; + } + + // Open tag + insert_text(bbtags[bbnumber]); + + if ((bbnumber == 14) && (imageTag == false)) imageTag = 1; // Check to stop additional tags after an unclosed image tag + if (bbtags[bbnumber] != "[*]") + { + arraypush(bbcode,bbnumber+1); + eval('document.forms[form_name].addbbcode'+bbnumber+'.value += "*"'); + } + document.forms[form_name].elements[text_name].focus(); + return; + } + + storeCaret(document.forms[form_name].elements[text_name]); +} + +// From http://www.massless.org/mozedit/ +function mozWrap(txtarea, open, close) +{ + var selLength = txtarea.textLength; + var selStart = txtarea.selectionStart; + var selEnd = txtarea.selectionEnd; + if (selEnd == 1 || selEnd == 2) + selEnd = selLength; + + var s1 = (txtarea.value).substring(0,selStart); + var s2 = (txtarea.value).substring(selStart, selEnd) + var s3 = (txtarea.value).substring(selEnd, selLength); + txtarea.value = s1 + open + s2 + close + s3; + return; +} + +// Insert at Claret position. Code from +// http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 +function storeCaret(textEl) { + if (textEl.createTextRange) { textEl.caretPos = document.selection.createRange().duplicate(); } +} + +function colorPalette(dir, width, height) +{ + var r = 0, g = 0, b = 0; + var numberList = new Array(6); + numberList[0] = "00"; + numberList[1] = "40"; + numberList[2] = "80"; + numberList[3] = "BF"; + numberList[4] = "FF"; + document.writeln('
+ + + + + + +lang['VIEW_AVATARS']; ?>: - - - - - @@ -1141,6 +1305,11 @@ if ($username || $user_id) case 'avatar': $can_upload = ($file_uploads && file_exists($phpbb_root_path . $config['avatar_path']) && is_writeable($phpbb_root_path . $config['avatar_path'])) ? true : false; + $display_gallery = (isset($_POST['displaygallery'])) ? true : false; + $avatar_category = request_var('category', ''); + + // Generate users avatar + $avatar_img = ''; if ($user_avatar) { switch ($user_avatar_type) @@ -1247,11 +1416,46 @@ if ($username || $user_id) case 'sig': include($phpbb_root_path . 'includes/functions_posting.'.$phpEx); + $signature_preview = ''; + if ($preview) + { + $signature_preview = $signature; + + // Fudge-o-rama ... + include($phpbb_root_path . 'includes/message_parser.'.$phpEx); + + $message_parser = new parse_message(); + $message_parser->message = $signature_preview; + $message_parser->parse($enable_html, $enable_bbcode, $enable_urls, $enable_smilies); + $signature_preview = $message_parser->message; + + if ($enable_bbcode) + { + include($phpbb_root_path . 'includes/bbcode.'.$phpEx); + $bbcode = new bbcode($message_parser->bbcode_bitfield); + + $bbcode->bbcode_second_pass($signature_preview, $message_parser->bbcode_uid); + } + + // If we allow users to disable display of emoticons + // we'll need an appropriate check and preg_replace here + $signature_preview = (empty($enable_smilies) || empty($config['allow_smilies'])) ? preg_replace('#(((?>([^><]+|(?R)))*)\<))#se', "preg_replace(\$censors['match'], \$censors['replace'], '\\0')", '>' . $signature_preview . '<'), 1, -1)); + } + + $signature_preview = str_replace("\n", '
', $signature_preview); + } + decode_text($user_sig, $user_sig_bbcode_uid); ?> + + + + + + + + + + + + + - +
lang['USER_ADMIN_' . strtoupper($action)]; ?>
/>lang['YES']; ?>   />lang['NO']; ?>
lang['DISABLE_CENSORS']; ?>: />lang['YES']; ?>   />lang['NO']; ?>
lang['HIDE_ONLINE']; ?>: />lang['YES']; ?>   />lang['NO']; ?>
lang['NOTIFY_METHOD']; ?>:
lang['NOTIFY_METHOD_EXPLAIN']; ?>
/>lang['NOTIFY_METHOD_EMAIL']; ?>   />lang['NOTIFY_METHOD_IM']; ?>   />lang['NOTIFY_METHOD_BOTH']; ?>
lang['NOTIFY_ON_PM']; ?>: />lang['YES']; ?>   />lang['NO']; ?>
lang['SIGNATURE']; ?>: @@ -1267,25 +1471,117 @@ if ($username || $user_id) - + - + + + +
- - +
 {L_FONT_SIZE}:  lang['FONT_SIZE']; ?>: {L_CLOSE_TAGS}lang['CLOSE_TAGS']; ?>
+ + + +
lang['OPTIONS']; ?>
+ + + + + + + + + + + + + + + +
lang['HTML_IS_ON'] : $user->lang['HTML_IS_OFF']; ?>
lang['BBCODE_IS_ON'], "", '') : sprintf($user->lang['BBCODE_IS_OFF'], "", ''); ?>
lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF']; ?>
lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF']; ?>
lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF']; ?>
+ + + + + + + + + + + + + + + + + + + + +
lang['DISABLE_HTML']; ?>
lang['DISABLE_BBCODE']; ?>
lang['DISABLE_SMILIES']; ?>
lang['DISABLE_MAGIC_URL']; ?>
lang['ADMIN_SIGNATURE_PREVIEW']; ?>
  lang['PREVIEW'] . '" />  ' : ''; ?>  
'); + for(r = 0; r < 5; r++) + { + if (dir == 'h') + { + document.writeln(''); + } + for(g = 0; g < 5; g++) + { + if (dir == 'v') + { + document.writeln(''); + } + for(b = 0; b < 5; b++) + { + color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); + document.write(''); + } + if (dir == 'v') + { + document.writeln(''); + } + } + if (dir == 'h') + { + document.writeln(''); + } + } + document.writeln('
'); + document.write('#' + color + ''); + document.writeln('
'); +} \ No newline at end of file diff --git a/phpBB/adm/subSilver.css b/phpBB/adm/subSilver.css index e5e1964ac2..451a1eb139 100644 --- a/phpBB/adm/subSilver.css +++ b/phpBB/adm/subSilver.css @@ -220,3 +220,5 @@ textarea.edit { font-weight: normal; border-width: 1px; } + +.helpline { background-color: #DEE3E7; border-style: none; } diff --git a/phpBB/common.php b/phpBB/common.php index 754183b025..ffac022403 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -125,6 +125,7 @@ define('MAIL_HIGH_PRIORITY', 2); define('LOG_ADMIN', 0); define('LOG_MOD', 1); define('LOG_CRITICAL', 2); +define('LOG_USERS', 3); // Private messaging define('PRIVMSGS_READ_MAIL', 0);