makepad_html/
lib.rs

1use makepad_live_id::*;
2
3#[derive(Debug)]
4pub struct HtmlError{
5    pub message:String,
6    pub position:usize,
7}
8
9#[derive(Default, PartialEq)]
10pub struct HtmlDoc{
11    pub decoded: String,
12    pub nodes: Vec<HtmlNode>,
13}
14
15#[derive(Debug, PartialEq)]
16pub enum HtmlNode{
17    OpenTag{lc:LiveId, nc:LiveId},
18    CloseTag{lc:LiveId, nc:LiveId},
19    Attribute{lc:LiveId, nc:LiveId, start:usize, end:usize},
20    Text{start: usize, end:usize, all_ws:bool}
21}
22/*
23/// A standalone owned copy of an HTML attribute.
24#[derive(Debug, Clone)]
25pub struct HtmlAttribute {
26    /// The LiveID of this attribute's key converted to lowercase.
27    pub lc: LiveId,
28    /// The LiveID of this attribute's key in its original normal case.
29    pub nc: LiveId,
30    /// The value of this attribute.
31    pub value: String,
32}*/
33 
34pub struct HtmlWalker<'a>{
35    decoded: &'a str,
36    pub nodes: &'a [HtmlNode],
37    pub index: usize,
38}
39 
40impl<'a> HtmlWalker<'a>{
41    pub fn index(&self)->usize{
42        self.index
43    }
44 
45    pub fn walk(&mut self){
46        if self.index < self.nodes.len(){
47            for i in self.index+1..self.nodes.len(){
48                // we skip attributes
49                if let HtmlNode::Attribute{..} = &self.nodes[i]{
50                    
51                }
52                else{
53                    self.index = i;
54                    return;
55                }
56            }
57            self.index = self.nodes.len();
58        } 
59    }
60    
61    pub fn jump_to_close(&mut self){
62        if self.index < self.nodes.len(){
63            let mut depth = 0;
64            for i in self.index+1..self.nodes.len(){
65                match &self.nodes[i]{
66                    HtmlNode::OpenTag{..}=>{
67                        depth +=1;
68                    }
69                    HtmlNode::CloseTag{..}=>{
70                        if depth == 0{
71                            self.index = i;
72                            return;
73                        }
74                        depth -= 1;
75                    }
76                    _=>()
77                }
78            }
79        } 
80        self.index = self.nodes.len();
81    }
82    
83    pub fn done(&self)->bool{
84        self.index >= self.nodes.len()
85    }
86/*
87    /// Iterates over and returns a list of all attributes for the current open HTML tag.
88    pub fn collect_attributes(&self) -> Vec<HtmlAttribute> {
89        let mut attrs = Vec::new();
90        for node in &self.nodes[self.index ..] {
91            match node {
92                HtmlNode::Attribute { lc, nc, start, end } => {
93                    attrs.push(HtmlAttribute {
94                        lc: *lc,
95                        nc: *nc,
96                        value: String::from(&self.decoded[*start..*end]),
97                    });
98                }
99                HtmlNode::CloseTag { .. } => break,
100                _ => continue,
101            }
102        }
103        attrs
104    }
105    */
106    /// Returns the first attribute of the currently-opened Html tag
107    /// whose key matches the given `flc` LiveId, which should be all lowercase.
108    ///
109    /// Matching is done after converting all attribute keys to lowercase.
110    pub fn find_attr_lc(&self, flc:LiveId)->Option<&'a str>{
111        for i in self.index..self.nodes.len(){
112            match &self.nodes[i]{
113                HtmlNode::CloseTag{..}=>{
114                    return None
115                }
116                HtmlNode::Attribute{lc, nc:_, start, end} if *lc == flc=>{
117                    return Some(&self.decoded[*start..*end])
118                }
119                _=>()
120            }
121        }
122        None
123    }
124    
125    pub fn while_attr_lc(&mut self)->Option<(LiveId, &'a str)>{
126        if self.index<self.nodes.len(){
127            match &self.nodes[self.index]{
128                HtmlNode::Attribute{lc, nc:_, start, end}=>{
129                    self.index += 1;
130                    return Some((*lc, &self.decoded[*start..*end]))
131                }
132                _=>()
133            }
134        }
135        None
136    }
137     
138    /// Returns the first attribute of the currently-opened Html tag 
139    /// whose key matches the given `fnc` LiveId, which is case-sensitive.
140    ///
141    /// Matching is done in a case-sensitive manner.
142    pub fn find_attr_nc(&self, fnc:LiveId)->Option<&'a str>{
143        for i in self.index..self.nodes.len(){
144            match &self.nodes[i]{
145                HtmlNode::CloseTag{..}=>{
146                    return None
147                }
148                HtmlNode::Attribute{lc:_, nc, start, end} if *nc == fnc=>{
149                    return Some(&self.decoded[*start..*end])
150                }
151                _=>()
152            }
153        }
154        None
155    }
156    
157    pub fn find_text(&self)->Option<&'a str>{
158        for i in self.index..self.nodes.len(){
159            match &self.nodes[i]{
160                HtmlNode::CloseTag{..}=>{
161                    return None
162                }
163                HtmlNode::Text{start, end,..} =>{
164                    return Some(&self.decoded[*start..*end])
165                }
166                _=>()
167            }
168        }
169        None
170    }
171    
172    pub fn find_tag_text(&self, tag:LiveId)->Option<&'a str>{
173        for i in self.index..self.nodes.len(){
174            match &self.nodes[i]{
175                HtmlNode::OpenTag{nc,..} if *nc == tag =>{
176                    // the next one must be a text node
177                    if let Some(HtmlNode::Text{start, end,..}) = self.nodes.get(i+1){
178                        return Some(&self.decoded[*start..*end])
179                    }
180                }
181                _=>()
182            }
183        }
184        None
185    }
186        
187    pub fn text(&self)->Option<&'a str>{
188        match self.nodes.get(self.index){
189            Some(HtmlNode::Text{start,end,..})=>{
190                Some(&self.decoded[*start..*end])
191            }
192            _=> None
193        }
194    }
195    
196    pub fn text_is_all_ws(&self)->bool{
197        match self.nodes.get(self.index){
198            Some(HtmlNode::Text{all_ws,..})=>{
199                *all_ws
200            }
201            _=> false
202        }
203    }
204    
205    pub fn open_tag_lc(&self)->Option<LiveId>{
206        match self.nodes.get(self.index){
207            Some(HtmlNode::OpenTag{lc,nc:_})=>{
208                Some(*lc)
209            }
210            _=> None
211        }
212    }
213    pub fn open_tag_nc(&self)->Option<LiveId>{
214        match self.nodes.get(self.index){
215            Some(HtmlNode::OpenTag{lc:_,nc})=>{
216                Some(*nc)
217            }
218            _=> None
219        }
220    }
221    pub fn open_tag(&self)->Option<(LiveId,LiveId)>{
222        match self.nodes.get(self.index){
223            Some(HtmlNode::OpenTag{lc,nc})=>{
224                Some((*lc, *nc))
225            }
226            _=> None
227        }
228    }
229    
230    pub fn close_tag_lc(&self)->Option<LiveId>{
231        match self.nodes.get(self.index){
232            Some(HtmlNode::CloseTag{lc,nc:_})=>{
233                Some(*lc)
234            }
235            _=> None
236        }
237    }
238    pub fn close_tag_nc(&self)->Option<LiveId>{
239        match self.nodes.get(self.index){
240            Some(HtmlNode::CloseTag{lc:_,nc})=>{
241                Some(*nc)
242            }
243            _=> None
244        }
245    }
246    pub fn close_tag(&self)->Option<(LiveId,LiveId)>{
247        match self.nodes.get(self.index){
248            Some(HtmlNode::CloseTag{lc,nc})=>{
249                Some((*lc, *nc))
250            }
251            _=> None
252        }
253    }
254 }
255 
256 impl HtmlDoc{
257     pub fn new_walker(&self)->HtmlWalker{
258         HtmlWalker{
259             decoded:&self.decoded,
260             index: 0,
261             nodes:&self.nodes,
262         }
263     }
264     
265     pub fn new_walker_with_index(&self, index: usize)->HtmlWalker{
266         HtmlWalker{
267             decoded:&self.decoded,
268             index,
269             nodes:&self.nodes,
270         }
271     }
272 } 
273
274 pub fn parse_html(body:&str, errors:  &mut Option<Vec<HtmlError>>, intern:InternLiveId)->HtmlDoc{
275     enum State{
276         Text{
277             start: usize,
278             dec_start: usize,
279             last_non_whitespace: usize,
280             collapse_ws: bool,
281         },
282         ElementName(usize),
283         ElementClose(usize),
284         ElementAttrs,
285         ElementCloseScanSpaces,
286         ElementSelfClose,
287         AttribName(usize),
288         AttribValueEq(LiveId,LiveId),
289         AttribValueStart(LiveId,LiveId),
290         AttribValueSq(LiveId, LiveId, usize),
291         AttribValueDq(LiveId, LiveId, usize),
292         AttribValueBare(LiveId, LiveId, usize),
293         CommentStartDash1,
294         CommentStartDash2,
295         CommentEndDash,
296         CommentEnd,
297         DocType,
298         HeaderQuestion,
299         HeaderAngle,
300         CommentBody
301     }
302             
303     fn process_entity(c:char, in_entity:&mut Option<usize>,  decoded:&mut String, last_non_whitespace:&mut usize, collapse_ws:bool){
304         if let Some(start) = *in_entity{ // scan entity
305             if c == ';'{ // potential end of entity
306                 match match_entity(&decoded[start+1..]){
307                     Err(_e)=>{
308                         *in_entity = None;
309                     }
310                     Ok(entity)=>{
311                         *in_entity = None;
312                         decoded.truncate(start);
313                         decoded.push(std::char::from_u32(entity).unwrap());
314                         return
315                     }
316                 }
317             }
318             // definitely not an entity
319             else if c.is_whitespace() ||  decoded.len() - start>"DOWNLEFTRIGHTVECTOR".len()  {
320                 *in_entity = None;
321             }
322        }
323        if c=='&'{
324            *in_entity = Some(decoded.len());
325        }
326        if collapse_ws && c.is_whitespace(){
327            if *last_non_whitespace == decoded.len(){
328                decoded.push(' ');
329            }
330        }
331        else{
332            decoded.push(c);
333            if !c.is_whitespace() {
334                *last_non_whitespace = decoded.len();
335            }
336        }
337    }
338     
339     let mut nodes = Vec::new();
340     let mut state = State::Text{
341         start: 0,
342         dec_start: 0,
343         last_non_whitespace: 0,
344         collapse_ws: true,
345     };
346     let mut decoded = String::new();
347     let mut in_entity = None;
348     
349     for (i, c) in body.char_indices(){
350         state = match state{
351             State::DocType=>{
352                 if c == '>'{
353                     State::Text{
354                        start:i+1, 
355                        dec_start: decoded.len(), 
356                        last_non_whitespace: decoded.len(),
357                        collapse_ws: true
358                    }
359                 }
360                 else{
361                     State::DocType
362                 }
363             }
364             State::HeaderQuestion=>{
365                 if c == '?'{
366                    State::HeaderAngle
367                 }
368                 else{
369                     State::HeaderQuestion
370                 }              
371             }
372             State::HeaderAngle=>{
373                 if c == '>'{
374                     State::Text{
375                         start:i+1, 
376                         dec_start: decoded.len(), 
377                         last_non_whitespace: decoded.len(),
378                         collapse_ws: true
379                     }
380                 }
381                 else{
382                     State::HeaderQuestion
383                 }
384             }
385             State::Text{start, dec_start, last_non_whitespace, collapse_ws}=>{ 
386                 if c == '<'{
387                    if let Some(start) = in_entity{
388                        if let Some(errors) = errors{errors.push(HtmlError{message:"Unterminated entity".into(), position:start})};
389                    }
390                    nodes.push(HtmlNode::Text{start:dec_start, end:decoded.len(), all_ws:dec_start == last_non_whitespace});
391                    State::ElementName(i+1)
392                 }
393                 else{
394                     let mut last_non_whitespace = last_non_whitespace;
395                     process_entity(c, &mut in_entity, &mut decoded, &mut last_non_whitespace, collapse_ws);
396                     State::Text{start, dec_start, last_non_whitespace, collapse_ws}
397                 }
398             }
399             State::ElementName(start)=>{
400                 if c == '/' && i == start{
401                     State::ElementClose(i+1)
402                 }
403                 else if c == '!' && i == start{
404                     State::CommentStartDash1
405                 }
406                 else if c == '?'{
407                     State::HeaderQuestion
408                 }
409                 else if c.is_whitespace(){
410                     if start == i{
411                          if let Some(errors) = errors{errors.push(HtmlError{message:"Found whitespace at beginning of tag".into(), position:i})};
412                        State::Text{
413                            start:i+1, 
414                            dec_start:decoded.len(), 
415                            last_non_whitespace: decoded.len(),
416                            collapse_ws: true
417                        }
418                     }
419                     else{
420                        nodes.push(HtmlNode::OpenTag{lc:LiveId::from_str_lc(&body[start..i]),nc:LiveId::from_str_with_intern(&body[start..i],intern)});
421                        State::ElementAttrs
422                    }
423                }
424                 else if c == '/'{
425                     nodes.push(HtmlNode::OpenTag{lc:LiveId::from_str_lc(&body[start..i]),nc:LiveId::from_str_with_intern(&body[start..i], intern)});
426                     State::ElementSelfClose
427                 }
428                 else if c == '>'{
429                     let lc = LiveId::from_str_lc(&body[start..i]);
430                     let nc = LiveId::from_str_with_intern(&body[start..i], intern);
431                     nodes.push(HtmlNode::OpenTag{lc, nc});
432                     State::Text{
433                         start:i+1, 
434                         dec_start:decoded.len(), 
435                         last_non_whitespace: decoded.len(),
436                         collapse_ws: lc != live_id!(pre) && lc != live_id!(code)
437                     }
438                 }
439                 else{
440                     State::ElementName(start)
441                 }
442             }
443             State::ElementClose(start)=>{
444                 if c == '>'{
445                     let lc = LiveId::from_str_lc(&body[start..i]);
446                     let nc = LiveId::from_str_with_intern(&body[start..i], intern);
447                     nodes.push(HtmlNode::CloseTag{lc, nc});
448                     State::Text{
449                         start:i+1, 
450                         dec_start:decoded.len(), 
451                         last_non_whitespace: decoded.len(),
452                         collapse_ws: true
453                     }
454                 }
455                 else if c.is_whitespace(){
456                     nodes.push(HtmlNode::CloseTag{lc:LiveId::from_str_lc(&body[start..i]),nc:LiveId::from_str_with_intern(&body[start..i], intern)});
457                     State::ElementCloseScanSpaces
458                 }
459                 else{
460                     State::ElementClose(start)
461                 }
462             }
463             State::ElementCloseScanSpaces=>{
464                 if c == '>'{
465                     State::Text{
466                         start:i+1, 
467                         dec_start:decoded.len(), 
468                         last_non_whitespace: decoded.len(),
469                         collapse_ws: true
470                     }
471                 }
472                 else if !c.is_whitespace(){
473                      if let Some(errors) = errors{errors.push(HtmlError{message:"Unexpected character after whitespace whilst looking for closing tag >".into(), position:i})};
474                      State::Text{
475                          start:i+1, 
476                          dec_start:decoded.len(), 
477                          last_non_whitespace: decoded.len(),
478                          collapse_ws: true
479                      }
480                 }
481                 else{
482                     State::ElementCloseScanSpaces
483                 }
484             }
485             State::ElementSelfClose=>{
486                 if c != '>'{
487                      if let Some(errors) = errors{errors.push(HtmlError{message:"Expected > after / self closed tag".into(), position:i})};
488                 }
489                 // look backwards to the OpenTag
490                 let begin = nodes.iter().rev().find_map(|v| if let HtmlNode::OpenTag{lc,nc} = v{Some((lc,nc))}else{None}).unwrap();
491                 nodes.push(HtmlNode::CloseTag{lc:*begin.0,nc:*begin.1});
492                 State::Text{
493                     start:i+1, 
494                     dec_start:decoded.len(), 
495                     last_non_whitespace: decoded.len(),
496                     collapse_ws: true
497                 }
498             }
499             State::ElementAttrs=>{
500                 if c == '/'{
501                     //nodes.push(HtmlNode::BeginElement(HtmlId::new(&body, start, i)));
502                     State::ElementSelfClose
503                 }
504                 else if c == '>'{
505                     
506                     let begin = nodes.iter().rev().find_map(|v| if let HtmlNode::OpenTag{lc,nc:_} = v{Some(*lc)}else{None});
507                     
508                     State::Text{
509                         start:i+1, 
510                         dec_start:decoded.len(), 
511                         last_non_whitespace: decoded.len(),
512                         collapse_ws: if let Some(lc) = begin{lc != live_id!(pre) && lc != live_id!(code)}else{true}
513                     }
514                 }
515                 else if !c.is_whitespace(){
516                     State::AttribName(i)
517                 }
518                 else{
519                     State::ElementAttrs
520                 }
521             }
522             State::AttribName(start)=>{
523                 if c.is_whitespace() {
524                     State::AttribValueEq(LiveId::from_str_lc(&body[start..i]),LiveId::from_str_with_intern(&body[start..i], intern))
525                 }
526                 else if c == '='{
527                     State::AttribValueStart(LiveId::from_str_lc(&body[start..i]),LiveId::from_str_with_intern(&body[start..i], intern))
528                 }
529                 else if c == '/'{
530                     nodes.push(HtmlNode::Attribute{lc:LiveId::from_str_lc(&body[start..i]),nc:LiveId::from_str_with_intern(&body[start..i], intern),start:0,end:0});
531                     State::ElementSelfClose
532                 }
533                 else if c == '>'{
534                     nodes.push(HtmlNode::Attribute{lc:LiveId::from_str_lc(&body[start..i]),nc:LiveId::from_str_with_intern(&body[start..i], intern),start:0,end:0});
535                    State::Text{
536                         start:i+1, 
537                         dec_start:decoded.len(), 
538                         last_non_whitespace: decoded.len(),
539                         collapse_ws: true
540                    }
541                 }
542                 else{
543                     State::AttribName(start)
544                 }
545             }
546             State::AttribValueEq(lc,nc)=>{
547                 if c == '/'{
548                     nodes.push(HtmlNode::Attribute{lc,nc,start:0,end:0});
549                     State::ElementSelfClose
550                 }
551                 else if c == '>'{
552                     nodes.push(HtmlNode::Attribute{lc,nc,start:0,end:0});
553                     State::Text{
554                         start:i+1, 
555                         dec_start:decoded.len(), 
556                         last_non_whitespace: decoded.len(),
557                         collapse_ws: true
558                     }
559                 }
560                 else if c == '='{
561                     State::AttribValueStart(lc,nc)
562                 }
563                 else if !c.is_whitespace(){
564                     nodes.push(HtmlNode::Attribute{lc,nc,start:0,end:0});
565                     State::AttribName(i)
566                 }
567                 else{
568                     State::AttribValueEq(lc,nc)
569                 }
570             }
571             State::AttribValueStart(lc,nc)=>{
572                 if c == '\"'{
573                     // double quoted attrib
574                     State::AttribValueDq(lc,nc, decoded.len())
575                 }
576                 else if c == '\''{
577                     // single quoted attrib 
578                     State::AttribValueSq(lc,nc, decoded.len())
579                 }
580                 else if !c.is_whitespace(){
581                     decoded.push(c);
582                     State::AttribValueBare(lc,nc, decoded.len()-1)
583                 }
584                 else{
585                     State::AttribValueStart(lc,nc)
586                 }
587             }
588             State::AttribValueSq(lc,nc, start)=>{
589                 if c == '\''{
590                     if let Some(start) = in_entity{
591                          if let Some(errors) = errors{errors.push(HtmlError{message:"Unterminated entity".into(), position:start})};
592                     }
593                     nodes.push(HtmlNode::Attribute{lc,nc, start, end:decoded.len()});
594                     State::ElementAttrs
595                 }
596                 else{
597                     process_entity(c, &mut in_entity, &mut decoded, &mut 0, false);
598                     State::AttribValueSq(lc,nc, start)
599                 }
600             }
601             State::AttribValueDq(lc,nc, start)=>{
602                 if c == '\"'{
603                     if let Some(start) = in_entity{
604                          if let Some(errors) = errors{errors.push(HtmlError{message:"Unterminated entity".into(), position:start})};
605                     }
606                     nodes.push(HtmlNode::Attribute{lc,nc, start, end:decoded.len()});
607                     State::ElementAttrs
608                 }
609                 else{
610                     process_entity(c, &mut in_entity, &mut decoded, &mut 0, false);
611                     State::AttribValueDq(lc,nc, start)
612                 }
613             }
614             State::AttribValueBare(lc,nc, start)=>{
615                 if c == '/'{
616                     nodes.push(HtmlNode::Attribute{lc,nc, start, end:decoded.len()});
617                     State::ElementSelfClose
618                 }
619                 else if c == '>'{
620                     nodes.push(HtmlNode::Attribute{lc,nc, start, end:decoded.len()});
621                     State::Text{
622                         start:i+1, 
623                         dec_start:decoded.len(), 
624                         last_non_whitespace: decoded.len(),
625                         collapse_ws: true
626                     }
627                 }
628                 else if c.is_whitespace(){
629                     nodes.push(HtmlNode::Attribute{lc,nc, start, end:decoded.len()});
630                     State::ElementAttrs
631                 }
632                 else{
633                     decoded.push(c);
634                     State::AttribValueBare(lc,nc, start)
635                 }
636             }
637             State::CommentStartDash1=>{
638                 if c != '-'{
639                     // we should scan for >
640                     State::DocType
641                     // if let Some(errors) = errors{errors.push(HtmlError{message:"Unexpected //character looking for - after <!".into(), position:i})};
642                 }
643                 else{
644                    State::CommentStartDash2
645                }
646             }
647             State::CommentStartDash2=>{
648                 if c != '-'{
649                      if let Some(errors) = errors{errors.push(HtmlError{message:"Unexpected character looking for - after <!-".into(), position:i})};
650                 }
651                 State::CommentBody
652             }
653             State::CommentBody=>{
654                 if c == '-'{
655                     State::CommentEndDash
656                 }
657                 else{
658                     State::CommentBody
659                 }
660             }
661             State::CommentEndDash=>{
662                 if c == '-'{
663                     State::CommentEnd
664                 }
665                 else{
666                     State::CommentBody
667                 }
668             },
669             State::CommentEnd=>{
670                 if c == '>'{
671                     State::Text{
672                         start:i+1, 
673                         dec_start:decoded.len(), 
674                         last_non_whitespace: decoded.len(),
675                         collapse_ws: true
676                     }
677                 }
678                 else{
679                     State::CommentBody
680                 }
681             }
682         }
683     }
684     if let State::Text{start:_, dec_start, last_non_whitespace, collapse_ws:_} = state{
685        nodes.push(HtmlNode::Text{start:dec_start, end:decoded.len(), all_ws:dec_start == last_non_whitespace});
686     }
687     else{ // if we didnt end in text state something is wrong
688          if let Some(errors) = errors{errors.push(HtmlError{message:"HTML Parsing endstate is not HtmlNode::Text".into(), position:body.len()})};
689     }
690     HtmlDoc{
691         nodes,
692         decoded,
693     }
694 }
695 
696 pub fn match_entity(what:&str)->Result<u32,String>{
697     Ok(match what{
698         "dollar"=>36,
699         "DOLLAR"=>36,
700         "cent"=>162,
701         "CENT"=>162,
702         "pound"=>163,
703         "POUND"=>163,
704         "curren"=>164,
705         "CURREN"=>164,
706         "yen"=>165,
707         "YEN"=>165,
708         "copy"=>169,
709         "COPY"=>169,
710         "reg"=>174,
711         "REG"=>174,
712         "trade"=>8482,
713         "TRADE"=>8482,
714         "commat"=>64,
715         "COMMAT"=>64,
716         "Copf"=>8450,
717         "copf"=>8450,
718         "COPF"=>8450,
719         "incare"=>8453,
720         "INCARE"=>8453,
721         "gscr"=>8458,
722         "GSCR"=>8458,
723         "hamilt"=>8459,
724         "HAMILT"=>8459,
725         "Hfr"=>8460,
726         "hfr"=>8460,
727         "HFR"=>8460,
728         "Hopf"=>8461,
729         "hopf"=>8461,
730         "HOPF"=>8461,
731         "planckh"=>8462,
732         "PLANCKH"=>8462,
733         "planck"=>8463,
734         "PLANCK"=>8463,
735         "Iscr"=>8464,
736         "iscr"=>8464,
737         "ISCR"=>8464,
738         "image"=>8465,
739         "IMAGE"=>8465,
740         "Lscr"=>8466,
741         "lscr"=>8466,
742         "LSCR"=>8466,
743         "ell"=>8467,
744         "ELL"=>8467,
745         "Nopf"=>8469,
746         "nopf"=>8469,
747         "NOPF"=>8469,
748         "numero"=>8470,
749         "NUMERO"=>8470,
750         "copysr"=>8471,
751         "COPYSR"=>8471,
752         "weierp"=>8472,
753         "WEIERP"=>8472,
754         "Popf"=>8473,
755         "popf"=>8473,
756         "POPF"=>8473,
757         "Qopf"=>8474,
758         "qopf"=>8474,
759         "QOPF"=>8474,
760         "Rscr"=>8475,
761         "rscr"=>8475,
762         "RSCR"=>8475,
763         "real"=>8476,
764         "REAL"=>8476,
765         "Ropf"=>8477,
766         "ropf"=>8477,
767         "ROPF"=>8477,
768         "rx"=>8478,
769         "RX"=>8478,
770         "Zopf"=>8484,
771         "zopf"=>8484,
772         "ZOPF"=>8484,
773         "mho"=>8487,
774         "MHO"=>8487,
775         "Zfr"=>8488,
776         "zfr"=>8488,
777         "ZFR"=>8488,
778         "iiota"=>8489,
779         "IIOTA"=>8489,
780         "bernou"=>8492,
781         "BERNOU"=>8492,
782         "Cfr"=>8493,
783         "cfr"=>8493,
784         "CFR"=>8493,
785         "escr"=>8495,
786         "ESCR"=>8495,
787         "Escr"=>8496,
788         "Fscr"=>8497,
789         "fscr"=>8497,
790         "FSCR"=>8497,
791         "Mscr"=>8499,
792         "mscr"=>8499,
793         "MSCR"=>8499,
794         "oscr"=>8500,
795         "OSCR"=>8500,
796         "alefsym"=>8501,
797         "ALEFSYM"=>8501,
798         "beth"=>8502,
799         "BETH"=>8502,
800         "gimel"=>8503,
801         "GIMEL"=>8503,
802         "daleth"=>8504,
803         "DALETH"=>8504,
804         "DD"=>8517,
805         "dd"=>8517,
806         "ee"=>8519,
807         "EE"=>8519,
808         "ii"=>8520,
809         "II"=>8520,
810         "starf"=>9733,
811         "STARF"=>9733,
812         "star"=>9734,
813         "STAR"=>9734,
814         "phone"=>9742,
815         "PHONE"=>9742,
816         "female"=>9792,
817         "FEMALE"=>9792,
818         "male"=>9794,
819         "MALE"=>9794,
820         "spades"=>9824,
821         "SPADES"=>9824,
822         "clubs"=>9827,
823         "CLUBS"=>9827,
824         "hearts"=>9829,
825         "HEARTS"=>9829,
826         "diams"=>9830,
827         "DIAMS"=>9830,
828         "loz"=>9674,
829         "LOZ"=>9674,
830         "sung"=>9834,
831         "SUNG"=>9834,
832         "flat"=>9837,
833         "FLAT"=>9837,
834         "natural"=>9838,
835         "NATURAL"=>9838,
836         "sharp"=>9839,
837         "SHARP"=>9839,
838         "check"=>10003,
839         "CHECK"=>10003,
840         "cross"=>10007,
841         "CROSS"=>10007,
842         "malt"=>10016,
843         "MALT"=>10016,
844         "sext"=>10038,
845         "SEXT"=>10038,
846         "VerticalSeparator"=>10072,
847         "verticalseparator"=>10072,
848         "VERTICALSEPARATOR"=>10072,
849         "lbbrk"=>10098,
850         "LBBRK"=>10098,
851         "rbbrk"=>10099,
852         "RBBRK"=>10099,
853         "excl"=>33,
854         "EXCL"=>33,
855         "num"=>35,
856         "NUM"=>35,
857         "percnt"=>37,
858         "PERCNT"=>37,
859         "amp"=>38,
860         "AMP"=>38,
861         "lpar"=>40,
862         "LPAR"=>40,
863         "rpar"=>41,
864         "RPAR"=>41,
865         "ast"=>42,
866         "AST"=>42,
867         "comma"=>44,
868         "COMMA"=>44,
869         "period"=>46,
870         "PERIOD"=>46,
871         "sol"=>47,
872         "SOL"=>47,
873         "colon"=>58,
874         "COLON"=>58,
875         "semi"=>59,
876         "SEMI"=>59,
877         "quest"=>63,
878         "QUEST"=>63,
879         "lbrack"=>91,
880         "LBRACK"=>91,
881         "bsol"=>92,
882         "BSOL"=>92,
883         "rbrack"=>93,
884         "RBRACK"=>93,
885         "Hat"=>94,
886         "hat"=>94,
887         "HAT"=>94,
888         "lowbar"=>95,
889         "LOWBAR"=>95,
890         "grave"=>96,
891         "GRAVE"=>96,
892         "lbrace"=>123,
893         "LBRACE"=>123,
894         "vert"=>124,
895         "VERT"=>124,
896         "rbrace"=>125,
897         "RBRACE"=>125,
898         "tilde"=>126,
899         "TILDE"=>126,
900         "circ"=>710,
901         "CIRC"=>710,
902         "nbsp"=>160,
903         "NBSP"=>160,
904         "ensp"=>8194,
905         "ENSP"=>8194,
906         "emsp"=>8195,
907         "EMSP"=>8195,
908         "thinsp"=>8201,
909         "THINSP"=>8201,
910         "zwnj"=>8204,
911         "ZWNJ"=>8204,
912         "zwj"=>8205,
913         "ZWJ"=>8205,
914         "lrm"=>8206,
915         "LRM"=>8206,
916         "rlm"=>8207,
917         "RLM"=>8207,
918         "iexcl"=>161,
919         "IEXCL"=>161,
920         "brvbar"=>166,
921         "BRVBAR"=>166,
922         "sect"=>167,
923         "SECT"=>167,
924         "uml"=>168,
925         "UML"=>168,
926         "ordf"=>170,
927         "ORDF"=>170,
928         "not"=>172,
929         "NOT"=>172,
930         "shy"=>173,
931         "SHY"=>173,
932         "macr"=>175,
933         "MACR"=>175,
934         "sup2"=>178,
935         "SUP2"=>178,
936         "sup3"=>179,
937         "SUP3"=>179,
938         "acute"=>180,
939         "ACUTE"=>180,
940         "micro"=>181,
941         "MICRO"=>181,
942         "para"=>182,
943         "PARA"=>182,
944         "middot"=>183,
945         "MIDDOT"=>183,
946         "cedil"=>184,
947         "CEDIL"=>184,
948         "sup1"=>185,
949         "SUP1"=>185,
950         "ordm"=>186,
951         "ORDM"=>186,
952         "iquest"=>191,
953         "IQUEST"=>191,
954         "hyphen"=>8208,
955         "HYPHEN"=>8208,
956         "ndash"=>8211,
957         "NDASH"=>8211,
958         "mdash"=>8212,
959         "MDASH"=>8212,
960         "horbar"=>8213,
961         "HORBAR"=>8213,
962         "Vert"=>8214,
963         "dagger"=>8224,
964         "DAGGER"=>8224,
965         "Dagger"=>8225,
966         "bull"=>8226,
967         "BULL"=>8226,
968         "nldr"=>8229,
969         "NLDR"=>8229,
970         "hellip"=>8230,
971         "HELLIP"=>8230,
972         ""=>8240,
973         "pertenk"=>8241,
974         "PERTENK"=>8241,
975         "prime"=>8242,
976         "PRIME"=>8242,
977         "Prime"=>8243,
978         "tprime"=>8244,
979         "TPRIME"=>8244,
980         "bprime"=>8245,
981         "BPRIME"=>8245,
982         "oline"=>8254,
983         "OLINE"=>8254,
984         "caret"=>8257,
985         "CARET"=>8257,
986         "hybull"=>8259,
987         "HYBULL"=>8259,
988         "frasl"=>8260,
989         "FRASL"=>8260,
990         "bsemi"=>8271,
991         "BSEMI"=>8271,
992         "qprime"=>8279,
993         "QPRIME"=>8279,
994         "quot"=>34,
995         "QUOT"=>34,
996         "apos"=>39,
997         "APOS"=>39,
998         "laquo"=>171,
999         "LAQUO"=>171,
1000         "raquo"=>187,
1001         "RAQUO"=>187,
1002         "lsquo"=>8216,
1003         "LSQUO"=>8216,
1004         "rsquo"=>8217,
1005         "RSQUO"=>8217,
1006         "sbquo"=>8218,
1007         "SBQUO"=>8218,
1008         "ldquo"=>8220,
1009         "LDQUO"=>8220,
1010         "rdquo"=>8221,
1011         "RDQUO"=>8221,
1012         "bdquo"=>8222,
1013         "BDQUO"=>8222,
1014         "lsaquo"=>8249,
1015         "LSAQUO"=>8249,
1016         "rsaquo"=>8250,
1017         "RSAQUO"=>8250,
1018         "frac14"=>188,
1019         "FRAC14"=>188,
1020         "frac12"=>189,
1021         "FRAC12"=>189,
1022         "frac34"=>190,
1023         "FRAC34"=>190,
1024         "frac13"=>8531,
1025         "FRAC13"=>8531,
1026         "frac23"=>8532,
1027         "FRAC23"=>8532,
1028         "frac15"=>8533,
1029         "FRAC15"=>8533,
1030         "frac25"=>8534,
1031         "FRAC25"=>8534,
1032         "frac35"=>8535,
1033         "FRAC35"=>8535,
1034         "frac45"=>8536,
1035         "FRAC45"=>8536,
1036         "frac16"=>8537,
1037         "FRAC16"=>8537,
1038         "frac56"=>8538,
1039         "FRAC56"=>8538,
1040         "frac18"=>8539,
1041         "FRAC18"=>8539,
1042         "frac38"=>8540,
1043         "FRAC38"=>8540,
1044         "frac58"=>8541,
1045         "FRAC58"=>8541,
1046         "frac78"=>8542,
1047         "FRAC78"=>8542,
1048         "plus"=>43,
1049         "PLUS"=>43,
1050         "minus"=>8722,
1051         "MINUS"=>8722,
1052         "times"=>215,
1053         "TIMES"=>215,
1054         "divide"=>247,
1055         "DIVIDE"=>247,
1056         "equals"=>61,
1057         "EQUALS"=>61,
1058         "ne"=>8800,
1059         "NE"=>8800,
1060         "plusmn"=>177,
1061         "PLUSMN"=>177,
1062         "lt"=>60,
1063         "LT"=>60,
1064         "gt"=>62,
1065         "GT"=>62,
1066         "deg"=>176,
1067         "DEG"=>176,
1068         "fnof"=>402,
1069         "FNOF"=>402,
1070         "permil"=>137,
1071         "PERMIL"=>137,
1072         "forall"=>8704,
1073         "FORALL"=>8704,
1074         "comp"=>8705,
1075         "COMP"=>8705,
1076         "part"=>8706,
1077         "PART"=>8706,
1078         "exist"=>8707,
1079         "EXIST"=>8707,
1080         "nexist"=>8708,
1081         "NEXIST"=>8708,
1082         "empty"=>8709,
1083         "EMPTY"=>8709,
1084         "nabla"=>8711,
1085         "NABLA"=>8711,
1086         "isin"=>8712,
1087         "ISIN"=>8712,
1088         "notin"=>8713,
1089         "NOTIN"=>8713,
1090         "ni"=>8715,
1091         "NI"=>8715,
1092         "notni"=>8716,
1093         "NOTNI"=>8716,
1094         "prod"=>8719,
1095         "PROD"=>8719,
1096         "coprod"=>8720,
1097         "COPROD"=>8720,
1098         "sum"=>8721,
1099         "SUM"=>8721,
1100         "mnplus"=>8723,
1101         "MNPLUS"=>8723,
1102         "plusdo"=>8724,
1103         "PLUSDO"=>8724,
1104         "setminus"=>8726,
1105         "SETMINUS"=>8726,
1106         "lowast"=>8727,
1107         "LOWAST"=>8727,
1108         "compfn"=>8728,
1109         "COMPFN"=>8728,
1110         "radic"=>8730,
1111         "RADIC"=>8730,
1112         "prop"=>8733,
1113         "PROP"=>8733,
1114         "infin"=>8734,
1115         "INFIN"=>8734,
1116         "angrt"=>8735,
1117         "ANGRT"=>8735,
1118         "ang"=>8736,
1119         "ANG"=>8736,
1120         "angmsd"=>8737,
1121         "ANGMSD"=>8737,
1122         "angsph"=>8738,
1123         "ANGSPH"=>8738,
1124         "mid"=>8739,
1125         "MID"=>8739,
1126         "nmid"=>8740,
1127         "NMID"=>8740,
1128         "parallel"=>8741,
1129         "PARALLEL"=>8741,
1130         "npar"=>8742,
1131         "NPAR"=>8742,
1132         "and"=>8743,
1133         "AND"=>8743,
1134         "or"=>8744,
1135         "OR"=>8744,
1136         "cap"=>8745,
1137         "CAP"=>8745,
1138         "cup"=>8746,
1139         "CUP"=>8746,
1140         "int"=>8747,
1141         "INT"=>8747,
1142         "Int"=>8748,
1143         "iiint"=>8749,
1144         "IIINT"=>8749,
1145         "conint"=>8750,
1146         "CONINT"=>8750,
1147         "Conint"=>8751,
1148         "Cconint"=>8752,
1149         "cconint"=>8752,
1150         "CCONINT"=>8752,
1151         "cwint"=>8753,
1152         "CWINT"=>8753,
1153         "cwconint"=>8754,
1154         "CWCONINT"=>8754,
1155         "awconint"=>8755,
1156         "AWCONINT"=>8755,
1157         "there4"=>8756,
1158         "THERE4"=>8756,
1159         "because"=>8757,
1160         "BECAUSE"=>8757,
1161         "ratio"=>8758,
1162         "RATIO"=>8758,
1163         "Colon"=>8759,
1164         "minusd"=>8760,
1165         "MINUSD"=>8760,
1166         "mDDot"=>8762,
1167         "mddot"=>8762,
1168         "MDDOT"=>8762,
1169         "homtht"=>8763,
1170         "HOMTHT"=>8763,
1171         "sim"=>8764,
1172         "SIM"=>8764,
1173         "bsim"=>8765,
1174         "BSIM"=>8765,
1175         "ac"=>8766,
1176         "AC"=>8766,
1177         "acd"=>8767,
1178         "ACD"=>8767,
1179         "wreath"=>8768,
1180         "WREATH"=>8768,
1181         "nsim"=>8769,
1182         "NSIM"=>8769,
1183         "esim"=>8770,
1184         "ESIM"=>8770,
1185         "sime"=>8771,
1186         "SIME"=>8771,
1187         "nsime"=>8772,
1188         "NSIME"=>8772,
1189         "cong"=>8773,
1190         "CONG"=>8773,
1191         "simne"=>8774,
1192         "SIMNE"=>8774,
1193         "ncong"=>8775,
1194         "NCONG"=>8775,
1195         "asymp"=>8776,
1196         "ASYMP"=>8776,
1197         "nap"=>8777,
1198         "NAP"=>8777,
1199         "approxeq"=>8778,
1200         "APPROXEQ"=>8778,
1201         "apid"=>8779,
1202         "APID"=>8779,
1203         "bcong"=>8780,
1204         "BCONG"=>8780,
1205         "asympeq"=>8781,
1206         "ASYMPEQ"=>8781,
1207         "bump"=>8782,
1208         "BUMP"=>8782,
1209         "bumpe"=>8783,
1210         "BUMPE"=>8783,
1211         "esdot"=>8784,
1212         "ESDOT"=>8784,
1213         "eDot"=>8785,
1214         "edot"=>8785,
1215         "EDOT"=>8785,
1216         "efDot"=>8786,
1217         "efdot"=>8786,
1218         "EFDOT"=>8786,
1219         "erDot"=>8787,
1220         "erdot"=>8787,
1221         "ERDOT"=>8787,
1222         "colone"=>8788,
1223         "COLONE"=>8788,
1224         "ecolon"=>8789,
1225         "ECOLON"=>8789,
1226         "ecir"=>8790,
1227         "ECIR"=>8790,
1228         "cire"=>8791,
1229         "CIRE"=>8791,
1230         "wedgeq"=>8793,
1231         "WEDGEQ"=>8793,
1232         "veeeq"=>8794,
1233         "VEEEQ"=>8794,
1234         "trie"=>8796,
1235         "TRIE"=>8796,
1236         "equest"=>8799,
1237         "EQUEST"=>8799,
1238         "equiv"=>8801,
1239         "EQUIV"=>8801,
1240         "nequiv"=>8802,
1241         "NEQUIV"=>8802,
1242         "le"=>8804,
1243         "LE"=>8804,
1244         "ge"=>8805,
1245         "GE"=>8805,
1246         "lE"=>8806,
1247         "gE"=>8807,
1248         "lnE"=>8808,
1249         "lne"=>8808,
1250         "LNE"=>8808,
1251         "gnE"=>8809,
1252         "gne"=>8809,
1253         "GNE"=>8809,
1254         "Lt"=>8810,
1255         "Gt"=>8811,
1256         "between"=>8812,
1257         "BETWEEN"=>8812,
1258         "NotCupCap"=>8813,
1259         "notcupcap"=>8813,
1260         "NOTCUPCAP"=>8813,
1261         "nlt"=>8814,
1262         "NLT"=>8814,
1263         "ngt"=>8815,
1264         "NGT"=>8815,
1265         "nle"=>8816,
1266         "NLE"=>8816,
1267         "nge"=>8817,
1268         "NGE"=>8817,
1269         "lsim"=>8818,
1270         "LSIM"=>8818,
1271         "gsim"=>8819,
1272         "GSIM"=>8819,
1273         "nlsim"=>8820,
1274         "NLSIM"=>8820,
1275         "ngsim"=>8821,
1276         "NGSIM"=>8821,
1277         "lg"=>8822,
1278         "LG"=>8822,
1279         "gl"=>8823,
1280         "GL"=>8823,
1281         "ntlg"=>8824,
1282         "NTLG"=>8824,
1283         "ntgl"=>8825,
1284         "NTGL"=>8825,
1285         "pr"=>8826,
1286         "PR"=>8826,
1287         "sc"=>8827,
1288         "SC"=>8827,
1289         "prcue"=>8828,
1290         "PRCUE"=>8828,
1291         "sccue"=>8829,
1292         "SCCUE"=>8829,
1293         "prsim"=>8830,
1294         "PRSIM"=>8830,
1295         "scsim"=>8831,
1296         "SCSIM"=>8831,
1297         "npr"=>8832,
1298         "NPR"=>8832,
1299         "nsc"=>8833,
1300         "NSC"=>8833,
1301         "sub"=>8834,
1302         "SUB"=>8834,
1303         "sup"=>8835,
1304         "SUP"=>8835,
1305         "nsub"=>8836,
1306         "NSUB"=>8836,
1307         "nsup"=>8837,
1308         "NSUP"=>8837,
1309         "sube"=>8838,
1310         "SUBE"=>8838,
1311         "supe"=>8839,
1312         "SUPE"=>8839,
1313         "nsube"=>8840,
1314         "NSUBE"=>8840,
1315         "nsupe"=>8841,
1316         "NSUPE"=>8841,
1317         "subne"=>8842,
1318         "SUBNE"=>8842,
1319         "supne"=>8843,
1320         "SUPNE"=>8843,
1321         "cupdot"=>8845,
1322         "CUPDOT"=>8845,
1323         "uplus"=>8846,
1324         "UPLUS"=>8846,
1325         "sqsub"=>8847,
1326         "SQSUB"=>8847,
1327         "sqsup"=>8848,
1328         "SQSUP"=>8848,
1329         "sqsube"=>8849,
1330         "SQSUBE"=>8849,
1331         "sqsupe"=>8850,
1332         "SQSUPE"=>8850,
1333         "sqcap"=>8851,
1334         "SQCAP"=>8851,
1335         "sqcup"=>8852,
1336         "SQCUP"=>8852,
1337         "oplus"=>8853,
1338         "OPLUS"=>8853,
1339         "ominus"=>8854,
1340         "OMINUS"=>8854,
1341         "otimes"=>8855,
1342         "OTIMES"=>8855,
1343         "osol"=>8856,
1344         "OSOL"=>8856,
1345         "odot"=>8857,
1346         "ODOT"=>8857,
1347         "ocir"=>8858,
1348         "OCIR"=>8858,
1349         "oast"=>8859,
1350         "OAST"=>8859,
1351         "odash"=>8861,
1352         "ODASH"=>8861,
1353         "plusb"=>8862,
1354         "PLUSB"=>8862,
1355         "minusb"=>8863,
1356         "MINUSB"=>8863,
1357         "timesb"=>8864,
1358         "TIMESB"=>8864,
1359         "sdotb"=>8865,
1360         "SDOTB"=>8865,
1361         "vdash"=>8866,
1362         "VDASH"=>8866,
1363         "dashv"=>8867,
1364         "DASHV"=>8867,
1365         "top"=>8868,
1366         "TOP"=>8868,
1367         "perp"=>8869,
1368         "PERP"=>8869,
1369         "models"=>8871,
1370         "MODELS"=>8871,
1371         "vDash"=>8872,
1372         "Vdash"=>8873,
1373         "Vvdash"=>8874,
1374         "vvdash"=>8874,
1375         "VVDASH"=>8874,
1376         "VDash"=>8875,
1377         "nvdash"=>8876,
1378         "NVDASH"=>8876,
1379         "nvDash"=>8877,
1380         "nVdash"=>8878,
1381         "nVDash"=>8879,
1382         "prurel"=>8880,
1383         "PRUREL"=>8880,
1384         "vltri"=>8882,
1385         "VLTRI"=>8882,
1386         "vrtri"=>8883,
1387         "VRTRI"=>8883,
1388         "ltrie"=>8884,
1389         "LTRIE"=>8884,
1390         "rtrie"=>8885,
1391         "RTRIE"=>8885,
1392         "origof"=>8886,
1393         "ORIGOF"=>8886,
1394         "imof"=>8887,
1395         "IMOF"=>8887,
1396         "mumap"=>8888,
1397         "MUMAP"=>8888,
1398         "hercon"=>8889,
1399         "HERCON"=>8889,
1400         "intcal"=>8890,
1401         "INTCAL"=>8890,
1402         "veebar"=>8891,
1403         "VEEBAR"=>8891,
1404         "barvee"=>8893,
1405         "BARVEE"=>8893,
1406         "angrtvb"=>8894,
1407         "ANGRTVB"=>8894,
1408         "lrtri"=>8895,
1409         "LRTRI"=>8895,
1410         "xwedge"=>8896,
1411         "XWEDGE"=>8896,
1412         "xvee"=>8897,
1413         "XVEE"=>8897,
1414         "xcap"=>8898,
1415         "XCAP"=>8898,
1416         "xcup"=>8899,
1417         "XCUP"=>8899,
1418         "diamond"=>8900,
1419         "DIAMOND"=>8900,
1420         "sdot"=>8901,
1421         "SDOT"=>8901,
1422         "Star"=>8902,
1423         "divonx"=>8903,
1424         "DIVONX"=>8903,
1425         "bowtie"=>8904,
1426         "BOWTIE"=>8904,
1427         "ltimes"=>8905,
1428         "LTIMES"=>8905,
1429         "rtimes"=>8906,
1430         "RTIMES"=>8906,
1431         "lthree"=>8907,
1432         "LTHREE"=>8907,
1433         "rthree"=>8908,
1434         "RTHREE"=>8908,
1435         "bsime"=>8909,
1436         "BSIME"=>8909,
1437         "cuvee"=>8910,
1438         "CUVEE"=>8910,
1439         "cuwed"=>8911,
1440         "CUWED"=>8911,
1441         "Sub"=>8912,
1442         "Sup"=>8913,
1443         "Cap"=>8914,
1444         "Cup"=>8915,
1445         "fork"=>8916,
1446         "FORK"=>8916,
1447         "epar"=>8917,
1448         "EPAR"=>8917,
1449         "ltdot"=>8918,
1450         "LTDOT"=>8918,
1451         "gtdot"=>8919,
1452         "GTDOT"=>8919,
1453         "Ll"=>8920,
1454         "ll"=>8920,
1455         "LL"=>8920,
1456         "Gg"=>8921,
1457         "gg"=>8921,
1458         "GG"=>8921,
1459         "leg"=>8922,
1460         "LEG"=>8922,
1461         "gel"=>8923,
1462         "GEL"=>8923,
1463         "cuepr"=>8926,
1464         "CUEPR"=>8926,
1465         "cuesc"=>8927,
1466         "CUESC"=>8927,
1467         "nprcue"=>8928,
1468         "NPRCUE"=>8928,
1469         "nsccue"=>8929,
1470         "NSCCUE"=>8929,
1471         "nsqsube"=>8930,
1472         "NSQSUBE"=>8930,
1473         "nsqsupe"=>8931,
1474         "NSQSUPE"=>8931,
1475         "lnsim"=>8934,
1476         "LNSIM"=>8934,
1477         "gnsim"=>8935,
1478         "GNSIM"=>8935,
1479         "prnsim"=>8936,
1480         "PRNSIM"=>8936,
1481         "scnsim"=>8937,
1482         "SCNSIM"=>8937,
1483         "nltri"=>8938,
1484         "NLTRI"=>8938,
1485         "nrtri"=>8939,
1486         "NRTRI"=>8939,
1487         "nltrie"=>8940,
1488         "NLTRIE"=>8940,
1489         "nrtrie"=>8941,
1490         "NRTRIE"=>8941,
1491         "vellip"=>8942,
1492         "VELLIP"=>8942,
1493         "ctdot"=>8943,
1494         "CTDOT"=>8943,
1495         "utdot"=>8944,
1496         "UTDOT"=>8944,
1497         "dtdot"=>8945,
1498         "DTDOT"=>8945,
1499         "disin"=>8946,
1500         "DISIN"=>8946,
1501         "isinsv"=>8947,
1502         "ISINSV"=>8947,
1503         "isins"=>8948,
1504         "ISINS"=>8948,
1505         "isindot"=>8949,
1506         "ISINDOT"=>8949,
1507         "notinvc"=>8950,
1508         "NOTINVC"=>8950,
1509         "notinvb"=>8951,
1510         "NOTINVB"=>8951,
1511         "isinE"=>8953,
1512         "isine"=>8953,
1513         "ISINE"=>8953,
1514         "nisd"=>8954,
1515         "NISD"=>8954,
1516         "xnis"=>8955,
1517         "XNIS"=>8955,
1518         "nis"=>8956,
1519         "NIS"=>8956,
1520         "notnivc"=>8957,
1521         "NOTNIVC"=>8957,
1522         "notnivb"=>8958,
1523         "NOTNIVB"=>8958,
1524         "lceil"=>8968,
1525         "LCEIL"=>8968,
1526         "rceil"=>8969,
1527         "RCEIL"=>8969,
1528         "lfloor"=>8970,
1529         "LFLOOR"=>8970,
1530         "rfloor"=>8971,
1531         "RFLOOR"=>8971,
1532         "lang"=>9001,
1533         "LANG"=>9001,
1534         "rang"=>9002,
1535         "RANG"=>9002,
1536         "Alpha"=>913,
1537         "alpha"=>913,
1538         "ALPHA"=>913,
1539         "Beta"=>914,
1540         "beta"=>914,
1541         "BETA"=>914,
1542         "Gamma"=>915,
1543         "gamma"=>915,
1544         "GAMMA"=>915,
1545         "Delta"=>916,
1546         "delta"=>916,
1547         "DELTA"=>916,
1548         "Epsilon"=>917,
1549         "epsilon"=>917,
1550         "EPSILON"=>917,
1551         "Zeta"=>918,
1552         "zeta"=>918,
1553         "ZETA"=>918,
1554         "Eta"=>919,
1555         "eta"=>919,
1556         "ETA"=>919,
1557         "Theta"=>920,
1558         "theta"=>920,
1559         "THETA"=>920,
1560         "Iota"=>921,
1561         "iota"=>921,
1562         "IOTA"=>921,
1563         "Kappa"=>922,
1564         "kappa"=>922,
1565         "KAPPA"=>922,
1566         "Lambda"=>923,
1567         "lambda"=>923,
1568         "LAMBDA"=>923,
1569         "Mu"=>924,
1570         "mu"=>924,
1571         "MU"=>924,
1572         "Nu"=>925,
1573         "nu"=>925,
1574         "NU"=>925,
1575         "Xi"=>926,
1576         "xi"=>926,
1577         "XI"=>926,
1578         "Omicron"=>927,
1579         "omicron"=>927,
1580         "OMICRON"=>927,
1581         "Pi"=>928,
1582         "pi"=>928,
1583         "PI"=>928,
1584         "Rho"=>929,
1585         "rho"=>929,
1586         "RHO"=>929,
1587         "Sigma"=>931,
1588         "sigma"=>931,
1589         "SIGMA"=>931,
1590         "Tau"=>932,
1591         "tau"=>932,
1592         "TAU"=>932,
1593         "Upsilon"=>933,
1594         "upsilon"=>933,
1595         "UPSILON"=>933,
1596         "Phi"=>934,
1597         "phi"=>934,
1598         "PHI"=>934,
1599         "Chi"=>935,
1600         "chi"=>935,
1601         "CHI"=>935,
1602         "Psi"=>936,
1603         "psi"=>936,
1604         "PSI"=>936,
1605         "Omega"=>937,
1606         "omega"=>937,
1607         "OMEGA"=>937,
1608         "sigmaf"=>962,
1609         "SIGMAF"=>962,
1610         "thetasym"=>977,
1611         "THETASYM"=>977,
1612         "upsih"=>978,
1613         "UPSIH"=>978,
1614         "piv"=>982,
1615         "PIV"=>982,
1616         "Agrave"=>192,
1617         "agrave"=>192,
1618         "AGRAVE"=>192,
1619         "Aacute"=>193,
1620         "aacute"=>193,
1621         "AACUTE"=>193,
1622         "Acirc"=>194,
1623         "acirc"=>194,
1624         "ACIRC"=>194,
1625         "Atilde"=>195,
1626         "atilde"=>195,
1627         "ATILDE"=>195,
1628         "Auml"=>196,
1629         "auml"=>196,
1630         "AUML"=>196,
1631         "Aring"=>197,
1632         "aring"=>197,
1633         "ARING"=>197,
1634         "AElig"=>198,
1635         "aelig"=>198,
1636         "AELIG"=>198,
1637         "Ccedil"=>199,
1638         "ccedil"=>199,
1639         "CCEDIL"=>199,
1640         "Egrave"=>200,
1641         "egrave"=>200,
1642         "EGRAVE"=>200,
1643         "Eacute"=>201,
1644         "eacute"=>201,
1645         "EACUTE"=>201,
1646         "Ecirc"=>202,
1647         "ecirc"=>202,
1648         "ECIRC"=>202,
1649         "Euml"=>203,
1650         "euml"=>203,
1651         "EUML"=>203,
1652         "Lgrave"=>204,
1653         "lgrave"=>204,
1654         "LGRAVE"=>204,
1655         "Lacute"=>313,
1656         "lacute"=>313,
1657         "LACUTE"=>313,
1658         "Lcirc"=>206,
1659         "lcirc"=>206,
1660         "LCIRC"=>206,
1661         "Luml"=>207,
1662         "luml"=>207,
1663         "LUML"=>207,
1664         "ETH"=>208,
1665         "eth"=>208,
1666         "Ntilde"=>209,
1667         "ntilde"=>209,
1668         "NTILDE"=>209,
1669         "Ograve"=>210,
1670         "ograve"=>210,
1671         "OGRAVE"=>210,
1672         "Oacute"=>211,
1673         "oacute"=>211,
1674         "OACUTE"=>211,
1675         "Ocirc"=>212,
1676         "ocirc"=>212,
1677         "OCIRC"=>212,
1678         "Otilde"=>213,
1679         "otilde"=>213,
1680         "OTILDE"=>213,
1681         "Ouml"=>214,
1682         "ouml"=>214,
1683         "OUML"=>214,
1684         "Oslash"=>216,
1685         "oslash"=>216,
1686         "OSLASH"=>216,
1687         "Ugrave"=>217,
1688         "ugrave"=>217,
1689         "UGRAVE"=>217,
1690         "Uacute"=>218,
1691         "uacute"=>218,
1692         "UACUTE"=>218,
1693         "Ucirc"=>219,
1694         "ucirc"=>219,
1695         "UCIRC"=>219,
1696         "Uuml"=>220,
1697         "uuml"=>220,
1698         "UUML"=>220,
1699         "Yacute"=>221,
1700         "yacute"=>221,
1701         "YACUTE"=>221,
1702         "THORN"=>222,
1703         "thorn"=>222,
1704         "szlig"=>223,
1705         "SZLIG"=>223,
1706         "igrave"=>236,
1707         "IGRAVE"=>236,
1708         "iacute"=>237,
1709         "IACUTE"=>237,
1710         "icirc"=>238,
1711         "ICIRC"=>238,
1712         "iuml"=>239,
1713         "IUML"=>239,
1714         "yuml"=>255,
1715         "YUML"=>255,
1716         "Amacr"=>256,
1717         "amacr"=>256,
1718         "AMACR"=>256,
1719         "Abreve"=>258,
1720         "abreve"=>258,
1721         "ABREVE"=>258,
1722         "Aogon"=>260,
1723         "aogon"=>260,
1724         "AOGON"=>260,
1725         "Cacute"=>262,
1726         "cacute"=>262,
1727         "CACUTE"=>262,
1728         "Ccirc"=>264,
1729         "ccirc"=>264,
1730         "CCIRC"=>264,
1731         "Cdot"=>266,
1732         "cdot"=>266,
1733         "CDOT"=>266,
1734         "Ccaron"=>268,
1735         "ccaron"=>268,
1736         "CCARON"=>268,
1737         "Dcaron"=>270,
1738         "dcaron"=>270,
1739         "DCARON"=>270,
1740         "Dstrok"=>272,
1741         "dstrok"=>272,
1742         "DSTROK"=>272,
1743         "Emacr"=>274,
1744         "emacr"=>274,
1745         "EMACR"=>274,
1746         "Edot"=>278,
1747         "Eogon"=>280,
1748         "eogon"=>280,
1749         "EOGON"=>280,
1750         "Ecaron"=>282,
1751         "ecaron"=>282,
1752         "ECARON"=>282,
1753         "Gcirc"=>284,
1754         "gcirc"=>284,
1755         "GCIRC"=>284,
1756         "Gbreve"=>286,
1757         "gbreve"=>286,
1758         "GBREVE"=>286,
1759         "Gdot"=>288,
1760         "gdot"=>288,
1761         "GDOT"=>288,
1762         "Gcedil"=>290,
1763         "gcedil"=>290,
1764         "GCEDIL"=>290,
1765         "Hcirc"=>292,
1766         "hcirc"=>292,
1767         "HCIRC"=>292,
1768         "Hstrok"=>294,
1769         "hstrok"=>294,
1770         "HSTROK"=>294,
1771         "Itilde"=>296,
1772         "itilde"=>296,
1773         "ITILDE"=>296,
1774         "Imacr"=>298,
1775         "imacr"=>298,
1776         "IMACR"=>298,
1777         "Iogon"=>302,
1778         "iogon"=>302,
1779         "IOGON"=>302,
1780         "Idot"=>304,
1781         "idot"=>304,
1782         "IDOT"=>304,
1783         "imath"=>305,
1784         "IMATH"=>305,
1785         "IJlig"=>306,
1786         "ijlig"=>306,
1787         "IJLIG"=>306,
1788         "Jcirc"=>308,
1789         "jcirc"=>308,
1790         "JCIRC"=>308,
1791         "Kcedil"=>310,
1792         "kcedil"=>310,
1793         "KCEDIL"=>310,
1794         "kgreen"=>312,
1795         "KGREEN"=>312,
1796         "Lcedil"=>315,
1797         "lcedil"=>315,
1798         "LCEDIL"=>315,
1799         "Lcaron"=>317,
1800         "lcaron"=>317,
1801         "LCARON"=>317,
1802         "Lmidot"=>319,
1803         "lmidot"=>319,
1804         "LMIDOT"=>319,
1805         "Lstrok"=>321,
1806         "lstrok"=>321,
1807         "LSTROK"=>321,
1808         "Nacute"=>323,
1809         "nacute"=>323,
1810         "NACUTE"=>323,
1811         "Ncedil"=>325,
1812         "ncedil"=>325,
1813         "NCEDIL"=>325,
1814         "Ncaron"=>327,
1815         "ncaron"=>327,
1816         "NCARON"=>327,
1817         "napos"=>329,
1818         "NAPOS"=>329,
1819         "ENG"=>330,
1820         "eng"=>330,
1821         "Omacr"=>332,
1822         "omacr"=>332,
1823         "OMACR"=>332,
1824         "Odblac"=>336,
1825         "odblac"=>336,
1826         "ODBLAC"=>336,
1827         "OElig"=>338,
1828         "oelig"=>338,
1829         "OELIG"=>338,
1830         "Racute"=>340,
1831         "racute"=>340,
1832         "RACUTE"=>340,
1833         "Rcedil"=>342,
1834         "rcedil"=>342,
1835         "RCEDIL"=>342,
1836         "Rcaron"=>344,
1837         "rcaron"=>344,
1838         "RCARON"=>344,
1839         "Sacute"=>346,
1840         "sacute"=>346,
1841         "SACUTE"=>346,
1842         "Scirc"=>348,
1843         "scirc"=>348,
1844         "SCIRC"=>348,
1845         "Scedil"=>350,
1846         "scedil"=>350,
1847         "SCEDIL"=>350,
1848         "Scaron"=>352,
1849         "scaron"=>352,
1850         "SCARON"=>352,
1851         "Tcedil"=>354,
1852         "tcedil"=>354,
1853         "TCEDIL"=>354,
1854         "Tcaron"=>356,
1855         "tcaron"=>356,
1856         "TCARON"=>356,
1857         "Tstrok"=>358,
1858         "tstrok"=>358,
1859         "TSTROK"=>358,
1860         "Utilde"=>360,
1861         "utilde"=>360,
1862         "UTILDE"=>360,
1863         "Umacr"=>362,
1864         "umacr"=>362,
1865         "UMACR"=>362,
1866         "Ubreve"=>364,
1867         "ubreve"=>364,
1868         "UBREVE"=>364,
1869         "Uring"=>366,
1870         "uring"=>366,
1871         "URING"=>366,
1872         "Udblac"=>368,
1873         "udblac"=>368,
1874         "UDBLAC"=>368,
1875         "Uogon"=>370,
1876         "uogon"=>370,
1877         "UOGON"=>370,
1878         "Wcirc"=>372,
1879         "wcirc"=>372,
1880         "WCIRC"=>372,
1881         "Ycirc"=>374,
1882         "ycirc"=>374,
1883         "YCIRC"=>374,
1884         "Yuml"=>376,
1885         "Zacute"=>377,
1886         "zacute"=>377,
1887         "ZACUTE"=>377,
1888         "Zdot"=>379,
1889         "zdot"=>379,
1890         "ZDOT"=>379,
1891         "Zcaron"=>381,
1892         "zcaron"=>381,
1893         "ZCARON"=>381,
1894         "DownBreve"=>785,
1895         "downbreve"=>785,
1896         "DOWNBREVE"=>785,
1897         "olarr"=>8634,
1898         "OLARR"=>8634,
1899         "orarr"=>8635,
1900         "ORARR"=>8635,
1901         "lharu"=>8636,
1902         "LHARU"=>8636,
1903         "lhard"=>8637,
1904         "LHARD"=>8637,
1905         "uharr"=>8638,
1906         "UHARR"=>8638,
1907         "uharl"=>8639,
1908         "UHARL"=>8639,
1909         "rharu"=>8640,
1910         "RHARU"=>8640,
1911         "rhard"=>8641,
1912         "RHARD"=>8641,
1913         "dharr"=>8642,
1914         "DHARR"=>8642,
1915         "dharl"=>8643,
1916         "DHARL"=>8643,
1917         "rlarr"=>8644,
1918         "RLARR"=>8644,
1919         "udarr"=>8645,
1920         "UDARR"=>8645,
1921         "lrarr"=>8646,
1922         "LRARR"=>8646,
1923         "llarr"=>8647,
1924         "LLARR"=>8647,
1925         "uuarr"=>8648,
1926         "UUARR"=>8648,
1927         "rrarr"=>8649,
1928         "RRARR"=>8649,
1929         "ddarr"=>8650,
1930         "DDARR"=>8650,
1931         "lrhar"=>8651,
1932         "LRHAR"=>8651,
1933         "rlhar"=>8652,
1934         "RLHAR"=>8652,
1935         "nlArr"=>8653,
1936         "nlarr"=>8653,
1937         "NLARR"=>8653,
1938         "nhArr"=>8654,
1939         "nharr"=>8654,
1940         "NHARR"=>8654,
1941         "nrArr"=>8655,
1942         "nrarr"=>8655,
1943         "NRARR"=>8655,
1944         "lArr"=>8656,
1945         "larr"=>8656,
1946         "LARR"=>8656,
1947         "uArr"=>8657,
1948         "uarr"=>8657,
1949         "UARR"=>8657,
1950         "rArr"=>8658,
1951         "rarr"=>8658,
1952         "RARR"=>8658,
1953         "dArr"=>8659,
1954         "darr"=>8659,
1955         "DARR"=>8659,
1956         "hArr"=>8660,
1957         "harr"=>8660,
1958         "HARR"=>8660,
1959         "vArr"=>8661,
1960         "varr"=>8661,
1961         "VARR"=>8661,
1962         "nwArr"=>8662,
1963         "nwarr"=>8662,
1964         "NWARR"=>8662,
1965         "neArr"=>8663,
1966         "nearr"=>8663,
1967         "NEARR"=>8663,
1968         "seArr"=>8664,
1969         "searr"=>8664,
1970         "SEARR"=>8664,
1971         "swArr"=>8665,
1972         "swarr"=>8665,
1973         "SWARR"=>8665,
1974         "lAarr"=>8666,
1975         "laarr"=>8666,
1976         "LAARR"=>8666,
1977         "rAarr"=>8667,
1978         "raarr"=>8667,
1979         "RAARR"=>8667,
1980         "ziglarr"=>8668,
1981         "ZIGLARR"=>8668,
1982         "zigrarr"=>8669,
1983         "ZIGRARR"=>8669,
1984         "larrb"=>8676,
1985         "LARRB"=>8676,
1986         "rarrb"=>8677,
1987         "RARRB"=>8677,
1988         "duarr"=>8693,
1989         "DUARR"=>8693,
1990         "hoarr"=>8703,
1991         "HOARR"=>8703,
1992         "loarr"=>8701,
1993         "LOARR"=>8701,
1994         "roarr"=>8702,
1995         "ROARR"=>8702,
1996         "xlarr"=>10229,
1997         "XLARR"=>10229,
1998         "xrarr"=>10230,
1999         "XRARR"=>10230,
2000         "xharr"=>10231,
2001         "XHARR"=>10231,
2002         "xlArr"=>10232,
2003         "xrArr"=>10233,
2004         "xhArr"=>10234,
2005         "dzigrarr"=>10239,
2006         "DZIGRARR"=>10239,
2007         "xmap"=>10236,
2008         "XMAP"=>10236,
2009         "nvlArr"=>10498,
2010         "nvlarr"=>10498,
2011         "NVLARR"=>10498,
2012         "nvrArr"=>10499,
2013         "nvrarr"=>10499,
2014         "NVRARR"=>10499,
2015         "nvHarr"=>10500,
2016         "nvharr"=>10500,
2017         "NVHARR"=>10500,
2018         "Map"=>10501,
2019         "map"=>10501,
2020         "MAP"=>10501,
2021         "lbarr"=>10508,
2022         "LBARR"=>10508,
2023         "rbarr"=>10509,
2024         "RBARR"=>10509,
2025         "lBarr"=>10510,
2026         "rBarr"=>10511,
2027         "RBarr"=>10512,
2028         "DDotrahd"=>10513,
2029         "ddotrahd"=>10513,
2030         "DDOTRAHD"=>10513,
2031         "UpArrowBar"=>10514,
2032         "uparrowbar"=>10514,
2033         "UPARROWBAR"=>10514,
2034         "DownArrowBar"=>10515,
2035         "downarrowbar"=>10515,
2036         "DOWNARROWBAR"=>10515,
2037         "Rarrtl"=>10518,
2038         "rarrtl"=>10518,
2039         "RARRTL"=>10518,
2040         "latail"=>10521,
2041         "LATAIL"=>10521,
2042         "ratail"=>10522,
2043         "RATAIL"=>10522,
2044         "lAtail"=>10523,
2045         "rAtail"=>10524,
2046         "larrfs"=>10525,
2047         "LARRFS"=>10525,
2048         "rarrfs"=>10526,
2049         "RARRFS"=>10526,
2050         "larrbfs"=>10527,
2051         "LARRBFS"=>10527,
2052         "rarrbfs"=>10528,
2053         "RARRBFS"=>10528,
2054         "nwarhk"=>10531,
2055         "NWARHK"=>10531,
2056         "nearhk"=>10532,
2057         "NEARHK"=>10532,
2058         "searhk"=>10533,
2059         "SEARHK"=>10533,
2060         "swarhk"=>10534,
2061         "SWARHK"=>10534,
2062         "nwnear"=>10535,
2063         "NWNEAR"=>10535,
2064         "nesear"=>10536,
2065         "NESEAR"=>10536,
2066         "seswar"=>10537,
2067         "SESWAR"=>10537,
2068         "swnwar"=>10538,
2069         "SWNWAR"=>10538,
2070         "cudarrr"=>10549,
2071         "CUDARRR"=>10549,
2072         "ldca"=>10550,
2073         "LDCA"=>10550,
2074         "rdca"=>10551,
2075         "RDCA"=>10551,
2076         "cudarrl"=>10552,
2077         "CUDARRL"=>10552,
2078         "larrpl"=>10553,
2079         "LARRPL"=>10553,
2080         "curarrm"=>10556,
2081         "CURARRM"=>10556,
2082         "cularrp"=>10557,
2083         "CULARRP"=>10557,
2084         "rarrpl"=>10565,
2085         "RARRPL"=>10565,
2086         "harrcir"=>10568,
2087         "HARRCIR"=>10568,
2088         "Uarrocir"=>10569,
2089         "uarrocir"=>10569,
2090         "UARROCIR"=>10569,
2091         "lurdshar"=>10570,
2092         "LURDSHAR"=>10570,
2093         "ldrushar"=>10571,
2094         "LDRUSHAR"=>10571,
2095         "RightUpDownVector"=>10575,
2096         "rightupdownvector"=>10575,
2097         "RIGHTUPDOWNVECTOR"=>10575,
2098         "DownLeftRightVector"=>10576,
2099         "downleftrightvector"=>10576,
2100         "DOWNLEFTRIGHTVECTOR"=>10576,
2101         "LeftUpDownVector"=>10577,
2102         "leftupdownvector"=>10577,
2103         "LEFTUPDOWNVECTOR"=>10577,
2104         "LeftVectorBar"=>10578,
2105         "leftvectorbar"=>10578,
2106         "LEFTVECTORBAR"=>10578,
2107         "RightVectorBar"=>10579,
2108         "rightvectorbar"=>10579,
2109         "RIGHTVECTORBAR"=>10579,
2110         "RightUpVectorBar"=>10580,
2111         "rightupvectorbar"=>10580,
2112         "RIGHTUPVECTORBAR"=>10580,
2113         "RightDownVectorBar"=>10581,
2114         "rightdownvectorbar"=>10581,
2115         "RIGHTDOWNVECTORBAR"=>10581,
2116         "DownLeftVectorBar"=>10582,
2117         "downleftvectorbar"=>10582,
2118         "DOWNLEFTVECTORBAR"=>10582,
2119         "DownRightVectorBar"=>10583,
2120         "downrightvectorbar"=>10583,
2121         "DOWNRIGHTVECTORBAR"=>10583,
2122         "LeftUpVectorBar"=>10584,
2123         "leftupvectorbar"=>10584,
2124         "LEFTUPVECTORBAR"=>10584,
2125         "LeftDownVectorBar"=>10585,
2126         "leftdownvectorbar"=>10585,
2127         "LEFTDOWNVECTORBAR"=>10585,
2128         "LeftTeeVector"=>10586,
2129         "leftteevector"=>10586,
2130         "LEFTTEEVECTOR"=>10586,
2131         "RightTeeVector"=>10587,
2132         "rightteevector"=>10587,
2133         "RIGHTTEEVECTOR"=>10587,
2134         "RightUpTeeVector"=>10588,
2135         "rightupteevector"=>10588,
2136         "RIGHTUPTEEVECTOR"=>10588,
2137         "RightDownTeeVector"=>10589,
2138         "rightdownteevector"=>10589,
2139         "RIGHTDOWNTEEVECTOR"=>10589,
2140         "DownLeftTeeVector"=>10590,
2141         "downleftteevector"=>10590,
2142         "DOWNLEFTTEEVECTOR"=>10590,
2143         "DownRightTeeVector"=>10591,
2144         "downrightteevector"=>10591,
2145         "DOWNRIGHTTEEVECTOR"=>10591,
2146         "LeftUpTeeVector"=>10592,
2147         "leftupteevector"=>10592,
2148         "LEFTUPTEEVECTOR"=>10592,
2149         "LeftDownTeeVector"=>10593,
2150         "leftdownteevector"=>10593,
2151         "LEFTDOWNTEEVECTOR"=>10593,
2152         "lHar"=>10594,
2153         "lhar"=>10594,
2154         "LHAR"=>10594,
2155         "uHar"=>10595,
2156         "uhar"=>10595,
2157         "UHAR"=>10595,
2158         "rHar"=>10596,
2159         "rhar"=>10596,
2160         "RHAR"=>10596,
2161         "dHar"=>10597,
2162         "dhar"=>10597,
2163         "DHAR"=>10597,
2164         "luruhar"=>10598,
2165         "LURUHAR"=>10598,
2166         "ldrdhar"=>10599,
2167         "LDRDHAR"=>10599,
2168         "ruluhar"=>10600,
2169         "RULUHAR"=>10600,
2170         "rdldhar"=>10601,
2171         "RDLDHAR"=>10601,
2172         "lharul"=>10602,
2173         "LHARUL"=>10602,
2174         "llhard"=>10603,
2175         "LLHARD"=>10603,
2176         "rharul"=>10604,
2177         "RHARUL"=>10604,
2178         "lrhard"=>10605,
2179         "LRHARD"=>10605,
2180         "udhar"=>10606,
2181         "UDHAR"=>10606,
2182         "duhar"=>10607,
2183         "DUHAR"=>10607,
2184         "RoundImplies"=>10608,
2185         "roundimplies"=>10608,
2186         "ROUNDIMPLIES"=>10608,
2187         "erarr"=>10609,
2188         "ERARR"=>10609,
2189         "simrarr"=>10610,
2190         "SIMRARR"=>10610,
2191         "larrsim"=>10611,
2192         "LARRSIM"=>10611,
2193         "rarrsim"=>10612,
2194         "RARRSIM"=>10612,
2195         "rarrap"=>10613,
2196         "RARRAP"=>10613,
2197         "ltlarr"=>10614,
2198         "LTLARR"=>10614,
2199         "gtrarr"=>10616,
2200         "GTRARR"=>10616,
2201         "subrarr"=>10617,
2202         "SUBRARR"=>10617,
2203         "suplarr"=>10619,
2204         "SUPLARR"=>10619,
2205         "lfisht"=>10620,
2206         "LFISHT"=>10620,
2207         "rfisht"=>10621,
2208         "RFISHT"=>10621,
2209         "ufisht"=>10622,
2210         "UFISHT"=>10622,
2211         "dfisht"=>10623,
2212         "DFISHT"=>10623,                   
2213         x=>{
2214             // check if we are a bare unicode number
2215             let x = x.as_bytes();
2216             if x[0] == b'#'{
2217                 if x.len()>1 && x[1] == b'x'{ // hex
2218                     if let Ok(utf8) = std::str::from_utf8(&x[2..]){
2219                         if let Ok(num) = i64::from_str_radix(utf8, 16){
2220                             num as u32
2221                         }
2222                         else{
2223                             return Err("Cannot parse hex html entity".into())
2224                         }
2225                     }
2226                     else{
2227                         return Err("Cannot parse hex html entity".into())
2228                     }
2229                 }
2230                 else{
2231                     if let Ok(utf8) = std::str::from_utf8(&x[1..]){
2232                         if let Ok(num) = utf8.parse::<i64>(){
2233                             num as u32
2234                         }
2235                         else{
2236                             return Err("Cannot parse digit html entity".into())
2237                         }
2238                     }
2239                     else{
2240                         return Err("Cannot parse digit html entity".into())
2241                     }
2242                 }
2243             }
2244             else{
2245                 return Err("unknown html entity".into())
2246             }
2247         }
2248     })
2249 }