<?php
/**
* Portable UTF-8
* Lightweight Library for Unicode Handling in PHP
* @details http://pageconfig.com/post/portable-utf8
* @demo http://pageconfig.com/post/portable-utf-8-demo
*
* @version 1.3
* @author Hamid Sarfraz
*
* @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
*
* @copyright 2013 Hamid sarfraz
* @license http://pageconfig.com/post/license
*/
/**
* utf8_url_slug( )
*
* Creates SEO Friendly URL Slugs with UTF-8 support
* Optionally can do transliteration
* @since 1.0
*
* @param string $str The text which is to be converted Slug
* @param int $maxl Optional. Sets the maximum number of characters
* to be allowed in the slug. Default is UNLIMITED.
* @param bool $trns
* @return string The UTF-8 encoded URL Slug.
*/
function utf8_url_slug( $str = '', $maxl = -1, $trns = false )
{
$str = utf8_clean( $str, true ); //True == $remove_bom
$str = utf8_strtolower( $str );
if( $trns && iconv_loaded() )
{
$str = iconv( 'UTF-8', 'US-ASCII//TRANSLIT//IGNORE', $str );
}
if( pcre_utf8_support() )
{
$str = preg_replace( '/[^\\p{L}\\p{Nd}\-_]+/u', '-', $str );
}
else
{
$str = preg_replace( '/[\>\<\+\?\&\"\'\/\\\:\s\-\#\%\=]+/', '-', $str );
}
if( $maxl > 0 )
{
$maxl = ( int ) $maxl;
$str = utf8_substr( $str, 0, $maxl );
}
$str = trim( $str, '_-' );
if( ! strlen( $str ) )
{
$str = substr( md5( microtime( true ) ), 0, ( $maxl == - 1 ? 32 : $maxl ) );
}
return $str;
}
/**
* is_utf8( )
*
* Checks whether the passed string contains only byte sequances that
* appear valid UTF-8 characters.
* @since 1.0
*
* @param string $str The string to be checked
* @return bool True if the check succeeds, False Otherwise
*/
function is_utf8( $str )
{
if( pcre_utf8_support() )
{
return ( bool ) preg_match( '//u', $str );
}
if( mbstring_loaded() )
{
return mb_check_encoding( $str, 'UTF-8' );
}
//Fallback
$len = strlen( $str );
for( $i = 0; $i < $len; $i ++ )
{
if( ( $str[ $i ] & "\x80" ) === "\x00" )
{
continue;
}
else if( ( ( $str[ $i ] & "\xE0" ) === "\xC0" ) && ( isset( $str[ $i + 1 ] ) ) )
{
if( ( $str[ $i + 1 ] & "\xC0" ) === "\x80" )
{
$i ++;
continue;
}
return false;
}
else if( ( ( $str[ $i ] & "\xF0" ) === "\xE0" ) && ( isset( $str[ $i + 2 ] ) ) )
{
if( ( ( $str[ $i + 1 ] & "\xC0" ) === "\x80" ) && ( ( $str[ $i + 2 ] & "\xC0" ) === "\x80" ) )
{
$i = $i + 2;
continue;
}
return false;
}
else if( ( ( $str[ $i ] & "\xF8" ) === "\xF0" ) && ( isset( $str[ $i + 3 ] ) ) )
{
if( ( ( $str[ $i + 1 ] & "\xC0" ) === "\x80" ) && ( ( $str[ $i + 2 ] & "\xC0" ) === "\x80" ) && ( ( $str[ $i + 3 ] & "\xC0" ) === "\x80" ) )
{
$i = $i + 3;
continue;
}
return false;
}
else
{
return false;
}
}
return true;
}
/**
* utf8_ord( )
*
* Calculates Unicode Code Point of the given UTF-8 encoded character
* @since 1.0
*
* @param string $chr The character of which to calculate Code Point
* @return int Unicode Code Point of the given character
* 0 on invalid UTF-8 byte sequence
*/
function utf8_ord( $chr )
{
$chr = utf8_split( $chr );
$chr = $chr[ 0 ];
switch( strlen( $chr ) )
{
case 1 :
return ord( $chr );
case 2 :
return ( ( ord( $chr[ 0 ] ) & 0x1F ) << 6 ) | ( ord( $chr[ 1 ] ) & 0x3F );
case 3 :
return ( ( ord( $chr[ 0 ] ) & 0x0F ) << 12 ) | ( ( ord( $chr[ 1 ] ) & 0x3F ) << 6 ) | ( ord( $chr[ 2 ] ) & 0x3F );
case 4 :
return ( ( ord( $chr[ 0 ] ) & 0x07 ) << 18 ) | ( ( ord( $chr[ 1 ] ) & 0x3F ) << 12 ) | ( ( ord( $chr[ 2 ] ) & 0x3F ) << 6 ) | ( ord( $chr[ 3 ] ) & 0x3F );
}
return 0;
}
/**
* utf8_strlen( )
*
* Finds the length of the given string in terms of number
* of valid UTF-8 characters it contains. Invalid characters are ignored.
* @since 1.0
*
* @param string $str The string for which to find the character length
* @return int Length of the Unicode String
*/
function utf8_strlen( $str )
{
if( mbstring_loaded() )
{
$str = utf8_clean( $str );
return mb_strlen( $str, 'UTF-8' );
}
if( iconv_loaded() )
{
$str = utf8_clean( $str );
return iconv_strlen( $str, 'UTF-8' );
}
//PCRE \X is buggy in many recent versions of PHP
//See the original post.
//if( pcre_utf8_support( ) )
//{
// $str = utf8_clean( $str );
//
// preg_match_all( '/\X/u' , $str , $matches );
//
// return count( $matches[0] );
//}
return count( utf8_split( $str ) );
}
/**
* utf8_chr( )
*
* Generates a UTF-8 encoded character from the given Code Point
* @since 1.0
*
* @param int $code_point The code point for which to generate a character
* @return string Milti-Byte character
* returns empty string on failure to encode
*/
function utf8_chr( $code_point )
{
if( ( $i = ( int ) $code_point ) !== $code_point )
{
//$code_point is a string, lets extract int code point from it
if( ! ( $i = ( int ) utf8_hex_to_int( $code_point ) ) )
{
return '';
}
}
//json not working properly for larger code points
//See the original post.
//if( extension_loaded( 'json' ) )
//{
// $hex = dechex( $i );
//
// return json_decode('"\u'. ( strlen( $hex ) < 4 ? substr( '000' . $hex , -4 ) : $hex ) .'"');
//}
//else
if( mbstring_loaded() /*extension_loaded( 'mbstring' )*/ )
{
return mb_convert_encoding( "&#$i;", 'UTF-8', 'HTML-ENTITIES' );
}
else
{
return html_entity_decode( "&#{$i};", ENT_QUOTES, 'UTF-8' );
}
}
/**
* pcre_utf8_support( )
*
* Checks if \u modifier is available that enables Unicode support in PCRE.
* @since 1.0
*
* @return bool True if support is available, false otherwise
*/
function pcre_utf8_support()
{
static $support;
if( ! isset( $support ) )
{
$support = @preg_match( '//u', '' );
//Cached the response
}
return $support;
}
/**
* utf8_clean( )
*
* Accepts a string and removes all non-UTF-8 characters from it.
* @since 1.0
*
* @param string $str The string to be sanitized.
* @return string Clean UTF-8 encoded string
*/
function utf8_clean( $str, $remove_bom = false )
{
//http://stackoverflow.com/questions/1401317/remove-non-utf8-characters-from-string
//caused connection reset problem on larger strings
//$regx = '/((?:[\x00-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}){1,})|./';
$regx = '/([\x00-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3})|./s';
$str = preg_replace( $regx, '$1', $str );
if( $remove_bom )
{
$str = utf8_str_replace( utf8_bom(), '', $str );
}
return $str;
}
/**
* utf8_split( )
*
* Convert a string to an array of Unicode characters.
* @since 1.0
*
* @param string $str The string to split into array.
* @param int $split_length Max character length of each array element
* @return array An array containing chunks of the string
*/
function utf8_split( $str, $split_length = 1 )
{
$str = ( string ) $str;
$ret = array();
if( pcre_utf8_support() )
{
$str = utf8_clean( $str );
// http://stackoverflow.com/a/8780076/369005
$ret = preg_split( '/(?<!^)(?!$)/u', $str );
// \X is buggy in many recent versions of PHP
//preg_match_all( '/\X/u' , $str , $ret );
//$ret = $ret[0];
}
else
{
//Fallback
$len = strlen( $str );
for( $i = 0; $i < $len; $i ++ )
{
if( ( $str[ $i ] & "\x80" ) === "\x00" )
{
$ret[] = $str[ $i ];
}
else if( ( ( $str[ $i ] & "\xE0" ) === "\xC0" ) && ( isset( $str[ $i + 1 ] ) ) )
{
if( ( $str[ $i + 1 ] & "\xC0" ) === "\x80" )
{
$ret[] = $str[ $i ] . $str[ $i + 1 ];
$i ++;
}
}
else if( ( ( $str[ $i ] & "\xF0" ) === "\xE0" ) && ( isset( $str[ $i + 2 ] ) ) )
{
if( ( ( $str[ $i + 1 ] & "\xC0" ) === "\x80" ) && ( ( $str[ $i + 2 ] & "\xC0" ) === "\x80" ) )
{
$ret[] = $str[ $i ] . $str[ $i + 1 ] . $str[ $i + 2 ];
$i = $i + 2;
}
}
else if( ( ( $str[ $i ] & "\xF8" ) === "\xF0" ) && ( isset( $str[ $i + 3 ] ) ) )
{
if( ( ( $str[ $i + 1 ] & "\xC0" ) === "\x80" ) && ( ( $str[ $i + 2 ] & "\xC0" ) === "\x80" ) && ( ( $str[ $i + 3 ] & "\xC0" ) === "\x80" ) )
{
$ret[] = $str[ $i ] . $str[ $i + 1 ] . $str[ $i + 2 ] . $str[ $i + 3 ];
$i = $i + 3;
}
}
}
}
if( $split_length > 1 )
{
$ret = array_chunk( $ret, $split_length );
$ret = array_map( 'implode', $ret );
}
if( $ret === false || $ret[ 0 ] === '' )
{
return array();
}
return $ret;
}
/**
* utf8_chunk_split( )
*
* Splits a string into smaller chunks and multiple lines, using the specified
* line ending character
* @since 1.0
*
* @param string $body The original string to be split.
* @param int $chunklen The maximum character length of a chunk
* @param string $end The character(s) to be inserted at the end of each chunk
* @return string The chunked string
*/
function utf8_chunk_split( $body, $chunklen = 76, $end = "\r\n" )
{
return implode( $end, utf8_split( $body, $chunklen ) );
}
/**
* utf8_fits_inside( )
*
* Checks if the number of Unicode characters in a string are not
* more than the specified integer.
* @since 1.0
*
* @param string $str The original string to be checked.
* @param int $box_size The size in number of chars to be checked against string.
* @return bool true if string is less than or equal to $box_size The
* false otherwise
*/
function utf8_fits_inside( $str, $box_size )
{
return ( utf8_strlen( $str ) <= $box_size );
}
/**
* utf8_chr_size_list( )
*
* Generates an array of byte length of each character of a Unicode string.
* @since 1.0
*
* @param string $str The original Unicode string
* @return array An array of byte lengths of each character.
*/
function utf8_chr_size_list( $str )
{
return array_map( 'strlen', utf8_split( $str ) );
}
/**
* utf8_max_chr_width( )
*
* Calculates and returns the maximum number of bytes taken by any
* UTF-8 encoded character in the given string
* @since 1.0
*
* @param string $str The original Unicode string
* @return array An array of byte lengths of each character.
*/
function utf8_max_chr_width( $str )
{
return max( utf8_chr_size_list( $string ) );
}
/**
* utf8_single_chr_html_encode( )
*
* Converts a UTF-8 character to HTML Numbered Entity like {
* @since 1.0
*
* @param string $chr The Unicode character to be encoded as numbered entity
* @return string HTML numbered entity
*/
function utf8_single_chr_html_encode( $chr )
{
return '&#' . utf8_ord( $chr ) . ';';
}
/**
* utf8_html_encode( )
*
* Converts a UTF-8 string to a series of
* HTML Numbered Entities like {'ی...
* @since 1.0
*
* @param string $str The Unicode string to be encoded as numbered entities
* @return string HTML numbered entities
*/
function utf8_html_encode( $str )
{
return implode( array_map( 'utf8_single_chr_html_encode', utf8_split( $str ) ) );
}
/**
* utf8_substr( )
*
* UTF-8 aware substr
* @since 1.0
*
* For detailed documentation see php.net/substr
*
* substr works with bytes, while utf8_substr works with characters
* and are identical in all other aspects.
*/
function utf8_substr( $str, $start = 0, $length = NULL )
{
//iconv and mbstring are not tolerant to invalid encoding
//further, their behaviour is inconsistant with that of PHP's substr
// Try to use mbstring functions firstly before iconv functions, because
// iconv_substr() can reproduces an error noticing about illegal character in input string
if( mbstring_loaded() )
{
$str = utf8_clean( $str );
if( $length === NULL )
{
// fplanque> The following produces an insane number on Mac OS X and then iconv_substr() will fail.
$length = PHP_INT_MAX;
// echo "PHP_INT_MAX=$length<br>\n";
// Conservative approach:
$length = strlen( $str ); // Gives a byte count but that's ok as logn as it >= char length
// Note: using 2^32 as a fixed value here will also bug! 2^32-1 will bug differently, etc.
}
return mb_substr( $str, $start, $length, 'UTF-8' );
}
if( iconv_loaded() )
{
$str = utf8_clean( $str );
if( $length === NULL )
{
// fplanque> The following produces an insane number on Mac OS X and then iconv_substr() will fail.
$length = PHP_INT_MAX;
// echo "PHP_INT_MAX=$length<br>\n";
// Conservative approach:
$length = strlen( $str ); // Gives a byte count but that's ok as logn as it >= char length
// Note: using 2^32 as a fixed value here will also bug! 2^32-1 will bug differently, etc.
}
return iconv_substr( $str, $start, $length, 'UTF-8' );
}
//Fallback
//Split to array, and remove invalid characters
$array = utf8_split( $str );
//Extract relevant part, and join to make sting again
return implode( array_slice( $array, $start, $length ) );
}
/**
* utf8_bom( )
*
* Returns the Byte Order Mark Character
* @since 1.0
*
* @return string Byte Order Mark
*/
function utf8_bom()
{
return "\xef\xbb\xbf";
//static $bom = 0;
//if( !$bom )
//{
// $bom = pack( 'CCC' , 0xEF , 0xBB , 0xBF );
//}
//return $bom;
}
/**
* is_bom( )
*
* Checks if the given string is a Byte Order Mark
* @since 1.0
*
* @param string $utf8_chr The input string
* @return bool True if the $utf8_chr is Byte Order Mark, False otherwise
*/
function is_bom( $utf8_chr )
{
return ( $utf8_chr === utf8_bom() );
}
/**
* utf8_file_has_bom( )
*
* Checks if a file starts with BOM character
* @since 1.0
*
* @param string $file_path Path to a valid file
* @return bool True if the file has BOM at the start, False otherwise
*/
function utf8_file_has_bom( $file_path )
{
return is_bom( file_get_contents( $file_path, 0, NULL, - 1, 3 ) );
}
/**
* utf8_string_has_bom( )
*
* Checks if string starts with BOM character
* @since 1.0
*
* @param string $str The input string
* @return bool True if the string has BOM at the start, False otherwise
*/
function utf8_string_has_bom( $str )
{
return is_bom( substr( $str, 0, 3 ) );
}
/**
* utf8_add_bom_to_string( )
*
* Prepends BOM character to the string and returns the whole string.
* If BOM already existed there, the Input string is returned.
* @since 1.0
*
* @param string $str The input string
* @return string The output string that contains BOM
*/
function utf8_add_bom_to_string( $str )
{
if( ! is_bom( substr( $str, 0, 3 ) ) )
{
$str = utf8_bom() . $str;
}
return $str;
}
/**
* utf8_str_shuffle( )
*
* Shuffles all the characters in the string.
* @since 1.0
*
* @param string $str The input string
* @return string The shuffled string
*/
function utf8_str_shuffle( $str )
{
$array = utf8_split( $str );
shuffle( $array );
return implode( '', $array );
}
/**
* utf8_count_chars( )
*
* Returns count of characters used in a string
* @since 1.0
*
* @param string $str The input string
* @return array An associative array of Character as keys and
* their count as values
*/
function utf8_count_chars( $str ) //there is no $mode parameters
{
$array = array_count_values( utf8_split( $str ) );
ksort( $array );
return $array;
}
/**
* utf8_strrev( )
*
* Reverses characters order in the string
* @since 1.0
*
* @param string $str The input string
* @return string The string with characters in the reverse sequence
*/
function utf8_strrev( $str )
{
return implode( array_reverse( utf8_split( $str ) ) );
}
/**
* utf8_strpos( )
*
* Finds the number of Characters to the left of first occurance of the needle
* @since 1.0
*
* For detailed documentation see php.net/strpos
*
* strpos works with bytes, while utf8_strpos works with characters
* and are identical in all other aspects.
*/
function utf8_strpos( $haystack, $needle, $offset = 0 )
{
//iconv and mbstring do not support integer $needle
if( ( ( int ) $needle ) === $needle && ( $needle >= 0 ) )
{
$needle = utf8_chr( $needle );
}
$needle = utf8_clean( ( string ) $needle );
$offset = ( int ) $offset;
//mb_strpos returns wrong position if invalid characters are found in $haystack before $needle
//iconv_strpos is not tolerant to invalid characters
$haystack = utf8_clean( $haystack );
if( mbstring_loaded() )
{
return mb_strpos( $haystack, $needle, $offset, 'UTF-8' );
}
if( iconv_loaded() )
{
return iconv_strpos( $haystack, $needle, $offset, 'UTF-8' );
}
if( $offset > 0 )
{
$haystack = utf8_substr( $haystack, $offset );
}
//Negative Offset not supported in PHP strpos(), ignoring
if( ( $pos = strpos( $haystack, $needle ) ) !== false )
{
$left = substr( $haystack, 0, $pos );
return ( $offset > 0 ? $offset : 0 ) + utf8_strlen( $left );
}
return false;
}
/**
* utf8_max( )
*
* Returns the UTF-8 character with the maximum code point in the given data
* @since 1.0
*
* @param mixed $arg A UTF-8 encoded string or an array of such strings
* @return string The character with the highest code point than others
*/
function utf8_max( $arg )
{
if( is_array( $arg ) )
{
$arg = implode( $arg );
}
return utf8_chr( max( utf8_codepoints( $arg ) ) );
}
/**
* utf8_min( )
*
* Returns the UTF-8 character with the minimum code point in the given data
* @since 1.0
*
* @param mixed $arg A UTF-8 encoded string or an array of such strings
* @return string The character with the lowest code point than others
*/
function utf8_min( $arg )
{
if( is_array( $arg ) )
{
$arg = implode( $arg );
}
return utf8_chr( min( utf8_codepoints( $arg ) ) );
}
/**
* utf8_codepoints( )
*
* Accepts a string and returns an array of Unicode Code Points
* @since 1.0
*
* @param mixed $arg A UTF-8 encoded string or an array of such strings
* @param bool $u_style If True, will return Code Points in U+xxxx format,
* default, Code Points will be returned as integers
* @return array The array of code points
*/
function utf8_codepoints( $arg, $u_style = false )
{
if( is_string( $arg ) )
{
$arg = utf8_split( $arg );
}
$arg = array_map( 'utf8_ord', $arg );
if( $u_style )
{
$arg = array_map( 'utf8_int_to_hex', $arg );
}
return $arg;
}
/**
* utf8_int_to_hex( )
*
* Converts Integer to hexadecimal U+xxxx code point representation
* @since 1.0
*
* @param int $int The integer to be converted to hexadecimal code point
* @return string The Code Point, or empty string on failure
*/
function utf8_int_to_hex( $int, $pfix = 'U+' )
{
if( ctype_digit( ( string ) $int ) )
{
$hex = dechex( ( int ) $int );
$hex = ( strlen( $hex ) < 4 ? substr( '0000' . $hex, - 4 ) : $hex );
return $pfix . $hex;
}
return '';
}
/**
* utf8_hex_to_int( )
*
* Opposite to utf8_int_to_hex( )
* Converts hexadecimal U+xxxx code point representation to Integer
* @since 1.0
*
* @param string $str The Hexadecimal Code Point representation
* @return int The Code Point, or 0 on failure
*/
function utf8_hex_to_int( $str )
{
if( preg_match( '/^(?:\\\u|U\+|)([a-z0-9]{4,6})$/i', $str, $match ) )
{
return ( int ) hexdec( $match[ 1 ] );
}
return 0;
}
/**
* utf8_chr_to_hex( )
*
* Get hexadecimal code point (U+xxxx) of a UTF-8 encoded character
* @since 1.0
*
* @param string $chr The input character
* @return string The Code Point encoded as U+xxxx
*/
function utf8_chr_to_hex( $chr, $pfix = 'U+' )
{
return utf8_int_to_hex( utf8_ord( $chr ), $pfix );
}
/**
* utf8_word_count( )
*
* Counts number of words in the UTF-8 string
* @since 1.0
*
* @param string $str The input string
* @return int The number of words in the string
*/
function utf8_word_count( $str )
{
return count( explode( '-', utf8_url_slug( $str ) ) );
}
//Since Version 1.2
/**
* utf8_string( )
*
* Makes a UTF-8 string from Code points
* @since 1.2
*
* @param array $array Integer or Hexadecimal codepoints
* @return string UTF-8 encoded string
*/
function utf8_string( $array )
{
return implode( array_map( 'utf8_chr', $array ) );
}
/**
* utf8_substr_count( )
*
* Count the number of sub string occurances
* @since 1.2
*
* @param string $haystack The string to search in
* @param string $needle The string to search for
* @param int $offset The offset where to start counting
* @param int $length The maximum length after the specified offset to search for the substring.
* @return int number of occurances of $needle
*/
function utf8_substr_count( $haystack, $needle, $offset = 0, $length = NULL )
{
if( $offset || $length )
{
$haystack = utf8_substr( $haystack, $offset, $length );
}
return ( $length === null ? substr_count( $haystack, $needle, $offset ) : substr_count( $haystack, $needle, $offset, $length ) );
}
/**
* is_ascii( )
*
* Checks if a string is 7 bit ASCII
* @since 1.2
*
* @param string $str The string to check
* @return bool True if ASCII, False otherwise
*/
function is_ascii( $str )
{
return ( bool ) ! preg_match( '/[\x80-\xFF]/', $str );
}
/**
* utf8_range( )
*
* Create an array containing a range of UTF-8 characters
* @since 1.2
*
* @param mixed $var1 Numeric or hexadecimal code points, or a UTF-8 character to start from
* @param mixed $var2 Numeric or hexadecimal code points, or a UTF-8 character to end at
* @return array Array of UTF-8 characters
*/
function utf8_range( $var1, $var2 )
{
if( ctype_digit( ( string ) $var1 ) )
{
$start = ( int ) $var1;
}
else if( ! ( $start = ( int ) utf8_hex_to_int( $var1 ) ) )
{
//if not u+0000 style codepoint
if( ! ( $start = utf8_ord( $var1 ) ) )
{
//if not a valid utf8 character
return array();
}
}
if( ctype_digit( ( string ) $var2 ) )
{
$end = ( int ) $var2;
}
else if( ! ( $end = ( int ) utf8_hex_to_int( $var2 ) ) )
{
//if not u+0000 style codepoint
if( ! ( $end = utf8_ord( $var1 ) ) )
{
//if not a valid utf8 character
return array();
}
}
return array_map( 'utf8_chr', range( $start, $end ) );
}
/**
* utf8_hash( )
*
* Creates a random string of UTF-8 characters
* @since 1.2
*
* @param int $len The length of string in characters
* @return string String consisting of random characters
*/
function utf8_hash( $len = 8 )
{
Static $chrs = array();
Static $chrs_len = null;
if( ! $chrs )
{
if( pcre_utf8_support() )
{
$chrs = array_map( 'utf8_chr', range( 48, 0xffff ) );
$chrs = preg_replace( '/[^\p{N}\p{Lu}\p{Ll}]/u', '', $chrs );
$chrs = array_values( array_filter( $chrs ) );
}
else
{
$chrs = array_merge( range( '0', '9' ), range( 'A', 'Z' ), range( 'a', 'z' ) );
}
$chrs_len = count( $chrs );
}
$hash = '';
for(; $len; -- $len )
{
$hash .= $chrs[ mt_rand() % $chrs_len ];
}
return $hash;
}
/**
* utf8_chr_map( )
*
* Applies callback to all characters of a string
* @since 1.2
*
* @param string $callback The callback function
* @param string $str UTF-8 string to run callback on
* @return array The outcome of callback
*/
function utf8_chr_map( $callback, $str )
{
$chrs = utf8_split( $str );
return array_map( $callback, $chars );
}
/**
* utf8_callback( )
*
* @Alias of utf8_chr_map( )
* @since 1.2
*/
function utf8_callback( $callback, $str )
{
return utf8_chr_map( $callback, $str );
}
/**
* utf8_access( )
*
* Returns a single UTF-8 character from string.
* @since 1.2
*
* @param string $str UTF-8 string
* @param int $pos The position of character to return.
* @return string Single Multi-Byte character
*/
function utf8_access( $string, $pos )
{
//return the character at the specified position: $str[1] like functionality
return utf8_substr( $string, $pos, 1 );
}
/**
* utf8_str_sort( )
*
* Sort all characters according to code points
* @since 1.2
*
* @param string $str UTF-8 string
* @param bool $unique Sort unique. If true, repeated characters are ignored
* @param bool $desc If true, will sort characters in reverse code point order.
* @return string String of sorted characters
*/
function utf8_str_sort( $str, $unique = false, $desc = false )
{
$array = utf8_codepoints( $str );
if( $unique )
{
$array = array_flip( array_flip( $array ) );
}
if( $desc )
{
arsort( $array );
}
else
{
asort( $array );
}
return utf8_string( $array );
}
/**
* utf8_strip_tags( )
*
* Strip HTML and PHP tags from a string
* @since 1.2
*
* @param string $str UTF-8 string
* @param string $allowable_tags The tags to allow in the string.
* @return string The stripped string.
*/
function utf8_strip_tags( $string, $allowable_tags = '' )
{
//clean broken utf8
$string = utf8_clean( $string );
return strip_tags( $string, $allowable_tags );
}
//Since Version 1.3
/**
* utf8_str_replace( )
*
* UTF-8 aware replace all occurrances of a string with another string
* @since 1.3
*
* @param mixed $search The value being searched for
* @param mixed $replace value that replaces search values
* @param mixed $subject The string or array being searched and replaced on.
* @param int $count Holds number of replaced needles
* @return mixed string or array with replaced values
*/
function utf8_str_replace( $search, $replace, $subject, &$count = 0 )
{
return str_replace( $search, $replace, $subject, $count );
}
/**
* utf8_str_repeat( )
*
* Repeat a UTF-8 encoded string
* @since 1.3
*
* @param string $input The string to be repeated
* @param int $multiplier Number of times string to be repeated
* @return string Returns the repeated string
*/
function utf8_str_repeat( $string, $multiplier )
{
return str_repeat( $string, $multiplier );
}
/**
* utf8_str_pad( )
*
* Pad a UTF-8 string to given length with another string
* @since 1.3
*
* @param string $input The input string
* @param int $pad_length The length of return string
* @param string $pad_string String to use for padding the input string
* @param int $pad_type can be STR_PAD_RIGHT, STR_PAD_LEFT or STR_PAD_BOTH
* @return string Returns the padded string
*/
function utf8_str_pad( $input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT )
{
$input_length = utf8_strlen( $input );
if( is_int( $pad_length ) && ( $pad_length > 0 ) && ( $pad_length >= $input_length ) )
{
$ps_length = utf8_strlen( $pad_string );
$diff = $pad_length - $input_length;
switch( $pad_type )
{
case STR_PAD_LEFT :
$pre = utf8_str_repeat( $pad_string, ( int ) ceil( $diff / $ps_length ) );
$pre = utf8_substr( $pre, 0, $diff );
$post = '';
break;
case STR_PAD_BOTH :
$pre = utf8_str_repeat( $pad_string, ( int ) ceil( $diff / $ps_length / 2 ) );
$pre = utf8_substr( $pre, 0, ( int ) $diff / 2 );
$post = utf8_str_repeat( $pad_string, ( int ) ceil( $diff / $ps_length / 2 ) );
$post = utf8_substr( $post, 0, ( int ) ceil( $diff / 2 ) );
break;
case STR_PAD_RIGHT :
default :
$post = utf8_str_repeat( $pad_string, ( int ) ceil( $diff / $ps_length ) );
$post = utf8_substr( $post, 0, $diff );
$pre = '';
}
return $pre . $input . $post;
}
return $input;
}
/**
* utf8_strrpos( )
*
* Find position of last occurrence of a char in a UTF-8 string
* @since 1.3
*
* @param string $haystack The string to search in
* @param string $needle The string to search for
* @param int $offset Number of char to ignore from start or end
* @return int THe position of last occurrance of needle
*/
function utf8_strrpos( $haystack, $needle, $offset = 0 )
{
if( ( ( int ) $needle ) === $needle && ( $needle >= 0 ) )
{
$needle = utf8_chr( $needle );
}
$needle = utf8_clean( ( string ) $needle );
$offset = ( int ) $offset;
$haystack = utf8_clean( $haystack );
if( mbstring_loaded() )
{ // mb_strrpos returns wrong position if invalid characters are found in $haystack before $needle
return mb_strrpos( $haystack, $needle, $offset, 'UTF-8' );
}
if( iconv_loaded() && $offset === 0 )
{
// iconv_strrpos is not tolerant to invalid characters
// iconv_strrpos does not accept $offset
return iconv_strrpos( $haystack, $needle, 'UTF-8' );
}
if( $offset > 0 )
{
$haystack = utf8_substr( $haystack, $offset );
}
else if( $offset < 0 )
{
$haystack = utf8_substr( $haystack, 0, $offset );
}
if( ( $pos = strrpos( $haystack, $needle ) ) !== false )
{
$left = substr( $haystack, 0, $pos );
return ( $offset > 0 ? $offset : 0 ) + utf8_strlen( $left );
}
return false;
}
/**
* utf8_remove_duplicates( )
*
* Removes duplicate occurrances of a string in another string
* @since 1.3
*
* @param string $str The base string
* @param string $what String to search for in the base string
* @return string The result string with removed duplicates
*/
function utf8_remove_duplicates( $str, $what = ' ' )
{
if( is_string( $what ) )
{
$what = array( $what );
}
if( is_array( $what ) )
{
foreach( $what as $item )
{
$str = preg_replace( '/(' . preg_quote( $item, '/' ) . ')+/', $item, $str );
}
}
return $str;
}
/**
* utf8_ws( )
*
* Returns an array of Unicode White Space characters
* @since 1.3
*
* @return array An array with numeric code point as key and White Space Character as value
*/
function utf8_ws()
{
Static $white = array(
// Numeric Code Point => UTF-8 Character
0 => "\x0", //NUL Byte
9 => "\x9", //Tab
10 => "\xa", //New Line
11 => "\xb", //Vertical Tab
13 => "\xd", //Carriage Return
32 => "\x20", //Ordinary Space
160 => "\xc2\xa0", //NO-BREAK SPACE
5760 => "\xe1\x9a\x80", //OGHAM SPACE MARK
6158 => "\xe1\xa0\x8e", //MONGOLIAN VOWEL SEPARATOR
8192 => "\xe2\x80\x80", //EN QUAD
8193 => "\xe2\x80\x81", //EM QUAD
8194 => "\xe2\x80\x82", //EN SPACE
8195 => "\xe2\x80\x83", //EM SPACE
8196 => "\xe2\x80\x84", //THREE-PER-EM SPACE
8197 => "\xe2\x80\x85", //FOUR-PER-EM SPACE
8198 => "\xe2\x80\x86", //SIX-PER-EM SPACE
8199 => "\xe2\x80\x87", //FIGURE SPACE
8200 => "\xe2\x80\x88", //PUNCTUATION SPACE
8201 => "\xe2\x80\x89", //THIN SPACE
8202 => "\xe2\x80\x8a", //HAIR SPACE
8232 => "\xe2\x80\xa8", //LINE SEPARATOR
8233 => "\xe2\x80\xa9", //PARAGRAPH SEPARATOR
8239 => "\xe2\x80\xaf", //NARROW NO-BREAK SPACE
8287 => "\xe2\x81\x9f", //MEDIUM MATHEMATICAL SPACE
12288 => "\xe3\x80\x80" );//IDEOGRAPHIC SPACE
return $white;
}
/**
* utf8_trim_util( )
*
* For internal use - Prepares a string and given chars for trim operations
* @since 1.3
*
* @param string $string The string to be trimmed
* @param string $chrs Optional characters to be stripped
*/
function utf8_trim_util( &$string, &$chrs )
{
if( empty( $chrs ) )
{ // No chars to trim specified, get array of whitespace chars:
$chrs = utf8_ws();
}
else if( is_string( $chrs ) )
{ // Split provided chars into array:
$chrs = utf8_split( $chrs );
}
// Make an array where each char to be trimmed has an entry:
$chrs = array_flip( $chrs );
$string = utf8_clean( $string ); //Cleanup is necessary here, or trim functions may break
// echo '$string after clean='.$string;
}
/**
* utf8_trim( )
*
* Strip whitespace or other characters from beginning or end of a UTF-8 string
* @since 1.3
*
* @param string $string The string to be trimmed
* @param string $chrs Optional characters to be stripped
* @return string The trimmed string
*/
function utf8_trim( $string = '', $chrs = '' )
{
if( $string === NULL || $string === '' )
{ // asimo> Don't try to trim a NULL or empty string, otherwise in some cases it will return false instead of ''
return $string;
}
$string = utf8_ltrim( $string, $chrs );
$string = utf8_rtrim( $string, $chrs );
return $string;
}
/**
* utf8_ltrim( )
*
* Strip whitespace or other characters from beginning of a UTF-8 string
* @since 1.3
*
* @param string $string The string to be trimmed
* @param string $chrs Optional characters to be stripped
* @return string The string with unwanted characters stripped from the left
*/
function utf8_ltrim( $string = '', $chrs = '' )
{
// Clean string & prepare array of chars to trim:
utf8_trim_util( $string, $chrs );
$s_look = utf8_split( $string );
$count = 0;
while( isset( $s_look[ $count ] ) && isset( $chrs[ $s_look[ $count ] ] ) )
{
++ $count;
}
// echo "trim count = $count ";
return utf8_substr( $string, $count );
}
/**
* utf8_rtrim( )
*
* Strip whitespace or other characters from end of a UTF-8 string
* @since 1.3
*
* @param string $string The string to be trimmed
* @param string $chrs Optional characters to be stripped
* @return string The string with unwanted characters stripped from the right
*/
function utf8_rtrim( $string = '', $chrs = '' )
{
utf8_trim_util( $string, $chrs );
$s_look = utf8_split( $string );
$len = count( $s_look );
while( $len && isset( $chrs[ $s_look[ $len - 1 ] ] ) )
{
-- $len;
}
return utf8_substr( $string, 0, $len );
}
/**
* utf8_strtolower( )
*
* Make a UTF-8 string Lower Case
* @since 1.3
*
* @param string $str The input string
* @return string The string with all upper case chars turned to lower case
*/
function utf8_strtolower( $str )
{
static $table = null;
if( mbstring_loaded() )
{
//Auto Removes Invalid UTF-8 Byte Sequances
return mb_strtolower( $str, 'UTF-8' );
}
//Fallback
if( empty( $table ) )
{
$table = array_flip( utf8_case_table() );
}
$str = utf8_clean( $str );
return strtr( $str, $table );
}
/**
* utf8_strtoupper( )
*
* Make a UTF-8 string Upper Case
* @since 1.3
*
* @param string $str The input string
* @return string The string with all lower case chars turned to upper case
*/
function utf8_strtoupper( $str )
{
static $table = null;
if( mbstring_loaded() )
{
//Auto Removes Invalid UTF-8 Byte Sequances
return mb_strtoupper( $str, 'UTF-8' );
}
//Fallback
if( empty( $table ) )
{
$table = utf8_case_table();
}
$str = utf8_clean( $str );
return strtr( $str, $table );
}
/**
* utf8_case_table( )
*
* Returns an array of all lower and upper case UTF-8 encoded characters
* @since 1.3
*
* @return array An array with lower case chars as keys and upper chars as values
*/
function utf8_case_table()
{
static $case = array(
//lower => upper
"\xf0\x90\x91\x8f" => "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8e" => "\xf0\x90\x90\xa6", "\xf0\x90\x91\x8d" => "\xf0\x90\x90\xa5", "\xf0\x90\x91\x8c" => "\xf0\x90\x90\xa4", "\xf0\x90\x91\x8b" => "\xf0\x90\x90\xa3", "\xf0\x90\x91\x8a" => "\xf0\x90\x90\xa2",
"\xf0\x90\x91\x89" => "\xf0\x90\x90\xa1", "\xf0\x90\x91\x88" => "\xf0\x90\x90\xa0", "\xf0\x90\x91\x87" => "\xf0\x90\x90\x9f", "\xf0\x90\x91\x86" => "\xf0\x90\x90\x9e", "\xf0\x90\x91\x85" => "\xf0\x90\x90\x9d", "\xf0\x90\x91\x84" => "\xf0\x90\x90\x9c",
"\xf0\x90\x91\x83" => "\xf0\x90\x90\x9b", "\xf0\x90\x91\x82" => "\xf0\x90\x90\x9a", "\xf0\x90\x91\x81" => "\xf0\x90\x90\x99", "\xf0\x90\x91\x80" => "\xf0\x90\x90\x98", "\xf0\x90\x90\xbf" => "\xf0\x90\x90\x97", "\xf0\x90\x90\xbe" => "\xf0\x90\x90\x96",
"\xf0\x90\x90\xbd" => "\xf0\x90\x90\x95", "\xf0\x90\x90\xbc" => "\xf0\x90\x90\x94", "\xf0\x90\x90\xbb" => "\xf0\x90\x90\x93", "\xf0\x90\x90\xba" => "\xf0\x90\x90\x92", "\xf0\x90\x90\xb9" => "\xf0\x90\x90\x91", "\xf0\x90\x90\xb8" => "\xf0\x90\x90\x90",
"\xf0\x90\x90\xb7" => "\xf0\x90\x90\x8f", "\xf0\x90\x90\xb6" => "\xf0\x90\x90\x8e", "\xf0\x90\x90\xb5" => "\xf0\x90\x90\x8d", "\xf0\x90\x90\xb4" => "\xf0\x90\x90\x8c", "\xf0\x90\x90\xb3" => "\xf0\x90\x90\x8b", "\xf0\x90\x90\xb2" => "\xf0\x90\x90\x8a",
"\xf0\x90\x90\xb1" => "\xf0\x90\x90\x89", "\xf0\x90\x90\xb0" => "\xf0\x90\x90\x88", "\xf0\x90\x90\xaf" => "\xf0\x90\x90\x87", "\xf0\x90\x90\xae" => "\xf0\x90\x90\x86", "\xf0\x90\x90\xad" => "\xf0\x90\x90\x85", "\xf0\x90\x90\xac" => "\xf0\x90\x90\x84",
"\xf0\x90\x90\xab" => "\xf0\x90\x90\x83", "\xf0\x90\x90\xaa" => "\xf0\x90\x90\x82", "\xf0\x90\x90\xa9" => "\xf0\x90\x90\x81", "\xf0\x90\x90\xa8" => "\xf0\x90\x90\x80", "\xef\xbd\x9a" => "\xef\xbc\xba", "\xef\xbd\x99" => "\xef\xbc\xb9", "\xef\xbd\x98" => "\xef\xbc\xb8",
"\xef\xbd\x97" => "\xef\xbc\xb7", "\xef\xbd\x96" => "\xef\xbc\xb6", "\xef\xbd\x95" => "\xef\xbc\xb5", "\xef\xbd\x94" => "\xef\xbc\xb4", "\xef\xbd\x93" => "\xef\xbc\xb3", "\xef\xbd\x92" => "\xef\xbc\xb2", "\xef\xbd\x91" => "\xef\xbc\xb1", "\xef\xbd\x90" => "\xef\xbc\xb0",
"\xef\xbd\x8f" => "\xef\xbc\xaf", "\xef\xbd\x8e" => "\xef\xbc\xae", "\xef\xbd\x8d" => "\xef\xbc\xad", "\xef\xbd\x8c" => "\xef\xbc\xac", "\xef\xbd\x8b" => "\xef\xbc\xab", "\xef\xbd\x8a" => "\xef\xbc\xaa", "\xef\xbd\x89" => "\xef\xbc\xa9", "\xef\xbd\x88" => "\xef\xbc\xa8",
"\xef\xbd\x87" => "\xef\xbc\xa7", "\xef\xbd\x86" => "\xef\xbc\xa6", "\xef\xbd\x85" => "\xef\xbc\xa5", "\xef\xbd\x84" => "\xef\xbc\xa4", "\xef\xbd\x83" => "\xef\xbc\xa3", "\xef\xbd\x82" => "\xef\xbc\xa2", "\xef\xbd\x81" => "\xef\xbc\xa1", "\xea\x9e\x8c" => "\xea\x9e\x8b",
"\xea\x9e\x87" => "\xea\x9e\x86", "\xea\x9e\x85" => "\xea\x9e\x84", "\xea\x9e\x83" => "\xea\x9e\x82", "\xea\x9e\x81" => "\xea\x9e\x80", "\xea\x9d\xbf" => "\xea\x9d\xbe", "\xea\x9d\xbc" => "\xea\x9d\xbb", "\xea\x9d\xba" => "\xea\x9d\xb9", "\xea\x9d\xaf" => "\xea\x9d\xae",
"\xea\x9d\xad" => "\xea\x9d\xac", "\xea\x9d\xab" => "\xea\x9d\xaa", "\xea\x9d\xa9" => "\xea\x9d\xa8", "\xea\x9d\xa7" => "\xea\x9d\xa6", "\xea\x9d\xa5" => "\xea\x9d\xa4", "\xea\x9d\xa3" => "\xea\x9d\xa2", "\xea\x9d\xa1" => "\xea\x9d\xa0", "\xea\x9d\x9f" => "\xea\x9d\x9e",
"\xea\x9d\x9d" => "\xea\x9d\x9c", "\xea\x9d\x9b" => "\xea\x9d\x9a", "\xea\x9d\x99" => "\xea\x9d\x98", "\xea\x9d\x97" => "\xea\x9d\x96", "\xea\x9d\x95" => "\xea\x9d\x94", "\xea\x9d\x93" => "\xea\x9d\x92", "\xea\x9d\x91" => "\xea\x9d\x90", "\xea\x9d\x8f" => "\xea\x9d\x8e",
"\xea\x9d\x8d" => "\xea\x9d\x8c", "\xea\x9d\x8b" => "\xea\x9d\x8a", "\xea\x9d\x89" => "\xea\x9d\x88", "\xea\x9d\x87" => "\xea\x9d\x86", "\xea\x9d\x85" => "\xea\x9d\x84", "\xea\x9d\x83" => "\xea\x9d\x82", "\xea\x9d\x81" => "\xea\x9d\x80", "\xea\x9c\xbf" => "\xea\x9c\xbe",
"\xea\x9c\xbd" => "\xea\x9c\xbc", "\xea\x9c\xbb" => "\xea\x9c\xba", "\xea\x9c\xb9" => "\xea\x9c\xb8", "\xea\x9c\xb7" => "\xea\x9c\xb6", "\xea\x9c\xb5" => "\xea\x9c\xb4", "\xea\x9c\xb3" => "\xea\x9c\xb2", "\xea\x9c\xaf" => "\xea\x9c\xae", "\xea\x9c\xad" => "\xea\x9c\xac",
"\xea\x9c\xab" => "\xea\x9c\xaa", "\xea\x9c\xa9" => "\xea\x9c\xa8", "\xea\x9c\xa7" => "\xea\x9c\xa6", "\xea\x9c\xa5" => "\xea\x9c\xa4", "\xea\x9c\xa3" => "\xea\x9c\xa2", "\xea\x9a\x97" => "\xea\x9a\x96", "\xea\x9a\x95" => "\xea\x9a\x94", "\xea\x9a\x93" => "\xea\x9a\x92",
"\xea\x9a\x91" => "\xea\x9a\x90", "\xea\x9a\x8f" => "\xea\x9a\x8e", "\xea\x9a\x8d" => "\xea\x9a\x8c", "\xea\x9a\x8b" => "\xea\x9a\x8a", "\xea\x9a\x89" => "\xea\x9a\x88", "\xea\x9a\x87" => "\xea\x9a\x86", "\xea\x9a\x85" => "\xea\x9a\x84", "\xea\x9a\x83" => "\xea\x9a\x82",
"\xea\x9a\x81" => "\xea\x9a\x80", "\xea\x99\xad" => "\xea\x99\xac", "\xea\x99\xab" => "\xea\x99\xaa", "\xea\x99\xa9" => "\xea\x99\xa8", "\xea\x99\xa7" => "\xea\x99\xa6", "\xea\x99\xa5" => "\xea\x99\xa4", "\xea\x99\xa3" => "\xea\x99\xa2", "\xea\x99\x9f" => "\xea\x99\x9e",
"\xea\x99\x9d" => "\xea\x99\x9c", "\xea\x99\x9b" => "\xea\x99\x9a", "\xea\x99\x99" => "\xea\x99\x98", "\xea\x99\x97" => "\xea\x99\x96", "\xea\x99\x95" => "\xea\x99\x94", "\xea\x99\x93" => "\xea\x99\x92", "\xea\x99\x91" => "\xea\x99\x90", "\xea\x99\x8f" => "\xea\x99\x8e",
"\xea\x99\x8d" => "\xea\x99\x8c", "\xea\x99\x8b" => "\xea\x99\x8a", "\xea\x99\x89" => "\xea\x99\x88", "\xea\x99\x87" => "\xea\x99\x86", "\xea\x99\x85" => "\xea\x99\x84", "\xea\x99\x83" => "\xea\x99\x82", "\xea\x99\x81" => "\xea\x99\x80", "\xe2\xb4\xa5" => "\xe1\x83\x85",
"\xe2\xb4\xa4" => "\xe1\x83\x84", "\xe2\xb4\xa3" => "\xe1\x83\x83", "\xe2\xb4\xa2" => "\xe1\x83\x82", "\xe2\xb4\xa1" => "\xe1\x83\x81", "\xe2\xb4\xa0" => "\xe1\x83\x80", "\xe2\xb4\x9f" => "\xe1\x82\xbf", "\xe2\xb4\x9e" => "\xe1\x82\xbe", "\xe2\xb4\x9d" => "\xe1\x82\xbd",
"\xe2\xb4\x9c" => "\xe1\x82\xbc", "\xe2\xb4\x9b" => "\xe1\x82\xbb", "\xe2\xb4\x9a" => "\xe1\x82\xba", "\xe2\xb4\x99" => "\xe1\x82\xb9", "\xe2\xb4\x98" => "\xe1\x82\xb8", "\xe2\xb4\x97" => "\xe1\x82\xb7", "\xe2\xb4\x96" => "\xe1\x82\xb6", "\xe2\xb4\x95" => "\xe1\x82\xb5",
"\xe2\xb4\x94" => "\xe1\x82\xb4", "\xe2\xb4\x93" => "\xe1\x82\xb3", "\xe2\xb4\x92" => "\xe1\x82\xb2", "\xe2\xb4\x91" => "\xe1\x82\xb1", "\xe2\xb4\x90" => "\xe1\x82\xb0", "\xe2\xb4\x8f" => "\xe1\x82\xaf", "\xe2\xb4\x8e" => "\xe1\x82\xae", "\xe2\xb4\x8d" => "\xe1\x82\xad",
"\xe2\xb4\x8c" => "\xe1\x82\xac", "\xe2\xb4\x8b" => "\xe1\x82\xab", "\xe2\xb4\x8a" => "\xe1\x82\xaa", "\xe2\xb4\x89" => "\xe1\x82\xa9", "\xe2\xb4\x88" => "\xe1\x82\xa8", "\xe2\xb4\x87" => "\xe1\x82\xa7", "\xe2\xb4\x86" => "\xe1\x82\xa6", "\xe2\xb4\x85" => "\xe1\x82\xa5",
"\xe2\xb4\x84" => "\xe1\x82\xa4", "\xe2\xb4\x83" => "\xe1\x82\xa3", "\xe2\xb4\x82" => "\xe1\x82\xa2", "\xe2\xb4\x81" => "\xe1\x82\xa1", "\xe2\xb4\x80" => "\xe1\x82\xa0", "\xe2\xb3\xae" => "\xe2\xb3\xad", "\xe2\xb3\xac" => "\xe2\xb3\xab", "\xe2\xb3\xa3" => "\xe2\xb3\xa2",
"\xe2\xb3\xa1" => "\xe2\xb3\xa0", "\xe2\xb3\x9f" => "\xe2\xb3\x9e", "\xe2\xb3\x9d" => "\xe2\xb3\x9c", "\xe2\xb3\x9b" => "\xe2\xb3\x9a", "\xe2\xb3\x99" => "\xe2\xb3\x98", "\xe2\xb3\x97" => "\xe2\xb3\x96", "\xe2\xb3\x95" => "\xe2\xb3\x94", "\xe2\xb3\x93" => "\xe2\xb3\x92",
"\xe2\xb3\x91" => "\xe2\xb3\x90", "\xe2\xb3\x8f" => "\xe2\xb3\x8e", "\xe2\xb3\x8d" => "\xe2\xb3\x8c", "\xe2\xb3\x8b" => "\xe2\xb3\x8a", "\xe2\xb3\x89" => "\xe2\xb3\x88", "\xe2\xb3\x87" => "\xe2\xb3\x86", "\xe2\xb3\x85" => "\xe2\xb3\x84", "\xe2\xb3\x83" => "\xe2\xb3\x82",
"\xe2\xb3\x81" => "\xe2\xb3\x80", "\xe2\xb2\xbf" => "\xe2\xb2\xbe", "\xe2\xb2\xbd" => "\xe2\xb2\xbc", "\xe2\xb2\xbb" => "\xe2\xb2\xba", "\xe2\xb2\xb9" => "\xe2\xb2\xb8", "\xe2\xb2\xb7" => "\xe2\xb2\xb6", "\xe2\xb2\xb5" => "\xe2\xb2\xb4", "\xe2\xb2\xb3" => "\xe2\xb2\xb2",
"\xe2\xb2\xb1" => "\xe2\xb2\xb0", "\xe2\xb2\xaf" => "\xe2\xb2\xae", "\xe2\xb2\xad" => "\xe2\xb2\xac", "\xe2\xb2\xab" => "\xe2\xb2\xaa", "\xe2\xb2\xa9" => "\xe2\xb2\xa8", "\xe2\xb2\xa7" => "\xe2\xb2\xa6", "\xe2\xb2\xa5" => "\xe2\xb2\xa4", "\xe2\xb2\xa3" => "\xe2\xb2\xa2",
"\xe2\xb2\xa1" => "\xe2\xb2\xa0", "\xe2\xb2\x9f" => "\xe2\xb2\x9e", "\xe2\xb2\x9d" => "\xe2\xb2\x9c", "\xe2\xb2\x9b" => "\xe2\xb2\x9a", "\xe2\xb2\x99" => "\xe2\xb2\x98", "\xe2\xb2\x97" => "\xe2\xb2\x96", "\xe2\xb2\x95" => "\xe2\xb2\x94", "\xe2\xb2\x93" => "\xe2\xb2\x92",
"\xe2\xb2\x91" => "\xe2\xb2\x90", "\xe2\xb2\x8f" => "\xe2\xb2\x8e", "\xe2\xb2\x8d" => "\xe2\xb2\x8c", "\xe2\xb2\x8b" => "\xe2\xb2\x8a", "\xe2\xb2\x89" => "\xe2\xb2\x88", "\xe2\xb2\x87" => "\xe2\xb2\x86", "\xe2\xb2\x85" => "\xe2\xb2\x84", "\xe2\xb2\x83" => "\xe2\xb2\x82",
"\xe2\xb2\x81" => "\xe2\xb2\x80", "\xe2\xb1\xb6" => "\xe2\xb1\xb5", "\xe2\xb1\xb3" => "\xe2\xb1\xb2", "\xe2\xb1\xac" => "\xe2\xb1\xab", "\xe2\xb1\xaa" => "\xe2\xb1\xa9", "\xe2\xb1\xa8" => "\xe2\xb1\xa7", "\xe2\xb1\xa6" => "\xc8\xbe", "\xe2\xb1\xa5" => "\xc8\xba",
"\xe2\xb1\xa1" => "\xe2\xb1\xa0", "\xe2\xb1\x9e" => "\xe2\xb0\xae", "\xe2\xb1\x9d" => "\xe2\xb0\xad", "\xe2\xb1\x9c" => "\xe2\xb0\xac", "\xe2\xb1\x9b" => "\xe2\xb0\xab", "\xe2\xb1\x9a" => "\xe2\xb0\xaa", "\xe2\xb1\x99" => "\xe2\xb0\xa9", "\xe2\xb1\x98" => "\xe2\xb0\xa8",
"\xe2\xb1\x97" => "\xe2\xb0\xa7", "\xe2\xb1\x96" => "\xe2\xb0\xa6", "\xe2\xb1\x95" => "\xe2\xb0\xa5", "\xe2\xb1\x94" => "\xe2\xb0\xa4", "\xe2\xb1\x93" => "\xe2\xb0\xa3", "\xe2\xb1\x92" => "\xe2\xb0\xa2", "\xe2\xb1\x91" => "\xe2\xb0\xa1", "\xe2\xb1\x90" => "\xe2\xb0\xa0",
"\xe2\xb1\x8f" => "\xe2\xb0\x9f", "\xe2\xb1\x8e" => "\xe2\xb0\x9e", "\xe2\xb1\x8d" => "\xe2\xb0\x9d", "\xe2\xb1\x8c" => "\xe2\xb0\x9c", "\xe2\xb1\x8b" => "\xe2\xb0\x9b", "\xe2\xb1\x8a" => "\xe2\xb0\x9a", "\xe2\xb1\x89" => "\xe2\xb0\x99", "\xe2\xb1\x88" => "\xe2\xb0\x98",
"\xe2\xb1\x87" => "\xe2\xb0\x97", "\xe2\xb1\x86" => "\xe2\xb0\x96", "\xe2\xb1\x85" => "\xe2\xb0\x95", "\xe2\xb1\x84" => "\xe2\xb0\x94", "\xe2\xb1\x83" => "\xe2\xb0\x93", "\xe2\xb1\x82" => "\xe2\xb0\x92", "\xe2\xb1\x81" => "\xe2\xb0\x91", "\xe2\xb1\x80" => "\xe2\xb0\x90",
"\xe2\xb0\xbf" => "\xe2\xb0\x8f", "\xe2\xb0\xbe" => "\xe2\xb0\x8e", "\xe2\xb0\xbd" => "\xe2\xb0\x8d", "\xe2\xb0\xbc" => "\xe2\xb0\x8c", "\xe2\xb0\xbb" => "\xe2\xb0\x8b", "\xe2\xb0\xba" => "\xe2\xb0\x8a", "\xe2\xb0\xb9" => "\xe2\xb0\x89", "\xe2\xb0\xb8" => "\xe2\xb0\x88",
"\xe2\xb0\xb7" => "\xe2\xb0\x87", "\xe2\xb0\xb6" => "\xe2\xb0\x86", "\xe2\xb0\xb5" => "\xe2\xb0\x85", "\xe2\xb0\xb4" => "\xe2\xb0\x84", "\xe2\xb0\xb3" => "\xe2\xb0\x83", "\xe2\xb0\xb2" => "\xe2\xb0\x82", "\xe2\xb0\xb1" => "\xe2\xb0\x81", "\xe2\xb0\xb0" => "\xe2\xb0\x80",
"\xe2\x86\x84" => "\xe2\x86\x83", "\xe2\x85\x8e" => "\xe2\x84\xb2", "\xe1\xbf\xb3" => "\xe1\xbf\xbc", "\xe1\xbf\xa5" => "\xe1\xbf\xac", "\xe1\xbf\xa1" => "\xe1\xbf\xa9", "\xe1\xbf\xa0" => "\xe1\xbf\xa8", "\xe1\xbf\x91" => "\xe1\xbf\x99", "\xe1\xbf\x90" => "\xe1\xbf\x98",
"\xe1\xbf\x83" => "\xe1\xbf\x8c", "\xe1\xbe\xbe" => "\xce\x99", "\xe1\xbe\xb3" => "\xe1\xbe\xbc", "\xe1\xbe\xb1" => "\xe1\xbe\xb9", "\xe1\xbe\xb0" => "\xe1\xbe\xb8", "\xe1\xbe\xa7" => "\xe1\xbe\xaf", "\xe1\xbe\xa6" => "\xe1\xbe\xae", "\xe1\xbe\xa5" => "\xe1\xbe\xad",
"\xe1\xbe\xa4" => "\xe1\xbe\xac", "\xe1\xbe\xa3" => "\xe1\xbe\xab", "\xe1\xbe\xa2" => "\xe1\xbe\xaa", "\xe1\xbe\xa1" => "\xe1\xbe\xa9", "\xe1\xbe\xa0" => "\xe1\xbe\xa8", "\xe1\xbe\x97" => "\xe1\xbe\x9f", "\xe1\xbe\x96" => "\xe1\xbe\x9e", "\xe1\xbe\x95" => "\xe1\xbe\x9d",
"\xe1\xbe\x94" => "\xe1\xbe\x9c", "\xe1\xbe\x93" => "\xe1\xbe\x9b", "\xe1\xbe\x92" => "\xe1\xbe\x9a", "\xe1\xbe\x91" => "\xe1\xbe\x99", "\xe1\xbe\x90" => "\xe1\xbe\x98", "\xe1\xbe\x87" => "\xe1\xbe\x8f", "\xe1\xbe\x86" => "\xe1\xbe\x8e", "\xe1\xbe\x85" => "\xe1\xbe\x8d",
"\xe1\xbe\x84" => "\xe1\xbe\x8c", "\xe1\xbe\x83" => "\xe1\xbe\x8b", "\xe1\xbe\x82" => "\xe1\xbe\x8a", "\xe1\xbe\x81" => "\xe1\xbe\x89", "\xe1\xbe\x80" => "\xe1\xbe\x88", "\xe1\xbd\xbd" => "\xe1\xbf\xbb", "\xe1\xbd\xbc" => "\xe1\xbf\xba", "\xe1\xbd\xbb" => "\xe1\xbf\xab",
"\xe1\xbd\xba" => "\xe1\xbf\xaa", "\xe1\xbd\xb9" => "\xe1\xbf\xb9", "\xe1\xbd\xb8" => "\xe1\xbf\xb8", "\xe1\xbd\xb7" => "\xe1\xbf\x9b", "\xe1\xbd\xb6" => "\xe1\xbf\x9a", "\xe1\xbd\xb5" => "\xe1\xbf\x8b", "\xe1\xbd\xb4" => "\xe1\xbf\x8a", "\xe1\xbd\xb3" => "\xe1\xbf\x89",
"\xe1\xbd\xb2" => "\xe1\xbf\x88", "\xe1\xbd\xb1" => "\xe1\xbe\xbb", "\xe1\xbd\xb0" => "\xe1\xbe\xba", "\xe1\xbd\xa7" => "\xe1\xbd\xaf", "\xe1\xbd\xa6" => "\xe1\xbd\xae", "\xe1\xbd\xa5" => "\xe1\xbd\xad", "\xe1\xbd\xa4" => "\xe1\xbd\xac", "\xe1\xbd\xa3" => "\xe1\xbd\xab",
"\xe1\xbd\xa2" => "\xe1\xbd\xaa", "\xe1\xbd\xa1" => "\xe1\xbd\xa9", "\xe1\xbd\xa0" => "\xe1\xbd\xa8", "\xe1\xbd\x97" => "\xe1\xbd\x9f", "\xe1\xbd\x95" => "\xe1\xbd\x9d", "\xe1\xbd\x93" => "\xe1\xbd\x9b", "\xe1\xbd\x91" => "\xe1\xbd\x99", "\xe1\xbd\x85" => "\xe1\xbd\x8d",
"\xe1\xbd\x84" => "\xe1\xbd\x8c", "\xe1\xbd\x83" => "\xe1\xbd\x8b", "\xe1\xbd\x82" => "\xe1\xbd\x8a", "\xe1\xbd\x81" => "\xe1\xbd\x89", "\xe1\xbd\x80" => "\xe1\xbd\x88", "\xe1\xbc\xb7" => "\xe1\xbc\xbf", "\xe1\xbc\xb6" => "\xe1\xbc\xbe", "\xe1\xbc\xb5" => "\xe1\xbc\xbd",
"\xe1\xbc\xb4" => "\xe1\xbc\xbc", "\xe1\xbc\xb3" => "\xe1\xbc\xbb", "\xe1\xbc\xb2" => "\xe1\xbc\xba", "\xe1\xbc\xb1" => "\xe1\xbc\xb9", "\xe1\xbc\xb0" => "\xe1\xbc\xb8", "\xe1\xbc\xa7" => "\xe1\xbc\xaf", "\xe1\xbc\xa6" => "\xe1\xbc\xae", "\xe1\xbc\xa5" => "\xe1\xbc\xad",
"\xe1\xbc\xa4" => "\xe1\xbc\xac", "\xe1\xbc\xa3" => "\xe1\xbc\xab", "\xe1\xbc\xa2" => "\xe1\xbc\xaa", "\xe1\xbc\xa1" => "\xe1\xbc\xa9", "\xe1\xbc\xa0" => "\xe1\xbc\xa8", "\xe1\xbc\x95" => "\xe1\xbc\x9d", "\xe1\xbc\x94" => "\xe1\xbc\x9c", "\xe1\xbc\x93" => "\xe1\xbc\x9b",
"\xe1\xbc\x92" => "\xe1\xbc\x9a", "\xe1\xbc\x91" => "\xe1\xbc\x99", "\xe1\xbc\x90" => "\xe1\xbc\x98", "\xe1\xbc\x87" => "\xe1\xbc\x8f", "\xe1\xbc\x86" => "\xe1\xbc\x8e", "\xe1\xbc\x85" => "\xe1\xbc\x8d", "\xe1\xbc\x84" => "\xe1\xbc\x8c", "\xe1\xbc\x83" => "\xe1\xbc\x8b",
"\xe1\xbc\x82" => "\xe1\xbc\x8a", "\xe1\xbc\x81" => "\xe1\xbc\x89", "\xe1\xbc\x80" => "\xe1\xbc\x88", "\xe1\xbb\xbf" => "\xe1\xbb\xbe", "\xe1\xbb\xbd" => "\xe1\xbb\xbc", "\xe1\xbb\xbb" => "\xe1\xbb\xba", "\xe1\xbb\xb9" => "\xe1\xbb\xb8", "\xe1\xbb\xb7" => "\xe1\xbb\xb6",
"\xe1\xbb\xb5" => "\xe1\xbb\xb4", "\xe1\xbb\xb3" => "\xe1\xbb\xb2", "\xe1\xbb\xb1" => "\xe1\xbb\xb0", "\xe1\xbb\xaf" => "\xe1\xbb\xae", "\xe1\xbb\xad" => "\xe1\xbb\xac", "\xe1\xbb\xab" => "\xe1\xbb\xaa", "\xe1\xbb\xa9" => "\xe1\xbb\xa8", "\xe1\xbb\xa7" => "\xe1\xbb\xa6",
"\xe1\xbb\xa5" => "\xe1\xbb\xa4", "\xe1\xbb\xa3" => "\xe1\xbb\xa2", "\xe1\xbb\xa1" => "\xe1\xbb\xa0", "\xe1\xbb\x9f" => "\xe1\xbb\x9e", "\xe1\xbb\x9d" => "\xe1\xbb\x9c", "\xe1\xbb\x9b" => "\xe1\xbb\x9a", "\xe1\xbb\x99" => "\xe1\xbb\x98", "\xe1\xbb\x97" => "\xe1\xbb\x96",
"\xe1\xbb\x95" => "\xe1\xbb\x94", "\xe1\xbb\x93" => "\xe1\xbb\x92", "\xe1\xbb\x91" => "\xe1\xbb\x90", "\xe1\xbb\x8f" => "\xe1\xbb\x8e", "\xe1\xbb\x8d" => "\xe1\xbb\x8c", "\xe1\xbb\x8b" => "\xe1\xbb\x8a", "\xe1\xbb\x89" => "\xe1\xbb\x88", "\xe1\xbb\x87" => "\xe1\xbb\x86",
"\xe1\xbb\x85" => "\xe1\xbb\x84", "\xe1\xbb\x83" => "\xe1\xbb\x82", "\xe1\xbb\x81" => "\xe1\xbb\x80", "\xe1\xba\xbf" => "\xe1\xba\xbe", "\xe1\xba\xbd" => "\xe1\xba\xbc", "\xe1\xba\xbb" => "\xe1\xba\xba", "\xe1\xba\xb9" => "\xe1\xba\xb8", "\xe1\xba\xb7" => "\xe1\xba\xb6",
"\xe1\xba\xb5" => "\xe1\xba\xb4", "\xe1\xba\xb3" => "\xe1\xba\xb2", "\xe1\xba\xb1" => "\xe1\xba\xb0", "\xe1\xba\xaf" => "\xe1\xba\xae", "\xe1\xba\xad" => "\xe1\xba\xac", "\xe1\xba\xab" => "\xe1\xba\xaa", "\xe1\xba\xa9" => "\xe1\xba\xa8", "\xe1\xba\xa7" => "\xe1\xba\xa6",
"\xe1\xba\xa5" => "\xe1\xba\xa4", "\xe1\xba\xa3" => "\xe1\xba\xa2", "\xe1\xba\xa1" => "\xe1\xba\xa0", "\xe1\xba\x9b" => "\xe1\xb9\xa0", "\xe1\xba\x95" => "\xe1\xba\x94", "\xe1\xba\x93" => "\xe1\xba\x92", "\xe1\xba\x91" => "\xe1\xba\x90", "\xe1\xba\x8f" => "\xe1\xba\x8e",
"\xe1\xba\x8d" => "\xe1\xba\x8c", "\xe1\xba\x8b" => "\xe1\xba\x8a", "\xe1\xba\x89" => "\xe1\xba\x88", "\xe1\xba\x87" => "\xe1\xba\x86", "\xe1\xba\x85" => "\xe1\xba\x84", "\xe1\xba\x83" => "\xe1\xba\x82", "\xe1\xba\x81" => "\xe1\xba\x80", "\xe1\xb9\xbf" => "\xe1\xb9\xbe",
"\xe1\xb9\xbd" => "\xe1\xb9\xbc", "\xe1\xb9\xbb" => "\xe1\xb9\xba", "\xe1\xb9\xb9" => "\xe1\xb9\xb8", "\xe1\xb9\xb7" => "\xe1\xb9\xb6", "\xe1\xb9\xb5" => "\xe1\xb9\xb4", "\xe1\xb9\xb3" => "\xe1\xb9\xb2", "\xe1\xb9\xb1" => "\xe1\xb9\xb0", "\xe1\xb9\xaf" => "\xe1\xb9\xae",
"\xe1\xb9\xad" => "\xe1\xb9\xac", "\xe1\xb9\xab" => "\xe1\xb9\xaa", "\xe1\xb9\xa9" => "\xe1\xb9\xa8", "\xe1\xb9\xa7" => "\xe1\xb9\xa6", "\xe1\xb9\xa5" => "\xe1\xb9\xa4", "\xe1\xb9\xa3" => "\xe1\xb9\xa2", "\xe1\xb9\xa1" => "\xe1\xb9\xa0", "\xe1\xb9\x9f" => "\xe1\xb9\x9e",
"\xe1\xb9\x9d" => "\xe1\xb9\x9c", "\xe1\xb9\x9b" => "\xe1\xb9\x9a", "\xe1\xb9\x99" => "\xe1\xb9\x98", "\xe1\xb9\x97" => "\xe1\xb9\x96", "\xe1\xb9\x95" => "\xe1\xb9\x94", "\xe1\xb9\x93" => "\xe1\xb9\x92", "\xe1\xb9\x91" => "\xe1\xb9\x90", "\xe1\xb9\x8f" => "\xe1\xb9\x8e",
"\xe1\xb9\x8d" => "\xe1\xb9\x8c", "\xe1\xb9\x8b" => "\xe1\xb9\x8a", "\xe1\xb9\x89" => "\xe1\xb9\x88", "\xe1\xb9\x87" => "\xe1\xb9\x86", "\xe1\xb9\x85" => "\xe1\xb9\x84", "\xe1\xb9\x83" => "\xe1\xb9\x82", "\xe1\xb9\x81" => "\xe1\xb9\x80", "\xe1\xb8\xbf" => "\xe1\xb8\xbe",
"\xe1\xb8\xbd" => "\xe1\xb8\xbc", "\xe1\xb8\xbb" => "\xe1\xb8\xba", "\xe1\xb8\xb9" => "\xe1\xb8\xb8", "\xe1\xb8\xb7" => "\xe1\xb8\xb6", "\xe1\xb8\xb5" => "\xe1\xb8\xb4", "\xe1\xb8\xb3" => "\xe1\xb8\xb2", "\xe1\xb8\xb1" => "\xe1\xb8\xb0", "\xe1\xb8\xaf" => "\xe1\xb8\xae",
"\xe1\xb8\xad" => "\xe1\xb8\xac", "\xe1\xb8\xab" => "\xe1\xb8\xaa", "\xe1\xb8\xa9" => "\xe1\xb8\xa8", "\xe1\xb8\xa7" => "\xe1\xb8\xa6", "\xe1\xb8\xa5" => "\xe1\xb8\xa4", "\xe1\xb8\xa3" => "\xe1\xb8\xa2", "\xe1\xb8\xa1" => "\xe1\xb8\xa0", "\xe1\xb8\x9f" => "\xe1\xb8\x9e",
"\xe1\xb8\x9d" => "\xe1\xb8\x9c", "\xe1\xb8\x9b" => "\xe1\xb8\x9a", "\xe1\xb8\x99" => "\xe1\xb8\x98", "\xe1\xb8\x97" => "\xe1\xb8\x96", "\xe1\xb8\x95" => "\xe1\xb8\x94", "\xe1\xb8\x93" => "\xe1\xb8\x92", "\xe1\xb8\x91" => "\xe1\xb8\x90", "\xe1\xb8\x8f" => "\xe1\xb8\x8e",
"\xe1\xb8\x8d" => "\xe1\xb8\x8c", "\xe1\xb8\x8b" => "\xe1\xb8\x8a", "\xe1\xb8\x89" => "\xe1\xb8\x88", "\xe1\xb8\x87" => "\xe1\xb8\x86", "\xe1\xb8\x85" => "\xe1\xb8\x84", "\xe1\xb8\x83" => "\xe1\xb8\x82", "\xe1\xb8\x81" => "\xe1\xb8\x80", "\xe1\xb5\xbd" => "\xe2\xb1\xa3",
"\xe1\xb5\xb9" => "\xea\x9d\xbd", "\xd6\x86" => "\xd5\x96", "\xd6\x85" => "\xd5\x95", "\xd6\x84" => "\xd5\x94", "\xd6\x83" => "\xd5\x93", "\xd6\x82" => "\xd5\x92", "\xd6\x81" => "\xd5\x91", "\xd6\x80" => "\xd5\x90", "\xd5\xbf" => "\xd5\x8f", "\xd5\xbe" => "\xd5\x8e",
"\xd5\xbd" => "\xd5\x8d", "\xd5\xbc" => "\xd5\x8c", "\xd5\xbb" => "\xd5\x8b", "\xd5\xba" => "\xd5\x8a", "\xd5\xb9" => "\xd5\x89", "\xd5\xb8" => "\xd5\x88", "\xd5\xb7" => "\xd5\x87", "\xd5\xb6" => "\xd5\x86", "\xd5\xb5" => "\xd5\x85", "\xd5\xb4" => "\xd5\x84", "\xd5\xb3" => "\xd5\x83",
"\xd5\xb2" => "\xd5\x82", "\xd5\xb1" => "\xd5\x81", "\xd5\xb0" => "\xd5\x80", "\xd5\xaf" => "\xd4\xbf", "\xd5\xae" => "\xd4\xbe", "\xd5\xad" => "\xd4\xbd", "\xd5\xac" => "\xd4\xbc", "\xd5\xab" => "\xd4\xbb", "\xd5\xaa" => "\xd4\xba", "\xd5\xa9" => "\xd4\xb9", "\xd5\xa8" => "\xd4\xb8",
"\xd5\xa7" => "\xd4\xb7", "\xd5\xa6" => "\xd4\xb6", "\xd5\xa5" => "\xd4\xb5", "\xd5\xa4" => "\xd4\xb4", "\xd5\xa3" => "\xd4\xb3", "\xd5\xa2" => "\xd4\xb2", "\xd5\xa1" => "\xd4\xb1", "\xd4\xa5" => "\xd4\xa4", "\xd4\xa3" => "\xd4\xa2", "\xd4\xa1" => "\xd4\xa0", "\xd4\x9f" => "\xd4\x9e",
"\xd4\x9d" => "\xd4\x9c", "\xd4\x9b" => "\xd4\x9a", "\xd4\x99" => "\xd4\x98", "\xd4\x97" => "\xd4\x96", "\xd4\x95" => "\xd4\x94", "\xd4\x93" => "\xd4\x92", "\xd4\x91" => "\xd4\x90", "\xd4\x8f" => "\xd4\x8e", "\xd4\x8d" => "\xd4\x8c", "\xd4\x8b" => "\xd4\x8a", "\xd4\x89" => "\xd4\x88",
"\xd4\x87" => "\xd4\x86", "\xd4\x85" => "\xd4\x84", "\xd4\x83" => "\xd4\x82", "\xd4\x81" => "\xd4\x80", "\xd3\xbf" => "\xd3\xbe", "\xd3\xbd" => "\xd3\xbc", "\xd3\xbb" => "\xd3\xba", "\xd3\xb9" => "\xd3\xb8", "\xd3\xb7" => "\xd3\xb6", "\xd3\xb5" => "\xd3\xb4", "\xd3\xb3" => "\xd3\xb2",
"\xd3\xb1" => "\xd3\xb0", "\xd3\xaf" => "\xd3\xae", "\xd3\xad" => "\xd3\xac", "\xd3\xab" => "\xd3\xaa", "\xd3\xa9" => "\xd3\xa8", "\xd3\xa7" => "\xd3\xa6", "\xd3\xa5" => "\xd3\xa4", "\xd3\xa3" => "\xd3\xa2", "\xd3\xa1" => "\xd3\xa0", "\xd3\x9f" => "\xd3\x9e", "\xd3\x9d" => "\xd3\x9c",
"\xd3\x9b" => "\xd3\x9a", "\xd3\x99" => "\xd3\x98", "\xd3\x97" => "\xd3\x96", "\xd3\x95" => "\xd3\x94", "\xd3\x93" => "\xd3\x92", "\xd3\x91" => "\xd3\x90", "\xd3\x8f" => "\xd3\x80", "\xd3\x8e" => "\xd3\x8d", "\xd3\x8c" => "\xd3\x8b", "\xd3\x8a" => "\xd3\x89", "\xd3\x88" => "\xd3\x87",
"\xd3\x86" => "\xd3\x85", "\xd3\x84" => "\xd3\x83", "\xd3\x82" => "\xd3\x81", "\xd2\xbf" => "\xd2\xbe", "\xd2\xbd" => "\xd2\xbc", "\xd2\xbb" => "\xd2\xba", "\xd2\xb9" => "\xd2\xb8", "\xd2\xb7" => "\xd2\xb6", "\xd2\xb5" => "\xd2\xb4", "\xd2\xb3" => "\xd2\xb2", "\xd2\xb1" => "\xd2\xb0",
"\xd2\xaf" => "\xd2\xae", "\xd2\xad" => "\xd2\xac", "\xd2\xab" => "\xd2\xaa", "\xd2\xa9" => "\xd2\xa8", "\xd2\xa7" => "\xd2\xa6", "\xd2\xa5" => "\xd2\xa4", "\xd2\xa3" => "\xd2\xa2", "\xd2\xa1" => "\xd2\xa0", "\xd2\x9f" => "\xd2\x9e", "\xd2\x9d" => "\xd2\x9c", "\xd2\x9b" => "\xd2\x9a",
"\xd2\x99" => "\xd2\x98", "\xd2\x97" => "\xd2\x96", "\xd2\x95" => "\xd2\x94", "\xd2\x93" => "\xd2\x92", "\xd2\x91" => "\xd2\x90", "\xd2\x8f" => "\xd2\x8e", "\xd2\x8d" => "\xd2\x8c", "\xd2\x8b" => "\xd2\x8a", "\xd2\x81" => "\xd2\x80", "\xd1\xbf" => "\xd1\xbe", "\xd1\xbd" => "\xd1\xbc",
"\xd1\xbb" => "\xd1\xba", "\xd1\xb9" => "\xd1\xb8", "\xd1\xb7" => "\xd1\xb6", "\xd1\xb5" => "\xd1\xb4", "\xd1\xb3" => "\xd1\xb2", "\xd1\xb1" => "\xd1\xb0", "\xd1\xaf" => "\xd1\xae", "\xd1\xad" => "\xd1\xac", "\xd1\xab" => "\xd1\xaa", "\xd1\xa9" => "\xd1\xa8", "\xd1\xa7" => "\xd1\xa6",
"\xd1\xa5" => "\xd1\xa4", "\xd1\xa3" => "\xd1\xa2", "\xd1\xa1" => "\xd1\xa0", "\xd1\x9f" => "\xd0\x8f", "\xd1\x9e" => "\xd0\x8e", "\xd1\x9d" => "\xd0\x8d", "\xd1\x9c" => "\xd0\x8c", "\xd1\x9b" => "\xd0\x8b", "\xd1\x9a" => "\xd0\x8a", "\xd1\x99" => "\xd0\x89", "\xd1\x98" => "\xd0\x88",
"\xd1\x97" => "\xd0\x87", "\xd1\x96" => "\xd0\x86", "\xd1\x95" => "\xd0\x85", "\xd1\x94" => "\xd0\x84", "\xd1\x93" => "\xd0\x83", "\xd1\x92" => "\xd0\x82", "\xd1\x91" => "\xd0\x81", "\xd1\x90" => "\xd0\x80", "\xd1\x8f" => "\xd0\xaf", "\xd1\x8e" => "\xd0\xae", "\xd1\x8d" => "\xd0\xad",
"\xd1\x8c" => "\xd0\xac", "\xd1\x8b" => "\xd0\xab", "\xd1\x8a" => "\xd0\xaa", "\xd1\x89" => "\xd0\xa9", "\xd1\x88" => "\xd0\xa8", "\xd1\x87" => "\xd0\xa7", "\xd1\x86" => "\xd0\xa6", "\xd1\x85" => "\xd0\xa5", "\xd1\x84" => "\xd0\xa4", "\xd1\x83" => "\xd0\xa3", "\xd1\x82" => "\xd0\xa2",
"\xd1\x81" => "\xd0\xa1", "\xd1\x80" => "\xd0\xa0", "\xd0\xbf" => "\xd0\x9f", "\xd0\xbe" => "\xd0\x9e", "\xd0\xbd" => "\xd0\x9d", "\xd0\xbc" => "\xd0\x9c", "\xd0\xbb" => "\xd0\x9b", "\xd0\xba" => "\xd0\x9a", "\xd0\xb9" => "\xd0\x99", "\xd0\xb8" => "\xd0\x98", "\xd0\xb7" => "\xd0\x97",
"\xd0\xb6" => "\xd0\x96", "\xd0\xb5" => "\xd0\x95", "\xd0\xb4" => "\xd0\x94", "\xd0\xb3" => "\xd0\x93", "\xd0\xb2" => "\xd0\x92", "\xd0\xb1" => "\xd0\x91", "\xd0\xb0" => "\xd0\x90", "\xcf\xbb" => "\xcf\xba", "\xcf\xb8" => "\xcf\xb7", "\xcf\xb5" => "\xce\x95", "\xcf\xb2" => "\xcf\xb9",
"\xcf\xb1" => "\xce\xa1", "\xcf\xb0" => "\xce\x9a", "\xcf\xaf" => "\xcf\xae", "\xcf\xad" => "\xcf\xac", "\xcf\xab" => "\xcf\xaa", "\xcf\xa9" => "\xcf\xa8", "\xcf\xa7" => "\xcf\xa6", "\xcf\xa5" => "\xcf\xa4", "\xcf\xa3" => "\xcf\xa2", "\xcf\xa1" => "\xcf\xa0", "\xcf\x9f" => "\xcf\x9e",
"\xcf\x9d" => "\xcf\x9c", "\xcf\x9b" => "\xcf\x9a", "\xcf\x99" => "\xcf\x98", "\xcf\x97" => "\xcf\x8f", "\xcf\x96" => "\xce\xa0", "\xcf\x95" => "\xce\xa6", "\xcf\x91" => "\xce\x98", "\xcf\x90" => "\xce\x92", "\xcf\x8e" => "\xce\x8f", "\xcf\x8d" => "\xce\x8e", "\xcf\x8c" => "\xce\x8c",
"\xcf\x8b" => "\xce\xab", "\xcf\x8a" => "\xce\xaa", "\xcf\x89" => "\xce\xa9", "\xcf\x88" => "\xce\xa8", "\xcf\x87" => "\xce\xa7", "\xcf\x86" => "\xce\xa6", "\xcf\x85" => "\xce\xa5", "\xcf\x84" => "\xce\xa4", "\xcf\x83" => "\xce\xa3", "\xcf\x82" => "\xce\xa3", "\xcf\x81" => "\xce\xa1",
"\xcf\x80" => "\xce\xa0", "\xce\xbf" => "\xce\x9f", "\xce\xbe" => "\xce\x9e", "\xce\xbd" => "\xce\x9d", "\xce\xbc" => "\xce\x9c", "\xce\xbb" => "\xce\x9b", "\xce\xba" => "\xce\x9a", "\xce\xb9" => "\xce\x99", "\xce\xb8" => "\xce\x98", "\xce\xb7" => "\xce\x97", "\xce\xb6" => "\xce\x96",
"\xce\xb5" => "\xce\x95", "\xce\xb4" => "\xce\x94", "\xce\xb3" => "\xce\x93", "\xce\xb2" => "\xce\x92", "\xce\xb1" => "\xce\x91", "\xce\xaf" => "\xce\x8a", "\xce\xae" => "\xce\x89", "\xce\xad" => "\xce\x88", "\xce\xac" => "\xce\x86", "\xcd\xbd" => "\xcf\xbf", "\xcd\xbc" => "\xcf\xbe",
"\xcd\xbb" => "\xcf\xbd", "\xcd\xb7" => "\xcd\xb6", "\xcd\xb3" => "\xcd\xb2", "\xcd\xb1" => "\xcd\xb0", "\xca\x92" => "\xc6\xb7", "\xca\x8c" => "\xc9\x85", "\xca\x8b" => "\xc6\xb2", "\xca\x8a" => "\xc6\xb1", "\xca\x89" => "\xc9\x84", "\xca\x88" => "\xc6\xae", "\xca\x83" => "\xc6\xa9",
"\xca\x80" => "\xc6\xa6", "\xc9\xbd" => "\xe2\xb1\xa4", "\xc9\xb5" => "\xc6\x9f", "\xc9\xb2" => "\xc6\x9d", "\xc9\xb1" => "\xe2\xb1\xae", "\xc9\xaf" => "\xc6\x9c", "\xc9\xab" => "\xe2\xb1\xa2", "\xc9\xa9" => "\xc6\x96", "\xc9\xa8" => "\xc6\x97", "\xc9\xa5" => "\xea\x9e\x8d",
"\xc9\xa3" => "\xc6\x94", "\xc9\xa0" => "\xc6\x93", "\xc9\x9b" => "\xc6\x90", "\xc9\x99" => "\xc6\x8f", "\xc9\x97" => "\xc6\x8a", "\xc9\x96" => "\xc6\x89", "\xc9\x94" => "\xc6\x86", "\xc9\x93" => "\xc6\x81", "\xc9\x92" => "\xe2\xb1\xb0", "\xc9\x91" => "\xe2\xb1\xad",
"\xc9\x90" => "\xe2\xb1\xaf", "\xc9\x8f" => "\xc9\x8e", "\xc9\x8d" => "\xc9\x8c", "\xc9\x8b" => "\xc9\x8a", "\xc9\x89" => "\xc9\x88", "\xc9\x87" => "\xc9\x86", "\xc9\x82" => "\xc9\x81", "\xc9\x80" => "\xe2\xb1\xbf", "\xc8\xbf" => "\xe2\xb1\xbe", "\xc8\xbc" => "\xc8\xbb",
"\xc8\xb3" => "\xc8\xb2", "\xc8\xb1" => "\xc8\xb0", "\xc8\xaf" => "\xc8\xae", "\xc8\xad" => "\xc8\xac", "\xc8\xab" => "\xc8\xaa", "\xc8\xa9" => "\xc8\xa8", "\xc8\xa7" => "\xc8\xa6", "\xc8\xa5" => "\xc8\xa4", "\xc8\xa3" => "\xc8\xa2", "\xc8\x9f" => "\xc8\x9e", "\xc8\x9d" => "\xc8\x9c",
"\xc8\x9b" => "\xc8\x9a", "\xc8\x99" => "\xc8\x98", "\xc8\x97" => "\xc8\x96", "\xc8\x95" => "\xc8\x94", "\xc8\x93" => "\xc8\x92", "\xc8\x91" => "\xc8\x90", "\xc8\x8f" => "\xc8\x8e", "\xc8\x8d" => "\xc8\x8c", "\xc8\x8b" => "\xc8\x8a", "\xc8\x89" => "\xc8\x88", "\xc8\x87" => "\xc8\x86",
"\xc8\x85" => "\xc8\x84", "\xc8\x83" => "\xc8\x82", "\xc8\x81" => "\xc8\x80", "\xc7\xbf" => "\xc7\xbe", "\xc7\xbd" => "\xc7\xbc", "\xc7\xbb" => "\xc7\xba", "\xc7\xb9" => "\xc7\xb8", "\xc7\xb5" => "\xc7\xb4", "\xc7\xb3" => "\xc7\xb2", "\xc7\xaf" => "\xc7\xae", "\xc7\xad" => "\xc7\xac",
"\xc7\xab" => "\xc7\xaa", "\xc7\xa9" => "\xc7\xa8", "\xc7\xa7" => "\xc7\xa6", "\xc7\xa5" => "\xc7\xa4", "\xc7\xa3" => "\xc7\xa2", "\xc7\xa1" => "\xc7\xa0", "\xc7\x9f" => "\xc7\x9e", "\xc7\x9d" => "\xc6\x8e", "\xc7\x9c" => "\xc7\x9b", "\xc7\x9a" => "\xc7\x99", "\xc7\x98" => "\xc7\x97",
"\xc7\x96" => "\xc7\x95", "\xc7\x94" => "\xc7\x93", "\xc7\x92" => "\xc7\x91", "\xc7\x90" => "\xc7\x8f", "\xc7\x8e" => "\xc7\x8d", "\xc7\x8c" => "\xc7\x8b", "\xc7\x89" => "\xc7\x88", "\xc7\x86" => "\xc7\x85", "\xc6\xbf" => "\xc7\xb7", "\xc6\xbd" => "\xc6\xbc", "\xc6\xb9" => "\xc6\xb8",
"\xc6\xb6" => "\xc6\xb5", "\xc6\xb4" => "\xc6\xb3", "\xc6\xb0" => "\xc6\xaf", "\xc6\xad" => "\xc6\xac", "\xc6\xa8" => "\xc6\xa7", "\xc6\xa5" => "\xc6\xa4", "\xc6\xa3" => "\xc6\xa2", "\xc6\xa1" => "\xc6\xa0", "\xc6\x9e" => "\xc8\xa0", "\xc6\x9a" => "\xc8\xbd", "\xc6\x99" => "\xc6\x98",
"\xc6\x95" => "\xc7\xb6", "\xc6\x92" => "\xc6\x91", "\xc6\x8c" => "\xc6\x8b", "\xc6\x88" => "\xc6\x87", "\xc6\x85" => "\xc6\x84", "\xc6\x83" => "\xc6\x82", "\xc6\x80" => "\xc9\x83", "\xc5\xbf" => "\x53", "\xc5\xbe" => "\xc5\xbd", "\xc5\xbc" => "\xc5\xbb", "\xc5\xba" => "\xc5\xb9",
"\xc5\xb7" => "\xc5\xb6", "\xc5\xb5" => "\xc5\xb4", "\xc5\xb3" => "\xc5\xb2", "\xc5\xb1" => "\xc5\xb0", "\xc5\xaf" => "\xc5\xae", "\xc5\xad" => "\xc5\xac", "\xc5\xab" => "\xc5\xaa", "\xc5\xa9" => "\xc5\xa8", "\xc5\xa7" => "\xc5\xa6", "\xc5\xa5" => "\xc5\xa4", "\xc5\xa3" => "\xc5\xa2",
"\xc5\xa1" => "\xc5\xa0", "\xc5\x9f" => "\xc5\x9e", "\xc5\x9d" => "\xc5\x9c", "\xc5\x9b" => "\xc5\x9a", "\xc5\x99" => "\xc5\x98", "\xc5\x97" => "\xc5\x96", "\xc5\x95" => "\xc5\x94", "\xc5\x93" => "\xc5\x92", "\xc5\x91" => "\xc5\x90", "\xc5\x8f" => "\xc5\x8e", "\xc5\x8d" => "\xc5\x8c",
"\xc5\x8b" => "\xc5\x8a", "\xc5\x88" => "\xc5\x87", "\xc5\x86" => "\xc5\x85", "\xc5\x84" => "\xc5\x83", "\xc5\x82" => "\xc5\x81", "\xc5\x80" => "\xc4\xbf", "\xc4\xbe" => "\xc4\xbd", "\xc4\xbc" => "\xc4\xbb", "\xc4\xba" => "\xc4\xb9", "\xc4\xb7" => "\xc4\xb6", "\xc4\xb5" => "\xc4\xb4",
"\xc4\xb3" => "\xc4\xb2", "\xc4\xb1" => "\x49", "\xc4\xaf" => "\xc4\xae", "\xc4\xad" => "\xc4\xac", "\xc4\xab" => "\xc4\xaa", "\xc4\xa9" => "\xc4\xa8", "\xc4\xa7" => "\xc4\xa6", "\xc4\xa5" => "\xc4\xa4", "\xc4\xa3" => "\xc4\xa2", "\xc4\xa1" => "\xc4\xa0", "\xc4\x9f" => "\xc4\x9e",
"\xc4\x9d" => "\xc4\x9c", "\xc4\x9b" => "\xc4\x9a", "\xc4\x99" => "\xc4\x98", "\xc4\x97" => "\xc4\x96", "\xc4\x95" => "\xc4\x94", "\xc4\x93" => "\xc4\x92", "\xc4\x91" => "\xc4\x90", "\xc4\x8f" => "\xc4\x8e", "\xc4\x8d" => "\xc4\x8c", "\xc4\x8b" => "\xc4\x8a", "\xc4\x89" => "\xc4\x88",
"\xc4\x87" => "\xc4\x86", "\xc4\x85" => "\xc4\x84", "\xc4\x83" => "\xc4\x82", "\xc4\x81" => "\xc4\x80", "\xc3\xbf" => "\xc5\xb8", "\xc3\xbe" => "\xc3\x9e", "\xc3\xbd" => "\xc3\x9d", "\xc3\xbc" => "\xc3\x9c", "\xc3\xbb" => "\xc3\x9b", "\xc3\xba" => "\xc3\x9a", "\xc3\xb9" => "\xc3\x99",
"\xc3\xb8" => "\xc3\x98", "\xc3\xb6" => "\xc3\x96", "\xc3\xb5" => "\xc3\x95", "\xc3\xb4" => "\xc3\x94", "\xc3\xb3" => "\xc3\x93", "\xc3\xb2" => "\xc3\x92", "\xc3\xb1" => "\xc3\x91", "\xc3\xb0" => "\xc3\x90", "\xc3\xaf" => "\xc3\x8f", "\xc3\xae" => "\xc3\x8e", "\xc3\xad" => "\xc3\x8d",
"\xc3\xac" => "\xc3\x8c", "\xc3\xab" => "\xc3\x8b", "\xc3\xaa" => "\xc3\x8a", "\xc3\xa9" => "\xc3\x89", "\xc3\xa8" => "\xc3\x88", "\xc3\xa7" => "\xc3\x87", "\xc3\xa6" => "\xc3\x86", "\xc3\xa5" => "\xc3\x85", "\xc3\xa4" => "\xc3\x84", "\xc3\xa3" => "\xc3\x83", "\xc3\xa2" => "\xc3\x82",
"\xc3\xa1" => "\xc3\x81", "\xc3\xa0" => "\xc3\x80", "\xc2\xb5" => "\xce\x9c", "\x7a" => "\x5a", "\x79" => "\x59", "\x78" => "\x58", "\x77" => "\x57", "\x76" => "\x56", "\x75" => "\x55", "\x74" => "\x54", "\x73" => "\x53", "\x72" => "\x52", "\x71" => "\x51", "\x70" => "\x50",
"\x6f" => "\x4f", "\x6e" => "\x4e", "\x6d" => "\x4d", "\x6c" => "\x4c", "\x6b" => "\x4b", "\x6a" => "\x4a", "\x69" => "\x49", "\x68" => "\x48", "\x67" => "\x47", "\x66" => "\x46", "\x65" => "\x45", "\x64" => "\x44", "\x63" => "\x43", "\x62" => "\x42", "\x61" => "\x41" );
return $case;
}
/**
* mbstring_loaded( )
*
* Checks whether mbstring is available on the server
* @since 1.3
*
* @return bool True if available, False otherwise
*/
function mbstring_loaded()
{
static $flag = null;
if( $flag === null )
{
// To disable using the mb_string extension please uncomment the next line
// $flag = false; return;
$flag = extension_loaded( 'mbstring' );
if( $flag )
{ // mbstring is loaded, set encoding to "UTF-8"
mb_internal_encoding( "UTF-8" );
mb_regex_encoding( "UTF-8" );
}
}
return $flag;
}
/**
* iconv_loaded( )
*
* Checks whether iconv is available on the server
* @since 1.3
*
* @return bool True if available, False otherwise
*/
function iconv_loaded()
{
static $flag = null;
if( $flag === null )
{
// To disable using the iconv extension please uncomment the next line
// $flag = false; return;
$flag = extension_loaded( 'iconv' );
if( $flag && version_compare( phpversion(), '5.6', '<' ) )
{ // iconv is loaded and version < 5.6 set encodings to "UTF-8"
// in PHP version > 5.6 these settings are deprecated
iconv_set_encoding( "internal_encoding", "UTF-8" );
iconv_set_encoding( "input_encoding", "UTF-8" );
iconv_set_encoding( "output_encoding", "UTF-8" );
}
}
return $flag;
}
/**
* utf8_ucfirst( )
*
* Makes string's first char Uppercase
* @since 1.3
*
* @param string $str The input string
* @return string The resulting string
*/
function utf8_ucfirst( $str )
{
return utf8_strtoupper( utf8_substr( $str, 0, 1 ) ) . utf8_substr( $str, 1 );
}
/**
* utf8_lcfirst( )
*
* Makes string's first char Lowercase
* @since 1.3
*
* @param string $str The input string
* @return string The resulting string
*/
function utf8_lcfirst( $str )
{
return utf8_strtolower( utf8_substr( $str, 0, 1 ) ) . utf8_substr( $str, 1 );
}
/**
* utf8_ucwords( )
*
* Uppercase the first character of each word in a string
* @since 1.3
*
* @param string $str The input string
* @return string The resulting string
*/
function utf8_ucwords( $str )
{
foreach( utf8_ws() as $ws )
{
$pos = - 1;
while( true )
{
if( ( $pos = utf8_strpos( $str, $ws, $pos + 1 ) ) === false )
{
break;
}
$str = utf8_substr( $str, 0, $pos + 1 ) . utf8_strtoupper( utf8_substr( $str, $pos + 1, 1 ) ) . utf8_substr( $str, $pos + 2 );
}
}
return utf8_ucfirst( $str );
}
/**
* utf8_stripos( )
*
* Find position of first occurrence of a case-insensitive string
* @since 1.3
*
* @param string $haystack The string to look in
* @param string $needle The string to look for
* @param int $offset (Optional) Number of characters to ignore in the begining
* @return int The position of needle
*/
function utf8_stripos( $haystack, $needle, $offset = 0 )
{
return utf8_strpos( utf8_strtolower( $haystack ), utf8_strtolower( $needle ), $offset );
}
/**
* utf8_strripos( )
*
* Find position of last occurrence of a case-insensitive string
* @since 1.3
*
* @param string $haystack The string to look in
* @param string $needle The string to look for
* @param int $offset (Optional) Number of characters to ignore in the begining or end
* @return int The position of offset
*/
function utf8_strripos( $haystack, $needle, $offset = 0 )
{
return utf8_strrpos( utf8_strtolower( $haystack ), utf8_strtolower( $needle ), $offset );
}
?>