/***************************************************************************/
/*                                                                         */
/*  syntax.js -- Version 1.2                                               */
/*                                                                         */
/*  Uyghur Unicode Input System -- syntax file.                            */
/*                                                                         */
/*  Copyleft  2003-2004 by Muhammad Abdulla                                */
/*                                                                         */
/*  Anyone is free to use and distribute this piece of software, provided  */
/*  that this copyright notice is retained. The author is not responsible  */
/*  for any damage caused by the usage of this software.                   */
/*                                                                         */
/*  Uyghurcha:                                                             */
/*  Bu programmini harkim mushu nashir hoquqi sozini saqlap qalghan halda  */
/*  ishlatsa wa tarqatsa bolidu. Bu programmini tuzguchi ishlitishtin      */
/*  kilip chiqqan ziyangha masul bolmaydu.                                 */
/*  Pikirliringiz bolsa muhammad@yulghun.com digan addrisqa hat awating.   */
/***************************************************************************/

var n = 1 ;
var AA           = n++ ;
var _AA_         = n++ ;
var _AA          = n++ ;
var __AA         = n++ ;
var AE           = n++ ;
var _AE          = n++ ;
var _AE_         = n++ ;
var __AE         = n++ ;
var OO           = n++ ;
var _OO          = n++ ;
var S_OO         = n++ ;
var __OO         = n++ ;
var OE           = n++ ;
var S_OE         = n++ ;
var _OE          = n++ ;
var __OE         = n++ ;
var UE           = n++ ;
var S_UE         = n++ ;
var _UE          = n++ ;
var __UE         = n++ ;
var UU           = n++ ;
var S_UU         = n++ ;
var _UU          = n++ ;
var __UU         = n++ ;
var II           = n++ ;
var I            = n++ ;
var _II          = n++ ;
var _I           = n++ ;
var II_          = n++ ;
var I_           = n++ ;
var SI_          = n++ ;
var _I_          = n++ ;
//var _II_         = n++ ;
var DSH          = n++ ;
//var DSH_         = n++ ;
var EE           = n++ ;
var E            = n++ ;
var _EE          = n++ ;
var _E           = n++ ;
var EE_          = n++ ;
var E_           = n++ ;
var _E_          = n++ ;
//var _EE_         = n++ ;
var BEE          = n++ ;
var _BEE         = n++ ;
var _BEE_        = n++ ;
var BEE_         = n++ ;
var NEE          = n++ ;
var _NEE         = n++ ;
var _NEE_        = n++ ;
var NEE_         = n++ ;
var GHEE         = n++ ;
var _GHEE        = n++ ;
var GHEE_        = n++ ;
var _GHEE_       = n++ ;
var PEE          = n++ ;
var _PEE         = n++ ;
var _PEE_        = n++ ;
var PEE_         = n++ ;
var DEE          = n++ ;
var _DEE         = n++ ;
var REE          = n++ ;
var _REE         = n++ ;
var ZEE          = n++ ;
var _ZEE         = n++ ;
var SZEE         = n++ ;
var _SZEE        = n++ ;
var TEE          = n++ ;
var _TEE         = n++ ;
var _TEE_        = n++ ;
var TEE_         = n++ ;
var FEE          = n++ ;
var _FEE         = n++ ;
//var __FEE        = n++ ;
var FEE_         = n++ ;
var _FEE_        = n++ ;
var KEE          = n++ ;
var _KEE_        = n++ ;
var KEE_         = n++ ;
var _KEE         = n++ ;
var JEE          = n++ ;
var _JEE_        = n++ ;
var _JEE         = n++ ;
var JEE_         = n++ ;
var NGEE         = n++ ;
var _NGEE_       = n++ ;
var _NGEE        = n++ ;
var NGEE_        = n++ ;
var CHEE         = n++ ;
var _CHEE_       = n++ ;
var _CHEE        = n++ ;
var CHEE_        = n++ ;
var SEE          = n++ ;
var _SEE_        = n++ ;
var SEE_         = n++ ;
var _SEE         = n++ ;
var QEE          = n++ ;
var _QEE         = n++ ;
var _QEE_        = n++ ;
var QEE_         = n++ ;
var SHEE         = n++ ;
var _SHEE_       = n++ ;
var SHEE_        = n++ ;
var _SHEE        = n++ ;
var HEE          = n++ ;
var _HEE_        = n++ ;
var _HEE         = n++ ;
var HEE_         = n++ ;
var LA           = n++ ;
var _LA          = n++ ;
var GEE          = n++ ;
var _GEE_        = n++ ;
var GEE_         = n++ ;
var _GEE         = n++ ;
var LEE          = n++ ;
var LEE_         = n++ ;
var _LEE_        = n++ ;
var _LEE         = n++ ;
var MEE          = n++ ;
var MEE_         = n++ ;
var _MEE_        = n++ ;
var _MEE         = n++ ;
var YEE          = n++ ;
var YEE_         = n++ ;
var _YEE_        = n++ ;
var _YEE         = n++ ;
var EHE_         = n++ ;
var _EHE_        = n++ ;
var VEE          = n++ ;
var _VEE         = n++ ;
var U_SEMICOLON  = n++ ;
var U_QUESTION   = n++ ;
var U_COMMA      = n++ ;
var ONE          = n++ ;
var TWO          = n++ ;
var THREE        = n++ ;
var FOUR         = n++ ;
var FIVE         = n++ ;
var SIX          = n++ ;
var SEVEN        = n++ ;
var EIGHT        = n++ ;
var NINE         = n++ ;
var ZERO         = n++ ;
var EXCLAMATION  = n++ ;
var ASTERISC     = n++ ;
var PERCENT      = n++ ;
var DOLLAR       = n++ ;
var POUND        = n++ ;
var AT           = n++ ;
var WEDGE        = n++ ;
var AND          = n++ ;
var LPAREN       = n++ ;
var RPAREN       = n++ ;
var LBRACK       = n++ ;
var RBRACK       = n++ ;
var LBRACE       = n++ ;
var RBRACE       = n++ ;
var DQUOTE       = n++ ;
var SQUOTE       = n++ ;
var LTHAN        = n++ ;
var GTHAN        = n++ ;
var PIPE         = n++ ;
var PRIM         = n++ ;
var PLUS         = n++ ;
var MINUS        = n++ ;
var EQUAL        = n++ ;
var TILDE        = n++ ;
var DOT          = n++ ;
var UNDERSCORE   = n++ ;
var SPACE        = n++ ;
var TAB          = n++ ;
var COLON        = n++ ;
var FSLASH       = n++ ;
var BSLASH       = n++ ;
var LFEED        = n++ ;

var WD_BEG = 2 ;
var IN_BEG = 1 ;
var NO_BEG = 0 ;

var char_code = new Array( n ) ;
var beg_form = new Array( n ) ;
var in_beg_form = new Array( n ) ;
var end_form = new Array( n ) ;
var med_form = new Array( n ) ;
var rev_med_form = new Array( n ) ;
var beg_tab  = new Array( n ) ;

// tables to store context dependent abstract indices
var wd_beg_tab = new Array ( 128 ) ;
var in_beg_tab = new Array ( 128 ) ;
var no_beg_tab = new Array ( 128 ) ;

// To improve performance, a new reverse index array is added to map Uyghur 
// Unicode character codes (number) to the abstract index used in this program.
// The two Arabic presention forms have ranges FB50-FDFF and FE70-FEFF, respectively.
// In order to save space, array index starts from zero, but will be padded afterwards 
// by FB50 to get the actual Unicode character number. The array size will be
// 0xFEFF - 0xFB50 = 0x3AF, which is 943 in decimal. This will be initialized only once
// in init when the page is loaded. 
var MAX = 0xFEFF ;
var PAD = 0xFB50 ;
var rev_index = new Array ( MAX - PAD ) ;

var initialized = 0 ;

