<?php


/**
 * Клас 'i18n_Charset' - Кункции за работа с кодови таблици за символи
 *
 * Канонизиране, откриване, конвертиране
 *
 *
 * @category  vendors
 * @package   i18n
 *
 * @author    Milen Georgiev <milen@download.bg>
 * @copyright 2006 - 2012 Experta OOD
 * @license   GPL 3
 *
 * @since     v 0.1
 */
class i18n_Charset extends core_MVC
{
    /**
     *  Масив с ключове - алиас-и на чар сетове и стойности - официални имена на чар сетове
     */
    public static $charsetsMatchs = array(
        'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE' => 'EUC-JP', 'CSISO159JISX02121990' => 'JIS_X0212', 'CSEUCPKDFMTJAPANESE' => 'EUC-JP',
        'CSHALFWIDTHKATAKANA' => 'JIS_X0201', 'CSPC850MULTILINGUAL' => 'CP850', 'CSISOLATINCYRILLIC' => 'ISO-8859-5',
        'JIS_C6220-1969-RO' => 'JIS_C6220-1969-RO', 'UNICODE-1-1-UTF-7' => 'UTF-7', 'CSISO14JISC6220RO' => 'JIS_C6220-1969-RO',
        'CSISOLATINARABIC' => 'ISO-8859-6', 'GEORGIAN-ACADEMY' => 'GEORGIAN-ACADEMY', 'ISO_646.IRV:1991' => 'US-ASCII',
        'ISO_8859-10:1992' => 'ISO-8859-10', 'CSISOLATINHEBREW' => 'ISO-8859-8', 'JIS_X0212.1990-0' => 'JIS_X0212',
        'ISO_8859-15:1998' => 'ISO-8859-15', 'ISO_8859-14:1998' => 'ISO-8859-14', 'MACCENTRALEUROPE' => 'MACCENTRALEUROPE',
        'ISO_8859-16:2000' => 'ISO-8859-16', 'ISO_8859-7:1987' => 'ISO-8859-7', 'CSUNICODE11UTF7' => 'UTF-7',
        'JISX0208.1983-0' => 'JIS_X0208', 'JISX0212.1990-0' => 'JIS_X0212', 'CSISO87JISX0208' => 'JIS_X0208',
        'CSISOLATINGREEK' => 'ISO-8859-7', 'ISO646.1991-IRV' => 'US-ASCII', 'ISO_8859-9:1989' => 'ISO-8859-9',
        'JISX0208.1990-0' => 'JIS_X0208', 'ISO-10646-UCS-2' => 'UCS-2', 'ISO_8859-1:1987' => 'ISO-8859-1', 'ISO-2022-CN-EXT' => 'ISO-2022-CN-EXT',
        'ISO_8859-8:1988' => 'ISO-8859-8', 'CSISO58GB231280' => 'GB_2312-80', 'ISO_8859-3:1988' => 'ISO-8859-3',
        'TCVN5712-1:1993' => 'TCVN', 'ISO_8859-2:1987' => 'ISO-8859-2', 'ISO_8859-6:1987' => 'ISO-8859-6', 'ISO_8859-4:1988' => 'ISO-8859-4',
        'ISO-10646-UCS-4' => 'UCS-4', 'JISX0201.1976-0' => 'JIS_X0201', 'ISO_8859-5:1988' => 'ISO-8859-5', 'CN-GB-ISOIR165' => 'ISO-IR-165',
        'KS_C_5601-1989' => 'EUC-KR', 'KSC5601.1987-0' => 'KSC_5601', 'KS_C_5601-1987' => 'CP949', 'UCS-4-INTERNAL' => 'UCS-4-INTERNAL',
        'JIS_X0208-1983' => 'JIS_X0208', 'ANSI_X3.4-1968' => 'US-ASCII', 'JIS_X0212-1990' => 'JIS_X0212', 'JIS_X0208-1990' => 'JIS_X0208',
        'UCS-2-INTERNAL' => 'UCS-2-INTERNAL', 'TIS620.2533-0' => 'TIS-620', 'ISO-2022-JP-2' => 'ISO-2022-JP-2',
        'TIS620.2529-1' => 'TIS-620', 'CSKSC56011987' => 'KSC_5601', 'UNICODELITTLE' => 'UCS-2LE', 'GB2312.1980-0' => 'GB_2312-80',
        'ISO-2022-JP-1' => 'ISO-2022-JP-1', 'TIS620.2533-1' => 'TIS-620', 'UCS-4-SWAPPED' => 'UCS-4-SWAPPED',
        'JISX0201-1976' => 'JIS_X0201', 'UCS-2-SWAPPED' => 'UCS-2-SWAPPED', 'CSISO57GB1988' => 'GB_1988-80',
        'KSX1001:1992' => 'KSC_5601', 'WINDOWS-874' => 'CP874', 'CSISOLATIN5' => 'ISO-8859-9', 'GEORGIAN-PS' => 'GEORGIAN-PS',
        'CSISOLATIN1' => 'ISO-8859-1', 'MACCROATIAN' => 'MACCROATIAN', 'CSISOLATIN3' => 'ISO-8859-3', 'ISO-2022-CN' => 'ISO-2022-CN',
        'CSISO2022CN' => 'ISO-2022-CN', 'VISCII1.1-1' => 'VISCII', 'CSMACINTOSH' => 'MACROMAN', 'CSISOLATIN2' => 'ISO-8859-2',
        'MACCYRILLIC' => 'MACCYRILLIC', 'CSISOLATIN4' => 'ISO-8859-4', 'ISO-2022-JP' => 'ISO-2022-JP', 'CSISO2022KR' => 'ISO-2022-KR',
        'ISO-2022-KR' => 'ISO-2022-KR', 'CSISOLATIN6' => 'ISO-8859-10', 'UNICODE-1-1' => 'UCS-2BE', 'CSUNICODE11' => 'UCS-2BE',
        'ISO-8859-13' => 'ISO-8859-13', 'ISO-8859-16' => 'ISO-8859-16', 'ISO-8859-14' => 'ISO-8859-14', 'ISO-8859-10' => 'ISO-8859-10',
        'ISO-8859-15' => 'ISO-8859-15', 'ISO-IR-157' => 'ISO-8859-10', 'ISO-IR-138' => 'ISO-8859-8', 'ISO_8859-8' => 'ISO-8859-8',
        'ISO-IR-159' => 'JIS_X0212', 'ISO_8859-7' => 'ISO-8859-7', 'ISO-8859-7' => 'ISO-8859-7', 'GB_1988-80' => 'GB_1988-80',
        'ISO-IR-179' => 'ISO-8859-13', 'ISO-IR-126' => 'ISO-8859-7', 'ISO-8859-9' => 'ISO-8859-9', 'ISO8859-10' => 'ISO-8859-10',
        'ISO-8859-8' => 'ISO-8859-8', 'ISO_8859-1' => 'ISO-8859-1', 'MACUKRAINE' => 'MACUKRAINE', 'MACROMANIA' => 'MACROMANIA',
        'MACTURKISH' => 'MACTURKISH', 'CSHPROMAN8' => 'HP-ROMAN8', 'ISO-IR-166' => 'TIS-620', 'IBM-CP1133' => 'CP1133',
        'MACICELAND' => 'MACICELAND', 'HZ-GB-2312' => 'HZ', 'ISO-IR-127' => 'ISO-8859-6', 'ISO-IR-148' => 'ISO-8859-9',
        'WINDOWS-BG' => 'CP1251', 'WINBALTRIM' => 'CP1257', 'TCVN5712-1' => 'TCVN', 'UNICODEBIG' => 'UCS-2BE',
        'ISO_8859-9' => 'ISO-8859-9', 'CSSHIFTJIS' => 'SJIS', 'ISO_8859-3' => 'ISO-8859-3', 'ISO-8859-3' => 'ISO-8859-3',
        'ISO-IR-165' => 'ISO-IR-165', 'ISO-IR-203' => 'ISO-8859-15', 'ISO-8859-4' => 'ISO-8859-4', 'ISO-IR-199' => 'ISO-8859-14',
        'ISO_8859-4' => 'ISO-8859-4', 'ISO-IR-144' => 'ISO-8859-5', 'ISO-IR-149' => 'KSC_5601', 'ISO-IR-101' => 'ISO-8859-2',
        'ISO-IR-226' => 'ISO-8859-16', 'ISO-8859-5' => 'ISO-8859-5', 'ISO_8859-2' => 'ISO-8859-2', 'ISO_8859-5' => 'ISO-8859-5',
        'ISO-8859-2' => 'ISO-8859-2', 'ISO-IR-110' => 'ISO-8859-4', 'ISO-IR-109' => 'ISO-8859-3', 'ISO-8859-6' => 'ISO-8859-6',
        'GB_2312-80' => 'GB_2312-80', 'ISO-IR-100' => 'ISO-8859-1', 'ISO-8859-1' => 'ISO-8859-1', 'ISO_8859-6' => 'ISO-8859-6',
        'ISO646-CN' => 'GB_1988-80', 'ISO-IR-87' => 'JIS_X0208', 'TCVN-5712' => 'TCVN', 'MACINTOSH' => 'MACROMAN',
        'SHIFT_JIS' => 'SJIS', 'ISO-IR-14' => 'JIS_C6220-1969-RO', 'JIS_X0201' => 'JIS_X0201', 'ISO646-JP' => 'JIS_C6220-1969-RO',
        'ISO646-US' => 'US-ASCII', 'JIS_X0208' => 'JIS_X0208', 'ISO-IR-57' => 'GB_1988-80', 'ISO2022KR' => 'ISO-2022-KR',
        'ISO8859-1' => 'ISO-8859-1', 'ISO2022JP' => 'ISO-2022-JP', 'BIG5HKSCS' => 'BIG5HKSCS', 'MACHEBREW' => 'MACHEBREW',
        'ISO8859-8' => 'ISO-8859-8', 'MACARABIC' => 'MACARABIC', 'HP-ROMAN8' => 'HP-ROMAN8', 'ISO2022CN' => 'ISO-2022-CN',
        'JIS_X0212' => 'JIS_X0212', 'ISO8859-9' => 'ISO-8859-9', 'SHIFT-JIS' => 'SJIS', 'ISO-IR-58' => 'GB_2312-80',
        'MULELAO-1' => 'MULELAO-1', 'ARMSCII-8' => 'ARMSCII-8', 'TIS620-0' => 'TIS-620', 'CSVISCII' => 'VISCII',
        'MACGREEK' => 'MACGREEK', 'NEXTSTEP' => 'NEXTSTEP', 'MACROMAN' => 'MACROMAN', 'CSIBM866' => 'CP866',
        'ISO-IR-6' => 'US-ASCII', 'CYRILLIC' => 'ISO-8859-5', 'US-ASCII' => 'US-ASCII', 'UTF-16LE' => 'UTF-16LE',
        'UTF-16BE' => 'UTF-16BE', 'KSC_5601' => 'KSC_5601', 'MS_KANJI' => 'SJIS', 'ELOT_928' => 'ISO-8859-7',
        'ECMA-114' => 'ISO-8859-6', 'ASMO-708' => 'ISO-8859-6', 'ECMA-118' => 'ISO-8859-7', 'BIG-FIVE' => 'BIG5',
        'CSGB2312' => 'EUC-CN', 'MS-GREEK' => 'CP1253', 'CHINESE' => 'GB_2312-80', '8859-13' => 'ISO-8859-13',
        'MACTHAI' => 'MACTHAI', '8859-15' => 'ISO-8859-15', 'WCHAR_T' => 'WCHAR_T', 'CSEUCKR' => 'EUC-KR', 'MS-ANSI' => 'CP1252',
        'JIS0212' => 'JIS_X0212', '2022JP2' => 'ISO-2022-JP-2', 'UCS-2LE' => 'UCS-2LE', 'UCS-4BE' => 'UCS-4BE',
        'GB18030' => 'GB18030', 'TIS-620' => 'TIS-620', 'MS-HEBR' => 'CP1255', '8859-14' => 'ISO-8859-14', '8859-16' => 'ISO-8859-16',
        '8859-10' => 'ISO-8859-10', 'BIGFIVE' => 'BIG5', 'UCS-4LE' => 'UCS-4LE', 'CN-BIG5' => 'BIG5', '2022JP1' => 'ISO-2022-JP-1',
        'UCS-2BE' => 'UCS-2BE', 'JIS0201' => 'JIS_X0201', 'CSEUCTW' => 'EUC-TW', 'MS-CYRL' => 'CP1251', 'CSASCII' => 'US-ASCII',
        'JIS0208' => 'JIS_X0208', 'CSKOI8R' => 'KOI8-R', 'MS-TURK' => 'CP1254', 'ASCII-8' => 'ASCII-8', 'MS-ARAB' => 'CP1256',
        'KOI8-RU' => 'KOI8-RU', 'VISCII' => 'VISCII', 'EUC_JP' => 'EUC-JP', 'GB2312' => 'EUC-CN', 'KOREAN' => 'KSC_5601',
        'EUC-CN' => 'EUC-CN', 'EUC-JP' => 'EUC-JP', 'EUC_CN' => 'EUC-CN', '2022JP' => 'ISO-2022-JP', 'KOI8-R' => 'KOI8-R',
        '8859_3' => 'ISO-8859-3', 'LATIN4' => 'ISO-8859-4', '8859-3' => 'ISO-8859-3', 'LATIN3' => 'ISO-8859-3',
        '8859-2' => 'ISO-8859-2', '8859_2' => 'ISO-8859-2', '8859-4' => 'ISO-8859-4', '8859_4' => 'ISO-8859-4',
        '8859-7' => 'ISO-8859-7', '8859_7' => 'ISO-8859-7', 'GREEK8' => 'ISO-8859-7', '8859_6' => 'ISO-8859-6',
        'TIS620' => 'TIS-620', '8859-6' => 'ISO-8859-6', 'EUC-KR' => 'EUC-KR', 'LATIN2' => 'ISO-8859-2', 'LATIN6' => 'ISO-8859-10',
        'LATIN7' => 'ISO-8859-13', 'CP1361' => 'JOHAB', 'UTF-16' => 'UTF-16', 'IBM367' => 'US-ASCII', 'CSUCS4' => 'UCS-4',
        'LATIN8' => 'ISO-8859-14', 'EUC_KR' => 'EUC-KR', '8859_1' => 'ISO-8859-1', '8859-1' => 'ISO-8859-1',
        'LATIN1' => 'ISO-8859-1', 'IBM819' => 'ISO-8859-1', '8859-5' => 'ISO-8859-5', '8859_5' => 'ISO-8859-5',
        'HEBREW' => 'ISO-8859-8', 'ARABIC' => 'ISO-8859-6', 'CP1256' => 'CP1256', 'EUC_TW' => 'EUC-TW', 'CP1255' => 'CP1255',
        'CP1254' => 'CP1254', 'CP1253' => 'CP1253', '8859_8' => 'ISO-8859-8', 'CP1258' => 'CP1258', 'ROMAN8' => 'HP-ROMAN8',
        'CP1133' => 'CP1133', 'IBM866' => 'CP866', 'EUC-TW' => 'EUC-TW', 'IBM850' => 'CP850', 'CP1252' => 'CP1252',
        'CP1257' => 'CP1257', 'KOI8-U' => 'KOI8-U', 'WIN-BG' => 'CP1251', 'CSBIG5' => 'BIG5', 'LATIN5' => 'ISO-8859-9',
        'CP1250' => 'CP1250', '8859_9' => 'ISO-8859-9', 'CP1251' => 'CP1251', 'X0212' => 'JIS_X0212', 'UCS-4' => 'UCS-4',
        'UTF-7' => 'UTF-7', 'CP950' => 'CP950', 'CP932' => 'CP932', 'UCS-2' => 'UCS-2', 'UTF-8' => 'UTF-8', 'ASCII' => 'US-ASCII',
        'CN-GB' => 'EUC-CN', 'EUCCN' => 'EUC-CN', 'CP367' => 'US-ASCII', 'CP874' => 'CP874', 'CP866' => 'CP866',
        'JOHAB' => 'JOHAB', 'CP819' => 'ISO-8859-1', 'CP936' => 'GBK', 'BIG-5' => 'BIG5', 'X0208' => 'JIS_X0208',
        'MS-EE' => 'CP1250', 'KOI8R' => 'KOI8-R', 'EUCJP' => 'EUC-JP', 'CP949' => 'CP949', 'GREEK' => 'ISO-8859-7',
        'EUCKR' => 'EUC-KR', 'X0201' => 'JIS_X0201', 'CP850' => 'CP850', 'EUCTW' => 'EUC-TW', 'BIG5' => 'BIG5',
        '1253' => 'CP1253', 'SJIS' => 'SJIS', '1254' => 'CP1254', '1255' => 'CP1255', '1256' => 'CP1256', '1251' => 'CP1251',
        '1250' => 'CP1250', 'ASCI' => 'US-ASCII', 'UTF8' => 'UTF-8', 'JAVA' => 'JAVA', '8859' => 'ISO-8859-1', '1257' => 'CP1257',
        '1252' => 'CP1252', '1258' => 'CP1258', '5601' => 'KSC_5601', 'TCVN' => 'TCVN', '850' => 'CP850', 'UHC' => 'CP949',
        'UTF' => 'UTF-8', '866' => 'CP866', 'GBK' => 'GBK', 'MAC' => 'MACROMAN', 'L6' => 'ISO-8859-10', 'CN' => 'GB_1988-80',
        'L7' => 'ISO-8859-13', 'US' => 'US-ASCII', 'L2' => 'ISO-8859-2', 'L5' => 'ISO-8859-9', 'R8' => 'HP-ROMAN8',
        'HZ' => 'HZ', 'L4' => 'ISO-8859-4', 'L3' => 'ISO-8859-3', 'L1' => 'ISO-8859-1', 'JP' => 'JIS_C6220-1969-RO',
        'L8' => 'ISO-8859-14',
    );
    
    
    public static $topCn1 = array(
        '的', '一', '是', '不', '了', '在', '人', '有', '我', '他', '这', '个', '们', '中', '来', '上', '大', '为', '和', '国', '地',
        '到', '以', '说', '时', '要', '就', '出', '会', '可', '也', '你', '对', '生', '能', '而', '子', '那', '得', '于', '着', '下',
        '自', '之', '年', '过', '发', '后', '作', '里', '用', '道', '行', '所', '然', '家', '种', '事', '成', '方', '多', '经', '么',
        '去', '法', '学', '如', '都', '同', '现', '当', '没', '动', '面', '起', '看', '定', '天', '分', '还', '进', '好', '小', '部',
        '其', '些', '主', '样', '理', '心', '她', '本', '前', '开', '但', '因', '只', '从', '想', '实', '寄', '件',
    );
    
