var VISCIIDauTable = new Array(39, 96, 63, 126, 46, 40, 94, 43, 100, 92);
var VISCIIMuTable = new Array ( 97, 229, 226, 101, 234, 105, 111, 244, 189, 117, 223, 121,
                               225, 224, 228, 227, 213, 233, 232, 235, 168, 169,
                               243, 242, 246, 245, 247, 250, 249, 252, 251, 248, 100,
                               65, 197, 194, 69, 202, 73, 79, 212, 180, 85, 191, 89,
                               193, 192, 196, 195, 128, 201, 200, 203, 136, 137,
                               211, 210, 153, 160, 154, 218, 217, 156, 157, 158, 68 );

var VISCIIMuDauTable = new Array( new Array( 225, 161, 164, 233, 170, 237, 243, 175, 190, 250, 209, 253,
                                 193, 129, 132, 201, 138, 205, 211, 143, 149, 218, 186, 221 ),
                                 new Array( 224, 162, 165, 232, 171, 236, 242, 176, 182, 249, 215, 207,
                                 192, 130, 133, 200, 139, 204, 210, 144, 150, 217, 187, 159 ),
                                 new Array( 228, 198, 166, 235, 172, 239, 246, 177, 183, 252, 216, 214,
                                 196, 2, 134, 203, 140, 155, 153, 145, 151, 156, 188, 20 ),
                                 new Array( 227, 199, 231, 168, 173, 238, 245, 178, 222, 251, 230, 219,
                                 195, 5, 6, 136, 141, 206, 160, 146, 179, 157, 255, 25 ),
                                 new Array( 213, 163, 167, 169, 174, 184, 247, 181, 254, 248, 241, 220,
                                 128, 131, 135, 137, 142, 152, 154, 147, 148, 158, 185, 30 )
                                 );