char_code[ AA ]     = 0xFBEA ;
char_code[ _AA_ ]   = 0xFE8D ;
char_code[ _AA ]    = 0xFE8E ;
char_code[ __AA ]   = 0xFBEB ;
char_code[ AE ]     = 0xFBEC ;
char_code[ _AE ]    = 0xFEEA ;
char_code[ _AE_ ]   = 0xFEE9 ;
char_code[ __AE ]  = 0xFBED ;
char_code[ OO ]     = 0xFBEE ;
char_code[ _OO ]    = 0xFEEE ;
char_code[ S_OO ]    = 0xFEED ;
char_code[ __OO ]   = 0xFBEF ;
char_code[ OE ]     = 0xFBF2 ;
char_code[ S_OE ]   = 0xFBD9 ;
char_code[ _OE ]    = 0xFBDA ;
char_code[ __OE ]   = 0xFBF3 ;
char_code[ UE ]     = 0xFBF4 ;
char_code[ S_UE ]   = 0xFBDB ;
char_code[ _UE ]    = 0xFBDC ;
char_code[ __UE ]   = 0xFBF5 ;
char_code[ UU  ]    = 0xFBF0 ;
char_code[ S_UU  ]  = 0xFBD7 ;
char_code[ _UU  ]   = 0xFBD8 ;
char_code[ __UU  ]  = 0xFBF1 ;
char_code[ II ]     = 0xFBF9 ;
char_code[ I ]      = 0xFEEF ;
char_code[ _II ]    = 0xFBFA ;
char_code[ _I ]     = 0xFEF0 ;
char_code[ II_ ]    = 0xFBFB ;
char_code[ I_ ]     = 0xFE8B ; // short II with hamza
char_code[ SI_ ]    = 0xFBE8 ; // short II without hamza
char_code[ _I_ ]    = 0xFE8C ;
//char_code[ _I_ ]    = 0xFBE9 ;
//char_code[ _II_ ]   = 0xFBD2 ;
//char_code[ _II_ ]   = 0xFE8C ;
char_code[ DSH ]    = 0xFBE9 ;
//char_code[ DSH_ ]   = 0xFBE8 ;
char_code[ EE ]     = 0xFBF6 ;
char_code[ E ]      = 0x06D0 ;
char_code[ _EE ]    = 0xFBF7 ;
char_code[ _E ]     = 0xFBE5 ; // the same with _EE?
char_code[ EE_ ]    = 0xFBF8 ;
char_code[ E_ ]     = 0xFBE6 ;
char_code[ _E_ ]    = 0xFBE7 ;
//char_code[ _EE_ ]   = 0xFBD1 ;
char_code[ BEE ]    = 0xFE8F ;
char_code[ _BEE ]   = 0xFE90 ;
char_code[ _BEE_ ]  = 0xFE92 ;
char_code[ BEE_ ]   = 0xFE91 ;
char_code[ NEE ]    = 0xFEE5 ;
char_code[ _NEE ]   = 0xFEE6 ;
char_code[ _NEE_ ]  = 0xFEE8 ;
char_code[ NEE_ ]   = 0xFEE7 ;
char_code[ GHEE ]   = 0xFECD ;
char_code[ _GHEE ]  = 0xFECE ;
char_code[ GHEE_ ]  = 0xFECF ;
char_code[ _GHEE_ ] = 0xFED0 ;
char_code[ PEE ]    = 0xFB56 ;
char_code[ _PEE ]   = 0xFB57 ;
char_code[ _PEE_ ]  = 0xFB59 ;
char_code[ PEE_ ]   = 0xFB58 ;
char_code[ DEE ]    = 0xFEA9 ;
char_code[ _DEE ]   = 0xFEAA ;
char_code[ REE ]    = 0xFEAD ;
char_code[ _REE ]   = 0xFEAE ;
char_code[ ZEE ]    = 0xFEAF ;
char_code[ _ZEE ]   = 0xFEB0 ;
char_code[ SZEE ]   = 0xFB8A ;
char_code[ _SZEE ]  = 0xFB8B ;
char_code[ TEE ]    = 0xFE95 ;
char_code[ _TEE ]   = 0xFE96 ;
char_code[ _TEE_ ]  = 0xFE98 ;
char_code[ TEE_ ]   = 0xFE97 ;
char_code[ FEE ]    = 0xFED1 ;
char_code[ _FEE ]   = 0xFED2 ;
//char_code[ __FEE ]  = 0xFED2 ;
char_code[ FEE_ ]   = 0xFED3 ;
char_code[ _FEE_ ]  = 0xFED4 ;
char_code[ KEE ]    = 0xFED9 ;
char_code[ _KEE_ ]  = 0xFEDC ;
char_code[ KEE_ ]   = 0xFEDB ;
char_code[ _KEE ]   = 0xFEDA ;
char_code[ JEE ]    = 0xFE9D ;
char_code[ _JEE_ ]  = 0xFEA0 ;
char_code[ _JEE ]   = 0xFE9E ;
char_code[ JEE_ ]   = 0xFE9F ;
char_code[ NGEE ]   = 0xFBD3 ;
char_code[ _NGEE_ ] = 0xFBD6 ;
char_code[ _NGEE ]  = 0xFBD4 ;
char_code[ NGEE_ ]  = 0xFBD5 ;
char_code[ CHEE ]   = 0xFB7A ;
char_code[ _CHEE_ ] = 0xFB7D ;
char_code[ _CHEE ]  = 0xFB7B ;
char_code[ CHEE_ ]  = 0xFB7C ;
char_code[ SEE ]    = 0xFEB1 ;
char_code[ _SEE_ ]  = 0xFEB4 ;
char_code[ SEE_ ]   = 0xFEB3 ;
char_code[ _SEE ]   = 0xFEB2 ;
char_code[ QEE ]    = 0xFED5 ;
char_code[ _QEE ]   = 0xFED6 ;
char_code[ _QEE_ ]  = 0xFED8 ;
char_code[ QEE_ ]   = 0xFED7 ;
char_code[ SHEE ]   = 0xFEB5 ;
char_code[ _SHEE_ ] = 0xFEB8 ;
char_code[ SHEE_ ]  = 0xFEB7 ;
char_code[ _SHEE ]  = 0xFEB6 ;
char_code[ HEE ]    = 0xFEA5 ;
char_code[ _HEE_ ]  = 0xFEA8 ;
char_code[ _HEE ]   = 0xFEA6 ;
char_code[ HEE_ ]   = 0xFEA7 ;
char_code[ LA ]    = 0xFEFB ;
char_code[ _LA ]     = 0xFEFC ;
char_code[ GEE ]    = 0xFB92 ;
char_code[ _GEE_ ]  = 0xFB95 ;
char_code[ GEE_ ]   = 0xFB94 ;
char_code[ _GEE ]   = 0xFB93 ;
char_code[ LEE ]    = 0xFEDD ;
char_code[ LEE_ ]   = 0xFEDF ;
char_code[ _LEE_ ]  = 0xFEE0 ;
char_code[ _LEE ]   = 0xFEDE ;
char_code[ MEE ]    = 0xFEE1 ;
char_code[ MEE_ ]   = 0xFEE3 ;
char_code[ _MEE_ ]  = 0xFEE4 ;
char_code[ _MEE ]   = 0xFEE2 ;
char_code[ YEE ]    = 0xFEF1 ;
char_code[ YEE_ ]   = 0xFEF3 ;
char_code[ _YEE_ ]  = 0xFEF4 ;
char_code[ _YEE ]   = 0xFEF2 ;
char_code[ EHE_ ]   = 0xFEEB ;
char_code[ _EHE_ ]  = 0xFEEC ;
// TODO: change the character codes above as below, and fix the eot file accordingly
// char_code[ EHE_ ]   = 0xFBAA ; 
// char_code[ _EHE_ ]  = 0xFBAD ;

char_code[ VEE ]    = 0xFBDE ;
char_code[ _VEE ]   = 0xFBDF ;

char_code[ U_SEMICOLON ]   = 0x061B ;
char_code[ U_QUESTION ]    = 0x061F ;
char_code[ U_COMMA ]    = 0x060C ;

//char_code[ U_COMMA ]    = gac ( ',' ) ;

/* Standard Part */
char_code [ ONE ] = gac ( '1' ) ;
char_code [ TWO ] =  gac ('2' ) ;
char_code [ THREE ] = gac ( '3' ) ;
char_code [ FOUR ] = gac ( '4' ) ;
char_code [ FIVE ] = gac ( '5' ) ;
char_code [ SIX ] = gac ( '6' ) ;
char_code [ SEVEN ] = gac ( '7' ) ;
char_code [ EIGHT ] = gac ( '8' ) ;
char_code [ NINE ] = gac ( '9' ) ;
char_code [ ZERO ] = gac ( '0' ) ;
char_code [ EXCLAMATION ] = gac ( '!' ) ;
char_code [ ASTERISC ] = gac ( '*' ) ;
char_code [ PERCENT ] = gac ( '%' ) ;
char_code [ DOLLAR ] = gac ( '$' ) ;
char_code [ POUND ] = gac ( '#' ) ;
char_code [ AT ] = gac ( '@' ) ;
char_code [ WEDGE ] = gac ( '^' ) ;
char_code [ AND ] = gac ( '&' ) ;
char_code [ LPAREN ] = gac ( '(' ) ;
char_code [ RPAREN ] = gac ( ')' ) ;
char_code [ LBRACK ] = gac ( '[' ) ;
char_code [ RBRACK ] = gac ( ']' ) ;
char_code [ LBRACE ] = gac ( '{' ) ;
char_code [ RBRACE ] = gac ( '}' ) ;
char_code [ DQUOTE ] = gac ( '"' ) ;
char_code [ SQUOTE ] = gac ( '\'' ) ;
char_code [ LTHAN ] = gac ( '<' ) ;
char_code [ GTHAN ] = gac ( '>' ) ;
char_code [ PIPE ] = gac ( '|' ) ;
char_code [ PRIM ] = gac ( '`' ) ;
char_code [ PLUS ] = gac ( '+' ) ;
char_code [ MINUS ] = gac ( '-' ) ;
char_code [ EQUAL ] = gac ( '=' ) ;
char_code [ TILDE ] = gac ( '~' ) ;
char_code [ DOT ] = gac ( '.' ) ;
char_code [ UNDERSCORE ] = gac ( '_' ) ;
char_code [ SPACE ] = gac ( ' ' ) ;
char_code [ TAB ] = gac ( '\t' ) ;
char_code [ COLON ] = gac ( ':' ) ;
char_code [ FSLASH ] = gac ( '/' ) ;
char_code [ BSLASH ] = gac ( '\\' ) ;
char_code [ LFEED ] = gac ( '\n' ) ;
//char_code [ LFEED ] = gac ( '\r' ) ;