    public static $topCn2 = array(
        '日', '军', '者', '意', '无', '力', '它', '与', '长', '把', '机', '十', '民', '第', '公', '此', '已', '工', '使', '情', '明',
        '性', '知', '全', '三', '又', '关', '点', '正', '业', '外', '将', '两', '高', '间', '由', '问', '很', '最', '重', '并', '物',
        '手', '应', '战', '向', '头', '文', '体', '政', '美', '相', '见', '被', '利', '什', '二', '等', '产', '或', '新', '己', '制',
        '身', '果', '加', '西', '斯', '月', '话', '合', '回', '特', '代', '内', '信', '表', '化', '老', '给', '世', '位', '次', '度',
        '门', '任', '常', '先', '海', '通', '教', '儿', '原', '东', '声', '提', '立', '及', '比', '员',
    );
    
    public static $topCyr1 = array(
        'на', 'та', 'ни', 'ат', 'ра', 'то', 'ст', 'от', 'те', 'ре', 'во', 'ен', 'ва', 'ко', 'пр', 'по',
    );
    
    public static $topCyr2 = array(
        'ка', 'но', 'ит', 'од', 'ан', 'за', 'да', 'ед', 'ов', 'ри', 'ти', 'не', 'ет', 'се', 'ин', 'ли', 'ор',
        'ро', 'ос', 'ав', 'ја', 'ле', 'де', 'ар', 'ск', 'ма', 'до', 'он', 'ме', 'ак',
    );
    
