diff options
| -rw-r--r-- | Makefile | 28 | ||||
| -rw-r--r-- | runtests.pl | 11 | ||||
| -rw-r--r-- | spec.txt | 73 | ||||
| -rw-r--r-- | src/blocks.c | 1381 | ||||
| -rw-r--r-- | src/bstrlib.c | 2979 | ||||
| -rw-r--r-- | src/bstrlib.h | 304 | ||||
| -rw-r--r-- | src/buffer.c | 354 | ||||
| -rw-r--r-- | src/buffer.h | 114 | ||||
| -rw-r--r-- | src/case_fold_switch.inc (renamed from src/case_fold_switch.c) | 0 | ||||
| -rw-r--r-- | src/casefold.c | 2699 | ||||
| -rw-r--r-- | src/chunk.h | 92 | ||||
| -rw-r--r-- | src/detab.c | 48 | ||||
| -rw-r--r-- | src/getopt.c | 199 | ||||
| -rw-r--r-- | src/html.c | 276 | ||||
| -rw-r--r-- | src/html/houdini.h | 46 | ||||
| -rw-r--r-- | src/html/houdini_href_e.c | 107 | ||||
| -rw-r--r-- | src/html/houdini_html_e.c | 81 | ||||
| -rw-r--r-- | src/html/houdini_html_u.c | 111 | ||||
| -rw-r--r-- | src/html/html.c | 228 | ||||
| -rw-r--r-- | src/html/html_unescape.gperf | 2131 | ||||
| -rw-r--r-- | src/html/html_unescape.h | 9746 | ||||
| -rw-r--r-- | src/inlines.c | 1677 | ||||
| -rw-r--r-- | src/inlines.h | 13 | ||||
| -rw-r--r-- | src/main.c | 142 | ||||
| -rw-r--r-- | src/print.c | 314 | ||||
| -rw-r--r-- | src/references.c | 141 | ||||
| -rw-r--r-- | src/references.h | 27 | ||||
| -rw-r--r-- | src/scanners.h | 57 | ||||
| -rw-r--r-- | src/scanners.re | 96 | ||||
| -rw-r--r-- | src/stmd.h | 194 | ||||
| -rw-r--r-- | src/utf8.c | 277 | ||||
| -rw-r--r-- | src/utf8.h | 17 | ||||
| -rw-r--r-- | src/uthash.h | 948 | 
33 files changed, 15370 insertions, 9541 deletions
@@ -1,4 +1,4 @@ -CFLAGS?=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS) +CFLAGS?=-g -O3 -Wall -Wextra -std=c99 -Isrc -Wno-missing-field-initializers $(OPTFLAGS)  LDFLAGS?=-g -O3 -Wall -Werror  SRCDIR?=src  DATADIR?=data @@ -6,7 +6,7 @@ DATADIR?=data  PROG?=./stmd  .PHONY: all oldtests test spec benchjs testjs -all: $(SRCDIR)/case_fold_switch.c $(PROG) +all: $(SRCDIR)/case_fold_switch.inc $(PROG)  README.html: README.md template.html  	pandoc --template template.html -S -s -t html5 -o $@ $< @@ -41,15 +41,22 @@ testjs: spec.txt  benchjs:  	node js/bench.js ${BENCHINP} -$(PROG): $(SRCDIR)/main.c $(SRCDIR)/inlines.o $(SRCDIR)/blocks.o $(SRCDIR)/detab.o $(SRCDIR)/bstrlib.o $(SRCDIR)/scanners.o $(SRCDIR)/print.o $(SRCDIR)/html.o $(SRCDIR)/utf8.o -	$(CC) $(LDFLAGS) -o $@ $^ +HTML_OBJ=$(SRCDIR)/html/html.o $(SRCDIR)/html/houdini_href_e.o $(SRCDIR)/html/houdini_html_e.o $(SRCDIR)/html/houdini_html_u.o + +STMD_OBJ=$(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/utf8.o $(SRCDIR)/references.c + +$(PROG): $(SRCDIR)/html/html_unescape.h $(SRCDIR)/case_fold_switch.inc $(HTML_OBJ) $(STMD_OBJ) $(SRCDIR)/main.c +	$(CC) $(LDFLAGS) -o $@ $(HTML_OBJ) $(STMD_OBJ) $(SRCDIR)/main.c  $(SRCDIR)/scanners.c: $(SRCDIR)/scanners.re  	re2c --case-insensitive -bis $< > $@ || (rm $@ && false) -$(SRCDIR)/case_fold_switch.c: $(DATADIR)/CaseFolding-3.2.0.txt +$(SRCDIR)/case_fold_switch.inc: $(DATADIR)/CaseFolding-3.2.0.txt  	perl mkcasefold.pl < $< > $@ +$(SRCDIR)/html/html_unescape.h: $(SRCDIR)/html/html_unescape.gperf +	gperf -I -t -N find_entity -H hash_entity -K entity -C -l --null-strings -m5 $< > $@ +  .PHONY: leakcheck clean fuzztest dingus upload  dingus: @@ -58,6 +65,9 @@ dingus:  leakcheck: $(PROG)  	cat oldtests/*/*.markdown | valgrind --leak-check=full --dsymutil=yes $(PROG) +operf: $(PROG) +	operf $(PROG) <bench.md >/dev/null +  fuzztest:  	for i in `seq 1 10`; do \  	  time cat /dev/urandom | head -c 100000 | iconv -f latin1 -t utf-8 | $(PROG) >/dev/null; done @@ -69,7 +79,7 @@ update-site: spec.html narrative.html  	(cd _site ; git pull ; git commit -a -m "Updated site for latest spec, narrative, js" ; git push; cd ..)  clean: -	-rm test $(SRCDIR)/*.o $(SRCDIR)/scanners.c -	-rm -r *.dSYM -	-rm README.html -	-rm spec.md fuzz.txt spec.html +	-rm -f test $(SRCDIR)/*.o $(SRCDIR)/scanners.c $(SRCDIR)/html/*.o +	-rm -rf *.dSYM +	-rm -f README.html +	-rm -f spec.md fuzz.txt spec.html diff --git a/runtests.pl b/runtests.pl index 2e2b795..0bff360 100644 --- a/runtests.pl +++ b/runtests.pl @@ -38,7 +38,9 @@ sub tidy      } elsif (/<\/pre/) {        $inpre = 0;      } -    if ($inpre) { +    # remove \r to allow mixing linux/windows newlines +	  s/\r//; +	  if ($inpre) {        print $outfh $_;      } else {        # remove leading spaces @@ -49,6 +51,7 @@ sub tidy        s/  */ /;        # collapse space before /> in tag        s/  *\/>/\/>/; +	  s/>\n$/>/;        # skip blank line        if (/^$/) {          next; @@ -69,15 +72,17 @@ sub dotest    # We use → to indicate tab and ␣ space in the spec    $markdown =~ s/→/\t/g;s/␣/ /g;    $html =~ s/→/\t/g;s/␣/ /g; -  open2(my $out, my $in, @PROG); +  my $pid = open2(my $out, my $in, @PROG);    print $in $markdown;    close $in;    flush $out;    $actual = do { local $/; <$out>; };    close $out; +  waitpid($pid, 0);    $html   = &tidy($html);    $actual = &tidy($actual);    $actual =~ s/\'/'/; +    if ($actual eq $html) {      print colored("✓", "green");      return 1; @@ -89,8 +94,10 @@ sub dotest      print $markdown;      print "=== expected ===============\n";      print $html; +	print "\n";      print "=== got ====================\n";      print $actual; +	print "\n";      print color "black";      return 0;    } @@ -2,8 +2,8 @@  title: CommonMark Spec  author:  - John MacFarlane -version: 1 -date: 2014-09-06 +version: 2 +date: 2014-09-19  ...  # Introduction @@ -1682,7 +1682,7 @@ them.  [Foo bar]  . -<p><a href="my url" title="title">Foo bar</a></p> +<p><a href="my%20url" title="title">Foo bar</a></p>  .  The title may be omitted: @@ -1745,7 +1745,7 @@ case-insensitive (see [matches](#matches)).  [αγω]  . -<p><a href="/φου">αγω</a></p> +<p><a href="/%CF%86%CE%BF%CF%85">αγω</a></p>  .  Here is a link reference definition with no corresponding link. @@ -3688,7 +3688,7 @@ raw HTML:  .  <http://google.com?find=\*>  . -<p><a href="http://google.com?find=\*">http://google.com?find=\*</a></p> +<p><a href="http://google.com?find=%5C*">http://google.com?find=\*</a></p>  .  . @@ -3727,47 +3727,59 @@ foo  ## Entities -Entities are parsed as entities, not as literal text, in all contexts -except code spans and code blocks. Three kinds of entities are recognized. +With the goal of making this standard as HTML-agnostic as possible, all HTML valid HTML Entities in any +context are recognized as such and converted into their actual values (i.e. the UTF8 characters representing +the entity itself) before they are stored in the AST. + +This allows implementations that target HTML output to trivially escape the entities when generating HTML, +and simplifies the job of implementations targetting other languages, as these will only need to handle the +UTF8 chars and need not be HTML-entity aware.  [Named entities](#name-entities) <a id="named-entities"></a> consist of `&` -+ a string of 2-32 alphanumerics beginning with a letter + `;`. ++ any of the valid HTML5 entity names + `;`. The [following document](http://www.whatwg.org/specs/web-apps/current-work/multipage/entities.json) +is used as an authoritative source of the valid entity names and their corresponding codepoints. + +Conforming implementations that target Markdown don't need to generate entities for all the valid +named entities that exist, with the exception of `"` (`"`), `&` (`&`), `<` (`<`) and `>` (`>`), +which always need to be written as entities for security reasons.  .    & © Æ Ď ¾ ℋ ⅆ ∲  . -<p>  & © Æ Ď ¾ ℋ ⅆ ∲</p> +<p>  & © Æ Ď ¾ ℋ ⅆ ∲</p>  .  [Decimal entities](#decimal-entities) <a id="decimal-entities"></a> -consist of `&#` + a string of 1--8 arabic digits + `;`. +consist of `&#` + a string of 1--8 arabic digits + `;`. Again, these entities need to be recognised +and tranformed into their corresponding UTF8 codepoints. Invalid Unicode codepoints will be written +as the "unknown codepoint" character (`0xFFFD`)  . - # Ӓ Ϡ � +# Ӓ Ϡ �  . -<p> # Ӓ Ϡ �</p> +<p># Ӓ Ϡ �</p>  .  [Hexadecimal entities](#hexadecimal-entities) <a id="hexadecimal-entities"></a>  consist of `&#` + either `X` or `x` + a string of 1-8 hexadecimal digits -+ `;`. ++ `;`. They will also be parsed and turned into their corresponding UTF8 values in the AST.  . - " ആ ಫ +" ആ ಫ  . -<p> " ആ ಫ</p> +<p>" ആ ಫ</p>  .  Here are some nonentities:  . -  &x; &#; &#x; � &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?; +  &x; &#; &#x; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;  . -<p>&nbsp &x; &#; &#x; &#123456789; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;</p> +<p>&nbsp &x; &#; &#x; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;</p>  .  Although HTML5 does accept some entities without a trailing semicolon -(such as `©`), these are not recognized as entities here: +(such as `©`), these are not recognized as entities here, because it makes the grammar too ambiguous:  .  © @@ -3775,13 +3787,12 @@ Although HTML5 does accept some entities without a trailing semicolon  <p>&copy</p>  . -On the other hand, many strings that are not on the list of HTML5 -named entities are recognized as entities here: +Strings that are not on the list of HTML5 named entities are not recognized as entities either:  .  &MadeUpEntity;  . -<p>&MadeUpEntity;</p> +<p>&MadeUpEntity;</p>  .  Entities are recognized in any context besides code spans or @@ -3797,7 +3808,7 @@ code blocks, including raw HTML, URLs, [link titles](#link-title), and  .  [foo](/föö "föö")  . -<p><a href="/föö" title="föö">foo</a></p> +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>  .  . @@ -3805,7 +3816,7 @@ code blocks, including raw HTML, URLs, [link titles](#link-title), and  [foo]: /föö "föö"  . -<p><a href="/föö" title="föö">foo</a></p> +<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>  .  . @@ -3813,7 +3824,7 @@ code blocks, including raw HTML, URLs, [link titles](#link-title), and  foo  ```  . -<pre><code class="language-föö">foo +<pre><code class="language-föö">foo  </code></pre>  . @@ -3946,7 +3957,7 @@ But this is a link:  .  <http://foo.bar.`baz>`  . -<p><a href="http://foo.bar.`baz">http://foo.bar.`baz</a>`</p> +<p><a href="http://foo.bar.%60baz">http://foo.bar.`baz</a>`</p>  .  And this is an HTML tag: @@ -4030,7 +4041,7 @@ for efficient parsing strategies that do not backtrack:      (a) it is not part of a sequence of four or more unescaped `_`s,      (b) it is not followed by whitespace, -    (c) is is not preceded by an ASCII alphanumeric character, and +    (c) it is not preceded by an ASCII alphanumeric character, and      (d) either it is not followed by a `_` character or it is          followed immediately by emphasis or strong emphasis. @@ -4754,7 +4765,7 @@ braces:  .  [link](</my uri>)  . -<p><a href="/my uri">link</a></p> +<p><a href="/my%20uri">link</a></p>  .  The destination cannot contain line breaks, even with pointy braces: @@ -4805,12 +4816,14 @@ in Markdown:  <p><a href="foo):">link</a></p>  . -URL-escaping and entities should be left alone inside the destination: +URL-escaping and should be left alone inside the destination, as all URL-escaped characters +are also valid URL characters. HTML entities in the destination will be parsed into their UTF8 +codepoints, as usual, and optionally URL-escaped when written as HTML.  .  [link](foo%20bä)  . -<p><a href="foo%20bä">link</a></p> +<p><a href="foo%20b%C3%A4">link</a></p>  .  Note that, because titles can often be parsed as destinations, @@ -4820,7 +4833,7 @@ get unexpected results:  .  [link]("title")  . -<p><a href=""title"">link</a></p> +<p><a href="%22title%22">link</a></p>  .  Titles may be in single quotes, double quotes, or parentheses: diff --git a/src/blocks.c b/src/blocks.c index 2776231..5b38116 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -1,747 +1,770 @@  #include <stdlib.h> +#include <assert.h>  #include <stdio.h>  #include <stdbool.h>  #include <ctype.h> -#include "bstrlib.h" +  #include "stmd.h" -#include "uthash.h" -#include "debug.h" +#include "utf8.h"  #include "scanners.h" +#include "inlines.h" +#include "html/houdini.h" + +#define peek_at(i, n) (i)->data[n] + +static void incorporate_line(strbuf *ln, int line_number, node_block** curptr); +static void finalize(node_block* b, int line_number); -static block* make_block(int tag, int start_line, int start_column) +static node_block* make_block(int tag, int start_line, int start_column)  { -  block* e; -  e = (block*) malloc(sizeof(block)); -  e->tag = tag; -  e->open = true; -  e->last_line_blank = false; -  e->start_line = start_line; -  e->start_column = start_column; -  e->end_line = start_line; -  e->children = NULL; -  e->last_child = NULL; -  e->parent = NULL; -  e->top = NULL; -  e->attributes.refmap = NULL; -  e->string_content = bfromcstr(""); -  e->inline_content = NULL; -  e->next = NULL; -  e->prev = NULL; -  return e; +	node_block* e; + +	e = malloc(sizeof(node_block)); +	memset(e, 0x0, sizeof(*e)); + +	e->tag = tag; +	e->open = true; +	e->start_line = start_line; +	e->start_column = start_column; +	e->end_line = start_line; +	strbuf_init(&e->string_content, 32); + +	return e;  } -// Create a root document block. -extern block* make_document() +// Create a root document node_block. +extern node_block* make_document()  { -  block * e = make_block(document, 1, 1); -  reference * map = NULL; -  reference ** refmap; -  refmap = (reference**) malloc(sizeof(reference*)); -  *refmap = map; -  e->attributes.refmap = refmap; -  e->top = e; -  return e; +	node_block *e = make_block(BLOCK_DOCUMENT, 1, 1); +	e->as.document.refmap = reference_map_new(); +	e->top = e; + +	return e;  }  // Returns true if line has only space characters, else false. -bool is_blank(bstring s, int offset) +bool is_blank(strbuf *s, int offset)  { -  char c; -  while ((c = bchar(s, offset))) { -    if (c == '\n') { -      return true; -    } else if (c == ' ') { -      offset++; -    } else { -      return false; -    } -  } -  return true; +	while (offset < s->size) { +		switch (s->ptr[offset]) { +			case '\n': +				return true; +			case ' ': +				offset++; +				break; +			default: +				return false; +		} +	} + +	return true;  }  static inline bool can_contain(int parent_type, int child_type)  { -  return ( parent_type == document || -           parent_type == block_quote || -           parent_type == list_item || -           (parent_type == list && child_type == list_item) ); +	return ( parent_type == BLOCK_DOCUMENT || +			parent_type == BLOCK_BQUOTE || +			parent_type == BLOCK_LIST_ITEM || +			(parent_type == BLOCK_LIST && child_type == BLOCK_LIST_ITEM) );  }  static inline bool accepts_lines(int block_type)  { -  return (block_type == paragraph || -          block_type == atx_header || -          block_type == indented_code || -          block_type == fenced_code); +	return (block_type == BLOCK_PARAGRAPH || +			block_type == BLOCK_ATX_HEADER || +			block_type == BLOCK_INDENTED_CODE || +			block_type == BLOCK_FENCED_CODE);  } -static int add_line(block* block, bstring ln, int offset) +static void add_line(node_block* node_block, chunk *ch, int offset)  { -  bstring s = bmidstr(ln, offset, blength(ln) - offset); -  check(block->open, "attempted to add line (%s) to closed container (%d)", -        ln->data, block->tag); -  check(bformata(block->string_content, "%s", s->data) == 0, -        "could not append line to string_content"); -  bdestroy(s); -  return 0; - error: -  return -1; +	assert(node_block->open); +	strbuf_put(&node_block->string_content, ch->data + offset, ch->len - offset);  } -static int remove_trailing_blank_lines(bstring ln) +static void remove_trailing_blank_lines(strbuf *ln)  { -  bstring tofind = bfromcstr(" \t\r\n"); -  int pos; -  // find last nonspace: -  pos = bninchrr(ln, blength(ln) - 1, tofind); -  if (pos == BSTR_ERR) { // all spaces -    bassigncstr(ln, ""); -  } else { -    // find next newline after it -    pos = bstrchrp(ln, '\n', pos); -    if (pos != BSTR_ERR) { -      check(bdelete(ln, pos, blength(ln) - pos) != BSTR_ERR, -        "failed to delete trailing blank lines"); -    } -  } -  bdestroy(tofind); -  return 0; - error: -  return -1; +	int i; + +	for (i = ln->size - 1; i >= 0; --i) { +		char c = ln->ptr[i]; + +		if (c != ' ' && c != '\t' && c != '\r' && c != '\n') +			break; +	} + +	if (i < 0) { +		strbuf_clear(ln); +		return; +	} + +	i = strbuf_strchr(ln, '\n', i); +	if (i >= 0) +		strbuf_truncate(ln, i);  } -// Check to see if a block ends with a blank line, descending +// Check to see if a node_block ends with a blank line, descending  // if needed into lists and sublists. -static bool ends_with_blank_line(block* block) +static bool ends_with_blank_line(node_block* node_block)  { -  if (block->last_line_blank) { -    return true; -  } -  if ((block->tag == list || block->tag == list_item) && block->last_child) { -    return ends_with_blank_line(block->last_child); -  } else { -    return false; -  } +	if (node_block->last_line_blank) { +		return true; +	} +	if ((node_block->tag == BLOCK_LIST || node_block->tag == BLOCK_LIST_ITEM) && node_block->last_child) { +		return ends_with_blank_line(node_block->last_child); +	} else { +		return false; +	}  }  // Break out of all containing lists -static int break_out_of_lists(block ** bptr, int line_number) +static int break_out_of_lists(node_block ** bptr, int line_number)  { -  block * container = *bptr; -  block * b = container->top; -  // find first containing list: -  while (b && b->tag != list) { -    b = b->last_child; -  } -  if (b) { -    while (container && container != b) { -      finalize(container, line_number); -      container = container->parent; -    } -    finalize(b, line_number); -    *bptr = b->parent; -  } -  return 0; +	node_block *container = *bptr; +	node_block *b = container->top; +	// find first containing BLOCK_LIST: +	while (b && b->tag != BLOCK_LIST) { +		b = b->last_child; +	} +	if (b) { +		while (container && container != b) { +			finalize(container, line_number); +			container = container->parent; +		} +		finalize(b, line_number); +		*bptr = b->parent; +	} +	return 0;  } -extern int finalize(block* b, int line_number) +static void finalize(node_block* b, int line_number)  { -  int firstlinelen; -  int pos; -  block* item; -  block* subitem; - -  check(b != NULL, "finalize called on null block"); -  if (!b->open) { -    return 0; // don't do anything if the block is already closed -  } -  b->open = false; -  if (line_number > b->start_line) { -    b->end_line = line_number - 1; -  } else { -    b->end_line = line_number; -  } - -  switch (b->tag) { - -  case paragraph: -    pos = 0; -    while (bchar(b->string_content, 0) == '[' && -           (pos = parse_reference(b->string_content, -                                  b->top->attributes.refmap))) { -      bdelete(b->string_content, 0, pos); -    } -    if (is_blank(b->string_content, 0)) { -      b->tag = reference_def; -    } -    break; - -  case indented_code: -    remove_trailing_blank_lines(b->string_content); -    bformata(b->string_content, "\n"); -    break; - -  case fenced_code: -    // first line of contents becomes info -    firstlinelen = bstrchr(b->string_content, '\n'); -    b->attributes.fenced_code_data.info = -      bmidstr(b->string_content, 0, firstlinelen); -    bdelete(b->string_content, 0, firstlinelen + 1); // +1 for \n -    btrimws(b->attributes.fenced_code_data.info); -    unescape(b->attributes.fenced_code_data.info); -    break; - -  case list: // determine tight/loose status -    b->attributes.list_data.tight = true; // tight by default -    item = b->children; - -    while (item) { -      // check for non-final non-empty list item ending with blank line: -      if (item->last_line_blank && item->next) { -        b->attributes.list_data.tight = false; -        break; -      } -      // recurse into children of list item, to see if there are -      // spaces between them: -      subitem = item->children; -      while (subitem) { -        if (ends_with_blank_line(subitem) && -            (item->next || subitem->next)) { -          b->attributes.list_data.tight = false; -          break; -        } -        subitem = subitem->next; -      } -      if (!(b->attributes.list_data.tight)) { -        break; -      } -      item = item->next; -    } - -    break; - -  default: -    break; -  } - -  return 0; - error: -  return -1; +	int firstlinelen; +	int pos; +	node_block* item; +	node_block* subitem; + +	if (!b->open) +		return; // don't do anything if the node_block is already closed + +	b->open = false; +	if (line_number > b->start_line) { +		b->end_line = line_number - 1; +	} else { +		b->end_line = line_number; +	} + +	switch (b->tag) { +		case BLOCK_PARAGRAPH: +			pos = 0; +			while (strbuf_at(&b->string_content, 0) == '[' && +					(pos = parse_reference_inline(&b->string_content, b->top->as.document.refmap))) { + +				strbuf_drop(&b->string_content, pos); +			} +			if (is_blank(&b->string_content, 0)) { +				b->tag = BLOCK_REFERENCE_DEF; +			} +			break; + +		case BLOCK_INDENTED_CODE: +			remove_trailing_blank_lines(&b->string_content); +			strbuf_putc(&b->string_content, '\n'); +			break; + +		case BLOCK_FENCED_CODE: +			// first line of contents becomes info +			firstlinelen = strbuf_strchr(&b->string_content, '\n', 0); + +			strbuf_init(&b->as.code.info, 0); +			houdini_unescape_html_f( +				&b->as.code.info, +				b->string_content.ptr, +				firstlinelen +			); + +			strbuf_drop(&b->string_content, firstlinelen + 1); + +			strbuf_trim(&b->as.code.info); +			strbuf_unescape(&b->as.code.info); +			break; + +		case BLOCK_LIST: // determine tight/loose status +			b->as.list.tight = true; // tight by default +			item = b->children; + +			while (item) { +				// check for non-final non-empty list item ending with blank line: +				if (item->last_line_blank && item->next) { +					b->as.list.tight = false; +					break; +				} +				// recurse into children of list item, to see if there are +				// spaces between them: +				subitem = item->children; +				while (subitem) { +					if (ends_with_blank_line(subitem) && +							(item->next || subitem->next)) { +						b->as.list.tight = false; +						break; +					} +					subitem = subitem->next; +				} +				if (!(b->as.list.tight)) { +					break; +				} +				item = item->next; +			} + +			break; + +		default: +			break; +	}  } -// Add a block as child of another.  Return pointer to child. -extern block* add_child(block* parent, -                        int block_type, int start_line, int start_column) +// Add a node_block as child of another.  Return pointer to child. +static node_block* add_child(node_block* parent, +		int block_type, int start_line, int start_column)  { -  // if 'parent' isn't the kind of block that can accept this child, -  // then back up til we hit a block that can. -  while (!can_contain(parent->tag, block_type)) { -    finalize(parent, start_line); -    parent = parent->parent; -  } - -  check(parent != NULL, "parent container cannot accept children"); - -  block* child = make_block(block_type, start_line, start_column); -  child->parent = parent; -  child->top = parent->top; - -  if (parent->last_child) { -    parent->last_child->next = child; -    child->prev = parent->last_child; -  } else { -    parent->children = child; -    child->prev = NULL; -  } -  parent->last_child = child; -  return child; - error: -  return NULL; +	assert(parent); + +	// if 'parent' isn't the kind of node_block that can accept this child, +	// then back up til we hit a node_block that can. +	while (!can_contain(parent->tag, block_type)) { +		finalize(parent, start_line); +		parent = parent->parent; +	} + +	node_block* child = make_block(block_type, start_line, start_column); +	child->parent = parent; +	child->top = parent->top; + +	if (parent->last_child) { +		parent->last_child->next = child; +		child->prev = parent->last_child; +	} else { +		parent->children = child; +		child->prev = NULL; +	} +	parent->last_child = child; +	return child;  } -// Free a block list and any children. -extern void free_blocks(block* e) +// Free a node_block list and any children. +void stmd_free_nodes(node_block *e)  { -  block * next; -  while (e != NULL) { -    next = e->next; -    free_inlines(e->inline_content); -    bdestroy(e->string_content); -    if (e->tag == fenced_code) { -      bdestroy(e->attributes.fenced_code_data.info); -    } else if (e->tag == document) { -      free_reference_map(e->attributes.refmap); -    } -    free_blocks(e->children); -    free(e); -    e = next; -  } +	node_block * next; +	while (e != NULL) { +		next = e->next; +		free_inlines(e->inline_content); +		strbuf_free(&e->string_content); +		if (e->tag == BLOCK_FENCED_CODE) { +			strbuf_free(&e->as.code.info); +		} else if (e->tag == BLOCK_DOCUMENT) { +			reference_map_free(e->as.document.refmap); +		} +		stmd_free_nodes(e->children); +		free(e); +		e = next; +	}  } -// Walk through block and all children, recursively, parsing +// Walk through node_block and all children, recursively, parsing  // string content into inline content where appropriate. -int process_inlines(block* cur, reference** refmap) +void process_inlines(node_block* cur, reference_map *refmap)  { -  switch (cur->tag) { - -  case paragraph: -  case atx_header: -  case setext_header: -    check(cur->string_content != NULL, "string_content is NULL"); -    cur->inline_content = parse_inlines(cur->string_content, refmap); -    bdestroy(cur->string_content); -    cur->string_content = NULL; -    break; - -  default: -    break; -  } - -  block * child = cur->children; -  while (child != NULL) { -    process_inlines(child, refmap); -    child = child->next; -  } - -  return 0; - error: -  return -1; +	switch (cur->tag) { +		case BLOCK_PARAGRAPH: +		case BLOCK_ATX_HEADER: +		case BLOCK_SETEXT_HEADER: +			cur->inline_content = parse_inlines(&cur->string_content, refmap); +			break; + +		default: +			break; +	} + +	node_block *child = cur->children; +	while (child != NULL) { +		process_inlines(child, refmap); +		child = child->next; +	}  }  // Attempts to parse a list item marker (bullet or enumerated).  // On success, returns length of the marker, and populates  // data with the details.  On failure, returns 0. -static int parse_list_marker(bstring ln, int pos, -                             struct ListData ** dataptr) +static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr)  { -  char c; -  int startpos; -  int start = 1; -  struct ListData * data; - -  startpos = pos; -  c = bchar(ln, pos); - -  if ((c == '*' || c == '-' || c == '+') && !scan_hrule(ln, pos)) { -    pos++; -    if (!isspace(bchar(ln, pos))) { -      return 0; -    } -    data = malloc(sizeof(struct ListData)); -    data->marker_offset = 0; // will be adjusted later -    data->list_type = bullet; -    data->bullet_char = c; -    data->start = 1; -    data->delimiter = period; -    data->tight = false; - -  } else if (isdigit(c)) { - -    pos++; -    while (isdigit(bchar(ln, pos))) { -      pos++; -    } - -    if (!sscanf((char *) ln->data + startpos, "%d", &start)) { -      log_err("sscanf failed"); -      return 0; -    } - -    c = bchar(ln, pos); -    if (c == '.' || c == ')') { -      pos++; -      if (!isspace(bchar(ln, pos))) { -        return 0; -      } -      data = malloc(sizeof(struct ListData)); -      data->marker_offset = 0; // will be adjusted later -      data->list_type = ordered; -      data->bullet_char = 0; -      data->start = start; -      data->delimiter = (c == '.' ? period : parens); -      data->tight = false; -    } else { -      return 0; -    } - -  } else { -    return 0; -  } - -  *dataptr = data; -  return (pos - startpos); +	unsigned char c; +	int startpos; +	struct ListData * data; + +	startpos = pos; +	c = peek_at(input, pos); + +	if ((c == '*' || c == '-' || c == '+') && !scan_hrule(input, pos)) { +		pos++; +		if (!isspace(peek_at(input, pos))) { +			return 0; +		} +		data = malloc(sizeof(struct ListData)); +		data->marker_offset = 0; // will be adjusted later +		data->list_type = bullet; +		data->bullet_char = c; +		data->start = 1; +		data->delimiter = period; +		data->tight = false; + +	} else if (isdigit(c)) { +		int start = 0; + +		do { +			start = (10 * start) + (peek_at(input, pos) - '0'); +			pos++; +		} while (isdigit(peek_at(input, pos))); + +		c = peek_at(input, pos); +		if (c == '.' || c == ')') { +			pos++; +			if (!isspace(peek_at(input, pos))) { +				return 0; +			} +			data = malloc(sizeof(struct ListData)); +			data->marker_offset = 0; // will be adjusted later +			data->list_type = ordered; +			data->bullet_char = 0; +			data->start = start; +			data->delimiter = (c == '.' ? period : parens); +			data->tight = false; +		} else { +			return 0; +		} + +	} else { +		return 0; +	} + +	*dataptr = data; +	return (pos - startpos);  }  // Return 1 if list item belongs in list, else 0. -static int lists_match(struct ListData list_data, -                       struct ListData item_data) +static int lists_match(struct ListData *list_data, struct ListData *item_data) +{ +	return (list_data->list_type == item_data->list_type && +			list_data->delimiter == item_data->delimiter && +			// list_data->marker_offset == item_data.marker_offset && +			list_data->bullet_char == item_data->bullet_char); +} + +static node_block *finalize_document(node_block *document, int linenum) +{ +	while (document != document->top) { +		finalize(document, linenum); +		document = document->parent; +	} + +	finalize(document, linenum); +	process_inlines(document, document->as.document.refmap); + +	return document; +} + +extern node_block *stmd_parse_file(FILE *f)  { -  return (list_data.list_type == item_data.list_type && -          list_data.delimiter == item_data.delimiter && -          // list_data.marker_offset == item_data.marker_offset && -          list_data.bullet_char == item_data.bullet_char); +	strbuf line = GH_BUF_INIT; +	unsigned char buffer[4096]; +	int linenum = 1; +	node_block *document = make_document(); + +	while (fgets((char *)buffer, sizeof(buffer), f)) { +		utf8proc_detab(&line, buffer, strlen((char *)buffer)); +		incorporate_line(&line, linenum, &document); +		strbuf_clear(&line); +		linenum++; +	} + +	strbuf_free(&line); +	return finalize_document(document, linenum);  } -// Process one line at a time, modifying a block. -// Returns 0 if successful.  curptr is changed to point to -// the currently open block. -extern int incorporate_line(bstring ln, int line_number, block** curptr) +extern node_block *stmd_parse_document(const unsigned char *buffer, size_t len)  { -  block* last_matched_container; -  int offset = 0; -  int matched = 0; -  int lev = 0; -  int i; -  struct ListData * data = NULL; -  bool all_matched = true; -  block* container; -  block* cur = *curptr; -  bool blank = false; -  int first_nonspace; -  int indent; - -  // detab input line -  check(bdetab(ln, 1) != BSTR_ERR, -        "invalid UTF-8 sequence in line %d\n", line_number); - -  // container starts at the document root. -  container = cur->top; - -  // for each containing block, try to parse the associated line start. -  // bail out on failure:  container will point to the last matching block. - -  while (container->last_child && container->last_child->open) { -    container = container->last_child; - -    first_nonspace = offset; -    while (bchar(ln, first_nonspace) == ' ') { -      first_nonspace++; -    } - -    indent = first_nonspace - offset; -    blank = bchar(ln, first_nonspace) == '\n'; - -    if (container->tag == block_quote) { - -      matched = indent <= 3 && bchar(ln, first_nonspace) == '>'; -      if (matched) { -        offset = first_nonspace + 1; -        if (bchar(ln, offset) == ' ') { -          offset++; -        } -      } else { -        all_matched = false; -      } - -    } else if (container->tag == list_item) { - -      if (indent >= container->attributes.list_data.marker_offset + -          container->attributes.list_data.padding) { -        offset += container->attributes.list_data.marker_offset + -          container->attributes.list_data.padding; -      } else if (blank) { -        offset = first_nonspace; -      } else { -        all_matched = false; -      } - -    } else if (container->tag == indented_code) { - -      if (indent >= CODE_INDENT) { -        offset += CODE_INDENT; -      } else if (blank) { -        offset = first_nonspace; -      } else { -        all_matched = false; -      } - -    } else if (container->tag == atx_header || -               container->tag == setext_header) { - -      // a header can never contain more than one line -      all_matched = false; - -    } else if (container->tag == fenced_code) { - -      // skip optional spaces of fence offset -      i = container->attributes.fenced_code_data.fence_offset; -      while (i > 0 && bchar(ln, offset) == ' ') { -        offset++; -        i--; -      } - -    } else if (container->tag == html_block) { - -      if (blank) { -        all_matched = false; -      } - -    } else if (container->tag == paragraph) { - -      if (blank) { -        container->last_line_blank =true; -        all_matched = false; -      } - -    } - -    if (!all_matched) { -      container = container->parent;  // back up to last matching block -      break; -    } -  } - -  last_matched_container = container; - -  // check to see if we've hit 2nd blank line, break out of list: -  if (blank && container->last_line_blank) { -    break_out_of_lists(&container, line_number); -  } - -  // unless last matched container is code block, try new container starts: -  while (container->tag != fenced_code && container->tag != indented_code && -         container->tag != html_block) { - -    first_nonspace = offset; -    while (bchar(ln, first_nonspace) == ' ') { -      first_nonspace++; -    } - -    indent = first_nonspace - offset; -    blank = bchar(ln, first_nonspace) == '\n'; - -    if (indent >= CODE_INDENT) { - -      if (cur->tag != paragraph && !blank) { -        offset += CODE_INDENT; -        container = add_child(container, indented_code, line_number, offset + 1); -      } else { // indent > 4 in lazy line -        break; -      } - -    } else if (bchar(ln, first_nonspace) == '>') { - -      offset = first_nonspace + 1; -      // optional following character -      if (bchar(ln, offset) == ' ') { -        offset++; -      } -      container = add_child(container, block_quote, line_number, offset + 1); - -    } else if ((matched = scan_atx_header_start(ln, first_nonspace))) { - -      offset = first_nonspace + matched; -      container = add_child(container, atx_header, line_number, offset + 1); -      int hashpos = bstrchrp(ln, '#', first_nonspace); -      check(hashpos != BSTR_ERR, "no # found in atx header start"); -      int level = 0; -      while (bchar(ln, hashpos) == '#') { -        level++; -        hashpos++; -      } -      container->attributes.header_level = level; - -    } else if ((matched = scan_open_code_fence(ln, first_nonspace))) { - -      container = add_child(container, fenced_code, line_number, -          first_nonspace + 1); -      container->attributes.fenced_code_data.fence_char = bchar(ln, -          first_nonspace); -      container->attributes.fenced_code_data.fence_length = matched; -      container->attributes.fenced_code_data.fence_offset = -        first_nonspace - offset; -      offset = first_nonspace + matched; - -    } else if ((matched = scan_html_block_tag(ln, first_nonspace))) { - -      container = add_child(container, html_block, line_number, -                            first_nonspace + 1); -      // note, we don't adjust offset because the tag is part of the text - -    } else if (container->tag == paragraph && -              (lev = scan_setext_header_line(ln, first_nonspace)) && -               // check that there is only one line in the paragraph: -               bstrrchrp(container->string_content, '\n', -                         blength(container->string_content) - 2) == BSTR_ERR) { - -        container->tag = setext_header; -        container->attributes.header_level = lev; -        offset = blength(ln) - 1; - -    } else if (!(container->tag == paragraph && !all_matched) && -               (matched = scan_hrule(ln, first_nonspace))) { - -      // it's only now that we know the line is not part of a setext header: -      container = add_child(container, hrule, line_number, first_nonspace + 1); -      finalize(container, line_number); -      container = container->parent; -      offset = blength(ln) - 1; - -    } else if ((matched = parse_list_marker(ln, first_nonspace, &data))) { - -        // compute padding: -        offset = first_nonspace + matched; -        i = 0; -        while (i <= 5 && bchar(ln, offset + i) == ' ') { -          i++; -        } -        // i = number of spaces after marker, up to 5 -        if (i >= 5 || i < 1 || bchar(ln, offset) == '\n') { -          data->padding = matched + 1; -          if (i > 0) { -            offset += 1; -          } -        } else { -          data->padding = matched + i; -          offset += i; -        } - -        // check container; if it's a list, see if this list item -        // can continue the list; otherwise, create a list container. - -        data->marker_offset = indent; - -        if (container->tag != list || -            !lists_match(container->attributes.list_data, *data)) { -          container = add_child(container, list, line_number, -              first_nonspace + 1); -          container->attributes.list_data = *data; -        } - -        // add the list item -        container = add_child(container, list_item, line_number, -            first_nonspace + 1); -        container->attributes.list_data = *data; -        free(data); - -    } else { -      break; -    } - -    if (accepts_lines(container->tag)) { -      // if it's a line container, it can't contain other containers -      break; -    } -  } - -  // what remains at offset is a text line.  add the text to the -  // appropriate container. - -  first_nonspace = offset; -  while (bchar(ln, first_nonspace) == ' ') { -    first_nonspace++; -  } - -  indent = first_nonspace - offset; -  blank = bchar(ln, first_nonspace) == '\n'; - -  // block quote lines are never blank as they start with > -  // and we don't count blanks in fenced code for purposes of tight/loose -  // lists or breaking out of lists.  we also don't set last_line_blank -  // on an empty list item. -  container->last_line_blank = (blank && -                                container->tag != block_quote && -                                container->tag != fenced_code && -                                !(container->tag == list_item && -                                  container->children == NULL && -                                  container->start_line == line_number)); - -    block *cont = container; -    while (cont->parent) { -      cont->parent->last_line_blank = false; -      cont = cont->parent; -    } - -  if (cur != last_matched_container && -      container == last_matched_container && -      !blank && -      cur->tag == paragraph && -      blength(cur->string_content) > 0) { - -    check(add_line(cur, ln, offset) == 0, "could not add line"); - -  } else { // not a lazy continuation - -    // finalize any blocks that were not matched and set cur to container: -    while (cur != last_matched_container) { - -      finalize(cur, line_number); -      cur = cur->parent; -      check(cur != NULL, "cur is NULL, last_matched_container->tag = %d", -            last_matched_container->tag); - -    } - -    if (container->tag == indented_code) { - -      check(add_line(container, ln, offset) == 0, "could not add line"); - -    } else if (container->tag == fenced_code) { - -      matched = (indent <= 3 -        && bchar(ln, first_nonspace) == container->attributes.fenced_code_data.fence_char) -        && scan_close_code_fence(ln, first_nonspace, -                                 container->attributes.fenced_code_data.fence_length); -      if (matched) { -        // if closing fence, don't add line to container; instead, close it: -        finalize(container, line_number); -        container = container->parent; // back up to parent -      } else { -        check(add_line(container, ln, offset) == 0, "could not add line"); -      } - -    } else if (container->tag == html_block) { - -      check(add_line(container, ln, offset) == 0, "could not add line"); - -    } else if (blank) { - -      // ??? do nothing - -    } else if (container->tag == atx_header) { - -      // chop off trailing ###s...use a scanner? -      brtrimws(ln); -      int p = blength(ln) - 1; -      int numhashes = 0; -      // if string ends in #s, remove these: -      while (bchar(ln, p) == '#') { -        p--; -        numhashes++; -      } -      if (bchar(ln, p) == '\\') { -        // the last # was escaped, so we include it. -        p++; -        numhashes--; -      } -      check(bdelete(ln, p + 1, numhashes) != BSTR_ERR, -            "could not delete final hashes"); -      check(add_line(container, ln, first_nonspace) == 0, "could not add line"); -      finalize(container, line_number); -      container = container->parent; - -    } else if (accepts_lines(container->tag)) { - -      check(add_line(container, ln, first_nonspace) == 0, "could not add line"); +	strbuf line = GH_BUF_INIT; +	int linenum = 1; +	const unsigned char *end = buffer + len; +	node_block *document = make_document(); + +	while (buffer < end) { +		const unsigned char *eol = memchr(buffer, '\n', end - buffer); + +		if (!eol) { +			utf8proc_detab(&line, buffer, end - buffer); +			buffer = end; +		} else { +			utf8proc_detab(&line, buffer, (eol - buffer) + 1); +			buffer += (eol - buffer) + 1; +		} + +		incorporate_line(&line, linenum, &document); +		strbuf_clear(&line); +		linenum++; +	} + +	strbuf_free(&line); +	return finalize_document(document, linenum); +} + +static void chop_trailing_hashtags(chunk *ch) +{ +	int n, orig_n; + +	chunk_rtrim(ch); +	orig_n = n = ch->len - 1; + +	// if string ends in #s, remove these: +	while (n >= 0 && peek_at(ch, n) == '#') +		n--; + +	// the last # was escaped, so we include it. +	if (n != orig_n && n >= 0 && peek_at(ch, n) == '\\') +		n++; + +	ch->len = n + 1; +} + +// Process one line at a time, modifying a node_block. +static void incorporate_line(strbuf *line, int line_number, node_block** curptr) +{ +	node_block* last_matched_container; +	int offset = 0; +	int matched = 0; +	int lev = 0; +	int i; +	struct ListData * data = NULL; +	bool all_matched = true; +	node_block* container; +	node_block* cur = *curptr; +	bool blank = false; +	int first_nonspace; +	int indent; +	chunk input; + +	input.data = line->ptr; +	input.len = line->size; + +	// container starts at the document root. +	container = cur->top; + +	// for each containing node_block, try to parse the associated line start. +	// bail out on failure:  container will point to the last matching node_block. + +	while (container->last_child && container->last_child->open) { +		container = container->last_child; + +		first_nonspace = offset; +		while (peek_at(&input, first_nonspace) == ' ') { +			first_nonspace++; +		} + +		indent = first_nonspace - offset; +		blank = peek_at(&input, first_nonspace) == '\n'; + +		if (container->tag == BLOCK_BQUOTE) { +			matched = indent <= 3 && peek_at(&input, first_nonspace) == '>'; +			if (matched) { +				offset = first_nonspace + 1; +				if (peek_at(&input, offset) == ' ') +					offset++; +			} else { +				all_matched = false; +			} + +		} else if (container->tag == BLOCK_LIST_ITEM) { + +			if (indent >= container->as.list.marker_offset + +					container->as.list.padding) { +				offset += container->as.list.marker_offset + +					container->as.list.padding; +			} else if (blank) { +				offset = first_nonspace; +			} else { +				all_matched = false; +			} + +		} else if (container->tag == BLOCK_INDENTED_CODE) { + +			if (indent >= CODE_INDENT) { +				offset += CODE_INDENT; +			} else if (blank) { +				offset = first_nonspace; +			} else { +				all_matched = false; +			} + +		} else if (container->tag == BLOCK_ATX_HEADER || +				container->tag == BLOCK_SETEXT_HEADER) { + +			// a header can never contain more than one line +			all_matched = false; + +		} else if (container->tag == BLOCK_FENCED_CODE) { + +			// skip optional spaces of fence offset +			i = container->as.code.fence_offset; +			while (i > 0 && peek_at(&input, offset) == ' ') { +				offset++; +				i--; +			} + +		} else if (container->tag == BLOCK_HTML) { + +			if (blank) { +				all_matched = false; +			} + +		} else if (container->tag == BLOCK_PARAGRAPH) { + +			if (blank) { +				container->last_line_blank = true; +				all_matched = false; +			} + +		} + +		if (!all_matched) { +			container = container->parent;  // back up to last matching node_block +			break; +		} +	} + +	last_matched_container = container; + +	// check to see if we've hit 2nd blank line, break out of list: +	if (blank && container->last_line_blank) { +		break_out_of_lists(&container, line_number); +	} + +	// unless last matched container is code node_block, try new container starts: +	while (container->tag != BLOCK_FENCED_CODE && container->tag != BLOCK_INDENTED_CODE && +			container->tag != BLOCK_HTML) { + +		first_nonspace = offset; +		while (peek_at(&input, first_nonspace) == ' ') +			first_nonspace++; + +		indent = first_nonspace - offset; +		blank = peek_at(&input, first_nonspace) == '\n'; + +		if (indent >= CODE_INDENT) { +			if (cur->tag != BLOCK_PARAGRAPH && !blank) { +				offset += CODE_INDENT; +				container = add_child(container, BLOCK_INDENTED_CODE, line_number, offset + 1); +			} else { // indent > 4 in lazy line +				break; +			} + +		} else if (peek_at(&input, first_nonspace) == '>') { + +			offset = first_nonspace + 1; +			// optional following character +			if (peek_at(&input, offset) == ' ') +				offset++; +			container = add_child(container, BLOCK_BQUOTE, line_number, offset + 1); + +		} else if ((matched = scan_atx_header_start(&input, first_nonspace))) { + +			offset = first_nonspace + matched; +			container = add_child(container, BLOCK_ATX_HEADER, line_number, offset + 1); + +			int hashpos = chunk_strchr(&input, '#', first_nonspace); +			int level = 0; + +			while (peek_at(&input, hashpos) == '#') { +				level++; +				hashpos++; +			} +			container->as.header.level = level; + +		} else if ((matched = scan_open_code_fence(&input, first_nonspace))) { + +			container = add_child(container, BLOCK_FENCED_CODE, line_number, first_nonspace + 1); +			container->as.code.fence_char = peek_at(&input, first_nonspace); +			container->as.code.fence_length = matched; +			container->as.code.fence_offset = first_nonspace - offset; +			offset = first_nonspace + matched; + +		} else if ((matched = scan_html_block_tag(&input, first_nonspace))) { + +			container = add_child(container, BLOCK_HTML, line_number, first_nonspace + 1); +			// note, we don't adjust offset because the tag is part of the text + +		} else if (container->tag == BLOCK_PARAGRAPH && +				(lev = scan_setext_header_line(&input, first_nonspace)) && +				// check that there is only one line in the paragraph: +				strbuf_strrchr(&container->string_content, '\n', +					strbuf_len(&container->string_content) - 2) < 0) { + +			container->tag = BLOCK_SETEXT_HEADER; +			container->as.header.level = lev; +			offset = input.len - 1; + +		} else if (!(container->tag == BLOCK_PARAGRAPH && !all_matched) && +				(matched = scan_hrule(&input, first_nonspace))) { + +			// it's only now that we know the line is not part of a setext header: +			container = add_child(container, BLOCK_HRULE, line_number, first_nonspace + 1); +			finalize(container, line_number); +			container = container->parent; +			offset = input.len - 1; + +		} else if ((matched = parse_list_marker(&input, first_nonspace, &data))) { + +			// compute padding: +			offset = first_nonspace + matched; +			i = 0; +			while (i <= 5 && peek_at(&input, offset + i) == ' ') { +				i++; +			} +			// i = number of spaces after marker, up to 5 +			if (i >= 5 || i < 1 || peek_at(&input, offset) == '\n') { +				data->padding = matched + 1; +				if (i > 0) { +					offset += 1; +				} +			} else { +				data->padding = matched + i; +				offset += i; +			} + +			// check container; if it's a list, see if this list item +			// can continue the list; otherwise, create a list container. + +			data->marker_offset = indent; + +			if (container->tag != BLOCK_LIST || +					!lists_match(&container->as.list, data)) { +				container = add_child(container, BLOCK_LIST, line_number, +						first_nonspace + 1); + +				memcpy(&container->as.list, data, sizeof(*data)); +			} + +			// add the list item +			container = add_child(container, BLOCK_LIST_ITEM, line_number, +					first_nonspace + 1); +			/* TODO: static */ +			memcpy(&container->as.list, data, sizeof(*data)); +			free(data); +		} else { +			break; +		} + +		if (accepts_lines(container->tag)) { +			// if it's a line container, it can't contain other containers +			break; +		} +	} + +	// what remains at offset is a text line.  add the text to the +	// appropriate container. + +	first_nonspace = offset; +	while (peek_at(&input, first_nonspace) == ' ') +		first_nonspace++; + +	indent = first_nonspace - offset; +	blank = peek_at(&input, first_nonspace) == '\n'; + +	// node_block quote lines are never blank as they start with > +	// and we don't count blanks in fenced code for purposes of tight/loose +	// lists or breaking out of lists.  we also don't set last_line_blank +	// on an empty list item. +	container->last_line_blank = (blank && +			container->tag != BLOCK_BQUOTE && +			container->tag != BLOCK_FENCED_CODE && +			!(container->tag == BLOCK_LIST_ITEM && +				container->children == NULL && +				container->start_line == line_number)); + +	node_block *cont = container; +	while (cont->parent) { +		cont->parent->last_line_blank = false; +		cont = cont->parent; +	} + +	if (cur != last_matched_container && +			container == last_matched_container && +			!blank && +			cur->tag == BLOCK_PARAGRAPH && +			strbuf_len(&cur->string_content) > 0) { + +		add_line(cur, &input, offset); + +	} else { // not a lazy continuation + +		// finalize any blocks that were not matched and set cur to container: +		while (cur != last_matched_container) { +			finalize(cur, line_number); +			cur = cur->parent; +			assert(cur != NULL); +		} + +		if (container->tag == BLOCK_INDENTED_CODE) { + +			add_line(container, &input, offset); + +		} else if (container->tag == BLOCK_FENCED_CODE) { +			matched = 0; + +			if (indent <= 3 && +				peek_at(&input, first_nonspace) == container->as.code.fence_char) { +				int fence_len = scan_close_code_fence(&input, first_nonspace); +				if (fence_len > container->as.code.fence_length) +					matched = 1; +			} + +			if (matched) { +				// if closing fence, don't add line to container; instead, close it: +				finalize(container, line_number); +				container = container->parent; // back up to parent +			} else { +				add_line(container, &input, offset); +			} + +		} else if (container->tag == BLOCK_HTML) { + +			add_line(container, &input, offset); + +		} else if (blank) { + +			// ??? do nothing + +		} else if (container->tag == BLOCK_ATX_HEADER) { + +			chop_trailing_hashtags(&input); +			add_line(container, &input, first_nonspace); +			finalize(container, line_number); +			container = container->parent; + +		} else if (accepts_lines(container->tag)) { + +			add_line(container, &input, first_nonspace); + +		} else if (container->tag != BLOCK_HRULE && container->tag != BLOCK_SETEXT_HEADER) { + +			// create paragraph container for line +			container = add_child(container, BLOCK_PARAGRAPH, line_number, first_nonspace + 1); +			add_line(container, &input, first_nonspace); -    } else if (container->tag != hrule && container->tag != setext_header) { - -      // create paragraph container for line -      container = add_child(container, paragraph, line_number, first_nonspace + 1); -      check(add_line(container, ln, first_nonspace) == 0, "could not add line"); - -    } else { +		} else { +			assert(false); +		} -      log_warn("Line %d with container type %d did not match any condition:\n\"%s\"", -               line_number, container->tag, ln->data); - -    } -    *curptr = container; -  } - -  return 0; - error: -  return -1; +		*curptr = container; +	}  } diff --git a/src/bstrlib.c b/src/bstrlib.c deleted file mode 100644 index 1b19dbe..0000000 --- a/src/bstrlib.c +++ /dev/null @@ -1,2979 +0,0 @@ -/*
 - * This source file is part of the bstring string library.  This code was
 - * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause 
 - * BSD open source license or GPL v2.0. Refer to the accompanying documentation 
 - * for details on usage and license.
 - */
 -
 -/*
 - * bstrlib.c
 - *
 - * This file is the core module for implementing the bstring functions.
 - */
 -
 -#if defined (_MSC_VER)
 -/* These warnings from MSVC++ are totally pointless. */
 -# define _CRT_SECURE_NO_WARNINGS
 -#endif
 -
 -#include <stdio.h>
 -#include <stddef.h>
 -#include <stdarg.h>
 -#include <stdlib.h>
 -#include <string.h>
 -#include <ctype.h>
 -#include "bstrlib.h"
 -
 -/* Optionally include a mechanism for debugging memory */
 -
 -#if defined(MEMORY_DEBUG) || defined(BSTRLIB_MEMORY_DEBUG)
 -#include "memdbg.h"
 -#endif
 -
 -#ifndef bstr__alloc
 -#define bstr__alloc(x) malloc (x)
 -#endif
 -
 -#ifndef bstr__free
 -#define bstr__free(p) free (p)
 -#endif
 -
 -#ifndef bstr__realloc
 -#define bstr__realloc(p,x) realloc ((p), (x))
 -#endif
 -
 -#ifndef bstr__memcpy
 -#define bstr__memcpy(d,s,l) memcpy ((d), (s), (l))
 -#endif
 -
 -#ifndef bstr__memmove
 -#define bstr__memmove(d,s,l) memmove ((d), (s), (l))
 -#endif
 -
 -#ifndef bstr__memset
 -#define bstr__memset(d,c,l) memset ((d), (c), (l))
 -#endif
 -
 -#ifndef bstr__memcmp
 -#define bstr__memcmp(d,c,l) memcmp ((d), (c), (l))
 -#endif
 -
 -#ifndef bstr__memchr
 -#define bstr__memchr(s,c,l) memchr ((s), (c), (l))
 -#endif
 -
 -/* Just a length safe wrapper for memmove. */
 -
 -#define bBlockCopy(D,S,L) { if ((L) > 0) bstr__memmove ((D),(S),(L)); }
 -
 -/* Compute the snapped size for a given requested size.  By snapping to powers
 -   of 2 like this, repeated reallocations are avoided. */
 -static int snapUpSize (int i) {
 -	if (i < 8) {
 -		i = 8;
 -	} else {
 -		unsigned int j;
 -		j = (unsigned int) i;
 -
 -		j |= (j >>  1);
 -		j |= (j >>  2);
 -		j |= (j >>  4);
 -		j |= (j >>  8);		/* Ok, since int >= 16 bits */
 -#if (UINT_MAX != 0xffff)
 -		j |= (j >> 16);		/* For 32 bit int systems */
 -#if (UINT_MAX > 0xffffffffUL)
 -		j |= (j >> 32);		/* For 64 bit int systems */
 -#endif
 -#endif
 -		/* Least power of two greater than i */
 -		j++;
 -		if ((int) j >= i) i = (int) j;
 -	}
 -	return i;
 -}
 -
 -/*  int balloc (bstring b, int len)
 - *
 - *  Increase the size of the memory backing the bstring b to at least len.
 - */
 -int balloc (bstring b, int olen) {
 -	int len;
 -	if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen <= 0 || 
 -	    b->mlen < b->slen || olen <= 0) {
 -		return BSTR_ERR;
 -	}
 -
 -	if (olen >= b->mlen) {
 -		unsigned char * x;
 -
 -		if ((len = snapUpSize (olen)) <= b->mlen) return BSTR_OK;
 -
 -		/* Assume probability of a non-moving realloc is 0.125 */
 -		if (7 * b->mlen < 8 * b->slen) {
 -
 -			/* If slen is close to mlen in size then use realloc to reduce
 -			   the memory defragmentation */
 -
 -			reallocStrategy:;
 -
 -			x = (unsigned char *) bstr__realloc (b->data, (size_t) len);
 -			if (x == NULL) {
 -
 -				/* Since we failed, try allocating the tighest possible 
 -				   allocation */
 -
 -				if (NULL == (x = (unsigned char *) bstr__realloc (b->data, (size_t) (len = olen)))) {
 -					return BSTR_ERR;
 -				}
 -			}
 -		} else {
 -
 -			/* If slen is not close to mlen then avoid the penalty of copying
 -			   the extra bytes that are allocated, but not considered part of
 -			   the string */
 -
 -			if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len))) {
 -
 -				/* Perhaps there is no available memory for the two 
 -				   allocations to be in memory at once */
 -
 -				goto reallocStrategy;
 -
 -			} else {
 -				if (b->slen) bstr__memcpy ((char *) x, (char *) b->data, (size_t) b->slen);
 -				bstr__free (b->data);
 -			}
 -		}
 -		b->data = x;
 -		b->mlen = len;
 -		b->data[b->slen] = (unsigned char) '\0';
 -	}
 -
 -	return BSTR_OK;
 -}
 -
 -/*  int ballocmin (bstring b, int len)
 - *
 - *  Set the size of the memory backing the bstring b to len or b->slen+1,
 - *  whichever is larger.  Note that repeated use of this function can degrade
 - *  performance.
 - */
 -int ballocmin (bstring b, int len) {
 -	unsigned char * s;
 -
 -	if (b == NULL || b->data == NULL || (b->slen+1) < 0 || b->mlen <= 0 || 
 -	    b->mlen < b->slen || len <= 0) {
 -		return BSTR_ERR;
 -	}
 -
 -	if (len < b->slen + 1) len = b->slen + 1;
 -
 -	if (len != b->mlen) {
 -		s = (unsigned char *) bstr__realloc (b->data, (size_t) len);
 -		if (NULL == s) return BSTR_ERR;
 -		s[b->slen] = (unsigned char) '\0';
 -		b->data = s;
 -		b->mlen = len;
 -	}
 -
 -	return BSTR_OK;
 -}
 -
 -/*  bstring bfromcstr (const char * str)
 - *
 - *  Create a bstring which contains the contents of the '\0' terminated char *
 - *  buffer str.
 - */
 -bstring bfromcstr (const char * str) {
 -bstring b;
 -int i;
 -size_t j;
 -
 -	if (str == NULL) return NULL;
 -	j = (strlen) (str);
 -	i = snapUpSize ((int) (j + (2 - (j != 0))));
 -	if (i <= (int) j) return NULL;
 -
 -	b = (bstring) bstr__alloc (sizeof (struct tagbstring));
 -	if (NULL == b) return NULL;
 -	b->slen = (int) j;
 -	if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) {
 -		bstr__free (b);
 -		return NULL;
 -	}
 -
 -	bstr__memcpy (b->data, str, j+1);
 -	return b;
 -}
 -
 -/*  bstring bfromcstralloc (int mlen, const char * str)
 - *
 - *  Create a bstring which contains the contents of the '\0' terminated char *
 - *  buffer str.  The memory buffer backing the string is at least len 
 - *  characters in length.
 - */
 -bstring bfromcstralloc (int mlen, const char * str) {
 -bstring b;
 -int i;
 -size_t j;
 -
 -	if (str == NULL) return NULL;
 -	j = (strlen) (str);
 -	i = snapUpSize ((int) (j + (2 - (j != 0))));
 -	if (i <= (int) j) return NULL;
 -
 -	b = (bstring) bstr__alloc (sizeof (struct tagbstring));
 -	if (b == NULL) return NULL;
 -	b->slen = (int) j;
 -	if (i < mlen) i = mlen;
 -
 -	if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) {
 -		bstr__free (b);
 -		return NULL;
 -	}
 -
 -	bstr__memcpy (b->data, str, j+1);
 -	return b;
 -}
 -
 -/*  bstring blk2bstr (const void * blk, int len)
 - *
 - *  Create a bstring which contains the content of the block blk of length 
 - *  len.
 - */
 -bstring blk2bstr (const void * blk, int len) {
 -bstring b;
 -int i;
 -
 -	if (blk == NULL || len < 0) return NULL;
 -	b = (bstring) bstr__alloc (sizeof (struct tagbstring));
 -	if (b == NULL) return NULL;
 -	b->slen = len;
 -
 -	i = len + (2 - (len != 0));
 -	i = snapUpSize (i);
 -
 -	b->mlen = i;
 -
 -	b->data = (unsigned char *) bstr__alloc ((size_t) b->mlen);
 -	if (b->data == NULL) {
 -		bstr__free (b);
 -		return NULL;
 -	}
 -
 -	if (len > 0) bstr__memcpy (b->data, blk, (size_t) len);
 -	b->data[len] = (unsigned char) '\0';
 -
 -	return b;
 -}
 -
 -/*  char * bstr2cstr (const_bstring s, char z)
 - *
 - *  Create a '\0' terminated char * buffer which is equal to the contents of 
 - *  the bstring s, except that any contained '\0' characters are converted 
 - *  to the character in z. This returned value should be freed with a 
 - *  bcstrfree () call, by the calling application.
 - */
 -char * bstr2cstr (const_bstring b, char z) {
 -int i, l;
 -char * r;
 -
 -	if (b == NULL || b->slen < 0 || b->data == NULL) return NULL;
 -	l = b->slen;
 -	r = (char *) bstr__alloc ((size_t) (l + 1));
 -	if (r == NULL) return r;
 -
 -	for (i=0; i < l; i ++) {
 -		r[i] = (char) ((b->data[i] == '\0') ? z : (char) (b->data[i]));
 -	}
 -
 -	r[l] = (unsigned char) '\0';
 -
 -	return r;
 -}
 -
 -/*  int bcstrfree (char * s)
 - *
 - *  Frees a C-string generated by bstr2cstr ().  This is normally unnecessary
 - *  since it just wraps a call to bstr__free (), however, if bstr__alloc () 
 - *  and bstr__free () have been redefined as a macros within the bstrlib 
 - *  module (via defining them in memdbg.h after defining 
 - *  BSTRLIB_MEMORY_DEBUG) with some difference in behaviour from the std 
 - *  library functions, then this allows a correct way of freeing the memory 
 - *  that allows higher level code to be independent from these macro 
 - *  redefinitions.
 - */
 -int bcstrfree (char * s) {
 -	if (s) {
 -		bstr__free (s);
 -		return BSTR_OK;
 -	}
 -	return BSTR_ERR;
 -}
 -
 -/*  int bconcat (bstring b0, const_bstring b1)
 - *
 - *  Concatenate the bstring b1 to the bstring b0.
 - */
 -int bconcat (bstring b0, const_bstring b1) {
 -int len, d;
 -bstring aux = (bstring) b1;
 -
 -	if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL) return BSTR_ERR;
 -
 -	d = b0->slen;
 -	len = b1->slen;
 -	if ((d | (b0->mlen - d) | len | (d + len)) < 0) return BSTR_ERR;
 -
 -	if (b0->mlen <= d + len + 1) {
 -		ptrdiff_t pd = b1->data - b0->data;
 -		if (0 <= pd && pd < b0->mlen) {
 -			if (NULL == (aux = bstrcpy (b1))) return BSTR_ERR;
 -		}
 -		if (balloc (b0, d + len + 1) != BSTR_OK) {
 -			if (aux != b1) bdestroy (aux);
 -			return BSTR_ERR;
 -		}
 -	}
 -
 -	bBlockCopy (&b0->data[d], &aux->data[0], (size_t) len);
 -	b0->data[d + len] = (unsigned char) '\0';
 -	b0->slen = d + len;
 -	if (aux != b1) bdestroy (aux);
 -	return BSTR_OK;
 -}
 -
 -/*  int bconchar (bstring b, char c)
 -/ *
 - *  Concatenate the single character c to the bstring b.
 - */
 -int bconchar (bstring b, char c) {
 -int d;
 -
 -	if (b == NULL) return BSTR_ERR;
 -	d = b->slen;
 -	if ((d | (b->mlen - d)) < 0 || balloc (b, d + 2) != BSTR_OK) return BSTR_ERR;
 -	b->data[d] = (unsigned char) c;
 -	b->data[d + 1] = (unsigned char) '\0';
 -	b->slen++;
 -	return BSTR_OK;
 -}
 -
 -/*  int bcatcstr (bstring b, const char * s)
 - *
 - *  Concatenate a char * string to a bstring.
 - */
 -int bcatcstr (bstring b, const char * s) {
 -char * d;
 -int i, l;
 -
 -	if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen
 -	 || b->mlen <= 0 || s == NULL) return BSTR_ERR;
 -
 -	/* Optimistically concatenate directly */
 -	l = b->mlen - b->slen;
 -	d = (char *) &b->data[b->slen];
 -	for (i=0; i < l; i++) {
 -		if ((*d++ = *s++) == '\0') {
 -			b->slen += i;
 -			return BSTR_OK;
 -		}
 -	}
 -	b->slen += i;
 -
 -	/* Need to explicitely resize and concatenate tail */
 -	return bcatblk (b, (const void *) s, (int) strlen (s));
 -}
 -
 -/*  int bcatblk (bstring b, const void * s, int len)
 - *
 - *  Concatenate a fixed length buffer to a bstring.
 - */
 -int bcatblk (bstring b, const void * s, int len) {
 -int nl;
 -
 -	if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen
 -	 || b->mlen <= 0 || s == NULL || len < 0) return BSTR_ERR;
 -
 -	if (0 > (nl = b->slen + len)) return BSTR_ERR; /* Overflow? */
 -	if (b->mlen <= nl && 0 > balloc (b, nl + 1)) return BSTR_ERR;
 -
 -	bBlockCopy (&b->data[b->slen], s, (size_t) len);
 -	b->slen = nl;
 -	b->data[nl] = (unsigned char) '\0';
 -	return BSTR_OK;
 -}
 -
 -/*  bstring bstrcpy (const_bstring b)
 - *
 - *  Create a copy of the bstring b.
 - */
 -bstring bstrcpy (const_bstring b) {
 -bstring b0;
 -int i,j;
 -
 -	/* Attempted to copy an invalid string? */
 -	if (b == NULL || b->slen < 0 || b->data == NULL) return NULL;
 -
 -	b0 = (bstring) bstr__alloc (sizeof (struct tagbstring));
 -	if (b0 == NULL) {
 -		/* Unable to allocate memory for string header */
 -		return NULL;
 -	}
 -
 -	i = b->slen;
 -	j = snapUpSize (i + 1);
 -
 -	b0->data = (unsigned char *) bstr__alloc (j);
 -	if (b0->data == NULL) {
 -		j = i + 1;
 -		b0->data = (unsigned char *) bstr__alloc (j);
 -		if (b0->data == NULL) {
 -			/* Unable to allocate memory for string data */
 -			bstr__free (b0);
 -			return NULL;
 -		}
 -	}
 -
 -	b0->mlen = j;
 -	b0->slen = i;
 -
 -	if (i) bstr__memcpy ((char *) b0->data, (char *) b->data, i);
 -	b0->data[b0->slen] = (unsigned char) '\0';
 -
 -	return b0;
 -}
 -
 -/*  int bassign (bstring a, const_bstring b)
 - *
 - *  Overwrite the string a with the contents of string b.
 - */
 -int bassign (bstring a, const_bstring b) {
 -	if (b == NULL || b->data == NULL || b->slen < 0)
 -		return BSTR_ERR;
 -	if (b->slen != 0) {
 -		if (balloc (a, b->slen) != BSTR_OK) return BSTR_ERR;
 -		bstr__memmove (a->data, b->data, b->slen);
 -	} else {
 -		if (a == NULL || a->data == NULL || a->mlen < a->slen || 
 -		    a->slen < 0 || a->mlen == 0) 
 -			return BSTR_ERR;
 -	}
 -	a->data[b->slen] = (unsigned char) '\0';
 -	a->slen = b->slen;
 -	return BSTR_OK;
 -}
 -
 -/*  int bassignmidstr (bstring a, const_bstring b, int left, int len)
 - *
 - *  Overwrite the string a with the middle of contents of string b 
 - *  starting from position left and running for a length len.  left and 
 - *  len are clamped to the ends of b as with the function bmidstr.
 - */
 -int bassignmidstr (bstring a, const_bstring b, int left, int len) {
 -	if (b == NULL || b->data == NULL || b->slen < 0)
 -		return BSTR_ERR;
 -
 -	if (left < 0) {
 -		len += left;
 -		left = 0;
 -	}
 -
 -	if (len > b->slen - left) len = b->slen - left;
 -
 -	if (a == NULL || a->data == NULL || a->mlen < a->slen ||
 -	    a->slen < 0 || a->mlen == 0)
 -		return BSTR_ERR;
 -
 -	if (len > 0) {
 -		if (balloc (a, len) != BSTR_OK) return BSTR_ERR;
 -		bstr__memmove (a->data, b->data + left, len);
 -		a->slen = len;
 -	} else {
 -		a->slen = 0;
 -	}
 -	a->data[a->slen] = (unsigned char) '\0';
 -	return BSTR_OK;
 -}
 -
 -/*  int bassigncstr (bstring a, const char * str)
 - *
 - *  Overwrite the string a with the contents of char * string str.  Note that 
 - *  the bstring a must be a well defined and writable bstring.  If an error 
 - *  occurs BSTR_ERR is returned however a may be partially overwritten.
 - */
 -int bassigncstr (bstring a, const char * str) {
 -int i;
 -size_t len;
 -	if (a == NULL || a->data == NULL || a->mlen < a->slen ||
 -	    a->slen < 0 || a->mlen == 0 || NULL == str) 
 -		return BSTR_ERR;
 -
 -	for (i=0; i < a->mlen; i++) {
 -		if ('\0' == (a->data[i] = str[i])) {
 -			a->slen = i;
 -			return BSTR_OK;
 -		}
 -	}
 -
 -	a->slen = i;
 -	len = strlen (str + i);
 -	if (len > INT_MAX || i + len + 1 > INT_MAX ||
 -	    0 > balloc (a, (int) (i + len + 1))) return BSTR_ERR;
 -	bBlockCopy (a->data + i, str + i, (size_t) len + 1);
 -	a->slen += (int) len;
 -	return BSTR_OK;
 -}
 -
 -/*  int bassignblk (bstring a, const void * s, int len)
 - *
 - *  Overwrite the string a with the contents of the block (s, len).  Note that 
 - *  the bstring a must be a well defined and writable bstring.  If an error 
 - *  occurs BSTR_ERR is returned and a is not overwritten.
 - */
 -int bassignblk (bstring a, const void * s, int len) {
 -	if (a == NULL || a->data == NULL || a->mlen < a->slen ||
 -	    a->slen < 0 || a->mlen == 0 || NULL == s || len + 1 < 1) 
 -		return BSTR_ERR;
 -	if (len + 1 > a->mlen && 0 > balloc (a, len + 1)) return BSTR_ERR;
 -	bBlockCopy (a->data, s, (size_t) len);
 -	a->data[len] = (unsigned char) '\0';
 -	a->slen = len;
 -	return BSTR_OK;
 -}
 -
 -/*  int btrunc (bstring b, int n)
 - *
 - *  Truncate the bstring to at most n characters.
 - */
 -int btrunc (bstring b, int n) {
 -	if (n < 0 || b == NULL || b->data == NULL || b->mlen < b->slen ||
 -	    b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
 -	if (b->slen > n) {
 -		b->slen = n;
 -		b->data[n] = (unsigned char) '\0';
 -	}
 -	return BSTR_OK;
 -}
 -
 -#define   upcase(c) (toupper ((unsigned char) c))
 -#define downcase(c) (tolower ((unsigned char) c))
 -#define   wspace(c) (isspace ((unsigned char) c))
 -
 -/*  int btoupper (bstring b)
 - *
 - *  Convert contents of bstring to upper case.
 - */
 -int btoupper (bstring b) {
 -int i, len;
 -	if (b == NULL || b->data == NULL || b->mlen < b->slen ||
 -	    b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
 -	for (i=0, len = b->slen; i < len; i++) {
 -		b->data[i] = (unsigned char) upcase (b->data[i]);
 -	}
 -	return BSTR_OK;
 -}
 -
 -/*  int btolower (bstring b)
 - *
 - *  Convert contents of bstring to lower case.
 - */
 -int btolower (bstring b) {
 -int i, len;
 -	if (b == NULL || b->data == NULL || b->mlen < b->slen ||
 -	    b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
 -	for (i=0, len = b->slen; i < len; i++) {
 -		b->data[i] = (unsigned char) downcase (b->data[i]);
 -	}
 -	return BSTR_OK;
 -}
 -
 -/*  int bstricmp (const_bstring b0, const_bstring b1)
 - *
 - *  Compare two strings without differentiating between case.  The return 
 - *  value is the difference of the values of the characters where the two 
 - *  strings first differ after lower case transformation, otherwise 0 is 
 - *  returned indicating that the strings are equal.  If the lengths are 
 - *  different, then a difference from 0 is given, but if the first extra 
 - *  character is '\0', then it is taken to be the value UCHAR_MAX+1.
 - */
 -int bstricmp (const_bstring b0, const_bstring b1) {
 -int i, v, n;
 -
 -	if (bdata (b0) == NULL || b0->slen < 0 || 
 -	    bdata (b1) == NULL || b1->slen < 0) return SHRT_MIN;
 -	if ((n = b0->slen) > b1->slen) n = b1->slen;
 -	else if (b0->slen == b1->slen && b0->data == b1->data) return BSTR_OK;
 -
 -	for (i = 0; i < n; i ++) {
 -		v  = (char) downcase (b0->data[i])
 -		   - (char) downcase (b1->data[i]);
 -		if (0 != v) return v;
 -	}
 -
 -	if (b0->slen > n) {
 -		v = (char) downcase (b0->data[n]);
 -		if (v) return v;
 -		return UCHAR_MAX + 1;
 -	}
 -	if (b1->slen > n) {
 -		v = - (char) downcase (b1->data[n]);
 -		if (v) return v;
 -		return - (int) (UCHAR_MAX + 1);
 -	}
 -	return BSTR_OK;
 -}
 -
 -/*  int bstrnicmp (const_bstring b0, const_bstring b1, int n)
 - *
 - *  Compare two strings without differentiating between case for at most n
 - *  characters.  If the position where the two strings first differ is
 - *  before the nth position, the return value is the difference of the values
 - *  of the characters, otherwise 0 is returned.  If the lengths are different
 - *  and less than n characters, then a difference from 0 is given, but if the 
 - *  first extra character is '\0', then it is taken to be the value 
 - *  UCHAR_MAX+1.
 - */
 -int bstrnicmp (const_bstring b0, const_bstring b1, int n) {
 -int i, v, m;
 -
 -	if (bdata (b0) == NULL || b0->slen < 0 || 
 -	    bdata (b1) == NULL || b1->slen < 0 || n < 0) return SHRT_MIN;
 -	m = n;
 -	if (m > b0->slen) m = b0->slen;
 -	if (m > b1->slen) m = b1->slen;
 -
 -	if (b0->data != b1->data) {
 -		for (i = 0; i < m; i ++) {
 -			v  = (char) downcase (b0->data[i]);
 -			v -= (char) downcase (b1->data[i]);
 -			if (v != 0) return b0->data[i] - b1->data[i];
 -		}
 -	}
 -
 -	if (n == m || b0->slen == b1->slen) return BSTR_OK;
 -
 -	if (b0->slen > m) {
 -		v = (char) downcase (b0->data[m]);
 -		if (v) return v;
 -		return UCHAR_MAX + 1;
 -	}
 -
 -	v = - (char) downcase (b1->data[m]);
 -	if (v) return v;
 -	return - (int) (UCHAR_MAX + 1);
 -}
 -
 -/*  int biseqcaseless (const_bstring b0, const_bstring b1)
 - *
 - *  Compare two strings for equality without differentiating between case.  
 - *  If the strings differ other than in case, 0 is returned, if the strings 
 - *  are the same, 1 is returned, if there is an error, -1 is returned.  If 
 - *  the length of the strings are different, this function is O(1).  '\0' 
 - *  termination characters are not treated in any special way.
 - */
 -int biseqcaseless (const_bstring b0, const_bstring b1) {
 -int i, n;
 -
 -	if (bdata (b0) == NULL || b0->slen < 0 || 
 -	    bdata (b1) == NULL || b1->slen < 0) return BSTR_ERR;
 -	if (b0->slen != b1->slen) return BSTR_OK;
 -	if (b0->data == b1->data || b0->slen == 0) return 1;
 -	for (i=0, n=b0->slen; i < n; i++) {
 -		if (b0->data[i] != b1->data[i]) {
 -			unsigned char c = (unsigned char) downcase (b0->data[i]);
 -			if (c != (unsigned char) downcase (b1->data[i])) return 0;
 -		}
 -	}
 -	return 1;
 -}
 -
 -/*  int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len)
 - *
 - *  Compare beginning of string b0 with a block of memory of length len 
 - *  without differentiating between case for equality.  If the beginning of b0
 - *  differs from the memory block other than in case (or if b0 is too short), 
 - *  0 is returned, if the strings are the same, 1 is returned, if there is an 
 - *  error, -1 is returned.  '\0' characters are not treated in any special 
 - *  way.
 - */
 -int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len) {
 -int i;
 -
 -	if (bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0)
 -		return BSTR_ERR;
 -	if (b0->slen < len) return BSTR_OK;
 -	if (b0->data == (const unsigned char *) blk || len == 0) return 1;
 -
 -	for (i = 0; i < len; i ++) {
 -		if (b0->data[i] != ((const unsigned char *) blk)[i]) {
 -			if (downcase (b0->data[i]) != 
 -			    downcase (((const unsigned char *) blk)[i])) return 0;
 -		}
 -	}
 -	return 1;
 -}
 -
 -/*
 - * int bltrimws (bstring b)
 - *
 - * Delete whitespace contiguous from the left end of the string.
 - */
 -int bltrimws (bstring b) {
 -int i, len;
 -
 -	if (b == NULL || b->data == NULL || b->mlen < b->slen ||
 -	    b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
 -
 -	for (len = b->slen, i = 0; i < len; i++) {
 -		if (!wspace (b->data[i])) {
 -			return bdelete (b, 0, i);
 -		}
 -	}
 -
 -	b->data[0] = (unsigned char) '\0';
 -	b->slen = 0;
 -	return BSTR_OK;
 -}
 -
 -/*
 - * int brtrimws (bstring b)
 - *
 - * Delete whitespace contiguous from the right end of the string.
 - */
 -int brtrimws (bstring b) {
 -int i;
 -
 -	if (b == NULL || b->data == NULL || b->mlen < b->slen ||
 -	    b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
 -
 -	for (i = b->slen - 1; i >= 0; i--) {
 -		if (!wspace (b->data[i])) {
 -			if (b->mlen > i) b->data[i+1] = (unsigned char) '\0';
 -			b->slen = i + 1;
 -			return BSTR_OK;
 -		}
 -	}
 -
 -	b->data[0] = (unsigned char) '\0';
 -	b->slen = 0;
 -	return BSTR_OK;
 -}
 -
 -/*
 - * int btrimws (bstring b)
 - *
 - * Delete whitespace contiguous from both ends of the string.
 - */
 -int btrimws (bstring b) {
 -int i, j;
 -
 -	if (b == NULL || b->data == NULL || b->mlen < b->slen ||
 -	    b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
 -
 -	for (i = b->slen - 1; i >= 0; i--) {
 -		if (!wspace (b->data[i])) {
 -			if (b->mlen > i) b->data[i+1] = (unsigned char) '\0';
 -			b->slen = i + 1;
 -			for (j = 0; wspace (b->data[j]); j++) {}
 -			return bdelete (b, 0, j);
 -		}
 -	}
 -
 -	b->data[0] = (unsigned char) '\0';
 -	b->slen = 0;
 -	return BSTR_OK;
 -}
 -
 -/*  int biseq (const_bstring b0, const_bstring b1)
 - *
 - *  Compare the string b0 and b1.  If the strings differ, 0 is returned, if 
 - *  the strings are the same, 1 is returned, if there is an error, -1 is 
 - *  returned.  If the length of the strings are different, this function is
 - *  O(1).  '\0' termination characters are not treated in any special way.
 - */
 -int biseq (const_bstring b0, const_bstring b1) {
 -	if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL ||
 -		b0->slen < 0 || b1->slen < 0) return BSTR_ERR;
 -	if (b0->slen != b1->slen) return BSTR_OK;
 -	if (b0->data == b1->data || b0->slen == 0) return 1;
 -	return !bstr__memcmp (b0->data, b1->data, b0->slen);
 -}
 -
 -/*  int bisstemeqblk (const_bstring b0, const void * blk, int len)
 - *
 - *  Compare beginning of string b0 with a block of memory of length len for 
 - *  equality.  If the beginning of b0 differs from the memory block (or if b0 
 - *  is too short), 0 is returned, if the strings are the same, 1 is returned, 
 - *  if there is an error, -1 is returned.  '\0' characters are not treated in 
 - *  any special way.
 - */
 -int bisstemeqblk (const_bstring b0, const void * blk, int len) {
 -int i;
 -
 -	if (bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0)
 -		return BSTR_ERR;
 -	if (b0->slen < len) return BSTR_OK;
 -	if (b0->data == (const unsigned char *) blk || len == 0) return 1;
 -
 -	for (i = 0; i < len; i ++) {
 -		if (b0->data[i] != ((const unsigned char *) blk)[i]) return BSTR_OK;
 -	}
 -	return 1;
 -}
 -
 -/*  int biseqcstr (const_bstring b, const char *s)
 - *
 - *  Compare the bstring b and char * string s.  The C string s must be '\0' 
 - *  terminated at exactly the length of the bstring b, and the contents 
 - *  between the two must be identical with the bstring b with no '\0' 
 - *  characters for the two contents to be considered equal.  This is 
 - *  equivalent to the condition that their current contents will be always be 
 - *  equal when comparing them in the same format after converting one or the 
 - *  other.  If the strings are equal 1 is returned, if they are unequal 0 is 
 - *  returned and if there is a detectable error BSTR_ERR is returned.
 - */
 -int biseqcstr (const_bstring b, const char * s) {
 -int i;
 -	if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return BSTR_ERR;
 -	for (i=0; i < b->slen; i++) {
 -		if (s[i] == '\0' || b->data[i] != (unsigned char) s[i]) return BSTR_OK;
 -	}
 -	return s[i] == '\0';
 -}
 -
 -/*  int biseqcstrcaseless (const_bstring b, const char *s)
 - *
 - *  Compare the bstring b and char * string s.  The C string s must be '\0' 
 - *  terminated at exactly the length of the bstring b, and the contents 
 - *  between the two must be identical except for case with the bstring b with 
 - *  no '\0' characters for the two contents to be considered equal.  This is 
 - *  equivalent to the condition that their current contents will be always be 
 - *  equal ignoring case when comparing them in the same format after 
 - *  converting one or the other.  If the strings are equal, except for case, 
 - *  1 is returned, if they are unequal regardless of case 0 is returned and 
 - *  if there is a detectable error BSTR_ERR is returned.
 - */
 -int biseqcstrcaseless (const_bstring b, const char * s) {
 -int i;
 -	if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return BSTR_ERR;
 -	for (i=0; i < b->slen; i++) {
 -		if (s[i] == '\0' || 
 -		    (b->data[i] != (unsigned char) s[i] && 
 -		     downcase (b->data[i]) != (unsigned char) downcase (s[i])))
 -			return BSTR_OK;
 -	}
 -	return s[i] == '\0';
 -}
 -
 -/*  int bstrcmp (const_bstring b0, const_bstring b1)
 - *
 - *  Compare the string b0 and b1.  If there is an error, SHRT_MIN is returned, 
 - *  otherwise a value less than or greater than zero, indicating that the 
 - *  string pointed to by b0 is lexicographically less than or greater than 
 - *  the string pointed to by b1 is returned.  If the the string lengths are 
 - *  unequal but the characters up until the length of the shorter are equal 
 - *  then a value less than, or greater than zero, indicating that the string 
 - *  pointed to by b0 is shorter or longer than the string pointed to by b1 is 
 - *  returned.  0 is returned if and only if the two strings are the same.  If 
 - *  the length of the strings are different, this function is O(n).  Like its
 - *  standard C library counter part strcmp, the comparison does not proceed 
 - *  past any '\0' termination characters encountered.
 - */
 -int bstrcmp (const_bstring b0, const_bstring b1) {
 -int i, v, n;
 -
 -	if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL ||
 -		b0->slen < 0 || b1->slen < 0) return SHRT_MIN;
 -	n = b0->slen; if (n > b1->slen) n = b1->slen;
 -	if (b0->slen == b1->slen && (b0->data == b1->data || b0->slen == 0))
 -		return BSTR_OK;
 -
 -	for (i = 0; i < n; i ++) {
 -		v = ((char) b0->data[i]) - ((char) b1->data[i]);
 -		if (v != 0) return v;
 -		if (b0->data[i] == (unsigned char) '\0') return BSTR_OK;
 -	}
 -
 -	if (b0->slen > n) return 1;
 -	if (b1->slen > n) return -1;
 -	return BSTR_OK;
 -}
 -
 -/*  int bstrncmp (const_bstring b0, const_bstring b1, int n)
 - *
 - *  Compare the string b0 and b1 for at most n characters.  If there is an 
 - *  error, SHRT_MIN is returned, otherwise a value is returned as if b0 and 
 - *  b1 were first truncated to at most n characters then bstrcmp was called
 - *  with these new strings are paremeters.  If the length of the strings are 
 - *  different, this function is O(n).  Like its standard C library counter 
 - *  part strcmp, the comparison does not proceed past any '\0' termination 
 - *  characters encountered.
 - */
 -int bstrncmp (const_bstring b0, const_bstring b1, int n) {
 -int i, v, m;
 -
 -	if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL ||
 -		b0->slen < 0 || b1->slen < 0) return SHRT_MIN;
 -	m = n;
 -	if (m > b0->slen) m = b0->slen;
 -	if (m > b1->slen) m = b1->slen;
 -
 -	if (b0->data != b1->data) {
 -		for (i = 0; i < m; i ++) {
 -			v = ((char) b0->data[i]) - ((char) b1->data[i]);
 -			if (v != 0) return v;
 -			if (b0->data[i] == (unsigned char) '\0') return BSTR_OK;
 -		}
 -	}
 -
 -	if (n == m || b0->slen == b1->slen) return BSTR_OK;
 -
 -	if (b0->slen > m) return 1;
 -	return -1;
 -}
 -
 -/*  bstring bmidstr (const_bstring b, int left, int len)
 - *
 - *  Create a bstring which is the substring of b starting from position left
 - *  and running for a length len (clamped by the end of the bstring b.)  If
 - *  b is detectably invalid, then NULL is returned.  The section described 
 - *  by (left, len) is clamped to the boundaries of b.
 - */
 -bstring bmidstr (const_bstring b, int left, int len) {
 -
 -	if (b == NULL || b->slen < 0 || b->data == NULL) return NULL;
 -
 -	if (left < 0) {
 -		len += left;
 -		left = 0;
 -	}
 -
 -	if (len > b->slen - left) len = b->slen - left;
 -
 -	if (len <= 0) return bfromcstr ("");
 -	return blk2bstr (b->data + left, len);
 -}
 -
 -/*  int bdelete (bstring b, int pos, int len)
 - *
 - *  Removes characters from pos to pos+len-1 inclusive and shifts the tail of 
 - *  the bstring starting from pos+len to pos.  len must be positive for this 
 - *  call to have any effect.  The section of the string described by (pos, 
 - *  len) is clamped to boundaries of the bstring b.
 - */
 -int bdelete (bstring b, int pos, int len) {
 -	/* Clamp to left side of bstring */
 -	if (pos < 0) {
 -		len += pos;
 -		pos = 0;
 -	}
 -
 -	if (len < 0 || b == NULL || b->data == NULL || b->slen < 0 || 
 -	    b->mlen < b->slen || b->mlen <= 0) 
 -		return BSTR_ERR;
 -	if (len > 0 && pos < b->slen) {
 -		if (pos + len >= b->slen) {
 -			b->slen = pos;
 -		} else {
 -			bBlockCopy ((char *) (b->data + pos),
 -			            (char *) (b->data + pos + len), 
 -			            b->slen - (pos+len));
 -			b->slen -= len;
 -		}
 -		b->data[b->slen] = (unsigned char) '\0';
 -	}
 -	return BSTR_OK;
 -}
 -
 -/*  int bdestroy (bstring b)
 - *
 - *  Free up the bstring.  Note that if b is detectably invalid or not writable
 - *  then no action is performed and BSTR_ERR is returned.  Like a freed memory
 - *  allocation, dereferences, writes or any other action on b after it has 
 - *  been bdestroyed is undefined.
 - */
 -int bdestroy (bstring b) {
 -	if (b == NULL || b->slen < 0 || b->mlen <= 0 || b->mlen < b->slen ||
 -	    b->data == NULL)
 -		return BSTR_ERR;
 -
 -	bstr__free (b->data);
 -
 -	/* In case there is any stale usage, there is one more chance to 
 -	   notice this error. */
 -
 -	b->slen = -1;
 -	b->mlen = -__LINE__;
 -	b->data = NULL;
 -
 -	bstr__free (b);
 -	return BSTR_OK;
 -}
 -
 -/*  int binstr (const_bstring b1, int pos, const_bstring b2)
 - *
 - *  Search for the bstring b2 in b1 starting from position pos, and searching 
 - *  forward.  If it is found then return with the first position where it is 
 - *  found, otherwise return BSTR_ERR.  Note that this is just a brute force 
 - *  string searcher that does not attempt clever things like the Boyer-Moore 
 - *  search algorithm.  Because of this there are many degenerate cases where 
 - *  this can take much longer than it needs to.
 - */
 -int binstr (const_bstring b1, int pos, const_bstring b2) {
 -int j, ii, ll, lf;
 -unsigned char * d0;
 -unsigned char c0;
 -register unsigned char * d1;
 -register unsigned char c1;
 -register int i;
 -
 -	if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
 -	    b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
 -	if (b1->slen == pos) return (b2->slen == 0)?pos:BSTR_ERR;
 -	if (b1->slen < pos || pos < 0) return BSTR_ERR;
 -	if (b2->slen == 0) return pos;
 -
 -	/* No space to find such a string? */
 -	if ((lf = b1->slen - b2->slen + 1) <= pos) return BSTR_ERR;
 -
 -	/* An obvious alias case */
 -	if (b1->data == b2->data && pos == 0) return 0;
 -
 -	i = pos;
 -
 -	d0 = b2->data;
 -	d1 = b1->data;
 -	ll = b2->slen;
 -
 -	/* Peel off the b2->slen == 1 case */
 -	c0 = d0[0];
 -	if (1 == ll) {
 -		for (;i < lf; i++) if (c0 == d1[i]) return i;
 -		return BSTR_ERR;
 -	}
 -
 -	c1 = c0;
 -	j = 0;
 -	lf = b1->slen - 1;
 -
 -	ii = -1;
 -	if (i < lf) do {
 -		/* Unrolled current character test */
 -		if (c1 != d1[i]) {
 -			if (c1 != d1[1+i]) {
 -				i += 2;
 -				continue;
 -			}
 -			i++;
 -		}
 -
 -		/* Take note if this is the start of a potential match */
 -		if (0 == j) ii = i;
 -
 -		/* Shift the test character down by one */
 -		j++;
 -		i++;
 -
 -		/* If this isn't past the last character continue */
 -		if (j < ll) {
 -			c1 = d0[j];
 -			continue;
 -		}
 -
 -		N0:;
 -
 -		/* If no characters mismatched, then we matched */
 -		if (i == ii+j) return ii;
 -
 -		/* Shift back to the beginning */
 -		i -= j;
 -		j  = 0;
 -		c1 = c0;
 -	} while (i < lf);
 -
 -	/* Deal with last case if unrolling caused a misalignment */
 -	if (i == lf && ll == j+1 && c1 == d1[i]) goto N0;
 -
 -	return BSTR_ERR;
 -}
 -
 -/*  int binstrr (const_bstring b1, int pos, const_bstring b2)
 - *
 - *  Search for the bstring b2 in b1 starting from position pos, and searching 
 - *  backward.  If it is found then return with the first position where it is 
 - *  found, otherwise return BSTR_ERR.  Note that this is just a brute force 
 - *  string searcher that does not attempt clever things like the Boyer-Moore 
 - *  search algorithm.  Because of this there are many degenerate cases where 
 - *  this can take much longer than it needs to.
 - */
 -int binstrr (const_bstring b1, int pos, const_bstring b2) {
 -int j, i, l;
 -unsigned char * d0, * d1;
 -
 -	if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
 -	    b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
 -	if (b1->slen == pos && b2->slen == 0) return pos;
 -	if (b1->slen < pos || pos < 0) return BSTR_ERR;
 -	if (b2->slen == 0) return pos;
 -
 -	/* Obvious alias case */
 -	if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return 0;
 -
 -	i = pos;
 -	if ((l = b1->slen - b2->slen) < 0) return BSTR_ERR;
 -
 -	/* If no space to find such a string then snap back */
 -	if (l + 1 <= i) i = l;
 -	j = 0;
 -
 -	d0 = b2->data;
 -	d1 = b1->data;
 -	l  = b2->slen;
 -
 -	for (;;) {
 -		if (d0[j] == d1[i + j]) {
 -			j ++;
 -			if (j >= l) return i;
 -		} else {
 -			i --;
 -			if (i < 0) break;
 -			j=0;
 -		}
 -	}
 -
 -	return BSTR_ERR;
 -}
 -
 -/*  int binstrcaseless (const_bstring b1, int pos, const_bstring b2)
 - *
 - *  Search for the bstring b2 in b1 starting from position pos, and searching 
 - *  forward but without regard to case.  If it is found then return with the 
 - *  first position where it is found, otherwise return BSTR_ERR.  Note that 
 - *  this is just a brute force string searcher that does not attempt clever 
 - *  things like the Boyer-Moore search algorithm.  Because of this there are 
 - *  many degenerate cases where this can take much longer than it needs to.
 - */
 -int binstrcaseless (const_bstring b1, int pos, const_bstring b2) {
 -int j, i, l, ll;
 -unsigned char * d0, * d1;
 -
 -	if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
 -	    b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
 -	if (b1->slen == pos) return (b2->slen == 0)?pos:BSTR_ERR;
 -	if (b1->slen < pos || pos < 0) return BSTR_ERR;
 -	if (b2->slen == 0) return pos;
 -
 -	l = b1->slen - b2->slen + 1;
 -
 -	/* No space to find such a string? */
 -	if (l <= pos) return BSTR_ERR;
 -
 -	/* An obvious alias case */
 -	if (b1->data == b2->data && pos == 0) return BSTR_OK;
 -
 -	i = pos;
 -	j = 0;
 -
 -	d0 = b2->data;
 -	d1 = b1->data;
 -	ll = b2->slen;
 -
 -	for (;;) {
 -		if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) {
 -			j ++;
 -			if (j >= ll) return i;
 -		} else {
 -			i ++;
 -			if (i >= l) break;
 -			j=0;
 -		}
 -	}
 -
 -	return BSTR_ERR;
 -}
 -
 -/*  int binstrrcaseless (const_bstring b1, int pos, const_bstring b2)
 - *
 - *  Search for the bstring b2 in b1 starting from position pos, and searching 
 - *  backward but without regard to case.  If it is found then return with the 
 - *  first position where it is found, otherwise return BSTR_ERR.  Note that 
 - *  this is just a brute force string searcher that does not attempt clever 
 - *  things like the Boyer-Moore search algorithm.  Because of this there are 
 - *  many degenerate cases where this can take much longer than it needs to.
 - */
 -int binstrrcaseless (const_bstring b1, int pos, const_bstring b2) {
 -int j, i, l;
 -unsigned char * d0, * d1;
 -
 -	if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
 -	    b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
 -	if (b1->slen == pos && b2->slen == 0) return pos;
 -	if (b1->slen < pos || pos < 0) return BSTR_ERR;
 -	if (b2->slen == 0) return pos;
 -
 -	/* Obvious alias case */
 -	if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return BSTR_OK;
 -
 -	i = pos;
 -	if ((l = b1->slen - b2->slen) < 0) return BSTR_ERR;
 -
 -	/* If no space to find such a string then snap back */
 -	if (l + 1 <= i) i = l;
 -	j = 0;
 -
 -	d0 = b2->data;
 -	d1 = b1->data;
 -	l  = b2->slen;
 -
 -	for (;;) {
 -		if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) {
 -			j ++;
 -			if (j >= l) return i;
 -		} else {
 -			i --;
 -			if (i < 0) break;
 -			j=0;
 -		}
 -	}
 -
 -	return BSTR_ERR;
 -}
 -
 -
 -/*  int bstrchrp (const_bstring b, int c, int pos)
 - *
 - *  Search for the character c in b forwards from the position pos 
 - *  (inclusive).
 - */
 -int bstrchrp (const_bstring b, int c, int pos) {
 -unsigned char * p;
 -
 -	if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return BSTR_ERR;
 -	p = (unsigned char *) bstr__memchr ((b->data + pos), (unsigned char) c, (b->slen - pos));
 -	if (p) return (int) (p - b->data);
 -	return BSTR_ERR;
 -}
 -
 -/*  int bstrrchrp (const_bstring b, int c, int pos)
 - *
 - *  Search for the character c in b backwards from the position pos in string 
 - *  (inclusive).
 - */
 -int bstrrchrp (const_bstring b, int c, int pos) {
 -int i;
 - 
 -	if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return BSTR_ERR;
 -	for (i=pos; i >= 0; i--) {
 -		if (b->data[i] == (unsigned char) c) return i;
 -	}
 -	return BSTR_ERR;
 -}
 -
 -#if !defined (BSTRLIB_AGGRESSIVE_MEMORY_FOR_SPEED_TRADEOFF)
 -#define LONG_LOG_BITS_QTY (3)
 -#define LONG_BITS_QTY (1 << LONG_LOG_BITS_QTY)
 -#define LONG_TYPE unsigned char
 -
 -#define CFCLEN ((1 << CHAR_BIT) / LONG_BITS_QTY)
 -struct charField { LONG_TYPE content[CFCLEN]; };
 -#define testInCharField(cf,c) ((cf)->content[(c) >> LONG_LOG_BITS_QTY] & (((long)1) << ((c) & (LONG_BITS_QTY-1))))
 -#define setInCharField(cf,idx) { \
 -	unsigned int c = (unsigned int) (idx); \
 -	(cf)->content[c >> LONG_LOG_BITS_QTY] |= (LONG_TYPE) (1ul << (c & (LONG_BITS_QTY-1))); \
 -}
 -
 -#else
 -
 -#define CFCLEN (1 << CHAR_BIT)
 -struct charField { unsigned char content[CFCLEN]; };
 -#define testInCharField(cf,c) ((cf)->content[(unsigned char) (c)])
 -#define setInCharField(cf,idx) (cf)->content[(unsigned int) (idx)] = ~0
 -
 -#endif
 -
 -/* Convert a bstring to charField */
 -static int buildCharField (struct charField * cf, const_bstring b) {
 -int i;
 -	if (b == NULL || b->data == NULL || b->slen <= 0) return BSTR_ERR;
 -	memset ((void *) cf->content, 0, sizeof (struct charField));
 -	for (i=0; i < b->slen; i++) {
 -		setInCharField (cf, b->data[i]);
 -	}
 -	return BSTR_OK;
 -}
 -
 -static void invertCharField (struct charField * cf) {
 -int i;
 -	for (i=0; i < CFCLEN; i++) cf->content[i] = ~cf->content[i];
 -}
 -
 -/* Inner engine for binchr */
 -static int binchrCF (const unsigned char * data, int len, int pos, const struct charField * cf) {
 -int i;
 -	for (i=pos; i < len; i++) {
 -		unsigned char c = (unsigned char) data[i];
 -		if (testInCharField (cf, c)) return i;
 -	}
 -	return BSTR_ERR;
 -}
 -
 -/*  int binchr (const_bstring b0, int pos, const_bstring b1);
 - *
 - *  Search for the first position in b0 starting from pos or after, in which 
 - *  one of the characters in b1 is found and return it.  If such a position 
 - *  does not exist in b0, then BSTR_ERR is returned.
 - */
 -int binchr (const_bstring b0, int pos, const_bstring b1) {
 -struct charField chrs;
 -	if (pos < 0 || b0 == NULL || b0->data == NULL ||
 -	    b0->slen <= pos) return BSTR_ERR;
 -	if (1 == b1->slen) return bstrchrp (b0, b1->data[0], pos);
 -	if (0 > buildCharField (&chrs, b1)) return BSTR_ERR;
 -	return binchrCF (b0->data, b0->slen, pos, &chrs);
 -}
 -
 -/* Inner engine for binchrr */
 -static int binchrrCF (const unsigned char * data, int pos, const struct charField * cf) {
 -int i;
 -	for (i=pos; i >= 0; i--) {
 -		unsigned int c = (unsigned int) data[i];
 -		if (testInCharField (cf, c)) return i;
 -	}
 -	return BSTR_ERR;
 -}
 -
 -/*  int binchrr (const_bstring b0, int pos, const_bstring b1);
 - *
 - *  Search for the last position in b0 no greater than pos, in which one of 
 - *  the characters in b1 is found and return it.  If such a position does not 
 - *  exist in b0, then BSTR_ERR is returned.
 - */
 -int binchrr (const_bstring b0, int pos, const_bstring b1) {
 -struct charField chrs;
 -	if (pos < 0 || b0 == NULL || b0->data == NULL || b1 == NULL ||
 -	    b0->slen < pos) return BSTR_ERR;
 -	if (pos == b0->slen) pos--;
 -	if (1 == b1->slen) return bstrrchrp (b0, b1->data[0], pos);
 -	if (0 > buildCharField (&chrs, b1)) return BSTR_ERR;
 -	return binchrrCF (b0->data, pos, &chrs);
 -}
 -
 -/*  int bninchr (const_bstring b0, int pos, const_bstring b1);
 - *
 - *  Search for the first position in b0 starting from pos or after, in which 
 - *  none of the characters in b1 is found and return it.  If such a position 
 - *  does not exist in b0, then BSTR_ERR is returned.
 - */
 -int bninchr (const_bstring b0, int pos, const_bstring b1) {
 -struct charField chrs;
 -	if (pos < 0 || b0 == NULL || b0->data == NULL || 
 -	    b0->slen <= pos) return BSTR_ERR;
 -	if (buildCharField (&chrs, b1) < 0) return BSTR_ERR;
 -	invertCharField (&chrs);
 -	return binchrCF (b0->data, b0->slen, pos, &chrs);
 -}
 -
 -/*  int bninchrr (const_bstring b0, int pos, const_bstring b1);
 - *
 - *  Search for the last position in b0 no greater than pos, in which none of 
 - *  the characters in b1 is found and return it.  If such a position does not 
 - *  exist in b0, then BSTR_ERR is returned.
 - */
 -int bninchrr (const_bstring b0, int pos, const_bstring b1) {
 -struct charField chrs;
 -	if (pos < 0 || b0 == NULL || b0->data == NULL || 
 -	    b0->slen < pos) return BSTR_ERR;
 -	if (pos == b0->slen) pos--;
 -	if (buildCharField (&chrs, b1) < 0) return BSTR_ERR;
 -	invertCharField (&chrs);
 -	return binchrrCF (b0->data, pos, &chrs);
 -}
 -
 -/*  int bsetstr (bstring b0, int pos, bstring b1, unsigned char fill)
 - *
 - *  Overwrite the string b0 starting at position pos with the string b1. If 
 - *  the position pos is past the end of b0, then the character "fill" is 
 - *  appended as necessary to make up the gap between the end of b0 and pos.
 - *  If b1 is NULL, it behaves as if it were a 0-length string.
 - */
 -int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill) {
 -int d, newlen;
 -ptrdiff_t pd;
 -bstring aux = (bstring) b1;
 -
 -	if (pos < 0 || b0 == NULL || b0->slen < 0 || NULL == b0->data || 
 -	    b0->mlen < b0->slen || b0->mlen <= 0) return BSTR_ERR;
 -	if (b1 != NULL && (b1->slen < 0 || b1->data == NULL)) return BSTR_ERR;
 -
 -	d = pos;
 -
 -	/* Aliasing case */
 -	if (NULL != aux) {
 -		if ((pd = (ptrdiff_t) (b1->data - b0->data)) >= 0 && pd < (ptrdiff_t) b0->mlen) {
 -			if (NULL == (aux = bstrcpy (b1))) return BSTR_ERR;
 -		}
 -		d += aux->slen;
 -	}
 -
 -	/* Increase memory size if necessary */
 -	if (balloc (b0, d + 1) != BSTR_OK) {
 -		if (aux != b1) bdestroy (aux);
 -		return BSTR_ERR;
 -	}
 -
 -	newlen = b0->slen;
 -
 -	/* Fill in "fill" character as necessary */
 -	if (pos > newlen) {
 -		bstr__memset (b0->data + b0->slen, (int) fill, (size_t) (pos - b0->slen));
 -		newlen = pos;
 -	}
 -
 -	/* Copy b1 to position pos in b0. */
 -	if (aux != NULL) {
 -		bBlockCopy ((char *) (b0->data + pos), (char *) aux->data, aux->slen);
 -		if (aux != b1) bdestroy (aux);
 -	}
 -
 -	/* Indicate the potentially increased size of b0 */
 -	if (d > newlen) newlen = d;
 -
 -	b0->slen = newlen;
 -	b0->data[newlen] = (unsigned char) '\0';
 -
 -	return BSTR_OK;
 -}
 -
 -/*  int binsert (bstring b1, int pos, bstring b2, unsigned char fill)
 - *
 - *  Inserts the string b2 into b1 at position pos.  If the position pos is 
 - *  past the end of b1, then the character "fill" is appended as necessary to 
 - *  make up the gap between the end of b1 and pos.  Unlike bsetstr, binsert
 - *  does not allow b2 to be NULL.
 - */
 -int binsert (bstring b1, int pos, const_bstring b2, unsigned char fill) {
 -int d, l;
 -ptrdiff_t pd;
 -bstring aux = (bstring) b2;
 -
 -	if (pos < 0 || b1 == NULL || b2 == NULL || b1->slen < 0 || 
 -	    b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return BSTR_ERR;
 -
 -	/* Aliasing case */
 -	if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->mlen) {
 -		if (NULL == (aux = bstrcpy (b2))) return BSTR_ERR;
 -	}
 -
 -	/* Compute the two possible end pointers */
 -	d = b1->slen + aux->slen;
 -	l = pos + aux->slen;
 -	if ((d|l) < 0) return BSTR_ERR;
 -
 -	if (l > d) {
 -		/* Inserting past the end of the string */
 -		if (balloc (b1, l + 1) != BSTR_OK) {
 -			if (aux != b2) bdestroy (aux);
 -			return BSTR_ERR;
 -		}
 -		bstr__memset (b1->data + b1->slen, (int) fill, (size_t) (pos - b1->slen));
 -		b1->slen = l;
 -	} else {
 -		/* Inserting in the middle of the string */
 -		if (balloc (b1, d + 1) != BSTR_OK) {
 -			if (aux != b2) bdestroy (aux);
 -			return BSTR_ERR;
 -		}
 -		bBlockCopy (b1->data + l, b1->data + pos, d - l);
 -		b1->slen = d;
 -	}
 -	bBlockCopy (b1->data + pos, aux->data, aux->slen);
 -	b1->data[b1->slen] = (unsigned char) '\0';
 -	if (aux != b2) bdestroy (aux);
 -	return BSTR_OK;
 -}
 -
 -/*  int breplace (bstring b1, int pos, int len, bstring b2, 
 - *                unsigned char fill)
 - *
 - *  Replace a section of a string from pos for a length len with the string b2.
 - *  fill is used is pos > b1->slen.
 - */
 -int breplace (bstring b1, int pos, int len, const_bstring b2, 
 -			  unsigned char fill) {
 -int pl, ret;
 -ptrdiff_t pd;
 -bstring aux = (bstring) b2;
 -
 -	if (pos < 0 || len < 0 || (pl = pos + len) < 0 || b1 == NULL || 
 -	    b2 == NULL || b1->data == NULL || b2->data == NULL || 
 -	    b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen ||
 -	    b1->mlen <= 0) return BSTR_ERR;
 -
 -	/* Straddles the end? */
 -	if (pl >= b1->slen) {
 -		if ((ret = bsetstr (b1, pos, b2, fill)) < 0) return ret;
 -		if (pos + b2->slen < b1->slen) {
 -			b1->slen = pos + b2->slen;
 -			b1->data[b1->slen] = (unsigned char) '\0';
 -		}
 -		return ret;
 -	}
 -
 -	/* Aliasing case */
 -	if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->slen) {
 -		if (NULL == (aux = bstrcpy (b2))) return BSTR_ERR;
 -	}
 -
 -	if (aux->slen > len) {
 -		if (balloc (b1, b1->slen + aux->slen - len) != BSTR_OK) {
 -			if (aux != b2) bdestroy (aux);
 -			return BSTR_ERR;
 -		}
 -	}
 -
 -	if (aux->slen != len) bstr__memmove (b1->data + pos + aux->slen, b1->data + pos + len, b1->slen - (pos + len));
 -	bstr__memcpy (b1->data + pos, aux->data, aux->slen);
 -	b1->slen += aux->slen - len;
 -	b1->data[b1->slen] = (unsigned char) '\0';
 -	if (aux != b2) bdestroy (aux);
 -	return BSTR_OK;
 -}
 -
 -/*  
 - *  findreplaceengine is used to implement bfindreplace and 
 - *  bfindreplacecaseless. It works by breaking the three cases of
 - *  expansion, reduction and replacement, and solving each of these
 - *  in the most efficient way possible.
 - */
 -
 -typedef int (*instr_fnptr) (const_bstring s1, int pos, const_bstring s2);
 -
 -#define INITIAL_STATIC_FIND_INDEX_COUNT 32
 -
 -static int findreplaceengine (bstring b, const_bstring find, const_bstring repl, int pos, instr_fnptr instr) {
 -int i, ret, slen, mlen, delta, acc;
 -int * d;
 -int static_d[INITIAL_STATIC_FIND_INDEX_COUNT+1]; /* This +1 is unnecessary, but it shuts up LINT. */
 -ptrdiff_t pd;
 -bstring auxf = (bstring) find;
 -bstring auxr = (bstring) repl;
 -
 -	if (b == NULL || b->data == NULL || find == NULL ||
 -	    find->data == NULL || repl == NULL || repl->data == NULL || 
 -	    pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen || 
 -	    b->mlen <= 0 || b->slen < 0 || repl->slen < 0) return BSTR_ERR;
 -	if (pos > b->slen - find->slen) return BSTR_OK;
 -
 -	/* Alias with find string */
 -	pd = (ptrdiff_t) (find->data - b->data);
 -	if ((ptrdiff_t) (pos - find->slen) < pd && pd < (ptrdiff_t) b->slen) {
 -		if (NULL == (auxf = bstrcpy (find))) return BSTR_ERR;
 -	}
 -
 -	/* Alias with repl string */
 -	pd = (ptrdiff_t) (repl->data - b->data);
 -	if ((ptrdiff_t) (pos - repl->slen) < pd && pd < (ptrdiff_t) b->slen) {
 -		if (NULL == (auxr = bstrcpy (repl))) {
 -			if (auxf != find) bdestroy (auxf);
 -			return BSTR_ERR;
 -		}
 -	}
 -
 -	delta = auxf->slen - auxr->slen;
 -
 -	/* in-place replacement since find and replace strings are of equal 
 -	   length */
 -	if (delta == 0) {
 -		while ((pos = instr (b, pos, auxf)) >= 0) {
 -			bstr__memcpy (b->data + pos, auxr->data, auxr->slen);
 -			pos += auxf->slen;
 -		}
 -		if (auxf != find) bdestroy (auxf);
 -		if (auxr != repl) bdestroy (auxr);
 -		return BSTR_OK;
 -	}
 -
 -	/* shrinking replacement since auxf->slen > auxr->slen */
 -	if (delta > 0) {
 -		acc = 0;
 -
 -		while ((i = instr (b, pos, auxf)) >= 0) {
 -			if (acc && i > pos)
 -				bstr__memmove (b->data + pos - acc, b->data + pos, i - pos);
 -			if (auxr->slen)
 -				bstr__memcpy (b->data + i - acc, auxr->data, auxr->slen);
 -			acc += delta;
 -			pos = i + auxf->slen;
 -		}
 -
 -		if (acc) {
 -			i = b->slen;
 -			if (i > pos)
 -				bstr__memmove (b->data + pos - acc, b->data + pos, i - pos);
 -			b->slen -= acc;
 -			b->data[b->slen] = (unsigned char) '\0';
 -		}
 -
 -		if (auxf != find) bdestroy (auxf);
 -		if (auxr != repl) bdestroy (auxr);
 -		return BSTR_OK;
 -	}
 -
 -	/* expanding replacement since find->slen < repl->slen.  Its a lot 
 -	   more complicated.  This works by first finding all the matches and 
 -	   storing them to a growable array, then doing at most one resize of
 -	   the destination bstring and then performing the direct memory transfers
 -	   of the string segment pieces to form the final result. The growable 
 -	   array of matches uses a deferred doubling reallocing strategy.  What 
 -	   this means is that it starts as a reasonably fixed sized auto array in 
 -	   the hopes that many if not most cases will never need to grow this 
 -	   array.  But it switches as soon as the bounds of the array will be 
 -	   exceeded.  An extra find result is always appended to this array that
 -	   corresponds to the end of the destination string, so slen is checked
 -	   against mlen - 1 rather than mlen before resizing.
 -	*/
 -
 -	mlen = INITIAL_STATIC_FIND_INDEX_COUNT;
 -	d = (int *) static_d; /* Avoid malloc for trivial/initial cases */
 -	acc = slen = 0;
 -
 -	while ((pos = instr (b, pos, auxf)) >= 0) {
 -		if (slen >= mlen - 1) {
 -			int sl, *t;
 -
 -			mlen += mlen;
 -			sl = sizeof (int *) * mlen;
 -			if (static_d == d) d = NULL; /* static_d cannot be realloced */
 -			if (mlen <= 0 || sl < mlen || NULL == (t = (int *) bstr__realloc (d, sl))) {
 -				ret = BSTR_ERR;
 -				goto done;
 -			}
 -			if (NULL == d) bstr__memcpy (t, static_d, sizeof (static_d));
 -			d = t;
 -		}
 -		d[slen] = pos;
 -		slen++;
 -		acc -= delta;
 -		pos += auxf->slen;
 -		if (pos < 0 || acc < 0) {
 -			ret = BSTR_ERR;
 -			goto done;
 -		}
 -	}
 -	
 -	/* slen <= INITIAL_STATIC_INDEX_COUNT-1 or mlen-1 here. */
 -	d[slen] = b->slen;
 -
 -	if (BSTR_OK == (ret = balloc (b, b->slen + acc + 1))) {
 -		b->slen += acc;
 -		for (i = slen-1; i >= 0; i--) {
 -			int s, l;
 -			s = d[i] + auxf->slen;
 -			l = d[i+1] - s; /* d[slen] may be accessed here. */
 -			if (l) {
 -				bstr__memmove (b->data + s + acc, b->data + s, l);
 -			}
 -			if (auxr->slen) {
 -				bstr__memmove (b->data + s + acc - auxr->slen, 
 -				               auxr->data, auxr->slen);
 -			}
 -			acc += delta;		
 -		}
 -		b->data[b->slen] = (unsigned char) '\0';
 -	}
 -
 -	done:;
 -	if (static_d == d) d = NULL;
 -	bstr__free (d);
 -	if (auxf != find) bdestroy (auxf);
 -	if (auxr != repl) bdestroy (auxr);
 -	return ret;
 -}
 -
 -/*  int bfindreplace (bstring b, const_bstring find, const_bstring repl, 
 - *                    int pos)
 - *
 - *  Replace all occurrences of a find string with a replace string after a
 - *  given point in a bstring.
 - */
 -int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos) {
 -	return findreplaceengine (b, find, repl, pos, binstr);
 -}
 -
 -/*  int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, 
 - *                    int pos)
 - *
 - *  Replace all occurrences of a find string, ignoring case, with a replace 
 - *  string after a given point in a bstring.
 - */
 -int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos) {
 -	return findreplaceengine (b, find, repl, pos, binstrcaseless);
 -}
 -
 -/*  int binsertch (bstring b, int pos, int len, unsigned char fill)
 - *
 - *  Inserts the character fill repeatedly into b at position pos for a 
 - *  length len.  If the position pos is past the end of b, then the 
 - *  character "fill" is appended as necessary to make up the gap between the 
 - *  end of b and the position pos + len.
 - */
 -int binsertch (bstring b, int pos, int len, unsigned char fill) {
 -int d, l, i;
 -
 -	if (pos < 0 || b == NULL || b->slen < 0 || b->mlen < b->slen ||
 -	    b->mlen <= 0 || len < 0) return BSTR_ERR;
 -
 -	/* Compute the two possible end pointers */
 -	d = b->slen + len;
 -	l = pos + len;
 -	if ((d|l) < 0) return BSTR_ERR;
 -
 -	if (l > d) {
 -		/* Inserting past the end of the string */
 -		if (balloc (b, l + 1) != BSTR_OK) return BSTR_ERR;
 -		pos = b->slen;
 -		b->slen = l;
 -	} else {
 -		/* Inserting in the middle of the string */
 -		if (balloc (b, d + 1) != BSTR_OK) return BSTR_ERR;
 -		for (i = d - 1; i >= l; i--) {
 -			b->data[i] = b->data[i - len];
 -		}
 -		b->slen = d;
 -	}
 -
 -	for (i=pos; i < l; i++) b->data[i] = fill;
 -	b->data[b->slen] = (unsigned char) '\0';
 -	return BSTR_OK;
 -}
 -
 -/*  int bpattern (bstring b, int len)
 - *
 - *  Replicate the bstring, b in place, end to end repeatedly until it 
 - *  surpasses len characters, then chop the result to exactly len characters. 
 - *  This function operates in-place.  The function will return with BSTR_ERR 
 - *  if b is NULL or of length 0, otherwise BSTR_OK is returned.
 - */
 -int bpattern (bstring b, int len) {
 -int i, d;
 -
 -	d = blength (b);
 -	if (d <= 0 || len < 0 || balloc (b, len + 1) != BSTR_OK) return BSTR_ERR;
 -	if (len > 0) {
 -		if (d == 1) return bsetstr (b, len, NULL, b->data[0]);
 -		for (i = d; i < len; i++) b->data[i] = b->data[i - d];
 -	}
 -	b->data[len] = (unsigned char) '\0';
 -	b->slen = len;
 -	return BSTR_OK;
 -}
 -
 -#define BS_BUFF_SZ (1024)
 -
 -/*  int breada (bstring b, bNread readPtr, void * parm)
 - *
 - *  Use a finite buffer fread-like function readPtr to concatenate to the 
 - *  bstring b the entire contents of file-like source data in a roughly 
 - *  efficient way.
 - */
 -int breada (bstring b, bNread readPtr, void * parm) {
 -int i, l, n;
 -
 -	if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen ||
 -	    b->mlen <= 0 || readPtr == NULL) return BSTR_ERR;
 -
 -	i = b->slen;
 -	for (n=i+16; ; n += ((n < BS_BUFF_SZ) ? n : BS_BUFF_SZ)) {
 -		if (BSTR_OK != balloc (b, n + 1)) return BSTR_ERR;
 -		l = (int) readPtr ((void *) (b->data + i), 1, n - i, parm);
 -		i += l;
 -		b->slen = i;
 -		if (i < n) break;
 -	}
 -
 -	b->data[i] = (unsigned char) '\0';
 -	return BSTR_OK;
 -}
 -
 -/*  bstring bread (bNread readPtr, void * parm)
 - *
 - *  Use a finite buffer fread-like function readPtr to create a bstring 
 - *  filled with the entire contents of file-like source data in a roughly 
 - *  efficient way.
 - */
 -bstring bread (bNread readPtr, void * parm) {
 -bstring buff;
 -
 -	if (0 > breada (buff = bfromcstr (""), readPtr, parm)) {
 -		bdestroy (buff);
 -		return NULL;
 -	}
 -	return buff;
 -}
 -
 -/*  int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator)
 - *
 - *  Use an fgetc-like single character stream reading function (getcPtr) to 
 - *  obtain a sequence of characters which are concatenated to the end of the
 - *  bstring b.  The stream read is terminated by the passed in terminator 
 - *  parameter.
 - *
 - *  If getcPtr returns with a negative number, or the terminator character 
 - *  (which is appended) is read, then the stream reading is halted and the 
 - *  function returns with a partial result in b.  If there is an empty partial
 - *  result, 1 is returned.  If no characters are read, or there is some other 
 - *  detectable error, BSTR_ERR is returned.
 - */
 -int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator) {
 -int c, d, e;
 -
 -	if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen ||
 -	    b->mlen <= 0 || getcPtr == NULL) return BSTR_ERR;
 -	d = 0;
 -	e = b->mlen - 2;
 -
 -	while ((c = getcPtr (parm)) >= 0) {
 -		if (d > e) {
 -			b->slen = d;
 -			if (balloc (b, d + 2) != BSTR_OK) return BSTR_ERR;
 -			e = b->mlen - 2;
 -		}
 -		b->data[d] = (unsigned char) c;
 -		d++;
 -		if (c == terminator) break;
 -	}
 -
 -	b->data[d] = (unsigned char) '\0';
 -	b->slen = d;
 -
 -	return d == 0 && c < 0;
 -}
 -
 -/*  int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator)
 - *
 - *  Use an fgetc-like single character stream reading function (getcPtr) to 
 - *  obtain a sequence of characters which are concatenated to the end of the
 - *  bstring b.  The stream read is terminated by the passed in terminator 
 - *  parameter.
 - *
 - *  If getcPtr returns with a negative number, or the terminator character 
 - *  (which is appended) is read, then the stream reading is halted and the 
 - *  function returns with a partial result concatentated to b.  If there is 
 - *  an empty partial result, 1 is returned.  If no characters are read, or 
 - *  there is some other detectable error, BSTR_ERR is returned.
 - */
 -int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator) {
 -int c, d, e;
 -
 -	if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen ||
 -	    b->mlen <= 0 || getcPtr == NULL) return BSTR_ERR;
 -	d = b->slen;
 -	e = b->mlen - 2;
 -
 -	while ((c = getcPtr (parm)) >= 0) {
 -		if (d > e) {
 -			b->slen = d;
 -			if (balloc (b, d + 2) != BSTR_OK) return BSTR_ERR;
 -			e = b->mlen - 2;
 -		}
 -		b->data[d] = (unsigned char) c;
 -		d++;
 -		if (c == terminator) break;
 -	}
 -
 -	b->data[d] = (unsigned char) '\0';
 -	b->slen = d;
 -
 -	return d == 0 && c < 0;
 -}
 -
 -/*  bstring bgets (bNgetc getcPtr, void * parm, char terminator)
 - *
 - *  Use an fgetc-like single character stream reading function (getcPtr) to 
 - *  obtain a sequence of characters which are concatenated into a bstring.  
 - *  The stream read is terminated by the passed in terminator function.
 - *
 - *  If getcPtr returns with a negative number, or the terminator character 
 - *  (which is appended) is read, then the stream reading is halted and the 
 - *  result obtained thus far is returned.  If no characters are read, or 
 - *  there is some other detectable error, NULL is returned.
 - */
 -bstring bgets (bNgetc getcPtr, void * parm, char terminator) {
 -bstring buff;
 -
 -	if (0 > bgetsa (buff = bfromcstr (""), getcPtr, parm, terminator) || 0 >= buff->slen) {
 -		bdestroy (buff);
 -		buff = NULL;
 -	}
 -	return buff;
 -}
 -
 -struct bStream {
 -	bstring buff;		/* Buffer for over-reads */
 -	void * parm;		/* The stream handle for core stream */
 -	bNread readFnPtr;	/* fread compatible fnptr for core stream */
 -	int isEOF;		/* track file's EOF state */
 -	int maxBuffSz;
 -};
 -
 -/*  struct bStream * bsopen (bNread readPtr, void * parm)
 - *
 - *  Wrap a given open stream (described by a fread compatible function 
 - *  pointer and stream handle) into an open bStream suitable for the bstring 
 - *  library streaming functions.
 - */
 -struct bStream * bsopen (bNread readPtr, void * parm) {
 -struct bStream * s;
 -
 -	if (readPtr == NULL) return NULL;
 -	s = (struct bStream *) bstr__alloc (sizeof (struct bStream));
 -	if (s == NULL) return NULL;
 -	s->parm = parm;
 -	s->buff = bfromcstr ("");
 -	s->readFnPtr = readPtr;
 -	s->maxBuffSz = BS_BUFF_SZ;
 -	s->isEOF = 0;
 -	return s;
 -}
 -
 -/*  int bsbufflength (struct bStream * s, int sz)
 - *
 - *  Set the length of the buffer used by the bStream.  If sz is zero, the 
 - *  length is not set.  This function returns with the previous length.
 - */
 -int bsbufflength (struct bStream * s, int sz) {
 -int oldSz;
 -	if (s == NULL || sz < 0) return BSTR_ERR;
 -	oldSz = s->maxBuffSz;
 -	if (sz > 0) s->maxBuffSz = sz;
 -	return oldSz;
 -}
 -
 -int bseof (const struct bStream * s) {
 -	if (s == NULL || s->readFnPtr == NULL) return BSTR_ERR;
 -	return s->isEOF && (s->buff->slen == 0);
 -}
 -
 -/*  void * bsclose (struct bStream * s)
 - *
 - *  Close the bStream, and return the handle to the stream that was originally
 - *  used to open the given stream.
 - */
 -void * bsclose (struct bStream * s) {
 -void * parm;
 -	if (s == NULL) return NULL;
 -	s->readFnPtr = NULL;
 -	if (s->buff) bdestroy (s->buff);
 -	s->buff = NULL;
 -	parm = s->parm;
 -	s->parm = NULL;
 -	s->isEOF = 1;
 -	bstr__free (s);
 -	return parm;
 -}
 -
 -/*  int bsreadlna (bstring r, struct bStream * s, char terminator)
 - *
 - *  Read a bstring terminated by the terminator character or the end of the
 - *  stream from the bStream (s) and return it into the parameter r.  This 
 - *  function may read additional characters from the core stream that are not 
 - *  returned, but will be retained for subsequent read operations.
 - */
 -int bsreadlna (bstring r, struct bStream * s, char terminator) {
 -int i, l, ret, rlo;
 -char * b;
 -struct tagbstring x;
 -
 -	if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 ||
 -	    r->slen < 0 || r->mlen < r->slen) return BSTR_ERR;
 -	l = s->buff->slen;
 -	if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
 -	b = (char *) s->buff->data;
 -	x.data = (unsigned char *) b;
 -
 -	/* First check if the current buffer holds the terminator */
 -	b[l] = terminator; /* Set sentinel */
 -	for (i=0; b[i] != terminator; i++) ;
 -	if (i < l) {
 -		x.slen = i + 1;
 -		ret = bconcat (r, &x);
 -		s->buff->slen = l;
 -		if (BSTR_OK == ret) bdelete (s->buff, 0, i + 1);
 -		return BSTR_OK;
 -	}
 -
 -	rlo = r->slen;
 -
 -	/* If not then just concatenate the entire buffer to the output */
 -	x.slen = l;
 -	if (BSTR_OK != bconcat (r, &x)) return BSTR_ERR;
 -
 -	/* Perform direct in-place reads into the destination to allow for
 -	   the minimum of data-copies */
 -	for (;;) {
 -		if (BSTR_OK != balloc (r, r->slen + s->maxBuffSz + 1)) return BSTR_ERR;
 -		b = (char *) (r->data + r->slen);
 -		l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm);
 -		if (l <= 0) {
 -			r->data[r->slen] = (unsigned char) '\0';
 -			s->buff->slen = 0;
 -			s->isEOF = 1;
 -			/* If nothing was read return with an error message */
 -			return BSTR_ERR & -(r->slen == rlo);
 -		}
 -		b[l] = terminator; /* Set sentinel */
 -		for (i=0; b[i] != terminator; i++) ;
 -		if (i < l) break;
 -		r->slen += l;
 -	}
 -
 -	/* Terminator found, push over-read back to buffer */
 -	i++;
 -	r->slen += i;
 -	s->buff->slen = l - i;
 -	bstr__memcpy (s->buff->data, b + i, l - i);
 -	r->data[r->slen] = (unsigned char) '\0';
 -	return BSTR_OK;
 -}
 -
 -/*  int bsreadlnsa (bstring r, struct bStream * s, bstring term)
 - *
 - *  Read a bstring terminated by any character in the term string or the end 
 - *  of the stream from the bStream (s) and return it into the parameter r.  
 - *  This function may read additional characters from the core stream that 
 - *  are not returned, but will be retained for subsequent read operations.
 - */
 -int bsreadlnsa (bstring r, struct bStream * s, const_bstring term) {
 -int i, l, ret, rlo;
 -unsigned char * b;
 -struct tagbstring x;
 -struct charField cf;
 -
 -	if (s == NULL || s->buff == NULL || r == NULL || term == NULL ||
 -	    term->data == NULL || r->mlen <= 0 || r->slen < 0 ||
 -	    r->mlen < r->slen) return BSTR_ERR;
 -	if (term->slen == 1) return bsreadlna (r, s, term->data[0]);
 -	if (term->slen < 1 || buildCharField (&cf, term)) return BSTR_ERR;
 -
 -	l = s->buff->slen;
 -	if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
 -	b = (unsigned char *) s->buff->data;
 -	x.data = b;
 -
 -	/* First check if the current buffer holds the terminator */
 -	b[l] = term->data[0]; /* Set sentinel */
 -	for (i=0; !testInCharField (&cf, b[i]); i++) ;
 -	if (i < l) {
 -		x.slen = i + 1;
 -		ret = bconcat (r, &x);
 -		s->buff->slen = l;
 -		if (BSTR_OK == ret) bdelete (s->buff, 0, i + 1);
 -		return BSTR_OK;
 -	}
 -
 -	rlo = r->slen;
 -
 -	/* If not then just concatenate the entire buffer to the output */
 -	x.slen = l;
 -	if (BSTR_OK != bconcat (r, &x)) return BSTR_ERR;
 -
 -	/* Perform direct in-place reads into the destination to allow for
 -	   the minimum of data-copies */
 -	for (;;) {
 -		if (BSTR_OK != balloc (r, r->slen + s->maxBuffSz + 1)) return BSTR_ERR;
 -		b = (unsigned char *) (r->data + r->slen);
 -		l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm);
 -		if (l <= 0) {
 -			r->data[r->slen] = (unsigned char) '\0';
 -			s->buff->slen = 0;
 -			s->isEOF = 1;
 -			/* If nothing was read return with an error message */
 -			return BSTR_ERR & -(r->slen == rlo);
 -		}
 -
 -		b[l] = term->data[0]; /* Set sentinel */
 -		for (i=0; !testInCharField (&cf, b[i]); i++) ;
 -		if (i < l) break;
 -		r->slen += l;
 -	}
 -
 -	/* Terminator found, push over-read back to buffer */
 -	i++;
 -	r->slen += i;
 -	s->buff->slen = l - i;
 -	bstr__memcpy (s->buff->data, b + i, l - i);
 -	r->data[r->slen] = (unsigned char) '\0';
 -	return BSTR_OK;
 -}
 -
 -/*  int bsreada (bstring r, struct bStream * s, int n)
 - *
 - *  Read a bstring of length n (or, if it is fewer, as many bytes as is 
 - *  remaining) from the bStream.  This function may read additional 
 - *  characters from the core stream that are not returned, but will be 
 - *  retained for subsequent read operations.  This function will not read
 - *  additional characters from the core stream beyond virtual stream pointer.
 - */
 -int bsreada (bstring r, struct bStream * s, int n) {
 -int l, ret, orslen;
 -char * b;
 -struct tagbstring x;
 -
 -	if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0
 -	 || r->slen < 0 || r->mlen < r->slen || n <= 0) return BSTR_ERR;
 -
 -	n += r->slen;
 -	if (n <= 0) return BSTR_ERR;
 -
 -	l = s->buff->slen;
 -
 -	orslen = r->slen;
 -
 -	if (0 == l) {
 -		if (s->isEOF) return BSTR_ERR;
 -		if (r->mlen > n) {
 -			l = (int) s->readFnPtr (r->data + r->slen, 1, n - r->slen, s->parm);
 -			if (0 >= l || l > n - r->slen) {
 -				s->isEOF = 1;
 -				return BSTR_ERR;
 -			}
 -			r->slen += l;
 -			r->data[r->slen] = (unsigned char) '\0';
 -			return 0;
 -		}
 -	}
 -
 -	if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
 -	b = (char *) s->buff->data;
 -	x.data = (unsigned char *) b;
 -
 -	do {
 -		if (l + r->slen >= n) {
 -			x.slen = n - r->slen;
 -			ret = bconcat (r, &x);
 -			s->buff->slen = l;
 -			if (BSTR_OK == ret) bdelete (s->buff, 0, x.slen);
 -			return BSTR_ERR & -(r->slen == orslen);
 -		}
 -
 -		x.slen = l;
 -		if (BSTR_OK != bconcat (r, &x)) break;
 -
 -		l = n - r->slen;
 -		if (l > s->maxBuffSz) l = s->maxBuffSz;
 -
 -		l = (int) s->readFnPtr (b, 1, l, s->parm);
 -
 -	} while (l > 0);
 -	if (l < 0) l = 0;
 -	if (l == 0) s->isEOF = 1;
 -	s->buff->slen = l;
 -	return BSTR_ERR & -(r->slen == orslen);
 -}
 -
 -/*  int bsreadln (bstring r, struct bStream * s, char terminator)
 - *
 - *  Read a bstring terminated by the terminator character or the end of the
 - *  stream from the bStream (s) and return it into the parameter r.  This 
 - *  function may read additional characters from the core stream that are not 
 - *  returned, but will be retained for subsequent read operations.
 - */
 -int bsreadln (bstring r, struct bStream * s, char terminator) {
 -	if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0)
 -		return BSTR_ERR;
 -	if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
 -	r->slen = 0;
 -	return bsreadlna (r, s, terminator);
 -}
 -
 -/*  int bsreadlns (bstring r, struct bStream * s, bstring term)
 - *
 - *  Read a bstring terminated by any character in the term string or the end 
 - *  of the stream from the bStream (s) and return it into the parameter r.  
 - *  This function may read additional characters from the core stream that 
 - *  are not returned, but will be retained for subsequent read operations.
 - */
 -int bsreadlns (bstring r, struct bStream * s, const_bstring term) {
 -	if (s == NULL || s->buff == NULL || r == NULL || term == NULL 
 -	 || term->data == NULL || r->mlen <= 0) return BSTR_ERR;
 -	if (term->slen == 1) return bsreadln (r, s, term->data[0]);
 -	if (term->slen < 1) return BSTR_ERR;
 -	if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
 -	r->slen = 0;
 -	return bsreadlnsa (r, s, term);
 -}
 -
 -/*  int bsread (bstring r, struct bStream * s, int n)
 - *
 - *  Read a bstring of length n (or, if it is fewer, as many bytes as is 
 - *  remaining) from the bStream.  This function may read additional 
 - *  characters from the core stream that are not returned, but will be 
 - *  retained for subsequent read operations.  This function will not read
 - *  additional characters from the core stream beyond virtual stream pointer.
 - */
 -int bsread (bstring r, struct bStream * s, int n) {
 -	if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0
 -	 || n <= 0) return BSTR_ERR;
 -	if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
 -	r->slen = 0;
 -	return bsreada (r, s, n);
 -}
 -
 -/*  int bsunread (struct bStream * s, const_bstring b)
 - *
 - *  Insert a bstring into the bStream at the current position.  These 
 - *  characters will be read prior to those that actually come from the core 
 - *  stream.
 - */
 -int bsunread (struct bStream * s, const_bstring b) {
 -	if (s == NULL || s->buff == NULL) return BSTR_ERR;
 -	return binsert (s->buff, 0, b, (unsigned char) '?');
 -}
 -
 -/*  int bspeek (bstring r, const struct bStream * s)
 - *
 - *  Return the currently buffered characters from the bStream that will be 
 - *  read prior to reads from the core stream.
 - */
 -int bspeek (bstring r, const struct bStream * s) {
 -	if (s == NULL || s->buff == NULL) return BSTR_ERR;
 -	return bassign (r, s->buff);
 -}
 -
 -/*  bstring bjoin (const struct bstrList * bl, const_bstring sep);
 - *
 - *  Join the entries of a bstrList into one bstring by sequentially 
 - *  concatenating them with the sep string in between.  If there is an error 
 - *  NULL is returned, otherwise a bstring with the correct result is returned.
 - */
 -bstring bjoin (const struct bstrList * bl, const_bstring sep) {
 -bstring b;
 -int i, c, v;
 -
 -	if (bl == NULL || bl->qty < 0) return NULL;
 -	if (sep != NULL && (sep->slen < 0 || sep->data == NULL)) return NULL;
 -
 -	for (i = 0, c = 1; i < bl->qty; i++) {
 -		v = bl->entry[i]->slen;
 -		if (v < 0) return NULL;	/* Invalid input */
 -		c += v;
 -		if (c < 0) return NULL;	/* Wrap around ?? */
 -	}
 -
 -	if (sep != NULL) c += (bl->qty - 1) * sep->slen;
 -
 -	b = (bstring) bstr__alloc (sizeof (struct tagbstring));
 -	if (NULL == b) return NULL; /* Out of memory */
 -	b->data = (unsigned char *) bstr__alloc (c);
 -	if (b->data == NULL) {
 -		bstr__free (b);
 -		return NULL;
 -	}
 -
 -	b->mlen = c;
 -	b->slen = c-1;
 -
 -	for (i = 0, c = 0; i < bl->qty; i++) {
 -		if (i > 0 && sep != NULL) {
 -			bstr__memcpy (b->data + c, sep->data, sep->slen);
 -			c += sep->slen;
 -		}
 -		v = bl->entry[i]->slen;
 -		bstr__memcpy (b->data + c, bl->entry[i]->data, v);
 -		c += v;
 -	}
 -	b->data[c] = (unsigned char) '\0';
 -	return b;
 -}
 -
 -#define BSSSC_BUFF_LEN (256)
 -
 -/*  int bssplitscb (struct bStream * s, const_bstring splitStr, 
 - *	int (* cb) (void * parm, int ofs, const_bstring entry), void * parm)
 - *
 - *  Iterate the set of disjoint sequential substrings read from a stream 
 - *  divided by any of the characters in splitStr.  An empty splitStr causes 
 - *  the whole stream to be iterated once.
 - *
 - *  Note: At the point of calling the cb function, the bStream pointer is 
 - *  pointed exactly at the position right after having read the split 
 - *  character.  The cb function can act on the stream by causing the bStream
 - *  pointer to move, and bssplitscb will continue by starting the next split
 - *  at the position of the pointer after the return from cb.
 - *
 - *  However, if the cb causes the bStream s to be destroyed then the cb must
 - *  return with a negative value, otherwise bssplitscb will continue in an 
 - *  undefined manner.
 - */
 -int bssplitscb (struct bStream * s, const_bstring splitStr, 
 -	int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) {
 -struct charField chrs;
 -bstring buff;
 -int i, p, ret;
 -
 -	if (cb == NULL || s == NULL || s->readFnPtr == NULL 
 -	 || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
 -
 -	if (NULL == (buff = bfromcstr (""))) return BSTR_ERR;
 -
 -	if (splitStr->slen == 0) {
 -		while (bsreada (buff, s, BSSSC_BUFF_LEN) >= 0) ;
 -		if ((ret = cb (parm, 0, buff)) > 0) 
 -			ret = 0;
 -	} else {
 -		buildCharField (&chrs, splitStr);
 -		ret = p = i = 0;
 -		for (;;) {
 -			if (i >= buff->slen) {
 -				bsreada (buff, s, BSSSC_BUFF_LEN);
 -				if (i >= buff->slen) {
 -					if (0 < (ret = cb (parm, p, buff))) ret = 0;
 -					break;
 -				}
 -			}
 -			if (testInCharField (&chrs, buff->data[i])) {
 -				struct tagbstring t;
 -				unsigned char c;
 -
 -				blk2tbstr (t, buff->data + i + 1, buff->slen - (i + 1));
 -				if ((ret = bsunread (s, &t)) < 0) break;
 -				buff->slen = i;
 -				c = buff->data[i];
 -				buff->data[i] = (unsigned char) '\0';
 -				if ((ret = cb (parm, p, buff)) < 0) break;
 -				buff->data[i] = c;
 -				buff->slen = 0;
 -				p += i + 1;
 -				i = -1;
 -			}
 -			i++;
 -		}
 -	}
 -
 -	bdestroy (buff);
 -	return ret;
 -}
 -
 -/*  int bssplitstrcb (struct bStream * s, const_bstring splitStr, 
 - *	int (* cb) (void * parm, int ofs, const_bstring entry), void * parm)
 - *
 - *  Iterate the set of disjoint sequential substrings read from a stream 
 - *  divided by the entire substring splitStr.  An empty splitStr causes 
 - *  each character of the stream to be iterated.
 - *
 - *  Note: At the point of calling the cb function, the bStream pointer is 
 - *  pointed exactly at the position right after having read the split 
 - *  character.  The cb function can act on the stream by causing the bStream
 - *  pointer to move, and bssplitscb will continue by starting the next split
 - *  at the position of the pointer after the return from cb.
 - *
 - *  However, if the cb causes the bStream s to be destroyed then the cb must
 - *  return with a negative value, otherwise bssplitscb will continue in an 
 - *  undefined manner.
 - */
 -int bssplitstrcb (struct bStream * s, const_bstring splitStr, 
 -	int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) {
 -bstring buff;
 -int i, p, ret;
 -
 -	if (cb == NULL || s == NULL || s->readFnPtr == NULL 
 -	 || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
 -
 -	if (splitStr->slen == 1) return bssplitscb (s, splitStr, cb, parm);
 -
 -	if (NULL == (buff = bfromcstr (""))) return BSTR_ERR;
 -
 -	if (splitStr->slen == 0) {
 -		for (i=0; bsreada (buff, s, BSSSC_BUFF_LEN) >= 0; i++) {
 -			if ((ret = cb (parm, 0, buff)) < 0) {
 -				bdestroy (buff);
 -				return ret;
 -			}
 -			buff->slen = 0;
 -		}
 -		return BSTR_OK;
 -	} else {
 -		ret = p = i = 0;
 -		for (i=p=0;;) {
 -			if ((ret = binstr (buff, 0, splitStr)) >= 0) {
 -				struct tagbstring t;
 -				blk2tbstr (t, buff->data, ret);
 -				i = ret + splitStr->slen;
 -				if ((ret = cb (parm, p, &t)) < 0) break;
 -				p += i;
 -				bdelete (buff, 0, i);
 -			} else {
 -				bsreada (buff, s, BSSSC_BUFF_LEN);
 -				if (bseof (s)) {
 -					if ((ret = cb (parm, p, buff)) > 0) ret = 0;
 -					break;
 -				}
 -			}
 -		}
 -	}
 -
 -	bdestroy (buff);
 -	return ret;
 -}
 -
 -/*  int bstrListCreate (void)
 - *
 - *  Create a bstrList.
 - */
 -struct bstrList * bstrListCreate (void) {
 -struct bstrList * sl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
 -	if (sl) {
 -		sl->entry = (bstring *) bstr__alloc (1*sizeof (bstring));
 -		if (!sl->entry) {
 -			bstr__free (sl);
 -			sl = NULL;
 -		} else {
 -			sl->qty = 0;
 -			sl->mlen = 1;
 -		}
 -	}
 -	return sl;
 -}
 -
 -/*  int bstrListDestroy (struct bstrList * sl)
 - *
 - *  Destroy a bstrList that has been created by bsplit, bsplits or bstrListCreate.
 - */
 -int bstrListDestroy (struct bstrList * sl) {
 -int i;
 -	if (sl == NULL || sl->qty < 0) return BSTR_ERR;
 -	for (i=0; i < sl->qty; i++) {
 -		if (sl->entry[i]) {
 -			bdestroy (sl->entry[i]);
 -			sl->entry[i] = NULL;
 -		}
 -	}
 -	sl->qty  = -1;
 -	sl->mlen = -1;
 -	bstr__free (sl->entry);
 -	sl->entry = NULL;
 -	bstr__free (sl);
 -	return BSTR_OK;
 -}
 -
 -/*  int bstrListAlloc (struct bstrList * sl, int msz)
 - *
 - *  Ensure that there is memory for at least msz number of entries for the
 - *  list.
 - */
 -int bstrListAlloc (struct bstrList * sl, int msz) {
 -bstring * l;
 -int smsz;
 -size_t nsz;
 -	if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return BSTR_ERR;
 -	if (sl->mlen >= msz) return BSTR_OK;
 -	smsz = snapUpSize (msz);
 -	nsz = ((size_t) smsz) * sizeof (bstring);
 -	if (nsz < (size_t) smsz) return BSTR_ERR;
 -	l = (bstring *) bstr__realloc (sl->entry, nsz);
 -	if (!l) {
 -		smsz = msz;
 -		nsz = ((size_t) smsz) * sizeof (bstring);
 -		l = (bstring *) bstr__realloc (sl->entry, nsz);
 -		if (!l) return BSTR_ERR;
 -	}
 -	sl->mlen = smsz;
 -	sl->entry = l;
 -	return BSTR_OK;
 -}
 -
 -/*  int bstrListAllocMin (struct bstrList * sl, int msz)
 - *
 - *  Try to allocate the minimum amount of memory for the list to include at
 - *  least msz entries or sl->qty whichever is greater.
 - */
 -int bstrListAllocMin (struct bstrList * sl, int msz) {
 -bstring * l;
 -size_t nsz;
 -	if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return BSTR_ERR;
 -	if (msz < sl->qty) msz = sl->qty;
 -	if (sl->mlen == msz) return BSTR_OK;
 -	nsz = ((size_t) msz) * sizeof (bstring);
 -	if (nsz < (size_t) msz) return BSTR_ERR;
 -	l = (bstring *) bstr__realloc (sl->entry, nsz);
 -	if (!l) return BSTR_ERR;
 -	sl->mlen = msz;
 -	sl->entry = l;
 -	return BSTR_OK;
 -}
 -
 -/*  int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
 - *	int (* cb) (void * parm, int ofs, int len), void * parm)
 - *
 - *  Iterate the set of disjoint sequential substrings over str divided by the
 - *  character in splitChar.
 - *
 - *  Note: Non-destructive modification of str from within the cb function 
 - *  while performing this split is not undefined.  bsplitcb behaves in 
 - *  sequential lock step with calls to cb.  I.e., after returning from a cb 
 - *  that return a non-negative integer, bsplitcb continues from the position 
 - *  1 character after the last detected split character and it will halt 
 - *  immediately if the length of str falls below this point.  However, if the 
 - *  cb function destroys str, then it *must* return with a negative value, 
 - *  otherwise bsplitcb will continue in an undefined manner.
 - */
 -int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
 -	int (* cb) (void * parm, int ofs, int len), void * parm) {
 -int i, p, ret;
 -
 -	if (cb == NULL || str == NULL || pos < 0 || pos > str->slen) 
 -		return BSTR_ERR;
 -
 -	p = pos;
 -	do {
 -		for (i=p; i < str->slen; i++) {
 -			if (str->data[i] == splitChar) break;
 -		}
 -		if ((ret = cb (parm, p, i - p)) < 0) return ret;
 -		p = i + 1;
 -	} while (p <= str->slen);
 -	return BSTR_OK;
 -}
 -
 -/*  int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
 - *	int (* cb) (void * parm, int ofs, int len), void * parm)
 - *
 - *  Iterate the set of disjoint sequential substrings over str divided by any 
 - *  of the characters in splitStr.  An empty splitStr causes the whole str to
 - *  be iterated once.
 - *
 - *  Note: Non-destructive modification of str from within the cb function 
 - *  while performing this split is not undefined.  bsplitscb behaves in 
 - *  sequential lock step with calls to cb.  I.e., after returning from a cb 
 - *  that return a non-negative integer, bsplitscb continues from the position 
 - *  1 character after the last detected split character and it will halt 
 - *  immediately if the length of str falls below this point.  However, if the 
 - *  cb function destroys str, then it *must* return with a negative value, 
 - *  otherwise bsplitscb will continue in an undefined manner.
 - */
 -int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
 -	int (* cb) (void * parm, int ofs, int len), void * parm) {
 -struct charField chrs;
 -int i, p, ret;
 -
 -	if (cb == NULL || str == NULL || pos < 0 || pos > str->slen 
 -	 || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
 -	if (splitStr->slen == 0) {
 -		if ((ret = cb (parm, 0, str->slen)) > 0) ret = 0;
 -		return ret;
 -	}
 -
 -	if (splitStr->slen == 1) 
 -		return bsplitcb (str, splitStr->data[0], pos, cb, parm);
 -
 -	buildCharField (&chrs, splitStr);
 -
 -	p = pos;
 -	do {
 -		for (i=p; i < str->slen; i++) {
 -			if (testInCharField (&chrs, str->data[i])) break;
 -		}
 -		if ((ret = cb (parm, p, i - p)) < 0) return ret;
 -		p = i + 1;
 -	} while (p <= str->slen);
 -	return BSTR_OK;
 -}
 -
 -/*  int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
 - *	int (* cb) (void * parm, int ofs, int len), void * parm)
 - *
 - *  Iterate the set of disjoint sequential substrings over str divided by the 
 - *  substring splitStr.  An empty splitStr causes the whole str to be 
 - *  iterated once.
 - *
 - *  Note: Non-destructive modification of str from within the cb function 
 - *  while performing this split is not undefined.  bsplitstrcb behaves in 
 - *  sequential lock step with calls to cb.  I.e., after returning from a cb 
 - *  that return a non-negative integer, bsplitscb continues from the position 
 - *  1 character after the last detected split character and it will halt 
 - *  immediately if the length of str falls below this point.  However, if the 
 - *  cb function destroys str, then it *must* return with a negative value, 
 - *  otherwise bsplitscb will continue in an undefined manner.
 - */
 -int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
 -	int (* cb) (void * parm, int ofs, int len), void * parm) {
 -int i, p, ret;
 -
 -	if (cb == NULL || str == NULL || pos < 0 || pos > str->slen 
 -	 || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
 -
 -	if (0 == splitStr->slen) {
 -		for (i=pos; i < str->slen; i++) {
 -			if ((ret = cb (parm, i, 1)) < 0) return ret;
 -		}
 -		return BSTR_OK;
 -	}
 -
 -	if (splitStr->slen == 1) 
 -		return bsplitcb (str, splitStr->data[0], pos, cb, parm);
 -
 -	for (i=p=pos; i <= str->slen - splitStr->slen; i++) {
 -		if (0 == bstr__memcmp (splitStr->data, str->data + i, splitStr->slen)) {
 -			if ((ret = cb (parm, p, i - p)) < 0) return ret;
 -			i += splitStr->slen;
 -			p = i;
 -		}
 -	}
 -	if ((ret = cb (parm, p, str->slen - p)) < 0) return ret;
 -	return BSTR_OK;
 -}
 -
 -struct genBstrList {
 -	bstring b;
 -	struct bstrList * bl;
 -};
 -
 -static int bscb (void * parm, int ofs, int len) {
 -struct genBstrList * g = (struct genBstrList *) parm;
 -	if (g->bl->qty >= g->bl->mlen) {
 -		int mlen = g->bl->mlen * 2;
 -		bstring * tbl;
 -
 -		while (g->bl->qty >= mlen) {
 -			if (mlen < g->bl->mlen) return BSTR_ERR;
 -			mlen += mlen;
 -		}
 -
 -		tbl = (bstring *) bstr__realloc (g->bl->entry, sizeof (bstring) * mlen);
 -		if (tbl == NULL) return BSTR_ERR;
 -
 -		g->bl->entry = tbl;
 -		g->bl->mlen = mlen;
 -	}
 -
 -	g->bl->entry[g->bl->qty] = bmidstr (g->b, ofs, len);
 -	g->bl->qty++;
 -	return BSTR_OK;
 -}
 -
 -/*  struct bstrList * bsplit (const_bstring str, unsigned char splitChar)
 - *
 - *  Create an array of sequential substrings from str divided by the character
 - *  splitChar.  
 - */
 -struct bstrList * bsplit (const_bstring str, unsigned char splitChar) {
 -struct genBstrList g;
 -
 -	if (str == NULL || str->data == NULL || str->slen < 0) return NULL;
 -
 -	g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
 -	if (g.bl == NULL) return NULL;
 -	g.bl->mlen = 4;
 -	g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring));
 -	if (NULL == g.bl->entry) {
 -		bstr__free (g.bl);
 -		return NULL;
 -	}
 -
 -	g.b = (bstring) str;
 -	g.bl->qty = 0;
 -	if (bsplitcb (str, splitChar, 0, bscb, &g) < 0) {
 -		bstrListDestroy (g.bl);
 -		return NULL;
 -	}
 -	return g.bl;
 -}
 -
 -/*  struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr)
 - *
 - *  Create an array of sequential substrings from str divided by the entire
 - *  substring splitStr.
 - */
 -struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr) {
 -struct genBstrList g;
 -
 -	if (str == NULL || str->data == NULL || str->slen < 0) return NULL;
 -
 -	g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
 -	if (g.bl == NULL) return NULL;
 -	g.bl->mlen = 4;
 -	g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring));
 -	if (NULL == g.bl->entry) {
 -		bstr__free (g.bl);
 -		return NULL;
 -	}
 -
 -	g.b = (bstring) str;
 -	g.bl->qty = 0;
 -	if (bsplitstrcb (str, splitStr, 0, bscb, &g) < 0) {
 -		bstrListDestroy (g.bl);
 -		return NULL;
 -	}
 -	return g.bl;
 -}
 -
 -/*  struct bstrList * bsplits (const_bstring str, bstring splitStr)
 - *
 - *  Create an array of sequential substrings from str divided by any of the 
 - *  characters in splitStr.  An empty splitStr causes a single entry bstrList
 - *  containing a copy of str to be returned.
 - */
 -struct bstrList * bsplits (const_bstring str, const_bstring splitStr) {
 -struct genBstrList g;
 -
 -	if (     str == NULL ||      str->slen < 0 ||      str->data == NULL ||
 -	    splitStr == NULL || splitStr->slen < 0 || splitStr->data == NULL)
 -		return NULL;
 -
 -	g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
 -	if (g.bl == NULL) return NULL;
 -	g.bl->mlen = 4;
 -	g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring));
 -	if (NULL == g.bl->entry) {
 -		bstr__free (g.bl);
 -		return NULL;
 -	}
 -	g.b = (bstring) str;
 -	g.bl->qty = 0;
 -
 -	if (bsplitscb (str, splitStr, 0, bscb, &g) < 0) {
 -		bstrListDestroy (g.bl);
 -		return NULL;
 -	}
 -	return g.bl;
 -}
 -
 -#if defined (__TURBOC__) && !defined (__BORLANDC__)
 -# ifndef BSTRLIB_NOVSNP
 -#  define BSTRLIB_NOVSNP
 -# endif
 -#endif
 -
 -/* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */
 -#if defined(__WATCOMC__) || defined(_MSC_VER)
 -#define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);}
 -#else
 -#ifdef BSTRLIB_NOVSNP
 -/* This is just a hack.  If you are using a system without a vsnprintf, it is 
 -   not recommended that bformat be used at all. */
 -#define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;}
 -#define START_VSNBUFF (256)
 -#else
 -
 -#if defined(__GNUC__) && !defined(__APPLE__)
 -/* Something is making gcc complain about this prototype not being here, so 
 -   I've just gone ahead and put it in. */
 -extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg);
 -#endif
 -
 -#define exvsnprintf(r,b,n,f,a) {r = vsnprintf (b,n,f,a);}
 -#endif
 -#endif
 -
 -#if !defined (BSTRLIB_NOVSNP)
 -
 -#ifndef START_VSNBUFF
 -#define START_VSNBUFF (16)
 -#endif
 -
 -/* On IRIX vsnprintf returns n-1 when the operation would overflow the target 
 -   buffer, WATCOM and MSVC both return -1, while C99 requires that the 
 -   returned value be exactly what the length would be if the buffer would be
 -   large enough.  This leads to the idea that if the return value is larger 
 -   than n, then changing n to the return value will reduce the number of
 -   iterations required. */
 -
 -/*  int bformata (bstring b, const char * fmt, ...)
 - *
 - *  After the first parameter, it takes the same parameters as printf (), but 
 - *  rather than outputting results to stdio, it appends the results to 
 - *  a bstring which contains what would have been output. Note that if there 
 - *  is an early generation of a '\0' character, the bstring will be truncated 
 - *  to this end point.
 - */
 -int bformata (bstring b, const char * fmt, ...) {
 -va_list arglist;
 -bstring buff;
 -int n, r;
 -
 -	if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 
 -	 || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR;
 -
 -	/* Since the length is not determinable beforehand, a search is
 -	   performed using the truncating "vsnprintf" call (to avoid buffer
 -	   overflows) on increasing potential sizes for the output result. */
 -
 -	if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF;
 -	if (NULL == (buff = bfromcstralloc (n + 2, ""))) {
 -		n = 1;
 -		if (NULL == (buff = bfromcstralloc (n + 2, ""))) return BSTR_ERR;
 -	}
 -
 -	for (;;) {
 -		va_start (arglist, fmt);
 -		exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist);
 -		va_end (arglist);
 -
 -		buff->data[n] = (unsigned char) '\0';
 -		buff->slen = (int) (strlen) ((char *) buff->data);
 -
 -		if (buff->slen < n) break;
 -
 -		if (r > n) n = r; else n += n;
 -
 -		if (BSTR_OK != balloc (buff, n + 2)) {
 -			bdestroy (buff);
 -			return BSTR_ERR;
 -		}
 -	}
 -
 -	r = bconcat (b, buff);
 -	bdestroy (buff);
 -	return r;
 -}
 -
 -/*  int bassignformat (bstring b, const char * fmt, ...)
 - *
 - *  After the first parameter, it takes the same parameters as printf (), but 
 - *  rather than outputting results to stdio, it outputs the results to 
 - *  the bstring parameter b. Note that if there is an early generation of a 
 - *  '\0' character, the bstring will be truncated to this end point.
 - */
 -int bassignformat (bstring b, const char * fmt, ...) {
 -va_list arglist;
 -bstring buff;
 -int n, r;
 -
 -	if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 
 -	 || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR;
 -
 -	/* Since the length is not determinable beforehand, a search is
 -	   performed using the truncating "vsnprintf" call (to avoid buffer
 -	   overflows) on increasing potential sizes for the output result. */
 -
 -	if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF;
 -	if (NULL == (buff = bfromcstralloc (n + 2, ""))) {
 -		n = 1;
 -		if (NULL == (buff = bfromcstralloc (n + 2, ""))) return BSTR_ERR;
 -	}
 -
 -	for (;;) {
 -		va_start (arglist, fmt);
 -		exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist);
 -		va_end (arglist);
 -
 -		buff->data[n] = (unsigned char) '\0';
 -		buff->slen = (int) (strlen) ((char *) buff->data);
 -
 -		if (buff->slen < n) break;
 -
 -		if (r > n) n = r; else n += n;
 -
 -		if (BSTR_OK != balloc (buff, n + 2)) {
 -			bdestroy (buff);
 -			return BSTR_ERR;
 -		}
 -	}
 -
 -	r = bassign (b, buff);
 -	bdestroy (buff);
 -	return r;
 -}
 -
 -/*  bstring bformat (const char * fmt, ...)
 - *
 - *  Takes the same parameters as printf (), but rather than outputting results
 - *  to stdio, it forms a bstring which contains what would have been output.
 - *  Note that if there is an early generation of a '\0' character, the 
 - *  bstring will be truncated to this end point.
 - */
 -bstring bformat (const char * fmt, ...) {
 -va_list arglist;
 -bstring buff;
 -int n, r;
 -
 -	if (fmt == NULL) return NULL;
 -
 -	/* Since the length is not determinable beforehand, a search is
 -	   performed using the truncating "vsnprintf" call (to avoid buffer
 -	   overflows) on increasing potential sizes for the output result. */
 -
 -	if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF;
 -	if (NULL == (buff = bfromcstralloc (n + 2, ""))) {
 -		n = 1;
 -		if (NULL == (buff = bfromcstralloc (n + 2, ""))) return NULL;
 -	}
 -
 -	for (;;) {
 -		va_start (arglist, fmt);
 -		exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist);
 -		va_end (arglist);
 -
 -		buff->data[n] = (unsigned char) '\0';
 -		buff->slen = (int) (strlen) ((char *) buff->data);
 -
 -		if (buff->slen < n) break;
 -
 -		if (r > n) n = r; else n += n;
 -
 -		if (BSTR_OK != balloc (buff, n + 2)) {
 -			bdestroy (buff);
 -			return NULL;
 -		}
 -	}
 -
 -	return buff;
 -}
 -
 -/*  int bvcformata (bstring b, int count, const char * fmt, va_list arglist)
 - *
 - *  The bvcformata function formats data under control of the format control 
 - *  string fmt and attempts to append the result to b.  The fmt parameter is 
 - *  the same as that of the printf function.  The variable argument list is 
 - *  replaced with arglist, which has been initialized by the va_start macro.
 - *  The size of the appended output is upper bounded by count.  If the 
 - *  required output exceeds count, the string b is not augmented with any 
 - *  contents and a value below BSTR_ERR is returned.  If a value below -count 
 - *  is returned then it is recommended that the negative of this value be 
 - *  used as an update to the count in a subsequent pass.  On other errors, 
 - *  such as running out of memory, parameter errors or numeric wrap around 
 - *  BSTR_ERR is returned.  BSTR_OK is returned when the output is successfully 
 - *  generated and appended to b.
 - *
 - *  Note: There is no sanity checking of arglist, and this function is
 - *  destructive of the contents of b from the b->slen point onward.  If there 
 - *  is an early generation of a '\0' character, the bstring will be truncated 
 - *  to this end point.
 - */
 -int bvcformata (bstring b, int count, const char * fmt, va_list arg) {
 -int n, r, l;
 -
 -	if (b == NULL || fmt == NULL || count <= 0 || b->data == NULL
 -	 || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR;
 -
 -	if (count > (n = b->slen + count) + 2) return BSTR_ERR;
 -	if (BSTR_OK != balloc (b, n + 2)) return BSTR_ERR;
 -
 -	exvsnprintf (r, (char *) b->data + b->slen, count + 2, fmt, arg);
 -
 -	/* Did the operation complete successfully within bounds? */
 -	for (l = b->slen; l <= n; l++) {
 -		if ('\0' == b->data[l]) {
 -			b->slen = l;
 -			return BSTR_OK;
 -		}
 -	}
 -
 -	/* Abort, since the buffer was not large enough.  The return value 
 -	   tries to help set what the retry length should be. */
 -
 -	b->data[b->slen] = '\0';
 -	if (r > count + 1) {	/* Does r specify a particular target length? */
 -		n = r;
 -	} else {
 -		n = count + count;	/* If not, just double the size of count */
 -		if (count > n) n = INT_MAX;
 -	}
 -	n = -n;
 -
 -	if (n > BSTR_ERR-1) n = BSTR_ERR-1;
 -	return n;
 -}
 -
 -#endif
 diff --git a/src/bstrlib.h b/src/bstrlib.h deleted file mode 100644 index c8fa694..0000000 --- a/src/bstrlib.h +++ /dev/null @@ -1,304 +0,0 @@ -/*
 - * This source file is part of the bstring string library.  This code was
 - * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause 
 - * BSD open source license or GPL v2.0. Refer to the accompanying documentation 
 - * for details on usage and license.
 - */
 -
 -/*
 - * bstrlib.h
 - *
 - * This file is the header file for the core module for implementing the 
 - * bstring functions.
 - */
 -
 -#ifndef BSTRLIB_INCLUDE
 -#define BSTRLIB_INCLUDE
 -
 -#ifdef __cplusplus
 -extern "C" {
 -#endif
 -
 -#include <stdarg.h>
 -#include <string.h>
 -#include <limits.h>
 -#include <ctype.h>
 -
 -#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
 -# if defined (__TURBOC__) && !defined (__BORLANDC__)
 -#  define BSTRLIB_NOVSNP
 -# endif
 -#endif
 -
 -#define BSTR_ERR (-1)
 -#define BSTR_OK (0)
 -#define BSTR_BS_BUFF_LENGTH_GET (0)
 -
 -typedef struct tagbstring * bstring;
 -typedef const struct tagbstring * const_bstring;
 -
 -/* Copy functions */
 -#define cstr2bstr bfromcstr
 -extern bstring bfromcstr (const char * str);
 -extern bstring bfromcstralloc (int mlen, const char * str);
 -extern bstring blk2bstr (const void * blk, int len);
 -extern char * bstr2cstr (const_bstring s, char z);
 -extern int bcstrfree (char * s);
 -extern bstring bstrcpy (const_bstring b1);
 -extern int bassign (bstring a, const_bstring b);
 -extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
 -extern int bassigncstr (bstring a, const char * str);
 -extern int bassignblk (bstring a, const void * s, int len);
 -
 -/* Destroy function */
 -extern int bdestroy (bstring b);
 -
 -/* Space allocation hinting functions */
 -extern int balloc (bstring s, int len);
 -extern int ballocmin (bstring b, int len);
 -
 -/* Substring extraction */
 -extern bstring bmidstr (const_bstring b, int left, int len);
 -
 -/* Various standard manipulations */
 -extern int bconcat (bstring b0, const_bstring b1);
 -extern int bconchar (bstring b0, char c);
 -extern int bcatcstr (bstring b, const char * s);
 -extern int bcatblk (bstring b, const void * s, int len);
 -extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
 -extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
 -extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
 -extern int bdelete (bstring s1, int pos, int len);
 -extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
 -extern int btrunc (bstring b, int n);
 -
 -/* Scan/search functions */
 -extern int bstricmp (const_bstring b0, const_bstring b1);
 -extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
 -extern int biseqcaseless (const_bstring b0, const_bstring b1);
 -extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
 -extern int biseq (const_bstring b0, const_bstring b1);
 -extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
 -extern int biseqcstr (const_bstring b, const char * s);
 -extern int biseqcstrcaseless (const_bstring b, const char * s);
 -extern int bstrcmp (const_bstring b0, const_bstring b1);
 -extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
 -extern int binstr (const_bstring s1, int pos, const_bstring s2);
 -extern int binstrr (const_bstring s1, int pos, const_bstring s2);
 -extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
 -extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
 -extern int bstrchrp (const_bstring b, int c, int pos);
 -extern int bstrrchrp (const_bstring b, int c, int pos);
 -#define bstrchr(b,c) bstrchrp ((b), (c), 0)
 -#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
 -extern int binchr (const_bstring b0, int pos, const_bstring b1);
 -extern int binchrr (const_bstring b0, int pos, const_bstring b1);
 -extern int bninchr (const_bstring b0, int pos, const_bstring b1);
 -extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
 -extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
 -extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
 -
 -/* List of string container functions */
 -struct bstrList {
 -    int qty, mlen;
 -    bstring * entry;
 -};
 -extern struct bstrList * bstrListCreate (void);
 -extern int bstrListDestroy (struct bstrList * sl);
 -extern int bstrListAlloc (struct bstrList * sl, int msz);
 -extern int bstrListAllocMin (struct bstrList * sl, int msz);
 -
 -/* String split and join functions */
 -extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
 -extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
 -extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
 -extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
 -extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
 -	int (* cb) (void * parm, int ofs, int len), void * parm);
 -extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
 -	int (* cb) (void * parm, int ofs, int len), void * parm);
 -extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
 -	int (* cb) (void * parm, int ofs, int len), void * parm);
 -
 -/* Miscellaneous functions */
 -extern int bpattern (bstring b, int len);
 -extern int btoupper (bstring b);
 -extern int btolower (bstring b);
 -extern int bltrimws (bstring b);
 -extern int brtrimws (bstring b);
 -extern int btrimws (bstring b);
 -
 -/* <*>printf format functions */
 -#if !defined (BSTRLIB_NOVSNP)
 -extern bstring bformat (const char * fmt, ...);
 -extern int bformata (bstring b, const char * fmt, ...);
 -extern int bassignformat (bstring b, const char * fmt, ...);
 -extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
 -
 -#define bvformata(ret, b, fmt, lastarg) { \
 -bstring bstrtmp_b = (b); \
 -const char * bstrtmp_fmt = (fmt); \
 -int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
 -	for (;;) { \
 -		va_list bstrtmp_arglist; \
 -		va_start (bstrtmp_arglist, lastarg); \
 -		bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
 -		va_end (bstrtmp_arglist); \
 -		if (bstrtmp_r >= 0) { /* Everything went ok */ \
 -			bstrtmp_r = BSTR_OK; \
 -			break; \
 -		} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
 -			bstrtmp_r = BSTR_ERR; \
 -			break; \
 -		} \
 -		bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
 -	} \
 -	ret = bstrtmp_r; \
 -}
 -
 -#endif
 -
 -typedef int (*bNgetc) (void *parm);
 -typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
 -
 -/* Input functions */
 -extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
 -extern bstring bread (bNread readPtr, void * parm);
 -extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
 -extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
 -extern int breada (bstring b, bNread readPtr, void * parm);
 -
 -/* Stream functions */
 -extern struct bStream * bsopen (bNread readPtr, void * parm);
 -extern void * bsclose (struct bStream * s);
 -extern int bsbufflength (struct bStream * s, int sz);
 -extern int bsreadln (bstring b, struct bStream * s, char terminator);
 -extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
 -extern int bsread (bstring b, struct bStream * s, int n);
 -extern int bsreadlna (bstring b, struct bStream * s, char terminator);
 -extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
 -extern int bsreada (bstring b, struct bStream * s, int n);
 -extern int bsunread (struct bStream * s, const_bstring b);
 -extern int bspeek (bstring r, const struct bStream * s);
 -extern int bssplitscb (struct bStream * s, const_bstring splitStr, 
 -	int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
 -extern int bssplitstrcb (struct bStream * s, const_bstring splitStr, 
 -	int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
 -extern int bseof (const struct bStream * s);
 -
 -struct tagbstring {
 -	int mlen;
 -	int slen;
 -	unsigned char * data;
 -};
 -
 -/* Accessor macros */
 -#define blengthe(b, e)      (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen))
 -#define blength(b)          (blengthe ((b), 0))
 -#define bdataofse(b, o, e)  (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o))
 -#define bdataofs(b, o)      (bdataofse ((b), (o), (void *)0))
 -#define bdatae(b, e)        (bdataofse (b, 0, e))
 -#define bdata(b)            (bdataofs (b, 0))
 -#define bchare(b, p, e)     ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e))
 -#define bchar(b, p)         bchare ((b), (p), '\0')
 -
 -/* Static constant string initialization macro */
 -#define bsStaticMlen(q,m)   {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
 -#if defined(_MSC_VER)
 -/* There are many versions of MSVC which emit __LINE__ as a non-constant. */
 -# define bsStatic(q)        bsStaticMlen(q,-32)
 -#endif
 -#ifndef bsStatic
 -# define bsStatic(q)        bsStaticMlen(q,-__LINE__)
 -#endif
 -
 -/* Static constant block parameter pair */
 -#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
 -
 -/* Reference building macros */
 -#define cstr2tbstr btfromcstr
 -#define btfromcstr(t,s) {                                            \
 -    (t).data = (unsigned char *) (s);                                \
 -    (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
 -    (t).mlen = -1;                                                   \
 -}
 -#define blk2tbstr(t,s,l) {            \
 -    (t).data = (unsigned char *) (s); \
 -    (t).slen = l;                     \
 -    (t).mlen = -1;                    \
 -}
 -#define btfromblk(t,s,l) blk2tbstr(t,s,l)
 -#define bmid2tbstr(t,b,p,l) {                                                \
 -    const_bstring bstrtmp_s = (b);                                           \
 -    if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) {              \
 -        int bstrtmp_left = (p);                                              \
 -        int bstrtmp_len  = (l);                                              \
 -        if (bstrtmp_left < 0) {                                              \
 -            bstrtmp_len += bstrtmp_left;                                     \
 -            bstrtmp_left = 0;                                                \
 -        }                                                                    \
 -        if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left)                    \
 -            bstrtmp_len = bstrtmp_s->slen - bstrtmp_left;                    \
 -        if (bstrtmp_len <= 0) {                                              \
 -            (t).data = (unsigned char *)"";                                  \
 -            (t).slen = 0;                                                    \
 -        } else {                                                             \
 -            (t).data = bstrtmp_s->data + bstrtmp_left;                       \
 -            (t).slen = bstrtmp_len;                                          \
 -        }                                                                    \
 -    } else {                                                                 \
 -        (t).data = (unsigned char *)"";                                      \
 -        (t).slen = 0;                                                        \
 -    }                                                                        \
 -    (t).mlen = -__LINE__;                                                    \
 -}
 -#define btfromblkltrimws(t,s,l) {                                            \
 -    int bstrtmp_idx = 0, bstrtmp_len = (l);                                  \
 -    unsigned char * bstrtmp_s = (s);                                         \
 -    if (bstrtmp_s && bstrtmp_len >= 0) {                                     \
 -        for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) {                   \
 -            if (!isspace (bstrtmp_s[bstrtmp_idx])) break;                    \
 -        }                                                                    \
 -    }                                                                        \
 -    (t).data = bstrtmp_s + bstrtmp_idx;                                      \
 -    (t).slen = bstrtmp_len - bstrtmp_idx;                                    \
 -    (t).mlen = -__LINE__;                                                    \
 -}
 -#define btfromblkrtrimws(t,s,l) {                                            \
 -    int bstrtmp_len = (l) - 1;                                               \
 -    unsigned char * bstrtmp_s = (s);                                         \
 -    if (bstrtmp_s && bstrtmp_len >= 0) {                                     \
 -        for (; bstrtmp_len >= 0; bstrtmp_len--) {                            \
 -            if (!isspace (bstrtmp_s[bstrtmp_len])) break;                    \
 -        }                                                                    \
 -    }                                                                        \
 -    (t).data = bstrtmp_s;                                                    \
 -    (t).slen = bstrtmp_len + 1;                                              \
 -    (t).mlen = -__LINE__;                                                    \
 -}
 -#define btfromblktrimws(t,s,l) {                                             \
 -    int bstrtmp_idx = 0, bstrtmp_len = (l) - 1;                              \
 -    unsigned char * bstrtmp_s = (s);                                         \
 -    if (bstrtmp_s && bstrtmp_len >= 0) {                                     \
 -        for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) {                  \
 -            if (!isspace (bstrtmp_s[bstrtmp_idx])) break;                    \
 -        }                                                                    \
 -        for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) {                  \
 -            if (!isspace (bstrtmp_s[bstrtmp_len])) break;                    \
 -        }                                                                    \
 -    }                                                                        \
 -    (t).data = bstrtmp_s + bstrtmp_idx;                                      \
 -    (t).slen = bstrtmp_len + 1 - bstrtmp_idx;                                \
 -    (t).mlen = -__LINE__;                                                    \
 -}
 -
 -/* Write protection macros */
 -#define bwriteprotect(t)     { if ((t).mlen >=  0) (t).mlen = -1; }
 -#define bwriteallow(t)       { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); }
 -#define biswriteprotected(t) ((t).mlen <= 0)
 -
 -#ifdef __cplusplus
 -}
 -#endif
 -
 -#endif
 diff --git a/src/buffer.c b/src/buffer.c new file mode 100644 index 0000000..7c2b86b --- /dev/null +++ b/src/buffer.c @@ -0,0 +1,354 @@ +#include <stdarg.h> +#include <ctype.h> +#include <string.h> +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/param.h> + +#include "buffer.h" + +/* Used as default value for strbuf->ptr so that people can always + * assume ptr is non-NULL and zero terminated even for new strbufs. + */ +unsigned char strbuf__initbuf[1]; +unsigned char strbuf__oom[1]; + +#define ENSURE_SIZE(b, d) \ +	if ((d) > buf->asize && strbuf_grow(b, (d)) < 0)\ +		return -1; + +void strbuf_init(strbuf *buf, int initial_size) +{ +	buf->asize = 0; +	buf->size = 0; +	buf->ptr = strbuf__initbuf; + +	if (initial_size) +		strbuf_grow(buf, initial_size); +} + +int strbuf_try_grow(strbuf *buf, int target_size, bool mark_oom) +{ +	unsigned char *new_ptr; +	int new_size; + +	if (buf->ptr == strbuf__oom) +		return -1; + +	if (target_size <= buf->asize) +		return 0; + +	if (buf->asize == 0) { +		new_size = target_size; +		new_ptr = NULL; +	} else { +		new_size = buf->asize; +		new_ptr = buf->ptr; +	} + +	/* grow the buffer size by 1.5, until it's big enough +	 * to fit our target size */ +	while (new_size < target_size) +		new_size = (new_size << 1) - (new_size >> 1); + +	/* round allocation up to multiple of 8 */ +	new_size = (new_size + 7) & ~7; + +	new_ptr = realloc(new_ptr, new_size); + +	if (!new_ptr) { +		if (mark_oom) +			buf->ptr = strbuf__oom; +		return -1; +	} + +	buf->asize = new_size; +	buf->ptr   = new_ptr; + +	/* truncate the existing buffer size if necessary */ +	if (buf->size >= buf->asize) +		buf->size = buf->asize - 1; +	buf->ptr[buf->size] = '\0'; + +	return 0; +} + +void strbuf_free(strbuf *buf) +{ +	if (!buf) return; + +	if (buf->ptr != strbuf__initbuf && buf->ptr != strbuf__oom) +		free(buf->ptr); + +	strbuf_init(buf, 0); +} + +void strbuf_clear(strbuf *buf) +{ +	buf->size = 0; + +	if (buf->asize > 0) +		buf->ptr[0] = '\0'; +} + +int strbuf_set(strbuf *buf, const unsigned char *data, int len) +{ +	if (len <= 0 || data == NULL) { +		strbuf_clear(buf); +	} else { +		if (data != buf->ptr) { +			ENSURE_SIZE(buf, len + 1); +			memmove(buf->ptr, data, len); +		} +		buf->size = len; +		buf->ptr[buf->size] = '\0'; +	} +	return 0; +} + +int strbuf_sets(strbuf *buf, const char *string) +{ +	return strbuf_set(buf, +		(const unsigned char *)string, +		string ? strlen(string) : 0); +} + +int strbuf_putc(strbuf *buf, int c) +{ +	ENSURE_SIZE(buf, buf->size + 2); +	buf->ptr[buf->size++] = c; +	buf->ptr[buf->size] = '\0'; +	return 0; +} + +int strbuf_put(strbuf *buf, const unsigned char *data, int len) +{ +	if (len <= 0) +		return 0; + +	ENSURE_SIZE(buf, buf->size + len + 1); +	memmove(buf->ptr + buf->size, data, len); +	buf->size += len; +	buf->ptr[buf->size] = '\0'; +	return 0; +} + +int strbuf_puts(strbuf *buf, const char *string) +{ +	return strbuf_put(buf, (const unsigned char *)string, strlen(string)); +} + +int strbuf_vprintf(strbuf *buf, const char *format, va_list ap) +{ +	const int expected_size = buf->size + (strlen(format) * 2); +	int len; + +	ENSURE_SIZE(buf, expected_size); + +	while (1) { +		va_list args; +		va_copy(args, ap); + +		len = vsnprintf( +			(char *)buf->ptr + buf->size, +			buf->asize - buf->size, +			format, args +		); + +		if (len < 0) { +			free(buf->ptr); +			buf->ptr = strbuf__oom; +			return -1; +		} + +		if (len + 1 <= buf->asize - buf->size) { +			buf->size += len; +			break; +		} + +		ENSURE_SIZE(buf, buf->size + len + 1); +	} + +	return 0; +} + +int strbuf_printf(strbuf *buf, const char *format, ...) +{ +	int r; +	va_list ap; + +	va_start(ap, format); +	r = strbuf_vprintf(buf, format, ap); +	va_end(ap); + +	return r; +} + +void strbuf_copy_cstr(char *data, int datasize, const strbuf *buf) +{ +	int copylen; + +	assert(data && datasize && buf); + +	data[0] = '\0'; + +	if (buf->size == 0 || buf->asize <= 0) +		return; + +	copylen = buf->size; +	if (copylen > datasize - 1) +		copylen = datasize - 1; +	memmove(data, buf->ptr, copylen); +	data[copylen] = '\0'; +} + +void strbuf_swap(strbuf *buf_a, strbuf *buf_b) +{ +	strbuf t = *buf_a; +	*buf_a = *buf_b; +	*buf_b = t; +} + +unsigned char *strbuf_detach(strbuf *buf) +{ +	unsigned char *data = buf->ptr; + +	if (buf->asize == 0 || buf->ptr == strbuf__oom) { +		/* return an empty string */ +		return calloc(1, 1); +	} + +	strbuf_init(buf, 0); +	return data; +} + +void strbuf_attach(strbuf *buf, unsigned char *ptr, int asize) +{ +	strbuf_free(buf); + +	if (ptr) { +		buf->ptr = ptr; +		buf->size = strlen((char *)ptr); +		if (asize) +			buf->asize = (asize < buf->size) ? buf->size + 1 : asize; +		else /* pass 0 to fall back on strlen + 1 */ +			buf->asize = buf->size + 1; +	} else { +		strbuf_grow(buf, asize); +	} +} + +int strbuf_cmp(const strbuf *a, const strbuf *b) +{ +	int result = memcmp(a->ptr, b->ptr, MIN(a->size, b->size)); +	return (result != 0) ? result : +		(a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0; +} + +int strbuf_strchr(const strbuf *buf, int c, int pos) +{ +	const unsigned char *p = memchr(buf->ptr + pos, c, buf->size - pos); +	if (!p) +		return -1; + +	return (int)(p - (const unsigned char *)buf->ptr); +} + +int strbuf_strrchr(const strbuf *buf, int c, int pos) +{ +	int i; + +	for (i = pos; i >= 0; i--) { +		if (buf->ptr[i] == (unsigned char) c) +			return i; +	} + +	return -1; +} + +void strbuf_truncate(strbuf *buf, int len) +{ +	if (len < buf->size) { +		buf->size = len; +		buf->ptr[buf->size] = '\0'; +	} +} + +void strbuf_drop(strbuf *buf, int n) +{ +	if (n > 0) { +		buf->size = buf->size - n; +		if (buf->size) +			memmove(buf->ptr, buf->ptr + n, buf->size); + +		buf->ptr[buf->size] = '\0'; +	} +} + +void strbuf_trim(strbuf *buf) +{ +	int i = 0; + +	if (!buf->size) +		return; + +	while (i < buf->size && isspace(buf->ptr[i])) +		i++; + +	strbuf_drop(buf, i); + +	/* rtrim */ +	while (buf->size > 0) { +		if (!isspace(buf->ptr[buf->size - 1])) +			break; + +		buf->size--; +	} + +	buf->ptr[buf->size] = '\0'; +} + +// Destructively modify string, collapsing consecutive +// space and newline characters into a single space. +void strbuf_normalize_whitespace(strbuf *s) +{ +	bool last_char_was_space = false; +	int r, w; + +	for (r = 0, w = 0; r < s->size; ++r) { +		switch (s->ptr[r]) { +		case ' ': +		case '\n': +			if (last_char_was_space) +				break; + +			s->ptr[w++] = ' '; +			last_char_was_space = true; +			break; + +		default: +			s->ptr[w++] = s->ptr[r]; +			last_char_was_space = false; +		} +	} + +	strbuf_truncate(s, w); +} + +// Destructively unescape a string: remove backslashes before punctuation chars. +extern void strbuf_unescape(strbuf *buf) +{ +	int r, w; + +	for (r = 0, w = 0; r < buf->size; ++r) { +		if (buf->ptr[r] == '\\' && ispunct(buf->ptr[r + 1])) +			continue; + +		buf->ptr[w++] = buf->ptr[r]; +	} + +	strbuf_truncate(buf, w); +} + diff --git a/src/buffer.h b/src/buffer.h new file mode 100644 index 0000000..1bc1eee --- /dev/null +++ b/src/buffer.h @@ -0,0 +1,114 @@ +#ifndef INCLUDE_buffer_h__ +#define INCLUDE_buffer_h__ + +#include <stdbool.h> +#include <stddef.h> +#include <stdarg.h> +#include <sys/types.h> + +typedef struct { +	unsigned char *ptr; +	int asize, size; +} strbuf; + +extern unsigned char strbuf__initbuf[]; +extern unsigned char strbuf__oom[]; + +#define GH_BUF_INIT { strbuf__initbuf, 0, 0 } + +/** + * Initialize a strbuf structure. + * + * For the cases where GH_BUF_INIT cannot be used to do static + * initialization. + */ +extern void strbuf_init(strbuf *buf, int initial_size); + +/** + * Attempt to grow the buffer to hold at least `target_size` bytes. + * + * If the allocation fails, this will return an error.  If mark_oom is true, + * this will mark the buffer as invalid for future operations; if false, + * existing buffer content will be preserved, but calling code must handle + * that buffer was not expanded. + */ +extern int strbuf_try_grow(strbuf *buf, int target_size, bool mark_oom); + +/** + * Grow the buffer to hold at least `target_size` bytes. + * + * If the allocation fails, this will return an error and the buffer will be + * marked as invalid for future operations, invaliding contents. + * + * @return 0 on success or -1 on failure + */ +static inline int strbuf_grow(strbuf *buf, int target_size) +{ +	return strbuf_try_grow(buf, target_size, true); +} + +extern void strbuf_free(strbuf *buf); +extern void strbuf_swap(strbuf *buf_a, strbuf *buf_b); + +/** + * Test if there have been any reallocation failures with this strbuf. + * + * Any function that writes to a strbuf can fail due to memory allocation + * issues.  If one fails, the strbuf will be marked with an OOM error and + * further calls to modify the buffer will fail.  Check strbuf_oom() at the + * end of your sequence and it will be true if you ran out of memory at any + * point with that buffer. + * + * @return false if no error, true if allocation error + */ +static inline bool strbuf_oom(const strbuf *buf) +{ +	return (buf->ptr == strbuf__oom); +} + + +static inline size_t strbuf_len(const strbuf *buf) +{ +	return buf->size; +} + +extern int strbuf_cmp(const strbuf *a, const strbuf *b); + +extern void strbuf_attach(strbuf *buf, unsigned char *ptr, int asize); +extern unsigned char *strbuf_detach(strbuf *buf); +extern void strbuf_copy_cstr(char *data, int datasize, const strbuf *buf); + +static inline const char *strbuf_cstr(const strbuf *buf) +{ +	return (char *)buf->ptr; +} + +#define strbuf_at(buf, n) ((buf)->ptr[n]) + +/* + * Functions below that return int value error codes will return 0 on + * success or -1 on failure (which generally means an allocation failed). + * Using a strbuf where the allocation has failed with result in -1 from + * all further calls using that buffer.  As a result, you can ignore the + * return code of these functions and call them in a series then just call + * strbuf_oom at the end. + */ +extern int strbuf_set(strbuf *buf, const unsigned char *data, int len); +extern int strbuf_sets(strbuf *buf, const char *string); +extern int strbuf_putc(strbuf *buf, int c); +extern int strbuf_put(strbuf *buf, const unsigned char *data, int len); +extern int strbuf_puts(strbuf *buf, const char *string); +extern int strbuf_printf(strbuf *buf, const char *format, ...) +	__attribute__((format (printf, 2, 3))); +extern int strbuf_vprintf(strbuf *buf, const char *format, va_list ap); +extern void strbuf_clear(strbuf *buf); + +int strbuf_strchr(const strbuf *buf, int c, int pos); +int strbuf_strrchr(const strbuf *buf, int c, int pos); +void strbuf_drop(strbuf *buf, int n); +void strbuf_truncate(strbuf *buf, int len); +void strbuf_trim(strbuf *buf); +void strbuf_normalize_whitespace(strbuf *s); +void strbuf_unescape(strbuf *s); + +#endif diff --git a/src/case_fold_switch.c b/src/case_fold_switch.inc index 70fdd75..70fdd75 100644 --- a/src/case_fold_switch.c +++ b/src/case_fold_switch.inc diff --git a/src/casefold.c b/src/casefold.c deleted file mode 100644 index 33f18aa..0000000 --- a/src/casefold.c +++ /dev/null @@ -1,2699 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> - - -  switch c { -    case 0x0041: -      bufpush(0x0061); -      break; -    case 0x0042: -      bufpush(0x0062); -      break; -    case 0x0043: -      bufpush(0x0063); -      break; -    case 0x0044: -      bufpush(0x0064); -      break; -    case 0x0045: -      bufpush(0x0065); -      break; -    case 0x0046: -      bufpush(0x0066); -      break; -    case 0x0047: -      bufpush(0x0067); -      break; -    case 0x0048: -      bufpush(0x0068); -      break; -    case 0x0049: -      bufpush(0x0069); -      break; -    case 0x0049: -      bufpush(0x0131); -      break; -    case 0x004A: -      bufpush(0x006A); -      break; -    case 0x004B: -      bufpush(0x006B); -      break; -    case 0x004C: -      bufpush(0x006C); -      break; -    case 0x004D: -      bufpush(0x006D); -      break; -    case 0x004E: -      bufpush(0x006E); -      break; -    case 0x004F: -      bufpush(0x006F); -      break; -    case 0x0050: -      bufpush(0x0070); -      break; -    case 0x0051: -      bufpush(0x0071); -      break; -    case 0x0052: -      bufpush(0x0072); -      break; -    case 0x0053: -      bufpush(0x0073); -      break; -    case 0x0054: -      bufpush(0x0074); -      break; -    case 0x0055: -      bufpush(0x0075); -      break; -    case 0x0056: -      bufpush(0x0076); -      break; -    case 0x0057: -      bufpush(0x0077); -      break; -    case 0x0058: -      bufpush(0x0078); -      break; -    case 0x0059: -      bufpush(0x0079); -      break; -    case 0x005A: -      bufpush(0x007A); -      break; -    case 0x00B5: -      bufpush(0x03BC); -      break; -    case 0x00C0: -      bufpush(0x00E0); -      break; -    case 0x00C1: -      bufpush(0x00E1); -      break; -    case 0x00C2: -      bufpush(0x00E2); -      break; -    case 0x00C3: -      bufpush(0x00E3); -      break; -    case 0x00C4: -      bufpush(0x00E4); -      break; -    case 0x00C5: -      bufpush(0x00E5); -      break; -    case 0x00C6: -      bufpush(0x00E6); -      break; -    case 0x00C7: -      bufpush(0x00E7); -      break; -    case 0x00C8: -      bufpush(0x00E8); -      break; -    case 0x00C9: -      bufpush(0x00E9); -      break; -    case 0x00CA: -      bufpush(0x00EA); -      break; -    case 0x00CB: -      bufpush(0x00EB); -      break; -    case 0x00CC: -      bufpush(0x00EC); -      break; -    case 0x00CD: -      bufpush(0x00ED); -      break; -    case 0x00CE: -      bufpush(0x00EE); -      break; -    case 0x00CF: -      bufpush(0x00EF); -      break; -    case 0x00D0: -      bufpush(0x00F0); -      break; -    case 0x00D1: -      bufpush(0x00F1); -      break; -    case 0x00D2: -      bufpush(0x00F2); -      break; -    case 0x00D3: -      bufpush(0x00F3); -      break; -    case 0x00D4: -      bufpush(0x00F4); -      break; -    case 0x00D5: -      bufpush(0x00F5); -      break; -    case 0x00D6: -      bufpush(0x00F6); -      break; -    case 0x00D8: -      bufpush(0x00F8); -      break; -    case 0x00D9: -      bufpush(0x00F9); -      break; -    case 0x00DA: -      bufpush(0x00FA); -      break; -    case 0x00DB: -      bufpush(0x00FB); -      break; -    case 0x00DC: -      bufpush(0x00FC); -      break; -    case 0x00DD: -      bufpush(0x00FD); -      break; -    case 0x00DE: -      bufpush(0x00FE); -      break; -    case 0x00DF: -      bufpush(0x0073); -      bufpush(0x0073); -      break; -    case 0x0100: -      bufpush(0x0101); -      break; -    case 0x0102: -      bufpush(0x0103); -      break; -    case 0x0104: -      bufpush(0x0105); -      break; -    case 0x0106: -      bufpush(0x0107); -      break; -    case 0x0108: -      bufpush(0x0109); -      break; -    case 0x010A: -      bufpush(0x010B); -      break; -    case 0x010C: -      bufpush(0x010D); -      break; -    case 0x010E: -      bufpush(0x010F); -      break; -    case 0x0110: -      bufpush(0x0111); -      break; -    case 0x0112: -      bufpush(0x0113); -      break; -    case 0x0114: -      bufpush(0x0115); -      break; -    case 0x0116: -      bufpush(0x0117); -      break; -    case 0x0118: -      bufpush(0x0119); -      break; -    case 0x011A: -      bufpush(0x011B); -      break; -    case 0x011C: -      bufpush(0x011D); -      break; -    case 0x011E: -      bufpush(0x011F); -      break; -    case 0x0120: -      bufpush(0x0121); -      break; -    case 0x0122: -      bufpush(0x0123); -      break; -    case 0x0124: -      bufpush(0x0125); -      break; -    case 0x0126: -      bufpush(0x0127); -      break; -    case 0x0128: -      bufpush(0x0129); -      break; -    case 0x012A: -      bufpush(0x012B); -      break; -    case 0x012C: -      bufpush(0x012D); -      break; -    case 0x012E: -      bufpush(0x012F); -      break; -    case 0x0130: -      bufpush(0x0069); -      bufpush(0x0307); -      break; -    case 0x0130: -      bufpush(0x0069); -      break; -    case 0x0132: -      bufpush(0x0133); -      break; -    case 0x0134: -      bufpush(0x0135); -      break; -    case 0x0136: -      bufpush(0x0137); -      break; -    case 0x0139: -      bufpush(0x013A); -      break; -    case 0x013B: -      bufpush(0x013C); -      break; -    case 0x013D: -      bufpush(0x013E); -      break; -    case 0x013F: -      bufpush(0x0140); -      break; -    case 0x0141: -      bufpush(0x0142); -      break; -    case 0x0143: -      bufpush(0x0144); -      break; -    case 0x0145: -      bufpush(0x0146); -      break; -    case 0x0147: -      bufpush(0x0148); -      break; -    case 0x0149: -      bufpush(0x02BC); -      bufpush(0x006E); -      break; -    case 0x014A: -      bufpush(0x014B); -      break; -    case 0x014C: -      bufpush(0x014D); -      break; -    case 0x014E: -      bufpush(0x014F); -      break; -    case 0x0150: -      bufpush(0x0151); -      break; -    case 0x0152: -      bufpush(0x0153); -      break; -    case 0x0154: -      bufpush(0x0155); -      break; -    case 0x0156: -      bufpush(0x0157); -      break; -    case 0x0158: -      bufpush(0x0159); -      break; -    case 0x015A: -      bufpush(0x015B); -      break; -    case 0x015C: -      bufpush(0x015D); -      break; -    case 0x015E: -      bufpush(0x015F); -      break; -    case 0x0160: -      bufpush(0x0161); -      break; -    case 0x0162: -      bufpush(0x0163); -      break; -    case 0x0164: -      bufpush(0x0165); -      break; -    case 0x0166: -      bufpush(0x0167); -      break; -    case 0x0168: -      bufpush(0x0169); -      break; -    case 0x016A: -      bufpush(0x016B); -      break; -    case 0x016C: -      bufpush(0x016D); -      break; -    case 0x016E: -      bufpush(0x016F); -      break; -    case 0x0170: -      bufpush(0x0171); -      break; -    case 0x0172: -      bufpush(0x0173); -      break; -    case 0x0174: -      bufpush(0x0175); -      break; -    case 0x0176: -      bufpush(0x0177); -      break; -    case 0x0178: -      bufpush(0x00FF); -      break; -    case 0x0179: -      bufpush(0x017A); -      break; -    case 0x017B: -      bufpush(0x017C); -      break; -    case 0x017D: -      bufpush(0x017E); -      break; -    case 0x017F: -      bufpush(0x0073); -      break; -    case 0x0181: -      bufpush(0x0253); -      break; -    case 0x0182: -      bufpush(0x0183); -      break; -    case 0x0184: -      bufpush(0x0185); -      break; -    case 0x0186: -      bufpush(0x0254); -      break; -    case 0x0187: -      bufpush(0x0188); -      break; -    case 0x0189: -      bufpush(0x0256); -      break; -    case 0x018A: -      bufpush(0x0257); -      break; -    case 0x018B: -      bufpush(0x018C); -      break; -    case 0x018E: -      bufpush(0x01DD); -      break; -    case 0x018F: -      bufpush(0x0259); -      break; -    case 0x0190: -      bufpush(0x025B); -      break; -    case 0x0191: -      bufpush(0x0192); -      break; -    case 0x0193: -      bufpush(0x0260); -      break; -    case 0x0194: -      bufpush(0x0263); -      break; -    case 0x0196: -      bufpush(0x0269); -      break; -    case 0x0197: -      bufpush(0x0268); -      break; -    case 0x0198: -      bufpush(0x0199); -      break; -    case 0x019C: -      bufpush(0x026F); -      break; -    case 0x019D: -      bufpush(0x0272); -      break; -    case 0x019F: -      bufpush(0x0275); -      break; -    case 0x01A0: -      bufpush(0x01A1); -      break; -    case 0x01A2: -      bufpush(0x01A3); -      break; -    case 0x01A4: -      bufpush(0x01A5); -      break; -    case 0x01A6: -      bufpush(0x0280); -      break; -    case 0x01A7: -      bufpush(0x01A8); -      break; -    case 0x01A9: -      bufpush(0x0283); -      break; -    case 0x01AC: -      bufpush(0x01AD); -      break; -    case 0x01AE: -      bufpush(0x0288); -      break; -    case 0x01AF: -      bufpush(0x01B0); -      break; -    case 0x01B1: -      bufpush(0x028A); -      break; -    case 0x01B2: -      bufpush(0x028B); -      break; -    case 0x01B3: -      bufpush(0x01B4); -      break; -    case 0x01B5: -      bufpush(0x01B6); -      break; -    case 0x01B7: -      bufpush(0x0292); -      break; -    case 0x01B8: -      bufpush(0x01B9); -      break; -    case 0x01BC: -      bufpush(0x01BD); -      break; -    case 0x01C4: -      bufpush(0x01C6); -      break; -    case 0x01C5: -      bufpush(0x01C6); -      break; -    case 0x01C7: -      bufpush(0x01C9); -      break; -    case 0x01C8: -      bufpush(0x01C9); -      break; -    case 0x01CA: -      bufpush(0x01CC); -      break; -    case 0x01CB: -      bufpush(0x01CC); -      break; -    case 0x01CD: -      bufpush(0x01CE); -      break; -    case 0x01CF: -      bufpush(0x01D0); -      break; -    case 0x01D1: -      bufpush(0x01D2); -      break; -    case 0x01D3: -      bufpush(0x01D4); -      break; -    case 0x01D5: -      bufpush(0x01D6); -      break; -    case 0x01D7: -      bufpush(0x01D8); -      break; -    case 0x01D9: -      bufpush(0x01DA); -      break; -    case 0x01DB: -      bufpush(0x01DC); -      break; -    case 0x01DE: -      bufpush(0x01DF); -      break; -    case 0x01E0: -      bufpush(0x01E1); -      break; -    case 0x01E2: -      bufpush(0x01E3); -      break; -    case 0x01E4: -      bufpush(0x01E5); -      break; -    case 0x01E6: -      bufpush(0x01E7); -      break; -    case 0x01E8: -      bufpush(0x01E9); -      break; -    case 0x01EA: -      bufpush(0x01EB); -      break; -    case 0x01EC: -      bufpush(0x01ED); -      break; -    case 0x01EE: -      bufpush(0x01EF); -      break; -    case 0x01F0: -      bufpush(0x006A); -      bufpush(0x030C); -      break; -    case 0x01F1: -      bufpush(0x01F3); -      break; -    case 0x01F2: -      bufpush(0x01F3); -      break; -    case 0x01F4: -      bufpush(0x01F5); -      break; -    case 0x01F6: -      bufpush(0x0195); -      break; -    case 0x01F7: -      bufpush(0x01BF); -      break; -    case 0x01F8: -      bufpush(0x01F9); -      break; -    case 0x01FA: -      bufpush(0x01FB); -      break; -    case 0x01FC: -      bufpush(0x01FD); -      break; -    case 0x01FE: -      bufpush(0x01FF); -      break; -    case 0x0200: -      bufpush(0x0201); -      break; -    case 0x0202: -      bufpush(0x0203); -      break; -    case 0x0204: -      bufpush(0x0205); -      break; -    case 0x0206: -      bufpush(0x0207); -      break; -    case 0x0208: -      bufpush(0x0209); -      break; -    case 0x020A: -      bufpush(0x020B); -      break; -    case 0x020C: -      bufpush(0x020D); -      break; -    case 0x020E: -      bufpush(0x020F); -      break; -    case 0x0210: -      bufpush(0x0211); -      break; -    case 0x0212: -      bufpush(0x0213); -      break; -    case 0x0214: -      bufpush(0x0215); -      break; -    case 0x0216: -      bufpush(0x0217); -      break; -    case 0x0218: -      bufpush(0x0219); -      break; -    case 0x021A: -      bufpush(0x021B); -      break; -    case 0x021C: -      bufpush(0x021D); -      break; -    case 0x021E: -      bufpush(0x021F); -      break; -    case 0x0220: -      bufpush(0x019E); -      break; -    case 0x0222: -      bufpush(0x0223); -      break; -    case 0x0224: -      bufpush(0x0225); -      break; -    case 0x0226: -      bufpush(0x0227); -      break; -    case 0x0228: -      bufpush(0x0229); -      break; -    case 0x022A: -      bufpush(0x022B); -      break; -    case 0x022C: -      bufpush(0x022D); -      break; -    case 0x022E: -      bufpush(0x022F); -      break; -    case 0x0230: -      bufpush(0x0231); -      break; -    case 0x0232: -      bufpush(0x0233); -      break; -    case 0x0345: -      bufpush(0x03B9); -      break; -    case 0x0386: -      bufpush(0x03AC); -      break; -    case 0x0388: -      bufpush(0x03AD); -      break; -    case 0x0389: -      bufpush(0x03AE); -      break; -    case 0x038A: -      bufpush(0x03AF); -      break; -    case 0x038C: -      bufpush(0x03CC); -      break; -    case 0x038E: -      bufpush(0x03CD); -      break; -    case 0x038F: -      bufpush(0x03CE); -      break; -    case 0x0390: -      bufpush(0x03B9); -      bufpush(0x0308); -      bufpush(0x0301); -      break; -    case 0x0391: -      bufpush(0x03B1); -      break; -    case 0x0392: -      bufpush(0x03B2); -      break; -    case 0x0393: -      bufpush(0x03B3); -      break; -    case 0x0394: -      bufpush(0x03B4); -      break; -    case 0x0395: -      bufpush(0x03B5); -      break; -    case 0x0396: -      bufpush(0x03B6); -      break; -    case 0x0397: -      bufpush(0x03B7); -      break; -    case 0x0398: -      bufpush(0x03B8); -      break; -    case 0x0399: -      bufpush(0x03B9); -      break; -    case 0x039A: -      bufpush(0x03BA); -      break; -    case 0x039B: -      bufpush(0x03BB); -      break; -    case 0x039C: -      bufpush(0x03BC); -      break; -    case 0x039D: -      bufpush(0x03BD); -      break; -    case 0x039E: -      bufpush(0x03BE); -      break; -    case 0x039F: -      bufpush(0x03BF); -      break; -    case 0x03A0: -      bufpush(0x03C0); -      break; -    case 0x03A1: -      bufpush(0x03C1); -      break; -    case 0x03A3: -      bufpush(0x03C3); -      break; -    case 0x03A4: -      bufpush(0x03C4); -      break; -    case 0x03A5: -      bufpush(0x03C5); -      break; -    case 0x03A6: -      bufpush(0x03C6); -      break; -    case 0x03A7: -      bufpush(0x03C7); -      break; -    case 0x03A8: -      bufpush(0x03C8); -      break; -    case 0x03A9: -      bufpush(0x03C9); -      break; -    case 0x03AA: -      bufpush(0x03CA); -      break; -    case 0x03AB: -      bufpush(0x03CB); -      break; -    case 0x03B0: -      bufpush(0x03C5); -      bufpush(0x0308); -      bufpush(0x0301); -      break; -    case 0x03C2: -      bufpush(0x03C3); -      break; -    case 0x03D0: -      bufpush(0x03B2); -      break; -    case 0x03D1: -      bufpush(0x03B8); -      break; -    case 0x03D5: -      bufpush(0x03C6); -      break; -    case 0x03D6: -      bufpush(0x03C0); -      break; -    case 0x03D8: -      bufpush(0x03D9); -      break; -    case 0x03DA: -      bufpush(0x03DB); -      break; -    case 0x03DC: -      bufpush(0x03DD); -      break; -    case 0x03DE: -      bufpush(0x03DF); -      break; -    case 0x03E0: -      bufpush(0x03E1); -      break; -    case 0x03E2: -      bufpush(0x03E3); -      break; -    case 0x03E4: -      bufpush(0x03E5); -      break; -    case 0x03E6: -      bufpush(0x03E7); -      break; -    case 0x03E8: -      bufpush(0x03E9); -      break; -    case 0x03EA: -      bufpush(0x03EB); -      break; -    case 0x03EC: -      bufpush(0x03ED); -      break; -    case 0x03EE: -      bufpush(0x03EF); -      break; -    case 0x03F0: -      bufpush(0x03BA); -      break; -    case 0x03F1: -      bufpush(0x03C1); -      break; -    case 0x03F2: -      bufpush(0x03C3); -      break; -    case 0x03F4: -      bufpush(0x03B8); -      break; -    case 0x03F5: -      bufpush(0x03B5); -      break; -    case 0x0400: -      bufpush(0x0450); -      break; -    case 0x0401: -      bufpush(0x0451); -      break; -    case 0x0402: -      bufpush(0x0452); -      break; -    case 0x0403: -      bufpush(0x0453); -      break; -    case 0x0404: -      bufpush(0x0454); -      break; -    case 0x0405: -      bufpush(0x0455); -      break; -    case 0x0406: -      bufpush(0x0456); -      break; -    case 0x0407: -      bufpush(0x0457); -      break; -    case 0x0408: -      bufpush(0x0458); -      break; -    case 0x0409: -      bufpush(0x0459); -      break; -    case 0x040A: -      bufpush(0x045A); -      break; -    case 0x040B: -      bufpush(0x045B); -      break; -    case 0x040C: -      bufpush(0x045C); -      break; -    case 0x040D: -      bufpush(0x045D); -      break; -    case 0x040E: -      bufpush(0x045E); -      break; -    case 0x040F: -      bufpush(0x045F); -      break; -    case 0x0410: -      bufpush(0x0430); -      break; -    case 0x0411: -      bufpush(0x0431); -      break; -    case 0x0412: -      bufpush(0x0432); -      break; -    case 0x0413: -      bufpush(0x0433); -      break; -    case 0x0414: -      bufpush(0x0434); -      break; -    case 0x0415: -      bufpush(0x0435); -      break; -    case 0x0416: -      bufpush(0x0436); -      break; -    case 0x0417: -      bufpush(0x0437); -      break; -    case 0x0418: -      bufpush(0x0438); -      break; -    case 0x0419: -      bufpush(0x0439); -      break; -    case 0x041A: -      bufpush(0x043A); -      break; -    case 0x041B: -      bufpush(0x043B); -      break; -    case 0x041C: -      bufpush(0x043C); -      break; -    case 0x041D: -      bufpush(0x043D); -      break; -    case 0x041E: -      bufpush(0x043E); -      break; -    case 0x041F: -      bufpush(0x043F); -      break; -    case 0x0420: -      bufpush(0x0440); -      break; -    case 0x0421: -      bufpush(0x0441); -      break; -    case 0x0422: -      bufpush(0x0442); -      break; -    case 0x0423: -      bufpush(0x0443); -      break; -    case 0x0424: -      bufpush(0x0444); -      break; -    case 0x0425: -      bufpush(0x0445); -      break; -    case 0x0426: -      bufpush(0x0446); -      break; -    case 0x0427: -      bufpush(0x0447); -      break; -    case 0x0428: -      bufpush(0x0448); -      break; -    case 0x0429: -      bufpush(0x0449); -      break; -    case 0x042A: -      bufpush(0x044A); -      break; -    case 0x042B: -      bufpush(0x044B); -      break; -    case 0x042C: -      bufpush(0x044C); -      break; -    case 0x042D: -      bufpush(0x044D); -      break; -    case 0x042E: -      bufpush(0x044E); -      break; -    case 0x042F: -      bufpush(0x044F); -      break; -    case 0x0460: -      bufpush(0x0461); -      break; -    case 0x0462: -      bufpush(0x0463); -      break; -    case 0x0464: -      bufpush(0x0465); -      break; -    case 0x0466: -      bufpush(0x0467); -      break; -    case 0x0468: -      bufpush(0x0469); -      break; -    case 0x046A: -      bufpush(0x046B); -      break; -    case 0x046C: -      bufpush(0x046D); -      break; -    case 0x046E: -      bufpush(0x046F); -      break; -    case 0x0470: -      bufpush(0x0471); -      break; -    case 0x0472: -      bufpush(0x0473); -      break; -    case 0x0474: -      bufpush(0x0475); -      break; -    case 0x0476: -      bufpush(0x0477); -      break; -    case 0x0478: -      bufpush(0x0479); -      break; -    case 0x047A: -      bufpush(0x047B); -      break; -    case 0x047C: -      bufpush(0x047D); -      break; -    case 0x047E: -      bufpush(0x047F); -      break; -    case 0x0480: -      bufpush(0x0481); -      break; -    case 0x048A: -      bufpush(0x048B); -      break; -    case 0x048C: -      bufpush(0x048D); -      break; -    case 0x048E: -      bufpush(0x048F); -      break; -    case 0x0490: -      bufpush(0x0491); -      break; -    case 0x0492: -      bufpush(0x0493); -      break; -    case 0x0494: -      bufpush(0x0495); -      break; -    case 0x0496: -      bufpush(0x0497); -      break; -    case 0x0498: -      bufpush(0x0499); -      break; -    case 0x049A: -      bufpush(0x049B); -      break; -    case 0x049C: -      bufpush(0x049D); -      break; -    case 0x049E: -      bufpush(0x049F); -      break; -    case 0x04A0: -      bufpush(0x04A1); -      break; -    case 0x04A2: -      bufpush(0x04A3); -      break; -    case 0x04A4: -      bufpush(0x04A5); -      break; -    case 0x04A6: -      bufpush(0x04A7); -      break; -    case 0x04A8: -      bufpush(0x04A9); -      break; -    case 0x04AA: -      bufpush(0x04AB); -      break; -    case 0x04AC: -      bufpush(0x04AD); -      break; -    case 0x04AE: -      bufpush(0x04AF); -      break; -    case 0x04B0: -      bufpush(0x04B1); -      break; -    case 0x04B2: -      bufpush(0x04B3); -      break; -    case 0x04B4: -      bufpush(0x04B5); -      break; -    case 0x04B6: -      bufpush(0x04B7); -      break; -    case 0x04B8: -      bufpush(0x04B9); -      break; -    case 0x04BA: -      bufpush(0x04BB); -      break; -    case 0x04BC: -      bufpush(0x04BD); -      break; -    case 0x04BE: -      bufpush(0x04BF); -      break; -    case 0x04C1: -      bufpush(0x04C2); -      break; -    case 0x04C3: -      bufpush(0x04C4); -      break; -    case 0x04C5: -      bufpush(0x04C6); -      break; -    case 0x04C7: -      bufpush(0x04C8); -      break; -    case 0x04C9: -      bufpush(0x04CA); -      break; -    case 0x04CB: -      bufpush(0x04CC); -      break; -    case 0x04CD: -      bufpush(0x04CE); -      break; -    case 0x04D0: -      bufpush(0x04D1); -      break; -    case 0x04D2: -      bufpush(0x04D3); -      break; -    case 0x04D4: -      bufpush(0x04D5); -      break; -    case 0x04D6: -      bufpush(0x04D7); -      break; -    case 0x04D8: -      bufpush(0x04D9); -      break; -    case 0x04DA: -      bufpush(0x04DB); -      break; -    case 0x04DC: -      bufpush(0x04DD); -      break; -    case 0x04DE: -      bufpush(0x04DF); -      break; -    case 0x04E0: -      bufpush(0x04E1); -      break; -    case 0x04E2: -      bufpush(0x04E3); -      break; -    case 0x04E4: -      bufpush(0x04E5); -      break; -    case 0x04E6: -      bufpush(0x04E7); -      break; -    case 0x04E8: -      bufpush(0x04E9); -      break; -    case 0x04EA: -      bufpush(0x04EB); -      break; -    case 0x04EC: -      bufpush(0x04ED); -      break; -    case 0x04EE: -      bufpush(0x04EF); -      break; -    case 0x04F0: -      bufpush(0x04F1); -      break; -    case 0x04F2: -      bufpush(0x04F3); -      break; -    case 0x04F4: -      bufpush(0x04F5); -      break; -    case 0x04F8: -      bufpush(0x04F9); -      break; -    case 0x0500: -      bufpush(0x0501); -      break; -    case 0x0502: -      bufpush(0x0503); -      break; -    case 0x0504: -      bufpush(0x0505); -      break; -    case 0x0506: -      bufpush(0x0507); -      break; -    case 0x0508: -      bufpush(0x0509); -      break; -    case 0x050A: -      bufpush(0x050B); -      break; -    case 0x050C: -      bufpush(0x050D); -      break; -    case 0x050E: -      bufpush(0x050F); -      break; -    case 0x0531: -      bufpush(0x0561); -      break; -    case 0x0532: -      bufpush(0x0562); -      break; -    case 0x0533: -      bufpush(0x0563); -      break; -    case 0x0534: -      bufpush(0x0564); -      break; -    case 0x0535: -      bufpush(0x0565); -      break; -    case 0x0536: -      bufpush(0x0566); -      break; -    case 0x0537: -      bufpush(0x0567); -      break; -    case 0x0538: -      bufpush(0x0568); -      break; -    case 0x0539: -      bufpush(0x0569); -      break; -    case 0x053A: -      bufpush(0x056A); -      break; -    case 0x053B: -      bufpush(0x056B); -      break; -    case 0x053C: -      bufpush(0x056C); -      break; -    case 0x053D: -      bufpush(0x056D); -      break; -    case 0x053E: -      bufpush(0x056E); -      break; -    case 0x053F: -      bufpush(0x056F); -      break; -    case 0x0540: -      bufpush(0x0570); -      break; -    case 0x0541: -      bufpush(0x0571); -      break; -    case 0x0542: -      bufpush(0x0572); -      break; -    case 0x0543: -      bufpush(0x0573); -      break; -    case 0x0544: -      bufpush(0x0574); -      break; -    case 0x0545: -      bufpush(0x0575); -      break; -    case 0x0546: -      bufpush(0x0576); -      break; -    case 0x0547: -      bufpush(0x0577); -      break; -    case 0x0548: -      bufpush(0x0578); -      break; -    case 0x0549: -      bufpush(0x0579); -      break; -    case 0x054A: -      bufpush(0x057A); -      break; -    case 0x054B: -      bufpush(0x057B); -      break; -    case 0x054C: -      bufpush(0x057C); -      break; -    case 0x054D: -      bufpush(0x057D); -      break; -    case 0x054E: -      bufpush(0x057E); -      break; -    case 0x054F: -      bufpush(0x057F); -      break; -    case 0x0550: -      bufpush(0x0580); -      break; -    case 0x0551: -      bufpush(0x0581); -      break; -    case 0x0552: -      bufpush(0x0582); -      break; -    case 0x0553: -      bufpush(0x0583); -      break; -    case 0x0554: -      bufpush(0x0584); -      break; -    case 0x0555: -      bufpush(0x0585); -      break; -    case 0x0556: -      bufpush(0x0586); -      break; -    case 0x0587: -      bufpush(0x0565); -      bufpush(0x0582); -      break; -    case 0x1E00: -      bufpush(0x1E01); -      break; -    case 0x1E02: -      bufpush(0x1E03); -      break; -    case 0x1E04: -      bufpush(0x1E05); -      break; -    case 0x1E06: -      bufpush(0x1E07); -      break; -    case 0x1E08: -      bufpush(0x1E09); -      break; -    case 0x1E0A: -      bufpush(0x1E0B); -      break; -    case 0x1E0C: -      bufpush(0x1E0D); -      break; -    case 0x1E0E: -      bufpush(0x1E0F); -      break; -    case 0x1E10: -      bufpush(0x1E11); -      break; -    case 0x1E12: -      bufpush(0x1E13); -      break; -    case 0x1E14: -      bufpush(0x1E15); -      break; -    case 0x1E16: -      bufpush(0x1E17); -      break; -    case 0x1E18: -      bufpush(0x1E19); -      break; -    case 0x1E1A: -      bufpush(0x1E1B); -      break; -    case 0x1E1C: -      bufpush(0x1E1D); -      break; -    case 0x1E1E: -      bufpush(0x1E1F); -      break; -    case 0x1E20: -      bufpush(0x1E21); -      break; -    case 0x1E22: -      bufpush(0x1E23); -      break; -    case 0x1E24: -      bufpush(0x1E25); -      break; -    case 0x1E26: -      bufpush(0x1E27); -      break; -    case 0x1E28: -      bufpush(0x1E29); -      break; -    case 0x1E2A: -      bufpush(0x1E2B); -      break; -    case 0x1E2C: -      bufpush(0x1E2D); -      break; -    case 0x1E2E: -      bufpush(0x1E2F); -      break; -    case 0x1E30: -      bufpush(0x1E31); -      break; -    case 0x1E32: -      bufpush(0x1E33); -      break; -    case 0x1E34: -      bufpush(0x1E35); -      break; -    case 0x1E36: -      bufpush(0x1E37); -      break; -    case 0x1E38: -      bufpush(0x1E39); -      break; -    case 0x1E3A: -      bufpush(0x1E3B); -      break; -    case 0x1E3C: -      bufpush(0x1E3D); -      break; -    case 0x1E3E: -      bufpush(0x1E3F); -      break; -    case 0x1E40: -      bufpush(0x1E41); -      break; -    case 0x1E42: -      bufpush(0x1E43); -      break; -    case 0x1E44: -      bufpush(0x1E45); -      break; -    case 0x1E46: -      bufpush(0x1E47); -      break; -    case 0x1E48: -      bufpush(0x1E49); -      break; -    case 0x1E4A: -      bufpush(0x1E4B); -      break; -    case 0x1E4C: -      bufpush(0x1E4D); -      break; -    case 0x1E4E: -      bufpush(0x1E4F); -      break; -    case 0x1E50: -      bufpush(0x1E51); -      break; -    case 0x1E52: -      bufpush(0x1E53); -      break; -    case 0x1E54: -      bufpush(0x1E55); -      break; -    case 0x1E56: -      bufpush(0x1E57); -      break; -    case 0x1E58: -      bufpush(0x1E59); -      break; -    case 0x1E5A: -      bufpush(0x1E5B); -      break; -    case 0x1E5C: -      bufpush(0x1E5D); -      break; -    case 0x1E5E: -      bufpush(0x1E5F); -      break; -    case 0x1E60: -      bufpush(0x1E61); -      break; -    case 0x1E62: -      bufpush(0x1E63); -      break; -    case 0x1E64: -      bufpush(0x1E65); -      break; -    case 0x1E66: -      bufpush(0x1E67); -      break; -    case 0x1E68: -      bufpush(0x1E69); -      break; -    case 0x1E6A: -      bufpush(0x1E6B); -      break; -    case 0x1E6C: -      bufpush(0x1E6D); -      break; -    case 0x1E6E: -      bufpush(0x1E6F); -      break; -    case 0x1E70: -      bufpush(0x1E71); -      break; -    case 0x1E72: -      bufpush(0x1E73); -      break; -    case 0x1E74: -      bufpush(0x1E75); -      break; -    case 0x1E76: -      bufpush(0x1E77); -      break; -    case 0x1E78: -      bufpush(0x1E79); -      break; -    case 0x1E7A: -      bufpush(0x1E7B); -      break; -    case 0x1E7C: -      bufpush(0x1E7D); -      break; -    case 0x1E7E: -      bufpush(0x1E7F); -      break; -    case 0x1E80: -      bufpush(0x1E81); -      break; -    case 0x1E82: -      bufpush(0x1E83); -      break; -    case 0x1E84: -      bufpush(0x1E85); -      break; -    case 0x1E86: -      bufpush(0x1E87); -      break; -    case 0x1E88: -      bufpush(0x1E89); -      break; -    case 0x1E8A: -      bufpush(0x1E8B); -      break; -    case 0x1E8C: -      bufpush(0x1E8D); -      break; -    case 0x1E8E: -      bufpush(0x1E8F); -      break; -    case 0x1E90: -      bufpush(0x1E91); -      break; -    case 0x1E92: -      bufpush(0x1E93); -      break; -    case 0x1E94: -      bufpush(0x1E95); -      break; -    case 0x1E96: -      bufpush(0x0068); -      bufpush(0x0331); -      break; -    case 0x1E97: -      bufpush(0x0074); -      bufpush(0x0308); -      break; -    case 0x1E98: -      bufpush(0x0077); -      bufpush(0x030A); -      break; -    case 0x1E99: -      bufpush(0x0079); -      bufpush(0x030A); -      break; -    case 0x1E9A: -      bufpush(0x0061); -      bufpush(0x02BE); -      break; -    case 0x1E9B: -      bufpush(0x1E61); -      break; -    case 0x1EA0: -      bufpush(0x1EA1); -      break; -    case 0x1EA2: -      bufpush(0x1EA3); -      break; -    case 0x1EA4: -      bufpush(0x1EA5); -      break; -    case 0x1EA6: -      bufpush(0x1EA7); -      break; -    case 0x1EA8: -      bufpush(0x1EA9); -      break; -    case 0x1EAA: -      bufpush(0x1EAB); -      break; -    case 0x1EAC: -      bufpush(0x1EAD); -      break; -    case 0x1EAE: -      bufpush(0x1EAF); -      break; -    case 0x1EB0: -      bufpush(0x1EB1); -      break; -    case 0x1EB2: -      bufpush(0x1EB3); -      break; -    case 0x1EB4: -      bufpush(0x1EB5); -      break; -    case 0x1EB6: -      bufpush(0x1EB7); -      break; -    case 0x1EB8: -      bufpush(0x1EB9); -      break; -    case 0x1EBA: -      bufpush(0x1EBB); -      break; -    case 0x1EBC: -      bufpush(0x1EBD); -      break; -    case 0x1EBE: -      bufpush(0x1EBF); -      break; -    case 0x1EC0: -      bufpush(0x1EC1); -      break; -    case 0x1EC2: -      bufpush(0x1EC3); -      break; -    case 0x1EC4: -      bufpush(0x1EC5); -      break; -    case 0x1EC6: -      bufpush(0x1EC7); -      break; -    case 0x1EC8: -      bufpush(0x1EC9); -      break; -    case 0x1ECA: -      bufpush(0x1ECB); -      break; -    case 0x1ECC: -      bufpush(0x1ECD); -      break; -    case 0x1ECE: -      bufpush(0x1ECF); -      break; -    case 0x1ED0: -      bufpush(0x1ED1); -      break; -    case 0x1ED2: -      bufpush(0x1ED3); -      break; -    case 0x1ED4: -      bufpush(0x1ED5); -      break; -    case 0x1ED6: -      bufpush(0x1ED7); -      break; -    case 0x1ED8: -      bufpush(0x1ED9); -      break; -    case 0x1EDA: -      bufpush(0x1EDB); -      break; -    case 0x1EDC: -      bufpush(0x1EDD); -      break; -    case 0x1EDE: -      bufpush(0x1EDF); -      break; -    case 0x1EE0: -      bufpush(0x1EE1); -      break; -    case 0x1EE2: -      bufpush(0x1EE3); -      break; -    case 0x1EE4: -      bufpush(0x1EE5); -      break; -    case 0x1EE6: -      bufpush(0x1EE7); -      break; -    case 0x1EE8: -      bufpush(0x1EE9); -      break; -    case 0x1EEA: -      bufpush(0x1EEB); -      break; -    case 0x1EEC: -      bufpush(0x1EED); -      break; -    case 0x1EEE: -      bufpush(0x1EEF); -      break; -    case 0x1EF0: -      bufpush(0x1EF1); -      break; -    case 0x1EF2: -      bufpush(0x1EF3); -      break; -    case 0x1EF4: -      bufpush(0x1EF5); -      break; -    case 0x1EF6: -      bufpush(0x1EF7); -      break; -    case 0x1EF8: -      bufpush(0x1EF9); -      break; -    case 0x1F08: -      bufpush(0x1F00); -      break; -    case 0x1F09: -      bufpush(0x1F01); -      break; -    case 0x1F0A: -      bufpush(0x1F02); -      break; -    case 0x1F0B: -      bufpush(0x1F03); -      break; -    case 0x1F0C: -      bufpush(0x1F04); -      break; -    case 0x1F0D: -      bufpush(0x1F05); -      break; -    case 0x1F0E: -      bufpush(0x1F06); -      break; -    case 0x1F0F: -      bufpush(0x1F07); -      break; -    case 0x1F18: -      bufpush(0x1F10); -      break; -    case 0x1F19: -      bufpush(0x1F11); -      break; -    case 0x1F1A: -      bufpush(0x1F12); -      break; -    case 0x1F1B: -      bufpush(0x1F13); -      break; -    case 0x1F1C: -      bufpush(0x1F14); -      break; -    case 0x1F1D: -      bufpush(0x1F15); -      break; -    case 0x1F28: -      bufpush(0x1F20); -      break; -    case 0x1F29: -      bufpush(0x1F21); -      break; -    case 0x1F2A: -      bufpush(0x1F22); -      break; -    case 0x1F2B: -      bufpush(0x1F23); -      break; -    case 0x1F2C: -      bufpush(0x1F24); -      break; -    case 0x1F2D: -      bufpush(0x1F25); -      break; -    case 0x1F2E: -      bufpush(0x1F26); -      break; -    case 0x1F2F: -      bufpush(0x1F27); -      break; -    case 0x1F38: -      bufpush(0x1F30); -      break; -    case 0x1F39: -      bufpush(0x1F31); -      break; -    case 0x1F3A: -      bufpush(0x1F32); -      break; -    case 0x1F3B: -      bufpush(0x1F33); -      break; -    case 0x1F3C: -      bufpush(0x1F34); -      break; -    case 0x1F3D: -      bufpush(0x1F35); -      break; -    case 0x1F3E: -      bufpush(0x1F36); -      break; -    case 0x1F3F: -      bufpush(0x1F37); -      break; -    case 0x1F48: -      bufpush(0x1F40); -      break; -    case 0x1F49: -      bufpush(0x1F41); -      break; -    case 0x1F4A: -      bufpush(0x1F42); -      break; -    case 0x1F4B: -      bufpush(0x1F43); -      break; -    case 0x1F4C: -      bufpush(0x1F44); -      break; -    case 0x1F4D: -      bufpush(0x1F45); -      break; -    case 0x1F50: -      bufpush(0x03C5); -      bufpush(0x0313); -      break; -    case 0x1F52: -      bufpush(0x03C5); -      bufpush(0x0313); -      bufpush(0x0300); -      break; -    case 0x1F54: -      bufpush(0x03C5); -      bufpush(0x0313); -      bufpush(0x0301); -      break; -    case 0x1F56: -      bufpush(0x03C5); -      bufpush(0x0313); -      bufpush(0x0342); -      break; -    case 0x1F59: -      bufpush(0x1F51); -      break; -    case 0x1F5B: -      bufpush(0x1F53); -      break; -    case 0x1F5D: -      bufpush(0x1F55); -      break; -    case 0x1F5F: -      bufpush(0x1F57); -      break; -    case 0x1F68: -      bufpush(0x1F60); -      break; -    case 0x1F69: -      bufpush(0x1F61); -      break; -    case 0x1F6A: -      bufpush(0x1F62); -      break; -    case 0x1F6B: -      bufpush(0x1F63); -      break; -    case 0x1F6C: -      bufpush(0x1F64); -      break; -    case 0x1F6D: -      bufpush(0x1F65); -      break; -    case 0x1F6E: -      bufpush(0x1F66); -      break; -    case 0x1F6F: -      bufpush(0x1F67); -      break; -    case 0x1F80: -      bufpush(0x1F00); -      bufpush(0x03B9); -      break; -    case 0x1F81: -      bufpush(0x1F01); -      bufpush(0x03B9); -      break; -    case 0x1F82: -      bufpush(0x1F02); -      bufpush(0x03B9); -      break; -    case 0x1F83: -      bufpush(0x1F03); -      bufpush(0x03B9); -      break; -    case 0x1F84: -      bufpush(0x1F04); -      bufpush(0x03B9); -      break; -    case 0x1F85: -      bufpush(0x1F05); -      bufpush(0x03B9); -      break; -    case 0x1F86: -      bufpush(0x1F06); -      bufpush(0x03B9); -      break; -    case 0x1F87: -      bufpush(0x1F07); -      bufpush(0x03B9); -      break; -    case 0x1F88: -      bufpush(0x1F00); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F89: -      bufpush(0x1F01); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F8A: -      bufpush(0x1F02); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F8B: -      bufpush(0x1F03); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F8C: -      bufpush(0x1F04); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F8D: -      bufpush(0x1F05); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F8E: -      bufpush(0x1F06); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F8F: -      bufpush(0x1F07); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F90: -      bufpush(0x1F20); -      bufpush(0x03B9); -      break; -    case 0x1F91: -      bufpush(0x1F21); -      bufpush(0x03B9); -      break; -    case 0x1F92: -      bufpush(0x1F22); -      bufpush(0x03B9); -      break; -    case 0x1F93: -      bufpush(0x1F23); -      bufpush(0x03B9); -      break; -    case 0x1F94: -      bufpush(0x1F24); -      bufpush(0x03B9); -      break; -    case 0x1F95: -      bufpush(0x1F25); -      bufpush(0x03B9); -      break; -    case 0x1F96: -      bufpush(0x1F26); -      bufpush(0x03B9); -      break; -    case 0x1F97: -      bufpush(0x1F27); -      bufpush(0x03B9); -      break; -    case 0x1F98: -      bufpush(0x1F20); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F99: -      bufpush(0x1F21); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F9A: -      bufpush(0x1F22); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F9B: -      bufpush(0x1F23); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F9C: -      bufpush(0x1F24); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F9D: -      bufpush(0x1F25); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F9E: -      bufpush(0x1F26); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1F9F: -      bufpush(0x1F27); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FA0: -      bufpush(0x1F60); -      bufpush(0x03B9); -      break; -    case 0x1FA1: -      bufpush(0x1F61); -      bufpush(0x03B9); -      break; -    case 0x1FA2: -      bufpush(0x1F62); -      bufpush(0x03B9); -      break; -    case 0x1FA3: -      bufpush(0x1F63); -      bufpush(0x03B9); -      break; -    case 0x1FA4: -      bufpush(0x1F64); -      bufpush(0x03B9); -      break; -    case 0x1FA5: -      bufpush(0x1F65); -      bufpush(0x03B9); -      break; -    case 0x1FA6: -      bufpush(0x1F66); -      bufpush(0x03B9); -      break; -    case 0x1FA7: -      bufpush(0x1F67); -      bufpush(0x03B9); -      break; -    case 0x1FA8: -      bufpush(0x1F60); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FA9: -      bufpush(0x1F61); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FAA: -      bufpush(0x1F62); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FAB: -      bufpush(0x1F63); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FAC: -      bufpush(0x1F64); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FAD: -      bufpush(0x1F65); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FAE: -      bufpush(0x1F66); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FAF: -      bufpush(0x1F67); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FB2: -      bufpush(0x1F70); -      bufpush(0x03B9); -      break; -    case 0x1FB3: -      bufpush(0x03B1); -      bufpush(0x03B9); -      break; -    case 0x1FB4: -      bufpush(0x03AC); -      bufpush(0x03B9); -      break; -    case 0x1FB6: -      bufpush(0x03B1); -      bufpush(0x0342); -      break; -    case 0x1FB7: -      bufpush(0x03B1); -      bufpush(0x0342); -      bufpush(0x03B9); -      break; -    case 0x1FB8: -      bufpush(0x1FB0); -      break; -    case 0x1FB9: -      bufpush(0x1FB1); -      break; -    case 0x1FBA: -      bufpush(0x1F70); -      break; -    case 0x1FBB: -      bufpush(0x1F71); -      break; -    case 0x1FBC: -      bufpush(0x03B1); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FBE: -      bufpush(0x03B9); -      break; -    case 0x1FC2: -      bufpush(0x1F74); -      bufpush(0x03B9); -      break; -    case 0x1FC3: -      bufpush(0x03B7); -      bufpush(0x03B9); -      break; -    case 0x1FC4: -      bufpush(0x03AE); -      bufpush(0x03B9); -      break; -    case 0x1FC6: -      bufpush(0x03B7); -      bufpush(0x0342); -      break; -    case 0x1FC7: -      bufpush(0x03B7); -      bufpush(0x0342); -      bufpush(0x03B9); -      break; -    case 0x1FC8: -      bufpush(0x1F72); -      break; -    case 0x1FC9: -      bufpush(0x1F73); -      break; -    case 0x1FCA: -      bufpush(0x1F74); -      break; -    case 0x1FCB: -      bufpush(0x1F75); -      break; -    case 0x1FCC: -      bufpush(0x03B7); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x1FD2: -      bufpush(0x03B9); -      bufpush(0x0308); -      bufpush(0x0300); -      break; -    case 0x1FD3: -      bufpush(0x03B9); -      bufpush(0x0308); -      bufpush(0x0301); -      break; -    case 0x1FD6: -      bufpush(0x03B9); -      bufpush(0x0342); -      break; -    case 0x1FD7: -      bufpush(0x03B9); -      bufpush(0x0308); -      bufpush(0x0342); -      break; -    case 0x1FD8: -      bufpush(0x1FD0); -      break; -    case 0x1FD9: -      bufpush(0x1FD1); -      break; -    case 0x1FDA: -      bufpush(0x1F76); -      break; -    case 0x1FDB: -      bufpush(0x1F77); -      break; -    case 0x1FE2: -      bufpush(0x03C5); -      bufpush(0x0308); -      bufpush(0x0300); -      break; -    case 0x1FE3: -      bufpush(0x03C5); -      bufpush(0x0308); -      bufpush(0x0301); -      break; -    case 0x1FE4: -      bufpush(0x03C1); -      bufpush(0x0313); -      break; -    case 0x1FE6: -      bufpush(0x03C5); -      bufpush(0x0342); -      break; -    case 0x1FE7: -      bufpush(0x03C5); -      bufpush(0x0308); -      bufpush(0x0342); -      break; -    case 0x1FE8: -      bufpush(0x1FE0); -      break; -    case 0x1FE9: -      bufpush(0x1FE1); -      break; -    case 0x1FEA: -      bufpush(0x1F7A); -      break; -    case 0x1FEB: -      bufpush(0x1F7B); -      break; -    case 0x1FEC: -      bufpush(0x1FE5); -      break; -    case 0x1FF2: -      bufpush(0x1F7C); -      bufpush(0x03B9); -      break; -    case 0x1FF3: -      bufpush(0x03C9); -      bufpush(0x03B9); -      break; -    case 0x1FF4: -      bufpush(0x03CE); -      bufpush(0x03B9); -      break; -    case 0x1FF6: -      bufpush(0x03C9); -      bufpush(0x0342); -      break; -    case 0x1FF7: -      bufpush(0x03C9); -      bufpush(0x0342); -      bufpush(0x03B9); -      break; -    case 0x1FF8: -      bufpush(0x1F78); -      break; -    case 0x1FF9: -      bufpush(0x1F79); -      break; -    case 0x1FFA: -      bufpush(0x1F7C); -      break; -    case 0x1FFB: -      bufpush(0x1F7D); -      break; -    case 0x1FFC: -      bufpush(0x03C9); -      bufpush(0x03B9); -      break; -    case 0x: -      break; -    case 0x2126: -      bufpush(0x03C9); -      break; -    case 0x212A: -      bufpush(0x006B); -      break; -    case 0x212B: -      bufpush(0x00E5); -      break; -    case 0x2160: -      bufpush(0x2170); -      break; -    case 0x2161: -      bufpush(0x2171); -      break; -    case 0x2162: -      bufpush(0x2172); -      break; -    case 0x2163: -      bufpush(0x2173); -      break; -    case 0x2164: -      bufpush(0x2174); -      break; -    case 0x2165: -      bufpush(0x2175); -      break; -    case 0x2166: -      bufpush(0x2176); -      break; -    case 0x2167: -      bufpush(0x2177); -      break; -    case 0x2168: -      bufpush(0x2178); -      break; -    case 0x2169: -      bufpush(0x2179); -      break; -    case 0x216A: -      bufpush(0x217A); -      break; -    case 0x216B: -      bufpush(0x217B); -      break; -    case 0x216C: -      bufpush(0x217C); -      break; -    case 0x216D: -      bufpush(0x217D); -      break; -    case 0x216E: -      bufpush(0x217E); -      break; -    case 0x216F: -      bufpush(0x217F); -      break; -    case 0x24B6: -      bufpush(0x24D0); -      break; -    case 0x24B7: -      bufpush(0x24D1); -      break; -    case 0x24B8: -      bufpush(0x24D2); -      break; -    case 0x24B9: -      bufpush(0x24D3); -      break; -    case 0x24BA: -      bufpush(0x24D4); -      break; -    case 0x24BB: -      bufpush(0x24D5); -      break; -    case 0x24BC: -      bufpush(0x24D6); -      break; -    case 0x24BD: -      bufpush(0x24D7); -      break; -    case 0x24BE: -      bufpush(0x24D8); -      break; -    case 0x24BF: -      bufpush(0x24D9); -      break; -    case 0x24C0: -      bufpush(0x24DA); -      break; -    case 0x24C1: -      bufpush(0x24DB); -      break; -    case 0x24C2: -      bufpush(0x24DC); -      break; -    case 0x24C3: -      bufpush(0x24DD); -      break; -    case 0x24C4: -      bufpush(0x24DE); -      break; -    case 0x24C5: -      bufpush(0x24DF); -      break; -    case 0x24C6: -      bufpush(0x24E0); -      break; -    case 0x24C7: -      bufpush(0x24E1); -      break; -    case 0x24C8: -      bufpush(0x24E2); -      break; -    case 0x24C9: -      bufpush(0x24E3); -      break; -    case 0x24CA: -      bufpush(0x24E4); -      break; -    case 0x24CB: -      bufpush(0x24E5); -      break; -    case 0x24CC: -      bufpush(0x24E6); -      break; -    case 0x24CD: -      bufpush(0x24E7); -      break; -    case 0x24CE: -      bufpush(0x24E8); -      break; -    case 0x24CF: -      bufpush(0x24E9); -      break; -    case 0xFB00: -      bufpush(0x0066); -      bufpush(0x0066); -      break; -    case 0xFB01: -      bufpush(0x0066); -      bufpush(0x0069); -      break; -    case 0xFB02: -      bufpush(0x0066); -      bufpush(0x006C); -      break; -    case 0xFB03: -      bufpush(0x0066); -      bufpush(0x0066); -      bufpush(0x0069); -      break; -    case 0xFB04: -      bufpush(0x0066); -      bufpush(0x0066); -      bufpush(0x006C); -      break; -    case 0xFB05: -      bufpush(0x0073); -      bufpush(0x0074); -      break; -    case 0xFB06: -      bufpush(0x0073); -      bufpush(0x0074); -      break; -    case 0xFB13: -      bufpush(0x0574); -      bufpush(0x0576); -      break; -    case 0xFB14: -      bufpush(0x0574); -      bufpush(0x0565); -      break; -    case 0xFB15: -      bufpush(0x0574); -      bufpush(0x056B); -      break; -    case 0xFB16: -      bufpush(0x057E); -      bufpush(0x0576); -      break; -    case 0xFB17: -      bufpush(0x0574); -      bufpush(0x056D); -      break; -    case 0xFF21: -      bufpush(0xFF41); -      break; -    case 0xFF22: -      bufpush(0xFF42); -      break; -    case 0xFF23: -      bufpush(0xFF43); -      break; -    case 0xFF24: -      bufpush(0xFF44); -      break; -    case 0xFF25: -      bufpush(0xFF45); -      break; -    case 0xFF26: -      bufpush(0xFF46); -      break; -    case 0xFF27: -      bufpush(0xFF47); -      break; -    case 0xFF28: -      bufpush(0xFF48); -      break; -    case 0xFF29: -      bufpush(0xFF49); -      break; -    case 0xFF2A: -      bufpush(0xFF4A); -      break; -    case 0xFF2B: -      bufpush(0xFF4B); -      break; -    case 0xFF2C: -      bufpush(0xFF4C); -      break; -    case 0xFF2D: -      bufpush(0xFF4D); -      break; -    case 0xFF2E: -      bufpush(0xFF4E); -      break; -    case 0xFF2F: -      bufpush(0xFF4F); -      break; -    case 0xFF30: -      bufpush(0xFF50); -      break; -    case 0xFF31: -      bufpush(0xFF51); -      break; -    case 0xFF32: -      bufpush(0xFF52); -      break; -    case 0xFF33: -      bufpush(0xFF53); -      break; -    case 0xFF34: -      bufpush(0xFF54); -      break; -    case 0xFF35: -      bufpush(0xFF55); -      break; -    case 0xFF36: -      bufpush(0xFF56); -      break; -    case 0xFF37: -      bufpush(0xFF57); -      break; -    case 0xFF38: -      bufpush(0xFF58); -      break; -    case 0xFF39: -      bufpush(0xFF59); -      break; -    case 0xFF3A: -      bufpush(0xFF5A); -      break; -    case 0x10400: -      bufpush(0x10428); -      break; -    case 0x10401: -      bufpush(0x10429); -      break; -    case 0x10402: -      bufpush(0x1042A); -      break; -    case 0x10403: -      bufpush(0x1042B); -      break; -    case 0x10404: -      bufpush(0x1042C); -      break; -    case 0x10405: -      bufpush(0x1042D); -      break; -    case 0x10406: -      bufpush(0x1042E); -      break; -    case 0x10407: -      bufpush(0x1042F); -      break; -    case 0x10408: -      bufpush(0x10430); -      break; -    case 0x10409: -      bufpush(0x10431); -      break; -    case 0x1040A: -      bufpush(0x10432); -      break; -    case 0x1040B: -      bufpush(0x10433); -      break; -    case 0x1040C: -      bufpush(0x10434); -      break; -    case 0x1040D: -      bufpush(0x10435); -      break; -    case 0x1040E: -      bufpush(0x10436); -      break; -    case 0x1040F: -      bufpush(0x10437); -      break; -    case 0x10410: -      bufpush(0x10438); -      break; -    case 0x10411: -      bufpush(0x10439); -      break; -    case 0x10412: -      bufpush(0x1043A); -      break; -    case 0x10413: -      bufpush(0x1043B); -      break; -    case 0x10414: -      bufpush(0x1043C); -      break; -    case 0x10415: -      bufpush(0x1043D); -      break; -    case 0x10416: -      bufpush(0x1043E); -      break; -    case 0x10417: -      bufpush(0x1043F); -      break; -    case 0x10418: -      bufpush(0x10440); -      break; -    case 0x10419: -      bufpush(0x10441); -      break; -    case 0x1041A: -      bufpush(0x10442); -      break; -    case 0x1041B: -      bufpush(0x10443); -      break; -    case 0x1041C: -      bufpush(0x10444); -      break; -    case 0x1041D: -      bufpush(0x10445); -      break; -    case 0x1041E: -      bufpush(0x10446); -      break; -    case 0x1041F: -      bufpush(0x10447); -      break; -    case 0x10420: -      bufpush(0x10448); -      break; -    case 0x10421: -      bufpush(0x10449); -      break; -    case 0x10422: -      bufpush(0x1044A); -      break; -    case 0x10423: -      bufpush(0x1044B); -      break; -    case 0x10424: -      bufpush(0x1044C); -      break; -    case 0x10425: -      bufpush(0x1044D); -      break; -  } diff --git a/src/chunk.h b/src/chunk.h new file mode 100644 index 0000000..f37a2f3 --- /dev/null +++ b/src/chunk.h @@ -0,0 +1,92 @@ +#ifndef _CHUNK_H_ +#define _CHUNK_H_ + +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <assert.h> +#include "buffer.h" + +typedef struct { +	const unsigned char *data; +	int len; +	int alloc; +} chunk; + +static inline void chunk_free(chunk *c) +{ +	if (c->alloc) +		free((char *)c->data); + +	c->data = NULL; +	c->alloc = 0; +	c->len = 0; +} + +static inline void chunk_ltrim(chunk *c) +{ +	assert(!c->alloc); + +	while (c->len && isspace(c->data[0])) { +		c->data++; +		c->len--; +	} +} + +static inline void chunk_rtrim(chunk *c) +{ +	while (c->len > 0) { +		if (!isspace(c->data[c->len - 1])) +			break; + +		c->len--; +	} +} + +static inline void chunk_trim(chunk *c) +{ +	chunk_ltrim(c); +	chunk_rtrim(c); +} + +static inline int chunk_strchr(chunk *ch, int c, int offset) +{ +	const unsigned char *p = memchr(ch->data + offset, c, ch->len - offset); +	return p ? (int)(p - ch->data) : ch->len; +} + +static inline unsigned char *chunk_to_cstr(chunk *c) +{ +	unsigned char *str; + +	str = malloc(c->len + 1); +	memcpy(str, c->data, c->len); +	str[c->len] = 0; + +	return str; +} + +static inline chunk chunk_literal(const char *data) +{ +	chunk c = {(const unsigned char *)data, data ? strlen(data) : 0, 0}; +	return c; +} + +static inline chunk chunk_dup(const chunk *ch, int pos, int len) +{ +	chunk c = {ch->data + pos, len, 0}; +	return c; +} + +static inline chunk chunk_buf_detach(strbuf *buf) +{ +	chunk c; + +	c.len = buf->size; +	c.data = strbuf_detach(buf); +	c.alloc = 1; + +	return c; +} + +#endif diff --git a/src/detab.c b/src/detab.c deleted file mode 100644 index e03fcf7..0000000 --- a/src/detab.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "bstrlib.h" - -// UTF-8 aware detab:  assumes s has no newlines, or only a final newline. -// Return 0 on success, BSTR_ERR if invalid UTF-8. -extern int bdetab(bstring s, int utf8) -{ -  unsigned char c; -  int pos = 0;  // a count of characters -  int byte = 0; // a count of bytes -  int high_chars_to_skip = 0; -  int numspaces = 0; -  while ((c = bchar(s, byte))) { -    if (utf8 && high_chars_to_skip > 0) { -      if (c >= 0x80) { -        high_chars_to_skip--; -        byte++; -      } else { -        return BSTR_ERR; // invalid utf-8 -      } -    } else if (c == '\t') { -      bdelete(s, byte, 1); // delete tab character -      numspaces = 4 - (pos % 4); -      binsertch(s, byte, numspaces, ' '); -      byte += numspaces; -      pos  += numspaces; -    } else if (c <= 0x80 || !utf8) { -      byte++; -      pos++; -    } else {  // multibyte utf8 sequences -      if (c >> 1 == 0176) { -        high_chars_to_skip = 5; -      } else if (c >> 2 == 076) { -        high_chars_to_skip = 4; -      } else if (c >> 3 == 036) { -        high_chars_to_skip = 3; -      } else if (c >> 4 == 016) { -        high_chars_to_skip = 2; -      } else if (c >> 5 == 06) { -        high_chars_to_skip = 1; -      } else { -        return BSTR_ERR; // invalid utf-8 -      } -      pos++; -      byte++; -    } -  } -  return 0; -} diff --git a/src/getopt.c b/src/getopt.c deleted file mode 100644 index 321dd9f..0000000 --- a/src/getopt.c +++ /dev/null @@ -1,199 +0,0 @@ -/* $Id: getopt.c 4022 2008-03-31 06:11:07Z rra $ - * - * Replacement implementation of getopt. - * - * This is a replacement implementation for getopt based on the my_getopt - * distribution by Benjamin Sittler.  Only the getopt interface is included, - * since remctl doesn't use GNU long options, and the code has been rearranged - * and reworked somewhat to fit with the remctl coding style. - * - * Copyright 1997, 2000, 2001, 2002 Benjamin Sittler - * Copyright 2008 Russ Allbery <rra@stanford.edu> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - *   - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - *   - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> -#include <portable/system.h> -#include <portable/getopt.h> - -/* - * If we're running the test suite, rename getopt and the global variables to - * avoid conflicts with the system version. - */ -#if TESTING -# define getopt test_getopt -int test_getopt(int, char **, const char *); -# define optind test_optind -# define opterr test_opterr -# define optopt test_optopt -# define optarg test_optarg -#endif - -/* Initialize global interface variables. */ -int optind = 1; -int opterr = 1; -int optopt = 0; -char *optarg = NULL; - -/* - * This is the plain old UNIX getopt, with GNU-style extensions.  If you're - * porting some piece of UNIX software, this is all you need.  It supports - * GNU-style permutation and optional arguments, but does not support the GNU - * -W extension. - * - * This function is not re-entrant or thread-safe, has static variables, and - * generally isn't a great interface, but normally you only call it once. - */ -int -getopt(int argc, char *argv[], const char *optstring) -{ -    const char *p; -    size_t offset = 0; -    char mode = '\0'; -    int colon_mode = 0; -    int option = -1; - -    /* Holds the current position in the parameter being parsed. */ -    static int charind = 0; - -    /* -     * By default, getopt permutes argv as it scans and leaves all non-options -     * at the end.  This can be changed with the first character of optstring -     * or the environment variable POSIXLY_CORRECT.  With a first character of -     * '+' or when POSIXLY_CORRECT is set, option processing stops at the -     * first non-option.  If the first character is '-', each non-option argv -     * element is handled as if it were the argument of an option with -     * character code 1.  mode holds this character. -     * -     * After the optional leading '+' and '-', optstring may contain ':'.  If -     * present, missing arguments return ':' instead of '?'.  colon_mode holds -     * this setting. -     */ -    if (getenv("POSIXLY_CORRECT") != NULL) { -        mode = '+'; -        colon_mode = '+'; -    } else { -        if (optstring[offset] == '+' || optstring[offset] == '-') { -            mode = optstring[offset]; -            offset++; -        } -        if (optstring[offset] == ':') { -            colon_mode = 1; -            offset++; -        } -    } - -    /* -     * charind holds where we left off.  If it's set, we were in the middle -     * of an argv element; if not, we pick up with the next element of -     * optind. -     */ -    optarg = NULL; -    if (charind == 0) { -        if (optind >= argc) -            option = -1; -        else if (strcmp(argv[optind], "--") == 0) { -            optind++; -            option = -1; -        } else if (argv[optind][0] != '-' || argv[optind][1] == '\0') { -            char *tmp; -            int i, j, k, end; - -            if (mode == '+') -                option = -1; -            else if (mode == '-') { -                optarg = argv[optind]; -                optind++; -                option = 1; -            } else { -                for (i = optind + 1, j = optind; i < argc; i++) -                    if ((argv[i][0] == '-') && (argv[i][1] != '\0')) { -                        optind = i; -                        option = getopt(argc, argv, optstring); -                        while (i > j) { -                            --i; -                            tmp = argv[i]; -                            end = (charind == 0) ? optind - 1 : optind; -                            for (k = i; k + 1 <= end; k++) { -                                argv[k] = argv[k + 1]; -                            } -                            argv[end] = tmp; -                            --optind; -                        } -                        break; -                    } -                if (i == argc) -                    option = -1; -            } -            return option; -        } else { -            charind = 1; -        } -    } -    if (charind != 0) { -        optopt = argv[optind][charind]; -        for (p = optstring + offset; *p != '\0'; p++) -            if (optopt == *p) { -                p++; -                if (*p == ':') { -                    if (argv[optind][charind + 1] != '\0') { -                        optarg = &argv[optind][charind + 1]; -                        optind++; -                        charind = 0; -                    } else { -                        p++; -                        if (*p != ':') { -                            charind = 0; -                            optind++; -                            if (optind >= argc) { -                                if (opterr) -                                    fprintf(stderr, "%s: option requires" -                                            " an argument -- %c\n", argv[0], -                                            optopt); -                                option = colon_mode ? ':' : '?'; -                                goto done; -                            } else { -                                optarg = argv[optind]; -                                optind++; -                            } -                        } -                    } -                } -                option = optopt; -            } -        if (option == -1) { -            if (opterr) -                fprintf(stderr, "%s: illegal option -- %c\n", argv[0], optopt); -            option = '?'; -        } -    } - -done: -    if (charind != 0) { -        charind++; -        if (argv[optind][charind] == '\0') { -            optind++; -            charind = 0; -        } -    } -    if (optind > argc) -        optind = argc; -    return option; -} diff --git a/src/html.c b/src/html.c deleted file mode 100644 index aeec5f1..0000000 --- a/src/html.c +++ /dev/null @@ -1,276 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <stdbool.h> -#include "bstrlib.h" -#include "stmd.h" -#include "debug.h" -#include "scanners.h" - -// Functions to convert block and inline lists to HTML strings. - -// Escape special characters in HTML.  More efficient than -// three calls to bfindreplace.  If preserve_entities is set, -// existing entities are left alone. -static bstring escape_html(bstring inp, bool preserve_entities) -{ -  int pos = 0; -  int match; -  char c; -  bstring escapable = blk2bstr("&<>\"", 4); -  bstring ent; -  bstring s = bstrcpy(inp); -  while ((pos = binchr(s, pos, escapable)) != BSTR_ERR) { -    c = bchar(s,pos); -    switch (c) { -    case '<': -      bdelete(s, pos, 1); -      ent = blk2bstr("<", 4); -      binsert(s, pos, ent, ' '); -      bdestroy(ent); -      pos += 4; -      break; -    case '>': -      bdelete(s, pos, 1); -      ent = blk2bstr(">", 4); -      binsert(s, pos, ent, ' '); -      bdestroy(ent); -      pos += 4; -      break; -    case '&': -      if (preserve_entities && (match = scan_entity(s, pos))) { -        pos += match; -      } else { -        bdelete(s, pos, 1); -        ent = blk2bstr("&", 5); -        binsert(s, pos, ent, ' '); -        bdestroy(ent); -        pos += 5; -      } -      break; -    case '"': -      bdelete(s, pos, 1); -      ent = blk2bstr(""", 6); -      binsert(s, pos, ent, ' '); -      bdestroy(ent); -      pos += 6; -      break; -    default: -      bdelete(s, pos, 1); -      log_err("unexpected character %02x", c); -    } -  } -  bdestroy(escapable); -  return s; -} - -static inline void cr(bstring buffer) -{ -  int c = bchar(buffer, blength(buffer) - 1); -  if (c != '\n' && c) { -    bconchar(buffer, '\n'); -  } -} - -// Convert a block list to HTML.  Returns 0 on success, and sets result. -extern int blocks_to_html(block* b, bstring* result, bool tight) -{ -  bstring contents = NULL; -  bstring escaped, escaped2; -  struct bstrList * info_words; -  struct ListData * data; -  bstring mbstart; -  bstring html = blk2bstr("", 0); - -  while(b != NULL) { -    switch(b->tag) { -    case document: -      check(blocks_to_html(b->children, &contents, false) == 0, -            "error converting blocks to html"); -      bformata(html, "%s", contents->data); -      bdestroy(contents); -      break; -    case paragraph: -      check(inlines_to_html(b->inline_content, &contents) == 0, -            "error converting inlines to html"); -      if (tight) { -        bformata(html, "%s", contents->data); -      } else { -        cr(html); -        bformata(html, "<p>%s</p>", contents->data); -        cr(html); -      } -      bdestroy(contents); -      break; -    case block_quote: -      check(blocks_to_html(b->children, &contents, false) == 0, -            "error converting blocks to html"); -      cr(html); -      bformata(html, "<blockquote>\n%s</blockquote>", contents->data); -      cr(html); -      bdestroy(contents); -      break; -    case list_item: -      check(blocks_to_html(b->children, &contents, tight) == 0, -            "error converting blocks to html"); -      brtrimws(contents); -      cr(html); -      bformata(html, "<li>%s</li>", contents->data); -      cr(html); -      bdestroy(contents); -      break; -    case list: -      // make sure a list starts at the beginning of the line: -      cr(html); -      data = &(b->attributes.list_data); -      check(blocks_to_html(b->children, &contents, data->tight) == 0, -            "error converting blocks to html"); -      mbstart = bformat(" start=\"%d\"", data->start); -      bformata(html, "<%s%s>\n%s</%s>", -               data->list_type == bullet ? "ul" : "ol", -               data->start == 1 ? "" : (char*) mbstart->data, -               contents->data, -               data->list_type == bullet ? "ul" : "ol"); -      cr(html); -      bdestroy(contents); -      bdestroy(mbstart); -      break; -    case atx_header: -    case setext_header: -      check(inlines_to_html(b->inline_content, &contents) == 0, -            "error converting inlines to html"); -      cr(html); -      bformata(html, "<h%d>%s</h%d>", -               b->attributes.header_level, -               contents->data, -               b->attributes.header_level); -      cr(html); -      bdestroy(contents); -      break; -    case indented_code: -      escaped = escape_html(b->string_content, false); -      cr(html); -      bformata(html, "<pre><code>%s</code></pre>", escaped->data); -      cr(html); -      bdestroy(escaped); -      break; -    case fenced_code: -      escaped = escape_html(b->string_content, false); -      cr(html); -      bformata(html, "<pre><code"); -      if (blength(b->attributes.fenced_code_data.info) > 0) { -        escaped2 = escape_html(b->attributes.fenced_code_data.info, true); -        info_words = bsplit(escaped2, ' '); -        bformata(html, " class=\"language-%s\"", info_words->entry[0]->data); -        bdestroy(escaped2); -        bstrListDestroy(info_words); -      } -      bformata(html, ">%s</code></pre>", escaped->data); -      cr(html); -      bdestroy(escaped); -      break; -    case html_block: -      bformata(html, "%s", b->string_content->data); -      break; -    case hrule: -      bformata(html, "<hr />"); -      cr(html); -      break; -    case reference_def: -      break; -    default: -      log_warn("block type %d not implemented\n", b->tag); -      break; -    } -    b = b->next; -  } -  *result = html; -  return 0; - error: -  return -1; -} - -// Convert an inline list to HTML.  Returns 0 on success, and sets result. -extern int inlines_to_html(inl* ils, bstring* result) -{ -  bstring contents = NULL; -  bstring html = blk2bstr("", 0); -  bstring mbtitle, escaped, escaped2; - -  while(ils != NULL) { -    switch(ils->tag) { -    case str: -      escaped = escape_html(ils->content.literal, false); -      bformata(html, "%s", escaped->data); -      bdestroy(escaped); -      break; -    case linebreak: -      bformata(html, "<br />\n"); -      break; -    case softbreak: -      bformata(html, "\n"); -      break; -    case code: -      escaped = escape_html(ils->content.literal, false); -      bformata(html, "<code>%s</code>", escaped->data); -      bdestroy(escaped); -      break; -    case raw_html: -    case entity: -      bformata(html, "%s", ils->content.literal->data); -      break; -    case link: -      check(inlines_to_html(ils->content.inlines, &contents) == 0, -            "error converting inlines to html"); -      if (blength(ils->content.linkable.title) > 0) { -        escaped = escape_html(ils->content.linkable.title, true); -        mbtitle = bformat(" title=\"%s\"", escaped->data); -        bdestroy(escaped); -      } else { -        mbtitle = blk2bstr("",0); -      } -      escaped = escape_html(ils->content.linkable.url, true); -      bformata(html, "<a href=\"%s\"%s>%s</a>", -               escaped->data, -               mbtitle->data, -               contents->data); -      bdestroy(escaped); -      bdestroy(mbtitle); -      bdestroy(contents); -      break; -    case image: -      check(inlines_to_html(ils->content.inlines, &contents) == 0, -            "error converting inlines to html"); -      escaped  = escape_html(ils->content.linkable.url, true); -      escaped2 = escape_html(contents, false); -      bdestroy(contents); -      bformata(html, "<img src=\"%s\" alt=\"%s\"", -               escaped->data, escaped2->data); -      bdestroy(escaped); -      bdestroy(escaped2); -      if (blength(ils->content.linkable.title) > 0) { -        escaped = escape_html(ils->content.linkable.title, true); -        bformata(html, " title=\"%s\"", escaped->data); -        bdestroy(escaped); -      } -      bformata(html, " />"); -      break; -    case strong: -      check(inlines_to_html(ils->content.inlines, &contents) == 0, -            "error converting inlines to html"); -      bformata(html, "<strong>%s</strong>", contents->data); -      bdestroy(contents); -      break; -    case emph: -      check(inlines_to_html(ils->content.inlines, &contents) == 0, -            "error converting inlines to html"); -      bformata(html, "<em>%s</em>", contents->data); -      bdestroy(contents); -      break; -    } -    ils = ils->next; -  } -  *result = html; -  return 0; - error: -  return -1; -} diff --git a/src/html/houdini.h b/src/html/houdini.h new file mode 100644 index 0000000..5fd690d --- /dev/null +++ b/src/html/houdini.h @@ -0,0 +1,46 @@ +#ifndef __HOUDINI_H__ +#define __HOUDINI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include "buffer.h" + +#define likely(x)       __builtin_expect((x),1) +#define unlikely(x)     __builtin_expect((x),0) + +#ifdef HOUDINI_USE_LOCALE +#	define _isxdigit(c) isxdigit(c) +#	define _isdigit(c) isdigit(c) +#else +/* + * Helper _isdigit methods -- do not trust the current locale + * */ +#	define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL) +#	define _isdigit(c) ((c) >= '0' && (c) <= '9') +#endif + +#define HOUDINI_ESCAPED_SIZE(x) (((x) * 12) / 10) +#define HOUDINI_UNESCAPED_SIZE(x) (x) + +extern size_t houdini_unescape_ent(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_escape_html(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_escape_html0(strbuf *ob, const uint8_t *src, size_t size, int secure); +extern int houdini_unescape_html(strbuf *ob, const uint8_t *src, size_t size); +extern void houdini_unescape_html_f(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_escape_xml(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_escape_uri(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_escape_url(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_escape_href(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_unescape_uri(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_unescape_url(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_escape_js(strbuf *ob, const uint8_t *src, size_t size); +extern int houdini_unescape_js(strbuf *ob, const uint8_t *src, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/html/houdini_href_e.c b/src/html/houdini_href_e.c new file mode 100644 index 0000000..12456ce --- /dev/null +++ b/src/html/houdini_href_e.c @@ -0,0 +1,107 @@ +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#include "html/houdini.h" + +/* + * The following characters will not be escaped: + * + *		-_.+!*'(),%#@?=;:/,+&$ alphanum + * + * Note that this character set is the addition of: + * + *	- The characters which are safe to be in an URL + *	- The characters which are *not* safe to be in + *	an URL because they are RESERVED characters. + * + * We asume (lazily) that any RESERVED char that + * appears inside an URL is actually meant to + * have its native function (i.e. as an URL + * component/separator) and hence needs no escaping. + * + * There are two exceptions: the chacters & (amp) + * and ' (single quote) do not appear in the table. + * They are meant to appear in the URL as components, + * yet they require special HTML-entity escaping + * to generate valid HTML markup. + * + * All other characters will be escaped to %XX. + * + */ +static const char HREF_SAFE[] = { +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, +	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +int +houdini_escape_href(strbuf *ob, const uint8_t *src, size_t size) +{ +	static const uint8_t hex_chars[] = "0123456789ABCDEF"; +	size_t  i = 0, org; +	uint8_t hex_str[3]; + +	hex_str[0] = '%'; + +	while (i < size) { +		org = i; +		while (i < size && HREF_SAFE[src[i]] != 0) +			i++; + +		if (likely(i > org)) +			strbuf_put(ob, src + org, i - org); + +		/* escaping */ +		if (i >= size) +			break; + +		switch (src[i]) { +		/* amp appears all the time in URLs, but needs +		 * HTML-entity escaping to be inside an href */ +		case '&': +			strbuf_puts(ob, "&"); +			break; + +		/* the single quote is a valid URL character +		 * according to the standard; it needs HTML +		 * entity escaping too */ +		case '\'': +			strbuf_puts(ob, "'"); +			break; + +		/* the space can be escaped to %20 or a plus +		 * sign. we're going with the generic escape +		 * for now. the plus thing is more commonly seen +		 * when building GET strings */ +#if 0 +		case ' ': +			strbuf_putc(ob, '+'); +			break; +#endif + +		/* every other character goes with a %XX escaping */ +		default: +			hex_str[1] = hex_chars[(src[i] >> 4) & 0xF]; +			hex_str[2] = hex_chars[src[i] & 0xF]; +			strbuf_put(ob, hex_str, 3); +		} + +		i++; +	} + +	return 1; +} diff --git a/src/html/houdini_html_e.c b/src/html/houdini_html_e.c new file mode 100644 index 0000000..f2e86fe --- /dev/null +++ b/src/html/houdini_html_e.c @@ -0,0 +1,81 @@ +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#include "html/houdini.h" + +/** + * According to the OWASP rules: + * + * & --> & + * < --> < + * > --> > + * " --> " + * ' --> '     ' is not recommended + * / --> /     forward slash is included as it helps end an HTML entity + * + */ +static const char HTML_ESCAPE_TABLE[] = { +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const char *HTML_ESCAPES[] = { +        "", +        """, +        "&", +        "'", +        "/", +        "<", +        ">" +}; + +int +houdini_escape_html0(strbuf *ob, const uint8_t *src, size_t size, int secure) +{ +	size_t  i = 0, org, esc = 0; + +	while (i < size) { +		org = i; +		while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0) +			i++; + +		if (i > org) +			strbuf_put(ob, src + org, i - org); + +		/* escaping */ +		if (unlikely(i >= size)) +			break; + +		/* The forward slash is only escaped in secure mode */ +		if ((src[i] == '/' || src[i] == '\'') && !secure) { +			strbuf_putc(ob, src[i]); +		} else { +			strbuf_puts(ob, HTML_ESCAPES[esc]); +		} + +		i++; +	} + +	return 1; +} + +int +houdini_escape_html(strbuf *ob, const uint8_t *src, size_t size) +{ +	return houdini_escape_html0(ob, src, size, 1); +} diff --git a/src/html/houdini_html_u.c b/src/html/houdini_html_u.c new file mode 100644 index 0000000..49b4956 --- /dev/null +++ b/src/html/houdini_html_u.c @@ -0,0 +1,111 @@ +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#include "houdini.h" +#include "utf8.h" +#include "html_unescape.h" + +size_t +houdini_unescape_ent(strbuf *ob, const uint8_t *src, size_t size) +{ +	size_t i = 0; + +	if (size > 3 && src[0] == '#') { +		int codepoint = 0; + +		if (_isdigit(src[1])) { +			for (i = 1; i < size && _isdigit(src[i]); ++i) { +				int cp = (codepoint * 10) + (src[i] - '0'); + +				if (cp < codepoint) +					return 0; + +				codepoint = cp; +			} +		} + +		else if (src[1] == 'x' || src[1] == 'X') { +			for (i = 2; i < size && _isxdigit(src[i]); ++i) { +				int cp = (codepoint * 16) + ((src[i] | 32) % 39 - 9); + +				if (cp < codepoint) +					return 0; + +				codepoint = cp; +			} +		} + +		if (i < size && src[i] == ';' && codepoint) { +			utf8proc_encode_char(codepoint, ob); +			return i + 1; +		} +	} + +	else { +		if (size > MAX_WORD_LENGTH) +			size = MAX_WORD_LENGTH; + +		for (i = MIN_WORD_LENGTH; i < size; ++i) { +			if (src[i] == ' ') +				break; + +			if (src[i] == ';') { +				const struct html_ent *entity = find_entity((char *)src, i); + +				if (entity != NULL) { +					strbuf_put(ob, entity->utf8, entity->utf8_len); +					return i + 1; +				} + +				break; +			} +		} +	} + +	return 0; +} + +int +houdini_unescape_html(strbuf *ob, const uint8_t *src, size_t size) +{ +	size_t  i = 0, org, ent; + +	while (i < size) { +		org = i; +		while (i < size && src[i] != '&') +			i++; + +		if (likely(i > org)) { +			if (unlikely(org == 0)) { +				if (i >= size) +					return 0; + +				strbuf_grow(ob, HOUDINI_UNESCAPED_SIZE(size)); +			} + +			strbuf_put(ob, src + org, i - org); +		} + +		/* escaping */ +		if (i >= size) +			break; + +		i++; + +		ent = houdini_unescape_ent(ob, src + i, size - i); +		i += ent; + +		/* not really an entity */ +		if (ent == 0) +			strbuf_putc(ob, '&'); +	} + +	return 1; +} + +void houdini_unescape_html_f(strbuf *ob, const uint8_t *src, size_t size) +{ +	if (!houdini_unescape_html(ob, src, size)) +		strbuf_put(ob, src, size); +} diff --git a/src/html/html.c b/src/html/html.c new file mode 100644 index 0000000..ab6fc35 --- /dev/null +++ b/src/html/html.c @@ -0,0 +1,228 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <string.h> +#include <assert.h> + +#include "stmd.h" +#include "debug.h" +#include "html/houdini.h" + +// Functions to convert node_block and inline lists to HTML strings. + +static void escape_html(strbuf *dest, const unsigned char *source, int length) +{ +	if (length < 0) +		length = strlen((char *)source); + +	houdini_escape_html0(dest, source, (size_t)length, 0); +} + +static void escape_href(strbuf *dest, const unsigned char *source, int length) +{ +	if (length < 0) +		length = strlen((char *)source); + +	houdini_escape_href(dest, source, (size_t)length); +} + +static inline void cr(strbuf *html) +{ +	if (html->size && html->ptr[html->size - 1] != '\n') +		strbuf_putc(html, '\n'); +} + +// Convert an inline list to HTML.  Returns 0 on success, and sets result. +static void inlines_to_html(strbuf *html, node_inl* ils) +{ +	strbuf scrap = GH_BUF_INIT; + +	while(ils != NULL) { +		switch(ils->tag) { +			case INL_STRING: +				escape_html(html, ils->content.literal.data, ils->content.literal.len); +				break; + +			case INL_LINEBREAK: +				strbuf_puts(html, "<br />\n"); +				break; + +			case INL_SOFTBREAK: +				strbuf_putc(html, '\n'); +				break; + +			case INL_CODE: +				strbuf_puts(html, "<code>"); +				escape_html(html, ils->content.literal.data, ils->content.literal.len); +				strbuf_puts(html, "</code>"); +				break; + +			case INL_RAW_HTML: +				strbuf_put(html, +						ils->content.literal.data, +						ils->content.literal.len); +				break; + +			case INL_LINK: +				strbuf_puts(html, "<a href=\""); +				if (ils->content.linkable.url) +					escape_href(html, ils->content.linkable.url, -1); + +				if (ils->content.linkable.title) { +					strbuf_puts(html, "\" title=\""); +					escape_html(html, ils->content.linkable.title, -1); +				} + +				strbuf_puts(html, "\">"); +				inlines_to_html(html, ils->content.inlines); +				strbuf_puts(html, "</a>"); +				break; + +			case INL_IMAGE: +				strbuf_puts(html, "<img src=\""); +				if (ils->content.linkable.url) +					escape_href(html, ils->content.linkable.url, -1); + +				inlines_to_html(&scrap, ils->content.inlines); +				strbuf_puts(html, "\" alt=\""); +				if (scrap.size) +					escape_html(html, scrap.ptr, scrap.size); +				strbuf_clear(&scrap); + +				if (ils->content.linkable.title) { +					strbuf_puts(html, "\" title=\""); +					escape_html(html, ils->content.linkable.title, -1); +				} + +				strbuf_puts(html, "\"/>"); +				break; + +			case INL_STRONG: +				strbuf_puts(html, "<strong>"); +				inlines_to_html(html, ils->content.inlines); +				strbuf_puts(html, "</strong>"); +				break; + +			case INL_EMPH: +				strbuf_puts(html, "<em>"); +				inlines_to_html(html, ils->content.inlines); +				strbuf_puts(html, "</em>"); +				break; +		} +		ils = ils->next; +	} + +	strbuf_free(&scrap); +} + +// Convert a node_block list to HTML.  Returns 0 on success, and sets result. +static void blocks_to_html(strbuf *html, node_block *b, bool tight) +{ +	struct ListData *data; + +	while(b != NULL) { +		switch(b->tag) { +			case BLOCK_DOCUMENT: +				blocks_to_html(html, b->children, false); +				break; + +			case BLOCK_PARAGRAPH: +				if (tight) { +					inlines_to_html(html, b->inline_content); +				} else { +					cr(html); +					strbuf_puts(html, "<p>"); +					inlines_to_html(html, b->inline_content); +					strbuf_puts(html, "</p>\n"); +				} +				break; + +			case BLOCK_BQUOTE: +				cr(html); +				strbuf_puts(html, "<blockquote>\n"); +				blocks_to_html(html, b->children, false); +				strbuf_puts(html, "</blockquote>\n"); +				break; + +			case BLOCK_LIST_ITEM: +				cr(html); +				strbuf_puts(html, "<li>"); +				blocks_to_html(html, b->children, tight); +				strbuf_trim(html); /* TODO: rtrim */ +				strbuf_puts(html, "</li>\n"); +				break; + +			case BLOCK_LIST: +				// make sure a list starts at the beginning of the line: +				cr(html); +				data = &(b->as.list); + +				if (data->start > 1) { +					strbuf_printf(html, "<%s start=\"%d\">\n", +							data->list_type == bullet ? "ul" : "ol", +							data->start); +				} else { +					strbuf_puts(html, data->list_type == bullet ? "<ul>\n" : "<ol>\n"); +				} + +				blocks_to_html(html, b->children, data->tight); +				strbuf_puts(html, data->list_type == bullet ? "</ul>" : "</ol>"); +				strbuf_putc(html, '\n'); +				break; + +			case BLOCK_ATX_HEADER: +			case BLOCK_SETEXT_HEADER: +				cr(html); +				strbuf_printf(html, "<h%d>", b->as.header.level); +				inlines_to_html(html, b->inline_content); +				strbuf_printf(html, "</h%d>\n", b->as.header.level); +				break; + +			case BLOCK_INDENTED_CODE: +			case BLOCK_FENCED_CODE: +				cr(html); + +				strbuf_puts(html, "<pre><code"); + +				if (b->tag == BLOCK_FENCED_CODE) { +					strbuf *info = &b->as.code.info; + +					if (strbuf_len(info) > 0) { +						int first_tag = strbuf_strchr(info, ' ', 0); +						if (first_tag < 0) +							first_tag = strbuf_len(info); + +						strbuf_puts(html, " class=\"language-"); +						escape_html(html, info->ptr, first_tag); +						strbuf_putc(html, '"'); +					} +				} + +				strbuf_putc(html, '>'); +				escape_html(html, b->string_content.ptr, b->string_content.size); +				strbuf_puts(html, "</code></pre>\n"); +				break; + +			case BLOCK_HTML: +				strbuf_put(html, b->string_content.ptr, b->string_content.size); +				break; + +			case BLOCK_HRULE: +				strbuf_puts(html, "<hr />\n"); +				break; + +			case BLOCK_REFERENCE_DEF: +				break; + +			default: +				assert(false); +		} + +		b = b->next; +	} +} + +void stmd_render_html(strbuf *html, node_block *root) +{ +	blocks_to_html(html, root, false); +} diff --git a/src/html/html_unescape.gperf b/src/html/html_unescape.gperf new file mode 100644 index 0000000..4d46f67 --- /dev/null +++ b/src/html/html_unescape.gperf @@ -0,0 +1,2131 @@ +struct html_ent { +	const char *entity; +	unsigned int utf8_len; +	unsigned char utf8[4]; +}; +%% +"Aacute", 2, {195, 129} +"aacute", 2, {195, 161} +"Abreve", 2, {196, 130} +"abreve", 2, {196, 131} +"ac", 3, {226, 136, 190} +"acd", 3, {226, 136, 191} +"acE", 3, {226, 136, 190} +"Acirc", 2, {195, 130} +"acirc", 2, {195, 162} +"acute", 2, {194, 180} +"Acy", 2, {208, 144} +"acy", 2, {208, 176} +"AElig", 2, {195, 134} +"aelig", 2, {195, 166} +"af", 3, {226, 129, 161} +"Afr", 4, {240, 157, 148, 132} +"afr", 4, {240, 157, 148, 158} +"Agrave", 2, {195, 128} +"agrave", 2, {195, 160} +"alefsym", 3, {226, 132, 181} +"aleph", 3, {226, 132, 181} +"Alpha", 2, {206, 145} +"alpha", 2, {206, 177} +"Amacr", 2, {196, 128} +"amacr", 2, {196, 129} +"amalg", 3, {226, 168, 191} +"amp", 1, {38} +"AMP", 1, {38} +"andand", 3, {226, 169, 149} +"And", 3, {226, 169, 147} +"and", 3, {226, 136, 167} +"andd", 3, {226, 169, 156} +"andslope", 3, {226, 169, 152} +"andv", 3, {226, 169, 154} +"ang", 3, {226, 136, 160} +"ange", 3, {226, 166, 164} +"angle", 3, {226, 136, 160} +"angmsdaa", 3, {226, 166, 168} +"angmsdab", 3, {226, 166, 169} +"angmsdac", 3, {226, 166, 170} +"angmsdad", 3, {226, 166, 171} +"angmsdae", 3, {226, 166, 172} +"angmsdaf", 3, {226, 166, 173} +"angmsdag", 3, {226, 166, 174} +"angmsdah", 3, {226, 166, 175} +"angmsd", 3, {226, 136, 161} +"angrt", 3, {226, 136, 159} +"angrtvb", 3, {226, 138, 190} +"angrtvbd", 3, {226, 166, 157} +"angsph", 3, {226, 136, 162} +"angst", 2, {195, 133} +"angzarr", 3, {226, 141, 188} +"Aogon", 2, {196, 132} +"aogon", 2, {196, 133} +"Aopf", 4, {240, 157, 148, 184} +"aopf", 4, {240, 157, 149, 146} +"apacir", 3, {226, 169, 175} +"ap", 3, {226, 137, 136} +"apE", 3, {226, 169, 176} +"ape", 3, {226, 137, 138} +"apid", 3, {226, 137, 139} +"apos", 1, {39} +"ApplyFunction", 3, {226, 129, 161} +"approx", 3, {226, 137, 136} +"approxeq", 3, {226, 137, 138} +"Aring", 2, {195, 133} +"aring", 2, {195, 165} +"Ascr", 4, {240, 157, 146, 156} +"ascr", 4, {240, 157, 146, 182} +"Assign", 3, {226, 137, 148} +"ast", 1, {42} +"asymp", 3, {226, 137, 136} +"asympeq", 3, {226, 137, 141} +"Atilde", 2, {195, 131} +"atilde", 2, {195, 163} +"Auml", 2, {195, 132} +"auml", 2, {195, 164} +"awconint", 3, {226, 136, 179} +"awint", 3, {226, 168, 145} +"backcong", 3, {226, 137, 140} +"backepsilon", 2, {207, 182} +"backprime", 3, {226, 128, 181} +"backsim", 3, {226, 136, 189} +"backsimeq", 3, {226, 139, 141} +"Backslash", 3, {226, 136, 150} +"Barv", 3, {226, 171, 167} +"barvee", 3, {226, 138, 189} +"barwed", 3, {226, 140, 133} +"Barwed", 3, {226, 140, 134} +"barwedge", 3, {226, 140, 133} +"bbrk", 3, {226, 142, 181} +"bbrktbrk", 3, {226, 142, 182} +"bcong", 3, {226, 137, 140} +"Bcy", 2, {208, 145} +"bcy", 2, {208, 177} +"bdquo", 3, {226, 128, 158} +"becaus", 3, {226, 136, 181} +"because", 3, {226, 136, 181} +"Because", 3, {226, 136, 181} +"bemptyv", 3, {226, 166, 176} +"bepsi", 2, {207, 182} +"bernou", 3, {226, 132, 172} +"Bernoullis", 3, {226, 132, 172} +"Beta", 2, {206, 146} +"beta", 2, {206, 178} +"beth", 3, {226, 132, 182} +"between", 3, {226, 137, 172} +"Bfr", 4, {240, 157, 148, 133} +"bfr", 4, {240, 157, 148, 159} +"bigcap", 3, {226, 139, 130} +"bigcirc", 3, {226, 151, 175} +"bigcup", 3, {226, 139, 131} +"bigodot", 3, {226, 168, 128} +"bigoplus", 3, {226, 168, 129} +"bigotimes", 3, {226, 168, 130} +"bigsqcup", 3, {226, 168, 134} +"bigstar", 3, {226, 152, 133} +"bigtriangledown", 3, {226, 150, 189} +"bigtriangleup", 3, {226, 150, 179} +"biguplus", 3, {226, 168, 132} +"bigvee", 3, {226, 139, 129} +"bigwedge", 3, {226, 139, 128} +"bkarow", 3, {226, 164, 141} +"blacklozenge", 3, {226, 167, 171} +"blacksquare", 3, {226, 150, 170} +"blacktriangle", 3, {226, 150, 180} +"blacktriangledown", 3, {226, 150, 190} +"blacktriangleleft", 3, {226, 151, 130} +"blacktriangleright", 3, {226, 150, 184} +"blank", 3, {226, 144, 163} +"blk12", 3, {226, 150, 146} +"blk14", 3, {226, 150, 145} +"blk34", 3, {226, 150, 147} +"block", 3, {226, 150, 136} +"bne", 1, {61} +"bnequiv", 3, {226, 137, 161} +"bNot", 3, {226, 171, 173} +"bnot", 3, {226, 140, 144} +"Bopf", 4, {240, 157, 148, 185} +"bopf", 4, {240, 157, 149, 147} +"bot", 3, {226, 138, 165} +"bottom", 3, {226, 138, 165} +"bowtie", 3, {226, 139, 136} +"boxbox", 3, {226, 167, 137} +"boxdl", 3, {226, 148, 144} +"boxdL", 3, {226, 149, 149} +"boxDl", 3, {226, 149, 150} +"boxDL", 3, {226, 149, 151} +"boxdr", 3, {226, 148, 140} +"boxdR", 3, {226, 149, 146} +"boxDr", 3, {226, 149, 147} +"boxDR", 3, {226, 149, 148} +"boxh", 3, {226, 148, 128} +"boxH", 3, {226, 149, 144} +"boxhd", 3, {226, 148, 172} +"boxHd", 3, {226, 149, 164} +"boxhD", 3, {226, 149, 165} +"boxHD", 3, {226, 149, 166} +"boxhu", 3, {226, 148, 180} +"boxHu", 3, {226, 149, 167} +"boxhU", 3, {226, 149, 168} +"boxHU", 3, {226, 149, 169} +"boxminus", 3, {226, 138, 159} +"boxplus", 3, {226, 138, 158} +"boxtimes", 3, {226, 138, 160} +"boxul", 3, {226, 148, 152} +"boxuL", 3, {226, 149, 155} +"boxUl", 3, {226, 149, 156} +"boxUL", 3, {226, 149, 157} +"boxur", 3, {226, 148, 148} +"boxuR", 3, {226, 149, 152} +"boxUr", 3, {226, 149, 153} +"boxUR", 3, {226, 149, 154} +"boxv", 3, {226, 148, 130} +"boxV", 3, {226, 149, 145} +"boxvh", 3, {226, 148, 188} +"boxvH", 3, {226, 149, 170} +"boxVh", 3, {226, 149, 171} +"boxVH", 3, {226, 149, 172} +"boxvl", 3, {226, 148, 164} +"boxvL", 3, {226, 149, 161} +"boxVl", 3, {226, 149, 162} +"boxVL", 3, {226, 149, 163} +"boxvr", 3, {226, 148, 156} +"boxvR", 3, {226, 149, 158} +"boxVr", 3, {226, 149, 159} +"boxVR", 3, {226, 149, 160} +"bprime", 3, {226, 128, 181} +"breve", 2, {203, 152} +"Breve", 2, {203, 152} +"brvbar", 2, {194, 166} +"bscr", 4, {240, 157, 146, 183} +"Bscr", 3, {226, 132, 172} +"bsemi", 3, {226, 129, 143} +"bsim", 3, {226, 136, 189} +"bsime", 3, {226, 139, 141} +"bsolb", 3, {226, 167, 133} +"bsol", 1, {92} +"bsolhsub", 3, {226, 159, 136} +"bull", 3, {226, 128, 162} +"bullet", 3, {226, 128, 162} +"bump", 3, {226, 137, 142} +"bumpE", 3, {226, 170, 174} +"bumpe", 3, {226, 137, 143} +"Bumpeq", 3, {226, 137, 142} +"bumpeq", 3, {226, 137, 143} +"Cacute", 2, {196, 134} +"cacute", 2, {196, 135} +"capand", 3, {226, 169, 132} +"capbrcup", 3, {226, 169, 137} +"capcap", 3, {226, 169, 139} +"cap", 3, {226, 136, 169} +"Cap", 3, {226, 139, 146} +"capcup", 3, {226, 169, 135} +"capdot", 3, {226, 169, 128} +"CapitalDifferentialD", 3, {226, 133, 133} +"caps", 3, {226, 136, 169} +"caret", 3, {226, 129, 129} +"caron", 2, {203, 135} +"Cayleys", 3, {226, 132, 173} +"ccaps", 3, {226, 169, 141} +"Ccaron", 2, {196, 140} +"ccaron", 2, {196, 141} +"Ccedil", 2, {195, 135} +"ccedil", 2, {195, 167} +"Ccirc", 2, {196, 136} +"ccirc", 2, {196, 137} +"Cconint", 3, {226, 136, 176} +"ccups", 3, {226, 169, 140} +"ccupssm", 3, {226, 169, 144} +"Cdot", 2, {196, 138} +"cdot", 2, {196, 139} +"cedil", 2, {194, 184} +"Cedilla", 2, {194, 184} +"cemptyv", 3, {226, 166, 178} +"cent", 2, {194, 162} +"centerdot", 2, {194, 183} +"CenterDot", 2, {194, 183} +"cfr", 4, {240, 157, 148, 160} +"Cfr", 3, {226, 132, 173} +"CHcy", 2, {208, 167} +"chcy", 2, {209, 135} +"check", 3, {226, 156, 147} +"checkmark", 3, {226, 156, 147} +"Chi", 2, {206, 167} +"chi", 2, {207, 135} +"circ", 2, {203, 134} +"circeq", 3, {226, 137, 151} +"circlearrowleft", 3, {226, 134, 186} +"circlearrowright", 3, {226, 134, 187} +"circledast", 3, {226, 138, 155} +"circledcirc", 3, {226, 138, 154} +"circleddash", 3, {226, 138, 157} +"CircleDot", 3, {226, 138, 153} +"circledR", 2, {194, 174} +"circledS", 3, {226, 147, 136} +"CircleMinus", 3, {226, 138, 150} +"CirclePlus", 3, {226, 138, 149} +"CircleTimes", 3, {226, 138, 151} +"cir", 3, {226, 151, 139} +"cirE", 3, {226, 167, 131} +"cire", 3, {226, 137, 151} +"cirfnint", 3, {226, 168, 144} +"cirmid", 3, {226, 171, 175} +"cirscir", 3, {226, 167, 130} +"ClockwiseContourIntegral", 3, {226, 136, 178} +"CloseCurlyDoubleQuote", 3, {226, 128, 157} +"CloseCurlyQuote", 3, {226, 128, 153} +"clubs", 3, {226, 153, 163} +"clubsuit", 3, {226, 153, 163} +"colon", 1, {58} +"Colon", 3, {226, 136, 183} +"Colone", 3, {226, 169, 180} +"colone", 3, {226, 137, 148} +"coloneq", 3, {226, 137, 148} +"comma", 1, {44} +"commat", 1, {64} +"comp", 3, {226, 136, 129} +"compfn", 3, {226, 136, 152} +"complement", 3, {226, 136, 129} +"complexes", 3, {226, 132, 130} +"cong", 3, {226, 137, 133} +"congdot", 3, {226, 169, 173} +"Congruent", 3, {226, 137, 161} +"conint", 3, {226, 136, 174} +"Conint", 3, {226, 136, 175} +"ContourIntegral", 3, {226, 136, 174} +"copf", 4, {240, 157, 149, 148} +"Copf", 3, {226, 132, 130} +"coprod", 3, {226, 136, 144} +"Coproduct", 3, {226, 136, 144} +"copy", 2, {194, 169} +"COPY", 2, {194, 169} +"copysr", 3, {226, 132, 151} +"CounterClockwiseContourIntegral", 3, {226, 136, 179} +"crarr", 3, {226, 134, 181} +"cross", 3, {226, 156, 151} +"Cross", 3, {226, 168, 175} +"Cscr", 4, {240, 157, 146, 158} +"cscr", 4, {240, 157, 146, 184} +"csub", 3, {226, 171, 143} +"csube", 3, {226, 171, 145} +"csup", 3, {226, 171, 144} +"csupe", 3, {226, 171, 146} +"ctdot", 3, {226, 139, 175} +"cudarrl", 3, {226, 164, 184} +"cudarrr", 3, {226, 164, 181} +"cuepr", 3, {226, 139, 158} +"cuesc", 3, {226, 139, 159} +"cularr", 3, {226, 134, 182} +"cularrp", 3, {226, 164, 189} +"cupbrcap", 3, {226, 169, 136} +"cupcap", 3, {226, 169, 134} +"CupCap", 3, {226, 137, 141} +"cup", 3, {226, 136, 170} +"Cup", 3, {226, 139, 147} +"cupcup", 3, {226, 169, 138} +"cupdot", 3, {226, 138, 141} +"cupor", 3, {226, 169, 133} +"cups", 3, {226, 136, 170} +"curarr", 3, {226, 134, 183} +"curarrm", 3, {226, 164, 188} +"curlyeqprec", 3, {226, 139, 158} +"curlyeqsucc", 3, {226, 139, 159} +"curlyvee", 3, {226, 139, 142} +"curlywedge", 3, {226, 139, 143} +"curren", 2, {194, 164} +"curvearrowleft", 3, {226, 134, 182} +"curvearrowright", 3, {226, 134, 183} +"cuvee", 3, {226, 139, 142} +"cuwed", 3, {226, 139, 143} +"cwconint", 3, {226, 136, 178} +"cwint", 3, {226, 136, 177} +"cylcty", 3, {226, 140, 173} +"dagger", 3, {226, 128, 160} +"Dagger", 3, {226, 128, 161} +"daleth", 3, {226, 132, 184} +"darr", 3, {226, 134, 147} +"Darr", 3, {226, 134, 161} +"dArr", 3, {226, 135, 147} +"dash", 3, {226, 128, 144} +"Dashv", 3, {226, 171, 164} +"dashv", 3, {226, 138, 163} +"dbkarow", 3, {226, 164, 143} +"dblac", 2, {203, 157} +"Dcaron", 2, {196, 142} +"dcaron", 2, {196, 143} +"Dcy", 2, {208, 148} +"dcy", 2, {208, 180} +"ddagger", 3, {226, 128, 161} +"ddarr", 3, {226, 135, 138} +"DD", 3, {226, 133, 133} +"dd", 3, {226, 133, 134} +"DDotrahd", 3, {226, 164, 145} +"ddotseq", 3, {226, 169, 183} +"deg", 2, {194, 176} +"Del", 3, {226, 136, 135} +"Delta", 2, {206, 148} +"delta", 2, {206, 180} +"demptyv", 3, {226, 166, 177} +"dfisht", 3, {226, 165, 191} +"Dfr", 4, {240, 157, 148, 135} +"dfr", 4, {240, 157, 148, 161} +"dHar", 3, {226, 165, 165} +"dharl", 3, {226, 135, 131} +"dharr", 3, {226, 135, 130} +"DiacriticalAcute", 2, {194, 180} +"DiacriticalDot", 2, {203, 153} +"DiacriticalDoubleAcute", 2, {203, 157} +"DiacriticalGrave", 1, {96} +"DiacriticalTilde", 2, {203, 156} +"diam", 3, {226, 139, 132} +"diamond", 3, {226, 139, 132} +"Diamond", 3, {226, 139, 132} +"diamondsuit", 3, {226, 153, 166} +"diams", 3, {226, 153, 166} +"die", 2, {194, 168} +"DifferentialD", 3, {226, 133, 134} +"digamma", 2, {207, 157} +"disin", 3, {226, 139, 178} +"div", 2, {195, 183} +"divide", 2, {195, 183} +"divideontimes", 3, {226, 139, 135} +"divonx", 3, {226, 139, 135} +"DJcy", 2, {208, 130} +"djcy", 2, {209, 146} +"dlcorn", 3, {226, 140, 158} +"dlcrop", 3, {226, 140, 141} +"dollar", 1, {36} +"Dopf", 4, {240, 157, 148, 187} +"dopf", 4, {240, 157, 149, 149} +"Dot", 2, {194, 168} +"dot", 2, {203, 153} +"DotDot", 3, {226, 131, 156} +"doteq", 3, {226, 137, 144} +"doteqdot", 3, {226, 137, 145} +"DotEqual", 3, {226, 137, 144} +"dotminus", 3, {226, 136, 184} +"dotplus", 3, {226, 136, 148} +"dotsquare", 3, {226, 138, 161} +"doublebarwedge", 3, {226, 140, 134} +"DoubleContourIntegral", 3, {226, 136, 175} +"DoubleDot", 2, {194, 168} +"DoubleDownArrow", 3, {226, 135, 147} +"DoubleLeftArrow", 3, {226, 135, 144} +"DoubleLeftRightArrow", 3, {226, 135, 148} +"DoubleLeftTee", 3, {226, 171, 164} +"DoubleLongLeftArrow", 3, {226, 159, 184} +"DoubleLongLeftRightArrow", 3, {226, 159, 186} +"DoubleLongRightArrow", 3, {226, 159, 185} +"DoubleRightArrow", 3, {226, 135, 146} +"DoubleRightTee", 3, {226, 138, 168} +"DoubleUpArrow", 3, {226, 135, 145} +"DoubleUpDownArrow", 3, {226, 135, 149} +"DoubleVerticalBar", 3, {226, 136, 165} +"DownArrowBar", 3, {226, 164, 147} +"downarrow", 3, {226, 134, 147} +"DownArrow", 3, {226, 134, 147} +"Downarrow", 3, {226, 135, 147} +"DownArrowUpArrow", 3, {226, 135, 181} +"DownBreve", 2, {204, 145} +"downdownarrows", 3, {226, 135, 138} +"downharpoonleft", 3, {226, 135, 131} +"downharpoonright", 3, {226, 135, 130} +"DownLeftRightVector", 3, {226, 165, 144} +"DownLeftTeeVector", 3, {226, 165, 158} +"DownLeftVectorBar", 3, {226, 165, 150} +"DownLeftVector", 3, {226, 134, 189} +"DownRightTeeVector", 3, {226, 165, 159} +"DownRightVectorBar", 3, {226, 165, 151} +"DownRightVector", 3, {226, 135, 129} +"DownTeeArrow", 3, {226, 134, 167} +"DownTee", 3, {226, 138, 164} +"drbkarow", 3, {226, 164, 144} +"drcorn", 3, {226, 140, 159} +"drcrop", 3, {226, 140, 140} +"Dscr", 4, {240, 157, 146, 159} +"dscr", 4, {240, 157, 146, 185} +"DScy", 2, {208, 133} +"dscy", 2, {209, 149} +"dsol", 3, {226, 167, 182} +"Dstrok", 2, {196, 144} +"dstrok", 2, {196, 145} +"dtdot", 3, {226, 139, 177} +"dtri", 3, {226, 150, 191} +"dtrif", 3, {226, 150, 190} +"duarr", 3, {226, 135, 181} +"duhar", 3, {226, 165, 175} +"dwangle", 3, {226, 166, 166} +"DZcy", 2, {208, 143} +"dzcy", 2, {209, 159} +"dzigrarr", 3, {226, 159, 191} +"Eacute", 2, {195, 137} +"eacute", 2, {195, 169} +"easter", 3, {226, 169, 174} +"Ecaron", 2, {196, 154} +"ecaron", 2, {196, 155} +"Ecirc", 2, {195, 138} +"ecirc", 2, {195, 170} +"ecir", 3, {226, 137, 150} +"ecolon", 3, {226, 137, 149} +"Ecy", 2, {208, 173} +"ecy", 2, {209, 141} +"eDDot", 3, {226, 169, 183} +"Edot", 2, {196, 150} +"edot", 2, {196, 151} +"eDot", 3, {226, 137, 145} +"ee", 3, {226, 133, 135} +"efDot", 3, {226, 137, 146} +"Efr", 4, {240, 157, 148, 136} +"efr", 4, {240, 157, 148, 162} +"eg", 3, {226, 170, 154} +"Egrave", 2, {195, 136} +"egrave", 2, {195, 168} +"egs", 3, {226, 170, 150} +"egsdot", 3, {226, 170, 152} +"el", 3, {226, 170, 153} +"Element", 3, {226, 136, 136} +"elinters", 3, {226, 143, 167} +"ell", 3, {226, 132, 147} +"els", 3, {226, 170, 149} +"elsdot", 3, {226, 170, 151} +"Emacr", 2, {196, 146} +"emacr", 2, {196, 147} +"empty", 3, {226, 136, 133} +"emptyset", 3, {226, 136, 133} +"EmptySmallSquare", 3, {226, 151, 187} +"emptyv", 3, {226, 136, 133} +"EmptyVerySmallSquare", 3, {226, 150, 171} +"emsp13", 3, {226, 128, 132} +"emsp14", 3, {226, 128, 133} +"emsp", 3, {226, 128, 131} +"ENG", 2, {197, 138} +"eng", 2, {197, 139} +"ensp", 3, {226, 128, 130} +"Eogon", 2, {196, 152} +"eogon", 2, {196, 153} +"Eopf", 4, {240, 157, 148, 188} +"eopf", 4, {240, 157, 149, 150} +"epar", 3, {226, 139, 149} +"eparsl", 3, {226, 167, 163} +"eplus", 3, {226, 169, 177} +"epsi", 2, {206, 181} +"Epsilon", 2, {206, 149} +"epsilon", 2, {206, 181} +"epsiv", 2, {207, 181} +"eqcirc", 3, {226, 137, 150} +"eqcolon", 3, {226, 137, 149} +"eqsim", 3, {226, 137, 130} +"eqslantgtr", 3, {226, 170, 150} +"eqslantless", 3, {226, 170, 149} +"Equal", 3, {226, 169, 181} +"equals", 1, {61} +"EqualTilde", 3, {226, 137, 130} +"equest", 3, {226, 137, 159} +"Equilibrium", 3, {226, 135, 140} +"equiv", 3, {226, 137, 161} +"equivDD", 3, {226, 169, 184} +"eqvparsl", 3, {226, 167, 165} +"erarr", 3, {226, 165, 177} +"erDot", 3, {226, 137, 147} +"escr", 3, {226, 132, 175} +"Escr", 3, {226, 132, 176} +"esdot", 3, {226, 137, 144} +"Esim", 3, {226, 169, 179} +"esim", 3, {226, 137, 130} +"Eta", 2, {206, 151} +"eta", 2, {206, 183} +"ETH", 2, {195, 144} +"eth", 2, {195, 176} +"Euml", 2, {195, 139} +"euml", 2, {195, 171} +"euro", 3, {226, 130, 172} +"excl", 1, {33} +"exist", 3, {226, 136, 131} +"Exists", 3, {226, 136, 131} +"expectation", 3, {226, 132, 176} +"exponentiale", 3, {226, 133, 135} +"ExponentialE", 3, {226, 133, 135} +"fallingdotseq", 3, {226, 137, 146} +"Fcy", 2, {208, 164} +"fcy", 2, {209, 132} +"female", 3, {226, 153, 128} +"ffilig", 3, {239, 172, 131} +"fflig", 3, {239, 172, 128} +"ffllig", 3, {239, 172, 132} +"Ffr", 4, {240, 157, 148, 137} +"ffr", 4, {240, 157, 148, 163} +"filig", 3, {239, 172, 129} +"FilledSmallSquare", 3, {226, 151, 188} +"FilledVerySmallSquare", 3, {226, 150, 170} +"fjlig", 1, {102} +"flat", 3, {226, 153, 173} +"fllig", 3, {239, 172, 130} +"fltns", 3, {226, 150, 177} +"fnof", 2, {198, 146} +"Fopf", 4, {240, 157, 148, 189} +"fopf", 4, {240, 157, 149, 151} +"forall", 3, {226, 136, 128} +"ForAll", 3, {226, 136, 128} +"fork", 3, {226, 139, 148} +"forkv", 3, {226, 171, 153} +"Fouriertrf", 3, {226, 132, 177} +"fpartint", 3, {226, 168, 141} +"frac12", 2, {194, 189} +"frac13", 3, {226, 133, 147} +"frac14", 2, {194, 188} +"frac15", 3, {226, 133, 149} +"frac16", 3, {226, 133, 153} +"frac18", 3, {226, 133, 155} +"frac23", 3, {226, 133, 148} +"frac25", 3, {226, 133, 150} +"frac34", 2, {194, 190} +"frac35", 3, {226, 133, 151} +"frac38", 3, {226, 133, 156} +"frac45", 3, {226, 133, 152} +"frac56", 3, {226, 133, 154} +"frac58", 3, {226, 133, 157} +"frac78", 3, {226, 133, 158} +"frasl", 3, {226, 129, 132} +"frown", 3, {226, 140, 162} +"fscr", 4, {240, 157, 146, 187} +"Fscr", 3, {226, 132, 177} +"gacute", 2, {199, 181} +"Gamma", 2, {206, 147} +"gamma", 2, {206, 179} +"Gammad", 2, {207, 156} +"gammad", 2, {207, 157} +"gap", 3, {226, 170, 134} +"Gbreve", 2, {196, 158} +"gbreve", 2, {196, 159} +"Gcedil", 2, {196, 162} +"Gcirc", 2, {196, 156} +"gcirc", 2, {196, 157} +"Gcy", 2, {208, 147} +"gcy", 2, {208, 179} +"Gdot", 2, {196, 160} +"gdot", 2, {196, 161} +"ge", 3, {226, 137, 165} +"gE", 3, {226, 137, 167} +"gEl", 3, {226, 170, 140} +"gel", 3, {226, 139, 155} +"geq", 3, {226, 137, 165} +"geqq", 3, {226, 137, 167} +"geqslant", 3, {226, 169, 190} +"gescc", 3, {226, 170, 169} +"ges", 3, {226, 169, 190} +"gesdot", 3, {226, 170, 128} +"gesdoto", 3, {226, 170, 130} +"gesdotol", 3, {226, 170, 132} +"gesl", 3, {226, 139, 155} +"gesles", 3, {226, 170, 148} +"Gfr", 4, {240, 157, 148, 138} +"gfr", 4, {240, 157, 148, 164} +"gg", 3, {226, 137, 171} +"Gg", 3, {226, 139, 153} +"ggg", 3, {226, 139, 153} +"gimel", 3, {226, 132, 183} +"GJcy", 2, {208, 131} +"gjcy", 2, {209, 147} +"gla", 3, {226, 170, 165} +"gl", 3, {226, 137, 183} +"glE", 3, {226, 170, 146} +"glj", 3, {226, 170, 164} +"gnap", 3, {226, 170, 138} +"gnapprox", 3, {226, 170, 138} +"gne", 3, {226, 170, 136} +"gnE", 3, {226, 137, 169} +"gneq", 3, {226, 170, 136} +"gneqq", 3, {226, 137, 169} +"gnsim", 3, {226, 139, 167} +"Gopf", 4, {240, 157, 148, 190} +"gopf", 4, {240, 157, 149, 152} +"grave", 1, {96} +"GreaterEqual", 3, {226, 137, 165} +"GreaterEqualLess", 3, {226, 139, 155} +"GreaterFullEqual", 3, {226, 137, 167} +"GreaterGreater", 3, {226, 170, 162} +"GreaterLess", 3, {226, 137, 183} +"GreaterSlantEqual", 3, {226, 169, 190} +"GreaterTilde", 3, {226, 137, 179} +"Gscr", 4, {240, 157, 146, 162} +"gscr", 3, {226, 132, 138} +"gsim", 3, {226, 137, 179} +"gsime", 3, {226, 170, 142} +"gsiml", 3, {226, 170, 144} +"gtcc", 3, {226, 170, 167} +"gtcir", 3, {226, 169, 186} +"gt", 1, {62} +"GT", 1, {62} +"Gt", 3, {226, 137, 171} +"gtdot", 3, {226, 139, 151} +"gtlPar", 3, {226, 166, 149} +"gtquest", 3, {226, 169, 188} +"gtrapprox", 3, {226, 170, 134} +"gtrarr", 3, {226, 165, 184} +"gtrdot", 3, {226, 139, 151} +"gtreqless", 3, {226, 139, 155} +"gtreqqless", 3, {226, 170, 140} +"gtrless", 3, {226, 137, 183} +"gtrsim", 3, {226, 137, 179} +"gvertneqq", 3, {226, 137, 169} +"gvnE", 3, {226, 137, 169} +"Hacek", 2, {203, 135} +"hairsp", 3, {226, 128, 138} +"half", 2, {194, 189} +"hamilt", 3, {226, 132, 139} +"HARDcy", 2, {208, 170} +"hardcy", 2, {209, 138} +"harrcir", 3, {226, 165, 136} +"harr", 3, {226, 134, 148} +"hArr", 3, {226, 135, 148} +"harrw", 3, {226, 134, 173} +"Hat", 1, {94} +"hbar", 3, {226, 132, 143} +"Hcirc", 2, {196, 164} +"hcirc", 2, {196, 165} +"hearts", 3, {226, 153, 165} +"heartsuit", 3, {226, 153, 165} +"hellip", 3, {226, 128, 166} +"hercon", 3, {226, 138, 185} +"hfr", 4, {240, 157, 148, 165} +"Hfr", 3, {226, 132, 140} +"HilbertSpace", 3, {226, 132, 139} +"hksearow", 3, {226, 164, 165} +"hkswarow", 3, {226, 164, 166} +"hoarr", 3, {226, 135, 191} +"homtht", 3, {226, 136, 187} +"hookleftarrow", 3, {226, 134, 169} +"hookrightarrow", 3, {226, 134, 170} +"hopf", 4, {240, 157, 149, 153} +"Hopf", 3, {226, 132, 141} +"horbar", 3, {226, 128, 149} +"HorizontalLine", 3, {226, 148, 128} +"hscr", 4, {240, 157, 146, 189} +"Hscr", 3, {226, 132, 139} +"hslash", 3, {226, 132, 143} +"Hstrok", 2, {196, 166} +"hstrok", 2, {196, 167} +"HumpDownHump", 3, {226, 137, 142} +"HumpEqual", 3, {226, 137, 143} +"hybull", 3, {226, 129, 131} +"hyphen", 3, {226, 128, 144} +"Iacute", 2, {195, 141} +"iacute", 2, {195, 173} +"ic", 3, {226, 129, 163} +"Icirc", 2, {195, 142} +"icirc", 2, {195, 174} +"Icy", 2, {208, 152} +"icy", 2, {208, 184} +"Idot", 2, {196, 176} +"IEcy", 2, {208, 149} +"iecy", 2, {208, 181} +"iexcl", 2, {194, 161} +"iff", 3, {226, 135, 148} +"ifr", 4, {240, 157, 148, 166} +"Ifr", 3, {226, 132, 145} +"Igrave", 2, {195, 140} +"igrave", 2, {195, 172} +"ii", 3, {226, 133, 136} +"iiiint", 3, {226, 168, 140} +"iiint", 3, {226, 136, 173} +"iinfin", 3, {226, 167, 156} +"iiota", 3, {226, 132, 169} +"IJlig", 2, {196, 178} +"ijlig", 2, {196, 179} +"Imacr", 2, {196, 170} +"imacr", 2, {196, 171} +"image", 3, {226, 132, 145} +"ImaginaryI", 3, {226, 133, 136} +"imagline", 3, {226, 132, 144} +"imagpart", 3, {226, 132, 145} +"imath", 2, {196, 177} +"Im", 3, {226, 132, 145} +"imof", 3, {226, 138, 183} +"imped", 2, {198, 181} +"Implies", 3, {226, 135, 146} +"incare", 3, {226, 132, 133} +"in", 3, {226, 136, 136} +"infin", 3, {226, 136, 158} +"infintie", 3, {226, 167, 157} +"inodot", 2, {196, 177} +"intcal", 3, {226, 138, 186} +"int", 3, {226, 136, 171} +"Int", 3, {226, 136, 172} +"integers", 3, {226, 132, 164} +"Integral", 3, {226, 136, 171} +"intercal", 3, {226, 138, 186} +"Intersection", 3, {226, 139, 130} +"intlarhk", 3, {226, 168, 151} +"intprod", 3, {226, 168, 188} +"InvisibleComma", 3, {226, 129, 163} +"InvisibleTimes", 3, {226, 129, 162} +"IOcy", 2, {208, 129} +"iocy", 2, {209, 145} +"Iogon", 2, {196, 174} +"iogon", 2, {196, 175} +"Iopf", 4, {240, 157, 149, 128} +"iopf", 4, {240, 157, 149, 154} +"Iota", 2, {206, 153} +"iota", 2, {206, 185} +"iprod", 3, {226, 168, 188} +"iquest", 2, {194, 191} +"iscr", 4, {240, 157, 146, 190} +"Iscr", 3, {226, 132, 144} +"isin", 3, {226, 136, 136} +"isindot", 3, {226, 139, 181} +"isinE", 3, {226, 139, 185} +"isins", 3, {226, 139, 180} +"isinsv", 3, {226, 139, 179} +"isinv", 3, {226, 136, 136} +"it", 3, {226, 129, 162} +"Itilde", 2, {196, 168} +"itilde", 2, {196, 169} +"Iukcy", 2, {208, 134} +"iukcy", 2, {209, 150} +"Iuml", 2, {195, 143} +"iuml", 2, {195, 175} +"Jcirc", 2, {196, 180} +"jcirc", 2, {196, 181} +"Jcy", 2, {208, 153} +"jcy", 2, {208, 185} +"Jfr", 4, {240, 157, 148, 141} +"jfr", 4, {240, 157, 148, 167} +"jmath", 2, {200, 183} +"Jopf", 4, {240, 157, 149, 129} +"jopf", 4, {240, 157, 149, 155} +"Jscr", 4, {240, 157, 146, 165} +"jscr", 4, {240, 157, 146, 191} +"Jsercy", 2, {208, 136} +"jsercy", 2, {209, 152} +"Jukcy", 2, {208, 132} +"jukcy", 2, {209, 148} +"Kappa", 2, {206, 154} +"kappa", 2, {206, 186} +"kappav", 2, {207, 176} +"Kcedil", 2, {196, 182} +"kcedil", 2, {196, 183} +"Kcy", 2, {208, 154} +"kcy", 2, {208, 186} +"Kfr", 4, {240, 157, 148, 142} +"kfr", 4, {240, 157, 148, 168} +"kgreen", 2, {196, 184} +"KHcy", 2, {208, 165} +"khcy", 2, {209, 133} +"KJcy", 2, {208, 140} +"kjcy", 2, {209, 156} +"Kopf", 4, {240, 157, 149, 130} +"kopf", 4, {240, 157, 149, 156} +"Kscr", 4, {240, 157, 146, 166} +"kscr", 4, {240, 157, 147, 128} +"lAarr", 3, {226, 135, 154} +"Lacute", 2, {196, 185} +"lacute", 2, {196, 186} +"laemptyv", 3, {226, 166, 180} +"lagran", 3, {226, 132, 146} +"Lambda", 2, {206, 155} +"lambda", 2, {206, 187} +"lang", 3, {226, 159, 168} +"Lang", 3, {226, 159, 170} +"langd", 3, {226, 166, 145} +"langle", 3, {226, 159, 168} +"lap", 3, {226, 170, 133} +"Laplacetrf", 3, {226, 132, 146} +"laquo", 2, {194, 171} +"larrb", 3, {226, 135, 164} +"larrbfs", 3, {226, 164, 159} +"larr", 3, {226, 134, 144} +"Larr", 3, {226, 134, 158} +"lArr", 3, {226, 135, 144} +"larrfs", 3, {226, 164, 157} +"larrhk", 3, {226, 134, 169} +"larrlp", 3, {226, 134, 171} +"larrpl", 3, {226, 164, 185} +"larrsim", 3, {226, 165, 179} +"larrtl", 3, {226, 134, 162} +"latail", 3, {226, 164, 153} +"lAtail", 3, {226, 164, 155} +"lat", 3, {226, 170, 171} +"late", 3, {226, 170, 173} +"lates", 3, {226, 170, 173} +"lbarr", 3, {226, 164, 140} +"lBarr", 3, {226, 164, 142} +"lbbrk", 3, {226, 157, 178} +"lbrace", 1, {123} +"lbrack", 1, {91} +"lbrke", 3, {226, 166, 139} +"lbrksld", 3, {226, 166, 143} +"lbrkslu", 3, {226, 166, 141} +"Lcaron", 2, {196, 189} +"lcaron", 2, {196, 190} +"Lcedil", 2, {196, 187} +"lcedil", 2, {196, 188} +"lceil", 3, {226, 140, 136} +"lcub", 1, {123} +"Lcy", 2, {208, 155} +"lcy", 2, {208, 187} +"ldca", 3, {226, 164, 182} +"ldquo", 3, {226, 128, 156} +"ldquor", 3, {226, 128, 158} +"ldrdhar", 3, {226, 165, 167} +"ldrushar", 3, {226, 165, 139} +"ldsh", 3, {226, 134, 178} +"le", 3, {226, 137, 164} +"lE", 3, {226, 137, 166} +"LeftAngleBracket", 3, {226, 159, 168} +"LeftArrowBar", 3, {226, 135, 164} +"leftarrow", 3, {226, 134, 144} +"LeftArrow", 3, {226, 134, 144} +"Leftarrow", 3, {226, 135, 144} +"LeftArrowRightArrow", 3, {226, 135, 134} +"leftarrowtail", 3, {226, 134, 162} +"LeftCeiling", 3, {226, 140, 136} +"LeftDoubleBracket", 3, {226, 159, 166} +"LeftDownTeeVector", 3, {226, 165, 161} +"LeftDownVectorBar", 3, {226, 165, 153} +"LeftDownVector", 3, {226, 135, 131} +"LeftFloor", 3, {226, 140, 138} +"leftharpoondown", 3, {226, 134, 189} +"leftharpoonup", 3, {226, 134, 188} +"leftleftarrows", 3, {226, 135, 135} +"leftrightarrow", 3, {226, 134, 148} +"LeftRightArrow", 3, {226, 134, 148} +"Leftrightarrow", 3, {226, 135, 148} +"leftrightarrows", 3, {226, 135, 134} +"leftrightharpoons", 3, {226, 135, 139} +"leftrightsquigarrow", 3, {226, 134, 173} +"LeftRightVector", 3, {226, 165, 142} +"LeftTeeArrow", 3, {226, 134, 164} +"LeftTee", 3, {226, 138, 163} +"LeftTeeVector", 3, {226, 165, 154} +"leftthreetimes", 3, {226, 139, 139} +"LeftTriangleBar", 3, {226, 167, 143} +"LeftTriangle", 3, {226, 138, 178} +"LeftTriangleEqual", 3, {226, 138, 180} +"LeftUpDownVector", 3, {226, 165, 145} +"LeftUpTeeVector", 3, {226, 165, 160} +"LeftUpVectorBar", 3, {226, 165, 152} +"LeftUpVector", 3, {226, 134, 191} +"LeftVectorBar", 3, {226, 165, 146} +"LeftVector", 3, {226, 134, 188} +"lEg", 3, {226, 170, 139} +"leg", 3, {226, 139, 154} +"leq", 3, {226, 137, 164} +"leqq", 3, {226, 137, 166} +"leqslant", 3, {226, 169, 189} +"lescc", 3, {226, 170, 168} +"les", 3, {226, 169, 189} +"lesdot", 3, {226, 169, 191} +"lesdoto", 3, {226, 170, 129} +"lesdotor", 3, {226, 170, 131} +"lesg", 3, {226, 139, 154} +"lesges", 3, {226, 170, 147} +"lessapprox", 3, {226, 170, 133} +"lessdot", 3, {226, 139, 150} +"lesseqgtr", 3, {226, 139, 154} +"lesseqqgtr", 3, {226, 170, 139} +"LessEqualGreater", 3, {226, 139, 154} +"LessFullEqual", 3, {226, 137, 166} +"LessGreater", 3, {226, 137, 182} +"lessgtr", 3, {226, 137, 182} +"LessLess", 3, {226, 170, 161} +"lesssim", 3, {226, 137, 178} +"LessSlantEqual", 3, {226, 169, 189} +"LessTilde", 3, {226, 137, 178} +"lfisht", 3, {226, 165, 188} +"lfloor", 3, {226, 140, 138} +"Lfr", 4, {240, 157, 148, 143} +"lfr", 4, {240, 157, 148, 169} +"lg", 3, {226, 137, 182} +"lgE", 3, {226, 170, 145} +"lHar", 3, {226, 165, 162} +"lhard", 3, {226, 134, 189} +"lharu", 3, {226, 134, 188} +"lharul", 3, {226, 165, 170} +"lhblk", 3, {226, 150, 132} +"LJcy", 2, {208, 137} +"ljcy", 2, {209, 153} +"llarr", 3, {226, 135, 135} +"ll", 3, {226, 137, 170} +"Ll", 3, {226, 139, 152} +"llcorner", 3, {226, 140, 158} +"Lleftarrow", 3, {226, 135, 154} +"llhard", 3, {226, 165, 171} +"lltri", 3, {226, 151, 186} +"Lmidot", 2, {196, 191} +"lmidot", 2, {197, 128} +"lmoustache", 3, {226, 142, 176} +"lmoust", 3, {226, 142, 176} +"lnap", 3, {226, 170, 137} +"lnapprox", 3, {226, 170, 137} +"lne", 3, {226, 170, 135} +"lnE", 3, {226, 137, 168} +"lneq", 3, {226, 170, 135} +"lneqq", 3, {226, 137, 168} +"lnsim", 3, {226, 139, 166} +"loang", 3, {226, 159, 172} +"loarr", 3, {226, 135, 189} +"lobrk", 3, {226, 159, 166} +"longleftarrow", 3, {226, 159, 181} +"LongLeftArrow", 3, {226, 159, 181} +"Longleftarrow", 3, {226, 159, 184} +"longleftrightarrow", 3, {226, 159, 183} +"LongLeftRightArrow", 3, {226, 159, 183} +"Longleftrightarrow", 3, {226, 159, 186} +"longmapsto", 3, {226, 159, 188} +"longrightarrow", 3, {226, 159, 182} +"LongRightArrow", 3, {226, 159, 182} +"Longrightarrow", 3, {226, 159, 185} +"looparrowleft", 3, {226, 134, 171} +"looparrowright", 3, {226, 134, 172} +"lopar", 3, {226, 166, 133} +"Lopf", 4, {240, 157, 149, 131} +"lopf", 4, {240, 157, 149, 157} +"loplus", 3, {226, 168, 173} +"lotimes", 3, {226, 168, 180} +"lowast", 3, {226, 136, 151} +"lowbar", 1, {95} +"LowerLeftArrow", 3, {226, 134, 153} +"LowerRightArrow", 3, {226, 134, 152} +"loz", 3, {226, 151, 138} +"lozenge", 3, {226, 151, 138} +"lozf", 3, {226, 167, 171} +"lpar", 1, {40} +"lparlt", 3, {226, 166, 147} +"lrarr", 3, {226, 135, 134} +"lrcorner", 3, {226, 140, 159} +"lrhar", 3, {226, 135, 139} +"lrhard", 3, {226, 165, 173} +"lrm", 3, {226, 128, 142} +"lrtri", 3, {226, 138, 191} +"lsaquo", 3, {226, 128, 185} +"lscr", 4, {240, 157, 147, 129} +"Lscr", 3, {226, 132, 146} +"lsh", 3, {226, 134, 176} +"Lsh", 3, {226, 134, 176} +"lsim", 3, {226, 137, 178} +"lsime", 3, {226, 170, 141} +"lsimg", 3, {226, 170, 143} +"lsqb", 1, {91} +"lsquo", 3, {226, 128, 152} +"lsquor", 3, {226, 128, 154} +"Lstrok", 2, {197, 129} +"lstrok", 2, {197, 130} +"ltcc", 3, {226, 170, 166} +"ltcir", 3, {226, 169, 185} +"lt", 1, {60} +"LT", 1, {60} +"Lt", 3, {226, 137, 170} +"ltdot", 3, {226, 139, 150} +"lthree", 3, {226, 139, 139} +"ltimes", 3, {226, 139, 137} +"ltlarr", 3, {226, 165, 182} +"ltquest", 3, {226, 169, 187} +"ltri", 3, {226, 151, 131} +"ltrie", 3, {226, 138, 180} +"ltrif", 3, {226, 151, 130} +"ltrPar", 3, {226, 166, 150} +"lurdshar", 3, {226, 165, 138} +"luruhar", 3, {226, 165, 166} +"lvertneqq", 3, {226, 137, 168} +"lvnE", 3, {226, 137, 168} +"macr", 2, {194, 175} +"male", 3, {226, 153, 130} +"malt", 3, {226, 156, 160} +"maltese", 3, {226, 156, 160} +"Map", 3, {226, 164, 133} +"map", 3, {226, 134, 166} +"mapsto", 3, {226, 134, 166} +"mapstodown", 3, {226, 134, 167} +"mapstoleft", 3, {226, 134, 164} +"mapstoup", 3, {226, 134, 165} +"marker", 3, {226, 150, 174} +"mcomma", 3, {226, 168, 169} +"Mcy", 2, {208, 156} +"mcy", 2, {208, 188} +"mdash", 3, {226, 128, 148} +"mDDot", 3, {226, 136, 186} +"measuredangle", 3, {226, 136, 161} +"MediumSpace", 3, {226, 129, 159} +"Mellintrf", 3, {226, 132, 179} +"Mfr", 4, {240, 157, 148, 144} +"mfr", 4, {240, 157, 148, 170} +"mho", 3, {226, 132, 167} +"micro", 2, {194, 181} +"midast", 1, {42} +"midcir", 3, {226, 171, 176} +"mid", 3, {226, 136, 163} +"middot", 2, {194, 183} +"minusb", 3, {226, 138, 159} +"minus", 3, {226, 136, 146} +"minusd", 3, {226, 136, 184} +"minusdu", 3, {226, 168, 170} +"MinusPlus", 3, {226, 136, 147} +"mlcp", 3, {226, 171, 155} +"mldr", 3, {226, 128, 166} +"mnplus", 3, {226, 136, 147} +"models", 3, {226, 138, 167} +"Mopf", 4, {240, 157, 149, 132} +"mopf", 4, {240, 157, 149, 158} +"mp", 3, {226, 136, 147} +"mscr", 4, {240, 157, 147, 130} +"Mscr", 3, {226, 132, 179} +"mstpos", 3, {226, 136, 190} +"Mu", 2, {206, 156} +"mu", 2, {206, 188} +"multimap", 3, {226, 138, 184} +"mumap", 3, {226, 138, 184} +"nabla", 3, {226, 136, 135} +"Nacute", 2, {197, 131} +"nacute", 2, {197, 132} +"nang", 3, {226, 136, 160} +"nap", 3, {226, 137, 137} +"napE", 3, {226, 169, 176} +"napid", 3, {226, 137, 139} +"napos", 2, {197, 137} +"napprox", 3, {226, 137, 137} +"natural", 3, {226, 153, 174} +"naturals", 3, {226, 132, 149} +"natur", 3, {226, 153, 174} +"nbsp", 2, {194, 160} +"nbump", 3, {226, 137, 142} +"nbumpe", 3, {226, 137, 143} +"ncap", 3, {226, 169, 131} +"Ncaron", 2, {197, 135} +"ncaron", 2, {197, 136} +"Ncedil", 2, {197, 133} +"ncedil", 2, {197, 134} +"ncong", 3, {226, 137, 135} +"ncongdot", 3, {226, 169, 173} +"ncup", 3, {226, 169, 130} +"Ncy", 2, {208, 157} +"ncy", 2, {208, 189} +"ndash", 3, {226, 128, 147} +"nearhk", 3, {226, 164, 164} +"nearr", 3, {226, 134, 151} +"neArr", 3, {226, 135, 151} +"nearrow", 3, {226, 134, 151} +"ne", 3, {226, 137, 160} +"nedot", 3, {226, 137, 144} +"NegativeMediumSpace", 3, {226, 128, 139} +"NegativeThickSpace", 3, {226, 128, 139} +"NegativeThinSpace", 3, {226, 128, 139} +"NegativeVeryThinSpace", 3, {226, 128, 139} +"nequiv", 3, {226, 137, 162} +"nesear", 3, {226, 164, 168} +"nesim", 3, {226, 137, 130} +"NestedGreaterGreater", 3, {226, 137, 171} +"NestedLessLess", 3, {226, 137, 170} +"NewLine", 1, {10} +"nexist", 3, {226, 136, 132} +"nexists", 3, {226, 136, 132} +"Nfr", 4, {240, 157, 148, 145} +"nfr", 4, {240, 157, 148, 171} +"ngE", 3, {226, 137, 167} +"nge", 3, {226, 137, 177} +"ngeq", 3, {226, 137, 177} +"ngeqq", 3, {226, 137, 167} +"ngeqslant", 3, {226, 169, 190} +"nges", 3, {226, 169, 190} +"nGg", 3, {226, 139, 153} +"ngsim", 3, {226, 137, 181} +"nGt", 3, {226, 137, 171} +"ngt", 3, {226, 137, 175} +"ngtr", 3, {226, 137, 175} +"nGtv", 3, {226, 137, 171} +"nharr", 3, {226, 134, 174} +"nhArr", 3, {226, 135, 142} +"nhpar", 3, {226, 171, 178} +"ni", 3, {226, 136, 139} +"nis", 3, {226, 139, 188} +"nisd", 3, {226, 139, 186} +"niv", 3, {226, 136, 139} +"NJcy", 2, {208, 138} +"njcy", 2, {209, 154} +"nlarr", 3, {226, 134, 154} +"nlArr", 3, {226, 135, 141} +"nldr", 3, {226, 128, 165} +"nlE", 3, {226, 137, 166} +"nle", 3, {226, 137, 176} +"nleftarrow", 3, {226, 134, 154} +"nLeftarrow", 3, {226, 135, 141} +"nleftrightarrow", 3, {226, 134, 174} +"nLeftrightarrow", 3, {226, 135, 142} +"nleq", 3, {226, 137, 176} +"nleqq", 3, {226, 137, 166} +"nleqslant", 3, {226, 169, 189} +"nles", 3, {226, 169, 189} +"nless", 3, {226, 137, 174} +"nLl", 3, {226, 139, 152} +"nlsim", 3, {226, 137, 180} +"nLt", 3, {226, 137, 170} +"nlt", 3, {226, 137, 174} +"nltri", 3, {226, 139, 170} +"nltrie", 3, {226, 139, 172} +"nLtv", 3, {226, 137, 170} +"nmid", 3, {226, 136, 164} +"NoBreak", 3, {226, 129, 160} +"NonBreakingSpace", 2, {194, 160} +"nopf", 4, {240, 157, 149, 159} +"Nopf", 3, {226, 132, 149} +"Not", 3, {226, 171, 172} +"not", 2, {194, 172} +"NotCongruent", 3, {226, 137, 162} +"NotCupCap", 3, {226, 137, 173} +"NotDoubleVerticalBar", 3, {226, 136, 166} +"NotElement", 3, {226, 136, 137} +"NotEqual", 3, {226, 137, 160} +"NotEqualTilde", 3, {226, 137, 130} +"NotExists", 3, {226, 136, 132} +"NotGreater", 3, {226, 137, 175} +"NotGreaterEqual", 3, {226, 137, 177} +"NotGreaterFullEqual", 3, {226, 137, 167} +"NotGreaterGreater", 3, {226, 137, 171} +"NotGreaterLess", 3, {226, 137, 185} +"NotGreaterSlantEqual", 3, {226, 169, 190} +"NotGreaterTilde", 3, {226, 137, 181} +"NotHumpDownHump", 3, {226, 137, 142} +"NotHumpEqual", 3, {226, 137, 143} +"notin", 3, {226, 136, 137} +"notindot", 3, {226, 139, 181} +"notinE", 3, {226, 139, 185} +"notinva", 3, {226, 136, 137} +"notinvb", 3, {226, 139, 183} +"notinvc", 3, {226, 139, 182} +"NotLeftTriangleBar", 3, {226, 167, 143} +"NotLeftTriangle", 3, {226, 139, 170} +"NotLeftTriangleEqual", 3, {226, 139, 172} +"NotLess", 3, {226, 137, 174} +"NotLessEqual", 3, {226, 137, 176} +"NotLessGreater", 3, {226, 137, 184} +"NotLessLess", 3, {226, 137, 170} +"NotLessSlantEqual", 3, {226, 169, 189} +"NotLessTilde", 3, {226, 137, 180} +"NotNestedGreaterGreater", 3, {226, 170, 162} +"NotNestedLessLess", 3, {226, 170, 161} +"notni", 3, {226, 136, 140} +"notniva", 3, {226, 136, 140} +"notnivb", 3, {226, 139, 190} +"notnivc", 3, {226, 139, 189} +"NotPrecedes", 3, {226, 138, 128} +"NotPrecedesEqual", 3, {226, 170, 175} +"NotPrecedesSlantEqual", 3, {226, 139, 160} +"NotReverseElement", 3, {226, 136, 140} +"NotRightTriangleBar", 3, {226, 167, 144} +"NotRightTriangle", 3, {226, 139, 171} +"NotRightTriangleEqual", 3, {226, 139, 173} +"NotSquareSubset", 3, {226, 138, 143} +"NotSquareSubsetEqual", 3, {226, 139, 162} +"NotSquareSuperset", 3, {226, 138, 144} +"NotSquareSupersetEqual", 3, {226, 139, 163} +"NotSubset", 3, {226, 138, 130} +"NotSubsetEqual", 3, {226, 138, 136} +"NotSucceeds", 3, {226, 138, 129} +"NotSucceedsEqual", 3, {226, 170, 176} +"NotSucceedsSlantEqual", 3, {226, 139, 161} +"NotSucceedsTilde", 3, {226, 137, 191} +"NotSuperset", 3, {226, 138, 131} +"NotSupersetEqual", 3, {226, 138, 137} +"NotTilde", 3, {226, 137, 129} +"NotTildeEqual", 3, {226, 137, 132} +"NotTildeFullEqual", 3, {226, 137, 135} +"NotTildeTilde", 3, {226, 137, 137} +"NotVerticalBar", 3, {226, 136, 164} +"nparallel", 3, {226, 136, 166} +"npar", 3, {226, 136, 166} +"nparsl", 3, {226, 171, 189} +"npart", 3, {226, 136, 130} +"npolint", 3, {226, 168, 148} +"npr", 3, {226, 138, 128} +"nprcue", 3, {226, 139, 160} +"nprec", 3, {226, 138, 128} +"npreceq", 3, {226, 170, 175} +"npre", 3, {226, 170, 175} +"nrarrc", 3, {226, 164, 179} +"nrarr", 3, {226, 134, 155} +"nrArr", 3, {226, 135, 143} +"nrarrw", 3, {226, 134, 157} +"nrightarrow", 3, {226, 134, 155} +"nRightarrow", 3, {226, 135, 143} +"nrtri", 3, {226, 139, 171} +"nrtrie", 3, {226, 139, 173} +"nsc", 3, {226, 138, 129} +"nsccue", 3, {226, 139, 161} +"nsce", 3, {226, 170, 176} +"Nscr", 4, {240, 157, 146, 169} +"nscr", 4, {240, 157, 147, 131} +"nshortmid", 3, {226, 136, 164} +"nshortparallel", 3, {226, 136, 166} +"nsim", 3, {226, 137, 129} +"nsime", 3, {226, 137, 132} +"nsimeq", 3, {226, 137, 132} +"nsmid", 3, {226, 136, 164} +"nspar", 3, {226, 136, 166} +"nsqsube", 3, {226, 139, 162} +"nsqsupe", 3, {226, 139, 163} +"nsub", 3, {226, 138, 132} +"nsubE", 3, {226, 171, 133} +"nsube", 3, {226, 138, 136} +"nsubset", 3, {226, 138, 130} +"nsubseteq", 3, {226, 138, 136} +"nsubseteqq", 3, {226, 171, 133} +"nsucc", 3, {226, 138, 129} +"nsucceq", 3, {226, 170, 176} +"nsup", 3, {226, 138, 133} +"nsupE", 3, {226, 171, 134} +"nsupe", 3, {226, 138, 137} +"nsupset", 3, {226, 138, 131} +"nsupseteq", 3, {226, 138, 137} +"nsupseteqq", 3, {226, 171, 134} +"ntgl", 3, {226, 137, 185} +"Ntilde", 2, {195, 145} +"ntilde", 2, {195, 177} +"ntlg", 3, {226, 137, 184} +"ntriangleleft", 3, {226, 139, 170} +"ntrianglelefteq", 3, {226, 139, 172} +"ntriangleright", 3, {226, 139, 171} +"ntrianglerighteq", 3, {226, 139, 173} +"Nu", 2, {206, 157} +"nu", 2, {206, 189} +"num", 1, {35} +"numero", 3, {226, 132, 150} +"numsp", 3, {226, 128, 135} +"nvap", 3, {226, 137, 141} +"nvdash", 3, {226, 138, 172} +"nvDash", 3, {226, 138, 173} +"nVdash", 3, {226, 138, 174} +"nVDash", 3, {226, 138, 175} +"nvge", 3, {226, 137, 165} +"nvgt", 1, {62} +"nvHarr", 3, {226, 164, 132} +"nvinfin", 3, {226, 167, 158} +"nvlArr", 3, {226, 164, 130} +"nvle", 3, {226, 137, 164} +"nvlt", 1, {60} +"nvltrie", 3, {226, 138, 180} +"nvrArr", 3, {226, 164, 131} +"nvrtrie", 3, {226, 138, 181} +"nvsim", 3, {226, 136, 188} +"nwarhk", 3, {226, 164, 163} +"nwarr", 3, {226, 134, 150} +"nwArr", 3, {226, 135, 150} +"nwarrow", 3, {226, 134, 150} +"nwnear", 3, {226, 164, 167} +"Oacute", 2, {195, 147} +"oacute", 2, {195, 179} +"oast", 3, {226, 138, 155} +"Ocirc", 2, {195, 148} +"ocirc", 2, {195, 180} +"ocir", 3, {226, 138, 154} +"Ocy", 2, {208, 158} +"ocy", 2, {208, 190} +"odash", 3, {226, 138, 157} +"Odblac", 2, {197, 144} +"odblac", 2, {197, 145} +"odiv", 3, {226, 168, 184} +"odot", 3, {226, 138, 153} +"odsold", 3, {226, 166, 188} +"OElig", 2, {197, 146} +"oelig", 2, {197, 147} +"ofcir", 3, {226, 166, 191} +"Ofr", 4, {240, 157, 148, 146} +"ofr", 4, {240, 157, 148, 172} +"ogon", 2, {203, 155} +"Ograve", 2, {195, 146} +"ograve", 2, {195, 178} +"ogt", 3, {226, 167, 129} +"ohbar", 3, {226, 166, 181} +"ohm", 2, {206, 169} +"oint", 3, {226, 136, 174} +"olarr", 3, {226, 134, 186} +"olcir", 3, {226, 166, 190} +"olcross", 3, {226, 166, 187} +"oline", 3, {226, 128, 190} +"olt", 3, {226, 167, 128} +"Omacr", 2, {197, 140} +"omacr", 2, {197, 141} +"Omega", 2, {206, 169} +"omega", 2, {207, 137} +"Omicron", 2, {206, 159} +"omicron", 2, {206, 191} +"omid", 3, {226, 166, 182} +"ominus", 3, {226, 138, 150} +"Oopf", 4, {240, 157, 149, 134} +"oopf", 4, {240, 157, 149, 160} +"opar", 3, {226, 166, 183} +"OpenCurlyDoubleQuote", 3, {226, 128, 156} +"OpenCurlyQuote", 3, {226, 128, 152} +"operp", 3, {226, 166, 185} +"oplus", 3, {226, 138, 149} +"orarr", 3, {226, 134, 187} +"Or", 3, {226, 169, 148} +"or", 3, {226, 136, 168} +"ord", 3, {226, 169, 157} +"order", 3, {226, 132, 180} +"orderof", 3, {226, 132, 180} +"ordf", 2, {194, 170} +"ordm", 2, {194, 186} +"origof", 3, {226, 138, 182} +"oror", 3, {226, 169, 150} +"orslope", 3, {226, 169, 151} +"orv", 3, {226, 169, 155} +"oS", 3, {226, 147, 136} +"Oscr", 4, {240, 157, 146, 170} +"oscr", 3, {226, 132, 180} +"Oslash", 2, {195, 152} +"oslash", 2, {195, 184} +"osol", 3, {226, 138, 152} +"Otilde", 2, {195, 149} +"otilde", 2, {195, 181} +"otimesas", 3, {226, 168, 182} +"Otimes", 3, {226, 168, 183} +"otimes", 3, {226, 138, 151} +"Ouml", 2, {195, 150} +"ouml", 2, {195, 182} +"ovbar", 3, {226, 140, 189} +"OverBar", 3, {226, 128, 190} +"OverBrace", 3, {226, 143, 158} +"OverBracket", 3, {226, 142, 180} +"OverParenthesis", 3, {226, 143, 156} +"para", 2, {194, 182} +"parallel", 3, {226, 136, 165} +"par", 3, {226, 136, 165} +"parsim", 3, {226, 171, 179} +"parsl", 3, {226, 171, 189} +"part", 3, {226, 136, 130} +"PartialD", 3, {226, 136, 130} +"Pcy", 2, {208, 159} +"pcy", 2, {208, 191} +"percnt", 1, {37} +"period", 1, {46} +"permil", 3, {226, 128, 176} +"perp", 3, {226, 138, 165} +"pertenk", 3, {226, 128, 177} +"Pfr", 4, {240, 157, 148, 147} +"pfr", 4, {240, 157, 148, 173} +"Phi", 2, {206, 166} +"phi", 2, {207, 134} +"phiv", 2, {207, 149} +"phmmat", 3, {226, 132, 179} +"phone", 3, {226, 152, 142} +"Pi", 2, {206, 160} +"pi", 2, {207, 128} +"pitchfork", 3, {226, 139, 148} +"piv", 2, {207, 150} +"planck", 3, {226, 132, 143} +"planckh", 3, {226, 132, 142} +"plankv", 3, {226, 132, 143} +"plusacir", 3, {226, 168, 163} +"plusb", 3, {226, 138, 158} +"pluscir", 3, {226, 168, 162} +"plus", 1, {43} +"plusdo", 3, {226, 136, 148} +"plusdu", 3, {226, 168, 165} +"pluse", 3, {226, 169, 178} +"PlusMinus", 2, {194, 177} +"plusmn", 2, {194, 177} +"plussim", 3, {226, 168, 166} +"plustwo", 3, {226, 168, 167} +"pm", 2, {194, 177} +"Poincareplane", 3, {226, 132, 140} +"pointint", 3, {226, 168, 149} +"popf", 4, {240, 157, 149, 161} +"Popf", 3, {226, 132, 153} +"pound", 2, {194, 163} +"prap", 3, {226, 170, 183} +"Pr", 3, {226, 170, 187} +"pr", 3, {226, 137, 186} +"prcue", 3, {226, 137, 188} +"precapprox", 3, {226, 170, 183} +"prec", 3, {226, 137, 186} +"preccurlyeq", 3, {226, 137, 188} +"Precedes", 3, {226, 137, 186} +"PrecedesEqual", 3, {226, 170, 175} +"PrecedesSlantEqual", 3, {226, 137, 188} +"PrecedesTilde", 3, {226, 137, 190} +"preceq", 3, {226, 170, 175} +"precnapprox", 3, {226, 170, 185} +"precneqq", 3, {226, 170, 181} +"precnsim", 3, {226, 139, 168} +"pre", 3, {226, 170, 175} +"prE", 3, {226, 170, 179} +"precsim", 3, {226, 137, 190} +"prime", 3, {226, 128, 178} +"Prime", 3, {226, 128, 179} +"primes", 3, {226, 132, 153} +"prnap", 3, {226, 170, 185} +"prnE", 3, {226, 170, 181} +"prnsim", 3, {226, 139, 168} +"prod", 3, {226, 136, 143} +"Product", 3, {226, 136, 143} +"profalar", 3, {226, 140, 174} +"profline", 3, {226, 140, 146} +"profsurf", 3, {226, 140, 147} +"prop", 3, {226, 136, 157} +"Proportional", 3, {226, 136, 157} +"Proportion", 3, {226, 136, 183} +"propto", 3, {226, 136, 157} +"prsim", 3, {226, 137, 190} +"prurel", 3, {226, 138, 176} +"Pscr", 4, {240, 157, 146, 171} +"pscr", 4, {240, 157, 147, 133} +"Psi", 2, {206, 168} +"psi", 2, {207, 136} +"puncsp", 3, {226, 128, 136} +"Qfr", 4, {240, 157, 148, 148} +"qfr", 4, {240, 157, 148, 174} +"qint", 3, {226, 168, 140} +"qopf", 4, {240, 157, 149, 162} +"Qopf", 3, {226, 132, 154} +"qprime", 3, {226, 129, 151} +"Qscr", 4, {240, 157, 146, 172} +"qscr", 4, {240, 157, 147, 134} +"quaternions", 3, {226, 132, 141} +"quatint", 3, {226, 168, 150} +"quest", 1, {63} +"questeq", 3, {226, 137, 159} +"quot", 1, {34} +"QUOT", 1, {34} +"rAarr", 3, {226, 135, 155} +"race", 3, {226, 136, 189} +"Racute", 2, {197, 148} +"racute", 2, {197, 149} +"radic", 3, {226, 136, 154} +"raemptyv", 3, {226, 166, 179} +"rang", 3, {226, 159, 169} +"Rang", 3, {226, 159, 171} +"rangd", 3, {226, 166, 146} +"range", 3, {226, 166, 165} +"rangle", 3, {226, 159, 169} +"raquo", 2, {194, 187} +"rarrap", 3, {226, 165, 181} +"rarrb", 3, {226, 135, 165} +"rarrbfs", 3, {226, 164, 160} +"rarrc", 3, {226, 164, 179} +"rarr", 3, {226, 134, 146} +"Rarr", 3, {226, 134, 160} +"rArr", 3, {226, 135, 146} +"rarrfs", 3, {226, 164, 158} +"rarrhk", 3, {226, 134, 170} +"rarrlp", 3, {226, 134, 172} +"rarrpl", 3, {226, 165, 133} +"rarrsim", 3, {226, 165, 180} +"Rarrtl", 3, {226, 164, 150} +"rarrtl", 3, {226, 134, 163} +"rarrw", 3, {226, 134, 157} +"ratail", 3, {226, 164, 154} +"rAtail", 3, {226, 164, 156} +"ratio", 3, {226, 136, 182} +"rationals", 3, {226, 132, 154} +"rbarr", 3, {226, 164, 141} +"rBarr", 3, {226, 164, 143} +"RBarr", 3, {226, 164, 144} +"rbbrk", 3, {226, 157, 179} +"rbrace", 1, {125} +"rbrack", 1, {93} +"rbrke", 3, {226, 166, 140} +"rbrksld", 3, {226, 166, 142} +"rbrkslu", 3, {226, 166, 144} +"Rcaron", 2, {197, 152} +"rcaron", 2, {197, 153} +"Rcedil", 2, {197, 150} +"rcedil", 2, {197, 151} +"rceil", 3, {226, 140, 137} +"rcub", 1, {125} +"Rcy", 2, {208, 160} +"rcy", 2, {209, 128} +"rdca", 3, {226, 164, 183} +"rdldhar", 3, {226, 165, 169} +"rdquo", 3, {226, 128, 157} +"rdquor", 3, {226, 128, 157} +"rdsh", 3, {226, 134, 179} +"real", 3, {226, 132, 156} +"realine", 3, {226, 132, 155} +"realpart", 3, {226, 132, 156} +"reals", 3, {226, 132, 157} +"Re", 3, {226, 132, 156} +"rect", 3, {226, 150, 173} +"reg", 2, {194, 174} +"REG", 2, {194, 174} +"ReverseElement", 3, {226, 136, 139} +"ReverseEquilibrium", 3, {226, 135, 139} +"ReverseUpEquilibrium", 3, {226, 165, 175} +"rfisht", 3, {226, 165, 189} +"rfloor", 3, {226, 140, 139} +"rfr", 4, {240, 157, 148, 175} +"Rfr", 3, {226, 132, 156} +"rHar", 3, {226, 165, 164} +"rhard", 3, {226, 135, 129} +"rharu", 3, {226, 135, 128} +"rharul", 3, {226, 165, 172} +"Rho", 2, {206, 161} +"rho", 2, {207, 129} +"rhov", 2, {207, 177} +"RightAngleBracket", 3, {226, 159, 169} +"RightArrowBar", 3, {226, 135, 165} +"rightarrow", 3, {226, 134, 146} +"RightArrow", 3, {226, 134, 146} +"Rightarrow", 3, {226, 135, 146} +"RightArrowLeftArrow", 3, {226, 135, 132} +"rightarrowtail", 3, {226, 134, 163} +"RightCeiling", 3, {226, 140, 137} +"RightDoubleBracket", 3, {226, 159, 167} +"RightDownTeeVector", 3, {226, 165, 157} +"RightDownVectorBar", 3, {226, 165, 149} +"RightDownVector", 3, {226, 135, 130} +"RightFloor", 3, {226, 140, 139} +"rightharpoondown", 3, {226, 135, 129} +"rightharpoonup", 3, {226, 135, 128} +"rightleftarrows", 3, {226, 135, 132} +"rightleftharpoons", 3, {226, 135, 140} +"rightrightarrows", 3, {226, 135, 137} +"rightsquigarrow", 3, {226, 134, 157} +"RightTeeArrow", 3, {226, 134, 166} +"RightTee", 3, {226, 138, 162} +"RightTeeVector", 3, {226, 165, 155} +"rightthreetimes", 3, {226, 139, 140} +"RightTriangleBar", 3, {226, 167, 144} +"RightTriangle", 3, {226, 138, 179} +"RightTriangleEqual", 3, {226, 138, 181} +"RightUpDownVector", 3, {226, 165, 143} +"RightUpTeeVector", 3, {226, 165, 156} +"RightUpVectorBar", 3, {226, 165, 148} +"RightUpVector", 3, {226, 134, 190} +"RightVectorBar", 3, {226, 165, 147} +"RightVector", 3, {226, 135, 128} +"ring", 2, {203, 154} +"risingdotseq", 3, {226, 137, 147} +"rlarr", 3, {226, 135, 132} +"rlhar", 3, {226, 135, 140} +"rlm", 3, {226, 128, 143} +"rmoustache", 3, {226, 142, 177} +"rmoust", 3, {226, 142, 177} +"rnmid", 3, {226, 171, 174} +"roang", 3, {226, 159, 173} +"roarr", 3, {226, 135, 190} +"robrk", 3, {226, 159, 167} +"ropar", 3, {226, 166, 134} +"ropf", 4, {240, 157, 149, 163} +"Ropf", 3, {226, 132, 157} +"roplus", 3, {226, 168, 174} +"rotimes", 3, {226, 168, 181} +"RoundImplies", 3, {226, 165, 176} +"rpar", 1, {41} +"rpargt", 3, {226, 166, 148} +"rppolint", 3, {226, 168, 146} +"rrarr", 3, {226, 135, 137} +"Rrightarrow", 3, {226, 135, 155} +"rsaquo", 3, {226, 128, 186} +"rscr", 4, {240, 157, 147, 135} +"Rscr", 3, {226, 132, 155} +"rsh", 3, {226, 134, 177} +"Rsh", 3, {226, 134, 177} +"rsqb", 1, {93} +"rsquo", 3, {226, 128, 153} +"rsquor", 3, {226, 128, 153} +"rthree", 3, {226, 139, 140} +"rtimes", 3, {226, 139, 138} +"rtri", 3, {226, 150, 185} +"rtrie", 3, {226, 138, 181} +"rtrif", 3, {226, 150, 184} +"rtriltri", 3, {226, 167, 142} +"RuleDelayed", 3, {226, 167, 180} +"ruluhar", 3, {226, 165, 168} +"rx", 3, {226, 132, 158} +"Sacute", 2, {197, 154} +"sacute", 2, {197, 155} +"sbquo", 3, {226, 128, 154} +"scap", 3, {226, 170, 184} +"Scaron", 2, {197, 160} +"scaron", 2, {197, 161} +"Sc", 3, {226, 170, 188} +"sc", 3, {226, 137, 187} +"sccue", 3, {226, 137, 189} +"sce", 3, {226, 170, 176} +"scE", 3, {226, 170, 180} +"Scedil", 2, {197, 158} +"scedil", 2, {197, 159} +"Scirc", 2, {197, 156} +"scirc", 2, {197, 157} +"scnap", 3, {226, 170, 186} +"scnE", 3, {226, 170, 182} +"scnsim", 3, {226, 139, 169} +"scpolint", 3, {226, 168, 147} +"scsim", 3, {226, 137, 191} +"Scy", 2, {208, 161} +"scy", 2, {209, 129} +"sdotb", 3, {226, 138, 161} +"sdot", 3, {226, 139, 133} +"sdote", 3, {226, 169, 166} +"searhk", 3, {226, 164, 165} +"searr", 3, {226, 134, 152} +"seArr", 3, {226, 135, 152} +"searrow", 3, {226, 134, 152} +"sect", 2, {194, 167} +"semi", 1, {59} +"seswar", 3, {226, 164, 169} +"setminus", 3, {226, 136, 150} +"setmn", 3, {226, 136, 150} +"sext", 3, {226, 156, 182} +"Sfr", 4, {240, 157, 148, 150} +"sfr", 4, {240, 157, 148, 176} +"sfrown", 3, {226, 140, 162} +"sharp", 3, {226, 153, 175} +"SHCHcy", 2, {208, 169} +"shchcy", 2, {209, 137} +"SHcy", 2, {208, 168} +"shcy", 2, {209, 136} +"ShortDownArrow", 3, {226, 134, 147} +"ShortLeftArrow", 3, {226, 134, 144} +"shortmid", 3, {226, 136, 163} +"shortparallel", 3, {226, 136, 165} +"ShortRightArrow", 3, {226, 134, 146} +"ShortUpArrow", 3, {226, 134, 145} +"shy", 2, {194, 173} +"Sigma", 2, {206, 163} +"sigma", 2, {207, 131} +"sigmaf", 2, {207, 130} +"sigmav", 2, {207, 130} +"sim", 3, {226, 136, 188} +"simdot", 3, {226, 169, 170} +"sime", 3, {226, 137, 131} +"simeq", 3, {226, 137, 131} +"simg", 3, {226, 170, 158} +"simgE", 3, {226, 170, 160} +"siml", 3, {226, 170, 157} +"simlE", 3, {226, 170, 159} +"simne", 3, {226, 137, 134} +"simplus", 3, {226, 168, 164} +"simrarr", 3, {226, 165, 178} +"slarr", 3, {226, 134, 144} +"SmallCircle", 3, {226, 136, 152} +"smallsetminus", 3, {226, 136, 150} +"smashp", 3, {226, 168, 179} +"smeparsl", 3, {226, 167, 164} +"smid", 3, {226, 136, 163} +"smile", 3, {226, 140, 163} +"smt", 3, {226, 170, 170} +"smte", 3, {226, 170, 172} +"smtes", 3, {226, 170, 172} +"SOFTcy", 2, {208, 172} +"softcy", 2, {209, 140} +"solbar", 3, {226, 140, 191} +"solb", 3, {226, 167, 132} +"sol", 1, {47} +"Sopf", 4, {240, 157, 149, 138} +"sopf", 4, {240, 157, 149, 164} +"spades", 3, {226, 153, 160} +"spadesuit", 3, {226, 153, 160} +"spar", 3, {226, 136, 165} +"sqcap", 3, {226, 138, 147} +"sqcaps", 3, {226, 138, 147} +"sqcup", 3, {226, 138, 148} +"sqcups", 3, {226, 138, 148} +"Sqrt", 3, {226, 136, 154} +"sqsub", 3, {226, 138, 143} +"sqsube", 3, {226, 138, 145} +"sqsubset", 3, {226, 138, 143} +"sqsubseteq", 3, {226, 138, 145} +"sqsup", 3, {226, 138, 144} +"sqsupe", 3, {226, 138, 146} +"sqsupset", 3, {226, 138, 144} +"sqsupseteq", 3, {226, 138, 146} +"square", 3, {226, 150, 161} +"Square", 3, {226, 150, 161} +"SquareIntersection", 3, {226, 138, 147} +"SquareSubset", 3, {226, 138, 143} +"SquareSubsetEqual", 3, {226, 138, 145} +"SquareSuperset", 3, {226, 138, 144} +"SquareSupersetEqual", 3, {226, 138, 146} +"SquareUnion", 3, {226, 138, 148} +"squarf", 3, {226, 150, 170} +"squ", 3, {226, 150, 161} +"squf", 3, {226, 150, 170} +"srarr", 3, {226, 134, 146} +"Sscr", 4, {240, 157, 146, 174} +"sscr", 4, {240, 157, 147, 136} +"ssetmn", 3, {226, 136, 150} +"ssmile", 3, {226, 140, 163} +"sstarf", 3, {226, 139, 134} +"Star", 3, {226, 139, 134} +"star", 3, {226, 152, 134} +"starf", 3, {226, 152, 133} +"straightepsilon", 2, {207, 181} +"straightphi", 2, {207, 149} +"strns", 2, {194, 175} +"sub", 3, {226, 138, 130} +"Sub", 3, {226, 139, 144} +"subdot", 3, {226, 170, 189} +"subE", 3, {226, 171, 133} +"sube", 3, {226, 138, 134} +"subedot", 3, {226, 171, 131} +"submult", 3, {226, 171, 129} +"subnE", 3, {226, 171, 139} +"subne", 3, {226, 138, 138} +"subplus", 3, {226, 170, 191} +"subrarr", 3, {226, 165, 185} +"subset", 3, {226, 138, 130} +"Subset", 3, {226, 139, 144} +"subseteq", 3, {226, 138, 134} +"subseteqq", 3, {226, 171, 133} +"SubsetEqual", 3, {226, 138, 134} +"subsetneq", 3, {226, 138, 138} +"subsetneqq", 3, {226, 171, 139} +"subsim", 3, {226, 171, 135} +"subsub", 3, {226, 171, 149} +"subsup", 3, {226, 171, 147} +"succapprox", 3, {226, 170, 184} +"succ", 3, {226, 137, 187} +"succcurlyeq", 3, {226, 137, 189} +"Succeeds", 3, {226, 137, 187} +"SucceedsEqual", 3, {226, 170, 176} +"SucceedsSlantEqual", 3, {226, 137, 189} +"SucceedsTilde", 3, {226, 137, 191} +"succeq", 3, {226, 170, 176} +"succnapprox", 3, {226, 170, 186} +"succneqq", 3, {226, 170, 182} +"succnsim", 3, {226, 139, 169} +"succsim", 3, {226, 137, 191} +"SuchThat", 3, {226, 136, 139} +"sum", 3, {226, 136, 145} +"Sum", 3, {226, 136, 145} +"sung", 3, {226, 153, 170} +"sup1", 2, {194, 185} +"sup2", 2, {194, 178} +"sup3", 2, {194, 179} +"sup", 3, {226, 138, 131} +"Sup", 3, {226, 139, 145} +"supdot", 3, {226, 170, 190} +"supdsub", 3, {226, 171, 152} +"supE", 3, {226, 171, 134} +"supe", 3, {226, 138, 135} +"supedot", 3, {226, 171, 132} +"Superset", 3, {226, 138, 131} +"SupersetEqual", 3, {226, 138, 135} +"suphsol", 3, {226, 159, 137} +"suphsub", 3, {226, 171, 151} +"suplarr", 3, {226, 165, 187} +"supmult", 3, {226, 171, 130} +"supnE", 3, {226, 171, 140} +"supne", 3, {226, 138, 139} +"supplus", 3, {226, 171, 128} +"supset", 3, {226, 138, 131} +"Supset", 3, {226, 139, 145} +"supseteq", 3, {226, 138, 135} +"supseteqq", 3, {226, 171, 134} +"supsetneq", 3, {226, 138, 139} +"supsetneqq", 3, {226, 171, 140} +"supsim", 3, {226, 171, 136} +"supsub", 3, {226, 171, 148} +"supsup", 3, {226, 171, 150} +"swarhk", 3, {226, 164, 166} +"swarr", 3, {226, 134, 153} +"swArr", 3, {226, 135, 153} +"swarrow", 3, {226, 134, 153} +"swnwar", 3, {226, 164, 170} +"szlig", 2, {195, 159} +"Tab", 1, {9} +"target", 3, {226, 140, 150} +"Tau", 2, {206, 164} +"tau", 2, {207, 132} +"tbrk", 3, {226, 142, 180} +"Tcaron", 2, {197, 164} +"tcaron", 2, {197, 165} +"Tcedil", 2, {197, 162} +"tcedil", 2, {197, 163} +"Tcy", 2, {208, 162} +"tcy", 2, {209, 130} +"tdot", 3, {226, 131, 155} +"telrec", 3, {226, 140, 149} +"Tfr", 4, {240, 157, 148, 151} +"tfr", 4, {240, 157, 148, 177} +"there4", 3, {226, 136, 180} +"therefore", 3, {226, 136, 180} +"Therefore", 3, {226, 136, 180} +"Theta", 2, {206, 152} +"theta", 2, {206, 184} +"thetasym", 2, {207, 145} +"thetav", 2, {207, 145} +"thickapprox", 3, {226, 137, 136} +"thicksim", 3, {226, 136, 188} +"ThickSpace", 3, {226, 129, 159} +"ThinSpace", 3, {226, 128, 137} +"thinsp", 3, {226, 128, 137} +"thkap", 3, {226, 137, 136} +"thksim", 3, {226, 136, 188} +"THORN", 2, {195, 158} +"thorn", 2, {195, 190} +"tilde", 2, {203, 156} +"Tilde", 3, {226, 136, 188} +"TildeEqual", 3, {226, 137, 131} +"TildeFullEqual", 3, {226, 137, 133} +"TildeTilde", 3, {226, 137, 136} +"timesbar", 3, {226, 168, 177} +"timesb", 3, {226, 138, 160} +"times", 2, {195, 151} +"timesd", 3, {226, 168, 176} +"tint", 3, {226, 136, 173} +"toea", 3, {226, 164, 168} +"topbot", 3, {226, 140, 182} +"topcir", 3, {226, 171, 177} +"top", 3, {226, 138, 164} +"Topf", 4, {240, 157, 149, 139} +"topf", 4, {240, 157, 149, 165} +"topfork", 3, {226, 171, 154} +"tosa", 3, {226, 164, 169} +"tprime", 3, {226, 128, 180} +"trade", 3, {226, 132, 162} +"TRADE", 3, {226, 132, 162} +"triangle", 3, {226, 150, 181} +"triangledown", 3, {226, 150, 191} +"triangleleft", 3, {226, 151, 131} +"trianglelefteq", 3, {226, 138, 180} +"triangleq", 3, {226, 137, 156} +"triangleright", 3, {226, 150, 185} +"trianglerighteq", 3, {226, 138, 181} +"tridot", 3, {226, 151, 172} +"trie", 3, {226, 137, 156} +"triminus", 3, {226, 168, 186} +"TripleDot", 3, {226, 131, 155} +"triplus", 3, {226, 168, 185} +"trisb", 3, {226, 167, 141} +"tritime", 3, {226, 168, 187} +"trpezium", 3, {226, 143, 162} +"Tscr", 4, {240, 157, 146, 175} +"tscr", 4, {240, 157, 147, 137} +"TScy", 2, {208, 166} +"tscy", 2, {209, 134} +"TSHcy", 2, {208, 139} +"tshcy", 2, {209, 155} +"Tstrok", 2, {197, 166} +"tstrok", 2, {197, 167} +"twixt", 3, {226, 137, 172} +"twoheadleftarrow", 3, {226, 134, 158} +"twoheadrightarrow", 3, {226, 134, 160} +"Uacute", 2, {195, 154} +"uacute", 2, {195, 186} +"uarr", 3, {226, 134, 145} +"Uarr", 3, {226, 134, 159} +"uArr", 3, {226, 135, 145} +"Uarrocir", 3, {226, 165, 137} +"Ubrcy", 2, {208, 142} +"ubrcy", 2, {209, 158} +"Ubreve", 2, {197, 172} +"ubreve", 2, {197, 173} +"Ucirc", 2, {195, 155} +"ucirc", 2, {195, 187} +"Ucy", 2, {208, 163} +"ucy", 2, {209, 131} +"udarr", 3, {226, 135, 133} +"Udblac", 2, {197, 176} +"udblac", 2, {197, 177} +"udhar", 3, {226, 165, 174} +"ufisht", 3, {226, 165, 190} +"Ufr", 4, {240, 157, 148, 152} +"ufr", 4, {240, 157, 148, 178} +"Ugrave", 2, {195, 153} +"ugrave", 2, {195, 185} +"uHar", 3, {226, 165, 163} +"uharl", 3, {226, 134, 191} +"uharr", 3, {226, 134, 190} +"uhblk", 3, {226, 150, 128} +"ulcorn", 3, {226, 140, 156} +"ulcorner", 3, {226, 140, 156} +"ulcrop", 3, {226, 140, 143} +"ultri", 3, {226, 151, 184} +"Umacr", 2, {197, 170} +"umacr", 2, {197, 171} +"uml", 2, {194, 168} +"UnderBar", 1, {95} +"UnderBrace", 3, {226, 143, 159} +"UnderBracket", 3, {226, 142, 181} +"UnderParenthesis", 3, {226, 143, 157} +"Union", 3, {226, 139, 131} +"UnionPlus", 3, {226, 138, 142} +"Uogon", 2, {197, 178} +"uogon", 2, {197, 179} +"Uopf", 4, {240, 157, 149, 140} +"uopf", 4, {240, 157, 149, 166} +"UpArrowBar", 3, {226, 164, 146} +"uparrow", 3, {226, 134, 145} +"UpArrow", 3, {226, 134, 145} +"Uparrow", 3, {226, 135, 145} +"UpArrowDownArrow", 3, {226, 135, 133} +"updownarrow", 3, {226, 134, 149} +"UpDownArrow", 3, {226, 134, 149} +"Updownarrow", 3, {226, 135, 149} +"UpEquilibrium", 3, {226, 165, 174} +"upharpoonleft", 3, {226, 134, 191} +"upharpoonright", 3, {226, 134, 190} +"uplus", 3, {226, 138, 142} +"UpperLeftArrow", 3, {226, 134, 150} +"UpperRightArrow", 3, {226, 134, 151} +"upsi", 2, {207, 133} +"Upsi", 2, {207, 146} +"upsih", 2, {207, 146} +"Upsilon", 2, {206, 165} +"upsilon", 2, {207, 133} +"UpTeeArrow", 3, {226, 134, 165} +"UpTee", 3, {226, 138, 165} +"upuparrows", 3, {226, 135, 136} +"urcorn", 3, {226, 140, 157} +"urcorner", 3, {226, 140, 157} +"urcrop", 3, {226, 140, 142} +"Uring", 2, {197, 174} +"uring", 2, {197, 175} +"urtri", 3, {226, 151, 185} +"Uscr", 4, {240, 157, 146, 176} +"uscr", 4, {240, 157, 147, 138} +"utdot", 3, {226, 139, 176} +"Utilde", 2, {197, 168} +"utilde", 2, {197, 169} +"utri", 3, {226, 150, 181} +"utrif", 3, {226, 150, 180} +"uuarr", 3, {226, 135, 136} +"Uuml", 2, {195, 156} +"uuml", 2, {195, 188} +"uwangle", 3, {226, 166, 167} +"vangrt", 3, {226, 166, 156} +"varepsilon", 2, {207, 181} +"varkappa", 2, {207, 176} +"varnothing", 3, {226, 136, 133} +"varphi", 2, {207, 149} +"varpi", 2, {207, 150} +"varpropto", 3, {226, 136, 157} +"varr", 3, {226, 134, 149} +"vArr", 3, {226, 135, 149} +"varrho", 2, {207, 177} +"varsigma", 2, {207, 130} +"varsubsetneq", 3, {226, 138, 138} +"varsubsetneqq", 3, {226, 171, 139} +"varsupsetneq", 3, {226, 138, 139} +"varsupsetneqq", 3, {226, 171, 140} +"vartheta", 2, {207, 145} +"vartriangleleft", 3, {226, 138, 178} +"vartriangleright", 3, {226, 138, 179} +"vBar", 3, {226, 171, 168} +"Vbar", 3, {226, 171, 171} +"vBarv", 3, {226, 171, 169} +"Vcy", 2, {208, 146} +"vcy", 2, {208, 178} +"vdash", 3, {226, 138, 162} +"vDash", 3, {226, 138, 168} +"Vdash", 3, {226, 138, 169} +"VDash", 3, {226, 138, 171} +"Vdashl", 3, {226, 171, 166} +"veebar", 3, {226, 138, 187} +"vee", 3, {226, 136, 168} +"Vee", 3, {226, 139, 129} +"veeeq", 3, {226, 137, 154} +"vellip", 3, {226, 139, 174} +"verbar", 1, {124} +"Verbar", 3, {226, 128, 150} +"vert", 1, {124} +"Vert", 3, {226, 128, 150} +"VerticalBar", 3, {226, 136, 163} +"VerticalLine", 1, {124} +"VerticalSeparator", 3, {226, 157, 152} +"VerticalTilde", 3, {226, 137, 128} +"VeryThinSpace", 3, {226, 128, 138} +"Vfr", 4, {240, 157, 148, 153} +"vfr", 4, {240, 157, 148, 179} +"vltri", 3, {226, 138, 178} +"vnsub", 3, {226, 138, 130} +"vnsup", 3, {226, 138, 131} +"Vopf", 4, {240, 157, 149, 141} +"vopf", 4, {240, 157, 149, 167} +"vprop", 3, {226, 136, 157} +"vrtri", 3, {226, 138, 179} +"Vscr", 4, {240, 157, 146, 177} +"vscr", 4, {240, 157, 147, 139} +"vsubnE", 3, {226, 171, 139} +"vsubne", 3, {226, 138, 138} +"vsupnE", 3, {226, 171, 140} +"vsupne", 3, {226, 138, 139} +"Vvdash", 3, {226, 138, 170} +"vzigzag", 3, {226, 166, 154} +"Wcirc", 2, {197, 180} +"wcirc", 2, {197, 181} +"wedbar", 3, {226, 169, 159} +"wedge", 3, {226, 136, 167} +"Wedge", 3, {226, 139, 128} +"wedgeq", 3, {226, 137, 153} +"weierp", 3, {226, 132, 152} +"Wfr", 4, {240, 157, 148, 154} +"wfr", 4, {240, 157, 148, 180} +"Wopf", 4, {240, 157, 149, 142} +"wopf", 4, {240, 157, 149, 168} +"wp", 3, {226, 132, 152} +"wr", 3, {226, 137, 128} +"wreath", 3, {226, 137, 128} +"Wscr", 4, {240, 157, 146, 178} +"wscr", 4, {240, 157, 147, 140} +"xcap", 3, {226, 139, 130} +"xcirc", 3, {226, 151, 175} +"xcup", 3, {226, 139, 131} +"xdtri", 3, {226, 150, 189} +"Xfr", 4, {240, 157, 148, 155} +"xfr", 4, {240, 157, 148, 181} +"xharr", 3, {226, 159, 183} +"xhArr", 3, {226, 159, 186} +"Xi", 2, {206, 158} +"xi", 2, {206, 190} +"xlarr", 3, {226, 159, 181} +"xlArr", 3, {226, 159, 184} +"xmap", 3, {226, 159, 188} +"xnis", 3, {226, 139, 187} +"xodot", 3, {226, 168, 128} +"Xopf", 4, {240, 157, 149, 143} +"xopf", 4, {240, 157, 149, 169} +"xoplus", 3, {226, 168, 129} +"xotime", 3, {226, 168, 130} +"xrarr", 3, {226, 159, 182} +"xrArr", 3, {226, 159, 185} +"Xscr", 4, {240, 157, 146, 179} +"xscr", 4, {240, 157, 147, 141} +"xsqcup", 3, {226, 168, 134} +"xuplus", 3, {226, 168, 132} +"xutri", 3, {226, 150, 179} +"xvee", 3, {226, 139, 129} +"xwedge", 3, {226, 139, 128} +"Yacute", 2, {195, 157} +"yacute", 2, {195, 189} +"YAcy", 2, {208, 175} +"yacy", 2, {209, 143} +"Ycirc", 2, {197, 182} +"ycirc", 2, {197, 183} +"Ycy", 2, {208, 171} +"ycy", 2, {209, 139} +"yen", 2, {194, 165} +"Yfr", 4, {240, 157, 148, 156} +"yfr", 4, {240, 157, 148, 182} +"YIcy", 2, {208, 135} +"yicy", 2, {209, 151} +"Yopf", 4, {240, 157, 149, 144} +"yopf", 4, {240, 157, 149, 170} +"Yscr", 4, {240, 157, 146, 180} +"yscr", 4, {240, 157, 147, 142} +"YUcy", 2, {208, 174} +"yucy", 2, {209, 142} +"yuml", 2, {195, 191} +"Yuml", 2, {197, 184} +"Zacute", 2, {197, 185} +"zacute", 2, {197, 186} +"Zcaron", 2, {197, 189} +"zcaron", 2, {197, 190} +"Zcy", 2, {208, 151} +"zcy", 2, {208, 183} +"Zdot", 2, {197, 187} +"zdot", 2, {197, 188} +"zeetrf", 3, {226, 132, 168} +"ZeroWidthSpace", 3, {226, 128, 139} +"Zeta", 2, {206, 150} +"zeta", 2, {206, 182} +"zfr", 4, {240, 157, 148, 183} +"Zfr", 3, {226, 132, 168} +"ZHcy", 2, {208, 150} +"zhcy", 2, {208, 182} +"zigrarr", 3, {226, 135, 157} +"zopf", 4, {240, 157, 149, 171} +"Zopf", 3, {226, 132, 164} +"Zscr", 4, {240, 157, 146, 181} +"zscr", 4, {240, 157, 147, 143} +"zwj", 3, {226, 128, 141} +"zwnj", 3, {226, 128, 140} diff --git a/src/html/html_unescape.h b/src/html/html_unescape.h new file mode 100644 index 0000000..5d12662 --- /dev/null +++ b/src/html/html_unescape.h @@ -0,0 +1,9746 @@ +/* C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -I -t -N find_entity -H hash_entity -K entity -C -l --null-strings -m5 src/html/html_unescape.gperf  */ +/* Computed positions: -k'1-7,10,12,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ +      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ +      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ +      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ +      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ +      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ +      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ +      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ +      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ +      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ +      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ +      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ +      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ +      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ +      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ +      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ +      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ +      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ +      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ +      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ +      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ +      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ +      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646.  */ +error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>." +#endif + +#line 1 "src/html/html_unescape.gperf" +struct html_ent { +	const char *entity; +	unsigned int utf8_len; +	unsigned char utf8[4]; +}; +#include <string.h> + +#define TOTAL_KEYWORDS 2125 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 31 +#define MIN_HASH_VALUE 39 +#define MAX_HASH_VALUE 16000 +/* maximum key range = 15962, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash_entity (str, len) +     register const char *str; +     register unsigned int len; +{ +  static const unsigned short asso_values[] = +    { +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,     2, +          3,     7,     2,     4,     8, 16001,    10, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001,  1890,  1538,   220,   165,  1045, +        535,  1971,  1187,  1262,    35,   126,   201,   133,   350,  1487, +       1965,     3,   478,   134,     8,   147,    73,    41,    23,   212, +          9, 16001,     2, 16001,     2, 16001, 16001,  4154,    29,  3168, +        429,    10,   146,  1925,  2307,   280,  1313,  1924,     4,   651, +         27,  1031,    65,   176,     2,     6,    17,    15,   107,   482, +       3207,  3865,   757,   131,   178,     4,     4, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, +      16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001 +    }; +  register int hval = len; + +  switch (hval) +    { +      default: +        hval += asso_values[(unsigned char)str[11]]; +      /*FALLTHROUGH*/ +      case 11: +      case 10: +        hval += asso_values[(unsigned char)str[9]]; +      /*FALLTHROUGH*/ +      case 9: +      case 8: +      case 7: +        hval += asso_values[(unsigned char)str[6]]; +      /*FALLTHROUGH*/ +      case 6: +        hval += asso_values[(unsigned char)str[5]]; +      /*FALLTHROUGH*/ +      case 5: +        hval += asso_values[(unsigned char)str[4]+1]; +      /*FALLTHROUGH*/ +      case 4: +        hval += asso_values[(unsigned char)str[3]+3]; +      /*FALLTHROUGH*/ +      case 3: +        hval += asso_values[(unsigned char)str[2]+1]; +      /*FALLTHROUGH*/ +      case 2: +        hval += asso_values[(unsigned char)str[1]+4]; +      /*FALLTHROUGH*/ +      case 1: +        hval += asso_values[(unsigned char)str[0]]; +        break; +    } +  return hval + asso_values[(unsigned char)str[len - 1]]; +} + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct html_ent * +find_entity (str, len) +     register const char *str; +     register unsigned int len; +{ +  static const unsigned char lengthtable[] = +    { +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  4, +       0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  4,  0,  0,  3, +       0,  0,  0,  0,  0,  0,  6,  0,  6,  5,  0,  5,  3,  4, +       3,  4,  0,  4,  0,  2,  5,  4,  0,  0,  0,  2,  0,  7, +       0,  7,  3,  0,  5,  0,  0,  0,  0,  0,  4,  0,  0,  6, +       0,  0,  0,  3,  6,  0,  4,  0,  0,  0,  0,  6,  4,  5, +       0,  0,  0,  5,  0,  5,  0,  6,  0,  0,  0,  4,  5,  5, +       5,  3,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0, +       0,  0,  0,  3,  4,  0,  3,  0,  0,  5,  0,  0,  3,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  5,  0, +       5,  0,  5,  6,  0,  6,  5,  0,  2,  5,  0,  5,  0,  0, +       0,  0,  4,  0,  0,  0,  3,  0,  3,  5,  0,  0,  5,  0, +       0,  0,  6,  0, 10,  0,  4,  0,  0,  5,  3,  5,  0,  0, +       0,  0,  0,  0,  0,  5,  0,  3,  0,  0,  0,  0,  6,  6, +       0,  6,  0,  0,  0,  0,  6,  0,  6,  0,  2,  0,  0,  0, +       4,  7,  0,  7,  0,  5,  0,  0,  0,  0,  0,  0,  0,  3, +       0,  4,  0,  4,  6,  0,  3,  0,  0,  0,  0,  0,  0,  4, +       4,  3,  0,  4,  0,  0,  2,  0,  0,  0,  4,  0,  4,  0, +       0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +      13,  0,  2,  0,  0,  0,  5,  0,  2,  0,  0,  0,  0,  0, +       0,  0,  3,  2,  4,  0,  6,  0,  0,  3,  0,  2,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  6,  0,  3,  4,  0,  0,  0, +       0,  4,  6,  0,  0,  0,  5,  5,  5,  0, 13,  0,  0,  4, +       0,  0,  5,  0,  4,  4,  5, 17, 18,  0,  0,  0,  0,  0, +       5,  0,  0, 17,  0,  0,  0,  0,  0,  5,  5,  0,  0,  0, +       5,  5,  0,  0,  0,  8,  0,  0,  0,  3,  0,  0,  6,  3, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  5,  6,  0,  0, +       0,  4,  0,  0,  5,  0,  6,  6,  6,  6,  6,  6,  6,  0, +       0,  6,  0,  6,  0,  6,  6,  6,  6,  6,  6,  0,  0,  0, +       6,  0,  6,  3,  4,  0,  0,  4,  3,  5,  0,  0,  3,  0, +       0,  0, 11,  5,  0,  0,  0,  4,  0,  0,  6,  0,  0,  0, +       5,  0,  0,  0,  5,  0,  5,  0,  0,  0,  0,  0,  0,  0, +       0,  5,  0,  0,  0,  0,  0,  5,  3,  0,  0,  4,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  4,  0,  4, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  5,  0,  0,  0,  0, +       3,  6,  0,  0,  0,  0,  0,  8,  8,  0,  0,  0,  4,  6, +       0,  0,  8,  0,  8,  0,  2,  0,  0,  0,  0,  4,  0,  0, +       0,  4,  0,  6,  0,  0,  0,  0,  6,  0,  4,  0,  0,  0, +       0,  6,  0,  5,  6,  2,  5,  8,  5,  0,  0,  4,  0,  4, +       0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  9,  0,  4,  4, +       4,  0,  4,  6,  4,  4,  4,  0,  0,  0,  5,  4,  5,  4, +       0,  0,  0,  0,  0,  4,  0,  0,  0,  4,  0,  4,  5,  4, +       5,  0,  0,  4,  0,  5,  0,  0,  0,  4,  0,  0,  0,  0, +       4,  4,  0,  5,  0,  0, 11,  0,  0,  6,  0,  0,  3,  0, +       0,  0,  0,  6,  0,  4,  0,  0,  4,  0,  0,  0,  0,  4, +       0,  0,  0,  0,  7,  4,  4,  0,  7,  0,  0,  0,  0,  0, +       5,  0,  0,  0,  3,  8,  4,  0,  0,  0,  5,  0,  6,  0, +       0,  0,  0,  6,  0,  4,  0,  0,  0,  5,  0,  6,  0,  0, +       0,  5,  5,  0,  0,  3,  6,  2,  0,  0,  4,  0,  0,  7, +       0,  4,  0,  4,  4,  4,  3,  5,  0,  0,  0,  0,  0,  0, +       6,  0,  4,  4,  0,  0,  0, 12, 13,  0,  0,  6,  8,  0, +       2,  0,  0, 17,  0,  0,  0,  4,  0,  5,  0,  7,  0,  5, +       0,  0,  0,  5,  4,  5,  0,  0,  3,  0,  0,  0,  5,  0, +       5, 12, 13,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  4,  0,  0,  0,  7,  0,  0,  6,  6,  6,  0,  4,  0, +       0,  0,  0, 17,  0,  0,  4,  5,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  5,  3,  6,  9,  0,  0, +       0,  9,  0,  0,  0,  0,  0,  6,  4,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0, 19,  0,  5,  0,  0, 17,  0,  0, +      14,  0,  0,  0,  0, 12,  4,  0,  0,  0,  4,  0,  2,  0, +       4,  0,  6,  0,  0,  3,  0,  0,  0,  3,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  4,  4,  0, +       4,  0,  4,  4,  4,  0,  0,  0,  0,  4,  0,  4,  0,  4, +       9,  0,  0,  4,  2,  0,  0,  4,  2,  4,  4,  0,  0,  0, +       0,  4,  6,  0,  0,  6,  9,  4,  0,  6,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  6,  0,  0, +       0,  0,  0,  4,  2,  0,  0,  0,  0,  0,  0,  4,  0,  0, +       0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  0,  0, 10,  0,  0,  0, 10,  6,  0,  0, +       0,  0,  6,  4,  6,  4,  0,  0,  0,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  0,  9,  0,  0,  4,  0,  0,  0,  0,  0, +       7,  4,  4,  7,  0,  7,  5,  0,  0,  6,  4,  4,  4,  0, +       4,  4,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  4,  0, +       0,  0,  4,  0,  0,  4,  4,  6,  0,  0,  0,  3,  5,  3, +       5, 11,  4,  0,  0,  4,  0,  0,  0,  5,  0,  0,  0,  0, +       7,  0,  0,  0,  0,  5,  0,  5,  0,  0,  0,  3,  5,  4, +       0,  0,  0,  5,  0,  6,  9,  7,  2,  0,  4,  0,  0,  4, +       0,  0,  0,  0,  4,  5,  6,  0,  0,  0,  0,  9, 10,  0, +       0,  0,  5,  0,  0,  0,  0, 11,  0,  0,  6,  0,  0,  0, +       0,  0,  0,  4,  8,  6,  0,  0,  0,  0,  0,  8,  0,  0, +       0,  0,  0,  0,  0,  5,  6,  0,  0,  0, 13,  5,  5,  6, +       0,  0,  0,  0,  2,  0,  0,  0,  4,  2,  4,  0,  0,  6, +       4,  0,  4,  0,  0,  0,  4,  0, 21,  0,  0,  0,  6,  0, +       3,  0,  0,  0,  6,  6,  0,  3, 13,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  7,  0,  0,  0,  0, +       0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  5,  0,  4,  0,  6,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  7,  3,  0,  0, +       0,  0,  0,  0,  0,  7,  3,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  3,  3,  0, +       3, 15,  3,  3,  3,  0,  0,  0,  3,  3,  6,  3,  6,  0, +       0,  0,  0,  3,  0,  0,  4,  3,  0,  3,  0, 12,  0,  0, +       0,  3,  0,  4,  0,  0,  0,  3,  0, 12,  0,  4,  5,  0, +       9,  0,  0,  7,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  3,  0,  0,  0,  0,  0,  5,  0,  3,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  4,  0,  0,  0, +       4,  0,  0,  0,  0,  0,  0,  0,  0, 12,  0,  0,  0,  0, +       0,  5,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  5, +       0,  3,  3,  0,  0,  6,  0,  0,  0,  0,  0,  4,  0,  0, +       3,  3,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  3,  7,  0,  0,  8,  0,  0,  0,  0, +       0,  0,  3,  4,  0,  6,  0,  0,  0, 15,  0,  0,  0,  0, +       0,  0,  0,  9,  0,  0,  0,  2,  0,  0,  0,  0,  9,  3, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  7,  3, 24,  0,  0, +       0,  0,  5,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  6,  7,  4,  0,  0,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  3,  3, +       0,  4,  0,  7,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0, +       0,  5,  2,  0,  0,  0,  6,  0,  3,  8,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  4,  6,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  5,  0,  9,  5,  7,  0,  0,  0,  0,  0,  0,  0, +       0,  7, 15,  7,  8,  4,  0,  5,  0,  0,  6,  0,  0,  0, +       0,  0,  0,  0,  4,  4,  5,  0,  0,  0,  0,  6, 14,  3, +      15,  0,  6,  0,  0,  0,  3,  0,  3,  3,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  6,  0,  0,  0, +       0,  0,  0,  5,  0,  0,  5, 16,  0,  5, 10,  0,  0,  0, +       5,  7,  0,  5,  0,  0,  6,  0,  3,  0,  0, 11,  5,  0, +       0,  4,  5,  0,  0,  5,  0,  0,  3,  0,  0,  0,  0,  8, +       0,  0,  0,  5,  0,  0,  0,  6,  3,  0,  0,  0,  0,  0, +       5,  0,  0,  3,  3,  3,  0,  0,  0,  6,  0,  0,  5,  6, +       0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0,  0, 11,  0,  6,  0,  6,  0,  0, 13,  0,  0,  7, +       0,  0,  0,  0,  7,  0,  6,  4,  5,  0,  3,  0,  0,  5, +       3,  0,  0,  0,  0,  0,  6,  0,  0,  4,  0,  0,  0,  0, +       3,  6,  5,  0,  0,  0,  0, 11,  0,  4,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0, +       0, 11,  0,  5,  5,  0,  0,  0,  0,  0,  0,  3,  0,  0, +       0,  0,  0,  8,  0,  7,  4,  0,  0,  0,  0,  5,  4,  9, +       0,  0,  5,  0,  0,  0,  0,  0,  8,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9, +       0,  6,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0, 11, +       0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  7,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  4,  0,  0, 14,  5,  0,  0,  8, +       0,  0,  0, 20,  7,  0,  0,  0,  0,  0,  0,  0,  0,  5, +       3,  0,  0,  4,  6,  0,  0,  0,  0,  6,  0,  0,  0,  7, +       0,  3,  6,  4,  6,  0,  0,  0,  0,  0,  0,  6,  3,  4, +       0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0, +       0, 11,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  4, +       0,  0,  0,  0,  0,  0,  0, 13, 18,  5,  0,  3,  0,  7, +       0,  4,  0,  0,  0,  4,  0,  0, 10, 11,  0,  0,  0,  6, +       0,  6,  0,  0,  5,  0,  5, 12, 12,  0,  0,  0,  4,  0, +       0, 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0, +      14,  0,  0,  0,  2,  4,  8,  4,  0,  3,  0,  0,  7,  0, +       3,  0,  0,  0,  3,  2,  0,  0,  0,  0,  6,  0,  6,  4, +       6,  7,  6,  6,  6,  0, 10,  0,  0,  0,  3,  6,  0,  4, +       0,  0,  0,  0,  0,  4,  0,  6,  6,  0,  4,  0,  0,  0, +       7,  0,  0,  7,  0,  0,  4,  0,  4,  0,  5,  6,  0,  6, +       0,  3,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0, +       9,  0,  0,  0,  0,  0,  8, 14,  0,  3,  0,  0,  0,  0, +       0,  0,  8,  0,  0,  7,  5,  0,  0,  0,  4,  0,  0,  0, +      17,  7,  0,  0,  4,  0,  0,  7,  0,  5,  0,  0,  7,  5, +       0,  0,  4,  0,  7,  2, 20,  0,  0,  0,  0, 13,  0,  0, +       0,  0,  6,  0,  7,  3,  5,  4,  0,  0,  0,  0,  5,  5, +       0,  0,  0,  0,  0,  4,  5,  0,  0,  0,  0,  0,  0,  0, +       5,  0,  5,  0,  0,  6,  0,  0,  6,  0,  0,  0,  0,  0, +       0,  0,  4,  9,  0,  5, 12,  0,  0,  0,  0,  5,  0,  5, +       4,  0,  0,  0,  9,  0,  0,  0, 10, 10,  0,  0,  4,  6, +       0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  2,  6,  0,  0,  0,  0,  0,  5,  0,  0,  0, +       0,  0,  6,  0,  0,  0,  0,  6,  6,  0,  3,  0,  0,  0, +       7,  0,  0,  0,  0,  7,  4,  0,  0,  0,  0,  0,  4,  0, +       9,  0,  0,  3,  0,  0,  0,  7,  0,  4,  0,  0,  5,  6, +       0,  0,  6,  3,  5,  4,  0,  0,  0,  0,  0,  6,  0,  5, +       0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  6,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  5, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0, +       6,  0,  0,  6,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  8,  0,  0,  0,  6,  0,  0,  0,  0,  4, +       0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0, 10,  0,  0,  6,  0,  6,  0,  0,  6, +       0,  0, 18,  0,  6,  0, 20, 15,  0,  0,  4,  4,  0,  0, +       0,  6,  0,  0,  0,  3,  0,  0,  0,  0,  0,  5,  4,  4, +       0,  7,  0,  6,  0,  4,  0,  5,  0,  0,  0,  0,  5,  0, +       0,  0,  4,  4,  0,  0,  0,  0,  4,  0,  4,  0, 11,  0, +      20, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0, 10,  0,  0,  8,  0,  0,  0,  6,  0,  0,  0, +       0,  4,  0,  0,  0,  0,  0,  4,  0,  0,  3,  0,  0,  6, +       0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4, +       0,  0,  0,  0,  0,  0, 13,  0,  0,  9,  0,  0,  0,  5, +       0,  0,  0,  5,  0,  3,  0,  0,  0,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  3,  0,  0, 17,  0,  5,  0,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  9,  0,  0,  0,  6,  0,  0,  0, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5, +       0,  7,  0,  0,  0,  9,  0,  0,  0,  0,  0,  0, 14,  0, +       0, 11,  0,  6,  0,  6,  0,  7,  5,  0,  0,  0,  6, 12, +      12,  0,  0,  0,  0, 16,  0, 14,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  5,  0,  5,  0,  0,  0,  7, +       0,  0,  5,  0,  0,  0,  0,  0,  0,  6,  0, 14,  0,  0, +       0,  0,  0,  0,  4,  0,  0,  0,  6,  0,  0,  0,  0,  0, +       0,  0,  8,  0,  0,  0,  0,  5,  0,  6,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  0,  0,  5,  0,  0,  0,  0,  0,  0, +       5,  0,  5,  0,  0,  0,  0,  0, 11,  6,  6,  3,  0,  0, +       0,  0,  7,  0,  6,  0,  6,  6,  4,  0,  0,  0,  7,  0, +       0,  0,  0,  0, 14,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  5,  0,  5,  0,  0,  0,  6,  0,  0,  0,  0, +       4,  4,  0,  0,  0,  0,  3,  3,  6,  0,  0,  0,  0,  0, +       0,  8,  0,  0,  0,  0,  0,  6,  0,  0,  0,  4,  6,  0, +       4,  4,  0,  0,  0,  0, 13,  0,  4,  0,  0,  0,  0,  4, +       2,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  7,  0, +       0,  0, 10,  0,  9,  0,  0,  4,  6,  0,  5,  0,  0,  0, +      13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0, 10,  0,  0,  0,  0,  0,  0,  8,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0, 12,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0, 12,  0, +       0,  0,  0,  0,  0,  0, 18,  0,  0,  4,  0,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  7,  0,  0,  0,  0,  5,  0,  5, +       0,  0,  0,  6,  0,  0,  5,  0,  0,  6,  0,  6,  0,  0, +      13,  6,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0, +       0,  4,  0,  6,  0,  6,  7,  0,  0,  0,  0,  0,  0,  0, +      14,  0,  6, 15,  0,  0,  7,  0,  3,  0,  3,  0,  0,  0, +       9,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0, +       0,  4,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 12,  0,  0, 15, +       0,  0,  0,  6,  0,  0,  6,  0,  0,  0,  0,  6,  0,  0, +       0,  0,  0,  0,  0,  7,  6,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0, +       0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  3,  9,  4,  0,  3,  0, +       0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  2, 15,  0,  0, +       0,  5,  0,  5,  0,  4,  0,  0,  0,  0,  0,  0, 16,  0, +       3,  3, 10,  0,  0,  0,  0,  0,  0,  0,  0,  4,  5,  4, +       5,  4,  0,  0,  6,  0,  5,  4,  0,  5,  5,  3,  5,  0, +       4,  0,  6,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  3, +       0,  0,  0,  0,  0,  3,  0,  0,  6,  0,  5,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  6,  8,  6,  0,  0,  0,  0,  0,  0,  0,  5, 16,  0, +       5,  7,  0,  6,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0, +       0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  7,  0,  7,  0,  0,  5,  0,  0, +       0,  0,  6,  0,  5,  4,  5,  0,  5,  5,  0,  0,  0,  0, +       5,  2,  6,  4,  0,  5,  0,  0,  5,  0,  4,  0,  0,  0, +       0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0, +       0,  6,  0,  0,  0,  0,  3,  5,  0,  0,  0,  2,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0, +       0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  8,  0,  0,  0,  0,  6,  5,  0,  0,  4, +       0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0, +       0,  4,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  4,  0,  4,  2,  6,  0,  6,  3,  3,  0,  0, +       3,  0,  4,  0,  6,  0,  3,  0,  0,  6,  0,  5, 31,  0, +       0,  0,  0,  0,  0,  0,  3,  6,  0,  0,  0,  0,  0,  0, +       0,  4,  0,  0,  5,  0,  0,  0,  3,  0,  0,  0,  0,  6, +       0,  8,  0,  5,  4,  0,  0,  0,  0,  3,  0,  0,  0,  0, +       0,  0,  0,  3,  0,  0,  0,  0,  0,  5,  0,  0,  5,  0, +       0,  0, 19,  0,  0,  0,  0, 24,  0,  0,  4,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,  5, +       0,  0,  0,  6,  0,  0,  0,  0, 14,  0,  0,  0,  0,  0, +       0, 16,  5,  0,  0,  3,  4,  4,  0,  5,  4,  5,  0,  0, +       0, 13,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  5,  5,  0,  0,  0,  0,  0,  0,  6,  0,  3, +       0,  7,  0, 10,  0,  0,  0,  0,  6,  0,  6,  0,  0, 13, +       0,  0,  0,  5,  0,  8,  0,  6,  0,  6,  8,  6,  0,  0, +       6,  6,  0, 10,  0,  8,  6,  6,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  6,  0, 11,  0,  0,  0,  6,  0,  0,  0, +       0,  7,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       7,  0,  0,  0, 17,  6,  0,  0,  0,  0,  0, 16,  0,  0, +       0,  0,  0,  0,  4,  0,  4,  0,  0,  0,  0,  0,  7,  0, +      14,  7,  6,  0,  6,  0,  7,  0,  0,  0,  0,  0,  0,  0, +       4,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  6, 10,  4, 14,  0,  0,  0,  9,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0, 14,  0,  4,  0,  6, +       0,  0,  0,  0,  0,  0,  0,  6,  3,  8,  4,  6,  6,  0, +       5,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0, +       0,  6,  0,  4,  0,  2,  0, 20, 21,  0,  0,  2,  0,  0, +       3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0, +       0,  0,  0,  0,  0,  6,  0,  0, 14,  4,  6, 17,  0,  0, +       0,  0,  0,  0,  0,  0,  6,  6,  0,  0,  0,  5,  0,  0, +       4,  6,  0,  2,  7,  0,  6,  5,  0,  8,  0,  0,  5,  0, +       4,  0,  0,  0,  5,  0,  4, 15,  5,  0,  4,  6,  0,  0, +       0,  0,  5,  5,  0,  0,  0,  0,  0,  0,  0, 17,  5,  0, +       0,  0,  9,  6,  0,  0, 12,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  6,  0,  5,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  7,  5,  0, +       0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  4,  0,  0,  0, +       0, 12,  0,  0,  0,  6,  0,  0,  0,  0, 10,  3,  0,  0, +       0,  4,  0,  5,  0,  0,  0,  0,  0,  4,  0,  0,  4,  0, +       0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  7,  0,  0, +       0,  0,  0,  0,  9,  0,  6,  0,  6,  0,  0,  0,  0, 19, +       5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0, +       0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  3, +       0,  0,  0,  0,  0,  0,  5,  0,  0,  5,  0,  6,  3,  6, +       0,  0,  0,  0,  0,  0,  0,  4,  0,  4,  2,  0,  0,  0, +       4,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  5,  0,  6,  0,  6,  0,  6,  0,  0, +       0,  0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  6,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0, 17,  0, +       0,  7,  0,  0,  2,  6,  2,  0,  0,  0,  2,  0,  0,  0, +       0,  3,  8,  0,  0,  3,  0,  5,  0,  5,  6,  0,  0,  0, +       0, 18,  0,  0,  0,  0,  5,  0,  7,  0,  0,  9,  0,  0, +       0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  4,  0,  4,  0,  0,  4,  0,  9,  0,  6,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  5,  0,  4,  0, +       0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  5,  0,  5,  6, +       0,  0,  0,  3,  3,  5,  0,  0,  0,  0,  6,  0,  0,  0, +       6,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  4, +       6, 13,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0, +      13,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0, +       0,  0,  5,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0,  0, +       8,  6,  8,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  0, 12,  0,  6,  0,  0,  0,  6,  0,  0, +       0,  6,  4,  0,  0,  7,  6,  5,  0,  0,  6,  0,  5,  5, +       5,  0,  0,  0,  9,  0,  0,  0,  0,  0,  5,  0,  6,  8, +       0,  0,  6,  0,  5,  8,  0,  0,  0,  6,  0,  4,  0,  9, +       0,  0,  0,  0,  4,  6,  4,  0,  0,  0,  0,  0,  3,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  4, +      11,  0,  0,  8,  9,  0,  0,  0,  0,  3,  5,  3,  0,  0, +       0,  0,  6,  4,  0,  0,  0,  9,  4,  3,  0,  2,  0,  0, +       0,  0,  0,  7,  5,  0,  0,  0,  0,  6,  0,  0,  0,  0, +       0, 14,  3,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0, 10, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  3,  0,  0,  0, +       0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0, 10,  7, +       5,  0,  6,  0,  6,  0,  3, 17,  0,  0,  0,  0,  0,  0, +      20,  0, 14,  4,  0,  0,  0,  0,  0,  0, 19,  6,  6,  0, +      10,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  6,  0, +       0,  3,  0,  0,  0,  4,  5,  0,  0,  4,  0,  5,  0,  0, +       0,  0,  0,  0,  7,  0,  4,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  4,  0,  0,  3,  0,  0,  0,  0, +       0,  0,  7,  0,  3,  0,  4,  0,  3,  0,  4,  0,  0, 13, +       0,  4,  0,  0,  0,  0,  0,  0,  0, 12,  0,  0,  0,  0, +       0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0, +       6,  0,  0,  0,  0,  0,  7,  0, 13,  0,  0, 15,  0,  0, +       5,  9,  0,  0,  0,  6,  0,  6,  0,  0,  4,  6,  0,  0, +       6,  4,  4,  0, 16,  0,  4,  0,  3,  0,  0, 11,  5, 15, +       0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  7,  0,  0,  5,  0,  5,  4,  0,  0,  4,  0, +      20,  4,  0,  0,  0,  0,  0,  5, 15,  4,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  4,  0,  0,  0,  5,  0,  0,  5,  0, +       0,  0,  0,  0,  0,  0,  0,  5,  5,  0, 22,  0,  0,  7, +       8,  0,  4,  0, 17,  0,  0,  0,  0,  0,  0,  0,  0,  6, +       0,  0,  6,  7,  0,  0,  0,  0,  6,  0,  6,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  4,  0,  5,  0, 12, 15,  6,  0, +      13,  0,  4,  0,  5,  4,  6,  0,  0,  0,  0,  4,  0,  0, +       4,  3,  5,  0,  0,  0,  0,  0,  0,  4,  0,  4,  0,  0, +       0,  0,  0,  0,  4,  0,  0,  9,  0,  0, 20,  0,  4, 10, +       0,  0,  0,  0,  4,  0,  5,  0,  0,  8,  6,  0,  5,  4, +       0,  0,  3,  0,  4,  0,  0,  6,  6,  0,  4,  0,  0,  0, +       0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  4,  0, +       0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 14,  0,  9, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0, 17, +       0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0, +       0,  0,  0, 14,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0, +       0, 14,  0,  0,  0,  0,  0,  0,  5,  6,  0,  5,  0,  0, +       0,  0,  0,  0,  5,  0,  8,  0,  0,  0,  4,  0,  0,  0, +       0,  0, 16, 15,  4,  0,  0, 11,  0,  0,  0,  8,  0,  0, +       0,  0,  0,  0,  0,  2,  0,  5,  0, 10,  0,  0,  5,  0, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0, +       5,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  4,  0,  0,  0,  0,  0,  0,  0,  2, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  8,  6,  5,  4,  0,  0,  0, +       0,  5,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  6,  0, +       0,  0,  0,  2,  4,  5,  0,  0,  0,  8,  0,  0,  3,  0, +       8,  0,  0,  4, 18,  0,  0,  0,  0,  4,  5,  0,  0,  0, +      16,  0,  0,  0,  0,  7,  0,  2,  3,  5,  0,  0,  5,  0, +       4,  4,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0, +       8,  0, 14,  0,  0,  0,  0,  5,  0,  0,  6,  0,  6,  0, +       5,  0,  5,  0,  5, 15,  0,  0,  8, 17, 12,  0,  0,  0, +       0,  0,  6,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  5,  0,  5,  0,  0, 20,  0,  0,  0,  0,  0, +      11,  0,  5,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0, 13, +       0,  0,  0,  0,  0,  6,  0,  6,  0,  6,  0,  6,  0,  5, +       8,  0,  0,  0,  0,  0,  6, 14,  0,  0,  0,  0,  0,  0, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, +       0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  4,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  5,  5,  0,  0,  0,  0,  0, +       0, 13,  0,  0,  0,  0,  0,  8,  4,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  7, +       0,  0, 16,  0, 14,  0, 18, 13,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  3,  0,  0,  0, 16,  0,  0,  0,  0,  0, +       0, 14,  0,  0, 17,  0,  0,  0,  0,  0,  0,  0,  0,  3, +       0,  0,  0,  0,  0,  0,  0, 13,  0,  0,  5,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  5,  0, +       4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6, +       0,  0,  0,  8, 17,  0,  0,  0,  5,  0,  0,  0,  8,  0, +       0,  0,  0,  0,  0,  0,  9,  0, 15,  0,  5,  0,  5,  0, +       0,  0,  0,  0,  0,  6,  5,  0,  0,  0,  0,  6,  4,  0, +       0,  9,  0,  0,  0,  0,  0,  6,  0,  6,  0,  0,  8,  0, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0, +       6,  2,  0,  0,  6,  0, 12,  6,  0,  0,  0, 16,  0,  0, +       0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0, +       0,  0, 14, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0, 10,  8,  0,  5,  0,  0,  6, +       0,  0,  0,  6,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0, +       0,  0,  5,  0,  0,  5,  6,  0,  0,  0,  0,  0,  0,  0, +       0,  8,  0,  0,  0, 14,  5,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  5,  0,  9,  0, +       0,  0,  5,  0,  0,  0,  0,  4,  6,  0,  0,  0,  0,  0, +       0,  8,  0,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,  0, +       3,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0, 21,  5,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  6,  0,  6,  0,  0,  0,  0,  0,  3,  5,  0, +       0,  5,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  2,  0, +       9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, +       5,  0,  0,  0,  0,  0,  0,  0,  0,  8,  5, 14,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0, +       5,  6,  0,  0,  4,  0,  4,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0, 13,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 12,  0,  0,  0, 18, 10,  0,  0, 18,  0,  7,  0,  0, +       0,  6,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  4, +       0,  5,  0,  0,  0,  0,  6,  0,  0,  5,  0,  0,  4,  0, +       0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  4,  0, +       0,  0,  5,  0, 12,  4, 12,  8,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  5,  0,  5,  0, +       0,  0,  0,  0,  8,  0,  0,  0,  0,  4,  0,  0,  0,  0, +       7,  5,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  4, +       5,  0,  0,  0,  5,  6,  7,  7,  0,  0,  0,  0,  0,  0, +       0,  6,  0,  8,  0,  0,  0,  0,  5,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0, +       0,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0, 10, 16,  0,  0,  0,  0,  0,  0, 17,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0, +       4,  6,  0,  0,  0,  5,  0,  0,  0,  8,  0,  0,  0,  0, +       0, 17,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  5,  0,  0,  0,  0, 17,  0,  5,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  5,  8,  0,  0,  0,  0,  0,  5,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0, +       0,  0,  0,  0,  0,  0, 15,  0,  0,  0,  0,  0,  7,  0, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  8,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  4,  0, +       8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  8,  0,  0,  0,  0,  0,  0,  0, 14,  0,  0,  0, +       0,  0,  0,  0,  0,  8,  4,  0,  7,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  4,  0,  4,  6,  8,  0,  5,  0, +       0,  4,  4,  0,  5,  4,  5,  0,  0,  0,  0,  0,  0,  6, +       0,  0,  5,  0,  0, 18,  0,  5,  0,  0,  0, 19,  0,  0, +       8,  0, 14,  0,  0,  0,  0, 13,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  5,  0,  0,  5,  0,  6,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0, 11,  0,  5, 13,  0,  0,  0,  7, +       0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  3,  0,  0, +       4,  0,  6, 13,  0,  8,  0,  5,  0,  0,  0,  5,  0,  0, +       7,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, +       3,  0,  3,  0,  3,  0,  3,  3,  3,  4,  0,  4,  0,  3, +       5,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  3, +       4,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  5, +       0, 18,  0,  0, 15,  7,  0,  3,  0,  0,  6,  5,  0,  5, +       0,  3,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0, +      12,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0, +       0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0, +       0,  0,  0,  0,  0,  3,  3,  0,  0,  0,  0,  0,  0,  7, +       0,  0,  0,  0,  3,  3,  0,  0,  0,  0,  0,  0,  5,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, +       7, 10,  0,  0,  0,  0,  0,  4,  0,  0,  9,  0,  0,  0, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 11,  0,  4,  0,  0,  0,  0,  0,  0,  0,  5,  3,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  6, 12,  0,  0,  0,  5,  6,  0,  0,  0,  0, +       0,  5,  0,  0,  0,  5,  0,  0,  0,  0,  5,  0, 17,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  5,  0,  0,  0,  0,  6,  5,  0,  0,  0,  3,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 13,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       4,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  5,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0, +       4, 15,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  6,  0,  9,  6,  0,  0,  0, +       3,  0,  0,  0,  0,  0,  7,  0,  0, 20,  0,  5,  0,  0, +       0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  5,  0,  0, +       0,  3,  0,  0,  6,  5,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  3,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,  7,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0, 14,  0,  0,  0,  0,  5,  6,  0,  0,  0,  0, +       0,  4,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0, +       0,  0,  5,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  5,  3,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  8,  0,  8,  0,  0,  5,  0,  0,  0,  0,  0,  0, +       5,  0,  0,  0,  0,  0,  6,  8,  0,  0, 17,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0, 17,  0,  6,  0,  0,  0,  0, +       0,  0,  0,  0,  7,  0,  0,  0,  6,  0,  0,  0,  0,  0, +       0,  0,  0, 13,  0,  0,  0,  0,  7,  0,  0,  3, 14,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, +       0,  7,  5,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0, +       0,  0,  0,  4,  4,  4,  0,  0,  0,  0,  6, 11, 19,  0, +       0,  5, 17,  0,  0,  0,  0,  0, 16,  5,  0,  0,  0,  0, +      16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +      16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0, +       7,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  6,  0,  0, +       0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  3,  0,  0, +       0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       7,  0,  7,  8,  0,  0,  0,  0,  0, 13,  0, 16,  5,  4, +       0,  0,  0,  6,  0,  0,  5,  0,  0,  0,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 21, +       9,  6,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0, +       0,  7,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  8, +       9, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  6,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       5,  7, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  3,  7,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  6,  0,  0,  0, +       0,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 14, +       0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  4, 10,  0,  0,  0,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  3,  0,  0,  0,  0,  0, 10,  0, 10,  0, +       0,  0, 21,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  5,  0,  0,  0, +       0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  6,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0, 11,  0, 20,  0,  3,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 13,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0, +       0,  3,  0,  0,  0,  0,  5, 14,  5,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 21, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  3,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0, 13,  0,  0,  0,  0,  5,  0, +       0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0, +       0,  4,  0,  0,  0,  0,  0,  0,  4,  0,  4,  0,  0,  0, +      18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  8,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 11,  5,  0,  0, +       0,  0,  0,  0,  0, 13,  0,  0,  0,  0,  0,  0,  7,  0, +      19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 14,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 11,  0,  5,  0, +       0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  6,  0,  0,  0,  0,  0, 16,  5,  0, 15,  0, +       0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  5,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  3,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  3,  3,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 15,  0,  0,  0,  0,  0,  6,  0,  0,  0,  9,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0, +       0,  0,  0,  3,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  4,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  5, 11,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0, 11, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  7,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  5,  0,  0,  0,  4,  7,  0,  0,  0,  0,  0,  6, +       0,  0,  0,  0,  4,  0,  0,  0,  5,  0,  0,  8,  0,  0, +       0,  0,  0,  0, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0, +       0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0, +       0,  0,  0,  0,  0,  0,  0, 15,  0,  0,  0,  0,  0,  4, +       0,  0, 11,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0, 15,  0,  0, 18,  0, +       0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0, 14,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +      14,  0,  0, 18,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 15,  0,  0, +       0,  0,  5,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  6, +       0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0, 14,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7, +      13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0, 14,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0, +       0,  0,  0, 12,  0,  0,  0, 14,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 13,  0,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 15,  0,  0, 18,  0,  0,  0,  7,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 15,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0, +       0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0, 11,  0, +       0,  5,  0,  0,  0,  7,  0,  0,  0, 11,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  5,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  5,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       9,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0, 19,  0,  0,  0, 21, 16,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0, 10,  0,  5,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +      10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0, +       0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0, 16,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  4,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0, 14,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  5, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0, 11,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0, 14,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       6,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0, 11,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0, 14,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, +       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15 +    }; +  static const struct html_ent wordlist[] = +    { +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1502 "src/html/html_unescape.gperf" +      {"rarr", 3, {226, 134, 146}}, +      {(char*)0}, +#line 834 "src/html/html_unescape.gperf" +      {"larr", 3, {226, 134, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 845 "src/html/html_unescape.gperf" +      {"lat", 3, {226, 170, 171}}, +      {(char*)0}, {(char*)0}, +#line 1904 "src/html/html_unescape.gperf" +      {"uarr", 3, {226, 134, 145}}, +      {(char*)0}, {(char*)0}, +#line 1236 "src/html/html_unescape.gperf" +      {"npr", 3, {226, 138, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1511 "src/html/html_unescape.gperf" +      {"rarrtl", 3, {226, 134, 163}}, +      {(char*)0}, +#line 842 "src/html/html_unescape.gperf" +      {"larrtl", 3, {226, 134, 162}}, +#line 1602 "src/html/html_unescape.gperf" +      {"roarr", 3, {226, 135, 190}}, +      {(char*)0}, +#line 964 "src/html/html_unescape.gperf" +      {"loarr", 3, {226, 135, 189}}, +#line 1169 "src/html/html_unescape.gperf" +      {"not", 2, {194, 172}}, +#line 1610 "src/html/html_unescape.gperf" +      {"rpar", 1, {41}}, +#line 147 "src/html/html_unescape.gperf" +      {"bot", 3, {226, 138, 165}}, +#line 990 "src/html/html_unescape.gperf" +      {"lpar", 1, {40}}, +      {(char*)0}, +#line 1716 "src/html/html_unescape.gperf" +      {"spar", 3, {226, 136, 165}}, +      {(char*)0}, +#line 946 "src/html/html_unescape.gperf" +      {"ll", 3, {226, 137, 170}}, +#line 1927 "src/html/html_unescape.gperf" +      {"uharr", 3, {226, 134, 190}}, +#line 506 "src/html/html_unescape.gperf" +      {"epar", 3, {226, 139, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 483 "src/html/html_unescape.gperf" +      {"el", 3, {226, 170, 153}}, +      {(char*)0}, +#line 1608 "src/html/html_unescape.gperf" +      {"rotimes", 3, {226, 168, 181}}, +      {(char*)0}, +#line 982 "src/html/html_unescape.gperf" +      {"lotimes", 3, {226, 168, 180}}, +#line 1389 "src/html/html_unescape.gperf" +      {"par", 3, {226, 136, 165}}, +      {(char*)0}, +#line 1133 "src/html/html_unescape.gperf" +      {"nharr", 3, {226, 134, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1232 "src/html/html_unescape.gperf" +      {"npar", 3, {226, 136, 166}}, +      {(char*)0}, {(char*)0}, +#line 1873 "src/html/html_unescape.gperf" +      {"tprime", 3, {226, 128, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 487 "src/html/html_unescape.gperf" +      {"els", 3, {226, 170, 149}}, +#line 507 "src/html/html_unescape.gperf" +      {"eparsl", 3, {226, 167, 163}}, +      {(char*)0}, +#line 501 "src/html/html_unescape.gperf" +      {"ensp", 3, {226, 128, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 194 "src/html/html_unescape.gperf" +      {"bprime", 3, {226, 128, 181}}, +#line 956 "src/html/html_unescape.gperf" +      {"lnap", 3, {226, 170, 137}}, +#line 138 "src/html/html_unescape.gperf" +      {"blk14", 3, {226, 150, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 137 "src/html/html_unescape.gperf" +      {"blk12", 3, {226, 150, 146}}, +      {(char*)0}, +#line 139 "src/html/html_unescape.gperf" +      {"blk34", 3, {226, 150, 147}}, +      {(char*)0}, +#line 1233 "src/html/html_unescape.gperf" +      {"nparsl", 3, {226, 171, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1144 "src/html/html_unescape.gperf" +      {"nldr", 3, {226, 128, 165}}, +#line 1595 "src/html/html_unescape.gperf" +      {"rlarr", 3, {226, 135, 132}}, +#line 1234 "src/html/html_unescape.gperf" +      {"npart", 3, {226, 136, 130}}, +#line 945 "src/html/html_unescape.gperf" +      {"llarr", 3, {226, 135, 135}}, +#line 1159 "src/html/html_unescape.gperf" +      {"nlt", 3, {226, 137, 174}}, +#line 1697 "src/html/html_unescape.gperf" +      {"slarr", 3, {226, 134, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1231 "src/html/html_unescape.gperf" +      {"nparallel", 3, {226, 136, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1826 "src/html/html_unescape.gperf" +      {"Tau", 2, {206, 164}}, +#line 1992 "src/html/html_unescape.gperf" +      {"varr", 3, {226, 134, 149}}, +      {(char*)0}, +#line 1739 "src/html/html_unescape.gperf" +      {"squ", 3, {226, 150, 161}}, +      {(char*)0}, {(char*)0}, +#line 1142 "src/html/html_unescape.gperf" +      {"nlarr", 3, {226, 134, 154}}, +      {(char*)0}, {(char*)0}, +#line 1827 "src/html/html_unescape.gperf" +      {"tau", 2, {207, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 958 "src/html/html_unescape.gperf" +      {"lne", 3, {226, 170, 135}}, +#line 1613 "src/html/html_unescape.gperf" +      {"rrarr", 3, {226, 135, 137}}, +      {(char*)0}, +#line 992 "src/html/html_unescape.gperf" +      {"lrarr", 3, {226, 135, 134}}, +      {(char*)0}, +#line 1741 "src/html/html_unescape.gperf" +      {"srarr", 3, {226, 134, 146}}, +#line 1557 "src/html/html_unescape.gperf" +      {"rharul", 3, {226, 165, 172}}, +      {(char*)0}, +#line 941 "src/html/html_unescape.gperf" +      {"lharul", 3, {226, 165, 170}}, +#line 526 "src/html/html_unescape.gperf" +      {"erarr", 3, {226, 165, 177}}, +      {(char*)0}, +#line 1434 "src/html/html_unescape.gperf" +      {"pr", 3, {226, 137, 186}}, +#line 1556 "src/html/html_unescape.gperf" +      {"rharu", 3, {226, 135, 128}}, +      {(char*)0}, +#line 940 "src/html/html_unescape.gperf" +      {"lharu", 3, {226, 134, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1905 "src/html/html_unescape.gperf" +      {"Uarr", 3, {226, 134, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1129 "src/html/html_unescape.gperf" +      {"nGt", 3, {226, 137, 171}}, +      {(char*)0}, +#line 141 "src/html/html_unescape.gperf" +      {"bne", 1, {61}}, +#line 1242 "src/html/html_unescape.gperf" +      {"nrarr", 3, {226, 134, 155}}, +      {(char*)0}, {(char*)0}, +#line 1819 "src/html/html_unescape.gperf" +      {"swarr", 3, {226, 134, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1498 "src/html/html_unescape.gperf" +      {"rarrap", 3, {226, 165, 181}}, +      {(char*)0}, +#line 1967 "src/html/html_unescape.gperf" +      {"upuparrows", 3, {226, 135, 136}}, +      {(char*)0}, +#line 345 "src/html/html_unescape.gperf" +      {"Darr", 3, {226, 134, 161}}, +      {(char*)0}, {(char*)0}, +#line 1517 "src/html/html_unescape.gperf" +      {"rbarr", 3, {226, 164, 141}}, +#line 398 "src/html/html_unescape.gperf" +      {"Dot", 2, {194, 168}}, +#line 848 "src/html/html_unescape.gperf" +      {"lbarr", 3, {226, 164, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1307 "src/html/html_unescape.gperf" +      {"nwarr", 3, {226, 134, 150}}, +      {(char*)0}, +#line 1704 "src/html/html_unescape.gperf" +      {"smt", 3, {226, 170, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 497 "src/html/html_unescape.gperf" +      {"emsp14", 3, {226, 128, 133}}, +#line 1508 "src/html/html_unescape.gperf" +      {"rarrpl", 3, {226, 165, 133}}, +      {(char*)0}, +#line 840 "src/html/html_unescape.gperf" +      {"larrpl", 3, {226, 164, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1406 "src/html/html_unescape.gperf" +      {"phmmat", 3, {226, 132, 179}}, +      {(char*)0}, +#line 496 "src/html/html_unescape.gperf" +      {"emsp13", 3, {226, 128, 132}}, +      {(char*)0}, +#line 1014 "src/html/html_unescape.gperf" +      {"LT", 1, {60}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 835 "src/html/html_unescape.gperf" +      {"Larr", 3, {226, 134, 158}}, +#line 1525 "src/html/html_unescape.gperf" +      {"rbrkslu", 3, {226, 166, 144}}, +      {(char*)0}, +#line 855 "src/html/html_unescape.gperf" +      {"lbrkslu", 3, {226, 166, 141}}, +      {(char*)0}, +#line 1082 "src/html/html_unescape.gperf" +      {"napos", 2, {197, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1146 "src/html/html_unescape.gperf" +      {"nle", 3, {226, 137, 176}}, +      {(char*)0}, +#line 1554 "src/html/html_unescape.gperf" +      {"rHar", 3, {226, 165, 164}}, +      {(char*)0}, +#line 938 "src/html/html_unescape.gperf" +      {"lHar", 3, {226, 165, 162}}, +#line 1477 "src/html/html_unescape.gperf" +      {"qprime", 3, {226, 129, 151}}, +      {(char*)0}, +#line 829 "src/html/html_unescape.gperf" +      {"lap", 3, {226, 170, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1087 "src/html/html_unescape.gperf" +      {"nbsp", 2, {194, 160}}, +#line 1925 "src/html/html_unescape.gperf" +      {"uHar", 3, {226, 165, 163}}, +#line 1868 "src/html/html_unescape.gperf" +      {"top", 3, {226, 138, 164}}, +      {(char*)0}, +#line 2004 "src/html/html_unescape.gperf" +      {"Vbar", 3, {226, 171, 171}}, +      {(char*)0}, {(char*)0}, +#line 947 "src/html/html_unescape.gperf" +      {"Ll", 3, {226, 139, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1432 "src/html/html_unescape.gperf" +      {"prap", 3, {226, 170, 183}}, +      {(char*)0}, +#line 498 "src/html/html_unescape.gperf" +      {"emsp", 3, {226, 128, 131}}, +      {(char*)0}, {(char*)0}, +#line 1079 "src/html/html_unescape.gperf" +      {"nap", 3, {226, 137, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 976 "src/html/html_unescape.gperf" +      {"looparrowleft", 3, {226, 134, 171}}, +      {(char*)0}, +#line 870 "src/html/html_unescape.gperf" +      {"le", 3, {226, 137, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1670 "src/html/html_unescape.gperf" +      {"sharp", 3, {226, 153, 175}}, +      {(char*)0}, +#line 474 "src/html/html_unescape.gperf" +      {"ee", 3, {226, 133, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 914 "src/html/html_unescape.gperf" +      {"les", 3, {226, 169, 189}}, +#line 745 "src/html/html_unescape.gperf" +      {"in", 3, {226, 136, 136}}, +#line 1461 "src/html/html_unescape.gperf" +      {"prop", 3, {226, 136, 157}}, +      {(char*)0}, +#line 1866 "src/html/html_unescape.gperf" +      {"topbot", 3, {226, 140, 182}}, +      {(char*)0}, {(char*)0}, +#line 750 "src/html/html_unescape.gperf" +      {"int", 3, {226, 136, 171}}, +      {(char*)0}, +#line 1105 "src/html/html_unescape.gperf" +      {"ne", 3, {226, 137, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1237 "src/html/html_unescape.gperf" +      {"nprcue", 3, {226, 139, 160}}, +      {(char*)0}, +#line 1447 "src/html/html_unescape.gperf" +      {"pre", 3, {226, 170, 175}}, +#line 509 "src/html/html_unescape.gperf" +      {"epsi", 2, {206, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1960 "src/html/html_unescape.gperf" +      {"upsi", 2, {207, 133}}, +#line 1839 "src/html/html_unescape.gperf" +      {"there4", 3, {226, 136, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1523 "src/html/html_unescape.gperf" +      {"rbrke", 3, {226, 166, 140}}, +#line 1658 "src/html/html_unescape.gperf" +      {"searr", 3, {226, 134, 152}}, +#line 853 "src/html/html_unescape.gperf" +      {"lbrke", 3, {226, 166, 139}}, +      {(char*)0}, +#line 132 "src/html/html_unescape.gperf" +      {"blacktriangle", 3, {226, 150, 180}}, +      {(char*)0}, {(char*)0}, +#line 960 "src/html/html_unescape.gperf" +      {"lneq", 3, {226, 170, 135}}, +      {(char*)0}, {(char*)0}, +#line 961 "src/html/html_unescape.gperf" +      {"lneqq", 3, {226, 137, 168}}, +      {(char*)0}, +#line 1418 "src/html/html_unescape.gperf" +      {"plus", 1, {43}}, +#line 1154 "src/html/html_unescape.gperf" +      {"nles", 3, {226, 169, 189}}, +#line 1106 "src/html/html_unescape.gperf" +      {"nedot", 3, {226, 137, 144}}, +#line 134 "src/html/html_unescape.gperf" +      {"blacktriangleleft", 3, {226, 151, 130}}, +#line 135 "src/html/html_unescape.gperf" +      {"blacktriangleright", 3, {226, 150, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1102 "src/html/html_unescape.gperf" +      {"nearr", 3, {226, 134, 151}}, +      {(char*)0}, {(char*)0}, +#line 133 "src/html/html_unescape.gperf" +      {"blacktriangledown", 3, {226, 150, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1155 "src/html/html_unescape.gperf" +      {"nless", 3, {226, 137, 174}}, +#line 490 "src/html/html_unescape.gperf" +      {"emacr", 2, {196, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2034 "src/html/html_unescape.gperf" +      {"vprop", 3, {226, 136, 157}}, +#line 1934 "src/html/html_unescape.gperf" +      {"umacr", 2, {197, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1701 "src/html/html_unescape.gperf" +      {"smeparsl", 3, {226, 167, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1033 "src/html/html_unescape.gperf" +      {"Map", 3, {226, 164, 133}}, +      {(char*)0}, {(char*)0}, +#line 1420 "src/html/html_unescape.gperf" +      {"plusdu", 3, {226, 168, 165}}, +#line 1168 "src/html/html_unescape.gperf" +      {"Not", 3, {226, 171, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2019 "src/html/html_unescape.gperf" +      {"Verbar", 3, {226, 128, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1399 "src/html/html_unescape.gperf" +      {"perp", 3, {226, 138, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 561 "src/html/html_unescape.gperf" +      {"fltns", 3, {226, 150, 177}}, +#line 1423 "src/html/html_unescape.gperf" +      {"plusmn", 2, {194, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1151 "src/html/html_unescape.gperf" +      {"nleq", 3, {226, 137, 176}}, +      {(char*)0}, {(char*)0}, +#line 1152 "src/html/html_unescape.gperf" +      {"nleqq", 3, {226, 137, 166}}, +      {(char*)0}, +#line 579 "src/html/html_unescape.gperf" +      {"frac34", 2, {194, 190}}, +#line 573 "src/html/html_unescape.gperf" +      {"frac14", 2, {194, 188}}, +#line 2018 "src/html/html_unescape.gperf" +      {"verbar", 1, {124}}, +#line 571 "src/html/html_unescape.gperf" +      {"frac12", 2, {194, 189}}, +#line 580 "src/html/html_unescape.gperf" +      {"frac35", 3, {226, 133, 151}}, +#line 574 "src/html/html_unescape.gperf" +      {"frac15", 3, {226, 133, 149}}, +#line 582 "src/html/html_unescape.gperf" +      {"frac45", 3, {226, 133, 152}}, +      {(char*)0}, {(char*)0}, +#line 578 "src/html/html_unescape.gperf" +      {"frac25", 3, {226, 133, 150}}, +      {(char*)0}, +#line 572 "src/html/html_unescape.gperf" +      {"frac13", 3, {226, 133, 147}}, +      {(char*)0}, +#line 575 "src/html/html_unescape.gperf" +      {"frac16", 3, {226, 133, 153}}, +#line 1466 "src/html/html_unescape.gperf" +      {"prurel", 3, {226, 138, 176}}, +#line 577 "src/html/html_unescape.gperf" +      {"frac23", 3, {226, 133, 148}}, +#line 581 "src/html/html_unescape.gperf" +      {"frac38", 3, {226, 133, 156}}, +#line 576 "src/html/html_unescape.gperf" +      {"frac18", 3, {226, 133, 155}}, +#line 583 "src/html/html_unescape.gperf" +      {"frac56", 3, {226, 133, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 584 "src/html/html_unescape.gperf" +      {"frac58", 3, {226, 133, 157}}, +      {(char*)0}, +#line 585 "src/html/html_unescape.gperf" +      {"frac78", 3, {226, 133, 158}}, +#line 910 "src/html/html_unescape.gperf" +      {"leq", 3, {226, 137, 164}}, +#line 344 "src/html/html_unescape.gperf" +      {"darr", 3, {226, 134, 147}}, +      {(char*)0}, {(char*)0}, +#line 1961 "src/html/html_unescape.gperf" +      {"Upsi", 2, {207, 146}}, +#line 399 "src/html/html_unescape.gperf" +      {"dot", 2, {203, 153}}, +#line 1407 "src/html/html_unescape.gperf" +      {"phone", 3, {226, 152, 142}}, +      {(char*)0}, {(char*)0}, +#line 219 "src/html/html_unescape.gperf" +      {"Cap", 3, {226, 139, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 131 "src/html/html_unescape.gperf" +      {"blacksquare", 3, {226, 150, 170}}, +#line 1600 "src/html/html_unescape.gperf" +      {"rnmid", 3, {226, 171, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 911 "src/html/html_unescape.gperf" +      {"leqq", 3, {226, 137, 166}}, +      {(char*)0}, {(char*)0}, +#line 749 "src/html/html_unescape.gperf" +      {"intcal", 3, {226, 138, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 372 "src/html/html_unescape.gperf" +      {"dharr", 3, {226, 135, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1555 "src/html/html_unescape.gperf" +      {"rhard", 3, {226, 135, 129}}, +      {(char*)0}, +#line 939 "src/html/html_unescape.gperf" +      {"lhard", 3, {226, 134, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1421 "src/html/html_unescape.gperf" +      {"pluse", 3, {226, 169, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1933 "src/html/html_unescape.gperf" +      {"Umacr", 2, {197, 170}}, +#line 2015 "src/html/html_unescape.gperf" +      {"Vee", 3, {226, 139, 129}}, +      {(char*)0}, {(char*)0}, +#line 1503 "src/html/html_unescape.gperf" +      {"Rarr", 3, {226, 134, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 304 "src/html/html_unescape.gperf" +      {"Cross", 3, {226, 168, 175}}, +      {(char*)0}, +#line 1620 "src/html/html_unescape.gperf" +      {"rsqb", 1, {93}}, +      {(char*)0}, +#line 1006 "src/html/html_unescape.gperf" +      {"lsqb", 1, {91}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1510 "src/html/html_unescape.gperf" +      {"Rarrtl", 3, {226, 164, 150}}, +      {(char*)0}, {(char*)0}, +#line 530 "src/html/html_unescape.gperf" +      {"esdot", 3, {226, 137, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2014 "src/html/html_unescape.gperf" +      {"vee", 3, {226, 136, 168}}, +#line 1089 "src/html/html_unescape.gperf" +      {"nbumpe", 3, {226, 137, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 948 "src/html/html_unescape.gperf" +      {"llcorner", 3, {226, 140, 158}}, +#line 570 "src/html/html_unescape.gperf" +      {"fpartint", 3, {226, 168, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1740 "src/html/html_unescape.gperf" +      {"squf", 3, {226, 150, 170}}, +#line 1414 "src/html/html_unescape.gperf" +      {"plankv", 3, {226, 132, 143}}, +      {(char*)0}, {(char*)0}, +#line 525 "src/html/html_unescape.gperf" +      {"eqvparsl", 3, {226, 167, 165}}, +      {(char*)0}, +#line 1930 "src/html/html_unescape.gperf" +      {"ulcorner", 3, {226, 140, 156}}, +      {(char*)0}, +#line 2055 "src/html/html_unescape.gperf" +      {"wp", 3, {226, 132, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 989 "src/html/html_unescape.gperf" +      {"lozf", 3, {226, 167, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 299 "src/html/html_unescape.gperf" +      {"COPY", 2, {194, 169}}, +      {(char*)0}, +#line 1929 "src/html/html_unescape.gperf" +      {"ulcorn", 3, {226, 140, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2013 "src/html/html_unescape.gperf" +      {"veebar", 3, {226, 138, 187}}, +      {(char*)0}, +#line 1392 "src/html/html_unescape.gperf" +      {"part", 3, {226, 136, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1730 "src/html/html_unescape.gperf" +      {"square", 3, {226, 150, 161}}, +      {(char*)0}, +#line 1088 "src/html/html_unescape.gperf" +      {"nbump", 3, {226, 137, 142}}, +#line 108 "src/html/html_unescape.gperf" +      {"bernou", 3, {226, 132, 172}}, +#line 2056 "src/html/html_unescape.gperf" +      {"wr", 3, {226, 137, 128}}, +#line 1518 "src/html/html_unescape.gperf" +      {"rBarr", 3, {226, 164, 143}}, +#line 993 "src/html/html_unescape.gperf" +      {"lrcorner", 3, {226, 140, 159}}, +#line 849 "src/html/html_unescape.gperf" +      {"lBarr", 3, {226, 164, 142}}, +      {(char*)0}, {(char*)0}, +#line 144 "src/html/html_unescape.gperf" +      {"bnot", 3, {226, 140, 144}}, +      {(char*)0}, +#line 1662 "src/html/html_unescape.gperf" +      {"semi", 1, {59}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1969 "src/html/html_unescape.gperf" +      {"urcorner", 3, {226, 140, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1218 "src/html/html_unescape.gperf" +      {"NotSubset", 3, {226, 138, 130}}, +      {(char*)0}, +#line 1605 "src/html/html_unescape.gperf" +      {"ropf", 4, {240, 157, 149, 163}}, +#line 1476 "src/html/html_unescape.gperf" +      {"Qopf", 3, {226, 132, 154}}, +#line 980 "src/html/html_unescape.gperf" +      {"lopf", 4, {240, 157, 149, 157}}, +      {(char*)0}, +#line 1713 "src/html/html_unescape.gperf" +      {"sopf", 4, {240, 157, 149, 164}}, +#line 1968 "src/html/html_unescape.gperf" +      {"urcorn", 3, {226, 140, 157}}, +#line 1869 "src/html/html_unescape.gperf" +      {"Topf", 4, {240, 157, 149, 139}}, +#line 2127 "src/html/html_unescape.gperf" +      {"Zopf", 3, {226, 132, 164}}, +#line 505 "src/html/html_unescape.gperf" +      {"eopf", 4, {240, 157, 149, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1604 "src/html/html_unescape.gperf" +      {"ropar", 3, {226, 166, 134}}, +#line 1945 "src/html/html_unescape.gperf" +      {"uopf", 4, {240, 157, 149, 166}}, +#line 978 "src/html/html_unescape.gperf" +      {"lopar", 3, {226, 166, 133}}, +#line 1870 "src/html/html_unescape.gperf" +      {"topf", 4, {240, 157, 149, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2075 "src/html/html_unescape.gperf" +      {"Xopf", 4, {240, 157, 149, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1166 "src/html/html_unescape.gperf" +      {"nopf", 4, {240, 157, 149, 159}}, +      {(char*)0}, +#line 146 "src/html/html_unescape.gperf" +      {"bopf", 4, {240, 157, 149, 147}}, +#line 512 "src/html/html_unescape.gperf" +      {"epsiv", 2, {207, 181}}, +#line 562 "src/html/html_unescape.gperf" +      {"fnof", 2, {198, 146}}, +#line 734 "src/html/html_unescape.gperf" +      {"imacr", 2, {196, 171}}, +      {(char*)0}, {(char*)0}, +#line 792 "src/html/html_unescape.gperf" +      {"Jopf", 4, {240, 157, 149, 129}}, +      {(char*)0}, +#line 1135 "src/html/html_unescape.gperf" +      {"nhpar", 3, {226, 171, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2053 "src/html/html_unescape.gperf" +      {"Wopf", 4, {240, 157, 149, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1721 "src/html/html_unescape.gperf" +      {"Sqrt", 3, {226, 136, 154}}, +#line 1263 "src/html/html_unescape.gperf" +      {"nsub", 3, {226, 138, 132}}, +      {(char*)0}, +#line 1081 "src/html/html_unescape.gperf" +      {"napid", 3, {226, 137, 139}}, +      {(char*)0}, {(char*)0}, +#line 1224 "src/html/html_unescape.gperf" +      {"NotSuperset", 3, {226, 138, 131}}, +      {(char*)0}, {(char*)0}, +#line 197 "src/html/html_unescape.gperf" +      {"brvbar", 2, {194, 166}}, +      {(char*)0}, {(char*)0}, +#line 1711 "src/html/html_unescape.gperf" +      {"sol", 1, {47}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 461 "src/html/html_unescape.gperf" +      {"easter", 3, {226, 169, 174}}, +      {(char*)0}, +#line 1429 "src/html/html_unescape.gperf" +      {"popf", 4, {240, 157, 149, 161}}, +      {(char*)0}, {(char*)0}, +#line 370 "src/html/html_unescape.gperf" +      {"dHar", 3, {226, 165, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2032 "src/html/html_unescape.gperf" +      {"Vopf", 4, {240, 157, 149, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1274 "src/html/html_unescape.gperf" +      {"nsupset", 3, {226, 138, 131}}, +#line 1271 "src/html/html_unescape.gperf" +      {"nsup", 3, {226, 138, 133}}, +#line 2003 "src/html/html_unescape.gperf" +      {"vBar", 3, {226, 171, 168}}, +      {(char*)0}, +#line 1266 "src/html/html_unescape.gperf" +      {"nsubset", 3, {226, 138, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1851 "src/html/html_unescape.gperf" +      {"thkap", 3, {226, 137, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1137 "src/html/html_unescape.gperf" +      {"nis", 3, {226, 139, 188}}, +#line 1460 "src/html/html_unescape.gperf" +      {"profsurf", 3, {226, 140, 147}}, +#line 1710 "src/html/html_unescape.gperf" +      {"solb", 3, {226, 167, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 962 "src/html/html_unescape.gperf" +      {"lnsim", 3, {226, 139, 166}}, +      {(char*)0}, +#line 1709 "src/html/html_unescape.gperf" +      {"solbar", 3, {226, 140, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1731 "src/html/html_unescape.gperf" +      {"Square", 3, {226, 150, 161}}, +      {(char*)0}, +#line 2033 "src/html/html_unescape.gperf" +      {"vopf", 4, {240, 157, 149, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1926 "src/html/html_unescape.gperf" +      {"uharl", 3, {226, 134, 191}}, +      {(char*)0}, +#line 1931 "src/html/html_unescape.gperf" +      {"ulcrop", 3, {226, 140, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 515 "src/html/html_unescape.gperf" +      {"eqsim", 3, {226, 137, 130}}, +#line 523 "src/html/html_unescape.gperf" +      {"equiv", 3, {226, 137, 161}}, +      {(char*)0}, {(char*)0}, +#line 486 "src/html/html_unescape.gperf" +      {"ell", 3, {226, 132, 147}}, +#line 1700 "src/html/html_unescape.gperf" +      {"smashp", 3, {226, 168, 179}}, +#line 1067 "src/html/html_unescape.gperf" +      {"mp", 3, {226, 136, 147}}, +      {(char*)0}, {(char*)0}, +#line 814 "src/html/html_unescape.gperf" +      {"Kopf", 4, {240, 157, 149, 130}}, +      {(char*)0}, {(char*)0}, +#line 1696 "src/html/html_unescape.gperf" +      {"simrarr", 3, {226, 165, 178}}, +      {(char*)0}, +#line 559 "src/html/html_unescape.gperf" +      {"flat", 3, {226, 153, 173}}, +      {(char*)0}, +#line 1065 "src/html/html_unescape.gperf" +      {"Mopf", 4, {240, 157, 149, 132}}, +#line 1712 "src/html/html_unescape.gperf" +      {"Sopf", 4, {240, 157, 149, 138}}, +#line 1062 "src/html/html_unescape.gperf" +      {"mldr", 3, {226, 128, 166}}, +#line 1597 "src/html/html_unescape.gperf" +      {"rlm", 3, {226, 128, 143}}, +#line 768 "src/html/html_unescape.gperf" +      {"iprod", 3, {226, 168, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 991 "src/html/html_unescape.gperf" +      {"lparlt", 3, {226, 166, 147}}, +      {(char*)0}, +#line 564 "src/html/html_unescape.gperf" +      {"fopf", 4, {240, 157, 149, 151}}, +#line 1944 "src/html/html_unescape.gperf" +      {"Uopf", 4, {240, 157, 149, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1996 "src/html/html_unescape.gperf" +      {"varsubsetneq", 3, {226, 138, 138}}, +#line 1997 "src/html/html_unescape.gperf" +      {"varsubsetneqq", 3, {226, 171, 139}}, +      {(char*)0}, {(char*)0}, +#line 1970 "src/html/html_unescape.gperf" +      {"urcrop", 3, {226, 140, 142}}, +#line 928 "src/html/html_unescape.gperf" +      {"LessLess", 3, {226, 170, 161}}, +      {(char*)0}, +#line 1543 "src/html/html_unescape.gperf" +      {"Re", 3, {226, 132, 156}}, +      {(char*)0}, {(char*)0}, +#line 1202 "src/html/html_unescape.gperf" +      {"NotNestedLessLess", 3, {226, 170, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 396 "src/html/html_unescape.gperf" +      {"Dopf", 4, {240, 157, 148, 187}}, +      {(char*)0}, +#line 568 "src/html/html_unescape.gperf" +      {"forkv", 3, {226, 171, 153}}, +      {(char*)0}, +#line 1261 "src/html/html_unescape.gperf" +      {"nsqsube", 3, {226, 139, 162}}, +      {(char*)0}, +#line 1273 "src/html/html_unescape.gperf" +      {"nsupe", 3, {226, 138, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1265 "src/html/html_unescape.gperf" +      {"nsube", 3, {226, 138, 136}}, +#line 1475 "src/html/html_unescape.gperf" +      {"qopf", 4, {240, 157, 149, 162}}, +#line 1596 "src/html/html_unescape.gperf" +      {"rlhar", 3, {226, 135, 140}}, +      {(char*)0}, {(char*)0}, +#line 996 "src/html/html_unescape.gperf" +      {"lrm", 3, {226, 128, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1157 "src/html/html_unescape.gperf" +      {"nlsim", 3, {226, 137, 180}}, +      {(char*)0}, +#line 1431 "src/html/html_unescape.gperf" +      {"pound", 2, {194, 163}}, +#line 1998 "src/html/html_unescape.gperf" +      {"varsupsetneq", 3, {226, 138, 139}}, +#line 1999 "src/html/html_unescape.gperf" +      {"varsupsetneqq", 3, {226, 171, 140}}, +      {(char*)0}, +#line 142 "src/html/html_unescape.gperf" +      {"bnequiv", 3, {226, 137, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 979 "src/html/html_unescape.gperf" +      {"Lopf", 4, {240, 157, 149, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1262 "src/html/html_unescape.gperf" +      {"nsqsupe", 3, {226, 139, 163}}, +      {(char*)0}, {(char*)0}, +#line 1507 "src/html/html_unescape.gperf" +      {"rarrlp", 3, {226, 134, 172}}, +#line 2046 "src/html/html_unescape.gperf" +      {"wedbar", 3, {226, 169, 159}}, +#line 839 "src/html/html_unescape.gperf" +      {"larrlp", 3, {226, 134, 171}}, +      {(char*)0}, +#line 2101 "src/html/html_unescape.gperf" +      {"Yopf", 4, {240, 157, 149, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1210 "src/html/html_unescape.gperf" +      {"NotReverseElement", 3, {226, 136, 140}}, +      {(char*)0}, {(char*)0}, +#line 295 "src/html/html_unescape.gperf" +      {"Copf", 3, {226, 132, 130}}, +#line 994 "src/html/html_unescape.gperf" +      {"lrhar", 3, {226, 135, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1391 "src/html/html_unescape.gperf" +      {"parsl", 3, {226, 171, 189}}, +#line 1935 "src/html/html_unescape.gperf" +      {"uml", 2, {194, 168}}, +#line 1039 "src/html/html_unescape.gperf" +      {"marker", 3, {226, 150, 174}}, +#line 1275 "src/html/html_unescape.gperf" +      {"nsupseteq", 3, {226, 138, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1267 "src/html/html_unescape.gperf" +      {"nsubseteq", 3, {226, 138, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1738 "src/html/html_unescape.gperf" +      {"squarf", 3, {226, 150, 170}}, +#line 2021 "src/html/html_unescape.gperf" +      {"Vert", 3, {226, 128, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1736 "src/html/html_unescape.gperf" +      {"SquareSupersetEqual", 3, {226, 138, 146}}, +      {(char*)0}, +#line 1465 "src/html/html_unescape.gperf" +      {"prsim", 3, {226, 137, 190}}, +      {(char*)0}, {(char*)0}, +#line 1734 "src/html/html_unescape.gperf" +      {"SquareSubsetEqual", 3, {226, 138, 145}}, +      {(char*)0}, {(char*)0}, +#line 1735 "src/html/html_unescape.gperf" +      {"SquareSuperset", 3, {226, 138, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1733 "src/html/html_unescape.gperf" +      {"SquareSubset", 3, {226, 138, 143}}, +#line 1290 "src/html/html_unescape.gperf" +      {"nvap", 3, {226, 137, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 765 "src/html/html_unescape.gperf" +      {"iopf", 4, {240, 157, 149, 154}}, +      {(char*)0}, +#line 1426 "src/html/html_unescape.gperf" +      {"pm", 2, {194, 177}}, +      {(char*)0}, +#line 2020 "src/html/html_unescape.gperf" +      {"vert", 1, {124}}, +      {(char*)0}, +#line 1845 "src/html/html_unescape.gperf" +      {"thetav", 2, {207, 145}}, +      {(char*)0}, {(char*)0}, +#line 987 "src/html/html_unescape.gperf" +      {"loz", 3, {226, 151, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1034 "src/html/html_unescape.gperf" +      {"map", 3, {226, 134, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 923 "src/html/html_unescape.gperf" +      {"lesseqqgtr", 3, {226, 170, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1616 "src/html/html_unescape.gperf" +      {"rscr", 4, {240, 157, 147, 135}}, +#line 1478 "src/html/html_unescape.gperf" +      {"Qscr", 4, {240, 157, 146, 172}}, +#line 999 "src/html/html_unescape.gperf" +      {"lscr", 4, {240, 157, 147, 129}}, +      {(char*)0}, +#line 1743 "src/html/html_unescape.gperf" +      {"sscr", 4, {240, 157, 147, 136}}, +      {(char*)0}, +#line 1891 "src/html/html_unescape.gperf" +      {"Tscr", 4, {240, 157, 146, 175}}, +#line 2128 "src/html/html_unescape.gperf" +      {"Zscr", 4, {240, 157, 146, 181}}, +#line 528 "src/html/html_unescape.gperf" +      {"escr", 3, {226, 132, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1975 "src/html/html_unescape.gperf" +      {"uscr", 4, {240, 157, 147, 138}}, +      {(char*)0}, +#line 1892 "src/html/html_unescape.gperf" +      {"tscr", 4, {240, 157, 147, 137}}, +      {(char*)0}, +#line 741 "src/html/html_unescape.gperf" +      {"imof", 3, {226, 138, 183}}, +#line 297 "src/html/html_unescape.gperf" +      {"Coproduct", 3, {226, 136, 144}}, +      {(char*)0}, {(char*)0}, +#line 2081 "src/html/html_unescape.gperf" +      {"Xscr", 4, {240, 157, 146, 179}}, +#line 2068 "src/html/html_unescape.gperf" +      {"Xi", 2, {206, 158}}, +      {(char*)0}, {(char*)0}, +#line 1253 "src/html/html_unescape.gperf" +      {"nscr", 4, {240, 157, 147, 131}}, +#line 1136 "src/html/html_unescape.gperf" +      {"ni", 3, {226, 136, 139}}, +#line 198 "src/html/html_unescape.gperf" +      {"bscr", 4, {240, 157, 146, 183}}, +#line 1167 "src/html/html_unescape.gperf" +      {"Nopf", 3, {226, 132, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 794 "src/html/html_unescape.gperf" +      {"Jscr", 4, {240, 157, 146, 165}}, +#line 1443 "src/html/html_unescape.gperf" +      {"preceq", 3, {226, 170, 175}}, +      {(char*)0}, {(char*)0}, +#line 1303 "src/html/html_unescape.gperf" +      {"nvrArr", 3, {226, 164, 131}}, +#line 88 "src/html/html_unescape.gperf" +      {"backprime", 3, {226, 128, 181}}, +#line 2058 "src/html/html_unescape.gperf" +      {"Wscr", 4, {240, 157, 146, 178}}, +      {(char*)0}, +#line 1989 "src/html/html_unescape.gperf" +      {"varphi", 2, {207, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1259 "src/html/html_unescape.gperf" +      {"nsmid", 3, {226, 136, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 393 "src/html/html_unescape.gperf" +      {"dlcorn", 3, {226, 140, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1468 "src/html/html_unescape.gperf" +      {"pscr", 4, {240, 157, 147, 133}}, +#line 1409 "src/html/html_unescape.gperf" +      {"pi", 2, {207, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2036 "src/html/html_unescape.gperf" +      {"Vscr", 4, {240, 157, 146, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1113 "src/html/html_unescape.gperf" +      {"nesim", 3, {226, 137, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1694 "src/html/html_unescape.gperf" +      {"simne", 3, {226, 137, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1276 "src/html/html_unescape.gperf" +      {"nsupseteqq", 3, {226, 171, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1268 "src/html/html_unescape.gperf" +      {"nsubseteqq", 3, {226, 171, 133}}, +#line 441 "src/html/html_unescape.gperf" +      {"drcorn", 3, {226, 140, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1521 "src/html/html_unescape.gperf" +      {"rbrace", 1, {125}}, +#line 2037 "src/html/html_unescape.gperf" +      {"vscr", 4, {240, 157, 147, 139}}, +#line 851 "src/html/html_unescape.gperf" +      {"lbrace", 1, {123}}, +#line 397 "src/html/html_unescape.gperf" +      {"dopf", 4, {240, 157, 149, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 586 "src/html/html_unescape.gperf" +      {"frasl", 3, {226, 129, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 931 "src/html/html_unescape.gperf" +      {"LessTilde", 3, {226, 137, 178}}, +      {(char*)0}, {(char*)0}, +#line 816 "src/html/html_unescape.gperf" +      {"Kscr", 4, {240, 157, 146, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1417 "src/html/html_unescape.gperf" +      {"pluscir", 3, {226, 168, 162}}, +#line 1069 "src/html/html_unescape.gperf" +      {"Mscr", 3, {226, 132, 179}}, +#line 1742 "src/html/html_unescape.gperf" +      {"Sscr", 4, {240, 157, 146, 174}}, +#line 1524 "src/html/html_unescape.gperf" +      {"rbrksld", 3, {226, 166, 142}}, +      {(char*)0}, +#line 854 "src/html/html_unescape.gperf" +      {"lbrksld", 3, {226, 166, 143}}, +#line 1519 "src/html/html_unescape.gperf" +      {"RBarr", 3, {226, 164, 144}}, +      {(char*)0}, {(char*)0}, +#line 1718 "src/html/html_unescape.gperf" +      {"sqcaps", 3, {226, 138, 147}}, +#line 1504 "src/html/html_unescape.gperf" +      {"rArr", 3, {226, 135, 146}}, +#line 143 "src/html/html_unescape.gperf" +      {"bNot", 3, {226, 171, 173}}, +#line 836 "src/html/html_unescape.gperf" +      {"lArr", 3, {226, 135, 144}}, +      {(char*)0}, +#line 588 "src/html/html_unescape.gperf" +      {"fscr", 4, {240, 157, 146, 187}}, +#line 1974 "src/html/html_unescape.gperf" +      {"Uscr", 4, {240, 157, 146, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1906 "src/html/html_unescape.gperf" +      {"uArr", 3, {226, 135, 145}}, +      {(char*)0}, {(char*)0}, +#line 1606 "src/html/html_unescape.gperf" +      {"Ropf", 3, {226, 132, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2054 "src/html/html_unescape.gperf" +      {"wopf", 4, {240, 157, 149, 168}}, +      {(char*)0}, {(char*)0}, +#line 443 "src/html/html_unescape.gperf" +      {"Dscr", 4, {240, 157, 146, 159}}, +#line 1352 "src/html/html_unescape.gperf" +      {"opar", 3, {226, 166, 183}}, +#line 1663 "src/html/html_unescape.gperf" +      {"seswar", 3, {226, 164, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 363 "src/html/html_unescape.gperf" +      {"Del", 3, {226, 136, 135}}, +#line 1486 "src/html/html_unescape.gperf" +      {"rAarr", 3, {226, 135, 155}}, +#line 1559 "src/html/html_unescape.gperf" +      {"rho", 2, {207, 129}}, +#line 818 "src/html/html_unescape.gperf" +      {"lAarr", 3, {226, 135, 154}}, +#line 1438 "src/html/html_unescape.gperf" +      {"preccurlyeq", 3, {226, 137, 188}}, +#line 1479 "src/html/html_unescape.gperf" +      {"qscr", 4, {240, 157, 147, 134}}, +      {(char*)0}, {(char*)0}, +#line 1029 "src/html/html_unescape.gperf" +      {"macr", 2, {194, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1186 "src/html/html_unescape.gperf" +      {"notin", 3, {226, 136, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 524 "src/html/html_unescape.gperf" +      {"equivDD", 3, {226, 169, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1717 "src/html/html_unescape.gperf" +      {"sqcap", 3, {226, 138, 147}}, +      {(char*)0}, +#line 1260 "src/html/html_unescape.gperf" +      {"nspar", 3, {226, 136, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1341 "src/html/html_unescape.gperf" +      {"olt", 3, {226, 167, 128}}, +#line 1515 "src/html/html_unescape.gperf" +      {"ratio", 3, {226, 136, 182}}, +#line 1000 "src/html/html_unescape.gperf" +      {"Lscr", 3, {226, 132, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 371 "src/html/html_unescape.gperf" +      {"dharl", 3, {226, 135, 131}}, +      {(char*)0}, +#line 394 "src/html/html_unescape.gperf" +      {"dlcrop", 3, {226, 140, 141}}, +#line 409 "src/html/html_unescape.gperf" +      {"DoubleDot", 2, {194, 168}}, +#line 405 "src/html/html_unescape.gperf" +      {"dotplus", 3, {226, 136, 148}}, +#line 1359 "src/html/html_unescape.gperf" +      {"or", 3, {226, 136, 168}}, +      {(char*)0}, +#line 2103 "src/html/html_unescape.gperf" +      {"Yscr", 4, {240, 157, 146, 180}}, +      {(char*)0}, {(char*)0}, +#line 563 "src/html/html_unescape.gperf" +      {"Fopf", 4, {240, 157, 148, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 305 "src/html/html_unescape.gperf" +      {"Cscr", 4, {240, 157, 146, 158}}, +#line 1337 "src/html/html_unescape.gperf" +      {"olarr", 3, {226, 134, 186}}, +#line 1244 "src/html/html_unescape.gperf" +      {"nrarrw", 3, {226, 134, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1027 "src/html/html_unescape.gperf" +      {"lvertneqq", 3, {226, 137, 168}}, +#line 516 "src/html/html_unescape.gperf" +      {"eqslantgtr", 3, {226, 170, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1854 "src/html/html_unescape.gperf" +      {"thorn", 2, {195, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 517 "src/html/html_unescape.gperf" +      {"eqslantless", 3, {226, 170, 149}}, +      {(char*)0}, {(char*)0}, +#line 744 "src/html/html_unescape.gperf" +      {"incare", 3, {226, 132, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1993 "src/html/html_unescape.gperf" +      {"vArr", 3, {226, 135, 149}}, +#line 1612 "src/html/html_unescape.gperf" +      {"rppolint", 3, {226, 168, 146}}, +#line 442 "src/html/html_unescape.gperf" +      {"drcrop", 3, {226, 140, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1388 "src/html/html_unescape.gperf" +      {"parallel", 3, {226, 136, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1357 "src/html/html_unescape.gperf" +      {"orarr", 3, {226, 134, 187}}, +#line 1745 "src/html/html_unescape.gperf" +      {"ssmile", 3, {226, 140, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 413 "src/html/html_unescape.gperf" +      {"DoubleLeftTee", 3, {226, 171, 164}}, +#line 527 "src/html/html_unescape.gperf" +      {"erDot", 3, {226, 137, 147}}, +#line 382 "src/html/html_unescape.gperf" +      {"diams", 3, {226, 153, 166}}, +#line 1744 "src/html/html_unescape.gperf" +      {"ssetmn", 3, {226, 136, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1369 "src/html/html_unescape.gperf" +      {"oS", 3, {226, 147, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 770 "src/html/html_unescape.gperf" +      {"iscr", 4, {240, 157, 146, 190}}, +#line 726 "src/html/html_unescape.gperf" +      {"ii", 3, {226, 133, 136}}, +#line 1544 "src/html/html_unescape.gperf" +      {"rect", 3, {226, 150, 173}}, +      {(char*)0}, {(char*)0}, +#line 1250 "src/html/html_unescape.gperf" +      {"nsccue", 3, {226, 139, 161}}, +#line 1661 "src/html/html_unescape.gperf" +      {"sect", 2, {194, 167}}, +      {(char*)0}, +#line 1061 "src/html/html_unescape.gperf" +      {"mlcp", 3, {226, 171, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1366 "src/html/html_unescape.gperf" +      {"oror", 3, {226, 169, 150}}, +      {(char*)0}, +#line 408 "src/html/html_unescape.gperf" +      {"DoubleContourIntegral", 3, {226, 136, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 519 "src/html/html_unescape.gperf" +      {"equals", 1, {61}}, +      {(char*)0}, +#line 680 "src/html/html_unescape.gperf" +      {"Hat", 1, {94}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1746 "src/html/html_unescape.gperf" +      {"sstarf", 3, {226, 139, 134}}, +#line 1070 "src/html/html_unescape.gperf" +      {"mstpos", 3, {226, 136, 190}}, +      {(char*)0}, +#line 383 "src/html/html_unescape.gperf" +      {"die", 2, {194, 168}}, +#line 1045 "src/html/html_unescape.gperf" +      {"measuredangle", 3, {226, 136, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 565 "src/html/html_unescape.gperf" +      {"forall", 3, {226, 136, 128}}, +      {(char*)0}, {(char*)0}, +#line 1190 "src/html/html_unescape.gperf" +      {"notinvb", 3, {226, 139, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1066 "src/html/html_unescape.gperf" +      {"mopf", 4, {240, 157, 149, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1139 "src/html/html_unescape.gperf" +      {"niv", 3, {226, 136, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2005 "src/html/html_unescape.gperf" +      {"vBarv", 3, {226, 171, 169}}, +      {(char*)0}, +#line 1252 "src/html/html_unescape.gperf" +      {"Nscr", 4, {240, 157, 146, 169}}, +      {(char*)0}, +#line 1397 "src/html/html_unescape.gperf" +      {"period", 1, {46}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 103 "src/html/html_unescape.gperf" +      {"becaus", 3, {226, 136, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 113 "src/html/html_unescape.gperf" +      {"between", 3, {226, 137, 172}}, +#line 751 "src/html/html_unescape.gperf" +      {"Int", 3, {226, 136, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 104 "src/html/html_unescape.gperf" +      {"because", 3, {226, 136, 181}}, +#line 1411 "src/html/html_unescape.gperf" +      {"piv", 2, {207, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1552 "src/html/html_unescape.gperf" +      {"rfr", 4, {240, 157, 148, 175}}, +#line 1472 "src/html/html_unescape.gperf" +      {"Qfr", 4, {240, 157, 148, 148}}, +#line 935 "src/html/html_unescape.gperf" +      {"lfr", 4, {240, 157, 148, 169}}, +      {(char*)0}, +#line 1668 "src/html/html_unescape.gperf" +      {"sfr", 4, {240, 157, 148, 176}}, +#line 1149 "src/html/html_unescape.gperf" +      {"nleftrightarrow", 3, {226, 134, 174}}, +#line 1837 "src/html/html_unescape.gperf" +      {"Tfr", 4, {240, 157, 148, 151}}, +#line 2122 "src/html/html_unescape.gperf" +      {"Zfr", 3, {226, 132, 168}}, +#line 477 "src/html/html_unescape.gperf" +      {"efr", 4, {240, 157, 148, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1686 "src/html/html_unescape.gperf" +      {"sim", 3, {226, 136, 188}}, +#line 1922 "src/html/html_unescape.gperf" +      {"ufr", 4, {240, 157, 148, 178}}, +#line 1607 "src/html/html_unescape.gperf" +      {"roplus", 3, {226, 168, 174}}, +#line 1838 "src/html/html_unescape.gperf" +      {"tfr", 4, {240, 157, 148, 177}}, +#line 981 "src/html/html_unescape.gperf" +      {"loplus", 3, {226, 168, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2064 "src/html/html_unescape.gperf" +      {"Xfr", 4, {240, 157, 148, 155}}, +      {(char*)0}, {(char*)0}, +#line 1539 "src/html/html_unescape.gperf" +      {"real", 3, {226, 132, 156}}, +#line 1120 "src/html/html_unescape.gperf" +      {"nfr", 4, {240, 157, 148, 171}}, +      {(char*)0}, +#line 115 "src/html/html_unescape.gperf" +      {"bfr", 4, {240, 157, 148, 159}}, +      {(char*)0}, +#line 1185 "src/html/html_unescape.gperf" +      {"NotHumpEqual", 3, {226, 137, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 789 "src/html/html_unescape.gperf" +      {"Jfr", 4, {240, 157, 148, 141}}, +      {(char*)0}, +#line 444 "src/html/html_unescape.gperf" +      {"dscr", 4, {240, 157, 146, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2051 "src/html/html_unescape.gperf" +      {"Wfr", 4, {240, 157, 148, 154}}, +      {(char*)0}, +#line 130 "src/html/html_unescape.gperf" +      {"blacklozenge", 3, {226, 167, 171}}, +      {(char*)0}, +#line 2126 "src/html/html_unescape.gperf" +      {"zopf", 4, {240, 157, 149, 171}}, +#line 1542 "src/html/html_unescape.gperf" +      {"reals", 3, {226, 132, 157}}, +      {(char*)0}, +#line 1171 "src/html/html_unescape.gperf" +      {"NotCupCap", 3, {226, 137, 173}}, +      {(char*)0}, {(char*)0}, +#line 1695 "src/html/html_unescape.gperf" +      {"simplus", 3, {226, 168, 164}}, +      {(char*)0}, +#line 566 "src/html/html_unescape.gperf" +      {"ForAll", 3, {226, 136, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1402 "src/html/html_unescape.gperf" +      {"pfr", 4, {240, 157, 148, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1343 "src/html/html_unescape.gperf" +      {"omacr", 2, {197, 141}}, +      {(char*)0}, +#line 2027 "src/html/html_unescape.gperf" +      {"Vfr", 4, {240, 157, 148, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 489 "src/html/html_unescape.gperf" +      {"Emacr", 2, {196, 146}}, +#line 1617 "src/html/html_unescape.gperf" +      {"Rscr", 3, {226, 132, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2059 "src/html/html_unescape.gperf" +      {"wscr", 4, {240, 157, 147, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1680 "src/html/html_unescape.gperf" +      {"ShortUpArrow", 3, {226, 134, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1665 "src/html/html_unescape.gperf" +      {"setmn", 3, {226, 136, 150}}, +      {(char*)0}, +#line 2028 "src/html/html_unescape.gperf" +      {"vfr", 4, {240, 157, 148, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 807 "src/html/html_unescape.gperf" +      {"Kfr", 4, {240, 157, 148, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1355 "src/html/html_unescape.gperf" +      {"operp", 3, {226, 166, 185}}, +      {(char*)0}, +#line 1048 "src/html/html_unescape.gperf" +      {"Mfr", 4, {240, 157, 148, 144}}, +#line 1667 "src/html/html_unescape.gperf" +      {"Sfr", 4, {240, 157, 148, 150}}, +      {(char*)0}, {(char*)0}, +#line 1161 "src/html/html_unescape.gperf" +      {"nltrie", 3, {226, 139, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 589 "src/html/html_unescape.gperf" +      {"Fscr", 3, {226, 132, 177}}, +      {(char*)0}, {(char*)0}, +#line 554 "src/html/html_unescape.gperf" +      {"ffr", 4, {240, 157, 148, 163}}, +#line 1921 "src/html/html_unescape.gperf" +      {"Ufr", 4, {240, 157, 148, 152}}, +      {(char*)0}, +#line 1677 "src/html/html_unescape.gperf" +      {"shortmid", 3, {226, 136, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1305 "src/html/html_unescape.gperf" +      {"nvsim", 3, {226, 136, 188}}, +#line 368 "src/html/html_unescape.gperf" +      {"Dfr", 4, {240, 157, 148, 135}}, +#line 921 "src/html/html_unescape.gperf" +      {"lessdot", 3, {226, 139, 150}}, +      {(char*)0}, {(char*)0}, +#line 1459 "src/html/html_unescape.gperf" +      {"profline", 3, {226, 140, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1473 "src/html/html_unescape.gperf" +      {"qfr", 4, {240, 157, 148, 174}}, +#line 346 "src/html/html_unescape.gperf" +      {"dArr", 3, {226, 135, 147}}, +      {(char*)0}, +#line 1248 "src/html/html_unescape.gperf" +      {"nrtrie", 3, {226, 139, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1679 "src/html/html_unescape.gperf" +      {"ShortRightArrow", 3, {226, 134, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1841 "src/html/html_unescape.gperf" +      {"Therefore", 3, {226, 136, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 358 "src/html/html_unescape.gperf" +      {"DD", 3, {226, 133, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1840 "src/html/html_unescape.gperf" +      {"therefore", 3, {226, 136, 180}}, +#line 934 "src/html/html_unescape.gperf" +      {"Lfr", 4, {240, 157, 148, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1825 "src/html/html_unescape.gperf" +      {"target", 3, {226, 140, 150}}, +      {(char*)0}, {(char*)0}, +#line 484 "src/html/html_unescape.gperf" +      {"Element", 3, {226, 136, 136}}, +#line 2097 "src/html/html_unescape.gperf" +      {"Yfr", 4, {240, 157, 148, 156}}, +#line 272 "src/html/html_unescape.gperf" +      {"ClockwiseContourIntegral", 3, {226, 136, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1338 "src/html/html_unescape.gperf" +      {"olcir", 3, {226, 166, 190}}, +      {(char*)0}, +#line 246 "src/html/html_unescape.gperf" +      {"Cfr", 3, {226, 132, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 549 "src/html/html_unescape.gperf" +      {"female", 3, {226, 153, 128}}, +#line 1270 "src/html/html_unescape.gperf" +      {"nsucceq", 3, {226, 170, 176}}, +#line 1313 "src/html/html_unescape.gperf" +      {"oast", 3, {226, 138, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1396 "src/html/html_unescape.gperf" +      {"percnt", 1, {37}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1363 "src/html/html_unescape.gperf" +      {"ordf", 2, {194, 170}}, +      {(char*)0}, +#line 1360 "src/html/html_unescape.gperf" +      {"ord", 3, {226, 169, 157}}, +#line 1558 "src/html/html_unescape.gperf" +      {"Rho", 2, {206, 161}}, +      {(char*)0}, +#line 1068 "src/html/html_unescape.gperf" +      {"mscr", 4, {240, 157, 147, 130}}, +      {(char*)0}, +#line 1304 "src/html/html_unescape.gperf" +      {"nvrtrie", 3, {226, 138, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 959 "src/html/html_unescape.gperf" +      {"lnE", 3, {226, 137, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1134 "src/html/html_unescape.gperf" +      {"nhArr", 3, {226, 135, 142}}, +#line 1358 "src/html/html_unescape.gperf" +      {"Or", 3, {226, 169, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 388 "src/html/html_unescape.gperf" +      {"divide", 2, {195, 183}}, +      {(char*)0}, +#line 722 "src/html/html_unescape.gperf" +      {"ifr", 4, {240, 157, 148, 166}}, +#line 485 "src/html/html_unescape.gperf" +      {"elinters", 3, {226, 143, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 204 "src/html/html_unescape.gperf" +      {"bsol", 1, {92}}, +#line 1299 "src/html/html_unescape.gperf" +      {"nvlArr", 3, {226, 164, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 733 "src/html/html_unescape.gperf" +      {"Imacr", 2, {196, 170}}, +      {(char*)0}, +#line 90 "src/html/html_unescape.gperf" +      {"backsimeq", 3, {226, 139, 141}}, +#line 1899 "src/html/html_unescape.gperf" +      {"twixt", 3, {226, 137, 172}}, +#line 1339 "src/html/html_unescape.gperf" +      {"olcross", 3, {226, 166, 187}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1509 "src/html/html_unescape.gperf" +      {"rarrsim", 3, {226, 165, 180}}, +#line 410 "src/html/html_unescape.gperf" +      {"DoubleDownArrow", 3, {226, 135, 147}}, +#line 841 "src/html/html_unescape.gperf" +      {"larrsim", 3, {226, 165, 179}}, +#line 492 "src/html/html_unescape.gperf" +      {"emptyset", 3, {226, 136, 133}}, +#line 1351 "src/html/html_unescape.gperf" +      {"oopf", 4, {240, 157, 149, 160}}, +      {(char*)0}, +#line 541 "src/html/html_unescape.gperf" +      {"exist", 3, {226, 136, 131}}, +      {(char*)0}, {(char*)0}, +#line 950 "src/html/html_unescape.gperf" +      {"llhard", 3, {226, 165, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 540 "src/html/html_unescape.gperf" +      {"excl", 1, {33}}, +#line 504 "src/html/html_unescape.gperf" +      {"Eopf", 4, {240, 157, 148, 188}}, +#line 1143 "src/html/html_unescape.gperf" +      {"nlArr", 3, {226, 135, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1850 "src/html/html_unescape.gperf" +      {"thinsp", 3, {226, 128, 137}}, +#line 1219 "src/html/html_unescape.gperf" +      {"NotSubsetEqual", 3, {226, 138, 136}}, +#line 1404 "src/html/html_unescape.gperf" +      {"phi", 2, {207, 134}}, +#line 411 "src/html/html_unescape.gperf" +      {"DoubleLeftArrow", 3, {226, 135, 144}}, +      {(char*)0}, +#line 1867 "src/html/html_unescape.gperf" +      {"topcir", 3, {226, 171, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 387 "src/html/html_unescape.gperf" +      {"div", 2, {195, 183}}, +      {(char*)0}, +#line 1119 "src/html/html_unescape.gperf" +      {"Nfr", 4, {240, 157, 148, 145}}, +#line 1145 "src/html/html_unescape.gperf" +      {"nlE", 3, {226, 137, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2129 "src/html/html_unescape.gperf" +      {"zscr", 4, {240, 157, 147, 143}}, +#line 995 "src/html/html_unescape.gperf" +      {"lrhard", 3, {226, 165, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 951 "src/html/html_unescape.gperf" +      {"lltri", 3, {226, 151, 186}}, +      {(char*)0}, {(char*)0}, +#line 1243 "src/html/html_unescape.gperf" +      {"nrArr", 3, {226, 135, 143}}, +#line 1225 "src/html/html_unescape.gperf" +      {"NotSupersetEqual", 3, {226, 138, 137}}, +      {(char*)0}, +#line 1820 "src/html/html_unescape.gperf" +      {"swArr", 3, {226, 135, 153}}, +#line 1848 "src/html/html_unescape.gperf" +      {"ThickSpace", 3, {226, 129, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1932 "src/html/html_unescape.gperf" +      {"ultri", 3, {226, 151, 184}}, +#line 1205 "src/html/html_unescape.gperf" +      {"notnivb", 3, {226, 139, 190}}, +      {(char*)0}, +#line 1450 "src/html/html_unescape.gperf" +      {"prime", 3, {226, 128, 178}}, +      {(char*)0}, {(char*)0}, +#line 1452 "src/html/html_unescape.gperf" +      {"primes", 3, {226, 132, 153}}, +      {(char*)0}, +#line 1335 "src/html/html_unescape.gperf" +      {"ohm", 2, {206, 169}}, +      {(char*)0}, {(char*)0}, +#line 265 "src/html/html_unescape.gperf" +      {"CircleTimes", 3, {226, 138, 151}}, +#line 1160 "src/html/html_unescape.gperf" +      {"nltri", 3, {226, 139, 170}}, +      {(char*)0}, {(char*)0}, +#line 1692 "src/html/html_unescape.gperf" +      {"siml", 3, {226, 170, 157}}, +#line 1308 "src/html/html_unescape.gperf" +      {"nwArr", 3, {226, 135, 150}}, +      {(char*)0}, {(char*)0}, +#line 1990 "src/html/html_unescape.gperf" +      {"varpi", 2, {207, 150}}, +      {(char*)0}, {(char*)0}, +#line 1368 "src/html/html_unescape.gperf" +      {"orv", 3, {226, 169, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1664 "src/html/html_unescape.gperf" +      {"setminus", 3, {226, 136, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 997 "src/html/html_unescape.gperf" +      {"lrtri", 3, {226, 138, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1398 "src/html/html_unescape.gperf" +      {"permil", 3, {226, 128, 176}}, +#line 1054 "src/html/html_unescape.gperf" +      {"mid", 3, {226, 136, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1973 "src/html/html_unescape.gperf" +      {"urtri", 3, {226, 151, 185}}, +      {(char*)0}, {(char*)0}, +#line 369 "src/html/html_unescape.gperf" +      {"dfr", 4, {240, 157, 148, 161}}, +#line 1050 "src/html/html_unescape.gperf" +      {"mho", 3, {226, 132, 167}}, +#line 1448 "src/html/html_unescape.gperf" +      {"prE", 3, {226, 170, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2041 "src/html/html_unescape.gperf" +      {"vsupne", 3, {226, 138, 139}}, +      {(char*)0}, {(char*)0}, +#line 1247 "src/html/html_unescape.gperf" +      {"nrtri", 3, {226, 139, 171}}, +#line 2039 "src/html/html_unescape.gperf" +      {"vsubne", 3, {226, 138, 138}}, +      {(char*)0}, +#line 473 "src/html/html_unescape.gperf" +      {"eDot", 3, {226, 137, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 919 "src/html/html_unescape.gperf" +      {"lesges", 3, {226, 170, 147}}, +      {(char*)0}, {(char*)0}, +#line 87 "src/html/html_unescape.gperf" +      {"backepsilon", 2, {207, 182}}, +      {(char*)0}, +#line 1513 "src/html/html_unescape.gperf" +      {"ratail", 3, {226, 164, 154}}, +      {(char*)0}, +#line 843 "src/html/html_unescape.gperf" +      {"latail", 3, {226, 164, 153}}, +      {(char*)0}, {(char*)0}, +#line 1954 "src/html/html_unescape.gperf" +      {"UpEquilibrium", 3, {226, 165, 174}}, +      {(char*)0}, {(char*)0}, +#line 511 "src/html/html_unescape.gperf" +      {"epsilon", 2, {206, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1964 "src/html/html_unescape.gperf" +      {"upsilon", 2, {207, 133}}, +      {(char*)0}, +#line 1052 "src/html/html_unescape.gperf" +      {"midast", 1, {42}}, +#line 698 "src/html/html_unescape.gperf" +      {"Hopf", 3, {226, 132, 141}}, +#line 2029 "src/html/html_unescape.gperf" +      {"vltri", 3, {226, 138, 178}}, +      {(char*)0}, +#line 1553 "src/html/html_unescape.gperf" +      {"Rfr", 3, {226, 132, 156}}, +      {(char*)0}, {(char*)0}, +#line 2048 "src/html/html_unescape.gperf" +      {"Wedge", 3, {226, 139, 128}}, +#line 2052 "src/html/html_unescape.gperf" +      {"wfr", 4, {240, 157, 148, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 94 "src/html/html_unescape.gperf" +      {"barwed", 3, {226, 140, 133}}, +      {(char*)0}, {(char*)0}, +#line 1031 "src/html/html_unescape.gperf" +      {"malt", 3, {226, 156, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 251 "src/html/html_unescape.gperf" +      {"Chi", 2, {206, 167}}, +#line 494 "src/html/html_unescape.gperf" +      {"emptyv", 3, {226, 136, 133}}, +#line 1203 "src/html/html_unescape.gperf" +      {"notni", 3, {226, 136, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 926 "src/html/html_unescape.gperf" +      {"LessGreater", 3, {226, 137, 182}}, +      {(char*)0}, +#line 378 "src/html/html_unescape.gperf" +      {"diam", 3, {226, 139, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2035 "src/html/html_unescape.gperf" +      {"vrtri", 3, {226, 138, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 263 "src/html/html_unescape.gperf" +      {"CircleMinus", 3, {226, 138, 150}}, +      {(char*)0}, +#line 1342 "src/html/html_unescape.gperf" +      {"Omacr", 2, {197, 140}}, +#line 1659 "src/html/html_unescape.gperf" +      {"seArr", 3, {226, 135, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 553 "src/html/html_unescape.gperf" +      {"Ffr", 4, {240, 157, 148, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1445 "src/html/html_unescape.gperf" +      {"precneqq", 3, {226, 170, 181}}, +      {(char*)0}, +#line 380 "src/html/html_unescape.gperf" +      {"Diamond", 3, {226, 139, 132}}, +#line 1364 "src/html/html_unescape.gperf" +      {"ordm", 2, {194, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1103 "src/html/html_unescape.gperf" +      {"neArr", 3, {226, 135, 151}}, +#line 764 "src/html/html_unescape.gperf" +      {"Iopf", 4, {240, 157, 149, 128}}, +#line 260 "src/html/html_unescape.gperf" +      {"CircleDot", 3, {226, 138, 153}}, +      {(char*)0}, {(char*)0}, +#line 1453 "src/html/html_unescape.gperf" +      {"prnap", 3, {226, 170, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 404 "src/html/html_unescape.gperf" +      {"dotminus", 3, {226, 136, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1254 "src/html/html_unescape.gperf" +      {"nshortmid", 3, {226, 136, 164}}, +      {(char*)0}, +#line 148 "src/html/html_unescape.gperf" +      {"bottom", 3, {226, 138, 165}}, +      {(char*)0}, +#line 1428 "src/html/html_unescape.gperf" +      {"pointint", 3, {226, 168, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1737 "src/html/html_unescape.gperf" +      {"SquareUnion", 3, {226, 138, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 793 "src/html/html_unescape.gperf" +      {"jopf", 4, {240, 157, 149, 155}}, +      {(char*)0}, {(char*)0}, +#line 1963 "src/html/html_unescape.gperf" +      {"Upsilon", 2, {206, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 279 "src/html/html_unescape.gperf" +      {"Colone", 3, {226, 169, 180}}, +      {(char*)0}, +#line 1301 "src/html/html_unescape.gperf" +      {"nvlt", 1, {60}}, +      {(char*)0}, {(char*)0}, +#line 1115 "src/html/html_unescape.gperf" +      {"NestedLessLess", 3, {226, 137, 170}}, +#line 278 "src/html/html_unescape.gperf" +      {"Colon", 3, {226, 136, 183}}, +      {(char*)0}, {(char*)0}, +#line 205 "src/html/html_unescape.gperf" +      {"bsolhsub", 3, {226, 159, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 412 "src/html/html_unescape.gperf" +      {"DoubleLeftRightArrow", 3, {226, 135, 148}}, +#line 1424 "src/html/html_unescape.gperf" +      {"plussim", 3, {226, 168, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 735 "src/html/html_unescape.gperf" +      {"image", 3, {226, 132, 145}}, +#line 481 "src/html/html_unescape.gperf" +      {"egs", 3, {226, 170, 150}}, +      {(char*)0}, {(char*)0}, +#line 1371 "src/html/html_unescape.gperf" +      {"oscr", 3, {226, 132, 180}}, +#line 1822 "src/html/html_unescape.gperf" +      {"swnwar", 3, {226, 164, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2117 "src/html/html_unescape.gperf" +      {"zeetrf", 3, {226, 132, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1032 "src/html/html_unescape.gperf" +      {"maltese", 3, {226, 156, 160}}, +      {(char*)0}, +#line 1049 "src/html/html_unescape.gperf" +      {"mfr", 4, {240, 157, 148, 170}}, +#line 1505 "src/html/html_unescape.gperf" +      {"rarrfs", 3, {226, 164, 158}}, +#line 529 "src/html/html_unescape.gperf" +      {"Escr", 3, {226, 132, 176}}, +#line 837 "src/html/html_unescape.gperf" +      {"larrfs", 3, {226, 164, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1063 "src/html/html_unescape.gperf" +      {"mnplus", 3, {226, 136, 147}}, +#line 1130 "src/html/html_unescape.gperf" +      {"ngt", 3, {226, 137, 175}}, +#line 1131 "src/html/html_unescape.gperf" +      {"ngtr", 3, {226, 137, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 628 "src/html/html_unescape.gperf" +      {"gl", 3, {226, 137, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 381 "src/html/html_unescape.gperf" +      {"diamondsuit", 3, {226, 153, 166}}, +#line 656 "src/html/html_unescape.gperf" +      {"GT", 1, {62}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 929 "src/html/html_unescape.gperf" +      {"lesssim", 3, {226, 137, 178}}, +#line 447 "src/html/html_unescape.gperf" +      {"dsol", 3, {226, 167, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1955 "src/html/html_unescape.gperf" +      {"upharpoonleft", 3, {226, 134, 191}}, +#line 1732 "src/html/html_unescape.gperf" +      {"SquareIntersection", 3, {226, 138, 147}}, +#line 1004 "src/html/html_unescape.gperf" +      {"lsime", 3, {226, 170, 141}}, +      {(char*)0}, +#line 1158 "src/html/html_unescape.gperf" +      {"nLt", 3, {226, 137, 170}}, +      {(char*)0}, +#line 1195 "src/html/html_unescape.gperf" +      {"NotLess", 3, {226, 137, 174}}, +      {(char*)0}, +#line 631 "src/html/html_unescape.gperf" +      {"gnap", 3, {226, 170, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1635 "src/html/html_unescape.gperf" +      {"scap", 3, {226, 170, 184}}, +      {(char*)0}, {(char*)0}, +#line 1037 "src/html/html_unescape.gperf" +      {"mapstoleft", 3, {226, 134, 164}}, +#line 1198 "src/html/html_unescape.gperf" +      {"NotLessLess", 3, {226, 137, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1551 "src/html/html_unescape.gperf" +      {"rfloor", 3, {226, 140, 139}}, +      {(char*)0}, +#line 933 "src/html/html_unescape.gperf" +      {"lfloor", 3, {226, 140, 138}}, +      {(char*)0}, {(char*)0}, +#line 1257 "src/html/html_unescape.gperf" +      {"nsime", 3, {226, 137, 132}}, +      {(char*)0}, +#line 202 "src/html/html_unescape.gperf" +      {"bsime", 3, {226, 139, 141}}, +#line 1196 "src/html/html_unescape.gperf" +      {"NotLessEqual", 3, {226, 137, 176}}, +#line 1200 "src/html/html_unescape.gperf" +      {"NotLessTilde", 3, {226, 137, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1090 "src/html/html_unescape.gperf" +      {"ncap", 3, {226, 169, 131}}, +      {(char*)0}, {(char*)0}, +#line 1197 "src/html/html_unescape.gperf" +      {"NotLessGreater", 3, {226, 137, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1449 "src/html/html_unescape.gperf" +      {"precsim", 3, {226, 137, 190}}, +      {(char*)0}, +#line 977 "src/html/html_unescape.gperf" +      {"looparrowright", 3, {226, 134, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1433 "src/html/html_unescape.gperf" +      {"Pr", 3, {226, 170, 187}}, +#line 1531 "src/html/html_unescape.gperf" +      {"rcub", 1, {125}}, +#line 1038 "src/html/html_unescape.gperf" +      {"mapstoup", 3, {226, 134, 165}}, +#line 861 "src/html/html_unescape.gperf" +      {"lcub", 1, {123}}, +      {(char*)0}, +#line 2121 "src/html/html_unescape.gperf" +      {"zfr", 4, {240, 157, 148, 183}}, +      {(char*)0}, {(char*)0}, +#line 1947 "src/html/html_unescape.gperf" +      {"uparrow", 3, {226, 134, 145}}, +      {(char*)0}, +#line 633 "src/html/html_unescape.gperf" +      {"gne", 3, {226, 170, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1641 "src/html/html_unescape.gperf" +      {"sce", 3, {226, 170, 176}}, +#line 740 "src/html/html_unescape.gperf" +      {"Im", 3, {226, 132, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1527 "src/html/html_unescape.gperf" +      {"rcaron", 2, {197, 153}}, +      {(char*)0}, +#line 857 "src/html/html_unescape.gperf" +      {"lcaron", 2, {196, 190}}, +#line 1350 "src/html/html_unescape.gperf" +      {"Oopf", 4, {240, 157, 149, 134}}, +#line 1637 "src/html/html_unescape.gperf" +      {"scaron", 2, {197, 161}}, +#line 89 "src/html/html_unescape.gperf" +      {"backsim", 3, {226, 136, 189}}, +#line 1829 "src/html/html_unescape.gperf" +      {"Tcaron", 2, {197, 164}}, +#line 2111 "src/html/html_unescape.gperf" +      {"Zcaron", 2, {197, 189}}, +#line 463 "src/html/html_unescape.gperf" +      {"ecaron", 2, {196, 155}}, +      {(char*)0}, +#line 109 "src/html/html_unescape.gperf" +      {"Bernoullis", 3, {226, 132, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1122 "src/html/html_unescape.gperf" +      {"nge", 3, {226, 137, 177}}, +#line 1830 "src/html/html_unescape.gperf" +      {"tcaron", 2, {197, 165}}, +      {(char*)0}, +#line 567 "src/html/html_unescape.gperf" +      {"fork", 3, {226, 139, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 702 "src/html/html_unescape.gperf" +      {"Hscr", 3, {226, 132, 139}}, +      {(char*)0}, +#line 1092 "src/html/html_unescape.gperf" +      {"ncaron", 2, {197, 136}}, +#line 488 "src/html/html_unescape.gperf" +      {"elsdot", 3, {226, 170, 151}}, +      {(char*)0}, +#line 1828 "src/html/html_unescape.gperf" +      {"tbrk", 3, {226, 142, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1887 "src/html/html_unescape.gperf" +      {"triplus", 3, {226, 168, 185}}, +      {(char*)0}, {(char*)0}, +#line 379 "src/html/html_unescape.gperf" +      {"diamond", 3, {226, 139, 132}}, +      {(char*)0}, {(char*)0}, +#line 1097 "src/html/html_unescape.gperf" +      {"ncup", 3, {226, 169, 130}}, +      {(char*)0}, +#line 97 "src/html/html_unescape.gperf" +      {"bbrk", 3, {226, 142, 181}}, +      {(char*)0}, +#line 587 "src/html/html_unescape.gperf" +      {"frown", 3, {226, 140, 162}}, +#line 129 "src/html/html_unescape.gperf" +      {"bkarow", 3, {226, 164, 141}}, +      {(char*)0}, +#line 1714 "src/html/html_unescape.gperf" +      {"spades", 3, {226, 153, 160}}, +      {(char*)0}, +#line 1470 "src/html/html_unescape.gperf" +      {"psi", 2, {207, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 145 "src/html/html_unescape.gperf" +      {"Bopf", 4, {240, 157, 148, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 395 "src/html/html_unescape.gperf" +      {"dollar", 1, {36}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 386 "src/html/html_unescape.gperf" +      {"disin", 3, {226, 139, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1715 "src/html/html_unescape.gperf" +      {"spadesuit", 3, {226, 153, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1226 "src/html/html_unescape.gperf" +      {"NotTilde", 3, {226, 137, 129}}, +#line 407 "src/html/html_unescape.gperf" +      {"doublebarwedge", 3, {226, 140, 134}}, +      {(char*)0}, +#line 595 "src/html/html_unescape.gperf" +      {"gap", 3, {226, 170, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 98 "src/html/html_unescape.gperf" +      {"bbrktbrk", 3, {226, 142, 182}}, +      {(char*)0}, {(char*)0}, +#line 1821 "src/html/html_unescape.gperf" +      {"swarrow", 3, {226, 134, 153}}, +#line 107 "src/html/html_unescape.gperf" +      {"bepsi", 2, {207, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 771 "src/html/html_unescape.gperf" +      {"Iscr", 3, {226, 132, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1228 "src/html/html_unescape.gperf" +      {"NotTildeFullEqual", 3, {226, 137, 135}}, +#line 514 "src/html/html_unescape.gperf" +      {"eqcolon", 3, {226, 137, 149}}, +      {(char*)0}, {(char*)0}, +#line 1864 "src/html/html_unescape.gperf" +      {"tint", 3, {226, 136, 173}}, +      {(char*)0}, {(char*)0}, +#line 757 "src/html/html_unescape.gperf" +      {"intprod", 3, {226, 168, 188}}, +      {(char*)0}, +#line 1272 "src/html/html_unescape.gperf" +      {"nsupE", 3, {226, 171, 134}}, +      {(char*)0}, {(char*)0}, +#line 1309 "src/html/html_unescape.gperf" +      {"nwarrow", 3, {226, 134, 150}}, +#line 1264 "src/html/html_unescape.gperf" +      {"nsubE", 3, {226, 171, 133}}, +      {(char*)0}, {(char*)0}, +#line 1126 "src/html/html_unescape.gperf" +      {"nges", 3, {226, 169, 190}}, +      {(char*)0}, +#line 1949 "src/html/html_unescape.gperf" +      {"Uparrow", 3, {226, 135, 145}}, +#line 605 "src/html/html_unescape.gperf" +      {"ge", 3, {226, 137, 165}}, +#line 1353 "src/html/html_unescape.gperf" +      {"OpenCurlyDoubleQuote", 3, {226, 128, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1699 "src/html/html_unescape.gperf" +      {"smallsetminus", 3, {226, 136, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1636 "src/html/html_unescape.gperf" +      {"Scaron", 2, {197, 160}}, +      {(char*)0}, +#line 1302 "src/html/html_unescape.gperf" +      {"nvltrie", 3, {226, 138, 180}}, +#line 613 "src/html/html_unescape.gperf" +      {"ges", 3, {226, 169, 190}}, +#line 136 "src/html/html_unescape.gperf" +      {"blank", 3, {226, 144, 163}}, +#line 1485 "src/html/html_unescape.gperf" +      {"QUOT", 1, {34}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 140 "src/html/html_unescape.gperf" +      {"block", 3, {226, 150, 136}}, +#line 1874 "src/html/html_unescape.gperf" +      {"trade", 3, {226, 132, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 795 "src/html/html_unescape.gperf" +      {"jscr", 4, {240, 157, 146, 191}}, +#line 2047 "src/html/html_unescape.gperf" +      {"wedge", 3, {226, 136, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 30 "src/html/html_unescape.gperf" +      {"Amacr", 2, {196, 128}}, +      {(char*)0}, +#line 518 "src/html/html_unescape.gperf" +      {"Equal", 3, {226, 169, 181}}, +      {(char*)0}, {(char*)0}, +#line 352 "src/html/html_unescape.gperf" +      {"Dcaron", 2, {196, 142}}, +      {(char*)0}, {(char*)0}, +#line 400 "src/html/html_unescape.gperf" +      {"DotDot", 3, {226, 131, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 635 "src/html/html_unescape.gperf" +      {"gneq", 3, {226, 170, 136}}, +#line 1991 "src/html/html_unescape.gperf" +      {"varpropto", 3, {226, 136, 157}}, +      {(char*)0}, +#line 636 "src/html/html_unescape.gperf" +      {"gneqq", 3, {226, 137, 169}}, +#line 1462 "src/html/html_unescape.gperf" +      {"Proportional", 3, {226, 136, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 775 "src/html/html_unescape.gperf" +      {"isins", 3, {226, 139, 180}}, +      {(char*)0}, +#line 470 "src/html/html_unescape.gperf" +      {"eDDot", 3, {226, 169, 183}}, +#line 772 "src/html/html_unescape.gperf" +      {"isin", 3, {226, 136, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1886 "src/html/html_unescape.gperf" +      {"TripleDot", 3, {226, 131, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 569 "src/html/html_unescape.gperf" +      {"Fouriertrf", 3, {226, 132, 177}}, +#line 1463 "src/html/html_unescape.gperf" +      {"Proportion", 3, {226, 136, 183}}, +      {(char*)0}, {(char*)0}, +#line 1123 "src/html/html_unescape.gperf" +      {"ngeq", 3, {226, 137, 177}}, +#line 856 "src/html/html_unescape.gperf" +      {"Lcaron", 2, {196, 189}}, +      {(char*)0}, +#line 1124 "src/html/html_unescape.gperf" +      {"ngeqq", 3, {226, 137, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 871 "src/html/html_unescape.gperf" +      {"lE", 3, {226, 137, 166}}, +#line 228 "src/html/html_unescape.gperf" +      {"Ccaron", 2, {196, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 200 "src/html/html_unescape.gperf" +      {"bsemi", 3, {226, 129, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1464 "src/html/html_unescape.gperf" +      {"propto", 3, {226, 136, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 915 "src/html/html_unescape.gperf" +      {"lesdot", 3, {226, 169, 191}}, +#line 292 "src/html/html_unescape.gperf" +      {"Conint", 3, {226, 136, 175}}, +      {(char*)0}, +#line 36 "src/html/html_unescape.gperf" +      {"And", 3, {226, 169, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1660 "src/html/html_unescape.gperf" +      {"searrow", 3, {226, 134, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1367 "src/html/html_unescape.gperf" +      {"orslope", 3, {226, 169, 151}}, +#line 677 "src/html/html_unescape.gperf" +      {"harr", 3, {226, 134, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 846 "src/html/html_unescape.gperf" +      {"late", 3, {226, 170, 173}}, +      {(char*)0}, +#line 244 "src/html/html_unescape.gperf" +      {"CenterDot", 2, {194, 183}}, +      {(char*)0}, {(char*)0}, +#line 1329 "src/html/html_unescape.gperf" +      {"ofr", 4, {240, 157, 148, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1104 "src/html/html_unescape.gperf" +      {"nearrow", 3, {226, 134, 151}}, +      {(char*)0}, +#line 1474 "src/html/html_unescape.gperf" +      {"qint", 3, {226, 168, 140}}, +      {(char*)0}, {(char*)0}, +#line 847 "src/html/html_unescape.gperf" +      {"lates", 3, {226, 170, 173}}, +#line 802 "src/html/html_unescape.gperf" +      {"kappav", 2, {207, 176}}, +      {(char*)0}, {(char*)0}, +#line 699 "src/html/html_unescape.gperf" +      {"horbar", 3, {226, 128, 149}}, +#line 476 "src/html/html_unescape.gperf" +      {"Efr", 4, {240, 157, 148, 136}}, +#line 693 "src/html/html_unescape.gperf" +      {"hoarr", 3, {226, 135, 191}}, +#line 1240 "src/html/html_unescape.gperf" +      {"npre", 3, {226, 170, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 748 "src/html/html_unescape.gperf" +      {"inodot", 2, {196, 177}}, +      {(char*)0}, +#line 1916 "src/html/html_unescape.gperf" +      {"udarr", 3, {226, 135, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 609 "src/html/html_unescape.gperf" +      {"geq", 3, {226, 137, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1258 "src/html/html_unescape.gperf" +      {"nsimeq", 3, {226, 137, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 610 "src/html/html_unescape.gperf" +      {"geqq", 3, {226, 137, 167}}, +      {(char*)0}, {(char*)0}, +#line 475 "src/html/html_unescape.gperf" +      {"efDot", 3, {226, 137, 146}}, +      {(char*)0}, {(char*)0}, +#line 1611 "src/html/html_unescape.gperf" +      {"rpargt", 3, {226, 166, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1370 "src/html/html_unescape.gperf" +      {"Oscr", 4, {240, 157, 146, 170}}, +      {(char*)0}, {(char*)0}, +#line 1419 "src/html/html_unescape.gperf" +      {"plusdo", 3, {226, 136, 148}}, +      {(char*)0}, {(char*)0}, +#line 822 "src/html/html_unescape.gperf" +      {"lagran", 3, {226, 132, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1847 "src/html/html_unescape.gperf" +      {"thicksim", 3, {226, 136, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1446 "src/html/html_unescape.gperf" +      {"precnsim", 3, {226, 139, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1091 "src/html/html_unescape.gperf" +      {"Ncaron", 2, {197, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1080 "src/html/html_unescape.gperf" +      {"napE", 3, {226, 169, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 728 "src/html/html_unescape.gperf" +      {"iiint", 3, {226, 136, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 199 "src/html/html_unescape.gperf" +      {"Bscr", 3, {226, 132, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1036 "src/html/html_unescape.gperf" +      {"mapstodown", 3, {226, 134, 167}}, +      {(char*)0}, {(char*)0}, +#line 1994 "src/html/html_unescape.gperf" +      {"varrho", 2, {207, 177}}, +      {(char*)0}, +#line 776 "src/html/html_unescape.gperf" +      {"isinsv", 3, {226, 139, 179}}, +      {(char*)0}, {(char*)0}, +#line 1297 "src/html/html_unescape.gperf" +      {"nvHarr", 3, {226, 164, 132}}, +      {(char*)0}, {(char*)0}, +#line 1192 "src/html/html_unescape.gperf" +      {"NotLeftTriangleBar", 3, {226, 167, 143}}, +      {(char*)0}, +#line 521 "src/html/html_unescape.gperf" +      {"equest", 3, {226, 137, 159}}, +      {(char*)0}, +#line 1194 "src/html/html_unescape.gperf" +      {"NotLeftTriangleEqual", 3, {226, 139, 172}}, +#line 1193 "src/html/html_unescape.gperf" +      {"NotLeftTriangle", 3, {226, 139, 170}}, +      {(char*)0}, {(char*)0}, +#line 61 "src/html/html_unescape.gperf" +      {"Aopf", 4, {240, 157, 148, 184}}, +#line 681 "src/html/html_unescape.gperf" +      {"hbar", 3, {226, 132, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1985 "src/html/html_unescape.gperf" +      {"vangrt", 3, {226, 166, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 689 "src/html/html_unescape.gperf" +      {"Hfr", 3, {226, 132, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1495 "src/html/html_unescape.gperf" +      {"range", 3, {226, 166, 165}}, +#line 1705 "src/html/html_unescape.gperf" +      {"smte", 3, {226, 170, 172}}, +#line 1003 "src/html/html_unescape.gperf" +      {"lsim", 3, {226, 137, 178}}, +      {(char*)0}, +#line 1235 "src/html/html_unescape.gperf" +      {"npolint", 3, {226, 168, 148}}, +      {(char*)0}, +#line 353 "src/html/html_unescape.gperf" +      {"dcaron", 2, {196, 143}}, +      {(char*)0}, +#line 532 "src/html/html_unescape.gperf" +      {"esim", 3, {226, 137, 130}}, +      {(char*)0}, +#line 1940 "src/html/html_unescape.gperf" +      {"Union", 3, {226, 139, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1706 "src/html/html_unescape.gperf" +      {"smtes", 3, {226, 170, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 815 "src/html/html_unescape.gperf" +      {"kopf", 4, {240, 157, 149, 156}}, +#line 639 "src/html/html_unescape.gperf" +      {"gopf", 4, {240, 157, 149, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1256 "src/html/html_unescape.gperf" +      {"nsim", 3, {226, 137, 129}}, +      {(char*)0}, +#line 201 "src/html/html_unescape.gperf" +      {"bsim", 3, {226, 136, 189}}, +      {(char*)0}, +#line 1698 "src/html/html_unescape.gperf" +      {"SmallCircle", 3, {226, 136, 152}}, +      {(char*)0}, +#line 1172 "src/html/html_unescape.gperf" +      {"NotDoubleVerticalBar", 3, {226, 136, 166}}, +#line 1201 "src/html/html_unescape.gperf" +      {"NotNestedGreaterGreater", 3, {226, 170, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 520 "src/html/html_unescape.gperf" +      {"EqualTilde", 3, {226, 137, 130}}, +      {(char*)0}, {(char*)0}, +#line 1187 "src/html/html_unescape.gperf" +      {"notindot", 3, {226, 139, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1526 "src/html/html_unescape.gperf" +      {"Rcaron", 2, {197, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1430 "src/html/html_unescape.gperf" +      {"Popf", 3, {226, 132, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 638 "src/html/html_unescape.gperf" +      {"Gopf", 4, {240, 157, 148, 190}}, +      {(char*)0}, {(char*)0}, +#line 723 "src/html/html_unescape.gperf" +      {"Ifr", 3, {226, 132, 145}}, +      {(char*)0}, {(char*)0}, +#line 2049 "src/html/html_unescape.gperf" +      {"wedgeq", 3, {226, 137, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1456 "src/html/html_unescape.gperf" +      {"prod", 3, {226, 136, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1374 "src/html/html_unescape.gperf" +      {"osol", 3, {226, 138, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 419 "src/html/html_unescape.gperf" +      {"DoubleUpArrow", 3, {226, 135, 145}}, +      {(char*)0}, {(char*)0}, +#line 290 "src/html/html_unescape.gperf" +      {"Congruent", 3, {226, 137, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 637 "src/html/html_unescape.gperf" +      {"gnsim", 3, {226, 139, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1651 "src/html/html_unescape.gperf" +      {"scsim", 3, {226, 137, 191}}, +      {(char*)0}, +#line 790 "src/html/html_unescape.gperf" +      {"jfr", 4, {240, 157, 148, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1962 "src/html/html_unescape.gperf" +      {"upsih", 2, {207, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1156 "src/html/html_unescape.gperf" +      {"nLl", 3, {226, 139, 152}}, +      {(char*)0}, {(char*)0}, +#line 420 "src/html/html_unescape.gperf" +      {"DoubleUpDownArrow", 3, {226, 135, 149}}, +      {(char*)0}, +#line 1128 "src/html/html_unescape.gperf" +      {"ngsim", 3, {226, 137, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 684 "src/html/html_unescape.gperf" +      {"hearts", 3, {226, 153, 165}}, +      {(char*)0}, +#line 922 "src/html/html_unescape.gperf" +      {"lesseqgtr", 3, {226, 139, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1112 "src/html/html_unescape.gperf" +      {"nesear", 3, {226, 164, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 542 "src/html/html_unescape.gperf" +      {"Exists", 3, {226, 136, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1703 "src/html/html_unescape.gperf" +      {"smile", 3, {226, 140, 163}}, +      {(char*)0}, +#line 1984 "src/html/html_unescape.gperf" +      {"uwangle", 3, {226, 166, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 685 "src/html/html_unescape.gperf" +      {"heartsuit", 3, {226, 153, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 700 "src/html/html_unescape.gperf" +      {"HorizontalLine", 3, {226, 148, 128}}, +      {(char*)0}, {(char*)0}, +#line 645 "src/html/html_unescape.gperf" +      {"GreaterLess", 3, {226, 137, 183}}, +      {(char*)0}, +#line 1615 "src/html/html_unescape.gperf" +      {"rsaquo", 3, {226, 128, 186}}, +      {(char*)0}, +#line 998 "src/html/html_unescape.gperf" +      {"lsaquo", 3, {226, 128, 185}}, +      {(char*)0}, +#line 1540 "src/html/html_unescape.gperf" +      {"realine", 3, {226, 132, 155}}, +#line 348 "src/html/html_unescape.gperf" +      {"Dashv", 3, {226, 171, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1687 "src/html/html_unescape.gperf" +      {"simdot", 3, {226, 169, 170}}, +#line 641 "src/html/html_unescape.gperf" +      {"GreaterEqual", 3, {226, 137, 165}}, +#line 647 "src/html/html_unescape.gperf" +      {"GreaterTilde", 3, {226, 137, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 642 "src/html/html_unescape.gperf" +      {"GreaterEqualLess", 3, {226, 139, 155}}, +      {(char*)0}, +#line 644 "src/html/html_unescape.gperf" +      {"GreaterGreater", 3, {226, 170, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1530 "src/html/html_unescape.gperf" +      {"rceil", 3, {226, 140, 137}}, +      {(char*)0}, +#line 860 "src/html/html_unescape.gperf" +      {"lceil", 3, {226, 140, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 927 "src/html/html_unescape.gperf" +      {"lessgtr", 3, {226, 137, 182}}, +      {(char*)0}, {(char*)0}, +#line 1340 "src/html/html_unescape.gperf" +      {"oline", 3, {226, 128, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1852 "src/html/html_unescape.gperf" +      {"thksim", 3, {226, 136, 188}}, +      {(char*)0}, +#line 759 "src/html/html_unescape.gperf" +      {"InvisibleTimes", 3, {226, 129, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1487 "src/html/html_unescape.gperf" +      {"race", 3, {226, 136, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 769 "src/html/html_unescape.gperf" +      {"iquest", 2, {194, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 737 "src/html/html_unescape.gperf" +      {"imagline", 3, {226, 132, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1966 "src/html/html_unescape.gperf" +      {"UpTee", 3, {226, 138, 165}}, +      {(char*)0}, +#line 1053 "src/html/html_unescape.gperf" +      {"midcir", 3, {226, 171, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1327 "src/html/html_unescape.gperf" +      {"ofcir", 3, {226, 166, 191}}, +      {(char*)0}, {(char*)0}, +#line 357 "src/html/html_unescape.gperf" +      {"ddarr", 3, {226, 135, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1494 "src/html/html_unescape.gperf" +      {"rangd", 3, {226, 166, 146}}, +      {(char*)0}, +#line 827 "src/html/html_unescape.gperf" +      {"langd", 3, {226, 166, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 522 "src/html/html_unescape.gperf" +      {"Equilibrium", 3, {226, 135, 140}}, +#line 1390 "src/html/html_unescape.gperf" +      {"parsim", 3, {226, 171, 179}}, +#line 2012 "src/html/html_unescape.gperf" +      {"Vdashl", 3, {226, 171, 166}}, +#line 1328 "src/html/html_unescape.gperf" +      {"Ofr", 4, {240, 157, 148, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 105 "src/html/html_unescape.gperf" +      {"Because", 3, {226, 136, 181}}, +      {(char*)0}, +#line 1514 "src/html/html_unescape.gperf" +      {"rAtail", 3, {226, 164, 156}}, +      {(char*)0}, +#line 844 "src/html/html_unescape.gperf" +      {"lAtail", 3, {226, 164, 155}}, +#line 1349 "src/html/html_unescape.gperf" +      {"ominus", 3, {226, 138, 150}}, +#line 74 "src/html/html_unescape.gperf" +      {"Ascr", 4, {240, 157, 146, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 510 "src/html/html_unescape.gperf" +      {"Epsilon", 2, {206, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1676 "src/html/html_unescape.gperf" +      {"ShortLeftArrow", 3, {226, 134, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 777 "src/html/html_unescape.gperf" +      {"isinv", 3, {226, 136, 136}}, +      {(char*)0}, +#line 1051 "src/html/html_unescape.gperf" +      {"micro", 2, {194, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2112 "src/html/html_unescape.gperf" +      {"zcaron", 2, {197, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 817 "src/html/html_unescape.gperf" +      {"kscr", 4, {240, 157, 147, 128}}, +#line 649 "src/html/html_unescape.gperf" +      {"gscr", 3, {226, 132, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 114 "src/html/html_unescape.gperf" +      {"Bfr", 4, {240, 157, 148, 133}}, +#line 608 "src/html/html_unescape.gperf" +      {"gel", 3, {226, 139, 155}}, +#line 687 "src/html/html_unescape.gperf" +      {"hercon", 3, {226, 138, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1885 "src/html/html_unescape.gperf" +      {"triminus", 3, {226, 168, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 480 "src/html/html_unescape.gperf" +      {"egrave", 2, {195, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1655 "src/html/html_unescape.gperf" +      {"sdot", 3, {226, 139, 133}}, +#line 1924 "src/html/html_unescape.gperf" +      {"ugrave", 2, {195, 185}}, +      {(char*)0}, +#line 2115 "src/html/html_unescape.gperf" +      {"Zdot", 2, {197, 187}}, +#line 472 "src/html/html_unescape.gperf" +      {"edot", 2, {196, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1229 "src/html/html_unescape.gperf" +      {"NotTildeTilde", 3, {226, 137, 137}}, +      {(char*)0}, +#line 1835 "src/html/html_unescape.gperf" +      {"tdot", 3, {226, 131, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1467 "src/html/html_unescape.gperf" +      {"Pscr", 4, {240, 157, 146, 171}}, +#line 1408 "src/html/html_unescape.gperf" +      {"Pi", 2, {206, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 648 "src/html/html_unescape.gperf" +      {"Gscr", 4, {240, 157, 146, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1425 "src/html/html_unescape.gperf" +      {"plustwo", 3, {226, 168, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1173 "src/html/html_unescape.gperf" +      {"NotElement", 3, {226, 136, 137}}, +      {(char*)0}, +#line 1422 "src/html/html_unescape.gperf" +      {"PlusMinus", 2, {194, 177}}, +      {(char*)0}, {(char*)0}, +#line 697 "src/html/html_unescape.gperf" +      {"hopf", 4, {240, 157, 149, 153}}, +#line 594 "src/html/html_unescape.gperf" +      {"gammad", 2, {207, 157}}, +      {(char*)0}, +#line 1044 "src/html/html_unescape.gperf" +      {"mDDot", 3, {226, 136, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 389 "src/html/html_unescape.gperf" +      {"divideontimes", 3, {226, 139, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 401 "src/html/html_unescape.gperf" +      {"doteq", 3, {226, 137, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1986 "src/html/html_unescape.gperf" +      {"varepsilon", 2, {207, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1439 "src/html/html_unescape.gperf" +      {"Precedes", 3, {226, 137, 186}}, +      {(char*)0}, {(char*)0}, +#line 593 "src/html/html_unescape.gperf" +      {"Gammad", 2, {207, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 349 "src/html/html_unescape.gperf" +      {"dashv", 3, {226, 138, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1170 "src/html/html_unescape.gperf" +      {"NotCongruent", 3, {226, 137, 162}}, +      {(char*)0}, {(char*)0}, +#line 1911 "src/html/html_unescape.gperf" +      {"ubreve", 2, {197, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1333 "src/html/html_unescape.gperf" +      {"ogt", 3, {226, 167, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1609 "src/html/html_unescape.gperf" +      {"RoundImplies", 3, {226, 165, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1441 "src/html/html_unescape.gperf" +      {"PrecedesSlantEqual", 3, {226, 137, 188}}, +      {(char*)0}, {(char*)0}, +#line 1688 "src/html/html_unescape.gperf" +      {"sime", 3, {226, 137, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1923 "src/html/html_unescape.gperf" +      {"Ugrave", 2, {195, 153}}, +      {(char*)0}, +#line 350 "src/html/html_unescape.gperf" +      {"dbkarow", 3, {226, 164, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1656 "src/html/html_unescape.gperf" +      {"sdote", 3, {226, 169, 166}}, +      {(char*)0}, +#line 2016 "src/html/html_unescape.gperf" +      {"veeeq", 3, {226, 137, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1035 "src/html/html_unescape.gperf" +      {"mapsto", 3, {226, 134, 166}}, +      {(char*)0}, {(char*)0}, +#line 1862 "src/html/html_unescape.gperf" +      {"times", 2, {195, 151}}, +      {(char*)0}, {(char*)0}, +#line 1496 "src/html/html_unescape.gperf" +      {"rangle", 3, {226, 159, 169}}, +      {(char*)0}, +#line 828 "src/html/html_unescape.gperf" +      {"langle", 3, {226, 159, 168}}, +      {(char*)0}, {(char*)0}, +#line 878 "src/html/html_unescape.gperf" +      {"leftarrowtail", 3, {226, 134, 162}}, +#line 673 "src/html/html_unescape.gperf" +      {"hamilt", 3, {226, 132, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1919 "src/html/html_unescape.gperf" +      {"udhar", 3, {226, 165, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1138 "src/html/html_unescape.gperf" +      {"nisd", 3, {226, 139, 186}}, +      {(char*)0}, +#line 1550 "src/html/html_unescape.gperf" +      {"rfisht", 3, {226, 165, 189}}, +      {(char*)0}, +#line 932 "src/html/html_unescape.gperf" +      {"lfisht", 3, {226, 165, 188}}, +#line 676 "src/html/html_unescape.gperf" +      {"harrcir", 3, {226, 165, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1354 "src/html/html_unescape.gperf" +      {"OpenCurlyQuote", 3, {226, 128, 152}}, +      {(char*)0}, +#line 1920 "src/html/html_unescape.gperf" +      {"ufisht", 3, {226, 165, 190}}, +#line 1184 "src/html/html_unescape.gperf" +      {"NotHumpDownHump", 3, {226, 137, 142}}, +      {(char*)0}, {(char*)0}, +#line 896 "src/html/html_unescape.gperf" +      {"LeftTee", 3, {226, 138, 163}}, +      {(char*)0}, +#line 1618 "src/html/html_unescape.gperf" +      {"rsh", 3, {226, 134, 177}}, +      {(char*)0}, +#line 1001 "src/html/html_unescape.gperf" +      {"lsh", 3, {226, 134, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 668 "src/html/html_unescape.gperf" +      {"gvertneqq", 3, {226, 137, 169}}, +      {(char*)0}, {(char*)0}, +#line 1861 "src/html/html_unescape.gperf" +      {"timesb", 3, {226, 138, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1650 "src/html/html_unescape.gperf" +      {"scpolint", 3, {226, 168, 147}}, +      {(char*)0}, {(char*)0}, +#line 237 "src/html/html_unescape.gperf" +      {"Cdot", 2, {196, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 455 "src/html/html_unescape.gperf" +      {"dwangle", 3, {226, 166, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1910 "src/html/html_unescape.gperf" +      {"Ubreve", 2, {197, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 905 "src/html/html_unescape.gperf" +      {"LeftUpVector", 3, {226, 134, 191}}, +      {(char*)0}, {(char*)0}, +#line 904 "src/html/html_unescape.gperf" +      {"LeftUpVectorBar", 3, {226, 165, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 462 "src/html/html_unescape.gperf" +      {"Ecaron", 2, {196, 154}}, +      {(char*)0}, {(char*)0}, +#line 694 "src/html/html_unescape.gperf" +      {"homtht", 3, {226, 136, 187}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 725 "src/html/html_unescape.gperf" +      {"igrave", 2, {195, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1239 "src/html/html_unescape.gperf" +      {"npreceq", 3, {226, 170, 175}}, +#line 467 "src/html/html_unescape.gperf" +      {"ecolon", 3, {226, 137, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 359 "src/html/html_unescape.gperf" +      {"dd", 3, {226, 133, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1689 "src/html/html_unescape.gperf" +      {"simeq", 3, {226, 137, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1188 "src/html/html_unescape.gperf" +      {"notinE", 3, {226, 139, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 120 "src/html/html_unescape.gperf" +      {"bigoplus", 3, {226, 168, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 22 "src/html/html_unescape.gperf" +      {"Afr", 4, {240, 157, 148, 132}}, +#line 874 "src/html/html_unescape.gperf" +      {"leftarrow", 3, {226, 134, 144}}, +#line 1336 "src/html/html_unescape.gperf" +      {"oint", 3, {226, 136, 174}}, +      {(char*)0}, +#line 1824 "src/html/html_unescape.gperf" +      {"Tab", 1, {9}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1330 "src/html/html_unescape.gperf" +      {"ogon", 2, {203, 155}}, +      {(char*)0}, {(char*)0}, +#line 1013 "src/html/html_unescape.gperf" +      {"lt", 1, {60}}, +#line 1150 "src/html/html_unescape.gperf" +      {"nLeftrightarrow", 3, {226, 135, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1499 "src/html/html_unescape.gperf" +      {"rarrb", 3, {226, 135, 165}}, +      {(char*)0}, +#line 832 "src/html/html_unescape.gperf" +      {"larrb", 3, {226, 135, 164}}, +      {(char*)0}, +#line 701 "src/html/html_unescape.gperf" +      {"hscr", 4, {240, 157, 146, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 902 "src/html/html_unescape.gperf" +      {"LeftUpDownVector", 3, {226, 165, 145}}, +      {(char*)0}, +#line 808 "src/html/html_unescape.gperf" +      {"kfr", 4, {240, 157, 148, 168}}, +#line 620 "src/html/html_unescape.gperf" +      {"gfr", 4, {240, 157, 148, 164}}, +#line 1946 "src/html/html_unescape.gperf" +      {"UpArrowBar", 3, {226, 164, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1251 "src/html/html_unescape.gperf" +      {"nsce", 3, {226, 170, 176}}, +#line 1016 "src/html/html_unescape.gperf" +      {"ltdot", 3, {226, 139, 150}}, +#line 617 "src/html/html_unescape.gperf" +      {"gesl", 3, {226, 139, 155}}, +#line 2074 "src/html/html_unescape.gperf" +      {"xodot", 3, {226, 168, 128}}, +#line 1748 "src/html/html_unescape.gperf" +      {"star", 3, {226, 152, 134}}, +      {(char*)0}, {(char*)0}, +#line 984 "src/html/html_unescape.gperf" +      {"lowbar", 1, {95}}, +      {(char*)0}, +#line 2066 "src/html/html_unescape.gperf" +      {"xharr", 3, {226, 159, 183}}, +#line 466 "src/html/html_unescape.gperf" +      {"ecir", 3, {226, 137, 150}}, +      {(char*)0}, +#line 1976 "src/html/html_unescape.gperf" +      {"utdot", 3, {226, 139, 176}}, +#line 1086 "src/html/html_unescape.gperf" +      {"natur", 3, {226, 153, 174}}, +#line 1002 "src/html/html_unescape.gperf" +      {"Lsh", 3, {226, 134, 176}}, +#line 746 "src/html/html_unescape.gperf" +      {"infin", 3, {226, 136, 158}}, +      {(char*)0}, +#line 284 "src/html/html_unescape.gperf" +      {"comp", 3, {226, 136, 129}}, +      {(char*)0}, +#line 1685 "src/html/html_unescape.gperf" +      {"sigmav", 2, {207, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2078 "src/html/html_unescape.gperf" +      {"xotime", 3, {226, 168, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1401 "src/html/html_unescape.gperf" +      {"Pfr", 4, {240, 157, 148, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 619 "src/html/html_unescape.gperf" +      {"Gfr", 4, {240, 157, 148, 138}}, +      {(char*)0}, {(char*)0}, +#line 116 "src/html/html_unescape.gperf" +      {"bigcap", 3, {226, 139, 130}}, +      {(char*)0}, +#line 1693 "src/html/html_unescape.gperf" +      {"simlE", 3, {226, 170, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 727 "src/html/html_unescape.gperf" +      {"iiiint", 3, {226, 168, 140}}, +#line 96 "src/html/html_unescape.gperf" +      {"barwedge", 3, {226, 140, 133}}, +#line 95 "src/html/html_unescape.gperf" +      {"Barwed", 3, {226, 140, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2070 "src/html/html_unescape.gperf" +      {"xlarr", 3, {226, 159, 181}}, +#line 924 "src/html/html_unescape.gperf" +      {"LessEqualGreater", 3, {226, 139, 154}}, +      {(char*)0}, +#line 302 "src/html/html_unescape.gperf" +      {"crarr", 3, {226, 134, 181}}, +#line 773 "src/html/html_unescape.gperf" +      {"isindot", 3, {226, 139, 181}}, +      {(char*)0}, +#line 283 "src/html/html_unescape.gperf" +      {"commat", 1, {64}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1055 "src/html/html_unescape.gperf" +      {"middot", 2, {194, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 917 "src/html/html_unescape.gperf" +      {"lesdotor", 3, {226, 170, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1684 "src/html/html_unescape.gperf" +      {"sigmaf", 2, {207, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1500 "src/html/html_unescape.gperf" +      {"rarrbfs", 3, {226, 164, 160}}, +      {(char*)0}, +#line 833 "src/html/html_unescape.gperf" +      {"larrbfs", 3, {226, 164, 159}}, +      {(char*)0}, {(char*)0}, +#line 2079 "src/html/html_unescape.gperf" +      {"xrarr", 3, {226, 159, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 118 "src/html/html_unescape.gperf" +      {"bigcup", 3, {226, 139, 131}}, +      {(char*)0}, +#line 275 "src/html/html_unescape.gperf" +      {"clubs", 3, {226, 153, 163}}, +#line 678 "src/html/html_unescape.gperf" +      {"hArr", 3, {226, 135, 148}}, +#line 1626 "src/html/html_unescape.gperf" +      {"rtrie", 3, {226, 138, 181}}, +      {(char*)0}, +#line 1022 "src/html/html_unescape.gperf" +      {"ltrie", 3, {226, 138, 180}}, +#line 742 "src/html/html_unescape.gperf" +      {"imped", 2, {198, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 503 "src/html/html_unescape.gperf" +      {"eogon", 2, {196, 153}}, +#line 1631 "src/html/html_unescape.gperf" +      {"rx", 3, {226, 132, 158}}, +#line 1024 "src/html/html_unescape.gperf" +      {"ltrPar", 3, {226, 166, 150}}, +#line 1747 "src/html/html_unescape.gperf" +      {"Star", 3, {226, 139, 134}}, +      {(char*)0}, +#line 1943 "src/html/html_unescape.gperf" +      {"uogon", 2, {197, 179}}, +      {(char*)0}, {(char*)0}, +#line 1856 "src/html/html_unescape.gperf" +      {"Tilde", 3, {226, 136, 188}}, +      {(char*)0}, +#line 672 "src/html/html_unescape.gperf" +      {"half", 2, {194, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1855 "src/html/html_unescape.gperf" +      {"tilde", 2, {203, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 876 "src/html/html_unescape.gperf" +      {"Leftarrow", 3, {226, 135, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 618 "src/html/html_unescape.gperf" +      {"gesles", 3, {226, 170, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 218 "src/html/html_unescape.gperf" +      {"cap", 3, {226, 136, 169}}, +#line 1752 "src/html/html_unescape.gperf" +      {"strns", 2, {194, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1015 "src/html/html_unescape.gperf" +      {"Lt", 3, {226, 137, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1454 "src/html/html_unescape.gperf" +      {"prnE", 3, {226, 170, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1727 "src/html/html_unescape.gperf" +      {"sqsupe", 3, {226, 138, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1728 "src/html/html_unescape.gperf" +      {"sqsupset", 3, {226, 138, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1883 "src/html/html_unescape.gperf" +      {"tridot", 3, {226, 151, 172}}, +#line 1361 "src/html/html_unescape.gperf" +      {"order", 3, {226, 132, 180}}, +      {(char*)0}, {(char*)0}, +#line 223 "src/html/html_unescape.gperf" +      {"caps", 3, {226, 136, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 303 "src/html/html_unescape.gperf" +      {"cross", 3, {226, 156, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 367 "src/html/html_unescape.gperf" +      {"dfisht", 3, {226, 165, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2072 "src/html/html_unescape.gperf" +      {"xmap", 3, {226, 159, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1726 "src/html/html_unescape.gperf" +      {"sqsup", 3, {226, 138, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1625 "src/html/html_unescape.gperf" +      {"rtri", 3, {226, 150, 185}}, +      {(char*)0}, +#line 1021 "src/html/html_unescape.gperf" +      {"ltri", 3, {226, 151, 131}}, +#line 778 "src/html/html_unescape.gperf" +      {"it", 3, {226, 129, 162}}, +#line 1599 "src/html/html_unescape.gperf" +      {"rmoust", 3, {226, 142, 177}}, +      {(char*)0}, +#line 955 "src/html/html_unescape.gperf" +      {"lmoust", 3, {226, 142, 176}}, +#line 634 "src/html/html_unescape.gperf" +      {"gnE", 3, {226, 137, 169}}, +#line 937 "src/html/html_unescape.gperf" +      {"lgE", 3, {226, 170, 145}}, +      {(char*)0}, {(char*)0}, +#line 1642 "src/html/html_unescape.gperf" +      {"scE", 3, {226, 170, 180}}, +      {(char*)0}, +#line 1979 "src/html/html_unescape.gperf" +      {"utri", 3, {226, 150, 181}}, +      {(char*)0}, +#line 2017 "src/html/html_unescape.gperf" +      {"vellip", 3, {226, 139, 174}}, +      {(char*)0}, +#line 535 "src/html/html_unescape.gperf" +      {"ETH", 2, {195, 144}}, +      {(char*)0}, {(char*)0}, +#line 953 "src/html/html_unescape.gperf" +      {"lmidot", 2, {197, 128}}, +      {(char*)0}, +#line 1942 "src/html/html_unescape.gperf" +      {"Uogon", 2, {197, 178}}, +#line 301 "src/html/html_unescape.gperf" +      {"CounterClockwiseContourIntegral", 3, {226, 136, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1121 "src/html/html_unescape.gperf" +      {"ngE", 3, {226, 137, 167}}, +#line 1310 "src/html/html_unescape.gperf" +      {"nwnear", 3, {226, 164, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 918 "src/html/html_unescape.gperf" +      {"lesg", 3, {226, 139, 154}}, +      {(char*)0}, {(char*)0}, +#line 1416 "src/html/html_unescape.gperf" +      {"plusb", 3, {226, 138, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1619 "src/html/html_unescape.gperf" +      {"Rsh", 3, {226, 134, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 300 "src/html/html_unescape.gperf" +      {"copysr", 3, {226, 132, 151}}, +      {(char*)0}, +#line 747 "src/html/html_unescape.gperf" +      {"infintie", 3, {226, 167, 157}}, +      {(char*)0}, +#line 739 "src/html/html_unescape.gperf" +      {"imath", 2, {196, 177}}, +#line 531 "src/html/html_unescape.gperf" +      {"Esim", 3, {226, 169, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1403 "src/html/html_unescape.gperf" +      {"Phi", 2, {206, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 629 "src/html/html_unescape.gperf" +      {"glE", 3, {226, 170, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2031 "src/html/html_unescape.gperf" +      {"vnsup", 3, {226, 138, 131}}, +      {(char*)0}, {(char*)0}, +#line 1691 "src/html/html_unescape.gperf" +      {"simgE", 3, {226, 170, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 414 "src/html/html_unescape.gperf" +      {"DoubleLongLeftArrow", 3, {226, 159, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 415 "src/html/html_unescape.gperf" +      {"DoubleLongLeftRightArrow", 3, {226, 159, 186}}, +      {(char*)0}, {(char*)0}, +#line 1296 "src/html/html_unescape.gperf" +      {"nvgt", 1, {62}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1047 "src/html/html_unescape.gperf" +      {"Mellintrf", 3, {226, 132, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1451 "src/html/html_unescape.gperf" +      {"Prime", 3, {226, 128, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 729 "src/html/html_unescape.gperf" +      {"iinfin", 3, {226, 167, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1547 "src/html/html_unescape.gperf" +      {"ReverseElement", 3, {226, 136, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 493 "src/html/html_unescape.gperf" +      {"EmptySmallSquare", 3, {226, 151, 187}}, +#line 1490 "src/html/html_unescape.gperf" +      {"radic", 3, {226, 136, 154}}, +      {(char*)0}, {(char*)0}, +#line 688 "src/html/html_unescape.gperf" +      {"hfr", 4, {240, 157, 148, 165}}, +#line 2116 "src/html/html_unescape.gperf" +      {"zdot", 2, {197, 188}}, +#line 1030 "src/html/html_unescape.gperf" +      {"male", 3, {226, 153, 130}}, +      {(char*)0}, +#line 1501 "src/html/html_unescape.gperf" +      {"rarrc", 3, {226, 164, 179}}, +#line 1437 "src/html/html_unescape.gperf" +      {"prec", 3, {226, 137, 186}}, +#line 1647 "src/html/html_unescape.gperf" +      {"scnap", 3, {226, 170, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 384 "src/html/html_unescape.gperf" +      {"DifferentialD", 3, {226, 133, 134}}, +      {(char*)0}, +#line 1064 "src/html/html_unescape.gperf" +      {"models", 3, {226, 138, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1012 "src/html/html_unescape.gperf" +      {"ltcir", 3, {226, 169, 185}}, +#line 763 "src/html/html_unescape.gperf" +      {"iogon", 2, {196, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 217 "src/html/html_unescape.gperf" +      {"capcap", 3, {226, 169, 139}}, +      {(char*)0}, +#line 721 "src/html/html_unescape.gperf" +      {"iff", 3, {226, 135, 148}}, +      {(char*)0}, +#line 361 "src/html/html_unescape.gperf" +      {"ddotseq", 3, {226, 169, 183}}, +      {(char*)0}, +#line 264 "src/html/html_unescape.gperf" +      {"CirclePlus", 3, {226, 138, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1623 "src/html/html_unescape.gperf" +      {"rthree", 3, {226, 139, 140}}, +      {(char*)0}, +#line 1017 "src/html/html_unescape.gperf" +      {"lthree", 3, {226, 139, 139}}, +      {(char*)0}, {(char*)0}, +#line 1442 "src/html/html_unescape.gperf" +      {"PrecedesTilde", 3, {226, 137, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 450 "src/html/html_unescape.gperf" +      {"dtdot", 3, {226, 139, 177}}, +      {(char*)0}, +#line 276 "src/html/html_unescape.gperf" +      {"clubsuit", 3, {226, 153, 163}}, +      {(char*)0}, +#line 1489 "src/html/html_unescape.gperf" +      {"racute", 2, {197, 149}}, +      {(char*)0}, +#line 820 "src/html/html_unescape.gperf" +      {"lacute", 2, {196, 186}}, +#line 1890 "src/html/html_unescape.gperf" +      {"trpezium", 3, {226, 143, 162}}, +#line 1633 "src/html/html_unescape.gperf" +      {"sacute", 2, {197, 155}}, +      {(char*)0}, {(char*)0}, +#line 2109 "src/html/html_unescape.gperf" +      {"Zacute", 2, {197, 185}}, +#line 460 "src/html/html_unescape.gperf" +      {"eacute", 2, {195, 169}}, +      {(char*)0}, +#line 1859 "src/html/html_unescape.gperf" +      {"TildeTilde", 3, {226, 137, 136}}, +      {(char*)0}, +#line 1907 "src/html/html_unescape.gperf" +      {"Uarrocir", 3, {226, 165, 137}}, +#line 1903 "src/html/html_unescape.gperf" +      {"uacute", 2, {195, 186}}, +#line 983 "src/html/html_unescape.gperf" +      {"lowast", 3, {226, 136, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1077 "src/html/html_unescape.gperf" +      {"nacute", 2, {197, 132}}, +      {(char*)0}, +#line 1207 "src/html/html_unescape.gperf" +      {"NotPrecedes", 3, {226, 138, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 952 "src/html/html_unescape.gperf" +      {"Lmidot", 2, {196, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1948 "src/html/html_unescape.gperf" +      {"UpArrow", 3, {226, 134, 145}}, +      {(char*)0}, +#line 1512 "src/html/html_unescape.gperf" +      {"rarrw", 3, {226, 134, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 439 "src/html/html_unescape.gperf" +      {"DownTee", 3, {226, 138, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 556 "src/html/html_unescape.gperf" +      {"FilledSmallSquare", 3, {226, 151, 188}}, +#line 220 "src/html/html_unescape.gperf" +      {"capcup", 3, {226, 169, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 643 "src/html/html_unescape.gperf" +      {"GreaterFullEqual", 3, {226, 137, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1300 "src/html/html_unescape.gperf" +      {"nvle", 3, {226, 137, 164}}, +      {(char*)0}, +#line 1884 "src/html/html_unescape.gperf" +      {"trie", 3, {226, 137, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1347 "src/html/html_unescape.gperf" +      {"omicron", 2, {206, 191}}, +      {(char*)0}, +#line 418 "src/html/html_unescape.gperf" +      {"DoubleRightTee", 3, {226, 138, 168}}, +#line 234 "src/html/html_unescape.gperf" +      {"Cconint", 3, {226, 136, 176}}, +#line 1622 "src/html/html_unescape.gperf" +      {"rsquor", 3, {226, 128, 153}}, +      {(char*)0}, +#line 1008 "src/html/html_unescape.gperf" +      {"lsquor", 3, {226, 128, 154}}, +      {(char*)0}, +#line 2125 "src/html/html_unescape.gperf" +      {"zigrarr", 3, {226, 135, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 294 "src/html/html_unescape.gperf" +      {"copf", 4, {240, 157, 149, 148}}, +      {(char*)0}, +#line 293 "src/html/html_unescape.gperf" +      {"ContourIntegral", 3, {226, 136, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 671 "src/html/html_unescape.gperf" +      {"hairsp", 3, {226, 128, 138}}, +#line 1729 "src/html/html_unescape.gperf" +      {"sqsupseteq", 3, {226, 138, 146}}, +#line 307 "src/html/html_unescape.gperf" +      {"csub", 3, {226, 171, 143}}, +#line 1956 "src/html/html_unescape.gperf" +      {"upharpoonright", 3, {226, 134, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 427 "src/html/html_unescape.gperf" +      {"DownBreve", 2, {204, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1675 "src/html/html_unescape.gperf" +      {"ShortDownArrow", 3, {226, 134, 147}}, +      {(char*)0}, +#line 2076 "src/html/html_unescape.gperf" +      {"xopf", 4, {240, 157, 149, 169}}, +      {(char*)0}, +#line 1632 "src/html/html_unescape.gperf" +      {"Sacute", 2, {197, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2040 "src/html/html_unescape.gperf" +      {"vsupnE", 3, {226, 171, 140}}, +#line 266 "src/html/html_unescape.gperf" +      {"cir", 3, {226, 151, 139}}, +#line 1415 "src/html/html_unescape.gperf" +      {"plusacir", 3, {226, 168, 163}}, +#line 309 "src/html/html_unescape.gperf" +      {"csup", 3, {226, 171, 144}}, +#line 2038 "src/html/html_unescape.gperf" +      {"vsubnE", 3, {226, 171, 139}}, +#line 1902 "src/html/html_unescape.gperf" +      {"Uacute", 2, {195, 154}}, +      {(char*)0}, +#line 774 "src/html/html_unescape.gperf" +      {"isinE", 3, {226, 139, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 607 "src/html/html_unescape.gperf" +      {"gEl", 3, {226, 170, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1720 "src/html/html_unescape.gperf" +      {"sqcups", 3, {226, 138, 148}}, +      {(char*)0}, +#line 1702 "src/html/html_unescape.gperf" +      {"smid", 3, {226, 136, 163}}, +      {(char*)0}, +#line 936 "src/html/html_unescape.gperf" +      {"lg", 3, {226, 137, 182}}, +      {(char*)0}, +#line 416 "src/html/html_unescape.gperf" +      {"DoubleLongRightArrow", 3, {226, 159, 185}}, +#line 1209 "src/html/html_unescape.gperf" +      {"NotPrecedesSlantEqual", 3, {226, 139, 160}}, +      {(char*)0}, {(char*)0}, +#line 478 "src/html/html_unescape.gperf" +      {"eg", 3, {226, 170, 154}}, +      {(char*)0}, {(char*)0}, +#line 34 "src/html/html_unescape.gperf" +      {"AMP", 1, {38}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1163 "src/html/html_unescape.gperf" +      {"nmid", 3, {226, 136, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1863 "src/html/html_unescape.gperf" +      {"timesd", 3, {226, 168, 176}}, +      {(char*)0}, {(char*)0}, +#line 434 "src/html/html_unescape.gperf" +      {"DownLeftVector", 3, {226, 134, 189}}, +#line 2131 "src/html/html_unescape.gperf" +      {"zwnj", 3, {226, 128, 140}}, +#line 819 "src/html/html_unescape.gperf" +      {"Lacute", 2, {196, 185}}, +#line 433 "src/html/html_unescape.gperf" +      {"DownLeftVectorBar", 3, {226, 165, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1332 "src/html/html_unescape.gperf" +      {"ograve", 2, {195, 178}}, +#line 2088 "src/html/html_unescape.gperf" +      {"Yacute", 2, {195, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1719 "src/html/html_unescape.gperf" +      {"sqcup", 3, {226, 138, 148}}, +      {(char*)0}, {(char*)0}, +#line 1323 "src/html/html_unescape.gperf" +      {"odot", 3, {226, 138, 153}}, +#line 213 "src/html/html_unescape.gperf" +      {"Cacute", 2, {196, 134}}, +      {(char*)0}, +#line 1286 "src/html/html_unescape.gperf" +      {"nu", 2, {206, 189}}, +#line 1889 "src/html/html_unescape.gperf" +      {"tritime", 3, {226, 168, 187}}, +      {(char*)0}, +#line 479 "src/html/html_unescape.gperf" +      {"Egrave", 2, {195, 136}}, +#line 508 "src/html/html_unescape.gperf" +      {"eplus", 3, {226, 169, 177}}, +      {(char*)0}, +#line 86 "src/html/html_unescape.gperf" +      {"backcong", 3, {226, 137, 140}}, +      {(char*)0}, {(char*)0}, +#line 1957 "src/html/html_unescape.gperf" +      {"uplus", 3, {226, 138, 142}}, +      {(char*)0}, +#line 471 "src/html/html_unescape.gperf" +      {"Edot", 2, {196, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 310 "src/html/html_unescape.gperf" +      {"csupe", 3, {226, 171, 146}}, +      {(char*)0}, +#line 1690 "src/html/html_unescape.gperf" +      {"simg", 3, {226, 170, 158}}, +#line 1959 "src/html/html_unescape.gperf" +      {"UpperRightArrow", 3, {226, 134, 151}}, +#line 308 "src/html/html_unescape.gperf" +      {"csube", 3, {226, 171, 145}}, +      {(char*)0}, +#line 451 "src/html/html_unescape.gperf" +      {"dtri", 3, {226, 150, 191}}, +#line 1455 "src/html/html_unescape.gperf" +      {"prnsim", 3, {226, 139, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 178 "src/html/html_unescape.gperf" +      {"boxUr", 3, {226, 149, 153}}, +#line 1981 "src/html/html_unescape.gperf" +      {"uuarr", 3, {226, 135, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 432 "src/html/html_unescape.gperf" +      {"DownLeftTeeVector", 3, {226, 165, 158}}, +#line 651 "src/html/html_unescape.gperf" +      {"gsime", 3, {226, 170, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 121 "src/html/html_unescape.gperf" +      {"bigotimes", 3, {226, 168, 130}}, +#line 342 "src/html/html_unescape.gperf" +      {"Dagger", 3, {226, 128, 161}}, +      {(char*)0}, {(char*)0}, +#line 755 "src/html/html_unescape.gperf" +      {"Intersection", 3, {226, 139, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 711 "src/html/html_unescape.gperf" +      {"iacute", 2, {195, 173}}, +      {(char*)0}, +#line 1435 "src/html/html_unescape.gperf" +      {"prcue", 3, {226, 137, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 482 "src/html/html_unescape.gperf" +      {"egsdot", 3, {226, 170, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 743 "src/html/html_unescape.gperf" +      {"Implies", 3, {226, 135, 146}}, +#line 2011 "src/html/html_unescape.gperf" +      {"VDash", 3, {226, 138, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 208 "src/html/html_unescape.gperf" +      {"bump", 3, {226, 137, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1071 "src/html/html_unescape.gperf" +      {"Mu", 2, {206, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2009 "src/html/html_unescape.gperf" +      {"vDash", 3, {226, 138, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1028 "src/html/html_unescape.gperf" +      {"lvnE", 3, {226, 137, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 895 "src/html/html_unescape.gperf" +      {"LeftTeeArrow", 3, {226, 134, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1076 "src/html/html_unescape.gperf" +      {"Nacute", 2, {197, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1937 "src/html/html_unescape.gperf" +      {"UnderBrace", 3, {226, 143, 159}}, +#line 1469 "src/html/html_unescape.gperf" +      {"Psi", 2, {206, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1560 "src/html/html_unescape.gperf" +      {"rhov", 2, {207, 177}}, +      {(char*)0}, +#line 913 "src/html/html_unescape.gperf" +      {"lescc", 3, {226, 170, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1790 "src/html/html_unescape.gperf" +      {"sup1", 2, {194, 185}}, +      {(char*)0}, {(char*)0}, +#line 1791 "src/html/html_unescape.gperf" +      {"sup2", 2, {194, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1792 "src/html/html_unescape.gperf" +      {"sup3", 2, {194, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 119 "src/html/html_unescape.gperf" +      {"bigodot", 3, {226, 168, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 425 "src/html/html_unescape.gperf" +      {"Downarrow", 3, {226, 135, 147}}, +      {(char*)0}, +#line 2083 "src/html/html_unescape.gperf" +      {"xsqcup", 3, {226, 168, 134}}, +      {(char*)0}, +#line 93 "src/html/html_unescape.gperf" +      {"barvee", 3, {226, 138, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1107 "src/html/html_unescape.gperf" +      {"NegativeMediumSpace", 3, {226, 128, 139}}, +#line 210 "src/html/html_unescape.gperf" +      {"bumpe", 3, {226, 137, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 306 "src/html/html_unescape.gperf" +      {"cscr", 4, {240, 157, 146, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1249 "src/html/html_unescape.gperf" +      {"nsc", 3, {226, 138, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1793 "src/html/html_unescape.gperf" +      {"sup", 3, {226, 138, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 239 "src/html/html_unescape.gperf" +      {"cedil", 2, {194, 184}}, +      {(char*)0}, {(char*)0}, +#line 192 "src/html/html_unescape.gperf" +      {"boxVr", 3, {226, 149, 159}}, +      {(char*)0}, +#line 1365 "src/html/html_unescape.gperf" +      {"origof", 3, {226, 138, 182}}, +#line 2130 "src/html/html_unescape.gperf" +      {"zwj", 3, {226, 128, 141}}, +#line 724 "src/html/html_unescape.gperf" +      {"Igrave", 2, {195, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 717 "src/html/html_unescape.gperf" +      {"Idot", 2, {196, 176}}, +      {(char*)0}, +#line 2082 "src/html/html_unescape.gperf" +      {"xscr", 4, {240, 157, 147, 141}}, +#line 2069 "src/html/html_unescape.gperf" +      {"xi", 2, {206, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1132 "src/html/html_unescape.gperf" +      {"nGtv", 3, {226, 137, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 166 "src/html/html_unescape.gperf" +      {"boxHu", 3, {226, 149, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1853 "src/html/html_unescape.gperf" +      {"THORN", 2, {195, 158}}, +      {(char*)0}, +#line 1488 "src/html/html_unescape.gperf" +      {"Racute", 2, {197, 148}}, +      {(char*)0}, +#line 1506 "src/html/html_unescape.gperf" +      {"rarrhk", 3, {226, 134, 170}}, +      {(char*)0}, +#line 838 "src/html/html_unescape.gperf" +      {"larrhk", 3, {226, 134, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1628 "src/html/html_unescape.gperf" +      {"rtriltri", 3, {226, 167, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 181 "src/html/html_unescape.gperf" +      {"boxV", 3, {226, 149, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 341 "src/html/html_unescape.gperf" +      {"dagger", 3, {226, 128, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1346 "src/html/html_unescape.gperf" +      {"Omicron", 2, {206, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 421 "src/html/html_unescape.gperf" +      {"DoubleVerticalBar", 3, {226, 136, 165}}, +      {(char*)0}, {(char*)0}, +#line 1118 "src/html/html_unescape.gperf" +      {"nexists", 3, {226, 136, 132}}, +      {(char*)0}, {(char*)0}, +#line 1285 "src/html/html_unescape.gperf" +      {"Nu", 2, {206, 157}}, +#line 1117 "src/html/html_unescape.gperf" +      {"nexist", 3, {226, 136, 132}}, +#line 606 "src/html/html_unescape.gperf" +      {"gE", 3, {226, 137, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 64 "src/html/html_unescape.gperf" +      {"ap", 3, {226, 137, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1794 "src/html/html_unescape.gperf" +      {"Sup", 3, {226, 139, 145}}, +#line 402 "src/html/html_unescape.gperf" +      {"doteqdot", 3, {226, 137, 145}}, +      {(char*)0}, {(char*)0}, +#line 500 "src/html/html_unescape.gperf" +      {"eng", 2, {197, 139}}, +      {(char*)0}, +#line 225 "src/html/html_unescape.gperf" +      {"caron", 2, {203, 135}}, +      {(char*)0}, +#line 168 "src/html/html_unescape.gperf" +      {"boxHU", 3, {226, 149, 169}}, +#line 614 "src/html/html_unescape.gperf" +      {"gesdot", 3, {226, 170, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1548 "src/html/html_unescape.gperf" +      {"ReverseEquilibrium", 3, {226, 135, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 175 "src/html/html_unescape.gperf" +      {"boxUL", 3, {226, 149, 157}}, +      {(char*)0}, +#line 1805 "src/html/html_unescape.gperf" +      {"supmult", 3, {226, 171, 130}}, +      {(char*)0}, {(char*)0}, +#line 1410 "src/html/html_unescape.gperf" +      {"pitchfork", 3, {226, 139, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1289 "src/html/html_unescape.gperf" +      {"numsp", 3, {226, 128, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1492 "src/html/html_unescape.gperf" +      {"rang", 3, {226, 159, 169}}, +      {(char*)0}, +#line 825 "src/html/html_unescape.gperf" +      {"lang", 3, {226, 159, 168}}, +      {(char*)0}, {(char*)0}, +#line 1316 "src/html/html_unescape.gperf" +      {"ocir", 3, {226, 138, 154}}, +      {(char*)0}, +#line 1516 "src/html/html_unescape.gperf" +      {"rationals", 3, {226, 132, 154}}, +      {(char*)0}, +#line 296 "src/html/html_unescape.gperf" +      {"coprod", 3, {226, 136, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1019 "src/html/html_unescape.gperf" +      {"ltlarr", 3, {226, 165, 182}}, +#line 195 "src/html/html_unescape.gperf" +      {"breve", 2, {203, 152}}, +      {(char*)0}, +#line 1078 "src/html/html_unescape.gperf" +      {"nang", 3, {226, 136, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1818 "src/html/html_unescape.gperf" +      {"swarhk", 3, {226, 164, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1497 "src/html/html_unescape.gperf" +      {"raquo", 2, {194, 187}}, +      {(char*)0}, +#line 831 "src/html/html_unescape.gperf" +      {"laquo", 2, {194, 171}}, +#line 1816 "src/html/html_unescape.gperf" +      {"supsub", 3, {226, 171, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 322 "src/html/html_unescape.gperf" +      {"Cup", 3, {226, 139, 147}}, +#line 66 "src/html/html_unescape.gperf" +      {"ape", 3, {226, 137, 138}}, +#line 1482 "src/html/html_unescape.gperf" +      {"quest", 1, {63}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1306 "src/html/html_unescape.gperf" +      {"nwarhk", 3, {226, 164, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1809 "src/html/html_unescape.gperf" +      {"supset", 3, {226, 138, 131}}, +      {(char*)0}, +#line 423 "src/html/html_unescape.gperf" +      {"downarrow", 3, {226, 134, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 453 "src/html/html_unescape.gperf" +      {"duarr", 3, {226, 135, 181}}, +      {(char*)0}, +#line 68 "src/html/html_unescape.gperf" +      {"apos", 1, {39}}, +#line 1331 "src/html/html_unescape.gperf" +      {"Ograve", 2, {195, 146}}, +#line 1678 "src/html/html_unescape.gperf" +      {"shortparallel", 3, {226, 136, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1269 "src/html/html_unescape.gperf" +      {"nsucc", 3, {226, 138, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 967 "src/html/html_unescape.gperf" +      {"LongLeftArrow", 3, {226, 159, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 916 "src/html/html_unescape.gperf" +      {"lesdoto", 3, {226, 170, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1807 "src/html/html_unescape.gperf" +      {"supne", 3, {226, 138, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1127 "src/html/html_unescape.gperf" +      {"nGg", 3, {226, 139, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1491 "src/html/html_unescape.gperf" +      {"raemptyv", 3, {226, 166, 179}}, +#line 1817 "src/html/html_unescape.gperf" +      {"supsup", 3, {226, 171, 150}}, +#line 821 "src/html/html_unescape.gperf" +      {"laemptyv", 3, {226, 166, 180}}, +      {(char*)0}, {(char*)0}, +#line 1871 "src/html/html_unescape.gperf" +      {"topfork", 3, {226, 171, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 502 "src/html/html_unescape.gperf" +      {"Eogon", 2, {196, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1594 "src/html/html_unescape.gperf" +      {"risingdotseq", 3, {226, 137, 147}}, +      {(char*)0}, +#line 212 "src/html/html_unescape.gperf" +      {"bumpeq", 3, {226, 137, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1010 "src/html/html_unescape.gperf" +      {"lstrok", 2, {197, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1897 "src/html/html_unescape.gperf" +      {"Tstrok", 2, {197, 166}}, +#line 650 "src/html/html_unescape.gperf" +      {"gsim", 3, {226, 137, 179}}, +      {(char*)0}, {(char*)0}, +#line 106 "src/html/html_unescape.gperf" +      {"bemptyv", 3, {226, 166, 176}}, +#line 2110 "src/html/html_unescape.gperf" +      {"zacute", 2, {197, 186}}, +#line 652 "src/html/html_unescape.gperf" +      {"gsiml", 3, {226, 170, 144}}, +      {(char*)0}, {(char*)0}, +#line 1898 "src/html/html_unescape.gperf" +      {"tstrok", 2, {197, 167}}, +      {(char*)0}, +#line 1601 "src/html/html_unescape.gperf" +      {"roang", 3, {226, 159, 173}}, +#line 189 "src/html/html_unescape.gperf" +      {"boxVL", 3, {226, 149, 163}}, +#line 963 "src/html/html_unescape.gperf" +      {"loang", 3, {226, 159, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1153 "src/html/html_unescape.gperf" +      {"nleqslant", 3, {226, 169, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1634 "src/html/html_unescape.gperf" +      {"sbquo", 3, {226, 128, 154}}, +      {(char*)0}, +#line 1657 "src/html/html_unescape.gperf" +      {"searhk", 3, {226, 164, 165}}, +#line 957 "src/html/html_unescape.gperf" +      {"lnapprox", 3, {226, 170, 137}}, +      {(char*)0}, {(char*)0}, +#line 1810 "src/html/html_unescape.gperf" +      {"Supset", 3, {226, 139, 145}}, +      {(char*)0}, +#line 162 "src/html/html_unescape.gperf" +      {"boxHd", 3, {226, 149, 164}}, +#line 1987 "src/html/html_unescape.gperf" +      {"varkappa", 2, {207, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 254 "src/html/html_unescape.gperf" +      {"circeq", 3, {226, 137, 151}}, +      {(char*)0}, +#line 2102 "src/html/html_unescape.gperf" +      {"yopf", 4, {240, 157, 149, 170}}, +      {(char*)0}, +#line 1941 "src/html/html_unescape.gperf" +      {"UnionPlus", 3, {226, 138, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 826 "src/html/html_unescape.gperf" +      {"Lang", 3, {226, 159, 170}}, +#line 1101 "src/html/html_unescape.gperf" +      {"nearhk", 3, {226, 164, 164}}, +#line 1674 "src/html/html_unescape.gperf" +      {"shcy", 2, {209, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 245 "src/html/html_unescape.gperf" +      {"cfr", 4, {240, 157, 148, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 800 "src/html/html_unescape.gperf" +      {"Kappa", 2, {206, 154}}, +#line 944 "src/html/html_unescape.gperf" +      {"ljcy", 2, {209, 153}}, +#line 1046 "src/html/html_unescape.gperf" +      {"MediumSpace", 3, {226, 129, 159}}, +      {(char*)0}, {(char*)0}, +#line 1811 "src/html/html_unescape.gperf" +      {"supseteq", 3, {226, 138, 135}}, +#line 1812 "src/html/html_unescape.gperf" +      {"supseteqq", 3, {226, 171, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1545 "src/html/html_unescape.gperf" +      {"reg", 2, {194, 174}}, +#line 31 "src/html/html_unescape.gperf" +      {"amacr", 2, {196, 129}}, +#line 909 "src/html/html_unescape.gperf" +      {"leg", 3, {226, 139, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2050 "src/html/html_unescape.gperf" +      {"weierp", 3, {226, 132, 152}}, +#line 1893 "src/html/html_unescape.gperf" +      {"TScy", 2, {208, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1813 "src/html/html_unescape.gperf" +      {"supsetneq", 3, {226, 138, 139}}, +#line 1141 "src/html/html_unescape.gperf" +      {"njcy", 2, {209, 154}}, +#line 2065 "src/html/html_unescape.gperf" +      {"xfr", 4, {240, 157, 148, 181}}, +      {(char*)0}, +#line 1072 "src/html/html_unescape.gperf" +      {"mu", 2, {206, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1298 "src/html/html_unescape.gperf" +      {"nvinfin", 3, {226, 167, 158}}, +#line 179 "src/html/html_unescape.gperf" +      {"boxUR", 3, {226, 149, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2077 "src/html/html_unescape.gperf" +      {"xoplus", 3, {226, 168, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 887 "src/html/html_unescape.gperf" +      {"leftleftarrows", 3, {226, 135, 135}}, +#line 1787 "src/html/html_unescape.gperf" +      {"sum", 3, {226, 136, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 112 "src/html/html_unescape.gperf" +      {"beth", 3, {226, 132, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 286 "src/html/html_unescape.gperf" +      {"complement", 3, {226, 136, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1287 "src/html/html_unescape.gperf" +      {"num", 1, {35}}, +#line 33 "src/html/html_unescape.gperf" +      {"amp", 1, {38}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 174 "src/html/html_unescape.gperf" +      {"boxUl", 3, {226, 149, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1177 "src/html/html_unescape.gperf" +      {"NotGreater", 3, {226, 137, 175}}, +#line 170 "src/html/html_unescape.gperf" +      {"boxplus", 3, {226, 138, 158}}, +#line 791 "src/html/html_unescape.gperf" +      {"jmath", 2, {200, 183}}, +      {(char*)0}, +#line 1669 "src/html/html_unescape.gperf" +      {"sfrown", 3, {226, 140, 162}}, +      {(char*)0}, +#line 448 "src/html/html_unescape.gperf" +      {"Dstrok", 2, {196, 144}}, +      {(char*)0}, +#line 37 "src/html/html_unescape.gperf" +      {"and", 3, {226, 136, 167}}, +#line 1180 "src/html/html_unescape.gperf" +      {"NotGreaterGreater", 3, {226, 137, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1182 "src/html/html_unescape.gperf" +      {"NotGreaterSlantEqual", 3, {226, 169, 190}}, +      {(char*)0}, +#line 1181 "src/html/html_unescape.gperf" +      {"NotGreaterLess", 3, {226, 137, 185}}, +#line 1484 "src/html/html_unescape.gperf" +      {"quot", 1, {34}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1179 "src/html/html_unescape.gperf" +      {"NotGreaterFullEqual", 3, {226, 137, 167}}, +#line 709 "src/html/html_unescape.gperf" +      {"hyphen", 3, {226, 128, 144}}, +#line 1412 "src/html/html_unescape.gperf" +      {"planck", 3, {226, 132, 143}}, +      {(char*)0}, +#line 1857 "src/html/html_unescape.gperf" +      {"TildeEqual", 3, {226, 137, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1872 "src/html/html_unescape.gperf" +      {"tosa", 3, {226, 164, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1009 "src/html/html_unescape.gperf" +      {"Lstrok", 2, {197, 129}}, +      {(char*)0}, {(char*)0}, +#line 1681 "src/html/html_unescape.gperf" +      {"shy", 2, {194, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2073 "src/html/html_unescape.gperf" +      {"xnis", 3, {226, 139, 187}}, +#line 762 "src/html/html_unescape.gperf" +      {"Iogon", 2, {196, 174}}, +      {(char*)0}, {(char*)0}, +#line 456 "src/html/html_unescape.gperf" +      {"DZcy", 2, {208, 143}}, +      {(char*)0}, +#line 1334 "src/html/html_unescape.gperf" +      {"ohbar", 3, {226, 166, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 271 "src/html/html_unescape.gperf" +      {"cirscir", 3, {226, 167, 130}}, +      {(char*)0}, +#line 1666 "src/html/html_unescape.gperf" +      {"sext", 3, {226, 156, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1387 "src/html/html_unescape.gperf" +      {"para", 2, {194, 182}}, +      {(char*)0}, {(char*)0}, +#line 77 "src/html/html_unescape.gperf" +      {"ast", 1, {42}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1483 "src/html/html_unescape.gperf" +      {"questeq", 3, {226, 137, 159}}, +      {(char*)0}, +#line 1788 "src/html/html_unescape.gperf" +      {"Sum", 3, {226, 136, 145}}, +      {(char*)0}, +#line 445 "src/html/html_unescape.gperf" +      {"DScy", 2, {208, 133}}, +      {(char*)0}, +#line 499 "src/html/html_unescape.gperf" +      {"ENG", 2, {197, 138}}, +      {(char*)0}, +#line 2123 "src/html/html_unescape.gperf" +      {"ZHcy", 2, {208, 150}}, +      {(char*)0}, {(char*)0}, +#line 966 "src/html/html_unescape.gperf" +      {"longleftarrow", 3, {226, 159, 181}}, +      {(char*)0}, +#line 347 "src/html/html_unescape.gperf" +      {"dash", 3, {226, 128, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 438 "src/html/html_unescape.gperf" +      {"DownTeeArrow", 3, {226, 134, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1814 "src/html/html_unescape.gperf" +      {"supsetneqq", 3, {226, 171, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1458 "src/html/html_unescape.gperf" +      {"profalar", 3, {226, 140, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1312 "src/html/html_unescape.gperf" +      {"oacute", 2, {195, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 193 "src/html/html_unescape.gperf" +      {"boxVR", 3, {226, 149, 160}}, +      {(char*)0}, {(char*)0}, +#line 459 "src/html/html_unescape.gperf" +      {"Eacute", 2, {195, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1808 "src/html/html_unescape.gperf" +      {"supplus", 3, {226, 171, 128}}, +      {(char*)0}, +#line 695 "src/html/html_unescape.gperf" +      {"hookleftarrow", 3, {226, 134, 169}}, +      {(char*)0}, {(char*)0}, +#line 274 "src/html/html_unescape.gperf" +      {"CloseCurlyQuote", 3, {226, 128, 153}}, +      {(char*)0}, {(char*)0}, +#line 1888 "src/html/html_unescape.gperf" +      {"trisb", 3, {226, 167, 141}}, +#line 406 "src/html/html_unescape.gperf" +      {"dotsquare", 3, {226, 138, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1624 "src/html/html_unescape.gperf" +      {"rtimes", 3, {226, 139, 138}}, +      {(char*)0}, +#line 1018 "src/html/html_unescape.gperf" +      {"ltimes", 3, {226, 139, 137}}, +      {(char*)0}, {(char*)0}, +#line 1865 "src/html/html_unescape.gperf" +      {"toea", 3, {226, 164, 168}}, +#line 24 "src/html/html_unescape.gperf" +      {"Agrave", 2, {195, 128}}, +      {(char*)0}, {(char*)0}, +#line 76 "src/html/html_unescape.gperf" +      {"Assign", 3, {226, 137, 148}}, +#line 1493 "src/html/html_unescape.gperf" +      {"Rang", 3, {226, 159, 171}}, +#line 761 "src/html/html_unescape.gperf" +      {"iocy", 2, {209, 145}}, +      {(char*)0}, +#line 1208 "src/html/html_unescape.gperf" +      {"NotPrecedesEqual", 3, {226, 170, 175}}, +      {(char*)0}, +#line 62 "src/html/html_unescape.gperf" +      {"aopf", 4, {240, 157, 149, 146}}, +      {(char*)0}, +#line 252 "src/html/html_unescape.gperf" +      {"chi", 2, {207, 135}}, +      {(char*)0}, {(char*)0}, +#line 1480 "src/html/html_unescape.gperf" +      {"quaternions", 3, {226, 132, 141}}, +#line 188 "src/html/html_unescape.gperf" +      {"boxVl", 3, {226, 149, 162}}, +#line 1178 "src/html/html_unescape.gperf" +      {"NotGreaterEqual", 3, {226, 137, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2067 "src/html/html_unescape.gperf" +      {"xhArr", 3, {226, 159, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1362 "src/html/html_unescape.gperf" +      {"orderof", 3, {226, 132, 180}}, +      {(char*)0}, {(char*)0}, +#line 1621 "src/html/html_unescape.gperf" +      {"rsquo", 3, {226, 128, 153}}, +      {(char*)0}, +#line 1007 "src/html/html_unescape.gperf" +      {"lsquo", 3, {226, 128, 152}}, +#line 2104 "src/html/html_unescape.gperf" +      {"yscr", 4, {240, 157, 147, 142}}, +      {(char*)0}, {(char*)0}, +#line 604 "src/html/html_unescape.gperf" +      {"gdot", 2, {196, 161}}, +      {(char*)0}, +#line 1215 "src/html/html_unescape.gperf" +      {"NotSquareSubsetEqual", 3, {226, 139, 162}}, +#line 810 "src/html/html_unescape.gperf" +      {"KHcy", 2, {208, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 203 "src/html/html_unescape.gperf" +      {"bsolb", 3, {226, 167, 133}}, +#line 1214 "src/html/html_unescape.gperf" +      {"NotSquareSubset", 3, {226, 138, 143}}, +#line 1673 "src/html/html_unescape.gperf" +      {"SHcy", 2, {208, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2099 "src/html/html_unescape.gperf" +      {"YIcy", 2, {208, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 339 "src/html/html_unescape.gperf" +      {"cwint", 3, {226, 136, 177}}, +      {(char*)0}, {(char*)0}, +#line 1842 "src/html/html_unescape.gperf" +      {"Theta", 2, {206, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1843 "src/html/html_unescape.gperf" +      {"theta", 2, {206, 184}}, +#line 2071 "src/html/html_unescape.gperf" +      {"xlArr", 3, {226, 159, 184}}, +      {(char*)0}, +#line 1217 "src/html/html_unescape.gperf" +      {"NotSquareSupersetEqual", 3, {226, 139, 163}}, +      {(char*)0}, {(char*)0}, +#line 366 "src/html/html_unescape.gperf" +      {"demptyv", 3, {226, 166, 177}}, +#line 1876 "src/html/html_unescape.gperf" +      {"triangle", 3, {226, 150, 181}}, +      {(char*)0}, +#line 603 "src/html/html_unescape.gperf" +      {"Gdot", 2, {196, 160}}, +      {(char*)0}, +#line 1216 "src/html/html_unescape.gperf" +      {"NotSquareSuperset", 3, {226, 138, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 9 "src/html/html_unescape.gperf" +      {"Abreve", 2, {196, 130}}, +      {(char*)0}, {(char*)0}, +#line 449 "src/html/html_unescape.gperf" +      {"dstrok", 2, {196, 145}}, +#line 1400 "src/html/html_unescape.gperf" +      {"pertenk", 3, {226, 128, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1522 "src/html/html_unescape.gperf" +      {"rbrack", 1, {93}}, +      {(char*)0}, +#line 852 "src/html/html_unescape.gperf" +      {"lbrack", 1, {91}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1324 "src/html/html_unescape.gperf" +      {"odsold", 3, {226, 166, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1348 "src/html/html_unescape.gperf" +      {"omid", 3, {226, 166, 182}}, +      {(char*)0}, +#line 2080 "src/html/html_unescape.gperf" +      {"xrArr", 3, {226, 159, 185}}, +      {(char*)0}, +#line 1878 "src/html/html_unescape.gperf" +      {"triangleleft", 3, {226, 151, 131}}, +#line 1183 "src/html/html_unescape.gperf" +      {"NotGreaterTilde", 3, {226, 137, 181}}, +#line 280 "src/html/html_unescape.gperf" +      {"colone", 3, {226, 137, 148}}, +      {(char*)0}, +#line 968 "src/html/html_unescape.gperf" +      {"Longleftarrow", 3, {226, 159, 184}}, +      {(char*)0}, +#line 767 "src/html/html_unescape.gperf" +      {"iota", 2, {206, 185}}, +      {(char*)0}, +#line 277 "src/html/html_unescape.gperf" +      {"colon", 1, {58}}, +#line 2119 "src/html/html_unescape.gperf" +      {"Zeta", 2, {206, 150}}, +#line 597 "src/html/html_unescape.gperf" +      {"gbreve", 2, {196, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 247 "src/html/html_unescape.gperf" +      {"CHcy", 2, {208, 167}}, +      {(char*)0}, {(char*)0}, +#line 2105 "src/html/html_unescape.gperf" +      {"YUcy", 2, {208, 174}}, +#line 1546 "src/html/html_unescape.gperf" +      {"REG", 2, {194, 174}}, +#line 1823 "src/html/html_unescape.gperf" +      {"szlig", 2, {195, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 457 "src/html/html_unescape.gperf" +      {"dzcy", 2, {209, 159}}, +      {(char*)0}, +#line 111 "src/html/html_unescape.gperf" +      {"beta", 2, {206, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 539 "src/html/html_unescape.gperf" +      {"euro", 3, {226, 130, 172}}, +      {(char*)0}, {(char*)0}, +#line 875 "src/html/html_unescape.gperf" +      {"LeftArrow", 3, {226, 134, 144}}, +      {(char*)0}, {(char*)0}, +#line 222 "src/html/html_unescape.gperf" +      {"CapitalDifferentialD", 3, {226, 133, 133}}, +      {(char*)0}, +#line 1593 "src/html/html_unescape.gperf" +      {"ring", 2, {203, 154}}, +#line 830 "src/html/html_unescape.gperf" +      {"Laplacetrf", 3, {226, 132, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 392 "src/html/html_unescape.gperf" +      {"djcy", 2, {209, 146}}, +      {(char*)0}, +#line 1356 "src/html/html_unescape.gperf" +      {"oplus", 3, {226, 138, 149}}, +      {(char*)0}, {(char*)0}, +#line 752 "src/html/html_unescape.gperf" +      {"integers", 3, {226, 132, 164}}, +#line 596 "src/html/html_unescape.gperf" +      {"Gbreve", 2, {196, 158}}, +      {(char*)0}, +#line 1909 "src/html/html_unescape.gperf" +      {"ubrcy", 2, {209, 158}}, +#line 538 "src/html/html_unescape.gperf" +      {"euml", 2, {195, 171}}, +      {(char*)0}, {(char*)0}, +#line 362 "src/html/html_unescape.gperf" +      {"deg", 2, {194, 176}}, +      {(char*)0}, +#line 1983 "src/html/html_unescape.gperf" +      {"uuml", 2, {195, 188}}, +      {(char*)0}, {(char*)0}, +#line 710 "src/html/html_unescape.gperf" +      {"Iacute", 2, {195, 141}}, +#line 1781 "src/html/html_unescape.gperf" +      {"succeq", 3, {226, 170, 176}}, +      {(char*)0}, +#line 812 "src/html/html_unescape.gperf" +      {"KJcy", 2, {208, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 320 "src/html/html_unescape.gperf" +      {"CupCap", 3, {226, 137, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1894 "src/html/html_unescape.gperf" +      {"tscy", 2, {209, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 242 "src/html/html_unescape.gperf" +      {"cent", 2, {194, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 391 "src/html/html_unescape.gperf" +      {"DJcy", 2, {208, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1858 "src/html/html_unescape.gperf" +      {"TildeFullEqual", 3, {226, 137, 133}}, +      {(char*)0}, +#line 1880 "src/html/html_unescape.gperf" +      {"triangleq", 3, {226, 137, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 454 "src/html/html_unescape.gperf" +      {"duhar", 3, {226, 165, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 880 "src/html/html_unescape.gperf" +      {"LeftDoubleBracket", 3, {226, 159, 166}}, +      {(char*)0}, +#line 943 "src/html/html_unescape.gperf" +      {"LJcy", 2, {208, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 719 "src/html/html_unescape.gperf" +      {"iecy", 2, {208, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1879 "src/html/html_unescape.gperf" +      {"trianglelefteq", 3, {226, 138, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1111 "src/html/html_unescape.gperf" +      {"nequiv", 3, {226, 137, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1255 "src/html/html_unescape.gperf" +      {"nshortparallel", 3, {226, 136, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1100 "src/html/html_unescape.gperf" +      {"ndash", 3, {226, 128, 147}}, +#line 149 "src/html/html_unescape.gperf" +      {"bowtie", 3, {226, 139, 136}}, +      {(char*)0}, +#line 558 "src/html/html_unescape.gperf" +      {"fjlig", 1, {102}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1908 "src/html/html_unescape.gperf" +      {"Ubrcy", 2, {208, 142}}, +      {(char*)0}, +#line 2000 "src/html/html_unescape.gperf" +      {"vartheta", 2, {207, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1982 "src/html/html_unescape.gperf" +      {"Uuml", 2, {195, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2002 "src/html/html_unescape.gperf" +      {"vartriangleright", 3, {226, 138, 179}}, +#line 2001 "src/html/html_unescape.gperf" +      {"vartriangleleft", 3, {226, 138, 178}}, +#line 75 "src/html/html_unescape.gperf" +      {"ascr", 4, {240, 157, 146, 182}}, +      {(char*)0}, {(char*)0}, +#line 1776 "src/html/html_unescape.gperf" +      {"succcurlyeq", 3, {226, 137, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 338 "src/html/html_unescape.gperf" +      {"cwconint", 3, {226, 136, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1639 "src/html/html_unescape.gperf" +      {"sc", 3, {226, 137, 187}}, +      {(char*)0}, +#line 560 "src/html/html_unescape.gperf" +      {"fllig", 3, {239, 172, 130}}, +      {(char*)0}, +#line 257 "src/html/html_unescape.gperf" +      {"circledast", 3, {226, 138, 155}}, +      {(char*)0}, {(char*)0}, +#line 2010 "src/html/html_unescape.gperf" +      {"Vdash", 3, {226, 138, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1293 "src/html/html_unescape.gperf" +      {"nVdash", 3, {226, 138, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1804 "src/html/html_unescape.gperf" +      {"suplarr", 3, {226, 165, 187}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1603 "src/html/html_unescape.gperf" +      {"robrk", 3, {226, 159, 167}}, +      {(char*)0}, +#line 965 "src/html/html_unescape.gperf" +      {"lobrk", 3, {226, 159, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2008 "src/html/html_unescape.gperf" +      {"vdash", 3, {226, 138, 162}}, +#line 2108 "src/html/html_unescape.gperf" +      {"Yuml", 2, {197, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 655 "src/html/html_unescape.gperf" +      {"gt", 1, {62}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 227 "src/html/html_unescape.gperf" +      {"ccaps", 3, {226, 169, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1777 "src/html/html_unescape.gperf" +      {"Succeeds", 3, {226, 137, 187}}, +#line 1311 "src/html/html_unescape.gperf" +      {"Oacute", 2, {195, 147}}, +#line 1875 "src/html/html_unescape.gperf" +      {"TRADE", 3, {226, 132, 162}}, +#line 1140 "src/html/html_unescape.gperf" +      {"NJcy", 2, {208, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 658 "src/html/html_unescape.gperf" +      {"gtdot", 3, {226, 139, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2098 "src/html/html_unescape.gperf" +      {"yfr", 4, {240, 157, 148, 182}}, +      {(char*)0}, {(char*)0}, +#line 285 "src/html/html_unescape.gperf" +      {"compfn", 3, {226, 136, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 657 "src/html/html_unescape.gperf" +      {"Gt", 3, {226, 137, 171}}, +#line 1648 "src/html/html_unescape.gperf" +      {"scnE", 3, {226, 170, 182}}, +#line 732 "src/html/html_unescape.gperf" +      {"ijlig", 2, {196, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 262 "src/html/html_unescape.gperf" +      {"circledS", 3, {226, 147, 136}}, +      {(char*)0}, {(char*)0}, +#line 2096 "src/html/html_unescape.gperf" +      {"yen", 2, {194, 165}}, +      {(char*)0}, +#line 1844 "src/html/html_unescape.gperf" +      {"thetasym", 2, {207, 145}}, +      {(char*)0}, {(char*)0}, +#line 784 "src/html/html_unescape.gperf" +      {"iuml", 2, {195, 175}}, +#line 1779 "src/html/html_unescape.gperf" +      {"SucceedsSlantEqual", 3, {226, 137, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 160 "src/html/html_unescape.gperf" +      {"boxH", 3, {226, 149, 144}}, +#line 1074 "src/html/html_unescape.gperf" +      {"mumap", 3, {226, 138, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1578 "src/html/html_unescape.gperf" +      {"rightrightarrows", 3, {226, 135, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 281 "src/html/html_unescape.gperf" +      {"coloneq", 3, {226, 137, 148}}, +      {(char*)0}, +#line 1638 "src/html/html_unescape.gperf" +      {"Sc", 3, {226, 170, 188}}, +#line 630 "src/html/html_unescape.gperf" +      {"glj", 3, {226, 170, 164}}, +#line 720 "src/html/html_unescape.gperf" +      {"iexcl", 2, {194, 161}}, +      {(char*)0}, {(char*)0}, +#line 235 "src/html/html_unescape.gperf" +      {"ccups", 3, {226, 169, 140}}, +      {(char*)0}, +#line 2060 "src/html/html_unescape.gperf" +      {"xcap", 3, {226, 139, 130}}, +#line 2124 "src/html/html_unescape.gperf" +      {"zhcy", 2, {208, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 164 "src/html/html_unescape.gperf" +      {"boxHD", 3, {226, 149, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 912 "src/html/html_unescape.gperf" +      {"leqslant", 3, {226, 169, 189}}, +      {(char*)0}, +#line 1958 "src/html/html_unescape.gperf" +      {"UpperLeftArrow", 3, {226, 134, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 351 "src/html/html_unescape.gperf" +      {"dblac", 2, {203, 157}}, +      {(char*)0}, {(char*)0}, +#line 1471 "src/html/html_unescape.gperf" +      {"puncsp", 3, {226, 128, 136}}, +      {(char*)0}, +#line 229 "src/html/html_unescape.gperf" +      {"ccaron", 2, {196, 141}}, +      {(char*)0}, +#line 1520 "src/html/html_unescape.gperf" +      {"rbbrk", 3, {226, 157, 179}}, +      {(char*)0}, +#line 850 "src/html/html_unescape.gperf" +      {"lbbrk", 3, {226, 157, 178}}, +      {(char*)0}, +#line 59 "src/html/html_unescape.gperf" +      {"Aogon", 2, {196, 132}}, +#line 899 "src/html/html_unescape.gperf" +      {"LeftTriangleBar", 3, {226, 167, 143}}, +      {(char*)0}, {(char*)0}, +#line 616 "src/html/html_unescape.gperf" +      {"gesdotol", 3, {226, 170, 132}}, +#line 901 "src/html/html_unescape.gperf" +      {"LeftTriangleEqual", 3, {226, 138, 180}}, +#line 900 "src/html/html_unescape.gperf" +      {"LeftTriangle", 3, {226, 138, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 291 "src/html/html_unescape.gperf" +      {"conint", 3, {226, 136, 174}}, +      {(char*)0}, {(char*)0}, +#line 440 "src/html/html_unescape.gperf" +      {"drbkarow", 3, {226, 164, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1627 "src/html/html_unescape.gperf" +      {"rtrif", 3, {226, 150, 184}}, +      {(char*)0}, +#line 1023 "src/html/html_unescape.gperf" +      {"ltrif", 3, {226, 151, 130}}, +      {(char*)0}, {(char*)0}, +#line 1549 "src/html/html_unescape.gperf" +      {"ReverseUpEquilibrium", 3, {226, 165, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 879 "src/html/html_unescape.gperf" +      {"LeftCeiling", 3, {226, 140, 136}}, +      {(char*)0}, +#line 1980 "src/html/html_unescape.gperf" +      {"utrif", 3, {226, 150, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2062 "src/html/html_unescape.gperf" +      {"xcup", 3, {226, 139, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 546 "src/html/html_unescape.gperf" +      {"fallingdotseq", 3, {226, 137, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1529 "src/html/html_unescape.gperf" +      {"rcedil", 2, {197, 151}}, +      {(char*)0}, +#line 859 "src/html/html_unescape.gperf" +      {"lcedil", 2, {196, 188}}, +      {(char*)0}, +#line 1644 "src/html/html_unescape.gperf" +      {"scedil", 2, {197, 159}}, +      {(char*)0}, +#line 1831 "src/html/html_unescape.gperf" +      {"Tcedil", 2, {197, 162}}, +      {(char*)0}, +#line 1749 "src/html/html_unescape.gperf" +      {"starf", 3, {226, 152, 133}}, +#line 169 "src/html/html_unescape.gperf" +      {"boxminus", 3, {226, 138, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1832 "src/html/html_unescape.gperf" +      {"tcedil", 2, {197, 163}}, +#line 2118 "src/html/html_unescape.gperf" +      {"ZeroWidthSpace", 3, {226, 128, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1094 "src/html/html_unescape.gperf" +      {"ncedil", 2, {197, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1405 "src/html/html_unescape.gperf" +      {"phiv", 2, {207, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 712 "src/html/html_unescape.gperf" +      {"ic", 3, {226, 129, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 221 "src/html/html_unescape.gperf" +      {"capdot", 3, {226, 169, 128}}, +      {(char*)0}, {(char*)0}, +#line 446 "src/html/html_unescape.gperf" +      {"dscy", 2, {209, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 249 "src/html/html_unescape.gperf" +      {"check", 3, {226, 156, 147}}, +#line 1382 "src/html/html_unescape.gperf" +      {"ovbar", 3, {226, 140, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1281 "src/html/html_unescape.gperf" +      {"ntriangleleft", 3, {226, 139, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1581 "src/html/html_unescape.gperf" +      {"RightTee", 3, {226, 138, 162}}, +#line 1295 "src/html/html_unescape.gperf" +      {"nvge", 3, {226, 137, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 893 "src/html/html_unescape.gperf" +      {"leftrightsquigarrow", 3, {226, 134, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 988 "src/html/html_unescape.gperf" +      {"lozenge", 3, {226, 151, 138}}, +      {(char*)0}, {(char*)0}, +#line 1584 "src/html/html_unescape.gperf" +      {"RightTriangleBar", 3, {226, 167, 144}}, +      {(char*)0}, +#line 1582 "src/html/html_unescape.gperf" +      {"RightTeeVector", 3, {226, 165, 155}}, +      {(char*)0}, +#line 1586 "src/html/html_unescape.gperf" +      {"RightTriangleEqual", 3, {226, 138, 181}}, +#line 1585 "src/html/html_unescape.gperf" +      {"RightTriangle", 3, {226, 138, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 803 "src/html/html_unescape.gperf" +      {"Kcedil", 2, {196, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1643 "src/html/html_unescape.gperf" +      {"Scedil", 2, {197, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 269 "src/html/html_unescape.gperf" +      {"cirfnint", 3, {226, 168, 144}}, +      {(char*)0}, {(char*)0}, +#line 491 "src/html/html_unescape.gperf" +      {"empty", 3, {226, 136, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 23 "src/html/html_unescape.gperf" +      {"afr", 4, {240, 157, 148, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 377 "src/html/html_unescape.gperf" +      {"DiacriticalTilde", 2, {203, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 883 "src/html/html_unescape.gperf" +      {"LeftDownVector", 3, {226, 135, 131}}, +      {(char*)0}, {(char*)0}, +#line 882 "src/html/html_unescape.gperf" +      {"LeftDownVectorBar", 3, {226, 165, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 908 "src/html/html_unescape.gperf" +      {"lEg", 3, {226, 170, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 69 "src/html/html_unescape.gperf" +      {"ApplyFunction", 3, {226, 129, 161}}, +      {(char*)0}, {(char*)0}, +#line 209 "src/html/html_unescape.gperf" +      {"bumpE", 3, {226, 170, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 858 "src/html/html_unescape.gperf" +      {"Lcedil", 2, {196, 187}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 224 "src/html/html_unescape.gperf" +      {"caret", 3, {226, 129, 129}}, +      {(char*)0}, +#line 92 "src/html/html_unescape.gperf" +      {"Barv", 3, {226, 171, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 230 "src/html/html_unescape.gperf" +      {"Ccedil", 2, {195, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 261 "src/html/html_unescape.gperf" +      {"circledR", 2, {194, 174}}, +#line 881 "src/html/html_unescape.gperf" +      {"LeftDownTeeVector", 3, {226, 165, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1896 "src/html/html_unescape.gperf" +      {"tshcy", 2, {209, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 403 "src/html/html_unescape.gperf" +      {"DotEqual", 3, {226, 137, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 243 "src/html/html_unescape.gperf" +      {"centerdot", 2, {194, 183}}, +      {(char*)0}, +#line 1282 "src/html/html_unescape.gperf" +      {"ntrianglelefteq", 3, {226, 139, 172}}, +      {(char*)0}, +#line 1057 "src/html/html_unescape.gperf" +      {"minus", 3, {226, 136, 146}}, +      {(char*)0}, +#line 624 "src/html/html_unescape.gperf" +      {"gimel", 3, {226, 132, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 7 "src/html/html_unescape.gperf" +      {"Aacute", 2, {195, 129}}, +#line 654 "src/html/html_unescape.gperf" +      {"gtcir", 3, {226, 169, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 662 "src/html/html_unescape.gperf" +      {"gtrarr", 3, {226, 165, 184}}, +#line 206 "src/html/html_unescape.gperf" +      {"bull", 3, {226, 128, 162}}, +      {(char*)0}, {(char*)0}, +#line 424 "src/html/html_unescape.gperf" +      {"DownArrow", 3, {226, 134, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1537 "src/html/html_unescape.gperf" +      {"rdquor", 3, {226, 128, 157}}, +      {(char*)0}, +#line 866 "src/html/html_unescape.gperf" +      {"ldquor", 3, {226, 128, 158}}, +      {(char*)0}, {(char*)0}, +#line 756 "src/html/html_unescape.gperf" +      {"intlarhk", 3, {226, 168, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1978 "src/html/html_unescape.gperf" +      {"utilde", 2, {197, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 590 "src/html/html_unescape.gperf" +      {"gacute", 2, {199, 181}}, +      {(char*)0}, +#line 1279 "src/html/html_unescape.gperf" +      {"ntilde", 2, {195, 177}}, +#line 21 "src/html/html_unescape.gperf" +      {"af", 3, {226, 129, 161}}, +      {(char*)0}, {(char*)0}, +#line 704 "src/html/html_unescape.gperf" +      {"Hstrok", 2, {196, 166}}, +      {(char*)0}, +#line 544 "src/html/html_unescape.gperf" +      {"exponentiale", 3, {226, 133, 135}}, +#line 1056 "src/html/html_unescape.gperf" +      {"minusb", 3, {226, 138, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1588 "src/html/html_unescape.gperf" +      {"RightUpTeeVector", 3, {226, 165, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1965 "src/html/html_unescape.gperf" +      {"UpTeeArrow", 3, {226, 134, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2120 "src/html/html_unescape.gperf" +      {"zeta", 2, {206, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 374 "src/html/html_unescape.gperf" +      {"DiacriticalDot", 2, {203, 153}}, +#line 375 "src/html/html_unescape.gperf" +      {"DiacriticalDoubleAcute", 2, {203, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1147 "src/html/html_unescape.gperf" +      {"nleftarrow", 3, {226, 134, 154}}, +#line 692 "src/html/html_unescape.gperf" +      {"hkswarow", 3, {226, 164, 166}}, +      {(char*)0}, +#line 730 "src/html/html_unescape.gperf" +      {"iiota", 3, {226, 132, 169}}, +      {(char*)0}, {(char*)0}, +#line 63 "src/html/html_unescape.gperf" +      {"apacir", 3, {226, 169, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1093 "src/html/html_unescape.gperf" +      {"Ncedil", 2, {197, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 215 "src/html/html_unescape.gperf" +      {"capand", 3, {226, 169, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1043 "src/html/html_unescape.gperf" +      {"mdash", 3, {226, 128, 148}}, +      {(char*)0}, {(char*)0}, +#line 555 "src/html/html_unescape.gperf" +      {"filig", 3, {239, 172, 129}}, +#line 1649 "src/html/html_unescape.gperf" +      {"scnsim", 3, {226, 139, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1541 "src/html/html_unescape.gperf" +      {"realpart", 3, {226, 132, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 898 "src/html/html_unescape.gperf" +      {"leftthreetimes", 3, {226, 139, 139}}, +#line 78 "src/html/html_unescape.gperf" +      {"asymp", 3, {226, 137, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 686 "src/html/html_unescape.gperf" +      {"hellip", 3, {226, 128, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 452 "src/html/html_unescape.gperf" +      {"dtrif", 3, {226, 150, 190}}, +      {(char*)0}, +#line 1176 "src/html/html_unescape.gperf" +      {"NotExists", 3, {226, 136, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1640 "src/html/html_unescape.gperf" +      {"sccue", 3, {226, 137, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2090 "src/html/html_unescape.gperf" +      {"YAcy", 2, {208, 175}}, +#line 1977 "src/html/html_unescape.gperf" +      {"Utilde", 2, {197, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1174 "src/html/html_unescape.gperf" +      {"NotEqual", 3, {226, 137, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1849 "src/html/html_unescape.gperf" +      {"ThinSpace", 3, {226, 128, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 65 "src/html/html_unescape.gperf" +      {"apE", 3, {226, 169, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 207 "src/html/html_unescape.gperf" +      {"bullet", 3, {226, 128, 162}}, +      {(char*)0}, {(char*)0}, +#line 273 "src/html/html_unescape.gperf" +      {"CloseCurlyDoubleQuote", 3, {226, 128, 157}}, +#line 364 "src/html/html_unescape.gperf" +      {"Delta", 2, {206, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 621 "src/html/html_unescape.gperf" +      {"gg", 3, {226, 137, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1379 "src/html/html_unescape.gperf" +      {"otimes", 3, {226, 138, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2057 "src/html/html_unescape.gperf" +      {"wreath", 3, {226, 137, 128}}, +      {(char*)0}, +#line 1528 "src/html/html_unescape.gperf" +      {"Rcedil", 2, {197, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 536 "src/html/html_unescape.gperf" +      {"eth", 2, {195, 176}}, +#line 1806 "src/html/html_unescape.gperf" +      {"supnE", 3, {226, 171, 140}}, +      {(char*)0}, {(char*)0}, +#line 85 "src/html/html_unescape.gperf" +      {"awint", 3, {226, 168, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 196 "src/html/html_unescape.gperf" +      {"Breve", 2, {203, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 622 "src/html/html_unescape.gperf" +      {"Gg", 3, {226, 139, 153}}, +      {(char*)0}, +#line 707 "src/html/html_unescape.gperf" +      {"HumpEqual", 3, {226, 137, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 949 "src/html/html_unescape.gperf" +      {"Lleftarrow", 3, {226, 135, 154}}, +#line 155 "src/html/html_unescape.gperf" +      {"boxdr", 3, {226, 148, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1783 "src/html/html_unescape.gperf" +      {"succneqq", 3, {226, 170, 182}}, +#line 1972 "src/html/html_unescape.gperf" +      {"uring", 2, {197, 175}}, +#line 930 "src/html/html_unescape.gperf" +      {"LessSlantEqual", 3, {226, 169, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1291 "src/html/html_unescape.gperf" +      {"nvdash", 3, {226, 138, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 670 "src/html/html_unescape.gperf" +      {"Hacek", 2, {203, 135}}, +#line 780 "src/html/html_unescape.gperf" +      {"itilde", 2, {196, 169}}, +      {(char*)0}, {(char*)0}, +#line 766 "src/html/html_unescape.gperf" +      {"Iota", 2, {206, 153}}, +      {(char*)0}, +#line 760 "src/html/html_unescape.gperf" +      {"IOcy", 2, {208, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 157 "src/html/html_unescape.gperf" +      {"boxDr", 3, {226, 149, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1780 "src/html/html_unescape.gperf" +      {"SucceedsTilde", 3, {226, 137, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 884 "src/html/html_unescape.gperf" +      {"LeftFloor", 3, {226, 140, 138}}, +#line 2042 "src/html/html_unescape.gperf" +      {"Vvdash", 3, {226, 138, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1877 "src/html/html_unescape.gperf" +      {"triangledown", 3, {226, 150, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 970 "src/html/html_unescape.gperf" +      {"LongLeftRightArrow", 3, {226, 159, 183}}, +#line 1573 "src/html/html_unescape.gperf" +      {"RightFloor", 3, {226, 140, 139}}, +      {(char*)0}, {(char*)0}, +#line 435 "src/html/html_unescape.gperf" +      {"DownRightTeeVector", 3, {226, 165, 159}}, +      {(char*)0}, +#line 1481 "src/html/html_unescape.gperf" +      {"quatint", 3, {226, 168, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1278 "src/html/html_unescape.gperf" +      {"Ntilde", 2, {195, 145}}, +      {(char*)0}, {(char*)0}, +#line 211 "src/html/html_unescape.gperf" +      {"Bumpeq", 3, {226, 137, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 669 "src/html/html_unescape.gperf" +      {"gvnE", 3, {226, 137, 169}}, +      {(char*)0}, +#line 165 "src/html/html_unescape.gperf" +      {"boxhu", 3, {226, 148, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 659 "src/html/html_unescape.gperf" +      {"gtlPar", 3, {226, 166, 149}}, +      {(char*)0}, {(char*)0}, +#line 1238 "src/html/html_unescape.gperf" +      {"nprec", 3, {226, 138, 128}}, +      {(char*)0}, {(char*)0}, +#line 1381 "src/html/html_unescape.gperf" +      {"ouml", 2, {195, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 612 "src/html/html_unescape.gperf" +      {"gescc", 3, {226, 170, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 537 "src/html/html_unescape.gperf" +      {"Euml", 2, {195, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1971 "src/html/html_unescape.gperf" +      {"Uring", 2, {197, 174}}, +      {(char*)0}, +#line 1938 "src/html/html_unescape.gperf" +      {"UnderBracket", 3, {226, 142, 181}}, +#line 1162 "src/html/html_unescape.gperf" +      {"nLtv", 3, {226, 137, 170}}, +#line 873 "src/html/html_unescape.gperf" +      {"LeftArrowBar", 3, {226, 135, 164}}, +#line 1096 "src/html/html_unescape.gperf" +      {"ncongdot", 3, {226, 169, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 79 "src/html/html_unescape.gperf" +      {"asympeq", 3, {226, 137, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1059 "src/html/html_unescape.gperf" +      {"minusdu", 3, {226, 168, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 365 "src/html/html_unescape.gperf" +      {"delta", 2, {206, 180}}, +      {(char*)0}, +#line 679 "src/html/html_unescape.gperf" +      {"harrw", 3, {226, 134, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 39 "src/html/html_unescape.gperf" +      {"andslope", 3, {226, 169, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 238 "src/html/html_unescape.gperf" +      {"cdot", 2, {196, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 226 "src/html/html_unescape.gperf" +      {"Cayleys", 3, {226, 132, 173}}, +#line 167 "src/html/html_unescape.gperf" +      {"boxhU", 3, {226, 149, 168}}, +      {(char*)0}, {(char*)0}, +#line 1785 "src/html/html_unescape.gperf" +      {"succsim", 3, {226, 137, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 267 "src/html/html_unescape.gperf" +      {"cirE", 3, {226, 167, 131}}, +#line 1654 "src/html/html_unescape.gperf" +      {"sdotb", 3, {226, 138, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1319 "src/html/html_unescape.gperf" +      {"odash", 3, {226, 138, 157}}, +#line 270 "src/html/html_unescape.gperf" +      {"cirmid", 3, {226, 171, 175}}, +#line 1803 "src/html/html_unescape.gperf" +      {"suphsub", 3, {226, 171, 151}}, +#line 1796 "src/html/html_unescape.gperf" +      {"supdsub", 3, {226, 171, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1795 "src/html/html_unescape.gperf" +      {"supdot", 3, {226, 170, 190}}, +      {(char*)0}, +#line 84 "src/html/html_unescape.gperf" +      {"awconint", 3, {226, 136, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1895 "src/html/html_unescape.gperf" +      {"TSHcy", 2, {208, 139}}, +      {(char*)0}, {(char*)0}, +#line 640 "src/html/html_unescape.gperf" +      {"grave", 1, {96}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1005 "src/html/html_unescape.gperf" +      {"lsimg", 3, {226, 170, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1950 "src/html/html_unescape.gperf" +      {"UpArrowDownArrow", 3, {226, 135, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 907 "src/html/html_unescape.gperf" +      {"LeftVector", 3, {226, 134, 188}}, +#line 417 "src/html/html_unescape.gperf" +      {"DoubleRightArrow", 3, {226, 135, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1109 "src/html/html_unescape.gperf" +      {"NegativeThinSpace", 3, {226, 128, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 942 "src/html/html_unescape.gperf" +      {"lhblk", 3, {226, 150, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 268 "src/html/html_unescape.gperf" +      {"cire", 3, {226, 137, 151}}, +#line 1294 "src/html/html_unescape.gperf" +      {"nVDash", 3, {226, 138, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1928 "src/html/html_unescape.gperf" +      {"uhblk", 3, {226, 150, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 738 "src/html/html_unescape.gperf" +      {"imagpart", 3, {226, 132, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1587 "src/html/html_unescape.gperf" +      {"RightUpDownVector", 3, {226, 165, 143}}, +      {(char*)0}, {(char*)0}, +#line 152 "src/html/html_unescape.gperf" +      {"boxdL", 3, {226, 149, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 627 "src/html/html_unescape.gperf" +      {"gla", 3, {226, 170, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 783 "src/html/html_unescape.gperf" +      {"Iuml", 2, {195, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1326 "src/html/html_unescape.gperf" +      {"oelig", 2, {197, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1199 "src/html/html_unescape.gperf" +      {"NotLessSlantEqual", 3, {226, 169, 189}}, +      {(char*)0}, +#line 154 "src/html/html_unescape.gperf" +      {"boxDL", 3, {226, 149, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 592 "src/html/html_unescape.gperf" +      {"gamma", 2, {206, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1378 "src/html/html_unescape.gperf" +      {"Otimes", 3, {226, 168, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 969 "src/html/html_unescape.gperf" +      {"longleftrightarrow", 3, {226, 159, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 591 "src/html/html_unescape.gperf" +      {"Gamma", 2, {206, 147}}, +#line 128 "src/html/html_unescape.gperf" +      {"bigwedge", 3, {226, 139, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 161 "src/html/html_unescape.gperf" +      {"boxhd", 3, {226, 148, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1797 "src/html/html_unescape.gperf" +      {"supE", 3, {226, 171, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 903 "src/html/html_unescape.gperf" +      {"LeftUpTeeVector", 3, {226, 165, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 615 "src/html/html_unescape.gperf" +      {"gesdoto", 3, {226, 170, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 801 "src/html/html_unescape.gperf" +      {"kappa", 2, {206, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1125 "src/html/html_unescape.gperf" +      {"ngeqslant", 3, {226, 169, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 666 "src/html/html_unescape.gperf" +      {"gtrless", 3, {226, 137, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 551 "src/html/html_unescape.gperf" +      {"fflig", 3, {239, 172, 128}}, +#line 122 "src/html/html_unescape.gperf" +      {"bigsqcup", 3, {226, 168, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 809 "src/html/html_unescape.gperf" +      {"kgreen", 2, {196, 184}}, +#line 1798 "src/html/html_unescape.gperf" +      {"supe", 3, {226, 138, 135}}, +      {(char*)0}, +#line 171 "src/html/html_unescape.gperf" +      {"boxtimes", 3, {226, 138, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 632 "src/html/html_unescape.gperf" +      {"gnapprox", 3, {226, 170, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 428 "src/html/html_unescape.gperf" +      {"downdownarrows", 3, {226, 135, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 126 "src/html/html_unescape.gperf" +      {"biguplus", 3, {226, 168, 132}}, +#line 811 "src/html/html_unescape.gperf" +      {"khcy", 2, {209, 133}}, +      {(char*)0}, +#line 356 "src/html/html_unescape.gperf" +      {"ddagger", 3, {226, 128, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1380 "src/html/html_unescape.gperf" +      {"Ouml", 2, {195, 150}}, +      {(char*)0}, +#line 110 "src/html/html_unescape.gperf" +      {"Beta", 2, {206, 146}}, +#line 1058 "src/html/html_unescape.gperf" +      {"minusd", 3, {226, 136, 184}}, +#line 1784 "src/html/html_unescape.gperf" +      {"succnsim", 3, {226, 139, 169}}, +      {(char*)0}, +#line 311 "src/html/html_unescape.gperf" +      {"ctdot", 3, {226, 139, 175}}, +      {(char*)0}, {(char*)0}, +#line 813 "src/html/html_unescape.gperf" +      {"kjcy", 2, {209, 156}}, +#line 626 "src/html/html_unescape.gperf" +      {"gjcy", 2, {209, 147}}, +      {(char*)0}, +#line 1095 "src/html/html_unescape.gperf" +      {"ncong", 3, {226, 137, 135}}, +#line 2086 "src/html/html_unescape.gperf" +      {"xvee", 3, {226, 139, 129}}, +#line 99 "src/html/html_unescape.gperf" +      {"bcong", 3, {226, 137, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1723 "src/html/html_unescape.gperf" +      {"sqsube", 3, {226, 138, 145}}, +      {(char*)0}, {(char*)0}, +#line 156 "src/html/html_unescape.gperf" +      {"boxdR", 3, {226, 149, 146}}, +      {(char*)0}, {(char*)0}, +#line 971 "src/html/html_unescape.gperf" +      {"Longleftrightarrow", 3, {226, 159, 186}}, +      {(char*)0}, +#line 1722 "src/html/html_unescape.gperf" +      {"sqsub", 3, {226, 138, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 431 "src/html/html_unescape.gperf" +      {"DownLeftRightVector", 3, {226, 165, 144}}, +      {(char*)0}, {(char*)0}, +#line 1724 "src/html/html_unescape.gperf" +      {"sqsubset", 3, {226, 138, 143}}, +      {(char*)0}, +#line 1230 "src/html/html_unescape.gperf" +      {"NotVerticalBar", 3, {226, 136, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1175 "src/html/html_unescape.gperf" +      {"NotEqualTilde", 3, {226, 137, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 151 "src/html/html_unescape.gperf" +      {"boxdl", 3, {226, 148, 144}}, +      {(char*)0}, {(char*)0}, +#line 158 "src/html/html_unescape.gperf" +      {"boxDR", 3, {226, 149, 148}}, +      {(char*)0}, +#line 35 "src/html/html_unescape.gperf" +      {"andand", 3, {226, 169, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1592 "src/html/html_unescape.gperf" +      {"RightVector", 3, {226, 135, 128}}, +      {(char*)0}, +#line 731 "src/html/html_unescape.gperf" +      {"IJlig", 2, {196, 178}}, +#line 1227 "src/html/html_unescape.gperf" +      {"NotTildeEqual", 3, {226, 137, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 58 "src/html/html_unescape.gperf" +      {"angzarr", 3, {226, 141, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 53 "src/html/html_unescape.gperf" +      {"angrt", 3, {226, 136, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 12 "src/html/html_unescape.gperf" +      {"acd", 3, {226, 136, 191}}, +      {(char*)0}, {(char*)0}, +#line 38 "src/html/html_unescape.gperf" +      {"andd", 3, {226, 169, 156}}, +      {(char*)0}, +#line 1241 "src/html/html_unescape.gperf" +      {"nrarrc", 3, {226, 164, 179}}, +#line 2026 "src/html/html_unescape.gperf" +      {"VeryThinSpace", 3, {226, 128, 138}}, +      {(char*)0}, +#line 1800 "src/html/html_unescape.gperf" +      {"Superset", 3, {226, 138, 131}}, +      {(char*)0}, +#line 153 "src/html/html_unescape.gperf" +      {"boxDl", 3, {226, 149, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2030 "src/html/html_unescape.gperf" +      {"vnsub", 3, {226, 138, 130}}, +      {(char*)0}, {(char*)0}, +#line 236 "src/html/html_unescape.gperf" +      {"ccupssm", 3, {226, 169, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1988 "src/html/html_unescape.gperf" +      {"varnothing", 3, {226, 136, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1533 "src/html/html_unescape.gperf" +      {"rcy", 2, {209, 128}}, +      {(char*)0}, +#line 863 "src/html/html_unescape.gperf" +      {"lcy", 2, {208, 187}}, +      {(char*)0}, +#line 1653 "src/html/html_unescape.gperf" +      {"scy", 2, {209, 129}}, +      {(char*)0}, +#line 1833 "src/html/html_unescape.gperf" +      {"Tcy", 2, {208, 162}}, +#line 2113 "src/html/html_unescape.gperf" +      {"Zcy", 2, {208, 151}}, +#line 469 "src/html/html_unescape.gperf" +      {"ecy", 2, {209, 141}}, +#line 1538 "src/html/html_unescape.gperf" +      {"rdsh", 3, {226, 134, 179}}, +      {(char*)0}, +#line 869 "src/html/html_unescape.gperf" +      {"ldsh", 3, {226, 134, 178}}, +      {(char*)0}, +#line 1915 "src/html/html_unescape.gperf" +      {"ucy", 2, {209, 131}}, +#line 185 "src/html/html_unescape.gperf" +      {"boxVH", 3, {226, 149, 172}}, +#line 1834 "src/html/html_unescape.gperf" +      {"tcy", 2, {209, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1099 "src/html/html_unescape.gperf" +      {"ncy", 2, {208, 189}}, +      {(char*)0}, +#line 101 "src/html/html_unescape.gperf" +      {"bcy", 2, {208, 177}}, +#line 1277 "src/html/html_unescape.gperf" +      {"ntgl", 3, {226, 137, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 787 "src/html/html_unescape.gperf" +      {"Jcy", 2, {208, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 289 "src/html/html_unescape.gperf" +      {"congdot", 3, {226, 169, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 57 "src/html/html_unescape.gperf" +      {"angst", 2, {195, 133}}, +      {(char*)0}, +#line 1570 "src/html/html_unescape.gperf" +      {"RightDownTeeVector", 3, {226, 165, 157}}, +      {(char*)0}, {(char*)0}, +#line 1386 "src/html/html_unescape.gperf" +      {"OverParenthesis", 3, {226, 143, 156}}, +#line 1020 "src/html/html_unescape.gperf" +      {"ltquest", 3, {226, 169, 187}}, +      {(char*)0}, +#line 1395 "src/html/html_unescape.gperf" +      {"pcy", 2, {208, 191}}, +      {(char*)0}, {(char*)0}, +#line 1376 "src/html/html_unescape.gperf" +      {"otilde", 2, {195, 181}}, +#line 1536 "src/html/html_unescape.gperf" +      {"rdquo", 3, {226, 128, 157}}, +      {(char*)0}, +#line 865 "src/html/html_unescape.gperf" +      {"ldquo", 3, {226, 128, 156}}, +      {(char*)0}, +#line 2006 "src/html/html_unescape.gperf" +      {"Vcy", 2, {208, 146}}, +      {(char*)0}, {(char*)0}, +#line 216 "src/html/html_unescape.gperf" +      {"capbrcup", 3, {226, 169, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 102 "src/html/html_unescape.gperf" +      {"bdquo", 3, {226, 128, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 422 "src/html/html_unescape.gperf" +      {"DownArrowBar", 3, {226, 164, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2007 "src/html/html_unescape.gperf" +      {"vcy", 2, {208, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 54 "src/html/html_unescape.gperf" +      {"angrtvb", 3, {226, 138, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 805 "src/html/html_unescape.gperf" +      {"Kcy", 2, {208, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1041 "src/html/html_unescape.gperf" +      {"Mcy", 2, {208, 156}}, +#line 1652 "src/html/html_unescape.gperf" +      {"Scy", 2, {208, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1116 "src/html/html_unescape.gperf" +      {"NewLine", 1, {10}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 548 "src/html/html_unescape.gperf" +      {"fcy", 2, {209, 132}}, +#line 1914 "src/html/html_unescape.gperf" +      {"Ucy", 2, {208, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 184 "src/html/html_unescape.gperf" +      {"boxVh", 3, {226, 149, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 354 "src/html/html_unescape.gperf" +      {"Dcy", 2, {208, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 705 "src/html/html_unescape.gperf" +      {"hstrok", 2, {196, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 862 "src/html/html_unescape.gperf" +      {"Lcy", 2, {208, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2094 "src/html/html_unescape.gperf" +      {"Ycy", 2, {208, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1815 "src/html/html_unescape.gperf" +      {"supsim", 3, {226, 171, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1165 "src/html/html_unescape.gperf" +      {"NonBreakingSpace", 2, {194, 160}}, +#line 1383 "src/html/html_unescape.gperf" +      {"OverBar", 3, {226, 128, 190}}, +#line 1725 "src/html/html_unescape.gperf" +      {"sqsubseteq", 3, {226, 138, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 625 "src/html/html_unescape.gperf" +      {"GJcy", 2, {208, 131}}, +      {(char*)0}, {(char*)0}, +#line 1384 "src/html/html_unescape.gperf" +      {"OverBrace", 3, {226, 143, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 513 "src/html/html_unescape.gperf" +      {"eqcirc", 3, {226, 137, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1385 "src/html/html_unescape.gperf" +      {"OverBracket", 3, {226, 142, 180}}, +      {(char*)0}, +#line 82 "src/html/html_unescape.gperf" +      {"Auml", 2, {195, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 16 "src/html/html_unescape.gperf" +      {"acute", 2, {194, 180}}, +#line 716 "src/html/html_unescape.gperf" +      {"icy", 2, {208, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 779 "src/html/html_unescape.gperf" +      {"Itilde", 2, {196, 168}}, +#line 690 "src/html/html_unescape.gperf" +      {"HilbertSpace", 3, {226, 132, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1345 "src/html/html_unescape.gperf" +      {"omega", 2, {207, 137}}, +#line 214 "src/html/html_unescape.gperf" +      {"cacute", 2, {196, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1646 "src/html/html_unescape.gperf" +      {"scirc", 2, {197, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 465 "src/html/html_unescape.gperf" +      {"ecirc", 2, {195, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1913 "src/html/html_unescape.gperf" +      {"ucirc", 2, {195, 187}}, +      {(char*)0}, +#line 646 "src/html/html_unescape.gperf" +      {"GreaterSlantEqual", 3, {226, 169, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 785 "src/html/html_unescape.gperf" +      {"Jcirc", 2, {196, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1292 "src/html/html_unescape.gperf" +      {"nvDash", 3, {226, 138, 173}}, +#line 2044 "src/html/html_unescape.gperf" +      {"Wcirc", 2, {197, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1098 "src/html/html_unescape.gperf" +      {"Ncy", 2, {208, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1580 "src/html/html_unescape.gperf" +      {"RightTeeArrow", 3, {226, 134, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 925 "src/html/html_unescape.gperf" +      {"LessFullEqual", 3, {226, 137, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1011 "src/html/html_unescape.gperf" +      {"ltcc", 3, {226, 170, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 27 "src/html/html_unescape.gperf" +      {"aleph", 3, {226, 132, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 355 "src/html/html_unescape.gperf" +      {"dcy", 2, {208, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1645 "src/html/html_unescape.gperf" +      {"Scirc", 2, {197, 156}}, +      {(char*)0}, +#line 920 "src/html/html_unescape.gperf" +      {"lessapprox", 3, {226, 170, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 718 "src/html/html_unescape.gperf" +      {"IEcy", 2, {208, 149}}, +#line 986 "src/html/html_unescape.gperf" +      {"LowerRightArrow", 3, {226, 134, 152}}, +#line 1912 "src/html/html_unescape.gperf" +      {"Ucirc", 2, {195, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 25 "src/html/html_unescape.gperf" +      {"agrave", 2, {195, 160}}, +      {(char*)0}, +#line 1060 "src/html/html_unescape.gperf" +      {"MinusPlus", 3, {226, 136, 147}}, +#line 127 "src/html/html_unescape.gperf" +      {"bigvee", 3, {226, 139, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1532 "src/html/html_unescape.gperf" +      {"Rcy", 2, {208, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1802 "src/html/html_unescape.gperf" +      {"suphsol", 3, {226, 159, 137}}, +      {(char*)0}, {(char*)0}, +#line 495 "src/html/html_unescape.gperf" +      {"EmptyVerySmallSquare", 3, {226, 150, 171}}, +      {(char*)0}, +#line 163 "src/html/html_unescape.gperf" +      {"boxhD", 3, {226, 149, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1436 "src/html/html_unescape.gperf" +      {"precapprox", 3, {226, 170, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 55 "src/html/html_unescape.gperf" +      {"angrtvbd", 3, {226, 166, 157}}, +#line 2092 "src/html/html_unescape.gperf" +      {"Ycirc", 2, {197, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1753 "src/html/html_unescape.gperf" +      {"sub", 3, {226, 138, 130}}, +      {(char*)0}, {(char*)0}, +#line 1375 "src/html/html_unescape.gperf" +      {"Otilde", 2, {195, 149}}, +#line 232 "src/html/html_unescape.gperf" +      {"Ccirc", 2, {196, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 547 "src/html/html_unescape.gperf" +      {"Fcy", 2, {208, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 287 "src/html/html_unescape.gperf" +      {"complexes", 3, {226, 132, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1763 "src/html/html_unescape.gperf" +      {"subrarr", 3, {226, 165, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 758 "src/html/html_unescape.gperf" +      {"InvisibleComma", 3, {226, 129, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 176 "src/html/html_unescape.gperf" +      {"boxur", 3, {226, 148, 148}}, +#line 10 "src/html/html_unescape.gperf" +      {"abreve", 2, {196, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1280 "src/html/html_unescape.gperf" +      {"ntlg", 3, {226, 137, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 714 "src/html/html_unescape.gperf" +      {"icirc", 2, {195, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2063 "src/html/html_unescape.gperf" +      {"xdtri", 3, {226, 150, 189}}, +#line 253 "src/html/html_unescape.gperf" +      {"circ", 2, {203, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 663 "src/html/html_unescape.gperf" +      {"gtrdot", 3, {226, 139, 151}}, +      {(char*)0}, {(char*)0}, +#line 611 "src/html/html_unescape.gperf" +      {"geqslant", 3, {226, 169, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1283 "src/html/html_unescape.gperf" +      {"ntriangleright", 3, {226, 139, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 314 "src/html/html_unescape.gperf" +      {"cuepr", 3, {226, 139, 158}}, +#line 1754 "src/html/html_unescape.gperf" +      {"Sub", 3, {226, 139, 144}}, +      {(char*)0}, +#line 1042 "src/html/html_unescape.gperf" +      {"mcy", 2, {208, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1860 "src/html/html_unescape.gperf" +      {"timesbar", 3, {226, 168, 177}}, +      {(char*)0}, +#line 691 "src/html/html_unescape.gperf" +      {"hksearow", 3, {226, 164, 165}}, +      {(char*)0}, {(char*)0}, +#line 1683 "src/html/html_unescape.gperf" +      {"sigma", 2, {207, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 325 "src/html/html_unescape.gperf" +      {"cupor", 3, {226, 169, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1373 "src/html/html_unescape.gperf" +      {"oslash", 2, {195, 184}}, +#line 458 "src/html/html_unescape.gperf" +      {"dzigrarr", 3, {226, 159, 191}}, +      {(char*)0}, {(char*)0}, +#line 892 "src/html/html_unescape.gperf" +      {"leftrightharpoons", 3, {226, 135, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1577 "src/html/html_unescape.gperf" +      {"rightleftharpoons", 3, {226, 135, 140}}, +      {(char*)0}, +#line 804 "src/html/html_unescape.gperf" +      {"kcedil", 2, {196, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1759 "src/html/html_unescape.gperf" +      {"submult", 3, {226, 171, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 333 "src/html/html_unescape.gperf" +      {"curren", 2, {194, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 897 "src/html/html_unescape.gperf" +      {"LeftTeeVector", 3, {226, 165, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 123 "src/html/html_unescape.gperf" +      {"bigstar", 3, {226, 152, 133}}, +      {(char*)0}, {(char*)0}, +#line 321 "src/html/html_unescape.gperf" +      {"cup", 3, {226, 136, 170}}, +#line 974 "src/html/html_unescape.gperf" +      {"LongRightArrow", 3, {226, 159, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 598 "src/html/html_unescape.gperf" +      {"Gcedil", 2, {196, 162}}, +      {(char*)0}, +#line 1440 "src/html/html_unescape.gperf" +      {"PrecedesEqual", 3, {226, 170, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 2114 "src/html/html_unescape.gperf" +      {"zcy", 2, {208, 183}}, +      {(char*)0}, +#line 1413 "src/html/html_unescape.gperf" +      {"planckh", 3, {226, 132, 142}}, +#line 1344 "src/html/html_unescape.gperf" +      {"Omega", 2, {206, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1772 "src/html/html_unescape.gperf" +      {"subsub", 3, {226, 171, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1534 "src/html/html_unescape.gperf" +      {"rdca", 3, {226, 164, 183}}, +#line 326 "src/html/html_unescape.gperf" +      {"cups", 3, {226, 136, 170}}, +#line 864 "src/html/html_unescape.gperf" +      {"ldca", 3, {226, 164, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1764 "src/html/html_unescape.gperf" +      {"subset", 3, {226, 138, 130}}, +#line 1220 "src/html/html_unescape.gperf" +      {"NotSucceeds", 3, {226, 138, 129}}, +#line 877 "src/html/html_unescape.gperf" +      {"LeftArrowRightArrow", 3, {226, 135, 134}}, +      {(char*)0}, {(char*)0}, +#line 2045 "src/html/html_unescape.gperf" +      {"wcirc", 2, {197, 181}}, +#line 1561 "src/html/html_unescape.gperf" +      {"RightAngleBracket", 3, {226, 159, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1284 "src/html/html_unescape.gperf" +      {"ntrianglerighteq", 3, {226, 139, 173}}, +#line 1682 "src/html/html_unescape.gperf" +      {"Sigma", 2, {206, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1223 "src/html/html_unescape.gperf" +      {"NotSucceedsTilde", 3, {226, 137, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 373 "src/html/html_unescape.gperf" +      {"DiacriticalAcute", 2, {194, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1761 "src/html/html_unescape.gperf" +      {"subne", 3, {226, 138, 138}}, +      {(char*)0}, +#line 1457 "src/html/html_unescape.gperf" +      {"Product", 3, {226, 136, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 259 "src/html/html_unescape.gperf" +      {"circleddash", 3, {226, 138, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1773 "src/html/html_unescape.gperf" +      {"subsup", 3, {226, 171, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 298 "src/html/html_unescape.gperf" +      {"copy", 2, {194, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 534 "src/html/html_unescape.gperf" +      {"eta", 2, {206, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 52 "src/html/html_unescape.gperf" +      {"angmsd", 3, {226, 136, 161}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1084 "src/html/html_unescape.gperf" +      {"natural", 3, {226, 153, 174}}, +      {(char*)0}, +#line 1799 "src/html/html_unescape.gperf" +      {"supedot", 3, {226, 171, 132}}, +#line 1085 "src/html/html_unescape.gperf" +      {"naturals", 3, {226, 132, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1881 "src/html/html_unescape.gperf" +      {"triangleright", 3, {226, 150, 185}}, +      {(char*)0}, +#line 376 "src/html/html_unescape.gperf" +      {"DiacriticalGrave", 1, {96}}, +#line 173 "src/html/html_unescape.gperf" +      {"boxuL", 3, {226, 149, 155}}, +#line 288 "src/html/html_unescape.gperf" +      {"cong", 3, {226, 137, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1836 "src/html/html_unescape.gperf" +      {"telrec", 3, {226, 140, 149}}, +      {(char*)0}, {(char*)0}, +#line 282 "src/html/html_unescape.gperf" +      {"comma", 1, {44}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1765 "src/html/html_unescape.gperf" +      {"Subset", 3, {226, 139, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1222 "src/html/html_unescape.gperf" +      {"NotSucceedsSlantEqual", 3, {226, 139, 161}}, +#line 664 "src/html/html_unescape.gperf" +      {"gtreqless", 3, {226, 139, 155}}, +#line 80 "src/html/html_unescape.gperf" +      {"Atilde", 2, {195, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 327 "src/html/html_unescape.gperf" +      {"curarr", 3, {226, 134, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 313 "src/html/html_unescape.gperf" +      {"cudarrr", 3, {226, 164, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 312 "src/html/html_unescape.gperf" +      {"cudarrl", 3, {226, 164, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1766 "src/html/html_unescape.gperf" +      {"subseteq", 3, {226, 138, 134}}, +#line 1767 "src/html/html_unescape.gperf" +      {"subseteqq", 3, {226, 171, 133}}, +#line 1579 "src/html/html_unescape.gperf" +      {"rightsquigarrow", 3, {226, 134, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 319 "src/html/html_unescape.gperf" +      {"cupcap", 3, {226, 169, 134}}, +#line 1769 "src/html/html_unescape.gperf" +      {"subsetneq", 3, {226, 138, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 60 "src/html/html_unescape.gperf" +      {"aogon", 2, {196, 133}}, +#line 1191 "src/html/html_unescape.gperf" +      {"notinvc", 3, {226, 139, 182}}, +#line 1583 "src/html/html_unescape.gperf" +      {"rightthreetimes", 3, {226, 139, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 2089 "src/html/html_unescape.gperf" +      {"yacute", 2, {195, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1148 "src/html/html_unescape.gperf" +      {"nLeftarrow", 3, {226, 135, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1318 "src/html/html_unescape.gperf" +      {"ocy", 2, {208, 190}}, +#line 241 "src/html/html_unescape.gperf" +      {"cemptyv", 3, {226, 166, 178}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 468 "src/html/html_unescape.gperf" +      {"Ecy", 2, {208, 173}}, +      {(char*)0}, {(char*)0}, +#line 323 "src/html/html_unescape.gperf" +      {"cupcup", 3, {226, 169, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1882 "src/html/html_unescape.gperf" +      {"trianglerighteq", 3, {226, 138, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 889 "src/html/html_unescape.gperf" +      {"LeftRightArrow", 3, {226, 134, 148}}, +      {(char*)0}, {(char*)0}, +#line 1775 "src/html/html_unescape.gperf" +      {"succ", 3, {226, 137, 187}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 426 "src/html/html_unescape.gperf" +      {"DownArrowUpArrow", 3, {226, 135, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1325 "src/html/html_unescape.gperf" +      {"OElig", 2, {197, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 248 "src/html/html_unescape.gperf" +      {"chcy", 2, {209, 135}}, +#line 665 "src/html/html_unescape.gperf" +      {"gtreqqless", 3, {226, 170, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 43 "src/html/html_unescape.gperf" +      {"angle", 3, {226, 136, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 13 "src/html/html_unescape.gperf" +      {"acE", 3, {226, 136, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1598 "src/html/html_unescape.gperf" +      {"rmoustache", 3, {226, 142, 177}}, +      {(char*)0}, +#line 954 "src/html/html_unescape.gperf" +      {"lmoustache", 3, {226, 142, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1110 "src/html/html_unescape.gperf" +      {"NegativeVeryThinSpace", 3, {226, 128, 139}}, +      {(char*)0}, {(char*)0}, +#line 1083 "src/html/html_unescape.gperf" +      {"napprox", 3, {226, 137, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1372 "src/html/html_unescape.gperf" +      {"Oslash", 2, {195, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1770 "src/html/html_unescape.gperf" +      {"subsetneqq", 3, {226, 171, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 72 "src/html/html_unescape.gperf" +      {"Aring", 2, {195, 133}}, +#line 177 "src/html/html_unescape.gperf" +      {"boxuR", 3, {226, 149, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1762 "src/html/html_unescape.gperf" +      {"subplus", 3, {226, 170, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2087 "src/html/html_unescape.gperf" +      {"xwedge", 3, {226, 139, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 172 "src/html/html_unescape.gperf" +      {"boxul", 3, {226, 148, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 190 "src/html/html_unescape.gperf" +      {"boxvr", 3, {226, 148, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 706 "src/html/html_unescape.gperf" +      {"HumpDownHump", 3, {226, 137, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 715 "src/html/html_unescape.gperf" +      {"Icy", 2, {208, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 71 "src/html/html_unescape.gperf" +      {"approxeq", 3, {226, 137, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 8 "src/html/html_unescape.gperf" +      {"aacute", 2, {195, 161}}, +#line 67 "src/html/html_unescape.gperf" +      {"apid", 3, {226, 137, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1952 "src/html/html_unescape.gperf" +      {"UpDownArrow", 3, {226, 134, 149}}, +      {(char*)0}, +#line 1114 "src/html/html_unescape.gperf" +      {"NestedGreaterGreater", 3, {226, 137, 171}}, +      {(char*)0}, +#line 788 "src/html/html_unescape.gperf" +      {"jcy", 2, {208, 185}}, +      {(char*)0}, {(char*)0}, +#line 667 "src/html/html_unescape.gperf" +      {"gtrsim", 3, {226, 137, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 180 "src/html/html_unescape.gperf" +      {"boxv", 3, {226, 148, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1315 "src/html/html_unescape.gperf" +      {"ocirc", 2, {195, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 464 "src/html/html_unescape.gperf" +      {"Ecirc", 2, {195, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1206 "src/html/html_unescape.gperf" +      {"notnivc", 3, {226, 139, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 125 "src/html/html_unescape.gperf" +      {"bigtriangleup", 3, {226, 150, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 343 "src/html/html_unescape.gperf" +      {"daleth", 3, {226, 132, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1317 "src/html/html_unescape.gperf" +      {"Ocy", 2, {208, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 682 "src/html/html_unescape.gperf" +      {"Hcirc", 2, {196, 164}}, +#line 1591 "src/html/html_unescape.gperf" +      {"RightVectorBar", 3, {226, 165, 147}}, +#line 19 "src/html/html_unescape.gperf" +      {"AElig", 2, {195, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 557 "src/html/html_unescape.gperf" +      {"FilledVerySmallSquare", 3, {226, 150, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 623 "src/html/html_unescape.gperf" +      {"ggg", 3, {226, 139, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 100 "src/html/html_unescape.gperf" +      {"Bcy", 2, {208, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1427 "src/html/html_unescape.gperf" +      {"Poincareplane", 3, {226, 132, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 187 "src/html/html_unescape.gperf" +      {"boxvL", 3, {226, 149, 161}}, +      {(char*)0}, {(char*)0}, +#line 1393 "src/html/html_unescape.gperf" +      {"PartialD", 3, {226, 136, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 713 "src/html/html_unescape.gperf" +      {"Icirc", 2, {195, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 316 "src/html/html_unescape.gperf" +      {"cularr", 3, {226, 134, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 159 "src/html/html_unescape.gperf" +      {"boxh", 3, {226, 148, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 40 "src/html/html_unescape.gperf" +      {"andv", 3, {226, 169, 154}}, +      {(char*)0}, +#line 1789 "src/html/html_unescape.gperf" +      {"sung", 3, {226, 153, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1569 "src/html/html_unescape.gperf" +      {"RightDoubleBracket", 3, {226, 159, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 786 "src/html/html_unescape.gperf" +      {"jcirc", 2, {196, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1936 "src/html/html_unescape.gperf" +      {"UnderBar", 1, {95}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1564 "src/html/html_unescape.gperf" +      {"RightArrow", 3, {226, 134, 146}}, +#line 258 "src/html/html_unescape.gperf" +      {"circledcirc", 3, {226, 138, 154}}, +#line 28 "src/html/html_unescape.gperf" +      {"Alpha", 2, {206, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 886 "src/html/html_unescape.gperf" +      {"leftharpoonup", 3, {226, 134, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 317 "src/html/html_unescape.gperf" +      {"cularrp", 3, {226, 164, 189}}, +      {(char*)0}, +#line 1566 "src/html/html_unescape.gperf" +      {"RightArrowLeftArrow", 3, {226, 135, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1995 "src/html/html_unescape.gperf" +      {"varsigma", 2, {207, 130}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1288 "src/html/html_unescape.gperf" +      {"numero", 3, {226, 132, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 552 "src/html/html_unescape.gperf" +      {"ffllig", 3, {239, 172, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 985 "src/html/html_unescape.gperf" +      {"LowerLeftArrow", 3, {226, 134, 153}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 543 "src/html/html_unescape.gperf" +      {"expectation", 3, {226, 132, 176}}, +      {(char*)0}, +#line 1314 "src/html/html_unescape.gperf" +      {"Ocirc", 2, {195, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2091 "src/html/html_unescape.gperf" +      {"yacy", 2, {209, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 824 "src/html/html_unescape.gperf" +      {"lambda", 2, {206, 187}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1221 "src/html/html_unescape.gperf" +      {"NotSucceedsEqual", 3, {226, 170, 176}}, +#line 191 "src/html/html_unescape.gperf" +      {"boxvR", 3, {226, 149, 158}}, +      {(char*)0}, +#line 124 "src/html/html_unescape.gperf" +      {"bigtriangledown", 3, {226, 150, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 41 "src/html/html_unescape.gperf" +      {"ang", 3, {226, 136, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2084 "src/html/html_unescape.gperf" +      {"xuplus", 3, {226, 168, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1075 "src/html/html_unescape.gperf" +      {"nabla", 3, {226, 136, 135}}, +#line 186 "src/html/html_unescape.gperf" +      {"boxvl", 3, {226, 148, 164}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 533 "src/html/html_unescape.gperf" +      {"Eta", 2, {206, 151}}, +      {(char*)0}, +#line 17 "src/html/html_unescape.gperf" +      {"Acy", 2, {208, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 806 "src/html/html_unescape.gperf" +      {"kcy", 2, {208, 186}}, +#line 602 "src/html/html_unescape.gperf" +      {"gcy", 2, {208, 179}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 894 "src/html/html_unescape.gperf" +      {"LeftRightVector", 3, {226, 165, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 231 "src/html/html_unescape.gperf" +      {"ccedil", 2, {195, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 91 "src/html/html_unescape.gperf" +      {"Backslash", 3, {226, 136, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 703 "src/html/html_unescape.gperf" +      {"hslash", 3, {226, 132, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1394 "src/html/html_unescape.gperf" +      {"Pcy", 2, {208, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 601 "src/html/html_unescape.gperf" +      {"Gcy", 2, {208, 147}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 660 "src/html/html_unescape.gperf" +      {"gtquest", 3, {226, 169, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 823 "src/html/html_unescape.gperf" +      {"Lambda", 2, {206, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1322 "src/html/html_unescape.gperf" +      {"odiv", 3, {226, 168, 184}}, +      {(char*)0}, +#line 885 "src/html/html_unescape.gperf" +      {"leftharpoondown", 3, {226, 134, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 972 "src/html/html_unescape.gperf" +      {"longmapsto", 3, {226, 159, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 798 "src/html/html_unescape.gperf" +      {"Jukcy", 2, {208, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 867 "src/html/html_unescape.gperf" +      {"ldrdhar", 3, {226, 165, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2085 "src/html/html_unescape.gperf" +      {"xutri", 3, {226, 150, 179}}, +#line 1246 "src/html/html_unescape.gperf" +      {"nRightarrow", 3, {226, 135, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 545 "src/html/html_unescape.gperf" +      {"ExponentialE", 3, {226, 133, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1245 "src/html/html_unescape.gperf" +      {"nrightarrow", 3, {226, 134, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 14 "src/html/html_unescape.gperf" +      {"Acirc", 2, {195, 130}}, +#line 1164 "src/html/html_unescape.gperf" +      {"NoBreak", 3, {226, 129, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 600 "src/html/html_unescape.gperf" +      {"gcirc", 2, {196, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 42 "src/html/html_unescape.gperf" +      {"ange", 3, {226, 166, 164}}, +#line 328 "src/html/html_unescape.gperf" +      {"curarrm", 3, {226, 164, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1671 "src/html/html_unescape.gperf" +      {"SHCHcy", 2, {208, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2107 "src/html/html_unescape.gperf" +      {"yuml", 2, {195, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1760 "src/html/html_unescape.gperf" +      {"subnE", 3, {226, 171, 139}}, +      {(char*)0}, {(char*)0}, +#line 360 "src/html/html_unescape.gperf" +      {"DDotrahd", 3, {226, 164, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1629 "src/html/html_unescape.gperf" +      {"RuleDelayed", 3, {226, 167, 180}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 599 "src/html/html_unescape.gperf" +      {"Gcirc", 2, {196, 156}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 796 "src/html/html_unescape.gperf" +      {"Jsercy", 2, {208, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 653 "src/html/html_unescape.gperf" +      {"gtcc", 3, {226, 170, 167}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 782 "src/html/html_unescape.gperf" +      {"iukcy", 2, {209, 150}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1951 "src/html/html_unescape.gperf" +      {"updownarrow", 3, {226, 134, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 331 "src/html/html_unescape.gperf" +      {"curlyvee", 3, {226, 139, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 550 "src/html/html_unescape.gperf" +      {"ffilig", 3, {239, 172, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2100 "src/html/html_unescape.gperf" +      {"yicy", 2, {209, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 390 "src/html/html_unescape.gperf" +      {"divonx", 3, {226, 139, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 661 "src/html/html_unescape.gperf" +      {"gtrapprox", 3, {226, 170, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1755 "src/html/html_unescape.gperf" +      {"subdot", 3, {226, 170, 189}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 891 "src/html/html_unescape.gperf" +      {"leftrightarrows", 3, {226, 135, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 83 "src/html/html_unescape.gperf" +      {"auml", 2, {195, 164}}, +      {(char*)0}, {(char*)0}, +#line 1953 "src/html/html_unescape.gperf" +      {"Updownarrow", 3, {226, 135, 149}}, +      {(char*)0}, +#line 1576 "src/html/html_unescape.gperf" +      {"rightleftarrows", 3, {226, 135, 132}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 437 "src/html/html_unescape.gperf" +      {"DownRightVector", 3, {226, 135, 129}}, +      {(char*)0}, {(char*)0}, +#line 436 "src/html/html_unescape.gperf" +      {"DownRightVectorBar", 3, {226, 165, 151}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 683 "src/html/html_unescape.gperf" +      {"hcirc", 2, {196, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1614 "src/html/html_unescape.gperf" +      {"Rrightarrow", 3, {226, 135, 155}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 973 "src/html/html_unescape.gperf" +      {"longrightarrow", 3, {226, 159, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 324 "src/html/html_unescape.gperf" +      {"cupdot", 3, {226, 138, 141}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 11 "src/html/html_unescape.gperf" +      {"ac", 3, {226, 136, 190}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 696 "src/html/html_unescape.gperf" +      {"hookrightarrow", 3, {226, 134, 170}}, +      {(char*)0}, {(char*)0}, +#line 1108 "src/html/html_unescape.gperf" +      {"NegativeThickSpace", 3, {226, 128, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1756 "src/html/html_unescape.gperf" +      {"subE", 3, {226, 171, 133}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1901 "src/html/html_unescape.gperf" +      {"twoheadrightarrow", 3, {226, 134, 160}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 430 "src/html/html_unescape.gperf" +      {"downharpoonright", 3, {226, 135, 130}}, +#line 429 "src/html/html_unescape.gperf" +      {"downharpoonleft", 3, {226, 135, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 20 "src/html/html_unescape.gperf" +      {"aelig", 2, {195, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1535 "src/html/html_unescape.gperf" +      {"rdldhar", 3, {226, 165, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 332 "src/html/html_unescape.gperf" +      {"curlywedge", 3, {226, 139, 143}}, +      {(char*)0}, +#line 708 "src/html/html_unescape.gperf" +      {"hybull", 3, {226, 129, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1757 "src/html/html_unescape.gperf" +      {"sube", 3, {226, 138, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 975 "src/html/html_unescape.gperf" +      {"Longrightarrow", 3, {226, 159, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 240 "src/html/html_unescape.gperf" +      {"Cedilla", 2, {194, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1189 "src/html/html_unescape.gperf" +      {"notinva", 3, {226, 136, 137}}, +#line 1778 "src/html/html_unescape.gperf" +      {"SucceedsEqual", 3, {226, 170, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 888 "src/html/html_unescape.gperf" +      {"leftrightarrow", 3, {226, 134, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1750 "src/html/html_unescape.gperf" +      {"straightepsilon", 2, {207, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 32 "src/html/html_unescape.gperf" +      {"amalg", 3, {226, 168, 191}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 81 "src/html/html_unescape.gperf" +      {"atilde", 2, {195, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1568 "src/html/html_unescape.gperf" +      {"RightCeiling", 3, {226, 140, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 890 "src/html/html_unescape.gperf" +      {"Leftrightarrow", 3, {226, 135, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1771 "src/html/html_unescape.gperf" +      {"subsim", 3, {226, 171, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 2023 "src/html/html_unescape.gperf" +      {"VerticalLine", 1, {124}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1590 "src/html/html_unescape.gperf" +      {"RightUpVector", 3, {226, 134, 190}}, +      {(char*)0}, {(char*)0}, +#line 1589 "src/html/html_unescape.gperf" +      {"RightUpVectorBar", 3, {226, 165, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1572 "src/html/html_unescape.gperf" +      {"RightDownVector", 3, {226, 135, 130}}, +      {(char*)0}, {(char*)0}, +#line 1571 "src/html/html_unescape.gperf" +      {"RightDownVectorBar", 3, {226, 165, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 26 "src/html/html_unescape.gperf" +      {"alefsym", 3, {226, 132, 181}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 256 "src/html/html_unescape.gperf" +      {"circlearrowright", 3, {226, 134, 187}}, +#line 255 "src/html/html_unescape.gperf" +      {"circlearrowleft", 3, {226, 134, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 781 "src/html/html_unescape.gperf" +      {"Iukcy", 2, {208, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1377 "src/html/html_unescape.gperf" +      {"otimesas", 3, {226, 168, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 754 "src/html/html_unescape.gperf" +      {"intercal", 3, {226, 138, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1846 "src/html/html_unescape.gperf" +      {"thickapprox", 3, {226, 137, 136}}, +      {(char*)0}, {(char*)0}, +#line 799 "src/html/html_unescape.gperf" +      {"jukcy", 2, {209, 148}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1204 "src/html/html_unescape.gperf" +      {"notniva", 3, {226, 136, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1444 "src/html/html_unescape.gperf" +      {"precnapprox", 3, {226, 170, 185}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 336 "src/html/html_unescape.gperf" +      {"cuvee", 3, {226, 139, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 73 "src/html/html_unescape.gperf" +      {"aring", 2, {195, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 233 "src/html/html_unescape.gperf" +      {"ccirc", 2, {196, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1563 "src/html/html_unescape.gperf" +      {"rightarrow", 3, {226, 134, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 753 "src/html/html_unescape.gperf" +      {"Integral", 3, {226, 136, 171}}, +#line 2061 "src/html/html_unescape.gperf" +      {"xcirc", 3, {226, 151, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 797 "src/html/html_unescape.gperf" +      {"jsercy", 2, {209, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 250 "src/html/html_unescape.gperf" +      {"checkmark", 3, {226, 156, 147}}, +      {(char*)0}, +#line 2025 "src/html/html_unescape.gperf" +      {"VerticalTilde", 3, {226, 137, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 183 "src/html/html_unescape.gperf" +      {"boxvH", 3, {226, 149, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1211 "src/html/html_unescape.gperf" +      {"NotRightTriangleBar", 3, {226, 167, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1213 "src/html/html_unescape.gperf" +      {"NotRightTriangleEqual", 3, {226, 139, 173}}, +#line 1212 "src/html/html_unescape.gperf" +      {"NotRightTriangle", 3, {226, 139, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 906 "src/html/html_unescape.gperf" +      {"LeftVectorBar", 3, {226, 165, 146}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 182 "src/html/html_unescape.gperf" +      {"boxvh", 3, {226, 148, 188}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 150 "src/html/html_unescape.gperf" +      {"boxbox", 3, {226, 167, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2095 "src/html/html_unescape.gperf" +      {"ycy", 2, {209, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1758 "src/html/html_unescape.gperf" +      {"subedot", 3, {226, 171, 131}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1707 "src/html/html_unescape.gperf" +      {"SOFTcy", 2, {208, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1565 "src/html/html_unescape.gperf" +      {"Rightarrow", 3, {226, 135, 146}}, +      {(char*)0}, +#line 29 "src/html/html_unescape.gperf" +      {"alpha", 2, {206, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1672 "src/html/html_unescape.gperf" +      {"shchcy", 2, {209, 137}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1708 "src/html/html_unescape.gperf" +      {"softcy", 2, {209, 140}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 18 "src/html/html_unescape.gperf" +      {"acy", 2, {208, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2093 "src/html/html_unescape.gperf" +      {"ycirc", 2, {197, 183}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 117 "src/html/html_unescape.gperf" +      {"bigcirc", 3, {226, 151, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 736 "src/html/html_unescape.gperf" +      {"ImaginaryI", 3, {226, 133, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 70 "src/html/html_unescape.gperf" +      {"approx", 3, {226, 137, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1801 "src/html/html_unescape.gperf" +      {"SupersetEqual", 3, {226, 138, 135}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2043 "src/html/html_unescape.gperf" +      {"vzigzag", 3, {226, 166, 154}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 315 "src/html/html_unescape.gperf" +      {"cuesc", 3, {226, 139, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1939 "src/html/html_unescape.gperf" +      {"UnderParenthesis", 3, {226, 143, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 15 "src/html/html_unescape.gperf" +      {"acirc", 2, {195, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1774 "src/html/html_unescape.gperf" +      {"succapprox", 3, {226, 170, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1040 "src/html/html_unescape.gperf" +      {"mcomma", 3, {226, 168, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 48 "src/html/html_unescape.gperf" +      {"angmsdae", 3, {226, 166, 172}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 45 "src/html/html_unescape.gperf" +      {"angmsdab", 3, {226, 166, 169}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 49 "src/html/html_unescape.gperf" +      {"angmsdaf", 3, {226, 166, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 56 "src/html/html_unescape.gperf" +      {"angsph", 3, {226, 136, 162}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1026 "src/html/html_unescape.gperf" +      {"luruhar", 3, {226, 165, 166}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 47 "src/html/html_unescape.gperf" +      {"angmsdad", 3, {226, 166, 171}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1900 "src/html/html_unescape.gperf" +      {"twoheadleftarrow", 3, {226, 134, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 340 "src/html/html_unescape.gperf" +      {"cylcty", 3, {226, 140, 173}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1751 "src/html/html_unescape.gperf" +      {"straightphi", 2, {207, 149}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1073 "src/html/html_unescape.gperf" +      {"multimap", 3, {226, 138, 184}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1562 "src/html/html_unescape.gperf" +      {"RightArrowBar", 3, {226, 135, 165}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 868 "src/html/html_unescape.gperf" +      {"ldrushar", 3, {226, 165, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 872 "src/html/html_unescape.gperf" +      {"LeftAngleBracket", 3, {226, 159, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1630 "src/html/html_unescape.gperf" +      {"ruluhar", 3, {226, 165, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 329 "src/html/html_unescape.gperf" +      {"curlyeqprec", 3, {226, 139, 158}}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2106 "src/html/html_unescape.gperf" +      {"yucy", 2, {209, 142}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1025 "src/html/html_unescape.gperf" +      {"lurdshar", 3, {226, 165, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 675 "src/html/html_unescape.gperf" +      {"hardcy", 2, {209, 138}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1574 "src/html/html_unescape.gperf" +      {"rightharpoondown", 3, {226, 135, 129}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1575 "src/html/html_unescape.gperf" +      {"rightharpoonup", 3, {226, 135, 128}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 674 "src/html/html_unescape.gperf" +      {"HARDcy", 2, {208, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1768 "src/html/html_unescape.gperf" +      {"SubsetEqual", 3, {226, 138, 134}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 385 "src/html/html_unescape.gperf" +      {"digamma", 2, {207, 157}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1918 "src/html/html_unescape.gperf" +      {"udblac", 2, {197, 177}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1786 "src/html/html_unescape.gperf" +      {"SuchThat", 3, {226, 136, 139}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 337 "src/html/html_unescape.gperf" +      {"cuwed", 3, {226, 139, 143}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1917 "src/html/html_unescape.gperf" +      {"Udblac", 2, {197, 176}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 50 "src/html/html_unescape.gperf" +      {"angmsdag", 3, {226, 166, 174}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 51 "src/html/html_unescape.gperf" +      {"angmsdah", 3, {226, 166, 175}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2022 "src/html/html_unescape.gperf" +      {"VerticalBar", 3, {226, 136, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 2024 "src/html/html_unescape.gperf" +      {"VerticalSeparator", 3, {226, 157, 152}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 1567 "src/html/html_unescape.gperf" +      {"rightarrowtail", 3, {226, 134, 163}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 1321 "src/html/html_unescape.gperf" +      {"odblac", 2, {197, 145}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 1782 "src/html/html_unescape.gperf" +      {"succnapprox", 3, {226, 170, 186}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 46 "src/html/html_unescape.gperf" +      {"angmsdac", 3, {226, 166, 170}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 1320 "src/html/html_unescape.gperf" +      {"Odblac", 2, {197, 144}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, +#line 318 "src/html/html_unescape.gperf" +      {"cupbrcap", 3, {226, 169, 136}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 44 "src/html/html_unescape.gperf" +      {"angmsdaa", 3, {226, 166, 168}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, +#line 330 "src/html/html_unescape.gperf" +      {"curlyeqsucc", 3, {226, 139, 159}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +#line 334 "src/html/html_unescape.gperf" +      {"curvearrowleft", 3, {226, 134, 182}}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0}, +      {(char*)0}, {(char*)0}, +#line 335 "src/html/html_unescape.gperf" +      {"curvearrowright", 3, {226, 134, 183}} +    }; + +  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) +    { +      register int key = hash_entity (str, len); + +      if (key <= MAX_HASH_VALUE && key >= 0) +        if (len == lengthtable[key]) +          { +            register const char *s = wordlist[key].entity; + +            if (s && *str == *s && !memcmp (str + 1, s + 1, len - 1)) +              return &wordlist[key]; +          } +    } +  return 0; +} diff --git a/src/inlines.c b/src/inlines.c index f75c846..71d75e9 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -1,251 +1,216 @@  #include <stdlib.h> +#include <string.h>  #include <stdio.h>  #include <stdbool.h>  #include <ctype.h> -#include "bstrlib.h" +  #include "stmd.h" -#include "uthash.h" -#include "debug.h" -#include "scanners.h" +#include "html/houdini.h"  #include "utf8.h" +#include "scanners.h" +#include "inlines.h" + +typedef struct Subject { +	chunk input; +	int pos; +	int label_nestlevel; +	reference_map *refmap; +} subject; + +static node_inl *parse_chunk_inlines(chunk *chunk, reference_map *refmap); +static node_inl *parse_inlines_while(subject* subj, int (*f)(subject*)); +static int parse_inline(subject* subj, node_inl ** last); -extern void free_reference(reference *ref) { -  bdestroy(ref->label); -  bdestroy(ref->url); -  bdestroy(ref->title); -  free(ref); -} - -extern void free_reference_map(reference **refmap) { -  /* free the hash table contents */ -  reference *s; -  reference *tmp; -  if (refmap != NULL) { -    HASH_ITER(hh, *refmap, s, tmp) { -      HASH_DEL(*refmap, s); -      free_reference(s); -    } -    free(refmap); -  } -} - -// normalize reference:  collapse internal whitespace to single space, -// remove leading/trailing whitespace, case fold -static bstring normalize_reference(bstring s) -{ -  bstring normalized = case_fold(s); -  int pos = 0; -  int startpos; -  char c; -  while ((c = bchar(normalized, pos))) { -    if (isspace(c)) { -      startpos = pos; -      // skip til next non-space -      pos++; -      while (isspace(bchar(s, pos))) { -        pos++; -      } -      bdelete(normalized, startpos, pos - startpos); -      binsertch(normalized, startpos, 1, ' '); -      pos = startpos + 1; -    } -    pos++; -  } -  btrimws(normalized); -  return normalized; -} - -// Returns reference if refmap contains a reference with matching -// label, otherwise NULL. -extern reference* lookup_reference(reference** refmap, bstring lab) -{ -  reference * ref = NULL; -  bstring label = normalize_reference(lab); -  if (refmap != NULL) { -    HASH_FIND_STR(*refmap, (char*) label->data, ref); -  } -  bdestroy(label); -  return ref; -} - -extern reference* make_reference(bstring label, bstring url, bstring title) -{ -  reference * ref; -  ref = malloc(sizeof(reference)); -  ref->label = normalize_reference(label); -  ref->url = bstrcpy(url); -  ref->title = bstrcpy(title); -  return ref; -} - -extern void add_reference(reference** refmap, reference* ref) -{ -  reference * t = NULL; -  HASH_FIND(hh, *refmap, (char*) ref->label->data, -            (unsigned) blength(ref->label), t); -  if (t == NULL) { -    HASH_ADD_KEYPTR(hh, *refmap, (char*) ref->label->data, -                    (unsigned) blength(ref->label), ref); -  } else { -    free_reference(ref);  // we free this now since it won't be in the refmap -  } +static void subject_from_chunk(subject *e, chunk *chunk, reference_map *refmap); +static void subject_from_buf(subject *e, strbuf *buffer, reference_map *refmap); +static int subject_find_special_char(subject *subj); + +static unsigned char *bufdup(const unsigned char *buf) +{ +	unsigned char *new = NULL; + +	if (buf) { +		int len = strlen((char *)buf); +		new = malloc(len + 1); +		memcpy(new, buf, len + 1); +	} + +	return new; +} + +static inline node_inl *make_link_(node_inl *label, unsigned char *url, unsigned char *title) +{ +	node_inl* e = (node_inl*) malloc(sizeof(node_inl)); +	e->tag = INL_LINK; +	e->content.linkable.label = label; +	e->content.linkable.url   = url; +	e->content.linkable.title = title; +	e->next = NULL; +	return e; +} + +inline static node_inl* make_ref_link(node_inl* label, reference *ref) +{ +	return make_link_(label, bufdup(ref->url), bufdup(ref->title)); +} + +inline static node_inl* make_autolink(node_inl* label, chunk url, int is_email) +{ +	return make_link_(label, clean_autolink(&url, is_email), NULL);  }  // Create an inline with a linkable string value. -inline static inl* make_linkable(int t, inl* label, bstring url, bstring title) +inline static node_inl* make_link(node_inl* label, chunk url, chunk title)  { -  inl* e = (inl*) malloc(sizeof(inl)); -  e->tag = t; -  e->content.linkable.label = label; -  e->content.linkable.url   = url; -  e->content.linkable.title = title; -  e->next = NULL; -  return e; +	return make_link_(label, clean_url(&url), clean_title(&title));  } -inline static inl* make_inlines(int t, inl* contents) +inline static node_inl* make_inlines(int t, node_inl* contents)  { -  inl* e = (inl*) malloc(sizeof(inl)); -  e->tag = t; -  e->content.inlines = contents; -  e->next = NULL; -  return e; +	node_inl* e = (node_inl*) malloc(sizeof(node_inl)); +	e->tag = t; +	e->content.inlines = contents; +	e->next = NULL; +	return e;  }  // Create an inline with a literal string value. -inline static inl* make_literal(int t, bstring s) +inline static node_inl* make_literal(int t, chunk s)  { -  inl* e = (inl*) malloc(sizeof(inl)); -  e->tag = t; -  e->content.literal = s; -  e->next = NULL; -  return e; +	node_inl* e = (node_inl*) malloc(sizeof(node_inl)); +	e->tag = t; +	e->content.literal = s; +	e->next = NULL; +	return e;  }  // Create an inline with no value. -inline static inl* make_simple(int t) +inline static node_inl* make_simple(int t)  { -  inl* e = (inl*) malloc(sizeof(inl)); -  e->tag = t; -  e->next = NULL; -  return e; +	node_inl* e = (node_inl*) malloc(sizeof(node_inl)); +	e->tag = t; +	e->next = NULL; +	return e;  }  // Macros for creating various kinds of inlines. -#define make_str(s) make_literal(str, s) -#define make_code(s) make_literal(code, s) -#define make_raw_html(s) make_literal(raw_html, s) -#define make_entity(s) make_literal(entity, s) -#define make_linebreak() make_simple(linebreak) -#define make_softbreak() make_simple(softbreak) -#define make_link(label, url, title) make_linkable(link, label, url, title) -#define make_image(alt, url, title) make_linkable(image, alt, url, title) -#define make_emph(contents) make_inlines(emph, contents) -#define make_strong(contents) make_inlines(strong, contents) +#define make_str(s) make_literal(INL_STRING, s) +#define make_code(s) make_literal(INL_CODE, s) +#define make_raw_html(s) make_literal(INL_RAW_HTML, s) +#define make_linebreak() make_simple(INL_LINEBREAK) +#define make_softbreak() make_simple(INL_SOFTBREAK) +#define make_emph(contents) make_inlines(INL_EMPH, contents) +#define make_strong(contents) make_inlines(INL_STRONG, contents)  // Free an inline list. -extern void free_inlines(inl* e) -{ -  inl * next; -  while (e != NULL) { -    switch (e->tag){ -    case str: -    case raw_html: -    case code: -    case entity: -      bdestroy(e->content.literal); -      break; -    case linebreak: -    case softbreak: -      break; -    case link: -    case image: -      bdestroy(e->content.linkable.url); -      bdestroy(e->content.linkable.title); -      free_inlines(e->content.linkable.label); -      break; -    case emph: -    case strong: -      free_inlines(e->content.inlines); -      break; -    default: -      break; -    } -    next = e->next; -    free(e); -    e = next; -  } +extern void free_inlines(node_inl* e) +{ +	node_inl * next; +	while (e != NULL) { +		switch (e->tag){ +			case INL_STRING: +			case INL_RAW_HTML: +			case INL_CODE: +				chunk_free(&e->content.literal); +				break; +			case INL_LINEBREAK: +			case INL_SOFTBREAK: +				break; +			case INL_LINK: +			case INL_IMAGE: +				free(e->content.linkable.url); +				free(e->content.linkable.title); +				free_inlines(e->content.linkable.label); +				break; +			case INL_EMPH: +			case INL_STRONG: +				free_inlines(e->content.inlines); +				break; +			default: +				break; +		} +		next = e->next; +		free(e); +		e = next; +	}  }  // Append inline list b to the end of inline list a.  // Return pointer to head of new list. -inline static inl* append_inlines(inl* a, inl* b) +inline static node_inl* append_inlines(node_inl* a, node_inl* b)  { -  if (a == NULL) {  // NULL acts like an empty list -    return b; -  } -  inl* cur = a; -  while (cur->next) { -    cur = cur->next; -  } -  cur->next = b; -  return a; +	if (a == NULL) {  // NULL acts like an empty list +		return b; +	} +	node_inl* cur = a; +	while (cur->next) { +		cur = cur->next; +	} +	cur->next = b; +	return a;  } -// Make a 'subject' from an input string. -static subject* make_subject(bstring s, reference** refmap) +static void subject_from_buf(subject *e, strbuf *buffer, reference_map *refmap)  { -  subject* e = (subject*) malloc(sizeof(subject)); -  // remove final whitespace -  brtrimws(s); -  e->buffer = s; -  e->pos = 0; -  e->label_nestlevel = 0; -  e->reference_map = refmap; -  return e; +	e->input.data = buffer->ptr; +	e->input.len = buffer->size; +	e->input.alloc = 0; +	e->pos = 0; +	e->label_nestlevel = 0; +	e->refmap = refmap; + +	chunk_rtrim(&e->input); +} + +static void subject_from_chunk(subject *e, chunk *chunk, reference_map *refmap) +{ +	e->input.data = chunk->data; +	e->input.len = chunk->len; +	e->input.alloc = 0; +	e->pos = 0; +	e->label_nestlevel = 0; +	e->refmap = refmap; + +	chunk_rtrim(&e->input);  }  inline static int isbacktick(int c)  { -  return (c == '`'); +	return (c == '`');  } -// Return the next character in the subject, without advancing. -// Return 0 if at the end of the subject. -#define peek_char(subj) bchar(subj->buffer, subj->pos) +static inline unsigned char peek_char(subject *subj) +{ +	return (subj->pos < subj->input.len) ? subj->input.data[subj->pos] : 0; +} + +static inline unsigned char peek_at(subject *subj, int pos) +{ +	return subj->input.data[pos]; +}  // Return true if there are more characters in the subject.  inline static int is_eof(subject* subj)  { -  return (subj->pos >= blength(subj->buffer)); +	return (subj->pos >= subj->input.len);  }  // Advance the subject.  Doesn't check for eof. -#define advance(subj) subj->pos += 1 +#define advance(subj) (subj)->pos += 1  // Take characters while a predicate holds, and return a string. -inline static bstring take_while(subject* subj, int (*f)(int)) +inline static chunk take_while(subject* subj, int (*f)(int))  { -  unsigned char c; -  int startpos = subj->pos; -  int len = 0; -  while ((c = peek_char(subj)) && (*f)(c)) { -    advance(subj); -    len++; -  } -  return bmidstr(subj->buffer, startpos, len); -} +	unsigned char c; +	int startpos = subj->pos; +	int len = 0; -// Take one character and return a string, or NULL if eof. -inline static bstring take_one(subject* subj) -{ -  int startpos = subj->pos; -  if (is_eof(subj)){ -    return NULL; -  } else { -    advance(subj); -    return bmidstr(subj->buffer, startpos, 1); -  } +	while ((c = peek_char(subj)) && (*f)(c)) { +		advance(subj); +		len++; +	} + +	return chunk_dup(&subj->input, startpos, len);  }  // Try to process a backtick code span that began with a @@ -255,381 +220,353 @@ inline static bstring take_one(subject* subj)  // after the closing backticks.  static int scan_to_closing_backticks(subject* subj, int openticklength)  { -  // read non backticks -  char c; -  while ((c = peek_char(subj)) && c != '`') { -    advance(subj); -  } -  if (is_eof(subj)) { -    return 0;  // did not find closing ticks, return 0 -  } -  int numticks = 0; -  while (peek_char(subj) == '`') { -      advance(subj); -      numticks++; -  } -  if (numticks != openticklength){ -    return(scan_to_closing_backticks(subj, openticklength)); -  } -  return (subj->pos); -} - -// Destructively modify bstring, collapsing consecutive -// space and newline characters into a single space. -static int normalize_whitespace(bstring s) -{ -  bool last_char_was_space = false; -  int pos = 0; -  char c; -  while ((c = bchar(s, pos))) { -    switch (c) { -    case ' ': -      if (last_char_was_space) { -        bdelete(s, pos, 1); -      } else { -        pos++; -      } -      last_char_was_space = true; -      break; -    case '\n': -      if (last_char_was_space) { -        bdelete(s, pos, 1); -      } else { -        bdelete(s, pos, 1); -        binsertch(s, pos, 1, ' '); -        pos++; -      } -      last_char_was_space = true; -      break; -    default: -      pos++; -      last_char_was_space = false; -    } -  } -  return 0; +	// read non backticks +	char c; +	while ((c = peek_char(subj)) && c != '`') { +		advance(subj); +	} +	if (is_eof(subj)) { +		return 0;  // did not find closing ticks, return 0 +	} +	int numticks = 0; +	while (peek_char(subj) == '`') { +		advance(subj); +		numticks++; +	} +	if (numticks != openticklength){ +		return(scan_to_closing_backticks(subj, openticklength)); +	} +	return (subj->pos);  }  // Parse backtick code section or raw backticks, return an inline.  // Assumes that the subject has a backtick at the current position. -static inl* handle_backticks(subject *subj) -{ -  bstring openticks = take_while(subj, isbacktick); -  bstring result; -  int ticklength = blength(openticks); -  int startpos = subj->pos; -  int endpos = scan_to_closing_backticks(subj, ticklength); -  if (endpos == 0) { // not found -    subj->pos = startpos; // rewind -    return make_str(openticks); -  } else { -    bdestroy(openticks); -    result = bmidstr(subj->buffer, startpos, endpos - startpos - ticklength); -    btrimws(result); -    normalize_whitespace(result); -    return make_code(result); -  } +static node_inl* handle_backticks(subject *subj) +{ +	chunk openticks = take_while(subj, isbacktick); +	int startpos = subj->pos; +	int endpos = scan_to_closing_backticks(subj, openticks.len); + +	if (endpos == 0) { // not found +		subj->pos = startpos; // rewind +		return make_str(openticks); +	} else { +		strbuf buf = GH_BUF_INIT; + +		strbuf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len); +		strbuf_trim(&buf); +		strbuf_normalize_whitespace(&buf); + +		return make_code(chunk_buf_detach(&buf)); +	}  }  // Scan ***, **, or * and return number scanned, or 0.  // Don't advance position.  static int scan_delims(subject* subj, char c, bool * can_open, bool * can_close)  { -  int numdelims = 0; -  char char_before, char_after; -  int startpos = subj->pos; - -  char_before = subj->pos == 0 ? '\n' : bchar(subj->buffer, subj->pos - 1); -  while (peek_char(subj) == c) { -    numdelims++; -    advance(subj); -  } -  char_after = peek_char(subj); -  *can_open = numdelims > 0 && numdelims <= 3 && !isspace(char_after); -  *can_close = numdelims > 0 && numdelims <= 3 && !isspace(char_before); -  if (c == '_') { -    *can_open = *can_open && !isalnum(char_before); -    *can_close = *can_close && !isalnum(char_after); -  } -  subj->pos = startpos; -  return numdelims; +	int numdelims = 0; +	char char_before, char_after; +	int startpos = subj->pos; + +	char_before = subj->pos == 0 ? '\n' : peek_at(subj, subj->pos - 1); +	while (peek_char(subj) == c) { +		numdelims++; +		advance(subj); +	} +	char_after = peek_char(subj); +	*can_open = numdelims > 0 && numdelims <= 3 && !isspace(char_after); +	*can_close = numdelims > 0 && numdelims <= 3 && !isspace(char_before); +	if (c == '_') { +		*can_open = *can_open && !isalnum(char_before); +		*can_close = *can_close && !isalnum(char_after); +	} +	subj->pos = startpos; +	return numdelims;  }  // Parse strong/emph or a fallback.  // Assumes the subject has '_' or '*' at the current position. -static inl* handle_strong_emph(subject* subj, char c) -{ -  bool can_open, can_close; -  inl * result = NULL; -  inl ** last = malloc(sizeof(inl *)); -  inl * new; -  inl * il; -  inl * first_head = NULL; -  inl * first_close = NULL; -  int first_close_delims = 0; -  int numdelims; - -  *last = NULL; - -  numdelims = scan_delims(subj, c, &can_open, &can_close); -  subj->pos += numdelims; - -  new = make_str(bmidstr(subj->buffer, subj->pos - numdelims, numdelims)); -  *last = new; -  first_head = new; -  result = new; - -  if (!can_open || numdelims == 0) { -    goto done; -  } - -  switch (numdelims) { -  case 1: -    while (true) { -      numdelims = scan_delims(subj, c, &can_open, &can_close); -      if (numdelims >= 1 && can_close) { -        subj->pos += 1; -        first_head->tag = emph; -        bdestroy(first_head->content.literal); -        first_head->content.inlines = first_head->next; -        first_head->next = NULL; -        goto done; -      } else { -        if (!parse_inline(subj, last)) { -          goto done; -        } -      } -    } -    break; -  case 2: -    while (true) { -      numdelims = scan_delims(subj, c, &can_open, &can_close); -      if (numdelims >= 2 && can_close) { -        subj->pos += 2; -        first_head->tag = strong; -        bdestroy(first_head->content.literal); -        first_head->content.inlines = first_head->next; -        first_head->next = NULL; -        goto done; -      } else { -        if (!parse_inline(subj, last)) { -          goto done; -        } -      } -    } -    break; -  case 3: -    while (true) { -      numdelims = scan_delims(subj, c, &can_open, &can_close); -      if (can_close && numdelims >= 1 && numdelims <= 3 && -          numdelims != first_close_delims) { -        new = make_str(bmidstr(subj->buffer, subj->pos, numdelims)); -        append_inlines(*last, new); -        *last = new; - -        if (first_close_delims == 1 && numdelims > 2) { -          numdelims = 2; -        } else if (first_close_delims == 2) { -          numdelims = 1; -        } else if (numdelims == 3) { -          // If we opened with ***, we interpret it as ** followed by * -          // giving us <strong><em> -          numdelims = 1; -        } - -        subj->pos += numdelims; -        if (first_close) { -          first_head->tag = first_close_delims == 1 ? strong : emph; -          bdestroy(first_head->content.literal); -          first_head->content.inlines = -            make_inlines(first_close_delims == 1 ? emph : strong, -                         first_head->next); - -          il = first_head->next; -          while (il->next && il->next != first_close) { -            il = il->next; -          } -          il->next = NULL; - -          first_head->content.inlines->next = first_close->next; - -          il = first_head->content.inlines; -          while (il->next && il->next != *last) { -            il = il->next; -          } -          il->next = NULL; -          free_inlines(*last); - -          first_close->next = NULL; -          free_inlines(first_close); -          first_head->next = NULL; -          goto done; -        } else { -          first_close = *last; -          first_close_delims = numdelims; -        } -      } else { -        if (!parse_inline(subj, last)) { -          goto done; -        } -      } -    } -    break; -  default: -    goto done; -  } - - done: -  free(last); -  return result; +static node_inl* handle_strong_emph(subject* subj, char c) +{ +	bool can_open, can_close; +	node_inl * result = NULL; +	node_inl ** last = malloc(sizeof(node_inl *)); +	node_inl * new; +	node_inl * il; +	node_inl * first_head = NULL; +	node_inl * first_close = NULL; +	int first_close_delims = 0; +	int numdelims; + +	*last = NULL; + +	numdelims = scan_delims(subj, c, &can_open, &can_close); +	subj->pos += numdelims; + +	new = make_str(chunk_dup(&subj->input, subj->pos - numdelims, numdelims)); +	*last = new; +	first_head = new; +	result = new; + +	if (!can_open || numdelims == 0) { +		goto done; +	} + +	switch (numdelims) { +		case 1: +			while (true) { +				numdelims = scan_delims(subj, c, &can_open, &can_close); +				if (numdelims >= 1 && can_close) { +					subj->pos += 1; +					first_head->tag = INL_EMPH; +					chunk_free(&first_head->content.literal); +					first_head->content.inlines = first_head->next; +					first_head->next = NULL; +					goto done; +				} else { +					if (!parse_inline(subj, last)) { +						goto done; +					} +				} +			} +			break; +		case 2: +			while (true) { +				numdelims = scan_delims(subj, c, &can_open, &can_close); +				if (numdelims >= 2 && can_close) { +					subj->pos += 2; +					first_head->tag = INL_STRONG; +					chunk_free(&first_head->content.literal); +					first_head->content.inlines = first_head->next; +					first_head->next = NULL; +					goto done; +				} else { +					if (!parse_inline(subj, last)) { +						goto done; +					} +				} +			} +			break; +		case 3: +			while (true) { +				numdelims = scan_delims(subj, c, &can_open, &can_close); +				if (can_close && numdelims >= 1 && numdelims <= 3 && +						numdelims != first_close_delims) { +					new = make_str(chunk_dup(&subj->input, subj->pos, numdelims)); +					append_inlines(*last, new); +					*last = new; +					if (first_close_delims == 1 && numdelims > 2) { +						numdelims = 2; +					} else if (first_close_delims == 2) { +						numdelims = 1; +					} else if (numdelims == 3) { +						// If we opened with ***, we interpret it as ** followed by * +						// giving us <strong><em> +						numdelims = 1; +					} +					subj->pos += numdelims; +					if (first_close) { +						first_head->tag = first_close_delims == 1 ? INL_STRONG : INL_EMPH; +						chunk_free(&first_head->content.literal); +						first_head->content.inlines = +							make_inlines(first_close_delims == 1 ? INL_EMPH : INL_STRONG, +									first_head->next); + +						il = first_head->next; +						while (il->next && il->next != first_close) { +							il = il->next; +						} +						il->next = NULL; + +						first_head->content.inlines->next = first_close->next; + +						il = first_head->content.inlines; +						while (il->next && il->next != *last) { +							il = il->next; +						} +						il->next = NULL; +						free_inlines(*last); + +						first_close->next = NULL; +						free_inlines(first_close); +						first_head->next = NULL; +						goto done; +					} else { +						first_close = *last; +						first_close_delims = numdelims; +					} +				} else { +					if (!parse_inline(subj, last)) { +						goto done; +					} +				} +			} +			break; +		default: +			goto done; +	} + +done: +	free(last); +	return result;  }  // Parse backslash-escape or just a backslash, returning an inline. -static inl* handle_backslash(subject *subj) +static node_inl* handle_backslash(subject *subj)  { -  advance(subj); -  unsigned char nextchar = peek_char(subj); -  if (ispunct(nextchar)) {  // only ascii symbols and newline can be escaped -    advance(subj); -    return make_str(bformat("%c", nextchar)); -  } else if (nextchar == '\n') { -    advance(subj); -    return make_linebreak(); -  } else { -    return make_str(bfromcstr("\\")); -  } +	advance(subj); +	unsigned char nextchar = peek_char(subj); +	if (ispunct(nextchar)) {  // only ascii symbols and newline can be escaped +		advance(subj); +		return make_str(chunk_dup(&subj->input, subj->pos - 1, 1)); +	} else if (nextchar == '\n') { +		advance(subj); +		return make_linebreak(); +	} else { +		return make_str(chunk_literal("\\")); +	}  }  // Parse an entity or a regular "&" string.  // Assumes the subject has an '&' character at the current position. -static inl* handle_entity(subject* subj) +static node_inl* handle_entity(subject* subj)  { -  int match; -  inl * result; -  match = scan_entity(subj->buffer, subj->pos); -  if (match) { -    result = make_entity(bmidstr(subj->buffer, subj->pos, match)); -    subj->pos += match; -  } else { -    advance(subj); -    result = make_str(bfromcstr("&")); -  } -  return result; +	strbuf ent = GH_BUF_INIT; +	size_t len; + +	advance(subj); + +	len = houdini_unescape_ent(&ent, +		subj->input.data + subj->pos, +		subj->input.len - subj->pos +	); + +	if (len == 0) +		return make_str(chunk_literal("&")); + +	subj->pos += len; +	return make_str(chunk_buf_detach(&ent));  }  // Like make_str, but parses entities.  // Returns an inline sequence consisting of str and entity elements. -static inl * make_str_with_entities(bstring s) -{ -  inl * result = NULL; -  inl * new; -  int searchpos; -  char c; -  subject * subj = make_subject(s, NULL); - -  while ((c = peek_char(subj))) { -    switch (c) { -    case '&': -      new = handle_entity(subj); -      break; -    default: -      searchpos = bstrchrp(subj->buffer, '&', subj->pos); -      if (searchpos == BSTR_ERR) { -        searchpos = blength(subj->buffer); -      } -      new = make_str(bmidstr(subj->buffer, subj->pos, searchpos - subj->pos)); -      subj->pos = searchpos; -    } -    result = append_inlines(result, new); -  } -  free(subj); -  return result; -} - -// Destructively unescape a string: remove backslashes before punctuation chars. -extern int unescape(bstring url) -{ -  // remove backslashes before punctuation chars: -  int searchpos = 0; -  while ((searchpos = bstrchrp(url, '\\', searchpos)) != BSTR_ERR) { -    if (ispunct(bchar(url, searchpos + 1))) { -      bdelete(url, searchpos, 1); -    } else { -      searchpos++; -    } -  } -  return 0; +static node_inl *make_str_with_entities(chunk *content) +{ +	strbuf unescaped = GH_BUF_INIT; + +	if (houdini_unescape_html(&unescaped, content->data, (size_t)content->len)) { +		return make_str(chunk_buf_detach(&unescaped)); +	} else { +		return make_str(*content); +	}  }  // Clean a URL: remove surrounding whitespace and surrounding <>,  // and remove \ that escape punctuation. -static int clean_url(bstring url) +unsigned char *clean_url(chunk *url) +{ +	strbuf buf = GH_BUF_INIT; + +	chunk_trim(url); + +	if (url->len == 0) +		return NULL; + +	if (url->data[0] == '<' && url->data[url->len - 1] == '>') { +		houdini_unescape_html_f(&buf, url->data + 1, url->len - 2); +	} else { +		houdini_unescape_html_f(&buf, url->data, url->len); +	} + +	strbuf_unescape(&buf); +	return strbuf_detach(&buf); +} + +unsigned char *clean_autolink(chunk *url, int is_email)  { -  // remove surrounding <> if any: -  int urllength = blength(url); -  btrimws(url); -  if (bchar(url, 0) == '<' && bchar(url, urllength - 1) == '>') { -    bdelete(url, 0, 1); -    bdelete(url, urllength - 2, 1); -  } -  unescape(url); -  return 0; +	strbuf buf = GH_BUF_INIT; + +	chunk_trim(url); + +	if (url->len == 0) +		return NULL; + +	if (is_email) +		strbuf_puts(&buf, "mailto:"); + +	houdini_unescape_html_f(&buf, url->data, url->len); +	return strbuf_detach(&buf);  }  // Clean a title: remove surrounding quotes and remove \ that escape punctuation. -static int clean_title(bstring title) +unsigned char *clean_title(chunk *title)  { -  // remove surrounding quotes if any: -  int titlelength = blength(title); -  if ((bchar(title, 0) == '\'' && bchar(title, titlelength - 1) == '\'') || -      (bchar(title, 0) == '(' && bchar(title, titlelength - 1) == ')') || -      (bchar(title, 0) == '"' && bchar(title, titlelength - 1) == '"')) { -    bdelete(title, 0, 1); -    bdelete(title, titlelength - 2, 1); -  } -  unescape(title); -  return 0; +	strbuf buf = GH_BUF_INIT; +	unsigned char first, last; + +	if (title->len == 0) +		return NULL; + +	first = title->data[0]; +	last = title->data[title->len - 1]; + +	// remove surrounding quotes if any: +	if ((first == '\'' && last == '\'') || +		(first == '(' && last == ')') || +		(first == '"' && last == '"')) { +		houdini_unescape_html_f(&buf, title->data + 1, title->len - 2); +	} else { +		houdini_unescape_html_f(&buf, title->data, title->len); +	} + +	strbuf_unescape(&buf); +	return strbuf_detach(&buf);  }  // Parse an autolink or HTML tag.  // Assumes the subject has a '<' character at the current position. -static inl* handle_pointy_brace(subject* subj) -{ -  int matchlen = 0; -  bstring contents; -  inl* result; - -  advance(subj);  // advance past first < -  // first try to match a URL autolink -  matchlen = scan_autolink_uri(subj->buffer, subj->pos); -  if (matchlen > 0) { -    contents = bmidstr(subj->buffer, subj->pos, matchlen - 1); -    subj->pos += matchlen; -    result =  make_link(make_str_with_entities(contents), -                        bstrcpy(contents), bfromcstr("")); -    bdestroy(contents); -    return result; -  } -  // next try to match an email autolink -  matchlen = scan_autolink_email(subj->buffer, subj->pos); -  if (matchlen > 0) { -    contents = bmidstr(subj->buffer, subj->pos, matchlen - 1); -    subj->pos += matchlen; -    result = make_link(make_str_with_entities(contents), -                       bformat("mailto:%s", contents->data), -                       bfromcstr("")); -    bdestroy(contents); -    return result; -  } -  // finally, try to match an html tag -  matchlen = scan_html_tag(subj->buffer, subj->pos); -  if (matchlen > 0) { -    contents = bmidstr(subj->buffer, subj->pos, matchlen); -    binsertch(contents, 0, 1, '<'); -    subj->pos += matchlen; -    return make_raw_html(contents); -  } else {// if nothing matches, just return the opening <: -    return make_str(bfromcstr("<")); -  } +static node_inl* handle_pointy_brace(subject* subj) +{ +	int matchlen = 0; +	chunk contents; + +	advance(subj);  // advance past first < + +	// first try to match a URL autolink +	matchlen = scan_autolink_uri(&subj->input, subj->pos); +	if (matchlen > 0) { +		contents = chunk_dup(&subj->input, subj->pos, matchlen - 1); +		subj->pos += matchlen; + +		return make_autolink( +			make_str_with_entities(&contents), +			contents, 0 +		); +	} + +	// next try to match an email autolink +	matchlen = scan_autolink_email(&subj->input, subj->pos); +	if (matchlen > 0) { +		contents = chunk_dup(&subj->input, subj->pos, matchlen - 1); +		subj->pos += matchlen; + +		return make_autolink( +				make_str_with_entities(&contents), +				contents, 1 +		); +	} + +	// finally, try to match an html tag +	matchlen = scan_html_tag(&subj->input, subj->pos); +	if (matchlen > 0) { +		contents = chunk_dup(&subj->input, subj->pos - 1, matchlen + 1); +		subj->pos += matchlen; +		return make_raw_html(contents); +	} + +	// if nothing matches, just return the opening <: +	return make_str(chunk_literal("<"));  }  // Parse a link label.  Returns 1 if successful. @@ -641,366 +578,384 @@ static inl* handle_pointy_brace(subject* subj)  // markers. So, 2 below contains a link while 1 does not:  // 1. [a link `with a ](/url)` character  // 2. [a link *with emphasized ](/url) text* -static int link_label(subject* subj, bstring* raw_label) -{ -  int nestlevel = 0; -  inl* tmp = NULL; -  bstring raw; -  int startpos = subj->pos; -  if (subj->label_nestlevel) { -    // if we've already checked to the end of the subject -    // for a label, even with a different starting [, we -    // know we won't find one here and we can just return. -    // Note:  nestlevel 1 would be: [foo [bar] -    // nestlevel 2 would be: [foo [bar [baz] -    subj->label_nestlevel--; -    return 0; -  } -  advance(subj);  // advance past [ -  char c; -  while ((c = peek_char(subj)) && (c != ']' || nestlevel > 0)) { -    switch (c) { -    case '`': -      tmp = handle_backticks(subj); -      free_inlines(tmp); -      break; -    case '<': -      tmp = handle_pointy_brace(subj); -      free_inlines(tmp); -      break; -    case '[':  // nested [] -      nestlevel++; -      advance(subj); -      break; -    case ']':  // nested [] -      nestlevel--; -      advance(subj); -      break; -    case '\\': -      advance(subj); -      if (ispunct(peek_char(subj))) { -        advance(subj); -      } -      break; -    default: -      advance(subj); -    } -  } -  if (c == ']') { -    if (raw_label != NULL) { -      raw = bmidstr(subj->buffer, startpos + 1, subj->pos - (startpos + 1)); -      *raw_label = raw; -    } -    subj->label_nestlevel = 0; -    advance(subj);  // advance past ] -    return 1; -  } else { -    if (c == 0) { -      subj->label_nestlevel = nestlevel; -    } -    subj->pos = startpos; // rewind -    return 0; -  } +static int link_label(subject* subj, chunk *raw_label) +{ +	int nestlevel = 0; +	node_inl* tmp = NULL; +	int startpos = subj->pos; + +	if (subj->label_nestlevel) { +		// if we've already checked to the end of the subject +		// for a label, even with a different starting [, we +		// know we won't find one here and we can just return. +		// Note:  nestlevel 1 would be: [foo [bar] +		// nestlevel 2 would be: [foo [bar [baz] +		subj->label_nestlevel--; +		return 0; +	} + +	advance(subj);  // advance past [ +	char c; +	while ((c = peek_char(subj)) && (c != ']' || nestlevel > 0)) { +		switch (c) { +			case '`': +				tmp = handle_backticks(subj); +				free_inlines(tmp); +				break; +			case '<': +				tmp = handle_pointy_brace(subj); +				free_inlines(tmp); +				break; +			case '[':  // nested [] +				nestlevel++; +				advance(subj); +				break; +			case ']':  // nested [] +				nestlevel--; +				advance(subj); +				break; +			case '\\': +				advance(subj); +				if (ispunct(peek_char(subj))) { +					advance(subj); +				} +				break; +			default: +				advance(subj); +		} +	} +	if (c == ']') { +		*raw_label = chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1)); +		subj->label_nestlevel = 0; +		advance(subj);  // advance past ] +		return 1; +	} else { +		if (c == 0) { +			subj->label_nestlevel = nestlevel; +		} +		subj->pos = startpos; // rewind +		return 0; +	}  }  // Parse a link or the link portion of an image, or return a fallback. -static inl* handle_left_bracket(subject* subj) -{ -  inl* lab = NULL; -  inl* result = NULL; -  reference* ref; -  int n; -  int sps; -  int found_label; -  int endlabel, starturl, endurl, starttitle, endtitle, endall; -  bstring url, title, rawlabel, reflabel; -  bstring rawlabel2 = NULL; -  found_label = link_label(subj, &rawlabel); -  endlabel = subj->pos; -  if (found_label) { -    if (peek_char(subj) == '(' && -        ((sps = scan_spacechars(subj->buffer, subj->pos + 1)) > -1) && -        ((n = scan_link_url(subj->buffer, subj->pos + 1 + sps)) > -1)) { -      // try to parse an explicit link: -      starturl = subj->pos + 1 + sps; // after ( -      endurl = starturl + n; -      starttitle = endurl + scan_spacechars(subj->buffer, endurl); -      // ensure there are spaces btw url and title -      endtitle = (starttitle == endurl) ? starttitle : -                 starttitle + scan_link_title(subj->buffer, starttitle); -      endall = endtitle + scan_spacechars(subj->buffer, endtitle); -      if (bchar(subj->buffer, endall) == ')') { -        subj->pos = endall + 1; -        url = bmidstr(subj->buffer, starturl, endurl - starturl); -        clean_url(url); -        title = bmidstr(subj->buffer, starttitle, endtitle - starttitle); -        clean_title(title); -        lab = parse_inlines(rawlabel, NULL); -        bdestroy(rawlabel); -        return make_link(lab, url, title); -      } else { -        // if we get here, we matched a label but didn't get further: -        subj->pos = endlabel; -        lab = parse_inlines(rawlabel, subj->reference_map); -        bdestroy(rawlabel); -        result = append_inlines(make_str(bfromcstr("[")), -                                append_inlines(lab, -                                               make_str(bfromcstr("]")))); -        return result; -      } -    } else { -      // Check for reference link. -      // First, see if there's another label: -      subj->pos = subj->pos + scan_spacechars(subj->buffer, endlabel); -      reflabel = rawlabel; -      // if followed by a nonempty link label, we change reflabel to it: -      if (peek_char(subj) == '[' && -          link_label(subj, &rawlabel2)) { -        if (blength(rawlabel2) > 0) { -          reflabel = rawlabel2; -        } -      } else { -        subj->pos = endlabel; -      } -      // lookup rawlabel in subject->reference_map: -      ref = lookup_reference(subj->reference_map, reflabel); -      if (ref != NULL) { // found -        lab = parse_inlines(rawlabel, NULL); -        result = make_link(lab, bstrcpy(ref->url), bstrcpy(ref->title)); -      } else { -        subj->pos = endlabel; -        lab = parse_inlines(rawlabel, subj->reference_map); -        result = append_inlines(make_str(bfromcstr("[")), -                               append_inlines(lab, make_str(bfromcstr("]")))); -      } -      bdestroy(rawlabel); -      bdestroy(rawlabel2); -      return result; -    } -  } -  // If we fall through to here, it means we didn't match a link: -  advance(subj);  // advance past [ -  return make_str(bfromcstr("[")); +static node_inl* handle_left_bracket(subject* subj) +{ +	node_inl *lab = NULL; +	node_inl *result = NULL; +	reference *ref; +	int n; +	int sps; +	int found_label; +	int endlabel, starturl, endurl, starttitle, endtitle, endall; + +	chunk rawlabel; +	chunk url, title; + +	found_label = link_label(subj, &rawlabel); +	endlabel = subj->pos; + +	if (found_label) { +		if (peek_char(subj) == '(' && +				((sps = scan_spacechars(&subj->input, subj->pos + 1)) > -1) && +				((n = scan_link_url(&subj->input, subj->pos + 1 + sps)) > -1)) { + +			// try to parse an explicit link: +			starturl = subj->pos + 1 + sps; // after ( +			endurl = starturl + n; +			starttitle = endurl + scan_spacechars(&subj->input, endurl); + +			// ensure there are spaces btw url and title +			endtitle = (starttitle == endurl) ? starttitle : +				starttitle + scan_link_title(&subj->input, starttitle); + +			endall = endtitle + scan_spacechars(&subj->input, endtitle); + +			if (peek_at(subj, endall) == ')') { +				subj->pos = endall + 1; + +				url = chunk_dup(&subj->input, starturl, endurl - starturl); +				title = chunk_dup(&subj->input, starttitle, endtitle - starttitle); +				lab = parse_chunk_inlines(&rawlabel, NULL); + +				return make_link(lab, url, title); +			} else { +				// if we get here, we matched a label but didn't get further: +				subj->pos = endlabel; +				lab = parse_chunk_inlines(&rawlabel, subj->refmap); +				result = append_inlines(make_str(chunk_literal("[")), +						append_inlines(lab, +							make_str(chunk_literal("]")))); +				return result; +			} +		} else { +			chunk rawlabel_tmp; +			chunk reflabel; + +			// Check for reference link. +			// First, see if there's another label: +			subj->pos = subj->pos + scan_spacechars(&subj->input, endlabel); +			reflabel = rawlabel; + +			// if followed by a nonempty link label, we change reflabel to it: +			if (peek_char(subj) == '[' && link_label(subj, &rawlabel_tmp)) { +				if (rawlabel_tmp.len > 0) +					reflabel = rawlabel_tmp; +			} else { +				subj->pos = endlabel; +			} + +			// lookup rawlabel in subject->reference_map: +			ref = reference_lookup(subj->refmap, &reflabel); +			if (ref != NULL) { // found +				lab = parse_chunk_inlines(&rawlabel, NULL); +				result = make_ref_link(lab, ref); +			} else { +				subj->pos = endlabel; +				lab = parse_chunk_inlines(&rawlabel, subj->refmap); +				result = append_inlines(make_str(chunk_literal("[")), +						append_inlines(lab, make_str(chunk_literal("]")))); +			} +			return result; +		} +	} +	// If we fall through to here, it means we didn't match a link: +	advance(subj);  // advance past [ +	return make_str(chunk_literal("["));  }  // Parse a hard or soft linebreak, returning an inline.  // Assumes the subject has a newline at the current position. -static inl* handle_newline(subject *subj) -{ -  int nlpos = subj->pos; -  // skip over newline -  advance(subj); -  // skip spaces at beginning of line -  while (peek_char(subj) == ' ') { -    advance(subj); -  } -  if (nlpos > 1 && -      bchar(subj->buffer, nlpos - 1) == ' ' && -      bchar(subj->buffer, nlpos - 2) == ' ') { -    return make_linebreak(); -  } else { -    return make_softbreak(); -  } +static node_inl* handle_newline(subject *subj) +{ +	int nlpos = subj->pos; +	// skip over newline +	advance(subj); +	// skip spaces at beginning of line +	while (peek_char(subj) == ' ') { +		advance(subj); +	} +	if (nlpos > 1 && +			peek_at(subj, nlpos - 1) == ' ' && +			peek_at(subj, nlpos - 2) == ' ') { +		return make_linebreak(); +	} else { +		return make_softbreak(); +	}  }  inline static int not_eof(subject* subj)  { -  return !is_eof(subj); +	return !is_eof(subj);  }  // Parse inlines while a predicate is satisfied.  Return inlines. -extern inl* parse_inlines_while(subject* subj, int (*f)(subject*)) +extern node_inl* parse_inlines_while(subject* subj, int (*f)(subject*))  { -  inl* result = NULL; -  inl** last = &result; -  while ((*f)(subj) && parse_inline(subj, last)) { -  } -  return result; +	node_inl* result = NULL; +	node_inl** last = &result; +	while ((*f)(subj) && parse_inline(subj, last)) { +	} +	return result; +} + +node_inl *parse_chunk_inlines(chunk *chunk, reference_map *refmap) +{ +	subject subj; +	subject_from_chunk(&subj, chunk, refmap); +	return parse_inlines_while(&subj, not_eof); +} + +static int subject_find_special_char(subject *subj) +{ +	// "\n\\`&_*[]<!" +	static const int8_t SPECIAL_CHARS[256] = { +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, +		1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +	int n = subj->pos + 1; + +	while (n < subj->input.len) { +		if (SPECIAL_CHARS[subj->input.data[n]]) +			return n; +		n++; +	} + +	return subj->input.len;  }  // Parse an inline, advancing subject, and add it to last element.  // Adjust tail to point to new last element of list.  // Return 0 if no inline can be parsed, 1 otherwise. -extern int parse_inline(subject* subj, inl ** last) -{ -  inl* new = NULL; -  bstring contents; -  bstring special_chars; -  unsigned char c; -  int endpos; -  c = peek_char(subj); -  if (c == 0) { -    return 0; -  } -  switch(c){ -    case '\n': -      new = handle_newline(subj); -      break; -    case '`': -      new = handle_backticks(subj); -      break; -    case '\\': -      new = handle_backslash(subj); -      break; -    case '&': -      new = handle_entity(subj); -      break; -    case '<': -      new = handle_pointy_brace(subj); -      break; -    case '_': -      if (subj->pos > 0 && (isalnum(bchar(subj->buffer, subj->pos - 1)) || -                            bchar(subj->buffer, subj->pos - 1) == '_')) { -        new = make_str(take_one(subj)); -      } else { -        new = handle_strong_emph(subj, '_'); -      } -      break; -    case '*': -      new = handle_strong_emph(subj, '*'); -      break; -    case '[': -      new = handle_left_bracket(subj); -      break; -    case '!': -      advance(subj); -      if (peek_char(subj) == '[') { -        new = handle_left_bracket(subj); -        if (new != NULL && new->tag == link) { -          new->tag = image; -        } else { -          new = append_inlines(make_str(bfromcstr("!")), new); -        } -      } else { -        new = make_str(bfromcstr("!")); -      } -      break; -    default: -      // we read until we hit a special character -      special_chars = bfromcstr("\n\\`&_*[]<!"); -      endpos = binchr(subj->buffer, subj->pos, special_chars); -      bdestroy(special_chars); -      if (endpos == subj->pos) { -        // current char is special: read a 1-character str -        contents = take_one(subj); -      } else if (endpos == BSTR_ERR) { -        // special char not found, take whole rest of buffer: -        endpos = subj->buffer->slen; -        contents = bmidstr(subj->buffer, subj->pos, endpos - subj->pos); -        subj->pos = endpos; -      } else { -        // take buffer from subj->pos to endpos to str. -        contents = bmidstr(subj->buffer, subj->pos, endpos - subj->pos); -        subj->pos = endpos; -        // if we're at a newline, strip trailing spaces. -        if (peek_char(subj) == '\n') { -          brtrimws(contents); -        } -      } -      new = make_str(contents); -  } -  if (*last == NULL) { -    *last = new; -  } else { -    append_inlines(*last, new); -  } -  return 1; -} - -extern inl* parse_inlines(bstring input, reference** refmap) -{ -  subject * subj = make_subject(input, refmap); -  inl * result = parse_inlines_while(subj, not_eof); -  free(subj); -  return result; +static int parse_inline(subject* subj, node_inl ** last) +{ +	node_inl* new = NULL; +	chunk contents; +	unsigned char c; +	int endpos; +	c = peek_char(subj); +	if (c == 0) { +		return 0; +	} +	switch(c){ +		case '\n': +			new = handle_newline(subj); +			break; +		case '`': +			new = handle_backticks(subj); +			break; +		case '\\': +			new = handle_backslash(subj); +			break; +		case '&': +			new = handle_entity(subj); +			break; +		case '<': +			new = handle_pointy_brace(subj); +			break; +		case '_': +			if (subj->pos > 0) { +				unsigned char prev = peek_at(subj, subj->pos - 1); +				if (isalnum(prev) || prev == '_') { +					new = make_str(chunk_literal("_")); +					advance(subj); +					break; +				} +			} + +			new = handle_strong_emph(subj, '_'); +			break; +		case '*': +			new = handle_strong_emph(subj, '*'); +			break; +		case '[': +			new = handle_left_bracket(subj); +			break; +		case '!': +			advance(subj); +			if (peek_char(subj) == '[') { +				new = handle_left_bracket(subj); +				if (new != NULL && new->tag == INL_LINK) { +					new->tag = INL_IMAGE; +				} else { +					new = append_inlines(make_str(chunk_literal("!")), new); +				} +			} else { +				new = make_str(chunk_literal("!")); +			} +			break; +		default: +			endpos = subject_find_special_char(subj); +			contents = chunk_dup(&subj->input, subj->pos, endpos - subj->pos); +			subj->pos = endpos; + +			// if we're at a newline, strip trailing spaces. +			if (peek_char(subj) == '\n') { +				chunk_rtrim(&contents); +			} + +			new = make_str(contents); +	} +	if (*last == NULL) { +		*last = new; +	} else { +		append_inlines(*last, new); +	} +	return 1; +} + +extern node_inl* parse_inlines(strbuf *input, reference_map *refmap) +{ +	subject subj; +	subject_from_buf(&subj, input, refmap); +	return parse_inlines_while(&subj, not_eof);  }  // Parse zero or more space characters, including at most one newline.  void spnl(subject* subj)  { -  bool seen_newline = false; -  while (peek_char(subj) == ' ' || -         (!seen_newline && -          (seen_newline = peek_char(subj) == '\n'))) { -    advance(subj); -  } +	bool seen_newline = false; +	while (peek_char(subj) == ' ' || +			(!seen_newline && +			 (seen_newline = peek_char(subj) == '\n'))) { +		advance(subj); +	}  }  // Parse reference.  Assumes string begins with '[' character.  // Modify refmap if a reference is encountered.  // Return 0 if no reference found, otherwise position of subject  // after reference is parsed. -extern int parse_reference(bstring input, reference** refmap) -{ -  subject * subj = make_subject(input, NULL); -  bstring lab = NULL; -  bstring url = NULL; -  bstring title = NULL; -  int matchlen = 0; -  int beforetitle; -  reference * new = NULL; -  int newpos; - -  // parse label: -  if (!link_label(subj, &lab)) { -    free(subj); -    return 0; -  } -  // colon: -  if (peek_char(subj) == ':') { -    advance(subj); -  } else { -    free(subj); -    bdestroy(lab); -    return 0; -  } -  // parse link url: -  spnl(subj); -  matchlen = scan_link_url(subj->buffer, subj->pos); -  if (matchlen) { -    url = bmidstr(subj->buffer, subj->pos, matchlen); -    clean_url(url); -    subj->pos += matchlen; -  } else { -    free(subj); -    bdestroy(lab); -    bdestroy(url); -    return 0; -  } -  // parse optional link_title -  beforetitle = subj->pos; -  spnl(subj); -  matchlen = scan_link_title(subj->buffer, subj->pos); -  if (matchlen) { -    title = bmidstr(subj->buffer, subj->pos, matchlen); -    clean_title(title); -    subj->pos += matchlen; -  } else { -    subj->pos = beforetitle; -    title = bfromcstr(""); -  } -  // parse final spaces and newline: -  while (peek_char(subj) == ' ') { -    advance(subj); -  } -  if (peek_char(subj) == '\n') { -    advance(subj); -  } else if (peek_char(subj) != 0) { -    free(subj); -    bdestroy(lab); -    bdestroy(url); -    bdestroy(title); -    return 0; -  } -  // insert reference into refmap -  new = make_reference(lab, url, title); -  add_reference(refmap, new); - -  newpos = subj->pos; -  free(subj); -  bdestroy(lab); -  bdestroy(url); -  bdestroy(title); -  return newpos; +int parse_reference_inline(strbuf *input, reference_map *refmap) +{ +	subject subj; + +	chunk lab; +	chunk url; +	chunk title; + +	int matchlen = 0; +	int beforetitle; + +	subject_from_buf(&subj, input, NULL); + +	// parse label: +	if (!link_label(&subj, &lab)) +		return 0; + +	// colon: +	if (peek_char(&subj) == ':') { +		advance(&subj); +	} else { +		return 0; +	} + +	// parse link url: +	spnl(&subj); +	matchlen = scan_link_url(&subj.input, subj.pos); +	if (matchlen) { +		url = chunk_dup(&subj.input, subj.pos, matchlen); +		subj.pos += matchlen; +	} else { +		return 0; +	} + +	// parse optional link_title +	beforetitle = subj.pos; +	spnl(&subj); +	matchlen = scan_link_title(&subj.input, subj.pos); +	if (matchlen) { +		title = chunk_dup(&subj.input, subj.pos, matchlen); +		subj.pos += matchlen; +	} else { +		subj.pos = beforetitle; +		title = chunk_literal(""); +	} +	// parse final spaces and newline: +	while (peek_char(&subj) == ' ') { +		advance(&subj); +	} +	if (peek_char(&subj) == '\n') { +		advance(&subj); +	} else if (peek_char(&subj) != 0) { +		return 0; +	} +	// insert reference into refmap +	reference_create(refmap, &lab, &url, &title); +	return subj.pos;  } diff --git a/src/inlines.h b/src/inlines.h new file mode 100644 index 0000000..8c6e2cb --- /dev/null +++ b/src/inlines.h @@ -0,0 +1,13 @@ +#ifndef _INLINES_H_ +#define _INLINES_H_ + +unsigned char *clean_url(chunk *url); +unsigned char *clean_autolink(chunk *url, int is_email); +unsigned char *clean_title(chunk *title); + +node_inl* parse_inlines(strbuf *input, reference_map *refmap); +void free_inlines(node_inl* e); + +int parse_reference_inline(strbuf *input, reference_map *refmap); + +#endif @@ -1,99 +1,77 @@  #include <stdlib.h>  #include <stdio.h> -#include "bstrlib.h" +#include <string.h>  #include "stmd.h"  #include "debug.h"  void print_usage()  { -  printf("Usage:   stmd [FILE*]\n"); -  printf("Options: --help, -h    Print usage information\n"); -  printf("         --ast         Print AST instead of HTML\n"); -  printf("         --version     Print version\n"); +	printf("Usage:   stmd [FILE*]\n"); +	printf("Options: --help, -h    Print usage information\n"); +	printf("         --ast         Print AST instead of HTML\n"); +	printf("         --version     Print version\n");  } -int main(int argc, char *argv[]) { -  int i; -  bool ast = false; -  int g = 0; -  int numfps = 0; -  int files[argc]; +static void print_document(node_block *document, bool ast) +{ +	strbuf html = GH_BUF_INIT; + +	if (ast) { +		stmd_debug_print(document); +	} else { +		stmd_render_html(&html, document); +		printf("%s", html.ptr); +		strbuf_free(&html); +	} +} -  for (i=1; i < argc; i++) { -    if (strcmp(argv[i], "--version") == 0) { -      printf("stmd %s", VERSION); -      printf(" - CommonMark converter (c) 2014 John MacFarlane\n"); -      exit(0); -    } else if ((strcmp(argv[i], "--help") == 0) || -               (strcmp(argv[i], "-h") == 0)) { -      print_usage(); -      exit(0); -    } else if (strcmp(argv[i], "--ast") == 0) { -      ast = true; -    } else if (*argv[i] == '-') { -      print_usage(); -      exit(1); -    } else { // treat as file argument -      files[g] = i; -      g++; -    } -  } +int main(int argc, char *argv[]) +{ +	int i, numfps = 0; +	bool ast = false; +	int files[argc]; +	node_block *document = NULL; -  numfps = g; -  bstring s = NULL; -  bstring html; -  g = 0; -  block * cur = make_document(); -  int linenum = 1; -  extern int errno; -  FILE * fp = NULL; +	for (i = 1; i < argc; i++) { +		if (strcmp(argv[i], "--version") == 0) { +			printf("stmd %s", VERSION); +			printf(" - CommonMark converter (c) 2014 John MacFarlane\n"); +			exit(0); +		} else if ((strcmp(argv[i], "--help") == 0) || +				(strcmp(argv[i], "-h") == 0)) { +			print_usage(); +			exit(0); +		} else if (strcmp(argv[i], "--ast") == 0) { +			ast = true; +		} else if (*argv[i] == '-') { +			print_usage(); +			exit(1); +		} else { // treat as file argument +			files[numfps++] = i; +		} +	} -  if (numfps == 0) { -    // read from stdin -    while ((s = bgets((bNgetc) fgetc, stdin, '\n'))) { -      check(incorporate_line(s, linenum, &cur) == 0, -          "error incorporating line %d", linenum); -      bdestroy(s); -      linenum++; -    } -  } else { -    // iterate over input file pointers -    for (g=0; g < numfps; g++) { +	if (numfps == 0) { +		document = stmd_parse_file(stdin); +		print_document(document, ast); +		stmd_free_nodes(document); +	} else { +		for (i = 0; i < numfps; i++) { +			FILE *fp = fopen(argv[files[i]], "r"); -      fp = fopen(argv[files[g]], "r"); -      if (fp == NULL) { -        fprintf(stderr, "Error opening file %s: %s\n", -                argv[files[g]], strerror(errno)); -        exit(1); -      } +			if (fp == NULL) { +				fprintf(stderr, "Error opening file %s: %s\n", +						argv[files[i]], strerror(errno)); +				exit(1); +			} -      while ((s = bgets((bNgetc) fgetc, fp, '\n'))) { -        check(incorporate_line(s, linenum, &cur) == 0, -            "error incorporating line %d", linenum); -        bdestroy(s); -        linenum++; -      } -      fclose(fp); -    } -  } +			document = stmd_parse_file(fp); +			print_document(document, ast); +			stmd_free_nodes(document); +			fclose(fp); +		} +	} -  while (cur != cur->top) { -    finalize(cur, linenum); -    cur = cur->parent; -  } -  check(cur == cur->top, "problems finalizing open containers"); -  finalize(cur, linenum); -  process_inlines(cur, cur->attributes.refmap); -  if (ast) { -    print_blocks(cur, 0); -  } else { -    check(blocks_to_html(cur, &html, false) == 0, "could not format as HTML"); -    printf("%s", html->data); -    bdestroy(html); -  } -  free_blocks(cur); -  return 0; -error: -  return -1; +	return 0;  } diff --git a/src/print.c b/src/print.c index a924870..83f8daa 100644 --- a/src/print.c +++ b/src/print.c @@ -1,168 +1,176 @@  #include <stdlib.h>  #include <stdio.h> -#include "bstrlib.h" +#include <string.h>  #include "stmd.h"  #include "debug.h" -static bstring format_str(bstring s) +static void print_str(const unsigned char *s, int len)  { -  int pos = 0; -  int len = blength(s); -  bstring result = bfromcstr(""); -  char c; -  bformata(result, "\""); -  while (pos < len) { -    c = bchar(s, pos); -    switch (c) { -    case '\n': -      bformata(result, "\\n"); -      break; -    case '"': -      bformata(result, "\\\""); -      break; -    case '\\': -      bformata(result, "\\\\"); -      break; -    default: -      bformata(result, "%c", c); -    } -    pos++; -  } -  bformata(result, "\""); -  return result; +	int i; + +	if (len < 0) +		len = strlen((char *)s); + +	putchar('"'); +	for (i = 0; i < len; ++i) { +		unsigned char c = s[i]; + +		switch (c) { +			case '\n': +				printf("\\n"); +				break; +			case '"': +				printf("\\\""); +				break; +			case '\\': +				printf("\\\\"); +				break; +			default: +				putchar((int)c); +		} +	} +	putchar('"');  } -// Functions to pretty-print inline and block lists, for debugging.  // Prettyprint an inline list, for debugging. -extern void print_blocks(block* b, int indent) +static void print_inlines(node_inl* ils, int indent)  { -  struct ListData * data; -  while(b != NULL) { -    // printf("%3d %3d %3d| ", b->start_line, b->start_column, b->end_line); -    for (int i=0; i < indent; i++) { -      putchar(' '); -    } -    switch(b->tag) { -    case document: -      printf("document\n"); -      print_blocks(b->children, indent + 2); -      break; -    case block_quote: -      printf("block_quote\n"); -      print_blocks(b->children, indent + 2); -      break; -    case list_item: -      data = &(b->attributes.list_data); -      printf("list_item\n"); -      print_blocks(b->children, indent + 2); -      break; -    case list: -      data = &(b->attributes.list_data); -      if (data->list_type == ordered) { -        printf("list (type=ordered tight=%s start=%d delim=%s)\n", -               (data->tight ? "true" : "false"), -               data->start, -               (data->delimiter == parens ? "parens" : "period")); -      } else { -        printf("list (type=bullet tight=%s bullet_char=%c)\n", -               (data->tight ? "true" : "false"), -               data->bullet_char); -      } -      print_blocks(b->children, indent + 2); -      break; -    case atx_header: -      printf("atx_header (level=%d)\n", b->attributes.header_level); -      print_inlines(b->inline_content, indent + 2); -      break; -    case setext_header: -      printf("setext_header (level=%d)\n", b->attributes.header_level); -      print_inlines(b->inline_content, indent + 2); -      break; -    case paragraph: -      printf("paragraph\n"); -      print_inlines(b->inline_content, indent + 2); -      break; -    case hrule: -      printf("hrule\n"); -      break; -    case indented_code: -      printf("indented_code %s\n", format_str(b->string_content)->data); -      break; -    case fenced_code: -      printf("fenced_code length=%d info=%s %s\n", -             b->attributes.fenced_code_data.fence_length, -             format_str(b->attributes.fenced_code_data.info)->data, -             format_str(b->string_content)->data); -      break; -    case html_block: -      printf("html_block %s\n", format_str(b->string_content)->data); -      break; -    case reference_def: -      printf("reference_def\n"); -      break; -    default: -      log_warn("block type %d not implemented\n", b->tag); -      break; -    } -    b = b->next; -  } +	while(ils != NULL) { +		for (int i=0; i < indent; i++) { +			putchar(' '); +		} +		switch(ils->tag) { +		case INL_STRING: +			printf("str "); +			print_str(ils->content.literal.data, ils->content.literal.len); +			putchar('\n'); +			break; +		case INL_LINEBREAK: +			printf("linebreak\n"); +			break; +		case INL_SOFTBREAK: +			printf("softbreak\n"); +			break; +		case INL_CODE: +			printf("code "); +			print_str(ils->content.literal.data, ils->content.literal.len); +			putchar('\n'); +			break; +		case INL_RAW_HTML: +			printf("html "); +			print_str(ils->content.literal.data, ils->content.literal.len); +			putchar('\n'); +			break; +		case INL_LINK: +		case INL_IMAGE: +			printf("%s url=", ils->tag == INL_LINK ? "link" : "image"); + +			if (ils->content.linkable.url) +				print_str(ils->content.linkable.url, -1); + +			if (ils->content.linkable.title) { +				printf(" title="); +				print_str(ils->content.linkable.title, -1); +			} +			putchar('\n'); +			print_inlines(ils->content.linkable.label, indent + 2); +			break; +		case INL_STRONG: +			printf("strong\n"); +			print_inlines(ils->content.linkable.label, indent + 2); +			break; +		case INL_EMPH: +			printf("emph\n"); +			print_inlines(ils->content.linkable.label, indent + 2); +			break; +		} +		ils = ils->next; +	}  } +// Functions to pretty-print inline and node_block lists, for debugging.  // Prettyprint an inline list, for debugging. -extern void print_inlines(inl* ils, int indent) +static void print_blocks(node_block* b, int indent) +{ +	struct ListData *data; + +	while(b != NULL) { +		for (int i=0; i < indent; i++) { +			putchar(' '); +		} + +		switch(b->tag) { +		case BLOCK_DOCUMENT: +			printf("document\n"); +			print_blocks(b->children, indent + 2); +			break; +		case BLOCK_BQUOTE: +			printf("block_quote\n"); +			print_blocks(b->children, indent + 2); +			break; +		case BLOCK_LIST_ITEM: +			printf("list_item\n"); +			print_blocks(b->children, indent + 2); +			break; +		case BLOCK_LIST: +			data = &(b->as.list); +			if (data->list_type == ordered) { +				printf("list (type=ordered tight=%s start=%d delim=%s)\n", +						(data->tight ? "true" : "false"), +						data->start, +						(data->delimiter == parens ? "parens" : "period")); +			} else { +				printf("list (type=bullet tight=%s bullet_char=%c)\n", +						(data->tight ? "true" : "false"), +						data->bullet_char); +			} +			print_blocks(b->children, indent + 2); +			break; +		case BLOCK_ATX_HEADER: +			printf("atx_header (level=%d)\n", b->as.header.level); +			print_inlines(b->inline_content, indent + 2); +			break; +		case BLOCK_SETEXT_HEADER: +			printf("setext_header (level=%d)\n", b->as.header.level); +			print_inlines(b->inline_content, indent + 2); +			break; +		case BLOCK_PARAGRAPH: +			printf("paragraph\n"); +			print_inlines(b->inline_content, indent + 2); +			break; +		case BLOCK_HRULE: +			printf("hrule\n"); +			break; +		case BLOCK_INDENTED_CODE: +			printf("indented_code "); +			print_str(b->string_content.ptr, -1); +			putchar('\n'); +			break; +		case BLOCK_FENCED_CODE: +			printf("fenced_code length=%d info=", +				b->as.code.fence_length); +			print_str(b->as.code.info.ptr, -1); +			putchar(' '); +			print_str(b->string_content.ptr, -1); +			putchar('\n'); +			break; +		case BLOCK_HTML: +			printf("html_block "); +			print_str(b->string_content.ptr, -1); +			putchar('\n'); +			break; +		case BLOCK_REFERENCE_DEF: +			printf("reference_def\n"); +			break; +		default: +			printf("# NOT IMPLEMENTED (%d)\n", b->tag); +			break; +		} +		b = b->next; +	} +} + +void stmd_debug_print(node_block *root)  { -  while(ils != NULL) { -    /* -    // we add 11 extra spaces for the line/column info -    for (int i=0; i < 11; i++) { -      putchar(' '); -    } -    putchar('|'); -    putchar(' '); -    */ -    for (int i=0; i < indent; i++) { -      putchar(' '); -    } -    switch(ils->tag) { -    case str: -      printf("str %s\n", format_str(ils->content.literal)->data); -      break; -    case linebreak: -      printf("linebreak\n"); -      break; -    case softbreak: -      printf("softbreak\n"); -      break; -    case code: -      printf("code %s\n", format_str(ils->content.literal)->data); -      break; -    case raw_html: -      printf("html %s\n", format_str(ils->content.literal)->data); -      break; -    case entity: -      printf("entity %s\n", format_str(ils->content.literal)->data); -      break; -    case link: -      printf("link url=%s title=%s\n", -             format_str(ils->content.linkable.url)->data, -             format_str(ils->content.linkable.title)->data); -      print_inlines(ils->content.linkable.label, indent + 2); -      break; -    case image: -      printf("image url=%s title=%s\n", -             format_str(ils->content.linkable.url)->data, -             format_str(ils->content.linkable.title)->data); -      print_inlines(ils->content.linkable.label, indent + 2); -      break; -    case strong: -      printf("strong\n"); -      print_inlines(ils->content.linkable.label, indent + 2); -      break; -    case emph: -      printf("emph\n"); -      print_inlines(ils->content.linkable.label, indent + 2); -      break; -    } -    ils = ils->next; -  } +	print_blocks(root, 0);  } diff --git a/src/references.c b/src/references.c new file mode 100644 index 0000000..3e54b48 --- /dev/null +++ b/src/references.c @@ -0,0 +1,141 @@ +#include "stmd.h" +#include "utf8.h" +#include "references.h" +#include "inlines.h" + +static unsigned int +refhash(const unsigned char *link_ref) +{ +	unsigned int hash = 0; + +	while (*link_ref) +		hash = (*link_ref++) + (hash << 6) + (hash << 16) - hash; + +	return hash; +} + +static void reference_free(reference *ref) +{ +	free(ref->label); +	free(ref->url); +	free(ref->title); +	free(ref); +} + +// normalize reference:  collapse internal whitespace to single space, +// remove leading/trailing whitespace, case fold +// Return NULL if the reference name is actually empty (i.e. composed +// solely from whitespace) +static unsigned char *normalize_reference(chunk *ref) +{ +	strbuf normalized = GH_BUF_INIT; +	unsigned char *result; + +	if (ref->len == 0) +		return NULL; + +	utf8proc_case_fold(&normalized, ref->data, ref->len); +	strbuf_trim(&normalized); +	strbuf_normalize_whitespace(&normalized); + +	result = strbuf_detach(&normalized); +	assert(result); + +	if (result[0] == '\0') { +		free(result); +		return NULL; +	} +	 +	return result; +} + +static void add_reference(reference_map *map, reference* ref) +{ +	reference *t = ref->next = map->table[ref->hash % REFMAP_SIZE]; + +	while (t) { +		if (t->hash == ref->hash && +			!strcmp((char *)t->label, (char *)ref->label)) { +			reference_free(ref); +			return; +		} + +		t = t->next; +	} + +	map->table[ref->hash % REFMAP_SIZE] = ref; +} + +extern void reference_create(reference_map *map, chunk *label, chunk *url, chunk *title) +{ +	reference *ref; +	unsigned char *reflabel = normalize_reference(label); + +	/* empty reference name, or composed from only whitespace */ +	if (reflabel == NULL) +		return; + +	ref = malloc(sizeof(reference)); +	ref->label = reflabel; +	ref->hash = refhash(ref->label); +	ref->url = clean_url(url); +	ref->title = clean_title(title); +	ref->next = NULL; + +	add_reference(map, ref); +} + +// Returns reference if refmap contains a reference with matching +// label, otherwise NULL. +reference* reference_lookup(reference_map *map, chunk *label) +{ +	reference *ref = NULL; +	unsigned char *norm; +	unsigned int hash; +	 +	if (map == NULL) +		return NULL; +	 +	norm = normalize_reference(label); +	if (norm == NULL) +		return NULL; + +	hash = refhash(norm); +	ref = map->table[hash % REFMAP_SIZE]; + +	while (ref) { +		if (ref->hash == hash && +			!strcmp((char *)ref->label, (char *)norm)) +			break; +		ref = ref->next; +	} + +	free(norm); +	return ref; +} + +void reference_map_free(reference_map *map) +{ +	unsigned int i; + +	for (i = 0; i < REFMAP_SIZE; ++i) { +		reference *ref = map->table[i]; +		reference *next; + +		while (ref) { +			next = ref->next; +			reference_free(ref); +			ref = next; +		} +	} + +	free(map); +} + +reference_map *reference_map_new(void) +{ +	reference_map *map = malloc(sizeof(reference_map)); +	memset(map, 0x0, sizeof(reference_map)); +	return map; +} + diff --git a/src/references.h b/src/references.h new file mode 100644 index 0000000..28937f1 --- /dev/null +++ b/src/references.h @@ -0,0 +1,27 @@ +#ifndef _REFERENCES_H_ +#define _REFERENCES_H_ + +#define REFMAP_SIZE 16 + +struct reference { +	struct reference *next; +	unsigned char *label; +	unsigned char *url; +	unsigned char *title; +	unsigned int hash; +}; + +typedef struct reference reference; + +struct reference_map { +	reference *table[REFMAP_SIZE]; +}; + +typedef struct reference_map reference_map; + +reference_map *reference_map_new(void); +void reference_map_free(reference_map *map); +reference* reference_lookup(reference_map *map, chunk *label); +extern void reference_create(reference_map *map, chunk *label, chunk *url, chunk *title); + +#endif diff --git a/src/scanners.h b/src/scanners.h index 71e0520..785d424 100644 --- a/src/scanners.h +++ b/src/scanners.h @@ -1,15 +1,42 @@ -#include "bstrlib.h" - -int scan_autolink_uri(bstring s, int pos); -int scan_autolink_email(bstring s, int pos); -int scan_html_tag(bstring s, int pos); -int scan_html_block_tag(bstring s, int pos); -int scan_link_url(bstring s, int pos); -int scan_link_title(bstring s, int pos); -int scan_spacechars(bstring s, int pos); -int scan_atx_header_start(bstring s, int pos); -int scan_setext_header_line(bstring s, int pos); -int scan_hrule(bstring s, int pos); -int scan_open_code_fence(bstring s, int pos); -int scan_close_code_fence(bstring s, int pos, int len); -int scan_entity(bstring s, int pos); +#include "stmd.h" + +extern int _scan_autolink_uri(const unsigned char *p); +extern int _scan_autolink_email(const unsigned char *p); +extern int _scan_html_tag(const unsigned char *p); +extern int _scan_html_block_tag(const unsigned char *p); +extern int _scan_link_url(const unsigned char *p); +extern int _scan_link_title(const unsigned char *p); +extern int _scan_spacechars(const unsigned char *p); +extern int _scan_atx_header_start(const unsigned char *p); +extern int _scan_setext_header_line(const unsigned char *p); +extern int _scan_hrule(const unsigned char *p); +extern int _scan_open_code_fence(const unsigned char *p); +extern int _scan_close_code_fence(const unsigned char *p); +extern int _scan_entity(const unsigned char *p); + +static int scan_at(int (*scanner)(const unsigned char *), chunk *c, int offset) +{ +	int res; +	unsigned char *ptr = (unsigned char *)c->data; +	unsigned char lim = ptr[c->len]; + +	ptr[c->len] = '\0'; +	res = scanner(ptr + offset); +	ptr[c->len] = lim; + +	return res; +} + +#define scan_autolink_uri(c, n) scan_at(&_scan_autolink_uri, c, n) +#define scan_autolink_email(c, n) scan_at(&_scan_autolink_email, c, n) +#define scan_html_tag(c, n) scan_at(&_scan_html_tag, c, n) +#define scan_html_block_tag(c, n) scan_at(&_scan_html_block_tag, c, n) +#define scan_link_url(c, n) scan_at(&_scan_link_url, c, n) +#define scan_link_title(c, n) scan_at(&_scan_link_title, c, n) +#define scan_spacechars(c, n) scan_at(&_scan_spacechars, c, n) +#define scan_atx_header_start(c, n) scan_at(&_scan_atx_header_start, c, n) +#define scan_setext_header_line(c, n) scan_at(&_scan_setext_header_line, c, n) +#define scan_hrule(c, n) scan_at(&_scan_hrule, c, n) +#define scan_open_code_fence(c, n) scan_at(&_scan_open_code_fence, c, n) +#define scan_close_code_fence(c, n) scan_at(&_scan_close_code_fence, c, n) +#define scan_entity(c, n) scan_at(&_scan_entity, c, n) diff --git a/src/scanners.re b/src/scanners.re index 305d1ea..28aba9d 100644 --- a/src/scanners.re +++ b/src/scanners.re @@ -1,4 +1,4 @@ -#include "bstrlib.h" +#include <stdlib.h>  /*!re2c    re2c:define:YYCTYPE  = "unsigned char"; @@ -55,11 +55,10 @@  */  // Try to match URI autolink after first <, returning number of chars matched. -extern int scan_autolink_uri(bstring s, int pos) +extern int _scan_autolink_uri(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    scheme [:]([^\x00-\x20<>\\]|escaped_char)*[>]  { return (p - start); }    .? { return 0; } @@ -67,11 +66,10 @@ extern int scan_autolink_uri(bstring s, int pos)  }  // Try to match email autolink after first <, returning num of chars matched. -extern int scan_autolink_email(bstring s, int pos) +extern int _scan_autolink_email(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    [a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+      [@] @@ -83,11 +81,10 @@ extern int scan_autolink_email(bstring s, int pos)  }  // Try to match an HTML tag after first <, returning num of chars matched. -extern int scan_html_tag(bstring s, int pos) +extern int _scan_html_tag(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    htmltag { return (p - start); }    .? { return 0; } @@ -96,11 +93,10 @@ extern int scan_html_tag(bstring s, int pos)  // Try to match an HTML block tag including first <,  // returning num of chars matched. -extern int scan_html_block_tag(bstring s, int pos) +extern int _scan_html_block_tag(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    [<] [/] blocktagname (spacechar | [>])  { return (p - start); }    [<] blocktagname (spacechar | [/>]) { return (p - start); } @@ -113,11 +109,10 @@ extern int scan_html_block_tag(bstring s, int pos)  // This may optionally be contained in <..>; otherwise  // whitespace and unbalanced right parentheses aren't allowed.  // Newlines aren't ever allowed. -extern int scan_link_url(bstring s, int pos) +extern int _scan_link_url(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    [ \n]* [<] ([^<>\n\\\x00] | escaped_char | [\\])* [>] { return (p - start); }    [ \n]* (reg_char+ | escaped_char | in_parens_nosp)* { return (p - start); } @@ -128,11 +123,10 @@ extern int scan_link_url(bstring s, int pos)  // Try to match a link title (in single quotes, in double quotes, or  // in parentheses), returning number of chars matched.  Allow one  // level of internal nesting (quotes within quotes). -extern int scan_link_title(bstring s, int pos) +extern int _scan_link_title(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    ["] (escaped_char|[^"\x00])* ["]   { return (p - start); }    ['] (escaped_char|[^'\x00])* ['] { return (p - start); } @@ -142,10 +136,9 @@ extern int scan_link_title(bstring s, int pos)  }  // Match space characters, including newlines. -extern int scan_spacechars(bstring s, int pos) +extern int _scan_spacechars(const unsigned char *p)  { -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *start = p; \  /*!re2c    [ \t\n]* { return (p - start); }    . { return 0; } @@ -153,11 +146,10 @@ extern int scan_spacechars(bstring s, int pos)  }  // Match ATX header start. -extern int scan_atx_header_start(bstring s, int pos) +extern int _scan_atx_header_start(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    [#]{1,6} ([ ]+|[\n])  { return (p - start); }    .? { return 0; } @@ -166,10 +158,9 @@ extern int scan_atx_header_start(bstring s, int pos)  // Match sexext header line.  Return 1 for level-1 header,  // 2 for level-2, 0 for no match. -extern int scan_setext_header_line(bstring s, int pos) +extern int _scan_setext_header_line(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); +  const unsigned char *marker = NULL;  /*!re2c    [=]+ [ ]* [\n] { return 1; }    [-]+ [ ]* [\n] { return 2; } @@ -180,11 +171,10 @@ extern int scan_setext_header_line(bstring s, int pos)  // Scan a horizontal rule line: "...three or more hyphens, asterisks,  // or underscores on a line by themselves. If you wish, you may use  // spaces between the hyphens or asterisks." -extern int scan_hrule(bstring s, int pos) +extern int _scan_hrule(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    ([*][ ]*){3,} [ \t]* [\n] { return (p - start); }    ([_][ ]*){3,} [ \t]* [\n] { return (p - start); } @@ -194,11 +184,10 @@ extern int scan_hrule(bstring s, int pos)  }  // Scan an opening code fence. -extern int scan_open_code_fence(bstring s, int pos) +extern int _scan_open_code_fence(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    [`]{3,} / [^`\n\x00]*[\n] { return (p - start); }    [~]{3,} / [^~\n\x00]*[\n] { return (p - start); } @@ -207,29 +196,22 @@ extern int scan_open_code_fence(bstring s, int pos)  }  // Scan a closing code fence with length at least len. -extern int scan_close_code_fence(bstring s, int pos, int len) +extern int _scan_close_code_fence(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c -  ([`]{3,} | [~]{3,}) / spacechar* [\n] -                              { if (p - start > len) { -                                return (p - start); -                              } else { -                                return 0; -                              } } +  ([`]{3,} | [~]{3,}) / spacechar* [\n] { return (p - start); }    .? { return 0; }  */  }  // Scans an entity.  // Returns number of chars matched. -extern int scan_entity(bstring s, int pos) +extern int _scan_entity(const unsigned char *p)  { -  unsigned char * marker = NULL; -  unsigned char * p = &(s->data[pos]); -  unsigned char * start = p; +  const unsigned char *marker = NULL; +  const unsigned char *start = p;  /*!re2c    [&] ([#] ([Xx][A-Fa-f0-9]{1,8}|[0-9]{1,8}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]       { return (p - start); } @@ -1,121 +1,115 @@ +#ifndef _STDMD_H_ +#define _STDMD_H_ +  #include <stdbool.h> -#include "bstrlib.h" -#include "uthash.h" +#include <stdio.h> +#include "buffer.h" +#include "chunk.h" +#include "references.h"  #define VERSION "0.1"  #define CODE_INDENT 4 -typedef struct Inline { -  enum { str, softbreak, linebreak, code, raw_html, entity, -         emph, strong, link, image } tag; -  union { -    bstring                  literal; -    struct Inline*           inlines; -    struct { struct Inline*  label; -             bstring         url; -             bstring         title; -           } linkable; -  } content; -  struct Inline*             next; -} inl; - -typedef struct Reference { -  bstring         label; -  bstring         url; -  bstring         title; -  UT_hash_handle  hh;      // used by uthash -} reference; +struct node_inl { +	enum { +		INL_STRING, +		INL_SOFTBREAK, +		INL_LINEBREAK, +		INL_CODE, +		INL_RAW_HTML, +		INL_EMPH, +		INL_STRONG, +		INL_LINK, +		INL_IMAGE +	} tag; +	union { +		chunk literal; +		struct node_inl *inlines; +		struct { +			struct node_inl *label; +			unsigned char *url; +			unsigned char *title; +		} linkable; +	} content; +	struct node_inl *next; +}; -typedef struct Subject { -  bstring        buffer; -  int            pos; -  reference**    reference_map; -  int            label_nestlevel; -} subject; +typedef struct node_inl node_inl;  // Types for blocks -  struct ListData { -  enum { bullet, -         ordered }  list_type; -  int               marker_offset; -  int               padding; -  int               start; -  enum { period, -         parens }   delimiter; -  unsigned char     bullet_char; -  bool              tight; +	enum { +		bullet, +		ordered +	}  list_type; +	int               marker_offset; +	int               padding; +	int               start; +	enum { +		period, +		parens +	} delimiter; +	unsigned char     bullet_char; +	bool              tight;  };  struct FencedCodeData { -  int               fence_length; -  int               fence_offset; -  char              fence_char; -  bstring           info; +	int               fence_length; +	int               fence_offset; +	char              fence_char; +	strbuf            info;  }; -typedef struct Block { -  enum { document, -         block_quote, -         list, -         list_item, -         fenced_code, -         indented_code, -         html_block, -         paragraph, -         atx_header, -         setext_header, -         hrule, -         reference_def -  }                  tag; -  int                start_line; -  int                start_column; -  int                end_line; -  bool               open; -  bool               last_line_blank; -  struct Block*      children; -  struct Block*      last_child; -  struct Block*      parent; -  struct Block*      top; -  bstring            string_content; -  inl*               inline_content; -  union  { -    struct ListData       list_data; -    struct FencedCodeData fenced_code_data; -    int                   header_level; -    reference**           refmap; -    }                     attributes; -  struct Block *     next; -  struct Block *     prev; -} block; +struct node_block { +	enum { +		BLOCK_DOCUMENT, +		BLOCK_BQUOTE, +		BLOCK_LIST, +		BLOCK_LIST_ITEM, +		BLOCK_FENCED_CODE, +		BLOCK_INDENTED_CODE, +		BLOCK_HTML, +		BLOCK_PARAGRAPH, +		BLOCK_ATX_HEADER, +		BLOCK_SETEXT_HEADER, +		BLOCK_HRULE, +		BLOCK_REFERENCE_DEF +	} tag; +	int start_line; +	int start_column; +	int end_line; +	bool open; +	bool last_line_blank; +	struct node_block* children; +	struct node_block* last_child; +	struct node_block* parent; +	struct node_block* top; +	strbuf string_content; +	node_inl* inline_content; -int parse_inline(subject* subj, inl ** last); -inl* parse_inlines(bstring input, reference** refmap); -inl* parse_inlines_while(subject* subj, int (*f)(subject*)); -void free_inlines(inl* e); -int parse_reference(bstring input, reference** refmap); -void free_reference(reference *ref); -void free_reference_map(reference **refmap); -reference* make_reference(bstring label, bstring url, bstring title); -reference* lookup_reference(reference** refmap, bstring label); -void add_reference(reference** refmap, reference* ref); -int unescape(bstring s); +	union  { +		struct ListData list; +		struct FencedCodeData code; +		struct { +			int level; +		} header; +		struct { +			reference_map *refmap; +		} document; +	} as; -extern block* make_document(); -extern block* add_child(block* parent, -                        int block_type, int start_line, int start_column); -void free_blocks(block* e); +	struct node_block *next; +	struct node_block *prev; +}; -// FOR NOW: -int process_inlines(block* cur, reference** refmap); -int incorporate_line(bstring ln, int line_number, block** curptr); -int finalize(block* b, int line_number); +typedef struct node_block node_block; -void print_inlines(inl* ils, int indent); -void print_blocks(block* blk, int indent); +node_block *stmd_parse_document(const unsigned char *buffer, size_t len); +node_block *stmd_parse_file(FILE *f); -int blocks_to_html(block* b, bstring* result, bool tight); -int inlines_to_html(inl* b, bstring* result); +void stmd_free_nodes(node_block *e); -int bdetab(bstring s, int utf8); +void stmd_debug_print(node_block *root); +void stmd_render_html(strbuf *html, node_block *root); +#endif @@ -1,106 +1,193 @@  #include <stdlib.h> -#include "bstrlib.h" -#include "debug.h" - -#define advance(s) \ -  s++; \ -  check(*s >> 6 == 0x02, "UTF-8 decode error on byte %x", *s); - -// Reads a unicode code point from a UTF8-encoded string, and -// puts it in the pointer n. If something illegal -// is encountered, 0xFFFD is emitted. -// Returns a pointer to next position in string, or NULL if no -// more characters remain. -extern unsigned char * from_utf8(unsigned char * s, unsigned int *n) +#include <stdint.h> +#include <unistd.h> +#include <assert.h> + +#include "utf8.h" + +static const int8_t utf8proc_utf8class[256] = { +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +	4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static void encode_unknown(strbuf *buf)  { -  int x = 0; - -  if (*s == 0) { -    return NULL; -  } else if (*s < 0x80) { -    x = *s; -  } else if (*s >> 5 == 0x06) { -    x = *s & 0x1F; -    advance(s); -    x = (x << 6) + (*s & 0x3F); -  } else if (*s >> 4 == 0x0E) { -    x = *s & 0x0F; -    advance(s); -    x = (x << 6) + (*s & 0x3F); -    advance(s); -    x = (x << 6) + (*s & 0x3F); -  } else if (*s >> 3 == 0x1E) { -    x = *s & 0x07; -    advance(s); -    x = (x << 6) + (*s & 0x3F); -    advance(s); -    x = (x << 6) + (*s & 0x3F); -    advance(s); -    x = (x << 6) + (*s & 0x3F); -  } else if (*s >> 2 == 0x3E) { -    x = *s & 0x03; -    advance(s); -    x = (x << 6) + (*s & 0x3F); -    advance(s); -    x = (x << 6) + (*s & 0x3F); -    advance(s); -    x = (x << 6) + (*s & 0x3F); -    advance(s); -    x = (x << 6) + (*s & 0x3F); -   } else { -    log_err("UTF-8 decode error on byte %x", *s); -    goto error; -  } -  *n = x; -  s++; -  return s; - error: -  *n = 0xFFFD; -  return s; +	static const uint8_t repl[] = {239, 191, 189}; +	strbuf_put(buf, repl, 3);  } -// Converts the unicode code point c to UTF-8, -// putting the result in dest.  Returns 0 on success, -1 on error. -extern int to_utf8(unsigned int c, bstring dest) +int utf8proc_charlen(const uint8_t *str, int str_len)  { -  if (c < 0x80) { -    bconchar(dest, c); -  } else if (c < 0x800) { -    bconchar(dest, 192 + c/64); -    bconchar(dest, 128 + c%64); -  } else if (c - 0xd800u < 0x800) { -    goto error; -  } else if (c < 0x10000) { -    bconchar(dest, 224 + c / 4096); -    bconchar(dest, 128 + c /64%64); -    bconchar(dest, 128 + c%64); -  } else if (c < 0x110000) { -    bconchar(dest, 240 + c/262144); -    bconchar(dest, 128 + c/4096%64); -    bconchar(dest, 128 + c/64%64); -    bconchar(dest, 128 + c%64); -  } else { -    goto error; -  } -  return 0; -error: -  return -1; +	int length, i; + +	if (!str_len) +		return 0; + +	length = utf8proc_utf8class[str[0]]; + +	if (!length) +		return -1; + +	if (str_len >= 0 && length > str_len) +		return -str_len; + +	for (i = 1; i < length; i++) { +		if ((str[i] & 0xC0) != 0x80) +			return -i; +	} + +	return length;  } -#define bufpush(x) \ -  check(to_utf8(x, buf) == 0, "UTF-8 encode error on code point  %04x", x) +void utf8proc_detab(strbuf *ob, const uint8_t *line, size_t size) +{ +	static const uint8_t whitespace[] = "    "; + +	size_t i = 0, tab = 0; + +	while (i < size) { +		size_t org = i; + +		while (i < size && line[i] != '\t' && line[i] <= 0x80) { +			i++; tab++; +		} + +		if (i > org) +			strbuf_put(ob, line + org, i - org); + +		if (i >= size) +			break; + +		if (line[i] == '\t') { +			int numspaces = 4 - (tab % 4); +			strbuf_put(ob, whitespace, numspaces); +			i += 1; +			tab += numspaces; +		} else { +			int charlen = utf8proc_charlen(line + i, size - i); + +			if (charlen >= 0) { +				strbuf_put(ob, line + i, charlen); +			} else { +				encode_unknown(ob); +				charlen = -charlen; +			} + +			i += charlen; +			tab += 1; +		} +	} +} + +int utf8proc_iterate(const uint8_t *str, int str_len, int32_t *dst) +{ +	int length; +	int32_t uc = -1; + +	*dst = -1; +	length = utf8proc_charlen(str, str_len); +	if (length < 0) +		return -1; + +	switch (length) { +		case 1: +			uc = str[0]; +			break; +		case 2: +			uc = ((str[0] & 0x1F) <<  6) + (str[1] & 0x3F); +			if (uc < 0x80) uc = -1; +			break; +		case 3: +			uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) <<  6) +				+ (str[2] & 0x3F); +			if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) || +					(uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1; +			break; +		case 4: +			uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) +				+ ((str[2] & 0x3F) <<  6) + (str[3] & 0x3F); +			if (uc < 0x10000 || uc >= 0x110000) uc = -1; +			break; +	} -// Returns the case-folded version of the source string, or NULL on error. -extern bstring case_fold(bstring source) +	if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE)) +		return -1; + +	*dst = uc; +	return length; +} + +void utf8proc_encode_char(int32_t uc, strbuf *buf)  { -  unsigned char * s = source->data; -  unsigned int c = 0; -  bstring buf = bfromcstr(""); -  while ((s = from_utf8(s, &c))) { -#include "case_fold_switch.c" -  } -  return buf; -error: -  return NULL; +	uint8_t dst[4]; +	int len = 0; + +	assert(uc >= 0); + +	if (uc < 0x80) { +		dst[0] = uc; +		len = 1; +	} else if (uc < 0x800) { +		dst[0] = 0xC0 + (uc >> 6); +		dst[1] = 0x80 + (uc & 0x3F); +		len = 2; +	} else if (uc == 0xFFFF) { +		dst[0] = 0xFF; +		len = 1; +	} else if (uc == 0xFFFE) { +		dst[0] = 0xFE; +		len = 1; +	} else if (uc < 0x10000) { +		dst[0] = 0xE0 + (uc >> 12); +		dst[1] = 0x80 + ((uc >> 6) & 0x3F); +		dst[2] = 0x80 + (uc & 0x3F); +		len = 3; +	} else if (uc < 0x110000) { +		dst[0] = 0xF0 + (uc >> 18); +		dst[1] = 0x80 + ((uc >> 12) & 0x3F); +		dst[2] = 0x80 + ((uc >> 6) & 0x3F); +		dst[3] = 0x80 + (uc & 0x3F); +		len = 4; +	} else { +		encode_unknown(buf); +		return; +	} + +	strbuf_put(buf, dst, len); +} + +void utf8proc_case_fold(strbuf *dest, const uint8_t *str, int len) +{ +	int32_t c; + +#define bufpush(x) \ +	utf8proc_encode_char(x, dest) + +	while (len > 0) { +		int char_len = utf8proc_iterate(str, len, &c); + +		if (char_len >= 0) { +#include "case_fold_switch.inc" +		} else { +			encode_unknown(dest); +			char_len = -char_len; +		} + +		str += char_len; +		len -= char_len; +	}  } @@ -1,6 +1,13 @@ -#include <stdlib.h> -#include "bstrlib.h" +#ifndef _H_STMD_UTF8_ +#define _H_STMD_UTF8_ -extern unsigned char * from_utf8(unsigned char * s, unsigned int *n); -extern int to_utf8(unsigned int c, bstring dest); -extern bstring case_fold(bstring source); +#include <stdint.h> +#include "buffer.h" + +void utf8proc_case_fold(strbuf *dest, const uint8_t *str, int len); +void utf8proc_encode_char(int32_t uc, strbuf *buf); +int utf8proc_iterate(const uint8_t *str, int str_len, int32_t *dst); +int utf8proc_charlen(const uint8_t *str, int str_len); +void utf8proc_detab(strbuf *dest, const uint8_t *line, size_t size); + +#endif diff --git a/src/uthash.h b/src/uthash.h deleted file mode 100644 index b9bc7e9..0000000 --- a/src/uthash.h +++ /dev/null @@ -1,948 +0,0 @@ -/* -Copyright (c) 2003-2013, Troy D. Hanson     http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -    * Redistributions of source code must retain the above copyright -      notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef UTHASH_H -#define UTHASH_H  - -#include <string.h>   /* memcmp,strlen */ -#include <stddef.h>   /* ptrdiff_t */ -#include <stdlib.h>   /* exit() */ - -/* These macros use decltype or the earlier __typeof GNU extension. -   As decltype is only available in newer compilers (VS2010 or gcc 4.3+ -   when compiling c++ source) this code uses whatever method is needed -   or, for VS2008 where neither is available, uses casting workarounds. */ -#ifdef _MSC_VER         /* MS compiler */ -#if _MSC_VER >= 1600 && defined(__cplusplus)  /* VS2010 or newer in C++ mode */ -#define DECLTYPE(x) (decltype(x)) -#else                   /* VS2008 or older (or VS2010 in C mode) */ -#define NO_DECLTYPE -#define DECLTYPE(x) -#endif -#else                   /* GNU, Sun and other compilers */ -#define DECLTYPE(x) (__typeof(x)) -#endif - -#ifdef NO_DECLTYPE -#define DECLTYPE_ASSIGN(dst,src)                                                 \ -do {                                                                             \ -  char **_da_dst = (char**)(&(dst));                                             \ -  *_da_dst = (char*)(src);                                                       \ -} while(0) -#else  -#define DECLTYPE_ASSIGN(dst,src)                                                 \ -do {                                                                             \ -  (dst) = DECLTYPE(dst)(src);                                                    \ -} while(0) -#endif - -/* a number of the hash function use uint32_t which isn't defined on win32 */ -#ifdef _MSC_VER -typedef unsigned int uint32_t; -typedef unsigned char uint8_t; -#else -#include <inttypes.h>   /* uint32_t */ -#endif - -#define UTHASH_VERSION 1.9.8 - -#ifndef uthash_fatal -#define uthash_fatal(msg) exit(-1)        /* fatal error (out of memory,etc) */ -#endif -#ifndef uthash_malloc -#define uthash_malloc(sz) malloc(sz)      /* malloc fcn                      */ -#endif -#ifndef uthash_free -#define uthash_free(ptr,sz) free(ptr)     /* free fcn                        */ -#endif - -#ifndef uthash_noexpand_fyi -#define uthash_noexpand_fyi(tbl)          /* can be defined to log noexpand  */ -#endif -#ifndef uthash_expand_fyi -#define uthash_expand_fyi(tbl)            /* can be defined to log expands   */ -#endif - -/* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS 32      /* initial number of buckets        */ -#define HASH_INITIAL_NUM_BUCKETS_LOG2 5  /* lg2 of initial number of buckets */ -#define HASH_BKT_CAPACITY_THRESH 10      /* expand when bucket count reaches */ - -/* calculate the element whose hash handle address is hhe */ -#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) - -#define HASH_FIND(hh,head,keyptr,keylen,out)                                     \ -do {                                                                             \ -  unsigned _hf_bkt,_hf_hashv;                                                    \ -  out=NULL;                                                                      \ -  if (head) {                                                                    \ -     HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt);   \ -     if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) {                           \ -       HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ],  \ -                        keyptr,keylen,out);                                      \ -     }                                                                           \ -  }                                                                              \ -} while (0) - -#ifdef HASH_BLOOM -#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) -#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) -#define HASH_BLOOM_MAKE(tbl)                                                     \ -do {                                                                             \ -  (tbl)->bloom_nbits = HASH_BLOOM;                                               \ -  (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN);                 \ -  if (!((tbl)->bloom_bv))  { uthash_fatal( "out of memory"); }                   \ -  memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN);                                \ -  (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE;                                       \ -} while (0)  - -#define HASH_BLOOM_FREE(tbl)                                                     \ -do {                                                                             \ -  uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN);                              \ -} while (0)  - -#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) -#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) - -#define HASH_BLOOM_ADD(tbl,hashv)                                                \ -  HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) - -#define HASH_BLOOM_TEST(tbl,hashv)                                               \ -  HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) - -#else -#define HASH_BLOOM_MAKE(tbl)  -#define HASH_BLOOM_FREE(tbl)  -#define HASH_BLOOM_ADD(tbl,hashv)  -#define HASH_BLOOM_TEST(tbl,hashv) (1) -#define HASH_BLOOM_BYTELEN 0 -#endif - -#define HASH_MAKE_TABLE(hh,head)                                                 \ -do {                                                                             \ -  (head)->hh.tbl = (UT_hash_table*)uthash_malloc(                                \ -                  sizeof(UT_hash_table));                                        \ -  if (!((head)->hh.tbl))  { uthash_fatal( "out of memory"); }                    \ -  memset((head)->hh.tbl, 0, sizeof(UT_hash_table));                              \ -  (head)->hh.tbl->tail = &((head)->hh);                                          \ -  (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS;                        \ -  (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2;              \ -  (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head);                    \ -  (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc(                      \ -          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \ -  if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); }             \ -  memset((head)->hh.tbl->buckets, 0,                                             \ -          HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket));               \ -  HASH_BLOOM_MAKE((head)->hh.tbl);                                               \ -  (head)->hh.tbl->signature = HASH_SIGNATURE;                                    \ -} while(0) - -#define HASH_ADD(hh,head,fieldname,keylen_in,add)                                \ -        HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) - -#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced)                   \ -do {                                                                             \ -  replaced=NULL;                                                                 \ -  HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced);                     \ -  if (replaced!=NULL) {                                                          \ -     HASH_DELETE(hh,head,replaced);                                              \ -  };                                                                             \ -  HASH_ADD(hh,head,fieldname,keylen_in,add);                                     \ -} while(0) -  -#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add)                            \ -do {                                                                             \ - unsigned _ha_bkt;                                                               \ - (add)->hh.next = NULL;                                                          \ - (add)->hh.key = (char*)(keyptr);                                                \ - (add)->hh.keylen = (unsigned)(keylen_in);                                       \ - if (!(head)) {                                                                  \ -    head = (add);                                                                \ -    (head)->hh.prev = NULL;                                                      \ -    HASH_MAKE_TABLE(hh,head);                                                    \ - } else {                                                                        \ -    (head)->hh.tbl->tail->next = (add);                                          \ -    (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail);         \ -    (head)->hh.tbl->tail = &((add)->hh);                                         \ - }                                                                               \ - (head)->hh.tbl->num_items++;                                                    \ - (add)->hh.tbl = (head)->hh.tbl;                                                 \ - HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets,                         \ -         (add)->hh.hashv, _ha_bkt);                                              \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh);                   \ - HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv);                                 \ - HASH_EMIT_KEY(hh,head,keyptr,keylen_in);                                        \ - HASH_FSCK(hh,head);                                                             \ -} while(0) - -#define HASH_TO_BKT( hashv, num_bkts, bkt )                                      \ -do {                                                                             \ -  bkt = ((hashv) & ((num_bkts) - 1));                                            \ -} while(0) - -/* delete "delptr" from the hash table. - * "the usual" patch-up process for the app-order doubly-linked-list. - * The use of _hd_hh_del below deserves special explanation. - * These used to be expressed using (delptr) but that led to a bug - * if someone used the same symbol for the head and deletee, like - *  HASH_DELETE(hh,users,users); - * We want that to work, but by changing the head (users) below - * we were forfeiting our ability to further refer to the deletee (users) - * in the patch-up process. Solution: use scratch space to - * copy the deletee pointer, then the latter references are via that - * scratch pointer rather than through the repointed (users) symbol. - */ -#define HASH_DELETE(hh,head,delptr)                                              \ -do {                                                                             \ -    unsigned _hd_bkt;                                                            \ -    struct UT_hash_handle *_hd_hh_del;                                           \ -    if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) )  {         \ -        uthash_free((head)->hh.tbl->buckets,                                     \ -                    (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ -        HASH_BLOOM_FREE((head)->hh.tbl);                                         \ -        uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                      \ -        head = NULL;                                                             \ -    } else {                                                                     \ -        _hd_hh_del = &((delptr)->hh);                                            \ -        if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) {     \ -            (head)->hh.tbl->tail =                                               \ -                (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) +               \ -                (head)->hh.tbl->hho);                                            \ -        }                                                                        \ -        if ((delptr)->hh.prev) {                                                 \ -            ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) +                  \ -                    (head)->hh.tbl->hho))->next = (delptr)->hh.next;             \ -        } else {                                                                 \ -            DECLTYPE_ASSIGN(head,(delptr)->hh.next);                             \ -        }                                                                        \ -        if (_hd_hh_del->next) {                                                  \ -            ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next +                     \ -                    (head)->hh.tbl->hho))->prev =                                \ -                    _hd_hh_del->prev;                                            \ -        }                                                                        \ -        HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt);   \ -        HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del);        \ -        (head)->hh.tbl->num_items--;                                             \ -    }                                                                            \ -    HASH_FSCK(hh,head);                                                          \ -} while (0) - - -/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ -#define HASH_FIND_STR(head,findstr,out)                                          \ -    HASH_FIND(hh,head,findstr,strlen(findstr),out) -#define HASH_ADD_STR(head,strfield,add)                                          \ -    HASH_ADD(hh,head,strfield,strlen(add->strfield),add) -#define HASH_REPLACE_STR(head,strfield,add,replaced)                             \ -  HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced) -#define HASH_FIND_INT(head,findint,out)                                          \ -    HASH_FIND(hh,head,findint,sizeof(int),out) -#define HASH_ADD_INT(head,intfield,add)                                          \ -    HASH_ADD(hh,head,intfield,sizeof(int),add) -#define HASH_REPLACE_INT(head,intfield,add,replaced)                             \ -    HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) -#define HASH_FIND_PTR(head,findptr,out)                                          \ -    HASH_FIND(hh,head,findptr,sizeof(void *),out) -#define HASH_ADD_PTR(head,ptrfield,add)                                          \ -    HASH_ADD(hh,head,ptrfield,sizeof(void *),add) -#define HASH_REPLACE_PTR(head,ptrfield,add,replaced)                             \ -    HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) -#define HASH_DEL(head,delptr)                                                    \ -    HASH_DELETE(hh,head,delptr) - -/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. - * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. - */ -#ifdef HASH_DEBUG -#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) -#define HASH_FSCK(hh,head)                                                       \ -do {                                                                             \ -    unsigned _bkt_i;                                                             \ -    unsigned _count, _bkt_count;                                                 \ -    char *_prev;                                                                 \ -    struct UT_hash_handle *_thh;                                                 \ -    if (head) {                                                                  \ -        _count = 0;                                                              \ -        for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) {       \ -            _bkt_count = 0;                                                      \ -            _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head;                      \ -            _prev = NULL;                                                        \ -            while (_thh) {                                                       \ -               if (_prev != (char*)(_thh->hh_prev)) {                            \ -                   HASH_OOPS("invalid hh_prev %p, actual %p\n",                  \ -                    _thh->hh_prev, _prev );                                      \ -               }                                                                 \ -               _bkt_count++;                                                     \ -               _prev = (char*)(_thh);                                            \ -               _thh = _thh->hh_next;                                             \ -            }                                                                    \ -            _count += _bkt_count;                                                \ -            if ((head)->hh.tbl->buckets[_bkt_i].count !=  _bkt_count) {          \ -               HASH_OOPS("invalid bucket count %d, actual %d\n",                 \ -                (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count);              \ -            }                                                                    \ -        }                                                                        \ -        if (_count != (head)->hh.tbl->num_items) {                               \ -            HASH_OOPS("invalid hh item count %d, actual %d\n",                   \ -                (head)->hh.tbl->num_items, _count );                             \ -        }                                                                        \ -        /* traverse hh in app order; check next/prev integrity, count */         \ -        _count = 0;                                                              \ -        _prev = NULL;                                                            \ -        _thh =  &(head)->hh;                                                     \ -        while (_thh) {                                                           \ -           _count++;                                                             \ -           if (_prev !=(char*)(_thh->prev)) {                                    \ -              HASH_OOPS("invalid prev %p, actual %p\n",                          \ -                    _thh->prev, _prev );                                         \ -           }                                                                     \ -           _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh);                    \ -           _thh = ( _thh->next ?  (UT_hash_handle*)((char*)(_thh->next) +        \ -                                  (head)->hh.tbl->hho) : NULL );                 \ -        }                                                                        \ -        if (_count != (head)->hh.tbl->num_items) {                               \ -            HASH_OOPS("invalid app item count %d, actual %d\n",                  \ -                (head)->hh.tbl->num_items, _count );                             \ -        }                                                                        \ -    }                                                                            \ -} while (0) -#else -#define HASH_FSCK(hh,head)  -#endif - -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to  - * the descriptor to which this macro is defined for tuning the hash function. - * The app can #include <unistd.h> to get the prototype for write(2). */ -#ifdef HASH_EMIT_KEYS -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                                   \ -do {                                                                             \ -    unsigned _klen = fieldlen;                                                   \ -    write(HASH_EMIT_KEYS, &_klen, sizeof(_klen));                                \ -    write(HASH_EMIT_KEYS, keyptr, fieldlen);                                     \ -} while (0) -#else  -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)                     -#endif - -/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ -#ifdef HASH_FUNCTION  -#define HASH_FCN HASH_FUNCTION -#else -#define HASH_FCN HASH_JEN -#endif - -/* The Bernstein hash function, used in Perl prior to v5.6 */ -#define HASH_BER(key,keylen,num_bkts,hashv,bkt)                                  \ -do {                                                                             \ -  unsigned _hb_keylen=keylen;                                                    \ -  char *_hb_key=(char*)(key);                                                    \ -  (hashv) = 0;                                                                   \ -  while (_hb_keylen--)  { (hashv) = ((hashv) * 33) + *_hb_key++; }               \ -  bkt = (hashv) & (num_bkts-1);                                                  \ -} while (0) - - -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at  - * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ -#define HASH_SAX(key,keylen,num_bkts,hashv,bkt)                                  \ -do {                                                                             \ -  unsigned _sx_i;                                                                \ -  char *_hs_key=(char*)(key);                                                    \ -  hashv = 0;                                                                     \ -  for(_sx_i=0; _sx_i < keylen; _sx_i++)                                          \ -      hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i];                     \ -  bkt = hashv & (num_bkts-1);                                                    \ -} while (0) - -#define HASH_FNV(key,keylen,num_bkts,hashv,bkt)                                  \ -do {                                                                             \ -  unsigned _fn_i;                                                                \ -  char *_hf_key=(char*)(key);                                                    \ -  hashv = 2166136261UL;                                                          \ -  for(_fn_i=0; _fn_i < keylen; _fn_i++)                                          \ -      hashv = (hashv * 16777619) ^ _hf_key[_fn_i];                               \ -  bkt = hashv & (num_bkts-1);                                                    \ -} while(0)  -  -#define HASH_OAT(key,keylen,num_bkts,hashv,bkt)                                  \ -do {                                                                             \ -  unsigned _ho_i;                                                                \ -  char *_ho_key=(char*)(key);                                                    \ -  hashv = 0;                                                                     \ -  for(_ho_i=0; _ho_i < keylen; _ho_i++) {                                        \ -      hashv += _ho_key[_ho_i];                                                   \ -      hashv += (hashv << 10);                                                    \ -      hashv ^= (hashv >> 6);                                                     \ -  }                                                                              \ -  hashv += (hashv << 3);                                                         \ -  hashv ^= (hashv >> 11);                                                        \ -  hashv += (hashv << 15);                                                        \ -  bkt = hashv & (num_bkts-1);                                                    \ -} while(0) - -#define HASH_JEN_MIX(a,b,c)                                                      \ -do {                                                                             \ -  a -= b; a -= c; a ^= ( c >> 13 );                                              \ -  b -= c; b -= a; b ^= ( a << 8 );                                               \ -  c -= a; c -= b; c ^= ( b >> 13 );                                              \ -  a -= b; a -= c; a ^= ( c >> 12 );                                              \ -  b -= c; b -= a; b ^= ( a << 16 );                                              \ -  c -= a; c -= b; c ^= ( b >> 5 );                                               \ -  a -= b; a -= c; a ^= ( c >> 3 );                                               \ -  b -= c; b -= a; b ^= ( a << 10 );                                              \ -  c -= a; c -= b; c ^= ( b >> 15 );                                              \ -} while (0) - -#define HASH_JEN(key,keylen,num_bkts,hashv,bkt)                                  \ -do {                                                                             \ -  unsigned _hj_i,_hj_j,_hj_k;                                                    \ -  unsigned char *_hj_key=(unsigned char*)(key);                                  \ -  hashv = 0xfeedbeef;                                                            \ -  _hj_i = _hj_j = 0x9e3779b9;                                                    \ -  _hj_k = (unsigned)(keylen);                                                      \ -  while (_hj_k >= 12) {                                                          \ -    _hj_i +=    (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 )                      \ -        + ( (unsigned)_hj_key[2] << 16 )                                         \ -        + ( (unsigned)_hj_key[3] << 24 ) );                                      \ -    _hj_j +=    (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 )                      \ -        + ( (unsigned)_hj_key[6] << 16 )                                         \ -        + ( (unsigned)_hj_key[7] << 24 ) );                                      \ -    hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 )                         \ -        + ( (unsigned)_hj_key[10] << 16 )                                        \ -        + ( (unsigned)_hj_key[11] << 24 ) );                                     \ -                                                                                 \ -     HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                          \ -                                                                                 \ -     _hj_key += 12;                                                              \ -     _hj_k -= 12;                                                                \ -  }                                                                              \ -  hashv += keylen;                                                               \ -  switch ( _hj_k ) {                                                             \ -     case 11: hashv += ( (unsigned)_hj_key[10] << 24 );                          \ -     case 10: hashv += ( (unsigned)_hj_key[9] << 16 );                           \ -     case 9:  hashv += ( (unsigned)_hj_key[8] << 8 );                            \ -     case 8:  _hj_j += ( (unsigned)_hj_key[7] << 24 );                           \ -     case 7:  _hj_j += ( (unsigned)_hj_key[6] << 16 );                           \ -     case 6:  _hj_j += ( (unsigned)_hj_key[5] << 8 );                            \ -     case 5:  _hj_j += _hj_key[4];                                               \ -     case 4:  _hj_i += ( (unsigned)_hj_key[3] << 24 );                           \ -     case 3:  _hj_i += ( (unsigned)_hj_key[2] << 16 );                           \ -     case 2:  _hj_i += ( (unsigned)_hj_key[1] << 8 );                            \ -     case 1:  _hj_i += _hj_key[0];                                               \ -  }                                                                              \ -  HASH_JEN_MIX(_hj_i, _hj_j, hashv);                                             \ -  bkt = hashv & (num_bkts-1);                                                    \ -} while(0) - -/* The Paul Hsieh hash function */ -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__)             \ -  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)             \ -                       +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif -#define HASH_SFH(key,keylen,num_bkts,hashv,bkt)                                  \ -do {                                                                             \ -  unsigned char *_sfh_key=(unsigned char*)(key);                                 \ -  uint32_t _sfh_tmp, _sfh_len = keylen;                                          \ -                                                                                 \ -  int _sfh_rem = _sfh_len & 3;                                                   \ -  _sfh_len >>= 2;                                                                \ -  hashv = 0xcafebabe;                                                            \ -                                                                                 \ -  /* Main loop */                                                                \ -  for (;_sfh_len > 0; _sfh_len--) {                                              \ -    hashv    += get16bits (_sfh_key);                                            \ -    _sfh_tmp       = (uint32_t)(get16bits (_sfh_key+2)) << 11  ^ hashv;          \ -    hashv     = (hashv << 16) ^ _sfh_tmp;                                        \ -    _sfh_key += 2*sizeof (uint16_t);                                             \ -    hashv    += hashv >> 11;                                                     \ -  }                                                                              \ -                                                                                 \ -  /* Handle end cases */                                                         \ -  switch (_sfh_rem) {                                                            \ -    case 3: hashv += get16bits (_sfh_key);                                       \ -            hashv ^= hashv << 16;                                                \ -            hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18);              \ -            hashv += hashv >> 11;                                                \ -            break;                                                               \ -    case 2: hashv += get16bits (_sfh_key);                                       \ -            hashv ^= hashv << 11;                                                \ -            hashv += hashv >> 17;                                                \ -            break;                                                               \ -    case 1: hashv += *_sfh_key;                                                  \ -            hashv ^= hashv << 10;                                                \ -            hashv += hashv >> 1;                                                 \ -  }                                                                              \ -                                                                                 \ -    /* Force "avalanching" of final 127 bits */                                  \ -    hashv ^= hashv << 3;                                                         \ -    hashv += hashv >> 5;                                                         \ -    hashv ^= hashv << 4;                                                         \ -    hashv += hashv >> 17;                                                        \ -    hashv ^= hashv << 25;                                                        \ -    hashv += hashv >> 6;                                                         \ -    bkt = hashv & (num_bkts-1);                                                  \ -} while(0)  - -#ifdef HASH_USING_NO_STRICT_ALIASING -/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. - * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. - * MurmurHash uses the faster approach only on CPU's where we know it's safe.  - * - * Note the preprocessor built-in defines can be emitted using: - * - *   gcc -m64 -dM -E - < /dev/null                  (on gcc) - *   cc -## a.c (where a.c is a simple test file)   (Sun Studio) - */ -#if (defined(__i386__) || defined(__x86_64__)  || defined(_M_IX86)) -#define MUR_GETBLOCK(p,i) p[i] -#else /* non intel */ -#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) -#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) -#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) -#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) -#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) -#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) -#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) -#define MUR_TWO_TWO(p)   ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) -#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >>  8)) -#else /* assume little endian non-intel */ -#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) -#define MUR_TWO_TWO(p)   ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) -#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) <<  8)) -#endif -#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) :           \ -                            (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ -                             (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) :  \ -                                                      MUR_ONE_THREE(p)))) -#endif -#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) -#define MUR_FMIX(_h) \ -do {                 \ -  _h ^= _h >> 16;    \ -  _h *= 0x85ebca6b;  \ -  _h ^= _h >> 13;    \ -  _h *= 0xc2b2ae35l; \ -  _h ^= _h >> 16;    \ -} while(0) - -#define HASH_MUR(key,keylen,num_bkts,hashv,bkt)                        \ -do {                                                                   \ -  const uint8_t *_mur_data = (const uint8_t*)(key);                    \ -  const int _mur_nblocks = (keylen) / 4;                               \ -  uint32_t _mur_h1 = 0xf88D5353;                                       \ -  uint32_t _mur_c1 = 0xcc9e2d51;                                       \ -  uint32_t _mur_c2 = 0x1b873593;                                       \ -  uint32_t _mur_k1 = 0;                                                \ -  const uint8_t *_mur_tail;                                            \ -  const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ -  int _mur_i;                                                          \ -  for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) {                      \ -    _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i);                        \ -    _mur_k1 *= _mur_c1;                                                \ -    _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \ -    _mur_k1 *= _mur_c2;                                                \ -                                                                       \ -    _mur_h1 ^= _mur_k1;                                                \ -    _mur_h1 = MUR_ROTL32(_mur_h1,13);                                  \ -    _mur_h1 = _mur_h1*5+0xe6546b64;                                    \ -  }                                                                    \ -  _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4);            \ -  _mur_k1=0;                                                           \ -  switch((keylen) & 3) {                                               \ -    case 3: _mur_k1 ^= _mur_tail[2] << 16;                             \ -    case 2: _mur_k1 ^= _mur_tail[1] << 8;                              \ -    case 1: _mur_k1 ^= _mur_tail[0];                                   \ -    _mur_k1 *= _mur_c1;                                                \ -    _mur_k1 = MUR_ROTL32(_mur_k1,15);                                  \ -    _mur_k1 *= _mur_c2;                                                \ -    _mur_h1 ^= _mur_k1;                                                \ -  }                                                                    \ -  _mur_h1 ^= (keylen);                                                 \ -  MUR_FMIX(_mur_h1);                                                   \ -  hashv = _mur_h1;                                                     \ -  bkt = hashv & (num_bkts-1);                                          \ -} while(0) -#endif  /* HASH_USING_NO_STRICT_ALIASING */ - -/* key comparison function; return 0 if keys equal */ -#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)  - -/* iterate over items in a known bucket to find desired item */ -#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out)                       \ -do {                                                                             \ - if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head));          \ - else out=NULL;                                                                  \ - while (out) {                                                                   \ -    if ((out)->hh.keylen == keylen_in) {                                           \ -        if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break;             \ -    }                                                                            \ -    if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ -    else out = NULL;                                                             \ - }                                                                               \ -} while(0) - -/* add an item to a bucket  */ -#define HASH_ADD_TO_BKT(head,addhh)                                              \ -do {                                                                             \ - head.count++;                                                                   \ - (addhh)->hh_next = head.hh_head;                                                \ - (addhh)->hh_prev = NULL;                                                        \ - if (head.hh_head) { (head).hh_head->hh_prev = (addhh); }                        \ - (head).hh_head=addhh;                                                           \ - if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH)             \ -     && (addhh)->tbl->noexpand != 1) {                                           \ -       HASH_EXPAND_BUCKETS((addhh)->tbl);                                        \ - }                                                                               \ -} while(0) - -/* remove an item from a given bucket */ -#define HASH_DEL_IN_BKT(hh,head,hh_del)                                          \ -    (head).count--;                                                              \ -    if ((head).hh_head == hh_del) {                                              \ -      (head).hh_head = hh_del->hh_next;                                          \ -    }                                                                            \ -    if (hh_del->hh_prev) {                                                       \ -        hh_del->hh_prev->hh_next = hh_del->hh_next;                              \ -    }                                                                            \ -    if (hh_del->hh_next) {                                                       \ -        hh_del->hh_next->hh_prev = hh_del->hh_prev;                              \ -    }                                                                 - -/* Bucket expansion has the effect of doubling the number of buckets - * and redistributing the items into the new buckets. Ideally the - * items will distribute more or less evenly into the new buckets - * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain).  - *  - * With the items distributed into more buckets, the chain length - * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain  - * length is the essence of how a hash provides constant time lookup. - *  - * The calculation of tbl->ideal_chain_maxlen below deserves some - * explanation. First, keep in mind that we're calculating the ideal - * maximum chain length based on the *new* (doubled) bucket count. - * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate  - * ceil(n/b). We don't depend on floating point arithmetic in this - * hash, so to calculate ceil(n/b) with integers we could write - *  - *      ceil(n/b) = (n/b) + ((n%b)?1:0) - *  - * and in fact a previous version of this hash did just that. - * But now we have improved things a bit by recognizing that b is - * always a power of two. We keep its base 2 log handy (call it lb), - * so now we can write this with a bit shift and logical AND: - *  - *      ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - *  - */ -#define HASH_EXPAND_BUCKETS(tbl)                                                 \ -do {                                                                             \ -    unsigned _he_bkt;                                                            \ -    unsigned _he_bkt_i;                                                          \ -    struct UT_hash_handle *_he_thh, *_he_hh_nxt;                                 \ -    UT_hash_bucket *_he_new_buckets, *_he_newbkt;                                \ -    _he_new_buckets = (UT_hash_bucket*)uthash_malloc(                            \ -             2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));              \ -    if (!_he_new_buckets) { uthash_fatal( "out of memory"); }                    \ -    memset(_he_new_buckets, 0,                                                   \ -            2 * tbl->num_buckets * sizeof(struct UT_hash_bucket));               \ -    tbl->ideal_chain_maxlen =                                                    \ -       (tbl->num_items >> (tbl->log2_num_buckets+1)) +                           \ -       ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0);                    \ -    tbl->nonideal_items = 0;                                                     \ -    for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++)                \ -    {                                                                            \ -        _he_thh = tbl->buckets[ _he_bkt_i ].hh_head;                             \ -        while (_he_thh) {                                                        \ -           _he_hh_nxt = _he_thh->hh_next;                                        \ -           HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt);            \ -           _he_newbkt = &(_he_new_buckets[ _he_bkt ]);                           \ -           if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) {                \ -             tbl->nonideal_items++;                                              \ -             _he_newbkt->expand_mult = _he_newbkt->count /                       \ -                                        tbl->ideal_chain_maxlen;                 \ -           }                                                                     \ -           _he_thh->hh_prev = NULL;                                              \ -           _he_thh->hh_next = _he_newbkt->hh_head;                               \ -           if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev =               \ -                _he_thh;                                                         \ -           _he_newbkt->hh_head = _he_thh;                                        \ -           _he_thh = _he_hh_nxt;                                                 \ -        }                                                                        \ -    }                                                                            \ -    uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ -    tbl->num_buckets *= 2;                                                       \ -    tbl->log2_num_buckets++;                                                     \ -    tbl->buckets = _he_new_buckets;                                              \ -    tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ?         \ -        (tbl->ineff_expands+1) : 0;                                              \ -    if (tbl->ineff_expands > 1) {                                                \ -        tbl->noexpand=1;                                                         \ -        uthash_noexpand_fyi(tbl);                                                \ -    }                                                                            \ -    uthash_expand_fyi(tbl);                                                      \ -} while(0) - - -/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh.  - * HASH_SRT was added to allow the hash handle name to be passed in. */ -#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) -#define HASH_SRT(hh,head,cmpfcn)                                                 \ -do {                                                                             \ -  unsigned _hs_i;                                                                \ -  unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize;               \ -  struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail;            \ -  if (head) {                                                                    \ -      _hs_insize = 1;                                                            \ -      _hs_looping = 1;                                                           \ -      _hs_list = &((head)->hh);                                                  \ -      while (_hs_looping) {                                                      \ -          _hs_p = _hs_list;                                                      \ -          _hs_list = NULL;                                                       \ -          _hs_tail = NULL;                                                       \ -          _hs_nmerges = 0;                                                       \ -          while (_hs_p) {                                                        \ -              _hs_nmerges++;                                                     \ -              _hs_q = _hs_p;                                                     \ -              _hs_psize = 0;                                                     \ -              for ( _hs_i = 0; _hs_i  < _hs_insize; _hs_i++ ) {                  \ -                  _hs_psize++;                                                   \ -                  _hs_q = (UT_hash_handle*)((_hs_q->next) ?                      \ -                          ((void*)((char*)(_hs_q->next) +                        \ -                          (head)->hh.tbl->hho)) : NULL);                         \ -                  if (! (_hs_q) ) break;                                         \ -              }                                                                  \ -              _hs_qsize = _hs_insize;                                            \ -              while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) {           \ -                  if (_hs_psize == 0) {                                          \ -                      _hs_e = _hs_q;                                             \ -                      _hs_q = (UT_hash_handle*)((_hs_q->next) ?                  \ -                              ((void*)((char*)(_hs_q->next) +                    \ -                              (head)->hh.tbl->hho)) : NULL);                     \ -                      _hs_qsize--;                                               \ -                  } else if ( (_hs_qsize == 0) || !(_hs_q) ) {                   \ -                      _hs_e = _hs_p;                                             \ -                      if (_hs_p){                                                \ -                        _hs_p = (UT_hash_handle*)((_hs_p->next) ?                \ -                                ((void*)((char*)(_hs_p->next) +                  \ -                                (head)->hh.tbl->hho)) : NULL);                   \ -                       }                                                         \ -                      _hs_psize--;                                               \ -                  } else if ((                                                   \ -                      cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ -                             DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ -                             ) <= 0) {                                           \ -                      _hs_e = _hs_p;                                             \ -                      if (_hs_p){                                                \ -                        _hs_p = (UT_hash_handle*)((_hs_p->next) ?                \ -                               ((void*)((char*)(_hs_p->next) +                   \ -                               (head)->hh.tbl->hho)) : NULL);                    \ -                       }                                                         \ -                      _hs_psize--;                                               \ -                  } else {                                                       \ -                      _hs_e = _hs_q;                                             \ -                      _hs_q = (UT_hash_handle*)((_hs_q->next) ?                  \ -                              ((void*)((char*)(_hs_q->next) +                    \ -                              (head)->hh.tbl->hho)) : NULL);                     \ -                      _hs_qsize--;                                               \ -                  }                                                              \ -                  if ( _hs_tail ) {                                              \ -                      _hs_tail->next = ((_hs_e) ?                                \ -                            ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL);          \ -                  } else {                                                       \ -                      _hs_list = _hs_e;                                          \ -                  }                                                              \ -                  if (_hs_e) {                                                   \ -                  _hs_e->prev = ((_hs_tail) ?                                    \ -                     ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL);              \ -                  }                                                              \ -                  _hs_tail = _hs_e;                                              \ -              }                                                                  \ -              _hs_p = _hs_q;                                                     \ -          }                                                                      \ -          if (_hs_tail){                                                         \ -            _hs_tail->next = NULL;                                               \ -          }                                                                      \ -          if ( _hs_nmerges <= 1 ) {                                              \ -              _hs_looping=0;                                                     \ -              (head)->hh.tbl->tail = _hs_tail;                                   \ -              DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list));      \ -          }                                                                      \ -          _hs_insize *= 2;                                                       \ -      }                                                                          \ -      HASH_FSCK(hh,head);                                                        \ - }                                                                               \ -} while (0) - -/* This function selects items from one hash into another hash.  - * The end result is that the selected items have dual presence  - * in both hashes. There is no copy of the items made; rather  - * they are added into the new hash through a secondary hash  - * hash handle that must be present in the structure. */ -#define HASH_SELECT(hh_dst, dst, hh_src, src, cond)                              \ -do {                                                                             \ -  unsigned _src_bkt, _dst_bkt;                                                   \ -  void *_last_elt=NULL, *_elt;                                                   \ -  UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL;                         \ -  ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst));                 \ -  if (src) {                                                                     \ -    for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) {     \ -      for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head;                \ -          _src_hh;                                                               \ -          _src_hh = _src_hh->hh_next) {                                          \ -          _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh);                       \ -          if (cond(_elt)) {                                                      \ -            _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho);               \ -            _dst_hh->key = _src_hh->key;                                         \ -            _dst_hh->keylen = _src_hh->keylen;                                   \ -            _dst_hh->hashv = _src_hh->hashv;                                     \ -            _dst_hh->prev = _last_elt;                                           \ -            _dst_hh->next = NULL;                                                \ -            if (_last_elt_hh) { _last_elt_hh->next = _elt; }                     \ -            if (!dst) {                                                          \ -              DECLTYPE_ASSIGN(dst,_elt);                                         \ -              HASH_MAKE_TABLE(hh_dst,dst);                                       \ -            } else {                                                             \ -              _dst_hh->tbl = (dst)->hh_dst.tbl;                                  \ -            }                                                                    \ -            HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt);    \ -            HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh);            \ -            (dst)->hh_dst.tbl->num_items++;                                      \ -            _last_elt = _elt;                                                    \ -            _last_elt_hh = _dst_hh;                                              \ -          }                                                                      \ -      }                                                                          \ -    }                                                                            \ -  }                                                                              \ -  HASH_FSCK(hh_dst,dst);                                                         \ -} while (0) - -#define HASH_CLEAR(hh,head)                                                      \ -do {                                                                             \ -  if (head) {                                                                    \ -    uthash_free((head)->hh.tbl->buckets,                                         \ -                (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket));      \ -    HASH_BLOOM_FREE((head)->hh.tbl);                                             \ -    uthash_free((head)->hh.tbl, sizeof(UT_hash_table));                          \ -    (head)=NULL;                                                                 \ -  }                                                                              \ -} while(0) - -#define HASH_OVERHEAD(hh,head)                                                   \ - (size_t)((((head)->hh.tbl->num_items   * sizeof(UT_hash_handle))   +            \ -           ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket))   +            \ -            (sizeof(UT_hash_table))                                 +            \ -            (HASH_BLOOM_BYTELEN))) - -#ifdef NO_DECLTYPE -#define HASH_ITER(hh,head,el,tmp)                                                \ -for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL);       \ -  el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))  -#else -#define HASH_ITER(hh,head,el,tmp)                                                \ -for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL);                 \ -  el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) -#endif - -/* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head)  -#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) - -typedef struct UT_hash_bucket { -   struct UT_hash_handle *hh_head; -   unsigned count; - -   /* expand_mult is normally set to 0. In this situation, the max chain length -    * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If -    * the bucket's chain exceeds this length, bucket expansion is triggered).  -    * However, setting expand_mult to a non-zero value delays bucket expansion -    * (that would be triggered by additions to this particular bucket) -    * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. -    * (The multiplier is simply expand_mult+1). The whole idea of this -    * multiplier is to reduce bucket expansions, since they are expensive, in -    * situations where we know that a particular bucket tends to be overused. -    * It is better to let its chain length grow to a longer yet-still-bounded -    * value, than to do an O(n) bucket expansion too often.  -    */ -   unsigned expand_mult; - -} UT_hash_bucket; - -/* random signature used only to find hash tables in external analysis */ -#define HASH_SIGNATURE 0xa0111fe1 -#define HASH_BLOOM_SIGNATURE 0xb12220f2 - -typedef struct UT_hash_table { -   UT_hash_bucket *buckets; -   unsigned num_buckets, log2_num_buckets; -   unsigned num_items; -   struct UT_hash_handle *tail; /* tail hh in app order, for fast append    */ -   ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ - -   /* in an ideal situation (all buckets used equally), no bucket would have -    * more than ceil(#items/#buckets) items. that's the ideal chain length. */ -   unsigned ideal_chain_maxlen; - -   /* nonideal_items is the number of items in the hash whose chain position -    * exceeds the ideal chain maxlen. these items pay the penalty for an uneven -    * hash distribution; reaching them in a chain traversal takes >ideal steps */ -   unsigned nonideal_items; - -   /* ineffective expands occur when a bucket doubling was performed, but  -    * afterward, more than half the items in the hash had nonideal chain -    * positions. If this happens on two consecutive expansions we inhibit any -    * further expansion, as it's not helping; this happens when the hash -    * function isn't a good fit for the key domain. When expansion is inhibited -    * the hash will still work, albeit no longer in constant time. */ -   unsigned ineff_expands, noexpand; - -   uint32_t signature; /* used only to find hash tables in external analysis */ -#ifdef HASH_BLOOM -   uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ -   uint8_t *bloom_bv; -   char bloom_nbits; -#endif - -} UT_hash_table; - -typedef struct UT_hash_handle { -   struct UT_hash_table *tbl; -   void *prev;                       /* prev element in app order      */ -   void *next;                       /* next element in app order      */ -   struct UT_hash_handle *hh_prev;   /* previous hh in bucket order    */ -   struct UT_hash_handle *hh_next;   /* next hh in bucket order        */ -   void *key;                        /* ptr to enclosing struct's key  */ -   unsigned keylen;                  /* enclosing struct's key len     */ -   unsigned hashv;                   /* result of hash-fcn(key)        */ -} UT_hash_handle; - -#endif /* UTHASH_H */  | 