// beginning table
beg_tab[ AA ]     = WD_BEG ;
beg_tab[ _AA_ ]   = WD_BEG ;
beg_tab[ _AA ]    = WD_BEG ;
beg_tab[ __AA ]   = WD_BEG ;
beg_tab[ AE ]     = WD_BEG ;
beg_tab[ _AE ]    = WD_BEG ;
beg_tab[ _AE_ ]   = WD_BEG ;
beg_tab[ __AE ]  = WD_BEG ;
beg_tab[ OO ]     = IN_BEG ;
beg_tab[ _OO ]    = IN_BEG ;
beg_tab[ S_OO ]    = IN_BEG ;
beg_tab[ __OO ]   = IN_BEG ;
beg_tab[ OE ]     = IN_BEG ;
beg_tab[ S_OE ]   = IN_BEG ;
beg_tab[ _OE ]    = IN_BEG ;
beg_tab[ __OE ]   = IN_BEG ;
beg_tab[ UE ]     = IN_BEG ;
beg_tab[ S_UE ]   = IN_BEG ;
beg_tab[ _UE ]    = IN_BEG ;
beg_tab[ __UE ]   = IN_BEG ;
beg_tab[ UU  ]    = IN_BEG ;
beg_tab[ S_UU  ]  = IN_BEG ;
beg_tab[ _UU  ]   = IN_BEG ;
beg_tab[ __UU  ]  = IN_BEG ;
beg_tab[ II ]     = NO_BEG ;
beg_tab[ I ]      = NO_BEG ;
beg_tab[ _II ]    = NO_BEG ;
beg_tab[ _I ]     = NO_BEG ;
beg_tab[ II_ ]    = NO_BEG ;
beg_tab[ I_ ]     = NO_BEG ;
beg_tab[ SI_ ]    = NO_BEG ;
beg_tab[ _I_ ]    = NO_BEG ;
//beg_tab[ _II_ ]   = NO_BEG ;
beg_tab[ DSH ]    = NO_BEG ;
//beg_tab[ DSH_ ]   = NO_BEG ;
beg_tab[ EE ]     = NO_BEG ;
beg_tab[ E ]      = NO_BEG ;
beg_tab[ _EE ]    = NO_BEG ;
beg_tab[ _E ]     = NO_BEG ;
beg_tab[ EE_ ]    = NO_BEG ;
beg_tab[ E_ ]     = NO_BEG ;
beg_tab[ _E_ ]    = NO_BEG ;
//beg_tab[ _EE_ ]   = NO_BEG ;
beg_tab[ BEE ]    = NO_BEG ;
beg_tab[ _BEE ]   = NO_BEG ;
beg_tab[ _BEE_ ]  = NO_BEG ;
beg_tab[ BEE_ ]   = NO_BEG ;
beg_tab[ NEE ]    = NO_BEG ;
beg_tab[ _NEE ]   = NO_BEG ;
beg_tab[ _NEE_ ]  = NO_BEG ;
beg_tab[ NEE_ ]   = NO_BEG ;
beg_tab[ GHEE ]   = NO_BEG ;
beg_tab[ _GHEE ]  = NO_BEG ;
beg_tab[ GHEE_ ]  = NO_BEG ;
beg_tab[ _GHEE_ ] = NO_BEG ;
beg_tab[ PEE ]    = NO_BEG ;
beg_tab[ _PEE ]   = NO_BEG ;
beg_tab[ _PEE_ ]  = NO_BEG ;
beg_tab[ PEE_ ]   = NO_BEG ;
beg_tab[ DEE ]    = IN_BEG ;
beg_tab[ _DEE ]   = IN_BEG ;
beg_tab[ REE ]    = IN_BEG ;
beg_tab[ _REE ]   = IN_BEG ;
beg_tab[ ZEE ]    = IN_BEG ;
beg_tab[ _ZEE ]   = IN_BEG ;
beg_tab[ SZEE ]   = IN_BEG ;
beg_tab[ _SZEE ]  = IN_BEG ;
beg_tab[ TEE ]    = NO_BEG ;
beg_tab[ _TEE ]   = NO_BEG ;
beg_tab[ _TEE_ ]  = NO_BEG ;
beg_tab[ TEE_ ]   = NO_BEG ;
beg_tab[ FEE ]    = NO_BEG ;
beg_tab[ _FEE ]   = NO_BEG ;
//beg_tab[ __FEE ]  = NO_BEG ;
beg_tab[ FEE_ ]   = NO_BEG ;
beg_tab[ _FEE_ ]  = NO_BEG ;
beg_tab[ KEE ]    = NO_BEG ;
beg_tab[ _KEE_ ]  = NO_BEG ;
beg_tab[ KEE_ ]   = NO_BEG ;
beg_tab[ _KEE ]   = NO_BEG ;
beg_tab[ JEE ]    = NO_BEG ;
beg_tab[ _JEE_ ]  = NO_BEG ;
beg_tab[ _JEE ]   = NO_BEG ;
beg_tab[ JEE_ ]   = NO_BEG ;
beg_tab[ NGEE ]   = NO_BEG ;
beg_tab[ _NGEE_ ] = NO_BEG ;
beg_tab[ _NGEE ]  = NO_BEG ;
beg_tab[ NGEE_ ]  = NO_BEG ;
beg_tab[ CHEE ]   = NO_BEG ;
beg_tab[ _CHEE_ ] = NO_BEG ;
beg_tab[ _CHEE ]  = NO_BEG ;
beg_tab[ CHEE_ ]  = NO_BEG ;
beg_tab[ SEE ]    = NO_BEG ;
beg_tab[ _SEE_ ]  = NO_BEG ;
beg_tab[ SEE_ ]   = NO_BEG ;
beg_tab[ _SEE ]   = NO_BEG ;
beg_tab[ QEE ]    = NO_BEG ;
beg_tab[ _QEE ]   = NO_BEG ;
beg_tab[ _QEE_ ]  = NO_BEG ;
beg_tab[ QEE_ ]   = NO_BEG ;
beg_tab[ SHEE ]   = NO_BEG ;
beg_tab[ _SHEE_ ] = NO_BEG ;
beg_tab[ SHEE_ ]  = NO_BEG ;
beg_tab[ _SHEE ]  = NO_BEG ;
beg_tab[ HEE ]    = NO_BEG ;
beg_tab[ _HEE_ ]  = NO_BEG ;
beg_tab[ _HEE ]   = NO_BEG ;
beg_tab[ HEE_ ]   = NO_BEG ;
beg_tab[ _LA ]    = WD_BEG ;
beg_tab[ LA ]     = WD_BEG ;
beg_tab[ GEE ]    = NO_BEG ;
beg_tab[ _GEE_ ]  = NO_BEG ;
beg_tab[ GEE_ ]   = NO_BEG ;
beg_tab[ _GEE ]   = NO_BEG ;
beg_tab[ LEE ]    = NO_BEG ;
beg_tab[ LEE_ ]   = NO_BEG ;
beg_tab[ _LEE_ ]  = NO_BEG ;
beg_tab[ _LEE ]   = NO_BEG ;
beg_tab[ MEE ]    = NO_BEG ;
beg_tab[ MEE_ ]   = NO_BEG ;
beg_tab[ _MEE_ ]  = NO_BEG ;
beg_tab[ _MEE ]   = NO_BEG ;
beg_tab[ YEE ]    = NO_BEG ;
beg_tab[ YEE_ ]   = NO_BEG ;
beg_tab[ _YEE_ ]  = NO_BEG ;
beg_tab[ _YEE ]   = NO_BEG ;
beg_tab[ EHE_ ]   = NO_BEG ;
beg_tab[ _EHE_ ]  = NO_BEG ;
beg_tab[ VEE ]    = IN_BEG ;
beg_tab[ _VEE ]   = IN_BEG ;

beg_tab[ U_SEMICOLON ]   = WD_BEG ;
beg_tab[ U_QUESTION ]    = WD_BEG ;
beg_tab[ U_COMMA ]    = WD_BEG ;

/* Standard Part */
beg_tab [ ONE ] = WD_BEG ;
beg_tab [ TWO ] = WD_BEG ;
beg_tab [ THREE ] = WD_BEG ;
beg_tab [ FOUR ] = WD_BEG ;
beg_tab [ FIVE ] = WD_BEG ;
beg_tab [ SIX ] = WD_BEG ;
beg_tab [ SEVEN ] = WD_BEG ;
beg_tab [ EIGHT ] = WD_BEG ;
beg_tab [ NINE ] = WD_BEG ;
beg_tab [ ZERO ] = WD_BEG ;
beg_tab [ EXCLAMATION ] = WD_BEG ;
beg_tab [ ASTERISC ] = WD_BEG ;
beg_tab [ PERCENT ] = WD_BEG ;
beg_tab [ DOLLAR ] = WD_BEG ;
beg_tab [ POUND ] = WD_BEG ;
beg_tab [ AT ] = WD_BEG ;
beg_tab [ WEDGE ] = WD_BEG ;
beg_tab [ AND ] = WD_BEG ;
beg_tab [ LPAREN ] = WD_BEG ;
beg_tab [ RPAREN ] = WD_BEG ;
beg_tab [ PLUS ] = WD_BEG ;
beg_tab [ MINUS ] = WD_BEG ;
beg_tab [ EQUAL ] = WD_BEG ;
beg_tab [ TILDE ] = WD_BEG ;
beg_tab [ DOT ] = WD_BEG ;
beg_tab [ UNDERSCORE ] = WD_BEG ;
beg_tab [ SPACE ] = WD_BEG ;
beg_tab [ TAB ] = WD_BEG ;
beg_tab [ LFEED ] = WD_BEG ;

// gac (Get As Charcode) -- returns a char code for a given character
function gac ( ascii )
{
   var str, ch ;

   str = ascii + "" ;

   ch = str.charCodeAt(0) ;

   return ch ;
};