    public static $topCyr3 = array(
        'го', 'ал', 'ве', 'ви', 'ди', 'ис', 'ел', 'ци', 'ол', 'ла', 'иј', 'ил', 'ки', 'ер', 'со', 'из', 'тр',
        'ад', 'ес', 'би', 'ек', 'ло', 'ми', 'об', 'ам', 'мо', 'ув', 'ем', 'тв', 'им', 'че', 'си', 'ом', 'ик',
        'га', 'дн', 'ог', 'ио', 'вр', 'ас', 'ив', 'ој', 'са', 'ок', 'ир', 'аз', 'ия', 'ев', 'ие', 'ње', 'ањ',
        'оп', 'гр', 'па', 'ру', 'нс', 'сл', 'бе', 'ич', 'бо', 'иц', 'вн', 'сп', 'нт', 'др',
    );
    
    public static $topLatExt = array(
        'të', 'ër', 'në', 'ës', 'ın', 'pë', 'rë', 'nı', 'jë', 'ní', 'għ', 'ën', 'së', 'kë', 'ão', 'tä', 'ça',
        'rı', 'ħa', 'lı', 'în', 'më', 'që', 'ió', 'şi', 'sı', 'ţi', 'aş', 'ür', 'ıl', 'aç', 'tı', 'rá', 'ön',
        'ää', 'dı', 'ón', 'ët', 'iş', 'tü', 'nç', 'vä', 'ği', 'oč', 'čn', 'že', 'yö', 'ır', 'či', 'vý', 'és',
        'št', 'ró', 'hë', 'dë', 'iğ', 'tă', 'ži', 'ýc', 'ná', 'şt', 'íc', 'tá', 'än', 'çã', 'ün', 'ně', 'né',
        'iż', 'că', 'să', 'ča', 'iç', 'ık', 'ių', 'ís', 'rí', 'är', 'tų', 'ów', 'ný', 'ię', 'çi', 'ša', 'eş',
        'ğı', 'áv', 'ım', 'ağ', 'eğ', 'tí', 'še', 'má', 'át', 'mé', 'iš', 'ši', 'ža', 'jš', 'jä', 'ış', 'rž',
        'sä', 'yı', 'ác', 'şk', 'lä', 'tó', 'ëm', 'ül', 'aţ', 'ře', 'äh', 'nţ', 'ės', 'př', 'už', 'şe', 'çe',
        'kı', 'bë', 'że', 'şl', 'lá', 'şm', 'ör', 'ár', 'şa', 'ëv', 'zá', 'ġi', 'án', 'ăr', 'če', 'eč', 'ré',
        'dü', 'õe', 'ığ', 'ás', 'gö', 'nč', 'üz', 'až', 'ač', 'óp', 'kä', 'ší', 'ál', 'uş', 'mı', 'eç', 'rü',
        'vé', 'żi', 'lë', 'ċi', 'ič', 'mä', 'té', 'õi', 'lí', 'şı', 'ät', 'oś', 'nü', 'ğr', 'eš', 'ím', 'jú',
        'eú', 'ân', 'üh', 'pä', 'ją', 'ía', 'gü', 'tö', 'ıy', 'ké', 'sü', 'çı', 'võ', 'äi', 'ăţ', 'ła', 'nė',
        'põ', 'ří', 'aí', 'ví', 'ož', 'ór', 'ük', 'śc', 'šk', 'só', 'vá', 'äl', 'ğu', 'iġ', 'ăt', 'ít', 'ço',
        'ký', 'žn', 'lă', 'rç', 'iċ', 'ał', 'eż', 'ín', 'uğ', 'ám', 'ém', 'cë', 'cı', 'ız', 'uç', 'üm', 'õh',
        'dí', 'ąc', 'dá', 'öz', 'čí', 'ţe', 'kü', 'ğl', 'sã', 'eľ', 'õu', 'čl', 'ră', 'zı', 'ež', 'vë', 'lü',
        'nú', 'sõ', 'mă', 'öl', 'üy', 'mě', 'yü', 'ęd', 'äm', 'aš', 'ös', 'äs', 'nă', 'dė', 'ţă', 'zą', 'uż',
        'ík', 'ús', 'tà', 'ėt', 'jų', 'mą', 'ať', 'bū', 'éh', 'öy', 'zë', 'çl', 'ři', 'bę', 'çë', 'iť', 'uč',
        'tě', 'sö', 'äv', 'üt', 'bü', 'ią', 'ým', 'jí', 'mí', 'vě', 'ză', 'ċe', 'vš', 'nä', 'ėj', 'bö', 'sú',
        'ūt', 'ká', 'äy', 'üş', 'ţa', 'ħd', 'ać', 'cí', 'mü', 'mó', 'ło',
    );
    
    public static $topLatExt2 = array(
        'sí', 'aż', 'sť', 'ëz', 'ëh', 'iţ', 'kõ', 'äk', 'ża', 'žu', 'ák', 'nó', 'lõ', 'õr', 'aħ', 'úc', 'tý',
        'ğe', 'eħ', 'ıs', 'bé', 'tú', 'ér', 'äe', 'kö', 'oł', 'ád', 'ħl', 'ýr', 'çõ', 'pı', 'lé', 'úr', 'iž',
        'dž', 'öö', 'tř', 'čt', 'ól', 'dé', 'öğ', 'ėm', 'lė', 'ħu', 'dě', 'aġ', 'ħo', 'ły', 'św', 'ży', 'eġ',
        'mħ', 'üs', 'ív', 'rà', 'íž', 'öt', 'bě', 'bė', 'ět', 'rė', 'ġe', 'ël', 'ğn', 'rý', 'ëp', 'ūr', 'çd',
        'iä', 'jõ', 'gó', 'tâ', 'şu', 'mų', 'ėl', 'rã', 'kó', 'ğü', 'õn', 'bč', 'uš', 'ăs', 'üğ', 'iū', 'ño',
        'ěj', 'ęc', 'óm', 'rġ', 'ġġ', 'rş', 'pó', 'oż', 'mú', 'añ', 'ýš', 'iá', 'ěk', 'ču', 'ęk', 'dú', 'õl',
        'oğ', 'câ', 'ña', 'łu', 'üç', 'šč', 'ūl', 'dů', 'şü', 'ħh', 'ġu', 'úl', 'pô', 'íl', 'ań', 'in', 'ěl',
        'hõ', 'sł', 'šn', 'ôž', 'sé', 'ún', 'čj', 'õj', 'cà', 'úm', 'žd', 'pâ', 'mė', 'ċj', 'ħi', 'eċ', 'ić',
        'ěn', 'łe', 'żo', 'úd', 'mõ', 'tõ', 'ńs', 'ūk', 'oħ', 'čo', 'ľo', 'ħr', 'àr', 'zí', 'ló', 'vă', 'ħe',
        'ľa', 'żu', 'üd', 'ść', 'ną', 'yć', 'ěs', 'pă', 'uţ', 'nã', 'áz', 'fı', 'lç', 'rä', 'il', 'eñ', 'íp',
        'sá', 'oš', 'tą', 'šl', 'pú', 'én', 'nõ', 'rò', 'mè', 'àn', 'üü', 'iã', 'ňo', 'gë', 'ês', 'úp', 'ką',
        'mô', 'ég', 'eń', 'ýv', 'ľn', 'vų', 'şb', 'ýs', 'lý', 'áš', 'úb', 'dè', 'uí', 'õt', 'èr', 'ök', 'uè',
        'ëd', 'zł', 'íz', 'žv', 'éc', 'gă', 'eň', 'ëj', 'ħm', 'éx', 'aċ', 'ąd', 'żs', 'âr', 'äg', 'lš', 'hü',
        'žb', 'rţ', 'tė', 'hä', 'õd', 'ċċ', 'ġo', 'ňa', 'rů', 'ât', 'eř', 'cţ', 'öd', 'ıd', 'kç', 'lų', 'ód',
        'bų', 'pě', 'bħ', 'úč', 'žt', 'èn', 'õp', 'ńc', 'są', 'śr', 'ží', 'ăm', 'há', 'įs', 'řa', 'is', 'kė',
        'dł', 'tç', 'áp', 'có', 'dą', 'gł', 'jū', 'íh', 'kł', 'ên', 'ję', 'hç', 'żj', 'ħħ', 'žo', 'sė', 'ăl',
        'çb', 'ħt', 'pá', 'ıt', 'šo', 'xò', 'ès', 'cħ', 'oġ', 'nš', 'zę', 'dă', 'áh', 'râ', 'cü', 'rč', 'łą',
        'eţ', 'dż', 'yš', 'mâ', 'dň', 'óc', 'dö', 'jó', 'eś', 'tã', 'ġj',
    );
    