var VISCIIMuDauArray = new Array(
                                 new Array( 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                 161, 162, 198, 199, 163, 0, 0, 0, 0, 0,
                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                 129, 130, 2, 5, 131, 0, 0, 0, 0, 0,
                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
                                 new Array( 226, 0, 0, 234, 0, 0, 244, 0, 0, 0, 0, 0,
                                 164, 165, 166, 231, 167, 170, 171, 172, 173, 174,
                                 175, 176, 177, 178, 181, 0, 0, 0, 0, 0, 0,
                                 194, 0, 0, 202, 0, 0, 212, 0, 0, 0, 0, 0,
                                 183, 133, 134, 6, 135, 138, 139, 140, 141, 142,
                                 143, 144, 145, 146, 147, 0, 0, 0, 0, 0, 0 ),
                                 new Array (  0, 0, 0, 0, 0, 0, 189, 0, 0, 223, 0, 0,
                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                 190, 182, 183, 222, 254, 209, 215, 216, 230, 241, 0,
                                 0, 0, 0, 0, 0, 0, 180, 0, 0, 191, 0, 0,
                                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                 149, 150, 151, 179, 148, 186, 187, 188, 255, 185, 0 )
                                 );

var VISCIIToV8 = new Array ( 4161, 8513, 8769,12353,16705,16961,17473,20545, 2117, 4165,16709,16965,
                            17477,18501,20549,16719,16975,17487,18511,20559,36943,33103,33359,33871,
                            4169, 1103, 4175, 1097, 1109, 2133, 4181, 601, 2127, 8545, 8801,12385,
                            16737,16993,17505,20577, 2149, 4197,16741,16997,17509,18533,20581,16751,
                            17007,17519,18543,34895,32847,20591,33391,33903, 4201,36949,33109,33365,
                            33877,32879,33135,32853, 577, 321,16449, 2113, 1089, 8257, 9313,10337,
                            581, 325,16453, 1093, 585, 329, 2121, 633, 0,33141, 591, 335,
                            16463, 4193, 1145,33397,33909, 597, 341, 2169, 4217, 345,34927,32885,
                            609, 353,16481, 2145, 1121, 8289,34933,18529, 613, 357,16485, 1125,
                            617, 361, 2153, 1129, 0,36981, 623, 367,16495, 2159, 1135, 4207,
                            4213, 629, 373, 2165, 1141, 377,36975,34901 );

var VISCIIToUnicode = new Array 
( 0x0000,0x0001,0x1eb2,0x0003,0x0004,0x1eb4,0x1eaa,0x0007,
 0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
 0x0010,0x0011,0x0012,0x0013,0x1ef6,0x0015,0x0016,0x0017,
 0x0018,0x1ef8,0x001a,0x001b,0x001c,0x001d,0x1ef4,0x001f,
 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f,
 0x1ea0,0x1eae,0x1eb0,0x1eb6,0x1ea4,0x1ea6,0x1ea8,0x1eac,
 0x1ebc,0x1eb8,0x1ebe,0x1ec0,0x1ec2,0x1ec4,0x1ec6,0x1ed0,
 0x1ed2,0x1ed4,0x1ed6,0x1ed8,0x1ee2,0x1eda,0x1edc,0x1ede,
 0x1eca,0x1ece,0x1ecc,0x1ec8,0x1ee6,0x0168,0x1ee4,0x1ef2,
 0x00d5,0x1eaf,0x1eb1,0x1eb7,0x1ea5,0x1ea7,0x1ea9,0x1ead,
 0x1ebd,0x1eb9,0x1ebf,0x1ec1,0x1ec3,0x1ec5,0x1ec7,0x1ed1,
 0x1ed3,0x1ed5,0x1ed7,0x1ee0,0x01a0,0x1ed9,0x1edd,0x1edf,
 0x1ecb,0x1ef0,0x1ee8,0x1eea,0x1eec,0x01a1,0x1edb,0x01af,
 0x00c0,0x00c1,0x00c2,0x00c3,0x1ea2,0x0102,0x1eb3,0x1eb5,
 0x00c8,0x00c9,0x00ca,0x1eba,0x00cc,0x00cd,0x0128,0x1ef3,
 0x0110,0x1ee9,0x00d2,0x00d3,0x00d4,0x1ea1,0x1ef7,0x1eeb,
 0x1eed,0x00d9,0x00da,0x1ef9,0x1ef5,0x00dd,0x1ee1,0x01b0,
 0x00e0,0x00e1,0x00e2,0x00e3,0x1ea3,0x0103,0x1eef,0x1eab,
 0x00e8,0x00e9,0x00ea,0x1ebb,0x00ec,0x00ed,0x0129,0x1ec9,
 0x0111,0x1ef1,0x00f2,0x00f3,0x00f4,0x00f5,0x1ecf,0x1ecd,
 0x1ee5,0x00f9,0x00fa,0x0169,0x1ee7,0x00fd,0x1ee3,0x1eee );


var TCVN_VISCII_MAP = new Array
( 0,218,158, 3,187,188,255, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 16,186,185,159, 20, 25,221, 30, 24, 25, 26, 27, 28, 29, 30, 31,
 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 192,196,195,193,128,131,135,200,203,136,201,137,142,204,155,206,
 205,152,210,153,160,211,154,147,150,151,179,149,148,217,156,157,
 160,197,194,202,212,180,191,208,229,226,234,244,189,223,240,130,
 176,177,178,179,180,224,228,227,225,213, 2,162,198,199,161, 5,
 129,133,134, 6,132,139,163,165,166,231,164,167,232,140,235,168,
 233,169,171,172,173,170,174,236,239,141,138,144,238,237,184,242,
 145,246,245,243,247,176,177,178,175,181,182,183,222,190,254,249,
 146,252,251,250,248,215,216,230,209,241,207,214,219,253,220,143);

var VISCII_TCVN_MAP = new Array
( 0, 1,186, 3, 4,191,195, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 132,192,175,133,196,193,194,134,137,139,218,197,205,217,140,255,
 219,224,240,151,156,155,152,153,145,147,150,142,158,159, 2, 19,
 160,190,187,198,202,199,200,203,207,209,213,210,211,212,214,232,
 229,230,231,179,180,233,234,235,222, 18, 17, 4, 5,172,237,166,
 128,131,162,130,129,161,188,189,135,138,163,136,141,144,143,250,
 167,248,146,149,164,185,251,245,246,157, 1,252,254, 22,236,173,
 181,184,169,183,182,168,247,201,204,208,170,206,215,221,220,216,
 174,249,223,227,171,226,225,228,244,239,243,242,241,253,238, 6);

var VPS_VISCII_MAP = new Array
( 0, 1,128,135,131,137,142, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 16, 17, 18, 19, 20,185, 22, 23, 24, 30, 26, 27, 6,255, 30, 31,
 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 192,196,195,132,133,134,247,178,197,170,171,172,174,129,130, 2,
 138,145,146,139,140,141,143,144,145,146,253,214,220,149,150,151,
 160,161,162,198,199,163,179,190,217,182,183,222,157,186,254,187,
 177,188,159, 25,205,204,181,155,206,211,216,230,210,153,160,241,
 165,193,194,164,166,231,167,240,235,201,202,169,239,173,184,219,
 191,156,176,175,212,246,189,200,215,209,218,251,223,221,203,223,
 224,225,226,227,228,213,229,231,232,233,234,168,236,237,238,238,
 5,208,242,243,244,245,246,180,248,249,250,252,252, 20,136,207);

var VISCII_VPS_MAP = new Array
( 0, 1,143, 3, 4,240, 28, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 16, 17, 18, 19,253, 21, 22, 23, 24,179, 26, 27, 28, 29, 25, 31,
 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
 2,141,142, 4,131,132,133, 3,254, 5,144,147,148,149, 6,150,
 151,152,153, 18, 19,157,158,159, 16,189, 17,183,209,172, 20,178,
 190,161,162,165,195,192,196,198,235,203,137,138,139,205,140,211,
 210,176,135,166,247,182,169,170,206, 21,173,175,177,214,167,208,
 128,193,194,130,129,136,163,164,215,201,202,222,181,180,184,255,
 241,217,188,185,212,229,155,216,186,168,218,207,156,221,171,220,
 224,225,226,227,228,230,187,197,232,233,234,200,236,237,239,204,
 199,191,242,243,244,245,213,134,248,249,250,219,251,154,174, 29);

var VNI_VISCII_MAP = new Array
( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
 64,255, 66, 67, 68,255, 70, 71, 72, 73, 74, 75, 76, 77, 78,255,
 80, 81, 82, 83, 84,255, 86, 87, 88,255, 90, 91, 92, 93, 94, 95,
 96,255, 98, 99,100,255,102,103,104,105,106,107,108,109,110,255,
 112,113,114,115,116,255,118,119,120,255,122,123,124,125,126,127,
 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
 192,193,194,195,196,197,155,199,200,201,202,203,204,205, 30,207,
 208,208,152,206,255,213,255,215,216,217,218,219,220,221,222,223,
 224,225,226,227,228,229,239,231,232,233,234,235,236,237,220,239,
 240,240,184,238,255,245,255,247,248,249,250,251,252,253,254,220 );

var VNIDOUBLE_VISCII_MAP = new Array
( 65,69,79,85,89,97,101,111,117,121,212,214,244,246,
 0x0010,0x111b,0x1c26,0x272b,0x2c30,0x3141,0x424c,0x4d57,0x585c,0x5d61,0x6266,0x676b,0x6c70,0x7175 );

var VNIDIPTHONGS_VISCII_MAP = new Array
( 0xc085,0xc184,0xc2c2,0xc306,0xc487,0xc586,0xc882,0xc981,
 0xcac5,0xcb83,0xcf80,0xd5c3,0xd8c0,0xd9c1,0xda02,0xdbc4,
 0xdc05,0xc08b,0xc18a,0xc2ca,0xc38d,0xc48e,0xc58c,0xcf89,
 0xd588,0xd8c8,0xd9c9,0xdbcb,0xc090,0xc18f,0xc2d4,0xc392,
 0xc493,0xc591,0xcf9a,0xd5a0,0xd8d2,0xd9d3,0xdb99,0xcf9e,
 0xd59d,0xd8d9,0xd9da,0xdb9c,0xcf1e,0xd519,0xd89f,0xd9dd,
 0xdb14,0xe0a5,0xe1a4,0xe2e2,0xe3e7,0xe4a7,0xe5a6,0xe8a2,
 0xe9a1,0xeae5,0xeba3,0xefd5,0xf5e3,0xf8e0,0xf9e1,0xfac6,
 0xfbe4,0xfcc7,0xe0ab,0xe1aa,0xe2ea,0xe3ad,0xe4ae,0xe5ac,
 0xefa9,0xf5a8,0xf8e8,0xf9e9,0xfbeb,0xe0b0,0xe1af,0xe2f4,
 0xe3b2,0xe4b5,0xe5b1,0xeff7,0xf5f5,0xf8f2,0xf9f3,0xfbf6,
 0xeff8,0xf5fb,0xf8f9,0xf9fa,0xfbfc,0xefdc,0xf5db,0xf8cf,
 0xf9fd,0xfbd6,0xcf94,0xd5b3,0xd896,0xd995,0xdb97,0xcfb9,
 0xd5ff,0xd8bb,0xd9ba,0xdbbc,0xeffe,0xf5de,0xf8b6,0xf9be,
 0xfbb7,0xeff1,0xf5e6,0xf8d7,0xf9d1,0xfbd8 );

var VISCII_VNI_MAP = new Array 
( 0xcf41,0xc941,0xc841,0xcb41,0xc141,0xc041,0xc541,0xc441,
 0xd545,0xcf45,0xc145,0xc045,0xc545,0xc345,0xc445,0xc14f,
 0xc04f,0xc54f,0xc34f,0xc44f,0xcfd4,0xd9d4,0xd8d4,0xdbd4,
 0x00d2,0xdb4f,0xcf4f,0x00c6,0xdb55,0xd555,0xcf55,0xd859,
 0xd54f,0xe961,0xe861,0xeb61,0xe161,0xe061,0xe561,0xe461,
 0xf565,0xef65,0xe165,0xe065,0xe565,0xe365,0xe465,0xe16f,
 0xe06f,0xe56f,0xe36f,0xd5d4,0x00d4,0xe46f,0xf8f4,0xfbf4,
 0x00f2,0xcfd6,0xd9d6,0xd8d6,0xdbd6,0x00f4,0xf9f4,0x00d6,
 0xd841,0xd941,0xc241,0xd541,0xdb41,0xca41,0xfa61,0xfc61,
 0xd845,0xd945,0xc245,0xdb45,0x00cc,0x00cd,0x00d3,0xf879,
 0x00d1,0xf9f6,0xd84f,0xd94f,0xc24f,0xef61,0xfb79,0xf8f6,
 0xfbf6,0xd855,0xd955,0xf579,0x00ee,0xd959,0xf5f4,0x00f6,
 0xf861,0xf961,0xe261,0xf561,0xfb61,0xea61,0xf5f6,0xe361,
 0xf865,0xf965,0xe265,0xfb65,0x00ec,0x00ed,0x00f3,0x00e6,
 0x00f1,0xeff6,0xf86f,0xf96f,0xe26f,0xf56f,0xfb6f,0xef6f,
 0xef75,0xf875,0xf975,0xf575,0xfb75,0xf979,0xeff4,0xd5d6 );


//////////////////////////////////////////////////////////////////////////////
//@function VIQRToVISCII(cSrcChar,cTrgChar) 
//////////////////////////////////////////////////////////////////////////////
function VIQRToVISCII(cSrcChar, cTrgChar) 
  {
  var c, nchar, bConverted;
  var nKeyIndex, nCharIndex;
  
  c = cSrcChar;
  bConverted   = false;
  nchar = cTrgChar;
  if (nchar == 68) 
    {
    nchar = 100;
    if (c == 45) c = nchar;
    }
  else if (nchar == 100) 
    {
    if (c == 45) c = nchar;
    }
  else if (nchar == 42) nchar = 43;
  for (nKeyIndex = 0; nKeyIndex < 9; nKeyIndex++) 
    {
    if (nchar == VISCIIDauTable[nKeyIndex]) 
      {
      for (nCharIndex=0; nCharIndex < 66; nCharIndex++)
        if (c == VISCIIMuTable[nCharIndex]) 
          {
          if (nKeyIndex < 5) 
            {
            c = (nCharIndex % 33);
            nchar =  (c < 12) ? nchar = VISCIIMuDauTable[nKeyIndex][c+Math.floor(nCharIndex / 33)*12] : 0;
            }    
          else
            if (nKeyIndex==8) 
              nchar= ((nCharIndex % 33) == 32) ? (c +140) : 0;
            else 
              nchar = VISCIIMuDauArray[nKeyIndex-5][nCharIndex];
            bConverted = (nchar != 0);
            break;
          }
        if (bConverted) cSrcChar=nchar;
        break;
      }
    }
  
  return (bConverted) ? cSrcChar : 0;
  }

//////////////////////////////////////////////////////////////////////////////
//@function VISCIIToVIQR(cSrcChar, strTarget) 
//////////////////////////////////////////////////////////////////////////////
function VISCIIToVIQR(cSrcChar, strTarget) 
  {
  var c;
  var NumChars = 1;
  var nKey = cSrcChar;

  switch (cSrcChar)
    {
    case 2:   nKey=9281;  break;
    case 5:   nKey=10305; break;
    case 6:   nKey=18497; break;
    case 20:  nKey=1113;  break;
    case 25:  nKey=2137;  break;
    case 30:  nKey=4185;  break;
    default:
      {
      if (cSrcChar < 128) break;
      if (cSrcChar >= 256) 
        {
        for (c=255; c > 0; c--) 
          {
          if (VISCIIToUnicode[c] == cSrcChar) 
            {
            cSrcChar = c;
            break;
            }
          }
        }
      if ((cSrcChar==240) || (cSrcChar==208)) 
        {
        nKey= cSrcChar - 140;
        strTarget[1] = nKey;
        NumChars++;
        }
      else nKey = VISCIIToV8[cSrcChar-128];
      }
    }
  
  strTarget[0]=(nKey & 0xFF);     
  nKey >>>= 8;
  if (nKey != 0)  cSrcChar=7;
  
  for (c=0x80; nKey != 0; c >>>= 1) 
    {
    if ((nKey & c) != 0) 
      {
      if (++NumChars ==2) strTarget[1]=VISCIIDauTable[cSrcChar];
      else                strTarget[2]=VISCIIDauTable[cSrcChar];
      nKey &= (~c);
      }
    cSrcChar--;
    }
  return(NumChars);
  }


//////////////////////////////////////////////////////////////////////////////
//@function StringVISCIIToVIQR(strSrc) 
//////////////////////////////////////////////////////////////////////////////
function StringVISCIIToVIQR(strSrc) 
  {
  if (strSrc == null) return(null);
  var c;
  var i,j,k;
  var strRet = "";
  var aChar = new Array (0,0,0);
  
  for (i=0; i < strSrc.length; i++) 
    {
    c = strSrc.charCodeAt(i);
    j = VISCIIToVIQR(c, aChar);
    for (k=0; k < j; k++) strRet += String.fromCharCode(aChar[k]);
    }
  return strRet;
  }


//////////////////////////////////////////////////////////////////////////////
//@function StringVIQRToVISCII( strSrc) 
//////////////////////////////////////////////////////////////////////////////
function StringVIQRToVISCII(strSrc) 
  {
  if (strSrc == null) return(null);
  var nLen = strSrc.length;
  if (nLen < 2) return(strSrc);
  
  var c, i, k;
  var strRet = "";
  var cNextChar=0;
  var nNextChar=0;
  
  var cOldChar = strSrc.charCodeAt(0);
  for (i=1; i < nLen; i++) 
    {
    c = strSrc.charCodeAt(i);
    
    if ((c==46 || c==63) && i < nLen -1)
      {
      cNextChar = strSrc.charCodeAt(i+1);
      if (cNextChar == 13) k=0;
      else if (cNextChar==32 && (i+2)<nLen)
        {
        nNextChar = strSrc.charCodeAt(i+2);
        
        k = ((nNextChar >=65 && nNextChar <=90) || nNextChar == 13) ? 0 : VIQRToVISCII(cOldChar,c);
        }
      else k = VIQRToVISCII(cOldChar,c);

      }
    else if ((c == 46 || c == 63) && i == nLen -1) k = 0;
    else k = VIQRToVISCII(cOldChar,c);
    
    if (k == 0) 
      {
      strRet += String.fromCharCode(cOldChar);
      cOldChar = c;
      }
    else cOldChar = k;
    }
  strRet += String.fromCharCode(cOldChar);
  
  return(strRet);
  }

//////////////////////////////////////////////////////////////////////////////
//@function StringVISCIIToUnicode(strSrc) 
//////////////////////////////////////////////////////////////////////////////
function StringVISCIIToUnicode(strSrc) 
  {
  if (strSrc == null) return(null);
  var strRet="";
  var c, i;
  for (i = 0; i < strSrc.length; i++) 
    {
    c = strSrc.charCodeAt(i);
    if (c < 256) c = VISCIIToUnicode[c];
    strRet += String.fromCharCode(c);
    }
  return(strRet);
  }

//////////////////////////////////////////////////////////////////////////////
//@function StringUnicodeToVISCII(strSrc) 
//////////////////////////////////////////////////////////////////////////////
function StringUnicodeToVISCII(strSrc) 
  {
  if (strSrc == null) return(null);
  var strRet="";
  var c, i, j;
  for (i=0; i < strSrc.length; i++) 
    {
    c = strSrc.charCodeAt(i);
    if (c >= 256) 
      {
      for (j=255; j > 0; j--) 
        {
        if (VISCIIToUnicode[j] == c) 
          {
          c = j;
          break;
          }
        }
      }
    strRet += String.fromCharCode(c);
    }
  return(strRet);
  }

//////////////////////////////////////////////////////////////////////////////
//@function StringVNIToVISCII(strSrc)
//////////////////////////////////////////////////////////////////////////////
function StringVNIToVISCII(strSrc)
  {
  if (strSrc == null) return(null);
  var cBuf, c;
  var i, j, nIndex, nFrom, nTo, nCharCode;
  var strRet = "";
  var nLen = strSrc.length;
  
  for (i=0; i < nLen; i++) 
    {
    c = strSrc.charCodeAt(i);
    if (c > 255) cBuf = c;
    else   cBuf = VNI_VISCII_MAP[c];
    if (cBuf != 255) strRet += String.fromCharCode(cBuf);
    else 
      {
      nIndex=0;
      for (j=0; j < 14; j++) 
        {
        if (c == VNIDOUBLE_VISCII_MAP[j]) 
          {
          nIndex = VNIDOUBLE_VISCII_MAP[j+14];
          break;
          }
        }
      if (nIndex != 0) 
        {
        if ((i+1) < nLen) 
          {
          cBuf = strSrc.charCodeAt(i+1);
          nFrom = (nIndex >>> 8);
          nTo = (nIndex & 0xFF);
          for (j = nFrom; j <= nTo; j++) 
            {
            nIndex = VNIDIPTHONGS_VISCII_MAP[j];
            nCharCode = (nIndex >>> 8);
            if (nCharCode == cBuf) 
              {
              c = (nIndex & 0xFF);
              i++;
              break;
              }
            }
          if (j > nTo) 
            {
            switch (c)
              {
              case 212: c = 180; break;
              case 214: c = 191; break;
              case 244: c = 189; break;
              case 246: c = 223; break;
              }
            }
          }
        }
      strRet += String.fromCharCode(c);
      }
    }
  return strRet;
  }

//////////////////////////////////////////////////////////////////////////////
//@function StringVISCIIToVNI(strSrc)
//////////////////////////////////////////////////////////////////////////////
function StringVISCIIToVNI(strSrc)
  {
  var nIndex,c,i;
  var strRet="";
  for (i=0; i < strSrc.length; i++) 
    {
    nIndex = 0;
    c = strSrc.charCodeAt(i);
    if (c < 32) 
      {
      if (c == 2) nIndex = 0xda41;
      else if (c == 5) nIndex = 0xdc41;
      else if (c == 6) nIndex = 0xc341;
      else if (c == 20) nIndex = 0xdb59;
      else if (c == 25) nIndex = 0xd559;
      else if (c == 30) c = 0xCE;
      }
    else if ((c > 127) && (c < 256)) nIndex = VISCII_VNI_MAP[c-128];
    if (nIndex != 0) {
      strRet += String.fromCharCode(nIndex & 0xFF);
      c = nIndex >>> 8;
      if (c != 0) strRet += String.fromCharCode(c);
      }
    else strRet += String.fromCharCode(c);
    }
  return strRet;
  }

//////////////////////////////////////////////////////////////////////////////
//@function SwapTableCharCode (strSrc, aMap)
//////////////////////////////////////////////////////////////////////////////
function SwapTableCharCode (strSrc, aMap)
  {
  if (strSrc == null) return(null);
  var i,c;
  var strRet="";
  for (i=0; i < strSrc.length; i++) 
    {
    c = strSrc.charCodeAt(i);
    if (c < 256) c = aMap[c];
    strRet += String.fromCharCode(c);
    }
  return strRet;
  }

//////////////////////////////////////////////////////////////////////////////
//@function Convert(SrcTextCtrl, SrcCharCode, TrgTextCtrl, TrgCharCode, wnd) 
//////////////////////////////////////////////////////////////////////////////
function Convert(SrcTextCtrl, SrcCharCode, TrgTextCtrl, TrgCharCode, wnd) 
  {
  wnd.style.cursor = "hand";
  var strRet = SrcTextCtrl.value;
  if ((strRet == null) || (strRet.length == 0) || (SrcCharCode == TrgCharCode)) 
    return;

  switch (SrcCharCode)
    {
    case 0: strRet = StringVIQRToVISCII(strRet); break;
    case 2: strRet = SwapTableCharCode(strRet,VPS_VISCII_MAP); break;
    case 3: strRet = StringVNIToVISCII(strRet); break;
    case 4: strRet = SwapTableCharCode(strRet,TCVN_VISCII_MAP); break;
    case 5: strRet = StringUnicodeToVISCII(strRet); break;
    }

  switch (TrgCharCode)
    {
    case 0: strRet = StringVISCIIToVIQR(strRet); break;
    case 2: strRet = SwapTableCharCode(strRet,VISCII_VPS_MAP); break;
    case 3: strRet = StringVISCIIToVNI(strRet); break;
    case 4: strRet = SwapTableCharCode(strRet,VISCII_TCVN_MAP); break;
    case 5: strRet = StringVISCIIToUnicode(strRet); break;
    }

  TrgTextCtrl.value = strRet;
  wnd.style.cursor = "hand";
  }