// loads beginning, medial, and ending forms, 
//   returns immediately if already initialized
function initialize ( ) {
   var i ;

   if ( initialized == 1 ) {
      return ;
   }

   initialized = 1 ;

   for ( i = 0 ; i < rev_index.length ; i++ ) {
      rev_index[i] = 0 ;
   }
   for ( i = 0 ; i < char_code.length ; i++ ) {
      rev_index[ char_code[i] - PAD ] = i ;
   }

   // word beginning form table
   for ( i = 0 ; i < wd_beg_tab.length ; i++ ) {
      wd_beg_tab[i] = 0 ;
   }

   wd_beg_tab [ gac( 'a' ) ] = EHE_ ;
   wd_beg_tab [ gac( 'A' ) ] = EHE_ ;
   wd_beg_tab [ gac( 'b' ) ] = BEE_ ;
   wd_beg_tab [ gac( 'B' ) ] = BEE_ ;
   wd_beg_tab [ gac( 'c' ) ] = GHEE_ ;
   wd_beg_tab [ gac( 'C' ) ] = GHEE_ ;
   wd_beg_tab [ gac( 'd' ) ] = DEE ;
   wd_beg_tab [ gac( 'D' ) ] = SZEE ;
   wd_beg_tab [ gac( 'e' ) ] = EE_ ;
   wd_beg_tab [ gac( 'E' ) ] = EE_ ;
   wd_beg_tab [ gac( 'f' ) ] = AA ;
   wd_beg_tab [ gac( 'F' ) ] = FEE_ ;
   wd_beg_tab [ gac( 'g' ) ] = AE ;
   wd_beg_tab [ gac( 'G' ) ] = GEE_ ;
   wd_beg_tab [ gac( 'h' ) ] = II_ ;
   wd_beg_tab [ gac( 'H' ) ] = HEE_ ;
   wd_beg_tab [ gac( 'i' ) ] = NGEE_ ;
   wd_beg_tab [ gac( 'I' ) ] = NGEE_ ;
   wd_beg_tab [ gac( 'j' ) ] = QEE_ ;
   wd_beg_tab [ gac( 'J' ) ] = JEE_ ;
   wd_beg_tab [ gac( 'k' ) ] = KEE_ ;
   wd_beg_tab [ gac( 'K' ) ] = OE ;
   wd_beg_tab [ gac( 'l' ) ] = LEE_ ;
   wd_beg_tab [ gac( 'L' ) ] = LA ;
   wd_beg_tab [ gac( 'm' ) ] = MEE_ ;
   wd_beg_tab [ gac( 'M' ) ] = MEE_ ;
   wd_beg_tab [ gac( 'n' ) ] = NEE_ ;
   wd_beg_tab [ gac( 'N' ) ] = NEE_ ;
   wd_beg_tab [ gac( 'o' ) ] = OO ;
   wd_beg_tab [ gac( 'O' ) ] = OO ;
   wd_beg_tab [ gac( 'p' ) ] = PEE_ ;
   wd_beg_tab [ gac( 'P' ) ] = PEE_ ;
   wd_beg_tab [ gac( 'q' ) ] = CHEE_ ;
   wd_beg_tab [ gac( 'Q' ) ] = CHEE_ ;
   wd_beg_tab [ gac( 'r' ) ] = REE ;
   wd_beg_tab [ gac( 'R' ) ] = REE ;
   wd_beg_tab [ gac( 's' ) ] = SEE_ ;
   wd_beg_tab [ gac( 'S' ) ] = SEE_ ;
   wd_beg_tab [ gac( 't' ) ] = TEE_ ;
   wd_beg_tab [ gac( 'u' ) ] = UU ;
   wd_beg_tab [ gac( 'U' ) ] = UU ;
   wd_beg_tab [ gac( 'v' ) ] = UE ;
   wd_beg_tab [ gac( 'V' ) ] = UE ;
   wd_beg_tab [ gac( 'w' ) ] = VEE ;
   wd_beg_tab [ gac( 'W' ) ] = VEE ;
   wd_beg_tab [ gac( 'x' ) ] = SHEE_ ;
   wd_beg_tab [ gac( 'X' ) ] = SHEE_ ;
   wd_beg_tab [ gac( 'y' ) ] = YEE_ ;
   wd_beg_tab [ gac( 'Y' ) ] = YEE_ ;
   wd_beg_tab [ gac( 'z' ) ] = ZEE ;
   wd_beg_tab [ gac( 'Z' ) ] = ZEE ;
   wd_beg_tab [ gac( '1' ) ] = ONE ;
   wd_beg_tab [ gac( '2' ) ] = TWO ;
   wd_beg_tab [ gac( '3' ) ] = THREE ;
   wd_beg_tab [ gac( '4' ) ] = FOUR ;
   wd_beg_tab [ gac( '5' ) ] = FIVE ;
   wd_beg_tab [ gac( '6' ) ] = SIX ;
   wd_beg_tab [ gac( '7' ) ] = SEVEN ;
   wd_beg_tab [ gac( '8' ) ] = EIGHT ;
   wd_beg_tab [ gac( '9' ) ] = NINE ;
   wd_beg_tab [ gac( '0' ) ] = ZERO ;
   wd_beg_tab [ gac( '!' ) ] = EXCLAMATION ;
   wd_beg_tab [ gac( '*' ) ] = ASTERISC ;
   wd_beg_tab [ gac( '%' ) ] = PERCENT ;
   wd_beg_tab [ gac( '$' ) ] = DOLLAR ;
   wd_beg_tab [ gac( '#' ) ] = POUND ;
   wd_beg_tab [ gac( '@' ) ] = AT ;
   wd_beg_tab [ gac( '^' ) ] = WEDGE ;
   wd_beg_tab [ gac( '&' ) ] = AND ;
   wd_beg_tab [ gac( '(' ) ] = LPAREN ;
   wd_beg_tab [ gac( ')' ) ] = RPAREN ;
   wd_beg_tab [ gac( '[' ) ] = LBRACK ;
   wd_beg_tab [ gac( ']' ) ] = RBRACK ;
   wd_beg_tab [ gac( '{' ) ] = LBRACE ;
   wd_beg_tab [ gac( '}' ) ] = RBRACE ;
   wd_beg_tab [ gac( '"' ) ] = DQUOTE ;
   wd_beg_tab [ gac( '\'' ) ] = SQUOTE ;
   wd_beg_tab [ gac( '<' ) ] = LTHAN ;
   wd_beg_tab [ gac( '>' ) ] = GTHAN ;
   wd_beg_tab [ gac( '|' ) ] = PIPE ;
   wd_beg_tab [ gac( '`' ) ] = PRIM ;
   wd_beg_tab [ gac( '+' ) ] = PLUS ;
   wd_beg_tab [ gac( '-' ) ] = MINUS ;
   wd_beg_tab [ gac( '=' ) ] = EQUAL ;
   wd_beg_tab [ gac( '~' ) ] = TILDE ;
   wd_beg_tab [ gac( '.' ) ] = DOT ;
   wd_beg_tab [ gac( '_' ) ] = UNDERSCORE ;
   wd_beg_tab [ gac( ' ' ) ] = SPACE ;
   wd_beg_tab [ gac( '\n' ) ] = LFEED ;
   wd_beg_tab [ gac( '\r' ) ] = LFEED ;
   wd_beg_tab [ gac( '\t') ] = SPACE ;
   wd_beg_tab [ gac( ':' ) ] = COLON ;
   wd_beg_tab [ gac( ',' ) ] = U_COMMA ;
   wd_beg_tab [ gac( '/' ) ] = I_ ;
   wd_beg_tab [ gac( '\\' ) ] = BSLASH ;
   wd_beg_tab [ gac( '?' ) ] = U_QUESTION ;
   wd_beg_tab [ gac( ';' ) ] = U_SEMICOLON ;

   // in-word beginning form table
   for ( i = 0 ; i < in_beg_tab.length ; i++ ) {
      in_beg_tab[i] = 0 ;
   }

   in_beg_tab [ gac ( 'a' ) ] = EHE_ ;
   in_beg_tab [ gac ( 'A' ) ] = EHE_ ;
   in_beg_tab [ gac ( 'b' ) ] = BEE_ ;
   in_beg_tab [ gac ( 'B' ) ] = BEE_ ;
   in_beg_tab [ gac ( 'c' ) ] = GHEE_ ;
   in_beg_tab [ gac ( 'C' ) ] = GHEE_ ;
   in_beg_tab [ gac ( 'd' ) ] = DEE ;
   in_beg_tab [ gac ( 'D' ) ] = SZEE ;
   in_beg_tab [ gac ( 'e' ) ] = E_ ;
   in_beg_tab [ gac ( 'E' ) ] = EE_ ;
   in_beg_tab [ gac ( 'f' ) ] = _AA_ ;
   in_beg_tab [ gac ( 'F' ) ] = FEE_ ;
   in_beg_tab [ gac ( 'g' ) ] = _AE_ ;
   in_beg_tab [ gac ( 'G' ) ] = GEE_ ;
   in_beg_tab [ gac ( 'h' ) ] = SI_ ;
   in_beg_tab [ gac ( 'H' ) ] = HEE_ ;
   in_beg_tab [ gac ( 'i' ) ] = NGEE_ ;
   in_beg_tab [ gac ( 'I' ) ] = II_ ;
   in_beg_tab [ gac ( 'j' ) ] = QEE_ ;
   in_beg_tab [ gac ( 'J' ) ] = JEE_ ;
   in_beg_tab [ gac ( 'k' ) ] = KEE_ ;
   in_beg_tab [ gac ( 'K' ) ] = S_OE ;
   in_beg_tab [ gac ( 'l' ) ] = LEE_ ;
   in_beg_tab [ gac ( 'L' ) ] = LA ;
   in_beg_tab [ gac ( 'm' ) ] = MEE_ ;
   in_beg_tab [ gac ( 'M' ) ] = MEE_ ;
   in_beg_tab [ gac ( 'n' ) ] = NEE_ ;
   in_beg_tab [ gac ( 'N' ) ] = NGEE_ ;
   in_beg_tab [ gac ( 'o' ) ] = S_OO ;
   in_beg_tab [ gac ( 'O' ) ] = S_OO ;
   in_beg_tab [ gac ( 'p' ) ] = PEE_ ;
   in_beg_tab [ gac ( 'P' ) ] = PEE_ ;
   in_beg_tab [ gac ( 'q' ) ] = CHEE_ ;
   in_beg_tab [ gac ( 'Q' ) ] = CHEE_ ;
   in_beg_tab [ gac ( 'r' ) ] = REE ;
   in_beg_tab [ gac ( 'R' ) ] = REE ;
   in_beg_tab [ gac ( 's' ) ] = SEE_ ;
   in_beg_tab [ gac ( 'S' ) ] = SEE_ ;
   in_beg_tab [ gac ( 't' ) ] = TEE_ ;
   in_beg_tab [ gac ( 'T' ) ] = TEE_ ;
   in_beg_tab [ gac ( 'u' ) ] = S_UU ;
   in_beg_tab [ gac ( 'U' ) ] = S_UU ;
   in_beg_tab [ gac ( 'v' ) ] = S_UE ;
   in_beg_tab [ gac ( 'V' ) ] = S_UE ;
   in_beg_tab [ gac ( 'w' ) ] = VEE ;
   in_beg_tab [ gac ( 'W' ) ] = VEE ;
   in_beg_tab [ gac ( 'x' ) ] = SHEE_ ;
   in_beg_tab [ gac ( 'X' ) ] = SHEE_ ;
   in_beg_tab [ gac ( 'y' ) ] = YEE_ ;
   in_beg_tab [ gac ( 'Y' ) ] = YEE_ ;
   in_beg_tab [ gac ( 'z' ) ] = ZEE ;
   in_beg_tab [ gac ( 'Z' ) ] = ZEE ;
   in_beg_tab [ gac ( '1' ) ] = ONE ;
   in_beg_tab [ gac ( '2' ) ] = TWO ;
   in_beg_tab [ gac ( '3' ) ] = THREE ;
   in_beg_tab [ gac ( '4' ) ] = FOUR ;
   in_beg_tab [ gac ( '5' ) ] = FIVE ;
   in_beg_tab [ gac ( '6' ) ] = SIX ;
   in_beg_tab [ gac ( '7' ) ] = SEVEN ;
   in_beg_tab [ gac ( '8' ) ] = EIGHT ;
   in_beg_tab [ gac ( '9' ) ] = NINE ;
   in_beg_tab [ gac ( '0' ) ] = ZERO ;
   in_beg_tab [ gac ( '!' ) ] = EXCLAMATION ;
   in_beg_tab [ gac ( '*' ) ] = ASTERISC ;
   in_beg_tab [ gac ( '%' ) ] = PERCENT ;
   in_beg_tab [ gac ( '$' ) ] = DOLLAR ;
   in_beg_tab [ gac ( '#' ) ] = POUND ;
   in_beg_tab [ gac ( '@' ) ] = AT ;
   in_beg_tab [ gac ( '^' ) ] = WEDGE ;
   in_beg_tab [ gac ( '&' ) ] = AND ;
   in_beg_tab [ gac ( '(' ) ] = LPAREN ;
   in_beg_tab [ gac ( ')' ) ] = RPAREN ;
   in_beg_tab [ gac ( '[' ) ] = LBRACK ;
   in_beg_tab [ gac ( ']' ) ] = RBRACK ;
   in_beg_tab [ gac ( '{' ) ] = LBRACE ;
   in_beg_tab [ gac ( '}' ) ] = RBRACE ;
   in_beg_tab [ gac ( '"' ) ] = DQUOTE ;
   in_beg_tab [ gac ( '\'' ) ] = SQUOTE ;
   in_beg_tab [ gac ( '<' ) ] = LTHAN ;
   in_beg_tab [ gac ( '>' ) ] = GTHAN ;
   in_beg_tab [ gac ( '|' ) ] = PIPE ;
   in_beg_tab [ gac ( '`' ) ] = PRIM ;
   in_beg_tab [ gac ( '+' ) ] = PLUS ;
   in_beg_tab [ gac ( '-' ) ] = MINUS ;
   in_beg_tab [ gac ( '=' ) ] = EQUAL ;
   in_beg_tab [ gac ( '~' ) ] = TILDE ;
   in_beg_tab [ gac ( '.' ) ] = DOT ;
   in_beg_tab [ gac ( '_' ) ] = UNDERSCORE ;
   in_beg_tab [ gac ( ' ' ) ] = SPACE ;
   in_beg_tab [ gac ( '\n' ) ] = LFEED ;
   in_beg_tab [ gac ( '\r' ) ] = LFEED ;
   in_beg_tab [ gac ( '\t') ] = SPACE ;
   in_beg_tab [ gac ( ':') ] = COLON ;
   in_beg_tab [ gac ( ',' ) ] = U_COMMA ;
   in_beg_tab [ gac ( '/' ) ] = I_ ;
   in_beg_tab [ gac ( '\\' ) ] = BSLASH ;
   in_beg_tab [ gac ( '?' ) ] = U_QUESTION ;
   in_beg_tab [ gac ( ';' ) ] = U_SEMICOLON ;

   // no-beginning form table
   for ( i = 0 ; i < in_beg_tab.length ; i++ ) {
      no_beg_tab[i] = 0 ;
   }

   no_beg_tab [ gac ( 'a' ) ] = _EHE_ ;
   no_beg_tab [ gac ( 'A' ) ] = _EHE_ ;
   no_beg_tab [ gac ( 'b' ) ] = _BEE_ ;
   no_beg_tab [ gac ( 'B' ) ] = _BEE_ ;
   no_beg_tab [ gac ( 'c' ) ] = _GHEE_ ;
   no_beg_tab [ gac ( 'C' ) ] = _GHEE_ ;
   no_beg_tab [ gac ( 'd' ) ] = _DEE ;
   no_beg_tab [ gac ( 'D' ) ] = _SZEE ;
   no_beg_tab [ gac ( 'e' ) ] = _E_ ;
   no_beg_tab [ gac ( 'E' ) ] = _E_ ;
   no_beg_tab [ gac ( 'f' ) ] = _AA ;
   no_beg_tab [ gac ( 'F' ) ] = _FEE_ ;
   no_beg_tab [ gac ( 'g' ) ] = _AE ;
   no_beg_tab [ gac ( 'G' ) ] = _GEE_ ;
   no_beg_tab [ gac ( 'h' ) ] = DSH ;
   no_beg_tab [ gac ( 'H' ) ] = _HEE_ ;
   no_beg_tab [ gac ( 'i' ) ] = _NGEE_ ;
   no_beg_tab [ gac ( 'I' ) ] = _NGEE_ ;
   no_beg_tab [ gac ( 'j' ) ] = _QEE_ ;
   no_beg_tab [ gac ( 'J' ) ] = _JEE_ ;
   no_beg_tab [ gac ( 'k' ) ] = _KEE_ ;
   no_beg_tab [ gac ( 'K' ) ] = _OE ;
   no_beg_tab [ gac ( 'l' ) ] = _LEE_ ;
   no_beg_tab [ gac ( 'L' ) ] = _LA ;
   no_beg_tab [ gac ( 'm' ) ] = _MEE_ ;
   no_beg_tab [ gac ( 'M' ) ] = _MEE_ ;
   no_beg_tab [ gac ( 'n' ) ] = _NEE_ ;
   no_beg_tab [ gac ( 'N' ) ] = _NGEE_ ;
   no_beg_tab [ gac ( 'o' ) ] = _OO ;
   no_beg_tab [ gac ( 'O' ) ] = _OO ;
   no_beg_tab [ gac ( 'p' ) ] = _PEE_ ;
   no_beg_tab [ gac ( 'P' ) ] = _PEE_ ;
   no_beg_tab [ gac ( 'q' ) ] = _CHEE_ ;
   no_beg_tab [ gac ( 'Q' ) ] = _CHEE_ ;
   no_beg_tab [ gac ( 'r' ) ] = _REE ;
   no_beg_tab [ gac ( 'R' ) ] = _REE ;
   no_beg_tab [ gac ( 's' ) ] = _SEE_ ;
   no_beg_tab [ gac ( 'S' ) ] = _SEE_ ;
   no_beg_tab [ gac ( 't' ) ] = _TEE_ ;
   no_beg_tab [ gac ( 'T' ) ] = _TEE_ ;
   no_beg_tab [ gac ( 'u' ) ] = _UU ;
   no_beg_tab [ gac ( 'U' ) ] = _UU ;
   no_beg_tab [ gac ( 'v' ) ] = _UE ;
   no_beg_tab [ gac ( 'V' ) ] = _UE ;
   no_beg_tab [ gac ( 'w' ) ] = _VEE ;
   no_beg_tab [ gac ( 'W' ) ] = _VEE ;
   no_beg_tab [ gac ( 'x' ) ] = _SHEE_ ;
   no_beg_tab [ gac ( 'X' ) ] = _SHEE_ ;
   no_beg_tab [ gac ( 'y' ) ] = _YEE_ ;
   no_beg_tab [ gac ( 'Y' ) ] = _YEE_ ;
   no_beg_tab [ gac ( 'z' ) ] = _ZEE ;
   no_beg_tab [ gac ( 'Z' ) ] = _ZEE ;
   no_beg_tab [ gac ( '1' ) ] = ONE ;
   no_beg_tab [ gac ( '2' ) ] = TWO ;
   no_beg_tab [ gac ( '3' ) ] = THREE ;
   no_beg_tab [ gac ( '4' ) ] = FOUR ;
   no_beg_tab [ gac ( '5' ) ] = FIVE ;
   no_beg_tab [ gac ( '6' ) ] = SIX ;
   no_beg_tab [ gac ( '7' ) ] = SEVEN ;
   no_beg_tab [ gac ( '8' ) ] = EIGHT ;
   no_beg_tab [ gac ( '9' ) ] = NINE ;
   no_beg_tab [ gac ( '0' ) ] = ZERO ;
   no_beg_tab [ gac ( '!' ) ] = EXCLAMATION ;
   no_beg_tab [ gac ( '*' ) ] = ASTERISC ;
   no_beg_tab [ gac ( '%' ) ] = PERCENT ;
   no_beg_tab [ gac ( '$' ) ] = DOLLAR ;
   no_beg_tab [ gac ( '#' ) ] = POUND ;
   no_beg_tab [ gac ( '@' ) ] = AT ;
   no_beg_tab [ gac ( '^' ) ] = WEDGE ;
   no_beg_tab [ gac ( '&' ) ] = AND ;
   no_beg_tab [ gac ( '(' ) ] = LPAREN ;
   no_beg_tab [ gac ( ')' ) ] = RPAREN ;
   no_beg_tab [ gac ( '[' ) ] = LBRACK ;
   no_beg_tab [ gac ( ']' ) ] = RBRACK ;
   no_beg_tab [ gac ( '{' ) ] = LBRACE ;
   no_beg_tab [ gac ( '}' ) ] = RBRACE ;
   no_beg_tab [ gac ( '"' ) ] = DQUOTE ;
   no_beg_tab [ gac ( '\'' ) ] = SQUOTE ;
   no_beg_tab [ gac ( '<' ) ] = LTHAN ;
   no_beg_tab [ gac ( '>' ) ] = GTHAN ;
   no_beg_tab [ gac ( '|' ) ] = PIPE ;
   no_beg_tab [ gac ( '`' ) ] = PRIM ;
   no_beg_tab [ gac ( '+' ) ] = PLUS ;
   no_beg_tab [ gac ( '-' ) ] = MINUS ;
   no_beg_tab [ gac ( '=' ) ] = EQUAL ;
   no_beg_tab [ gac ( '~' ) ] = TILDE ;
   no_beg_tab [ gac ( '.' ) ] = DOT ;
   no_beg_tab [ gac ( '_' ) ] = UNDERSCORE ;
   no_beg_tab [ gac ( ' ' ) ] = SPACE ;
   no_beg_tab [ gac ( '\n' ) ] = LFEED ;
   no_beg_tab [ gac ( '\r' ) ] = LFEED ;
   no_beg_tab [ gac ( '\t') ] = SPACE ;
   no_beg_tab [ gac ( ':') ] = COLON ;
   no_beg_tab [ gac ( ',' ) ] = U_COMMA ;
   no_beg_tab [ gac ( '/' ) ] = _I_ ;
   no_beg_tab [ gac ( '\\' ) ] = BSLASH ;
   no_beg_tab [ gac ( '?' ) ] = U_QUESTION ;
   no_beg_tab [ gac ( ';' ) ] = U_SEMICOLON ;

   for ( i = 0 ; i < beg_form.length ; i++ ) {
      beg_form[i] = 0 ;
   }

   beg_form[ _AA ] = AA ;
   beg_form[ _AA_ ] = AA ;
   beg_form[ __AA ] = AA ;
   beg_form[ _AE ] = AE ;
   beg_form[ _AE_ ] = AE ;
   beg_form[ __AE ] = AE ;
   beg_form[ _OO ] = OO ;
   beg_form[ __OO ] = OO ;
   beg_form[ S_OO ] = OO ;
   beg_form[ _OE ] = OE ;
   beg_form[ __OE ] = OE ;
   beg_form[ S_OE ] = OE ;
   beg_form[ _UU ] = UU ;
   beg_form[ __UU ] = UU ;
   beg_form[ S_UU ] = UU ;
   beg_form[ _UE ] = UE ;
   beg_form[ __UE ] = UE ;
   beg_form[ S_UE ] = UE ;

   beg_form[ _BEE ] = BEE ;
   beg_form[ _BEE_ ] = BEE_ ;
   beg_form[ _CHEE ] = CHEE ;
   beg_form[ _CHEE_ ] = CHEE_ ;
   beg_form[ _DEE ] = DEE ;
   beg_form[ _EHE_ ] = EHE_ ;
   beg_form[ _II ] = II ;
   beg_form[ _I  ] = I ;
   //beg_form[ _II_ ] = II_ ;
   beg_form[ _I_ ] = SI_ ;
   beg_form[ DSH ] = SI_ ;
   beg_form[ _EE ] = EE ;
   beg_form[ _E  ] = E ;
   beg_form[ _E_ ] = E_ ;
   //beg_form[ _EE_ ] = EE_ ;
   beg_form[ _GEE ] = GEE ;
   beg_form[ _GEE_ ] = GEE_ ;
   beg_form[ _FEE ] = FEE ;
   beg_form[ _FEE_ ] = FEE_ ;
   beg_form[ _GHEE ] = GHEE ;
   beg_form[ _GHEE_ ] = GHEE_ ;
   beg_form[ _HEE ] = HEE ;
   beg_form[ _HEE_ ] = HEE_ ;
   beg_form[ _KEE ] = KEE ;
   beg_form[ _KEE_ ] = KEE_ ;
   beg_form[ _JEE ] = JEE ;
   beg_form[ _JEE_ ] = JEE_ ;
   beg_form[ _NGEE ] = NGEE ;
   beg_form[ _NGEE_ ] = NGEE_ ;
   beg_form[ _PEE ] = PEE ;
   beg_form[ _PEE_ ] = PEE_ ;
   beg_form[ _TEE ] = TEE ;
   beg_form[ _TEE_ ] = TEE_ ;
   beg_form[ _NEE ] = NEE ;
   beg_form[ _NEE_ ] = NEE_ ;
   beg_form[ _MEE ] = MEE ;
   beg_form[ _MEE_ ] = MEE_ ;
   beg_form[ _LEE ] = LEE ;
   beg_form[ _LEE_ ] = LEE_ ;
   beg_form[ _QEE ] = QEE ;
   beg_form[ _QEE_ ] = QEE_ ;
   beg_form[ _REE ] = REE ;
   beg_form[ _SEE ] = SEE ;
   beg_form[ _SEE_ ] = SEE_ ;
   beg_form[ _SHEE ] = SHEE ;
   beg_form[ _SHEE_ ] = SHEE_ ;
   beg_form[ _SZEE ] = SZEE ;
   beg_form[ _VEE ] = VEE ;
   beg_form[ _YEE ] = YEE ;
   beg_form[ _YEE_] = YEE_ ;
   beg_form[ _ZEE ] = ZEE ;

   beg_form[ _LA ] = LA ;

   for ( i = 0 ; i < in_beg_form.length ; i++ ) {
      in_beg_form[i] = 0 ;
   }

   in_beg_form[ AA ] = _AA_ ;
   in_beg_form[ _AA ] = _AA_ ;
   in_beg_form[ __AA ] = _AA_ ;
   in_beg_form[ AE ] = _AE_ ;
   in_beg_form[ _AE ] = _AE_ ;
   in_beg_form[ __AE ] = _AE_ ;
   in_beg_form[ OO ] = S_OO ;
   in_beg_form[ _OO ] = S_OO ;
   in_beg_form[ __OO ] = S_OO ;
   in_beg_form[ OE ] = S_OE ;
   in_beg_form[ _OE ] = S_OE ;
   in_beg_form[ __OE ] = S_OE ;
   in_beg_form[ UU ] = S_UU ;
   in_beg_form[ _UU ] = S_UU ;
   in_beg_form[ __UU ] = S_UU ;
   in_beg_form[ UE ] = S_UE ;
   in_beg_form[ _UE ] = S_UE ;
   in_beg_form[ __UE ] = S_UE ;

   in_beg_form[ _BEE ] = BEE ;
   in_beg_form[ _BEE_ ] = BEE_ ;
   in_beg_form[ _CHEE ] = CHEE ;
   in_beg_form[ _CHEE_ ] = CHEE_ ;
   in_beg_form[ _DEE ] = DEE ;
   in_beg_form[ _EHE_ ] = EHE_ ;
   in_beg_form[ _II ] = II ;
   in_beg_form[ _I  ] = I ;
   //in_beg_form[ _II_ ] = II_ ;
   in_beg_form[ _I_ ] = SI_ ;
   in_beg_form[ _EE ] = EE ;
   in_beg_form[ _E  ] = E ;
   in_beg_form[ _E_ ] = E_ ;
   //in_beg_form[ _EE_ ] = EE_ ;
   in_beg_form[ _GEE ] = GEE ;
   in_beg_form[ _GEE_ ] = GEE_ ;
   in_beg_form[ _FEE ] = FEE ;
   in_beg_form[ _FEE_ ] = FEE_ ;
   in_beg_form[ _GHEE ] = GHEE ;
   in_beg_form[ _GHEE_ ] = GHEE_ ;
   in_beg_form[ _HEE ] = HEE ;
   in_beg_form[ _HEE_ ] = HEE_ ;
   in_beg_form[ _KEE ] = KEE ;
   in_beg_form[ _KEE_ ] = KEE_ ;
   in_beg_form[ _JEE ] = JEE ;
   in_beg_form[ _JEE_ ] = JEE_ ;
   in_beg_form[ _NGEE ] = NGEE ;
   in_beg_form[ _NGEE_ ] = NGEE_ ;
   in_beg_form[ _PEE ] = PEE ;
   in_beg_form[ _PEE_ ] = PEE_ ;
   in_beg_form[ _TEE ] = TEE ;
   in_beg_form[ _TEE_ ] = TEE_ ;
   in_beg_form[ _NEE ] = NEE ;
   in_beg_form[ _NEE_ ] = NEE_ ;
   in_beg_form[ _MEE ] = MEE ;
   in_beg_form[ _MEE_ ] = MEE_ ;
   in_beg_form[ _LEE ] = LEE ;
   in_beg_form[ _LEE_ ] = LEE_ ;
   in_beg_form[ _QEE ] = QEE ;
   in_beg_form[ _QEE_ ] = QEE_ ;
   in_beg_form[ _REE ] = REE ;
   in_beg_form[ _SEE ] = SEE ;
   in_beg_form[ _SEE_ ] = SEE_ ;
   in_beg_form[ _SHEE ] = SHEE ;
   in_beg_form[ _SHEE_ ] = SHEE_ ;
   in_beg_form[ _SZEE ] = SZEE ;
   in_beg_form[ _VEE ] = VEE ;
   in_beg_form[ _YEE ] = YEE ;
   in_beg_form[ _YEE_] = YEE_ ;
   in_beg_form[ _ZEE ] = ZEE ;

   in_beg_form[ _LA ] = LA ;

   for ( i = 0 ; i < med_form.length ; i++ ) {
      med_form[i] = 0 ;
   }

   med_form[ BEE ] = BEE_ ;
   med_form[ _BEE ] = _BEE_ ;
   med_form[ CHEE ] = CHEE_ ;
   med_form[ _CHEE ] = _CHEE_ ;
   med_form[ II ] = II_ ;
   med_form[ I  ] = SI_ ;
   //med_form[ _II ] = _II_ ;
   med_form[ _II ] = _I_ ;
   med_form[ _I ] = DSH ;
   //med_form[ _I ] = _I_ ;
   med_form[ EE ] = EE_ ;
   med_form[ E ] = E_ ;
   //med_form[ E_  ] = _EE ;
   med_form[ _E ] = _E_ ;
   //med_form[ _EE ] = _EE_ ;
   med_form[ _EE ] = _E_ ;
   med_form[ GEE ] = GEE_ ;
   med_form[ _GEE ] = _GEE_ ;
   med_form[ FEE ] = FEE_ ;
   med_form[ _FEE ] = _FEE_ ;
   med_form[ GHEE ] = GHEE_ ;
   med_form[ _GHEE ] = _GHEE_ ;
   med_form[ HEE ] = HEE_ ;
   med_form[ _HEE ] = _HEE_ ;
   med_form[ KEE ] = KEE_ ;
   med_form[ _KEE ] = _KEE_ ;
   med_form[ JEE ] = JEE_ ;
   med_form[ _JEE ] = _JEE_ ;
   med_form[ NGEE ] = NGEE_ ;
   med_form[ _NGEE ] = _NGEE_ ;
   med_form[ PEE ] = PEE_ ;
   med_form[ _PEE ] = _PEE_ ;
   med_form[ TEE ] = TEE_ ;
   med_form[ _TEE ] = _TEE_ ;
   med_form[ NEE ] = NEE_ ;
   med_form[ _NEE ] = _NEE_ ;
   med_form[ MEE ] = MEE_ ;
   med_form[ _MEE ] = _MEE_ ;
   med_form[ LEE ] = LEE_ ;
   med_form[ _LEE ] = _LEE_ ;
   med_form[ QEE ] = QEE_ ;
   med_form[ _QEE ] = _QEE_ ;
   med_form[ SEE ] = SEE_ ;
   med_form[ _SEE ] = _SEE_ ;
   med_form[ SHEE ] = SHEE_ ;
   med_form[ _SHEE ] = _SHEE_ ;
   med_form[ YEE ] = YEE_ ;
   med_form[ _YEE] = _YEE_ ;

   for ( i = 0 ; i < rev_med_form.length ; i++ ) {
      rev_med_form[i] = 0 ;
   }

   rev_med_form[ AA ] = _AA ;
   rev_med_form[ _AA_ ] = _AA ;
   rev_med_form[ AE ] = _AE ;
   rev_med_form[ _AE_ ] = _AE ;
   rev_med_form[ OO ] = _OO ;
   rev_med_form[ S_OO ] = _OO ;
   rev_med_form[ OE ] = _OE ;
   rev_med_form[ S_OE ] = _OE ;
   rev_med_form[ UU ] = _UU ;
   rev_med_form[ S_UU ] = _UU ;
   rev_med_form[ UE ] = _UE ;
   rev_med_form[ S_UE ] = _UE ;

   rev_med_form[ BEE ] = _BEE ;
   rev_med_form[ BEE_ ] = _BEE_ ;
   rev_med_form[ CHEE ] = _CHEE ;
   rev_med_form[ CHEE_ ] = _CHEE_ ;
   rev_med_form[ DEE ] = _DEE ;
   rev_med_form[ EHE_ ] = _EHE_ ;
   rev_med_form[ II ] = _II ;
   rev_med_form[ I  ] = _I ;
   //rev_med_form[ II_ ] = _II_ ;
   rev_med_form[ II_ ] = _I_ ;
   rev_med_form[ SI_ ] = _I_ ;
   rev_med_form[ EE ] = _EE ;
   rev_med_form[ E ] = _E ;
   //rev_med_form[ E_  ] = _EE ;
   rev_med_form[ E_ ] = _E_ ;
   //rev_med_form[ EE_ ] = _EE_ ;
   rev_med_form[ EE_ ] = _E_ ;
   rev_med_form[ GEE ] = _GEE ;
   rev_med_form[ GEE_ ] = _GEE_ ;
   rev_med_form[ FEE ] = _FEE ;
   rev_med_form[ FEE_ ] = _FEE_ ;
   rev_med_form[ GHEE ] = _GHEE ;
   rev_med_form[ GHEE_ ] = _GHEE_ ;
   rev_med_form[ HEE ] = _HEE ;
   rev_med_form[ HEE_ ] = _HEE_ ;
   rev_med_form[ KEE ] = _KEE ;
   rev_med_form[ KEE_ ] = _KEE_ ;
   rev_med_form[ JEE ] = _JEE ;
   rev_med_form[ JEE_ ] = _JEE_ ;
   rev_med_form[ NGEE ] = _NGEE ;
   rev_med_form[ NGEE_ ] = _NGEE_ ;
   rev_med_form[ PEE ] = _PEE ;
   rev_med_form[ PEE_ ] = _PEE_ ;
   rev_med_form[ TEE ] = _TEE ;
   rev_med_form[ TEE_ ] = _TEE_ ;
   rev_med_form[ NEE ] = _NEE ;
   rev_med_form[ NEE_ ] = _NEE_ ;
   rev_med_form[ MEE ] = _MEE ;
   rev_med_form[ MEE_ ] = _MEE_ ;
   rev_med_form[ LEE ] = _LEE ;
   rev_med_form[ LEE_ ] = _LEE_ ;
   rev_med_form[ QEE ] = _QEE ;
   rev_med_form[ QEE_ ] = _QEE_ ;
   rev_med_form[ REE ] = _REE ;
   rev_med_form[ SEE ] = _SEE ;
   rev_med_form[ SEE_ ] = _SEE_ ;
   rev_med_form[ SHEE ] = _SHEE ;
   rev_med_form[ SHEE_ ] = _SHEE_ ;
   rev_med_form[ SZEE ] = _SZEE ;
   rev_med_form[ VEE ] = _VEE ;
   rev_med_form[ YEE ] = _YEE ;
   rev_med_form[ YEE_ ] = _YEE_ ;
   rev_med_form[ ZEE ] = _ZEE ;

   rev_med_form[ LA ] = _LA ;

   for ( i = 0 ; i < end_form.length ; i++ ) {
      end_form[i] = 0 ;
   }

   end_form[ BEE_ ] = BEE ;
   end_form[ _BEE_ ] = _BEE ;
   end_form[ CHEE_ ] = CHEE ;
   end_form[ _CHEE_ ] = _CHEE ;
   end_form[ II_ ] = II ;
   end_form[ SI_  ] = I ;
   //end_form[ _II_ ] = _II ;
   end_form[ DSH ] = _I ;
   //end_form[ _I_ ] = _I ;
   end_form[ EE_ ] = EE ;
   end_form[ E_  ] = E ;
   end_form[ _E_ ] = _E ;
   //end_form[ _EE_ ] = _EE ;
   end_form[ GEE_ ] = GEE ;
   end_form[ _GEE_ ] = _GEE ;
   end_form[ FEE_ ] = FEE ;
   end_form[ _FEE_ ] = _FEE ;
   end_form[ GHEE_ ] = GHEE ;
   end_form[ _GHEE_ ] = _GHEE ;
   end_form[ HEE_ ] = HEE ;
   end_form[ _HEE_ ] = _HEE ;
   end_form[ KEE_ ] = KEE ;
   end_form[ _KEE_ ] = _KEE ;
   end_form[ JEE_ ] = JEE ;
   end_form[ _JEE_ ] = _JEE ;
   end_form[ NGEE_ ] = NGEE ;
   end_form[ _NGEE_ ] = _NGEE ;
   end_form[ PEE_ ] = PEE ;
   end_form[ _PEE_ ] = _PEE ;
   end_form[ TEE_ ] = TEE ;
   end_form[ _TEE_ ] = _TEE ;
   end_form[ NEE_ ] = NEE ;
   end_form[ _NEE_ ] = _NEE ;
   end_form[ MEE_ ] = MEE ;
   end_form[ _MEE_ ] = _MEE ;
   end_form[ LEE_ ] = LEE ;
   end_form[ _LEE_ ] = _LEE ;
   end_form[ QEE_ ] = QEE ;
   end_form[ _QEE_ ] = _QEE ;
   end_form[ SEE_ ] = SEE ;
   end_form[ _SEE_ ] = _SEE ;
   end_form[ SHEE_ ] = SHEE ;
   end_form[ _SHEE_ ] = _SHEE ;
   end_form[ YEE_ ] = YEE ;
   end_form[ _YEE_ ] = _YEE ;
};