    public static $topGreek1 = array(
        'ου', 'το', 'αι', 'τη', 'ικ', 'τα', 'κα', 'πο', 'στ', 'ει', 'τι', 'να', 'αν', 'εί', 'με', 'ια', 'σε',
        'ση', 'ατ', 'ρα', 'απ', 'ρο', 'ης', 'ων', 'τε', 'ερ', 'ντ', 'ον', 'δι', 'μα', 'ρι', 'πρ', 'οι', 'υν',
        'εν', 'ία', 'πα', 'ού', 'νο', 'ην', 'λο', 'αρ', 'ισ', 'ιο', 'ετ', 'ασ', 'ες', 'συ', 'κο', 'πε', 'πό',
        'επ', 'ολ', 'λλ', 'υπ', 'ας', 'κή', 'ις', 'γι', 'ορ', 'λε', 'ρε', 'ότ', 'δε', 'ών', 'κε', 'νι', 'ησ',
        'ημ', 'ος', 'νε', 'ευ', 'ελ', 'ογ', 'τω', 'κό', 'πι', 'ργ', 'κά', 'έρ', 'ομ', 'υς', 'ρί', 'μο', 'εκ',
        'ίο', 'τρ', 'λη', 'ίν', 'αλ', 'ακ', 'μέ', 'ής', 'λί', 'λι', 'κτ', 'υρ', 'οπ', 'έν', 'ρά', 'χε', 'αφ',
        'οσ', 'σι', 'γρ', 'ητ', 'ές', 'δη', 'τή', 'τό', 'μι', 'υτ', 'αμ', 'θε', 'νη', 'γο', 'ρό', 'εσ', 'ως',
        'τέ', 'χο', 'ύν', 'όσ', 'αγ', 'ίτ', 'οί', 'γε', 'ηρ', 'υσ', 'ιβ', 'ήμ', 'υλ', 'φο', 'κρ', 'όμ', 'λα',
        'εξ', 'πλ', 'βλ', 'ωσ', 'σο', 'σα', 'αυ', 'τά', 'αδ', 'βι', 'έχ', 'άν', 'γα', 'έσ', 'μό', 'σμ', 'σί',
        'μμ', 'ιδ', 'άλ', 'ός', 'ιε', 'έλ', 'όν', 'υμ', 'αθ', 'ιν', 'ιτ', 'μπ', 'δο', 'δή', 'ίδ', 'οκ', 'μη',
        'ίσ', 'ιά', 'οτ', 'νό', 'λή', 'ρη', 'νω', 'ιμ', 'ρω', 'γκ', 'σχ', 'λά', 'ηλ', 'κώ', 'ζε', 'ίζ', 'μά',
        'εχ', 'άσ', 'θα', 'δρ', 'ώσ', 'ίε', 'λέ', 'τί', 'υγ', 'ρώ', 'κλ', 'σκ', 'εγ', 'ρέ', 'κυ', 'ήσ', 'κέ',
        'χρ', 'θη', 'νά', 'οδ', 'βο', 'φα', 'ωτ', 'ίω', 'ξε', 'νή', 'οφ', 'θέ', 'άτ', 'ηγ', 'νδ', 'όπ', 'τυ',
        'πω', 'δα', 'ρχ', 'φέ', 'έτ', 'ήτ', 'ρν', 'αί', 'εφ', 'φε', 'ιρ', 'χα', 'όγ', 'γί', 'νί', 'πί', 'ζο',
        'υβ', 'δυ', 'πά', 'όλ', 'όρ', 'εδ', 'εμ', 'άρ', 'γό', 'πτ', 'μί', 'νέ', 'λω', 'κη', 'άδ', 'σω', 'πέ',
        'άζ', 'θο', 'φι', 'ιλ', 'εύ', 'ύσ', 'θυ', 'γγ', 'μβ', 'ύς', 'ηκ', 'ιό', 'βά', 'σσ', 'λό', 'άμ', 'βέ',
        'νώ', 'εθ', 'τώ', 'ύτ', 'έα', 'ώρ', 'ήθ', 'ωρ', 'υκ', 'σπ', 'έμ', 'χώ', 'ήρ', 'έπ', 'ηθ', 'ίπ', 'ωπ',
        'λώ', 'αξ', 'εω', 'ώς', 'ίκ', 'μφ', 'λύ', 'σύ', 'γή', 'ιχ', 'βα', );
    
    public static $topGreek2 = array(
        'γμ', 'ίς', 'άθ', 'ιώ', 'μή', 'ρή', 'φυ', 'ιπ', 'σή', 'ύμ', 'φω', 'υθ', 'κύ', 'ώτ', 'οχ', 'ύλ', 'γω',
        'κι', 'ξα', 'χω', 'ψη', 'πη', 'βρ', 'ρσ', 'τσ', 'φά', 'ωμ', 'αβ', 'έκ', 'χι', 'κδ', 'άπ', 'δί', 'ρτ',
        'ιω', 'ξι', 'σφ', 'οβ', 'ρμ', 'κί', 'ήν', 'δω', 'βε', 'ίμ', 'χό', 'χν', 'γλ', 'ήλ', 'ιθ', 'γν', 'θν',
        'λυ', 'ύο', 'άγ', 'γέ', 'σό', 'σθ', 'θω', 'νθ', 'ύπ', 'φύ', 'ύκ', 'έο', 'φή', 'οθ', 'θμ', 'έγ', 'φί',
        'γη', 'έω', 'ξο', 'θώ', 'ξη', 'αχ', 'εο', 'μω', 'τλ', 'κπ', 'πή', 'θι', 'ωγ', 'ύρ', 'ψε', 'λπ', 'δό',
        'ίχ', 'γχ', 'άφ', 'τμ', 'ίη', 'γά', 'όκ', 'δέ', 'θή', 'ωθ', 'ίλ', 'ήγ', 'τύ', 'δύ', 'όδ', 'δώ', 'ρυ',
        'ίθ', 'θρ', 'χέ', 'ώπ', 'ίρ', 'ιέ', 'ξώ', 'χθ', 'χί', 'έξ', 'ώφ', 'ρύ', 'ήφ', 'άκ', 'αζ', 'ψή', 'χή',
        'ήκ', 'νν', 'χη', 'άχ', 'ώδ', 'υχ', 'ζή', 'άς', 'ϊκ', 'υο', 'αϊ', 'ιφ', 'ξύ', 'ιξ', 'ρθ', 'άξ', 'πώ',
        'ήπ', 'ζη', 'ρξ', 'θό', 'ρρ', 'σβ', 'οη', 'υδ', 'φό', 'ύε', 'φθ', 'υζ', 'όχ', 'όφ', 'νυ', 'ρκ', 'ιζ',
        'ηφ', 'μώ', 'άβ', 'οε', 'εβ', 'ιγ', 'όθ', 'ππ', 'νσ', 'ρδ', 'φη', 'ύγ', 'υξ', 'ξω', 'υε', 'ξέ', 'εη',
        'ύθ', 'γώ', 'βή', 'έε', 'ηδ', 'έδ', 'θί', 'σλ', 'βδ', 'ίξ', 'υψ', 'εζ', 'πν', 'σώ', 'θύ', 'ωβ', 'ξή',
        'ξά', 'ττ', 'ίγ', 'όε', 'εά', 'έθ', 'φρ', 'ζα', 'υα', 'κκ', 'αύ', 'έφ', 'θλ', 'εα', 'χύ', 'ζό', 'ηχ',
        'ζί', 'ηψ', 'υφ', 'ξί', 'όβ', 'ήψ', 'βί', 'εψ', 'ρφ', 'ψέ', 'ζω', 'αο', 'ήδ', 'υέ', 'ψο', 'οϊ', 'υή',
        'κθ', 'χά', 'όψ', 'λτ', 'ύχ', 'ύφ', 'πχ', 'νύ', 'ύξ', 'ύψ', 'κμ', 'έψ', 'σδ', 'ωφ', 'ιή', 'αε', 'κω',
        'σά', 'ώμ', 'μυ', 'μν', 'ζι', 'ϊσ', 'ωλ', 'οή', 'δά', 'λμ', 'ύδ', 'οα', 'βώ', 'λθ', 'όη', 'ύω', 'ώθ',
        'ώη', 'οψ', 'υι', 'οο', 'γύ', 'ιη', 'θά', 'πυ', 'εό', 'χυ', 'αό', 'ηξ', 'κβ', 'ϋπ', 'βω', 'κσ', 'οϋ',
        'άψ', 'ζώ', 'ωζ', 'ζυ', 'βυ', 'ωή', 'τς', 'ωε', 'εώ', 'άε', 'οξ', 'υώ', 'άυ', 'αψ', 'ωδ', 'άι', 'λχ',
        'χμ', 'νκ', 'ρπ', 'ιψ', 'λκ', 'χτ', 'ι΄', 'ϊό', 'υά', 'φν', 'οζ', );
    
