function save_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, $update = FALSE) { $arrForm = createFieldForm($pDB_2); $oForm = new paloForm($smarty, $arrForm); if (isset($_GET['id']) && !ctype_digit($_GET['id'])) { unset($_GET['id']); } if (isset($_POST['id']) && !ctype_digit($_POST['id'])) { unset($_POST['id']); } if (false) { //(!$oForm->validateForm($_POST)) { // Falla la validación básica del formulario $smarty->assign("mb_title", "Kiểm tra:"); $arrErrores = $oForm->arrErroresValidacion; $strErrorMsg = "<b>Các trường sau có lỗi:</b> "; if (is_array($arrErrores) && count($arrErrores) > 0) { foreach ($arrErrores as $k => $v) { $strErrorMsg .= "{$k}, "; } } $smarty->assign("mb_message", $strErrorMsg); $smarty->assign("REQUIRED_FIELD", "Bắt buộc"); $smarty->assign("SAVE", "Lưu"); $smarty->assign("CANCEL", "Hủy bỏ"); $smarty->assign("title", "Thông tin khách hàng"); if (isset($_POST['customer_type'])) { switch ($_POST['customer_type']) { case '0': $smarty->assign("check_0", "checked"); break; case '1': $smarty->assign("check_1", "checked"); break; case '2': $smarty->assign("check_2", "checked"); break; case '3': $smarty->assign("check_3", "checked"); break; default: break; } } if ($update) { $_POST["edit"] = 'edit'; return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } else { $smarty->assign("Show", 1); $htmlForm = $oForm->fetchForm("{$local_templates_dir}/new_adress_book.tpl", "Thông tin khách hàng", $_POST); $contenidoModulo = "<form method='POST' enctype='multipart/form-data' style='margin-bottom:0;' action='?menu={$module_name}'>" . $htmlForm . "</form>"; return $contenidoModulo; } } else { //NO HAY ERRORES $idPost = getParameter('id'); $padress_book = new paloAdressBook($pDB); $contactData = $padress_book->contactData($idPost); $type = getParameter('customer_type'); if ($type == '0' || $type == '1') { $phone = getParameter('phone'); $data = array('customer_code' => getParameter('customer_code'), 'firstname' => getParameter('firstname'), 'lastname' => getParameter('lastname'), 'birthday' => date('Y-m-d', strtotime(getParameter('birthday'))), 'birthplace' => getParameter('birthplace'), 'cmnd' => getParameter('cmnd'), 'passport' => getParameter('passport'), 'address' => getParameter('address'), 'company' => getParameter('company'), 'email' => getParameter('email'), 'agent_id' => getParameter('booker'), 'sale' => getParameter('sale'), 'payment_type' => getParameter('payment_type'), 'accountant' => getParameter('accountant'), 'membership' => getParameter('membership'), 'customer_phone' => explode("\n", trim($phone))); } else { $data = array('customer_code' => getParameter('company_code'), 'firstname' => getParameter('company_name'), 'agent_id' => getParameter('company_booker'), 'sale' => getParameter('company_sale'), 'accountant' => getParameter('company_accountant'), 'address' => getParameter('company_address'), 'membership' => getParameter('company_membership'), 'payment_type' => getParameter('company_pay_type'), 'contact_name' => getParameter('contact_name'), 'contact_phone' => getParameter('contact_phone'), 'contact_email' => getParameter('contact_email')); } if ($update && isset($contactData['id'])) { // actualizacion del contacto if ($contactData) { $idt = $contactData['id']; $result = $padress_book->updateContact($data, $type, $idt); if (!$result) { $smarty->assign("mb_title", "Lỗi database"); $smarty->assign("mb_message", $padress_book->errMsg); return report_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } else { $smarty->assign("mb_title", $arrLang["Validation Error"]); $smarty->assign("mb_message", $arrLang["Internal Error"]); return report_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } else { //// creacion de contacto $result = $padress_book->addContact($data, $type); if (!$result) { $smarty->assign("mb_title", "Lỗi"); $smarty->assign("mb_message", $padress_book->errMsg); return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } if (!$result) { return $pDB->errMsg; } if ($_POST['id']) { header("Location: ?menu={$module_name}&action=show&id=" . $_POST['id']); } else { header("Location: ?menu={$module_name}"); } } }
function updateContact($id, $phone, $first_name, $last_name, $email = NULL, $address = NULL, $company = NULL, $notes = NULL, $status = NULL, $cell_phone = NULL, $home_phone = NULL, $fax1 = NULL, $fax2 = NULL, $province = NULL, $city = NULL, $company_contact = NULL, $contact_rol = NULL, $picture = NULL, $addressBookType = "external") { global $arrConf; if (!$this->_checkUserAuthorized('address_book')) { return false; } $isAdminGroup = $this->_getACL()->isUserAdministratorGroup($_SERVER['PHP_AUTH_USER']); $dbAddressBook = $this->_getDB($arrConf['dsn_conn_database']); $addressBook = new paloAdressBook($dbAddressBook); // Obtener el ID del usuario logoneado $id_user = $this->_leerIdUser(); if (is_null($id_user)) { return false; } // Elegir entre la agenda interna y externa if (!isset($addressBookType) || !in_array($addressBookType, array('internal', 'external'))) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Unrecognized address book type, must be internal or external'; $this->errMsg["cn"] = get_class($this); return false; } $contactData = $addressBook->contactData($id, $id_user, $addressBookType, $isAdminGroup, $this->_astDSN); if (!is_array($contactData) || count($contactData) == 0) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid id contact'; $this->errMsg["fd"] = 'Contact do not exist'; $this->errMsg["cn"] = get_class($this); return false; } // Validar que el teléfono está presente y es numérico if (!isset($phone) || !preg_match('/^\\d+$/', $phone)) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Invalid phone, must be numeric string'; $this->errMsg["cn"] = get_class($this); return false; } if (isset($cell_phone) && !preg_match('/^[\\*|#]*[[:digit:]]*$/', $cell_phone)) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Invalid cell phone, it must be a numeric string and can only contain at the beginning * or #'; $this->errMsg["cn"] = get_class($this); return false; } if (isset($home_phone) && !preg_match('/^[\\*|#]*[[:digit:]]*$/', $home_phone)) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Invalid home phone, it must be a numeric string and can only contain at the beginning * or #'; $this->errMsg["cn"] = get_class($this); return false; } if (isset($fax1) && !preg_match('/^[\\*|#]*[[:digit:]]*$/', $fax1)) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Invalid fax1, it must be a numeric string and can only contain at the beginning * or #'; $this->errMsg["cn"] = get_class($this); return false; } if (isset($fax2) && !preg_match('/^[\\*|#]*[[:digit:]]*$/', $fax2)) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Invalid fax2, it must be a numeric string and can only contain at the beginning * or #'; $this->errMsg["cn"] = get_class($this); return false; } if (isset($picture) && $picture != "") { $picture = base64_decode($picture); $tmpname = "/tmp/image" . time(); file_put_contents($tmpname, $picture); //localización temporal de la imagen $size = getimagesize($tmpname); if (!is_array($size)) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Invalid picture, the format of the image is incorrect'; $this->errMsg["cn"] = get_class($this); return false; } $destination_path = "/var/www/address_book_images"; //Se procede a redimensionar la imagen para evitar inyección de código dentro de la imagen y luego se guarda $extension = $addressBook->saveResizeImage($tmpname, $size[0], $size[1], $size[0], $size[1], $size[2], $destination_path . "/{$id}"); //Se procede a guardar la imagen en formato thumbnail $new_width = 48; $new_height = 48; $addressBook->saveResizeImage($tmpname, $size[0], $size[1], $new_width, $new_height, $size[2], $destination_path . "/{$id}_Thumbnail"); $picture = $id . $extension; unlink($tmpname); } else { $picture = $contactData["picture"]; } $arrStatus = array("isPrivate", "isPublic"); if (!in_array($status, $arrStatus)) { $status = $contactData["status"]; } $first_name = isset($first_name) ? $first_name : $contactData["name"]; $last_name = isset($last_name) ? $last_name : $contactData["last_name"]; $work_phone = isset($phone) ? $phone : $contactData["telefono"]; $cell_phone = isset($cell_phone) ? $cell_phone : $contactData["cell_phone"]; $home_phone = isset($home_phone) ? $home_phone : $contactData["home_phone"]; $fax1 = isset($fax1) ? $fax1 : $contactData["fax1"]; $fax2 = isset($fax2) ? $fax2 : $contactData["fax2"]; $email = isset($email) ? $email : $contactData["email"]; $province = isset($province) ? $province : $contactData["province"]; $city = isset($city) ? $city : $contactData["city"]; $address = isset($address) ? $address : $contactData["address"]; $company = isset($company) ? $company : $contactData["company"]; $company_contact = isset($company_contact) ? $company_contact : $contactData["company_contact"]; $contact_rol = isset($contact_rol) ? $contact_rol : $contactData["contact_rol"]; $notes = isset($notes) ? $notes : $contactData["notes"]; $data = array($first_name, $last_name, $phone, $cell_phone, $home_phone, $fax1, $fax2, $email, $id_user, $picture, $province, $city, $address, $company, $company_contact, $contact_rol, "external", $notes, $status, NULL, NULL); $result = $addressBook->updateContact($data, $id); if (!$result) { $this->errMsg["fc"] = 'DBERROR'; $this->errMsg["fm"] = 'Database operation failed'; $this->errMsg["fd"] = 'Unable to write data to external phonebook - ' . $addressBook->_DB->errMsg; $this->errMsg["cn"] = get_class($addressBook); return false; } return true; }
function save_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, $update = FALSE) { $arrForm = createFieldForm($arrLang); $oForm = new paloForm($smarty, $arrForm); $pACL = new paloACL($pDB_2); $id_user = $pACL->getIdUser($_SESSION["elastix_user"]); $bandera = true; if (!$oForm->validateForm($_POST)) { // Falla la validación básica del formulario $smarty->assign("mb_title", $arrLang["Validation Error"]); $arrErrores = $oForm->arrErroresValidacion; $strErrorMsg = "<b>{$arrLang['The following fields contain errors']}:</b><br/>"; if (is_array($arrErrores) && count($arrErrores) > 0) { foreach ($arrErrores as $k => $v) { $strErrorMsg .= "{$k}, "; } } $smarty->assign("mb_message", $strErrorMsg); $smarty->assign("REQUIRED_FIELD", $arrLang["Required field"]); $smarty->assign("SAVE", $arrLang["Save"]); $smarty->assign("CANCEL", $arrLang["Cancel"]); $smarty->assign("title", $arrLang["Address Book"]); $smarty->assign("new_contact", $arrLang["New Contact"]); $smarty->assign("address_from_csv", $arrLang["Address Book from CSV"]); $smarty->assign("private_contact", $arrLang["Private Contact"]); $smarty->assign("public_contact", $arrLang["Public Contact"]); if (isset($_POST['address_book_options']) && $_POST['address_book_options'] == 'address_from_csv') { $smarty->assign("check_csv", "checked"); } else { $smarty->assign("check_new_contact", "checked"); } if (isset($_POST['address_book_status']) && $_POST['address_book_status'] == 'isPrivate') { $smarty->assign("check_isPrivate", "checked"); } else { $smarty->assign("check_isPublic", "checked"); } $smarty->assign("SAVE", $arrLang["Save"]); $smarty->assign("CANCEL", $arrLang["Cancel"]); $smarty->assign("REQUIRED_FIELD", $arrLang["Required field"]); $smarty->assign("label_file", $arrLang["File"]); $smarty->assign("DOWNLOAD", $arrLang["Download Address Book"]); $smarty->assign("HeaderFile", $arrLang["Header File Address Book"]); $smarty->assign("AboutContacts", $arrLang["About Address Book"]); if ($update) { $_POST["edit"] = 'edit'; return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } else { $smarty->assign("Show", 1); $smarty->assign("ShowImg", 1); $htmlForm = $oForm->fetchForm("{$local_templates_dir}/new_adress_book.tpl", $arrLang["Address Book"], $_POST); $contenidoModulo = "<form method='POST' enctype='multipart/form-data' style='margin-bottom:0;' action='?menu={$module_name}'>" . $htmlForm . "</form>"; return $contenidoModulo; } } else { $pictureUpload = $_FILES['picture']['name']; $file_upload = ""; $ruta_destino = "/var/www/address_book_images"; $idPost = $_POST['id']; $data = array(); $padress_book = new paloAdressBook($pDB); $contactData = $padress_book->contactData($idPost, $id_user); $lastId = 0; if ($update) { $idImg = $contactData['id']; } else { $idImg = date("Ymdhis"); } //valido el tipo de archivo if (isset($pictureUpload) && $pictureUpload != "") { // \w cualquier caracter, letra o guion bajo // \s cualquier espacio en blanco if (!preg_match("/^(\\w|-|\\.|\\(|\\)|\\s)+\\.(png|PNG|JPG|jpg|JPEG|jpeg)\$/", $pictureUpload)) { $smarty->assign("mb_title", $arrLang["Validation Error"]); $smarty->assign("mb_message", $arrLang["Invalid file extension.- It must be png or jpg or jpeg"]); if ($update) { return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, TRUE); } else { return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } else { if (is_uploaded_file($_FILES['picture']['tmp_name'])) { $file_upload = basename($_FILES['picture']['tmp_name']); // verificando que solo tenga la ruta al archivo $file_name = basename("/tmp/" . $_FILES['picture']['name']); $ruta_archivo = "/tmp/{$file_upload}"; $arrIm = explode(".", $pictureUpload); $renameFile = "{$ruta_destino}/{$idImg}." . $arrIm[count($arrIm) - 1]; $file_upload = $idImg . "." . $arrIm[count($arrIm) - 1]; $filesize = $_FILES['picture']['size']; $filetype = $_FILES['picture']['type']; $sizeImgUp = getimagesize($ruta_archivo); if (!$sizeImgUp) { $smarty->assign("mb_title", $arrLang["ERROR"]); $smarty->assign("mb_message", $arrLang["Possible file upload attack. Filename"] . " : " . $pictureUpload); if ($update) { return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, TRUE); } else { return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } //realizar acciones if (!rename($ruta_archivo, $renameFile)) { $smarty->assign("mb_title", $arrLang["ERROR"]); $smarty->assign("mb_message", $arrLang["Error to Upload"] . " : " . $pictureUpload); if ($update) { return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, TRUE); } else { return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } else { //redimensiono la imagen $ancho_thumbnail = 48; $alto_thumbnail = 48; $thumbnail_path = $ruta_destino . "/{$idImg}" . "_Thumbnail." . $arrIm[count($arrIm) - 1]; if (is_file($renameFile)) { if (!redimensionarImagen($renameFile, $thumbnail_path, $ancho_thumbnail, $alto_thumbnail)) { $smarty->assign("mb_title", $arrLang["ERROR"]); $smarty->assign("mb_message", $arrLang["Possible file upload attack. Filename"] . " : " . $pictureUpload); if ($update) { return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, TRUE); } else { return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } } $ancho = 280; $alto = 200; if (is_file($renameFile)) { if (!redimensionarImagen($renameFile, $renameFile, $ancho, $alto)) { $smarty->assign("mb_title", $arrLang["ERROR"]); $smarty->assign("mb_message", $arrLang["Possible file upload attack. Filename"] . " : " . $pictureUpload); if ($update) { return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, TRUE); } else { return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } } } } else { $smarty->assign("mb_title", $arrLang["ERROR"]); $smarty->assign("mb_message", $arrLang["Possible file upload attack. Filename"] . " : " . $pictureUpload); if ($update) { return view_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk, TRUE); } else { return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } } } $namedb = isset($_POST['name']) ? $_POST['name'] : ""; $last_namedb = isset($_POST['last_name']) ? $_POST['last_name'] : ""; $telefonodb = isset($_POST['telefono']) ? $_POST['telefono'] : ""; //$extensiondb = isset($_POST['extension'])?$_POST['extension']:""; $emaildb = isset($_POST['email']) ? $_POST['email'] : ""; $iduserdb = isset($id_user) ? "{$id_user}" : ""; $picturedb = isset($file_upload) ? "{$file_upload}" : ""; $addressdb = isset($_POST['address']) ? $_POST['address'] : ""; $companydb = isset($_POST['company']) ? $_POST['company'] : ""; $notesdb = isset($_POST['notes']) ? $_POST['notes'] : ""; $statusdb = isset($_POST['address_book_status']) ? $_POST['address_book_status'] : ""; $data = array($namedb, $last_namedb, $telefonodb, $emaildb, $iduserdb, $picturedb, $addressdb, $companydb, $notesdb, $statusdb); if ($update) { // actualizacion del contacto if ($contactData) { if ($file_upload == "") { $data[5] = $contactData['picture']; } $result = $padress_book->updateContact($data, $_POST['id']); if (!$result) { $smarty->assign("mb_title", $arrLang["Validation Error"]); $smarty->assign("mb_message", $arrLang["Internal Error"]); return report_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } else { $smarty->assign("mb_title", $arrLang["Validation Error"]); $smarty->assign("mb_message", $arrLang["Internal Error"]); return report_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } } else { //// creacion de contacto $result = $padress_book->addContact($data); if (!$result) { $smarty->assign("mb_title", $arrLang["Validation Error"]); $smarty->assign("mb_message", $arrLang["Internal Error"]); return new_adress_book($smarty, $module_name, $local_templates_dir, $pDB, $pDB_2, $arrLang, $arrConf, $dsn_agi_manager, $dsnAsterisk); } $lastId = $pDB->getLastInsertId(); $contactData2 = $padress_book->contactData($lastId, $id_user); if ($contactData2['picture'] != "" && isset($contactData2['picture'])) { $arrIm = explode(".", $contactData2['picture']); $renameFile = "{$ruta_destino}/" . $lastId . "." . $arrIm[count($arrIm) - 1]; $file_upload = $lastId . "." . $arrIm[count($arrIm) - 1]; rename($ruta_destino . "/" . $contactData2['picture'], $renameFile); rename($ruta_destino . "/" . $idImg . "_Thumbnail." . $arrIm[count($arrIm) - 1], $ruta_destino . "/" . $lastId . "_Thumbnail." . $arrIm[count($arrIm) - 1]); $data[5] = $file_upload; $padress_book->updateContact($data, $lastId); } } if (!$result) { return $pDB->errMsg; } //'?menu=$module_name&action=show&id=".$adress_book['id']."' if ($_POST['id']) { header("Location: ?menu={$module_name}&action=show&id=" . $_POST['id']); } else { header("Location: ?menu={$module_name}"); } } }
function updateContact($id, $phone, $first_name, $last_name, $email) { global $arrConf; if (!$this->_checkUserAuthorized('address_book')) { return false; } $dbAddressBook = $this->_getDB($arrConf['dsn_conn_database']); $addressBook = new paloAdressBook($dbAddressBook); // Obtener el ID del usuario logoneado $id_user = $this->_leerIdUser(); if (is_null($id_user)) { return false; } $contactData = $addressBook->contactData($id, $id_user); if (!is_array($contactData) || count($contactData) == 0) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid id contact'; $this->errMsg["fd"] = 'Contact do not exist'; $this->errMsg["cn"] = get_class($this); return false; } if (isset($phone) && !preg_match('/^\\d+$/', $phone)) { $this->errMsg["fc"] = 'PARAMERROR'; $this->errMsg["fm"] = 'Invalid format'; $this->errMsg["fd"] = 'Invalid phone, must be numeric string'; $this->errMsg["cn"] = get_class($this); return false; } $first_name = isset($first_name) ? $first_name : $contactData["name"]; $last_name = isset($last_name) ? $last_name : $contactData["last_name"]; $phone = isset($phone) ? $phone : $contactData["telefono"]; $email = isset($email) ? $email : $contactData["email"]; $data = array($first_name, $last_name, $phone, $email, $id_user, $contactData["picture"], $contactData["address"], $contactData["company"], $contactData["notes"], $contactData["status"]); $result = $addressBook->updateContact($data, $id); if (!$result) { $this->errMsg["fc"] = 'DBERROR'; $this->errMsg["fm"] = 'Database operation failed'; $this->errMsg["fd"] = 'Unable to write data to external phonebook - ' . $addressBook->_DB->errMsg; $this->errMsg["cn"] = get_class($addressBook); return false; } return true; }