/*
 * Returns a string according to the input cur. 
 * The input cur is expected to be the ascii code of the key pressed. 
 * However, prev and next are in Unicode representation. Both prev and next
 * may be updated depending on the their original shapes and the input cur.
 */
function getContextString ( prev, cur, next )
{
   var str, str1, str2 ;
   var code, code1, code2 ;
   var idx, idx1, idx2 ;

   // TODO: don't check this every time, move it to "onLoad"
   if ( initialized != 1 ) {
      initialize () ;
   }

   // backspace or delete pressed
   if ( cur == -1 ) {
      if ( prev == -1 ) { // nothing in front
         if ( next == -1 ) { // nothing in the back
            return "" ;
         } else {
            if ( ! isInPF(next) ) {
               return String.fromCharCode ( next ) ;
            }

            idx2 = getIndex ( next ) ;
            if ( beg_form[idx2] != 0 ) {
               code2 = getUniCode ( beg_form[idx2] ) ;
            } else {
               code2 = next ;
            }
            return String.fromCharCode ( code2 ) ;
         }
      } else if ( next == -1 ) {
         if ( prev < 0xFB00 ) {
            return String.fromCharCode ( prev ) ;
         }

         idx = getIndex ( prev ) ;
         if ( end_form[idx] != 0 ) {
            code = getUniCode ( end_form[idx] ) ;
         } else {
            code = prev ;
         }
         return String.fromCharCode ( code ) ;
      } else {
         if ( ! isInPF(prev) ) {
            if (! isInPF(next) ) {
               return String.fromCharCode ( prev, next ) ;
            } else {
               idx2 = getIndex ( next ) ;
               if ( beg_form[idx2] != 0 ) {
                  code2 = getUniCode ( beg_form[idx2] ) ;
               } else {
                  code2 = next ;
               }
               return String.fromCharCode ( prev, code2 ) ;
            }
         } else if ( ! isInPF(next) ) {
            idx = getIndex ( prev ) ;
            if ( end_form[idx] != 0 ) {
                code = getUniCode ( end_form[idx] ) ;
            } else {
               code = prev ;
            }
            return String.fromCharCode ( code, next ) ;
         }

         idx = getIndex ( prev ) ;
         idx2 = getIndex ( next ) ;
         code = prev ;

         str2 = joint_special ( idx, idx2 ) ;
         if ( str2 != "" ) {
            return str2 ;
         }

         if ( beg_tab[idx] == WD_BEG ) {
            if ( beg_form[idx2] != 0 ) {
               code2 = getUniCode ( beg_form[idx2] ) ;
            } else {
               code2 = next ;
            }
         } else if ( beg_tab[idx] == IN_BEG ) {
            if ( in_beg_form[idx2] != 0 ) {
               code2 = getUniCode ( in_beg_form[idx2] ) ;
            } else {
               code2 = next ;
            }
         } else {
            if ( med_form[idx] != 0 ) {
               code = getUniCode( med_form[idx] ) ;
            } else {
               code = prev ;
            }

            if ( rev_med_form[idx2] != 0 ) {
               code2 = getUniCode ( rev_med_form[idx2] ) ;
            } else {
               code2 = next ;
            }
         }
      }
      return String.fromCharCode ( code, code2 ) ;
   }

   // a regular input key is pressed (non-backspace, non-delete)
   if ( prev == -1 ) {  // nothing in front, inserting text at the beginning of text
      if ( next == -1 ) {  // and nothing in back, the first character
         idx1 = map_index ( cur, -1 ) ;
         code = getUniCode ( idx1 ) ;
         if ( end_form[idx1] != 0 ) {
            code = getUniCode ( end_form[idx1] ) ;
         }
         str = String.fromCharCode ( code ) ;
      } else { // inserting at the beginning of the text 
         if ( ! isInPF(next) ) {
            str = getContextString ( -1, cur, -1 ) + String.fromCharCode(next) ;
            return str ;
         }

         idx1 = map_index ( cur, prev ) ;
         idx2 = getIndex ( next ) ;  // next charcode index
         code1 = getUniCode ( idx1 ) ;

         if ( is_alien ( idx1 ) || is_wd_beginner(idx1) ) {
            if ( beg_form[idx2] != 0 ) {
               code2 = getUniCode ( beg_form[idx2] ) ;
            } else {
               code2 = next ;
            }
         } else if ( is_in_beginner ( idx1 ) ) {
            if ( in_beg_form[idx2] != 0 ) {
               code2 = getUniCode ( in_beg_form[idx2] ) ;
            } else {
               code2 = next ;
            }
         } else {
            str2 = joint_special ( idx1, idx2 ) ;
            if ( str2 != "" ) {
               return str2 ;
            }

            if ( rev_med_form[idx2] != 0 ) { // update the next letter if necessary
               code2 = getUniCode ( rev_med_form[idx2] ) ;
            } else {
               code2 = next ;
            }
         }

         str = String.fromCharCode ( code1, code2 ) ;
      }
   } else if ( next == -1 ) { // inserting text at the end of the text 

      if ( ! isInPF(prev) ) {
         str = String.fromCharCode(prev) + getContextString ( -1, cur, -1 ) ;
         return str ;
      }

      idx = getIndex ( prev ) ;
      code1 = getUniCode ( map_index ( cur, idx ) ) ; // ucode for cur

      idx1 = getIndex ( code1 ) ;  // current code index

      str2 = joint_special ( idx, idx1 ) ;

      if ( str2 != "" ) {
         return str2 ;
      }

      if ( is_alien (idx1) == true ) { // if cur is not regular char
         if ( end_form[ idx ] != 0 ) { // check for end form
            code = getUniCode ( end_form[idx] ) ;

            str = String.fromCharCode ( code, getUniCode(idx1) ) ;
         } else {
            str = String.fromCharCode ( prev, code1 ) ;
         }
      } else {
         if ( med_form[idx] != 0 ) {  // see if to use medial form
            code = getUniCode ( med_form[idx] ) ;
         } else {
            code = prev ;
         }

         if ( end_form[idx1] != 0 ) {
            code1 = getUniCode ( end_form[idx1] ) ;
         }

         str = String.fromCharCode ( code, code1 ) ;
      }
   } else { // inserting a letter in the middle of the text
      idx = getIndex ( prev ) ;  // previous charcode index
      code = getUniCode ( map_index ( cur, idx ) ) ; // ucode for cur

      idx1 = getIndex ( code ) ;  // current code index
      idx2 = getIndex ( next ) ;  // next charcode index

      /*
      if ( next == String("\r").charCodeAt(0) ) {
         str = getContextString ( prev, cur, -1 ) + String.fromCharCode(next) ;
         return str ;
      }
      */
      if ( ! isInPF(prev) ) {
         if ( ! isInPF(next) ) {
            str=String.fromCharCode(prev)+getContextString(-1,cur,-1)+String.fromCharCode(next);
         } else {
            str= String.fromCharCode(prev) + getContextString(-1, cur, next);
         }
         return str ;
      }

      //if ( next < 128 || next==getUniCode(U_COMMA) || next==getUniCode(U_QUESTION) ) {
      if ( ! isInPF(next) ) {
         if ( ! isInPF(prev) ) {
            str=String.fromCharCode(prev)+getContextString(-1,cur,-1)+String.fromCharCode(next);
         } else {
            str= getContextString(prev,cur, -1) + String.fromCharCode(next) ;
         }
         return str ;
      }

      if ( is_alien ( idx1 ) ) {
         if ( end_form[ idx ] != 0 ) { // check for end form
            code1 = getUniCode ( end_form[idx] ) ;

            str1 = String.fromCharCode ( code1, getUniCode(idx1) ) ;
         } else {
            str1 = String.fromCharCode ( prev, code ) ;
         }

         if ( beg_form[idx2] != 0 ) {
            str2 = String.fromCharCode ( getUniCode ( beg_form[idx2] ) ) ;
         } else {
            str2 = String.fromCharCode(next) ;
         }

         str = str1.concat ( str2 ) ;
      } else if ( is_wd_beginner ( idx1 ) ) {
         if ( beg_form[idx2] != 0 ) {
            str2 = String.fromCharCode ( getUniCode ( beg_form[idx2] ) ) ;
         } else {
            str2 = String.fromCharCode(next) ;
         }


         str1 = joint_special ( idx, idx1 ) ;
         if ( str1 != "" ) {
            return str1.concat ( str2 ) ;
         }

         if ( med_form[idx] != 0 ) {  // see if to use medial form
            code1 = getUniCode ( med_form[idx] ) ;
         } else {
            code1 = prev ;
         }

         str1 = String.fromCharCode ( code1, code ) ;

         str = str1.concat ( str2 ) ;
      } else if ( is_in_beginner(idx1) ) {
         if ( in_beg_form[idx2] != 0 ) {
            str2 = String.fromCharCode ( getUniCode ( in_beg_form[idx2] ) ) ;
         } else {
            str2 = String.fromCharCode ( next ) ;
         }

         str1 = joint_special ( idx, idx1 ) ;
         if ( str1 != "" ) {
            return str1.concat ( str2 ) ;
         }

         if ( med_form[idx] != 0 ) {  // see if to use medial form
            code1 = getUniCode ( med_form[idx] ) ;
         } else {
            code1 = prev ;
         }

         str1 = String.fromCharCode ( code1, code ) ;

         str = str1.concat ( str2 ) ;
      } else {
         if ( med_form[idx] != 0 ) {  // see if to use medial form
            code1 = getUniCode ( med_form[idx] ) ;
         } else {
            code1 = prev ;
         }

         str2 = joint_special ( idx1, idx2 ) ;
         if ( str2 != "" ) {
            str1 = String.fromCharCode ( code1 ) ;
            return str1.concat ( str2 ) ;
         }

         if ( rev_med_form[idx2] != 0 ) { // update the next letter if necessary
            code2 = getUniCode ( rev_med_form[idx2] ) ;
         } else {
            code2 = getUniCode ( idx2 ) ;
         }

         str = String.fromCharCode ( code1, code, code2 ) ;
      }
   }

   return str ;
};