    public static $topArabic1 = array(
        'ال', 'لا', 'لم', 'ار', 'ية', 'را', 'ري', 'ان', 'وا', 'لي', 'في', 'ات', 'ام', 'ما', 'يا', 'من', 'ين',
        'با', 'ني', 'لة', 'ول', 'لس', 'يل', 'عل', 'نا', 'لع', 'بي', 'ور', 'قا', 'ير', 'لت', 'ون', 'اس', 'لق',
        'اب', 'دي', 'لى', 'عا', 'عر', 'لل', 'لح', 'مع', 'وم', 'ها', 'ائ', 'رب', 'اف', 'اء', 'لأ', 'اق', 'مي',
        'بر', 'مة', 'اع', 'ست', 'ــ', 'لو', 'لن', 'اد', 'دا', 'لك', 'يد', 'ئي', 'سي', 'كا', 'مو', 'لب', 'يو',
        'رة', 'مس', 'سل', 'لف', 'تا', 'تق', 'لج', 'سا', 'وق', 'دو', 'سو', 'مر', 'حا', 'عد', 'يس', 'تر', 'تح',
        'تي', 'وي', 'لد', 'او', 'شر', 'يق', 'يم', 'قي', 'صر', 'مل', 'قد', 'رو', 'كت', 'تو', 'تم', 'ته', 'وز',
        'تب', 'لش', 'نو', 'اح', 'فا', 'اه', 'زي', 'حم', 'وك', 'رس', 'نت', 'أم', 'بل', 'طا', 'تع', 'كي', 'كو',
        'قر', 'دم', 'عت', 'ود', 'له', 'رك', 'قو', 'سط', 'جم', 'مص', 'لر', 'جا', 'مح', 'مد', 'يت', 'قب', 'وس',
        'طي', 'قت', 'سر', 'حر', 'عم', 'فة', 'بو', 'عي', 'اي', 'دة', 'خب', 'يع', 'أل', 'هر', 'لإ', 'عن', 'اج',
        'بع', 'شا', 'كر', 'تل', 'يه', 'اك', 'عة', 'هم', 'رئ', 'مت', 'مق', 'حو', 'حد', 'جي', 'اث', 'وب', 'لخ',
        'مج', 'مه', 'رض', 'لص', 'رد', 'بة', 'كل', 'وت', 'فل', 'اخ', 'صح', 'ضا', 'در', 'يف', 'ذا', 'عو', 'صا',
        'يب', 'طو', 'عب', 'وض', 'إل', 'ند', 'خا', 'جو', 'اص', 'خل', 'اش', 'نه', 'فر', 'أر', 'مش', 'حي', 'بن',
        'جن', 'رف', 'تص', 'بح', 'شع', 'حت', 'أو', 'وع', 'صل', 'أن', 'حق', 'تن', 'سب', 'به', 'تف', 'يخ', 'جد',
        'وف', 'ذي', 'حة', 'بد', 'صف', 'مك', 'لث', 'قل', 'قة', 'ثا', 'رح', 'حك', 'رج', 'اض', 'زا', 'لذ', 'إن',
        'حل', 'يي', 'فو', 'هو', 'ضي', 'طر', 'يك', 'خط', 'لغ', 'تخ', 'رق', 'جل', 'جه', 'ضة', 'صو', 'نظ', 'اط',
        'وط', 'صد', 'وج', 'زر', 'أس', 'هد', 'دس', 'طل', 'نف', 'نح', 'يح', 'از', 'هي', 'اً', 'قع', 'تس', 'ده',
        'شي', 'فق', 'سن', 'غر', 'يط', 'نة', 'إس', 'صي', 'رم', 'أح', 'ره', 'نب', 'قص', 'دع', 'طن', 'سف', 'فت',
        'يش', 'تش', 'تط', 'مب', 'مف', 'ظا', 'نش', 'دن', 'نس', 'زم', 'أع',
    );
    
    public static $topArabic2 = array(
        'لط', 'بت', 'دى', 'حس', 'رت', 'يز', 'حث', 'تك', 'خر', 'يج', 'دد', 'سم', 'زو', 'نص', 'وص', 'غا', 'نق',
        'أي', 'كث', 'رص', 'بق', 'تد', 'وأ', 'جت', 'مؤ', 'بم', 'ثي', 'سع', 'صة', 'هل', 'جب', 'طة', 'جر', 'تت',
        'حف', 'خو', 'أخ', 'عه', 'نط', 'وح', 'مز', 'قط', 'فع', 'ثق', 'ثر', 'كم', 'شت', 'ضع', 'فض', 'جز', 'دل',
        'وى', 'أد', 'رأ', 'شف', 'شق', 'إي', 'هن', 'رش', 'سة', 'شك', 'نع', 'دب', 'لز', 'رن', 'فظ', 'غة', 'سج',
        'غي', 'بس', 'هذ', 'رى', 'كد', 'فس', 'تز', 'كن', 'سك', 'قف', 'أب', 'ئر', 'طب', 'زة', 'فه', 'هج', 'اذ',
        'كب', 'ثل', 'تج', 'عش', 'َّ', 'سق', 'قه', 'بط', 'دف', 'قذ', 'دث', 'ؤو', 'أف', 'يُ', 'دخ', 'مغ', 'خد',
        'ِل', 'غز', 'بـ', 'رط', 'إع', 'فح', 'دت', 'نج', 'أج', 'مط', 'اة', 'شه', 'طق', 'عق', 'شم', 'ئم', 'فن',
        'ذك', 'أك', 'هة', 'نم', 'ضر', 'ؤك', 'مث', 'دِ', 'مَ', 'يض', 'حج', 'كة', 'تأ', 'ئت', 'يؤ', 'شب', 'ظة',
        'هز', 'بك', 'ُم', 'َل', 'خي', 'فب', 'تض', 'رع', 'ضح', 'رآ', 'قن', 'ذل', 'إخ', 'لـ', 'وغ', 'وة', 'حن',
        'خم', 'وه', 'خت', 'وظ', 'سأ', 'عج', 'نز', 'بغ', 'شو', 'عث', 'قض', 'ثم', 'يث', 'سه', 'كز', 'آن', 'ّه',
        'مم', 'سؤ', 'غد', 'فك', 'بِ', 'أت', 'ذر', 'حز', 'غو', 'يَ', 'زب', 'ثة', 'غل', 'بب', 'عص', 'طف', 'زع',
        'أز', 'ة،', 'ي،', 'بص', 'صن', 'بش', 'لض', 'سد', 'قس', 'قم', 'ظي', 'بإ', 'ظه', 'رغ', 'عَ', 'ِد', 'َي',
        'تذ', 'لَ', 'تظ', 'حذ', 'خص', 'اغ', 'نك', 'أش', 'ضو', 'ثن', 'سح', 'ؤت', 'فج', 'صب', 'بأ', 'عط', 'حب',
        'وو', 'ظر', 'يص', 'كس', 'عز', 'ضم', 'قَ', 'ئن', 'أق', 'رل', 'تة', 'جة', 'ثو', 'مخ', 'تغ', 'رز', 'حص',
        'عض', 'صم', 'ه،', 'َع', 'ئب', 'َه', 'فَ', 'جئ', 'فد', 'يئ', 'ـد', 'ضد', 'صع', 'زه', 'ئف', 'َد', 'إم',
        'طع', 'شط', 'فى', 'وش', 'تئ', 'شل', 'بج', 'جع', 'دق', 'ضب', 'بث', 'ءا', 'ئة', 'إح', 'أه', 'آخ', 'قش',
        'ظم', 'إر', 'عُ', 'أَ', 'قق', 'ذه', 'َت', 'ِه', 'حى', 'نَ', 'تث', 'هه', 'شخ', 'نغ', 'شن', 'أث', 'طى',
        'ؤق', 'شأ', 'هت', 'تى', 'بض', 'ضل', 'أط', 'وخ', 'نن', 'نذ', 'غب',
    );
    
    public static $topLatinExt = array('ë', 'ı', 'ä', 'í', 'á', 'ş', 'ü', 'ç', 'ó', 'č', 'ă', 'š', 'é', 'ž', 'ö', 'ğ', 'ħ',
        'õ', 'ý', 'ų', 'ż', 'ú', 'ţ', 'ą', 'ě', 'ã', 'ė', 'î', 'ę', 'Â', 'ġ', 'ł', 'ř', 'à', 'ċ', 'ť', 'ś', 'İ', 'â',
        'ū', 'ć', 'è', 'ů', 'ľ', 'ò', 'Ú', 'į', 'Ğ', 'Ü', 'ô', 'ň', 'ñ', 'Ħ', 'Ç', 'ń', 'ê', 'Ş', 'Ö', 'Î', 'Č', 'Š');
    
    
    public static $commonCharsets = array(
        'CP1251' => 'cyrillic',
        'UTF-8' => 'roman,cyrillic,chinese,japanese,arabic,hebrew,greek,armenian',
        'CP1252' => 'roman',
        'ISO-8859-1' => 'roman',
        'ISO-8859-2' => 'roman',
        'KOI8-R' => 'cyrillic',
        'ISO-8859-15' => 'roman',
        'CP1250' => 'roman',
        'ISO-8859-5' => 'cyrillic',
        'ISO-8859-7' => 'greek',
        'ISO-8859-9' => 'roman',
        'GB2312' => 'all',
    );
    
    public static $rareCharsets = array(
        'ISO-8859-3' => 'roman',
        'CP1253' => 'greek',
        'ISO-8859-13' => 'roman',
        'CP1254' => 'roman',
        'CP1258' => 'roman', // Vietnam
        'MACROMAN' => 'roman',
        
        // 'EUC-CN'        => 'all',
        // 'BIG5'          => 'all',
        // 'GBK'           => 'all',
        // 'EUC-KR'        => 'all',
        'CP1257' => 'roman',
        'CP1256' => 'arabic',
        'JIS_C6220-1969-RO' => 'japanese',
        'ISO-8859-1|CP1251' => 'cyrillic',
        'MIK' => 'cyrillic',
        'CP874' => 'roman,thai',
        'CP1252_REP_UTF8' => 'all',
        'CP1251_REP_UTF8' => 'all',
        'ISO-8859-1_REP_UTF8' => 'all',
        'CP819|866' => 'all',
    );
    
