BidiEngine.js 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506
  1. define("dojox/string/BidiEngine", ["dojo/_base/lang", "dojo/_base/declare"],
  2. function(lang,declare){
  3. lang.getObject("string", true, dojox);
  4. declare("dojox.string.BidiEngine", null, {
  5. // summary:
  6. // This class provides a bidi transformation engine, i.e.
  7. // functions for reordering and shaping bidi text.
  8. // description:
  9. // Bidi stands for support for languages with a bidirectional script.
  10. //
  11. // Usually Unicode Bidi Algorithm used by OS platform (and web browsers) is capable of properly transforming
  12. // Bidi text and as a result it is adequately displayed on the screen. However, in some situations,
  13. // Unicode Bidi Algorithm is not invoked or is not properly applied. This may occur in situation in which software
  14. // responsible for rendering the text is not leveraging Unicode Bidi Algorithm implemented by OS (e.g. dojox.GFX renderers).
  15. //
  16. // Bidi engine provided in this class implements Unicode Bidi Algorithm as specified at:
  17. // http://www.unicode.org/reports/tr9/.
  18. //
  19. // For more information on basic Bidi concepts please read following article:
  20. // "Bidirectional script support - A primer" available from:
  21. // http://www.ibm.com/developerworks/websphere/library/techarticles/bidi/bidigen.html
  22. //
  23. // As of February 2011, Bidi engine has following limitations:
  24. // 1. No support for following numeric shaping options:
  25. // H - Hindi,
  26. // C - Contextual,
  27. // N - Nominal.
  28. // 2. No support for following shaping options:
  29. // I - Initial shaping,
  30. // M - Middle shaping,
  31. // F - Final shaping,
  32. // B - Isolated shaping.
  33. // 3. No support for source-to-target or/and target-to-source maps.
  34. // 4. No support for LRE/RLE/LRO/RLO/PDF (they are handled like neutrals).
  35. // 5. No support for Windows compatibility.
  36. // 6. No support for insert/remove marks.
  37. // 7. No support for code pages (currently only UTF-8 is supported. Ideally we should convert from any code page to UTF-8).
  38. bidiTransform: function (/*String*/text, /*String*/formatIn, /*String*/formatOut){
  39. // summary:
  40. // Central public API for Bidi engine. Transforms the text according to formatIn, formatOut parameters.
  41. // If formatIn or formatOut parametrs are not valid throws an exception.
  42. // inputText:
  43. // Input text subject to application of Bidi transformation.
  44. // formatIn:
  45. // Input Bidi layout in which inputText is passed to the function.
  46. // formatOut:
  47. // Output Bidi layout to which inputText should be transformed.
  48. // description:
  49. // Both formatIn and formatOut parameters are 5 letters long strings.
  50. // For example - "ILYNN". Each letter is associated with specific attribute of Bidi layout.
  51. // Possible and default values for each one of the letters are provided below:
  52. //
  53. // First letter:
  54. // Letter position/index:
  55. // 1
  56. // Letter meaning:
  57. // Ordering Schema.
  58. // Possible values:
  59. // I - Implicit (Logical).
  60. // V - Visual.
  61. // Default value:
  62. // I
  63. //
  64. // Second letter:
  65. // Letter position/index:
  66. // 2
  67. // Letter meaning:
  68. // Orientation.
  69. // Possible values:
  70. // L - Left To Right.
  71. // R - Right To Left.
  72. // C - Contextual Left to Right.
  73. // D - Contextual Right to Left.
  74. // Default value:
  75. // L
  76. //
  77. // Third letter:
  78. // Letter position/index:
  79. // 3
  80. // Letter meaning:
  81. // Symmetric Swapping.
  82. // Possible values:
  83. // Y - Symmetric swapping is on.
  84. // N - Symmetric swapping is off.
  85. // Default value:
  86. // Y
  87. //
  88. // Fourth letter:
  89. // Letter position/index:
  90. // 4
  91. // Letter meaning:
  92. // Shaping.
  93. // Possible values:
  94. // S - Text is shaped.
  95. // N - Text is not shaped.
  96. // Default value:
  97. // N
  98. //
  99. // Fifth letter:
  100. // Letter position/index:
  101. // 5
  102. // Letter meaning:
  103. // Numeric Shaping.
  104. // Possible values:
  105. // N - Nominal.
  106. // Default value:
  107. // N
  108. //
  109. // The output of this function is original text (passed via first argument) transformed from input Bidi layout (second argument)
  110. // to output Bidi layout (last argument).
  111. //
  112. // Sample call:
  113. // | mytext = bidiTransform("HELLO WORLD", "ILYNN", "VLYNN");
  114. // In this case, "HELLO WORLD" text is transformed from Logical - LTR to Visual - LTR Bidi layout with
  115. // default values for symmetric swapping (Yes), shaping (Not shaped) and numeric shaping (Nominal).
  116. // returns: /*String*/ or throws an exception.
  117. // Original text transformed from input Bidi layout (second argument)
  118. // to output Bidi layout (last argument).
  119. // Throws an exception if the bidi layout strings are not valid.
  120. // tags:
  121. // public
  122. if(!text){
  123. return '';
  124. }
  125. if(!formatIn && !formatOut){
  126. return text;
  127. }
  128. // regex for format validation
  129. // Allowed values for format string are:
  130. // 1st letter- I, V
  131. // 2nd letter- L, R, C, D
  132. // 3rd letter- Y, N
  133. // 4th letter- S, N
  134. // 5th letter- N
  135. var validFormat = /^[(I|V)][(L|R|C|D)][(Y|N)][(S|N)][N]$/;
  136. if(!validFormat.test(formatIn) || !validFormat.test(formatOut)){
  137. throw new Error("dojox.string.BidiEngine: the bidi layout string is wrong!");
  138. }
  139. if(formatIn == formatOut){
  140. return text;
  141. }
  142. var orientIn = getOrientation(formatIn.charAt(1))
  143. , orientOut = getOrientation(formatOut.charAt(1))
  144. , os_in = (formatIn.charAt(0) == 'I') ? 'L' : formatIn.charAt(0)
  145. , os_out = (formatOut.charAt(0) == 'I') ? 'L' : formatOut.charAt(0)
  146. , inFormat = os_in + orientIn
  147. , outFormat = os_out + orientOut
  148. , swap = formatIn.charAt(2) + formatOut.charAt(2)
  149. ;
  150. if(inFormat){
  151. bdx.defInFormat = inFormat;
  152. }
  153. if(outFormat){
  154. bdx.defOutFormat = outFormat;
  155. }
  156. if(swap){
  157. bdx.defSwap = swap;
  158. }
  159. var stage1_text = doBidiReorder(text, os_in + orientIn, os_out + orientOut, formatIn.charAt(2) + formatOut.charAt(2))
  160. , isRtl = false;
  161. if(formatOut.charAt(1) == 'R'){
  162. isRtl = true;
  163. }else if(formatOut.charAt(1) == 'C' || formatOut.charAt(1) == 'D'){
  164. isRtl = this.checkContextual(stage1_text);
  165. }
  166. if(formatIn.charAt(3) == formatOut.charAt(3)){
  167. return stage1_text;
  168. }else if(formatOut.charAt(3) == 'S'){
  169. return shape(isRtl, stage1_text, true);
  170. }
  171. if(formatOut.charAt(3) == 'N'){
  172. return deshape(stage1_text, isRtl, true);
  173. }
  174. },
  175. checkContextual: function(/*String*/text){
  176. // summary:
  177. // Determine the base direction of a bidi text according
  178. // to its first strong directional character.
  179. // text:
  180. // The text to check.
  181. // returns: /*String*/
  182. // "ltr" or "rtl" according to the first strong character.
  183. // If there is no strong character, returns the value of the
  184. // document dir property.
  185. // tags:
  186. // public
  187. var dir = firstStrongDir(text);
  188. if(dir != "ltr" && dir != "rtl"){
  189. dir = document.dir.toLowerCase();
  190. if(dir != "ltr" && dir != "rtl"){dir = "ltr";}
  191. }
  192. return dir;
  193. },
  194. hasBidiChar: function(/*String*/text){
  195. // summary:
  196. // Return true if text contains RTL directed character.
  197. // text:
  198. // The source string.
  199. // description:
  200. // Iterates over the text string, letter by letter starting from its beginning,
  201. // searching for RTL directed character.
  202. // Return true if found else false. Needed for vml transformation.
  203. // returns: /*Boolean*/
  204. // true - if text has a RTL directed character.
  205. // false - otherwise.
  206. // tags:
  207. // public
  208. var type = null, uc = null, hi = null;
  209. for(var i = 0; i < text.length; i++){
  210. uc = text.charAt(i).charCodeAt(0);
  211. hi = MasterTable[uc >> 8];
  212. type = hi < TBBASE ? hi : UnicodeTable[hi - TBBASE][uc & 0xFF];
  213. if(type == UBAT_R || type == UBAT_AL){
  214. return true;
  215. }
  216. if(type == UBAT_B){
  217. break;
  218. }
  219. }
  220. return false;
  221. }
  222. });
  223. function doBidiReorder(/*String*/text, /*String*/inFormat,
  224. /*String*/outFormat, /*String*/swap){
  225. // summary:
  226. // Reorder the source text according to the bidi attributes
  227. // of source and result.
  228. // text:
  229. // The text to reorder.
  230. // inFormat:
  231. // Ordering scheme and base direction of the source text.
  232. // Can be "LLTR", "LRTL", "LCLR", "LCRL", "VLTR", "VRTL",
  233. // "VCLR", "VCRL".
  234. // The first letter is "L" for logical ordering scheme,
  235. // "V" for visual ordering scheme.
  236. // The other letters specify the base direction.
  237. // "CLR" means contextual direction defaulting to LTR if
  238. // there is no strong letter.
  239. // "CRL" means contextual direction defaulting to RTL if
  240. // there is no strong letter.
  241. // The initial value is "LLTR", if none, the initial value is used.
  242. // outFormat:
  243. // Required ordering scheme and base direction of the
  244. // result. Has the same format as inFormat.
  245. // If none, the initial value "VLTR" is used.
  246. // swap:
  247. // Symmetric swapping attributes of source and result.
  248. // The allowed values can be "YN", "NY", "YY" and "NN".
  249. // The first letter reflects the symmetric swapping attribute
  250. // of the source, the second letter that of the result.
  251. // returns:
  252. // Text reordered according to source and result attributes.
  253. if(inFormat == undefined){
  254. inFormat = bdx.defInFormat;
  255. }
  256. if(outFormat == undefined){
  257. outFormat = bdx.defOutFormat;
  258. }
  259. if(swap == undefined){
  260. swap = bdx.defSwap;
  261. }
  262. if(inFormat == outFormat){
  263. return text;
  264. }
  265. var dir, inOrdering = inFormat.substring(0,1)
  266. , inOrientation = inFormat.substring(1,4)
  267. , outOrdering = outFormat.substring(0,1)
  268. , outOrientation = outFormat.substring(1,4)
  269. ;
  270. if(inOrientation.charAt(0) == "C"){
  271. dir = firstStrongDir(text);
  272. if(dir == "ltr" || dir == "rtl"){
  273. inOrientation = dir.toUpperCase();
  274. }else{
  275. inOrientation = inFormat.charAt(2) == "L" ? "LTR" : "RTL";
  276. }
  277. inFormat = inOrdering + inOrientation;
  278. }
  279. if(outOrientation.charAt(0) == "C"){
  280. dir = firstStrongDir(text);
  281. if(dir == "rtl"){
  282. outOrientation = "RTL";
  283. }else if(dir == "ltr"){
  284. dir = lastStrongDir(text);
  285. outOrientation = dir.toUpperCase();
  286. }else{
  287. outOrientation = outFormat.charAt(2) == "L" ? "LTR" : "RTL";
  288. }
  289. outFormat = outOrdering + outOrientation;
  290. }
  291. if(inFormat == outFormat){
  292. return text;
  293. }
  294. bdx.inFormat = inFormat;
  295. bdx.outFormat = outFormat;
  296. bdx.swap = swap;
  297. if((inOrdering == "L") && (outFormat == "VLTR")){ //core cases
  298. //cases: LLTR->VLTR, LRTL->VLTR
  299. if(inOrientation == "LTR"){
  300. bdx.dir = LTR;
  301. return doReorder(text);
  302. }
  303. if(inOrientation == "RTL"){
  304. bdx.dir = RTL;
  305. return doReorder(text);
  306. }
  307. }
  308. if((inOrdering == "V") && (outOrdering == "V")){
  309. //inOrientation != outOrientation
  310. //cases: VRTL->VLTR, VLTR->VRTL
  311. return invertStr(text);
  312. }
  313. if((inOrdering == "L") && (outFormat == "VRTL")){
  314. //cases: LLTR->VRTL, LRTL->VRTL
  315. if(inOrientation == "LTR"){
  316. bdx.dir = LTR;
  317. text = doReorder(text);
  318. }else{
  319. //inOrientation == RTL
  320. bdx.dir = RTL;
  321. text = doReorder(text);
  322. }
  323. return invertStr(text);
  324. }
  325. if((inFormat == "VLTR") && (outFormat == "LLTR")){
  326. //case: VLTR->LLTR
  327. bdx.dir = LTR;
  328. return doReorder(text);
  329. }
  330. if((inOrdering == "V") && (outOrdering == "L") && (inOrientation != outOrientation)){
  331. //cases: VLTR->LRTL, VRTL->LLTR
  332. text = invertStr(text);
  333. return (inOrientation == "RTL") ? doBidiReorder(text, "LLTR","VLTR", swap) : doBidiReorder(text, "LRTL","VRTL", swap);
  334. }
  335. if((inFormat == "VRTL") && (outFormat == "LRTL")){
  336. //case VRTL->LRTL
  337. return doBidiReorder(text, "LRTL","VRTL", swap);
  338. }
  339. if((inOrdering == "L") && (outOrdering == "L")){
  340. //inOrientation != outOrientation
  341. //cases: LRTL->LLTR, LLTR->LRTL
  342. var saveSwap = bdx.swap;
  343. bdx.swap = saveSwap.substr(0, 1) + "N";
  344. if(inOrientation == "RTL"){
  345. //LRTL->LLTR
  346. bdx.dir = RTL;
  347. text = doReorder(text);
  348. bdx.swap = "N" + saveSwap.substr(1, 2);
  349. bdx.dir = LTR;
  350. text = doReorder(text);
  351. }else{ //LLTR->LRTL
  352. bdx.dir = LTR;
  353. text = doReorder(text);
  354. bdx.swap = "N" + saveSwap.substr(1, 2);
  355. text = doBidiReorder(text, "VLTR","LRTL", bdx.swap);
  356. }
  357. return text;
  358. }
  359. };
  360. function shape(/*boolean*/rtl, /*String*/text, /*boolean*/compress){
  361. // summary:
  362. // Shape the source text.
  363. // rtl:
  364. // Flag indicating if the text is in RTL direction (logical
  365. // direction for Arabic words).
  366. // text:
  367. // The text to shape.
  368. // compress:
  369. // A flag indicates to insert extra space after the lam alef compression
  370. // to preserve the buffer size or not insert an extra space which will lead
  371. // to decrease the buffer size. this option can be:
  372. // - true (default) to not insert extra space after compressing Lam+Alef into one character Lamalef
  373. // - false to insert an extra space after compressed Lamalef to preserve the buffer size
  374. // returns:
  375. // text shaped.
  376. // tags:
  377. // private.
  378. if(text.length == 0){
  379. return;
  380. }
  381. if(rtl == undefined){
  382. rtl = true;
  383. }
  384. if(compress == undefined){
  385. compress = true;
  386. }
  387. text = new String(text);
  388. var str06 = text.split("")
  389. , Ix = 0
  390. , step = +1
  391. , nIEnd = str06.length
  392. ;
  393. if(!rtl){
  394. Ix = str06.length - 1;
  395. step = -1;
  396. nIEnd = 1;
  397. }
  398. var previousCursive = 0, compressArray = [], compressArrayIndx = 0;
  399. for(var index = Ix; index * step < nIEnd; index = index + step){
  400. if(isArabicAlefbet(str06[index]) || isArabicDiacritics(str06[index])){
  401. // Arabic letter Lam
  402. if(str06[index] == '\u0644'){
  403. if(isNextAlef(str06, (index + step), step, nIEnd)){
  404. str06[index] = (previousCursive == 0) ? getLamAlefFE(str06[index + step], LamAlefInialTableFE) : getLamAlefFE(str06[index + step], LamAlefMedialTableFE);
  405. index += step;
  406. setAlefToSpace(str06, index, step, nIEnd);
  407. if(compress){
  408. compressArray[compressArrayIndx] = index;
  409. compressArrayIndx++;
  410. }
  411. previousCursive = 0;
  412. continue;
  413. }
  414. }
  415. var currentChr = str06[index];
  416. if(previousCursive == 1){
  417. // if next is Arabic
  418. //Character is in medial form
  419. // else character is in final form
  420. str06[index] = (isNextArabic(str06, (index + step), step, nIEnd)) ?
  421. getMedialFormCharacterFE(str06[index]) : getFormCharacterFE(str06[index], FinalForm);
  422. }else{
  423. if(isNextArabic(str06, (index + step), step, nIEnd) == true){
  424. //character is in Initial form
  425. str06[index] = getFormCharacterFE(str06[index],InitialForm);
  426. }else{
  427. str06[index] = getFormCharacterFE(str06[index], IsolatedForm);
  428. }
  429. }
  430. //exam if the current character is cursive
  431. if(!isArabicDiacritics(currentChr)){
  432. previousCursive = 1;
  433. }
  434. if(isStandAlonCharacter(currentChr) == true){
  435. previousCursive = 0;
  436. }
  437. }else{
  438. previousCursive = 0;
  439. }
  440. }
  441. var outBuf = "";
  442. for(idx = 0; idx < str06.length; idx++){
  443. if(!(compress && indexOf(compressArray, compressArray.length, idx) > -1)){
  444. outBuf += str06[idx];
  445. }
  446. }
  447. return outBuf;
  448. };
  449. function firstStrongDir(/*String*/text){
  450. // summary:
  451. // Return the first strong character direction
  452. // text:
  453. // The source string.
  454. // description:
  455. // Iterates over the text string, letter by letter starting from its beginning,
  456. // searching for first "strong" character.
  457. // Returns if strong character was found with the direction defined by this
  458. // character, if no strong character was found returns an empty string.
  459. // returns: /*String*/
  460. // "ltr" - if the first strong character is Latin.
  461. // "rtl" - if the first strong character is RTL directed character.
  462. // "" - if the strong character wasn't found.
  463. // tags:
  464. // private
  465. var type = null, uc = null, hi = null;
  466. for(var i = 0; i < text.length; i++){
  467. uc = text.charAt(i).charCodeAt(0);
  468. hi = MasterTable[uc >> 8];
  469. type = hi < TBBASE ? hi : UnicodeTable[hi - TBBASE][uc & 0xFF];
  470. if(type == UBAT_R || type == UBAT_AL){
  471. return "rtl";
  472. }
  473. if(type == UBAT_L){
  474. return "ltr";
  475. }
  476. if(type == UBAT_B){
  477. break;
  478. }
  479. }
  480. return "";
  481. };
  482. function lastStrongDir(text){
  483. // summary:
  484. // Return the last strong character direction
  485. // text:
  486. // The source string.
  487. // description:
  488. // Iterates over the text string, letter by letter starting from its end,
  489. // searching for first (from the end) "strong" character.
  490. // Returns if strong character was found with the direction defined by this
  491. // character, if no strong character was found returns an empty string.
  492. // tags:
  493. // private
  494. var type = null;
  495. for(var i = text.length - 1; i >= 0; i--){
  496. type = getCharacterType(text.charAt(i));
  497. if(type == UBAT_R || type == UBAT_AL){
  498. return "rtl";
  499. }
  500. if(type == UBAT_L){
  501. return "ltr";
  502. }
  503. if(type == UBAT_B){
  504. break;
  505. }
  506. }
  507. return "";
  508. };
  509. function deshape(/*String*/text, /*boolean*/rtl, /*boolean*/consume_next_space){
  510. // summary:
  511. // deshape the source text.
  512. // text:
  513. // the text to be deshape.
  514. // rtl:
  515. // flag indicating if the text is in RTL direction (logical
  516. // direction for Arabic words).
  517. // consume_next_space:
  518. // flag indicating whether to consume the space next to the
  519. // the lam alef if there is a space followed the Lamalef character to preserve the buffer size.
  520. // In case there is no space next to the lam alef the buffer size will be increased due to the
  521. // expansion of the lam alef one character into lam+alef two characters
  522. // returns: text deshaped.
  523. if(text.length == 0){
  524. return;
  525. }
  526. if(consume_next_space == undefined){
  527. consume_next_space = true;
  528. }
  529. if(rtl == undefined){
  530. rtl = true;
  531. }
  532. text = new String(text);
  533. var outBuf = "", strFE = [], textBuff = "";
  534. if(consume_next_space){
  535. for(var j = 0; j < text.length; j++){
  536. if(text.charAt(j) == ' '){
  537. if(rtl){
  538. if(j > 0){
  539. if(text.charAt(j - 1) >= '\uFEF5' && text.charAt(j - 1) <= '\uFEFC'){
  540. continue;
  541. }
  542. }
  543. }else{
  544. if(j+1 < text.length){
  545. if(text.charAt(j + 1) >= '\uFEF5' && text.charAt(j + 1) <= '\uFEFC'){
  546. continue;
  547. }
  548. }
  549. }
  550. }
  551. textBuff += text.charAt(j);
  552. }
  553. }else{
  554. textBuff = new String(text);
  555. }
  556. strFE = textBuff.split("");
  557. for(var i = 0; i < textBuff.length; i++){
  558. if(strFE[i] >= '\uFE70' && strFE[i] < '\uFEFF'){
  559. var chNum = textBuff.charCodeAt(i);
  560. if(strFE[i] >= '\uFEF5' && strFE[i] <= '\uFEFC'){
  561. //expand the LamAlef
  562. if(rtl){
  563. //Lam + Alef
  564. outBuf += '\u0644';
  565. outBuf += AlefTable[parseInt((chNum - 65269) / 2)];
  566. }else{
  567. outBuf += AlefTable[parseInt((chNum - 65269) / 2)];
  568. outBuf += '\u0644';
  569. }
  570. }else{
  571. outBuf += FETo06Table[chNum - 65136];
  572. }
  573. }else{
  574. outBuf += strFE[i];
  575. }
  576. }
  577. return outBuf;
  578. };
  579. function doReorder(str){
  580. // summary:
  581. // Helper to the doBidiReorder. Manages the UBA.
  582. // str:
  583. // the string to reorder.
  584. // returns:
  585. // text reordered according to source and result attributes.
  586. // tags:
  587. // private
  588. var chars = str.split(""), levels = [];
  589. computeLevels(chars, levels);
  590. swapChars(chars, levels);
  591. invertLevel(2, chars, levels);
  592. invertLevel(1, chars, levels);
  593. return chars.join("");
  594. };
  595. function computeLevels(chars, levels){
  596. var len = chars.length
  597. , impTab = bdx.dir ? impTab_RTL : impTab_LTR
  598. , prevState = null, newClass = null, newLevel = null, newState = 0
  599. , action = null, cond = null, condPos = -1, i = null, ix = null
  600. , types = []
  601. , classes = []
  602. ;
  603. bdx.hiLevel = bdx.dir;
  604. bdx.lastArabic = false;
  605. bdx.hasUBAT_AL = false,
  606. bdx.hasUBAT_B = false;
  607. bdx.hasUBAT_S = false;
  608. for(i = 0; i < len; i++){
  609. types[i] = getCharacterType(chars[i]);
  610. }
  611. for(ix = 0; ix < len; ix++){
  612. prevState = newState;
  613. classes[ix] = newClass = getCharClass(chars, types, classes, ix);
  614. newState = impTab[prevState][newClass];
  615. action = newState & 0xF0;
  616. newState &= 0x0F;
  617. levels[ix] = newLevel = impTab[newState][ITIL];
  618. if(action > 0){
  619. if(action == 0x10){ // set conditional run to level 1
  620. for(i = condPos; i < ix; i++){
  621. levels[i] = 1;
  622. }
  623. condPos = -1;
  624. }else{ // 0x20 confirm the conditional run
  625. condPos = -1;
  626. }
  627. }
  628. cond = impTab[newState][ITCOND];
  629. if(cond){
  630. if(condPos == -1){
  631. condPos = ix;
  632. }
  633. }else{ // unconditional level
  634. if(condPos > -1){
  635. for(i = condPos; i < ix; i++){
  636. levels[i] = newLevel;
  637. }
  638. condPos = -1;
  639. }
  640. }
  641. if(types[ix] == UBAT_B){
  642. levels[ix] = 0;
  643. }
  644. bdx.hiLevel |= newLevel;
  645. }
  646. if(bdx.hasUBAT_S){
  647. for(i = 0; i < len; i++){
  648. if(types[i] == UBAT_S){
  649. levels[i] = bdx.dir;
  650. for(var j = i - 1; j >= 0; j--){
  651. if(types[j] == UBAT_WS){
  652. levels[j] = bdx.dir;
  653. }else{
  654. break;
  655. }
  656. }
  657. }
  658. }
  659. }
  660. };
  661. function swapChars(chars, levels){
  662. // summary:
  663. // Swap characters with symmetrical mirroring as all kinds of parenthesis.
  664. // (When needed).
  665. // chars:
  666. // The source string as Array of characters.
  667. // levels:
  668. // An array (like hash) of flags for each character in the source string,
  669. // that defines if swapping should be applied on the following character.
  670. // description:
  671. // First checks if the swapping should be applied, if not returns, else
  672. // uses the levels "hash" to find what characters should be swapped.
  673. // tags:
  674. // private
  675. if(bdx.hiLevel == 0 || bdx.swap.substr(0, 1) == bdx.swap.substr(1, 2)){
  676. return;
  677. };
  678. //console.log("bdx.hiLevel == 0: " + bdx.hiLevel + "bdx.swap[0]: "+ bdx.swap[0] +" bdx.swap[1]: " +bdx.swap[1]);
  679. for(var i = 0; i < chars.length; i++){
  680. if(levels[i] == 1){chars[i] = getMirror(chars[i]);}
  681. }
  682. };
  683. function getCharacterType(ch){
  684. // summary:
  685. // Return the type of the character.
  686. // ch:
  687. // The character to be checked.
  688. // description:
  689. // Check the type of the character according to MasterTable,
  690. // type = LTR, RTL, neutral,Arabic-Indic digit etc.
  691. // tags:
  692. // private
  693. var uc = ch.charCodeAt(0)
  694. , hi = MasterTable[uc >> 8];
  695. return (hi < TBBASE) ? hi : UnicodeTable[hi - TBBASE][uc & 0xFF];
  696. };
  697. function invertStr(str){
  698. // summary:
  699. // Return the reversed string.
  700. // str:
  701. // The string to be reversed.
  702. // description:
  703. // Reverse the string str.
  704. // tags:
  705. // private
  706. var chars = str.split("");
  707. chars.reverse();
  708. return chars.join("");
  709. };
  710. function indexOf(cArray, cLength, idx){
  711. var counter = -1;
  712. for(var i = 0; i < cLength; i++){
  713. if(cArray[i] == idx){
  714. return i;
  715. }
  716. }
  717. return -1;
  718. };
  719. function isArabicAlefbet(c){
  720. for(var i = 0; i < ArabicAlefBetIntervalsBegine.length; i++){
  721. if(c >= ArabicAlefBetIntervalsBegine[i] && c <= ArabicAlefBetIntervalsEnd[i]){
  722. return true;
  723. }
  724. }
  725. return false;
  726. };
  727. function isNextArabic(str06, index, step, nIEnd){
  728. while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
  729. index += step;
  730. }
  731. if(((index) * step) < nIEnd && isArabicAlefbet(str06[index])){
  732. return true;
  733. }
  734. return false;
  735. };
  736. function isNextAlef(str06, index, step, nIEnd){
  737. while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
  738. index += step;
  739. }
  740. var c = ' ';
  741. if(((index) * step) < nIEnd){
  742. c = str06[index];
  743. }else{
  744. return false;
  745. }
  746. for(var i = 0; i < AlefTable.length; i++){
  747. if(AlefTable[i] == c){
  748. return true;
  749. }
  750. }
  751. return false;
  752. };
  753. function invertLevel(lev, chars, levels){
  754. if(bdx.hiLevel < lev){
  755. return;
  756. }
  757. if(lev == 1 && bdx.dir == RTL && !bdx.hasUBAT_B){
  758. chars.reverse();
  759. return;
  760. }
  761. var len = chars.length, start = 0, end, lo, hi, tmp;
  762. while(start < len){
  763. if(levels[start] >= lev){
  764. end = start + 1;
  765. while(end < len && levels[end] >= lev){
  766. end++;
  767. }
  768. for(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){
  769. tmp = chars[lo];
  770. chars[lo] = chars[hi];
  771. chars[hi] = tmp;
  772. }
  773. start = end;
  774. }
  775. start++;
  776. }
  777. };
  778. function getCharClass(chars, types, classes, ix){
  779. // summary:
  780. // Return the class if ix character in chars.
  781. // chars:
  782. // The source string as Array of characters.
  783. // types:
  784. // Array of types, for each character in chars.
  785. // classes:
  786. // Array of classes that already been solved.
  787. // ix:
  788. // the index of checked character.
  789. // tags:
  790. // private
  791. var cType = types[ix], wType, nType, len, i;
  792. switch(cType){
  793. case UBAT_L:
  794. case UBAT_R:
  795. bdx.lastArabic = false;
  796. case UBAT_ON:
  797. case UBAT_AN:
  798. return cType;
  799. case UBAT_EN:
  800. return bdx.lastArabic ? UBAT_AN : UBAT_EN;
  801. case UBAT_AL:
  802. bdx.lastArabic = true;
  803. bdx.hasUBAT_AL = true;
  804. return UBAT_R;
  805. case UBAT_WS:
  806. return UBAT_ON;
  807. case UBAT_CS:
  808. if(ix < 1 || (ix + 1) >= types.length ||
  809. ((wType = classes[ix - 1]) != UBAT_EN && wType != UBAT_AN) ||
  810. ((nType = types[ix + 1]) != UBAT_EN && nType != UBAT_AN)){
  811. return UBAT_ON;
  812. }
  813. if(bdx.lastArabic){nType = UBAT_AN;}
  814. return nType == wType ? nType : UBAT_ON;
  815. case UBAT_ES:
  816. wType = ix > 0 ? classes[ix - 1] : UBAT_B;
  817. if(wType == UBAT_EN && (ix + 1) < types.length && types[ix + 1] == UBAT_EN){
  818. return UBAT_EN;
  819. }
  820. return UBAT_ON;
  821. case UBAT_ET:
  822. if(ix > 0 && classes[ix - 1] == UBAT_EN){
  823. return UBAT_EN;
  824. }
  825. if(bdx.lastArabic){
  826. return UBAT_ON;
  827. }
  828. i = ix + 1;
  829. len = types.length;
  830. while(i < len && types[i] == UBAT_ET){
  831. i++;
  832. }
  833. if(i < len && types[i] == UBAT_EN){
  834. return UBAT_EN;
  835. }
  836. return UBAT_ON;
  837. case UBAT_NSM:
  838. if(bdx.inFormat == "VLTR"){ // visual to implicit transformation
  839. len = types.length;
  840. i = ix + 1;
  841. while(i < len && types[i] == UBAT_NSM){
  842. i++;
  843. }
  844. if(i < len){
  845. var c = chars[ix]
  846. , rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E
  847. ;
  848. wType = types[i];
  849. if(rtlCandidate && (wType == UBAT_R || wType == UBAT_AL)){
  850. return UBAT_R;
  851. }
  852. }
  853. }
  854. if(ix < 1 || (wType = types[ix - 1]) == UBAT_B){
  855. return UBAT_ON;
  856. }
  857. return classes[ix - 1];
  858. case UBAT_B:
  859. lastArabic = false;
  860. bdx.hasUBAT_B = true;
  861. return bdx.dir;
  862. case UBAT_S:
  863. bdx.hasUBAT_S = true;
  864. return UBAT_ON;
  865. case UBAT_LRE:
  866. case UBAT_RLE:
  867. case UBAT_LRO:
  868. case UBAT_RLO:
  869. case UBAT_PDF:
  870. lastArabic = false;
  871. case UBAT_BN:
  872. return UBAT_ON;
  873. }
  874. };
  875. function getMirror(c){
  876. // summary:
  877. // Calculates the mirrored character of c
  878. // c:
  879. // The character to be mirrored.
  880. // tags:
  881. // private
  882. var mid, low = 0, high = SwapTable.length - 1;
  883. while(low <= high){
  884. mid = Math.floor((low + high) / 2);
  885. if(c < SwapTable[mid][0]){
  886. high = mid - 1;
  887. }else if(c > SwapTable[mid][0]){
  888. low = mid + 1;
  889. }else{
  890. return SwapTable[mid][1];
  891. }
  892. }
  893. return c;
  894. };
  895. function isStandAlonCharacter(c){
  896. for(var i = 0; i < StandAlonForm.length; i++){
  897. if(StandAlonForm[i] == c){
  898. return true;
  899. }
  900. }
  901. return false;
  902. };
  903. function getMedialFormCharacterFE(c){
  904. for(var i = 0; i < BaseForm.length; i++){
  905. if(c == BaseForm[i]){
  906. return MedialForm[i];
  907. }
  908. }
  909. return c;
  910. };
  911. function getFormCharacterFE(/*char*/ c, /*char[]*/formArr){
  912. for(var i = 0; i < BaseForm.length; i++){
  913. if(c == BaseForm[i]){
  914. return formArr[i];
  915. }
  916. }
  917. return c;
  918. };
  919. function isArabicDiacritics(c){
  920. return (c >= '\u064b' && c <= '\u0655') ? true : false;
  921. };
  922. function getOrientation(/*Char*/ oc){
  923. if(oc == 'L'){
  924. return "LTR";
  925. }
  926. if(oc == 'R'){
  927. return "RTL";
  928. }
  929. if(oc == 'C'){
  930. return "CLR";
  931. }
  932. if(oc == 'D'){
  933. return "CRL";
  934. }
  935. };
  936. function setAlefToSpace(str06, index, step, nIEnd){
  937. while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
  938. index += step;
  939. }
  940. if(((index) * step) < nIEnd){
  941. str06[index] = ' ';
  942. return true;
  943. }
  944. return false;
  945. };
  946. function getLamAlefFE(alef06, LamAlefForm){
  947. for(var i = 0; i < AlefTable.length; i++){
  948. if(alef06 == AlefTable[i]){
  949. return LamAlefForm[i];
  950. }
  951. }
  952. return alef06;
  953. };
  954. function LamAlef(alef){
  955. // summary:
  956. // If the alef variable is an ARABIC ALEF letter,
  957. // return the LamAlef code associated with the specific
  958. // alef character.
  959. // alef:
  960. // The alef code type.
  961. // description:
  962. // If "alef" is an ARABIC ALEF letter, identify which alef is it,
  963. // using AlefTable, then return the LamAlef associated with it.
  964. // tags:
  965. // private
  966. for(var i = 0; i < AlefTable.length; i++){
  967. if(AlefTable[i] == alef){
  968. return AlefTable[i];
  969. }
  970. }
  971. return 0;
  972. };
  973. var bdx = {
  974. dir: 0,
  975. defInFormat: "LLTR",
  976. defoutFormat: "VLTR",
  977. defSwap: "YN",
  978. inFormat: "LLTR",
  979. outFormat: "VLTR",
  980. swap: "YN",
  981. hiLevel: 0,
  982. lastArabic: false,
  983. hasUBAT_AL: false,
  984. hasBlockSep: false,
  985. hasSegSep: false
  986. };
  987. var ITIL = 5;
  988. var ITCOND = 6;
  989. var LTR = 0;
  990. var RTL = 1;
  991. /****************************************************************************/
  992. /* Array in which directional characters are replaced by their symmetric. */
  993. /****************************************************************************/
  994. var SwapTable = [
  995. [ "\u0028", "\u0029" ], /* Round brackets */
  996. [ "\u0029", "\u0028" ],
  997. [ "\u003C", "\u003E" ], /* Less than/greater than */
  998. [ "\u003E", "\u003C" ],
  999. [ "\u005B", "\u005D" ], /* Square brackets */
  1000. [ "\u005D", "\u005B" ],
  1001. [ "\u007B", "\u007D" ], /* Curly brackets */
  1002. [ "\u007D", "\u007B" ],
  1003. [ "\u00AB", "\u00BB" ], /* Double angle quotation marks */
  1004. [ "\u00BB", "\u00AB" ],
  1005. [ "\u2039", "\u203A" ], /* single angle quotation mark */
  1006. [ "\u203A", "\u2039" ],
  1007. [ "\u207D", "\u207E" ], /* Superscript parentheses */
  1008. [ "\u207E", "\u207D" ],
  1009. [ "\u208D", "\u208E" ], /* Subscript parentheses */
  1010. [ "\u208E", "\u208D" ],
  1011. [ "\u2264", "\u2265" ], /* Less/greater than or equal */
  1012. [ "\u2265", "\u2264" ],
  1013. [ "\u2329", "\u232A" ], /* Angle brackets */
  1014. [ "\u232A", "\u2329" ],
  1015. [ "\uFE59", "\uFE5A" ], /* Small round brackets */
  1016. [ "\uFE5A", "\uFE59" ],
  1017. [ "\uFE5B", "\uFE5C" ], /* Small curly brackets */
  1018. [ "\uFE5C", "\uFE5B" ],
  1019. [ "\uFE5D", "\uFE5E" ], /* Small tortoise shell brackets */
  1020. [ "\uFE5E", "\uFE5D" ],
  1021. [ "\uFE64", "\uFE65" ], /* Small less than/greater than */
  1022. [ "\uFE65", "\uFE64" ]
  1023. ];
  1024. var AlefTable = ['\u0622', '\u0623', '\u0625', '\u0627'];
  1025. var AlefTableFE = [0xFE81, 0xFE82, 0xFE83, 0xFE84, 0xFE87, 0xFE88, 0xFE8D, 0xFE8E];
  1026. var LamTableFE = [0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0];
  1027. var LamAlefInialTableFE = ['\ufef5', '\ufef7', '\ufef9', '\ufefb'];
  1028. var LamAlefMedialTableFE = ['\ufef6', '\ufef8', '\ufefa', '\ufefc'];
  1029. /**
  1030. * Arabic Characters in the base form
  1031. */
  1032. var BaseForm = ['\u0627', '\u0628', '\u062A', '\u062B', '\u062C', '\u062D', '\u062E', '\u062F', '\u0630', '\u0631', '\u0632', '\u0633', '\u0634', '\u0635', '\u0636', '\u0637', '\u0638', '\u0639', '\u063A', '\u0641', '\u0642', '\u0643', '\u0644', '\u0645', '\u0646', '\u0647', '\u0648', '\u064A', '\u0625', '\u0623', '\u0622', '\u0629', '\u0649', '\u06CC', '\u0626', '\u0624', '\u064B', '\u064C', '\u064D', '\u064E', '\u064F', '\u0650', '\u0651', '\u0652', '\u0621'];
  1033. /**
  1034. * Arabic shaped characters in Isolated form
  1035. */
  1036. var IsolatedForm = ['\uFE8D', '\uFE8F', '\uFE95', '\uFE99', '\uFE9D', '\uFEA1', '\uFEA5', '\uFEA9', '\uFEAB', '\uFEAD', '\uFEAF', '\uFEB1', '\uFEB5', '\uFEB9', '\uFEBD', '\uFEC1', '\uFEC5', '\uFEC9', '\uFECD', '\uFED1', '\uFED5', '\uFED9', '\uFEDD', '\uFEE1', '\uFEE5', '\uFEE9', '\uFEED', '\uFEF1', '\uFE87', '\uFE83', '\uFE81', '\uFE93', '\uFEEF', '\uFBFC', '\uFE89', '\uFE85', '\uFE70', '\uFE72', '\uFE74', '\uFE76', '\uFE78', '\uFE7A', '\uFE7C', '\uFE7E', '\uFE80'];
  1037. /**
  1038. * Arabic shaped characters in Final form
  1039. */
  1040. var FinalForm = ['\uFE8E', '\uFE90', '\uFE96', '\uFE9A', '\uFE9E', '\uFEA2', '\uFEA6', '\uFEAA', '\uFEAC', '\uFEAE', '\uFEB0', '\uFEB2', '\uFEB6', '\uFEBA', '\uFEBE', '\uFEC2', '\uFEC6', '\uFECA', '\uFECE', '\uFED2', '\uFED6', '\uFEDA', '\uFEDE', '\uFEE2', '\uFEE6', '\uFEEA', '\uFEEE', '\uFEF2', '\uFE88', '\uFE84', '\uFE82', '\uFE94', '\uFEF0', '\uFBFD', '\uFE8A', '\uFE86', '\uFE70', '\uFE72', '\uFE74', '\uFE76', '\uFE78', '\uFE7A', '\uFE7C', '\uFE7E', '\uFE80'];
  1041. /**
  1042. * Arabic shaped characters in Media form
  1043. */
  1044. var MedialForm = ['\uFE8E', '\uFE92', '\uFE98', '\uFE9C', '\uFEA0', '\uFEA4', '\uFEA8', '\uFEAA', '\uFEAC', '\uFEAE', '\uFEB0', '\uFEB4', '\uFEB8', '\uFEBC', '\uFEC0', '\uFEC4', '\uFEC8', '\uFECC', '\uFED0', '\uFED4', '\uFED8', '\uFEDC', '\uFEE0', '\uFEE4', '\uFEE8', '\uFEEC', '\uFEEE', '\uFEF4', '\uFE88', '\uFE84', '\uFE82', '\uFE94', '\uFEF0', '\uFBFF', '\uFE8C', '\uFE86', '\uFE71', '\uFE72', '\uFE74', '\uFE77', '\uFE79', '\uFE7B', '\uFE7D', '\uFE7F', '\uFE80'];
  1045. /**
  1046. * Arabic shaped characters in Initial form
  1047. */
  1048. var InitialForm = ['\uFE8D', '\uFE91', '\uFE97', '\uFE9B', '\uFE9F', '\uFEA3', '\uFEA7', '\uFEA9', '\uFEAB', '\uFEAD', '\uFEAF', '\uFEB3', '\uFEB7', '\uFEBB', '\uFEBF', '\uFEC3', '\uFEC7', '\uFECB', '\uFECF', '\uFED3', '\uFED7', '\uFEDB', '\uFEDF', '\uFEE3', '\uFEE7', '\uFEEB', '\uFEED', '\uFEF3', '\uFE87', '\uFE83', '\uFE81', '\uFE93', '\uFEEF', '\uFBFE', '\uFE8B', '\uFE85', '\uFE70', '\uFE72', '\uFE74', '\uFE76', '\uFE78', '\uFE7A', '\uFE7C', '\uFE7E', '\uFE80'];
  1049. /**
  1050. * Arabic characters that couldn't join to the next character
  1051. */
  1052. var StandAlonForm = ['\u0621', '\u0627', '\u062F', '\u0630', '\u0631', '\u0632', '\u0648', '\u0622', '\u0629', '\u0626', '\u0624', '\u0625', '\u0675', '\u0623'];
  1053. var FETo06Table = ['\u064B', '\u064B', '\u064C', '\u061F', '\u064D', '\u061F', '\u064E', '\u064E', '\u064F', '\u064F', '\u0650', '\u0650', '\u0651', '\u0651', '\u0652', '\u0652', '\u0621', '\u0622', '\u0622', '\u0623', '\u0623', '\u0624', '\u0624', '\u0625', '\u0625', '\u0626', '\u0626', '\u0626', '\u0626', '\u0627', '\u0627', '\u0628', '\u0628', '\u0628', '\u0628', '\u0629', '\u0629', '\u062A', '\u062A', '\u062A', '\u062A', '\u062B', '\u062B', '\u062B', '\u062B', '\u062C', '\u062C', '\u062C', '\u062c', '\u062D', '\u062D', '\u062D', '\u062D', '\u062E', '\u062E', '\u062E', '\u062E', '\u062F', '\u062F', '\u0630', '\u0630', '\u0631', '\u0631', '\u0632', '\u0632', '\u0633', '\u0633', '\u0633', '\u0633', '\u0634', '\u0634', '\u0634', '\u0634', '\u0635', '\u0635', '\u0635', '\u0635', '\u0636', '\u0636', '\u0636', '\u0636', '\u0637', '\u0637', '\u0637', '\u0637', '\u0638', '\u0638', '\u0638', '\u0638', '\u0639', '\u0639', '\u0639', '\u0639', '\u063A', '\u063A', '\u063A', '\u063A', '\u0641', '\u0641', '\u0641', '\u0641', '\u0642', '\u0642', '\u0642', '\u0642', '\u0643', '\u0643', '\u0643', '\u0643', '\u0644', '\u0644', '\u0644', '\u0644', '\u0645', '\u0645', '\u0645', '\u0645', '\u0646', '\u0646', '\u0646', '\u0646', '\u0647', '\u0647', '\u0647', '\u0647', '\u0648', '\u0648', '\u0649', '\u0649', '\u064A', '\u064A', '\u064A', '\u064A', '\uFEF5', '\uFEF6', '\uFEF7', '\uFEF8', '\uFEF9', '\uFEFA', '\uFEFB', '\uFEFC', '\u061F', '\u061F', '\u061F'];
  1054. var ArabicAlefBetIntervalsBegine = ['\u0621', '\u0641'];
  1055. var ArabicAlefBetIntervalsEnd = ['\u063A', '\u064a'];
  1056. var Link06 = [
  1057. 1 + 32 + 256 * 0x11,
  1058. 1 + 32 + 256 * 0x13,
  1059. 1 + 256 * 0x15,
  1060. 1 + 32 + 256 * 0x17,
  1061. 1 + 2 + 256 * 0x19,
  1062. 1 + 32 + 256 * 0x1D,
  1063. 1 + 2 + 256 * 0x1F,
  1064. 1 + 256 * 0x23,
  1065. 1 + 2 + 256 * 0x25,
  1066. 1 + 2 + 256 * 0x29,
  1067. 1 + 2 + 256 * 0x2D,
  1068. 1 + 2 + 256 * 0x31,
  1069. 1 + 2 + 256 * 0x35,
  1070. 1 + 256 * 0x39,
  1071. 1 + 256 * 0x3B,
  1072. 1 + 256 * 0x3D,
  1073. 1 + 256 * 0x3F,
  1074. 1 + 2 + 256 * 0x41,
  1075. 1 + 2 + 256 * 0x45,
  1076. 1 + 2 + 256 * 0x49,
  1077. 1 + 2 + 256 * 0x4D,
  1078. 1 + 2 + 256 * 0x51,
  1079. 1 + 2 + 256 * 0x55,
  1080. 1 + 2 + 256 * 0x59,
  1081. 1 + 2 + 256 * 0x5D,
  1082. 0, 0, 0, 0, 0, /* 0x63B - 0x63F */
  1083. 1 + 2,
  1084. 1 + 2 + 256 * 0x61,
  1085. 1 + 2 + 256 * 0x65,
  1086. 1 + 2 + 256 * 0x69,
  1087. 1 + 2 + 16 + 256 * 0x6D,
  1088. 1 + 2 + 256 * 0x71,
  1089. 1 + 2 + 256 * 0x75,
  1090. 1 + 2 + 256 * 0x79,
  1091. 1 + 256 * 0x7D,
  1092. 1 + 256 * 0x7F,
  1093. 1 + 2 + 256 * 0x81,
  1094. 4, 4, 4, 4,
  1095. 4, 4, 4, 4, /* 0x64B - 0x652 */
  1096. 0, 0, 0, 0, 0,
  1097. 0, 0, 0, 0, /* 0x653 - 0x65B */
  1098. 1 + 256 * 0x85,
  1099. 1 + 256 * 0x87,
  1100. 1 + 256 * 0x89,
  1101. 1 + 256 * 0x8B,
  1102. 0, 0, 0, 0, 0,
  1103. 0, 0, 0, 0, 0,
  1104. 0, 0, 0, 0, 0, 0,/* 0x660 - 0x66F */
  1105. 4,
  1106. 0,
  1107. 1 + 32,
  1108. 1 + 32,
  1109. 0,
  1110. 1 + 32,
  1111. 1, 1,
  1112. 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
  1113. 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
  1114. 1+2, 1+2, 1+2, 1+2,
  1115. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1116. 1, 1, 1, 1, 1, 1, 1, 1,
  1117. 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
  1118. 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
  1119. 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
  1120. 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2,
  1121. 1,
  1122. 1+2,
  1123. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1124. 1+2,
  1125. 1,
  1126. 1+2, 1+2, 1+2, 1+2,
  1127. 1, 1
  1128. ];
  1129. var LinkFE = [
  1130. 1 + 2,
  1131. 1 + 2,
  1132. 1 + 2, 0, 1+ 2, 0, 1+ 2,
  1133. 1 + 2,
  1134. 1+ 2, 1 + 2, 1+2, 1 + 2,
  1135. 1+ 2, 1 + 2, 1+2, 1 + 2,
  1136. 0, 0 + 32, 1 + 32, 0 + 32,
  1137. 1 + 32, 0, 1, 0 + 32,
  1138. 1 + 32, 0, 2, 1 + 2,
  1139. 1, 0 + 32, 1 + 32, 0,
  1140. 2, 1 + 2, 1, 0,
  1141. 1, 0, 2, 1 + 2,
  1142. 1, 0, 2, 1 + 2,
  1143. 1, 0, 2, 1 + 2,
  1144. 1, 0, 2, 1 + 2,
  1145. 1, 0, 2, 1 + 2,
  1146. 1, 0, 1, 0,
  1147. 1, 0, 1, 0,
  1148. 1, 0, 2, 1+2,
  1149. 1, 0, 2, 1+2,
  1150. 1, 0, 2, 1+2,
  1151. 1, 0, 2, 1+2,
  1152. 1, 0, 2, 1+2,
  1153. 1, 0, 2, 1+2,
  1154. 1, 0, 2, 1+2,
  1155. 1, 0, 2, 1+2,
  1156. 1, 0, 2, 1+2,
  1157. 1, 0, 2, 1+2,
  1158. 1, 0, 2, 1+2,
  1159. 1, 0 + 16, 2 + 16, 1 + 2 +16,
  1160. 1 + 16, 0, 2, 1+2,
  1161. 1, 0, 2, 1+2,
  1162. 1, 0, 2, 1+2,
  1163. 1, 0, 1, 0,
  1164. 1, 0, 2, 1+2,
  1165. 1, 0, 1, 0,
  1166. 1, 0, 1, 0,
  1167. 1
  1168. ];
  1169. var impTab_LTR = [
  1170. /* L, R, EN, AN, N, IL, Cond */
  1171. /* 0 LTR text */ [ 0, 3, 0, 1, 0, 0, 0 ],
  1172. /* 1 LTR+AN */ [ 0, 3, 0, 1, 2, 2, 0 ],
  1173. /* 2 LTR+AN+N */ [ 0, 3, 0, 0x11, 2, 0, 1 ],
  1174. /* 3 RTL text */ [ 0, 3, 5, 5, 4, 1, 0 ],
  1175. /* 4 RTL cont */ [ 0, 3, 0x15, 0x15, 4, 0, 1 ],
  1176. /* 5 RTL+EN/AN */ [ 0, 3, 5, 5, 4, 2, 0 ]
  1177. ];
  1178. var impTab_RTL = [
  1179. /* L, R, EN, AN, N, IL, Cond */
  1180. /* 0 RTL text */ [ 2, 0, 1, 1, 0, 1, 0 ],
  1181. /* 1 RTL+EN/AN */ [ 2, 0, 1, 1, 0, 2, 0 ],
  1182. /* 2 LTR text */ [ 2, 0, 2, 1, 3, 2, 0 ],
  1183. /* 3 LTR+cont */ [ 2, 0, 2, 0x21, 3, 1, 1 ]
  1184. ];
  1185. var UBAT_L = 0; /* left to right */
  1186. var UBAT_R = 1; /* right to left */
  1187. var UBAT_EN = 2; /* European digit */
  1188. var UBAT_AN = 3; /* Arabic-Indic digit */
  1189. var UBAT_ON = 4; /* neutral */
  1190. var UBAT_B = 5; /* block separator */
  1191. var UBAT_S = 6; /* segment separator */
  1192. var UBAT_AL = 7; /* Arabic Letter */
  1193. var UBAT_WS = 8; /* white space */
  1194. var UBAT_CS = 9; /* common digit separator */
  1195. var UBAT_ES = 10; /* European digit separator */
  1196. var UBAT_ET = 11; /* European digit terminator */
  1197. var UBAT_NSM = 12; /* Non Spacing Mark */
  1198. var UBAT_LRE = 13; /* LRE */
  1199. var UBAT_RLE = 14; /* RLE */
  1200. var UBAT_PDF = 15; /* PDF */
  1201. var UBAT_LRO = 16; /* LRO */
  1202. var UBAT_RLO = 17; /* RLO */
  1203. var UBAT_BN = 18; /* Boundary Neutral */
  1204. var TBBASE = 100;
  1205. var TB00 = TBBASE + 0;
  1206. var TB05 = TBBASE + 1;
  1207. var TB06 = TBBASE + 2;
  1208. var TB07 = TBBASE + 3;
  1209. var TB20 = TBBASE + 4;
  1210. var TBFB = TBBASE + 5;
  1211. var TBFE = TBBASE + 6;
  1212. var TBFF = TBBASE + 7;
  1213. var L = UBAT_L;
  1214. var R = UBAT_R;
  1215. var EN = UBAT_EN;
  1216. var AN = UBAT_AN;
  1217. var ON = UBAT_ON;
  1218. var B = UBAT_B;
  1219. var S = UBAT_S;
  1220. var AL = UBAT_AL;
  1221. var WS = UBAT_WS;
  1222. var CS = UBAT_CS;
  1223. var ES = UBAT_ES;
  1224. var ET = UBAT_ET;
  1225. var NSM = UBAT_NSM;
  1226. var LRE = UBAT_LRE;
  1227. var RLE = UBAT_RLE;
  1228. var PDF = UBAT_PDF;
  1229. var LRO = UBAT_LRO;
  1230. var RLO = UBAT_RLO;
  1231. var BN = UBAT_BN;
  1232. var MasterTable = [
  1233. /************************************************************************************************************************************/
  1234. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1235. /************************************************************************************************************************************/
  1236. /*0-*/ TB00, L , L , L , L , TB05, TB06, TB07, R , L , L , L , L , L , L , L ,
  1237. /*1-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1238. /*2-*/ TB20, ON , ON , ON , L , ON , L , ON , L , ON , ON , ON , L , L , ON , ON ,
  1239. /*3-*/ L , L , L , L , L , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1240. /*4-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , L , L , ON ,
  1241. /*5-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1242. /*6-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1243. /*7-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1244. /*8-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1245. /*9-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , L ,
  1246. /*A-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , ON , ON , ON ,
  1247. /*B-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1248. /*C-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1249. /*D-*/ ON , ON , ON , ON , ON , ON , ON , L , L , ON , ON , L , L , ON , ON , L ,
  1250. /*E-*/ L , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1251. /*F-*/ ON , ON , ON , ON , ON , ON , ON , ON , L , L , L , TBFB, AL , AL , TBFE, TBFF
  1252. ];
  1253. delete TB00;
  1254. delete TB05;
  1255. delete TB06;
  1256. delete TB07;
  1257. delete TB20;
  1258. delete TBFB;
  1259. delete TBFE;
  1260. delete TBFF;
  1261. var UnicodeTable = [
  1262. [ /* Table 00: Unicode 00xx */
  1263. /************************************************************************************************************************************/
  1264. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1265. /************************************************************************************************************************************/
  1266. /*0-*/ BN , BN , BN , BN , BN , BN , BN , BN , BN , S , B , S , WS , B , BN , BN ,
  1267. /*1-*/ BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , B , B , B , S ,
  1268. /*2-*/ WS , ON , ON , ET , ET , ET , ON , ON , ON , ON , ON , ES , CS , ES , CS , CS ,
  1269. /*3-*/ EN , EN , EN , EN , EN , EN , EN , EN , EN , EN , CS , ON , ON , ON , ON , ON ,
  1270. /*4-*/ ON , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1271. /*5-*/ L , L , L , L , L , L , L , L , L , L , L , ON , ON , ON , ON , ON ,
  1272. /*6-*/ ON , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1273. /*7-*/ L , L , L , L , L , L , L , L , L , L , L , ON , ON , ON , ON , BN ,
  1274. /*8-*/ BN , BN , BN , BN , BN , B , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN ,
  1275. /*9-*/ BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN , BN ,
  1276. /*A-*/ CS , ON , ET , ET , ET , ET , ON , ON , ON , ON , L , ON , ON , BN , ON , ON ,
  1277. /*B-*/ ET , ET , EN , EN , ON , L , ON , ON , ON , EN , L , ON , ON , ON , ON , ON ,
  1278. /*C-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1279. /*D-*/ L , L , L , L , L , L , L , ON , L , L , L , L , L , L , L , L ,
  1280. /*E-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1281. /*F-*/ L , L , L , L , L , L , L , ON , L , L , L , L , L , L , L , L
  1282. ],
  1283. [ /* Table 01: Unicode 05xx */
  1284. /************************************************************************************************************************************/
  1285. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1286. /************************************************************************************************************************************/
  1287. /*0-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1288. /*1-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1289. /*2-*/ L , L , L , L , L , L , L , L , ON , ON , ON , ON , ON , ON , ON , ON ,
  1290. /*3-*/ ON , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1291. /*4-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1292. /*5-*/ L , L , L , L , L , L , L , ON , ON , L , L , L , L , L , L , L ,
  1293. /*6-*/ ON , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1294. /*7-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1295. /*8-*/ L , L , L , L , L , L , L , L , ON , L , ON , ON , ON , ON , ON , ON ,
  1296. /*9-*/ ON , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1297. /*A-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1298. /*B-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , R , NSM ,
  1299. /*C-*/ R , NSM , NSM , R , NSM , NSM , R , NSM , ON , ON , ON , ON , ON , ON , ON , ON ,
  1300. /*D-*/ R , R , R , R , R , R , R , R , R , R , R , R , R , R , R , R ,
  1301. /*E-*/ R , R , R , R , R , R , R , R , R , R , R , ON , ON , ON , ON , ON ,
  1302. /*F-*/ R , R , R , R , R , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON
  1303. ],
  1304. [ /* Table 02: Unicode 06xx */
  1305. /************************************************************************************************************************************/
  1306. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1307. /************************************************************************************************************************************/
  1308. /*0-*/ AN , AN , AN , AN , ON , ON , ON , ON , AL , ET , ET , AL , CS , AL , ON , ON ,
  1309. /*1-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , AL , ON , ON , AL , AL ,
  1310. /*2-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1311. /*3-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1312. /*4-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , NSM , NSM , NSM , NSM , NSM ,
  1313. /*5-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1314. /*6-*/ AN , AN , AN , AN , AN , AN , AN , AN , AN , AN , ET , AN , AN , AL , AL , AL ,
  1315. /*7-*/ NSM , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1316. /*8-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1317. /*9-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1318. /*A-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1319. /*B-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1320. /*C-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1321. /*D-*/ AL , AL , AL , AL , AL , AL , NSM , NSM , NSM , NSM , NSM , NSM , NSM , AN , ON , NSM ,
  1322. /*E-*/ NSM , NSM , NSM , NSM , NSM , AL , AL , NSM , NSM , ON , NSM , NSM , NSM , NSM , AL , AL ,
  1323. /*F-*/ EN , EN , EN , EN , EN , EN , EN , EN , EN , EN , AL , AL , AL , AL , AL , AL
  1324. ],
  1325. [ /* Table 03: Unicode 07xx */
  1326. /************************************************************************************************************************************/
  1327. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1328. /************************************************************************************************************************************/
  1329. /*0-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , ON , AL ,
  1330. /*1-*/ AL , NSM , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1331. /*2-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1332. /*3-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1333. /*4-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , ON , ON , AL , AL , AL ,
  1334. /*5-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1335. /*6-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1336. /*7-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1337. /*8-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1338. /*9-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1339. /*A-*/ AL , AL , AL , AL , AL , AL , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1340. /*B-*/ NSM , AL , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1341. /*C-*/ R , R , R , R , R , R , R , R , R , R , R , R , R , R , R , R ,
  1342. /*D-*/ R , R , R , R , R , R , R , R , R , R , R , R , R , R , R , R ,
  1343. /*E-*/ R , R , R , R , R , R , R , R , R , R , R , NSM , NSM , NSM , NSM , NSM ,
  1344. /*F-*/ NSM , NSM , NSM , NSM , R , R , ON , ON , ON , ON , R , ON , ON , ON , ON , ON
  1345. ],
  1346. [ /* Table 04: Unicode 20xx */
  1347. /************************************************************************************************************************************/
  1348. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1349. /************************************************************************************************************************************/
  1350. /*0-*/ WS , WS , WS , WS , WS , WS , WS , WS , WS , WS , WS , BN , BN , BN , L , R ,
  1351. /*1-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1352. /*2-*/ ON , ON , ON , ON , ON , ON , ON , ON , WS , B , LRE , RLE , PDF , LRO , RLO , CS ,
  1353. /*3-*/ ET , ET , ET , ET , ET , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1354. /*4-*/ ON , ON , ON , ON , CS , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1355. /*5-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , WS ,
  1356. /*6-*/ BN , BN , BN , BN , BN , ON , ON , ON , ON , ON , BN , BN , BN , BN , BN , BN ,
  1357. /*7-*/ EN , L , ON , ON , EN , EN , EN , EN , EN , EN , ES , ES , ON , ON , ON , L ,
  1358. /*8-*/ EN , EN , EN , EN , EN , EN , EN , EN , EN , EN , ES , ES , ON , ON , ON , ON ,
  1359. /*9-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , ON , ON , ON ,
  1360. /*A-*/ ET , ET , ET , ET , ET , ET , ET , ET , ET , ET , ET , ET , ET , ET , ET , ET ,
  1361. /*B-*/ ET , ET , ET , ET , ET , ET , ET , ET , ET , ET , ON , ON , ON , ON , ON , ON ,
  1362. /*C-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1363. /*D-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1364. /*E-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1365. /*F-*/ NSM , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON
  1366. ],
  1367. [ /* Table 05: Unicode FBxx */
  1368. /************************************************************************************************************************************/
  1369. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1370. /************************************************************************************************************************************/
  1371. /*0-*/ L , L , L , L , L , L , L , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1372. /*1-*/ ON , ON , ON , L , L , L , L , L , ON , ON , ON , ON , ON , R , NSM , R ,
  1373. /*2-*/ R , R , R , R , R , R , R , R , R , ES , R , R , R , R , R , R ,
  1374. /*3-*/ R , R , R , R , R , R , R , ON , R , R , R , R , R , ON , R , ON ,
  1375. /*4-*/ R , R , ON , R , R , ON , R , R , R , R , R , R , R , R , R , R ,
  1376. /*5-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1377. /*6-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1378. /*7-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1379. /*8-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1380. /*9-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1381. /*A-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1382. /*B-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1383. /*C-*/ AL , AL , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1384. /*D-*/ ON , ON , ON , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1385. /*E-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1386. /*F-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL
  1387. ],
  1388. [ /* Table 06: Unicode FExx */
  1389. /************************************************************************************************************************************/
  1390. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1391. /************************************************************************************************************************************/
  1392. /*0-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM , NSM ,
  1393. /*1-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1394. /*2-*/ NSM , NSM , NSM , NSM , NSM , NSM , NSM , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1395. /*3-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1396. /*4-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1397. /*5-*/ CS , ON , CS , ON , ON , CS , ON , ON , ON , ON , ON , ON , ON , ON , ON , ET ,
  1398. /*6-*/ ON , ON , ES , ES , ON , ON , ON , ON , ON , ET , ET , ON , ON , ON , ON , ON ,
  1399. /*7-*/ AL , AL , AL , AL , AL , ON , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1400. /*8-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1401. /*9-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1402. /*A-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1403. /*B-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1404. /*C-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1405. /*D-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1406. /*E-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL ,
  1407. /*F-*/ AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , AL , ON , ON , BN
  1408. ],
  1409. [ /* Table 07: Unicode FFxx */
  1410. /************************************************************************************************************************************/
  1411. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  1412. /************************************************************************************************************************************/
  1413. /*0-*/ ON , ON , ON , ET , ET , ET , ON , ON , ON , ON , ON , ES , CS , ES , CS , CS ,
  1414. /*1-*/ EN , EN , EN , EN , EN , EN , EN , EN , EN , EN , CS , ON , ON , ON , ON , ON ,
  1415. /*2-*/ ON , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1416. /*3-*/ L , L , L , L , L , L , L , L , L , L , L , ON , ON , ON , ON , ON ,
  1417. /*4-*/ ON , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1418. /*5-*/ L , L , L , L , L , L , L , L , L , L , L , ON , ON , ON , ON , ON ,
  1419. /*6-*/ ON , ON , ON , ON , ON , ON , L , L , L , L , L , L , L , L , L , L ,
  1420. /*7-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1421. /*8-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1422. /*9-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1423. /*A-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , L ,
  1424. /*B-*/ L , L , L , L , L , L , L , L , L , L , L , L , L , L , L , ON ,
  1425. /*C-*/ ON , ON , L , L , L , L , L , L , ON , ON , L , L , L , L , L , L ,
  1426. /*D-*/ ON , ON , L , L , L , L , L , L , ON , ON , L , L , L , ON , ON , ON ,
  1427. /*E-*/ ET , ET , ON , ON , ON , ET , ET , ON , ON , ON , ON , ON , ON , ON , ON , ON ,
  1428. /*F-*/ ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON , ON
  1429. ]
  1430. ];
  1431. delete L;
  1432. delete R;
  1433. delete EN;
  1434. delete AN;
  1435. delete ON;
  1436. delete B;
  1437. delete S;
  1438. delete AL;
  1439. delete WS;
  1440. delete CS;
  1441. delete ES;
  1442. delete ET;
  1443. delete NSM;
  1444. delete LRE;
  1445. delete RLE;
  1446. delete PDF;
  1447. delete LRO;
  1448. delete RLO;
  1449. delete BN;
  1450. return dojox.string.BidiEngine;
  1451. });