2015-03-27 02:00:01 +01:00
|
|
|
|
<?php defined('BLUDIT') or die('Bludit CMS.');
|
2015-03-08 18:02:59 +01:00
|
|
|
|
|
2015-05-31 03:06:55 +02:00
|
|
|
|
class Text {
|
2015-03-08 18:02:59 +01:00
|
|
|
|
|
2015-10-02 06:30:16 +02:00
|
|
|
|
private static $specialChars = array(
|
|
|
|
|
// Latin
|
|
|
|
|
'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'AE', 'Ç'=>'C',
|
|
|
|
|
'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I',
|
|
|
|
|
'Ð'=>'D', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ő'=>'O',
|
|
|
|
|
'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ű'=>'U', 'Ý'=>'Y', 'Þ'=>'TH',
|
|
|
|
|
'ß'=>'ss',
|
|
|
|
|
'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'ae', 'ç'=>'c',
|
|
|
|
|
'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i',
|
|
|
|
|
'ð'=>'d', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ő'=>'o',
|
|
|
|
|
'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ü'=>'u', 'ű'=>'u', 'ý'=>'y', 'þ'=>'th',
|
|
|
|
|
'ÿ'=>'y',
|
|
|
|
|
// Latin symbols
|
|
|
|
|
'©'=>'(c)',
|
|
|
|
|
// Greek
|
|
|
|
|
'Α'=>'A', 'Β'=>'B', 'Γ'=>'G', 'Δ'=>'D', 'Ε'=>'E', 'Ζ'=>'Z', 'Η'=>'H', 'Θ'=>'8',
|
|
|
|
|
'Ι'=>'I', 'Κ'=>'K', 'Λ'=>'L', 'Μ'=>'M', 'Ν'=>'N', 'Ξ'=>'3', 'Ο'=>'O', 'Π'=>'P',
|
|
|
|
|
'Ρ'=>'R', 'Σ'=>'S', 'Τ'=>'T', 'Υ'=>'Y', 'Φ'=>'F', 'Χ'=>'X', 'Ψ'=>'PS', 'Ω'=>'W',
|
|
|
|
|
'Ά'=>'A', 'Έ'=>'E', 'Ί'=>'I', 'Ό'=>'O', 'Ύ'=>'Y', 'Ή'=>'H', 'Ώ'=>'W', 'Ϊ'=>'I',
|
|
|
|
|
'Ϋ'=>'Y',
|
|
|
|
|
'α'=>'a', 'β'=>'b', 'γ'=>'g', 'δ'=>'d', 'ε'=>'e', 'ζ'=>'z', 'η'=>'h', 'θ'=>'8',
|
|
|
|
|
'ι'=>'i', 'κ'=>'k', 'λ'=>'l', 'μ'=>'m', 'ν'=>'n', 'ξ'=>'3', 'ο'=>'o', 'π'=>'p',
|
|
|
|
|
'ρ'=>'r', 'σ'=>'s', 'τ'=>'t', 'υ'=>'y', 'φ'=>'f', 'χ'=>'x', 'ψ'=>'ps', 'ω'=>'w',
|
|
|
|
|
'ά'=>'a', 'έ'=>'e', 'ί'=>'i', 'ό'=>'o', 'ύ'=>'y', 'ή'=>'h', 'ώ'=>'w', 'ς'=>'s',
|
|
|
|
|
'ϊ'=>'i', 'ΰ'=>'y', 'ϋ'=>'y', 'ΐ'=>'i',
|
|
|
|
|
// Turkish
|
|
|
|
|
'Ş'=>'S', 'İ'=>'I', 'Ç'=>'C', 'Ü'=>'U', 'Ö'=>'O', 'Ğ'=>'G',
|
|
|
|
|
'ş'=>'s', 'ı'=>'i', 'ç'=>'c', 'ü'=>'u', 'ö'=>'o', 'ğ'=>'g',
|
|
|
|
|
// Russian
|
|
|
|
|
'А'=>'A', 'Б'=>'B', 'В'=>'V', 'Г'=>'G', 'Д'=>'D', 'Е'=>'E', 'Ё'=>'Yo', 'Ж'=>'Zh',
|
|
|
|
|
'З'=>'Z', 'И'=>'I', 'Й'=>'J', 'К'=>'K', 'Л'=>'L', 'М'=>'M', 'Н'=>'N', 'О'=>'O',
|
|
|
|
|
'П'=>'P', 'Р'=>'R', 'С'=>'S', 'Т'=>'T', 'У'=>'U', 'Ф'=>'F', 'Х'=>'H', 'Ц'=>'C',
|
|
|
|
|
'Ч'=>'Ch', 'Ш'=>'Sh', 'Щ'=>'Sh', 'Ъ'=>'', 'Ы'=>'Y', 'Ь'=>'', 'Э'=>'E', 'Ю'=>'Yu',
|
|
|
|
|
'Я'=>'Ya',
|
|
|
|
|
'а'=>'a', 'б'=>'b', 'в'=>'v', 'г'=>'g', 'д'=>'d', 'е'=>'e', 'ё'=>'yo', 'ж'=>'zh',
|
|
|
|
|
'з'=>'z', 'и'=>'i', 'й'=>'j', 'к'=>'k', 'л'=>'l', 'м'=>'m', 'н'=>'n', 'о'=>'o',
|
|
|
|
|
'п'=>'p', 'р'=>'r', 'с'=>'s', 'т'=>'t', 'у'=>'u', 'ф'=>'f', 'х'=>'h', 'ц'=>'c',
|
|
|
|
|
'ч'=>'ch', 'ш'=>'sh', 'щ'=>'sh', 'ъ'=>'', 'ы'=>'y', 'ь'=>'', 'э'=>'e', 'ю'=>'yu',
|
|
|
|
|
'я'=>'ya',
|
2016-09-17 12:33:42 +02:00
|
|
|
|
// Bulgarian
|
2016-09-17 12:31:43 +02:00
|
|
|
|
'А'=>'A', 'Б'=>'B', 'В'=>'V', 'Г'=>'G', 'Д'=>'D', 'Е'=>'E', 'Ж'=>'Zh', 'З'=>'Z',
|
|
|
|
|
'И'=>'I', 'Й'=>'J', 'К'=>'K', 'Л'=>'L', 'М'=>'M', 'Н'=>'N', 'О'=>'O', 'П'=>'P',
|
|
|
|
|
'Р'=>'R', 'С'=>'S', 'Т'=>'T', 'У'=>'U', 'Ф'=>'F', 'Х'=>'H', 'Ц'=>'C', 'Ч'=>'Ch',
|
2017-05-16 00:46:20 +02:00
|
|
|
|
'Ш'=>'Sh', 'Щ'=>'Sh', 'Ъ'=>'', 'Ь'=>'J','Ю'=>'Yu','Я'=>'Ya',
|
2016-09-17 12:31:43 +02:00
|
|
|
|
'а'=>'a', 'б'=>'b', 'в'=>'v', 'г'=>'g', 'д'=>'d', 'е'=>'e', 'ж'=>'zh','з'=>'z',
|
|
|
|
|
'и'=>'i', 'й'=>'j', 'к'=>'k', 'л'=>'l', 'м'=>'m', 'н'=>'n', 'о'=>'o','п'=>'p',
|
|
|
|
|
'р'=>'r', 'с'=>'s', 'т'=>'t', 'у'=>'u', 'ф'=>'f', 'х'=>'h', 'ц'=>'c', 'ч'=>'ch',
|
|
|
|
|
'ш'=>'sh', 'щ'=>'sh', 'ъ'=>'', 'ь'=>'j', 'ю'=>'yu', 'я'=>'ya',
|
2015-10-02 06:30:16 +02:00
|
|
|
|
// Ukrainian
|
|
|
|
|
'Є'=>'Ye', 'І'=>'I', 'Ї'=>'Yi', 'Ґ'=>'G',
|
|
|
|
|
'є'=>'ye', 'і'=>'i', 'ї'=>'yi', 'ґ'=>'g',
|
|
|
|
|
// Czech
|
|
|
|
|
'Č'=>'C', 'Ď'=>'D', 'Ě'=>'E', 'Ň'=>'N', 'Ř'=>'R', 'Š'=>'S', 'Ť'=>'T', 'Ů'=>'U',
|
|
|
|
|
'Ž'=>'Z',
|
|
|
|
|
'č'=>'c', 'ď'=>'d', 'ě'=>'e', 'ň'=>'n', 'ř'=>'r', 'š'=>'s', 'ť'=>'t', 'ů'=>'u',
|
|
|
|
|
'ž'=>'z',
|
|
|
|
|
// Polish
|
|
|
|
|
'Ą'=>'A', 'Ć'=>'C', 'Ę'=>'e', 'Ł'=>'L', 'Ń'=>'N', 'Ó'=>'o', 'Ś'=>'S', 'Ź'=>'Z',
|
|
|
|
|
'Ż'=>'Z',
|
|
|
|
|
'ą'=>'a', 'ć'=>'c', 'ę'=>'e', 'ł'=>'l', 'ń'=>'n', 'ó'=>'o', 'ś'=>'s', 'ź'=>'z',
|
|
|
|
|
'ż'=>'z',
|
|
|
|
|
// Latvian
|
|
|
|
|
'Ā'=>'A', 'Č'=>'C', 'Ē'=>'E', 'Ģ'=>'G', 'Ī'=>'i', 'Ķ'=>'k', 'Ļ'=>'L', 'Ņ'=>'N',
|
|
|
|
|
'Š'=>'S', 'Ū'=>'u', 'Ž'=>'Z',
|
|
|
|
|
'ā'=>'a', 'č'=>'c', 'ē'=>'e', 'ģ'=>'g', 'ī'=>'i', 'ķ'=>'k', 'ļ'=>'l', 'ņ'=>'n',
|
|
|
|
|
'š'=>'s', 'ū'=>'u', 'ž'=>'z'
|
|
|
|
|
);
|
|
|
|
|
|
2015-06-29 04:51:48 +02:00
|
|
|
|
public static function addSlashes($string, $begin=true, $end=true)
|
2015-06-26 06:31:53 +02:00
|
|
|
|
{
|
|
|
|
|
if($begin) {
|
2015-06-29 04:51:48 +02:00
|
|
|
|
$string = '/' . ltrim($string, '/');
|
2015-06-26 06:31:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($end) {
|
2015-06-29 04:51:48 +02:00
|
|
|
|
$string = rtrim($string, '/') . '/';
|
2015-06-26 06:31:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-06-29 04:51:48 +02:00
|
|
|
|
if($string=='//') {
|
2015-06-26 06:31:53 +02:00
|
|
|
|
return '/';
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-29 04:51:48 +02:00
|
|
|
|
return $string;
|
2015-06-26 06:31:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-29 19:21:11 +02:00
|
|
|
|
public static function startsWith($string, $startString)
|
2015-05-05 03:00:01 +02:00
|
|
|
|
{
|
2016-05-29 19:21:11 +02:00
|
|
|
|
$length = self::length($startString);
|
2015-05-05 03:00:01 +02:00
|
|
|
|
|
2016-05-29 19:21:11 +02:00
|
|
|
|
return( mb_substr($string, 0, $length)===$startString );
|
|
|
|
|
}
|
2015-05-05 03:00:01 +02:00
|
|
|
|
|
2016-05-29 19:21:11 +02:00
|
|
|
|
public static function endsWith($string, $endsString)
|
|
|
|
|
{
|
|
|
|
|
$length = (-1)*self::length($endsString);
|
|
|
|
|
|
|
|
|
|
return( mb_substr($string, $length)===$endsString );
|
2015-05-05 03:00:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function endsWithNumeric($string)
|
|
|
|
|
{
|
2016-05-29 19:21:11 +02:00
|
|
|
|
return( is_numeric(mb_substr($string, -1, 1)) );
|
2015-05-05 03:00:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function randomText($length)
|
|
|
|
|
{
|
|
|
|
|
$characteres = "1234567890abcdefghijklmnopqrstuvwxyz!@#%^&*";
|
|
|
|
|
$text = '';
|
|
|
|
|
for($i=0; $i<$length; $i++) {
|
|
|
|
|
$text .= $characteres{rand(0,41)};
|
|
|
|
|
}
|
|
|
|
|
return $text;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-20 05:14:28 +02:00
|
|
|
|
public static function replaceAssoc(array $replace, $text)
|
|
|
|
|
{
|
|
|
|
|
return str_replace(array_keys($replace), array_values($replace), $text);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-22 17:45:31 +02:00
|
|
|
|
// Convert unicode characters to utf-8 characters
|
2017-11-01 19:38:56 +01:00
|
|
|
|
// Characters that cannot be converted will be removed from the string
|
|
|
|
|
// This function can return an empty string
|
2015-08-07 19:59:21 +02:00
|
|
|
|
public static function cleanUrl($string, $separator='-')
|
|
|
|
|
{
|
2018-01-21 16:35:47 +01:00
|
|
|
|
global $Language;
|
|
|
|
|
|
2017-10-31 00:06:06 +01:00
|
|
|
|
if (EXTREME_FRIENDLY_URL) {
|
2018-04-22 17:45:31 +02:00
|
|
|
|
$string = trim($string, '-');
|
|
|
|
|
$string = self::lowercase($string);
|
2016-06-03 02:57:13 +02:00
|
|
|
|
$string = preg_replace("/[\/_|+ -]+/", $separator, $string);
|
|
|
|
|
return $string;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-02 06:30:16 +02:00
|
|
|
|
// Transliterate characters to ASCII
|
2018-01-21 16:35:47 +01:00
|
|
|
|
$specialCharsFromDictionary = $Language->getSpecialChars();
|
|
|
|
|
$string = str_replace(array_keys($specialCharsFromDictionary), $specialCharsFromDictionary, $string);
|
2015-10-02 06:30:16 +02:00
|
|
|
|
$string = str_replace(array_keys(self::$specialChars), self::$specialChars, $string);
|
|
|
|
|
|
2017-10-31 00:06:06 +01:00
|
|
|
|
if (function_exists('iconv')) {
|
|
|
|
|
if (@iconv(CHARSET, 'ASCII//TRANSLIT//IGNORE', $string)!==false) {
|
|
|
|
|
$string = iconv(CHARSET, 'ASCII//TRANSLIT//IGNORE', $string);
|
|
|
|
|
}
|
2015-08-07 19:59:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$string = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $string);
|
|
|
|
|
$string = trim($string, '-');
|
|
|
|
|
$string = self::lowercase($string);
|
|
|
|
|
$string = preg_replace("/[\/_|+ -]+/", $separator, $string);
|
|
|
|
|
|
|
|
|
|
return $string;
|
|
|
|
|
}
|
2015-05-05 03:00:01 +02:00
|
|
|
|
|
2015-03-08 18:02:59 +01:00
|
|
|
|
// Replace all occurrences of the search string with the replacement string.
|
2017-12-17 21:16:30 +01:00
|
|
|
|
// replace("%body%", "black", "<body text='%body%'>");
|
2015-03-08 18:02:59 +01:00
|
|
|
|
public static function replace($search, $replace, $string)
|
|
|
|
|
{
|
|
|
|
|
return str_replace($search,$replace,$string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// String to lowercase
|
2017-08-06 17:27:30 +02:00
|
|
|
|
public static function lowercase($string)
|
2015-03-08 18:02:59 +01:00
|
|
|
|
{
|
2017-08-06 17:27:30 +02:00
|
|
|
|
return mb_strtolower($string, CHARSET);
|
2015-03-08 18:02:59 +01:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-31 03:06:55 +02:00
|
|
|
|
// Make a string's first character uppercase
|
2017-08-06 17:27:30 +02:00
|
|
|
|
public static function firstCharUp($string)
|
2015-05-31 03:06:55 +02:00
|
|
|
|
{
|
|
|
|
|
// Thanks http://stackoverflow.com/questions/2517947/ucfirst-function-for-multibyte-character-encodings
|
2017-08-06 17:27:30 +02:00
|
|
|
|
$strlen = mb_strlen($string, CHARSET);
|
|
|
|
|
$firstChar = mb_substr($string, 0, 1, CHARSET);
|
|
|
|
|
$then = mb_substr($string, 1, $strlen - 1, CHARSET);
|
2015-05-31 03:06:55 +02:00
|
|
|
|
|
2017-08-06 17:27:30 +02:00
|
|
|
|
return mb_strtoupper($firstChar, CHARSET).$then;
|
2015-05-31 03:06:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 01:45:30 +01:00
|
|
|
|
// Find position of first occurrence of substring in a string otherwise returns FALSE.
|
|
|
|
|
public static function stringPosition($string, $substring)
|
2015-03-08 18:02:59 +01:00
|
|
|
|
{
|
2017-08-06 17:27:30 +02:00
|
|
|
|
return mb_strpos($string, $substring, 0, CHARSET);
|
2015-05-05 03:00:01 +02:00
|
|
|
|
}
|
2015-03-08 18:02:59 +01:00
|
|
|
|
|
2017-05-16 00:46:20 +02:00
|
|
|
|
public static function stringContains($string, $substring)
|
|
|
|
|
{
|
|
|
|
|
return (self::stringPosition($string, $substring) !== false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 03:00:01 +02:00
|
|
|
|
// Returns the portion of string specified by the start and length parameters.
|
|
|
|
|
public static function cut($string, $start, $length)
|
2015-03-08 18:02:59 +01:00
|
|
|
|
{
|
2017-08-06 17:27:30 +02:00
|
|
|
|
$cut = mb_substr($string, $start, $length, CHARSET);
|
2015-05-07 03:00:01 +02:00
|
|
|
|
|
|
|
|
|
if(empty($cut)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $cut;
|
2015-03-08 18:02:59 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-08 00:15:52 +02:00
|
|
|
|
public static function removeHTMLTags($string)
|
|
|
|
|
{
|
|
|
|
|
return strip_tags($string);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-08 18:02:59 +01:00
|
|
|
|
// Return string length
|
|
|
|
|
public static function length($string)
|
|
|
|
|
{
|
2017-08-06 17:27:30 +02:00
|
|
|
|
return mb_strlen($string, CHARSET);
|
2015-05-05 03:00:01 +02:00
|
|
|
|
}
|
2015-03-08 18:02:59 +01:00
|
|
|
|
|
2015-03-27 02:00:01 +01:00
|
|
|
|
public static function isEmpty($string)
|
|
|
|
|
{
|
|
|
|
|
$string = trim($string);
|
|
|
|
|
|
2016-05-29 19:21:11 +02:00
|
|
|
|
if(empty($string)) {
|
2015-03-27 02:00:01 +01:00
|
|
|
|
return true;
|
2016-05-29 19:21:11 +02:00
|
|
|
|
}
|
2015-03-27 02:00:01 +01:00
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-29 04:51:48 +02:00
|
|
|
|
public static function isNotEmpty($string)
|
2015-03-08 18:02:59 +01:00
|
|
|
|
{
|
2015-06-29 04:51:48 +02:00
|
|
|
|
return !self::isEmpty($string);
|
2015-03-08 18:02:59 +01:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-24 05:28:25 +02:00
|
|
|
|
public static function imgRel2Abs($string, $base)
|
|
|
|
|
{
|
2017-10-07 02:45:03 +02:00
|
|
|
|
$pattern = '/<img([^>]*)(src)=\"(?!https:)(?!http:)(?!\/\/)(.*?)\"(.*?)>/';
|
|
|
|
|
$replace = "<img\${1} src=\"".$base."\${3}\" \${4}>";
|
2017-08-02 01:11:57 +02:00
|
|
|
|
|
|
|
|
|
return preg_replace($pattern, $replace, $string);
|
2015-08-22 18:33:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function pre2htmlentities($string)
|
|
|
|
|
{
|
|
|
|
|
return preg_replace_callback('/<pre.*?><code(.*?)>(.*?)<\/code><\/pre>/imsu',
|
2017-12-06 18:49:53 +01:00
|
|
|
|
function ($input) {
|
|
|
|
|
return "<pre><code $input[1]>".htmlentities($input[2])."</code></pre>";
|
|
|
|
|
},
|
2015-08-22 18:33:33 +02:00
|
|
|
|
$string);
|
2015-07-24 05:28:25 +02:00
|
|
|
|
}
|
2017-08-06 17:27:30 +02:00
|
|
|
|
|
2017-08-06 16:17:34 +02:00
|
|
|
|
// Truncates the string under the limit specified by the limit parameter.
|
|
|
|
|
public static function truncate($string, $limit, $end = '...')
|
|
|
|
|
{
|
|
|
|
|
// Check if over $limit
|
|
|
|
|
if(mb_strlen($string) > $limit) {
|
2017-08-06 17:27:30 +02:00
|
|
|
|
|
2017-08-06 16:17:34 +02:00
|
|
|
|
// Check if string is only one word
|
|
|
|
|
if(preg_match('/\s/', $string)) {
|
2017-08-06 17:27:30 +02:00
|
|
|
|
|
2017-08-06 16:17:34 +02:00
|
|
|
|
// Append the string specified by the end parameter to the end of the string as it is over the limit.
|
2017-08-06 17:27:30 +02:00
|
|
|
|
$truncate = trim(mb_substr($string, 0, mb_strpos($string, ' ', $limit, CHARSET), CHARSET));
|
2017-08-06 16:17:34 +02:00
|
|
|
|
} else {
|
2017-08-06 17:27:30 +02:00
|
|
|
|
$truncate = trim(mb_substr($string, 0, $limit, CHARSET));
|
2017-08-06 16:17:34 +02:00
|
|
|
|
}
|
|
|
|
|
$truncate = $truncate.$end;
|
|
|
|
|
} else {
|
|
|
|
|
$truncate = $string;
|
|
|
|
|
}
|
2017-08-06 17:27:30 +02:00
|
|
|
|
|
2017-08-06 16:17:34 +02:00
|
|
|
|
if(empty($truncate)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $truncate;
|
|
|
|
|
}
|
2018-04-13 23:32:29 +02:00
|
|
|
|
|
2017-12-06 18:49:53 +01:00
|
|
|
|
}
|