/*
 * joint_special ( idx1, idx2 ) -- return a single character string if idx1 and
 *  idx2 forms a special joint letter such as LA, _LA, __AA, etc.
 */
function joint_special ( idx1, idx2 ) {
   var i = -1 ;

   if ( idx1 == LEE || idx1 == LEE_ ) { // for LA
      if ( idx2 == AA || idx2 == _AA || idx2 == _AA_ || idx2 == __AA ) {
         i = LA ;
      }
   } else if ( idx1 == _LEE || idx1 == _LEE_ ) { // for _LA
      if ( idx2 == AA || idx2 == _AA || idx2 == _AA_ || idx2 == __AA ) {
         i = _LA ;
      }
   } else if ( idx1 == I_ ) { // for I_ + _AA = AA, _I_ + _AA = __AA, etc.
      if ( idx2 == AA || idx2 == _AA || idx2 == _AA_ ) {
         i = AA ;
      } else if ( idx2 == AE || idx2 == _AE || idx2 == _AE_ ) {
         i = AE ;
      } else if ( idx2 == OO || idx2 == _OO || idx2 == S_OO ) {
         i = OO ;
      } else if ( idx2 == OE || idx2 == _OE || idx2 == S_OE ) {
         i = OE ;
      } else if ( idx2 == UU || idx2 == _UU || idx2 == S_UU ) {
         i = UU ;
      } else if ( idx2 == UE || idx2 == _UE || idx2 == S_UE ) {
         i = UE ;
      } else if ( idx2 == DSH ) {
         //i = II ;
      } else if ( idx2 == _E_ ) {
         //i = EE ;
      }
   } else if ( idx1 == _I_ ) {
      if ( idx2 == AA || idx2 == _AA || idx2 == _AA_ ) {
         i = __AA ;
      } else if ( idx2 == AE || idx2 == _AE || idx2 == _AE_ ) {
         i = __AE ;
      } else if ( idx2 == OO || idx2 == _OO || idx2 == S_OO ) {
         i = __OO ;
      } else if ( idx2 == OE || idx2 == _OE || idx2 == S_OE ) {
         i = __OE ;
      } else if ( idx2 == UU || idx2 == _UU || idx2 == S_UU ) {
         i = __UU ;
      } else if ( idx2 == UE || idx2 == _UE || idx2 == S_UE ) {
         i = __UE ;
      } else if ( idx2 == DSH ) {
         //i = _II ;
      } else if ( idx2 == _E_ ) {
         //i = _EE ;
      }
   }

   if ( i != -1 ) {
      return String.fromCharCode ( getUniCode ( i ) ) ;
   }

   return "" ;
}