    public static $cyrillicAlphabet = 'А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ ѝ Ъ Ю Я а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ь ъ ю я';
    
    
    /**
     * Начални символи за цитати
     */
    public static $openSign2 = array('„', '–', '“', '…', '‒', '—', '•');
    
    
    /**
     * Крайни символи за цитати
     */
    public static $closeSign2 = array('–', '”', '…', '•', '—', '“');
    
    
    /**
     * UTF-8 рейнджове на различни скриптове за писане
     */
    public static $utf8ScriptRanges = array(
        array(0x0041, 0x005A, 'latin'),
        array(0x0061, 0x007A, 'latin'),
        array(0x00C0, 0x00F6, 'latExt'),
        array(0x00F7, 0x00FF, 'latExt'),
        array(0x0100, 0x02AF, 'latExt2'),
        array(0x0000, 0x00FF, 'sign'),
        array(0xFF00, 0xFFEF, 'sign'),
        array(0x200B, 0x2E80, 'sign2'),
        array(0x0410, 0x042F, 'cyrillic'),
        array(0x0430, 0x044F, 'cyrillic'),
        array(0x0400, 0x04FF, 'cyrExt'),
        array(0x4E00, 0x9FCC, 'chinese'),
        array(0x3400, 0x4DB5, 'chinese'),
        array(0x20000, 0x2A6DF, 'chinese'),
        array(0x2A700, 0x2B734, 'chinese'),
        array(0x2B740, 0x2B81D, 'chinese'),
        array(0x3000, 0x303F, 'chinese'),
        array(0x3040, 0x309F, 'japanese'),
        array(0x30A0, 0x30FF, 'japanese'),
        array(0x4E00, 0x9FBF, 'japanese'),
        array(0x0600, 0x06FF, 'arabic'),
        array(0x0750, 0x077F, 'arabic'),
        array(0x08A0, 0x08FF, 'arabic'),
        array(0xFB50, 0xFDFF, 'arabic'),
        array(0xFE70, 0xFEFF, 'arabic'),
        array(0x10E60, 0x10E7F, 'arabic'),
        array(0x1EE00, 0x1EEFF, 'arabic'),
        array(0x0590, 0x05FF, 'hebrew'),
        array(0x0370, 0x03FF, 'greek'),
        array(0x0530, 0x058F, 'armenian')
    );
    
    
    /**
     * Намира кой е предполагаемия charset
     */
    public static function detect($text, $assumedCharsets = array(), $isHtml = false)
    {
        if(($assumedCharsets == 'UTF-8' || $assumedCharsets == '')  && preg_match('%^(?:
          [\x09\x0A\x0D\x20-\x7E]            # ASCII
        | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
        | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
        | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
        | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
        | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
        | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
        | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
        )*$%xs', $text)) {
 
            return 'UTF-8';
        }

        if (self::is7bit($text)) {
            if($isHtml) {
                $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
                if (!self::is7bit($text)) {
                
                    return 'HTML_ENTITIES';
                } 
            } else {
                return 'US-ASCII';
            }
        }

        $step = 10;
        $oa = $assumedCharsets;
        $newAssumedCharsets = array();
        if (!$assumedCharsets) {
            $assumedCharsets = array();
        }
        if (is_string($assumedCharsets)) {
            if ($cs = self::getCanonical($assumedCharsets)) {
                $newAssumedCharsets[$cs] = $step;
            }
        } else {
            expect(is_array($assumedCharsets), $assumedCharsets);
            
            // Нормализираме имената на $assumedCharsets
            if (countR($assumedCharsets)) {
                foreach ($assumedCharsets as $cs => $weight) {
                    if ($cs = self::getCanonical($cs)) {
                        $newAssumedCharsets[$cs] = $weight;
                    }
                }
            }
        }
        
        $assumedCharsets = $newAssumedCharsets;
        
        // Ако е даден HTML опитваме се да извлечем charset и и след това махаме HTML елементите
        if ($isHtml) {
            $pattern = '/<meta[^>]+charset\s*=\s*[\'\"]?(.*?)[[\'\"]]?[\/\s>]/i';
            preg_match($pattern, $text, $match);
            if ($match[1]) {
                if ($cs = self::getCanonical(($match[1]))) {
                    $assumedCharsets[$cs] += $step * 0.7;
                }
            }
            
            $text = preg_replace('/<script.*?<\/script>/u', ' ', $text);
            $text = preg_replace('/<style.*?<\/style>/u', ' ', $text);
            $text = strip_tags($text);
            $text = str_replace('&nbsp;', ' ', $text);
            $text = preg_replace('/&#?[a-z0-9]{2,8};/i', '', $text);
        }
        
        
        // Ако текста е 7-битов
        if (self::is7bit($text)) {
            if (countR($assumedCharsets)) {
                $cs = array_search(max($assumedCharsets), $assumedCharsets);
            }
            
            if ($cs && (@self::iconv(self::iconv($text, $cs), 'UTF-8', $cs) != $text)) {
                unset($cs);
            }
            
            if (!$cs) {
                $cs = 'US-ASCII';
            }
            
            return $cs;
        }
        
        $rates = array(0);
        
        // Намираме скриптовите рейтинги на препоръчаните кодировки
        // и им влагаме теглата
        if (countR($assumedCharsets)) {
            foreach ($assumedCharsets as $cs => $weight) {
                $sample = $text;
                $sample = self::iconv($sample, $cs, 'UTF-8//IGNORE');
                if (!$sample) {
                    continue;
                }
                $debug = $sample . ' ';
                $rates[$cs] = self::rateScript($sample, 'all', $debug);
                $resDebug[$cs] = $debug;
                
                $rates[$cs] = $rates[$cs] * (1 + $weight / 100) + $weight / 1000;
            }
        }
        
        $max = max($rates);
        
        if ($max < 1.1) {
            // Намираме скриптовите рейтинги на всички често срещани кодировки
            foreach (static::$commonCharsets as $cs => $scripts) {
                if ($rates[$cs]) {
                    continue;
                }
                
                $sample = $text;
                $sample = self::iconv($sample, $cs, 'UTF-8//IGNORE');
                
                if (!$sample) {
                    continue;
                }
                
                $debug = $sample . ' ';
                $rates[$cs] = self::rateScript($sample, 'all', $debug);
                
                $resDebug[$cs] = $debug;
            }
        }
        
        
        $max = max($rates);
        
        
        // Ако нямаме максимална стойност над 1, то разглеждаме и няколко по-редки
        if ($max < 1.1) {
            foreach (static::$rareCharsets as $cs => $scripts) {
                if ($rates[$cs]) {
                    continue;
                }
                
                $sample = $text;
                $sample = self::iconv($sample, $cs, 'UTF-8//IGNORE');
                if (!$sample) {
                    continue;
                }
                $debug = $sample . ' ';
                $rates[$cs] = self::rateScript($sample, 'all', $debug);
                $resDebug[$cs] = $debug;
                
                // Добавка за правилно UTF-8 кодиране
                if (strpos($cs, 'REP_UTF8')) {
                    $weight = $assumedCharsets['UTF-8'];
                    $rates[$cs] = $rates[$cs] * (1 + $weight / 100) + $weight / 1000;
                }
            }
        }
        
        // arsort($rates);
        
        $resArr = array_keys($rates, max($rates));
        
        $charset = $resArr[0];
        
        // Todo: да се разгледа случая, когато имаме няколко чарсета на първо място
        
        // expect($charset, $charset, $resArr, max($rates), $rates, $assumedCharsets, $oa);
        
        // Ако не сме успели да установим чарсета - приемаме, че е UTF-8
        if (!$charset) {
            $charset = 'UTF-8';
        }
        
        return $charset;
    }
    
    
    /**
     * Връща отрязък от кода - от началот, от средата и от края
     *
     * @param string $text
     *
     * @return bool|string
     */
    public static function getSampleText($text)
    {
        if (!($len = strlen($text))) {
            
            return false;
        }
        
        $maxTrays = 50000;
        
        static $parts = array();
        $crc = crc32($text);
        
        if (!isset($parts[$crc])) {
            
            // Ако стринга е дълъг, няма да се прави обработка на целия
            // Вземаме 3 части от стринга, като по-приоритетни са тези, които имат други символи освен 7 битови
            if ($len > 2500) {
                
                // По-колко символа ще се взема от началото, края и средата на стринга
                $strMaxLen = 400;
                $not7BitStr = 'not7bit';
                
                $partLen = ceil(($len) / 3);
                $partLenE = 2 * $partLen;
                
                $bitStrArr = array();
                $strArr = array();
                $strCntArr = array();
                
                $p = 0;
                $trays = 0;
                while ('' != ($char = self::nextChar($text, $p))) {
                    $trays++;
                    
                    // В зависимост от положениети на маркера, определяме ключа
                    if ($p <= $partLen) {
                        $k = 'begin';
                    } elseif ($p >= $partLenE) {
                        $k = 'end';
                    } else {
                        $k = 'mid';
                    }
                    
                    $bitStr = $bitStrArr[$k];
                    
                    // Докато не намерим символ различен от 7 бита, правим проверка
                    if ($bitStr != $not7BitStr && ord($char) > 127) {
                        $bitStrArr[$k] = $bitStr = $not7BitStr;
                    }
                    
                    if ($strCntArr[$k][$bitStr] <= $strMaxLen) {
                        $strArr[$bitStr][$k] .= $char;
                        $strCntArr[$k][$bitStr]++;
                    } else {
                        
                        // Ако сме намерили стринга, няма нужда да ходим до края в интервала
                        // Прескачаме на следващия интервал или, ако сме в края - прекъсваме
                        // Това е за бързодействие при стрингове със съдържание на символи различни от 7 бита
                        if ($bitStr == $not7BitStr || $trays > $maxTrays) {
                            if ($k == 'begin') {
                                $p = $partLen;
                            } elseif ($k == 'mid') {
                                $p = $partLenE;
                            } elseif ($k == 'end') {
                                break;
                            }
                            $trays = 0;
                        }
                    }
                }
                
                // Опитваме се да генерираме нов стринг от откритите
                $text = '';
                foreach ($strCntArr as $key => $vArr) {
                    
                    // Ако не е 7 битов стринг, искаме да е над определена дължина (може да е намерен в края)
                    
                    if ($vArr[$not7BitStr] > floor($strMaxLen / 2.5)) {
                        $text .= $strArr[$not7BitStr][$key];
                    } else {
                        $text .= $strArr[''][$key];
                        
                        // Ако има много малко текст (под 160 символа), който не е 7 битово, да се конкатинира с 7 битовия
                        if ($strArr[$not7BitStr][$key]) {
                            $text .= $strArr[$not7BitStr][$key];
                        }
                    }
                }
            }
            
            $parts[$crc] = $text;
        } else {
            $text = $parts[$crc];
        }
        
        return $text;
    }
    
    
    /**
     * Преброява символите от различните скриптове
     *
     * @param string       $text
     * @param array|string $scripts
     * @param string|NULL  $debug
     *
     * @return bool|string
     */
    public static function rateScript($text, $scripts, &$debug = null)
    { 
        $scripts = arr::make($scripts, true);
        
        $text = self::getSampleText($text);
        
        if ($text === false) {
            
            return false;
        }
        
        static $rateArr = array();
        $hash = md5(crc32($text) . implode('|', $scripts));
        
        if (!isset($rateArr[$hash])) {
            
            // Вземаме дължината на стринга в mb
            // Горе се взема не в mb и затова го вземаме пак, но този път ще е на по-кратък стринг
            $len = mb_strlen($text);
            
            $sL = $SL = 'sign';
            
            $c = '';
            
            $i = 0;
            
            while ('' != ($c = self::nextChar($text, $i))) {
                $m = mb_strtolower($c);
                
                $s = self::getScript($c);
                
                $S = $s;
                
                if ($s == 'cyrillic' || $s == 'cyrExt') {
                    $S = 'cyrillic';
                } elseif ($s == 'latExt' || $s == 'latExt2' || $s == 'latin') {
                    $S = 'latin';
                } elseif ($s == 'sign' || $s == 'sign2') {
                    $S = 'sign';
                }
                
                // $debug .= "[ $s " . $S . ' ' . $c . ' ' . dechex(self::utf8Ord($c)) . "]"; // dechex(self::utf8Ord($c));
                // Ако е валиден моно-сктипт - даваме +1
                // Ако имаме два различни скрипта, вземаме -1
                // Ако имаме знак - даваме +1
                if ($S != 'sign') {
                    if ($S == $SL || $SL == 'sign') {
                        if ($scripts[$S] || $S == 'latin' || $scripts['all']) {
                            ++$total;
                            
                            // $debug .= '+mono:' . $total . ';';
                        }
                    } else {
                        $total -= 1.5;
                        
                        // $debug .= '-mono:' . $total . ';';
                    }
                    
                    if ($scripts[$S] || $S == 'latin' || $scripts['all']) {
                        $total += 0.05;
                        
                        // $debug .= "+{$S}:" . $total . ';';
                    }
                } else {
                    if ($c == $cL) {
                        if ($c == '?') {
                            $total -= 0.5;
                        
                        // $debug .= '+??:' . $total . ';';
                        } else {
                            $total += 1.0;
                            
                            // $debug .= '+ssign:' . $total . ';';
                        }
                    } else {
                        $total += 0.80;
                        
                        // $debug .= '+sign:' . $total . ';';
                    }
                }
                
                // Ако имаме две разширени латински знака -0.2
                if (($s == 'latExt' || $s == 'latExt2') && ($sL == 'latExt' || $sL == 'latExt2')) {
                    $total -= 0.8;
                    
                    // $debug .= '-dle:' . $total . ';';
                }
                
                // Ако имаме две разширени латински знака -0.2
                if (($s == 'latExt' || $s == 'latExt2') && ($sL == 'sign')) {
                    $total -= 0.7;
                    
                    // $debug .= '-dle1:' . $total . ';';
                }
                
                // Ако имаме два разширени кирилски знака -0.4
                if ($s == 'cyrExt' && $sL == 'cyrExt') {
                    $total -= 0.9;
                    
                    // $debug .= '-dce:'. $total . ';';
                }
                
                // Ако имаме 3 разширени латински знака -0.6
                if (($s == 'latExt' || $s == 'latExt2') && ($sL == 'latExt' || $sL == 'latExt2') && ($sLL == 'latExt' || $sLL == 'latExt2')) {
                    $total -= 0.6;
                    
                    // $debug .= '-tle:'. $total . ';';
                }
                
                if ($S != 'sign') {
                    if (($c == $cL) && ($cL == $cLL)) {
                        $total -= 0.2;
                        
                        // $debug .= '-3a:'. $total . ';';
                    }
                }
                
                // Ако имаме три разширени кирилски знака -0.4
                if ($s == 'cyrExt' && $sL == 'cyrExt' && $sLL == 'cyrExt') {
                    $total -= 1.9;
                    
                    // $debug .= '-tce:'. $total . ';';
                }
                
                
                // Ако скрипт, знак, скрипт - 0.5
                if ($S != 'sign' && $SL == 'sign' && $SLL != 'sign' && $S != $SLL) {
                    $total -= 0.2;
                    
                    // $debug .= '-SsS:'. $total . ';';
                }
                
                if ($S != 'sign' && $cL == '?' && $SLL != 'sign') {
                    --$total;
                    
                    // $debug .= '-S?S:'. $total . ';';
                }
                
                
                // Правила за големи и малки букви
                if (($S == 'cyrillic' || $S == 'latin' || $S == 'greek') && ($SL == 'cyrillic' || $SL == 'latin' || $SL == 'greek')) {
                    
                    // Ако имаме малка и голяма буква -0.5
                    if ($m != $c) {
                        if ($mL == $cL) {
                            $total -= 1.2;
                            
                            // $debug .= '-aA:'. $total . ';';
                        }
                    }
                    
                    // Ако имаме знак, голяма буква, малка буква +0.5
                    if ($m == $c) {
                        if ($mL != $cL) {
                            if ($SLL == 'sign') {
                                $total += 0.4;
                                
                                // $debug .= '+Aa:'. $total . ';';
                            }
                        }
                    }
                }
                
                // Ако сме с китайски скрипт и имаме топ100, даваме +0.3
                if ($S == 'chinese') {
                    if (in_array($c, self::$topCn1)) {
                        $total += 1.2;
                    
                    // $debug .= '+Cn1';
                    } elseif (in_array($c, self::$topCn2)) {
                        $total += 0.6;
                    
                    // $debug .= '+Cn2';
                    } else {
                        $total -= 0.05;
                        
                        // $debug .= '-Cn:'. $total . ';';
                    }
                }
                
                // Ако сме с арабски скрипт и имаме топ100, даваме +0.3
                if ($S == 'arabic') {
                    if (in_array($c, self::$topArabic1)) {
                        $total += 1.8;
                    
                    // $debug .= '+Ar1';
                    } elseif (in_array($c, self::$topArabic2)) {
                        $total += 0.8;
                    
                    // $debug .= '+Ar2';
                    } else {
                        $total -= 0.02;
                        
                        // $debug .= '-Ar:'. $total . ';';
                    }
                }
                
                // Ако сме кирилски скрипт и имаме топ1,2,3 даваме
                if ($S == 'cyrillic' && $SL == 'cyrillic') {
                    $w2 = $mL . $m;
                    if (in_array($w2, self::$topCyr1)) {
                        $total += 1.8;
                    
                    // $debug .= '+Cyr1:'. $total . ';';
                    } elseif (in_array($w2, self::$topCyr2)) {
                        $total += 1.2;
                    
                    // $debug .= '+Cyr2:'. $total . ';';
                    } elseif (in_array($w2, self::$topCyr3)) {
                        $total += 0.6;
                    
                    // $debug .= '+Cyr3:'. $total . ';';
                    } else {
                        $total -= 0.09;
                        
                        // $debug .= '-Cyr:'. $total . ';';
                    }
                }
                
                // Ако сме латински скрипт и имаме топ даваме
                if ($S == 'latin' && $SL == 'latin' && ($s != 'latin' || $sL != 'latin')) {
                    $w2 = $mL . $m;
                    if (in_array($w2, self::$topLatExt)) {
                        $total += 2.8;
                    
                    // $debug .= '+LatTop:'. $total . ';';
                    } elseif (in_array($w2, self::$topLatExt2)) {
                        $total += 1.6;
                    
                    // $debug .= '+LatTop:'. $total . ';';
                    } else {
                        $total -= 0.3;
                        
                        // $debug .= '-LatTop:'. $total . ';';
                    }
                }
                
                
                // Ако сме гръцки скрипт и имаме топ1,2  даваме
                if ($S == 'greek' && $SL == 'greek') {
                    $w2 = $mL . $m;
                    if (in_array($w2, self::$topGreek1)) {
                        $total += 0.8;
                    
                    // $debug .= '+Cyr1:'. $total . ';';
                    } elseif (in_array($w2, self::$topGreek2)) {
                        $total += 0.4;
                    
                    // $debug .= '+Cyr2:'. $total . ';';
                    } else {
                        $total -= 0.3;
                        
                        // $debug .= '-Cyr:'. $total . ';';
                    }
                }
                
                
                // Ако кирилски разширен сктипт вадим
                if ($s == 'cyrExt') {
                    $total -= 0.5;
                    
                    // $debug .= '-CyrEx:'. $total . ';';
                }
                
                if ($s == 'latExt') {
                    if (!in_array($c, self::$topLatinExt)) {
                        $total -= 0.6;
                        
                        // $debug .= '-LatEx:'. $total . ';';
                    }
                }
                
                if ($sL == 'sign2') {
                    if (in_array($cL, self::$openSign2)) {
                        if ($S == 'latin' || $S == 'cyrillic' || $S == 'greek') {
                            if ($SLL == 'sign') {
                                $total += 0.4;
                            
                            // $debug .= '+Op:'. $total . ';';
                            } elseif ($SLL == 'latin' || $SLL == 'cyrillic' || $SLL == 'greek') {
                                $total -= 0.4;
                                
                                // $debug .= '-oP:'. $total . ';';
                            }
                        }
                    }
                    
                    if (in_array($cL, self::$closeSign2)) {
                        if ($SLL == 'latin' || $SLL == 'cyrillic' || $SLL == 'greek') {
                            if ($S == 'sign') {
                                $total += 0.3;
                            
                            // $debug .= '+Cl:'. $total . ';';
                            } elseif ($S == 'latin' || $S == 'cyrillic' || $S == 'greek') {
                                $total -= 0.3;
                                
                                // $debug .= '-cL:'. $total . ';';
                            }
                        }
                    }
                    
                    if ($SLL == 'latin' || $SLL == 'cyrillic' || $SLL == 'greek') {
                        if ($SLL == $S) {
                            $total -= 0.9;
                            
                            // $debug .= '-Ss2S:'. $total . ';';
                        }
                    }
                }
                
                // Шифтваме регистъра
                $sLL = $sL;
                $SLL = $SL;
                $cLL = $cL;
                $mLL = $mL;
                
                $sL = $s;
                $SL = $S;
                $cL = $c;
                $mL = $m;
            }
            
            $rateArr[$hash] = $total / $len;
        }
        
        return $rateArr[$hash];
    }
    
    
    /**
     * От кой писмен скрипт е символа
     */
    public static function getScript($c)
    {
        // Вземаме UNICODE стойността на символа
        $o = self::utf8Ord($c);
        
        // Определяме скрипта за писане, според рейнджа на който принадлежи
        foreach (self::$utf8ScriptRanges as $ranges) {
            if ($ranges[0] <= $o && $o <= $ranges[1]) {
                
                return $ranges[2];
            }
        }
        
        return dechex($o);
    }
    
    
    /**
     * Опитва се да извлече име на позната за iconv()
     * име на кодировка на символи от зададения стринг
     */
    public static function getCanonical($charset)
    {
        $charset = strtoupper(trim($charset));
        
        if (!$charset) {
            
            return ;
        }
        
        static $charsetArr = array();
        
        if (isset($charsetArr[$charset])) {
            
            return $charsetArr[$charset];
        }
        
        if ($name = self::$charsetsMatchs[$charset]) {
            $findCharset = $name;
        } else {
            foreach (self::$charsetsMatchs as $key => $name) {
                if (strpos($charset, (string) $key) !== false) {
                    $findCharset = $name;
                    break;
                }
            }
        }
        
        if (!$findCharset) {
            $findCharset = substr($charset, 0, 64);
        }
        
        // Ако функцията iconv разпознава $findCharset като кодова таблица, връщаме $findCharset
        if (self::iconv('OK', $findCharset) == 'OK') {
            $charsetArr[$charset] = $findCharset;
        } else {
            $charsetArr[$charset] = false;
        }
        
        return $charsetArr[$charset];
    }
    
    
    /**
     * Конвертира стринга към UTF-8, като предполага, че входния параметър е в $fromCharset
     * Прави и допълнителни на iconv конвертирания. Генерира събития
     */
    public static function iconv_($str, $fromCharset, $toCharset = 'UTF-8', $mode = '')
    {
        // Вдигаме лимита на паметта, ако е по-малък от 2048M
        // Понякога iconv и mb_convert_encoding изискват много памет
        // особено при големи стрингове
        // Това е само предпазна мярка, ако все пак не стига паметта, ще дава грешка
        $mLimit = '2048M';
        if (core_Os::getBytesFromMemoryLimit() < core_Os::getBytesFromMemoryLimit($mLimit)) {
            ini_set('memory_limit', $mLimit);
        }

        list($toCharset, $mode) = explode('//', $toCharset);
        
        if ($mode && strpos($mode, '//') !== 0) {
            $mode = "//{$mode}";
        }
        
        if ($fromCharset == 'ISO-8859-1|CP1251') {
            $str = iconv('UTF-8', 'ISO-8859-1' . $mode, $str);
            $str = iconv('CP1251', 'UTF-8' . $mode, $str);
        } elseif ($fromCharset == 'CP819|866') {
            $str = iconv('UTF-8', 'CP819' . $mode, $str);
            $str = iconv('866', 'UTF-8' . $mode, $str);
        } elseif ($fromCharset == 'MIK') {
            $str = self::iconvMik2Utf8($str, $mode);
        } elseif ($fromCharset == 'HTML_ENTITIES') {
            $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
        } elseif ($fromCharset == 'CP1251_REP_UTF8') {
            static $fromCP1251, $toCP1251;
            if (!$fromCP1251) {
                $toCP1251 = explode(' ', self::$cyrillicAlphabet);
                $fromCP1251 = explode(' ', mb_convert_encoding(self::$cyrillicAlphabet, 'UTF-8', 'CP1251'));
            }
            $str = str_replace($fromCP1251, $toCP1251, $str);
        } elseif ($fromCharset == 'CP1252_REP_UTF8') {
            static $fromCP1252, $toCP1252;
            if (!$fromCP1252) {
                $toCP1252 = explode(' ', self::$cyrillicAlphabet);
                $fromCP1252 = explode(' ', mb_convert_encoding(self::$cyrillicAlphabet, 'UTF-8', 'CP1252'));
            }
            $str = str_replace($fromCP1252, $toCP1252, $str);
        } elseif ($fromCharset == 'ISO-8859-1_REP_UTF8') {
            static $fromISO88591, $toISO88591;
            if (!$fromISO88591) {
                $toISO88591 = explode(' ', self::$cyrillicAlphabet);
                $fromISO88591 = explode(' ', mb_convert_encoding(self::$cyrillicAlphabet, 'UTF-8', 'ISO-8859-1'));
            }
            $str = str_replace($fromISO88591, $toISO88591, $str);
        } elseif ($fromCharset != 'DEFAULT') {
            // Фикс за УТФ-8 стрингове, които съдържат грешни последователсности
            if ($fromCharset == 'UTF-8' && $mode == '//IGNORE') {
                $str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');
            } else {
                $str = iconv($fromCharset, 'UTF-8' . $mode, $str);
            }
        }
        
        // До тук стринга е в UTF-8
        if ($toCharset == 'ISO-8859-1|CP1251') {
            $str = iconv('UTF-8', 'CP1251' . $mode, $str);
            $str = iconv('ISO-8859-1', 'UTF-8' . $mode, $str);
        }
        if ($toCharset == 'CP819|866') {
            $str = iconv('UTF-8', '866' . $mode, $str);
            $str = iconv('CP819', 'UTF-8' . $mode, $str);
        } elseif ($toCharset == 'MIK') {
            $str = self::iconvUtf82Mik($str, $mode);
        } elseif ($toCharset != 'DEFAULT' && $toCharset != 'UTF-8') {
            $str = iconv('UTF-8', $toCharset . $mode, $str);
        }
        
        return $str;
    }
    
    
    /**
     * Конвертира от зададена кодова таблица, към UTF-8
     * Прави проверка, кодовата таблица да е неправилно зададена
     */
    public static function convertToUtf8($text, $fromCharsets = array(), $isHtml = false)
    { 
        $bFrom = $fromCharsets;        
        
        if (preg_match('%^(?:
      [\x09\x0A\x0D\x20-\x7E]            # ASCII
    | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
    | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
    | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
    | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
    | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
    | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
    )*$%xs', $text) || $fromCharsets != 'UTF-8') {
    
            $fromCharset = self::detect($text, $fromCharsets, $isHtml);
        }
        
        if ($fromCharset == 'HTML_ENTITIES' && $isHtml) {
            if (!$bFrom || is_array($bFrom)) {
                $pattern = '/<meta[^>]+charset\s*=\s*[\'\"]?(.*?)[[\'\"]]?[\/\s>]/i';
                preg_match($pattern, $text, $match);
                $bFrom = self::getCanonical(($match[1]));
            }
            
            if ($bFrom && $bFrom != $fromCharset) {
                $nText = @self::iconv($text, $bFrom, 'UTF-8//IGNORE');
                if ($nText) {
                    $text = $nText;
                }
            }
        }
        
        // Конвертираме текста в "UTF-8"
        if ($fromCharset) {
            $text = self::iconv($text, $fromCharset, 'UTF-8//IGNORE');
        }
        
        return $text;
    }
    
    
    /**
     * Конвертира utf8mb4 към UTF8
     * 
     * @param string $text
     * @param boolean $checkCharset
     * 
     * @return string
     */
    public static function utf8mb4ToUtf8($text, $checkCharset = true)
    {
        if ($checkCharset && defined('EF_DB_CHARSET') && (EF_DB_CHARSET == 'utf8mb4')) {
            
            return $text;
        }
        
        $text = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $text);
        