function is_alien ( code )
{
   if ( code > _VEE ) {
      return true ;
   }
   // The code above takes advantage of index order, use this if you are changing that order:
   /*
   if ( code == SPACE || code == DOT || code == EXCLAMATION || code == U_QUESTION ||
         code == U_SEMICOLON || code == U_COMMA || code == MINUS || code == ONE ||
         code == TWO || code == THREE || code == FOUR || code == FIVE ||
         code == SIX || code == SEVEN || code == EIGHT || code == NINE ||
         code == ZERO || code == ASTERISC || code == PERCENT || code == DOLLAR ||
         code == POUND || code == AT || code == WEDGE || code == AND ||
         code == LPAREN || code == RPAREN || code == PLUS || code == EQUAL ||
         code == TILDE || code == UNDERSCORE || code == COLON || code == LFEED ||
         code == DQUOTE || code == SQUOTE || code == RBRACK || code == LBRACK ||
         code == LBRACE || code == RBRACE || code == LTHAN || code == GTHAN ||
         code == FSLASH || code == PIPE || code == PRIM ) {
      return true ;
   } 
   */

   return false ;
};

/*
 * is_wd_beginner ( idx ) -- returns true if idx represents an Uyghur character that
 * mandates the next character be in the beginning form.
 */
function is_wd_beginner ( idx ) // should next character be in beginning form
{
   if ( idx == AA || idx == _AA_ || idx == _AA || idx == __AA ||
         idx == AE || idx == _AE_ || idx == _AE || idx == __AE ||
         idx == LA || idx == _LA ) {
      return true ;
   }

   return false ;
};