        return $text;
    }
    
    
    /**
     * Проверява дали аргумента е 7 битов стринг
     *
     * @param string $text - Стринга, който ще се проверява
     *
     * @return bool
     */
    public static function is7Bit($text)
    {
        $res = preg_match('/[^\\x00-\\x7F]/', $text);
        
        return !$res;
    }
    
    
    /**
     * Конвертира от МИК (българска ДОС-овска кодировка) към UTF-8
     */
    public static function iconvMik2Utf8($str, $mode = '')
    {
        $out = '';
        for ($i = 0; $i < strlen($str); $i++) {
            $c = ord($str[$i]);
            if ($c >= 128) {
                $c = $c ^ 64;
            }
            $out .= chr($c);
        }
        
        $out = iconv('CP1251', 'UTF-8' . $mode, $out);
        
        return $out;
    }
    
    
    /**
     * Конвертира от UTF-8 към МИК (българска ДОС-овска кодировка)
     */
    public static function iconvUtf82Mik($str, $mode = '')
    {
        $str = iconv('UTF-8', 'CP1251' . $mode, $str);
        
        $out = '';
        for ($i = 0; $i < strlen($str); $i++) {
            $c = ord($str[$i]);
            if ($c >= 128) {
                $c = $c ^ 64;
            }
            $out .= chr($c);
        }
        
        return $out;
    }
    
    
    /**
     * Циклене по UTF-8 низове
     */
    public static function nextChar($string, &$pointer)
    {
        $c = mb_substr(substr($string, $pointer, 5), 0, 1);
        
        $pointer += strlen($c);
        
        return $c;
    }
    
    
    /**
     * UTF-8 еквивалент на ord();
     */
    public static function utf8Ord($ch)
    {
        $len = strlen($ch);
        
        if ($len <= 0) {
            
            return false;
        }
        
        $h = ord($ch[0]);
        
        if ($h <= 0x7F) {
            $res = $h;
        } elseif ($h < 0xC2) {
            $res = false;
        } elseif ($h <= 0xDF && $len > 1) {
            $res = ($h & 0x1F) << 6 | (ord($ch[1]) & 0x3F);
        } elseif ($h <= 0xEF && $len > 2) {
            $res = ($h & 0x0F) << 12 | (ord($ch[1]) & 0x3F) << 6 | (ord($ch[2]) & 0x3F);
        } elseif ($h <= 0xF4 && $len > 3) {
            $res = ($h & 0x0F) << 18 | (ord($ch[1]) & 0x3F) << 12 | (ord($ch[2]) & 0x3F) << 6 | (ord($ch[3]) & 0x3F);
        } else {
            $res = false;
        }
        
        return $res;
    }
}