/*
 * is_wd_beginner ( idx ) -- returns true if idx represents an Uyghur character that
 * mandates the next character be in the in-word beginning form.
 */
function is_in_beginner ( idx )//should next character be in in-word beginning form
{
   return beg_tab[idx] == IN_BEG ;
};


function getUniCode ( charCode )
{
   var ucode ;

   ucode = char_code[charCode] ;

   return ucode ;
};

/*
 * getIndex ( uniChar ) -- reverse lookup the index from code_char table
 */
function getIndex ( uniChar )
{
   // This function is function is changed on Aug. 13, 2004 to use a table (rev_index) instead of
   // searching through sequentially to find a corresponding index for a Unicode character number.
   var i = rev_index [ uniChar - PAD ] ;

   return i != 0 ? i : SPACE ;
};

/* isInPF -- returns true if code is in Arabic Presentation Form range, false otherwise.
 */
function isInPF ( code ) {
   if ( (0xFB50 <= code && code <= 0xFDFF) || (0xFE70 <= code && code <= 0xFEFF) ) {
      return true;
   }

   return false;
}

/*
 * map_index ( input, prev ) -- returns the index for input according to the previous character
 * This function is changed on Aug. 13, 2004 to use a table to return indices instead of stepping
 * through a long switch statement.
 */
function map_index ( input, prev )
{
   var wd_beg, in_beg ;

   var str = String.fromCharCode ( input ) ;
   cur = str.charAt(0) ;

   wd_beg = beg_tab [prev] ;

   if ( wd_beg != WD_BEG ) {
      in_beg = beg_tab[prev] ;
   }

   if ( wd_beg == WD_BEG || prev == -1 ) {
      return ( wd_beg_tab[input] ) ;
   } else if ( in_beg == IN_BEG ) {
      return ( in_beg_tab[input] ) ;
   } else {
      return ( no_beg_tab[input] ) ;
   }
}