FYI: This is the classic Lorem Ipsum text that has been used" " for placeholder purposes throughout the print industry since the 1500s." " Its purpose here is to test how large blocks of text will look with the fonts and sizes you have selected." " These results are generally consistent but may vary slightly depending on which browser you use (This example is rendered with Webkit).
"); lipsum.append("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque laoreet vestibulum libero vitae accumsan. "); lipsum.append("Nullam et nulla nunc, non luctus elit. Etiam aliquam, turpis nec pellentesque interdum, purus nulla dictum tortor, "); lipsum.append("nec lacinia orci turpis ac lectus. Suspendisse dignissim, lectus nec posuere consectetur, massa quam rhoncus velit, "); lipsum.append("eu viverra est risus ac enim. Nullam augue lacus, imperdiet ac iaculis eu, scelerisque quis nulla. Donec tempor "); lipsum.append("lacus molestie arcu aliquam scelerisque. Proin vitae augue quis quam imperdiet porttitor id sed magna. Nulla non "); lipsum.append("urna purus. Vivamus dui diam, eleifend a laoreet sit amet, dignissim vel odio. Pellentesque adipiscing sodales ante "); lipsum.append("at tempor. Vestibulum libero risus, malesuada vel scelerisque ut, facilisis ac nulla. Nam congue urna non diam pretium "); lipsum.append("dapibus.
"); lipsum.append("Proin viverra odio a dolor lacinia tincidunt. Nunc tempor adipiscing dolor, id condimentum leo facilisis a. Aliquam "); lipsum.append("erat volutpat. Cras vitae ligula mauris. Etiam nec orci ac velit mattis semper vel ut metus. Pellentesque sagittis "); lipsum.append("ultricies nisi, at commodo metus posuere a. Sed neque nunc, sagittis non elementum ut, imperdiet eget purus. "); lipsum.append("Nulla non tortor sit amet ipsum porttitor suscipit. Maecenas ipsum erat, porta id porta ac, convallis sit amet erat. "); lipsum.append("Nunc libero felis, blandit id vehicula dapibus, vehicula quis erat. Nam feugiat, elit a vestibulum sagittis, diam "); lipsum.append("metus faucibus nulla, hendrerit ullamcorper mi nulla sit amet tellus. Praesent placerat velit quis lectus lacinia "); lipsum.append("sed laoreet magna sagittis. Maecenas lacinia, metus at ultrices sodales, quam orci ullamcorper neque, viverra "); lipsum.append("molestie metus dolor vel velit. Mauris ligula orci, ullamcorper at adipiscing ornare, euismod sed augue. Praesent "); lipsum.append("nec leo arcu, id elementum leo. Aliquam fringilla semper nulla, eget congue turpis volutpat sed.
"); QString css_header_spec; if(use_em_header){ css_header_spec=header_size + "em"; } else{ css_header_spec=header_size + "pt"; } QString css_body_spec; if(use_em_body){ css_body_spec=body_size + "em"; } else{ css_body_spec=body_size + "pt"; } QString bgcolor; QString datebox_color; if(use_system_colors){ // use system colors for datebox QPalette pal; QColor bg=pal.highlight().color(); QColor fg=pal.highlightedText().color(); bgcolor=bg.name(); datebox_color=fg.name(); } else{ bgcolor="#e2e2e2"; datebox_color="#000000"; } QString output; output.append("\n"); output.append("\n"); output.append("\n"); output.append("\n"); output.append("This file was generated by RoboJournal " + Buffer::version +" on [export date & timestamp].
"); output.append("\n"); output.append(""); return output; } robojournal-0.4.2/ui/mainwindow.cpp 0000644 0001750 0001750 00000353071 12215133025 016051 0 ustar will will /* This file is part of RoboJournal. Copyright (c) 2012 by Will KraftEnter the pattern (one or more words) you wish to search for in this field and click the Search button to continue.
FYI: The pattern search function is case-sensitive!
Click Search to display all entries marked with the currently-selected tag.
"); ui->SearchTerm->setToolTip("The search pattern input field is not available in tag search mode.
"); GetTagList(); Buffer::LastSearchTerm.clear(); } else{ ui->SearchTerm->setDisabled(false); ui->TagList->setDisabled(true); ui->TagList->setToolTip("Tag search is not available in pattern-match mode.
"); ui->SearchTerm->setToolTip("Enter the pattern (one or more words) you wish to search for in this field and click the Search button to continue.
FYI: The pattern search function is case-sensitive!
Tags: No tag data
"; // } // else{ // entry_tags=entry_tags.replace(";","" << body << "
" << endl; //stream << "\t\t" << entry_tags << "
This file was generated by RoboJournal " << Buffer::version << " on " << exportdt << "
" << endl; stream << "" << endl; stream << "" << endl; } // do plain text export else{ // Convert HTML Hyphens and dashes to plain text body=body.replace(QRegExp("—"),"--"); body=body.replace(QRegExp("–"),"-"); body=body.replace(QRegExp("…"),"..."); body=body.replace(QRegExp("’"),"\'"); body=body.replace(QRegExp("?sup>"),""); // word wrapping is still broken, don't use it. /* QString formatted_body; QStringList body_wrap=Do_Word_Wrap(body); for(int i=0; iAll entries have been arranged from oldest to newest.
"; } else{ intro="All entries have been arranged from newest to oldest.
"; } if(file.open(QIODevice::ReadWrite)) { QTextStream stream(&file); // HTML Export if(use_html){ // Prepare CSS values SetupCSS(); stream << "" << endl; stream << "" << endl; stream << "" << endl; stream << "" << endl; stream << "Tags: No tag data
"; } else{ entry_tags=entry_tags.replace(";","" << entry_body << "
" << endl; stream << "\t\t" << entry_tags << "
This file was generated by RoboJournal " << Buffer::version << " on " << exportdt << "
" << endl; stream << "" << endl; stream << "" << endl; file.close(); } // plain text export else{ QString br="\n"; #ifdef _WIN32 // Use Windows style linebreaks if necessary. A real text editor knows what to do with \n but // we have to assume most people will use Notepad. Why they don't get anything better is something // I'll never understand. br="\r\n"; #endif // remove HTML from intro intro=intro.replace("?\\w+>",""); // add title and header to text file stream << dumptitle << br << br << endl; stream << intro << br << br << endl; stream << "##########################################################" << br << br << endl; while(j.hasNext()){ count++; QString entrynumber=QString::number(count); QStringList thisentry=j.next(); QString entry_title=thisentry.at(0); QString entry_month=thisentry.at(2); QString entry_day=thisentry.at(1); QString entry_year=thisentry.at(3); QString entry_tags=thisentry.at(4); QString entry_body=thisentry.at(5); QString entry_time=thisentry.at(6); entry_body=entry_body.replace("\n",br); // Convert HTML Hyphens and dashes to plain text entry_body=entry_body.replace(QRegExp("—"),"--"); entry_body=entry_body.replace(QRegExp("–"),"-"); entry_body=entry_body.replace(QRegExp("…"),"..."); entry_body=entry_body.replace(QRegExp("’"),"\'"); entry_body=entry_body.replace(QRegExp("?sup>"),""); //strip HTML from entry body entry_body=entry_body.replace("?\\w+>",""); if(entry_tags.isEmpty()){ entry_tags="No tag data."; } else{ // turn tags into bullet list QString tagdiv=br + "*"; entry_tags=entry_tags.replace(";",tagdiv); entry_tags= br + "Tags: " + br + br + "*" + entry_tags; } if(entry_time.isEmpty()){ entry_time="[Unknown Time]"; } QString datestamp= entry_day + "/" + entry_month + "/" + entry_year; stream << entrynumber << ". " << entry_title << br << br << endl; stream << "On " << datestamp << " at " << entry_time << ", " << Buffer::username << " wrote:" << br << br<< endl; stream << entry_body << br << br << endl; stream << entry_tags << br << br << endl; stream << "##########################################################" << br << br << endl; } stream << "This file was generated by RoboJournal " << Buffer::version << " on " << exportdt << endl; file.close(); } QMessageBox b; b.information(this,"RoboJournal", "This feature is temporarily unavailable on Linux-based operating systems.
"); ui->ShowSpellingErrors->setToolTip("This feature is temporarily unavailable on Linux-based operating systems.
"); ui->Dictionary->setToolTip("This feature is temporarily unavailable on Linux-based operating systems.
"); ui->BrowseButton->setToolTip("This feature is temporarily unavailable on Linux-based operating systems.
"); #endif } ConfigurationEditor::~ConfigurationEditor() { delete ui; } //############################################################################################################# void ConfigurationEditor::PopulateForm(){ ui->TrimWhiteSpace->setChecked(Buffer::trim_whitespace); ui->ForceHyphens->setChecked(Buffer::use_html_hyphens); ui->ForceSmartQuotes->setChecked(Buffer::use_smart_quotes); ui->MiscFormatting->setChecked(Buffer::use_misc_processing); if(Buffer::use_custom_theme){ ui->CustomThemeEditor->setDisabled(false); ui->CustomThemeEditor->setChecked(Buffer::use_custom_theme_editor); } else{ ui->CustomThemeEditor->setDisabled(true); ui->CustomThemeEditor->setChecked(false); } if(Buffer::use_spellcheck){ ui->UseSpellCheck->setChecked(true); ui->BrowseButton->setDisabled(false); ui->ShowSpellingErrors->setDisabled(false); ui->Dictionary->setDisabled(false); ui->ShowSpellingErrors->setChecked(Buffer::show_spell_errors_by_default); ui->Dictionary->setText(Buffer::current_dictionary); } else{ ui->UseSpellCheck->setChecked(false); ui->ShowSpellingErrors->setDisabled(true); ui->ShowSpellingErrors->setChecked(false); ui->BrowseButton->setDisabled(true); ui->Dictionary->setDisabled(true); ui->Dictionary->clear(); } } //############################################################################################################# void ConfigurationEditor::GetChanges(){ Newconfig::new_trim_whitespace=ui->TrimWhiteSpace->isChecked(); Newconfig::new_use_html_hyphens=ui->ForceHyphens->isChecked(); Newconfig::new_use_smart_quotes=ui->ForceSmartQuotes->isChecked(); Newconfig::new_use_custom_theme_editor=ui->CustomThemeEditor->isChecked(); Newconfig::new_use_spellcheck=ui->UseSpellCheck->isChecked(); Newconfig::new_show_spell_errors_by_default=ui->ShowSpellingErrors->isChecked(); Newconfig::new_current_dictionary=ui->Dictionary->text(); Newconfig::new_use_misc_processing=ui->MiscFormatting->isChecked(); // Preserve current AFF value if the user didn't make changes this session if(!aff_file.isEmpty()){ Newconfig::new_current_dictionary_aff=aff_file; } else{ Newconfig::new_current_dictionary_aff=Buffer::current_dictionary_aff; } } //############################################################################################################# void ConfigurationEditor::on_BrowseButton_clicked() { QString folderpath=QDir::homePath()+ QDir::separator() + ".robojournal"+ QDir::separator(); // This code is from Jan Sundermeyer's Spellcheck program. QString fileName = QFileDialog::getOpenFileName(this, tr("Select Dictionary"), folderpath, tr("Dictionary (*.dic)")); QString new_Dict=fileName; //Find AFF file and save it. if(!new_Dict.isEmpty()){ aff_file=Find_AFF_File(new_Dict); } if(!new_Dict.isEmpty()){ ui->Dictionary->setText(new_Dict); } else{ ui->UseSpellCheck->setChecked(false); ui->ShowSpellingErrors->setChecked(false); ui->BrowseButton->setEnabled(false); ui->ShowSpellingErrors->setEnabled(false); ui->Dictionary->setEnabled(false); } } //############################################################################################################# // Find and return the AFF file for the chosen dictionary. The AFF file contains grammer rules and more importantly keeps the // app from segfaulting on Windows. QString ConfigurationEditor::Find_AFF_File(QString dict){ using namespace std; QString aff_file="none"; int slashes=dict.count("/"); QString directory=dict.section("/",0,slashes-1); //cout << "Directory: " << directory.toStdString() << endl; QString dict_name=dict.section("/",slashes); dict_name.chop(4); //cout << "Base dict name: " << dict_name.toStdString() << endl; dict_name=dict_name+".aff"; QFile Aff(directory + QDir::separator() + dict_name); if(Aff.exists()){ cout << "OUTPUT: Found AFF File for selected dictionary (" << Aff.fileName().toStdString() << ")" << endl; aff_file=Aff.fileName(); } else{ QMessageBox m; int h=m.critical(this,"RoboJournal","RoboJournal couldn't find the AFF file for " "" + dict + " in the expected location. Do you want to find this file manually?",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes); switch(h){ case QMessageBox::Yes: aff_file= QFileDialog::getOpenFileName(this, tr("Select Aff File"),dict_name, tr("Aff Files (*.aff)")); break; case QMessageBox::No: // do nothing break; } } return aff_file; } //############################################################################################################# void ConfigurationEditor::on_UseSpellCheck_clicked(bool checked) { if(checked){ ui->BrowseButton->setDisabled(false); ui->Dictionary->setDisabled(false); ui->ShowSpellingErrors->setDisabled(false); ui->ShowSpellingErrors->setChecked(true); if(Buffer::current_dictionary.isEmpty()){ ui->BrowseButton->click(); } else{ ui->Dictionary->setText(Buffer::current_dictionary); } } else{ ui->BrowseButton->setDisabled(true); ui->Dictionary->setDisabled(true); ui->ShowSpellingErrors->setDisabled(true); ui->ShowSpellingErrors->setChecked(false); ui->Dictionary->clear(); } } robojournal-0.4.2/ui/highlighter.h 0000775 0001750 0001750 00000011114 12142060704 015634 0 ustar will will /* This file is part of RoboJournal. Copyright (c) 2013 by Will Kraftana1ana2
format
for (int i = 0; i < n; i++) s+= strlen((*slst)[i]);
char * r = (char *) malloc(6 + 5 * s + 7 * n + 7 + 1); // XXX 5*s->&->&
if (!r) return 0;
strcpy(r, "");
for (int i = 0; i < n; i++) {
int l = strlen(r);
strcpy(r + l, "");
strcpy(r + l + 3, (*slst)[i]);
mystrrep(r + l + 3, "\t", " ");
mystrrep(r + l + 3, "<", "<");
mystrrep(r + l + 3, "&", "&");
strcat(r, "");
free((*slst)[i]);
}
strcat(r, "
");
(*slst)[0] = r;
return 1;
} else if (check_xml_par(q, "type=", "stem")) {
if (get_xml_par(cw, strchr(q2, '>'), MAXWORDUTF8LEN)) return stem(slst, cw);
} else if (check_xml_par(q, "type=", "generate")) {
int n = get_xml_par(cw, strchr(q2, '>'), MAXWORDUTF8LEN);
if (n == 0) return 0;
char * q3 = strstr(q2 + 1, "'), ""))) {
int n2 = generate(slst, cw, slst2, n);
freelist(&slst2, n);
return uniqlist(*slst, n2);
}
}
}
return 0;
}
#ifdef HUNSPELL_EXPERIMENTAL
// XXX need UTF-8 support
char * Hunspell::morph_with_correction(const char * word)
{
char cw[MAXWORDUTF8LEN];
char wspace[MAXWORDUTF8LEN];
if (! pSMgr || maxdic == 0) return NULL;
int wl = strlen(word);
if (utf8) {
if (wl >= MAXWORDUTF8LEN) return NULL;
} else {
if (wl >= MAXWORDLEN) return NULL;
}
int captype = 0;
int abbv = 0;
wl = cleanword(cw, word, &captype, &abbv);
if (wl == 0) return NULL;
char result[MAXLNLEN];
char * st = NULL;
*result = '\0';
switch(captype) {
case NOCAP: {
st = pSMgr->suggest_morph_for_spelling_error(cw);
if (st) {
strcat(result, st);
free(st);
}
if (abbv) {
memcpy(wspace,cw,wl);
*(wspace+wl) = '.';
*(wspace+wl+1) = '\0';
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
}
break;
}
case INITCAP: {
memcpy(wspace,cw,(wl+1));
mkallsmall(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
strcat(result, st);
free(st);
}
st = pSMgr->suggest_morph_for_spelling_error(cw);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
if (abbv) {
memcpy(wspace,cw,wl);
*(wspace+wl) = '.';
*(wspace+wl+1) = '\0';
mkallsmall(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
mkinitcap(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
}
break;
}
case HUHCAP: {
st = pSMgr->suggest_morph_for_spelling_error(cw);
if (st) {
strcat(result, st);
free(st);
}
memcpy(wspace,cw,(wl+1));
mkallsmall(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
break;
}
case ALLCAP: {
memcpy(wspace,cw,(wl+1));
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
strcat(result, st);
free(st);
}
mkallsmall(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
mkinitcap(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
if (abbv) {
memcpy(wspace,cw,(wl+1));
*(wspace+wl) = '.';
*(wspace+wl+1) = '\0';
if (*result) strcat(result, "\n");
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
strcat(result, st);
free(st);
}
mkallsmall(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
mkinitcap(wspace);
st = pSMgr->suggest_morph_for_spelling_error(wspace);
if (st) {
if (*result) strcat(result, "\n");
strcat(result, st);
free(st);
}
}
break;
}
}
if (*result) return mystrdup(result);
return NULL;
}
#endif // END OF HUNSPELL_EXPERIMENTAL CODE
Hunhandle *Hunspell_create(const char * affpath, const char * dpath)
{
return (Hunhandle*)(new Hunspell(affpath, dpath));
}
Hunhandle *Hunspell_create_key(const char * affpath, const char * dpath,
const char * key)
{
return (Hunhandle*)(new Hunspell(affpath, dpath, key));
}
void Hunspell_destroy(Hunhandle *pHunspell)
{
delete (Hunspell*)(pHunspell);
}
int Hunspell_spell(Hunhandle *pHunspell, const char *word)
{
return ((Hunspell*)pHunspell)->spell(word);
}
char *Hunspell_get_dic_encoding(Hunhandle *pHunspell)
{
return ((Hunspell*)pHunspell)->get_dic_encoding();
}
int Hunspell_suggest(Hunhandle *pHunspell, char*** slst, const char * word)
{
return ((Hunspell*)pHunspell)->suggest(slst, word);
}
int Hunspell_analyze(Hunhandle *pHunspell, char*** slst, const char * word)
{
return ((Hunspell*)pHunspell)->analyze(slst, word);
}
int Hunspell_stem(Hunhandle *pHunspell, char*** slst, const char * word)
{
return ((Hunspell*)pHunspell)->stem(slst, word);
}
int Hunspell_stem(Hunhandle *pHunspell, char*** slst, char** desc, int n)
{
return ((Hunspell*)pHunspell)->stem(slst, desc, n);
}
int Hunspell_generate(Hunhandle *pHunspell, char*** slst, const char * word,
const char * word2)
{
return ((Hunspell*)pHunspell)->generate(slst, word, word2);
}
int Hunspell_generate(Hunhandle *pHunspell, char*** slst, const char * word,
char** desc, int n)
{
return ((Hunspell*)pHunspell)->generate(slst, word, desc, n);
}
/* functions for run-time modification of the dictionary */
/* add word to the run-time dictionary */
int Hunspell_add(Hunhandle *pHunspell, const char * word) {
return ((Hunspell*)pHunspell)->add(word);
}
/* add word to the run-time dictionary with affix flags of
* the example (a dictionary word): Hunspell will recognize
* affixed forms of the new word, too.
*/
int Hunspell_add_with_affix(Hunhandle *pHunspell, const char * word,
const char * example) {
return ((Hunspell*)pHunspell)->add_with_affix(word, example);
}
/* remove word from the run-time dictionary */
int Hunspell_remove(Hunhandle *pHunspell, const char * word) {
return ((Hunspell*)pHunspell)->remove(word);
}
void Hunspell_free_list(Hunhandle *pHunspell, char *** slst, int n) {
freelist(slst, n);
}
robojournal-0.4.2/ui/hunspell/dictmgr.cxx 0000644 0001750 0001750 00000015756 12211723646 017217 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include
#include
#include
#include
#include "ui/hunspell/dictmgr.hxx"
using namespace std;
DictMgr::DictMgr(const char * dictpath, const char * etype)
{
// load list of etype entries
numdict = 0;
pdentry = (dictentry *)malloc(MAXDICTIONARIES*sizeof(struct dictentry));
if (pdentry) {
if (parse_file(dictpath, etype)) {
numdict = 0;
// no dictionary.lst found is okay
}
} else {
numdict = 0;
}
}
DictMgr::~DictMgr()
{
dictentry * pdict = NULL;
if (pdentry) {
pdict = pdentry;
for (int i=0;ilang) {
free(pdict->lang);
pdict->lang = NULL;
}
if (pdict->region) {
free(pdict->region);
pdict->region=NULL;
}
if (pdict->filename) {
free(pdict->filename);
pdict->filename = NULL;
}
pdict++;
}
free(pdentry);
pdentry = NULL;
pdict = NULL;
}
numdict = 0;
}
// read in list of etype entries and build up structure to describe them
int DictMgr::parse_file(const char * dictpath, const char * etype)
{
int i;
char line[MAXDICTENTRYLEN+1];
dictentry * pdict = pdentry;
// open the dictionary list file
FILE * dictlst;
dictlst = fopen(dictpath,"r");
if (!dictlst) {
return 1;
}
// step one is to parse the dictionary list building up the
// descriptive structures
// read in each line ignoring any that dont start with etype
while (fgets(line,MAXDICTENTRYLEN,dictlst)) {
mychomp(line);
/* parse in a dictionary entry */
if (strncmp(line,etype,4) == 0) {
if (numdict < MAXDICTIONARIES) {
char * tp = line;
char * piece;
i = 0;
while ((piece=mystrsep(&tp,' '))) {
if (*piece != '\0') {
switch(i) {
case 0: break;
case 1: pdict->lang = mystrdup(piece); break;
case 2: if (strcmp (piece, "ANY") == 0)
pdict->region = mystrdup("");
else
pdict->region = mystrdup(piece);
break;
case 3: pdict->filename = mystrdup(piece); break;
default: break;
}
i++;
}
free(piece);
}
if (i == 4) {
numdict++;
pdict++;
} else {
fprintf(stderr,"dictionary list corruption in line \"%s\"\n",line);
fflush(stderr);
}
}
}
}
fclose(dictlst);
return 0;
}
// return text encoding of dictionary
int DictMgr::get_list(dictentry ** ppentry)
{
*ppentry = pdentry;
return numdict;
}
// strip strings into token based on single char delimiter
// acts like strsep() but only uses a delim char and not
// a delim string
char * DictMgr::mystrsep(char ** stringp, const char delim)
{
char * rv = NULL;
char * mp = *stringp;
int n = strlen(mp);
if (n > 0) {
char * dp = (char *)memchr(mp,(int)((unsigned char)delim),n);
if (dp) {
*stringp = dp+1;
int nc = (int)((unsigned long)dp - (unsigned long)mp);
rv = (char *) malloc(nc+1);
if (rv) {
memcpy(rv,mp,nc);
*(rv+nc) = '\0';
return rv;
}
} else {
rv = (char *) malloc(n+1);
if (rv) {
memcpy(rv, mp, n);
*(rv+n) = '\0';
*stringp = mp + n;
return rv;
}
}
}
return NULL;
}
// replaces strdup with ansi version
char * DictMgr::mystrdup(const char * s)
{
char * d = NULL;
if (s) {
int sl = strlen(s);
d = (char *) malloc(((sl+1) * sizeof(char)));
if (d) memcpy(d,s,((sl+1)*sizeof(char)));
}
return d;
}
// remove cross-platform text line end characters
void DictMgr:: mychomp(char * s)
{
int k = strlen(s);
if ((k > 0) && ((*(s+k-1)=='\r') || (*(s+k-1)=='\n'))) *(s+k-1) = '\0';
if ((k > 1) && (*(s+k-2) == '\r')) *(s+k-2) = '\0';
}
robojournal-0.4.2/ui/hunspell/w_char.hxx 0000644 0001750 0001750 00000006131 12211723646 017021 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __WCHARHXX__
#define __WCHARHXX__
#ifdef WIN32
typedef struct {
#else
typedef struct __attribute__ ((packed)) {
#endif
unsigned char l;
unsigned char h;
} w_char;
// two character arrays
struct replentry {
char * pattern;
char * pattern2;
};
#endif
robojournal-0.4.2/ui/hunspell/suggestmgr.hxx 0000644 0001750 0001750 00000015160 12211723646 017747 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _SUGGESTMGR_HXX_
#define _SUGGESTMGR_HXX_
#define MAXSWL 100
#define MAXSWUTF8L (MAXSWL * 4)
#define MAX_ROOTS 100
#define MAX_WORDS 100
#define MAX_GUESS 200
#define MAXNGRAMSUGS 4
#define MAXPHONSUGS 2
// timelimit: max ~1/4 sec (process time on Linux) for a time consuming function
#define TIMELIMIT (CLOCKS_PER_SEC >> 2)
#define MINTIMER 100
#define MAXPLUSTIMER 100
#define NGRAM_LONGER_WORSE (1 << 0)
#define NGRAM_ANY_MISMATCH (1 << 1)
#define NGRAM_LOWERING (1 << 2)
#include "ui/hunspell/atypes.hxx"
#include "ui/hunspell/affixmgr.hxx"
#include "ui/hunspell/hashmgr.hxx"
#include "ui/hunspell/langnum.hxx"
#include
enum { LCS_UP, LCS_LEFT, LCS_UPLEFT };
class SuggestMgr
{
char * ckey;
int ckeyl;
w_char * ckey_utf;
char * ctry;
int ctryl;
w_char * ctry_utf;
AffixMgr* pAMgr;
int maxSug;
struct cs_info * csconv;
int utf8;
int langnum;
int nosplitsugs;
int maxngramsugs;
int complexprefixes;
public:
SuggestMgr(const char * tryme, int maxn, AffixMgr *aptr);
~SuggestMgr();
int suggest(char*** slst, const char * word, int nsug, int * onlycmpdsug);
int ngsuggest(char ** wlst, char * word, int ns, HashMgr** pHMgr, int md);
int suggest_auto(char*** slst, const char * word, int nsug);
int suggest_stems(char*** slst, const char * word, int nsug);
int suggest_pos_stems(char*** slst, const char * word, int nsug);
char * suggest_morph(const char * word);
char * suggest_gen(char ** pl, int pln, char * pattern);
char * suggest_morph_for_spelling_error(const char * word);
private:
int testsug(char** wlst, const char * candidate, int wl, int ns, int cpdsuggest,
int * timer, clock_t * timelimit);
int checkword(const char *, int, int, int *, clock_t *);
int check_forbidden(const char *, int);
int capchars(char **, const char *, int, int);
int replchars(char**, const char *, int, int);
int doubletwochars(char**, const char *, int, int);
int forgotchar(char **, const char *, int, int);
int swapchar(char **, const char *, int, int);
int longswapchar(char **, const char *, int, int);
int movechar(char **, const char *, int, int);
int extrachar(char **, const char *, int, int);
int badcharkey(char **, const char *, int, int);
int badchar(char **, const char *, int, int);
int twowords(char **, const char *, int, int);
int fixstems(char **, const char *, int);
int capchars_utf(char **, const w_char *, int wl, int, int);
int doubletwochars_utf(char**, const w_char *, int wl, int, int);
int forgotchar_utf(char**, const w_char *, int wl, int, int);
int extrachar_utf(char**, const w_char *, int wl, int, int);
int badcharkey_utf(char **, const w_char *, int wl, int, int);
int badchar_utf(char **, const w_char *, int wl, int, int);
int swapchar_utf(char **, const w_char *, int wl, int, int);
int longswapchar_utf(char **, const w_char *, int, int, int);
int movechar_utf(char **, const w_char *, int, int, int);
int mapchars(char**, const char *, int, int);
int map_related(const char *, int, char ** wlst, int, int, const mapentry*, int, int *, clock_t *);
int map_related_utf(w_char *, int, int, int, char ** wlst, int, const mapentry*, int, int *, clock_t *);
int ngram(int n, char * s1, const char * s2, int opt);
int mystrlen(const char * word);
int leftcommonsubstring(char * s1, const char * s2);
int commoncharacterpositions(char * s1, const char * s2, int * is_swap);
void bubblesort( char ** rwd, char ** rwd2, int * rsc, int n);
void lcs(const char * s, const char * s2, int * l1, int * l2, char ** result);
int lcslen(const char * s, const char* s2);
char * suggest_hentry_gen(hentry * rv, char * pattern);
};
#endif
robojournal-0.4.2/ui/hunspell/affixmgr.hxx 0000644 0001750 0001750 00000027362 12211723646 017372 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _AFFIXMGR_HXX_
#define _AFFIXMGR_HXX_
#ifdef MOZILLA_CLIENT
#ifdef __SUNPRO_CC // for SunONE Studio compiler
using namespace std;
#endif
#include
#else
#include
#endif
#include "ui/hunspell/atypes.hxx"
#include "ui/hunspell/baseaffix.hxx"
#include "ui/hunspell/hashmgr.hxx"
#include "ui/hunspell/phonet.hxx"
// check flag duplication
#define dupSFX (1 << 0)
#define dupPFX (1 << 1)
class AffixMgr
{
AffEntry * pStart[SETSIZE];
AffEntry * sStart[SETSIZE];
AffEntry * pFlag[CONTSIZE];
AffEntry * sFlag[CONTSIZE];
HashMgr * pHMgr;
HashMgr ** alldic;
int * maxdic;
char * keystring;
char * trystring;
char * encoding;
struct cs_info * csconv;
int utf8;
int complexprefixes;
FLAG compoundflag;
FLAG compoundbegin;
FLAG compoundmiddle;
FLAG compoundend;
FLAG compoundroot;
FLAG compoundforbidflag;
FLAG compoundpermitflag;
int checkcompounddup;
int checkcompoundrep;
int checkcompoundcase;
int checkcompoundtriple;
FLAG forbiddenword;
FLAG nosuggest;
FLAG needaffix;
int cpdmin;
int numrep;
replentry * reptable;
int nummap;
mapentry * maptable;
int numbreak;
char ** breaktable;
int numcheckcpd;
replentry * checkcpdtable;
int numdefcpd;
flagentry * defcpdtable;
phonetable * phone;
int maxngramsugs;
int nosplitsugs;
int sugswithdots;
int cpdwordmax;
int cpdmaxsyllable;
char * cpdvowels;
w_char * cpdvowels_utf16;
int cpdvowels_utf16_len;
char * cpdsyllablenum;
const char * pfxappnd; // BUG: not stateless
const char * sfxappnd; // BUG: not stateless
FLAG sfxflag; // BUG: not stateless
char * derived; // BUG: not stateless
AffEntry * sfx; // BUG: not stateless
AffEntry * pfx; // BUG: not stateless
int checknum;
char * wordchars;
unsigned short * wordchars_utf16;
int wordchars_utf16_len;
char * ignorechars;
unsigned short * ignorechars_utf16;
int ignorechars_utf16_len;
char * version;
char * lang;
int langnum;
FLAG lemma_present;
FLAG circumfix;
FLAG onlyincompound;
FLAG keepcase;
FLAG substandard;
int checksharps;
int havecontclass; // boolean variable
char contclasses[CONTSIZE]; // flags of possible continuing classes (twofold affix)
flag flag_mode;
public:
AffixMgr(const char * affpath, HashMgr** ptr, int * md,
const char * key = NULL);
~AffixMgr();
struct hentry * affix_check(const char * word, int len,
const unsigned short needflag = (unsigned short) 0,
char in_compound = IN_CPD_NOT);
struct hentry * prefix_check(const char * word, int len,
char in_compound, const FLAG needflag = FLAG_NULL);
inline int isSubset(const char * s1, const char * s2);
struct hentry * prefix_check_twosfx(const char * word, int len,
char in_compound, const FLAG needflag = FLAG_NULL);
inline int isRevSubset(const char * s1, const char * end_of_s2, int len);
struct hentry * suffix_check(const char * word, int len, int sfxopts,
AffEntry* ppfx, char ** wlst, int maxSug, int * ns,
const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL,
char in_compound = IN_CPD_NOT);
struct hentry * suffix_check_twosfx(const char * word, int len,
int sfxopts, AffEntry* ppfx, const FLAG needflag = FLAG_NULL);
char * affix_check_morph(const char * word, int len,
const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT);
char * prefix_check_morph(const char * word, int len,
char in_compound, const FLAG needflag = FLAG_NULL);
char * suffix_check_morph (const char * word, int len, int sfxopts,
AffEntry * ppfx, const FLAG cclass = FLAG_NULL,
const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT);
char * prefix_check_twosfx_morph(const char * word, int len,
char in_compound, const FLAG needflag = FLAG_NULL);
char * suffix_check_twosfx_morph(const char * word, int len,
int sfxopts, AffEntry * ppfx, const FLAG needflag = FLAG_NULL);
char * morphgen(char * ts, int wl, const unsigned short * ap,
unsigned short al, char * morph, char * targetmorph, int level);
int expand_rootword(struct guessword * wlst, int maxn, const char * ts,
int wl, const unsigned short * ap, unsigned short al, char * bad,
int, char *);
short get_syllable (const char * word, int wlen);
int cpdrep_check(const char * word, int len);
int cpdpat_check(const char * word, int len);
int defcpd_check(hentry *** words, short wnum, hentry * rv,
hentry ** rwords, char all);
int cpdcase_check(const char * word, int len);
inline int candidate_check(const char * word, int len);
struct hentry * compound_check(const char * word, int len, short wordnum,
short numsyllable, short maxwordnum, short wnum, hentry ** words,
char hu_mov_rule, int * cmpdstemnum, int * cmpdstem, char is_sug);
int compound_check_morph(const char * word, int len, short wordnum,
short numsyllable, short maxwordnum, short wnum, hentry ** words,
char hu_mov_rule, char ** result, char * partresult);
struct hentry * lookup(const char * word);
int get_numrep();
struct replentry * get_reptable();
struct phonetable * get_phonetable();
int get_nummap();
struct mapentry * get_maptable();
int get_numbreak();
char ** get_breaktable();
char * get_encoding();
int get_langnum();
char * get_key_string();
char * get_try_string();
const char * get_wordchars();
unsigned short * get_wordchars_utf16(int * len);
char * get_ignore();
unsigned short * get_ignore_utf16(int * len);
int get_compound();
FLAG get_compoundflag();
FLAG get_compoundbegin();
FLAG get_forbiddenword();
FLAG get_nosuggest();
FLAG get_needaffix();
FLAG get_onlyincompound();
FLAG get_compoundroot();
FLAG get_lemma_present();
int get_checknum();
char * get_possible_root();
const char * get_prefix();
const char * get_suffix();
const char * get_derived();
const char * get_version();
const int have_contclass();
int get_utf8();
int get_complexprefixes();
char * get_suffixed(char );
int get_maxngramsugs();
int get_nosplitsugs();
int get_sugswithdots(void);
FLAG get_keepcase(void);
int get_checksharps(void);
char * encode_flag(unsigned short aflag);
private:
int parse_file(const char * affpath, const char * key);
int parse_flag(char * line, unsigned short * out, const char * name);
int parse_num(char * line, int * out, const char * name);
int parse_cpdsyllable(char * line);
int parse_reptable(char * line, FileMgr * af);
int parse_phonetable(char * line, FileMgr * af);
int parse_maptable(char * line, FileMgr * af);
int parse_breaktable(char * line, FileMgr * af);
int parse_checkcpdtable(char * line, FileMgr * af);
int parse_defcpdtable(char * line, FileMgr * af);
int parse_affix(char * line, const char at, FileMgr * af, char * dupflags);
void reverse_condition(char *);
void debugflag(char * result, unsigned short flag);
int condlen(char *);
int encodeit(struct affentry * ptr, char * cs);
int build_pfxtree(AffEntry* pfxptr);
int build_sfxtree(AffEntry* sfxptr);
int process_pfx_order();
int process_sfx_order();
AffEntry * process_pfx_in_order(AffEntry * ptr, AffEntry * nptr);
AffEntry * process_sfx_in_order(AffEntry * ptr, AffEntry * nptr);
int process_pfx_tree_to_list();
int process_sfx_tree_to_list();
int redundant_condition(char, char * strip, int stripl,
const char * cond, char *);
};
#endif
robojournal-0.4.2/ui/hunspell/affixmgr.cxx 0000644 0001750 0001750 00000430576 12211723646 017372 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "license.hunspell"
#include "license.myspell"
#ifndef MOZILLA_CLIENT
#include
#include
#include
#include
#else
#include
#include
#include
#include
#endif
#include "ui/hunspell/affixmgr.hxx"
#include "ui/hunspell/affentry.hxx"
#include "ui/hunspell/langnum.hxx"
#include "ui/hunspell/csutil.hxx"
#ifndef MOZILLA_CLIENT
#ifndef WIN32
using namespace std;
#endif
#endif
AffixMgr::AffixMgr(const char * affpath, HashMgr** ptr, int * md, const char * key)
{
// register hash manager and load affix data from aff file
pHMgr = ptr[0];
alldic = ptr;
maxdic = md;
keystring = NULL;
trystring = NULL;
encoding=NULL;
utf8 = 0;
complexprefixes = 0;
maptable = NULL;
nummap = 0;
breaktable = NULL;
numbreak = 0;
reptable = NULL;
numrep = 0;
checkcpdtable = NULL;
numcheckcpd = 0;
defcpdtable = NULL;
numdefcpd = 0;
phone = NULL;
compoundflag = FLAG_NULL; // permits word in compound forms
compoundbegin = FLAG_NULL; // may be first word in compound forms
compoundmiddle = FLAG_NULL; // may be middle word in compound forms
compoundend = FLAG_NULL; // may be last word in compound forms
compoundroot = FLAG_NULL; // compound word signing flag
compoundpermitflag = FLAG_NULL; // compound permitting flag for suffixed word
compoundforbidflag = FLAG_NULL; // compound fordidden flag for suffixed word
checkcompounddup = 0; // forbid double words in compounds
checkcompoundrep = 0; // forbid bad compounds (may be non compound word with a REP substitution)
checkcompoundcase = 0; // forbid upper and lowercase combinations at word bounds
checkcompoundtriple = 0; // forbid compounds with triple letters
forbiddenword = FORBIDDENWORD; // forbidden word signing flag
nosuggest = FLAG_NULL; // don't suggest words signed with NOSUGGEST flag
lang = NULL; // language
langnum = 0; // language code (see http://l10n.openoffice.org/languages.html)
needaffix = FLAG_NULL; // forbidden root, allowed only with suffixes
cpdwordmax = -1; // default: unlimited wordcount in compound words
cpdmin = -1; // undefined
cpdmaxsyllable = 0; // default: unlimited syllablecount in compound words
cpdvowels=NULL; // vowels (for calculating of Hungarian compounding limit, O(n) search! XXX)
cpdvowels_utf16=NULL; // vowels for UTF-8 encoding (bsearch instead of O(n) search)
cpdvowels_utf16_len=0; // vowels
pfxappnd=NULL; // previous prefix for counting the syllables of prefix BUG
sfxappnd=NULL; // previous suffix for counting a special syllables BUG
cpdsyllablenum=NULL; // syllable count incrementing flag
checknum=0; // checking numbers, and word with numbers
wordchars=NULL; // letters + spec. word characters
wordchars_utf16=NULL; // letters + spec. word characters
wordchars_utf16_len=0; // letters + spec. word characters
ignorechars=NULL; // letters + spec. word characters
ignorechars_utf16=NULL; // letters + spec. word characters
ignorechars_utf16_len=0; // letters + spec. word characters
version=NULL; // affix and dictionary file version string
havecontclass=0; // flags of possible continuing classes (double affix)
// LEMMA_PRESENT: not put root into the morphological output. Lemma presents
// in morhological description in dictionary file. It's often combined with PSEUDOROOT.
lemma_present = FLAG_NULL;
circumfix = FLAG_NULL;
onlyincompound = FLAG_NULL;
flag_mode = FLAG_CHAR; // default one-character flags in affix and dic file
maxngramsugs = -1; // undefined
nosplitsugs = 0;
sugswithdots = 0;
keepcase = 0;
checksharps = 0;
substandard = FLAG_NULL;
derived = NULL; // XXX not threadsafe variable for experimental stemming
sfx = NULL;
pfx = NULL;
for (int i=0; i < SETSIZE; i++) {
pStart[i] = NULL;
sStart[i] = NULL;
pFlag[i] = NULL;
sFlag[i] = NULL;
}
for (int j=0; j < CONTSIZE; j++) {
contclasses[j] = 0;
}
if (parse_file(affpath, key)) {
HUNSPELL_WARNING(stderr, "Failure loading aff file %s\n",affpath);
}
if (cpdmin == -1) cpdmin = MINCPDLEN;
}
AffixMgr::~AffixMgr()
{
// pass through linked prefix entries and clean up
for (int i=0; i < SETSIZE ;i++) {
pFlag[i] = NULL;
PfxEntry * ptr = (PfxEntry *)pStart[i];
PfxEntry * nptr = NULL;
while (ptr) {
nptr = ptr->getNext();
delete(ptr);
ptr = nptr;
nptr = NULL;
}
}
// pass through linked suffix entries and clean up
for (int j=0; j < SETSIZE ; j++) {
sFlag[j] = NULL;
SfxEntry * ptr = (SfxEntry *)sStart[j];
SfxEntry * nptr = NULL;
while (ptr) {
nptr = ptr->getNext();
delete(ptr);
ptr = nptr;
nptr = NULL;
}
sStart[j] = NULL;
}
if (keystring) free(keystring);
keystring=NULL;
if (trystring) free(trystring);
trystring=NULL;
if (encoding) free(encoding);
encoding=NULL;
if (maptable) {
for (int j=0; j < nummap; j++) {
if (maptable[j].set) free(maptable[j].set);
if (maptable[j].set_utf16) free(maptable[j].set_utf16);
maptable[j].set = NULL;
maptable[j].len = 0;
}
free(maptable);
maptable = NULL;
}
nummap = 0;
if (breaktable) {
for (int j=0; j < numbreak; j++) {
if (breaktable[j]) free(breaktable[j]);
breaktable[j] = NULL;
}
free(breaktable);
breaktable = NULL;
}
numbreak = 0;
if (reptable) {
for (int j=0; j < numrep; j++) {
free(reptable[j].pattern);
free(reptable[j].pattern2);
}
free(reptable);
reptable = NULL;
}
if (phone && phone->rules) {
for (int j=0; j < phone->num + 1; j++) {
free(phone->rules[j * 2]);
free(phone->rules[j * 2 + 1]);
}
free(phone->rules);
free(phone);
phone = NULL;
}
if (defcpdtable) {
for (int j=0; j < numdefcpd; j++) {
free(defcpdtable[j].def);
defcpdtable[j].def = NULL;
}
free(defcpdtable);
defcpdtable = NULL;
}
numrep = 0;
if (checkcpdtable) {
for (int j=0; j < numcheckcpd; j++) {
free(checkcpdtable[j].pattern);
free(checkcpdtable[j].pattern2);
checkcpdtable[j].pattern = NULL;
checkcpdtable[j].pattern2 = NULL;
}
free(checkcpdtable);
checkcpdtable = NULL;
}
numcheckcpd = 0;
FREE_FLAG(compoundflag);
FREE_FLAG(compoundbegin);
FREE_FLAG(compoundmiddle);
FREE_FLAG(compoundend);
FREE_FLAG(compoundpermitflag);
FREE_FLAG(compoundforbidflag);
FREE_FLAG(compoundroot);
FREE_FLAG(forbiddenword);
FREE_FLAG(nosuggest);
FREE_FLAG(needaffix);
FREE_FLAG(lemma_present);
FREE_FLAG(circumfix);
FREE_FLAG(onlyincompound);
cpdwordmax = 0;
pHMgr = NULL;
cpdmin = 0;
cpdmaxsyllable = 0;
if (cpdvowels) free(cpdvowels);
if (cpdvowels_utf16) free(cpdvowels_utf16);
if (cpdsyllablenum) free(cpdsyllablenum);
free_utf_tbl();
if (lang) free(lang);
if (wordchars) free(wordchars);
if (wordchars_utf16) free(wordchars_utf16);
if (ignorechars) free(ignorechars);
if (ignorechars_utf16) free(ignorechars_utf16);
if (version) free(version);
if (derived) free(derived);
checknum=0;
}
// read in aff file and build up prefix and suffix entry objects
int AffixMgr::parse_file(const char * affpath, const char * key)
{
char * line; // io buffers
char ft; // affix type
// checking flag duplication
char dupflags[CONTSIZE];
char dupflags_ini = 1;
// first line indicator for removing byte order mark
int firstline = 1;
// open the affix file
FileMgr * afflst = new FileMgr(affpath, key);
if (!afflst) {
HUNSPELL_WARNING(stderr, "error: could not open affix description file %s\n",affpath);
return 1;
}
// step one is to parse the affix file building up the internal
// affix data structures
// read in each line ignoring any that do not
// start with a known line type indicator
while ((line = afflst->getline())) {
mychomp(line);
/* remove byte order mark */
if (firstline) {
firstline = 0;
if (strncmp(line,"\xEF\xBB\xBF",3) == 0) {
memmove(line, line+3, strlen(line+3)+1);
HUNSPELL_WARNING(stderr, "warning: affix file begins with byte order mark: possible incompatibility with old Hunspell versions\n");
}
}
/* parse in the keyboard string */
if (strncmp(line,"KEY",3) == 0) {
if (parse_string(line, &keystring, "KEY")) {
delete afflst;
return 1;
}
}
/* parse in the try string */
if (strncmp(line,"TRY",3) == 0) {
if (parse_string(line, &trystring, "TRY")) {
delete afflst;
return 1;
}
}
/* parse in the name of the character set used by the .dict and .aff */
if (strncmp(line,"SET",3) == 0) {
if (parse_string(line, &encoding, "SET")) {
delete afflst;
return 1;
}
if (strcmp(encoding, "UTF-8") == 0) {
utf8 = 1;
#ifndef OPENOFFICEORG
#ifndef MOZILLA_CLIENT
if (initialize_utf_tbl()) return 1;
#endif
#endif
}
}
/* parse COMPLEXPREFIXES for agglutinative languages with right-to-left writing system */
if (strncmp(line,"COMPLEXPREFIXES",15) == 0)
complexprefixes = 1;
/* parse in the flag used by the controlled compound words */
if (strncmp(line,"COMPOUNDFLAG",12) == 0) {
if (parse_flag(line, &compoundflag, "COMPOUNDFLAG")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by compound words */
if (strncmp(line,"COMPOUNDBEGIN",13) == 0) {
if (complexprefixes) {
if (parse_flag(line, &compoundend, "COMPOUNDBEGIN")) {
delete afflst;
return 1;
}
} else {
if (parse_flag(line, &compoundbegin, "COMPOUNDBEGIN")) {
delete afflst;
return 1;
}
}
}
/* parse in the flag used by compound words */
if (strncmp(line,"COMPOUNDMIDDLE",14) == 0) {
if (parse_flag(line, &compoundmiddle, "COMPOUNDMIDDLE")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by compound words */
if (strncmp(line,"COMPOUNDEND",11) == 0) {
if (complexprefixes) {
if (parse_flag(line, &compoundbegin, "COMPOUNDEND")) {
delete afflst;
return 1;
}
} else {
if (parse_flag(line, &compoundend, "COMPOUNDEND")) {
delete afflst;
return 1;
}
}
}
/* parse in the data used by compound_check() method */
if (strncmp(line,"COMPOUNDWORDMAX",15) == 0) {
if (parse_num(line, &cpdwordmax, "COMPOUNDWORDMAX")) {
delete afflst;
return 1;
}
}
/* parse in the flag sign compounds in dictionary */
if (strncmp(line,"COMPOUNDROOT",12) == 0) {
if (parse_flag(line, &compoundroot, "COMPOUNDROOT")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by compound_check() method */
if (strncmp(line,"COMPOUNDPERMITFLAG",18) == 0) {
if (parse_flag(line, &compoundpermitflag, "COMPOUNDPERMITFLAG")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by compound_check() method */
if (strncmp(line,"COMPOUNDFORBIDFLAG",18) == 0) {
if (parse_flag(line, &compoundforbidflag, "COMPOUNDFORBIDFLAG")) {
delete afflst;
return 1;
}
}
if (strncmp(line,"CHECKCOMPOUNDDUP",16) == 0) {
checkcompounddup = 1;
}
if (strncmp(line,"CHECKCOMPOUNDREP",16) == 0) {
checkcompoundrep = 1;
}
if (strncmp(line,"CHECKCOMPOUNDTRIPLE",19) == 0) {
checkcompoundtriple = 1;
}
if (strncmp(line,"CHECKCOMPOUNDCASE",17) == 0) {
checkcompoundcase = 1;
}
if (strncmp(line,"NOSUGGEST",9) == 0) {
if (parse_flag(line, &nosuggest, "NOSUGGEST")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by forbidden words */
if (strncmp(line,"FORBIDDENWORD",13) == 0) {
if (parse_flag(line, &forbiddenword, "FORBIDDENWORD")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by forbidden words */
if (strncmp(line,"LEMMA_PRESENT",13) == 0) {
if (parse_flag(line, &lemma_present, "LEMMA_PRESENT")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by circumfixes */
if (strncmp(line,"CIRCUMFIX",9) == 0) {
if (parse_flag(line, &circumfix, "CIRCUMFIX")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by fogemorphemes */
if (strncmp(line,"ONLYINCOMPOUND",14) == 0) {
if (parse_flag(line, &onlyincompound, "ONLYINCOMPOUND")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by `needaffixs' */
if (strncmp(line,"PSEUDOROOT",10) == 0) {
if (parse_flag(line, &needaffix, "PSEUDOROOT")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by `needaffixs' */
if (strncmp(line,"NEEDAFFIX",9) == 0) {
if (parse_flag(line, &needaffix, "NEEDAFFIX")) {
delete afflst;
return 1;
}
}
/* parse in the minimal length for words in compounds */
if (strncmp(line,"COMPOUNDMIN",11) == 0) {
if (parse_num(line, &cpdmin, "COMPOUNDMIN")) {
delete afflst;
return 1;
}
if (cpdmin < 1) cpdmin = 1;
}
/* parse in the max. words and syllables in compounds */
if (strncmp(line,"COMPOUNDSYLLABLE",16) == 0) {
if (parse_cpdsyllable(line)) {
delete afflst;
return 1;
}
}
/* parse in the flag used by compound_check() method */
if (strncmp(line,"SYLLABLENUM",11) == 0) {
if (parse_string(line, &cpdsyllablenum, "SYLLABLENUM")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by the controlled compound words */
if (strncmp(line,"CHECKNUM",8) == 0) {
checknum=1;
}
/* parse in the extra word characters */
if (strncmp(line,"WORDCHARS",9) == 0) {
if (parse_array(line, &wordchars, &wordchars_utf16, &wordchars_utf16_len, "WORDCHARS", utf8)) {
delete afflst;
return 1;
}
}
/* parse in the ignored characters (for example, Arabic optional diacretics charachters */
if (strncmp(line,"IGNORE",6) == 0) {
if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, "IGNORE", utf8)) {
delete afflst;
return 1;
}
}
/* parse in the typical fault correcting table */
if (strncmp(line,"REP",3) == 0) {
if (parse_reptable(line, afflst)) {
delete afflst;
return 1;
}
}
/* parse in the phonetic translation table */
if (strncmp(line,"PHONE",5) == 0) {
if (parse_phonetable(line, afflst)) {
delete afflst;
return 1;
}
}
/* parse in the checkcompoundpattern table */
if (strncmp(line,"CHECKCOMPOUNDPATTERN",20) == 0) {
if (parse_checkcpdtable(line, afflst)) {
delete afflst;
return 1;
}
}
/* parse in the defcompound table */
if (strncmp(line,"COMPOUNDRULE",12) == 0) {
if (parse_defcpdtable(line, afflst)) {
delete afflst;
return 1;
}
}
/* parse in the related character map table */
if (strncmp(line,"MAP",3) == 0) {
if (parse_maptable(line, afflst)) {
delete afflst;
return 1;
}
}
/* parse in the word breakpoints table */
if (strncmp(line,"BREAK",5) == 0) {
if (parse_breaktable(line, afflst)) {
delete afflst;
return 1;
}
}
/* parse in the language for language specific codes */
if (strncmp(line,"LANG",4) == 0) {
if (parse_string(line, &lang, "LANG")) {
delete afflst;
return 1;
}
langnum = get_lang_num(lang);
}
if (strncmp(line,"VERSION",7) == 0) {
if (parse_string(line, &version, "VERSION")) {
delete afflst;
return 1;
}
}
if (strncmp(line,"MAXNGRAMSUGS",12) == 0) {
if (parse_num(line, &maxngramsugs, "MAXNGRAMSUGS")) {
delete afflst;
return 1;
}
}
if (strncmp(line,"NOSPLITSUGS",11) == 0) {
nosplitsugs=1;
}
if (strncmp(line,"SUGSWITHDOTS",12) == 0) {
sugswithdots=1;
}
/* parse in the flag used by forbidden words */
if (strncmp(line,"KEEPCASE",8) == 0) {
if (parse_flag(line, &keepcase, "KEEPCASE")) {
delete afflst;
return 1;
}
}
/* parse in the flag used by the affix generator */
if (strncmp(line,"SUBSTANDARD",11) == 0) {
if (parse_flag(line, &substandard, "SUBSTANDARD")) {
delete afflst;
return 1;
}
}
if (strncmp(line,"CHECKSHARPS",11) == 0) {
checksharps=1;
}
/* parse this affix: P - prefix, S - suffix */
ft = ' ';
if (strncmp(line,"PFX",3) == 0) ft = complexprefixes ? 'S' : 'P';
if (strncmp(line,"SFX",3) == 0) ft = complexprefixes ? 'P' : 'S';
if (ft != ' ') {
if (dupflags_ini) {
for (int i = 0; i < CONTSIZE; i++) dupflags[i] = 0;
dupflags_ini = 0;
}
if (parse_affix(line, ft, afflst, dupflags)) {
delete afflst;
process_pfx_tree_to_list();
process_sfx_tree_to_list();
return 1;
}
}
}
delete afflst;
// convert affix trees to sorted list
process_pfx_tree_to_list();
process_sfx_tree_to_list();
// now we can speed up performance greatly taking advantage of the
// relationship between the affixes and the idea of "subsets".
// View each prefix as a potential leading subset of another and view
// each suffix (reversed) as a potential trailing subset of another.
// To illustrate this relationship if we know the prefix "ab" is found in the
// word to examine, only prefixes that "ab" is a leading subset of need be examined.
// Furthermore is "ab" is not present then none of the prefixes that "ab" is
// is a subset need be examined.
// The same argument goes for suffix string that are reversed.
// Then to top this off why not examine the first char of the word to quickly
// limit the set of prefixes to examine (i.e. the prefixes to examine must
// be leading supersets of the first character of the word (if they exist)
// To take advantage of this "subset" relationship, we need to add two links
// from entry. One to take next if the current prefix is found (call it nexteq)
// and one to take next if the current prefix is not found (call it nextne).
// Since we have built ordered lists, all that remains is to properly intialize
// the nextne and nexteq pointers that relate them
process_pfx_order();
process_sfx_order();
/* get encoding for CHECKCOMPOUNDCASE */
if (!utf8) {
char * enc = get_encoding();
csconv = get_current_cs(enc);
free(enc);
enc = NULL;
char expw[MAXLNLEN];
if (wordchars) {
strcpy(expw, wordchars);
free(wordchars);
} else *expw = '\0';
for (int i = 0; i <= 255; i++) {
if ( (csconv[i].cupper != csconv[i].clower) &&
(! strchr(expw, (char) i))) {
*(expw + strlen(expw) + 1) = '\0';
*(expw + strlen(expw)) = (char) i;
}
}
wordchars = mystrdup(expw);
}
// temporary BREAK definition for German dash handling (OOo issue 64400)
if ((langnum == LANG_de) && (!breaktable)) {
breaktable = (char **) malloc(sizeof(char *));
if (!breaktable) return 1;
breaktable[0] = mystrdup("-");
if (breaktable[0]) numbreak = 1;
}
return 0;
}
// we want to be able to quickly access prefix information
// both by prefix flag, and sorted by prefix string itself
// so we need to set up two indexes
int AffixMgr::build_pfxtree(AffEntry* pfxptr)
{
PfxEntry * ptr;
PfxEntry * pptr;
PfxEntry * ep = (PfxEntry*) pfxptr;
// get the right starting points
const char * key = ep->getKey();
const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF);
// first index by flag which must exist
ptr = (PfxEntry*)pFlag[flg];
ep->setFlgNxt(ptr);
pFlag[flg] = (AffEntry *) ep;
// handle the special case of null affix string
if (strlen(key) == 0) {
// always inset them at head of list at element 0
ptr = (PfxEntry*)pStart[0];
ep->setNext(ptr);
pStart[0] = (AffEntry*)ep;
return 0;
}
// now handle the normal case
ep->setNextEQ(NULL);
ep->setNextNE(NULL);
unsigned char sp = *((const unsigned char *)key);
ptr = (PfxEntry*)pStart[sp];
// handle the first insert
if (!ptr) {
pStart[sp] = (AffEntry*)ep;
return 0;
}
// otherwise use binary tree insertion so that a sorted
// list can easily be generated later
pptr = NULL;
for (;;) {
pptr = ptr;
if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) {
ptr = ptr->getNextEQ();
if (!ptr) {
pptr->setNextEQ(ep);
break;
}
} else {
ptr = ptr->getNextNE();
if (!ptr) {
pptr->setNextNE(ep);
break;
}
}
}
return 0;
}
// we want to be able to quickly access suffix information
// both by suffix flag, and sorted by the reverse of the
// suffix string itself; so we need to set up two indexes
int AffixMgr::build_sfxtree(AffEntry* sfxptr)
{
SfxEntry * ptr;
SfxEntry * pptr;
SfxEntry * ep = (SfxEntry *) sfxptr;
/* get the right starting point */
const char * key = ep->getKey();
const unsigned char flg = (unsigned char) (ep->getFlag() & 0x00FF);
// first index by flag which must exist
ptr = (SfxEntry*)sFlag[flg];
ep->setFlgNxt(ptr);
sFlag[flg] = (AffEntry *) ep;
// next index by affix string
// handle the special case of null affix string
if (strlen(key) == 0) {
// always inset them at head of list at element 0
ptr = (SfxEntry*)sStart[0];
ep->setNext(ptr);
sStart[0] = (AffEntry*)ep;
return 0;
}
// now handle the normal case
ep->setNextEQ(NULL);
ep->setNextNE(NULL);
unsigned char sp = *((const unsigned char *)key);
ptr = (SfxEntry*)sStart[sp];
// handle the first insert
if (!ptr) {
sStart[sp] = (AffEntry*)ep;
return 0;
}
// otherwise use binary tree insertion so that a sorted
// list can easily be generated later
pptr = NULL;
for (;;) {
pptr = ptr;
if (strcmp(ep->getKey(), ptr->getKey() ) <= 0) {
ptr = ptr->getNextEQ();
if (!ptr) {
pptr->setNextEQ(ep);
break;
}
} else {
ptr = ptr->getNextNE();
if (!ptr) {
pptr->setNextNE(ep);
break;
}
}
}
return 0;
}
// convert from binary tree to sorted list
int AffixMgr::process_pfx_tree_to_list()
{
for (int i=1; i< SETSIZE; i++) {
pStart[i] = process_pfx_in_order(pStart[i],NULL);
}
return 0;
}
AffEntry* AffixMgr::process_pfx_in_order(AffEntry* ptr, AffEntry* nptr)
{
if (ptr) {
nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextNE(), nptr);
((PfxEntry*) ptr)->setNext((PfxEntry*) nptr);
nptr = process_pfx_in_order(((PfxEntry*) ptr)->getNextEQ(), ptr);
}
return nptr;
}
// convert from binary tree to sorted list
int AffixMgr:: process_sfx_tree_to_list()
{
for (int i=1; i< SETSIZE; i++) {
sStart[i] = process_sfx_in_order(sStart[i],NULL);
}
return 0;
}
AffEntry* AffixMgr::process_sfx_in_order(AffEntry* ptr, AffEntry* nptr)
{
if (ptr) {
nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextNE(), nptr);
((SfxEntry*) ptr)->setNext((SfxEntry*) nptr);
nptr = process_sfx_in_order(((SfxEntry*) ptr)->getNextEQ(), ptr);
}
return nptr;
}
// reinitialize the PfxEntry links NextEQ and NextNE to speed searching
// using the idea of leading subsets this time
int AffixMgr::process_pfx_order()
{
PfxEntry* ptr;
// loop through each prefix list starting point
for (int i=1; i < SETSIZE; i++) {
ptr = (PfxEntry*)pStart[i];
// look through the remainder of the list
// and find next entry with affix that
// the current one is not a subset of
// mark that as destination for NextNE
// use next in list that you are a subset
// of as NextEQ
for (; ptr != NULL; ptr = ptr->getNext()) {
PfxEntry * nptr = ptr->getNext();
for (; nptr != NULL; nptr = nptr->getNext()) {
if (! isSubset( ptr->getKey() , nptr->getKey() )) break;
}
ptr->setNextNE(nptr);
ptr->setNextEQ(NULL);
if ((ptr->getNext()) && isSubset(ptr->getKey() , (ptr->getNext())->getKey()))
ptr->setNextEQ(ptr->getNext());
}
// now clean up by adding smart search termination strings:
// if you are already a superset of the previous prefix
// but not a subset of the next, search can end here
// so set NextNE properly
ptr = (PfxEntry *) pStart[i];
for (; ptr != NULL; ptr = ptr->getNext()) {
PfxEntry * nptr = ptr->getNext();
PfxEntry * mptr = NULL;
for (; nptr != NULL; nptr = nptr->getNext()) {
if (! isSubset(ptr->getKey(),nptr->getKey())) break;
mptr = nptr;
}
if (mptr) mptr->setNextNE(NULL);
}
}
return 0;
}
// initialize the SfxEntry links NextEQ and NextNE to speed searching
// using the idea of leading subsets this time
int AffixMgr::process_sfx_order()
{
SfxEntry* ptr;
// loop through each prefix list starting point
for (int i=1; i < SETSIZE; i++) {
ptr = (SfxEntry *) sStart[i];
// look through the remainder of the list
// and find next entry with affix that
// the current one is not a subset of
// mark that as destination for NextNE
// use next in list that you are a subset
// of as NextEQ
for (; ptr != NULL; ptr = ptr->getNext()) {
SfxEntry * nptr = ptr->getNext();
for (; nptr != NULL; nptr = nptr->getNext()) {
if (! isSubset(ptr->getKey(),nptr->getKey())) break;
}
ptr->setNextNE(nptr);
ptr->setNextEQ(NULL);
if ((ptr->getNext()) && isSubset(ptr->getKey(),(ptr->getNext())->getKey()))
ptr->setNextEQ(ptr->getNext());
}
// now clean up by adding smart search termination strings:
// if you are already a superset of the previous suffix
// but not a subset of the next, search can end here
// so set NextNE properly
ptr = (SfxEntry *) sStart[i];
for (; ptr != NULL; ptr = ptr->getNext()) {
SfxEntry * nptr = ptr->getNext();
SfxEntry * mptr = NULL;
for (; nptr != NULL; nptr = nptr->getNext()) {
if (! isSubset(ptr->getKey(),nptr->getKey())) break;
mptr = nptr;
}
if (mptr) mptr->setNextNE(NULL);
}
}
return 0;
}
// add flags to the result for dictionary debugging
void AffixMgr::debugflag(char * result, unsigned short flag) {
char * st = encode_flag(flag);
strcat(result, " ");
strcat(result, MORPH_FLAG);
if (st) {
strcat(result, st);
free(st);
}
}
// calculate the character length of the condition
int AffixMgr::condlen(char * st)
{
int l = 0;
bool group = false;
for(; *st; st++) {
if (*st == '[') {
group = true;
l++;
} else if (*st == ']') group = false;
else if (!group && (!utf8 ||
(!(*st & 0x80) || ((*st & 0xc0) == 0x80)))) l++;
}
return l;
}
int AffixMgr::encodeit(struct affentry * ptr, char * cs)
{
if (strcmp(cs,".") != 0) {
ptr->numconds = (char) condlen(cs);
strncpy(ptr->c.conds, cs, MAXCONDLEN);
// long condition (end of conds padded by strncpy)
if (ptr->c.conds[MAXCONDLEN - 1] && cs[MAXCONDLEN]) {
ptr->opts += aeLONGCOND;
ptr->c.l.conds2 = mystrdup(cs + MAXCONDLEN_1);
if (!ptr->c.l.conds2) return 1;
}
} else {
ptr->numconds = 0;
ptr->c.conds[0] = '\0';
}
return 0;
}
// return 1 if s1 is a leading subset of s2 (dots are for infixes)
inline int AffixMgr::isSubset(const char * s1, const char * s2)
{
while (((*s1 == *s2) || (*s1 == '.')) && (*s1 != '\0')) {
s1++;
s2++;
}
return (*s1 == '\0');
}
// check word for prefixes
struct hentry * AffixMgr::prefix_check(const char * word, int len, char in_compound,
const FLAG needflag)
{
struct hentry * rv= NULL;
pfx = NULL;
pfxappnd = NULL;
sfxappnd = NULL;
// first handle the special case of 0 length prefixes
PfxEntry * pe = (PfxEntry *) pStart[0];
while (pe) {
if (
// fogemorpheme
((in_compound != IN_CPD_NOT) || !(pe->getCont() &&
(TESTAFF(pe->getCont(), onlyincompound, pe->getContLen())))) &&
// permit prefixes in compounds
((in_compound != IN_CPD_END) || (pe->getCont() &&
(TESTAFF(pe->getCont(), compoundpermitflag, pe->getContLen()))))
) {
// check prefix
rv = pe->checkword(word, len, in_compound, needflag);
if (rv) {
pfx=(AffEntry *)pe; // BUG: pfx not stateless
return rv;
}
}
pe = pe->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)word);
PfxEntry * pptr = (PfxEntry *)pStart[sp];
while (pptr) {
if (isSubset(pptr->getKey(),word)) {
if (
// fogemorpheme
((in_compound != IN_CPD_NOT) || !(pptr->getCont() &&
(TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen())))) &&
// permit prefixes in compounds
((in_compound != IN_CPD_END) || (pptr->getCont() &&
(TESTAFF(pptr->getCont(), compoundpermitflag, pptr->getContLen()))))
) {
// check prefix
rv = pptr->checkword(word, len, in_compound, needflag);
if (rv) {
pfx=(AffEntry *)pptr; // BUG: pfx not stateless
return rv;
}
}
pptr = pptr->getNextEQ();
} else {
pptr = pptr->getNextNE();
}
}
return NULL;
}
// check word for prefixes
struct hentry * AffixMgr::prefix_check_twosfx(const char * word, int len,
char in_compound, const FLAG needflag)
{
struct hentry * rv= NULL;
pfx = NULL;
sfxappnd = NULL;
// first handle the special case of 0 length prefixes
PfxEntry * pe = (PfxEntry *) pStart[0];
while (pe) {
rv = pe->check_twosfx(word, len, in_compound, needflag);
if (rv) return rv;
pe = pe->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)word);
PfxEntry * pptr = (PfxEntry *)pStart[sp];
while (pptr) {
if (isSubset(pptr->getKey(),word)) {
rv = pptr->check_twosfx(word, len, in_compound, needflag);
if (rv) {
pfx = (AffEntry *)pptr;
return rv;
}
pptr = pptr->getNextEQ();
} else {
pptr = pptr->getNextNE();
}
}
return NULL;
}
// check word for prefixes
char * AffixMgr::prefix_check_morph(const char * word, int len, char in_compound,
const FLAG needflag)
{
char * st;
char result[MAXLNLEN];
result[0] = '\0';
pfx = NULL;
sfxappnd = NULL;
// first handle the special case of 0 length prefixes
PfxEntry * pe = (PfxEntry *) pStart[0];
while (pe) {
st = pe->check_morph(word,len,in_compound, needflag);
if (st) {
strcat(result, st);
free(st);
}
// if (rv) return rv;
pe = pe->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)word);
PfxEntry * pptr = (PfxEntry *)pStart[sp];
while (pptr) {
if (isSubset(pptr->getKey(),word)) {
st = pptr->check_morph(word,len,in_compound, needflag);
if (st) {
// fogemorpheme
if ((in_compound != IN_CPD_NOT) || !((pptr->getCont() &&
(TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen()))))) {
strcat(result, st);
pfx = (AffEntry *)pptr;
}
free(st);
}
pptr = pptr->getNextEQ();
} else {
pptr = pptr->getNextNE();
}
}
if (*result) return mystrdup(result);
return NULL;
}
// check word for prefixes
char * AffixMgr::prefix_check_twosfx_morph(const char * word, int len,
char in_compound, const FLAG needflag)
{
char * st;
char result[MAXLNLEN];
result[0] = '\0';
pfx = NULL;
sfxappnd = NULL;
// first handle the special case of 0 length prefixes
PfxEntry * pe = (PfxEntry *) pStart[0];
while (pe) {
st = pe->check_twosfx_morph(word,len,in_compound, needflag);
if (st) {
strcat(result, st);
free(st);
}
pe = pe->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)word);
PfxEntry * pptr = (PfxEntry *)pStart[sp];
while (pptr) {
if (isSubset(pptr->getKey(),word)) {
st = pptr->check_twosfx_morph(word, len, in_compound, needflag);
if (st) {
strcat(result, st);
free(st);
pfx = (AffEntry *)pptr;
}
pptr = pptr->getNextEQ();
} else {
pptr = pptr->getNextNE();
}
}
if (*result) return mystrdup(result);
return NULL;
}
// Is word a non compound with a REP substitution (see checkcompoundrep)?
int AffixMgr::cpdrep_check(const char * word, int wl)
{
char candidate[MAXLNLEN];
const char * r;
int lenr, lenp;
if ((wl < 2) || !numrep) return 0;
for (int i=0; i < numrep; i++ ) {
r = word;
lenr = strlen(reptable[i].pattern2);
lenp = strlen(reptable[i].pattern);
// search every occurence of the pattern in the word
while ((r=strstr(r, reptable[i].pattern)) != NULL) {
strcpy(candidate, word);
if (r-word + lenr + strlen(r+lenp) >= MAXLNLEN) break;
strcpy(candidate+(r-word),reptable[i].pattern2);
strcpy(candidate+(r-word)+lenr, r+lenp);
if (candidate_check(candidate,strlen(candidate))) return 1;
r++; // search for the next letter
}
}
return 0;
}
// forbid compoundings when there are special patterns at word bound
int AffixMgr::cpdpat_check(const char * word, int pos)
{
int len;
for (int i = 0; i < numcheckcpd; i++) {
if (isSubset(checkcpdtable[i].pattern2, word + pos) &&
(len = strlen(checkcpdtable[i].pattern)) && (pos > len) &&
(strncmp(word + pos - len, checkcpdtable[i].pattern, len) == 0)) return 1;
}
return 0;
}
// forbid compounding with neighbouring upper and lower case characters at word bounds
int AffixMgr::cpdcase_check(const char * word, int pos)
{
if (utf8) {
w_char u, w;
const char * p;
u8_u16(&u, 1, word + pos);
for (p = word + pos - 1; (*p & 0xc0) == 0x80; p--);
u8_u16(&w, 1, p);
unsigned short a = (u.h << 8) + u.l;
unsigned short b = (w.h << 8) + w.l;
if (((unicodetoupper(a, langnum) == a) || (unicodetoupper(b, langnum) == b))) return 1;
} else {
unsigned char a = *(word + pos - 1);
unsigned char b = *(word + pos);
if ((csconv[a].ccase || csconv[b].ccase) && (a != '-') && (b != '-')) return 1;
}
return 0;
}
// check compound patterns
int AffixMgr::defcpd_check(hentry *** words, short wnum, hentry * rv, hentry ** def, char all)
{
signed short btpp[MAXWORDLEN]; // metacharacter (*, ?) positions for backtracking
signed short btwp[MAXWORDLEN]; // word positions for metacharacters
int btnum[MAXWORDLEN]; // number of matched characters in metacharacter positions
short bt = 0;
int i;
int ok;
int w = 0;
if (!*words) {
w = 1;
*words = def;
}
(*words)[wnum] = rv;
for (i = 0; i < numdefcpd; i++) {
signed short pp = 0; // pattern position
signed short wp = 0; // "words" position
int ok2;
ok = 1;
ok2 = 1;
do {
while ((pp < defcpdtable[i].len) && (wp <= wnum)) {
if (((pp+1) < defcpdtable[i].len) &&
((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) {
int wend = (defcpdtable[i].def[pp+1] == '?') ? wp : wnum;
ok2 = 1;
pp+=2;
btpp[bt] = pp;
btwp[bt] = wp;
while (wp <= wend) {
if (!(*words)[wp]->alen ||
!TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp-2], (*words)[wp]->alen)) {
ok2 = 0;
break;
}
wp++;
}
if (wp <= wnum) ok2 = 0;
btnum[bt] = wp - btwp[bt];
if (btnum[bt] > 0) bt++;
if (ok2) break;
} else {
ok2 = 1;
if (!(*words)[wp] || !(*words)[wp]->alen ||
!TESTAFF((*words)[wp]->astr, defcpdtable[i].def[pp], (*words)[wp]->alen)) {
ok = 0;
break;
}
pp++;
wp++;
if ((defcpdtable[i].len == pp) && !(wp > wnum)) ok = 0;
}
}
if (ok && ok2) {
int r = pp;
while ((defcpdtable[i].len > r) && ((r+1) < defcpdtable[i].len) &&
((defcpdtable[i].def[r+1] == '*') || (defcpdtable[i].def[r+1] == '?'))) r+=2;
if (defcpdtable[i].len <= r) return 1;
}
// backtrack
if (bt) do {
ok = 1;
btnum[bt - 1]--;
pp = btpp[bt - 1];
wp = btwp[bt - 1] + (signed short) btnum[bt - 1];
} while ((btnum[bt - 1] < 0) && --bt);
} while (bt);
if (ok && ok2 && (!all || (defcpdtable[i].len <= pp))) return 1;
// check zero ending
while (ok && ok2 && (defcpdtable[i].len > pp) && ((pp+1) < defcpdtable[i].len) &&
((defcpdtable[i].def[pp+1] == '*') || (defcpdtable[i].def[pp+1] == '?'))) pp+=2;
if (ok && ok2 && (defcpdtable[i].len <= pp)) return 1;
}
(*words)[wnum] = NULL;
if (w) *words = NULL;
return 0;
}
inline int AffixMgr::candidate_check(const char * word, int len)
{
struct hentry * rv=NULL;
rv = lookup(word);
if (rv) return 1;
// rv = prefix_check(word,len,1);
// if (rv) return 1;
rv = affix_check(word,len);
if (rv) return 1;
return 0;
}
// calculate number of syllable for compound-checking
short AffixMgr::get_syllable(const char * word, int wlen)
{
if (cpdmaxsyllable==0) return 0;
short num=0;
if (!utf8) {
for (int i=0; i 0; i--) {
if (flag_bsearch((unsigned short *) cpdvowels_utf16,
((unsigned short *) w)[i - 1], cpdvowels_utf16_len)) num++;
}
}
return num;
}
// check if compound word is correctly spelled
// hu_mov_rule = spec. Hungarian rule (XXX)
struct hentry * AffixMgr::compound_check(const char * word, int len,
short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words = NULL,
char hu_mov_rule = 0, int * cmpdstemnum = NULL, int * cmpdstem = NULL, char is_sug = 0)
{
int i;
short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;
int oldcmpdstemnum = 0;
struct hentry * rv = NULL;
struct hentry * rv_first;
struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking
char st [MAXWORDUTF8LEN + 4];
char ch;
int cmin;
int cmax;
int checked_prefix;
#ifdef HUNSTEM
if (cmpdstemnum) {
if (wordnum == 0) {
*cmpdstemnum = 1;
} else {
(*cmpdstemnum)++;
}
}
#endif
if (utf8) {
for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) {
cmin++;
for (; (word[cmin] & 0xc0) == 0x80; cmin++);
}
for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) {
cmax--;
for (; (word[cmax] & 0xc0) == 0x80; cmax--);
}
} else {
cmin = cpdmin;
cmax = len - cpdmin + 1;
}
strcpy(st, word);
for (i = cmin; i < cmax; i++) {
oldnumsyllable = numsyllable;
oldwordnum = wordnum;
checked_prefix = 0;
// go to end of the UTF-8 character
if (utf8) {
for (; (st[i] & 0xc0) == 0x80; i++);
if (i >= cmax) return NULL;
}
ch = st[i];
st[i] = '\0';
sfx = NULL;
pfx = NULL;
// FIRST WORD
rv = lookup(st); // perhaps without prefix
// search homonym with compound flag
while ((rv) && !hu_mov_rule &&
((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
!((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
(compoundbegin && !wordnum &&
TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
(compoundmiddle && wordnum && !words &&
TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||
(numdefcpd &&
((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) ||
(words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0))))
))) {
rv = rv->next_homonym;
}
if (!rv) {
if (compoundflag &&
!(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {
if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&
((SfxEntry*)sfx)->getCont() &&
((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag,
((SfxEntry*)sfx)->getContLen())) || (compoundend &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
}
if (rv ||
(((wordnum == 0) && compoundbegin &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||
((wordnum > 0) && compoundmiddle &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))
) checked_prefix = 1;
// else check forbiddenwords and needaffix
} else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
TESTAFF(rv->astr, needaffix, rv->alen) ||
(is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen))
)) {
st[i] = ch;
continue;
}
// check non_compound flag in suffix and prefix
if ((rv) && !hu_mov_rule &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
// check compoundend flag in suffix and prefix
if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
// check compoundmiddle flag in suffix and prefix
if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
// check forbiddenwords
if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
(is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) {
return NULL;
}
// increment word number, if the second root has a compoundroot flag
if ((rv) && compoundroot &&
(TESTAFF(rv->astr, compoundroot, rv->alen))) {
wordnum++;
}
// first word is acceptable in compound words?
if (((rv) &&
( checked_prefix || (words && words[wnum]) ||
(compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen))// ||
// (numdefcpd && )
// LANG_hu section: spec. Hungarian rule
|| ((langnum == LANG_hu) && hu_mov_rule && (
TESTAFF(rv->astr, 'F', rv->alen) || // XXX hardwired Hungarian dictionary codes
TESTAFF(rv->astr, 'G', rv->alen) ||
TESTAFF(rv->astr, 'H', rv->alen)
)
)
// END of LANG_hu section
)
&& ! (( checkcompoundtriple && // test triple letters
(word[i-1]==word[i]) && (
((i>1) && (word[i-1]==word[i-2])) ||
((word[i-1]==word[i+1])) // may be word[i+1] == '\0'
)
) ||
(
// test CHECKCOMPOUNDPATTERN
numcheckcpd && cpdpat_check(word, i)
) ||
(
checkcompoundcase && cpdcase_check(word, i)
))
)
// LANG_hu section: spec. Hungarian rule
|| ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) &&
(sfx && ((SfxEntry*)sfx)->getCont() && ( // XXX hardwired Hungarian dic. codes
TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) ||
TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen())
)
)
)
// END of LANG_hu section
) {
// LANG_hu section: spec. Hungarian rule
if (langnum == LANG_hu) {
// calculate syllable number of the word
numsyllable += get_syllable(st, i);
// + 1 word, if syllable number of the prefix > 1 (hungarian convention)
if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;
}
// END of LANG_hu section
#ifdef HUNSTEM
if (cmpdstem) cmpdstem[*cmpdstemnum - 1] = i;
#endif
// NEXT WORD(S)
rv_first = rv;
rv = lookup((word+i)); // perhaps without prefix
// search homonym with compound flag
while ((rv) && ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
!((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
(compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) ||
(numdefcpd && words && defcpd_check(&words, wnum + 1, rv, NULL,1))))) {
rv = rv->next_homonym;
}
if (rv && words && words[wnum + 1]) return rv;
oldnumsyllable2 = numsyllable;
oldwordnum2 = wordnum;
// LANG_hu section: spec. Hungarian rule, XXX hardwired dictionary code
if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) {
numsyllable--;
}
// END of LANG_hu section
// increment word number, if the second root has a compoundroot flag
if ((rv) && (compoundroot) &&
(TESTAFF(rv->astr, compoundroot, rv->alen))) {
wordnum++;
}
// check forbiddenwords
if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
(is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL;
// second word is acceptable, as a root?
// hungarian conventions: compounding is acceptable,
// when compound forms consist of 2 words, or if more,
// then the syllable number of root words must be 6, or lesser.
if ((rv) && (
(compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
(compoundend && TESTAFF(rv->astr, compoundend, rv->alen))
)
&& (
((cpdwordmax==-1) || (wordnum+1clen)<=cpdmaxsyllable))
)
&& (
(!checkcompounddup || (rv != rv_first))
)
)
{
// forbid compound word, if it is a non compound word with typical fault
if (checkcompoundrep && cpdrep_check(word,len)) return NULL;
return rv;
}
numsyllable = oldnumsyllable2 ;
wordnum = oldwordnum2;
// perhaps second word has prefix or/and suffix
sfx = NULL;
sfxflag = FLAG_NULL;
rv = (compoundflag) ? affix_check((word+i),strlen(word+i), compoundflag, IN_CPD_END) : NULL;
if (!rv && compoundend) {
sfx = NULL;
pfx = NULL;
rv = affix_check((word+i),strlen(word+i), compoundend, IN_CPD_END);
}
if (!rv && numdefcpd && words) {
rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END);
if (rv && defcpd_check(&words, wnum + 1, rv, NULL, 1)) return rv;
rv = NULL;
}
// check non_compound flag in suffix and prefix
if ((rv) &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
// check forbiddenwords
if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
(is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) return NULL;
// pfxappnd = prefix of word+i, or NULL
// calculate syllable number of prefix.
// hungarian convention: when syllable number of prefix is more,
// than 1, the prefix+word counts as two words.
if (langnum == LANG_hu) {
// calculate syllable number of the word
numsyllable += get_syllable(word + i, strlen(word + i));
// - affix syllable num.
// XXX only second suffix (inflections, not derivations)
if (sfxappnd) {
char * tmp = myrevstrdup(sfxappnd);
numsyllable -= get_syllable(tmp, strlen(tmp));
free(tmp);
}
// + 1 word, if syllable number of the prefix > 1 (hungarian convention)
if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;
// increment syllable num, if last word has a SYLLABLENUM flag
// and the suffix is beginning `s'
if (cpdsyllablenum) {
switch (sfxflag) {
case 'c': { numsyllable+=2; break; }
case 'J': { numsyllable += 1; break; }
case 'I': { if (TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; }
}
}
}
// increment word number, if the second word has a compoundroot flag
if ((rv) && (compoundroot) &&
(TESTAFF(rv->astr, compoundroot, rv->alen))) {
wordnum++;
}
// second word is acceptable, as a word with prefix or/and suffix?
// hungarian conventions: compounding is acceptable,
// when compound forms consist 2 word, otherwise
// the syllable number of root words is 6, or lesser.
if ((rv) &&
(
((cpdwordmax == -1) || (wordnum + 1 < cpdwordmax)) ||
((cpdmaxsyllable == 0) ||
(numsyllable <= cpdmaxsyllable))
)
&& (
(!checkcompounddup || (rv != rv_first))
)) {
// forbid compound word, if it is a non compound word with typical fault
if (checkcompoundrep && cpdrep_check(word, len)) return NULL;
return rv;
}
numsyllable = oldnumsyllable2;
wordnum = oldwordnum2;
#ifdef HUNSTEM
if (cmpdstemnum) oldcmpdstemnum = *cmpdstemnum;
#endif
// perhaps second word is a compound word (recursive call)
if (wordnum < maxwordnum) {
rv = compound_check((word+i),strlen(word+i), wordnum+1,
numsyllable, maxwordnum, wnum + 1, words,
0, cmpdstemnum, cmpdstem, is_sug);
} else {
rv=NULL;
}
if (rv) {
// forbid compound word, if it is a non compound word with typical fault
if (checkcompoundrep && cpdrep_check(word, len)) return NULL;
return rv;
} else {
#ifdef HUNSTEM
if (cmpdstemnum) *cmpdstemnum = oldcmpdstemnum;
#endif
}
}
st[i] = ch;
wordnum = oldwordnum;
numsyllable = oldnumsyllable;
}
return NULL;
}
// check if compound word is correctly spelled
// hu_mov_rule = spec. Hungarian rule (XXX)
int AffixMgr::compound_check_morph(const char * word, int len,
short wordnum, short numsyllable, short maxwordnum, short wnum, hentry ** words,
char hu_mov_rule = 0, char ** result = NULL, char * partresult = NULL)
{
int i;
short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2;
int ok = 0;
struct hentry * rv = NULL;
struct hentry * rv_first;
struct hentry * rwords[MAXWORDLEN]; // buffer for COMPOUND pattern checking
char st [MAXWORDUTF8LEN + 4];
char ch;
int checked_prefix;
char presult[MAXLNLEN];
int cmin;
int cmax;
if (utf8) {
for (cmin = 0, i = 0; (i < cpdmin) && word[cmin]; i++) {
cmin++;
for (; (word[cmin] & 0xc0) == 0x80; cmin++);
}
for (cmax = len, i = 0; (i < (cpdmin - 1)) && cmax; i++) {
cmax--;
for (; (word[cmax] & 0xc0) == 0x80; cmax--);
}
} else {
cmin = cpdmin;
cmax = len - cpdmin + 1;
}
strcpy(st, word);
for (i = cmin; i < cmax; i++) {
oldnumsyllable = numsyllable;
oldwordnum = wordnum;
checked_prefix = 0;
// go to end of the UTF-8 character
if (utf8) {
for (; (st[i] & 0xc0) == 0x80; i++);
if (i >= cmax) return 0;
}
ch = st[i];
st[i] = '\0';
sfx = NULL;
// FIRST WORD
*presult = '\0';
if (partresult) strcat(presult, partresult);
rv = lookup(st); // perhaps without prefix
// search homonym with compound flag
while ((rv) && !hu_mov_rule &&
((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
!((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
(compoundbegin && !wordnum &&
TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
(compoundmiddle && wordnum && !words &&
TESTAFF(rv->astr, compoundmiddle, rv->alen)) ||
(numdefcpd &&
((!words && !wordnum && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0)) ||
(words && defcpd_check(&words, wnum, rv, (hentry **) &rwords, 0))))
))) {
rv = rv->next_homonym;
}
if (rv) {
sprintf(presult + strlen(presult), "%c%s%s", MSEP_FLD, MORPH_PART, st);
if (!HENTRY_FIND(rv, MORPH_STEM)) {
sprintf(presult + strlen(presult), "%c%s%s", MSEP_FLD, MORPH_STEM, st);
}
// store the pointer of the hash entry
// sprintf(presult + strlen(presult), "%c%s%p", MSEP_FLD, MORPH_HENTRY, rv);
if (HENTRY_DATA(rv)) {
sprintf(presult + strlen(presult), "%c%s", MSEP_FLD, HENTRY_DATA2(rv));
}
}
if (!rv) {
if (compoundflag &&
!(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {
if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&
((SfxEntry*)sfx)->getCont() &&
((compoundforbidflag && TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag,
((SfxEntry*)sfx)->getContLen())) || (compoundend &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
}
if (rv ||
(((wordnum == 0) && compoundbegin &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||
((wordnum > 0) && compoundmiddle &&
((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))
) {
// char * p = prefix_check_morph(st, i, 0, compound);
char * p = NULL;
if (compoundflag) p = affix_check_morph(st, i, compoundflag);
if (!p || (*p == '\0')) {
if (p) free(p);
p = NULL;
if ((wordnum == 0) && compoundbegin) {
p = affix_check_morph(st, i, compoundbegin);
} else if ((wordnum > 0) && compoundmiddle) {
p = affix_check_morph(st, i, compoundmiddle);
}
}
if (p && (*p != '\0')) {
sprintf(presult + strlen(presult), "%c%s%s%s", MSEP_FLD,
MORPH_PART, st, line_uniq_app(&p, MSEP_REC));
}
if (p) free(p);
checked_prefix = 1;
}
// else check forbiddenwords
} else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
TESTAFF(rv->astr, needaffix, rv->alen))) {
st[i] = ch;
continue;
}
// check non_compound flag in suffix and prefix
if ((rv) && !hu_mov_rule &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag,
((SfxEntry*)sfx)->getContLen())))) {
continue;
}
// check compoundend flag in suffix and prefix
if ((rv) && !checked_prefix && compoundend && !hu_mov_rule &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundend,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundend,
((SfxEntry*)sfx)->getContLen())))) {
continue;
}
// check compoundmiddle flag in suffix and prefix
if ((rv) && !checked_prefix && (wordnum==0) && compoundmiddle && !hu_mov_rule &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundmiddle,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundmiddle,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
// check forbiddenwords
if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) continue;
// increment word number, if the second root has a compoundroot flag
if ((rv) && (compoundroot) &&
(TESTAFF(rv->astr, compoundroot, rv->alen))) {
wordnum++;
}
// first word is acceptable in compound words?
if (((rv) &&
( checked_prefix || (words && words[wnum]) ||
(compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
((oldwordnum == 0) && compoundbegin && TESTAFF(rv->astr, compoundbegin, rv->alen)) ||
((oldwordnum > 0) && compoundmiddle && TESTAFF(rv->astr, compoundmiddle, rv->alen))
// LANG_hu section: spec. Hungarian rule
|| ((langnum == LANG_hu) && // hu_mov_rule
hu_mov_rule && (
TESTAFF(rv->astr, 'F', rv->alen) ||
TESTAFF(rv->astr, 'G', rv->alen) ||
TESTAFF(rv->astr, 'H', rv->alen)
)
)
// END of LANG_hu section
)
&& ! (( checkcompoundtriple && // test triple letters
(word[i-1]==word[i]) && (
((i>1) && (word[i-1]==word[i-2])) ||
((word[i-1]==word[i+1])) // may be word[i+1] == '\0'
)
) ||
(
// test CHECKCOMPOUNDPATTERN
numcheckcpd && cpdpat_check(word, i)
) ||
(
checkcompoundcase && cpdcase_check(word, i)
))
)
// LANG_hu section: spec. Hungarian rule
|| ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st,i)) &&
(sfx && ((SfxEntry*)sfx)->getCont() && (
TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) 'x', ((SfxEntry*)sfx)->getContLen()) ||
TESTAFF(((SfxEntry*)sfx)->getCont(), (unsigned short) '%', ((SfxEntry*)sfx)->getContLen())
)
)
)
// END of LANG_hu section
) {
// LANG_hu section: spec. Hungarian rule
if (langnum == LANG_hu) {
// calculate syllable number of the word
numsyllable += get_syllable(st, i);
// + 1 word, if syllable number of the prefix > 1 (hungarian convention)
if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;
}
// END of LANG_hu section
// NEXT WORD(S)
rv_first = rv;
rv = lookup((word+i)); // perhaps without prefix
// search homonym with compound flag
while ((rv) && ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) ||
!((compoundflag && !words && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
(compoundend && !words && TESTAFF(rv->astr, compoundend, rv->alen)) ||
(numdefcpd && defcpd_check(&words, wnum + 1, rv, NULL,1))))) {
rv = rv->next_homonym;
}
if (rv && words && words[wnum + 1]) {
strcat(*result, presult);
strcat(*result, " ");
strcat(*result, MORPH_PART);
strcat(*result, word+i);
if (complexprefixes && HENTRY_DATA(rv)) strcat(*result, HENTRY_DATA2(rv));
if (!HENTRY_FIND(rv, MORPH_STEM)) {
strcat(*result, " ");
strcat(*result, MORPH_STEM);
strcat(*result, HENTRY_WORD(rv));
}
// store the pointer of the hash entry
// sprintf(*result + strlen(*result), " %s%p", MORPH_HENTRY, rv);
if (!complexprefixes && HENTRY_DATA(rv)) {
strcat(*result, " ");
strcat(*result, HENTRY_DATA2(rv));
}
strcat(*result, "\n");
ok = 1;
return 0;
}
oldnumsyllable2 = numsyllable;
oldwordnum2 = wordnum;
// LANG_hu section: spec. Hungarian rule
if ((rv) && (langnum == LANG_hu) && (TESTAFF(rv->astr, 'I', rv->alen)) && !(TESTAFF(rv->astr, 'J', rv->alen))) {
numsyllable--;
}
// END of LANG_hu section
// increment word number, if the second root has a compoundroot flag
if ((rv) && (compoundroot) &&
(TESTAFF(rv->astr, compoundroot, rv->alen))) {
wordnum++;
}
// check forbiddenwords
if ((rv) && (rv->astr) && TESTAFF(rv->astr, forbiddenword, rv->alen)) {
st[i] = ch;
continue;
}
// second word is acceptable, as a root?
// hungarian conventions: compounding is acceptable,
// when compound forms consist of 2 words, or if more,
// then the syllable number of root words must be 6, or lesser.
if ((rv) && (
(compoundflag && TESTAFF(rv->astr, compoundflag, rv->alen)) ||
(compoundend && TESTAFF(rv->astr, compoundend, rv->alen))
)
&& (
((cpdwordmax==-1) || (wordnum+1blen)<=cpdmaxsyllable))
)
&& (
(!checkcompounddup || (rv != rv_first))
)
)
{
// bad compound word
strcat(*result, presult);
strcat(*result, " ");
strcat(*result, MORPH_PART);
strcat(*result, word+i);
if (HENTRY_DATA(rv)) {
if (complexprefixes) strcat(*result, HENTRY_DATA2(rv));
if (! HENTRY_FIND(rv, MORPH_STEM)) {
strcat(*result, " ");
strcat(*result, MORPH_STEM);
strcat(*result, HENTRY_WORD(rv));
}
// store the pointer of the hash entry
// sprintf(*result + strlen(*result), " %s%p", MORPH_HENTRY, rv);
if (!complexprefixes) {
strcat(*result, " ");
strcat(*result, HENTRY_DATA2(rv));
}
}
strcat(*result, "\n");
ok = 1;
}
numsyllable = oldnumsyllable2 ;
wordnum = oldwordnum2;
// perhaps second word has prefix or/and suffix
sfx = NULL;
sfxflag = FLAG_NULL;
if (compoundflag) rv = affix_check((word+i),strlen(word+i), compoundflag); else rv = NULL;
if (!rv && compoundend) {
sfx = NULL;
pfx = NULL;
rv = affix_check((word+i),strlen(word+i), compoundend);
}
if (!rv && numdefcpd && words) {
rv = affix_check((word+i),strlen(word+i), 0, IN_CPD_END);
if (rv && words && defcpd_check(&words, wnum + 1, rv, NULL, 1)) {
char * m = NULL;
if (compoundflag) m = affix_check_morph((word+i),strlen(word+i), compoundflag);
if ((!m || *m == '\0') && compoundend) {
if (m) free(m);
m = affix_check_morph((word+i),strlen(word+i), compoundend);
}
strcat(*result, presult);
if (m || (*m != '\0')) {
sprintf(*result + strlen(*result), "%c%s%s%s", MSEP_FLD,
MORPH_PART, word + i, line_uniq_app(&m, MSEP_REC));
}
if (m) free(m);
strcat(*result, "\n");
ok = 1;
}
}
// check non_compound flag in suffix and prefix
if ((rv) &&
((pfx && ((PfxEntry*)pfx)->getCont() &&
TESTAFF(((PfxEntry*)pfx)->getCont(), compoundforbidflag,
((PfxEntry*)pfx)->getContLen())) ||
(sfx && ((SfxEntry*)sfx)->getCont() &&
TESTAFF(((SfxEntry*)sfx)->getCont(), compoundforbidflag,
((SfxEntry*)sfx)->getContLen())))) {
rv = NULL;
}
// check forbiddenwords
if ((rv) && (rv->astr) && (TESTAFF(rv->astr,forbiddenword,rv->alen))
&& (! TESTAFF(rv->astr, needaffix, rv->alen))) {
st[i] = ch;
continue;
}
if (langnum == LANG_hu) {
// calculate syllable number of the word
numsyllable += get_syllable(word + i, strlen(word + i));
// - affix syllable num.
// XXX only second suffix (inflections, not derivations)
if (sfxappnd) {
char * tmp = myrevstrdup(sfxappnd);
numsyllable -= get_syllable(tmp, strlen(tmp));
free(tmp);
}
// + 1 word, if syllable number of the prefix > 1 (hungarian convention)
if (pfx && (get_syllable(((PfxEntry *)pfx)->getKey(),strlen(((PfxEntry *)pfx)->getKey())) > 1)) wordnum++;
// increment syllable num, if last word has a SYLLABLENUM flag
// and the suffix is beginning `s'
if (cpdsyllablenum) {
switch (sfxflag) {
case 'c': { numsyllable+=2; break; }
case 'J': { numsyllable += 1; break; }
case 'I': { if (rv && TESTAFF(rv->astr, 'J', rv->alen)) numsyllable += 1; break; }
}
}
}
// increment word number, if the second word has a compoundroot flag
if ((rv) && (compoundroot) &&
(TESTAFF(rv->astr, compoundroot, rv->alen))) {
wordnum++;
}
// second word is acceptable, as a word with prefix or/and suffix?
// hungarian conventions: compounding is acceptable,
// when compound forms consist 2 word, otherwise
// the syllable number of root words is 6, or lesser.
if ((rv) &&
(
((cpdwordmax==-1) || (wordnum+1 0) && *s1 && (*s1 == *end_of_s2)) {
s1++;
end_of_s2--;
len--;
}
return (*s1 == '\0');
}
*/
inline int AffixMgr::isRevSubset(const char * s1, const char * end_of_s2, int len)
{
while ((len > 0) && (*s1 != '\0') && ((*s1 == *end_of_s2) || (*s1 == '.'))) {
s1++;
end_of_s2--;
len--;
}
return (*s1 == '\0');
}
// check word for suffixes
struct hentry * AffixMgr::suffix_check (const char * word, int len,
int sfxopts, AffEntry * ppfx, char ** wlst, int maxSug, int * ns,
const FLAG cclass, const FLAG needflag, char in_compound)
{
struct hentry * rv = NULL;
char result[MAXLNLEN];
PfxEntry* ep = (PfxEntry *) ppfx;
// first handle the special case of 0 length suffixes
SfxEntry * se = (SfxEntry *) sStart[0];
while (se) {
if (!cclass || se->getCont()) {
// suffixes are not allowed in beginning of compounds
if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass
// except when signed with compoundpermitflag flag
(se->getCont() && compoundpermitflag &&
TESTAFF(se->getCont(),compoundpermitflag,se->getContLen()))) && (!circumfix ||
// no circumfix flag in prefix and suffix
((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(!se->getCont() || !(TESTAFF(se->getCont(),circumfix,se->getContLen())))) ||
// circumfix flag in prefix AND suffix
((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(se->getCont() && (TESTAFF(se->getCont(),circumfix,se->getContLen()))))) &&
// fogemorpheme
(in_compound ||
!((se->getCont() && (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) &&
// needaffix on prefix or first suffix
(cclass ||
!(se->getCont() && TESTAFF(se->getCont(), needaffix, se->getContLen())) ||
(ppfx && !((ep->getCont()) &&
TESTAFF(ep->getCont(), needaffix,
ep->getContLen())))
)
) {
rv = se->checkword(word,len, sfxopts, ppfx, wlst, maxSug, ns, (FLAG) cclass,
needflag, (in_compound ? 0 : onlyincompound));
if (rv) {
sfx=(AffEntry *)se; // BUG: sfx not stateless
return rv;
}
}
}
se = se->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)(word + len - 1));
SfxEntry * sptr = (SfxEntry *) sStart[sp];
while (sptr) {
if (isRevSubset(sptr->getKey(), word + len - 1, len)
) {
// suffixes are not allowed in beginning of compounds
if ((((in_compound != IN_CPD_BEGIN)) || // && !cclass
// except when signed with compoundpermitflag flag
(sptr->getCont() && compoundpermitflag &&
TESTAFF(sptr->getCont(),compoundpermitflag,sptr->getContLen()))) && (!circumfix ||
// no circumfix flag in prefix and suffix
((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(!sptr->getCont() || !(TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))) ||
// circumfix flag in prefix AND suffix
((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(sptr->getCont() && (TESTAFF(sptr->getCont(),circumfix,sptr->getContLen()))))) &&
// fogemorpheme
(in_compound ||
!((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) &&
// needaffix on prefix or first suffix
(cclass ||
!(sptr->getCont() && TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())) ||
(ppfx && !((ep->getCont()) &&
TESTAFF(ep->getCont(), needaffix,
ep->getContLen())))
)
) {
rv = sptr->checkword(word,len, sfxopts, ppfx, wlst,
maxSug, ns, cclass, needflag, (in_compound ? 0 : onlyincompound));
if (rv) {
sfx=(AffEntry *)sptr; // BUG: sfx not stateless
sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless
if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless
if (cclass || sptr->getCont()) {
if (!derived) {
derived = mystrdup(word);
} else {
strcat(result, " ");
strcpy(result, MORPH_STEM);
strcpy(result, derived); // XXX check size
strcat(result, "\n");
strcat(result, " ");
strcat(result, MORPH_STEM);
strcat(result, word);
// store the pointer of the hash entry
// sprintf(result + strlen(result), " %s%p", MORPH_HENTRY, rv);
free(derived);
derived = mystrdup(result);
}
}
return rv;
}
}
sptr = sptr->getNextEQ();
} else {
sptr = sptr->getNextNE();
}
}
return NULL;
}
// check word for two-level suffixes
struct hentry * AffixMgr::suffix_check_twosfx(const char * word, int len,
int sfxopts, AffEntry * ppfx, const FLAG needflag)
{
struct hentry * rv = NULL;
// first handle the special case of 0 length suffixes
SfxEntry * se = (SfxEntry *) sStart[0];
while (se) {
if (contclasses[se->getFlag()])
{
rv = se->check_twosfx(word,len, sfxopts, ppfx, needflag);
if (rv) return rv;
}
se = se->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)(word + len - 1));
SfxEntry * sptr = (SfxEntry *) sStart[sp];
while (sptr) {
if (isRevSubset(sptr->getKey(), word + len - 1, len)) {
if (contclasses[sptr->getFlag()])
{
rv = sptr->check_twosfx(word,len, sfxopts, ppfx, needflag);
if (rv) {
sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless
if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless
return rv;
}
}
sptr = sptr->getNextEQ();
} else {
sptr = sptr->getNextNE();
}
}
return NULL;
}
char * AffixMgr::suffix_check_twosfx_morph(const char * word, int len,
int sfxopts, AffEntry * ppfx, const FLAG needflag)
{
char result[MAXLNLEN];
char result2[MAXLNLEN];
char result3[MAXLNLEN];
char * st;
result[0] = '\0';
result2[0] = '\0';
result3[0] = '\0';
// first handle the special case of 0 length suffixes
SfxEntry * se = (SfxEntry *) sStart[0];
while (se) {
if (contclasses[se->getFlag()])
{
st = se->check_twosfx_morph(word,len, sfxopts, ppfx, needflag);
if (st) {
if (ppfx) {
if (((PfxEntry *) ppfx)->getMorph()) {
strcat(result, ((PfxEntry *) ppfx)->getMorph());
strcat(result, " ");
} else debugflag(result, ((PfxEntry *) ppfx)->getFlag());
}
strcat(result, st);
free(st);
if (se->getMorph()) {
strcat(result, " ");
strcat(result, se->getMorph());
} else debugflag(result, se->getFlag());
strcat(result, "\n");
}
}
se = se->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)(word + len - 1));
SfxEntry * sptr = (SfxEntry *) sStart[sp];
while (sptr) {
if (isRevSubset(sptr->getKey(), word + len - 1, len)) {
if (contclasses[sptr->getFlag()])
{
st = sptr->check_twosfx_morph(word,len, sfxopts, ppfx, needflag);
if (st) {
sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless
if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless
strcpy(result2, st);
free(st);
result3[0] = '\0';
#ifdef DEBUG
unsigned short flag = sptr->getFlag();
if (flag_mode == FLAG_NUM) {
sprintf(result3, "<%d>", sptr->getKey());
} else if (flag_mode == FLAG_LONG) {
sprintf(result3, "<%c%c>", flag >> 8, (flag << 8) >>8);
} else sprintf(result3, "<%c>", flag);
strcat(result3, ":");
#endif
if (sptr->getMorph()) {
strcat(result3, " ");
strcat(result3, sptr->getMorph());
} else debugflag(result3, sptr->getFlag());
strlinecat(result2, result3);
strcat(result2, "\n");
strcat(result, result2);
}
}
sptr = sptr->getNextEQ();
} else {
sptr = sptr->getNextNE();
}
}
if (*result) return mystrdup(result);
return NULL;
}
char * AffixMgr::suffix_check_morph(const char * word, int len,
int sfxopts, AffEntry * ppfx, const FLAG cclass, const FLAG needflag, char in_compound)
{
char result[MAXLNLEN];
struct hentry * rv = NULL;
result[0] = '\0';
PfxEntry* ep = (PfxEntry *) ppfx;
// first handle the special case of 0 length suffixes
SfxEntry * se = (SfxEntry *) sStart[0];
while (se) {
if (!cclass || se->getCont()) {
// suffixes are not allowed in beginning of compounds
if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass
// except when signed with compoundpermitflag flag
(se->getCont() && compoundpermitflag &&
TESTAFF(se->getCont(),compoundpermitflag,se->getContLen()))) && (!circumfix ||
// no circumfix flag in prefix and suffix
((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(!se->getCont() || !(TESTAFF(se->getCont(),circumfix,se->getContLen())))) ||
// circumfix flag in prefix AND suffix
((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(se->getCont() && (TESTAFF(se->getCont(),circumfix,se->getContLen()))))) &&
// fogemorpheme
(in_compound ||
!((se->getCont() && (TESTAFF(se->getCont(), onlyincompound, se->getContLen()))))) &&
// needaffix on prefix or first suffix
(cclass ||
!(se->getCont() && TESTAFF(se->getCont(), needaffix, se->getContLen())) ||
(ppfx && !((ep->getCont()) &&
TESTAFF(ep->getCont(), needaffix,
ep->getContLen())))
)
))
rv = se->checkword(word,len, sfxopts, ppfx, NULL, 0, 0, cclass, needflag);
while (rv) {
if (ppfx) {
if (((PfxEntry *) ppfx)->getMorph()) {
strcat(result, ((PfxEntry *) ppfx)->getMorph());
strcat(result, " ");
} else debugflag(result, ((PfxEntry *) ppfx)->getFlag());
}
if (complexprefixes && HENTRY_DATA(rv)) strcat(result, HENTRY_DATA2(rv));
if (! HENTRY_FIND(rv, MORPH_STEM)) {
strcat(result, " ");
strcat(result, MORPH_STEM);
strcat(result, HENTRY_WORD(rv));
}
// store the pointer of the hash entry
// sprintf(result + strlen(result), " %s%p", MORPH_HENTRY, rv);
if (!complexprefixes && HENTRY_DATA(rv)) {
strcat(result, " ");
strcat(result, HENTRY_DATA2(rv));
}
if (se->getMorph()) {
strcat(result, " ");
strcat(result, se->getMorph());
} else debugflag(result, se->getFlag());
strcat(result, "\n");
rv = se->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag);
}
}
se = se->getNext();
}
// now handle the general case
unsigned char sp = *((const unsigned char *)(word + len - 1));
SfxEntry * sptr = (SfxEntry *) sStart[sp];
while (sptr) {
if (isRevSubset(sptr->getKey(), word + len - 1, len)
) {
// suffixes are not allowed in beginning of compounds
if (((((in_compound != IN_CPD_BEGIN)) || // && !cclass
// except when signed with compoundpermitflag flag
(sptr->getCont() && compoundpermitflag &&
TESTAFF(sptr->getCont(),compoundpermitflag,sptr->getContLen()))) && (!circumfix ||
// no circumfix flag in prefix and suffix
((!ppfx || !(ep->getCont()) || !TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(!sptr->getCont() || !(TESTAFF(sptr->getCont(),circumfix,sptr->getContLen())))) ||
// circumfix flag in prefix AND suffix
((ppfx && (ep->getCont()) && TESTAFF(ep->getCont(),
circumfix, ep->getContLen())) &&
(sptr->getCont() && (TESTAFF(sptr->getCont(),circumfix,sptr->getContLen()))))) &&
// fogemorpheme
(in_compound ||
!((sptr->getCont() && (TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))) &&
// needaffix on first suffix
(cclass || !(sptr->getCont() &&
TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())))
)) rv = sptr->checkword(word,len, sfxopts, ppfx, NULL, 0, 0, cclass, needflag);
while (rv) {
if (ppfx) {
if (((PfxEntry *) ppfx)->getMorph()) {
strcat(result, ((PfxEntry *) ppfx)->getMorph());
strcat(result, " ");
} else debugflag(result, ((PfxEntry *) ppfx)->getFlag());
}
if (complexprefixes && HENTRY_DATA(rv)) strcat(result, HENTRY_DATA2(rv));
if (! HENTRY_FIND(rv, MORPH_STEM)) {
strcat(result, " ");
strcat(result, MORPH_STEM);
strcat(result, HENTRY_WORD(rv));
}
// store the pointer of the hash entry
// sprintf(result + strlen(result), " %s%p", MORPH_HENTRY, rv);
if (!complexprefixes && HENTRY_DATA(rv)) {
strcat(result, " ");
strcat(result, HENTRY_DATA2(rv));
}
#ifdef DEBUG
unsigned short flag = sptr->getFlag();
if (flag_mode == FLAG_NUM) {
sprintf(result, "<%d>", sptr->getKey());
} else if (flag_mode == FLAG_LONG) {
sprintf(result, "<%c%c>", flag >> 8, (flag << 8) >>8);
} else sprintf(result, "<%c>", flag);
strcat(result, ":");
#endif
if (sptr->getMorph()) {
strcat(result, " ");
strcat(result, sptr->getMorph());
} else debugflag(result, sptr->getFlag());
strcat(result, "\n");
rv = sptr->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag);
}
sptr = sptr->getNextEQ();
} else {
sptr = sptr->getNextNE();
}
}
if (*result) return mystrdup(result);
return NULL;
}
// check if word with affixes is correctly spelled
struct hentry * AffixMgr::affix_check (const char * word, int len, const FLAG needflag, char in_compound)
{
struct hentry * rv= NULL;
if (derived) free(derived);
derived = NULL;
// check all prefixes (also crossed with suffixes if allowed)
rv = prefix_check(word, len, in_compound, needflag);
if (rv) return rv;
// if still not found check all suffixes
rv = suffix_check(word, len, 0, NULL, NULL, 0, NULL, FLAG_NULL, needflag, in_compound);
if (havecontclass) {
sfx = NULL;
pfx = NULL;
if (rv) return rv;
// if still not found check all two-level suffixes
rv = suffix_check_twosfx(word, len, 0, NULL, needflag);
if (rv) return rv;
// if still not found check all two-level suffixes
rv = prefix_check_twosfx(word, len, IN_CPD_NOT, needflag);
}
return rv;
}
// check if word with affixes is correctly spelled
char * AffixMgr::affix_check_morph(const char * word, int len, const FLAG needflag, char in_compound)
{
char result[MAXLNLEN];
char * st = NULL;
*result = '\0';
// check all prefixes (also crossed with suffixes if allowed)
st = prefix_check_morph(word, len, in_compound);
if (st) {
strcat(result, st);
free(st);
}
// if still not found check all suffixes
st = suffix_check_morph(word, len, 0, NULL, '\0', needflag, in_compound);
if (st) {
strcat(result, st);
free(st);
}
if (havecontclass) {
sfx = NULL;
pfx = NULL;
// if still not found check all two-level suffixes
st = suffix_check_twosfx_morph(word, len, 0, NULL, needflag);
if (st) {
strcat(result, st);
free(st);
}
// if still not found check all two-level suffixes
st = prefix_check_twosfx_morph(word, len, IN_CPD_NOT, needflag);
if (st) {
strcat(result, st);
free(st);
}
}
return mystrdup(result);
}
char * AffixMgr::morphgen(char * ts, int wl, const unsigned short * ap,
unsigned short al, char * morph, char * targetmorph, int level)
{
// handle suffixes
char * stemmorph;
char * stemmorphcatpos;
char mymorph[MAXLNLEN];
if (!morph && !targetmorph) return NULL;
// check substandard flag
if (TESTAFF(ap, substandard, al)) return NULL;
if (morphcmp(morph, targetmorph) == 0) return mystrdup(ts);
// int targetcount = get_sfxcount(targetmorph);
// use input suffix fields, if exist
if (strstr(morph, MORPH_INFL_SFX) || strstr(morph, MORPH_DERI_SFX)) {
stemmorph = mymorph;
strcpy(stemmorph, morph);
strcat(stemmorph, " ");
stemmorphcatpos = stemmorph + strlen(stemmorph);
} else {
stemmorph = morph;
stemmorphcatpos = NULL;
}
for (int i = 0; i < al; i++) {
const unsigned char c = (unsigned char) (ap[i] & 0x00FF);
SfxEntry * sptr = (SfxEntry *)sFlag[c];
while (sptr) {
if (sptr->getFlag() == ap[i] && ((sptr->getContLen() == 0) ||
// don't generate forms with substandard affixes
!TESTAFF(sptr->getCont(), substandard, sptr->getContLen()))) {
if (stemmorphcatpos) strcpy(stemmorphcatpos, sptr->getMorph());
else stemmorph = (char *) sptr->getMorph();
int cmp = morphcmp(stemmorph, targetmorph);
if (cmp == 0) {
char * newword = sptr->add(ts, wl);
if (newword) {
hentry * check = pHMgr->lookup(newword); // XXX extra dic
if (!check || !check->astr ||
!TESTAFF(check->astr, forbiddenword, check->alen)) {
return newword;
}
free(newword);
}
}
// recursive call for secondary suffixes
if ((level == 0) && (cmp == 1) && (sptr->getContLen() > 0) &&
// (get_sfxcount(stemmorph) < targetcount) &&
!TESTAFF(sptr->getCont(), substandard, sptr->getContLen())) {
char * newword = sptr->add(ts, wl);
if (newword) {
char * newword2 = morphgen(newword, strlen(newword), sptr->getCont(),
sptr->getContLen(), stemmorph, targetmorph, 1);
if (newword2) {
free(newword);
return newword2;
}
free(newword);
newword = NULL;
}
}
}
sptr = (SfxEntry *)sptr ->getFlgNxt();
}
}
return NULL;
}
int AffixMgr::expand_rootword(struct guessword * wlst, int maxn, const char * ts,
int wl, const unsigned short * ap, unsigned short al, char * bad, int badl,
char * phon)
{
int nh=0;
// first add root word to list
if ((nh < maxn) && !(al && ((needaffix && TESTAFF(ap, needaffix, al)) ||
(onlyincompound && TESTAFF(ap, onlyincompound, al))))) {
wlst[nh].word = mystrdup(ts);
if (!wlst[nh].word) return 0;
wlst[nh].allow = (1 == 0);
wlst[nh].orig = NULL;
nh++;
// add special phonetic version
if (phon && (nh < maxn)) {
wlst[nh].word = mystrdup(phon);
if (!wlst[nh].word) return nh - 1;
wlst[nh].allow = (1 == 0);
wlst[nh].orig = mystrdup(ts);
if (!wlst[nh].orig) return nh - 1;
nh++;
}
}
// handle suffixes
for (int i = 0; i < al; i++) {
const unsigned char c = (unsigned char) (ap[i] & 0x00FF);
SfxEntry * sptr = (SfxEntry *)sFlag[c];
while (sptr) {
if ((sptr->getFlag() == ap[i]) && (!sptr->getKeyLen() || ((badl > sptr->getKeyLen()) &&
(strcmp(sptr->getAffix(), bad + badl - sptr->getKeyLen()) == 0))) &&
// check needaffix flag
!(sptr->getCont() && ((needaffix &&
TESTAFF(sptr->getCont(), needaffix, sptr->getContLen())) ||
(circumfix &&
TESTAFF(sptr->getCont(), circumfix, sptr->getContLen())) ||
(onlyincompound &&
TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))))
) {
char * newword = sptr->add(ts, wl);
if (newword) {
if (nh < maxn) {
wlst[nh].word = newword;
wlst[nh].allow = sptr->allowCross();
wlst[nh].orig = NULL;
nh++;
// add special phonetic version
if (phon && (nh < maxn)) {
char st[MAXWORDUTF8LEN];
strcpy(st, phon);
strcat(st, sptr->getKey());
reverseword(st + strlen(phon));
wlst[nh].word = mystrdup(st);
if (!wlst[nh].word) return nh - 1;
wlst[nh].allow = (1 == 0);
wlst[nh].orig = mystrdup(newword);
if (!wlst[nh].orig) return nh - 1;
nh++;
}
} else {
free(newword);
}
}
}
sptr = (SfxEntry *)sptr ->getFlgNxt();
}
}
int n = nh;
// handle cross products of prefixes and suffixes
for (int j=1;jgetFlag() == ap[k]) && cptr->allowCross() && (!cptr->getKeyLen() || ((badl > cptr->getKeyLen()) &&
(strncmp(cptr->getKey(), bad, cptr->getKeyLen()) == 0)))) {
int l1 = strlen(wlst[j].word);
char * newword = cptr->add(wlst[j].word, l1);
if (newword) {
if (nh < maxn) {
wlst[nh].word = newword;
wlst[nh].allow = cptr->allowCross();
wlst[nh].orig = NULL;
nh++;
} else {
free(newword);
}
}
}
cptr = (PfxEntry *)cptr ->getFlgNxt();
}
}
}
// now handle pure prefixes
for (int m = 0; m < al; m ++) {
const unsigned char c = (unsigned char) (ap[m] & 0x00FF);
PfxEntry * ptr = (PfxEntry *) pFlag[c];
while (ptr) {
if ((ptr->getFlag() == ap[m]) && (!ptr->getKeyLen() || ((badl > ptr->getKeyLen()) &&
(strncmp(ptr->getKey(), bad, ptr->getKeyLen()) == 0))) &&
// check needaffix flag
!(ptr->getCont() && ((needaffix &&
TESTAFF(ptr->getCont(), needaffix, ptr->getContLen())) ||
(circumfix &&
TESTAFF(ptr->getCont(), circumfix, ptr->getContLen())) ||
(onlyincompound &&
TESTAFF(ptr->getCont(), onlyincompound, ptr->getContLen()))))
) {
char * newword = ptr->add(ts, wl);
if (newword) {
if (nh < maxn) {
wlst[nh].word = newword;
wlst[nh].allow = ptr->allowCross();
wlst[nh].orig = NULL;
nh++;
} else {
free(newword);
}
}
}
ptr = (PfxEntry *)ptr ->getFlgNxt();
}
}
return nh;
}
// return length of replacing table
int AffixMgr::get_numrep()
{
return numrep;
}
// return replacing table
struct replentry * AffixMgr::get_reptable()
{
if (! reptable ) return NULL;
return reptable;
}
// return replacing table
struct phonetable * AffixMgr::get_phonetable()
{
if (! phone ) return NULL;
return phone;
}
// return length of character map table
int AffixMgr::get_nummap()
{
return nummap;
}
// return character map table
struct mapentry * AffixMgr::get_maptable()
{
if (! maptable ) return NULL;
return maptable;
}
// return length of word break table
int AffixMgr::get_numbreak()
{
return numbreak;
}
// return character map table
char ** AffixMgr::get_breaktable()
{
if (! breaktable ) return NULL;
return breaktable;
}
// return text encoding of dictionary
char * AffixMgr::get_encoding()
{
if (! encoding ) encoding = mystrdup(SPELL_ENCODING);
return mystrdup(encoding);
}
// return text encoding of dictionary
int AffixMgr::get_langnum()
{
return langnum;
}
// return double prefix option
int AffixMgr::get_complexprefixes()
{
return complexprefixes;
}
FLAG AffixMgr::get_keepcase()
{
return keepcase;
}
int AffixMgr::get_checksharps()
{
return checksharps;
}
char * AffixMgr::encode_flag(unsigned short aflag)
{
return pHMgr->encode_flag(aflag);
}
// return the preferred ignore string for suggestions
char * AffixMgr::get_ignore()
{
if (!ignorechars) return NULL;
return ignorechars;
}
// return the preferred ignore string for suggestions
unsigned short * AffixMgr::get_ignore_utf16(int * len)
{
*len = ignorechars_utf16_len;
return ignorechars_utf16;
}
// return the keyboard string for suggestions
char * AffixMgr::get_key_string()
{
if (! keystring ) keystring = mystrdup(SPELL_KEYSTRING);
return mystrdup(keystring);
}
// return the preferred try string for suggestions
char * AffixMgr::get_try_string()
{
if (! trystring ) return NULL;
return mystrdup(trystring);
}
// return the preferred try string for suggestions
const char * AffixMgr::get_wordchars()
{
return wordchars;
}
unsigned short * AffixMgr::get_wordchars_utf16(int * len)
{
*len = wordchars_utf16_len;
return wordchars_utf16;
}
// is there compounding?
int AffixMgr::get_compound()
{
return compoundflag || compoundbegin || numdefcpd;
}
// return the compound words control flag
FLAG AffixMgr::get_compoundflag()
{
return compoundflag;
}
// return the forbidden words control flag
FLAG AffixMgr::get_forbiddenword()
{
return forbiddenword;
}
// return the forbidden words control flag
FLAG AffixMgr::get_nosuggest()
{
return nosuggest;
}
// return the forbidden words flag modify flag
FLAG AffixMgr::get_needaffix()
{
return needaffix;
}
// return the onlyincompound flag
FLAG AffixMgr::get_onlyincompound()
{
return onlyincompound;
}
// return the compound word signal flag
FLAG AffixMgr::get_compoundroot()
{
return compoundroot;
}
// return the compound begin signal flag
FLAG AffixMgr::get_compoundbegin()
{
return compoundbegin;
}
// return the value of checknum
int AffixMgr::get_checknum()
{
return checknum;
}
// return the value of prefix
const char * AffixMgr::get_prefix()
{
if (pfx) return ((PfxEntry *)pfx)->getKey();
return NULL;
}
// return the value of suffix
const char * AffixMgr::get_suffix()
{
return sfxappnd;
}
// return the value of derived form (base word with first suffix).
const char * AffixMgr::get_derived()
{
return derived;
}
// return the value of suffix
const char * AffixMgr::get_version()
{
return version;
}
// return lemma_present flag
FLAG AffixMgr::get_lemma_present()
{
return lemma_present;
}
// utility method to look up root words in hash table
struct hentry * AffixMgr::lookup(const char * word)
{
int i;
struct hentry * he = NULL;
for (i = 0; i < *maxdic && !he; i++) {
he = (alldic[i])->lookup(word);
}
return he;
}
// return the value of suffix
const int AffixMgr::have_contclass()
{
return havecontclass;
}
// return utf8
int AffixMgr::get_utf8()
{
return utf8;
}
// return nosplitsugs
int AffixMgr::get_maxngramsugs(void)
{
return maxngramsugs;
}
// return nosplitsugs
int AffixMgr::get_nosplitsugs(void)
{
return nosplitsugs;
}
// return sugswithdots
int AffixMgr::get_sugswithdots(void)
{
return sugswithdots;
}
/* parse flag */
int AffixMgr::parse_flag(char * line, unsigned short * out, const char * name) {
char * s = NULL;
if (*out != FLAG_NULL && !(*out >= DEFAULTFLAGS)) {
HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", name);
return 1;
}
if (parse_string(line, &s, name)) return 1;
*out = pHMgr->decode_flag(s);
free(s);
return 0;
}
/* parse num */
int AffixMgr::parse_num(char * line, int * out, const char * name) {
char * s = NULL;
if (*out != -1) {
HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", name);
return 1;
}
if (parse_string(line, &s, name)) return 1;
*out = atoi(s);
free(s);
return 0;
}
/* parse in the max syllablecount of compound words and */
int AffixMgr::parse_cpdsyllable(char * line)
{
char * tp = line;
char * piece;
int i = 0;
int np = 0;
w_char w[MAXWORDLEN];
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: { np++; break; }
case 1: { cpdmaxsyllable = atoi(piece); np++; break; }
case 2: {
if (!utf8) {
cpdvowels = mystrdup(piece);
} else {
int n = u8_u16(w, MAXWORDLEN, piece);
if (n > 0) {
flag_qsort((unsigned short *) w, 0, n);
cpdvowels_utf16 = (w_char *) malloc(n * sizeof(w_char));
if (!cpdvowels_utf16) return 1;
memcpy(cpdvowels_utf16, w, n * sizeof(w_char));
}
cpdvowels_utf16_len = n;
}
np++;
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (np < 2) {
HUNSPELL_WARNING(stderr, "error: missing compoundsyllable information\n");
return 1;
}
if (np == 2) cpdvowels = mystrdup("aeiouAEIOU");
return 0;
}
/* parse in the typical fault correcting table */
int AffixMgr::parse_reptable(char * line, FileMgr * af)
{
if (numrep != 0) {
HUNSPELL_WARNING(stderr, "error: duplicate REP tables used\n");
return 1;
}
char * tp = line;
char * piece;
int i = 0;
int np = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: { np++; break; }
case 1: {
numrep = atoi(piece);
if (numrep < 1) {
HUNSPELL_WARNING(stderr, "incorrect number of entries in replacement table\n");
return 1;
}
reptable = (replentry *) malloc(numrep * sizeof(struct replentry));
if (!reptable) return 1;
np++;
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (np != 2) {
HUNSPELL_WARNING(stderr, "error: missing replacement table information\n");
return 1;
}
/* now parse the numrep lines to read in the remainder of the table */
char * nl;
for (int j=0; j < numrep; j++) {
if (!(nl = af->getline())) return 1;
mychomp(nl);
tp = nl;
i = 0;
reptable[j].pattern = NULL;
reptable[j].pattern2 = NULL;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: {
if (strncmp(piece,"REP",3) != 0) {
HUNSPELL_WARNING(stderr, "error: replacement table is corrupt\n");
numrep = 0;
return 1;
}
break;
}
case 1: { reptable[j].pattern = mystrrep(mystrdup(piece),"_"," "); break; }
case 2: { reptable[j].pattern2 = mystrrep(mystrdup(piece),"_"," "); break; }
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if ((!(reptable[j].pattern)) || (!(reptable[j].pattern2))) {
HUNSPELL_WARNING(stderr, "error: replacement table is corrupt\n");
numrep = 0;
return 1;
}
}
return 0;
}
/* parse in the typical fault correcting table */
int AffixMgr::parse_phonetable(char * line, FileMgr * af)
{
if (phone) {
HUNSPELL_WARNING(stderr, "error: duplicate PHONE tables used\n");
return 1;
}
char * tp = line;
char * piece;
int i = 0;
int np = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: { np++; break; }
case 1: {
phone = (phonetable *) malloc(sizeof(struct phonetable));
phone->num = atoi(piece);
phone->rules = NULL;
phone->utf8 = (char) utf8;
if (!phone) return 1;
if (phone->num < 1) {
HUNSPELL_WARNING(stderr, "incorrect number of entries in phonelacement table\n");
return 1;
}
phone->rules = (char * *) malloc(2 * (phone->num + 1) * sizeof(char *));
if (!phone->rules) return 1;
np++;
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (np != 2) {
HUNSPELL_WARNING(stderr, "error: missing PHONE table information\n");
return 1;
}
/* now parse the phone->num lines to read in the remainder of the table */
char * nl;
for (int j=0; j < phone->num; j++) {
if (!(nl = af->getline())) return 1;
mychomp(nl);
tp = nl;
i = 0;
phone->rules[j * 2] = NULL;
phone->rules[j * 2 + 1] = NULL;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: {
if (strncmp(piece,"PHONE",5) != 0) {
HUNSPELL_WARNING(stderr, "error: PHONE table is corrupt\n");
phone->num = 0;
return 1;
}
break;
}
case 1: { phone->rules[j * 2] = mystrrep(mystrdup(piece),"_",""); break; }
case 2: { phone->rules[j * 2 + 1] = mystrrep(mystrdup(piece),"_",""); break; }
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if ((!(phone->rules[j * 2])) || (!(phone->rules[j * 2 + 1]))) {
HUNSPELL_WARNING(stderr, "error: PHONE table is corrupt\n");
phone->num = 0;
return 1;
}
}
phone->rules[phone->num * 2] = mystrdup("");
phone->rules[phone->num * 2 + 1] = mystrdup("");
init_phonet_hash(*phone);
return 0;
}
/* parse in the checkcompoundpattern table */
int AffixMgr::parse_checkcpdtable(char * line, FileMgr * af)
{
if (numcheckcpd != 0) {
HUNSPELL_WARNING(stderr, "error: duplicate compound pattern tables used\n");
return 1;
}
char * tp = line;
char * piece;
int i = 0;
int np = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: { np++; break; }
case 1: {
numcheckcpd = atoi(piece);
if (numcheckcpd < 1) {
HUNSPELL_WARNING(stderr, "incorrect number of entries in compound pattern table\n");
return 1;
}
checkcpdtable = (replentry *) malloc(numcheckcpd * sizeof(struct replentry));
if (!checkcpdtable) return 1;
np++;
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (np != 2) {
HUNSPELL_WARNING(stderr, "error: missing compound pattern table information\n");
return 1;
}
/* now parse the numcheckcpd lines to read in the remainder of the table */
char * nl;
for (int j=0; j < numcheckcpd; j++) {
if (!(nl = af->getline())) return 1;
mychomp(nl);
tp = nl;
i = 0;
checkcpdtable[j].pattern = NULL;
checkcpdtable[j].pattern2 = NULL;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: {
if (strncmp(piece,"CHECKCOMPOUNDPATTERN",20) != 0) {
HUNSPELL_WARNING(stderr, "error: compound pattern table is corrupt\n");
numcheckcpd = 0;
return 1;
}
break;
}
case 1: { checkcpdtable[j].pattern = mystrdup(piece); break; }
case 2: { checkcpdtable[j].pattern2 = mystrdup(piece); break; }
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if ((!(checkcpdtable[j].pattern)) || (!(checkcpdtable[j].pattern2))) {
HUNSPELL_WARNING(stderr, "error: compound pattern table is corrupt\n");
numcheckcpd = 0;
return 1;
}
}
return 0;
}
/* parse in the compound rule table */
int AffixMgr::parse_defcpdtable(char * line, FileMgr * af)
{
if (numdefcpd != 0) {
HUNSPELL_WARNING(stderr, "error: duplicate compound rule tables used\n");
return 1;
}
char * tp = line;
char * piece;
int i = 0;
int np = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: { np++; break; }
case 1: {
numdefcpd = atoi(piece);
if (numdefcpd < 1) {
HUNSPELL_WARNING(stderr, "incorrect number of entries in compound rule table\n");
return 1;
}
defcpdtable = (flagentry *) malloc(numdefcpd * sizeof(flagentry));
if (!defcpdtable) return 1;
np++;
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (np != 2) {
HUNSPELL_WARNING(stderr, "error: missing compound rule table information\n");
return 1;
}
/* now parse the numdefcpd lines to read in the remainder of the table */
char * nl;
for (int j=0; j < numdefcpd; j++) {
if (!(nl = af->getline())) return 1;
mychomp(nl);
tp = nl;
i = 0;
defcpdtable[j].def = NULL;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: {
if (strncmp(piece, "COMPOUNDRULE", 12) != 0) {
HUNSPELL_WARNING(stderr, "error: compound rule table is corrupt\n");
numdefcpd = 0;
return 1;
}
break;
}
case 1: {
defcpdtable[j].len =
pHMgr->decode_flags(&(defcpdtable[j].def), piece);
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (!defcpdtable[j].len) {
HUNSPELL_WARNING(stderr, "error: compound rule table is corrupt\n");
numdefcpd = 0;
return 1;
}
}
return 0;
}
/* parse in the character map table */
int AffixMgr::parse_maptable(char * line, FileMgr * af)
{
if (nummap != 0) {
HUNSPELL_WARNING(stderr, "error: duplicate MAP tables used\n");
return 1;
}
char * tp = line;
char * piece;
int i = 0;
int np = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: { np++; break; }
case 1: {
nummap = atoi(piece);
if (nummap < 1) {
HUNSPELL_WARNING(stderr, "incorrect number of entries in map table\n");
return 1;
}
maptable = (mapentry *) malloc(nummap * sizeof(struct mapentry));
if (!maptable) return 1;
np++;
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (np != 2) {
HUNSPELL_WARNING(stderr, "error: missing map table information\n");
return 1;
}
/* now parse the nummap lines to read in the remainder of the table */
char * nl;
for (int j=0; j < nummap; j++) {
if (!(nl = af->getline())) return 1;
mychomp(nl);
tp = nl;
i = 0;
maptable[j].set = NULL;
maptable[j].len = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: {
if (strncmp(piece,"MAP",3) != 0) {
HUNSPELL_WARNING(stderr, "error: map table is corrupt\n");
nummap = 0;
return 1;
}
break;
}
case 1: {
maptable[j].len = 0;
maptable[j].set = NULL;
maptable[j].set_utf16 = NULL;
if (!utf8) {
maptable[j].set = mystrdup(piece);
maptable[j].len = strlen(maptable[j].set);
} else {
w_char w[MAXWORDLEN];
int n = u8_u16(w, MAXWORDLEN, piece);
if (n > 0) {
flag_qsort((unsigned short *) w, 0, n);
maptable[j].set_utf16 = (w_char *) malloc(n * sizeof(w_char));
if (!maptable[j].set_utf16) return 1;
memcpy(maptable[j].set_utf16, w, n * sizeof(w_char));
}
maptable[j].len = n;
}
break; }
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if ((!(maptable[j].set || maptable[j].set_utf16)) || (!(maptable[j].len))) {
HUNSPELL_WARNING(stderr, "error: map table is corrupt\n");
nummap = 0;
return 1;
}
}
return 0;
}
/* parse in the word breakpoint table */
int AffixMgr::parse_breaktable(char * line, FileMgr * af)
{
if (numbreak != 0) {
HUNSPELL_WARNING(stderr, "error: duplicate word breakpoint tables used\n");
return 1;
}
char * tp = line;
char * piece;
int i = 0;
int np = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: { np++; break; }
case 1: {
numbreak = atoi(piece);
if (numbreak < 1) {
HUNSPELL_WARNING(stderr, "incorrect number of entries in BREAK table\n");
return 1;
}
breaktable = (char **) malloc(numbreak * sizeof(char *));
if (!breaktable) return 1;
np++;
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (np != 2) {
HUNSPELL_WARNING(stderr, "error: missing word breakpoint table information\n");
return 1;
}
/* now parse the numbreak lines to read in the remainder of the table */
char * nl;
for (int j=0; j < numbreak; j++) {
if (!(nl = af->getline())) return 1;
mychomp(nl);
tp = nl;
i = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
case 0: {
if (strncmp(piece,"BREAK",5) != 0) {
HUNSPELL_WARNING(stderr, "error: BREAK table is corrupt\n");
numbreak = 0;
return 1;
}
break;
}
case 1: {
breaktable[j] = mystrdup(piece);
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
if (!breaktable) {
HUNSPELL_WARNING(stderr, "error: BREAK table is corrupt\n");
numbreak = 0;
return 1;
}
}
return 0;
}
void AffixMgr::reverse_condition(char * piece) {
int neg = 0;
for (char * k = piece + strlen(piece) - 1; k >= piece; k--) {
switch(*k) {
case '[': {
if (neg) *(k+1) = '['; else *k = ']';
break;
}
case ']': {
*k = '[';
if (neg) *(k+1) = '^';
neg = 0;
break;
}
case '^': {
if (*(k+1) == ']') neg = 1; else *(k+1) = *k;
break;
}
default: {
if (neg) *(k+1) = *k;
}
}
}
}
int AffixMgr::parse_affix(char * line, const char at, FileMgr * af, char * dupflags)
{
int numents = 0; // number of affentry structures to parse
unsigned short aflag = 0; // affix char identifier
char ff=0;
struct affentry * ptr= NULL;
struct affentry * nptr= NULL;
char * tp = line;
char * nl = line;
char * piece;
int i = 0;
// checking lines with bad syntax
#ifdef DEBUG
int basefieldnum = 0;
#endif
// split affix header line into pieces
int np = 0;
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
// piece 1 - is type of affix
case 0: { np++; break; }
// piece 2 - is affix char
case 1: {
np++;
aflag = pHMgr->decode_flag(piece);
if (((at == 'S') && (dupflags[aflag] & dupSFX)) ||
((at == 'P') && (dupflags[aflag] & dupPFX))) {
HUNSPELL_WARNING(stderr, "error: duplicate affix flag %s in line %s\n", piece, nl);
// return 1; XXX permissive mode for bad dictionaries
}
dupflags[aflag] += (char) ((at == 'S') ? dupSFX : dupPFX);
break;
}
// piece 3 - is cross product indicator
case 2: { np++; if (*piece == 'Y') ff = aeXPRODUCT; break; }
// piece 4 - is number of affentries
case 3: {
np++;
numents = atoi(piece);
if (numents == 0) {
char * err = pHMgr->encode_flag(aflag);
if (err) {
HUNSPELL_WARNING(stderr, "error: affix %s header has incorrect entry count in line %s\n",
err, nl);
free(err);
}
return 1;
}
ptr = (struct affentry *) malloc(numents * sizeof(struct affentry));
if (!ptr) return 1;
ptr->opts = ff;
if (utf8) ptr->opts += aeUTF8;
if (pHMgr->is_aliasf()) ptr->opts += aeALIASF;
if (pHMgr->is_aliasm()) ptr->opts += aeALIASM;
ptr->aflag = aflag;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
// check to make sure we parsed enough pieces
if (np != 4) {
char * err = pHMgr->encode_flag(aflag);
if (err) {
HUNSPELL_WARNING(stderr, "error: affix %s header has insufficient data in line %s\n", err, nl);
free(err);
}
free(ptr);
return 1;
}
// store away ptr to first affentry
nptr = ptr;
// now parse numents affentries for this affix
for (int j=0; j < numents; j++) {
if (!(nl = af->getline())) return 1;
mychomp(nl);
tp = nl;
i = 0;
np = 0;
// split line into pieces
piece = mystrsep(&tp, 0);
while (piece) {
if (*piece != '\0') {
switch(i) {
// piece 1 - is type
case 0: {
np++;
if (nptr != ptr) nptr->opts = ptr->opts &
(char) (aeXPRODUCT + aeUTF8 + aeALIASF + aeALIASM);
break;
}
// piece 2 - is affix char
case 1: {
np++;
if (pHMgr->decode_flag(piece) != aflag) {
char * err = pHMgr->encode_flag(aflag);
if (err) {
HUNSPELL_WARNING(stderr, "error: affix %s is corrupt near line %s\n", err, nl);
HUNSPELL_WARNING(stderr, "error: possible incorrect count\n");
free(err);
}
return 1;
}
if (nptr != ptr) nptr->aflag = ptr->aflag;
break;
}
// piece 3 - is string to strip or 0 for null
case 2: {
np++;
if (complexprefixes) {
if (utf8) reverseword_utf(piece); else reverseword(piece);
}
nptr->strip = mystrdup(piece);
nptr->stripl = (unsigned char) strlen(nptr->strip);
if (strcmp(nptr->strip,"0") == 0) {
free(nptr->strip);
nptr->strip=mystrdup("");
nptr->stripl = 0;
}
break;
}
// piece 4 - is affix string or 0 for null
case 3: {
char * dash;
nptr->morphcode = NULL;
nptr->contclass = NULL;
nptr->contclasslen = 0;
np++;
dash = strchr(piece, '/');
if (dash) {
*dash = '\0';
if (ignorechars) {
if (utf8) {
remove_ignored_chars_utf(piece, ignorechars_utf16, ignorechars_utf16_len);
} else {
remove_ignored_chars(piece,ignorechars);
}
}
if (complexprefixes) {
if (utf8) reverseword_utf(piece); else reverseword(piece);
}
nptr->appnd = mystrdup(piece);
if (pHMgr->is_aliasf()) {
int index = atoi(dash + 1);
nptr->contclasslen = (unsigned short) pHMgr->get_aliasf(index, &(nptr->contclass));
if (!nptr->contclasslen) HUNSPELL_WARNING(stderr, "error: bad affix flag alias: \"%s\"\n", dash+1);
} else {
nptr->contclasslen = (unsigned short) pHMgr->decode_flags(&(nptr->contclass), dash + 1);
flag_qsort(nptr->contclass, 0, nptr->contclasslen);
}
*dash = '/';
havecontclass = 1;
for (unsigned short _i = 0; _i < nptr->contclasslen; _i++) {
contclasses[(nptr->contclass)[_i]] = 1;
}
} else {
if (ignorechars) {
if (utf8) {
remove_ignored_chars_utf(piece, ignorechars_utf16, ignorechars_utf16_len);
} else {
remove_ignored_chars(piece,ignorechars);
}
}
if (complexprefixes) {
if (utf8) reverseword_utf(piece); else reverseword(piece);
}
nptr->appnd = mystrdup(piece);
}
nptr->appndl = (unsigned char) strlen(nptr->appnd);
if (strcmp(nptr->appnd,"0") == 0) {
free(nptr->appnd);
nptr->appnd=mystrdup("");
nptr->appndl = 0;
}
break;
}
// piece 5 - is the conditions descriptions
case 4: {
np++;
if (complexprefixes) {
if (utf8) reverseword_utf(piece); else reverseword(piece);
reverse_condition(piece);
}
if (nptr->stripl && (strcmp(piece, ".") != 0) &&
redundant_condition(at, nptr->strip, nptr->stripl, piece, nl))
strcpy(piece, ".");
if (at == 'S') {
reverseword(piece);
reverse_condition(piece);
}
if (encodeit(nptr, piece)) return 1;
break;
}
case 5: {
np++;
if (pHMgr->is_aliasm()) {
int index = atoi(piece);
nptr->morphcode = pHMgr->get_aliasm(index);
} else {
if (complexprefixes) { // XXX - fix me for morph. gen.
if (utf8) reverseword_utf(piece); else reverseword(piece);
}
// add the remaining of the line
if (*tp) {
*(tp - 1) = ' ';
tp = tp + strlen(tp);
}
nptr->morphcode = mystrdup(piece);
if (!nptr->morphcode) return 1;
}
break;
}
default: break;
}
i++;
}
piece = mystrsep(&tp, 0);
}
// check to make sure we parsed enough pieces
if (np < 4) {
char * err = pHMgr->encode_flag(aflag);
if (err) {
HUNSPELL_WARNING(stderr, "error: affix %s is corrupt near line %s\n", err, nl);
free(err);
}
free(ptr);
return 1;
}
#ifdef DEBUG
// detect unnecessary fields, excepting comments
if (basefieldnum) {
int fieldnum = !(nptr->morphcode) ? 5 : ((*(nptr->morphcode)=='#') ? 5 : 6);
if (fieldnum != basefieldnum)
HUNSPELL_WARNING(stderr, "warning: bad field number:\n%s\n", nl);
} else {
basefieldnum = !(nptr->morphcode) ? 5 : ((*(nptr->morphcode)=='#') ? 5 : 6);
}
#endif
nptr++;
}
// now create SfxEntry or PfxEntry objects and use links to
// build an ordered (sorted by affix string) list
nptr = ptr;
for (int k = 0; k < numents; k++) {
if (at == 'P') {
PfxEntry * pfxptr = new PfxEntry(this,nptr);
build_pfxtree((AffEntry *)pfxptr);
} else {
SfxEntry * sfxptr = new SfxEntry(this,nptr);
build_sfxtree((AffEntry *)sfxptr);
}
nptr++;
}
free(ptr);
return 0;
}
int AffixMgr::redundant_condition(char ft, char * strip, int stripl, const char * cond, char * warnvar) {
int condl = strlen(cond);
int i;
int j;
int neg;
int in;
if (ft == 'P') { // prefix
if (strncmp(strip, cond, condl) == 0) return 1;
if (utf8) {
} else {
for (i = 0, j = 0; (i < stripl) && (j < condl); i++, j++) {
if (cond[j] != '[') {
if (cond[j] != strip[i]) {
HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
}
} else {
neg = (cond[j+1] == '^') ? 1 : 0;
in = 0;
do {
j++;
if (strip[i] == cond[j]) in = 1;
} while ((j < (condl - 1)) && (cond[j] != ']'));
if (j == (condl - 1) && (cond[j] != ']')) {
HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar);
return 0;
}
if ((!neg && !in) || (neg && in)) {
HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
return 0;
}
}
}
if (j >= condl) return 1;
}
} else { // suffix
if ((stripl >= condl) && strcmp(strip + stripl - condl, cond) == 0) return 1;
if (utf8) {
} else {
for (i = stripl - 1, j = condl - 1; (i >= 0) && (j >= 0); i--, j--) {
if (cond[j] != ']') {
if (cond[j] != strip[i]) {
HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
}
} else {
in = 0;
do {
j--;
if (strip[i] == cond[j]) in = 1;
} while ((j > 0) && (cond[j] != '['));
if ((j == 0) && (cond[j] != '[')) {
HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar);
return 0;
}
neg = (cond[j+1] == '^') ? 1 : 0;
if ((!neg && !in) || (neg && in)) {
HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
return 0;
}
}
}
if (j < 0) return 1;
}
}
return 0;
}
robojournal-0.4.2/ui/hunspell/license.hunspell 0000644 0001750 0001750 00000004136 12211723646 020226 0 ustar will will /* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
//#include "config.h"
robojournal-0.4.2/ui/hunspell/suggestmgr.cxx 0000644 0001750 0001750 00000173333 12211723646 017751 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "license.hunspell"
#include "license.myspell"
#ifndef MOZILLA_CLIENT
#include
#include
#include
#include
#else
#include
#include
#include
#include
#endif
#include "ui/hunspell/suggestmgr.hxx"
#include "ui/hunspell/htypes.hxx"
#include "ui/hunspell/csutil.hxx"
#ifndef MOZILLA_CLIENT
#ifndef WIN32
using namespace std;
#endif
#endif
const w_char W_VLINE = { '\0', '|' };
SuggestMgr::SuggestMgr(const char * tryme, int maxn,
AffixMgr * aptr)
{
// register affix manager and check in string of chars to
// try when building candidate suggestions
pAMgr = aptr;
ckeyl = 0;
ckey = NULL;
ckey_utf = NULL;
ctryl = 0;
ctry = NULL;
ctry_utf = NULL;
utf8 = 0;
langnum = 0;
complexprefixes = 0;
maxSug = maxn;
nosplitsugs = 0;
maxngramsugs = MAXNGRAMSUGS;
if (pAMgr) {
char * enc = pAMgr->get_encoding();
csconv = get_current_cs(enc);
free(enc);
langnum = pAMgr->get_langnum();
ckey = pAMgr->get_key_string();
nosplitsugs = pAMgr->get_nosplitsugs();
if (pAMgr->get_maxngramsugs() >= 0) maxngramsugs = pAMgr->get_maxngramsugs();
utf8 = pAMgr->get_utf8();
complexprefixes = pAMgr->get_complexprefixes();
}
if (ckey) {
if (utf8) {
w_char t[MAXSWL];
ckeyl = u8_u16(t, MAXSWL, ckey);
ckey_utf = (w_char *) malloc(ckeyl * sizeof(w_char));
if (ckey_utf) memcpy(ckey_utf, t, ckeyl * sizeof(w_char));
} else {
ckeyl = strlen(ckey);
}
}
if (tryme) {
ctry = mystrdup(tryme);
if (ctry) ctryl = strlen(ctry);
if (ctry && utf8) {
w_char t[MAXSWL];
ctryl = u8_u16(t, MAXSWL, tryme);
ctry_utf = (w_char *) malloc(ctryl * sizeof(w_char));
if (ctry_utf) memcpy(ctry_utf, t, ctryl * sizeof(w_char));
else ctryl = 0;
}
}
}
SuggestMgr::~SuggestMgr()
{
pAMgr = NULL;
if (ckey) free(ckey);
ckey = NULL;
if (ckey_utf) free(ckey_utf);
ckey_utf = NULL;
ckeyl = 0;
if (ctry) free(ctry);
ctry = NULL;
if (ctry_utf) free(ctry_utf);
ctry_utf = NULL;
ctryl = 0;
maxSug = 0;
}
int SuggestMgr::testsug(char** wlst, const char * candidate, int wl, int ns, int cpdsuggest,
int * timer, clock_t * timelimit) {
int cwrd = 1;
if (ns == maxSug) return maxSug;
for (int k=0; k < ns; k++) {
if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
}
if ((cwrd) && checkword(candidate, wl, cpdsuggest, timer, timelimit)) {
wlst[ns] = mystrdup(candidate);
if (wlst[ns] == NULL) {
for (int j=0; j HTML)
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? capchars_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
capchars(wlst, word, nsug, cpdsuggest);
}
// perhaps we made a typical fault of spelling
if ((nsug < maxSug) && (nsug > -1))
nsug = replchars(wlst, word, nsug, cpdsuggest);
// perhaps we made chose the wrong char from a related set
if ((nsug < maxSug) && (nsug > -1)) {
nsug = mapchars(wlst, word, nsug, cpdsuggest);
}
// did we swap the order of chars by mistake
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? swapchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
swapchar(wlst, word, nsug, cpdsuggest);
}
// did we swap the order of non adjacent chars by mistake
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? longswapchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
longswapchar(wlst, word, nsug, cpdsuggest);
}
// did we just hit the wrong key in place of a good char (case and keyboard)
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? badcharkey_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
badcharkey(wlst, word, nsug, cpdsuggest);
}
// did we add a char that should not be there
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? extrachar_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
extrachar(wlst, word, nsug, cpdsuggest);
}
// only suggest compound words when no other suggestion
if ((cpdsuggest == 0) && (nsug > 0)) nocompoundtwowords=1;
// did we forgot a char
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? forgotchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
forgotchar(wlst, word, nsug, cpdsuggest);
}
// did we move a char
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? movechar_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
movechar(wlst, word, nsug, cpdsuggest);
}
// did we just hit the wrong key in place of a good char
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? badchar_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
badchar(wlst, word, nsug, cpdsuggest);
}
// did we double two characters
if ((nsug < maxSug) && (nsug > -1)) {
nsug = (utf8) ? doubletwochars_utf(wlst, word_utf, wl, nsug, cpdsuggest) :
doubletwochars(wlst, word, nsug, cpdsuggest);
}
// perhaps we forgot to hit space and two words ran together
if ((!nosplitsugs) && (nsug < maxSug) && (nsug > -1)) {
nsug = twowords(wlst, word, nsug, cpdsuggest);
}
} // repeating ``for'' statement compounding support
if (nsug < 0) {
// we ran out of memory - we should free up as much as possible
for (int i = 0; i < maxSug; i++)
if (wlst[i] != NULL) free(wlst[i]);
free(wlst);
wlst = NULL;
}
if (!nocompoundtwowords && (nsug > 0) && onlycompoundsug) *onlycompoundsug = 1;
*slst = wlst;
return nsug;
}
// generate suggestions for a word with typical mistake
// pass in address of array of char * pointers
#ifdef HUNSPELL_EXPERIMENTAL
int SuggestMgr::suggest_auto(char*** slst, const char * w, int nsug)
{
int nocompoundtwowords = 0;
char ** wlst;
char w2[MAXWORDUTF8LEN];
const char * word = w;
// word reversing wrapper for complex prefixes
if (complexprefixes) {
strcpy(w2, w);
if (utf8) reverseword_utf(w2); else reverseword(w2);
word = w2;
}
if (*slst) {
wlst = *slst;
} else {
wlst = (char **) malloc(maxSug * sizeof(char *));
if (wlst == NULL) return -1;
}
for (int cpdsuggest=0; (cpdsuggest<2) && (nocompoundtwowords==0); cpdsuggest++) {
// perhaps we made a typical fault of spelling
if ((nsug < maxSug) && (nsug > -1))
nsug = replchars(wlst, word, nsug, cpdsuggest);
// perhaps we made chose the wrong char from a related set
if ((nsug < maxSug) && (nsug > -1))
nsug = mapchars(wlst, word, nsug, cpdsuggest);
if ((cpdsuggest==0) && (nsug>0)) nocompoundtwowords=1;
// perhaps we forgot to hit space and two words ran together
if ((nsug < maxSug) && (nsug > -1) && check_forbidden(word, strlen(word))) {
nsug = twowords(wlst, word, nsug, cpdsuggest);
}
} // repeating ``for'' statement compounding support
if (nsug < 0) {
for (int i=0;i HTML)
int SuggestMgr::capchars_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
w_char candidate_utf[MAXSWL];
memcpy(candidate_utf, word, wl * sizeof(w_char));
mkallcap_utf(candidate_utf, wl, langnum);
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
return testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
}
// suggestions for an uppercase word (html -> HTML)
int SuggestMgr::capchars(char** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
strcpy(candidate, word);
mkallcap(candidate, csconv);
return testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
}
// suggestions for when chose the wrong char out of a related set
int SuggestMgr::mapchars(char** wlst, const char * word, int ns, int cpdsuggest)
{
clock_t timelimit;
int timer;
int wl = strlen(word);
if (wl < 2 || ! pAMgr) return ns;
int nummap = pAMgr->get_nummap();
struct mapentry* maptable = pAMgr->get_maptable();
if (maptable==NULL) return ns;
timelimit = clock();
timer = MINTIMER;
if (utf8) {
w_char w[MAXSWL];
int len = u8_u16(w, MAXSWL, word);
ns = map_related_utf(w, len, 0, cpdsuggest, wlst, ns, maptable, nummap, &timer, &timelimit);
} else ns = map_related(word, 0, wlst, cpdsuggest, ns, maptable, nummap, &timer, &timelimit);
return ns;
}
int SuggestMgr::map_related(const char * word, int i, char** wlst,
int cpdsuggest, int ns,
const mapentry* maptable, int nummap, int * timer, clock_t * timelimit)
{
char c = *(word + i);
if (c == 0) {
int cwrd = 1;
int wl = strlen(word);
for (int m=0; m < ns; m++)
if (strcmp(word,wlst[m]) == 0) cwrd = 0;
if ((cwrd) && checkword(word, wl, cpdsuggest, timer, timelimit)) {
if (ns < maxSug) {
wlst[ns] = mystrdup(word);
if (wlst[ns] == NULL) return -1;
ns++;
}
}
return ns;
}
int in_map = 0;
for (int j = 0; j < nummap; j++) {
if (strchr(maptable[j].set,c) != 0) {
in_map = 1;
char * newword = mystrdup(word);
if (!newword) return -1;
for (int k = 0; k < maptable[j].len; k++) {
*(newword + i) = *(maptable[j].set + k);
ns = map_related(newword, (i+1), wlst, cpdsuggest,
ns, maptable, nummap, timer, timelimit);
if (!(*timer)) return ns;
}
free(newword);
}
}
if (!in_map) {
i++;
ns = map_related(word, i, wlst, cpdsuggest,
ns, maptable, nummap, timer, timelimit);
}
return ns;
}
int SuggestMgr::map_related_utf(w_char * word, int len, int i, int cpdsuggest,
char** wlst, int ns, const mapentry* maptable, int nummap,
int * timer, clock_t * timelimit)
{
if (i == len) {
int cwrd = 1;
int wl;
char s[MAXSWUTF8L];
u16_u8(s, MAXSWUTF8L, word, len);
wl = strlen(s);
for (int m=0; m < ns; m++)
if (strcmp(s,wlst[m]) == 0) cwrd = 0;
if ((cwrd) && checkword(s, wl, cpdsuggest, timer, timelimit)) {
if (ns < maxSug) {
wlst[ns] = mystrdup(s);
if (wlst[ns] == NULL) return -1;
ns++;
}
}
return ns;
}
int in_map = 0;
unsigned short c = *((unsigned short *) word + i);
for (int j = 0; j < nummap; j++) {
if (flag_bsearch((unsigned short *) maptable[j].set_utf16, c, maptable[j].len)) {
in_map = 1;
for (int k = 0; k < maptable[j].len; k++) {
*(word + i) = *(maptable[j].set_utf16 + k);
ns = map_related_utf(word, len, i + 1, cpdsuggest,
wlst, ns, maptable, nummap, timer, timelimit);
if (!(*timer)) return ns;
}
*((unsigned short *) word + i) = c;
}
}
if (!in_map) {
i++;
ns = map_related_utf(word, len, i, cpdsuggest,
wlst, ns, maptable, nummap, timer, timelimit);
}
return ns;
}
// suggestions for a typical fault of spelling, that
// differs with more, than 1 letter from the right form.
int SuggestMgr::replchars(char** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
const char * r;
int lenr, lenp;
int wl = strlen(word);
if (wl < 2 || ! pAMgr) return ns;
int numrep = pAMgr->get_numrep();
struct replentry* reptable = pAMgr->get_reptable();
if (reptable==NULL) return ns;
for (int i=0; i < numrep; i++ ) {
r = word;
lenr = strlen(reptable[i].pattern2);
lenp = strlen(reptable[i].pattern);
// search every occurence of the pattern in the word
while ((r=strstr(r, reptable[i].pattern)) != NULL) {
strcpy(candidate, word);
if (r-word + lenr + strlen(r+lenp) >= MAXSWUTF8L) break;
strcpy(candidate+(r-word),reptable[i].pattern2);
strcpy(candidate+(r-word)+lenr, r+lenp);
ns = testsug(wlst, candidate, wl-lenp+lenr, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
// check REP suggestions with space
char * sp = strchr(candidate, ' ');
if (sp) {
*sp = '\0';
if (checkword(candidate, strlen(candidate), 0, NULL, NULL)) {
int oldns = ns;
*sp = ' ';
ns = testsug(wlst, sp + 1, strlen(sp + 1), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
if (oldns < ns) {
free(wlst[ns - 1]);
wlst[ns - 1] = mystrdup(candidate);
if (!wlst[ns - 1]) return -1;
}
}
*sp = ' ';
}
r++; // search for the next letter
}
}
return ns;
}
// perhaps we doubled two characters (pattern aba -> ababa, for example vacation -> vacacation)
int SuggestMgr::doubletwochars(char** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
int state=0;
int wl = strlen(word);
if (wl < 5 || ! pAMgr) return ns;
for (int i=2; i < wl; i++ ) {
if (word[i]==word[i-2]) {
state++;
if (state==3) {
strcpy(candidate,word);
strcpy(candidate+i-1,word+i+1);
ns = testsug(wlst, candidate, wl-2, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
state=0;
}
} else {
state=0;
}
}
return ns;
}
// perhaps we doubled two characters (pattern aba -> ababa, for example vacation -> vacacation)
int SuggestMgr::doubletwochars_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
w_char candidate_utf[MAXSWL];
char candidate[MAXSWUTF8L];
int state=0;
if (wl < 5 || ! pAMgr) return ns;
for (int i=2; i < wl; i++) {
if (w_char_eq(word[i], word[i-2])) {
state++;
if (state==3) {
memcpy(candidate_utf, word, (i - 1) * sizeof(w_char));
memcpy(candidate_utf+i-1, word+i+1, (wl-i-1) * sizeof(w_char));
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl-2);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
state=0;
}
} else {
state=0;
}
}
return ns;
}
// error is wrong char in place of correct one (case and keyboard related version)
int SuggestMgr::badcharkey(char ** wlst, const char * word, int ns, int cpdsuggest)
{
char tmpc;
char candidate[MAXSWUTF8L];
int wl = strlen(word);
strcpy(candidate, word);
// swap out each char one by one and try uppercase and neighbor
// keyboard chars in its place to see if that makes a good word
for (int i=0; i < wl; i++) {
tmpc = candidate[i];
// check with uppercase letters
candidate[i] = csconv[((unsigned char)tmpc)].cupper;
if (tmpc != candidate[i]) {
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
candidate[i] = tmpc;
}
// check neighbor characters in keyboard string
if (!ckey) continue;
char * loc = strchr(ckey, tmpc);
while (loc) {
if ((loc > ckey) && (*(loc - 1) != '|')) {
candidate[i] = *(loc - 1);
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
if ((*(loc + 1) != '|') && (*(loc + 1) != '\0')) {
candidate[i] = *(loc + 1);
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
loc = strchr(loc + 1, tmpc);
}
candidate[i] = tmpc;
}
return ns;
}
// error is wrong char in place of correct one (case and keyboard related version)
int SuggestMgr::badcharkey_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
w_char tmpc;
w_char candidate_utf[MAXSWL];
char candidate[MAXSWUTF8L];
memcpy(candidate_utf, word, wl * sizeof(w_char));
// swap out each char one by one and try all the tryme
// chars in its place to see if that makes a good word
for (int i=0; i < wl; i++) {
tmpc = candidate_utf[i];
// check with uppercase letters
mkallcap_utf(candidate_utf + i, 1, langnum);
if (!w_char_eq(tmpc, candidate_utf[i])) {
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
candidate_utf[i] = tmpc;
}
// check neighbor characters in keyboard string
if (!ckey) continue;
w_char * loc = ckey_utf;
while ((loc < (ckey_utf + ckeyl)) && !w_char_eq(*loc, tmpc)) loc++;
while (loc < (ckey_utf + ckeyl)) {
if ((loc > ckey_utf) && !w_char_eq(*(loc - 1), W_VLINE)) {
candidate_utf[i] = *(loc - 1);
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
if (((loc + 1) < (ckey_utf + ckeyl)) && !w_char_eq(*(loc + 1), W_VLINE)) {
candidate_utf[i] = *(loc + 1);
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
do { loc++; } while ((loc < (ckey_utf + ckeyl)) && !w_char_eq(*loc, tmpc));
}
candidate_utf[i] = tmpc;
}
return ns;
}
// error is wrong char in place of correct one
int SuggestMgr::badchar(char ** wlst, const char * word, int ns, int cpdsuggest)
{
char tmpc;
char candidate[MAXSWUTF8L];
clock_t timelimit = clock();
int timer = MINTIMER;
int wl = strlen(word);
strcpy(candidate, word);
// swap out each char one by one and try all the tryme
// chars in its place to see if that makes a good word
for (int i=0; i < wl; i++) {
tmpc = candidate[i];
for (int j=0; j < ctryl; j++) {
if (ctry[j] == tmpc) continue;
candidate[i] = ctry[j];
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, &timer, &timelimit);
if (ns == -1) return -1;
if (!timer) return ns;
candidate[i] = tmpc;
}
}
return ns;
}
// error is wrong char in place of correct one
int SuggestMgr::badchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
w_char tmpc;
w_char candidate_utf[MAXSWL];
char candidate[MAXSWUTF8L];
clock_t timelimit = clock();
int timer = MINTIMER;
memcpy(candidate_utf, word, wl * sizeof(w_char));
// swap out each char one by one and try all the tryme
// chars in its place to see if that makes a good word
for (int i=0; i < wl; i++) {
tmpc = candidate_utf[i];
for (int j=0; j < ctryl; j++) {
if (w_char_eq(tmpc, ctry_utf[j])) continue;
candidate_utf[i] = ctry_utf[j];
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, &timer, &timelimit);
if (ns == -1) return -1;
if (!timer) return ns;
candidate_utf[i] = tmpc;
}
}
return ns;
}
// error is word has an extra letter it does not need
int SuggestMgr::extrachar_utf(char** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
w_char candidate_utf[MAXSWL];
const w_char * p;
w_char * r;
if (wl < 2) return ns;
// try omitting one char of word at a time
memcpy(candidate_utf, word + 1, (wl - 1) * sizeof(w_char));
for (p = word, r = candidate_utf; p < word + wl; ) {
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl - 1);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
*r++ = *p++;
}
return ns;
}
// error is word has an extra letter it does not need
int SuggestMgr::extrachar(char** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
const char * p;
char * r;
int wl = strlen(word);
if (wl < 2) return ns;
// try omitting one char of word at a time
strcpy (candidate, word + 1);
for (p = word, r = candidate; *p != 0; ) {
ns = testsug(wlst, candidate, wl-1, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
*r++ = *p++;
}
return ns;
}
// error is missing a letter it needs
int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
const char * p;
char * q;
clock_t timelimit = clock();
int timer = MINTIMER;
int wl = strlen(word);
// try inserting a tryme character before every letter
strcpy(candidate + 1, word);
for (p = word, q = candidate; *p != 0; ) {
for (int i = 0; i < ctryl; i++) {
*q = ctry[i];
ns = testsug(wlst, candidate, wl+1, ns, cpdsuggest, &timer, &timelimit);
if (ns == -1) return -1;
if (!timer) return ns;
}
*q++ = *p++;
}
// now try adding one to end */
for (int i = 0; i < ctryl; i++) {
*q = ctry[i];
ns = testsug(wlst, candidate, wl+1, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
return ns;
}
// error is missing a letter it needs
int SuggestMgr::forgotchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
w_char candidate_utf[MAXSWL];
char candidate[MAXSWUTF8L];
const w_char * p;
w_char * q;
int cwrd;
clock_t timelimit = clock();
int timer = MINTIMER;
// try inserting a tryme character before every letter
memcpy (candidate_utf + 1, word, wl * sizeof(w_char));
for (p = word, q = candidate_utf; p < (word + wl); ) {
for (int i = 0; i < ctryl; i++) {
*q = ctry_utf[i];
cwrd = 1;
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl + 1);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, &timer, &timelimit);
if (ns == -1) return -1;
if (!timer) return ns;
}
*q++ = *p++;
}
// now try adding one to end */
for (int i = 0; i < ctryl; i++) {
*q = ctry_utf[i];
cwrd = 1;
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl + 1);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
return ns;
}
/* error is should have been two words */
int SuggestMgr::twowords(char ** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
char * p;
int c1, c2;
int forbidden = 0;
int cwrd;
int wl=strlen(word);
if (wl < 3) return ns;
if (langnum == LANG_hu) forbidden = check_forbidden(word, wl);
strcpy(candidate + 1, word);
// split the string into two pieces after every char
// if both pieces are good words make them a suggestion
for (p = candidate + 1; p[1] != '\0'; p++) {
p[-1] = *p;
// go to end of the UTF-8 character
while (utf8 && ((p[1] & 0xc0) == 0x80)) {
*p = p[1];
p++;
}
if (utf8 && p[1] == '\0') break; // last UTF-8 character
*p = '\0';
c1 = checkword(candidate,strlen(candidate), cpdsuggest, NULL, NULL);
if (c1) {
c2 = checkword((p+1),strlen(p+1), cpdsuggest, NULL, NULL);
if (c2) {
*p = ' ';
// spec. Hungarian code (need a better compound word support)
if ((langnum == LANG_hu) && !forbidden &&
// if 3 repeating letter, use - instead of space
(((p[-1] == p[1]) && (((p>candidate+1) && (p[-1] == p[-2])) || (p[-1] == p[2]))) ||
// or multiple compounding, with more, than 6 syllables
((c1 == 3) && (c2 >= 2)))) *p = '-';
cwrd = 1;
for (int k=0; k < ns; k++)
if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
if (ns < maxSug) {
if (cwrd) {
wlst[ns] = mystrdup(candidate);
if (wlst[ns] == NULL) return -1;
ns++;
}
} else return ns;
// add two word suggestion with dash, if TRY string contains
// "a" or "-"
// NOTE: cwrd doesn't modified for REP twoword sugg.
if (ctry && (strchr(ctry, 'a') || strchr(ctry, '-')) &&
mystrlen(p + 1) > 1 &&
mystrlen(candidate) - mystrlen(p) > 1) {
*p = '-';
for (int k=0; k < ns; k++)
if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
if (ns < maxSug) {
if (cwrd) {
wlst[ns] = mystrdup(candidate);
if (wlst[ns] == NULL) return -1;
ns++;
}
} else return ns;
}
}
}
}
return ns;
}
// error is adjacent letter were swapped
int SuggestMgr::swapchar(char ** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
char * p;
char tmpc;
int wl=strlen(word);
// try swapping adjacent chars one by one
strcpy(candidate, word);
for (p = candidate; p[1] != 0; p++) {
tmpc = *p;
*p = p[1];
p[1] = tmpc;
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
p[1] = *p;
*p = tmpc;
}
// try double swaps for short words
// ahev -> have, owudl -> would
if (wl == 4 || wl == 5) {
candidate[0] = word[1];
candidate[1] = word[0];
candidate[2] = word[2];
candidate[wl - 2] = word[wl - 1];
candidate[wl - 1] = word[wl - 2];
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
if (wl == 5) {
candidate[0] = word[0];
candidate[1] = word[2];
candidate[2] = word[1];
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
}
return ns;
}
// error is adjacent letter were swapped
int SuggestMgr::swapchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
w_char candidate_utf[MAXSWL];
char candidate[MAXSWUTF8L];
w_char * p;
w_char tmpc;
int len = 0;
// try swapping adjacent chars one by one
memcpy (candidate_utf, word, wl * sizeof(w_char));
for (p = candidate_utf; p < (candidate_utf + wl - 1); p++) {
tmpc = *p;
*p = p[1];
p[1] = tmpc;
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
if (len == 0) len = strlen(candidate);
ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
p[1] = *p;
*p = tmpc;
}
// try double swaps for short words
// ahev -> have, owudl -> would, suodn -> sound
if (wl == 4 || wl == 5) {
candidate_utf[0] = word[1];
candidate_utf[1] = word[0];
candidate_utf[2] = word[2];
candidate_utf[wl - 2] = word[wl - 1];
candidate_utf[wl - 1] = word[wl - 2];
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
if (wl == 5) {
candidate_utf[0] = word[0];
candidate_utf[1] = word[2];
candidate_utf[2] = word[1];
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, len, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
}
return ns;
}
// error is not adjacent letter were swapped
int SuggestMgr::longswapchar(char ** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
char * p;
char * q;
char tmpc;
int wl=strlen(word);
// try swapping not adjacent chars one by one
strcpy(candidate, word);
for (p = candidate; *p != 0; p++) {
for (q = candidate; *q != 0; q++) {
if (abs(p-q) > 1) {
tmpc = *p;
*p = *q;
*q = tmpc;
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
*q = *p;
*p = tmpc;
}
}
}
return ns;
}
// error is adjacent letter were swapped
int SuggestMgr::longswapchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
w_char candidate_utf[MAXSWL];
char candidate[MAXSWUTF8L];
w_char * p;
w_char * q;
w_char tmpc;
// try swapping not adjacent chars
memcpy (candidate_utf, word, wl * sizeof(w_char));
for (p = candidate_utf; p < (candidate_utf + wl); p++) {
for (q = candidate_utf; q < (candidate_utf + wl); q++) {
if (abs(p-q) > 1) {
tmpc = *p;
*p = *q;
*q = tmpc;
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
*q = *p;
*p = tmpc;
}
}
}
return ns;
}
// error is a letter was moved
int SuggestMgr::movechar(char ** wlst, const char * word, int ns, int cpdsuggest)
{
char candidate[MAXSWUTF8L];
char * p;
char * q;
char tmpc;
int wl=strlen(word);
// try moving a char
strcpy(candidate, word);
for (p = candidate; *p != 0; p++) {
for (q = p + 1; (*q != 0) && ((q - p) < 10); q++) {
tmpc = *(q-1);
*(q-1) = *q;
*q = tmpc;
if ((q-p) < 2) continue; // omit swap char
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
strcpy(candidate, word);
}
for (p = candidate + wl - 1; p > candidate; p--) {
for (q = p - 1; (q >= candidate) && ((p - q) < 10); q--) {
tmpc = *(q+1);
*(q+1) = *q;
*q = tmpc;
if ((p-q) < 2) continue; // omit swap char
ns = testsug(wlst, candidate, wl, ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
strcpy(candidate, word);
}
return ns;
}
// error is a letter was moved
int SuggestMgr::movechar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
{
w_char candidate_utf[MAXSWL];
char candidate[MAXSWUTF8L];
w_char * p;
w_char * q;
w_char tmpc;
// try moving a char
memcpy (candidate_utf, word, wl * sizeof(w_char));
for (p = candidate_utf; p < (candidate_utf + wl); p++) {
for (q = p + 1; (q < (candidate_utf + wl)) && ((q - p) < 10); q++) {
tmpc = *(q-1);
*(q-1) = *q;
*q = tmpc;
if ((q-p) < 2) continue; // omit swap char
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
memcpy (candidate_utf, word, wl * sizeof(w_char));
}
for (p = candidate_utf + wl - 1; p > candidate_utf; p--) {
for (q = p - 1; (q >= candidate_utf) && ((p - q) < 10); q--) {
tmpc = *(q+1);
*(q+1) = *q;
*q = tmpc;
if ((p-q) < 2) continue; // omit swap char
u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
if (ns == -1) return -1;
}
memcpy (candidate_utf, word, wl * sizeof(w_char));
}
return ns;
}
// generate a set of suggestions for very poorly spelled words
int SuggestMgr::ngsuggest(char** wlst, char * w, int ns, HashMgr** pHMgr, int md)
{
int i, j;
int lval;
int sc, scphon;
int lp, lpphon;
int nonbmp = 0;
// exhaustively search through all root words
// keeping track of the MAX_ROOTS most similar root words
struct hentry * roots[MAX_ROOTS];
char * rootsphon[MAX_ROOTS];
int scores[MAX_ROOTS];
int scoresphon[MAX_ROOTS];
for (i = 0; i < MAX_ROOTS; i++) {
roots[i] = NULL;
scores[i] = -100 * i;
rootsphon[i] = NULL;
scoresphon[i] = -100 * i;
}
lp = MAX_ROOTS - 1;
lpphon = MAX_ROOTS - 1;
scphon = scoresphon[MAX_ROOTS-1];
char w2[MAXWORDUTF8LEN];
char f[MAXSWUTF8L];
char * word = w;
// word reversing wrapper for complex prefixes
if (complexprefixes) {
strcpy(w2, w);
if (utf8) reverseword_utf(w2); else reverseword(w2);
word = w2;
}
char mw[MAXSWUTF8L];
w_char u8[MAXSWL];
int nc = strlen(word);
int n = (utf8) ? u8_u16(u8, MAXSWL, word) : nc;
// set character based ngram suggestion for words with non-BMP Unicode characters
if (n == -1) {
utf8 = 0;
n = nc;
nonbmp = 1;
}
struct hentry* hp = NULL;
int col = -1;
phonetable * ph = (pAMgr) ? pAMgr->get_phonetable() : NULL;
char target[MAXSWUTF8L];
char candidate[MAXSWUTF8L];
if (ph) {
strcpy(candidate, word);
mkallcap(candidate, csconv);
phonet(candidate, target, n, *ph);
}
for (i = 0; i < md; i++) {
while (0 != (hp = (pHMgr[i])->walk_hashtable(col, hp))) {
if ((hp->astr) && (pAMgr) &&
(TESTAFF(hp->astr, pAMgr->get_forbiddenword(), hp->alen) ||
TESTAFF(hp->astr, ONLYUPCASEFLAG, hp->alen) ||
TESTAFF(hp->astr, pAMgr->get_nosuggest(), hp->alen) ||
TESTAFF(hp->astr, pAMgr->get_onlyincompound(), hp->alen))) continue;
sc = ngram(3, word, HENTRY_WORD(hp), NGRAM_LONGER_WORSE + NGRAM_LOWERING) +
leftcommonsubstring(word, HENTRY_WORD(hp));
// check special pronounciation
if ((hp->var & H_OPT_PHON) && copy_field(f, HENTRY_DATA(hp), MORPH_PHON)) {
int sc2 = ngram(3, word, f, NGRAM_LONGER_WORSE + NGRAM_LOWERING) +
leftcommonsubstring(word, f);
if (sc2 > sc) sc = sc2;
}
if (ph && (sc > 2) && (abs(n - (int) hp->clen) <= 3)) {
char target2[MAXSWUTF8L];
strcpy(candidate, HENTRY_WORD(hp));
mkallcap(candidate, csconv);
phonet(candidate, target2, -1, *ph);
scphon = 2 * ngram(3, target, target2, NGRAM_LONGER_WORSE);
}
if (sc > scores[lp]) {
scores[lp] = sc;
roots[lp] = hp;
lval = sc;
for (j=0; j < MAX_ROOTS; j++)
if (scores[j] < lval) {
lp = j;
lval = scores[j];
}
}
if (scphon > scoresphon[lpphon]) {
scoresphon[lpphon] = scphon;
rootsphon[lpphon] = HENTRY_WORD(hp);
lval = scphon;
for (j=0; j < MAX_ROOTS; j++)
if (scoresphon[j] < lval) {
lpphon = j;
lval = scoresphon[j];
}
}
}}
// find minimum threshhold for a passable suggestion
// mangle original word three differnt ways
// and score them to generate a minimum acceptable score
int thresh = 0;
for (int sp = 1; sp < 4; sp++) {
if (utf8) {
for (int k=sp; k < n; k+=4) *((unsigned short *) u8 + k) = '*';
u16_u8(mw, MAXSWUTF8L, u8, n);
thresh = thresh + ngram(n, word, mw, NGRAM_ANY_MISMATCH + NGRAM_LOWERING);
} else {
strcpy(mw, word);
for (int k=sp; k < n; k+=4) *(mw + k) = '*';
thresh = thresh + ngram(n, word, mw, NGRAM_ANY_MISMATCH + NGRAM_LOWERING);
}
}
thresh = thresh / 3;
thresh--;
// now expand affixes on each of these root words and
// and use length adjusted ngram scores to select
// possible suggestions
char * guess[MAX_GUESS];
char * guessorig[MAX_GUESS];
int gscore[MAX_GUESS];
for(i=0;iexpand_rootword(glst, MAX_WORDS, HENTRY_WORD(rp), rp->blen,
rp->astr, rp->alen, word, nc,
((rp->var & H_OPT_PHON) ? copy_field(f, HENTRY_DATA(rp), MORPH_PHON) : NULL));
for (int k = 0; k < nw ; k++) {
sc = ngram(n, word, glst[k].word, NGRAM_ANY_MISMATCH + NGRAM_LOWERING) +
leftcommonsubstring(word, glst[k].word);
if ((sc > thresh)) {
if (sc > gscore[lp]) {
if (guess[lp]) {
free (guess[lp]);
if (guessorig[lp]) {
free(guessorig[lp]);
guessorig[lp] = NULL;
}
}
gscore[lp] = sc;
guess[lp] = glst[k].word;
guessorig[lp] = glst[k].orig;
lval = sc;
for (j=0; j < MAX_GUESS; j++)
if (gscore[j] < lval) {
lp = j;
lval = gscore[j];
}
} else {
free(glst[k].word);
if (glst[k].orig) free(glst[k].orig);
}
} else {
free(glst[k].word);
if (glst[k].orig) free(glst[k].orig);
}
}
}
}
free(glst);
// now we are done generating guesses
// sort in order of decreasing score
bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS);
if (ph) bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS);
// weight suggestions with a similarity index, based on
// the longest common subsequent algorithm and resort
int is_swap;
for (i=0; i < MAX_GUESS; i++) {
if (guess[i]) {
// lowering guess[i]
char gl[MAXSWUTF8L];
int len;
if (utf8) {
w_char _w[MAXSWL];
len = u8_u16(_w, MAXSWL, guess[i]);
mkallsmall_utf(_w, len, langnum);
u16_u8(gl, MAXSWUTF8L, _w, len);
} else {
strcpy(gl, guess[i]);
mkallsmall(gl, csconv);
len = strlen(guess[i]);
}
int _lcs = lcslen(word, gl);
// same characters with different casing
if ((n == len) && (n == _lcs)) {
gscore[i] += 2000;
break;
}
// heuristic weigthing of ngram scores
gscore[i] +=
// length of longest common subsequent minus length difference
2 * _lcs - abs((int) (n - len)) +
// weight length of the left common substring
leftcommonsubstring(word, gl) +
// weight equal character positions
((_lcs == commoncharacterpositions(word, gl, &is_swap)) ? 1: 0) +
// swap character (not neighboring)
((is_swap) ? 1000 : 0);
}
}
bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS);
// phonetic version
if (ph) for (i=0; i < MAX_ROOTS; i++) {
if (rootsphon[i]) {
// lowering rootphon[i]
char gl[MAXSWUTF8L];
int len;
if (utf8) {
w_char _w[MAXSWL];
len = u8_u16(_w, MAXSWL, rootsphon[i]);
mkallsmall_utf(_w, len, langnum);
u16_u8(gl, MAXSWUTF8L, _w, len);
} else {
strcpy(gl, rootsphon[i]);
mkallsmall(gl, csconv);
len = strlen(rootsphon[i]);
}
// heuristic weigthing of ngram scores
scoresphon[i] += 2 * lcslen(word, gl) - abs((int) (n - len)) +
// weight length of the left common substring
leftcommonsubstring(word, gl);
}
}
if (ph) bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS);
// copy over
int oldns = ns;
int same = 0;
for (i=0; i < MAX_GUESS; i++) {
if (guess[i]) {
if ((ns < oldns + maxngramsugs) && (ns < maxSug) && (!same || (gscore[i] > 1000))) {
int unique = 1;
// leave only excellent suggestions, if exists
if (gscore[i] > 1000) same = 1;
for (j = 0; j < ns; j++) {
// don't suggest previous suggestions or a previous suggestion with prefixes or affixes
if ((!guessorig[i] && strstr(guess[i], wlst[j])) ||
(guessorig[i] && strstr(guessorig[i], wlst[j])) ||
// check forbidden words
!checkword(guess[i], strlen(guess[i]), 0, NULL, NULL)) unique = 0;
}
if (unique) {
wlst[ns++] = guess[i];
if (guessorig[i]) {
free(guess[i]);
wlst[ns-1] = guessorig[i];
}
} else {
free(guess[i]);
if (guessorig[i]) free(guessorig[i]);
}
} else {
free(guess[i]);
if (guessorig[i]) free(guessorig[i]);
}
}
}
oldns = ns;
if (ph) for (i=0; i < MAX_ROOTS; i++) {
if (rootsphon[i]) {
if ((ns < oldns + MAXPHONSUGS) && (ns < maxSug)) {
int unique = 1;
for (j = 0; j < ns; j++) {
// don't suggest previous suggestions or a previous suggestion with prefixes or affixes
if (strstr(rootsphon[i], wlst[j]) ||
// check forbidden words
!checkword(rootsphon[i], strlen(rootsphon[i]), 0, NULL, NULL)) unique = 0;
}
if (unique) {
wlst[ns++] = mystrdup(rootsphon[i]);
if (!wlst[ns - 1]) return ns - 1;
}
}
}
}
if (nonbmp) utf8 = 1;
return ns;
}
// see if a candidate suggestion is spelled correctly
// needs to check both root words and words with affixes
// obsolote MySpell-HU modifications:
// return value 2 and 3 marks compounding with hyphen (-)
// `3' marks roots without suffix
int SuggestMgr::checkword(const char * word, int len, int cpdsuggest, int * timer, clock_t * timelimit)
{
struct hentry * rv=NULL;
int nosuffix = 0;
// check time limit
if (timer) {
(*timer)--;
if (!(*timer) && timelimit) {
if ((clock() - *timelimit) > TIMELIMIT) return 0;
*timer = MAXPLUSTIMER;
}
}
if (pAMgr) {
if (cpdsuggest==1) {
if (pAMgr->get_compound()) {
rv = pAMgr->compound_check(word,len,0,0,0,0,NULL,0,NULL,NULL,1);
if (rv) return 3; // XXX obsolote categorisation
}
return 0;
}
rv = pAMgr->lookup(word);
if (rv) {
if ((rv->astr) && (TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen)
|| TESTAFF(rv->astr,pAMgr->get_nosuggest(),rv->alen))) return 0;
while (rv) {
if (rv->astr && (TESTAFF(rv->astr,pAMgr->get_needaffix(),rv->alen) ||
TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) {
rv = rv->next_homonym;
} else break;
}
} else rv = pAMgr->prefix_check(word, len, 0); // only prefix, and prefix + suffix XXX
if (rv) {
nosuffix=1;
} else {
rv = pAMgr->suffix_check(word, len, 0, NULL, NULL, 0, NULL); // only suffix
}
if (!rv && pAMgr->have_contclass()) {
rv = pAMgr->suffix_check_twosfx(word, len, 0, NULL, FLAG_NULL);
if (!rv) rv = pAMgr->prefix_check_twosfx(word, len, 1, FLAG_NULL);
}
// check forbidden words
if ((rv) && (rv->astr) && (TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen) ||
TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
TESTAFF(rv->astr,pAMgr->get_nosuggest(),rv->alen) ||
TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) return 0;
if (rv) { // XXX obsolote
if ((pAMgr->get_compoundflag()) &&
TESTAFF(rv->astr, pAMgr->get_compoundflag(), rv->alen)) return 2 + nosuffix;
return 1;
}
}
return 0;
}
int SuggestMgr::check_forbidden(const char * word, int len)
{
struct hentry * rv = NULL;
if (pAMgr) {
rv = pAMgr->lookup(word);
if (rv && rv->astr && (TESTAFF(rv->astr,pAMgr->get_needaffix(),rv->alen) ||
TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) rv = NULL;
if (!(pAMgr->prefix_check(word,len,1)))
rv = pAMgr->suffix_check(word,len, 0, NULL, NULL, 0, NULL); // prefix+suffix, suffix
// check forbidden words
if ((rv) && (rv->astr) && TESTAFF(rv->astr,pAMgr->get_forbiddenword(),rv->alen)) return 1;
}
return 0;
}
#ifdef HUNSPELL_EXPERIMENTAL
// suggest possible stems
int SuggestMgr::suggest_pos_stems(char*** slst, const char * w, int nsug)
{
char ** wlst;
struct hentry * rv = NULL;
char w2[MAXSWUTF8L];
const char * word = w;
// word reversing wrapper for complex prefixes
if (complexprefixes) {
strcpy(w2, w);
if (utf8) reverseword_utf(w2); else reverseword(w2);
word = w2;
}
int wl = strlen(word);
if (*slst) {
wlst = *slst;
} else {
wlst = (char **) calloc(maxSug, sizeof(char *));
if (wlst == NULL) return -1;
}
rv = pAMgr->suffix_check(word, wl, 0, NULL, wlst, maxSug, &nsug);
// delete dash from end of word
if (nsug > 0) {
for (int j=0; j < nsug; j++) {
if (wlst[j][strlen(wlst[j]) - 1] == '-') wlst[j][strlen(wlst[j]) - 1] = '\0';
}
}
*slst = wlst;
return nsug;
}
#endif // END OF HUNSPELL_EXPERIMENTAL CODE
char * SuggestMgr::suggest_morph(const char * w)
{
char result[MAXLNLEN];
char * r = (char *) result;
char * st;
struct hentry * rv = NULL;
*result = '\0';
if (! pAMgr) return NULL;
char w2[MAXSWUTF8L];
const char * word = w;
// word reversing wrapper for complex prefixes
if (complexprefixes) {
strcpy(w2, w);
if (utf8) reverseword_utf(w2); else reverseword(w2);
word = w2;
}
rv = pAMgr->lookup(word);
while (rv) {
if ((!rv->astr) || !(TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) ||
TESTAFF(rv->astr, pAMgr->get_needaffix(), rv->alen) ||
TESTAFF(rv->astr,pAMgr->get_onlyincompound(),rv->alen))) {
if (!HENTRY_FIND(rv, MORPH_STEM)) {
strcat(result, " ");
strcat(result, MORPH_STEM);
strcat(result, word);
}
if (HENTRY_DATA(rv)) {
strcat(result, " ");
strcat(result, HENTRY_DATA2(rv));
}
strcat(result, "\n");
}
rv = rv->next_homonym;
}
st = pAMgr->affix_check_morph(word,strlen(word));
if (st) {
strcat(result, st);
free(st);
}
if (pAMgr->get_compound() && (*result == '\0'))
pAMgr->compound_check_morph(word, strlen(word),
0, 0, 100, 0,NULL, 0, &r, NULL);
return (*result) ? mystrdup(line_uniq(result, MSEP_REC)) : NULL;
}
#ifdef HUNSPELL_EXPERIMENTAL
char * SuggestMgr::suggest_morph_for_spelling_error(const char * word)
{
char * p = NULL;
char ** wlst = (char **) calloc(maxSug, sizeof(char *));
if (!**wlst) return NULL;
// we will use only the first suggestion
for (int i = 0; i < maxSug - 1; i++) wlst[i] = "";
int ns = suggest(&wlst, word, maxSug - 1, NULL);
if (ns == maxSug) {
p = suggest_morph(wlst[maxSug - 1]);
free(wlst[maxSug - 1]);
}
if (wlst) free(wlst);
return p;
}
#endif // END OF HUNSPELL_EXPERIMENTAL CODE
/* affixation */
char * SuggestMgr::suggest_hentry_gen(hentry * rv, char * pattern)
{
char result[MAXLNLEN];
*result = '\0';
int sfxcount = get_sfxcount(pattern);
if (get_sfxcount(HENTRY_DATA(rv)) > sfxcount) return NULL;
if (HENTRY_DATA(rv)) {
char * aff = pAMgr->morphgen(HENTRY_WORD(rv), rv->blen, rv->astr, rv->alen,
HENTRY_DATA(rv), pattern, 0);
if (aff) {
strcat(result, aff);
strcat(result, "\n");
free(aff);
}
}
// check all allomorphs
char allomorph[MAXLNLEN];
char * p = NULL;
if (HENTRY_DATA(rv)) p = (char *) strstr(HENTRY_DATA2(rv), MORPH_ALLOMORPH);
while (p) {
struct hentry * rv2 = NULL;
p += MORPH_TAG_LEN;
int plen = fieldlen(p);
strncpy(allomorph, p, plen);
allomorph[plen] = '\0';
rv2 = pAMgr->lookup(allomorph);
while (rv2) {
// if (HENTRY_DATA(rv2) && get_sfxcount(HENTRY_DATA(rv2)) <= sfxcount) {
if (HENTRY_DATA(rv2)) {
char * st = (char *) strstr(HENTRY_DATA2(rv2), MORPH_STEM);
if (st && (strncmp(st + MORPH_TAG_LEN,
HENTRY_WORD(rv), fieldlen(st + MORPH_TAG_LEN)) == 0)) {
char * aff = pAMgr->morphgen(HENTRY_WORD(rv2), rv2->blen, rv2->astr, rv2->alen,
HENTRY_DATA(rv2), pattern, 0);
if (aff) {
strcat(result, aff);
strcat(result, "\n");
free(aff);
}
}
}
rv2 = rv2->next_homonym;
}
p = strstr(p + plen, MORPH_ALLOMORPH);
}
return (*result) ? mystrdup(result) : NULL;
}
char * SuggestMgr::suggest_gen(char ** desc, int n, char * pattern) {
char result[MAXLNLEN];
char result2[MAXLNLEN];
char newpattern[MAXLNLEN];
*newpattern = '\0';
if (n == 0) return 0;
*result2 = '\0';
struct hentry * rv = NULL;
if (!pAMgr) return NULL;
// search affixed forms with and without derivational suffixes
while(1) {
for (int k = 0; k < n; k++) {
*result = '\0';
// add compound word parts (except the last one)
char * s = (char *) desc[k];
char * part = strstr(s, MORPH_PART);
if (part) {
char * nextpart = strstr(part + 1, MORPH_PART);
while (nextpart) {
copy_field(result + strlen(result), part, MORPH_PART);
part = nextpart;
nextpart = strstr(part + 1, MORPH_PART);
}
s = part;
}
char **pl;
char tok[MAXLNLEN];
strcpy(tok, s);
char * alt = strstr(tok, " | ");
while (alt) {
alt[1] = MSEP_ALT;
alt = strstr(alt, " | ");
}
int pln = line_tok(tok, &pl, MSEP_ALT);
for (int i = 0; i < pln; i++) {
// remove inflectional and terminal suffixes
char * is = strstr(pl[i], MORPH_INFL_SFX);
if (is) *is = '\0';
char * ts = strstr(pl[i], MORPH_TERM_SFX);
while (ts) {
*ts = '_';
ts = strstr(pl[i], MORPH_TERM_SFX);
}
char * st = strstr(s, MORPH_STEM);
if (st) {
copy_field(tok, st, MORPH_STEM);
rv = pAMgr->lookup(tok);
while (rv) {
char newpat[MAXLNLEN];
strcpy(newpat, pl[i]);
strcat(newpat, pattern);
char * sg = suggest_hentry_gen(rv, newpat);
if (!sg) sg = suggest_hentry_gen(rv, pattern);
if (sg) {
char ** gen;
int genl = line_tok(sg, &gen, MSEP_REC);
free(sg);
sg = NULL;
for (int j = 0; j < genl; j++) {
if (strstr(pl[i], MORPH_SURF_PFX)) {
int r2l = strlen(result2);
result2[r2l] = MSEP_REC;
strcpy(result2 + r2l + 1, result);
copy_field(result2 + strlen(result2), pl[i], MORPH_SURF_PFX);
strcat(result2, gen[j]);
} else {
sprintf(result2 + strlen(result2), "%c%s%s",
MSEP_REC, result, gen[j]);
}
}
freelist(&gen, genl);
}
rv = rv->next_homonym;
}
}
}
freelist(&pl, pln);
}
if (*result2 || !strstr(pattern, MORPH_DERI_SFX)) break;
strcpy(newpattern, pattern);
pattern = newpattern;
char * ds = strstr(pattern, MORPH_DERI_SFX);
while (ds) {
strncpy(ds, MORPH_TERM_SFX, MORPH_TAG_LEN);
ds = strstr(pattern, MORPH_DERI_SFX);
}
}
return (*result2 ? mystrdup(result2) : NULL);
}
// generate an n-gram score comparing s1 and s2
int SuggestMgr::ngram(int n, char * s1, const char * s2, int opt)
{
int nscore = 0;
int ns;
int l1;
int l2;
if (utf8) {
w_char su1[MAXSWL];
w_char su2[MAXSWL];
l1 = u8_u16(su1, MAXSWL, s1);
l2 = u8_u16(su2, MAXSWL, s2);
if ((l2 <= 0) || (l1 == -1)) return 0;
// lowering dictionary word
if (opt & NGRAM_LOWERING) mkallsmall_utf(su2, l2, langnum);
for (int j = 1; j <= n; j++) {
ns = 0;
for (int i = 0; i <= (l1-j); i++) {
for (int l = 0; l <= (l2-j); l++) {
int k;
for (k = 0; (k < j); k++) {
w_char * c1 = su1 + i + k;
w_char * c2 = su2 + l + k;
if ((c1->l != c2->l) || (c1->h != c2->h)) break;
}
if (k == j) {
ns++;
break;
}
}
}
nscore = nscore + ns;
if (ns < 2) break;
}
} else {
char t[MAXSWUTF8L];
l1 = strlen(s1);
l2 = strlen(s2);
if (l2 == 0) return 0;
strcpy(t, s2);
if (opt & NGRAM_LOWERING) mkallsmall(t, csconv);
for (int j = 1; j <= n; j++) {
ns = 0;
for (int i = 0; i <= (l1-j); i++) {
char c = *(s1 + i + j);
*(s1 + i + j) = '\0';
if (strstr(t,(s1+i))) ns++;
*(s1 + i + j ) = c;
}
nscore = nscore + ns;
if (ns < 2) break;
}
}
ns = 0;
if (opt & NGRAM_LONGER_WORSE) ns = (l2-l1)-2;
if (opt & NGRAM_ANY_MISMATCH) ns = abs(l2-l1)-2;
ns = (nscore - ((ns > 0) ? ns : 0));
return ns;
}
// length of the left common substring of s1 and (decapitalised) s2
int SuggestMgr::leftcommonsubstring(char * s1, const char * s2) {
if (utf8) {
w_char su1[MAXSWL];
w_char su2[MAXSWL];
// decapitalize dictionary word
if (complexprefixes) {
int l1 = u8_u16(su1, MAXSWL, s1);
int l2 = u8_u16(su2, MAXSWL, s2);
if (*((short *)su1+l1-1) == *((short *)su2+l2-1)) return 1;
} else {
int i;
u8_u16(su1, 1, s1);
u8_u16(su2, 1, s2);
unsigned short idx = (su2->h << 8) + su2->l;
if (*((short *)su1) != *((short *)su2) &&
(*((unsigned short *)su1) != unicodetolower(idx, langnum))) return 0;
int l1 = u8_u16(su1, MAXSWL, s1);
int l2 = u8_u16(su2, MAXSWL, s2);
for(i = 1; (i < l1) && (i < l2) &&
(*((short *)(su1 + i)) == *((short *)(su2 + i))); i++);
return i;
}
} else {
if (complexprefixes) {
int l1 = strlen(s1);
int l2 = strlen(s2);
if (*(s2+l1-1) == *(s2+l2-1)) return 1;
} else {
char * olds = s1;
// decapitalise dictionary word
if ((*s1 != *s2) && (*s1 != csconv[((unsigned char)*s2)].clower)) return 0;
do {
s1++; s2++;
} while ((*s1 == *s2) && (*s1 != '\0'));
return s1 - olds;
}
}
return 0;
}
int SuggestMgr::commoncharacterpositions(char * s1, const char * s2, int * is_swap) {
int num = 0;
int diff = 0;
int diffpos[2];
*is_swap = 0;
if (utf8) {
w_char su1[MAXSWL];
w_char su2[MAXSWL];
int l1 = u8_u16(su1, MAXSWL, s1);
int l2 = u8_u16(su2, MAXSWL, s2);
// decapitalize dictionary word
if (complexprefixes) {
mkallsmall_utf(su2+l2-1, 1, langnum);
} else {
mkallsmall_utf(su2, 1, langnum);
}
for (int i = 0; (i < l1) && (i < l2); i++) {
if (((short *) su1)[i] == ((short *) su2)[i]) {
num++;
} else {
if (diff < 2) diffpos[diff] = i;
diff++;
}
}
if ((diff == 2) && (l1 == l2) &&
(((short *) su1)[diffpos[0]] == ((short *) su2)[diffpos[1]]) &&
(((short *) su1)[diffpos[1]] == ((short *) su2)[diffpos[0]])) *is_swap = 1;
} else {
int i;
char t[MAXSWUTF8L];
strcpy(t, s2);
// decapitalize dictionary word
if (complexprefixes) {
int l2 = strlen(t);
*(t+l2-1) = csconv[((unsigned char)*(t+l2-1))].clower;
} else {
mkallsmall(t, csconv);
}
for (i = 0; (*(s1+i) != 0) && (*(t+i) != 0); i++) {
if (*(s1+i) == *(t+i)) {
num++;
} else {
if (diff < 2) diffpos[diff] = i;
diff++;
}
}
if ((diff == 2) && (*(s1+i) == 0) && (*(t+i) == 0) &&
(*(s1+diffpos[0]) == *(t+diffpos[1])) &&
(*(s1+diffpos[1]) == *(t+diffpos[0]))) *is_swap = 1;
}
return num;
}
int SuggestMgr::mystrlen(const char * word) {
if (utf8) {
w_char w[MAXSWL];
return u8_u16(w, MAXSWL, word);
} else return strlen(word);
}
// sort in decreasing order of score
void SuggestMgr::bubblesort(char** rword, char** rword2, int* rsc, int n )
{
int m = 1;
while (m < n) {
int j = m;
while (j > 0) {
if (rsc[j-1] < rsc[j]) {
int sctmp = rsc[j-1];
char * wdtmp = rword[j-1];
rsc[j-1] = rsc[j];
rword[j-1] = rword[j];
rsc[j] = sctmp;
rword[j] = wdtmp;
if (rword2) {
wdtmp = rword2[j-1];
rword2[j-1] = rword2[j];
rword2[j] = wdtmp;
}
j--;
} else break;
}
m++;
}
return;
}
// longest common subsequence
void SuggestMgr::lcs(const char * s, const char * s2, int * l1, int * l2, char ** result) {
int n, m;
w_char su[MAXSWL];
w_char su2[MAXSWL];
char * b;
char * c;
int i;
int j;
if (utf8) {
m = u8_u16(su, MAXSWL, s);
n = u8_u16(su2, MAXSWL, s2);
} else {
m = strlen(s);
n = strlen(s2);
}
c = (char *) malloc((m + 1) * (n + 1));
b = (char *) malloc((m + 1) * (n + 1));
if (!c || !b) {
if (c) free(c);
if (b) free(b);
*result = NULL;
return;
}
for (i = 1; i <= m; i++) c[i*(n+1)] = 0;
for (j = 0; j <= n; j++) c[j] = 0;
for (i = 1; i <= m; i++) {
for (j = 1; j <= n; j++) {
if ((utf8) && (*((short *) su+i-1) == *((short *)su2+j-1))
|| (!utf8) && ((*(s+i-1)) == (*(s2+j-1)))) {
c[i*(n+1) + j] = c[(i-1)*(n+1) + j-1]+1;
b[i*(n+1) + j] = LCS_UPLEFT;
} else if (c[(i-1)*(n+1) + j] >= c[i*(n+1) + j-1]) {
c[i*(n+1) + j] = c[(i-1)*(n+1) + j];
b[i*(n+1) + j] = LCS_UP;
} else {
c[i*(n+1) + j] = c[i*(n+1) + j-1];
b[i*(n+1) + j] = LCS_LEFT;
}
}
}
*result = b;
free(c);
*l1 = m;
*l2 = n;
}
int SuggestMgr::lcslen(const char * s, const char* s2) {
int m;
int n;
int i;
int j;
char * result;
int len = 0;
lcs(s, s2, &m, &n, &result);
if (!result) return 0;
i = m;
j = n;
while ((i != 0) && (j != 0)) {
if (result[i*(n+1) + j] == LCS_UPLEFT) {
len++;
i--;
j--;
} else if (result[i*(n+1) + j] == LCS_UP) {
i--;
} else j--;
}
free(result);
return len;
}
robojournal-0.4.2/ui/hunspell/langnum.hxx 0000644 0001750 0001750 00000006531 12211723646 017223 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _LANGNUM_HXX_
#define _LANGNUM_HXX_
/*
language numbers for language specific codes
see http://l10n.openoffice.org/languages.html
*/
enum {
LANG_ar=96,
LANG_az=100, // custom number
LANG_bg=41,
LANG_ca=37,
LANG_cs=42,
LANG_da=45,
LANG_de=49,
LANG_el=30,
LANG_en=01,
LANG_es=34,
LANG_eu=10,
LANG_fr=02,
LANG_gl=38,
LANG_hr=78,
LANG_hu=36,
LANG_it=39,
LANG_la=99, // custom number
LANG_lv=101, // custom number
LANG_nl=31,
LANG_pl=48,
LANG_pt=03,
LANG_ru=07,
LANG_sv=50,
LANG_tr=90,
LANG_uk=80,
LANG_xx=999
};
#endif
robojournal-0.4.2/ui/hunspell/dictmgr.hxx 0000644 0001750 0001750 00000006621 12211723646 017213 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _DICTMGR_HXX_
#define _DICTMGR_HXX_
#define MAXDICTIONARIES 100
#define MAXDICTENTRYLEN 1024
struct dictentry {
char * filename;
char * lang;
char * region;
};
class DictMgr
{
int numdict;
dictentry * pdentry;
public:
DictMgr(const char * dictpath, const char * etype);
~DictMgr();
int get_list(dictentry** ppentry);
private:
int parse_file(const char * dictpath, const char * etype);
char * mystrsep(char ** stringp, const char delim);
char * mystrdup(const char * s);
void mychomp(char * s);
};
#endif
robojournal-0.4.2/ui/hunspell/hunzip.hxx 0000644 0001750 0001750 00000007525 12211723646 017103 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* hunzip: file decompression for sorted dictionaries with optional encryption,
* algorithm: prefix-suffix encoding and 16-bit Huffman encoding */
#ifndef _HUNZIP_HXX_
#define _HUNZIP_HXX_
#define BUFSIZE 65536
#define HZIP_EXTENSION ".hz"
#define MSG_OPEN "error: %s: cannot open\n"
#define MSG_FORMAT "error: %s: not in hzip format\n"
#define MSG_MEMORY "error: %s: missing memory\n"
#define MSG_KEY "error: %s: missing or bad password\n"
struct bit {
unsigned char c[2];
int v[2];
};
class Hunzip
{
protected:
char * filename;
FILE * fin;
int bufsiz, lastbit, inc, inbits, outc;
struct bit * dec; // code table
char in[BUFSIZE]; // input buffer
char out[BUFSIZE + 1]; // Huffman-decoded buffer
char line[BUFSIZE + 50]; // decoded line
int getcode(const char * key);
int getbuf();
int fail(const char * err, const char * par);
public:
Hunzip(const char * filename, const char * key = NULL);
~Hunzip();
const char * getline();
};
#endif
robojournal-0.4.2/ui/hunspell/affentry.hxx 0000644 0001750 0001750 00000016210 12211723646 017373 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _AFFIX_HXX_
#define _AFFIX_HXX_
#include "atypes.hxx"
#include "baseaffix.hxx"
#include "affixmgr.hxx"
/* A Prefix Entry */
class PfxEntry : public AffEntry
{
AffixMgr* pmyMgr;
PfxEntry * next;
PfxEntry * nexteq;
PfxEntry * nextne;
PfxEntry * flgnxt;
public:
PfxEntry(AffixMgr* pmgr, affentry* dp );
~PfxEntry();
inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); }
struct hentry * checkword(const char * word, int len, char in_compound,
const FLAG needflag = FLAG_NULL);
struct hentry * check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = NULL);
char * check_morph(const char * word, int len, char in_compound,
const FLAG needflag = FLAG_NULL);
char * check_twosfx_morph(const char * word, int len,
char in_compound, const FLAG needflag = FLAG_NULL);
inline FLAG getFlag() { return aflag; }
inline const char * getKey() { return appnd; }
char * add(const char * word, int len);
inline short getKeyLen() { return appndl; }
inline const char * getMorph() { return morphcode; }
inline const unsigned short * getCont() { return contclass; }
inline short getContLen() { return contclasslen; }
inline PfxEntry * getNext() { return next; }
inline PfxEntry * getNextNE() { return nextne; }
inline PfxEntry * getNextEQ() { return nexteq; }
inline PfxEntry * getFlgNxt() { return flgnxt; }
inline void setNext(PfxEntry * ptr) { next = ptr; }
inline void setNextNE(PfxEntry * ptr) { nextne = ptr; }
inline void setNextEQ(PfxEntry * ptr) { nexteq = ptr; }
inline void setFlgNxt(PfxEntry * ptr) { flgnxt = ptr; }
inline char * nextchar(char * p);
inline int test_condition(const char * st);
};
/* A Suffix Entry */
class SfxEntry : public AffEntry
{
AffixMgr* pmyMgr;
char * rappnd;
SfxEntry * next;
SfxEntry * nexteq;
SfxEntry * nextne;
SfxEntry * flgnxt;
SfxEntry * l_morph;
SfxEntry * r_morph;
SfxEntry * eq_morph;
public:
SfxEntry(AffixMgr* pmgr, affentry* dp );
~SfxEntry();
inline bool allowCross() { return ((opts & aeXPRODUCT) != 0); }
struct hentry * checkword(const char * word, int len, int optflags,
AffEntry* ppfx, char ** wlst, int maxSug, int * ns,
// const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound=IN_CPD_NOT);
const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, const FLAG badflag = 0);
struct hentry * check_twosfx(const char * word, int len, int optflags, AffEntry* ppfx, const FLAG needflag = NULL);
char * check_twosfx_morph(const char * word, int len, int optflags,
AffEntry* ppfx, const FLAG needflag = FLAG_NULL);
struct hentry * get_next_homonym(struct hentry * he);
struct hentry * get_next_homonym(struct hentry * word, int optflags, AffEntry* ppfx,
const FLAG cclass, const FLAG needflag);
inline FLAG getFlag() { return aflag; }
inline const char * getKey() { return rappnd; }
char * add(const char * word, int len);
inline const char * getMorph() { return morphcode; }
inline const unsigned short * getCont() { return contclass; }
inline short getContLen() { return contclasslen; }
inline const char * getAffix() { return appnd; }
inline short getKeyLen() { return appndl; }
inline SfxEntry * getNext() { return next; }
inline SfxEntry * getNextNE() { return nextne; }
inline SfxEntry * getNextEQ() { return nexteq; }
inline SfxEntry * getLM() { return l_morph; }
inline SfxEntry * getRM() { return r_morph; }
inline SfxEntry * getEQM() { return eq_morph; }
inline SfxEntry * getFlgNxt() { return flgnxt; }
inline void setNext(SfxEntry * ptr) { next = ptr; }
inline void setNextNE(SfxEntry * ptr) { nextne = ptr; }
inline void setNextEQ(SfxEntry * ptr) { nexteq = ptr; }
inline void setFlgNxt(SfxEntry * ptr) { flgnxt = ptr; }
inline char * nextchar(char * p);
inline int test_condition(const char * st, const char * begin);
};
#endif
robojournal-0.4.2/ui/hunspell/baseaffix.hxx 0000644 0001750 0001750 00000006540 12211723646 017512 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _BASEAFF_HXX_
#define _BASEAFF_HXX_
class AffEntry
{
public:
protected:
char * appnd;
char * strip;
unsigned char appndl;
unsigned char stripl;
char numconds;
char opts;
unsigned short aflag;
union {
char conds[MAXCONDLEN];
struct {
char conds1[MAXCONDLEN_1];
char * conds2;
} l;
} c;
char * morphcode;
unsigned short * contclass;
short contclasslen;
};
#endif
robojournal-0.4.2/ui/hunspell/utf_info.cxx 0000644 0001750 0001750 00000726655 12211723646 017406 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ui/hunspell/csutil.hxx"
/* fields: Unicode letter, toupper, tolower */
static struct unicode_info utf_lst[] = {
{ 0x0041, 0x0041, 0x0061 },
{ 0x0042, 0x0042, 0x0062 },
{ 0x0043, 0x0043, 0x0063 },
{ 0x0044, 0x0044, 0x0064 },
{ 0x0045, 0x0045, 0x0065 },
{ 0x0046, 0x0046, 0x0066 },
{ 0x0047, 0x0047, 0x0067 },
{ 0x0048, 0x0048, 0x0068 },
{ 0x0049, 0x0049, 0x0069 },
{ 0x004A, 0x004A, 0x006A },
{ 0x004B, 0x004B, 0x006B },
{ 0x004C, 0x004C, 0x006C },
{ 0x004D, 0x004D, 0x006D },
{ 0x004E, 0x004E, 0x006E },
{ 0x004F, 0x004F, 0x006F },
{ 0x0050, 0x0050, 0x0070 },
{ 0x0051, 0x0051, 0x0071 },
{ 0x0052, 0x0052, 0x0072 },
{ 0x0053, 0x0053, 0x0073 },
{ 0x0054, 0x0054, 0x0074 },
{ 0x0055, 0x0055, 0x0075 },
{ 0x0056, 0x0056, 0x0076 },
{ 0x0057, 0x0057, 0x0077 },
{ 0x0058, 0x0058, 0x0078 },
{ 0x0059, 0x0059, 0x0079 },
{ 0x005A, 0x005A, 0x007A },
{ 0x0061, 0x0041, 0x0061 },
{ 0x0062, 0x0042, 0x0062 },
{ 0x0063, 0x0043, 0x0063 },
{ 0x0064, 0x0044, 0x0064 },
{ 0x0065, 0x0045, 0x0065 },
{ 0x0066, 0x0046, 0x0066 },
{ 0x0067, 0x0047, 0x0067 },
{ 0x0068, 0x0048, 0x0068 },
{ 0x0069, 0x0049, 0x0069 },
{ 0x006A, 0x004A, 0x006A },
{ 0x006B, 0x004B, 0x006B },
{ 0x006C, 0x004C, 0x006C },
{ 0x006D, 0x004D, 0x006D },
{ 0x006E, 0x004E, 0x006E },
{ 0x006F, 0x004F, 0x006F },
{ 0x0070, 0x0050, 0x0070 },
{ 0x0071, 0x0051, 0x0071 },
{ 0x0072, 0x0052, 0x0072 },
{ 0x0073, 0x0053, 0x0073 },
{ 0x0074, 0x0054, 0x0074 },
{ 0x0075, 0x0055, 0x0075 },
{ 0x0076, 0x0056, 0x0076 },
{ 0x0077, 0x0057, 0x0077 },
{ 0x0078, 0x0058, 0x0078 },
{ 0x0079, 0x0059, 0x0079 },
{ 0x007A, 0x005A, 0x007A },
{ 0x00AA, 0x00AA, 0x00AA },
{ 0x00B5, 0x039C, 0x00B5 },
{ 0x00BA, 0x00BA, 0x00BA },
{ 0x00C0, 0x00C0, 0x00E0 },
{ 0x00C1, 0x00C1, 0x00E1 },
{ 0x00C2, 0x00C2, 0x00E2 },
{ 0x00C3, 0x00C3, 0x00E3 },
{ 0x00C4, 0x00C4, 0x00E4 },
{ 0x00C5, 0x00C5, 0x00E5 },
{ 0x00C6, 0x00C6, 0x00E6 },
{ 0x00C7, 0x00C7, 0x00E7 },
{ 0x00C8, 0x00C8, 0x00E8 },
{ 0x00C9, 0x00C9, 0x00E9 },
{ 0x00CA, 0x00CA, 0x00EA },
{ 0x00CB, 0x00CB, 0x00EB },
{ 0x00CC, 0x00CC, 0x00EC },
{ 0x00CD, 0x00CD, 0x00ED },
{ 0x00CE, 0x00CE, 0x00EE },
{ 0x00CF, 0x00CF, 0x00EF },
{ 0x00D0, 0x00D0, 0x00F0 },
{ 0x00D1, 0x00D1, 0x00F1 },
{ 0x00D2, 0x00D2, 0x00F2 },
{ 0x00D3, 0x00D3, 0x00F3 },
{ 0x00D4, 0x00D4, 0x00F4 },
{ 0x00D5, 0x00D5, 0x00F5 },
{ 0x00D6, 0x00D6, 0x00F6 },
{ 0x00D8, 0x00D8, 0x00F8 },
{ 0x00D9, 0x00D9, 0x00F9 },
{ 0x00DA, 0x00DA, 0x00FA },
{ 0x00DB, 0x00DB, 0x00FB },
{ 0x00DC, 0x00DC, 0x00FC },
{ 0x00DD, 0x00DD, 0x00FD },
{ 0x00DE, 0x00DE, 0x00FE },
{ 0x00DF, 0x00DF, 0x00DF },
{ 0x00E0, 0x00C0, 0x00E0 },
{ 0x00E1, 0x00C1, 0x00E1 },
{ 0x00E2, 0x00C2, 0x00E2 },
{ 0x00E3, 0x00C3, 0x00E3 },
{ 0x00E4, 0x00C4, 0x00E4 },
{ 0x00E5, 0x00C5, 0x00E5 },
{ 0x00E6, 0x00C6, 0x00E6 },
{ 0x00E7, 0x00C7, 0x00E7 },
{ 0x00E8, 0x00C8, 0x00E8 },
{ 0x00E9, 0x00C9, 0x00E9 },
{ 0x00EA, 0x00CA, 0x00EA },
{ 0x00EB, 0x00CB, 0x00EB },
{ 0x00EC, 0x00CC, 0x00EC },
{ 0x00ED, 0x00CD, 0x00ED },
{ 0x00EE, 0x00CE, 0x00EE },
{ 0x00EF, 0x00CF, 0x00EF },
{ 0x00F0, 0x00D0, 0x00F0 },
{ 0x00F1, 0x00D1, 0x00F1 },
{ 0x00F2, 0x00D2, 0x00F2 },
{ 0x00F3, 0x00D3, 0x00F3 },
{ 0x00F4, 0x00D4, 0x00F4 },
{ 0x00F5, 0x00D5, 0x00F5 },
{ 0x00F6, 0x00D6, 0x00F6 },
{ 0x00F8, 0x00D8, 0x00F8 },
{ 0x00F9, 0x00D9, 0x00F9 },
{ 0x00FA, 0x00DA, 0x00FA },
{ 0x00FB, 0x00DB, 0x00FB },
{ 0x00FC, 0x00DC, 0x00FC },
{ 0x00FD, 0x00DD, 0x00FD },
{ 0x00FE, 0x00DE, 0x00FE },
{ 0x00FF, 0x0178, 0x00FF },
{ 0x0100, 0x0100, 0x0101 },
{ 0x0101, 0x0100, 0x0101 },
{ 0x0102, 0x0102, 0x0103 },
{ 0x0103, 0x0102, 0x0103 },
{ 0x0104, 0x0104, 0x0105 },
{ 0x0105, 0x0104, 0x0105 },
{ 0x0106, 0x0106, 0x0107 },
{ 0x0107, 0x0106, 0x0107 },
{ 0x0108, 0x0108, 0x0109 },
{ 0x0109, 0x0108, 0x0109 },
{ 0x010A, 0x010A, 0x010B },
{ 0x010B, 0x010A, 0x010B },
{ 0x010C, 0x010C, 0x010D },
{ 0x010D, 0x010C, 0x010D },
{ 0x010E, 0x010E, 0x010F },
{ 0x010F, 0x010E, 0x010F },
{ 0x0110, 0x0110, 0x0111 },
{ 0x0111, 0x0110, 0x0111 },
{ 0x0112, 0x0112, 0x0113 },
{ 0x0113, 0x0112, 0x0113 },
{ 0x0114, 0x0114, 0x0115 },
{ 0x0115, 0x0114, 0x0115 },
{ 0x0116, 0x0116, 0x0117 },
{ 0x0117, 0x0116, 0x0117 },
{ 0x0118, 0x0118, 0x0119 },
{ 0x0119, 0x0118, 0x0119 },
{ 0x011A, 0x011A, 0x011B },
{ 0x011B, 0x011A, 0x011B },
{ 0x011C, 0x011C, 0x011D },
{ 0x011D, 0x011C, 0x011D },
{ 0x011E, 0x011E, 0x011F },
{ 0x011F, 0x011E, 0x011F },
{ 0x0120, 0x0120, 0x0121 },
{ 0x0121, 0x0120, 0x0121 },
{ 0x0122, 0x0122, 0x0123 },
{ 0x0123, 0x0122, 0x0123 },
{ 0x0124, 0x0124, 0x0125 },
{ 0x0125, 0x0124, 0x0125 },
{ 0x0126, 0x0126, 0x0127 },
{ 0x0127, 0x0126, 0x0127 },
{ 0x0128, 0x0128, 0x0129 },
{ 0x0129, 0x0128, 0x0129 },
{ 0x012A, 0x012A, 0x012B },
{ 0x012B, 0x012A, 0x012B },
{ 0x012C, 0x012C, 0x012D },
{ 0x012D, 0x012C, 0x012D },
{ 0x012E, 0x012E, 0x012F },
{ 0x012F, 0x012E, 0x012F },
{ 0x0130, 0x0130, 0x0069 },
{ 0x0131, 0x0049, 0x0131 },
{ 0x0132, 0x0132, 0x0133 },
{ 0x0133, 0x0132, 0x0133 },
{ 0x0134, 0x0134, 0x0135 },
{ 0x0135, 0x0134, 0x0135 },
{ 0x0136, 0x0136, 0x0137 },
{ 0x0137, 0x0136, 0x0137 },
{ 0x0138, 0x0138, 0x0138 },
{ 0x0139, 0x0139, 0x013A },
{ 0x013A, 0x0139, 0x013A },
{ 0x013B, 0x013B, 0x013C },
{ 0x013C, 0x013B, 0x013C },
{ 0x013D, 0x013D, 0x013E },
{ 0x013E, 0x013D, 0x013E },
{ 0x013F, 0x013F, 0x0140 },
{ 0x0140, 0x013F, 0x0140 },
{ 0x0141, 0x0141, 0x0142 },
{ 0x0142, 0x0141, 0x0142 },
{ 0x0143, 0x0143, 0x0144 },
{ 0x0144, 0x0143, 0x0144 },
{ 0x0145, 0x0145, 0x0146 },
{ 0x0146, 0x0145, 0x0146 },
{ 0x0147, 0x0147, 0x0148 },
{ 0x0148, 0x0147, 0x0148 },
{ 0x0149, 0x0149, 0x0149 },
{ 0x014A, 0x014A, 0x014B },
{ 0x014B, 0x014A, 0x014B },
{ 0x014C, 0x014C, 0x014D },
{ 0x014D, 0x014C, 0x014D },
{ 0x014E, 0x014E, 0x014F },
{ 0x014F, 0x014E, 0x014F },
{ 0x0150, 0x0150, 0x0151 },
{ 0x0151, 0x0150, 0x0151 },
{ 0x0152, 0x0152, 0x0153 },
{ 0x0153, 0x0152, 0x0153 },
{ 0x0154, 0x0154, 0x0155 },
{ 0x0155, 0x0154, 0x0155 },
{ 0x0156, 0x0156, 0x0157 },
{ 0x0157, 0x0156, 0x0157 },
{ 0x0158, 0x0158, 0x0159 },
{ 0x0159, 0x0158, 0x0159 },
{ 0x015A, 0x015A, 0x015B },
{ 0x015B, 0x015A, 0x015B },
{ 0x015C, 0x015C, 0x015D },
{ 0x015D, 0x015C, 0x015D },
{ 0x015E, 0x015E, 0x015F },
{ 0x015F, 0x015E, 0x015F },
{ 0x0160, 0x0160, 0x0161 },
{ 0x0161, 0x0160, 0x0161 },
{ 0x0162, 0x0162, 0x0163 },
{ 0x0163, 0x0162, 0x0163 },
{ 0x0164, 0x0164, 0x0165 },
{ 0x0165, 0x0164, 0x0165 },
{ 0x0166, 0x0166, 0x0167 },
{ 0x0167, 0x0166, 0x0167 },
{ 0x0168, 0x0168, 0x0169 },
{ 0x0169, 0x0168, 0x0169 },
{ 0x016A, 0x016A, 0x016B },
{ 0x016B, 0x016A, 0x016B },
{ 0x016C, 0x016C, 0x016D },
{ 0x016D, 0x016C, 0x016D },
{ 0x016E, 0x016E, 0x016F },
{ 0x016F, 0x016E, 0x016F },
{ 0x0170, 0x0170, 0x0171 },
{ 0x0171, 0x0170, 0x0171 },
{ 0x0172, 0x0172, 0x0173 },
{ 0x0173, 0x0172, 0x0173 },
{ 0x0174, 0x0174, 0x0175 },
{ 0x0175, 0x0174, 0x0175 },
{ 0x0176, 0x0176, 0x0177 },
{ 0x0177, 0x0176, 0x0177 },
{ 0x0178, 0x0178, 0x00FF },
{ 0x0179, 0x0179, 0x017A },
{ 0x017A, 0x0179, 0x017A },
{ 0x017B, 0x017B, 0x017C },
{ 0x017C, 0x017B, 0x017C },
{ 0x017D, 0x017D, 0x017E },
{ 0x017E, 0x017D, 0x017E },
{ 0x017F, 0x0053, 0x017F },
{ 0x0180, 0x0180, 0x0180 },
{ 0x0181, 0x0181, 0x0253 },
{ 0x0182, 0x0182, 0x0183 },
{ 0x0183, 0x0182, 0x0183 },
{ 0x0184, 0x0184, 0x0185 },
{ 0x0185, 0x0184, 0x0185 },
{ 0x0186, 0x0186, 0x0254 },
{ 0x0187, 0x0187, 0x0188 },
{ 0x0188, 0x0187, 0x0188 },
{ 0x0189, 0x0189, 0x0256 },
{ 0x018A, 0x018A, 0x0257 },
{ 0x018B, 0x018B, 0x018C },
{ 0x018C, 0x018B, 0x018C },
{ 0x018D, 0x018D, 0x018D },
{ 0x018E, 0x018E, 0x01DD },
{ 0x018F, 0x018F, 0x0259 },
{ 0x0190, 0x0190, 0x025B },
{ 0x0191, 0x0191, 0x0192 },
{ 0x0192, 0x0191, 0x0192 },
{ 0x0193, 0x0193, 0x0260 },
{ 0x0194, 0x0194, 0x0263 },
{ 0x0195, 0x01F6, 0x0195 },
{ 0x0196, 0x0196, 0x0269 },
{ 0x0197, 0x0197, 0x0268 },
{ 0x0198, 0x0198, 0x0199 },
{ 0x0199, 0x0198, 0x0199 },
{ 0x019A, 0x023D, 0x019A },
{ 0x019B, 0x019B, 0x019B },
{ 0x019C, 0x019C, 0x026F },
{ 0x019D, 0x019D, 0x0272 },
{ 0x019E, 0x0220, 0x019E },
{ 0x019F, 0x019F, 0x0275 },
{ 0x01A0, 0x01A0, 0x01A1 },
{ 0x01A1, 0x01A0, 0x01A1 },
{ 0x01A2, 0x01A2, 0x01A3 },
{ 0x01A3, 0x01A2, 0x01A3 },
{ 0x01A4, 0x01A4, 0x01A5 },
{ 0x01A5, 0x01A4, 0x01A5 },
{ 0x01A6, 0x01A6, 0x0280 },
{ 0x01A7, 0x01A7, 0x01A8 },
{ 0x01A8, 0x01A7, 0x01A8 },
{ 0x01A9, 0x01A9, 0x0283 },
{ 0x01AA, 0x01AA, 0x01AA },
{ 0x01AB, 0x01AB, 0x01AB },
{ 0x01AC, 0x01AC, 0x01AD },
{ 0x01AD, 0x01AC, 0x01AD },
{ 0x01AE, 0x01AE, 0x0288 },
{ 0x01AF, 0x01AF, 0x01B0 },
{ 0x01B0, 0x01AF, 0x01B0 },
{ 0x01B1, 0x01B1, 0x028A },
{ 0x01B2, 0x01B2, 0x028B },
{ 0x01B3, 0x01B3, 0x01B4 },
{ 0x01B4, 0x01B3, 0x01B4 },
{ 0x01B5, 0x01B5, 0x01B6 },
{ 0x01B6, 0x01B5, 0x01B6 },
{ 0x01B7, 0x01B7, 0x0292 },
{ 0x01B8, 0x01B8, 0x01B9 },
{ 0x01B9, 0x01B8, 0x01B9 },
{ 0x01BA, 0x01BA, 0x01BA },
{ 0x01BB, 0x01BB, 0x01BB },
{ 0x01BC, 0x01BC, 0x01BD },
{ 0x01BD, 0x01BC, 0x01BD },
{ 0x01BE, 0x01BE, 0x01BE },
{ 0x01BF, 0x01F7, 0x01BF },
{ 0x01C0, 0x01C0, 0x01C0 },
{ 0x01C1, 0x01C1, 0x01C1 },
{ 0x01C2, 0x01C2, 0x01C2 },
{ 0x01C3, 0x01C3, 0x01C3 },
{ 0x01C4, 0x01C4, 0x01C6 },
{ 0x01C5, 0x01C4, 0x01C6 },
{ 0x01C6, 0x01C4, 0x01C6 },
{ 0x01C7, 0x01C7, 0x01C9 },
{ 0x01C8, 0x01C7, 0x01C9 },
{ 0x01C9, 0x01C7, 0x01C9 },
{ 0x01CA, 0x01CA, 0x01CC },
{ 0x01CB, 0x01CA, 0x01CC },
{ 0x01CC, 0x01CA, 0x01CC },
{ 0x01CD, 0x01CD, 0x01CE },
{ 0x01CE, 0x01CD, 0x01CE },
{ 0x01CF, 0x01CF, 0x01D0 },
{ 0x01D0, 0x01CF, 0x01D0 },
{ 0x01D1, 0x01D1, 0x01D2 },
{ 0x01D2, 0x01D1, 0x01D2 },
{ 0x01D3, 0x01D3, 0x01D4 },
{ 0x01D4, 0x01D3, 0x01D4 },
{ 0x01D5, 0x01D5, 0x01D6 },
{ 0x01D6, 0x01D5, 0x01D6 },
{ 0x01D7, 0x01D7, 0x01D8 },
{ 0x01D8, 0x01D7, 0x01D8 },
{ 0x01D9, 0x01D9, 0x01DA },
{ 0x01DA, 0x01D9, 0x01DA },
{ 0x01DB, 0x01DB, 0x01DC },
{ 0x01DC, 0x01DB, 0x01DC },
{ 0x01DD, 0x018E, 0x01DD },
{ 0x01DE, 0x01DE, 0x01DF },
{ 0x01DF, 0x01DE, 0x01DF },
{ 0x01E0, 0x01E0, 0x01E1 },
{ 0x01E1, 0x01E0, 0x01E1 },
{ 0x01E2, 0x01E2, 0x01E3 },
{ 0x01E3, 0x01E2, 0x01E3 },
{ 0x01E4, 0x01E4, 0x01E5 },
{ 0x01E5, 0x01E4, 0x01E5 },
{ 0x01E6, 0x01E6, 0x01E7 },
{ 0x01E7, 0x01E6, 0x01E7 },
{ 0x01E8, 0x01E8, 0x01E9 },
{ 0x01E9, 0x01E8, 0x01E9 },
{ 0x01EA, 0x01EA, 0x01EB },
{ 0x01EB, 0x01EA, 0x01EB },
{ 0x01EC, 0x01EC, 0x01ED },
{ 0x01ED, 0x01EC, 0x01ED },
{ 0x01EE, 0x01EE, 0x01EF },
{ 0x01EF, 0x01EE, 0x01EF },
{ 0x01F0, 0x01F0, 0x01F0 },
{ 0x01F1, 0x01F1, 0x01F3 },
{ 0x01F2, 0x01F1, 0x01F3 },
{ 0x01F3, 0x01F1, 0x01F3 },
{ 0x01F4, 0x01F4, 0x01F5 },
{ 0x01F5, 0x01F4, 0x01F5 },
{ 0x01F6, 0x01F6, 0x0195 },
{ 0x01F7, 0x01F7, 0x01BF },
{ 0x01F8, 0x01F8, 0x01F9 },
{ 0x01F9, 0x01F8, 0x01F9 },
{ 0x01FA, 0x01FA, 0x01FB },
{ 0x01FB, 0x01FA, 0x01FB },
{ 0x01FC, 0x01FC, 0x01FD },
{ 0x01FD, 0x01FC, 0x01FD },
{ 0x01FE, 0x01FE, 0x01FF },
{ 0x01FF, 0x01FE, 0x01FF },
{ 0x0200, 0x0200, 0x0201 },
{ 0x0201, 0x0200, 0x0201 },
{ 0x0202, 0x0202, 0x0203 },
{ 0x0203, 0x0202, 0x0203 },
{ 0x0204, 0x0204, 0x0205 },
{ 0x0205, 0x0204, 0x0205 },
{ 0x0206, 0x0206, 0x0207 },
{ 0x0207, 0x0206, 0x0207 },
{ 0x0208, 0x0208, 0x0209 },
{ 0x0209, 0x0208, 0x0209 },
{ 0x020A, 0x020A, 0x020B },
{ 0x020B, 0x020A, 0x020B },
{ 0x020C, 0x020C, 0x020D },
{ 0x020D, 0x020C, 0x020D },
{ 0x020E, 0x020E, 0x020F },
{ 0x020F, 0x020E, 0x020F },
{ 0x0210, 0x0210, 0x0211 },
{ 0x0211, 0x0210, 0x0211 },
{ 0x0212, 0x0212, 0x0213 },
{ 0x0213, 0x0212, 0x0213 },
{ 0x0214, 0x0214, 0x0215 },
{ 0x0215, 0x0214, 0x0215 },
{ 0x0216, 0x0216, 0x0217 },
{ 0x0217, 0x0216, 0x0217 },
{ 0x0218, 0x0218, 0x0219 },
{ 0x0219, 0x0218, 0x0219 },
{ 0x021A, 0x021A, 0x021B },
{ 0x021B, 0x021A, 0x021B },
{ 0x021C, 0x021C, 0x021D },
{ 0x021D, 0x021C, 0x021D },
{ 0x021E, 0x021E, 0x021F },
{ 0x021F, 0x021E, 0x021F },
{ 0x0220, 0x0220, 0x019E },
{ 0x0221, 0x0221, 0x0221 },
{ 0x0222, 0x0222, 0x0223 },
{ 0x0223, 0x0222, 0x0223 },
{ 0x0224, 0x0224, 0x0225 },
{ 0x0225, 0x0224, 0x0225 },
{ 0x0226, 0x0226, 0x0227 },
{ 0x0227, 0x0226, 0x0227 },
{ 0x0228, 0x0228, 0x0229 },
{ 0x0229, 0x0228, 0x0229 },
{ 0x022A, 0x022A, 0x022B },
{ 0x022B, 0x022A, 0x022B },
{ 0x022C, 0x022C, 0x022D },
{ 0x022D, 0x022C, 0x022D },
{ 0x022E, 0x022E, 0x022F },
{ 0x022F, 0x022E, 0x022F },
{ 0x0230, 0x0230, 0x0231 },
{ 0x0231, 0x0230, 0x0231 },
{ 0x0232, 0x0232, 0x0233 },
{ 0x0233, 0x0232, 0x0233 },
{ 0x0234, 0x0234, 0x0234 },
{ 0x0235, 0x0235, 0x0235 },
{ 0x0236, 0x0236, 0x0236 },
{ 0x0237, 0x0237, 0x0237 },
{ 0x0238, 0x0238, 0x0238 },
{ 0x0239, 0x0239, 0x0239 },
{ 0x023A, 0x023A, 0x023A },
{ 0x023B, 0x023B, 0x023C },
{ 0x023C, 0x023B, 0x023C },
{ 0x023D, 0x023D, 0x019A },
{ 0x023E, 0x023E, 0x023E },
{ 0x023F, 0x023F, 0x023F },
{ 0x0240, 0x0240, 0x0240 },
{ 0x0241, 0x0241, 0x0294 },
{ 0x0250, 0x0250, 0x0250 },
{ 0x0251, 0x0251, 0x0251 },
{ 0x0252, 0x0252, 0x0252 },
{ 0x0253, 0x0181, 0x0253 },
{ 0x0254, 0x0186, 0x0254 },
{ 0x0255, 0x0255, 0x0255 },
{ 0x0256, 0x0189, 0x0256 },
{ 0x0257, 0x018A, 0x0257 },
{ 0x0258, 0x0258, 0x0258 },
{ 0x0259, 0x018F, 0x0259 },
{ 0x025A, 0x025A, 0x025A },
{ 0x025B, 0x0190, 0x025B },
{ 0x025C, 0x025C, 0x025C },
{ 0x025D, 0x025D, 0x025D },
{ 0x025E, 0x025E, 0x025E },
{ 0x025F, 0x025F, 0x025F },
{ 0x0260, 0x0193, 0x0260 },
{ 0x0261, 0x0261, 0x0261 },
{ 0x0262, 0x0262, 0x0262 },
{ 0x0263, 0x0194, 0x0263 },
{ 0x0264, 0x0264, 0x0264 },
{ 0x0265, 0x0265, 0x0265 },
{ 0x0266, 0x0266, 0x0266 },
{ 0x0267, 0x0267, 0x0267 },
{ 0x0268, 0x0197, 0x0268 },
{ 0x0269, 0x0196, 0x0269 },
{ 0x026A, 0x026A, 0x026A },
{ 0x026B, 0x026B, 0x026B },
{ 0x026C, 0x026C, 0x026C },
{ 0x026D, 0x026D, 0x026D },
{ 0x026E, 0x026E, 0x026E },
{ 0x026F, 0x019C, 0x026F },
{ 0x0270, 0x0270, 0x0270 },
{ 0x0271, 0x0271, 0x0271 },
{ 0x0272, 0x019D, 0x0272 },
{ 0x0273, 0x0273, 0x0273 },
{ 0x0274, 0x0274, 0x0274 },
{ 0x0275, 0x019F, 0x0275 },
{ 0x0276, 0x0276, 0x0276 },
{ 0x0277, 0x0277, 0x0277 },
{ 0x0278, 0x0278, 0x0278 },
{ 0x0279, 0x0279, 0x0279 },
{ 0x027A, 0x027A, 0x027A },
{ 0x027B, 0x027B, 0x027B },
{ 0x027C, 0x027C, 0x027C },
{ 0x027D, 0x027D, 0x027D },
{ 0x027E, 0x027E, 0x027E },
{ 0x027F, 0x027F, 0x027F },
{ 0x0280, 0x01A6, 0x0280 },
{ 0x0281, 0x0281, 0x0281 },
{ 0x0282, 0x0282, 0x0282 },
{ 0x0283, 0x01A9, 0x0283 },
{ 0x0284, 0x0284, 0x0284 },
{ 0x0285, 0x0285, 0x0285 },
{ 0x0286, 0x0286, 0x0286 },
{ 0x0287, 0x0287, 0x0287 },
{ 0x0288, 0x01AE, 0x0288 },
{ 0x0289, 0x0289, 0x0289 },
{ 0x028A, 0x01B1, 0x028A },
{ 0x028B, 0x01B2, 0x028B },
{ 0x028C, 0x028C, 0x028C },
{ 0x028D, 0x028D, 0x028D },
{ 0x028E, 0x028E, 0x028E },
{ 0x028F, 0x028F, 0x028F },
{ 0x0290, 0x0290, 0x0290 },
{ 0x0291, 0x0291, 0x0291 },
{ 0x0292, 0x01B7, 0x0292 },
{ 0x0293, 0x0293, 0x0293 },
{ 0x0294, 0x0241, 0x0294 },
{ 0x0295, 0x0295, 0x0295 },
{ 0x0296, 0x0296, 0x0296 },
{ 0x0297, 0x0297, 0x0297 },
{ 0x0298, 0x0298, 0x0298 },
{ 0x0299, 0x0299, 0x0299 },
{ 0x029A, 0x029A, 0x029A },
{ 0x029B, 0x029B, 0x029B },
{ 0x029C, 0x029C, 0x029C },
{ 0x029D, 0x029D, 0x029D },
{ 0x029E, 0x029E, 0x029E },
{ 0x029F, 0x029F, 0x029F },
{ 0x02A0, 0x02A0, 0x02A0 },
{ 0x02A1, 0x02A1, 0x02A1 },
{ 0x02A2, 0x02A2, 0x02A2 },
{ 0x02A3, 0x02A3, 0x02A3 },
{ 0x02A4, 0x02A4, 0x02A4 },
{ 0x02A5, 0x02A5, 0x02A5 },
{ 0x02A6, 0x02A6, 0x02A6 },
{ 0x02A7, 0x02A7, 0x02A7 },
{ 0x02A8, 0x02A8, 0x02A8 },
{ 0x02A9, 0x02A9, 0x02A9 },
{ 0x02AA, 0x02AA, 0x02AA },
{ 0x02AB, 0x02AB, 0x02AB },
{ 0x02AC, 0x02AC, 0x02AC },
{ 0x02AD, 0x02AD, 0x02AD },
{ 0x02AE, 0x02AE, 0x02AE },
{ 0x02AF, 0x02AF, 0x02AF },
{ 0x02B0, 0x02B0, 0x02B0 },
{ 0x02B1, 0x02B1, 0x02B1 },
{ 0x02B2, 0x02B2, 0x02B2 },
{ 0x02B3, 0x02B3, 0x02B3 },
{ 0x02B4, 0x02B4, 0x02B4 },
{ 0x02B5, 0x02B5, 0x02B5 },
{ 0x02B6, 0x02B6, 0x02B6 },
{ 0x02B7, 0x02B7, 0x02B7 },
{ 0x02B8, 0x02B8, 0x02B8 },
{ 0x02B9, 0x02B9, 0x02B9 },
{ 0x02BA, 0x02BA, 0x02BA },
{ 0x02BB, 0x02BB, 0x02BB },
{ 0x02BC, 0x02BC, 0x02BC },
{ 0x02BD, 0x02BD, 0x02BD },
{ 0x02BE, 0x02BE, 0x02BE },
{ 0x02BF, 0x02BF, 0x02BF },
{ 0x02C0, 0x02C0, 0x02C0 },
{ 0x02C1, 0x02C1, 0x02C1 },
{ 0x02C6, 0x02C6, 0x02C6 },
{ 0x02C7, 0x02C7, 0x02C7 },
{ 0x02C8, 0x02C8, 0x02C8 },
{ 0x02C9, 0x02C9, 0x02C9 },
{ 0x02CA, 0x02CA, 0x02CA },
{ 0x02CB, 0x02CB, 0x02CB },
{ 0x02CC, 0x02CC, 0x02CC },
{ 0x02CD, 0x02CD, 0x02CD },
{ 0x02CE, 0x02CE, 0x02CE },
{ 0x02CF, 0x02CF, 0x02CF },
{ 0x02D0, 0x02D0, 0x02D0 },
{ 0x02D1, 0x02D1, 0x02D1 },
{ 0x02E0, 0x02E0, 0x02E0 },
{ 0x02E1, 0x02E1, 0x02E1 },
{ 0x02E2, 0x02E2, 0x02E2 },
{ 0x02E3, 0x02E3, 0x02E3 },
{ 0x02E4, 0x02E4, 0x02E4 },
{ 0x02EE, 0x02EE, 0x02EE },
{ 0x0300, 0x0300, 0x0300 },
{ 0x0301, 0x0301, 0x0301 },
{ 0x0302, 0x0302, 0x0302 },
{ 0x0303, 0x0303, 0x0303 },
{ 0x0304, 0x0304, 0x0304 },
{ 0x0305, 0x0305, 0x0305 },
{ 0x0306, 0x0306, 0x0306 },
{ 0x0307, 0x0307, 0x0307 },
{ 0x0308, 0x0308, 0x0308 },
{ 0x0309, 0x0309, 0x0309 },
{ 0x030A, 0x030A, 0x030A },
{ 0x030B, 0x030B, 0x030B },
{ 0x030C, 0x030C, 0x030C },
{ 0x030D, 0x030D, 0x030D },
{ 0x030E, 0x030E, 0x030E },
{ 0x030F, 0x030F, 0x030F },
{ 0x0310, 0x0310, 0x0310 },
{ 0x0311, 0x0311, 0x0311 },
{ 0x0312, 0x0312, 0x0312 },
{ 0x0313, 0x0313, 0x0313 },
{ 0x0314, 0x0314, 0x0314 },
{ 0x0315, 0x0315, 0x0315 },
{ 0x0316, 0x0316, 0x0316 },
{ 0x0317, 0x0317, 0x0317 },
{ 0x0318, 0x0318, 0x0318 },
{ 0x0319, 0x0319, 0x0319 },
{ 0x031A, 0x031A, 0x031A },
{ 0x031B, 0x031B, 0x031B },
{ 0x031C, 0x031C, 0x031C },
{ 0x031D, 0x031D, 0x031D },
{ 0x031E, 0x031E, 0x031E },
{ 0x031F, 0x031F, 0x031F },
{ 0x0320, 0x0320, 0x0320 },
{ 0x0321, 0x0321, 0x0321 },
{ 0x0322, 0x0322, 0x0322 },
{ 0x0323, 0x0323, 0x0323 },
{ 0x0324, 0x0324, 0x0324 },
{ 0x0325, 0x0325, 0x0325 },
{ 0x0326, 0x0326, 0x0326 },
{ 0x0327, 0x0327, 0x0327 },
{ 0x0328, 0x0328, 0x0328 },
{ 0x0329, 0x0329, 0x0329 },
{ 0x032A, 0x032A, 0x032A },
{ 0x032B, 0x032B, 0x032B },
{ 0x032C, 0x032C, 0x032C },
{ 0x032D, 0x032D, 0x032D },
{ 0x032E, 0x032E, 0x032E },
{ 0x032F, 0x032F, 0x032F },
{ 0x0330, 0x0330, 0x0330 },
{ 0x0331, 0x0331, 0x0331 },
{ 0x0332, 0x0332, 0x0332 },
{ 0x0333, 0x0333, 0x0333 },
{ 0x0334, 0x0334, 0x0334 },
{ 0x0335, 0x0335, 0x0335 },
{ 0x0336, 0x0336, 0x0336 },
{ 0x0337, 0x0337, 0x0337 },
{ 0x0338, 0x0338, 0x0338 },
{ 0x0339, 0x0339, 0x0339 },
{ 0x033A, 0x033A, 0x033A },
{ 0x033B, 0x033B, 0x033B },
{ 0x033C, 0x033C, 0x033C },
{ 0x033D, 0x033D, 0x033D },
{ 0x033E, 0x033E, 0x033E },
{ 0x033F, 0x033F, 0x033F },
{ 0x0340, 0x0340, 0x0340 },
{ 0x0341, 0x0341, 0x0341 },
{ 0x0342, 0x0342, 0x0342 },
{ 0x0343, 0x0343, 0x0343 },
{ 0x0344, 0x0344, 0x0344 },
{ 0x0345, 0x0399, 0x0345 },
{ 0x0346, 0x0346, 0x0346 },
{ 0x0347, 0x0347, 0x0347 },
{ 0x0348, 0x0348, 0x0348 },
{ 0x0349, 0x0349, 0x0349 },
{ 0x034A, 0x034A, 0x034A },
{ 0x034B, 0x034B, 0x034B },
{ 0x034C, 0x034C, 0x034C },
{ 0x034D, 0x034D, 0x034D },
{ 0x034E, 0x034E, 0x034E },
{ 0x034F, 0x034F, 0x034F },
{ 0x0350, 0x0350, 0x0350 },
{ 0x0351, 0x0351, 0x0351 },
{ 0x0352, 0x0352, 0x0352 },
{ 0x0353, 0x0353, 0x0353 },
{ 0x0354, 0x0354, 0x0354 },
{ 0x0355, 0x0355, 0x0355 },
{ 0x0356, 0x0356, 0x0356 },
{ 0x0357, 0x0357, 0x0357 },
{ 0x0358, 0x0358, 0x0358 },
{ 0x0359, 0x0359, 0x0359 },
{ 0x035A, 0x035A, 0x035A },
{ 0x035B, 0x035B, 0x035B },
{ 0x035C, 0x035C, 0x035C },
{ 0x035D, 0x035D, 0x035D },
{ 0x035E, 0x035E, 0x035E },
{ 0x035F, 0x035F, 0x035F },
{ 0x0360, 0x0360, 0x0360 },
{ 0x0361, 0x0361, 0x0361 },
{ 0x0362, 0x0362, 0x0362 },
{ 0x0363, 0x0363, 0x0363 },
{ 0x0364, 0x0364, 0x0364 },
{ 0x0365, 0x0365, 0x0365 },
{ 0x0366, 0x0366, 0x0366 },
{ 0x0367, 0x0367, 0x0367 },
{ 0x0368, 0x0368, 0x0368 },
{ 0x0369, 0x0369, 0x0369 },
{ 0x036A, 0x036A, 0x036A },
{ 0x036B, 0x036B, 0x036B },
{ 0x036C, 0x036C, 0x036C },
{ 0x036D, 0x036D, 0x036D },
{ 0x036E, 0x036E, 0x036E },
{ 0x036F, 0x036F, 0x036F },
{ 0x037A, 0x037A, 0x037A },
{ 0x0386, 0x0386, 0x03AC },
{ 0x0388, 0x0388, 0x03AD },
{ 0x0389, 0x0389, 0x03AE },
{ 0x038A, 0x038A, 0x03AF },
{ 0x038C, 0x038C, 0x03CC },
{ 0x038E, 0x038E, 0x03CD },
{ 0x038F, 0x038F, 0x03CE },
{ 0x0390, 0x0390, 0x0390 },
{ 0x0391, 0x0391, 0x03B1 },
{ 0x0392, 0x0392, 0x03B2 },
{ 0x0393, 0x0393, 0x03B3 },
{ 0x0394, 0x0394, 0x03B4 },
{ 0x0395, 0x0395, 0x03B5 },
{ 0x0396, 0x0396, 0x03B6 },
{ 0x0397, 0x0397, 0x03B7 },
{ 0x0398, 0x0398, 0x03B8 },
{ 0x0399, 0x0399, 0x03B9 },
{ 0x039A, 0x039A, 0x03BA },
{ 0x039B, 0x039B, 0x03BB },
{ 0x039C, 0x039C, 0x03BC },
{ 0x039D, 0x039D, 0x03BD },
{ 0x039E, 0x039E, 0x03BE },
{ 0x039F, 0x039F, 0x03BF },
{ 0x03A0, 0x03A0, 0x03C0 },
{ 0x03A1, 0x03A1, 0x03C1 },
{ 0x03A3, 0x03A3, 0x03C3 },
{ 0x03A4, 0x03A4, 0x03C4 },
{ 0x03A5, 0x03A5, 0x03C5 },
{ 0x03A6, 0x03A6, 0x03C6 },
{ 0x03A7, 0x03A7, 0x03C7 },
{ 0x03A8, 0x03A8, 0x03C8 },
{ 0x03A9, 0x03A9, 0x03C9 },
{ 0x03AA, 0x03AA, 0x03CA },
{ 0x03AB, 0x03AB, 0x03CB },
{ 0x03AC, 0x0386, 0x03AC },
{ 0x03AD, 0x0388, 0x03AD },
{ 0x03AE, 0x0389, 0x03AE },
{ 0x03AF, 0x038A, 0x03AF },
{ 0x03B0, 0x03B0, 0x03B0 },
{ 0x03B1, 0x0391, 0x03B1 },
{ 0x03B2, 0x0392, 0x03B2 },
{ 0x03B3, 0x0393, 0x03B3 },
{ 0x03B4, 0x0394, 0x03B4 },
{ 0x03B5, 0x0395, 0x03B5 },
{ 0x03B6, 0x0396, 0x03B6 },
{ 0x03B7, 0x0397, 0x03B7 },
{ 0x03B8, 0x0398, 0x03B8 },
{ 0x03B9, 0x0399, 0x03B9 },
{ 0x03BA, 0x039A, 0x03BA },
{ 0x03BB, 0x039B, 0x03BB },
{ 0x03BC, 0x039C, 0x03BC },
{ 0x03BD, 0x039D, 0x03BD },
{ 0x03BE, 0x039E, 0x03BE },
{ 0x03BF, 0x039F, 0x03BF },
{ 0x03C0, 0x03A0, 0x03C0 },
{ 0x03C1, 0x03A1, 0x03C1 },
{ 0x03C2, 0x03A3, 0x03C2 },
{ 0x03C3, 0x03A3, 0x03C3 },
{ 0x03C4, 0x03A4, 0x03C4 },
{ 0x03C5, 0x03A5, 0x03C5 },
{ 0x03C6, 0x03A6, 0x03C6 },
{ 0x03C7, 0x03A7, 0x03C7 },
{ 0x03C8, 0x03A8, 0x03C8 },
{ 0x03C9, 0x03A9, 0x03C9 },
{ 0x03CA, 0x03AA, 0x03CA },
{ 0x03CB, 0x03AB, 0x03CB },
{ 0x03CC, 0x038C, 0x03CC },
{ 0x03CD, 0x038E, 0x03CD },
{ 0x03CE, 0x038F, 0x03CE },
{ 0x03D0, 0x0392, 0x03D0 },
{ 0x03D1, 0x0398, 0x03D1 },
{ 0x03D2, 0x03D2, 0x03D2 },
{ 0x03D3, 0x03D3, 0x03D3 },
{ 0x03D4, 0x03D4, 0x03D4 },
{ 0x03D5, 0x03A6, 0x03D5 },
{ 0x03D6, 0x03A0, 0x03D6 },
{ 0x03D7, 0x03D7, 0x03D7 },
{ 0x03D8, 0x03D8, 0x03D9 },
{ 0x03D9, 0x03D8, 0x03D9 },
{ 0x03DA, 0x03DA, 0x03DB },
{ 0x03DB, 0x03DA, 0x03DB },
{ 0x03DC, 0x03DC, 0x03DD },
{ 0x03DD, 0x03DC, 0x03DD },
{ 0x03DE, 0x03DE, 0x03DF },
{ 0x03DF, 0x03DE, 0x03DF },
{ 0x03E0, 0x03E0, 0x03E1 },
{ 0x03E1, 0x03E0, 0x03E1 },
{ 0x03E2, 0x03E2, 0x03E3 },
{ 0x03E3, 0x03E2, 0x03E3 },
{ 0x03E4, 0x03E4, 0x03E5 },
{ 0x03E5, 0x03E4, 0x03E5 },
{ 0x03E6, 0x03E6, 0x03E7 },
{ 0x03E7, 0x03E6, 0x03E7 },
{ 0x03E8, 0x03E8, 0x03E9 },
{ 0x03E9, 0x03E8, 0x03E9 },
{ 0x03EA, 0x03EA, 0x03EB },
{ 0x03EB, 0x03EA, 0x03EB },
{ 0x03EC, 0x03EC, 0x03ED },
{ 0x03ED, 0x03EC, 0x03ED },
{ 0x03EE, 0x03EE, 0x03EF },
{ 0x03EF, 0x03EE, 0x03EF },
{ 0x03F0, 0x039A, 0x03F0 },
{ 0x03F1, 0x03A1, 0x03F1 },
{ 0x03F2, 0x03F9, 0x03F2 },
{ 0x03F3, 0x03F3, 0x03F3 },
{ 0x03F4, 0x03F4, 0x03B8 },
{ 0x03F5, 0x0395, 0x03F5 },
{ 0x03F7, 0x03F7, 0x03F8 },
{ 0x03F8, 0x03F7, 0x03F8 },
{ 0x03F9, 0x03F9, 0x03F2 },
{ 0x03FA, 0x03FA, 0x03FB },
{ 0x03FB, 0x03FA, 0x03FB },
{ 0x03FC, 0x03FC, 0x03FC },
{ 0x03FD, 0x03FD, 0x03FD },
{ 0x03FE, 0x03FE, 0x03FE },
{ 0x03FF, 0x03FF, 0x03FF },
{ 0x0400, 0x0400, 0x0450 },
{ 0x0401, 0x0401, 0x0451 },
{ 0x0402, 0x0402, 0x0452 },
{ 0x0403, 0x0403, 0x0453 },
{ 0x0404, 0x0404, 0x0454 },
{ 0x0405, 0x0405, 0x0455 },
{ 0x0406, 0x0406, 0x0456 },
{ 0x0407, 0x0407, 0x0457 },
{ 0x0408, 0x0408, 0x0458 },
{ 0x0409, 0x0409, 0x0459 },
{ 0x040A, 0x040A, 0x045A },
{ 0x040B, 0x040B, 0x045B },
{ 0x040C, 0x040C, 0x045C },
{ 0x040D, 0x040D, 0x045D },
{ 0x040E, 0x040E, 0x045E },
{ 0x040F, 0x040F, 0x045F },
{ 0x0410, 0x0410, 0x0430 },
{ 0x0411, 0x0411, 0x0431 },
{ 0x0412, 0x0412, 0x0432 },
{ 0x0413, 0x0413, 0x0433 },
{ 0x0414, 0x0414, 0x0434 },
{ 0x0415, 0x0415, 0x0435 },
{ 0x0416, 0x0416, 0x0436 },
{ 0x0417, 0x0417, 0x0437 },
{ 0x0418, 0x0418, 0x0438 },
{ 0x0419, 0x0419, 0x0439 },
{ 0x041A, 0x041A, 0x043A },
{ 0x041B, 0x041B, 0x043B },
{ 0x041C, 0x041C, 0x043C },
{ 0x041D, 0x041D, 0x043D },
{ 0x041E, 0x041E, 0x043E },
{ 0x041F, 0x041F, 0x043F },
{ 0x0420, 0x0420, 0x0440 },
{ 0x0421, 0x0421, 0x0441 },
{ 0x0422, 0x0422, 0x0442 },
{ 0x0423, 0x0423, 0x0443 },
{ 0x0424, 0x0424, 0x0444 },
{ 0x0425, 0x0425, 0x0445 },
{ 0x0426, 0x0426, 0x0446 },
{ 0x0427, 0x0427, 0x0447 },
{ 0x0428, 0x0428, 0x0448 },
{ 0x0429, 0x0429, 0x0449 },
{ 0x042A, 0x042A, 0x044A },
{ 0x042B, 0x042B, 0x044B },
{ 0x042C, 0x042C, 0x044C },
{ 0x042D, 0x042D, 0x044D },
{ 0x042E, 0x042E, 0x044E },
{ 0x042F, 0x042F, 0x044F },
{ 0x0430, 0x0410, 0x0430 },
{ 0x0431, 0x0411, 0x0431 },
{ 0x0432, 0x0412, 0x0432 },
{ 0x0433, 0x0413, 0x0433 },
{ 0x0434, 0x0414, 0x0434 },
{ 0x0435, 0x0415, 0x0435 },
{ 0x0436, 0x0416, 0x0436 },
{ 0x0437, 0x0417, 0x0437 },
{ 0x0438, 0x0418, 0x0438 },
{ 0x0439, 0x0419, 0x0439 },
{ 0x043A, 0x041A, 0x043A },
{ 0x043B, 0x041B, 0x043B },
{ 0x043C, 0x041C, 0x043C },
{ 0x043D, 0x041D, 0x043D },
{ 0x043E, 0x041E, 0x043E },
{ 0x043F, 0x041F, 0x043F },
{ 0x0440, 0x0420, 0x0440 },
{ 0x0441, 0x0421, 0x0441 },
{ 0x0442, 0x0422, 0x0442 },
{ 0x0443, 0x0423, 0x0443 },
{ 0x0444, 0x0424, 0x0444 },
{ 0x0445, 0x0425, 0x0445 },
{ 0x0446, 0x0426, 0x0446 },
{ 0x0447, 0x0427, 0x0447 },
{ 0x0448, 0x0428, 0x0448 },
{ 0x0449, 0x0429, 0x0449 },
{ 0x044A, 0x042A, 0x044A },
{ 0x044B, 0x042B, 0x044B },
{ 0x044C, 0x042C, 0x044C },
{ 0x044D, 0x042D, 0x044D },
{ 0x044E, 0x042E, 0x044E },
{ 0x044F, 0x042F, 0x044F },
{ 0x0450, 0x0400, 0x0450 },
{ 0x0451, 0x0401, 0x0451 },
{ 0x0452, 0x0402, 0x0452 },
{ 0x0453, 0x0403, 0x0453 },
{ 0x0454, 0x0404, 0x0454 },
{ 0x0455, 0x0405, 0x0455 },
{ 0x0456, 0x0406, 0x0456 },
{ 0x0457, 0x0407, 0x0457 },
{ 0x0458, 0x0408, 0x0458 },
{ 0x0459, 0x0409, 0x0459 },
{ 0x045A, 0x040A, 0x045A },
{ 0x045B, 0x040B, 0x045B },
{ 0x045C, 0x040C, 0x045C },
{ 0x045D, 0x040D, 0x045D },
{ 0x045E, 0x040E, 0x045E },
{ 0x045F, 0x040F, 0x045F },
{ 0x0460, 0x0460, 0x0461 },
{ 0x0461, 0x0460, 0x0461 },
{ 0x0462, 0x0462, 0x0463 },
{ 0x0463, 0x0462, 0x0463 },
{ 0x0464, 0x0464, 0x0465 },
{ 0x0465, 0x0464, 0x0465 },
{ 0x0466, 0x0466, 0x0467 },
{ 0x0467, 0x0466, 0x0467 },
{ 0x0468, 0x0468, 0x0469 },
{ 0x0469, 0x0468, 0x0469 },
{ 0x046A, 0x046A, 0x046B },
{ 0x046B, 0x046A, 0x046B },
{ 0x046C, 0x046C, 0x046D },
{ 0x046D, 0x046C, 0x046D },
{ 0x046E, 0x046E, 0x046F },
{ 0x046F, 0x046E, 0x046F },
{ 0x0470, 0x0470, 0x0471 },
{ 0x0471, 0x0470, 0x0471 },
{ 0x0472, 0x0472, 0x0473 },
{ 0x0473, 0x0472, 0x0473 },
{ 0x0474, 0x0474, 0x0475 },
{ 0x0475, 0x0474, 0x0475 },
{ 0x0476, 0x0476, 0x0477 },
{ 0x0477, 0x0476, 0x0477 },
{ 0x0478, 0x0478, 0x0479 },
{ 0x0479, 0x0478, 0x0479 },
{ 0x047A, 0x047A, 0x047B },
{ 0x047B, 0x047A, 0x047B },
{ 0x047C, 0x047C, 0x047D },
{ 0x047D, 0x047C, 0x047D },
{ 0x047E, 0x047E, 0x047F },
{ 0x047F, 0x047E, 0x047F },
{ 0x0480, 0x0480, 0x0481 },
{ 0x0481, 0x0480, 0x0481 },
{ 0x0483, 0x0483, 0x0483 },
{ 0x0484, 0x0484, 0x0484 },
{ 0x0485, 0x0485, 0x0485 },
{ 0x0486, 0x0486, 0x0486 },
{ 0x048A, 0x048A, 0x048B },
{ 0x048B, 0x048A, 0x048B },
{ 0x048C, 0x048C, 0x048D },
{ 0x048D, 0x048C, 0x048D },
{ 0x048E, 0x048E, 0x048F },
{ 0x048F, 0x048E, 0x048F },
{ 0x0490, 0x0490, 0x0491 },
{ 0x0491, 0x0490, 0x0491 },
{ 0x0492, 0x0492, 0x0493 },
{ 0x0493, 0x0492, 0x0493 },
{ 0x0494, 0x0494, 0x0495 },
{ 0x0495, 0x0494, 0x0495 },
{ 0x0496, 0x0496, 0x0497 },
{ 0x0497, 0x0496, 0x0497 },
{ 0x0498, 0x0498, 0x0499 },
{ 0x0499, 0x0498, 0x0499 },
{ 0x049A, 0x049A, 0x049B },
{ 0x049B, 0x049A, 0x049B },
{ 0x049C, 0x049C, 0x049D },
{ 0x049D, 0x049C, 0x049D },
{ 0x049E, 0x049E, 0x049F },
{ 0x049F, 0x049E, 0x049F },
{ 0x04A0, 0x04A0, 0x04A1 },
{ 0x04A1, 0x04A0, 0x04A1 },
{ 0x04A2, 0x04A2, 0x04A3 },
{ 0x04A3, 0x04A2, 0x04A3 },
{ 0x04A4, 0x04A4, 0x04A5 },
{ 0x04A5, 0x04A4, 0x04A5 },
{ 0x04A6, 0x04A6, 0x04A7 },
{ 0x04A7, 0x04A6, 0x04A7 },
{ 0x04A8, 0x04A8, 0x04A9 },
{ 0x04A9, 0x04A8, 0x04A9 },
{ 0x04AA, 0x04AA, 0x04AB },
{ 0x04AB, 0x04AA, 0x04AB },
{ 0x04AC, 0x04AC, 0x04AD },
{ 0x04AD, 0x04AC, 0x04AD },
{ 0x04AE, 0x04AE, 0x04AF },
{ 0x04AF, 0x04AE, 0x04AF },
{ 0x04B0, 0x04B0, 0x04B1 },
{ 0x04B1, 0x04B0, 0x04B1 },
{ 0x04B2, 0x04B2, 0x04B3 },
{ 0x04B3, 0x04B2, 0x04B3 },
{ 0x04B4, 0x04B4, 0x04B5 },
{ 0x04B5, 0x04B4, 0x04B5 },
{ 0x04B6, 0x04B6, 0x04B7 },
{ 0x04B7, 0x04B6, 0x04B7 },
{ 0x04B8, 0x04B8, 0x04B9 },
{ 0x04B9, 0x04B8, 0x04B9 },
{ 0x04BA, 0x04BA, 0x04BB },
{ 0x04BB, 0x04BA, 0x04BB },
{ 0x04BC, 0x04BC, 0x04BD },
{ 0x04BD, 0x04BC, 0x04BD },
{ 0x04BE, 0x04BE, 0x04BF },
{ 0x04BF, 0x04BE, 0x04BF },
{ 0x04C0, 0x04C0, 0x04C0 },
{ 0x04C1, 0x04C1, 0x04C2 },
{ 0x04C2, 0x04C1, 0x04C2 },
{ 0x04C3, 0x04C3, 0x04C4 },
{ 0x04C4, 0x04C3, 0x04C4 },
{ 0x04C5, 0x04C5, 0x04C6 },
{ 0x04C6, 0x04C5, 0x04C6 },
{ 0x04C7, 0x04C7, 0x04C8 },
{ 0x04C8, 0x04C7, 0x04C8 },
{ 0x04C9, 0x04C9, 0x04CA },
{ 0x04CA, 0x04C9, 0x04CA },
{ 0x04CB, 0x04CB, 0x04CC },
{ 0x04CC, 0x04CB, 0x04CC },
{ 0x04CD, 0x04CD, 0x04CE },
{ 0x04CE, 0x04CD, 0x04CE },
{ 0x04D0, 0x04D0, 0x04D1 },
{ 0x04D1, 0x04D0, 0x04D1 },
{ 0x04D2, 0x04D2, 0x04D3 },
{ 0x04D3, 0x04D2, 0x04D3 },
{ 0x04D4, 0x04D4, 0x04D5 },
{ 0x04D5, 0x04D4, 0x04D5 },
{ 0x04D6, 0x04D6, 0x04D7 },
{ 0x04D7, 0x04D6, 0x04D7 },
{ 0x04D8, 0x04D8, 0x04D9 },
{ 0x04D9, 0x04D8, 0x04D9 },
{ 0x04DA, 0x04DA, 0x04DB },
{ 0x04DB, 0x04DA, 0x04DB },
{ 0x04DC, 0x04DC, 0x04DD },
{ 0x04DD, 0x04DC, 0x04DD },
{ 0x04DE, 0x04DE, 0x04DF },
{ 0x04DF, 0x04DE, 0x04DF },
{ 0x04E0, 0x04E0, 0x04E1 },
{ 0x04E1, 0x04E0, 0x04E1 },
{ 0x04E2, 0x04E2, 0x04E3 },
{ 0x04E3, 0x04E2, 0x04E3 },
{ 0x04E4, 0x04E4, 0x04E5 },
{ 0x04E5, 0x04E4, 0x04E5 },
{ 0x04E6, 0x04E6, 0x04E7 },
{ 0x04E7, 0x04E6, 0x04E7 },
{ 0x04E8, 0x04E8, 0x04E9 },
{ 0x04E9, 0x04E8, 0x04E9 },
{ 0x04EA, 0x04EA, 0x04EB },
{ 0x04EB, 0x04EA, 0x04EB },
{ 0x04EC, 0x04EC, 0x04ED },
{ 0x04ED, 0x04EC, 0x04ED },
{ 0x04EE, 0x04EE, 0x04EF },
{ 0x04EF, 0x04EE, 0x04EF },
{ 0x04F0, 0x04F0, 0x04F1 },
{ 0x04F1, 0x04F0, 0x04F1 },
{ 0x04F2, 0x04F2, 0x04F3 },
{ 0x04F3, 0x04F2, 0x04F3 },
{ 0x04F4, 0x04F4, 0x04F5 },
{ 0x04F5, 0x04F4, 0x04F5 },
{ 0x04F6, 0x04F6, 0x04F7 },
{ 0x04F7, 0x04F6, 0x04F7 },
{ 0x04F8, 0x04F8, 0x04F9 },
{ 0x04F9, 0x04F8, 0x04F9 },
{ 0x0500, 0x0500, 0x0501 },
{ 0x0501, 0x0500, 0x0501 },
{ 0x0502, 0x0502, 0x0503 },
{ 0x0503, 0x0502, 0x0503 },
{ 0x0504, 0x0504, 0x0505 },
{ 0x0505, 0x0504, 0x0505 },
{ 0x0506, 0x0506, 0x0507 },
{ 0x0507, 0x0506, 0x0507 },
{ 0x0508, 0x0508, 0x0509 },
{ 0x0509, 0x0508, 0x0509 },
{ 0x050A, 0x050A, 0x050B },
{ 0x050B, 0x050A, 0x050B },
{ 0x050C, 0x050C, 0x050D },
{ 0x050D, 0x050C, 0x050D },
{ 0x050E, 0x050E, 0x050F },
{ 0x050F, 0x050E, 0x050F },
{ 0x0531, 0x0531, 0x0561 },
{ 0x0532, 0x0532, 0x0562 },
{ 0x0533, 0x0533, 0x0563 },
{ 0x0534, 0x0534, 0x0564 },
{ 0x0535, 0x0535, 0x0565 },
{ 0x0536, 0x0536, 0x0566 },
{ 0x0537, 0x0537, 0x0567 },
{ 0x0538, 0x0538, 0x0568 },
{ 0x0539, 0x0539, 0x0569 },
{ 0x053A, 0x053A, 0x056A },
{ 0x053B, 0x053B, 0x056B },
{ 0x053C, 0x053C, 0x056C },
{ 0x053D, 0x053D, 0x056D },
{ 0x053E, 0x053E, 0x056E },
{ 0x053F, 0x053F, 0x056F },
{ 0x0540, 0x0540, 0x0570 },
{ 0x0541, 0x0541, 0x0571 },
{ 0x0542, 0x0542, 0x0572 },
{ 0x0543, 0x0543, 0x0573 },
{ 0x0544, 0x0544, 0x0574 },
{ 0x0545, 0x0545, 0x0575 },
{ 0x0546, 0x0546, 0x0576 },
{ 0x0547, 0x0547, 0x0577 },
{ 0x0548, 0x0548, 0x0578 },
{ 0x0549, 0x0549, 0x0579 },
{ 0x054A, 0x054A, 0x057A },
{ 0x054B, 0x054B, 0x057B },
{ 0x054C, 0x054C, 0x057C },
{ 0x054D, 0x054D, 0x057D },
{ 0x054E, 0x054E, 0x057E },
{ 0x054F, 0x054F, 0x057F },
{ 0x0550, 0x0550, 0x0580 },
{ 0x0551, 0x0551, 0x0581 },
{ 0x0552, 0x0552, 0x0582 },
{ 0x0553, 0x0553, 0x0583 },
{ 0x0554, 0x0554, 0x0584 },
{ 0x0555, 0x0555, 0x0585 },
{ 0x0556, 0x0556, 0x0586 },
{ 0x0559, 0x0559, 0x0559 },
{ 0x0561, 0x0531, 0x0561 },
{ 0x0562, 0x0532, 0x0562 },
{ 0x0563, 0x0533, 0x0563 },
{ 0x0564, 0x0534, 0x0564 },
{ 0x0565, 0x0535, 0x0565 },
{ 0x0566, 0x0536, 0x0566 },
{ 0x0567, 0x0537, 0x0567 },
{ 0x0568, 0x0538, 0x0568 },
{ 0x0569, 0x0539, 0x0569 },
{ 0x056A, 0x053A, 0x056A },
{ 0x056B, 0x053B, 0x056B },
{ 0x056C, 0x053C, 0x056C },
{ 0x056D, 0x053D, 0x056D },
{ 0x056E, 0x053E, 0x056E },
{ 0x056F, 0x053F, 0x056F },
{ 0x0570, 0x0540, 0x0570 },
{ 0x0571, 0x0541, 0x0571 },
{ 0x0572, 0x0542, 0x0572 },
{ 0x0573, 0x0543, 0x0573 },
{ 0x0574, 0x0544, 0x0574 },
{ 0x0575, 0x0545, 0x0575 },
{ 0x0576, 0x0546, 0x0576 },
{ 0x0577, 0x0547, 0x0577 },
{ 0x0578, 0x0548, 0x0578 },
{ 0x0579, 0x0549, 0x0579 },
{ 0x057A, 0x054A, 0x057A },
{ 0x057B, 0x054B, 0x057B },
{ 0x057C, 0x054C, 0x057C },
{ 0x057D, 0x054D, 0x057D },
{ 0x057E, 0x054E, 0x057E },
{ 0x057F, 0x054F, 0x057F },
{ 0x0580, 0x0550, 0x0580 },
{ 0x0581, 0x0551, 0x0581 },
{ 0x0582, 0x0552, 0x0582 },
{ 0x0583, 0x0553, 0x0583 },
{ 0x0584, 0x0554, 0x0584 },
{ 0x0585, 0x0555, 0x0585 },
{ 0x0586, 0x0556, 0x0586 },
{ 0x0587, 0x0587, 0x0587 },
{ 0x0591, 0x0591, 0x0591 },
{ 0x0592, 0x0592, 0x0592 },
{ 0x0593, 0x0593, 0x0593 },
{ 0x0594, 0x0594, 0x0594 },
{ 0x0595, 0x0595, 0x0595 },
{ 0x0596, 0x0596, 0x0596 },
{ 0x0597, 0x0597, 0x0597 },
{ 0x0598, 0x0598, 0x0598 },
{ 0x0599, 0x0599, 0x0599 },
{ 0x059A, 0x059A, 0x059A },
{ 0x059B, 0x059B, 0x059B },
{ 0x059C, 0x059C, 0x059C },
{ 0x059D, 0x059D, 0x059D },
{ 0x059E, 0x059E, 0x059E },
{ 0x059F, 0x059F, 0x059F },
{ 0x05A0, 0x05A0, 0x05A0 },
{ 0x05A1, 0x05A1, 0x05A1 },
{ 0x05A2, 0x05A2, 0x05A2 },
{ 0x05A3, 0x05A3, 0x05A3 },
{ 0x05A4, 0x05A4, 0x05A4 },
{ 0x05A5, 0x05A5, 0x05A5 },
{ 0x05A6, 0x05A6, 0x05A6 },
{ 0x05A7, 0x05A7, 0x05A7 },
{ 0x05A8, 0x05A8, 0x05A8 },
{ 0x05A9, 0x05A9, 0x05A9 },
{ 0x05AA, 0x05AA, 0x05AA },
{ 0x05AB, 0x05AB, 0x05AB },
{ 0x05AC, 0x05AC, 0x05AC },
{ 0x05AD, 0x05AD, 0x05AD },
{ 0x05AE, 0x05AE, 0x05AE },
{ 0x05AF, 0x05AF, 0x05AF },
{ 0x05B0, 0x05B0, 0x05B0 },
{ 0x05B1, 0x05B1, 0x05B1 },
{ 0x05B2, 0x05B2, 0x05B2 },
{ 0x05B3, 0x05B3, 0x05B3 },
{ 0x05B4, 0x05B4, 0x05B4 },
{ 0x05B5, 0x05B5, 0x05B5 },
{ 0x05B6, 0x05B6, 0x05B6 },
{ 0x05B7, 0x05B7, 0x05B7 },
{ 0x05B8, 0x05B8, 0x05B8 },
{ 0x05B9, 0x05B9, 0x05B9 },
{ 0x05BB, 0x05BB, 0x05BB },
{ 0x05BC, 0x05BC, 0x05BC },
{ 0x05BD, 0x05BD, 0x05BD },
{ 0x05BF, 0x05BF, 0x05BF },
{ 0x05C1, 0x05C1, 0x05C1 },
{ 0x05C2, 0x05C2, 0x05C2 },
{ 0x05C4, 0x05C4, 0x05C4 },
{ 0x05C5, 0x05C5, 0x05C5 },
{ 0x05C7, 0x05C7, 0x05C7 },
{ 0x05D0, 0x05D0, 0x05D0 },
{ 0x05D1, 0x05D1, 0x05D1 },
{ 0x05D2, 0x05D2, 0x05D2 },
{ 0x05D3, 0x05D3, 0x05D3 },
{ 0x05D4, 0x05D4, 0x05D4 },
{ 0x05D5, 0x05D5, 0x05D5 },
{ 0x05D6, 0x05D6, 0x05D6 },
{ 0x05D7, 0x05D7, 0x05D7 },
{ 0x05D8, 0x05D8, 0x05D8 },
{ 0x05D9, 0x05D9, 0x05D9 },
{ 0x05DA, 0x05DA, 0x05DA },
{ 0x05DB, 0x05DB, 0x05DB },
{ 0x05DC, 0x05DC, 0x05DC },
{ 0x05DD, 0x05DD, 0x05DD },
{ 0x05DE, 0x05DE, 0x05DE },
{ 0x05DF, 0x05DF, 0x05DF },
{ 0x05E0, 0x05E0, 0x05E0 },
{ 0x05E1, 0x05E1, 0x05E1 },
{ 0x05E2, 0x05E2, 0x05E2 },
{ 0x05E3, 0x05E3, 0x05E3 },
{ 0x05E4, 0x05E4, 0x05E4 },
{ 0x05E5, 0x05E5, 0x05E5 },
{ 0x05E6, 0x05E6, 0x05E6 },
{ 0x05E7, 0x05E7, 0x05E7 },
{ 0x05E8, 0x05E8, 0x05E8 },
{ 0x05E9, 0x05E9, 0x05E9 },
{ 0x05EA, 0x05EA, 0x05EA },
{ 0x05F0, 0x05F0, 0x05F0 },
{ 0x05F1, 0x05F1, 0x05F1 },
{ 0x05F2, 0x05F2, 0x05F2 },
{ 0x0610, 0x0610, 0x0610 },
{ 0x0611, 0x0611, 0x0611 },
{ 0x0612, 0x0612, 0x0612 },
{ 0x0613, 0x0613, 0x0613 },
{ 0x0614, 0x0614, 0x0614 },
{ 0x0615, 0x0615, 0x0615 },
{ 0x0621, 0x0621, 0x0621 },
{ 0x0622, 0x0622, 0x0622 },
{ 0x0623, 0x0623, 0x0623 },
{ 0x0624, 0x0624, 0x0624 },
{ 0x0625, 0x0625, 0x0625 },
{ 0x0626, 0x0626, 0x0626 },
{ 0x0627, 0x0627, 0x0627 },
{ 0x0628, 0x0628, 0x0628 },
{ 0x0629, 0x0629, 0x0629 },
{ 0x062A, 0x062A, 0x062A },
{ 0x062B, 0x062B, 0x062B },
{ 0x062C, 0x062C, 0x062C },
{ 0x062D, 0x062D, 0x062D },
{ 0x062E, 0x062E, 0x062E },
{ 0x062F, 0x062F, 0x062F },
{ 0x0630, 0x0630, 0x0630 },
{ 0x0631, 0x0631, 0x0631 },
{ 0x0632, 0x0632, 0x0632 },
{ 0x0633, 0x0633, 0x0633 },
{ 0x0634, 0x0634, 0x0634 },
{ 0x0635, 0x0635, 0x0635 },
{ 0x0636, 0x0636, 0x0636 },
{ 0x0637, 0x0637, 0x0637 },
{ 0x0638, 0x0638, 0x0638 },
{ 0x0639, 0x0639, 0x0639 },
{ 0x063A, 0x063A, 0x063A },
{ 0x0640, 0x0640, 0x0640 },
{ 0x0641, 0x0641, 0x0641 },
{ 0x0642, 0x0642, 0x0642 },
{ 0x0643, 0x0643, 0x0643 },
{ 0x0644, 0x0644, 0x0644 },
{ 0x0645, 0x0645, 0x0645 },
{ 0x0646, 0x0646, 0x0646 },
{ 0x0647, 0x0647, 0x0647 },
{ 0x0648, 0x0648, 0x0648 },
{ 0x0649, 0x0649, 0x0649 },
{ 0x064A, 0x064A, 0x064A },
{ 0x064B, 0x064B, 0x064B },
{ 0x064C, 0x064C, 0x064C },
{ 0x064D, 0x064D, 0x064D },
{ 0x064E, 0x064E, 0x064E },
{ 0x064F, 0x064F, 0x064F },
{ 0x0650, 0x0650, 0x0650 },
{ 0x0651, 0x0651, 0x0651 },
{ 0x0652, 0x0652, 0x0652 },
{ 0x0653, 0x0653, 0x0653 },
{ 0x0654, 0x0654, 0x0654 },
{ 0x0655, 0x0655, 0x0655 },
{ 0x0656, 0x0656, 0x0656 },
{ 0x0657, 0x0657, 0x0657 },
{ 0x0658, 0x0658, 0x0658 },
{ 0x0659, 0x0659, 0x0659 },
{ 0x065A, 0x065A, 0x065A },
{ 0x065B, 0x065B, 0x065B },
{ 0x065C, 0x065C, 0x065C },
{ 0x065D, 0x065D, 0x065D },
{ 0x065E, 0x065E, 0x065E },
{ 0x066E, 0x066E, 0x066E },
{ 0x066F, 0x066F, 0x066F },
{ 0x0670, 0x0670, 0x0670 },
{ 0x0671, 0x0671, 0x0671 },
{ 0x0672, 0x0672, 0x0672 },
{ 0x0673, 0x0673, 0x0673 },
{ 0x0674, 0x0674, 0x0674 },
{ 0x0675, 0x0675, 0x0675 },
{ 0x0676, 0x0676, 0x0676 },
{ 0x0677, 0x0677, 0x0677 },
{ 0x0678, 0x0678, 0x0678 },
{ 0x0679, 0x0679, 0x0679 },
{ 0x067A, 0x067A, 0x067A },
{ 0x067B, 0x067B, 0x067B },
{ 0x067C, 0x067C, 0x067C },
{ 0x067D, 0x067D, 0x067D },
{ 0x067E, 0x067E, 0x067E },
{ 0x067F, 0x067F, 0x067F },
{ 0x0680, 0x0680, 0x0680 },
{ 0x0681, 0x0681, 0x0681 },
{ 0x0682, 0x0682, 0x0682 },
{ 0x0683, 0x0683, 0x0683 },
{ 0x0684, 0x0684, 0x0684 },
{ 0x0685, 0x0685, 0x0685 },
{ 0x0686, 0x0686, 0x0686 },
{ 0x0687, 0x0687, 0x0687 },
{ 0x0688, 0x0688, 0x0688 },
{ 0x0689, 0x0689, 0x0689 },
{ 0x068A, 0x068A, 0x068A },
{ 0x068B, 0x068B, 0x068B },
{ 0x068C, 0x068C, 0x068C },
{ 0x068D, 0x068D, 0x068D },
{ 0x068E, 0x068E, 0x068E },
{ 0x068F, 0x068F, 0x068F },
{ 0x0690, 0x0690, 0x0690 },
{ 0x0691, 0x0691, 0x0691 },
{ 0x0692, 0x0692, 0x0692 },
{ 0x0693, 0x0693, 0x0693 },
{ 0x0694, 0x0694, 0x0694 },
{ 0x0695, 0x0695, 0x0695 },
{ 0x0696, 0x0696, 0x0696 },
{ 0x0697, 0x0697, 0x0697 },
{ 0x0698, 0x0698, 0x0698 },
{ 0x0699, 0x0699, 0x0699 },
{ 0x069A, 0x069A, 0x069A },
{ 0x069B, 0x069B, 0x069B },
{ 0x069C, 0x069C, 0x069C },
{ 0x069D, 0x069D, 0x069D },
{ 0x069E, 0x069E, 0x069E },
{ 0x069F, 0x069F, 0x069F },
{ 0x06A0, 0x06A0, 0x06A0 },
{ 0x06A1, 0x06A1, 0x06A1 },
{ 0x06A2, 0x06A2, 0x06A2 },
{ 0x06A3, 0x06A3, 0x06A3 },
{ 0x06A4, 0x06A4, 0x06A4 },
{ 0x06A5, 0x06A5, 0x06A5 },
{ 0x06A6, 0x06A6, 0x06A6 },
{ 0x06A7, 0x06A7, 0x06A7 },
{ 0x06A8, 0x06A8, 0x06A8 },
{ 0x06A9, 0x06A9, 0x06A9 },
{ 0x06AA, 0x06AA, 0x06AA },
{ 0x06AB, 0x06AB, 0x06AB },
{ 0x06AC, 0x06AC, 0x06AC },
{ 0x06AD, 0x06AD, 0x06AD },
{ 0x06AE, 0x06AE, 0x06AE },
{ 0x06AF, 0x06AF, 0x06AF },
{ 0x06B0, 0x06B0, 0x06B0 },
{ 0x06B1, 0x06B1, 0x06B1 },
{ 0x06B2, 0x06B2, 0x06B2 },
{ 0x06B3, 0x06B3, 0x06B3 },
{ 0x06B4, 0x06B4, 0x06B4 },
{ 0x06B5, 0x06B5, 0x06B5 },
{ 0x06B6, 0x06B6, 0x06B6 },
{ 0x06B7, 0x06B7, 0x06B7 },
{ 0x06B8, 0x06B8, 0x06B8 },
{ 0x06B9, 0x06B9, 0x06B9 },
{ 0x06BA, 0x06BA, 0x06BA },
{ 0x06BB, 0x06BB, 0x06BB },
{ 0x06BC, 0x06BC, 0x06BC },
{ 0x06BD, 0x06BD, 0x06BD },
{ 0x06BE, 0x06BE, 0x06BE },
{ 0x06BF, 0x06BF, 0x06BF },
{ 0x06C0, 0x06C0, 0x06C0 },
{ 0x06C1, 0x06C1, 0x06C1 },
{ 0x06C2, 0x06C2, 0x06C2 },
{ 0x06C3, 0x06C3, 0x06C3 },
{ 0x06C4, 0x06C4, 0x06C4 },
{ 0x06C5, 0x06C5, 0x06C5 },
{ 0x06C6, 0x06C6, 0x06C6 },
{ 0x06C7, 0x06C7, 0x06C7 },
{ 0x06C8, 0x06C8, 0x06C8 },
{ 0x06C9, 0x06C9, 0x06C9 },
{ 0x06CA, 0x06CA, 0x06CA },
{ 0x06CB, 0x06CB, 0x06CB },
{ 0x06CC, 0x06CC, 0x06CC },
{ 0x06CD, 0x06CD, 0x06CD },
{ 0x06CE, 0x06CE, 0x06CE },
{ 0x06CF, 0x06CF, 0x06CF },
{ 0x06D0, 0x06D0, 0x06D0 },
{ 0x06D1, 0x06D1, 0x06D1 },
{ 0x06D2, 0x06D2, 0x06D2 },
{ 0x06D3, 0x06D3, 0x06D3 },
{ 0x06D5, 0x06D5, 0x06D5 },
{ 0x06D6, 0x06D6, 0x06D6 },
{ 0x06D7, 0x06D7, 0x06D7 },
{ 0x06D8, 0x06D8, 0x06D8 },
{ 0x06D9, 0x06D9, 0x06D9 },
{ 0x06DA, 0x06DA, 0x06DA },
{ 0x06DB, 0x06DB, 0x06DB },
{ 0x06DC, 0x06DC, 0x06DC },
{ 0x06DF, 0x06DF, 0x06DF },
{ 0x06E0, 0x06E0, 0x06E0 },
{ 0x06E1, 0x06E1, 0x06E1 },
{ 0x06E2, 0x06E2, 0x06E2 },
{ 0x06E3, 0x06E3, 0x06E3 },
{ 0x06E4, 0x06E4, 0x06E4 },
{ 0x06E5, 0x06E5, 0x06E5 },
{ 0x06E6, 0x06E6, 0x06E6 },
{ 0x06E7, 0x06E7, 0x06E7 },
{ 0x06E8, 0x06E8, 0x06E8 },
{ 0x06EA, 0x06EA, 0x06EA },
{ 0x06EB, 0x06EB, 0x06EB },
{ 0x06EC, 0x06EC, 0x06EC },
{ 0x06ED, 0x06ED, 0x06ED },
{ 0x06EE, 0x06EE, 0x06EE },
{ 0x06EF, 0x06EF, 0x06EF },
{ 0x06FA, 0x06FA, 0x06FA },
{ 0x06FB, 0x06FB, 0x06FB },
{ 0x06FC, 0x06FC, 0x06FC },
{ 0x06FF, 0x06FF, 0x06FF },
{ 0x0710, 0x0710, 0x0710 },
{ 0x0711, 0x0711, 0x0711 },
{ 0x0712, 0x0712, 0x0712 },
{ 0x0713, 0x0713, 0x0713 },
{ 0x0714, 0x0714, 0x0714 },
{ 0x0715, 0x0715, 0x0715 },
{ 0x0716, 0x0716, 0x0716 },
{ 0x0717, 0x0717, 0x0717 },
{ 0x0718, 0x0718, 0x0718 },
{ 0x0719, 0x0719, 0x0719 },
{ 0x071A, 0x071A, 0x071A },
{ 0x071B, 0x071B, 0x071B },
{ 0x071C, 0x071C, 0x071C },
{ 0x071D, 0x071D, 0x071D },
{ 0x071E, 0x071E, 0x071E },
{ 0x071F, 0x071F, 0x071F },
{ 0x0720, 0x0720, 0x0720 },
{ 0x0721, 0x0721, 0x0721 },
{ 0x0722, 0x0722, 0x0722 },
{ 0x0723, 0x0723, 0x0723 },
{ 0x0724, 0x0724, 0x0724 },
{ 0x0725, 0x0725, 0x0725 },
{ 0x0726, 0x0726, 0x0726 },
{ 0x0727, 0x0727, 0x0727 },
{ 0x0728, 0x0728, 0x0728 },
{ 0x0729, 0x0729, 0x0729 },
{ 0x072A, 0x072A, 0x072A },
{ 0x072B, 0x072B, 0x072B },
{ 0x072C, 0x072C, 0x072C },
{ 0x072D, 0x072D, 0x072D },
{ 0x072E, 0x072E, 0x072E },
{ 0x072F, 0x072F, 0x072F },
{ 0x0730, 0x0730, 0x0730 },
{ 0x0731, 0x0731, 0x0731 },
{ 0x0732, 0x0732, 0x0732 },
{ 0x0733, 0x0733, 0x0733 },
{ 0x0734, 0x0734, 0x0734 },
{ 0x0735, 0x0735, 0x0735 },
{ 0x0736, 0x0736, 0x0736 },
{ 0x0737, 0x0737, 0x0737 },
{ 0x0738, 0x0738, 0x0738 },
{ 0x0739, 0x0739, 0x0739 },
{ 0x073A, 0x073A, 0x073A },
{ 0x073B, 0x073B, 0x073B },
{ 0x073C, 0x073C, 0x073C },
{ 0x073D, 0x073D, 0x073D },
{ 0x073E, 0x073E, 0x073E },
{ 0x073F, 0x073F, 0x073F },
{ 0x0740, 0x0740, 0x0740 },
{ 0x0741, 0x0741, 0x0741 },
{ 0x0742, 0x0742, 0x0742 },
{ 0x0743, 0x0743, 0x0743 },
{ 0x0744, 0x0744, 0x0744 },
{ 0x0745, 0x0745, 0x0745 },
{ 0x0746, 0x0746, 0x0746 },
{ 0x0747, 0x0747, 0x0747 },
{ 0x0748, 0x0748, 0x0748 },
{ 0x0749, 0x0749, 0x0749 },
{ 0x074A, 0x074A, 0x074A },
{ 0x074D, 0x074D, 0x074D },
{ 0x074E, 0x074E, 0x074E },
{ 0x074F, 0x074F, 0x074F },
{ 0x0750, 0x0750, 0x0750 },
{ 0x0751, 0x0751, 0x0751 },
{ 0x0752, 0x0752, 0x0752 },
{ 0x0753, 0x0753, 0x0753 },
{ 0x0754, 0x0754, 0x0754 },
{ 0x0755, 0x0755, 0x0755 },
{ 0x0756, 0x0756, 0x0756 },
{ 0x0757, 0x0757, 0x0757 },
{ 0x0758, 0x0758, 0x0758 },
{ 0x0759, 0x0759, 0x0759 },
{ 0x075A, 0x075A, 0x075A },
{ 0x075B, 0x075B, 0x075B },
{ 0x075C, 0x075C, 0x075C },
{ 0x075D, 0x075D, 0x075D },
{ 0x075E, 0x075E, 0x075E },
{ 0x075F, 0x075F, 0x075F },
{ 0x0760, 0x0760, 0x0760 },
{ 0x0761, 0x0761, 0x0761 },
{ 0x0762, 0x0762, 0x0762 },
{ 0x0763, 0x0763, 0x0763 },
{ 0x0764, 0x0764, 0x0764 },
{ 0x0765, 0x0765, 0x0765 },
{ 0x0766, 0x0766, 0x0766 },
{ 0x0767, 0x0767, 0x0767 },
{ 0x0768, 0x0768, 0x0768 },
{ 0x0769, 0x0769, 0x0769 },
{ 0x076A, 0x076A, 0x076A },
{ 0x076B, 0x076B, 0x076B },
{ 0x076C, 0x076C, 0x076C },
{ 0x076D, 0x076D, 0x076D },
{ 0x0780, 0x0780, 0x0780 },
{ 0x0781, 0x0781, 0x0781 },
{ 0x0782, 0x0782, 0x0782 },
{ 0x0783, 0x0783, 0x0783 },
{ 0x0784, 0x0784, 0x0784 },
{ 0x0785, 0x0785, 0x0785 },
{ 0x0786, 0x0786, 0x0786 },
{ 0x0787, 0x0787, 0x0787 },
{ 0x0788, 0x0788, 0x0788 },
{ 0x0789, 0x0789, 0x0789 },
{ 0x078A, 0x078A, 0x078A },
{ 0x078B, 0x078B, 0x078B },
{ 0x078C, 0x078C, 0x078C },
{ 0x078D, 0x078D, 0x078D },
{ 0x078E, 0x078E, 0x078E },
{ 0x078F, 0x078F, 0x078F },
{ 0x0790, 0x0790, 0x0790 },
{ 0x0791, 0x0791, 0x0791 },
{ 0x0792, 0x0792, 0x0792 },
{ 0x0793, 0x0793, 0x0793 },
{ 0x0794, 0x0794, 0x0794 },
{ 0x0795, 0x0795, 0x0795 },
{ 0x0796, 0x0796, 0x0796 },
{ 0x0797, 0x0797, 0x0797 },
{ 0x0798, 0x0798, 0x0798 },
{ 0x0799, 0x0799, 0x0799 },
{ 0x079A, 0x079A, 0x079A },
{ 0x079B, 0x079B, 0x079B },
{ 0x079C, 0x079C, 0x079C },
{ 0x079D, 0x079D, 0x079D },
{ 0x079E, 0x079E, 0x079E },
{ 0x079F, 0x079F, 0x079F },
{ 0x07A0, 0x07A0, 0x07A0 },
{ 0x07A1, 0x07A1, 0x07A1 },
{ 0x07A2, 0x07A2, 0x07A2 },
{ 0x07A3, 0x07A3, 0x07A3 },
{ 0x07A4, 0x07A4, 0x07A4 },
{ 0x07A5, 0x07A5, 0x07A5 },
{ 0x07A6, 0x07A6, 0x07A6 },
{ 0x07A7, 0x07A7, 0x07A7 },
{ 0x07A8, 0x07A8, 0x07A8 },
{ 0x07A9, 0x07A9, 0x07A9 },
{ 0x07AA, 0x07AA, 0x07AA },
{ 0x07AB, 0x07AB, 0x07AB },
{ 0x07AC, 0x07AC, 0x07AC },
{ 0x07AD, 0x07AD, 0x07AD },
{ 0x07AE, 0x07AE, 0x07AE },
{ 0x07AF, 0x07AF, 0x07AF },
{ 0x07B0, 0x07B0, 0x07B0 },
{ 0x07B1, 0x07B1, 0x07B1 },
{ 0x0901, 0x0901, 0x0901 },
{ 0x0902, 0x0902, 0x0902 },
{ 0x0904, 0x0904, 0x0904 },
{ 0x0905, 0x0905, 0x0905 },
{ 0x0906, 0x0906, 0x0906 },
{ 0x0907, 0x0907, 0x0907 },
{ 0x0908, 0x0908, 0x0908 },
{ 0x0909, 0x0909, 0x0909 },
{ 0x090A, 0x090A, 0x090A },
{ 0x090B, 0x090B, 0x090B },
{ 0x090C, 0x090C, 0x090C },
{ 0x090D, 0x090D, 0x090D },
{ 0x090E, 0x090E, 0x090E },
{ 0x090F, 0x090F, 0x090F },
{ 0x0910, 0x0910, 0x0910 },
{ 0x0911, 0x0911, 0x0911 },
{ 0x0912, 0x0912, 0x0912 },
{ 0x0913, 0x0913, 0x0913 },
{ 0x0914, 0x0914, 0x0914 },
{ 0x0915, 0x0915, 0x0915 },
{ 0x0916, 0x0916, 0x0916 },
{ 0x0917, 0x0917, 0x0917 },
{ 0x0918, 0x0918, 0x0918 },
{ 0x0919, 0x0919, 0x0919 },
{ 0x091A, 0x091A, 0x091A },
{ 0x091B, 0x091B, 0x091B },
{ 0x091C, 0x091C, 0x091C },
{ 0x091D, 0x091D, 0x091D },
{ 0x091E, 0x091E, 0x091E },
{ 0x091F, 0x091F, 0x091F },
{ 0x0920, 0x0920, 0x0920 },
{ 0x0921, 0x0921, 0x0921 },
{ 0x0922, 0x0922, 0x0922 },
{ 0x0923, 0x0923, 0x0923 },
{ 0x0924, 0x0924, 0x0924 },
{ 0x0925, 0x0925, 0x0925 },
{ 0x0926, 0x0926, 0x0926 },
{ 0x0927, 0x0927, 0x0927 },
{ 0x0928, 0x0928, 0x0928 },
{ 0x0929, 0x0929, 0x0929 },
{ 0x092A, 0x092A, 0x092A },
{ 0x092B, 0x092B, 0x092B },
{ 0x092C, 0x092C, 0x092C },
{ 0x092D, 0x092D, 0x092D },
{ 0x092E, 0x092E, 0x092E },
{ 0x092F, 0x092F, 0x092F },
{ 0x0930, 0x0930, 0x0930 },
{ 0x0931, 0x0931, 0x0931 },
{ 0x0932, 0x0932, 0x0932 },
{ 0x0933, 0x0933, 0x0933 },
{ 0x0934, 0x0934, 0x0934 },
{ 0x0935, 0x0935, 0x0935 },
{ 0x0936, 0x0936, 0x0936 },
{ 0x0937, 0x0937, 0x0937 },
{ 0x0938, 0x0938, 0x0938 },
{ 0x0939, 0x0939, 0x0939 },
{ 0x093C, 0x093C, 0x093C },
{ 0x093D, 0x093D, 0x093D },
{ 0x0941, 0x0941, 0x0941 },
{ 0x0942, 0x0942, 0x0942 },
{ 0x0943, 0x0943, 0x0943 },
{ 0x0944, 0x0944, 0x0944 },
{ 0x0945, 0x0945, 0x0945 },
{ 0x0946, 0x0946, 0x0946 },
{ 0x0947, 0x0947, 0x0947 },
{ 0x0948, 0x0948, 0x0948 },
{ 0x094D, 0x094D, 0x094D },
{ 0x0950, 0x0950, 0x0950 },
{ 0x0951, 0x0951, 0x0951 },
{ 0x0952, 0x0952, 0x0952 },
{ 0x0953, 0x0953, 0x0953 },
{ 0x0954, 0x0954, 0x0954 },
{ 0x0958, 0x0958, 0x0958 },
{ 0x0959, 0x0959, 0x0959 },
{ 0x095A, 0x095A, 0x095A },
{ 0x095B, 0x095B, 0x095B },
{ 0x095C, 0x095C, 0x095C },
{ 0x095D, 0x095D, 0x095D },
{ 0x095E, 0x095E, 0x095E },
{ 0x095F, 0x095F, 0x095F },
{ 0x0960, 0x0960, 0x0960 },
{ 0x0961, 0x0961, 0x0961 },
{ 0x0962, 0x0962, 0x0962 },
{ 0x0963, 0x0963, 0x0963 },
{ 0x097D, 0x097D, 0x097D },
{ 0x0981, 0x0981, 0x0981 },
{ 0x0985, 0x0985, 0x0985 },
{ 0x0986, 0x0986, 0x0986 },
{ 0x0987, 0x0987, 0x0987 },
{ 0x0988, 0x0988, 0x0988 },
{ 0x0989, 0x0989, 0x0989 },
{ 0x098A, 0x098A, 0x098A },
{ 0x098B, 0x098B, 0x098B },
{ 0x098C, 0x098C, 0x098C },
{ 0x098F, 0x098F, 0x098F },
{ 0x0990, 0x0990, 0x0990 },
{ 0x0993, 0x0993, 0x0993 },
{ 0x0994, 0x0994, 0x0994 },
{ 0x0995, 0x0995, 0x0995 },
{ 0x0996, 0x0996, 0x0996 },
{ 0x0997, 0x0997, 0x0997 },
{ 0x0998, 0x0998, 0x0998 },
{ 0x0999, 0x0999, 0x0999 },
{ 0x099A, 0x099A, 0x099A },
{ 0x099B, 0x099B, 0x099B },
{ 0x099C, 0x099C, 0x099C },
{ 0x099D, 0x099D, 0x099D },
{ 0x099E, 0x099E, 0x099E },
{ 0x099F, 0x099F, 0x099F },
{ 0x09A0, 0x09A0, 0x09A0 },
{ 0x09A1, 0x09A1, 0x09A1 },
{ 0x09A2, 0x09A2, 0x09A2 },
{ 0x09A3, 0x09A3, 0x09A3 },
{ 0x09A4, 0x09A4, 0x09A4 },
{ 0x09A5, 0x09A5, 0x09A5 },
{ 0x09A6, 0x09A6, 0x09A6 },
{ 0x09A7, 0x09A7, 0x09A7 },
{ 0x09A8, 0x09A8, 0x09A8 },
{ 0x09AA, 0x09AA, 0x09AA },
{ 0x09AB, 0x09AB, 0x09AB },
{ 0x09AC, 0x09AC, 0x09AC },
{ 0x09AD, 0x09AD, 0x09AD },
{ 0x09AE, 0x09AE, 0x09AE },
{ 0x09AF, 0x09AF, 0x09AF },
{ 0x09B0, 0x09B0, 0x09B0 },
{ 0x09B2, 0x09B2, 0x09B2 },
{ 0x09B6, 0x09B6, 0x09B6 },
{ 0x09B7, 0x09B7, 0x09B7 },
{ 0x09B8, 0x09B8, 0x09B8 },
{ 0x09B9, 0x09B9, 0x09B9 },
{ 0x09BC, 0x09BC, 0x09BC },
{ 0x09BD, 0x09BD, 0x09BD },
{ 0x09C1, 0x09C1, 0x09C1 },
{ 0x09C2, 0x09C2, 0x09C2 },
{ 0x09C3, 0x09C3, 0x09C3 },
{ 0x09C4, 0x09C4, 0x09C4 },
{ 0x09CD, 0x09CD, 0x09CD },
{ 0x09CE, 0x09CE, 0x09CE },
{ 0x09DC, 0x09DC, 0x09DC },
{ 0x09DD, 0x09DD, 0x09DD },
{ 0x09DF, 0x09DF, 0x09DF },
{ 0x09E0, 0x09E0, 0x09E0 },
{ 0x09E1, 0x09E1, 0x09E1 },
{ 0x09E2, 0x09E2, 0x09E2 },
{ 0x09E3, 0x09E3, 0x09E3 },
{ 0x09F0, 0x09F0, 0x09F0 },
{ 0x09F1, 0x09F1, 0x09F1 },
{ 0x0A01, 0x0A01, 0x0A01 },
{ 0x0A02, 0x0A02, 0x0A02 },
{ 0x0A05, 0x0A05, 0x0A05 },
{ 0x0A06, 0x0A06, 0x0A06 },
{ 0x0A07, 0x0A07, 0x0A07 },
{ 0x0A08, 0x0A08, 0x0A08 },
{ 0x0A09, 0x0A09, 0x0A09 },
{ 0x0A0A, 0x0A0A, 0x0A0A },
{ 0x0A0F, 0x0A0F, 0x0A0F },
{ 0x0A10, 0x0A10, 0x0A10 },
{ 0x0A13, 0x0A13, 0x0A13 },
{ 0x0A14, 0x0A14, 0x0A14 },
{ 0x0A15, 0x0A15, 0x0A15 },
{ 0x0A16, 0x0A16, 0x0A16 },
{ 0x0A17, 0x0A17, 0x0A17 },
{ 0x0A18, 0x0A18, 0x0A18 },
{ 0x0A19, 0x0A19, 0x0A19 },
{ 0x0A1A, 0x0A1A, 0x0A1A },
{ 0x0A1B, 0x0A1B, 0x0A1B },
{ 0x0A1C, 0x0A1C, 0x0A1C },
{ 0x0A1D, 0x0A1D, 0x0A1D },
{ 0x0A1E, 0x0A1E, 0x0A1E },
{ 0x0A1F, 0x0A1F, 0x0A1F },
{ 0x0A20, 0x0A20, 0x0A20 },
{ 0x0A21, 0x0A21, 0x0A21 },
{ 0x0A22, 0x0A22, 0x0A22 },
{ 0x0A23, 0x0A23, 0x0A23 },
{ 0x0A24, 0x0A24, 0x0A24 },
{ 0x0A25, 0x0A25, 0x0A25 },
{ 0x0A26, 0x0A26, 0x0A26 },
{ 0x0A27, 0x0A27, 0x0A27 },
{ 0x0A28, 0x0A28, 0x0A28 },
{ 0x0A2A, 0x0A2A, 0x0A2A },
{ 0x0A2B, 0x0A2B, 0x0A2B },
{ 0x0A2C, 0x0A2C, 0x0A2C },
{ 0x0A2D, 0x0A2D, 0x0A2D },
{ 0x0A2E, 0x0A2E, 0x0A2E },
{ 0x0A2F, 0x0A2F, 0x0A2F },
{ 0x0A30, 0x0A30, 0x0A30 },
{ 0x0A32, 0x0A32, 0x0A32 },
{ 0x0A33, 0x0A33, 0x0A33 },
{ 0x0A35, 0x0A35, 0x0A35 },
{ 0x0A36, 0x0A36, 0x0A36 },
{ 0x0A38, 0x0A38, 0x0A38 },
{ 0x0A39, 0x0A39, 0x0A39 },
{ 0x0A3C, 0x0A3C, 0x0A3C },
{ 0x0A41, 0x0A41, 0x0A41 },
{ 0x0A42, 0x0A42, 0x0A42 },
{ 0x0A47, 0x0A47, 0x0A47 },
{ 0x0A48, 0x0A48, 0x0A48 },
{ 0x0A4B, 0x0A4B, 0x0A4B },
{ 0x0A4C, 0x0A4C, 0x0A4C },
{ 0x0A4D, 0x0A4D, 0x0A4D },
{ 0x0A59, 0x0A59, 0x0A59 },
{ 0x0A5A, 0x0A5A, 0x0A5A },
{ 0x0A5B, 0x0A5B, 0x0A5B },
{ 0x0A5C, 0x0A5C, 0x0A5C },
{ 0x0A5E, 0x0A5E, 0x0A5E },
{ 0x0A70, 0x0A70, 0x0A70 },
{ 0x0A71, 0x0A71, 0x0A71 },
{ 0x0A72, 0x0A72, 0x0A72 },
{ 0x0A73, 0x0A73, 0x0A73 },
{ 0x0A74, 0x0A74, 0x0A74 },
{ 0x0A81, 0x0A81, 0x0A81 },
{ 0x0A82, 0x0A82, 0x0A82 },
{ 0x0A85, 0x0A85, 0x0A85 },
{ 0x0A86, 0x0A86, 0x0A86 },
{ 0x0A87, 0x0A87, 0x0A87 },
{ 0x0A88, 0x0A88, 0x0A88 },
{ 0x0A89, 0x0A89, 0x0A89 },
{ 0x0A8A, 0x0A8A, 0x0A8A },
{ 0x0A8B, 0x0A8B, 0x0A8B },
{ 0x0A8C, 0x0A8C, 0x0A8C },
{ 0x0A8D, 0x0A8D, 0x0A8D },
{ 0x0A8F, 0x0A8F, 0x0A8F },
{ 0x0A90, 0x0A90, 0x0A90 },
{ 0x0A91, 0x0A91, 0x0A91 },
{ 0x0A93, 0x0A93, 0x0A93 },
{ 0x0A94, 0x0A94, 0x0A94 },
{ 0x0A95, 0x0A95, 0x0A95 },
{ 0x0A96, 0x0A96, 0x0A96 },
{ 0x0A97, 0x0A97, 0x0A97 },
{ 0x0A98, 0x0A98, 0x0A98 },
{ 0x0A99, 0x0A99, 0x0A99 },
{ 0x0A9A, 0x0A9A, 0x0A9A },
{ 0x0A9B, 0x0A9B, 0x0A9B },
{ 0x0A9C, 0x0A9C, 0x0A9C },
{ 0x0A9D, 0x0A9D, 0x0A9D },
{ 0x0A9E, 0x0A9E, 0x0A9E },
{ 0x0A9F, 0x0A9F, 0x0A9F },
{ 0x0AA0, 0x0AA0, 0x0AA0 },
{ 0x0AA1, 0x0AA1, 0x0AA1 },
{ 0x0AA2, 0x0AA2, 0x0AA2 },
{ 0x0AA3, 0x0AA3, 0x0AA3 },
{ 0x0AA4, 0x0AA4, 0x0AA4 },
{ 0x0AA5, 0x0AA5, 0x0AA5 },
{ 0x0AA6, 0x0AA6, 0x0AA6 },
{ 0x0AA7, 0x0AA7, 0x0AA7 },
{ 0x0AA8, 0x0AA8, 0x0AA8 },
{ 0x0AAA, 0x0AAA, 0x0AAA },
{ 0x0AAB, 0x0AAB, 0x0AAB },
{ 0x0AAC, 0x0AAC, 0x0AAC },
{ 0x0AAD, 0x0AAD, 0x0AAD },
{ 0x0AAE, 0x0AAE, 0x0AAE },
{ 0x0AAF, 0x0AAF, 0x0AAF },
{ 0x0AB0, 0x0AB0, 0x0AB0 },
{ 0x0AB2, 0x0AB2, 0x0AB2 },
{ 0x0AB3, 0x0AB3, 0x0AB3 },
{ 0x0AB5, 0x0AB5, 0x0AB5 },
{ 0x0AB6, 0x0AB6, 0x0AB6 },
{ 0x0AB7, 0x0AB7, 0x0AB7 },
{ 0x0AB8, 0x0AB8, 0x0AB8 },
{ 0x0AB9, 0x0AB9, 0x0AB9 },
{ 0x0ABC, 0x0ABC, 0x0ABC },
{ 0x0ABD, 0x0ABD, 0x0ABD },
{ 0x0AC1, 0x0AC1, 0x0AC1 },
{ 0x0AC2, 0x0AC2, 0x0AC2 },
{ 0x0AC3, 0x0AC3, 0x0AC3 },
{ 0x0AC4, 0x0AC4, 0x0AC4 },
{ 0x0AC5, 0x0AC5, 0x0AC5 },
{ 0x0AC7, 0x0AC7, 0x0AC7 },
{ 0x0AC8, 0x0AC8, 0x0AC8 },
{ 0x0ACD, 0x0ACD, 0x0ACD },
{ 0x0AD0, 0x0AD0, 0x0AD0 },
{ 0x0AE0, 0x0AE0, 0x0AE0 },
{ 0x0AE1, 0x0AE1, 0x0AE1 },
{ 0x0AE2, 0x0AE2, 0x0AE2 },
{ 0x0AE3, 0x0AE3, 0x0AE3 },
{ 0x0B01, 0x0B01, 0x0B01 },
{ 0x0B05, 0x0B05, 0x0B05 },
{ 0x0B06, 0x0B06, 0x0B06 },
{ 0x0B07, 0x0B07, 0x0B07 },
{ 0x0B08, 0x0B08, 0x0B08 },
{ 0x0B09, 0x0B09, 0x0B09 },
{ 0x0B0A, 0x0B0A, 0x0B0A },
{ 0x0B0B, 0x0B0B, 0x0B0B },
{ 0x0B0C, 0x0B0C, 0x0B0C },
{ 0x0B0F, 0x0B0F, 0x0B0F },
{ 0x0B10, 0x0B10, 0x0B10 },
{ 0x0B13, 0x0B13, 0x0B13 },
{ 0x0B14, 0x0B14, 0x0B14 },
{ 0x0B15, 0x0B15, 0x0B15 },
{ 0x0B16, 0x0B16, 0x0B16 },
{ 0x0B17, 0x0B17, 0x0B17 },
{ 0x0B18, 0x0B18, 0x0B18 },
{ 0x0B19, 0x0B19, 0x0B19 },
{ 0x0B1A, 0x0B1A, 0x0B1A },
{ 0x0B1B, 0x0B1B, 0x0B1B },
{ 0x0B1C, 0x0B1C, 0x0B1C },
{ 0x0B1D, 0x0B1D, 0x0B1D },
{ 0x0B1E, 0x0B1E, 0x0B1E },
{ 0x0B1F, 0x0B1F, 0x0B1F },
{ 0x0B20, 0x0B20, 0x0B20 },
{ 0x0B21, 0x0B21, 0x0B21 },
{ 0x0B22, 0x0B22, 0x0B22 },
{ 0x0B23, 0x0B23, 0x0B23 },
{ 0x0B24, 0x0B24, 0x0B24 },
{ 0x0B25, 0x0B25, 0x0B25 },
{ 0x0B26, 0x0B26, 0x0B26 },
{ 0x0B27, 0x0B27, 0x0B27 },
{ 0x0B28, 0x0B28, 0x0B28 },
{ 0x0B2A, 0x0B2A, 0x0B2A },
{ 0x0B2B, 0x0B2B, 0x0B2B },
{ 0x0B2C, 0x0B2C, 0x0B2C },
{ 0x0B2D, 0x0B2D, 0x0B2D },
{ 0x0B2E, 0x0B2E, 0x0B2E },
{ 0x0B2F, 0x0B2F, 0x0B2F },
{ 0x0B30, 0x0B30, 0x0B30 },
{ 0x0B32, 0x0B32, 0x0B32 },
{ 0x0B33, 0x0B33, 0x0B33 },
{ 0x0B35, 0x0B35, 0x0B35 },
{ 0x0B36, 0x0B36, 0x0B36 },
{ 0x0B37, 0x0B37, 0x0B37 },
{ 0x0B38, 0x0B38, 0x0B38 },
{ 0x0B39, 0x0B39, 0x0B39 },
{ 0x0B3C, 0x0B3C, 0x0B3C },
{ 0x0B3D, 0x0B3D, 0x0B3D },
{ 0x0B3F, 0x0B3F, 0x0B3F },
{ 0x0B41, 0x0B41, 0x0B41 },
{ 0x0B42, 0x0B42, 0x0B42 },
{ 0x0B43, 0x0B43, 0x0B43 },
{ 0x0B4D, 0x0B4D, 0x0B4D },
{ 0x0B56, 0x0B56, 0x0B56 },
{ 0x0B5C, 0x0B5C, 0x0B5C },
{ 0x0B5D, 0x0B5D, 0x0B5D },
{ 0x0B5F, 0x0B5F, 0x0B5F },
{ 0x0B60, 0x0B60, 0x0B60 },
{ 0x0B61, 0x0B61, 0x0B61 },
{ 0x0B71, 0x0B71, 0x0B71 },
{ 0x0B82, 0x0B82, 0x0B82 },
{ 0x0B83, 0x0B83, 0x0B83 },
{ 0x0B85, 0x0B85, 0x0B85 },
{ 0x0B86, 0x0B86, 0x0B86 },
{ 0x0B87, 0x0B87, 0x0B87 },
{ 0x0B88, 0x0B88, 0x0B88 },
{ 0x0B89, 0x0B89, 0x0B89 },
{ 0x0B8A, 0x0B8A, 0x0B8A },
{ 0x0B8E, 0x0B8E, 0x0B8E },
{ 0x0B8F, 0x0B8F, 0x0B8F },
{ 0x0B90, 0x0B90, 0x0B90 },
{ 0x0B92, 0x0B92, 0x0B92 },
{ 0x0B93, 0x0B93, 0x0B93 },
{ 0x0B94, 0x0B94, 0x0B94 },
{ 0x0B95, 0x0B95, 0x0B95 },
{ 0x0B99, 0x0B99, 0x0B99 },
{ 0x0B9A, 0x0B9A, 0x0B9A },
{ 0x0B9C, 0x0B9C, 0x0B9C },
{ 0x0B9E, 0x0B9E, 0x0B9E },
{ 0x0B9F, 0x0B9F, 0x0B9F },
{ 0x0BA3, 0x0BA3, 0x0BA3 },
{ 0x0BA4, 0x0BA4, 0x0BA4 },
{ 0x0BA8, 0x0BA8, 0x0BA8 },
{ 0x0BA9, 0x0BA9, 0x0BA9 },
{ 0x0BAA, 0x0BAA, 0x0BAA },
{ 0x0BAE, 0x0BAE, 0x0BAE },
{ 0x0BAF, 0x0BAF, 0x0BAF },
{ 0x0BB0, 0x0BB0, 0x0BB0 },
{ 0x0BB1, 0x0BB1, 0x0BB1 },
{ 0x0BB2, 0x0BB2, 0x0BB2 },
{ 0x0BB3, 0x0BB3, 0x0BB3 },
{ 0x0BB4, 0x0BB4, 0x0BB4 },
{ 0x0BB5, 0x0BB5, 0x0BB5 },
{ 0x0BB6, 0x0BB6, 0x0BB6 },
{ 0x0BB7, 0x0BB7, 0x0BB7 },
{ 0x0BB8, 0x0BB8, 0x0BB8 },
{ 0x0BB9, 0x0BB9, 0x0BB9 },
{ 0x0BC0, 0x0BC0, 0x0BC0 },
{ 0x0BCD, 0x0BCD, 0x0BCD },
{ 0x0C05, 0x0C05, 0x0C05 },
{ 0x0C06, 0x0C06, 0x0C06 },
{ 0x0C07, 0x0C07, 0x0C07 },
{ 0x0C08, 0x0C08, 0x0C08 },
{ 0x0C09, 0x0C09, 0x0C09 },
{ 0x0C0A, 0x0C0A, 0x0C0A },
{ 0x0C0B, 0x0C0B, 0x0C0B },
{ 0x0C0C, 0x0C0C, 0x0C0C },
{ 0x0C0E, 0x0C0E, 0x0C0E },
{ 0x0C0F, 0x0C0F, 0x0C0F },
{ 0x0C10, 0x0C10, 0x0C10 },
{ 0x0C12, 0x0C12, 0x0C12 },
{ 0x0C13, 0x0C13, 0x0C13 },
{ 0x0C14, 0x0C14, 0x0C14 },
{ 0x0C15, 0x0C15, 0x0C15 },
{ 0x0C16, 0x0C16, 0x0C16 },
{ 0x0C17, 0x0C17, 0x0C17 },
{ 0x0C18, 0x0C18, 0x0C18 },
{ 0x0C19, 0x0C19, 0x0C19 },
{ 0x0C1A, 0x0C1A, 0x0C1A },
{ 0x0C1B, 0x0C1B, 0x0C1B },
{ 0x0C1C, 0x0C1C, 0x0C1C },
{ 0x0C1D, 0x0C1D, 0x0C1D },
{ 0x0C1E, 0x0C1E, 0x0C1E },
{ 0x0C1F, 0x0C1F, 0x0C1F },
{ 0x0C20, 0x0C20, 0x0C20 },
{ 0x0C21, 0x0C21, 0x0C21 },
{ 0x0C22, 0x0C22, 0x0C22 },
{ 0x0C23, 0x0C23, 0x0C23 },
{ 0x0C24, 0x0C24, 0x0C24 },
{ 0x0C25, 0x0C25, 0x0C25 },
{ 0x0C26, 0x0C26, 0x0C26 },
{ 0x0C27, 0x0C27, 0x0C27 },
{ 0x0C28, 0x0C28, 0x0C28 },
{ 0x0C2A, 0x0C2A, 0x0C2A },
{ 0x0C2B, 0x0C2B, 0x0C2B },
{ 0x0C2C, 0x0C2C, 0x0C2C },
{ 0x0C2D, 0x0C2D, 0x0C2D },
{ 0x0C2E, 0x0C2E, 0x0C2E },
{ 0x0C2F, 0x0C2F, 0x0C2F },
{ 0x0C30, 0x0C30, 0x0C30 },
{ 0x0C31, 0x0C31, 0x0C31 },
{ 0x0C32, 0x0C32, 0x0C32 },
{ 0x0C33, 0x0C33, 0x0C33 },
{ 0x0C35, 0x0C35, 0x0C35 },
{ 0x0C36, 0x0C36, 0x0C36 },
{ 0x0C37, 0x0C37, 0x0C37 },
{ 0x0C38, 0x0C38, 0x0C38 },
{ 0x0C39, 0x0C39, 0x0C39 },
{ 0x0C3E, 0x0C3E, 0x0C3E },
{ 0x0C3F, 0x0C3F, 0x0C3F },
{ 0x0C40, 0x0C40, 0x0C40 },
{ 0x0C46, 0x0C46, 0x0C46 },
{ 0x0C47, 0x0C47, 0x0C47 },
{ 0x0C48, 0x0C48, 0x0C48 },
{ 0x0C4A, 0x0C4A, 0x0C4A },
{ 0x0C4B, 0x0C4B, 0x0C4B },
{ 0x0C4C, 0x0C4C, 0x0C4C },
{ 0x0C4D, 0x0C4D, 0x0C4D },
{ 0x0C55, 0x0C55, 0x0C55 },
{ 0x0C56, 0x0C56, 0x0C56 },
{ 0x0C60, 0x0C60, 0x0C60 },
{ 0x0C61, 0x0C61, 0x0C61 },
{ 0x0C85, 0x0C85, 0x0C85 },
{ 0x0C86, 0x0C86, 0x0C86 },
{ 0x0C87, 0x0C87, 0x0C87 },
{ 0x0C88, 0x0C88, 0x0C88 },
{ 0x0C89, 0x0C89, 0x0C89 },
{ 0x0C8A, 0x0C8A, 0x0C8A },
{ 0x0C8B, 0x0C8B, 0x0C8B },
{ 0x0C8C, 0x0C8C, 0x0C8C },
{ 0x0C8E, 0x0C8E, 0x0C8E },
{ 0x0C8F, 0x0C8F, 0x0C8F },
{ 0x0C90, 0x0C90, 0x0C90 },
{ 0x0C92, 0x0C92, 0x0C92 },
{ 0x0C93, 0x0C93, 0x0C93 },
{ 0x0C94, 0x0C94, 0x0C94 },
{ 0x0C95, 0x0C95, 0x0C95 },
{ 0x0C96, 0x0C96, 0x0C96 },
{ 0x0C97, 0x0C97, 0x0C97 },
{ 0x0C98, 0x0C98, 0x0C98 },
{ 0x0C99, 0x0C99, 0x0C99 },
{ 0x0C9A, 0x0C9A, 0x0C9A },
{ 0x0C9B, 0x0C9B, 0x0C9B },
{ 0x0C9C, 0x0C9C, 0x0C9C },
{ 0x0C9D, 0x0C9D, 0x0C9D },
{ 0x0C9E, 0x0C9E, 0x0C9E },
{ 0x0C9F, 0x0C9F, 0x0C9F },
{ 0x0CA0, 0x0CA0, 0x0CA0 },
{ 0x0CA1, 0x0CA1, 0x0CA1 },
{ 0x0CA2, 0x0CA2, 0x0CA2 },
{ 0x0CA3, 0x0CA3, 0x0CA3 },
{ 0x0CA4, 0x0CA4, 0x0CA4 },
{ 0x0CA5, 0x0CA5, 0x0CA5 },
{ 0x0CA6, 0x0CA6, 0x0CA6 },
{ 0x0CA7, 0x0CA7, 0x0CA7 },
{ 0x0CA8, 0x0CA8, 0x0CA8 },
{ 0x0CAA, 0x0CAA, 0x0CAA },
{ 0x0CAB, 0x0CAB, 0x0CAB },
{ 0x0CAC, 0x0CAC, 0x0CAC },
{ 0x0CAD, 0x0CAD, 0x0CAD },
{ 0x0CAE, 0x0CAE, 0x0CAE },
{ 0x0CAF, 0x0CAF, 0x0CAF },
{ 0x0CB0, 0x0CB0, 0x0CB0 },
{ 0x0CB1, 0x0CB1, 0x0CB1 },
{ 0x0CB2, 0x0CB2, 0x0CB2 },
{ 0x0CB3, 0x0CB3, 0x0CB3 },
{ 0x0CB5, 0x0CB5, 0x0CB5 },
{ 0x0CB6, 0x0CB6, 0x0CB6 },
{ 0x0CB7, 0x0CB7, 0x0CB7 },
{ 0x0CB8, 0x0CB8, 0x0CB8 },
{ 0x0CB9, 0x0CB9, 0x0CB9 },
{ 0x0CBC, 0x0CBC, 0x0CBC },
{ 0x0CBD, 0x0CBD, 0x0CBD },
{ 0x0CBF, 0x0CBF, 0x0CBF },
{ 0x0CC6, 0x0CC6, 0x0CC6 },
{ 0x0CCC, 0x0CCC, 0x0CCC },
{ 0x0CCD, 0x0CCD, 0x0CCD },
{ 0x0CDE, 0x0CDE, 0x0CDE },
{ 0x0CE0, 0x0CE0, 0x0CE0 },
{ 0x0CE1, 0x0CE1, 0x0CE1 },
{ 0x0D05, 0x0D05, 0x0D05 },
{ 0x0D06, 0x0D06, 0x0D06 },
{ 0x0D07, 0x0D07, 0x0D07 },
{ 0x0D08, 0x0D08, 0x0D08 },
{ 0x0D09, 0x0D09, 0x0D09 },
{ 0x0D0A, 0x0D0A, 0x0D0A },
{ 0x0D0B, 0x0D0B, 0x0D0B },
{ 0x0D0C, 0x0D0C, 0x0D0C },
{ 0x0D0E, 0x0D0E, 0x0D0E },
{ 0x0D0F, 0x0D0F, 0x0D0F },
{ 0x0D10, 0x0D10, 0x0D10 },
{ 0x0D12, 0x0D12, 0x0D12 },
{ 0x0D13, 0x0D13, 0x0D13 },
{ 0x0D14, 0x0D14, 0x0D14 },
{ 0x0D15, 0x0D15, 0x0D15 },
{ 0x0D16, 0x0D16, 0x0D16 },
{ 0x0D17, 0x0D17, 0x0D17 },
{ 0x0D18, 0x0D18, 0x0D18 },
{ 0x0D19, 0x0D19, 0x0D19 },
{ 0x0D1A, 0x0D1A, 0x0D1A },
{ 0x0D1B, 0x0D1B, 0x0D1B },
{ 0x0D1C, 0x0D1C, 0x0D1C },
{ 0x0D1D, 0x0D1D, 0x0D1D },
{ 0x0D1E, 0x0D1E, 0x0D1E },
{ 0x0D1F, 0x0D1F, 0x0D1F },
{ 0x0D20, 0x0D20, 0x0D20 },
{ 0x0D21, 0x0D21, 0x0D21 },
{ 0x0D22, 0x0D22, 0x0D22 },
{ 0x0D23, 0x0D23, 0x0D23 },
{ 0x0D24, 0x0D24, 0x0D24 },
{ 0x0D25, 0x0D25, 0x0D25 },
{ 0x0D26, 0x0D26, 0x0D26 },
{ 0x0D27, 0x0D27, 0x0D27 },
{ 0x0D28, 0x0D28, 0x0D28 },
{ 0x0D2A, 0x0D2A, 0x0D2A },
{ 0x0D2B, 0x0D2B, 0x0D2B },
{ 0x0D2C, 0x0D2C, 0x0D2C },
{ 0x0D2D, 0x0D2D, 0x0D2D },
{ 0x0D2E, 0x0D2E, 0x0D2E },
{ 0x0D2F, 0x0D2F, 0x0D2F },
{ 0x0D30, 0x0D30, 0x0D30 },
{ 0x0D31, 0x0D31, 0x0D31 },
{ 0x0D32, 0x0D32, 0x0D32 },
{ 0x0D33, 0x0D33, 0x0D33 },
{ 0x0D34, 0x0D34, 0x0D34 },
{ 0x0D35, 0x0D35, 0x0D35 },
{ 0x0D36, 0x0D36, 0x0D36 },
{ 0x0D37, 0x0D37, 0x0D37 },
{ 0x0D38, 0x0D38, 0x0D38 },
{ 0x0D39, 0x0D39, 0x0D39 },
{ 0x0D41, 0x0D41, 0x0D41 },
{ 0x0D42, 0x0D42, 0x0D42 },
{ 0x0D43, 0x0D43, 0x0D43 },
{ 0x0D4D, 0x0D4D, 0x0D4D },
{ 0x0D60, 0x0D60, 0x0D60 },
{ 0x0D61, 0x0D61, 0x0D61 },
{ 0x0D85, 0x0D85, 0x0D85 },
{ 0x0D86, 0x0D86, 0x0D86 },
{ 0x0D87, 0x0D87, 0x0D87 },
{ 0x0D88, 0x0D88, 0x0D88 },
{ 0x0D89, 0x0D89, 0x0D89 },
{ 0x0D8A, 0x0D8A, 0x0D8A },
{ 0x0D8B, 0x0D8B, 0x0D8B },
{ 0x0D8C, 0x0D8C, 0x0D8C },
{ 0x0D8D, 0x0D8D, 0x0D8D },
{ 0x0D8E, 0x0D8E, 0x0D8E },
{ 0x0D8F, 0x0D8F, 0x0D8F },
{ 0x0D90, 0x0D90, 0x0D90 },
{ 0x0D91, 0x0D91, 0x0D91 },
{ 0x0D92, 0x0D92, 0x0D92 },
{ 0x0D93, 0x0D93, 0x0D93 },
{ 0x0D94, 0x0D94, 0x0D94 },
{ 0x0D95, 0x0D95, 0x0D95 },
{ 0x0D96, 0x0D96, 0x0D96 },
{ 0x0D9A, 0x0D9A, 0x0D9A },
{ 0x0D9B, 0x0D9B, 0x0D9B },
{ 0x0D9C, 0x0D9C, 0x0D9C },
{ 0x0D9D, 0x0D9D, 0x0D9D },
{ 0x0D9E, 0x0D9E, 0x0D9E },
{ 0x0D9F, 0x0D9F, 0x0D9F },
{ 0x0DA0, 0x0DA0, 0x0DA0 },
{ 0x0DA1, 0x0DA1, 0x0DA1 },
{ 0x0DA2, 0x0DA2, 0x0DA2 },
{ 0x0DA3, 0x0DA3, 0x0DA3 },
{ 0x0DA4, 0x0DA4, 0x0DA4 },
{ 0x0DA5, 0x0DA5, 0x0DA5 },
{ 0x0DA6, 0x0DA6, 0x0DA6 },
{ 0x0DA7, 0x0DA7, 0x0DA7 },
{ 0x0DA8, 0x0DA8, 0x0DA8 },
{ 0x0DA9, 0x0DA9, 0x0DA9 },
{ 0x0DAA, 0x0DAA, 0x0DAA },
{ 0x0DAB, 0x0DAB, 0x0DAB },
{ 0x0DAC, 0x0DAC, 0x0DAC },
{ 0x0DAD, 0x0DAD, 0x0DAD },
{ 0x0DAE, 0x0DAE, 0x0DAE },
{ 0x0DAF, 0x0DAF, 0x0DAF },
{ 0x0DB0, 0x0DB0, 0x0DB0 },
{ 0x0DB1, 0x0DB1, 0x0DB1 },
{ 0x0DB3, 0x0DB3, 0x0DB3 },
{ 0x0DB4, 0x0DB4, 0x0DB4 },
{ 0x0DB5, 0x0DB5, 0x0DB5 },
{ 0x0DB6, 0x0DB6, 0x0DB6 },
{ 0x0DB7, 0x0DB7, 0x0DB7 },
{ 0x0DB8, 0x0DB8, 0x0DB8 },
{ 0x0DB9, 0x0DB9, 0x0DB9 },
{ 0x0DBA, 0x0DBA, 0x0DBA },
{ 0x0DBB, 0x0DBB, 0x0DBB },
{ 0x0DBD, 0x0DBD, 0x0DBD },
{ 0x0DC0, 0x0DC0, 0x0DC0 },
{ 0x0DC1, 0x0DC1, 0x0DC1 },
{ 0x0DC2, 0x0DC2, 0x0DC2 },
{ 0x0DC3, 0x0DC3, 0x0DC3 },
{ 0x0DC4, 0x0DC4, 0x0DC4 },
{ 0x0DC5, 0x0DC5, 0x0DC5 },
{ 0x0DC6, 0x0DC6, 0x0DC6 },
{ 0x0DCA, 0x0DCA, 0x0DCA },
{ 0x0DD2, 0x0DD2, 0x0DD2 },
{ 0x0DD3, 0x0DD3, 0x0DD3 },
{ 0x0DD4, 0x0DD4, 0x0DD4 },
{ 0x0DD6, 0x0DD6, 0x0DD6 },
{ 0x0E01, 0x0E01, 0x0E01 },
{ 0x0E02, 0x0E02, 0x0E02 },
{ 0x0E03, 0x0E03, 0x0E03 },
{ 0x0E04, 0x0E04, 0x0E04 },
{ 0x0E05, 0x0E05, 0x0E05 },
{ 0x0E06, 0x0E06, 0x0E06 },
{ 0x0E07, 0x0E07, 0x0E07 },
{ 0x0E08, 0x0E08, 0x0E08 },
{ 0x0E09, 0x0E09, 0x0E09 },
{ 0x0E0A, 0x0E0A, 0x0E0A },
{ 0x0E0B, 0x0E0B, 0x0E0B },
{ 0x0E0C, 0x0E0C, 0x0E0C },
{ 0x0E0D, 0x0E0D, 0x0E0D },
{ 0x0E0E, 0x0E0E, 0x0E0E },
{ 0x0E0F, 0x0E0F, 0x0E0F },
{ 0x0E10, 0x0E10, 0x0E10 },
{ 0x0E11, 0x0E11, 0x0E11 },
{ 0x0E12, 0x0E12, 0x0E12 },
{ 0x0E13, 0x0E13, 0x0E13 },
{ 0x0E14, 0x0E14, 0x0E14 },
{ 0x0E15, 0x0E15, 0x0E15 },
{ 0x0E16, 0x0E16, 0x0E16 },
{ 0x0E17, 0x0E17, 0x0E17 },
{ 0x0E18, 0x0E18, 0x0E18 },
{ 0x0E19, 0x0E19, 0x0E19 },
{ 0x0E1A, 0x0E1A, 0x0E1A },
{ 0x0E1B, 0x0E1B, 0x0E1B },
{ 0x0E1C, 0x0E1C, 0x0E1C },
{ 0x0E1D, 0x0E1D, 0x0E1D },
{ 0x0E1E, 0x0E1E, 0x0E1E },
{ 0x0E1F, 0x0E1F, 0x0E1F },
{ 0x0E20, 0x0E20, 0x0E20 },
{ 0x0E21, 0x0E21, 0x0E21 },
{ 0x0E22, 0x0E22, 0x0E22 },
{ 0x0E23, 0x0E23, 0x0E23 },
{ 0x0E24, 0x0E24, 0x0E24 },
{ 0x0E25, 0x0E25, 0x0E25 },
{ 0x0E26, 0x0E26, 0x0E26 },
{ 0x0E27, 0x0E27, 0x0E27 },
{ 0x0E28, 0x0E28, 0x0E28 },
{ 0x0E29, 0x0E29, 0x0E29 },
{ 0x0E2A, 0x0E2A, 0x0E2A },
{ 0x0E2B, 0x0E2B, 0x0E2B },
{ 0x0E2C, 0x0E2C, 0x0E2C },
{ 0x0E2D, 0x0E2D, 0x0E2D },
{ 0x0E2E, 0x0E2E, 0x0E2E },
{ 0x0E2F, 0x0E2F, 0x0E2F },
{ 0x0E30, 0x0E30, 0x0E30 },
{ 0x0E31, 0x0E31, 0x0E31 },
{ 0x0E32, 0x0E32, 0x0E32 },
{ 0x0E33, 0x0E33, 0x0E33 },
{ 0x0E34, 0x0E34, 0x0E34 },
{ 0x0E35, 0x0E35, 0x0E35 },
{ 0x0E36, 0x0E36, 0x0E36 },
{ 0x0E37, 0x0E37, 0x0E37 },
{ 0x0E38, 0x0E38, 0x0E38 },
{ 0x0E39, 0x0E39, 0x0E39 },
{ 0x0E3A, 0x0E3A, 0x0E3A },
{ 0x0E40, 0x0E40, 0x0E40 },
{ 0x0E41, 0x0E41, 0x0E41 },
{ 0x0E42, 0x0E42, 0x0E42 },
{ 0x0E43, 0x0E43, 0x0E43 },
{ 0x0E44, 0x0E44, 0x0E44 },
{ 0x0E45, 0x0E45, 0x0E45 },
{ 0x0E46, 0x0E46, 0x0E46 },
{ 0x0E47, 0x0E47, 0x0E47 },
{ 0x0E48, 0x0E48, 0x0E48 },
{ 0x0E49, 0x0E49, 0x0E49 },
{ 0x0E4A, 0x0E4A, 0x0E4A },
{ 0x0E4B, 0x0E4B, 0x0E4B },
{ 0x0E4C, 0x0E4C, 0x0E4C },
{ 0x0E4D, 0x0E4D, 0x0E4D },
{ 0x0E4E, 0x0E4E, 0x0E4E },
{ 0x0E81, 0x0E81, 0x0E81 },
{ 0x0E82, 0x0E82, 0x0E82 },
{ 0x0E84, 0x0E84, 0x0E84 },
{ 0x0E87, 0x0E87, 0x0E87 },
{ 0x0E88, 0x0E88, 0x0E88 },
{ 0x0E8A, 0x0E8A, 0x0E8A },
{ 0x0E8D, 0x0E8D, 0x0E8D },
{ 0x0E94, 0x0E94, 0x0E94 },
{ 0x0E95, 0x0E95, 0x0E95 },
{ 0x0E96, 0x0E96, 0x0E96 },
{ 0x0E97, 0x0E97, 0x0E97 },
{ 0x0E99, 0x0E99, 0x0E99 },
{ 0x0E9A, 0x0E9A, 0x0E9A },
{ 0x0E9B, 0x0E9B, 0x0E9B },
{ 0x0E9C, 0x0E9C, 0x0E9C },
{ 0x0E9D, 0x0E9D, 0x0E9D },
{ 0x0E9E, 0x0E9E, 0x0E9E },
{ 0x0E9F, 0x0E9F, 0x0E9F },
{ 0x0EA1, 0x0EA1, 0x0EA1 },
{ 0x0EA2, 0x0EA2, 0x0EA2 },
{ 0x0EA3, 0x0EA3, 0x0EA3 },
{ 0x0EA5, 0x0EA5, 0x0EA5 },
{ 0x0EA7, 0x0EA7, 0x0EA7 },
{ 0x0EAA, 0x0EAA, 0x0EAA },
{ 0x0EAB, 0x0EAB, 0x0EAB },
{ 0x0EAD, 0x0EAD, 0x0EAD },
{ 0x0EAE, 0x0EAE, 0x0EAE },
{ 0x0EAF, 0x0EAF, 0x0EAF },
{ 0x0EB0, 0x0EB0, 0x0EB0 },
{ 0x0EB1, 0x0EB1, 0x0EB1 },
{ 0x0EB2, 0x0EB2, 0x0EB2 },
{ 0x0EB3, 0x0EB3, 0x0EB3 },
{ 0x0EB4, 0x0EB4, 0x0EB4 },
{ 0x0EB5, 0x0EB5, 0x0EB5 },
{ 0x0EB6, 0x0EB6, 0x0EB6 },
{ 0x0EB7, 0x0EB7, 0x0EB7 },
{ 0x0EB8, 0x0EB8, 0x0EB8 },
{ 0x0EB9, 0x0EB9, 0x0EB9 },
{ 0x0EBB, 0x0EBB, 0x0EBB },
{ 0x0EBC, 0x0EBC, 0x0EBC },
{ 0x0EBD, 0x0EBD, 0x0EBD },
{ 0x0EC0, 0x0EC0, 0x0EC0 },
{ 0x0EC1, 0x0EC1, 0x0EC1 },
{ 0x0EC2, 0x0EC2, 0x0EC2 },
{ 0x0EC3, 0x0EC3, 0x0EC3 },
{ 0x0EC4, 0x0EC4, 0x0EC4 },
{ 0x0EC6, 0x0EC6, 0x0EC6 },
{ 0x0EC8, 0x0EC8, 0x0EC8 },
{ 0x0EC9, 0x0EC9, 0x0EC9 },
{ 0x0ECA, 0x0ECA, 0x0ECA },
{ 0x0ECB, 0x0ECB, 0x0ECB },
{ 0x0ECC, 0x0ECC, 0x0ECC },
{ 0x0ECD, 0x0ECD, 0x0ECD },
{ 0x0EDC, 0x0EDC, 0x0EDC },
{ 0x0EDD, 0x0EDD, 0x0EDD },
{ 0x0F00, 0x0F00, 0x0F00 },
{ 0x0F18, 0x0F18, 0x0F18 },
{ 0x0F19, 0x0F19, 0x0F19 },
{ 0x0F35, 0x0F35, 0x0F35 },
{ 0x0F37, 0x0F37, 0x0F37 },
{ 0x0F39, 0x0F39, 0x0F39 },
{ 0x0F40, 0x0F40, 0x0F40 },
{ 0x0F41, 0x0F41, 0x0F41 },
{ 0x0F42, 0x0F42, 0x0F42 },
{ 0x0F43, 0x0F43, 0x0F43 },
{ 0x0F44, 0x0F44, 0x0F44 },
{ 0x0F45, 0x0F45, 0x0F45 },
{ 0x0F46, 0x0F46, 0x0F46 },
{ 0x0F47, 0x0F47, 0x0F47 },
{ 0x0F49, 0x0F49, 0x0F49 },
{ 0x0F4A, 0x0F4A, 0x0F4A },
{ 0x0F4B, 0x0F4B, 0x0F4B },
{ 0x0F4C, 0x0F4C, 0x0F4C },
{ 0x0F4D, 0x0F4D, 0x0F4D },
{ 0x0F4E, 0x0F4E, 0x0F4E },
{ 0x0F4F, 0x0F4F, 0x0F4F },
{ 0x0F50, 0x0F50, 0x0F50 },
{ 0x0F51, 0x0F51, 0x0F51 },
{ 0x0F52, 0x0F52, 0x0F52 },
{ 0x0F53, 0x0F53, 0x0F53 },
{ 0x0F54, 0x0F54, 0x0F54 },
{ 0x0F55, 0x0F55, 0x0F55 },
{ 0x0F56, 0x0F56, 0x0F56 },
{ 0x0F57, 0x0F57, 0x0F57 },
{ 0x0F58, 0x0F58, 0x0F58 },
{ 0x0F59, 0x0F59, 0x0F59 },
{ 0x0F5A, 0x0F5A, 0x0F5A },
{ 0x0F5B, 0x0F5B, 0x0F5B },
{ 0x0F5C, 0x0F5C, 0x0F5C },
{ 0x0F5D, 0x0F5D, 0x0F5D },
{ 0x0F5E, 0x0F5E, 0x0F5E },
{ 0x0F5F, 0x0F5F, 0x0F5F },
{ 0x0F60, 0x0F60, 0x0F60 },
{ 0x0F61, 0x0F61, 0x0F61 },
{ 0x0F62, 0x0F62, 0x0F62 },
{ 0x0F63, 0x0F63, 0x0F63 },
{ 0x0F64, 0x0F64, 0x0F64 },
{ 0x0F65, 0x0F65, 0x0F65 },
{ 0x0F66, 0x0F66, 0x0F66 },
{ 0x0F67, 0x0F67, 0x0F67 },
{ 0x0F68, 0x0F68, 0x0F68 },
{ 0x0F69, 0x0F69, 0x0F69 },
{ 0x0F6A, 0x0F6A, 0x0F6A },
{ 0x0F71, 0x0F71, 0x0F71 },
{ 0x0F72, 0x0F72, 0x0F72 },
{ 0x0F73, 0x0F73, 0x0F73 },
{ 0x0F74, 0x0F74, 0x0F74 },
{ 0x0F75, 0x0F75, 0x0F75 },
{ 0x0F76, 0x0F76, 0x0F76 },
{ 0x0F77, 0x0F77, 0x0F77 },
{ 0x0F78, 0x0F78, 0x0F78 },
{ 0x0F79, 0x0F79, 0x0F79 },
{ 0x0F7A, 0x0F7A, 0x0F7A },
{ 0x0F7B, 0x0F7B, 0x0F7B },
{ 0x0F7C, 0x0F7C, 0x0F7C },
{ 0x0F7D, 0x0F7D, 0x0F7D },
{ 0x0F7E, 0x0F7E, 0x0F7E },
{ 0x0F80, 0x0F80, 0x0F80 },
{ 0x0F81, 0x0F81, 0x0F81 },
{ 0x0F82, 0x0F82, 0x0F82 },
{ 0x0F83, 0x0F83, 0x0F83 },
{ 0x0F84, 0x0F84, 0x0F84 },
{ 0x0F86, 0x0F86, 0x0F86 },
{ 0x0F87, 0x0F87, 0x0F87 },
{ 0x0F88, 0x0F88, 0x0F88 },
{ 0x0F89, 0x0F89, 0x0F89 },
{ 0x0F8A, 0x0F8A, 0x0F8A },
{ 0x0F8B, 0x0F8B, 0x0F8B },
{ 0x0F90, 0x0F90, 0x0F90 },
{ 0x0F91, 0x0F91, 0x0F91 },
{ 0x0F92, 0x0F92, 0x0F92 },
{ 0x0F93, 0x0F93, 0x0F93 },
{ 0x0F94, 0x0F94, 0x0F94 },
{ 0x0F95, 0x0F95, 0x0F95 },
{ 0x0F96, 0x0F96, 0x0F96 },
{ 0x0F97, 0x0F97, 0x0F97 },
{ 0x0F99, 0x0F99, 0x0F99 },
{ 0x0F9A, 0x0F9A, 0x0F9A },
{ 0x0F9B, 0x0F9B, 0x0F9B },
{ 0x0F9C, 0x0F9C, 0x0F9C },
{ 0x0F9D, 0x0F9D, 0x0F9D },
{ 0x0F9E, 0x0F9E, 0x0F9E },
{ 0x0F9F, 0x0F9F, 0x0F9F },
{ 0x0FA0, 0x0FA0, 0x0FA0 },
{ 0x0FA1, 0x0FA1, 0x0FA1 },
{ 0x0FA2, 0x0FA2, 0x0FA2 },
{ 0x0FA3, 0x0FA3, 0x0FA3 },
{ 0x0FA4, 0x0FA4, 0x0FA4 },
{ 0x0FA5, 0x0FA5, 0x0FA5 },
{ 0x0FA6, 0x0FA6, 0x0FA6 },
{ 0x0FA7, 0x0FA7, 0x0FA7 },
{ 0x0FA8, 0x0FA8, 0x0FA8 },
{ 0x0FA9, 0x0FA9, 0x0FA9 },
{ 0x0FAA, 0x0FAA, 0x0FAA },
{ 0x0FAB, 0x0FAB, 0x0FAB },
{ 0x0FAC, 0x0FAC, 0x0FAC },
{ 0x0FAD, 0x0FAD, 0x0FAD },
{ 0x0FAE, 0x0FAE, 0x0FAE },
{ 0x0FAF, 0x0FAF, 0x0FAF },
{ 0x0FB0, 0x0FB0, 0x0FB0 },
{ 0x0FB1, 0x0FB1, 0x0FB1 },
{ 0x0FB2, 0x0FB2, 0x0FB2 },
{ 0x0FB3, 0x0FB3, 0x0FB3 },
{ 0x0FB4, 0x0FB4, 0x0FB4 },
{ 0x0FB5, 0x0FB5, 0x0FB5 },
{ 0x0FB6, 0x0FB6, 0x0FB6 },
{ 0x0FB7, 0x0FB7, 0x0FB7 },
{ 0x0FB8, 0x0FB8, 0x0FB8 },
{ 0x0FB9, 0x0FB9, 0x0FB9 },
{ 0x0FBA, 0x0FBA, 0x0FBA },
{ 0x0FBB, 0x0FBB, 0x0FBB },
{ 0x0FBC, 0x0FBC, 0x0FBC },
{ 0x0FC6, 0x0FC6, 0x0FC6 },
{ 0x1000, 0x1000, 0x1000 },
{ 0x1001, 0x1001, 0x1001 },
{ 0x1002, 0x1002, 0x1002 },
{ 0x1003, 0x1003, 0x1003 },
{ 0x1004, 0x1004, 0x1004 },
{ 0x1005, 0x1005, 0x1005 },
{ 0x1006, 0x1006, 0x1006 },
{ 0x1007, 0x1007, 0x1007 },
{ 0x1008, 0x1008, 0x1008 },
{ 0x1009, 0x1009, 0x1009 },
{ 0x100A, 0x100A, 0x100A },
{ 0x100B, 0x100B, 0x100B },
{ 0x100C, 0x100C, 0x100C },
{ 0x100D, 0x100D, 0x100D },
{ 0x100E, 0x100E, 0x100E },
{ 0x100F, 0x100F, 0x100F },
{ 0x1010, 0x1010, 0x1010 },
{ 0x1011, 0x1011, 0x1011 },
{ 0x1012, 0x1012, 0x1012 },
{ 0x1013, 0x1013, 0x1013 },
{ 0x1014, 0x1014, 0x1014 },
{ 0x1015, 0x1015, 0x1015 },
{ 0x1016, 0x1016, 0x1016 },
{ 0x1017, 0x1017, 0x1017 },
{ 0x1018, 0x1018, 0x1018 },
{ 0x1019, 0x1019, 0x1019 },
{ 0x101A, 0x101A, 0x101A },
{ 0x101B, 0x101B, 0x101B },
{ 0x101C, 0x101C, 0x101C },
{ 0x101D, 0x101D, 0x101D },
{ 0x101E, 0x101E, 0x101E },
{ 0x101F, 0x101F, 0x101F },
{ 0x1020, 0x1020, 0x1020 },
{ 0x1021, 0x1021, 0x1021 },
{ 0x1023, 0x1023, 0x1023 },
{ 0x1024, 0x1024, 0x1024 },
{ 0x1025, 0x1025, 0x1025 },
{ 0x1026, 0x1026, 0x1026 },
{ 0x1027, 0x1027, 0x1027 },
{ 0x1029, 0x1029, 0x1029 },
{ 0x102A, 0x102A, 0x102A },
{ 0x102D, 0x102D, 0x102D },
{ 0x102E, 0x102E, 0x102E },
{ 0x102F, 0x102F, 0x102F },
{ 0x1030, 0x1030, 0x1030 },
{ 0x1032, 0x1032, 0x1032 },
{ 0x1036, 0x1036, 0x1036 },
{ 0x1037, 0x1037, 0x1037 },
{ 0x1039, 0x1039, 0x1039 },
{ 0x1050, 0x1050, 0x1050 },
{ 0x1051, 0x1051, 0x1051 },
{ 0x1052, 0x1052, 0x1052 },
{ 0x1053, 0x1053, 0x1053 },
{ 0x1054, 0x1054, 0x1054 },
{ 0x1055, 0x1055, 0x1055 },
{ 0x1058, 0x1058, 0x1058 },
{ 0x1059, 0x1059, 0x1059 },
{ 0x10A0, 0x10A0, 0x2D00 },
{ 0x10A1, 0x10A1, 0x2D01 },
{ 0x10A2, 0x10A2, 0x2D02 },
{ 0x10A3, 0x10A3, 0x2D03 },
{ 0x10A4, 0x10A4, 0x2D04 },
{ 0x10A5, 0x10A5, 0x2D05 },
{ 0x10A6, 0x10A6, 0x2D06 },
{ 0x10A7, 0x10A7, 0x2D07 },
{ 0x10A8, 0x10A8, 0x2D08 },
{ 0x10A9, 0x10A9, 0x2D09 },
{ 0x10AA, 0x10AA, 0x2D0A },
{ 0x10AB, 0x10AB, 0x2D0B },
{ 0x10AC, 0x10AC, 0x2D0C },
{ 0x10AD, 0x10AD, 0x2D0D },
{ 0x10AE, 0x10AE, 0x2D0E },
{ 0x10AF, 0x10AF, 0x2D0F },
{ 0x10B0, 0x10B0, 0x2D10 },
{ 0x10B1, 0x10B1, 0x2D11 },
{ 0x10B2, 0x10B2, 0x2D12 },
{ 0x10B3, 0x10B3, 0x2D13 },
{ 0x10B4, 0x10B4, 0x2D14 },
{ 0x10B5, 0x10B5, 0x2D15 },
{ 0x10B6, 0x10B6, 0x2D16 },
{ 0x10B7, 0x10B7, 0x2D17 },
{ 0x10B8, 0x10B8, 0x2D18 },
{ 0x10B9, 0x10B9, 0x2D19 },
{ 0x10BA, 0x10BA, 0x2D1A },
{ 0x10BB, 0x10BB, 0x2D1B },
{ 0x10BC, 0x10BC, 0x2D1C },
{ 0x10BD, 0x10BD, 0x2D1D },
{ 0x10BE, 0x10BE, 0x2D1E },
{ 0x10BF, 0x10BF, 0x2D1F },
{ 0x10C0, 0x10C0, 0x2D20 },
{ 0x10C1, 0x10C1, 0x2D21 },
{ 0x10C2, 0x10C2, 0x2D22 },
{ 0x10C3, 0x10C3, 0x2D23 },
{ 0x10C4, 0x10C4, 0x2D24 },
{ 0x10C5, 0x10C5, 0x2D25 },
{ 0x10D0, 0x10D0, 0x10D0 },
{ 0x10D1, 0x10D1, 0x10D1 },
{ 0x10D2, 0x10D2, 0x10D2 },
{ 0x10D3, 0x10D3, 0x10D3 },
{ 0x10D4, 0x10D4, 0x10D4 },
{ 0x10D5, 0x10D5, 0x10D5 },
{ 0x10D6, 0x10D6, 0x10D6 },
{ 0x10D7, 0x10D7, 0x10D7 },
{ 0x10D8, 0x10D8, 0x10D8 },
{ 0x10D9, 0x10D9, 0x10D9 },
{ 0x10DA, 0x10DA, 0x10DA },
{ 0x10DB, 0x10DB, 0x10DB },
{ 0x10DC, 0x10DC, 0x10DC },
{ 0x10DD, 0x10DD, 0x10DD },
{ 0x10DE, 0x10DE, 0x10DE },
{ 0x10DF, 0x10DF, 0x10DF },
{ 0x10E0, 0x10E0, 0x10E0 },
{ 0x10E1, 0x10E1, 0x10E1 },
{ 0x10E2, 0x10E2, 0x10E2 },
{ 0x10E3, 0x10E3, 0x10E3 },
{ 0x10E4, 0x10E4, 0x10E4 },
{ 0x10E5, 0x10E5, 0x10E5 },
{ 0x10E6, 0x10E6, 0x10E6 },
{ 0x10E7, 0x10E7, 0x10E7 },
{ 0x10E8, 0x10E8, 0x10E8 },
{ 0x10E9, 0x10E9, 0x10E9 },
{ 0x10EA, 0x10EA, 0x10EA },
{ 0x10EB, 0x10EB, 0x10EB },
{ 0x10EC, 0x10EC, 0x10EC },
{ 0x10ED, 0x10ED, 0x10ED },
{ 0x10EE, 0x10EE, 0x10EE },
{ 0x10EF, 0x10EF, 0x10EF },
{ 0x10F0, 0x10F0, 0x10F0 },
{ 0x10F1, 0x10F1, 0x10F1 },
{ 0x10F2, 0x10F2, 0x10F2 },
{ 0x10F3, 0x10F3, 0x10F3 },
{ 0x10F4, 0x10F4, 0x10F4 },
{ 0x10F5, 0x10F5, 0x10F5 },
{ 0x10F6, 0x10F6, 0x10F6 },
{ 0x10F7, 0x10F7, 0x10F7 },
{ 0x10F8, 0x10F8, 0x10F8 },
{ 0x10F9, 0x10F9, 0x10F9 },
{ 0x10FA, 0x10FA, 0x10FA },
{ 0x10FC, 0x10FC, 0x10FC },
{ 0x1100, 0x1100, 0x1100 },
{ 0x1101, 0x1101, 0x1101 },
{ 0x1102, 0x1102, 0x1102 },
{ 0x1103, 0x1103, 0x1103 },
{ 0x1104, 0x1104, 0x1104 },
{ 0x1105, 0x1105, 0x1105 },
{ 0x1106, 0x1106, 0x1106 },
{ 0x1107, 0x1107, 0x1107 },
{ 0x1108, 0x1108, 0x1108 },
{ 0x1109, 0x1109, 0x1109 },
{ 0x110A, 0x110A, 0x110A },
{ 0x110B, 0x110B, 0x110B },
{ 0x110C, 0x110C, 0x110C },
{ 0x110D, 0x110D, 0x110D },
{ 0x110E, 0x110E, 0x110E },
{ 0x110F, 0x110F, 0x110F },
{ 0x1110, 0x1110, 0x1110 },
{ 0x1111, 0x1111, 0x1111 },
{ 0x1112, 0x1112, 0x1112 },
{ 0x1113, 0x1113, 0x1113 },
{ 0x1114, 0x1114, 0x1114 },
{ 0x1115, 0x1115, 0x1115 },
{ 0x1116, 0x1116, 0x1116 },
{ 0x1117, 0x1117, 0x1117 },
{ 0x1118, 0x1118, 0x1118 },
{ 0x1119, 0x1119, 0x1119 },
{ 0x111A, 0x111A, 0x111A },
{ 0x111B, 0x111B, 0x111B },
{ 0x111C, 0x111C, 0x111C },
{ 0x111D, 0x111D, 0x111D },
{ 0x111E, 0x111E, 0x111E },
{ 0x111F, 0x111F, 0x111F },
{ 0x1120, 0x1120, 0x1120 },
{ 0x1121, 0x1121, 0x1121 },
{ 0x1122, 0x1122, 0x1122 },
{ 0x1123, 0x1123, 0x1123 },
{ 0x1124, 0x1124, 0x1124 },
{ 0x1125, 0x1125, 0x1125 },
{ 0x1126, 0x1126, 0x1126 },
{ 0x1127, 0x1127, 0x1127 },
{ 0x1128, 0x1128, 0x1128 },
{ 0x1129, 0x1129, 0x1129 },
{ 0x112A, 0x112A, 0x112A },
{ 0x112B, 0x112B, 0x112B },
{ 0x112C, 0x112C, 0x112C },
{ 0x112D, 0x112D, 0x112D },
{ 0x112E, 0x112E, 0x112E },
{ 0x112F, 0x112F, 0x112F },
{ 0x1130, 0x1130, 0x1130 },
{ 0x1131, 0x1131, 0x1131 },
{ 0x1132, 0x1132, 0x1132 },
{ 0x1133, 0x1133, 0x1133 },
{ 0x1134, 0x1134, 0x1134 },
{ 0x1135, 0x1135, 0x1135 },
{ 0x1136, 0x1136, 0x1136 },
{ 0x1137, 0x1137, 0x1137 },
{ 0x1138, 0x1138, 0x1138 },
{ 0x1139, 0x1139, 0x1139 },
{ 0x113A, 0x113A, 0x113A },
{ 0x113B, 0x113B, 0x113B },
{ 0x113C, 0x113C, 0x113C },
{ 0x113D, 0x113D, 0x113D },
{ 0x113E, 0x113E, 0x113E },
{ 0x113F, 0x113F, 0x113F },
{ 0x1140, 0x1140, 0x1140 },
{ 0x1141, 0x1141, 0x1141 },
{ 0x1142, 0x1142, 0x1142 },
{ 0x1143, 0x1143, 0x1143 },
{ 0x1144, 0x1144, 0x1144 },
{ 0x1145, 0x1145, 0x1145 },
{ 0x1146, 0x1146, 0x1146 },
{ 0x1147, 0x1147, 0x1147 },
{ 0x1148, 0x1148, 0x1148 },
{ 0x1149, 0x1149, 0x1149 },
{ 0x114A, 0x114A, 0x114A },
{ 0x114B, 0x114B, 0x114B },
{ 0x114C, 0x114C, 0x114C },
{ 0x114D, 0x114D, 0x114D },
{ 0x114E, 0x114E, 0x114E },
{ 0x114F, 0x114F, 0x114F },
{ 0x1150, 0x1150, 0x1150 },
{ 0x1151, 0x1151, 0x1151 },
{ 0x1152, 0x1152, 0x1152 },
{ 0x1153, 0x1153, 0x1153 },
{ 0x1154, 0x1154, 0x1154 },
{ 0x1155, 0x1155, 0x1155 },
{ 0x1156, 0x1156, 0x1156 },
{ 0x1157, 0x1157, 0x1157 },
{ 0x1158, 0x1158, 0x1158 },
{ 0x1159, 0x1159, 0x1159 },
{ 0x115F, 0x115F, 0x115F },
{ 0x1160, 0x1160, 0x1160 },
{ 0x1161, 0x1161, 0x1161 },
{ 0x1162, 0x1162, 0x1162 },
{ 0x1163, 0x1163, 0x1163 },
{ 0x1164, 0x1164, 0x1164 },
{ 0x1165, 0x1165, 0x1165 },
{ 0x1166, 0x1166, 0x1166 },
{ 0x1167, 0x1167, 0x1167 },
{ 0x1168, 0x1168, 0x1168 },
{ 0x1169, 0x1169, 0x1169 },
{ 0x116A, 0x116A, 0x116A },
{ 0x116B, 0x116B, 0x116B },
{ 0x116C, 0x116C, 0x116C },
{ 0x116D, 0x116D, 0x116D },
{ 0x116E, 0x116E, 0x116E },
{ 0x116F, 0x116F, 0x116F },
{ 0x1170, 0x1170, 0x1170 },
{ 0x1171, 0x1171, 0x1171 },
{ 0x1172, 0x1172, 0x1172 },
{ 0x1173, 0x1173, 0x1173 },
{ 0x1174, 0x1174, 0x1174 },
{ 0x1175, 0x1175, 0x1175 },
{ 0x1176, 0x1176, 0x1176 },
{ 0x1177, 0x1177, 0x1177 },
{ 0x1178, 0x1178, 0x1178 },
{ 0x1179, 0x1179, 0x1179 },
{ 0x117A, 0x117A, 0x117A },
{ 0x117B, 0x117B, 0x117B },
{ 0x117C, 0x117C, 0x117C },
{ 0x117D, 0x117D, 0x117D },
{ 0x117E, 0x117E, 0x117E },
{ 0x117F, 0x117F, 0x117F },
{ 0x1180, 0x1180, 0x1180 },
{ 0x1181, 0x1181, 0x1181 },
{ 0x1182, 0x1182, 0x1182 },
{ 0x1183, 0x1183, 0x1183 },
{ 0x1184, 0x1184, 0x1184 },
{ 0x1185, 0x1185, 0x1185 },
{ 0x1186, 0x1186, 0x1186 },
{ 0x1187, 0x1187, 0x1187 },
{ 0x1188, 0x1188, 0x1188 },
{ 0x1189, 0x1189, 0x1189 },
{ 0x118A, 0x118A, 0x118A },
{ 0x118B, 0x118B, 0x118B },
{ 0x118C, 0x118C, 0x118C },
{ 0x118D, 0x118D, 0x118D },
{ 0x118E, 0x118E, 0x118E },
{ 0x118F, 0x118F, 0x118F },
{ 0x1190, 0x1190, 0x1190 },
{ 0x1191, 0x1191, 0x1191 },
{ 0x1192, 0x1192, 0x1192 },
{ 0x1193, 0x1193, 0x1193 },
{ 0x1194, 0x1194, 0x1194 },
{ 0x1195, 0x1195, 0x1195 },
{ 0x1196, 0x1196, 0x1196 },
{ 0x1197, 0x1197, 0x1197 },
{ 0x1198, 0x1198, 0x1198 },
{ 0x1199, 0x1199, 0x1199 },
{ 0x119A, 0x119A, 0x119A },
{ 0x119B, 0x119B, 0x119B },
{ 0x119C, 0x119C, 0x119C },
{ 0x119D, 0x119D, 0x119D },
{ 0x119E, 0x119E, 0x119E },
{ 0x119F, 0x119F, 0x119F },
{ 0x11A0, 0x11A0, 0x11A0 },
{ 0x11A1, 0x11A1, 0x11A1 },
{ 0x11A2, 0x11A2, 0x11A2 },
{ 0x11A8, 0x11A8, 0x11A8 },
{ 0x11A9, 0x11A9, 0x11A9 },
{ 0x11AA, 0x11AA, 0x11AA },
{ 0x11AB, 0x11AB, 0x11AB },
{ 0x11AC, 0x11AC, 0x11AC },
{ 0x11AD, 0x11AD, 0x11AD },
{ 0x11AE, 0x11AE, 0x11AE },
{ 0x11AF, 0x11AF, 0x11AF },
{ 0x11B0, 0x11B0, 0x11B0 },
{ 0x11B1, 0x11B1, 0x11B1 },
{ 0x11B2, 0x11B2, 0x11B2 },
{ 0x11B3, 0x11B3, 0x11B3 },
{ 0x11B4, 0x11B4, 0x11B4 },
{ 0x11B5, 0x11B5, 0x11B5 },
{ 0x11B6, 0x11B6, 0x11B6 },
{ 0x11B7, 0x11B7, 0x11B7 },
{ 0x11B8, 0x11B8, 0x11B8 },
{ 0x11B9, 0x11B9, 0x11B9 },
{ 0x11BA, 0x11BA, 0x11BA },
{ 0x11BB, 0x11BB, 0x11BB },
{ 0x11BC, 0x11BC, 0x11BC },
{ 0x11BD, 0x11BD, 0x11BD },
{ 0x11BE, 0x11BE, 0x11BE },
{ 0x11BF, 0x11BF, 0x11BF },
{ 0x11C0, 0x11C0, 0x11C0 },
{ 0x11C1, 0x11C1, 0x11C1 },
{ 0x11C2, 0x11C2, 0x11C2 },
{ 0x11C3, 0x11C3, 0x11C3 },
{ 0x11C4, 0x11C4, 0x11C4 },
{ 0x11C5, 0x11C5, 0x11C5 },
{ 0x11C6, 0x11C6, 0x11C6 },
{ 0x11C7, 0x11C7, 0x11C7 },
{ 0x11C8, 0x11C8, 0x11C8 },
{ 0x11C9, 0x11C9, 0x11C9 },
{ 0x11CA, 0x11CA, 0x11CA },
{ 0x11CB, 0x11CB, 0x11CB },
{ 0x11CC, 0x11CC, 0x11CC },
{ 0x11CD, 0x11CD, 0x11CD },
{ 0x11CE, 0x11CE, 0x11CE },
{ 0x11CF, 0x11CF, 0x11CF },
{ 0x11D0, 0x11D0, 0x11D0 },
{ 0x11D1, 0x11D1, 0x11D1 },
{ 0x11D2, 0x11D2, 0x11D2 },
{ 0x11D3, 0x11D3, 0x11D3 },
{ 0x11D4, 0x11D4, 0x11D4 },
{ 0x11D5, 0x11D5, 0x11D5 },
{ 0x11D6, 0x11D6, 0x11D6 },
{ 0x11D7, 0x11D7, 0x11D7 },
{ 0x11D8, 0x11D8, 0x11D8 },
{ 0x11D9, 0x11D9, 0x11D9 },
{ 0x11DA, 0x11DA, 0x11DA },
{ 0x11DB, 0x11DB, 0x11DB },
{ 0x11DC, 0x11DC, 0x11DC },
{ 0x11DD, 0x11DD, 0x11DD },
{ 0x11DE, 0x11DE, 0x11DE },
{ 0x11DF, 0x11DF, 0x11DF },
{ 0x11E0, 0x11E0, 0x11E0 },
{ 0x11E1, 0x11E1, 0x11E1 },
{ 0x11E2, 0x11E2, 0x11E2 },
{ 0x11E3, 0x11E3, 0x11E3 },
{ 0x11E4, 0x11E4, 0x11E4 },
{ 0x11E5, 0x11E5, 0x11E5 },
{ 0x11E6, 0x11E6, 0x11E6 },
{ 0x11E7, 0x11E7, 0x11E7 },
{ 0x11E8, 0x11E8, 0x11E8 },
{ 0x11E9, 0x11E9, 0x11E9 },
{ 0x11EA, 0x11EA, 0x11EA },
{ 0x11EB, 0x11EB, 0x11EB },
{ 0x11EC, 0x11EC, 0x11EC },
{ 0x11ED, 0x11ED, 0x11ED },
{ 0x11EE, 0x11EE, 0x11EE },
{ 0x11EF, 0x11EF, 0x11EF },
{ 0x11F0, 0x11F0, 0x11F0 },
{ 0x11F1, 0x11F1, 0x11F1 },
{ 0x11F2, 0x11F2, 0x11F2 },
{ 0x11F3, 0x11F3, 0x11F3 },
{ 0x11F4, 0x11F4, 0x11F4 },
{ 0x11F5, 0x11F5, 0x11F5 },
{ 0x11F6, 0x11F6, 0x11F6 },
{ 0x11F7, 0x11F7, 0x11F7 },
{ 0x11F8, 0x11F8, 0x11F8 },
{ 0x11F9, 0x11F9, 0x11F9 },
{ 0x1200, 0x1200, 0x1200 },
{ 0x1201, 0x1201, 0x1201 },
{ 0x1202, 0x1202, 0x1202 },
{ 0x1203, 0x1203, 0x1203 },
{ 0x1204, 0x1204, 0x1204 },
{ 0x1205, 0x1205, 0x1205 },
{ 0x1206, 0x1206, 0x1206 },
{ 0x1207, 0x1207, 0x1207 },
{ 0x1208, 0x1208, 0x1208 },
{ 0x1209, 0x1209, 0x1209 },
{ 0x120A, 0x120A, 0x120A },
{ 0x120B, 0x120B, 0x120B },
{ 0x120C, 0x120C, 0x120C },
{ 0x120D, 0x120D, 0x120D },
{ 0x120E, 0x120E, 0x120E },
{ 0x120F, 0x120F, 0x120F },
{ 0x1210, 0x1210, 0x1210 },
{ 0x1211, 0x1211, 0x1211 },
{ 0x1212, 0x1212, 0x1212 },
{ 0x1213, 0x1213, 0x1213 },
{ 0x1214, 0x1214, 0x1214 },
{ 0x1215, 0x1215, 0x1215 },
{ 0x1216, 0x1216, 0x1216 },
{ 0x1217, 0x1217, 0x1217 },
{ 0x1218, 0x1218, 0x1218 },
{ 0x1219, 0x1219, 0x1219 },
{ 0x121A, 0x121A, 0x121A },
{ 0x121B, 0x121B, 0x121B },
{ 0x121C, 0x121C, 0x121C },
{ 0x121D, 0x121D, 0x121D },
{ 0x121E, 0x121E, 0x121E },
{ 0x121F, 0x121F, 0x121F },
{ 0x1220, 0x1220, 0x1220 },
{ 0x1221, 0x1221, 0x1221 },
{ 0x1222, 0x1222, 0x1222 },
{ 0x1223, 0x1223, 0x1223 },
{ 0x1224, 0x1224, 0x1224 },
{ 0x1225, 0x1225, 0x1225 },
{ 0x1226, 0x1226, 0x1226 },
{ 0x1227, 0x1227, 0x1227 },
{ 0x1228, 0x1228, 0x1228 },
{ 0x1229, 0x1229, 0x1229 },
{ 0x122A, 0x122A, 0x122A },
{ 0x122B, 0x122B, 0x122B },
{ 0x122C, 0x122C, 0x122C },
{ 0x122D, 0x122D, 0x122D },
{ 0x122E, 0x122E, 0x122E },
{ 0x122F, 0x122F, 0x122F },
{ 0x1230, 0x1230, 0x1230 },
{ 0x1231, 0x1231, 0x1231 },
{ 0x1232, 0x1232, 0x1232 },
{ 0x1233, 0x1233, 0x1233 },
{ 0x1234, 0x1234, 0x1234 },
{ 0x1235, 0x1235, 0x1235 },
{ 0x1236, 0x1236, 0x1236 },
{ 0x1237, 0x1237, 0x1237 },
{ 0x1238, 0x1238, 0x1238 },
{ 0x1239, 0x1239, 0x1239 },
{ 0x123A, 0x123A, 0x123A },
{ 0x123B, 0x123B, 0x123B },
{ 0x123C, 0x123C, 0x123C },
{ 0x123D, 0x123D, 0x123D },
{ 0x123E, 0x123E, 0x123E },
{ 0x123F, 0x123F, 0x123F },
{ 0x1240, 0x1240, 0x1240 },
{ 0x1241, 0x1241, 0x1241 },
{ 0x1242, 0x1242, 0x1242 },
{ 0x1243, 0x1243, 0x1243 },
{ 0x1244, 0x1244, 0x1244 },
{ 0x1245, 0x1245, 0x1245 },
{ 0x1246, 0x1246, 0x1246 },
{ 0x1247, 0x1247, 0x1247 },
{ 0x1248, 0x1248, 0x1248 },
{ 0x124A, 0x124A, 0x124A },
{ 0x124B, 0x124B, 0x124B },
{ 0x124C, 0x124C, 0x124C },
{ 0x124D, 0x124D, 0x124D },
{ 0x1250, 0x1250, 0x1250 },
{ 0x1251, 0x1251, 0x1251 },
{ 0x1252, 0x1252, 0x1252 },
{ 0x1253, 0x1253, 0x1253 },
{ 0x1254, 0x1254, 0x1254 },
{ 0x1255, 0x1255, 0x1255 },
{ 0x1256, 0x1256, 0x1256 },
{ 0x1258, 0x1258, 0x1258 },
{ 0x125A, 0x125A, 0x125A },
{ 0x125B, 0x125B, 0x125B },
{ 0x125C, 0x125C, 0x125C },
{ 0x125D, 0x125D, 0x125D },
{ 0x1260, 0x1260, 0x1260 },
{ 0x1261, 0x1261, 0x1261 },
{ 0x1262, 0x1262, 0x1262 },
{ 0x1263, 0x1263, 0x1263 },
{ 0x1264, 0x1264, 0x1264 },
{ 0x1265, 0x1265, 0x1265 },
{ 0x1266, 0x1266, 0x1266 },
{ 0x1267, 0x1267, 0x1267 },
{ 0x1268, 0x1268, 0x1268 },
{ 0x1269, 0x1269, 0x1269 },
{ 0x126A, 0x126A, 0x126A },
{ 0x126B, 0x126B, 0x126B },
{ 0x126C, 0x126C, 0x126C },
{ 0x126D, 0x126D, 0x126D },
{ 0x126E, 0x126E, 0x126E },
{ 0x126F, 0x126F, 0x126F },
{ 0x1270, 0x1270, 0x1270 },
{ 0x1271, 0x1271, 0x1271 },
{ 0x1272, 0x1272, 0x1272 },
{ 0x1273, 0x1273, 0x1273 },
{ 0x1274, 0x1274, 0x1274 },
{ 0x1275, 0x1275, 0x1275 },
{ 0x1276, 0x1276, 0x1276 },
{ 0x1277, 0x1277, 0x1277 },
{ 0x1278, 0x1278, 0x1278 },
{ 0x1279, 0x1279, 0x1279 },
{ 0x127A, 0x127A, 0x127A },
{ 0x127B, 0x127B, 0x127B },
{ 0x127C, 0x127C, 0x127C },
{ 0x127D, 0x127D, 0x127D },
{ 0x127E, 0x127E, 0x127E },
{ 0x127F, 0x127F, 0x127F },
{ 0x1280, 0x1280, 0x1280 },
{ 0x1281, 0x1281, 0x1281 },
{ 0x1282, 0x1282, 0x1282 },
{ 0x1283, 0x1283, 0x1283 },
{ 0x1284, 0x1284, 0x1284 },
{ 0x1285, 0x1285, 0x1285 },
{ 0x1286, 0x1286, 0x1286 },
{ 0x1287, 0x1287, 0x1287 },
{ 0x1288, 0x1288, 0x1288 },
{ 0x128A, 0x128A, 0x128A },
{ 0x128B, 0x128B, 0x128B },
{ 0x128C, 0x128C, 0x128C },
{ 0x128D, 0x128D, 0x128D },
{ 0x1290, 0x1290, 0x1290 },
{ 0x1291, 0x1291, 0x1291 },
{ 0x1292, 0x1292, 0x1292 },
{ 0x1293, 0x1293, 0x1293 },
{ 0x1294, 0x1294, 0x1294 },
{ 0x1295, 0x1295, 0x1295 },
{ 0x1296, 0x1296, 0x1296 },
{ 0x1297, 0x1297, 0x1297 },
{ 0x1298, 0x1298, 0x1298 },
{ 0x1299, 0x1299, 0x1299 },
{ 0x129A, 0x129A, 0x129A },
{ 0x129B, 0x129B, 0x129B },
{ 0x129C, 0x129C, 0x129C },
{ 0x129D, 0x129D, 0x129D },
{ 0x129E, 0x129E, 0x129E },
{ 0x129F, 0x129F, 0x129F },
{ 0x12A0, 0x12A0, 0x12A0 },
{ 0x12A1, 0x12A1, 0x12A1 },
{ 0x12A2, 0x12A2, 0x12A2 },
{ 0x12A3, 0x12A3, 0x12A3 },
{ 0x12A4, 0x12A4, 0x12A4 },
{ 0x12A5, 0x12A5, 0x12A5 },
{ 0x12A6, 0x12A6, 0x12A6 },
{ 0x12A7, 0x12A7, 0x12A7 },
{ 0x12A8, 0x12A8, 0x12A8 },
{ 0x12A9, 0x12A9, 0x12A9 },
{ 0x12AA, 0x12AA, 0x12AA },
{ 0x12AB, 0x12AB, 0x12AB },
{ 0x12AC, 0x12AC, 0x12AC },
{ 0x12AD, 0x12AD, 0x12AD },
{ 0x12AE, 0x12AE, 0x12AE },
{ 0x12AF, 0x12AF, 0x12AF },
{ 0x12B0, 0x12B0, 0x12B0 },
{ 0x12B2, 0x12B2, 0x12B2 },
{ 0x12B3, 0x12B3, 0x12B3 },
{ 0x12B4, 0x12B4, 0x12B4 },
{ 0x12B5, 0x12B5, 0x12B5 },
{ 0x12B8, 0x12B8, 0x12B8 },
{ 0x12B9, 0x12B9, 0x12B9 },
{ 0x12BA, 0x12BA, 0x12BA },
{ 0x12BB, 0x12BB, 0x12BB },
{ 0x12BC, 0x12BC, 0x12BC },
{ 0x12BD, 0x12BD, 0x12BD },
{ 0x12BE, 0x12BE, 0x12BE },
{ 0x12C0, 0x12C0, 0x12C0 },
{ 0x12C2, 0x12C2, 0x12C2 },
{ 0x12C3, 0x12C3, 0x12C3 },
{ 0x12C4, 0x12C4, 0x12C4 },
{ 0x12C5, 0x12C5, 0x12C5 },
{ 0x12C8, 0x12C8, 0x12C8 },
{ 0x12C9, 0x12C9, 0x12C9 },
{ 0x12CA, 0x12CA, 0x12CA },
{ 0x12CB, 0x12CB, 0x12CB },
{ 0x12CC, 0x12CC, 0x12CC },
{ 0x12CD, 0x12CD, 0x12CD },
{ 0x12CE, 0x12CE, 0x12CE },
{ 0x12CF, 0x12CF, 0x12CF },
{ 0x12D0, 0x12D0, 0x12D0 },
{ 0x12D1, 0x12D1, 0x12D1 },
{ 0x12D2, 0x12D2, 0x12D2 },
{ 0x12D3, 0x12D3, 0x12D3 },
{ 0x12D4, 0x12D4, 0x12D4 },
{ 0x12D5, 0x12D5, 0x12D5 },
{ 0x12D6, 0x12D6, 0x12D6 },
{ 0x12D8, 0x12D8, 0x12D8 },
{ 0x12D9, 0x12D9, 0x12D9 },
{ 0x12DA, 0x12DA, 0x12DA },
{ 0x12DB, 0x12DB, 0x12DB },
{ 0x12DC, 0x12DC, 0x12DC },
{ 0x12DD, 0x12DD, 0x12DD },
{ 0x12DE, 0x12DE, 0x12DE },
{ 0x12DF, 0x12DF, 0x12DF },
{ 0x12E0, 0x12E0, 0x12E0 },
{ 0x12E1, 0x12E1, 0x12E1 },
{ 0x12E2, 0x12E2, 0x12E2 },
{ 0x12E3, 0x12E3, 0x12E3 },
{ 0x12E4, 0x12E4, 0x12E4 },
{ 0x12E5, 0x12E5, 0x12E5 },
{ 0x12E6, 0x12E6, 0x12E6 },
{ 0x12E7, 0x12E7, 0x12E7 },
{ 0x12E8, 0x12E8, 0x12E8 },
{ 0x12E9, 0x12E9, 0x12E9 },
{ 0x12EA, 0x12EA, 0x12EA },
{ 0x12EB, 0x12EB, 0x12EB },
{ 0x12EC, 0x12EC, 0x12EC },
{ 0x12ED, 0x12ED, 0x12ED },
{ 0x12EE, 0x12EE, 0x12EE },
{ 0x12EF, 0x12EF, 0x12EF },
{ 0x12F0, 0x12F0, 0x12F0 },
{ 0x12F1, 0x12F1, 0x12F1 },
{ 0x12F2, 0x12F2, 0x12F2 },
{ 0x12F3, 0x12F3, 0x12F3 },
{ 0x12F4, 0x12F4, 0x12F4 },
{ 0x12F5, 0x12F5, 0x12F5 },
{ 0x12F6, 0x12F6, 0x12F6 },
{ 0x12F7, 0x12F7, 0x12F7 },
{ 0x12F8, 0x12F8, 0x12F8 },
{ 0x12F9, 0x12F9, 0x12F9 },
{ 0x12FA, 0x12FA, 0x12FA },
{ 0x12FB, 0x12FB, 0x12FB },
{ 0x12FC, 0x12FC, 0x12FC },
{ 0x12FD, 0x12FD, 0x12FD },
{ 0x12FE, 0x12FE, 0x12FE },
{ 0x12FF, 0x12FF, 0x12FF },
{ 0x1300, 0x1300, 0x1300 },
{ 0x1301, 0x1301, 0x1301 },
{ 0x1302, 0x1302, 0x1302 },
{ 0x1303, 0x1303, 0x1303 },
{ 0x1304, 0x1304, 0x1304 },
{ 0x1305, 0x1305, 0x1305 },
{ 0x1306, 0x1306, 0x1306 },
{ 0x1307, 0x1307, 0x1307 },
{ 0x1308, 0x1308, 0x1308 },
{ 0x1309, 0x1309, 0x1309 },
{ 0x130A, 0x130A, 0x130A },
{ 0x130B, 0x130B, 0x130B },
{ 0x130C, 0x130C, 0x130C },
{ 0x130D, 0x130D, 0x130D },
{ 0x130E, 0x130E, 0x130E },
{ 0x130F, 0x130F, 0x130F },
{ 0x1310, 0x1310, 0x1310 },
{ 0x1312, 0x1312, 0x1312 },
{ 0x1313, 0x1313, 0x1313 },
{ 0x1314, 0x1314, 0x1314 },
{ 0x1315, 0x1315, 0x1315 },
{ 0x1318, 0x1318, 0x1318 },
{ 0x1319, 0x1319, 0x1319 },
{ 0x131A, 0x131A, 0x131A },
{ 0x131B, 0x131B, 0x131B },
{ 0x131C, 0x131C, 0x131C },
{ 0x131D, 0x131D, 0x131D },
{ 0x131E, 0x131E, 0x131E },
{ 0x131F, 0x131F, 0x131F },
{ 0x1320, 0x1320, 0x1320 },
{ 0x1321, 0x1321, 0x1321 },
{ 0x1322, 0x1322, 0x1322 },
{ 0x1323, 0x1323, 0x1323 },
{ 0x1324, 0x1324, 0x1324 },
{ 0x1325, 0x1325, 0x1325 },
{ 0x1326, 0x1326, 0x1326 },
{ 0x1327, 0x1327, 0x1327 },
{ 0x1328, 0x1328, 0x1328 },
{ 0x1329, 0x1329, 0x1329 },
{ 0x132A, 0x132A, 0x132A },
{ 0x132B, 0x132B, 0x132B },
{ 0x132C, 0x132C, 0x132C },
{ 0x132D, 0x132D, 0x132D },
{ 0x132E, 0x132E, 0x132E },
{ 0x132F, 0x132F, 0x132F },
{ 0x1330, 0x1330, 0x1330 },
{ 0x1331, 0x1331, 0x1331 },
{ 0x1332, 0x1332, 0x1332 },
{ 0x1333, 0x1333, 0x1333 },
{ 0x1334, 0x1334, 0x1334 },
{ 0x1335, 0x1335, 0x1335 },
{ 0x1336, 0x1336, 0x1336 },
{ 0x1337, 0x1337, 0x1337 },
{ 0x1338, 0x1338, 0x1338 },
{ 0x1339, 0x1339, 0x1339 },
{ 0x133A, 0x133A, 0x133A },
{ 0x133B, 0x133B, 0x133B },
{ 0x133C, 0x133C, 0x133C },
{ 0x133D, 0x133D, 0x133D },
{ 0x133E, 0x133E, 0x133E },
{ 0x133F, 0x133F, 0x133F },
{ 0x1340, 0x1340, 0x1340 },
{ 0x1341, 0x1341, 0x1341 },
{ 0x1342, 0x1342, 0x1342 },
{ 0x1343, 0x1343, 0x1343 },
{ 0x1344, 0x1344, 0x1344 },
{ 0x1345, 0x1345, 0x1345 },
{ 0x1346, 0x1346, 0x1346 },
{ 0x1347, 0x1347, 0x1347 },
{ 0x1348, 0x1348, 0x1348 },
{ 0x1349, 0x1349, 0x1349 },
{ 0x134A, 0x134A, 0x134A },
{ 0x134B, 0x134B, 0x134B },
{ 0x134C, 0x134C, 0x134C },
{ 0x134D, 0x134D, 0x134D },
{ 0x134E, 0x134E, 0x134E },
{ 0x134F, 0x134F, 0x134F },
{ 0x1350, 0x1350, 0x1350 },
{ 0x1351, 0x1351, 0x1351 },
{ 0x1352, 0x1352, 0x1352 },
{ 0x1353, 0x1353, 0x1353 },
{ 0x1354, 0x1354, 0x1354 },
{ 0x1355, 0x1355, 0x1355 },
{ 0x1356, 0x1356, 0x1356 },
{ 0x1357, 0x1357, 0x1357 },
{ 0x1358, 0x1358, 0x1358 },
{ 0x1359, 0x1359, 0x1359 },
{ 0x135A, 0x135A, 0x135A },
{ 0x135F, 0x135F, 0x135F },
{ 0x1380, 0x1380, 0x1380 },
{ 0x1381, 0x1381, 0x1381 },
{ 0x1382, 0x1382, 0x1382 },
{ 0x1383, 0x1383, 0x1383 },
{ 0x1384, 0x1384, 0x1384 },
{ 0x1385, 0x1385, 0x1385 },
{ 0x1386, 0x1386, 0x1386 },
{ 0x1387, 0x1387, 0x1387 },
{ 0x1388, 0x1388, 0x1388 },
{ 0x1389, 0x1389, 0x1389 },
{ 0x138A, 0x138A, 0x138A },
{ 0x138B, 0x138B, 0x138B },
{ 0x138C, 0x138C, 0x138C },
{ 0x138D, 0x138D, 0x138D },
{ 0x138E, 0x138E, 0x138E },
{ 0x138F, 0x138F, 0x138F },
{ 0x13A0, 0x13A0, 0x13A0 },
{ 0x13A1, 0x13A1, 0x13A1 },
{ 0x13A2, 0x13A2, 0x13A2 },
{ 0x13A3, 0x13A3, 0x13A3 },
{ 0x13A4, 0x13A4, 0x13A4 },
{ 0x13A5, 0x13A5, 0x13A5 },
{ 0x13A6, 0x13A6, 0x13A6 },
{ 0x13A7, 0x13A7, 0x13A7 },
{ 0x13A8, 0x13A8, 0x13A8 },
{ 0x13A9, 0x13A9, 0x13A9 },
{ 0x13AA, 0x13AA, 0x13AA },
{ 0x13AB, 0x13AB, 0x13AB },
{ 0x13AC, 0x13AC, 0x13AC },
{ 0x13AD, 0x13AD, 0x13AD },
{ 0x13AE, 0x13AE, 0x13AE },
{ 0x13AF, 0x13AF, 0x13AF },
{ 0x13B0, 0x13B0, 0x13B0 },
{ 0x13B1, 0x13B1, 0x13B1 },
{ 0x13B2, 0x13B2, 0x13B2 },
{ 0x13B3, 0x13B3, 0x13B3 },
{ 0x13B4, 0x13B4, 0x13B4 },
{ 0x13B5, 0x13B5, 0x13B5 },
{ 0x13B6, 0x13B6, 0x13B6 },
{ 0x13B7, 0x13B7, 0x13B7 },
{ 0x13B8, 0x13B8, 0x13B8 },
{ 0x13B9, 0x13B9, 0x13B9 },
{ 0x13BA, 0x13BA, 0x13BA },
{ 0x13BB, 0x13BB, 0x13BB },
{ 0x13BC, 0x13BC, 0x13BC },
{ 0x13BD, 0x13BD, 0x13BD },
{ 0x13BE, 0x13BE, 0x13BE },
{ 0x13BF, 0x13BF, 0x13BF },
{ 0x13C0, 0x13C0, 0x13C0 },
{ 0x13C1, 0x13C1, 0x13C1 },
{ 0x13C2, 0x13C2, 0x13C2 },
{ 0x13C3, 0x13C3, 0x13C3 },
{ 0x13C4, 0x13C4, 0x13C4 },
{ 0x13C5, 0x13C5, 0x13C5 },
{ 0x13C6, 0x13C6, 0x13C6 },
{ 0x13C7, 0x13C7, 0x13C7 },
{ 0x13C8, 0x13C8, 0x13C8 },
{ 0x13C9, 0x13C9, 0x13C9 },
{ 0x13CA, 0x13CA, 0x13CA },
{ 0x13CB, 0x13CB, 0x13CB },
{ 0x13CC, 0x13CC, 0x13CC },
{ 0x13CD, 0x13CD, 0x13CD },
{ 0x13CE, 0x13CE, 0x13CE },
{ 0x13CF, 0x13CF, 0x13CF },
{ 0x13D0, 0x13D0, 0x13D0 },
{ 0x13D1, 0x13D1, 0x13D1 },
{ 0x13D2, 0x13D2, 0x13D2 },
{ 0x13D3, 0x13D3, 0x13D3 },
{ 0x13D4, 0x13D4, 0x13D4 },
{ 0x13D5, 0x13D5, 0x13D5 },
{ 0x13D6, 0x13D6, 0x13D6 },
{ 0x13D7, 0x13D7, 0x13D7 },
{ 0x13D8, 0x13D8, 0x13D8 },
{ 0x13D9, 0x13D9, 0x13D9 },
{ 0x13DA, 0x13DA, 0x13DA },
{ 0x13DB, 0x13DB, 0x13DB },
{ 0x13DC, 0x13DC, 0x13DC },
{ 0x13DD, 0x13DD, 0x13DD },
{ 0x13DE, 0x13DE, 0x13DE },
{ 0x13DF, 0x13DF, 0x13DF },
{ 0x13E0, 0x13E0, 0x13E0 },
{ 0x13E1, 0x13E1, 0x13E1 },
{ 0x13E2, 0x13E2, 0x13E2 },
{ 0x13E3, 0x13E3, 0x13E3 },
{ 0x13E4, 0x13E4, 0x13E4 },
{ 0x13E5, 0x13E5, 0x13E5 },
{ 0x13E6, 0x13E6, 0x13E6 },
{ 0x13E7, 0x13E7, 0x13E7 },
{ 0x13E8, 0x13E8, 0x13E8 },
{ 0x13E9, 0x13E9, 0x13E9 },
{ 0x13EA, 0x13EA, 0x13EA },
{ 0x13EB, 0x13EB, 0x13EB },
{ 0x13EC, 0x13EC, 0x13EC },
{ 0x13ED, 0x13ED, 0x13ED },
{ 0x13EE, 0x13EE, 0x13EE },
{ 0x13EF, 0x13EF, 0x13EF },
{ 0x13F0, 0x13F0, 0x13F0 },
{ 0x13F1, 0x13F1, 0x13F1 },
{ 0x13F2, 0x13F2, 0x13F2 },
{ 0x13F3, 0x13F3, 0x13F3 },
{ 0x13F4, 0x13F4, 0x13F4 },
{ 0x1401, 0x1401, 0x1401 },
{ 0x1402, 0x1402, 0x1402 },
{ 0x1403, 0x1403, 0x1403 },
{ 0x1404, 0x1404, 0x1404 },
{ 0x1405, 0x1405, 0x1405 },
{ 0x1406, 0x1406, 0x1406 },
{ 0x1407, 0x1407, 0x1407 },
{ 0x1408, 0x1408, 0x1408 },
{ 0x1409, 0x1409, 0x1409 },
{ 0x140A, 0x140A, 0x140A },
{ 0x140B, 0x140B, 0x140B },
{ 0x140C, 0x140C, 0x140C },
{ 0x140D, 0x140D, 0x140D },
{ 0x140E, 0x140E, 0x140E },
{ 0x140F, 0x140F, 0x140F },
{ 0x1410, 0x1410, 0x1410 },
{ 0x1411, 0x1411, 0x1411 },
{ 0x1412, 0x1412, 0x1412 },
{ 0x1413, 0x1413, 0x1413 },
{ 0x1414, 0x1414, 0x1414 },
{ 0x1415, 0x1415, 0x1415 },
{ 0x1416, 0x1416, 0x1416 },
{ 0x1417, 0x1417, 0x1417 },
{ 0x1418, 0x1418, 0x1418 },
{ 0x1419, 0x1419, 0x1419 },
{ 0x141A, 0x141A, 0x141A },
{ 0x141B, 0x141B, 0x141B },
{ 0x141C, 0x141C, 0x141C },
{ 0x141D, 0x141D, 0x141D },
{ 0x141E, 0x141E, 0x141E },
{ 0x141F, 0x141F, 0x141F },
{ 0x1420, 0x1420, 0x1420 },
{ 0x1421, 0x1421, 0x1421 },
{ 0x1422, 0x1422, 0x1422 },
{ 0x1423, 0x1423, 0x1423 },
{ 0x1424, 0x1424, 0x1424 },
{ 0x1425, 0x1425, 0x1425 },
{ 0x1426, 0x1426, 0x1426 },
{ 0x1427, 0x1427, 0x1427 },
{ 0x1428, 0x1428, 0x1428 },
{ 0x1429, 0x1429, 0x1429 },
{ 0x142A, 0x142A, 0x142A },
{ 0x142B, 0x142B, 0x142B },
{ 0x142C, 0x142C, 0x142C },
{ 0x142D, 0x142D, 0x142D },
{ 0x142E, 0x142E, 0x142E },
{ 0x142F, 0x142F, 0x142F },
{ 0x1430, 0x1430, 0x1430 },
{ 0x1431, 0x1431, 0x1431 },
{ 0x1432, 0x1432, 0x1432 },
{ 0x1433, 0x1433, 0x1433 },
{ 0x1434, 0x1434, 0x1434 },
{ 0x1435, 0x1435, 0x1435 },
{ 0x1436, 0x1436, 0x1436 },
{ 0x1437, 0x1437, 0x1437 },
{ 0x1438, 0x1438, 0x1438 },
{ 0x1439, 0x1439, 0x1439 },
{ 0x143A, 0x143A, 0x143A },
{ 0x143B, 0x143B, 0x143B },
{ 0x143C, 0x143C, 0x143C },
{ 0x143D, 0x143D, 0x143D },
{ 0x143E, 0x143E, 0x143E },
{ 0x143F, 0x143F, 0x143F },
{ 0x1440, 0x1440, 0x1440 },
{ 0x1441, 0x1441, 0x1441 },
{ 0x1442, 0x1442, 0x1442 },
{ 0x1443, 0x1443, 0x1443 },
{ 0x1444, 0x1444, 0x1444 },
{ 0x1445, 0x1445, 0x1445 },
{ 0x1446, 0x1446, 0x1446 },
{ 0x1447, 0x1447, 0x1447 },
{ 0x1448, 0x1448, 0x1448 },
{ 0x1449, 0x1449, 0x1449 },
{ 0x144A, 0x144A, 0x144A },
{ 0x144B, 0x144B, 0x144B },
{ 0x144C, 0x144C, 0x144C },
{ 0x144D, 0x144D, 0x144D },
{ 0x144E, 0x144E, 0x144E },
{ 0x144F, 0x144F, 0x144F },
{ 0x1450, 0x1450, 0x1450 },
{ 0x1451, 0x1451, 0x1451 },
{ 0x1452, 0x1452, 0x1452 },
{ 0x1453, 0x1453, 0x1453 },
{ 0x1454, 0x1454, 0x1454 },
{ 0x1455, 0x1455, 0x1455 },
{ 0x1456, 0x1456, 0x1456 },
{ 0x1457, 0x1457, 0x1457 },
{ 0x1458, 0x1458, 0x1458 },
{ 0x1459, 0x1459, 0x1459 },
{ 0x145A, 0x145A, 0x145A },
{ 0x145B, 0x145B, 0x145B },
{ 0x145C, 0x145C, 0x145C },
{ 0x145D, 0x145D, 0x145D },
{ 0x145E, 0x145E, 0x145E },
{ 0x145F, 0x145F, 0x145F },
{ 0x1460, 0x1460, 0x1460 },
{ 0x1461, 0x1461, 0x1461 },
{ 0x1462, 0x1462, 0x1462 },
{ 0x1463, 0x1463, 0x1463 },
{ 0x1464, 0x1464, 0x1464 },
{ 0x1465, 0x1465, 0x1465 },
{ 0x1466, 0x1466, 0x1466 },
{ 0x1467, 0x1467, 0x1467 },
{ 0x1468, 0x1468, 0x1468 },
{ 0x1469, 0x1469, 0x1469 },
{ 0x146A, 0x146A, 0x146A },
{ 0x146B, 0x146B, 0x146B },
{ 0x146C, 0x146C, 0x146C },
{ 0x146D, 0x146D, 0x146D },
{ 0x146E, 0x146E, 0x146E },
{ 0x146F, 0x146F, 0x146F },
{ 0x1470, 0x1470, 0x1470 },
{ 0x1471, 0x1471, 0x1471 },
{ 0x1472, 0x1472, 0x1472 },
{ 0x1473, 0x1473, 0x1473 },
{ 0x1474, 0x1474, 0x1474 },
{ 0x1475, 0x1475, 0x1475 },
{ 0x1476, 0x1476, 0x1476 },
{ 0x1477, 0x1477, 0x1477 },
{ 0x1478, 0x1478, 0x1478 },
{ 0x1479, 0x1479, 0x1479 },
{ 0x147A, 0x147A, 0x147A },
{ 0x147B, 0x147B, 0x147B },
{ 0x147C, 0x147C, 0x147C },
{ 0x147D, 0x147D, 0x147D },
{ 0x147E, 0x147E, 0x147E },
{ 0x147F, 0x147F, 0x147F },
{ 0x1480, 0x1480, 0x1480 },
{ 0x1481, 0x1481, 0x1481 },
{ 0x1482, 0x1482, 0x1482 },
{ 0x1483, 0x1483, 0x1483 },
{ 0x1484, 0x1484, 0x1484 },
{ 0x1485, 0x1485, 0x1485 },
{ 0x1486, 0x1486, 0x1486 },
{ 0x1487, 0x1487, 0x1487 },
{ 0x1488, 0x1488, 0x1488 },
{ 0x1489, 0x1489, 0x1489 },
{ 0x148A, 0x148A, 0x148A },
{ 0x148B, 0x148B, 0x148B },
{ 0x148C, 0x148C, 0x148C },
{ 0x148D, 0x148D, 0x148D },
{ 0x148E, 0x148E, 0x148E },
{ 0x148F, 0x148F, 0x148F },
{ 0x1490, 0x1490, 0x1490 },
{ 0x1491, 0x1491, 0x1491 },
{ 0x1492, 0x1492, 0x1492 },
{ 0x1493, 0x1493, 0x1493 },
{ 0x1494, 0x1494, 0x1494 },
{ 0x1495, 0x1495, 0x1495 },
{ 0x1496, 0x1496, 0x1496 },
{ 0x1497, 0x1497, 0x1497 },
{ 0x1498, 0x1498, 0x1498 },
{ 0x1499, 0x1499, 0x1499 },
{ 0x149A, 0x149A, 0x149A },
{ 0x149B, 0x149B, 0x149B },
{ 0x149C, 0x149C, 0x149C },
{ 0x149D, 0x149D, 0x149D },
{ 0x149E, 0x149E, 0x149E },
{ 0x149F, 0x149F, 0x149F },
{ 0x14A0, 0x14A0, 0x14A0 },
{ 0x14A1, 0x14A1, 0x14A1 },
{ 0x14A2, 0x14A2, 0x14A2 },
{ 0x14A3, 0x14A3, 0x14A3 },
{ 0x14A4, 0x14A4, 0x14A4 },
{ 0x14A5, 0x14A5, 0x14A5 },
{ 0x14A6, 0x14A6, 0x14A6 },
{ 0x14A7, 0x14A7, 0x14A7 },
{ 0x14A8, 0x14A8, 0x14A8 },
{ 0x14A9, 0x14A9, 0x14A9 },
{ 0x14AA, 0x14AA, 0x14AA },
{ 0x14AB, 0x14AB, 0x14AB },
{ 0x14AC, 0x14AC, 0x14AC },
{ 0x14AD, 0x14AD, 0x14AD },
{ 0x14AE, 0x14AE, 0x14AE },
{ 0x14AF, 0x14AF, 0x14AF },
{ 0x14B0, 0x14B0, 0x14B0 },
{ 0x14B1, 0x14B1, 0x14B1 },
{ 0x14B2, 0x14B2, 0x14B2 },
{ 0x14B3, 0x14B3, 0x14B3 },
{ 0x14B4, 0x14B4, 0x14B4 },
{ 0x14B5, 0x14B5, 0x14B5 },
{ 0x14B6, 0x14B6, 0x14B6 },
{ 0x14B7, 0x14B7, 0x14B7 },
{ 0x14B8, 0x14B8, 0x14B8 },
{ 0x14B9, 0x14B9, 0x14B9 },
{ 0x14BA, 0x14BA, 0x14BA },
{ 0x14BB, 0x14BB, 0x14BB },
{ 0x14BC, 0x14BC, 0x14BC },
{ 0x14BD, 0x14BD, 0x14BD },
{ 0x14BE, 0x14BE, 0x14BE },
{ 0x14BF, 0x14BF, 0x14BF },
{ 0x14C0, 0x14C0, 0x14C0 },
{ 0x14C1, 0x14C1, 0x14C1 },
{ 0x14C2, 0x14C2, 0x14C2 },
{ 0x14C3, 0x14C3, 0x14C3 },
{ 0x14C4, 0x14C4, 0x14C4 },
{ 0x14C5, 0x14C5, 0x14C5 },
{ 0x14C6, 0x14C6, 0x14C6 },
{ 0x14C7, 0x14C7, 0x14C7 },
{ 0x14C8, 0x14C8, 0x14C8 },
{ 0x14C9, 0x14C9, 0x14C9 },
{ 0x14CA, 0x14CA, 0x14CA },
{ 0x14CB, 0x14CB, 0x14CB },
{ 0x14CC, 0x14CC, 0x14CC },
{ 0x14CD, 0x14CD, 0x14CD },
{ 0x14CE, 0x14CE, 0x14CE },
{ 0x14CF, 0x14CF, 0x14CF },
{ 0x14D0, 0x14D0, 0x14D0 },
{ 0x14D1, 0x14D1, 0x14D1 },
{ 0x14D2, 0x14D2, 0x14D2 },
{ 0x14D3, 0x14D3, 0x14D3 },
{ 0x14D4, 0x14D4, 0x14D4 },
{ 0x14D5, 0x14D5, 0x14D5 },
{ 0x14D6, 0x14D6, 0x14D6 },
{ 0x14D7, 0x14D7, 0x14D7 },
{ 0x14D8, 0x14D8, 0x14D8 },
{ 0x14D9, 0x14D9, 0x14D9 },
{ 0x14DA, 0x14DA, 0x14DA },
{ 0x14DB, 0x14DB, 0x14DB },
{ 0x14DC, 0x14DC, 0x14DC },
{ 0x14DD, 0x14DD, 0x14DD },
{ 0x14DE, 0x14DE, 0x14DE },
{ 0x14DF, 0x14DF, 0x14DF },
{ 0x14E0, 0x14E0, 0x14E0 },
{ 0x14E1, 0x14E1, 0x14E1 },
{ 0x14E2, 0x14E2, 0x14E2 },
{ 0x14E3, 0x14E3, 0x14E3 },
{ 0x14E4, 0x14E4, 0x14E4 },
{ 0x14E5, 0x14E5, 0x14E5 },
{ 0x14E6, 0x14E6, 0x14E6 },
{ 0x14E7, 0x14E7, 0x14E7 },
{ 0x14E8, 0x14E8, 0x14E8 },
{ 0x14E9, 0x14E9, 0x14E9 },
{ 0x14EA, 0x14EA, 0x14EA },
{ 0x14EB, 0x14EB, 0x14EB },
{ 0x14EC, 0x14EC, 0x14EC },
{ 0x14ED, 0x14ED, 0x14ED },
{ 0x14EE, 0x14EE, 0x14EE },
{ 0x14EF, 0x14EF, 0x14EF },
{ 0x14F0, 0x14F0, 0x14F0 },
{ 0x14F1, 0x14F1, 0x14F1 },
{ 0x14F2, 0x14F2, 0x14F2 },
{ 0x14F3, 0x14F3, 0x14F3 },
{ 0x14F4, 0x14F4, 0x14F4 },
{ 0x14F5, 0x14F5, 0x14F5 },
{ 0x14F6, 0x14F6, 0x14F6 },
{ 0x14F7, 0x14F7, 0x14F7 },
{ 0x14F8, 0x14F8, 0x14F8 },
{ 0x14F9, 0x14F9, 0x14F9 },
{ 0x14FA, 0x14FA, 0x14FA },
{ 0x14FB, 0x14FB, 0x14FB },
{ 0x14FC, 0x14FC, 0x14FC },
{ 0x14FD, 0x14FD, 0x14FD },
{ 0x14FE, 0x14FE, 0x14FE },
{ 0x14FF, 0x14FF, 0x14FF },
{ 0x1500, 0x1500, 0x1500 },
{ 0x1501, 0x1501, 0x1501 },
{ 0x1502, 0x1502, 0x1502 },
{ 0x1503, 0x1503, 0x1503 },
{ 0x1504, 0x1504, 0x1504 },
{ 0x1505, 0x1505, 0x1505 },
{ 0x1506, 0x1506, 0x1506 },
{ 0x1507, 0x1507, 0x1507 },
{ 0x1508, 0x1508, 0x1508 },
{ 0x1509, 0x1509, 0x1509 },
{ 0x150A, 0x150A, 0x150A },
{ 0x150B, 0x150B, 0x150B },
{ 0x150C, 0x150C, 0x150C },
{ 0x150D, 0x150D, 0x150D },
{ 0x150E, 0x150E, 0x150E },
{ 0x150F, 0x150F, 0x150F },
{ 0x1510, 0x1510, 0x1510 },
{ 0x1511, 0x1511, 0x1511 },
{ 0x1512, 0x1512, 0x1512 },
{ 0x1513, 0x1513, 0x1513 },
{ 0x1514, 0x1514, 0x1514 },
{ 0x1515, 0x1515, 0x1515 },
{ 0x1516, 0x1516, 0x1516 },
{ 0x1517, 0x1517, 0x1517 },
{ 0x1518, 0x1518, 0x1518 },
{ 0x1519, 0x1519, 0x1519 },
{ 0x151A, 0x151A, 0x151A },
{ 0x151B, 0x151B, 0x151B },
{ 0x151C, 0x151C, 0x151C },
{ 0x151D, 0x151D, 0x151D },
{ 0x151E, 0x151E, 0x151E },
{ 0x151F, 0x151F, 0x151F },
{ 0x1520, 0x1520, 0x1520 },
{ 0x1521, 0x1521, 0x1521 },
{ 0x1522, 0x1522, 0x1522 },
{ 0x1523, 0x1523, 0x1523 },
{ 0x1524, 0x1524, 0x1524 },
{ 0x1525, 0x1525, 0x1525 },
{ 0x1526, 0x1526, 0x1526 },
{ 0x1527, 0x1527, 0x1527 },
{ 0x1528, 0x1528, 0x1528 },
{ 0x1529, 0x1529, 0x1529 },
{ 0x152A, 0x152A, 0x152A },
{ 0x152B, 0x152B, 0x152B },
{ 0x152C, 0x152C, 0x152C },
{ 0x152D, 0x152D, 0x152D },
{ 0x152E, 0x152E, 0x152E },
{ 0x152F, 0x152F, 0x152F },
{ 0x1530, 0x1530, 0x1530 },
{ 0x1531, 0x1531, 0x1531 },
{ 0x1532, 0x1532, 0x1532 },
{ 0x1533, 0x1533, 0x1533 },
{ 0x1534, 0x1534, 0x1534 },
{ 0x1535, 0x1535, 0x1535 },
{ 0x1536, 0x1536, 0x1536 },
{ 0x1537, 0x1537, 0x1537 },
{ 0x1538, 0x1538, 0x1538 },
{ 0x1539, 0x1539, 0x1539 },
{ 0x153A, 0x153A, 0x153A },
{ 0x153B, 0x153B, 0x153B },
{ 0x153C, 0x153C, 0x153C },
{ 0x153D, 0x153D, 0x153D },
{ 0x153E, 0x153E, 0x153E },
{ 0x153F, 0x153F, 0x153F },
{ 0x1540, 0x1540, 0x1540 },
{ 0x1541, 0x1541, 0x1541 },
{ 0x1542, 0x1542, 0x1542 },
{ 0x1543, 0x1543, 0x1543 },
{ 0x1544, 0x1544, 0x1544 },
{ 0x1545, 0x1545, 0x1545 },
{ 0x1546, 0x1546, 0x1546 },
{ 0x1547, 0x1547, 0x1547 },
{ 0x1548, 0x1548, 0x1548 },
{ 0x1549, 0x1549, 0x1549 },
{ 0x154A, 0x154A, 0x154A },
{ 0x154B, 0x154B, 0x154B },
{ 0x154C, 0x154C, 0x154C },
{ 0x154D, 0x154D, 0x154D },
{ 0x154E, 0x154E, 0x154E },
{ 0x154F, 0x154F, 0x154F },
{ 0x1550, 0x1550, 0x1550 },
{ 0x1551, 0x1551, 0x1551 },
{ 0x1552, 0x1552, 0x1552 },
{ 0x1553, 0x1553, 0x1553 },
{ 0x1554, 0x1554, 0x1554 },
{ 0x1555, 0x1555, 0x1555 },
{ 0x1556, 0x1556, 0x1556 },
{ 0x1557, 0x1557, 0x1557 },
{ 0x1558, 0x1558, 0x1558 },
{ 0x1559, 0x1559, 0x1559 },
{ 0x155A, 0x155A, 0x155A },
{ 0x155B, 0x155B, 0x155B },
{ 0x155C, 0x155C, 0x155C },
{ 0x155D, 0x155D, 0x155D },
{ 0x155E, 0x155E, 0x155E },
{ 0x155F, 0x155F, 0x155F },
{ 0x1560, 0x1560, 0x1560 },
{ 0x1561, 0x1561, 0x1561 },
{ 0x1562, 0x1562, 0x1562 },
{ 0x1563, 0x1563, 0x1563 },
{ 0x1564, 0x1564, 0x1564 },
{ 0x1565, 0x1565, 0x1565 },
{ 0x1566, 0x1566, 0x1566 },
{ 0x1567, 0x1567, 0x1567 },
{ 0x1568, 0x1568, 0x1568 },
{ 0x1569, 0x1569, 0x1569 },
{ 0x156A, 0x156A, 0x156A },
{ 0x156B, 0x156B, 0x156B },
{ 0x156C, 0x156C, 0x156C },
{ 0x156D, 0x156D, 0x156D },
{ 0x156E, 0x156E, 0x156E },
{ 0x156F, 0x156F, 0x156F },
{ 0x1570, 0x1570, 0x1570 },
{ 0x1571, 0x1571, 0x1571 },
{ 0x1572, 0x1572, 0x1572 },
{ 0x1573, 0x1573, 0x1573 },
{ 0x1574, 0x1574, 0x1574 },
{ 0x1575, 0x1575, 0x1575 },
{ 0x1576, 0x1576, 0x1576 },
{ 0x1577, 0x1577, 0x1577 },
{ 0x1578, 0x1578, 0x1578 },
{ 0x1579, 0x1579, 0x1579 },
{ 0x157A, 0x157A, 0x157A },
{ 0x157B, 0x157B, 0x157B },
{ 0x157C, 0x157C, 0x157C },
{ 0x157D, 0x157D, 0x157D },
{ 0x157E, 0x157E, 0x157E },
{ 0x157F, 0x157F, 0x157F },
{ 0x1580, 0x1580, 0x1580 },
{ 0x1581, 0x1581, 0x1581 },
{ 0x1582, 0x1582, 0x1582 },
{ 0x1583, 0x1583, 0x1583 },
{ 0x1584, 0x1584, 0x1584 },
{ 0x1585, 0x1585, 0x1585 },
{ 0x1586, 0x1586, 0x1586 },
{ 0x1587, 0x1587, 0x1587 },
{ 0x1588, 0x1588, 0x1588 },
{ 0x1589, 0x1589, 0x1589 },
{ 0x158A, 0x158A, 0x158A },
{ 0x158B, 0x158B, 0x158B },
{ 0x158C, 0x158C, 0x158C },
{ 0x158D, 0x158D, 0x158D },
{ 0x158E, 0x158E, 0x158E },
{ 0x158F, 0x158F, 0x158F },
{ 0x1590, 0x1590, 0x1590 },
{ 0x1591, 0x1591, 0x1591 },
{ 0x1592, 0x1592, 0x1592 },
{ 0x1593, 0x1593, 0x1593 },
{ 0x1594, 0x1594, 0x1594 },
{ 0x1595, 0x1595, 0x1595 },
{ 0x1596, 0x1596, 0x1596 },
{ 0x1597, 0x1597, 0x1597 },
{ 0x1598, 0x1598, 0x1598 },
{ 0x1599, 0x1599, 0x1599 },
{ 0x159A, 0x159A, 0x159A },
{ 0x159B, 0x159B, 0x159B },
{ 0x159C, 0x159C, 0x159C },
{ 0x159D, 0x159D, 0x159D },
{ 0x159E, 0x159E, 0x159E },
{ 0x159F, 0x159F, 0x159F },
{ 0x15A0, 0x15A0, 0x15A0 },
{ 0x15A1, 0x15A1, 0x15A1 },
{ 0x15A2, 0x15A2, 0x15A2 },
{ 0x15A3, 0x15A3, 0x15A3 },
{ 0x15A4, 0x15A4, 0x15A4 },
{ 0x15A5, 0x15A5, 0x15A5 },
{ 0x15A6, 0x15A6, 0x15A6 },
{ 0x15A7, 0x15A7, 0x15A7 },
{ 0x15A8, 0x15A8, 0x15A8 },
{ 0x15A9, 0x15A9, 0x15A9 },
{ 0x15AA, 0x15AA, 0x15AA },
{ 0x15AB, 0x15AB, 0x15AB },
{ 0x15AC, 0x15AC, 0x15AC },
{ 0x15AD, 0x15AD, 0x15AD },
{ 0x15AE, 0x15AE, 0x15AE },
{ 0x15AF, 0x15AF, 0x15AF },
{ 0x15B0, 0x15B0, 0x15B0 },
{ 0x15B1, 0x15B1, 0x15B1 },
{ 0x15B2, 0x15B2, 0x15B2 },
{ 0x15B3, 0x15B3, 0x15B3 },
{ 0x15B4, 0x15B4, 0x15B4 },
{ 0x15B5, 0x15B5, 0x15B5 },
{ 0x15B6, 0x15B6, 0x15B6 },
{ 0x15B7, 0x15B7, 0x15B7 },
{ 0x15B8, 0x15B8, 0x15B8 },
{ 0x15B9, 0x15B9, 0x15B9 },
{ 0x15BA, 0x15BA, 0x15BA },
{ 0x15BB, 0x15BB, 0x15BB },
{ 0x15BC, 0x15BC, 0x15BC },
{ 0x15BD, 0x15BD, 0x15BD },
{ 0x15BE, 0x15BE, 0x15BE },
{ 0x15BF, 0x15BF, 0x15BF },
{ 0x15C0, 0x15C0, 0x15C0 },
{ 0x15C1, 0x15C1, 0x15C1 },
{ 0x15C2, 0x15C2, 0x15C2 },
{ 0x15C3, 0x15C3, 0x15C3 },
{ 0x15C4, 0x15C4, 0x15C4 },
{ 0x15C5, 0x15C5, 0x15C5 },
{ 0x15C6, 0x15C6, 0x15C6 },
{ 0x15C7, 0x15C7, 0x15C7 },
{ 0x15C8, 0x15C8, 0x15C8 },
{ 0x15C9, 0x15C9, 0x15C9 },
{ 0x15CA, 0x15CA, 0x15CA },
{ 0x15CB, 0x15CB, 0x15CB },
{ 0x15CC, 0x15CC, 0x15CC },
{ 0x15CD, 0x15CD, 0x15CD },
{ 0x15CE, 0x15CE, 0x15CE },
{ 0x15CF, 0x15CF, 0x15CF },
{ 0x15D0, 0x15D0, 0x15D0 },
{ 0x15D1, 0x15D1, 0x15D1 },
{ 0x15D2, 0x15D2, 0x15D2 },
{ 0x15D3, 0x15D3, 0x15D3 },
{ 0x15D4, 0x15D4, 0x15D4 },
{ 0x15D5, 0x15D5, 0x15D5 },
{ 0x15D6, 0x15D6, 0x15D6 },
{ 0x15D7, 0x15D7, 0x15D7 },
{ 0x15D8, 0x15D8, 0x15D8 },
{ 0x15D9, 0x15D9, 0x15D9 },
{ 0x15DA, 0x15DA, 0x15DA },
{ 0x15DB, 0x15DB, 0x15DB },
{ 0x15DC, 0x15DC, 0x15DC },
{ 0x15DD, 0x15DD, 0x15DD },
{ 0x15DE, 0x15DE, 0x15DE },
{ 0x15DF, 0x15DF, 0x15DF },
{ 0x15E0, 0x15E0, 0x15E0 },
{ 0x15E1, 0x15E1, 0x15E1 },
{ 0x15E2, 0x15E2, 0x15E2 },
{ 0x15E3, 0x15E3, 0x15E3 },
{ 0x15E4, 0x15E4, 0x15E4 },
{ 0x15E5, 0x15E5, 0x15E5 },
{ 0x15E6, 0x15E6, 0x15E6 },
{ 0x15E7, 0x15E7, 0x15E7 },
{ 0x15E8, 0x15E8, 0x15E8 },
{ 0x15E9, 0x15E9, 0x15E9 },
{ 0x15EA, 0x15EA, 0x15EA },
{ 0x15EB, 0x15EB, 0x15EB },
{ 0x15EC, 0x15EC, 0x15EC },
{ 0x15ED, 0x15ED, 0x15ED },
{ 0x15EE, 0x15EE, 0x15EE },
{ 0x15EF, 0x15EF, 0x15EF },
{ 0x15F0, 0x15F0, 0x15F0 },
{ 0x15F1, 0x15F1, 0x15F1 },
{ 0x15F2, 0x15F2, 0x15F2 },
{ 0x15F3, 0x15F3, 0x15F3 },
{ 0x15F4, 0x15F4, 0x15F4 },
{ 0x15F5, 0x15F5, 0x15F5 },
{ 0x15F6, 0x15F6, 0x15F6 },
{ 0x15F7, 0x15F7, 0x15F7 },
{ 0x15F8, 0x15F8, 0x15F8 },
{ 0x15F9, 0x15F9, 0x15F9 },
{ 0x15FA, 0x15FA, 0x15FA },
{ 0x15FB, 0x15FB, 0x15FB },
{ 0x15FC, 0x15FC, 0x15FC },
{ 0x15FD, 0x15FD, 0x15FD },
{ 0x15FE, 0x15FE, 0x15FE },
{ 0x15FF, 0x15FF, 0x15FF },
{ 0x1600, 0x1600, 0x1600 },
{ 0x1601, 0x1601, 0x1601 },
{ 0x1602, 0x1602, 0x1602 },
{ 0x1603, 0x1603, 0x1603 },
{ 0x1604, 0x1604, 0x1604 },
{ 0x1605, 0x1605, 0x1605 },
{ 0x1606, 0x1606, 0x1606 },
{ 0x1607, 0x1607, 0x1607 },
{ 0x1608, 0x1608, 0x1608 },
{ 0x1609, 0x1609, 0x1609 },
{ 0x160A, 0x160A, 0x160A },
{ 0x160B, 0x160B, 0x160B },
{ 0x160C, 0x160C, 0x160C },
{ 0x160D, 0x160D, 0x160D },
{ 0x160E, 0x160E, 0x160E },
{ 0x160F, 0x160F, 0x160F },
{ 0x1610, 0x1610, 0x1610 },
{ 0x1611, 0x1611, 0x1611 },
{ 0x1612, 0x1612, 0x1612 },
{ 0x1613, 0x1613, 0x1613 },
{ 0x1614, 0x1614, 0x1614 },
{ 0x1615, 0x1615, 0x1615 },
{ 0x1616, 0x1616, 0x1616 },
{ 0x1617, 0x1617, 0x1617 },
{ 0x1618, 0x1618, 0x1618 },
{ 0x1619, 0x1619, 0x1619 },
{ 0x161A, 0x161A, 0x161A },
{ 0x161B, 0x161B, 0x161B },
{ 0x161C, 0x161C, 0x161C },
{ 0x161D, 0x161D, 0x161D },
{ 0x161E, 0x161E, 0x161E },
{ 0x161F, 0x161F, 0x161F },
{ 0x1620, 0x1620, 0x1620 },
{ 0x1621, 0x1621, 0x1621 },
{ 0x1622, 0x1622, 0x1622 },
{ 0x1623, 0x1623, 0x1623 },
{ 0x1624, 0x1624, 0x1624 },
{ 0x1625, 0x1625, 0x1625 },
{ 0x1626, 0x1626, 0x1626 },
{ 0x1627, 0x1627, 0x1627 },
{ 0x1628, 0x1628, 0x1628 },
{ 0x1629, 0x1629, 0x1629 },
{ 0x162A, 0x162A, 0x162A },
{ 0x162B, 0x162B, 0x162B },
{ 0x162C, 0x162C, 0x162C },
{ 0x162D, 0x162D, 0x162D },
{ 0x162E, 0x162E, 0x162E },
{ 0x162F, 0x162F, 0x162F },
{ 0x1630, 0x1630, 0x1630 },
{ 0x1631, 0x1631, 0x1631 },
{ 0x1632, 0x1632, 0x1632 },
{ 0x1633, 0x1633, 0x1633 },
{ 0x1634, 0x1634, 0x1634 },
{ 0x1635, 0x1635, 0x1635 },
{ 0x1636, 0x1636, 0x1636 },
{ 0x1637, 0x1637, 0x1637 },
{ 0x1638, 0x1638, 0x1638 },
{ 0x1639, 0x1639, 0x1639 },
{ 0x163A, 0x163A, 0x163A },
{ 0x163B, 0x163B, 0x163B },
{ 0x163C, 0x163C, 0x163C },
{ 0x163D, 0x163D, 0x163D },
{ 0x163E, 0x163E, 0x163E },
{ 0x163F, 0x163F, 0x163F },
{ 0x1640, 0x1640, 0x1640 },
{ 0x1641, 0x1641, 0x1641 },
{ 0x1642, 0x1642, 0x1642 },
{ 0x1643, 0x1643, 0x1643 },
{ 0x1644, 0x1644, 0x1644 },
{ 0x1645, 0x1645, 0x1645 },
{ 0x1646, 0x1646, 0x1646 },
{ 0x1647, 0x1647, 0x1647 },
{ 0x1648, 0x1648, 0x1648 },
{ 0x1649, 0x1649, 0x1649 },
{ 0x164A, 0x164A, 0x164A },
{ 0x164B, 0x164B, 0x164B },
{ 0x164C, 0x164C, 0x164C },
{ 0x164D, 0x164D, 0x164D },
{ 0x164E, 0x164E, 0x164E },
{ 0x164F, 0x164F, 0x164F },
{ 0x1650, 0x1650, 0x1650 },
{ 0x1651, 0x1651, 0x1651 },
{ 0x1652, 0x1652, 0x1652 },
{ 0x1653, 0x1653, 0x1653 },
{ 0x1654, 0x1654, 0x1654 },
{ 0x1655, 0x1655, 0x1655 },
{ 0x1656, 0x1656, 0x1656 },
{ 0x1657, 0x1657, 0x1657 },
{ 0x1658, 0x1658, 0x1658 },
{ 0x1659, 0x1659, 0x1659 },
{ 0x165A, 0x165A, 0x165A },
{ 0x165B, 0x165B, 0x165B },
{ 0x165C, 0x165C, 0x165C },
{ 0x165D, 0x165D, 0x165D },
{ 0x165E, 0x165E, 0x165E },
{ 0x165F, 0x165F, 0x165F },
{ 0x1660, 0x1660, 0x1660 },
{ 0x1661, 0x1661, 0x1661 },
{ 0x1662, 0x1662, 0x1662 },
{ 0x1663, 0x1663, 0x1663 },
{ 0x1664, 0x1664, 0x1664 },
{ 0x1665, 0x1665, 0x1665 },
{ 0x1666, 0x1666, 0x1666 },
{ 0x1667, 0x1667, 0x1667 },
{ 0x1668, 0x1668, 0x1668 },
{ 0x1669, 0x1669, 0x1669 },
{ 0x166A, 0x166A, 0x166A },
{ 0x166B, 0x166B, 0x166B },
{ 0x166C, 0x166C, 0x166C },
{ 0x166F, 0x166F, 0x166F },
{ 0x1670, 0x1670, 0x1670 },
{ 0x1671, 0x1671, 0x1671 },
{ 0x1672, 0x1672, 0x1672 },
{ 0x1673, 0x1673, 0x1673 },
{ 0x1674, 0x1674, 0x1674 },
{ 0x1675, 0x1675, 0x1675 },
{ 0x1676, 0x1676, 0x1676 },
{ 0x1681, 0x1681, 0x1681 },
{ 0x1682, 0x1682, 0x1682 },
{ 0x1683, 0x1683, 0x1683 },
{ 0x1684, 0x1684, 0x1684 },
{ 0x1685, 0x1685, 0x1685 },
{ 0x1686, 0x1686, 0x1686 },
{ 0x1687, 0x1687, 0x1687 },
{ 0x1688, 0x1688, 0x1688 },
{ 0x1689, 0x1689, 0x1689 },
{ 0x168A, 0x168A, 0x168A },
{ 0x168B, 0x168B, 0x168B },
{ 0x168C, 0x168C, 0x168C },
{ 0x168D, 0x168D, 0x168D },
{ 0x168E, 0x168E, 0x168E },
{ 0x168F, 0x168F, 0x168F },
{ 0x1690, 0x1690, 0x1690 },
{ 0x1691, 0x1691, 0x1691 },
{ 0x1692, 0x1692, 0x1692 },
{ 0x1693, 0x1693, 0x1693 },
{ 0x1694, 0x1694, 0x1694 },
{ 0x1695, 0x1695, 0x1695 },
{ 0x1696, 0x1696, 0x1696 },
{ 0x1697, 0x1697, 0x1697 },
{ 0x1698, 0x1698, 0x1698 },
{ 0x1699, 0x1699, 0x1699 },
{ 0x169A, 0x169A, 0x169A },
{ 0x16A0, 0x16A0, 0x16A0 },
{ 0x16A1, 0x16A1, 0x16A1 },
{ 0x16A2, 0x16A2, 0x16A2 },
{ 0x16A3, 0x16A3, 0x16A3 },
{ 0x16A4, 0x16A4, 0x16A4 },
{ 0x16A5, 0x16A5, 0x16A5 },
{ 0x16A6, 0x16A6, 0x16A6 },
{ 0x16A7, 0x16A7, 0x16A7 },
{ 0x16A8, 0x16A8, 0x16A8 },
{ 0x16A9, 0x16A9, 0x16A9 },
{ 0x16AA, 0x16AA, 0x16AA },
{ 0x16AB, 0x16AB, 0x16AB },
{ 0x16AC, 0x16AC, 0x16AC },
{ 0x16AD, 0x16AD, 0x16AD },
{ 0x16AE, 0x16AE, 0x16AE },
{ 0x16AF, 0x16AF, 0x16AF },
{ 0x16B0, 0x16B0, 0x16B0 },
{ 0x16B1, 0x16B1, 0x16B1 },
{ 0x16B2, 0x16B2, 0x16B2 },
{ 0x16B3, 0x16B3, 0x16B3 },
{ 0x16B4, 0x16B4, 0x16B4 },
{ 0x16B5, 0x16B5, 0x16B5 },
{ 0x16B6, 0x16B6, 0x16B6 },
{ 0x16B7, 0x16B7, 0x16B7 },
{ 0x16B8, 0x16B8, 0x16B8 },
{ 0x16B9, 0x16B9, 0x16B9 },
{ 0x16BA, 0x16BA, 0x16BA },
{ 0x16BB, 0x16BB, 0x16BB },
{ 0x16BC, 0x16BC, 0x16BC },
{ 0x16BD, 0x16BD, 0x16BD },
{ 0x16BE, 0x16BE, 0x16BE },
{ 0x16BF, 0x16BF, 0x16BF },
{ 0x16C0, 0x16C0, 0x16C0 },
{ 0x16C1, 0x16C1, 0x16C1 },
{ 0x16C2, 0x16C2, 0x16C2 },
{ 0x16C3, 0x16C3, 0x16C3 },
{ 0x16C4, 0x16C4, 0x16C4 },
{ 0x16C5, 0x16C5, 0x16C5 },
{ 0x16C6, 0x16C6, 0x16C6 },
{ 0x16C7, 0x16C7, 0x16C7 },
{ 0x16C8, 0x16C8, 0x16C8 },
{ 0x16C9, 0x16C9, 0x16C9 },
{ 0x16CA, 0x16CA, 0x16CA },
{ 0x16CB, 0x16CB, 0x16CB },
{ 0x16CC, 0x16CC, 0x16CC },
{ 0x16CD, 0x16CD, 0x16CD },
{ 0x16CE, 0x16CE, 0x16CE },
{ 0x16CF, 0x16CF, 0x16CF },
{ 0x16D0, 0x16D0, 0x16D0 },
{ 0x16D1, 0x16D1, 0x16D1 },
{ 0x16D2, 0x16D2, 0x16D2 },
{ 0x16D3, 0x16D3, 0x16D3 },
{ 0x16D4, 0x16D4, 0x16D4 },
{ 0x16D5, 0x16D5, 0x16D5 },
{ 0x16D6, 0x16D6, 0x16D6 },
{ 0x16D7, 0x16D7, 0x16D7 },
{ 0x16D8, 0x16D8, 0x16D8 },
{ 0x16D9, 0x16D9, 0x16D9 },
{ 0x16DA, 0x16DA, 0x16DA },
{ 0x16DB, 0x16DB, 0x16DB },
{ 0x16DC, 0x16DC, 0x16DC },
{ 0x16DD, 0x16DD, 0x16DD },
{ 0x16DE, 0x16DE, 0x16DE },
{ 0x16DF, 0x16DF, 0x16DF },
{ 0x16E0, 0x16E0, 0x16E0 },
{ 0x16E1, 0x16E1, 0x16E1 },
{ 0x16E2, 0x16E2, 0x16E2 },
{ 0x16E3, 0x16E3, 0x16E3 },
{ 0x16E4, 0x16E4, 0x16E4 },
{ 0x16E5, 0x16E5, 0x16E5 },
{ 0x16E6, 0x16E6, 0x16E6 },
{ 0x16E7, 0x16E7, 0x16E7 },
{ 0x16E8, 0x16E8, 0x16E8 },
{ 0x16E9, 0x16E9, 0x16E9 },
{ 0x16EA, 0x16EA, 0x16EA },
{ 0x1700, 0x1700, 0x1700 },
{ 0x1701, 0x1701, 0x1701 },
{ 0x1702, 0x1702, 0x1702 },
{ 0x1703, 0x1703, 0x1703 },
{ 0x1704, 0x1704, 0x1704 },
{ 0x1705, 0x1705, 0x1705 },
{ 0x1706, 0x1706, 0x1706 },
{ 0x1707, 0x1707, 0x1707 },
{ 0x1708, 0x1708, 0x1708 },
{ 0x1709, 0x1709, 0x1709 },
{ 0x170A, 0x170A, 0x170A },
{ 0x170B, 0x170B, 0x170B },
{ 0x170C, 0x170C, 0x170C },
{ 0x170E, 0x170E, 0x170E },
{ 0x170F, 0x170F, 0x170F },
{ 0x1710, 0x1710, 0x1710 },
{ 0x1711, 0x1711, 0x1711 },
{ 0x1712, 0x1712, 0x1712 },
{ 0x1713, 0x1713, 0x1713 },
{ 0x1714, 0x1714, 0x1714 },
{ 0x1720, 0x1720, 0x1720 },
{ 0x1721, 0x1721, 0x1721 },
{ 0x1722, 0x1722, 0x1722 },
{ 0x1723, 0x1723, 0x1723 },
{ 0x1724, 0x1724, 0x1724 },
{ 0x1725, 0x1725, 0x1725 },
{ 0x1726, 0x1726, 0x1726 },
{ 0x1727, 0x1727, 0x1727 },
{ 0x1728, 0x1728, 0x1728 },
{ 0x1729, 0x1729, 0x1729 },
{ 0x172A, 0x172A, 0x172A },
{ 0x172B, 0x172B, 0x172B },
{ 0x172C, 0x172C, 0x172C },
{ 0x172D, 0x172D, 0x172D },
{ 0x172E, 0x172E, 0x172E },
{ 0x172F, 0x172F, 0x172F },
{ 0x1730, 0x1730, 0x1730 },
{ 0x1731, 0x1731, 0x1731 },
{ 0x1732, 0x1732, 0x1732 },
{ 0x1733, 0x1733, 0x1733 },
{ 0x1734, 0x1734, 0x1734 },
{ 0x1740, 0x1740, 0x1740 },
{ 0x1741, 0x1741, 0x1741 },
{ 0x1742, 0x1742, 0x1742 },
{ 0x1743, 0x1743, 0x1743 },
{ 0x1744, 0x1744, 0x1744 },
{ 0x1745, 0x1745, 0x1745 },
{ 0x1746, 0x1746, 0x1746 },
{ 0x1747, 0x1747, 0x1747 },
{ 0x1748, 0x1748, 0x1748 },
{ 0x1749, 0x1749, 0x1749 },
{ 0x174A, 0x174A, 0x174A },
{ 0x174B, 0x174B, 0x174B },
{ 0x174C, 0x174C, 0x174C },
{ 0x174D, 0x174D, 0x174D },
{ 0x174E, 0x174E, 0x174E },
{ 0x174F, 0x174F, 0x174F },
{ 0x1750, 0x1750, 0x1750 },
{ 0x1751, 0x1751, 0x1751 },
{ 0x1752, 0x1752, 0x1752 },
{ 0x1753, 0x1753, 0x1753 },
{ 0x1760, 0x1760, 0x1760 },
{ 0x1761, 0x1761, 0x1761 },
{ 0x1762, 0x1762, 0x1762 },
{ 0x1763, 0x1763, 0x1763 },
{ 0x1764, 0x1764, 0x1764 },
{ 0x1765, 0x1765, 0x1765 },
{ 0x1766, 0x1766, 0x1766 },
{ 0x1767, 0x1767, 0x1767 },
{ 0x1768, 0x1768, 0x1768 },
{ 0x1769, 0x1769, 0x1769 },
{ 0x176A, 0x176A, 0x176A },
{ 0x176B, 0x176B, 0x176B },
{ 0x176C, 0x176C, 0x176C },
{ 0x176E, 0x176E, 0x176E },
{ 0x176F, 0x176F, 0x176F },
{ 0x1770, 0x1770, 0x1770 },
{ 0x1772, 0x1772, 0x1772 },
{ 0x1773, 0x1773, 0x1773 },
{ 0x1780, 0x1780, 0x1780 },
{ 0x1781, 0x1781, 0x1781 },
{ 0x1782, 0x1782, 0x1782 },
{ 0x1783, 0x1783, 0x1783 },
{ 0x1784, 0x1784, 0x1784 },
{ 0x1785, 0x1785, 0x1785 },
{ 0x1786, 0x1786, 0x1786 },
{ 0x1787, 0x1787, 0x1787 },
{ 0x1788, 0x1788, 0x1788 },
{ 0x1789, 0x1789, 0x1789 },
{ 0x178A, 0x178A, 0x178A },
{ 0x178B, 0x178B, 0x178B },
{ 0x178C, 0x178C, 0x178C },
{ 0x178D, 0x178D, 0x178D },
{ 0x178E, 0x178E, 0x178E },
{ 0x178F, 0x178F, 0x178F },
{ 0x1790, 0x1790, 0x1790 },
{ 0x1791, 0x1791, 0x1791 },
{ 0x1792, 0x1792, 0x1792 },
{ 0x1793, 0x1793, 0x1793 },
{ 0x1794, 0x1794, 0x1794 },
{ 0x1795, 0x1795, 0x1795 },
{ 0x1796, 0x1796, 0x1796 },
{ 0x1797, 0x1797, 0x1797 },
{ 0x1798, 0x1798, 0x1798 },
{ 0x1799, 0x1799, 0x1799 },
{ 0x179A, 0x179A, 0x179A },
{ 0x179B, 0x179B, 0x179B },
{ 0x179C, 0x179C, 0x179C },
{ 0x179D, 0x179D, 0x179D },
{ 0x179E, 0x179E, 0x179E },
{ 0x179F, 0x179F, 0x179F },
{ 0x17A0, 0x17A0, 0x17A0 },
{ 0x17A1, 0x17A1, 0x17A1 },
{ 0x17A2, 0x17A2, 0x17A2 },
{ 0x17A3, 0x17A3, 0x17A3 },
{ 0x17A4, 0x17A4, 0x17A4 },
{ 0x17A5, 0x17A5, 0x17A5 },
{ 0x17A6, 0x17A6, 0x17A6 },
{ 0x17A7, 0x17A7, 0x17A7 },
{ 0x17A8, 0x17A8, 0x17A8 },
{ 0x17A9, 0x17A9, 0x17A9 },
{ 0x17AA, 0x17AA, 0x17AA },
{ 0x17AB, 0x17AB, 0x17AB },
{ 0x17AC, 0x17AC, 0x17AC },
{ 0x17AD, 0x17AD, 0x17AD },
{ 0x17AE, 0x17AE, 0x17AE },
{ 0x17AF, 0x17AF, 0x17AF },
{ 0x17B0, 0x17B0, 0x17B0 },
{ 0x17B1, 0x17B1, 0x17B1 },
{ 0x17B2, 0x17B2, 0x17B2 },
{ 0x17B3, 0x17B3, 0x17B3 },
{ 0x17B7, 0x17B7, 0x17B7 },
{ 0x17B8, 0x17B8, 0x17B8 },
{ 0x17B9, 0x17B9, 0x17B9 },
{ 0x17BA, 0x17BA, 0x17BA },
{ 0x17BB, 0x17BB, 0x17BB },
{ 0x17BC, 0x17BC, 0x17BC },
{ 0x17BD, 0x17BD, 0x17BD },
{ 0x17C6, 0x17C6, 0x17C6 },
{ 0x17C9, 0x17C9, 0x17C9 },
{ 0x17CA, 0x17CA, 0x17CA },
{ 0x17CB, 0x17CB, 0x17CB },
{ 0x17CC, 0x17CC, 0x17CC },
{ 0x17CD, 0x17CD, 0x17CD },
{ 0x17CE, 0x17CE, 0x17CE },
{ 0x17CF, 0x17CF, 0x17CF },
{ 0x17D0, 0x17D0, 0x17D0 },
{ 0x17D1, 0x17D1, 0x17D1 },
{ 0x17D2, 0x17D2, 0x17D2 },
{ 0x17D3, 0x17D3, 0x17D3 },
{ 0x17D7, 0x17D7, 0x17D7 },
{ 0x17DC, 0x17DC, 0x17DC },
{ 0x17DD, 0x17DD, 0x17DD },
{ 0x180B, 0x180B, 0x180B },
{ 0x180C, 0x180C, 0x180C },
{ 0x180D, 0x180D, 0x180D },
{ 0x1820, 0x1820, 0x1820 },
{ 0x1821, 0x1821, 0x1821 },
{ 0x1822, 0x1822, 0x1822 },
{ 0x1823, 0x1823, 0x1823 },
{ 0x1824, 0x1824, 0x1824 },
{ 0x1825, 0x1825, 0x1825 },
{ 0x1826, 0x1826, 0x1826 },
{ 0x1827, 0x1827, 0x1827 },
{ 0x1828, 0x1828, 0x1828 },
{ 0x1829, 0x1829, 0x1829 },
{ 0x182A, 0x182A, 0x182A },
{ 0x182B, 0x182B, 0x182B },
{ 0x182C, 0x182C, 0x182C },
{ 0x182D, 0x182D, 0x182D },
{ 0x182E, 0x182E, 0x182E },
{ 0x182F, 0x182F, 0x182F },
{ 0x1830, 0x1830, 0x1830 },
{ 0x1831, 0x1831, 0x1831 },
{ 0x1832, 0x1832, 0x1832 },
{ 0x1833, 0x1833, 0x1833 },
{ 0x1834, 0x1834, 0x1834 },
{ 0x1835, 0x1835, 0x1835 },
{ 0x1836, 0x1836, 0x1836 },
{ 0x1837, 0x1837, 0x1837 },
{ 0x1838, 0x1838, 0x1838 },
{ 0x1839, 0x1839, 0x1839 },
{ 0x183A, 0x183A, 0x183A },
{ 0x183B, 0x183B, 0x183B },
{ 0x183C, 0x183C, 0x183C },
{ 0x183D, 0x183D, 0x183D },
{ 0x183E, 0x183E, 0x183E },
{ 0x183F, 0x183F, 0x183F },
{ 0x1840, 0x1840, 0x1840 },
{ 0x1841, 0x1841, 0x1841 },
{ 0x1842, 0x1842, 0x1842 },
{ 0x1843, 0x1843, 0x1843 },
{ 0x1844, 0x1844, 0x1844 },
{ 0x1845, 0x1845, 0x1845 },
{ 0x1846, 0x1846, 0x1846 },
{ 0x1847, 0x1847, 0x1847 },
{ 0x1848, 0x1848, 0x1848 },
{ 0x1849, 0x1849, 0x1849 },
{ 0x184A, 0x184A, 0x184A },
{ 0x184B, 0x184B, 0x184B },
{ 0x184C, 0x184C, 0x184C },
{ 0x184D, 0x184D, 0x184D },
{ 0x184E, 0x184E, 0x184E },
{ 0x184F, 0x184F, 0x184F },
{ 0x1850, 0x1850, 0x1850 },
{ 0x1851, 0x1851, 0x1851 },
{ 0x1852, 0x1852, 0x1852 },
{ 0x1853, 0x1853, 0x1853 },
{ 0x1854, 0x1854, 0x1854 },
{ 0x1855, 0x1855, 0x1855 },
{ 0x1856, 0x1856, 0x1856 },
{ 0x1857, 0x1857, 0x1857 },
{ 0x1858, 0x1858, 0x1858 },
{ 0x1859, 0x1859, 0x1859 },
{ 0x185A, 0x185A, 0x185A },
{ 0x185B, 0x185B, 0x185B },
{ 0x185C, 0x185C, 0x185C },
{ 0x185D, 0x185D, 0x185D },
{ 0x185E, 0x185E, 0x185E },
{ 0x185F, 0x185F, 0x185F },
{ 0x1860, 0x1860, 0x1860 },
{ 0x1861, 0x1861, 0x1861 },
{ 0x1862, 0x1862, 0x1862 },
{ 0x1863, 0x1863, 0x1863 },
{ 0x1864, 0x1864, 0x1864 },
{ 0x1865, 0x1865, 0x1865 },
{ 0x1866, 0x1866, 0x1866 },
{ 0x1867, 0x1867, 0x1867 },
{ 0x1868, 0x1868, 0x1868 },
{ 0x1869, 0x1869, 0x1869 },
{ 0x186A, 0x186A, 0x186A },
{ 0x186B, 0x186B, 0x186B },
{ 0x186C, 0x186C, 0x186C },
{ 0x186D, 0x186D, 0x186D },
{ 0x186E, 0x186E, 0x186E },
{ 0x186F, 0x186F, 0x186F },
{ 0x1870, 0x1870, 0x1870 },
{ 0x1871, 0x1871, 0x1871 },
{ 0x1872, 0x1872, 0x1872 },
{ 0x1873, 0x1873, 0x1873 },
{ 0x1874, 0x1874, 0x1874 },
{ 0x1875, 0x1875, 0x1875 },
{ 0x1876, 0x1876, 0x1876 },
{ 0x1877, 0x1877, 0x1877 },
{ 0x1880, 0x1880, 0x1880 },
{ 0x1881, 0x1881, 0x1881 },
{ 0x1882, 0x1882, 0x1882 },
{ 0x1883, 0x1883, 0x1883 },
{ 0x1884, 0x1884, 0x1884 },
{ 0x1885, 0x1885, 0x1885 },
{ 0x1886, 0x1886, 0x1886 },
{ 0x1887, 0x1887, 0x1887 },
{ 0x1888, 0x1888, 0x1888 },
{ 0x1889, 0x1889, 0x1889 },
{ 0x188A, 0x188A, 0x188A },
{ 0x188B, 0x188B, 0x188B },
{ 0x188C, 0x188C, 0x188C },
{ 0x188D, 0x188D, 0x188D },
{ 0x188E, 0x188E, 0x188E },
{ 0x188F, 0x188F, 0x188F },
{ 0x1890, 0x1890, 0x1890 },
{ 0x1891, 0x1891, 0x1891 },
{ 0x1892, 0x1892, 0x1892 },
{ 0x1893, 0x1893, 0x1893 },
{ 0x1894, 0x1894, 0x1894 },
{ 0x1895, 0x1895, 0x1895 },
{ 0x1896, 0x1896, 0x1896 },
{ 0x1897, 0x1897, 0x1897 },
{ 0x1898, 0x1898, 0x1898 },
{ 0x1899, 0x1899, 0x1899 },
{ 0x189A, 0x189A, 0x189A },
{ 0x189B, 0x189B, 0x189B },
{ 0x189C, 0x189C, 0x189C },
{ 0x189D, 0x189D, 0x189D },
{ 0x189E, 0x189E, 0x189E },
{ 0x189F, 0x189F, 0x189F },
{ 0x18A0, 0x18A0, 0x18A0 },
{ 0x18A1, 0x18A1, 0x18A1 },
{ 0x18A2, 0x18A2, 0x18A2 },
{ 0x18A3, 0x18A3, 0x18A3 },
{ 0x18A4, 0x18A4, 0x18A4 },
{ 0x18A5, 0x18A5, 0x18A5 },
{ 0x18A6, 0x18A6, 0x18A6 },
{ 0x18A7, 0x18A7, 0x18A7 },
{ 0x18A8, 0x18A8, 0x18A8 },
{ 0x18A9, 0x18A9, 0x18A9 },
{ 0x1900, 0x1900, 0x1900 },
{ 0x1901, 0x1901, 0x1901 },
{ 0x1902, 0x1902, 0x1902 },
{ 0x1903, 0x1903, 0x1903 },
{ 0x1904, 0x1904, 0x1904 },
{ 0x1905, 0x1905, 0x1905 },
{ 0x1906, 0x1906, 0x1906 },
{ 0x1907, 0x1907, 0x1907 },
{ 0x1908, 0x1908, 0x1908 },
{ 0x1909, 0x1909, 0x1909 },
{ 0x190A, 0x190A, 0x190A },
{ 0x190B, 0x190B, 0x190B },
{ 0x190C, 0x190C, 0x190C },
{ 0x190D, 0x190D, 0x190D },
{ 0x190E, 0x190E, 0x190E },
{ 0x190F, 0x190F, 0x190F },
{ 0x1910, 0x1910, 0x1910 },
{ 0x1911, 0x1911, 0x1911 },
{ 0x1912, 0x1912, 0x1912 },
{ 0x1913, 0x1913, 0x1913 },
{ 0x1914, 0x1914, 0x1914 },
{ 0x1915, 0x1915, 0x1915 },
{ 0x1916, 0x1916, 0x1916 },
{ 0x1917, 0x1917, 0x1917 },
{ 0x1918, 0x1918, 0x1918 },
{ 0x1919, 0x1919, 0x1919 },
{ 0x191A, 0x191A, 0x191A },
{ 0x191B, 0x191B, 0x191B },
{ 0x191C, 0x191C, 0x191C },
{ 0x1920, 0x1920, 0x1920 },
{ 0x1921, 0x1921, 0x1921 },
{ 0x1922, 0x1922, 0x1922 },
{ 0x1927, 0x1927, 0x1927 },
{ 0x1928, 0x1928, 0x1928 },
{ 0x1932, 0x1932, 0x1932 },
{ 0x1939, 0x1939, 0x1939 },
{ 0x193A, 0x193A, 0x193A },
{ 0x193B, 0x193B, 0x193B },
{ 0x1950, 0x1950, 0x1950 },
{ 0x1951, 0x1951, 0x1951 },
{ 0x1952, 0x1952, 0x1952 },
{ 0x1953, 0x1953, 0x1953 },
{ 0x1954, 0x1954, 0x1954 },
{ 0x1955, 0x1955, 0x1955 },
{ 0x1956, 0x1956, 0x1956 },
{ 0x1957, 0x1957, 0x1957 },
{ 0x1958, 0x1958, 0x1958 },
{ 0x1959, 0x1959, 0x1959 },
{ 0x195A, 0x195A, 0x195A },
{ 0x195B, 0x195B, 0x195B },
{ 0x195C, 0x195C, 0x195C },
{ 0x195D, 0x195D, 0x195D },
{ 0x195E, 0x195E, 0x195E },
{ 0x195F, 0x195F, 0x195F },
{ 0x1960, 0x1960, 0x1960 },
{ 0x1961, 0x1961, 0x1961 },
{ 0x1962, 0x1962, 0x1962 },
{ 0x1963, 0x1963, 0x1963 },
{ 0x1964, 0x1964, 0x1964 },
{ 0x1965, 0x1965, 0x1965 },
{ 0x1966, 0x1966, 0x1966 },
{ 0x1967, 0x1967, 0x1967 },
{ 0x1968, 0x1968, 0x1968 },
{ 0x1969, 0x1969, 0x1969 },
{ 0x196A, 0x196A, 0x196A },
{ 0x196B, 0x196B, 0x196B },
{ 0x196C, 0x196C, 0x196C },
{ 0x196D, 0x196D, 0x196D },
{ 0x1970, 0x1970, 0x1970 },
{ 0x1971, 0x1971, 0x1971 },
{ 0x1972, 0x1972, 0x1972 },
{ 0x1973, 0x1973, 0x1973 },
{ 0x1974, 0x1974, 0x1974 },
{ 0x1980, 0x1980, 0x1980 },
{ 0x1981, 0x1981, 0x1981 },
{ 0x1982, 0x1982, 0x1982 },
{ 0x1983, 0x1983, 0x1983 },
{ 0x1984, 0x1984, 0x1984 },
{ 0x1985, 0x1985, 0x1985 },
{ 0x1986, 0x1986, 0x1986 },
{ 0x1987, 0x1987, 0x1987 },
{ 0x1988, 0x1988, 0x1988 },
{ 0x1989, 0x1989, 0x1989 },
{ 0x198A, 0x198A, 0x198A },
{ 0x198B, 0x198B, 0x198B },
{ 0x198C, 0x198C, 0x198C },
{ 0x198D, 0x198D, 0x198D },
{ 0x198E, 0x198E, 0x198E },
{ 0x198F, 0x198F, 0x198F },
{ 0x1990, 0x1990, 0x1990 },
{ 0x1991, 0x1991, 0x1991 },
{ 0x1992, 0x1992, 0x1992 },
{ 0x1993, 0x1993, 0x1993 },
{ 0x1994, 0x1994, 0x1994 },
{ 0x1995, 0x1995, 0x1995 },
{ 0x1996, 0x1996, 0x1996 },
{ 0x1997, 0x1997, 0x1997 },
{ 0x1998, 0x1998, 0x1998 },
{ 0x1999, 0x1999, 0x1999 },
{ 0x199A, 0x199A, 0x199A },
{ 0x199B, 0x199B, 0x199B },
{ 0x199C, 0x199C, 0x199C },
{ 0x199D, 0x199D, 0x199D },
{ 0x199E, 0x199E, 0x199E },
{ 0x199F, 0x199F, 0x199F },
{ 0x19A0, 0x19A0, 0x19A0 },
{ 0x19A1, 0x19A1, 0x19A1 },
{ 0x19A2, 0x19A2, 0x19A2 },
{ 0x19A3, 0x19A3, 0x19A3 },
{ 0x19A4, 0x19A4, 0x19A4 },
{ 0x19A5, 0x19A5, 0x19A5 },
{ 0x19A6, 0x19A6, 0x19A6 },
{ 0x19A7, 0x19A7, 0x19A7 },
{ 0x19A8, 0x19A8, 0x19A8 },
{ 0x19A9, 0x19A9, 0x19A9 },
{ 0x19C1, 0x19C1, 0x19C1 },
{ 0x19C2, 0x19C2, 0x19C2 },
{ 0x19C3, 0x19C3, 0x19C3 },
{ 0x19C4, 0x19C4, 0x19C4 },
{ 0x19C5, 0x19C5, 0x19C5 },
{ 0x19C6, 0x19C6, 0x19C6 },
{ 0x19C7, 0x19C7, 0x19C7 },
{ 0x1A00, 0x1A00, 0x1A00 },
{ 0x1A01, 0x1A01, 0x1A01 },
{ 0x1A02, 0x1A02, 0x1A02 },
{ 0x1A03, 0x1A03, 0x1A03 },
{ 0x1A04, 0x1A04, 0x1A04 },
{ 0x1A05, 0x1A05, 0x1A05 },
{ 0x1A06, 0x1A06, 0x1A06 },
{ 0x1A07, 0x1A07, 0x1A07 },
{ 0x1A08, 0x1A08, 0x1A08 },
{ 0x1A09, 0x1A09, 0x1A09 },
{ 0x1A0A, 0x1A0A, 0x1A0A },
{ 0x1A0B, 0x1A0B, 0x1A0B },
{ 0x1A0C, 0x1A0C, 0x1A0C },
{ 0x1A0D, 0x1A0D, 0x1A0D },
{ 0x1A0E, 0x1A0E, 0x1A0E },
{ 0x1A0F, 0x1A0F, 0x1A0F },
{ 0x1A10, 0x1A10, 0x1A10 },
{ 0x1A11, 0x1A11, 0x1A11 },
{ 0x1A12, 0x1A12, 0x1A12 },
{ 0x1A13, 0x1A13, 0x1A13 },
{ 0x1A14, 0x1A14, 0x1A14 },
{ 0x1A15, 0x1A15, 0x1A15 },
{ 0x1A16, 0x1A16, 0x1A16 },
{ 0x1A17, 0x1A17, 0x1A17 },
{ 0x1A18, 0x1A18, 0x1A18 },
{ 0x1D00, 0x1D00, 0x1D00 },
{ 0x1D01, 0x1D01, 0x1D01 },
{ 0x1D02, 0x1D02, 0x1D02 },
{ 0x1D03, 0x1D03, 0x1D03 },
{ 0x1D04, 0x1D04, 0x1D04 },
{ 0x1D05, 0x1D05, 0x1D05 },
{ 0x1D06, 0x1D06, 0x1D06 },
{ 0x1D07, 0x1D07, 0x1D07 },
{ 0x1D08, 0x1D08, 0x1D08 },
{ 0x1D09, 0x1D09, 0x1D09 },
{ 0x1D0A, 0x1D0A, 0x1D0A },
{ 0x1D0B, 0x1D0B, 0x1D0B },
{ 0x1D0C, 0x1D0C, 0x1D0C },
{ 0x1D0D, 0x1D0D, 0x1D0D },
{ 0x1D0E, 0x1D0E, 0x1D0E },
{ 0x1D0F, 0x1D0F, 0x1D0F },
{ 0x1D10, 0x1D10, 0x1D10 },
{ 0x1D11, 0x1D11, 0x1D11 },
{ 0x1D12, 0x1D12, 0x1D12 },
{ 0x1D13, 0x1D13, 0x1D13 },
{ 0x1D14, 0x1D14, 0x1D14 },
{ 0x1D15, 0x1D15, 0x1D15 },
{ 0x1D16, 0x1D16, 0x1D16 },
{ 0x1D17, 0x1D17, 0x1D17 },
{ 0x1D18, 0x1D18, 0x1D18 },
{ 0x1D19, 0x1D19, 0x1D19 },
{ 0x1D1A, 0x1D1A, 0x1D1A },
{ 0x1D1B, 0x1D1B, 0x1D1B },
{ 0x1D1C, 0x1D1C, 0x1D1C },
{ 0x1D1D, 0x1D1D, 0x1D1D },
{ 0x1D1E, 0x1D1E, 0x1D1E },
{ 0x1D1F, 0x1D1F, 0x1D1F },
{ 0x1D20, 0x1D20, 0x1D20 },
{ 0x1D21, 0x1D21, 0x1D21 },
{ 0x1D22, 0x1D22, 0x1D22 },
{ 0x1D23, 0x1D23, 0x1D23 },
{ 0x1D24, 0x1D24, 0x1D24 },
{ 0x1D25, 0x1D25, 0x1D25 },
{ 0x1D26, 0x1D26, 0x1D26 },
{ 0x1D27, 0x1D27, 0x1D27 },
{ 0x1D28, 0x1D28, 0x1D28 },
{ 0x1D29, 0x1D29, 0x1D29 },
{ 0x1D2A, 0x1D2A, 0x1D2A },
{ 0x1D2B, 0x1D2B, 0x1D2B },
{ 0x1D2C, 0x1D2C, 0x1D2C },
{ 0x1D2D, 0x1D2D, 0x1D2D },
{ 0x1D2E, 0x1D2E, 0x1D2E },
{ 0x1D2F, 0x1D2F, 0x1D2F },
{ 0x1D30, 0x1D30, 0x1D30 },
{ 0x1D31, 0x1D31, 0x1D31 },
{ 0x1D32, 0x1D32, 0x1D32 },
{ 0x1D33, 0x1D33, 0x1D33 },
{ 0x1D34, 0x1D34, 0x1D34 },
{ 0x1D35, 0x1D35, 0x1D35 },
{ 0x1D36, 0x1D36, 0x1D36 },
{ 0x1D37, 0x1D37, 0x1D37 },
{ 0x1D38, 0x1D38, 0x1D38 },
{ 0x1D39, 0x1D39, 0x1D39 },
{ 0x1D3A, 0x1D3A, 0x1D3A },
{ 0x1D3B, 0x1D3B, 0x1D3B },
{ 0x1D3C, 0x1D3C, 0x1D3C },
{ 0x1D3D, 0x1D3D, 0x1D3D },
{ 0x1D3E, 0x1D3E, 0x1D3E },
{ 0x1D3F, 0x1D3F, 0x1D3F },
{ 0x1D40, 0x1D40, 0x1D40 },
{ 0x1D41, 0x1D41, 0x1D41 },
{ 0x1D42, 0x1D42, 0x1D42 },
{ 0x1D43, 0x1D43, 0x1D43 },
{ 0x1D44, 0x1D44, 0x1D44 },
{ 0x1D45, 0x1D45, 0x1D45 },
{ 0x1D46, 0x1D46, 0x1D46 },
{ 0x1D47, 0x1D47, 0x1D47 },
{ 0x1D48, 0x1D48, 0x1D48 },
{ 0x1D49, 0x1D49, 0x1D49 },
{ 0x1D4A, 0x1D4A, 0x1D4A },
{ 0x1D4B, 0x1D4B, 0x1D4B },
{ 0x1D4C, 0x1D4C, 0x1D4C },
{ 0x1D4D, 0x1D4D, 0x1D4D },
{ 0x1D4E, 0x1D4E, 0x1D4E },
{ 0x1D4F, 0x1D4F, 0x1D4F },
{ 0x1D50, 0x1D50, 0x1D50 },
{ 0x1D51, 0x1D51, 0x1D51 },
{ 0x1D52, 0x1D52, 0x1D52 },
{ 0x1D53, 0x1D53, 0x1D53 },
{ 0x1D54, 0x1D54, 0x1D54 },
{ 0x1D55, 0x1D55, 0x1D55 },
{ 0x1D56, 0x1D56, 0x1D56 },
{ 0x1D57, 0x1D57, 0x1D57 },
{ 0x1D58, 0x1D58, 0x1D58 },
{ 0x1D59, 0x1D59, 0x1D59 },
{ 0x1D5A, 0x1D5A, 0x1D5A },
{ 0x1D5B, 0x1D5B, 0x1D5B },
{ 0x1D5C, 0x1D5C, 0x1D5C },
{ 0x1D5D, 0x1D5D, 0x1D5D },
{ 0x1D5E, 0x1D5E, 0x1D5E },
{ 0x1D5F, 0x1D5F, 0x1D5F },
{ 0x1D60, 0x1D60, 0x1D60 },
{ 0x1D61, 0x1D61, 0x1D61 },
{ 0x1D62, 0x1D62, 0x1D62 },
{ 0x1D63, 0x1D63, 0x1D63 },
{ 0x1D64, 0x1D64, 0x1D64 },
{ 0x1D65, 0x1D65, 0x1D65 },
{ 0x1D66, 0x1D66, 0x1D66 },
{ 0x1D67, 0x1D67, 0x1D67 },
{ 0x1D68, 0x1D68, 0x1D68 },
{ 0x1D69, 0x1D69, 0x1D69 },
{ 0x1D6A, 0x1D6A, 0x1D6A },
{ 0x1D6B, 0x1D6B, 0x1D6B },
{ 0x1D6C, 0x1D6C, 0x1D6C },
{ 0x1D6D, 0x1D6D, 0x1D6D },
{ 0x1D6E, 0x1D6E, 0x1D6E },
{ 0x1D6F, 0x1D6F, 0x1D6F },
{ 0x1D70, 0x1D70, 0x1D70 },
{ 0x1D71, 0x1D71, 0x1D71 },
{ 0x1D72, 0x1D72, 0x1D72 },
{ 0x1D73, 0x1D73, 0x1D73 },
{ 0x1D74, 0x1D74, 0x1D74 },
{ 0x1D75, 0x1D75, 0x1D75 },
{ 0x1D76, 0x1D76, 0x1D76 },
{ 0x1D77, 0x1D77, 0x1D77 },
{ 0x1D78, 0x1D78, 0x1D78 },
{ 0x1D79, 0x1D79, 0x1D79 },
{ 0x1D7A, 0x1D7A, 0x1D7A },
{ 0x1D7B, 0x1D7B, 0x1D7B },
{ 0x1D7C, 0x1D7C, 0x1D7C },
{ 0x1D7D, 0x1D7D, 0x1D7D },
{ 0x1D7E, 0x1D7E, 0x1D7E },
{ 0x1D7F, 0x1D7F, 0x1D7F },
{ 0x1D80, 0x1D80, 0x1D80 },
{ 0x1D81, 0x1D81, 0x1D81 },
{ 0x1D82, 0x1D82, 0x1D82 },
{ 0x1D83, 0x1D83, 0x1D83 },
{ 0x1D84, 0x1D84, 0x1D84 },
{ 0x1D85, 0x1D85, 0x1D85 },
{ 0x1D86, 0x1D86, 0x1D86 },
{ 0x1D87, 0x1D87, 0x1D87 },
{ 0x1D88, 0x1D88, 0x1D88 },
{ 0x1D89, 0x1D89, 0x1D89 },
{ 0x1D8A, 0x1D8A, 0x1D8A },
{ 0x1D8B, 0x1D8B, 0x1D8B },
{ 0x1D8C, 0x1D8C, 0x1D8C },
{ 0x1D8D, 0x1D8D, 0x1D8D },
{ 0x1D8E, 0x1D8E, 0x1D8E },
{ 0x1D8F, 0x1D8F, 0x1D8F },
{ 0x1D90, 0x1D90, 0x1D90 },
{ 0x1D91, 0x1D91, 0x1D91 },
{ 0x1D92, 0x1D92, 0x1D92 },
{ 0x1D93, 0x1D93, 0x1D93 },
{ 0x1D94, 0x1D94, 0x1D94 },
{ 0x1D95, 0x1D95, 0x1D95 },
{ 0x1D96, 0x1D96, 0x1D96 },
{ 0x1D97, 0x1D97, 0x1D97 },
{ 0x1D98, 0x1D98, 0x1D98 },
{ 0x1D99, 0x1D99, 0x1D99 },
{ 0x1D9A, 0x1D9A, 0x1D9A },
{ 0x1D9B, 0x1D9B, 0x1D9B },
{ 0x1D9C, 0x1D9C, 0x1D9C },
{ 0x1D9D, 0x1D9D, 0x1D9D },
{ 0x1D9E, 0x1D9E, 0x1D9E },
{ 0x1D9F, 0x1D9F, 0x1D9F },
{ 0x1DA0, 0x1DA0, 0x1DA0 },
{ 0x1DA1, 0x1DA1, 0x1DA1 },
{ 0x1DA2, 0x1DA2, 0x1DA2 },
{ 0x1DA3, 0x1DA3, 0x1DA3 },
{ 0x1DA4, 0x1DA4, 0x1DA4 },
{ 0x1DA5, 0x1DA5, 0x1DA5 },
{ 0x1DA6, 0x1DA6, 0x1DA6 },
{ 0x1DA7, 0x1DA7, 0x1DA7 },
{ 0x1DA8, 0x1DA8, 0x1DA8 },
{ 0x1DA9, 0x1DA9, 0x1DA9 },
{ 0x1DAA, 0x1DAA, 0x1DAA },
{ 0x1DAB, 0x1DAB, 0x1DAB },
{ 0x1DAC, 0x1DAC, 0x1DAC },
{ 0x1DAD, 0x1DAD, 0x1DAD },
{ 0x1DAE, 0x1DAE, 0x1DAE },
{ 0x1DAF, 0x1DAF, 0x1DAF },
{ 0x1DB0, 0x1DB0, 0x1DB0 },
{ 0x1DB1, 0x1DB1, 0x1DB1 },
{ 0x1DB2, 0x1DB2, 0x1DB2 },
{ 0x1DB3, 0x1DB3, 0x1DB3 },
{ 0x1DB4, 0x1DB4, 0x1DB4 },
{ 0x1DB5, 0x1DB5, 0x1DB5 },
{ 0x1DB6, 0x1DB6, 0x1DB6 },
{ 0x1DB7, 0x1DB7, 0x1DB7 },
{ 0x1DB8, 0x1DB8, 0x1DB8 },
{ 0x1DB9, 0x1DB9, 0x1DB9 },
{ 0x1DBA, 0x1DBA, 0x1DBA },
{ 0x1DBB, 0x1DBB, 0x1DBB },
{ 0x1DBC, 0x1DBC, 0x1DBC },
{ 0x1DBD, 0x1DBD, 0x1DBD },
{ 0x1DBE, 0x1DBE, 0x1DBE },
{ 0x1DBF, 0x1DBF, 0x1DBF },
{ 0x1DC0, 0x1DC0, 0x1DC0 },
{ 0x1DC1, 0x1DC1, 0x1DC1 },
{ 0x1DC2, 0x1DC2, 0x1DC2 },
{ 0x1DC3, 0x1DC3, 0x1DC3 },
{ 0x1E00, 0x1E00, 0x1E01 },
{ 0x1E01, 0x1E00, 0x1E01 },
{ 0x1E02, 0x1E02, 0x1E03 },
{ 0x1E03, 0x1E02, 0x1E03 },
{ 0x1E04, 0x1E04, 0x1E05 },
{ 0x1E05, 0x1E04, 0x1E05 },
{ 0x1E06, 0x1E06, 0x1E07 },
{ 0x1E07, 0x1E06, 0x1E07 },
{ 0x1E08, 0x1E08, 0x1E09 },
{ 0x1E09, 0x1E08, 0x1E09 },
{ 0x1E0A, 0x1E0A, 0x1E0B },
{ 0x1E0B, 0x1E0A, 0x1E0B },
{ 0x1E0C, 0x1E0C, 0x1E0D },
{ 0x1E0D, 0x1E0C, 0x1E0D },
{ 0x1E0E, 0x1E0E, 0x1E0F },
{ 0x1E0F, 0x1E0E, 0x1E0F },
{ 0x1E10, 0x1E10, 0x1E11 },
{ 0x1E11, 0x1E10, 0x1E11 },
{ 0x1E12, 0x1E12, 0x1E13 },
{ 0x1E13, 0x1E12, 0x1E13 },
{ 0x1E14, 0x1E14, 0x1E15 },
{ 0x1E15, 0x1E14, 0x1E15 },
{ 0x1E16, 0x1E16, 0x1E17 },
{ 0x1E17, 0x1E16, 0x1E17 },
{ 0x1E18, 0x1E18, 0x1E19 },
{ 0x1E19, 0x1E18, 0x1E19 },
{ 0x1E1A, 0x1E1A, 0x1E1B },
{ 0x1E1B, 0x1E1A, 0x1E1B },
{ 0x1E1C, 0x1E1C, 0x1E1D },
{ 0x1E1D, 0x1E1C, 0x1E1D },
{ 0x1E1E, 0x1E1E, 0x1E1F },
{ 0x1E1F, 0x1E1E, 0x1E1F },
{ 0x1E20, 0x1E20, 0x1E21 },
{ 0x1E21, 0x1E20, 0x1E21 },
{ 0x1E22, 0x1E22, 0x1E23 },
{ 0x1E23, 0x1E22, 0x1E23 },
{ 0x1E24, 0x1E24, 0x1E25 },
{ 0x1E25, 0x1E24, 0x1E25 },
{ 0x1E26, 0x1E26, 0x1E27 },
{ 0x1E27, 0x1E26, 0x1E27 },
{ 0x1E28, 0x1E28, 0x1E29 },
{ 0x1E29, 0x1E28, 0x1E29 },
{ 0x1E2A, 0x1E2A, 0x1E2B },
{ 0x1E2B, 0x1E2A, 0x1E2B },
{ 0x1E2C, 0x1E2C, 0x1E2D },
{ 0x1E2D, 0x1E2C, 0x1E2D },
{ 0x1E2E, 0x1E2E, 0x1E2F },
{ 0x1E2F, 0x1E2E, 0x1E2F },
{ 0x1E30, 0x1E30, 0x1E31 },
{ 0x1E31, 0x1E30, 0x1E31 },
{ 0x1E32, 0x1E32, 0x1E33 },
{ 0x1E33, 0x1E32, 0x1E33 },
{ 0x1E34, 0x1E34, 0x1E35 },
{ 0x1E35, 0x1E34, 0x1E35 },
{ 0x1E36, 0x1E36, 0x1E37 },
{ 0x1E37, 0x1E36, 0x1E37 },
{ 0x1E38, 0x1E38, 0x1E39 },
{ 0x1E39, 0x1E38, 0x1E39 },
{ 0x1E3A, 0x1E3A, 0x1E3B },
{ 0x1E3B, 0x1E3A, 0x1E3B },
{ 0x1E3C, 0x1E3C, 0x1E3D },
{ 0x1E3D, 0x1E3C, 0x1E3D },
{ 0x1E3E, 0x1E3E, 0x1E3F },
{ 0x1E3F, 0x1E3E, 0x1E3F },
{ 0x1E40, 0x1E40, 0x1E41 },
{ 0x1E41, 0x1E40, 0x1E41 },
{ 0x1E42, 0x1E42, 0x1E43 },
{ 0x1E43, 0x1E42, 0x1E43 },
{ 0x1E44, 0x1E44, 0x1E45 },
{ 0x1E45, 0x1E44, 0x1E45 },
{ 0x1E46, 0x1E46, 0x1E47 },
{ 0x1E47, 0x1E46, 0x1E47 },
{ 0x1E48, 0x1E48, 0x1E49 },
{ 0x1E49, 0x1E48, 0x1E49 },
{ 0x1E4A, 0x1E4A, 0x1E4B },
{ 0x1E4B, 0x1E4A, 0x1E4B },
{ 0x1E4C, 0x1E4C, 0x1E4D },
{ 0x1E4D, 0x1E4C, 0x1E4D },
{ 0x1E4E, 0x1E4E, 0x1E4F },
{ 0x1E4F, 0x1E4E, 0x1E4F },
{ 0x1E50, 0x1E50, 0x1E51 },
{ 0x1E51, 0x1E50, 0x1E51 },
{ 0x1E52, 0x1E52, 0x1E53 },
{ 0x1E53, 0x1E52, 0x1E53 },
{ 0x1E54, 0x1E54, 0x1E55 },
{ 0x1E55, 0x1E54, 0x1E55 },
{ 0x1E56, 0x1E56, 0x1E57 },
{ 0x1E57, 0x1E56, 0x1E57 },
{ 0x1E58, 0x1E58, 0x1E59 },
{ 0x1E59, 0x1E58, 0x1E59 },
{ 0x1E5A, 0x1E5A, 0x1E5B },
{ 0x1E5B, 0x1E5A, 0x1E5B },
{ 0x1E5C, 0x1E5C, 0x1E5D },
{ 0x1E5D, 0x1E5C, 0x1E5D },
{ 0x1E5E, 0x1E5E, 0x1E5F },
{ 0x1E5F, 0x1E5E, 0x1E5F },
{ 0x1E60, 0x1E60, 0x1E61 },
{ 0x1E61, 0x1E60, 0x1E61 },
{ 0x1E62, 0x1E62, 0x1E63 },
{ 0x1E63, 0x1E62, 0x1E63 },
{ 0x1E64, 0x1E64, 0x1E65 },
{ 0x1E65, 0x1E64, 0x1E65 },
{ 0x1E66, 0x1E66, 0x1E67 },
{ 0x1E67, 0x1E66, 0x1E67 },
{ 0x1E68, 0x1E68, 0x1E69 },
{ 0x1E69, 0x1E68, 0x1E69 },
{ 0x1E6A, 0x1E6A, 0x1E6B },
{ 0x1E6B, 0x1E6A, 0x1E6B },
{ 0x1E6C, 0x1E6C, 0x1E6D },
{ 0x1E6D, 0x1E6C, 0x1E6D },
{ 0x1E6E, 0x1E6E, 0x1E6F },
{ 0x1E6F, 0x1E6E, 0x1E6F },
{ 0x1E70, 0x1E70, 0x1E71 },
{ 0x1E71, 0x1E70, 0x1E71 },
{ 0x1E72, 0x1E72, 0x1E73 },
{ 0x1E73, 0x1E72, 0x1E73 },
{ 0x1E74, 0x1E74, 0x1E75 },
{ 0x1E75, 0x1E74, 0x1E75 },
{ 0x1E76, 0x1E76, 0x1E77 },
{ 0x1E77, 0x1E76, 0x1E77 },
{ 0x1E78, 0x1E78, 0x1E79 },
{ 0x1E79, 0x1E78, 0x1E79 },
{ 0x1E7A, 0x1E7A, 0x1E7B },
{ 0x1E7B, 0x1E7A, 0x1E7B },
{ 0x1E7C, 0x1E7C, 0x1E7D },
{ 0x1E7D, 0x1E7C, 0x1E7D },
{ 0x1E7E, 0x1E7E, 0x1E7F },
{ 0x1E7F, 0x1E7E, 0x1E7F },
{ 0x1E80, 0x1E80, 0x1E81 },
{ 0x1E81, 0x1E80, 0x1E81 },
{ 0x1E82, 0x1E82, 0x1E83 },
{ 0x1E83, 0x1E82, 0x1E83 },
{ 0x1E84, 0x1E84, 0x1E85 },
{ 0x1E85, 0x1E84, 0x1E85 },
{ 0x1E86, 0x1E86, 0x1E87 },
{ 0x1E87, 0x1E86, 0x1E87 },
{ 0x1E88, 0x1E88, 0x1E89 },
{ 0x1E89, 0x1E88, 0x1E89 },
{ 0x1E8A, 0x1E8A, 0x1E8B },
{ 0x1E8B, 0x1E8A, 0x1E8B },
{ 0x1E8C, 0x1E8C, 0x1E8D },
{ 0x1E8D, 0x1E8C, 0x1E8D },
{ 0x1E8E, 0x1E8E, 0x1E8F },
{ 0x1E8F, 0x1E8E, 0x1E8F },
{ 0x1E90, 0x1E90, 0x1E91 },
{ 0x1E91, 0x1E90, 0x1E91 },
{ 0x1E92, 0x1E92, 0x1E93 },
{ 0x1E93, 0x1E92, 0x1E93 },
{ 0x1E94, 0x1E94, 0x1E95 },
{ 0x1E95, 0x1E94, 0x1E95 },
{ 0x1E96, 0x1E96, 0x1E96 },
{ 0x1E97, 0x1E97, 0x1E97 },
{ 0x1E98, 0x1E98, 0x1E98 },
{ 0x1E99, 0x1E99, 0x1E99 },
{ 0x1E9A, 0x1E9A, 0x1E9A },
{ 0x1E9B, 0x1E60, 0x1E9B },
{ 0x1EA0, 0x1EA0, 0x1EA1 },
{ 0x1EA1, 0x1EA0, 0x1EA1 },
{ 0x1EA2, 0x1EA2, 0x1EA3 },
{ 0x1EA3, 0x1EA2, 0x1EA3 },
{ 0x1EA4, 0x1EA4, 0x1EA5 },
{ 0x1EA5, 0x1EA4, 0x1EA5 },
{ 0x1EA6, 0x1EA6, 0x1EA7 },
{ 0x1EA7, 0x1EA6, 0x1EA7 },
{ 0x1EA8, 0x1EA8, 0x1EA9 },
{ 0x1EA9, 0x1EA8, 0x1EA9 },
{ 0x1EAA, 0x1EAA, 0x1EAB },
{ 0x1EAB, 0x1EAA, 0x1EAB },
{ 0x1EAC, 0x1EAC, 0x1EAD },
{ 0x1EAD, 0x1EAC, 0x1EAD },
{ 0x1EAE, 0x1EAE, 0x1EAF },
{ 0x1EAF, 0x1EAE, 0x1EAF },
{ 0x1EB0, 0x1EB0, 0x1EB1 },
{ 0x1EB1, 0x1EB0, 0x1EB1 },
{ 0x1EB2, 0x1EB2, 0x1EB3 },
{ 0x1EB3, 0x1EB2, 0x1EB3 },
{ 0x1EB4, 0x1EB4, 0x1EB5 },
{ 0x1EB5, 0x1EB4, 0x1EB5 },
{ 0x1EB6, 0x1EB6, 0x1EB7 },
{ 0x1EB7, 0x1EB6, 0x1EB7 },
{ 0x1EB8, 0x1EB8, 0x1EB9 },
{ 0x1EB9, 0x1EB8, 0x1EB9 },
{ 0x1EBA, 0x1EBA, 0x1EBB },
{ 0x1EBB, 0x1EBA, 0x1EBB },
{ 0x1EBC, 0x1EBC, 0x1EBD },
{ 0x1EBD, 0x1EBC, 0x1EBD },
{ 0x1EBE, 0x1EBE, 0x1EBF },
{ 0x1EBF, 0x1EBE, 0x1EBF },
{ 0x1EC0, 0x1EC0, 0x1EC1 },
{ 0x1EC1, 0x1EC0, 0x1EC1 },
{ 0x1EC2, 0x1EC2, 0x1EC3 },
{ 0x1EC3, 0x1EC2, 0x1EC3 },
{ 0x1EC4, 0x1EC4, 0x1EC5 },
{ 0x1EC5, 0x1EC4, 0x1EC5 },
{ 0x1EC6, 0x1EC6, 0x1EC7 },
{ 0x1EC7, 0x1EC6, 0x1EC7 },
{ 0x1EC8, 0x1EC8, 0x1EC9 },
{ 0x1EC9, 0x1EC8, 0x1EC9 },
{ 0x1ECA, 0x1ECA, 0x1ECB },
{ 0x1ECB, 0x1ECA, 0x1ECB },
{ 0x1ECC, 0x1ECC, 0x1ECD },
{ 0x1ECD, 0x1ECC, 0x1ECD },
{ 0x1ECE, 0x1ECE, 0x1ECF },
{ 0x1ECF, 0x1ECE, 0x1ECF },
{ 0x1ED0, 0x1ED0, 0x1ED1 },
{ 0x1ED1, 0x1ED0, 0x1ED1 },
{ 0x1ED2, 0x1ED2, 0x1ED3 },
{ 0x1ED3, 0x1ED2, 0x1ED3 },
{ 0x1ED4, 0x1ED4, 0x1ED5 },
{ 0x1ED5, 0x1ED4, 0x1ED5 },
{ 0x1ED6, 0x1ED6, 0x1ED7 },
{ 0x1ED7, 0x1ED6, 0x1ED7 },
{ 0x1ED8, 0x1ED8, 0x1ED9 },
{ 0x1ED9, 0x1ED8, 0x1ED9 },
{ 0x1EDA, 0x1EDA, 0x1EDB },
{ 0x1EDB, 0x1EDA, 0x1EDB },
{ 0x1EDC, 0x1EDC, 0x1EDD },
{ 0x1EDD, 0x1EDC, 0x1EDD },
{ 0x1EDE, 0x1EDE, 0x1EDF },
{ 0x1EDF, 0x1EDE, 0x1EDF },
{ 0x1EE0, 0x1EE0, 0x1EE1 },
{ 0x1EE1, 0x1EE0, 0x1EE1 },
{ 0x1EE2, 0x1EE2, 0x1EE3 },
{ 0x1EE3, 0x1EE2, 0x1EE3 },
{ 0x1EE4, 0x1EE4, 0x1EE5 },
{ 0x1EE5, 0x1EE4, 0x1EE5 },
{ 0x1EE6, 0x1EE6, 0x1EE7 },
{ 0x1EE7, 0x1EE6, 0x1EE7 },
{ 0x1EE8, 0x1EE8, 0x1EE9 },
{ 0x1EE9, 0x1EE8, 0x1EE9 },
{ 0x1EEA, 0x1EEA, 0x1EEB },
{ 0x1EEB, 0x1EEA, 0x1EEB },
{ 0x1EEC, 0x1EEC, 0x1EED },
{ 0x1EED, 0x1EEC, 0x1EED },
{ 0x1EEE, 0x1EEE, 0x1EEF },
{ 0x1EEF, 0x1EEE, 0x1EEF },
{ 0x1EF0, 0x1EF0, 0x1EF1 },
{ 0x1EF1, 0x1EF0, 0x1EF1 },
{ 0x1EF2, 0x1EF2, 0x1EF3 },
{ 0x1EF3, 0x1EF2, 0x1EF3 },
{ 0x1EF4, 0x1EF4, 0x1EF5 },
{ 0x1EF5, 0x1EF4, 0x1EF5 },
{ 0x1EF6, 0x1EF6, 0x1EF7 },
{ 0x1EF7, 0x1EF6, 0x1EF7 },
{ 0x1EF8, 0x1EF8, 0x1EF9 },
{ 0x1EF9, 0x1EF8, 0x1EF9 },
{ 0x1F00, 0x1F08, 0x1F00 },
{ 0x1F01, 0x1F09, 0x1F01 },
{ 0x1F02, 0x1F0A, 0x1F02 },
{ 0x1F03, 0x1F0B, 0x1F03 },
{ 0x1F04, 0x1F0C, 0x1F04 },
{ 0x1F05, 0x1F0D, 0x1F05 },
{ 0x1F06, 0x1F0E, 0x1F06 },
{ 0x1F07, 0x1F0F, 0x1F07 },
{ 0x1F08, 0x1F08, 0x1F00 },
{ 0x1F09, 0x1F09, 0x1F01 },
{ 0x1F0A, 0x1F0A, 0x1F02 },
{ 0x1F0B, 0x1F0B, 0x1F03 },
{ 0x1F0C, 0x1F0C, 0x1F04 },
{ 0x1F0D, 0x1F0D, 0x1F05 },
{ 0x1F0E, 0x1F0E, 0x1F06 },
{ 0x1F0F, 0x1F0F, 0x1F07 },
{ 0x1F10, 0x1F18, 0x1F10 },
{ 0x1F11, 0x1F19, 0x1F11 },
{ 0x1F12, 0x1F1A, 0x1F12 },
{ 0x1F13, 0x1F1B, 0x1F13 },
{ 0x1F14, 0x1F1C, 0x1F14 },
{ 0x1F15, 0x1F1D, 0x1F15 },
{ 0x1F18, 0x1F18, 0x1F10 },
{ 0x1F19, 0x1F19, 0x1F11 },
{ 0x1F1A, 0x1F1A, 0x1F12 },
{ 0x1F1B, 0x1F1B, 0x1F13 },
{ 0x1F1C, 0x1F1C, 0x1F14 },
{ 0x1F1D, 0x1F1D, 0x1F15 },
{ 0x1F20, 0x1F28, 0x1F20 },
{ 0x1F21, 0x1F29, 0x1F21 },
{ 0x1F22, 0x1F2A, 0x1F22 },
{ 0x1F23, 0x1F2B, 0x1F23 },
{ 0x1F24, 0x1F2C, 0x1F24 },
{ 0x1F25, 0x1F2D, 0x1F25 },
{ 0x1F26, 0x1F2E, 0x1F26 },
{ 0x1F27, 0x1F2F, 0x1F27 },
{ 0x1F28, 0x1F28, 0x1F20 },
{ 0x1F29, 0x1F29, 0x1F21 },
{ 0x1F2A, 0x1F2A, 0x1F22 },
{ 0x1F2B, 0x1F2B, 0x1F23 },
{ 0x1F2C, 0x1F2C, 0x1F24 },
{ 0x1F2D, 0x1F2D, 0x1F25 },
{ 0x1F2E, 0x1F2E, 0x1F26 },
{ 0x1F2F, 0x1F2F, 0x1F27 },
{ 0x1F30, 0x1F38, 0x1F30 },
{ 0x1F31, 0x1F39, 0x1F31 },
{ 0x1F32, 0x1F3A, 0x1F32 },
{ 0x1F33, 0x1F3B, 0x1F33 },
{ 0x1F34, 0x1F3C, 0x1F34 },
{ 0x1F35, 0x1F3D, 0x1F35 },
{ 0x1F36, 0x1F3E, 0x1F36 },
{ 0x1F37, 0x1F3F, 0x1F37 },
{ 0x1F38, 0x1F38, 0x1F30 },
{ 0x1F39, 0x1F39, 0x1F31 },
{ 0x1F3A, 0x1F3A, 0x1F32 },
{ 0x1F3B, 0x1F3B, 0x1F33 },
{ 0x1F3C, 0x1F3C, 0x1F34 },
{ 0x1F3D, 0x1F3D, 0x1F35 },
{ 0x1F3E, 0x1F3E, 0x1F36 },
{ 0x1F3F, 0x1F3F, 0x1F37 },
{ 0x1F40, 0x1F48, 0x1F40 },
{ 0x1F41, 0x1F49, 0x1F41 },
{ 0x1F42, 0x1F4A, 0x1F42 },
{ 0x1F43, 0x1F4B, 0x1F43 },
{ 0x1F44, 0x1F4C, 0x1F44 },
{ 0x1F45, 0x1F4D, 0x1F45 },
{ 0x1F48, 0x1F48, 0x1F40 },
{ 0x1F49, 0x1F49, 0x1F41 },
{ 0x1F4A, 0x1F4A, 0x1F42 },
{ 0x1F4B, 0x1F4B, 0x1F43 },
{ 0x1F4C, 0x1F4C, 0x1F44 },
{ 0x1F4D, 0x1F4D, 0x1F45 },
{ 0x1F50, 0x1F50, 0x1F50 },
{ 0x1F51, 0x1F59, 0x1F51 },
{ 0x1F52, 0x1F52, 0x1F52 },
{ 0x1F53, 0x1F5B, 0x1F53 },
{ 0x1F54, 0x1F54, 0x1F54 },
{ 0x1F55, 0x1F5D, 0x1F55 },
{ 0x1F56, 0x1F56, 0x1F56 },
{ 0x1F57, 0x1F5F, 0x1F57 },
{ 0x1F59, 0x1F59, 0x1F51 },
{ 0x1F5B, 0x1F5B, 0x1F53 },
{ 0x1F5D, 0x1F5D, 0x1F55 },
{ 0x1F5F, 0x1F5F, 0x1F57 },
{ 0x1F60, 0x1F68, 0x1F60 },
{ 0x1F61, 0x1F69, 0x1F61 },
{ 0x1F62, 0x1F6A, 0x1F62 },
{ 0x1F63, 0x1F6B, 0x1F63 },
{ 0x1F64, 0x1F6C, 0x1F64 },
{ 0x1F65, 0x1F6D, 0x1F65 },
{ 0x1F66, 0x1F6E, 0x1F66 },
{ 0x1F67, 0x1F6F, 0x1F67 },
{ 0x1F68, 0x1F68, 0x1F60 },
{ 0x1F69, 0x1F69, 0x1F61 },
{ 0x1F6A, 0x1F6A, 0x1F62 },
{ 0x1F6B, 0x1F6B, 0x1F63 },
{ 0x1F6C, 0x1F6C, 0x1F64 },
{ 0x1F6D, 0x1F6D, 0x1F65 },
{ 0x1F6E, 0x1F6E, 0x1F66 },
{ 0x1F6F, 0x1F6F, 0x1F67 },
{ 0x1F70, 0x1FBA, 0x1F70 },
{ 0x1F71, 0x1FBB, 0x1F71 },
{ 0x1F72, 0x1FC8, 0x1F72 },
{ 0x1F73, 0x1FC9, 0x1F73 },
{ 0x1F74, 0x1FCA, 0x1F74 },
{ 0x1F75, 0x1FCB, 0x1F75 },
{ 0x1F76, 0x1FDA, 0x1F76 },
{ 0x1F77, 0x1FDB, 0x1F77 },
{ 0x1F78, 0x1FF8, 0x1F78 },
{ 0x1F79, 0x1FF9, 0x1F79 },
{ 0x1F7A, 0x1FEA, 0x1F7A },
{ 0x1F7B, 0x1FEB, 0x1F7B },
{ 0x1F7C, 0x1FFA, 0x1F7C },
{ 0x1F7D, 0x1FFB, 0x1F7D },
{ 0x1F80, 0x1F88, 0x1F80 },
{ 0x1F81, 0x1F89, 0x1F81 },
{ 0x1F82, 0x1F8A, 0x1F82 },
{ 0x1F83, 0x1F8B, 0x1F83 },
{ 0x1F84, 0x1F8C, 0x1F84 },
{ 0x1F85, 0x1F8D, 0x1F85 },
{ 0x1F86, 0x1F8E, 0x1F86 },
{ 0x1F87, 0x1F8F, 0x1F87 },
{ 0x1F88, 0x1F88, 0x1F80 },
{ 0x1F89, 0x1F89, 0x1F81 },
{ 0x1F8A, 0x1F8A, 0x1F82 },
{ 0x1F8B, 0x1F8B, 0x1F83 },
{ 0x1F8C, 0x1F8C, 0x1F84 },
{ 0x1F8D, 0x1F8D, 0x1F85 },
{ 0x1F8E, 0x1F8E, 0x1F86 },
{ 0x1F8F, 0x1F8F, 0x1F87 },
{ 0x1F90, 0x1F98, 0x1F90 },
{ 0x1F91, 0x1F99, 0x1F91 },
{ 0x1F92, 0x1F9A, 0x1F92 },
{ 0x1F93, 0x1F9B, 0x1F93 },
{ 0x1F94, 0x1F9C, 0x1F94 },
{ 0x1F95, 0x1F9D, 0x1F95 },
{ 0x1F96, 0x1F9E, 0x1F96 },
{ 0x1F97, 0x1F9F, 0x1F97 },
{ 0x1F98, 0x1F98, 0x1F90 },
{ 0x1F99, 0x1F99, 0x1F91 },
{ 0x1F9A, 0x1F9A, 0x1F92 },
{ 0x1F9B, 0x1F9B, 0x1F93 },
{ 0x1F9C, 0x1F9C, 0x1F94 },
{ 0x1F9D, 0x1F9D, 0x1F95 },
{ 0x1F9E, 0x1F9E, 0x1F96 },
{ 0x1F9F, 0x1F9F, 0x1F97 },
{ 0x1FA0, 0x1FA8, 0x1FA0 },
{ 0x1FA1, 0x1FA9, 0x1FA1 },
{ 0x1FA2, 0x1FAA, 0x1FA2 },
{ 0x1FA3, 0x1FAB, 0x1FA3 },
{ 0x1FA4, 0x1FAC, 0x1FA4 },
{ 0x1FA5, 0x1FAD, 0x1FA5 },
{ 0x1FA6, 0x1FAE, 0x1FA6 },
{ 0x1FA7, 0x1FAF, 0x1FA7 },
{ 0x1FA8, 0x1FA8, 0x1FA0 },
{ 0x1FA9, 0x1FA9, 0x1FA1 },
{ 0x1FAA, 0x1FAA, 0x1FA2 },
{ 0x1FAB, 0x1FAB, 0x1FA3 },
{ 0x1FAC, 0x1FAC, 0x1FA4 },
{ 0x1FAD, 0x1FAD, 0x1FA5 },
{ 0x1FAE, 0x1FAE, 0x1FA6 },
{ 0x1FAF, 0x1FAF, 0x1FA7 },
{ 0x1FB0, 0x1FB8, 0x1FB0 },
{ 0x1FB1, 0x1FB9, 0x1FB1 },
{ 0x1FB2, 0x1FB2, 0x1FB2 },
{ 0x1FB3, 0x1FBC, 0x1FB3 },
{ 0x1FB4, 0x1FB4, 0x1FB4 },
{ 0x1FB6, 0x1FB6, 0x1FB6 },
{ 0x1FB7, 0x1FB7, 0x1FB7 },
{ 0x1FB8, 0x1FB8, 0x1FB0 },
{ 0x1FB9, 0x1FB9, 0x1FB1 },
{ 0x1FBA, 0x1FBA, 0x1F70 },
{ 0x1FBB, 0x1FBB, 0x1F71 },
{ 0x1FBC, 0x1FBC, 0x1FB3 },
{ 0x1FBE, 0x0399, 0x1FBE },
{ 0x1FC2, 0x1FC2, 0x1FC2 },
{ 0x1FC3, 0x1FCC, 0x1FC3 },
{ 0x1FC4, 0x1FC4, 0x1FC4 },
{ 0x1FC6, 0x1FC6, 0x1FC6 },
{ 0x1FC7, 0x1FC7, 0x1FC7 },
{ 0x1FC8, 0x1FC8, 0x1F72 },
{ 0x1FC9, 0x1FC9, 0x1F73 },
{ 0x1FCA, 0x1FCA, 0x1F74 },
{ 0x1FCB, 0x1FCB, 0x1F75 },
{ 0x1FCC, 0x1FCC, 0x1FC3 },
{ 0x1FD0, 0x1FD8, 0x1FD0 },
{ 0x1FD1, 0x1FD9, 0x1FD1 },
{ 0x1FD2, 0x1FD2, 0x1FD2 },
{ 0x1FD3, 0x1FD3, 0x1FD3 },
{ 0x1FD6, 0x1FD6, 0x1FD6 },
{ 0x1FD7, 0x1FD7, 0x1FD7 },
{ 0x1FD8, 0x1FD8, 0x1FD0 },
{ 0x1FD9, 0x1FD9, 0x1FD1 },
{ 0x1FDA, 0x1FDA, 0x1F76 },
{ 0x1FDB, 0x1FDB, 0x1F77 },
{ 0x1FE0, 0x1FE8, 0x1FE0 },
{ 0x1FE1, 0x1FE9, 0x1FE1 },
{ 0x1FE2, 0x1FE2, 0x1FE2 },
{ 0x1FE3, 0x1FE3, 0x1FE3 },
{ 0x1FE4, 0x1FE4, 0x1FE4 },
{ 0x1FE5, 0x1FEC, 0x1FE5 },
{ 0x1FE6, 0x1FE6, 0x1FE6 },
{ 0x1FE7, 0x1FE7, 0x1FE7 },
{ 0x1FE8, 0x1FE8, 0x1FE0 },
{ 0x1FE9, 0x1FE9, 0x1FE1 },
{ 0x1FEA, 0x1FEA, 0x1F7A },
{ 0x1FEB, 0x1FEB, 0x1F7B },
{ 0x1FEC, 0x1FEC, 0x1FE5 },
{ 0x1FF2, 0x1FF2, 0x1FF2 },
{ 0x1FF3, 0x1FFC, 0x1FF3 },
{ 0x1FF4, 0x1FF4, 0x1FF4 },
{ 0x1FF6, 0x1FF6, 0x1FF6 },
{ 0x1FF7, 0x1FF7, 0x1FF7 },
{ 0x1FF8, 0x1FF8, 0x1F78 },
{ 0x1FF9, 0x1FF9, 0x1F79 },
{ 0x1FFA, 0x1FFA, 0x1F7C },
{ 0x1FFB, 0x1FFB, 0x1F7D },
{ 0x1FFC, 0x1FFC, 0x1FF3 },
{ 0x2071, 0x2071, 0x2071 },
{ 0x207F, 0x207F, 0x207F },
{ 0x2090, 0x2090, 0x2090 },
{ 0x2091, 0x2091, 0x2091 },
{ 0x2092, 0x2092, 0x2092 },
{ 0x2093, 0x2093, 0x2093 },
{ 0x2094, 0x2094, 0x2094 },
{ 0x20D0, 0x20D0, 0x20D0 },
{ 0x20D1, 0x20D1, 0x20D1 },
{ 0x20D2, 0x20D2, 0x20D2 },
{ 0x20D3, 0x20D3, 0x20D3 },
{ 0x20D4, 0x20D4, 0x20D4 },
{ 0x20D5, 0x20D5, 0x20D5 },
{ 0x20D6, 0x20D6, 0x20D6 },
{ 0x20D7, 0x20D7, 0x20D7 },
{ 0x20D8, 0x20D8, 0x20D8 },
{ 0x20D9, 0x20D9, 0x20D9 },
{ 0x20DA, 0x20DA, 0x20DA },
{ 0x20DB, 0x20DB, 0x20DB },
{ 0x20DC, 0x20DC, 0x20DC },
{ 0x20E1, 0x20E1, 0x20E1 },
{ 0x20E5, 0x20E5, 0x20E5 },
{ 0x20E6, 0x20E6, 0x20E6 },
{ 0x20E7, 0x20E7, 0x20E7 },
{ 0x20E8, 0x20E8, 0x20E8 },
{ 0x20E9, 0x20E9, 0x20E9 },
{ 0x20EA, 0x20EA, 0x20EA },
{ 0x20EB, 0x20EB, 0x20EB },
{ 0x2102, 0x2102, 0x2102 },
{ 0x2107, 0x2107, 0x2107 },
{ 0x210A, 0x210A, 0x210A },
{ 0x210B, 0x210B, 0x210B },
{ 0x210C, 0x210C, 0x210C },
{ 0x210D, 0x210D, 0x210D },
{ 0x210E, 0x210E, 0x210E },
{ 0x210F, 0x210F, 0x210F },
{ 0x2110, 0x2110, 0x2110 },
{ 0x2111, 0x2111, 0x2111 },
{ 0x2112, 0x2112, 0x2112 },
{ 0x2113, 0x2113, 0x2113 },
{ 0x2115, 0x2115, 0x2115 },
{ 0x2119, 0x2119, 0x2119 },
{ 0x211A, 0x211A, 0x211A },
{ 0x211B, 0x211B, 0x211B },
{ 0x211C, 0x211C, 0x211C },
{ 0x211D, 0x211D, 0x211D },
{ 0x2124, 0x2124, 0x2124 },
{ 0x2126, 0x2126, 0x03C9 },
{ 0x2128, 0x2128, 0x2128 },
{ 0x212A, 0x212A, 0x006B },
{ 0x212B, 0x212B, 0x00E5 },
{ 0x212C, 0x212C, 0x212C },
{ 0x212D, 0x212D, 0x212D },
{ 0x212F, 0x212F, 0x212F },
{ 0x2130, 0x2130, 0x2130 },
{ 0x2131, 0x2131, 0x2131 },
{ 0x2133, 0x2133, 0x2133 },
{ 0x2134, 0x2134, 0x2134 },
{ 0x2135, 0x2135, 0x2135 },
{ 0x2136, 0x2136, 0x2136 },
{ 0x2137, 0x2137, 0x2137 },
{ 0x2138, 0x2138, 0x2138 },
{ 0x2139, 0x2139, 0x2139 },
{ 0x213C, 0x213C, 0x213C },
{ 0x213D, 0x213D, 0x213D },
{ 0x213E, 0x213E, 0x213E },
{ 0x213F, 0x213F, 0x213F },
{ 0x2145, 0x2145, 0x2145 },
{ 0x2146, 0x2146, 0x2146 },
{ 0x2147, 0x2147, 0x2147 },
{ 0x2148, 0x2148, 0x2148 },
{ 0x2149, 0x2149, 0x2149 },
{ 0x2C00, 0x2C00, 0x2C30 },
{ 0x2C01, 0x2C01, 0x2C31 },
{ 0x2C02, 0x2C02, 0x2C32 },
{ 0x2C03, 0x2C03, 0x2C33 },
{ 0x2C04, 0x2C04, 0x2C34 },
{ 0x2C05, 0x2C05, 0x2C35 },
{ 0x2C06, 0x2C06, 0x2C36 },
{ 0x2C07, 0x2C07, 0x2C37 },
{ 0x2C08, 0x2C08, 0x2C38 },
{ 0x2C09, 0x2C09, 0x2C39 },
{ 0x2C0A, 0x2C0A, 0x2C3A },
{ 0x2C0B, 0x2C0B, 0x2C3B },
{ 0x2C0C, 0x2C0C, 0x2C3C },
{ 0x2C0D, 0x2C0D, 0x2C3D },
{ 0x2C0E, 0x2C0E, 0x2C3E },
{ 0x2C0F, 0x2C0F, 0x2C3F },
{ 0x2C10, 0x2C10, 0x2C40 },
{ 0x2C11, 0x2C11, 0x2C41 },
{ 0x2C12, 0x2C12, 0x2C42 },
{ 0x2C13, 0x2C13, 0x2C43 },
{ 0x2C14, 0x2C14, 0x2C44 },
{ 0x2C15, 0x2C15, 0x2C45 },
{ 0x2C16, 0x2C16, 0x2C46 },
{ 0x2C17, 0x2C17, 0x2C47 },
{ 0x2C18, 0x2C18, 0x2C48 },
{ 0x2C19, 0x2C19, 0x2C49 },
{ 0x2C1A, 0x2C1A, 0x2C4A },
{ 0x2C1B, 0x2C1B, 0x2C4B },
{ 0x2C1C, 0x2C1C, 0x2C4C },
{ 0x2C1D, 0x2C1D, 0x2C4D },
{ 0x2C1E, 0x2C1E, 0x2C4E },
{ 0x2C1F, 0x2C1F, 0x2C4F },
{ 0x2C20, 0x2C20, 0x2C50 },
{ 0x2C21, 0x2C21, 0x2C51 },
{ 0x2C22, 0x2C22, 0x2C52 },
{ 0x2C23, 0x2C23, 0x2C53 },
{ 0x2C24, 0x2C24, 0x2C54 },
{ 0x2C25, 0x2C25, 0x2C55 },
{ 0x2C26, 0x2C26, 0x2C56 },
{ 0x2C27, 0x2C27, 0x2C57 },
{ 0x2C28, 0x2C28, 0x2C58 },
{ 0x2C29, 0x2C29, 0x2C59 },
{ 0x2C2A, 0x2C2A, 0x2C5A },
{ 0x2C2B, 0x2C2B, 0x2C5B },
{ 0x2C2C, 0x2C2C, 0x2C5C },
{ 0x2C2D, 0x2C2D, 0x2C5D },
{ 0x2C2E, 0x2C2E, 0x2C5E },
{ 0x2C30, 0x2C00, 0x2C30 },
{ 0x2C31, 0x2C01, 0x2C31 },
{ 0x2C32, 0x2C02, 0x2C32 },
{ 0x2C33, 0x2C03, 0x2C33 },
{ 0x2C34, 0x2C04, 0x2C34 },
{ 0x2C35, 0x2C05, 0x2C35 },
{ 0x2C36, 0x2C06, 0x2C36 },
{ 0x2C37, 0x2C07, 0x2C37 },
{ 0x2C38, 0x2C08, 0x2C38 },
{ 0x2C39, 0x2C09, 0x2C39 },
{ 0x2C3A, 0x2C0A, 0x2C3A },
{ 0x2C3B, 0x2C0B, 0x2C3B },
{ 0x2C3C, 0x2C0C, 0x2C3C },
{ 0x2C3D, 0x2C0D, 0x2C3D },
{ 0x2C3E, 0x2C0E, 0x2C3E },
{ 0x2C3F, 0x2C0F, 0x2C3F },
{ 0x2C40, 0x2C10, 0x2C40 },
{ 0x2C41, 0x2C11, 0x2C41 },
{ 0x2C42, 0x2C12, 0x2C42 },
{ 0x2C43, 0x2C13, 0x2C43 },
{ 0x2C44, 0x2C14, 0x2C44 },
{ 0x2C45, 0x2C15, 0x2C45 },
{ 0x2C46, 0x2C16, 0x2C46 },
{ 0x2C47, 0x2C17, 0x2C47 },
{ 0x2C48, 0x2C18, 0x2C48 },
{ 0x2C49, 0x2C19, 0x2C49 },
{ 0x2C4A, 0x2C1A, 0x2C4A },
{ 0x2C4B, 0x2C1B, 0x2C4B },
{ 0x2C4C, 0x2C1C, 0x2C4C },
{ 0x2C4D, 0x2C1D, 0x2C4D },
{ 0x2C4E, 0x2C1E, 0x2C4E },
{ 0x2C4F, 0x2C1F, 0x2C4F },
{ 0x2C50, 0x2C20, 0x2C50 },
{ 0x2C51, 0x2C21, 0x2C51 },
{ 0x2C52, 0x2C22, 0x2C52 },
{ 0x2C53, 0x2C23, 0x2C53 },
{ 0x2C54, 0x2C24, 0x2C54 },
{ 0x2C55, 0x2C25, 0x2C55 },
{ 0x2C56, 0x2C26, 0x2C56 },
{ 0x2C57, 0x2C27, 0x2C57 },
{ 0x2C58, 0x2C28, 0x2C58 },
{ 0x2C59, 0x2C29, 0x2C59 },
{ 0x2C5A, 0x2C2A, 0x2C5A },
{ 0x2C5B, 0x2C2B, 0x2C5B },
{ 0x2C5C, 0x2C2C, 0x2C5C },
{ 0x2C5D, 0x2C2D, 0x2C5D },
{ 0x2C5E, 0x2C2E, 0x2C5E },
{ 0x2C80, 0x2C80, 0x2C81 },
{ 0x2C81, 0x2C80, 0x2C81 },
{ 0x2C82, 0x2C82, 0x2C83 },
{ 0x2C83, 0x2C82, 0x2C83 },
{ 0x2C84, 0x2C84, 0x2C85 },
{ 0x2C85, 0x2C84, 0x2C85 },
{ 0x2C86, 0x2C86, 0x2C87 },
{ 0x2C87, 0x2C86, 0x2C87 },
{ 0x2C88, 0x2C88, 0x2C89 },
{ 0x2C89, 0x2C88, 0x2C89 },
{ 0x2C8A, 0x2C8A, 0x2C8B },
{ 0x2C8B, 0x2C8A, 0x2C8B },
{ 0x2C8C, 0x2C8C, 0x2C8D },
{ 0x2C8D, 0x2C8C, 0x2C8D },
{ 0x2C8E, 0x2C8E, 0x2C8F },
{ 0x2C8F, 0x2C8E, 0x2C8F },
{ 0x2C90, 0x2C90, 0x2C91 },
{ 0x2C91, 0x2C90, 0x2C91 },
{ 0x2C92, 0x2C92, 0x2C93 },
{ 0x2C93, 0x2C92, 0x2C93 },
{ 0x2C94, 0x2C94, 0x2C95 },
{ 0x2C95, 0x2C94, 0x2C95 },
{ 0x2C96, 0x2C96, 0x2C97 },
{ 0x2C97, 0x2C96, 0x2C97 },
{ 0x2C98, 0x2C98, 0x2C99 },
{ 0x2C99, 0x2C98, 0x2C99 },
{ 0x2C9A, 0x2C9A, 0x2C9B },
{ 0x2C9B, 0x2C9A, 0x2C9B },
{ 0x2C9C, 0x2C9C, 0x2C9D },
{ 0x2C9D, 0x2C9C, 0x2C9D },
{ 0x2C9E, 0x2C9E, 0x2C9F },
{ 0x2C9F, 0x2C9E, 0x2C9F },
{ 0x2CA0, 0x2CA0, 0x2CA1 },
{ 0x2CA1, 0x2CA0, 0x2CA1 },
{ 0x2CA2, 0x2CA2, 0x2CA3 },
{ 0x2CA3, 0x2CA2, 0x2CA3 },
{ 0x2CA4, 0x2CA4, 0x2CA5 },
{ 0x2CA5, 0x2CA4, 0x2CA5 },
{ 0x2CA6, 0x2CA6, 0x2CA7 },
{ 0x2CA7, 0x2CA6, 0x2CA7 },
{ 0x2CA8, 0x2CA8, 0x2CA9 },
{ 0x2CA9, 0x2CA8, 0x2CA9 },
{ 0x2CAA, 0x2CAA, 0x2CAB },
{ 0x2CAB, 0x2CAA, 0x2CAB },
{ 0x2CAC, 0x2CAC, 0x2CAD },
{ 0x2CAD, 0x2CAC, 0x2CAD },
{ 0x2CAE, 0x2CAE, 0x2CAF },
{ 0x2CAF, 0x2CAE, 0x2CAF },
{ 0x2CB0, 0x2CB0, 0x2CB1 },
{ 0x2CB1, 0x2CB0, 0x2CB1 },
{ 0x2CB2, 0x2CB2, 0x2CB3 },
{ 0x2CB3, 0x2CB2, 0x2CB3 },
{ 0x2CB4, 0x2CB4, 0x2CB5 },
{ 0x2CB5, 0x2CB4, 0x2CB5 },
{ 0x2CB6, 0x2CB6, 0x2CB7 },
{ 0x2CB7, 0x2CB6, 0x2CB7 },
{ 0x2CB8, 0x2CB8, 0x2CB9 },
{ 0x2CB9, 0x2CB8, 0x2CB9 },
{ 0x2CBA, 0x2CBA, 0x2CBB },
{ 0x2CBB, 0x2CBA, 0x2CBB },
{ 0x2CBC, 0x2CBC, 0x2CBD },
{ 0x2CBD, 0x2CBC, 0x2CBD },
{ 0x2CBE, 0x2CBE, 0x2CBF },
{ 0x2CBF, 0x2CBE, 0x2CBF },
{ 0x2CC0, 0x2CC0, 0x2CC1 },
{ 0x2CC1, 0x2CC0, 0x2CC1 },
{ 0x2CC2, 0x2CC2, 0x2CC3 },
{ 0x2CC3, 0x2CC2, 0x2CC3 },
{ 0x2CC4, 0x2CC4, 0x2CC5 },
{ 0x2CC5, 0x2CC4, 0x2CC5 },
{ 0x2CC6, 0x2CC6, 0x2CC7 },
{ 0x2CC7, 0x2CC6, 0x2CC7 },
{ 0x2CC8, 0x2CC8, 0x2CC9 },
{ 0x2CC9, 0x2CC8, 0x2CC9 },
{ 0x2CCA, 0x2CCA, 0x2CCB },
{ 0x2CCB, 0x2CCA, 0x2CCB },
{ 0x2CCC, 0x2CCC, 0x2CCD },
{ 0x2CCD, 0x2CCC, 0x2CCD },
{ 0x2CCE, 0x2CCE, 0x2CCF },
{ 0x2CCF, 0x2CCE, 0x2CCF },
{ 0x2CD0, 0x2CD0, 0x2CD1 },
{ 0x2CD1, 0x2CD0, 0x2CD1 },
{ 0x2CD2, 0x2CD2, 0x2CD3 },
{ 0x2CD3, 0x2CD2, 0x2CD3 },
{ 0x2CD4, 0x2CD4, 0x2CD5 },
{ 0x2CD5, 0x2CD4, 0x2CD5 },
{ 0x2CD6, 0x2CD6, 0x2CD7 },
{ 0x2CD7, 0x2CD6, 0x2CD7 },
{ 0x2CD8, 0x2CD8, 0x2CD9 },
{ 0x2CD9, 0x2CD8, 0x2CD9 },
{ 0x2CDA, 0x2CDA, 0x2CDB },
{ 0x2CDB, 0x2CDA, 0x2CDB },
{ 0x2CDC, 0x2CDC, 0x2CDD },
{ 0x2CDD, 0x2CDC, 0x2CDD },
{ 0x2CDE, 0x2CDE, 0x2CDF },
{ 0x2CDF, 0x2CDE, 0x2CDF },
{ 0x2CE0, 0x2CE0, 0x2CE1 },
{ 0x2CE1, 0x2CE0, 0x2CE1 },
{ 0x2CE2, 0x2CE2, 0x2CE3 },
{ 0x2CE3, 0x2CE2, 0x2CE3 },
{ 0x2CE4, 0x2CE4, 0x2CE4 },
{ 0x2D00, 0x10A0, 0x2D00 },
{ 0x2D01, 0x10A1, 0x2D01 },
{ 0x2D02, 0x10A2, 0x2D02 },
{ 0x2D03, 0x10A3, 0x2D03 },
{ 0x2D04, 0x10A4, 0x2D04 },
{ 0x2D05, 0x10A5, 0x2D05 },
{ 0x2D06, 0x10A6, 0x2D06 },
{ 0x2D07, 0x10A7, 0x2D07 },
{ 0x2D08, 0x10A8, 0x2D08 },
{ 0x2D09, 0x10A9, 0x2D09 },
{ 0x2D0A, 0x10AA, 0x2D0A },
{ 0x2D0B, 0x10AB, 0x2D0B },
{ 0x2D0C, 0x10AC, 0x2D0C },
{ 0x2D0D, 0x10AD, 0x2D0D },
{ 0x2D0E, 0x10AE, 0x2D0E },
{ 0x2D0F, 0x10AF, 0x2D0F },
{ 0x2D10, 0x10B0, 0x2D10 },
{ 0x2D11, 0x10B1, 0x2D11 },
{ 0x2D12, 0x10B2, 0x2D12 },
{ 0x2D13, 0x10B3, 0x2D13 },
{ 0x2D14, 0x10B4, 0x2D14 },
{ 0x2D15, 0x10B5, 0x2D15 },
{ 0x2D16, 0x10B6, 0x2D16 },
{ 0x2D17, 0x10B7, 0x2D17 },
{ 0x2D18, 0x10B8, 0x2D18 },
{ 0x2D19, 0x10B9, 0x2D19 },
{ 0x2D1A, 0x10BA, 0x2D1A },
{ 0x2D1B, 0x10BB, 0x2D1B },
{ 0x2D1C, 0x10BC, 0x2D1C },
{ 0x2D1D, 0x10BD, 0x2D1D },
{ 0x2D1E, 0x10BE, 0x2D1E },
{ 0x2D1F, 0x10BF, 0x2D1F },
{ 0x2D20, 0x10C0, 0x2D20 },
{ 0x2D21, 0x10C1, 0x2D21 },
{ 0x2D22, 0x10C2, 0x2D22 },
{ 0x2D23, 0x10C3, 0x2D23 },
{ 0x2D24, 0x10C4, 0x2D24 },
{ 0x2D25, 0x10C5, 0x2D25 },
{ 0x2D30, 0x2D30, 0x2D30 },
{ 0x2D31, 0x2D31, 0x2D31 },
{ 0x2D32, 0x2D32, 0x2D32 },
{ 0x2D33, 0x2D33, 0x2D33 },
{ 0x2D34, 0x2D34, 0x2D34 },
{ 0x2D35, 0x2D35, 0x2D35 },
{ 0x2D36, 0x2D36, 0x2D36 },
{ 0x2D37, 0x2D37, 0x2D37 },
{ 0x2D38, 0x2D38, 0x2D38 },
{ 0x2D39, 0x2D39, 0x2D39 },
{ 0x2D3A, 0x2D3A, 0x2D3A },
{ 0x2D3B, 0x2D3B, 0x2D3B },
{ 0x2D3C, 0x2D3C, 0x2D3C },
{ 0x2D3D, 0x2D3D, 0x2D3D },
{ 0x2D3E, 0x2D3E, 0x2D3E },
{ 0x2D3F, 0x2D3F, 0x2D3F },
{ 0x2D40, 0x2D40, 0x2D40 },
{ 0x2D41, 0x2D41, 0x2D41 },
{ 0x2D42, 0x2D42, 0x2D42 },
{ 0x2D43, 0x2D43, 0x2D43 },
{ 0x2D44, 0x2D44, 0x2D44 },
{ 0x2D45, 0x2D45, 0x2D45 },
{ 0x2D46, 0x2D46, 0x2D46 },
{ 0x2D47, 0x2D47, 0x2D47 },
{ 0x2D48, 0x2D48, 0x2D48 },
{ 0x2D49, 0x2D49, 0x2D49 },
{ 0x2D4A, 0x2D4A, 0x2D4A },
{ 0x2D4B, 0x2D4B, 0x2D4B },
{ 0x2D4C, 0x2D4C, 0x2D4C },
{ 0x2D4D, 0x2D4D, 0x2D4D },
{ 0x2D4E, 0x2D4E, 0x2D4E },
{ 0x2D4F, 0x2D4F, 0x2D4F },
{ 0x2D50, 0x2D50, 0x2D50 },
{ 0x2D51, 0x2D51, 0x2D51 },
{ 0x2D52, 0x2D52, 0x2D52 },
{ 0x2D53, 0x2D53, 0x2D53 },
{ 0x2D54, 0x2D54, 0x2D54 },
{ 0x2D55, 0x2D55, 0x2D55 },
{ 0x2D56, 0x2D56, 0x2D56 },
{ 0x2D57, 0x2D57, 0x2D57 },
{ 0x2D58, 0x2D58, 0x2D58 },
{ 0x2D59, 0x2D59, 0x2D59 },
{ 0x2D5A, 0x2D5A, 0x2D5A },
{ 0x2D5B, 0x2D5B, 0x2D5B },
{ 0x2D5C, 0x2D5C, 0x2D5C },
{ 0x2D5D, 0x2D5D, 0x2D5D },
{ 0x2D5E, 0x2D5E, 0x2D5E },
{ 0x2D5F, 0x2D5F, 0x2D5F },
{ 0x2D60, 0x2D60, 0x2D60 },
{ 0x2D61, 0x2D61, 0x2D61 },
{ 0x2D62, 0x2D62, 0x2D62 },
{ 0x2D63, 0x2D63, 0x2D63 },
{ 0x2D64, 0x2D64, 0x2D64 },
{ 0x2D65, 0x2D65, 0x2D65 },
{ 0x2D6F, 0x2D6F, 0x2D6F },
{ 0x2D80, 0x2D80, 0x2D80 },
{ 0x2D81, 0x2D81, 0x2D81 },
{ 0x2D82, 0x2D82, 0x2D82 },
{ 0x2D83, 0x2D83, 0x2D83 },
{ 0x2D84, 0x2D84, 0x2D84 },
{ 0x2D85, 0x2D85, 0x2D85 },
{ 0x2D86, 0x2D86, 0x2D86 },
{ 0x2D87, 0x2D87, 0x2D87 },
{ 0x2D88, 0x2D88, 0x2D88 },
{ 0x2D89, 0x2D89, 0x2D89 },
{ 0x2D8A, 0x2D8A, 0x2D8A },
{ 0x2D8B, 0x2D8B, 0x2D8B },
{ 0x2D8C, 0x2D8C, 0x2D8C },
{ 0x2D8D, 0x2D8D, 0x2D8D },
{ 0x2D8E, 0x2D8E, 0x2D8E },
{ 0x2D8F, 0x2D8F, 0x2D8F },
{ 0x2D90, 0x2D90, 0x2D90 },
{ 0x2D91, 0x2D91, 0x2D91 },
{ 0x2D92, 0x2D92, 0x2D92 },
{ 0x2D93, 0x2D93, 0x2D93 },
{ 0x2D94, 0x2D94, 0x2D94 },
{ 0x2D95, 0x2D95, 0x2D95 },
{ 0x2D96, 0x2D96, 0x2D96 },
{ 0x2DA0, 0x2DA0, 0x2DA0 },
{ 0x2DA1, 0x2DA1, 0x2DA1 },
{ 0x2DA2, 0x2DA2, 0x2DA2 },
{ 0x2DA3, 0x2DA3, 0x2DA3 },
{ 0x2DA4, 0x2DA4, 0x2DA4 },
{ 0x2DA5, 0x2DA5, 0x2DA5 },
{ 0x2DA6, 0x2DA6, 0x2DA6 },
{ 0x2DA8, 0x2DA8, 0x2DA8 },
{ 0x2DA9, 0x2DA9, 0x2DA9 },
{ 0x2DAA, 0x2DAA, 0x2DAA },
{ 0x2DAB, 0x2DAB, 0x2DAB },
{ 0x2DAC, 0x2DAC, 0x2DAC },
{ 0x2DAD, 0x2DAD, 0x2DAD },
{ 0x2DAE, 0x2DAE, 0x2DAE },
{ 0x2DB0, 0x2DB0, 0x2DB0 },
{ 0x2DB1, 0x2DB1, 0x2DB1 },
{ 0x2DB2, 0x2DB2, 0x2DB2 },
{ 0x2DB3, 0x2DB3, 0x2DB3 },
{ 0x2DB4, 0x2DB4, 0x2DB4 },
{ 0x2DB5, 0x2DB5, 0x2DB5 },
{ 0x2DB6, 0x2DB6, 0x2DB6 },
{ 0x2DB8, 0x2DB8, 0x2DB8 },
{ 0x2DB9, 0x2DB9, 0x2DB9 },
{ 0x2DBA, 0x2DBA, 0x2DBA },
{ 0x2DBB, 0x2DBB, 0x2DBB },
{ 0x2DBC, 0x2DBC, 0x2DBC },
{ 0x2DBD, 0x2DBD, 0x2DBD },
{ 0x2DBE, 0x2DBE, 0x2DBE },
{ 0x2DC0, 0x2DC0, 0x2DC0 },
{ 0x2DC1, 0x2DC1, 0x2DC1 },
{ 0x2DC2, 0x2DC2, 0x2DC2 },
{ 0x2DC3, 0x2DC3, 0x2DC3 },
{ 0x2DC4, 0x2DC4, 0x2DC4 },
{ 0x2DC5, 0x2DC5, 0x2DC5 },
{ 0x2DC6, 0x2DC6, 0x2DC6 },
{ 0x2DC8, 0x2DC8, 0x2DC8 },
{ 0x2DC9, 0x2DC9, 0x2DC9 },
{ 0x2DCA, 0x2DCA, 0x2DCA },
{ 0x2DCB, 0x2DCB, 0x2DCB },
{ 0x2DCC, 0x2DCC, 0x2DCC },
{ 0x2DCD, 0x2DCD, 0x2DCD },
{ 0x2DCE, 0x2DCE, 0x2DCE },
{ 0x2DD0, 0x2DD0, 0x2DD0 },
{ 0x2DD1, 0x2DD1, 0x2DD1 },
{ 0x2DD2, 0x2DD2, 0x2DD2 },
{ 0x2DD3, 0x2DD3, 0x2DD3 },
{ 0x2DD4, 0x2DD4, 0x2DD4 },
{ 0x2DD5, 0x2DD5, 0x2DD5 },
{ 0x2DD6, 0x2DD6, 0x2DD6 },
{ 0x2DD8, 0x2DD8, 0x2DD8 },
{ 0x2DD9, 0x2DD9, 0x2DD9 },
{ 0x2DDA, 0x2DDA, 0x2DDA },
{ 0x2DDB, 0x2DDB, 0x2DDB },
{ 0x2DDC, 0x2DDC, 0x2DDC },
{ 0x2DDD, 0x2DDD, 0x2DDD },
{ 0x2DDE, 0x2DDE, 0x2DDE },
{ 0x3005, 0x3005, 0x3005 },
{ 0x3006, 0x3006, 0x3006 },
{ 0x302A, 0x302A, 0x302A },
{ 0x302B, 0x302B, 0x302B },
{ 0x302C, 0x302C, 0x302C },
{ 0x302D, 0x302D, 0x302D },
{ 0x302E, 0x302E, 0x302E },
{ 0x302F, 0x302F, 0x302F },
{ 0x3031, 0x3031, 0x3031 },
{ 0x3032, 0x3032, 0x3032 },
{ 0x3033, 0x3033, 0x3033 },
{ 0x3034, 0x3034, 0x3034 },
{ 0x3035, 0x3035, 0x3035 },
{ 0x303B, 0x303B, 0x303B },
{ 0x303C, 0x303C, 0x303C },
{ 0x3041, 0x3041, 0x3041 },
{ 0x3042, 0x3042, 0x3042 },
{ 0x3043, 0x3043, 0x3043 },
{ 0x3044, 0x3044, 0x3044 },
{ 0x3045, 0x3045, 0x3045 },
{ 0x3046, 0x3046, 0x3046 },
{ 0x3047, 0x3047, 0x3047 },
{ 0x3048, 0x3048, 0x3048 },
{ 0x3049, 0x3049, 0x3049 },
{ 0x304A, 0x304A, 0x304A },
{ 0x304B, 0x304B, 0x304B },
{ 0x304C, 0x304C, 0x304C },
{ 0x304D, 0x304D, 0x304D },
{ 0x304E, 0x304E, 0x304E },
{ 0x304F, 0x304F, 0x304F },
{ 0x3050, 0x3050, 0x3050 },
{ 0x3051, 0x3051, 0x3051 },
{ 0x3052, 0x3052, 0x3052 },
{ 0x3053, 0x3053, 0x3053 },
{ 0x3054, 0x3054, 0x3054 },
{ 0x3055, 0x3055, 0x3055 },
{ 0x3056, 0x3056, 0x3056 },
{ 0x3057, 0x3057, 0x3057 },
{ 0x3058, 0x3058, 0x3058 },
{ 0x3059, 0x3059, 0x3059 },
{ 0x305A, 0x305A, 0x305A },
{ 0x305B, 0x305B, 0x305B },
{ 0x305C, 0x305C, 0x305C },
{ 0x305D, 0x305D, 0x305D },
{ 0x305E, 0x305E, 0x305E },
{ 0x305F, 0x305F, 0x305F },
{ 0x3060, 0x3060, 0x3060 },
{ 0x3061, 0x3061, 0x3061 },
{ 0x3062, 0x3062, 0x3062 },
{ 0x3063, 0x3063, 0x3063 },
{ 0x3064, 0x3064, 0x3064 },
{ 0x3065, 0x3065, 0x3065 },
{ 0x3066, 0x3066, 0x3066 },
{ 0x3067, 0x3067, 0x3067 },
{ 0x3068, 0x3068, 0x3068 },
{ 0x3069, 0x3069, 0x3069 },
{ 0x306A, 0x306A, 0x306A },
{ 0x306B, 0x306B, 0x306B },
{ 0x306C, 0x306C, 0x306C },
{ 0x306D, 0x306D, 0x306D },
{ 0x306E, 0x306E, 0x306E },
{ 0x306F, 0x306F, 0x306F },
{ 0x3070, 0x3070, 0x3070 },
{ 0x3071, 0x3071, 0x3071 },
{ 0x3072, 0x3072, 0x3072 },
{ 0x3073, 0x3073, 0x3073 },
{ 0x3074, 0x3074, 0x3074 },
{ 0x3075, 0x3075, 0x3075 },
{ 0x3076, 0x3076, 0x3076 },
{ 0x3077, 0x3077, 0x3077 },
{ 0x3078, 0x3078, 0x3078 },
{ 0x3079, 0x3079, 0x3079 },
{ 0x307A, 0x307A, 0x307A },
{ 0x307B, 0x307B, 0x307B },
{ 0x307C, 0x307C, 0x307C },
{ 0x307D, 0x307D, 0x307D },
{ 0x307E, 0x307E, 0x307E },
{ 0x307F, 0x307F, 0x307F },
{ 0x3080, 0x3080, 0x3080 },
{ 0x3081, 0x3081, 0x3081 },
{ 0x3082, 0x3082, 0x3082 },
{ 0x3083, 0x3083, 0x3083 },
{ 0x3084, 0x3084, 0x3084 },
{ 0x3085, 0x3085, 0x3085 },
{ 0x3086, 0x3086, 0x3086 },
{ 0x3087, 0x3087, 0x3087 },
{ 0x3088, 0x3088, 0x3088 },
{ 0x3089, 0x3089, 0x3089 },
{ 0x308A, 0x308A, 0x308A },
{ 0x308B, 0x308B, 0x308B },
{ 0x308C, 0x308C, 0x308C },
{ 0x308D, 0x308D, 0x308D },
{ 0x308E, 0x308E, 0x308E },
{ 0x308F, 0x308F, 0x308F },
{ 0x3090, 0x3090, 0x3090 },
{ 0x3091, 0x3091, 0x3091 },
{ 0x3092, 0x3092, 0x3092 },
{ 0x3093, 0x3093, 0x3093 },
{ 0x3094, 0x3094, 0x3094 },
{ 0x3095, 0x3095, 0x3095 },
{ 0x3096, 0x3096, 0x3096 },
{ 0x3099, 0x3099, 0x3099 },
{ 0x309A, 0x309A, 0x309A },
{ 0x309D, 0x309D, 0x309D },
{ 0x309E, 0x309E, 0x309E },
{ 0x309F, 0x309F, 0x309F },
{ 0x30A1, 0x30A1, 0x30A1 },
{ 0x30A2, 0x30A2, 0x30A2 },
{ 0x30A3, 0x30A3, 0x30A3 },
{ 0x30A4, 0x30A4, 0x30A4 },
{ 0x30A5, 0x30A5, 0x30A5 },
{ 0x30A6, 0x30A6, 0x30A6 },
{ 0x30A7, 0x30A7, 0x30A7 },
{ 0x30A8, 0x30A8, 0x30A8 },
{ 0x30A9, 0x30A9, 0x30A9 },
{ 0x30AA, 0x30AA, 0x30AA },
{ 0x30AB, 0x30AB, 0x30AB },
{ 0x30AC, 0x30AC, 0x30AC },
{ 0x30AD, 0x30AD, 0x30AD },
{ 0x30AE, 0x30AE, 0x30AE },
{ 0x30AF, 0x30AF, 0x30AF },
{ 0x30B0, 0x30B0, 0x30B0 },
{ 0x30B1, 0x30B1, 0x30B1 },
{ 0x30B2, 0x30B2, 0x30B2 },
{ 0x30B3, 0x30B3, 0x30B3 },
{ 0x30B4, 0x30B4, 0x30B4 },
{ 0x30B5, 0x30B5, 0x30B5 },
{ 0x30B6, 0x30B6, 0x30B6 },
{ 0x30B7, 0x30B7, 0x30B7 },
{ 0x30B8, 0x30B8, 0x30B8 },
{ 0x30B9, 0x30B9, 0x30B9 },
{ 0x30BA, 0x30BA, 0x30BA },
{ 0x30BB, 0x30BB, 0x30BB },
{ 0x30BC, 0x30BC, 0x30BC },
{ 0x30BD, 0x30BD, 0x30BD },
{ 0x30BE, 0x30BE, 0x30BE },
{ 0x30BF, 0x30BF, 0x30BF },
{ 0x30C0, 0x30C0, 0x30C0 },
{ 0x30C1, 0x30C1, 0x30C1 },
{ 0x30C2, 0x30C2, 0x30C2 },
{ 0x30C3, 0x30C3, 0x30C3 },
{ 0x30C4, 0x30C4, 0x30C4 },
{ 0x30C5, 0x30C5, 0x30C5 },
{ 0x30C6, 0x30C6, 0x30C6 },
{ 0x30C7, 0x30C7, 0x30C7 },
{ 0x30C8, 0x30C8, 0x30C8 },
{ 0x30C9, 0x30C9, 0x30C9 },
{ 0x30CA, 0x30CA, 0x30CA },
{ 0x30CB, 0x30CB, 0x30CB },
{ 0x30CC, 0x30CC, 0x30CC },
{ 0x30CD, 0x30CD, 0x30CD },
{ 0x30CE, 0x30CE, 0x30CE },
{ 0x30CF, 0x30CF, 0x30CF },
{ 0x30D0, 0x30D0, 0x30D0 },
{ 0x30D1, 0x30D1, 0x30D1 },
{ 0x30D2, 0x30D2, 0x30D2 },
{ 0x30D3, 0x30D3, 0x30D3 },
{ 0x30D4, 0x30D4, 0x30D4 },
{ 0x30D5, 0x30D5, 0x30D5 },
{ 0x30D6, 0x30D6, 0x30D6 },
{ 0x30D7, 0x30D7, 0x30D7 },
{ 0x30D8, 0x30D8, 0x30D8 },
{ 0x30D9, 0x30D9, 0x30D9 },
{ 0x30DA, 0x30DA, 0x30DA },
{ 0x30DB, 0x30DB, 0x30DB },
{ 0x30DC, 0x30DC, 0x30DC },
{ 0x30DD, 0x30DD, 0x30DD },
{ 0x30DE, 0x30DE, 0x30DE },
{ 0x30DF, 0x30DF, 0x30DF },
{ 0x30E0, 0x30E0, 0x30E0 },
{ 0x30E1, 0x30E1, 0x30E1 },
{ 0x30E2, 0x30E2, 0x30E2 },
{ 0x30E3, 0x30E3, 0x30E3 },
{ 0x30E4, 0x30E4, 0x30E4 },
{ 0x30E5, 0x30E5, 0x30E5 },
{ 0x30E6, 0x30E6, 0x30E6 },
{ 0x30E7, 0x30E7, 0x30E7 },
{ 0x30E8, 0x30E8, 0x30E8 },
{ 0x30E9, 0x30E9, 0x30E9 },
{ 0x30EA, 0x30EA, 0x30EA },
{ 0x30EB, 0x30EB, 0x30EB },
{ 0x30EC, 0x30EC, 0x30EC },
{ 0x30ED, 0x30ED, 0x30ED },
{ 0x30EE, 0x30EE, 0x30EE },
{ 0x30EF, 0x30EF, 0x30EF },
{ 0x30F0, 0x30F0, 0x30F0 },
{ 0x30F1, 0x30F1, 0x30F1 },
{ 0x30F2, 0x30F2, 0x30F2 },
{ 0x30F3, 0x30F3, 0x30F3 },
{ 0x30F4, 0x30F4, 0x30F4 },
{ 0x30F5, 0x30F5, 0x30F5 },
{ 0x30F6, 0x30F6, 0x30F6 },
{ 0x30F7, 0x30F7, 0x30F7 },
{ 0x30F8, 0x30F8, 0x30F8 },
{ 0x30F9, 0x30F9, 0x30F9 },
{ 0x30FA, 0x30FA, 0x30FA },
{ 0x30FC, 0x30FC, 0x30FC },
{ 0x30FD, 0x30FD, 0x30FD },
{ 0x30FE, 0x30FE, 0x30FE },
{ 0x30FF, 0x30FF, 0x30FF },
{ 0x3105, 0x3105, 0x3105 },
{ 0x3106, 0x3106, 0x3106 },
{ 0x3107, 0x3107, 0x3107 },
{ 0x3108, 0x3108, 0x3108 },
{ 0x3109, 0x3109, 0x3109 },
{ 0x310A, 0x310A, 0x310A },
{ 0x310B, 0x310B, 0x310B },
{ 0x310C, 0x310C, 0x310C },
{ 0x310D, 0x310D, 0x310D },
{ 0x310E, 0x310E, 0x310E },
{ 0x310F, 0x310F, 0x310F },
{ 0x3110, 0x3110, 0x3110 },
{ 0x3111, 0x3111, 0x3111 },
{ 0x3112, 0x3112, 0x3112 },
{ 0x3113, 0x3113, 0x3113 },
{ 0x3114, 0x3114, 0x3114 },
{ 0x3115, 0x3115, 0x3115 },
{ 0x3116, 0x3116, 0x3116 },
{ 0x3117, 0x3117, 0x3117 },
{ 0x3118, 0x3118, 0x3118 },
{ 0x3119, 0x3119, 0x3119 },
{ 0x311A, 0x311A, 0x311A },
{ 0x311B, 0x311B, 0x311B },
{ 0x311C, 0x311C, 0x311C },
{ 0x311D, 0x311D, 0x311D },
{ 0x311E, 0x311E, 0x311E },
{ 0x311F, 0x311F, 0x311F },
{ 0x3120, 0x3120, 0x3120 },
{ 0x3121, 0x3121, 0x3121 },
{ 0x3122, 0x3122, 0x3122 },
{ 0x3123, 0x3123, 0x3123 },
{ 0x3124, 0x3124, 0x3124 },
{ 0x3125, 0x3125, 0x3125 },
{ 0x3126, 0x3126, 0x3126 },
{ 0x3127, 0x3127, 0x3127 },
{ 0x3128, 0x3128, 0x3128 },
{ 0x3129, 0x3129, 0x3129 },
{ 0x312A, 0x312A, 0x312A },
{ 0x312B, 0x312B, 0x312B },
{ 0x312C, 0x312C, 0x312C },
{ 0x3131, 0x3131, 0x3131 },
{ 0x3132, 0x3132, 0x3132 },
{ 0x3133, 0x3133, 0x3133 },
{ 0x3134, 0x3134, 0x3134 },
{ 0x3135, 0x3135, 0x3135 },
{ 0x3136, 0x3136, 0x3136 },
{ 0x3137, 0x3137, 0x3137 },
{ 0x3138, 0x3138, 0x3138 },
{ 0x3139, 0x3139, 0x3139 },
{ 0x313A, 0x313A, 0x313A },
{ 0x313B, 0x313B, 0x313B },
{ 0x313C, 0x313C, 0x313C },
{ 0x313D, 0x313D, 0x313D },
{ 0x313E, 0x313E, 0x313E },
{ 0x313F, 0x313F, 0x313F },
{ 0x3140, 0x3140, 0x3140 },
{ 0x3141, 0x3141, 0x3141 },
{ 0x3142, 0x3142, 0x3142 },
{ 0x3143, 0x3143, 0x3143 },
{ 0x3144, 0x3144, 0x3144 },
{ 0x3145, 0x3145, 0x3145 },
{ 0x3146, 0x3146, 0x3146 },
{ 0x3147, 0x3147, 0x3147 },
{ 0x3148, 0x3148, 0x3148 },
{ 0x3149, 0x3149, 0x3149 },
{ 0x314A, 0x314A, 0x314A },
{ 0x314B, 0x314B, 0x314B },
{ 0x314C, 0x314C, 0x314C },
{ 0x314D, 0x314D, 0x314D },
{ 0x314E, 0x314E, 0x314E },
{ 0x314F, 0x314F, 0x314F },
{ 0x3150, 0x3150, 0x3150 },
{ 0x3151, 0x3151, 0x3151 },
{ 0x3152, 0x3152, 0x3152 },
{ 0x3153, 0x3153, 0x3153 },
{ 0x3154, 0x3154, 0x3154 },
{ 0x3155, 0x3155, 0x3155 },
{ 0x3156, 0x3156, 0x3156 },
{ 0x3157, 0x3157, 0x3157 },
{ 0x3158, 0x3158, 0x3158 },
{ 0x3159, 0x3159, 0x3159 },
{ 0x315A, 0x315A, 0x315A },
{ 0x315B, 0x315B, 0x315B },
{ 0x315C, 0x315C, 0x315C },
{ 0x315D, 0x315D, 0x315D },
{ 0x315E, 0x315E, 0x315E },
{ 0x315F, 0x315F, 0x315F },
{ 0x3160, 0x3160, 0x3160 },
{ 0x3161, 0x3161, 0x3161 },
{ 0x3162, 0x3162, 0x3162 },
{ 0x3163, 0x3163, 0x3163 },
{ 0x3164, 0x3164, 0x3164 },
{ 0x3165, 0x3165, 0x3165 },
{ 0x3166, 0x3166, 0x3166 },
{ 0x3167, 0x3167, 0x3167 },
{ 0x3168, 0x3168, 0x3168 },
{ 0x3169, 0x3169, 0x3169 },
{ 0x316A, 0x316A, 0x316A },
{ 0x316B, 0x316B, 0x316B },
{ 0x316C, 0x316C, 0x316C },
{ 0x316D, 0x316D, 0x316D },
{ 0x316E, 0x316E, 0x316E },
{ 0x316F, 0x316F, 0x316F },
{ 0x3170, 0x3170, 0x3170 },
{ 0x3171, 0x3171, 0x3171 },
{ 0x3172, 0x3172, 0x3172 },
{ 0x3173, 0x3173, 0x3173 },
{ 0x3174, 0x3174, 0x3174 },
{ 0x3175, 0x3175, 0x3175 },
{ 0x3176, 0x3176, 0x3176 },
{ 0x3177, 0x3177, 0x3177 },
{ 0x3178, 0x3178, 0x3178 },
{ 0x3179, 0x3179, 0x3179 },
{ 0x317A, 0x317A, 0x317A },
{ 0x317B, 0x317B, 0x317B },
{ 0x317C, 0x317C, 0x317C },
{ 0x317D, 0x317D, 0x317D },
{ 0x317E, 0x317E, 0x317E },
{ 0x317F, 0x317F, 0x317F },
{ 0x3180, 0x3180, 0x3180 },
{ 0x3181, 0x3181, 0x3181 },
{ 0x3182, 0x3182, 0x3182 },
{ 0x3183, 0x3183, 0x3183 },
{ 0x3184, 0x3184, 0x3184 },
{ 0x3185, 0x3185, 0x3185 },
{ 0x3186, 0x3186, 0x3186 },
{ 0x3187, 0x3187, 0x3187 },
{ 0x3188, 0x3188, 0x3188 },
{ 0x3189, 0x3189, 0x3189 },
{ 0x318A, 0x318A, 0x318A },
{ 0x318B, 0x318B, 0x318B },
{ 0x318C, 0x318C, 0x318C },
{ 0x318D, 0x318D, 0x318D },
{ 0x318E, 0x318E, 0x318E },
{ 0x31A0, 0x31A0, 0x31A0 },
{ 0x31A1, 0x31A1, 0x31A1 },
{ 0x31A2, 0x31A2, 0x31A2 },
{ 0x31A3, 0x31A3, 0x31A3 },
{ 0x31A4, 0x31A4, 0x31A4 },
{ 0x31A5, 0x31A5, 0x31A5 },
{ 0x31A6, 0x31A6, 0x31A6 },
{ 0x31A7, 0x31A7, 0x31A7 },
{ 0x31A8, 0x31A8, 0x31A8 },
{ 0x31A9, 0x31A9, 0x31A9 },
{ 0x31AA, 0x31AA, 0x31AA },
{ 0x31AB, 0x31AB, 0x31AB },
{ 0x31AC, 0x31AC, 0x31AC },
{ 0x31AD, 0x31AD, 0x31AD },
{ 0x31AE, 0x31AE, 0x31AE },
{ 0x31AF, 0x31AF, 0x31AF },
{ 0x31B0, 0x31B0, 0x31B0 },
{ 0x31B1, 0x31B1, 0x31B1 },
{ 0x31B2, 0x31B2, 0x31B2 },
{ 0x31B3, 0x31B3, 0x31B3 },
{ 0x31B4, 0x31B4, 0x31B4 },
{ 0x31B5, 0x31B5, 0x31B5 },
{ 0x31B6, 0x31B6, 0x31B6 },
{ 0x31B7, 0x31B7, 0x31B7 },
{ 0x31F0, 0x31F0, 0x31F0 },
{ 0x31F1, 0x31F1, 0x31F1 },
{ 0x31F2, 0x31F2, 0x31F2 },
{ 0x31F3, 0x31F3, 0x31F3 },
{ 0x31F4, 0x31F4, 0x31F4 },
{ 0x31F5, 0x31F5, 0x31F5 },
{ 0x31F6, 0x31F6, 0x31F6 },
{ 0x31F7, 0x31F7, 0x31F7 },
{ 0x31F8, 0x31F8, 0x31F8 },
{ 0x31F9, 0x31F9, 0x31F9 },
{ 0x31FA, 0x31FA, 0x31FA },
{ 0x31FB, 0x31FB, 0x31FB },
{ 0x31FC, 0x31FC, 0x31FC },
{ 0x31FD, 0x31FD, 0x31FD },
{ 0x31FE, 0x31FE, 0x31FE },
{ 0x31FF, 0x31FF, 0x31FF },
{ 0x3400, 0x3400, 0x3400 },
{ 0x4DB5, 0x4DB5, 0x4DB5 },
{ 0x4E00, 0x4E00, 0x4E00 },
{ 0x9FBB, 0x9FBB, 0x9FBB },
{ 0xA000, 0xA000, 0xA000 },
{ 0xA001, 0xA001, 0xA001 },
{ 0xA002, 0xA002, 0xA002 },
{ 0xA003, 0xA003, 0xA003 },
{ 0xA004, 0xA004, 0xA004 },
{ 0xA005, 0xA005, 0xA005 },
{ 0xA006, 0xA006, 0xA006 },
{ 0xA007, 0xA007, 0xA007 },
{ 0xA008, 0xA008, 0xA008 },
{ 0xA009, 0xA009, 0xA009 },
{ 0xA00A, 0xA00A, 0xA00A },
{ 0xA00B, 0xA00B, 0xA00B },
{ 0xA00C, 0xA00C, 0xA00C },
{ 0xA00D, 0xA00D, 0xA00D },
{ 0xA00E, 0xA00E, 0xA00E },
{ 0xA00F, 0xA00F, 0xA00F },
{ 0xA010, 0xA010, 0xA010 },
{ 0xA011, 0xA011, 0xA011 },
{ 0xA012, 0xA012, 0xA012 },
{ 0xA013, 0xA013, 0xA013 },
{ 0xA014, 0xA014, 0xA014 },
{ 0xA015, 0xA015, 0xA015 },
{ 0xA016, 0xA016, 0xA016 },
{ 0xA017, 0xA017, 0xA017 },
{ 0xA018, 0xA018, 0xA018 },
{ 0xA019, 0xA019, 0xA019 },
{ 0xA01A, 0xA01A, 0xA01A },
{ 0xA01B, 0xA01B, 0xA01B },
{ 0xA01C, 0xA01C, 0xA01C },
{ 0xA01D, 0xA01D, 0xA01D },
{ 0xA01E, 0xA01E, 0xA01E },
{ 0xA01F, 0xA01F, 0xA01F },
{ 0xA020, 0xA020, 0xA020 },
{ 0xA021, 0xA021, 0xA021 },
{ 0xA022, 0xA022, 0xA022 },
{ 0xA023, 0xA023, 0xA023 },
{ 0xA024, 0xA024, 0xA024 },
{ 0xA025, 0xA025, 0xA025 },
{ 0xA026, 0xA026, 0xA026 },
{ 0xA027, 0xA027, 0xA027 },
{ 0xA028, 0xA028, 0xA028 },
{ 0xA029, 0xA029, 0xA029 },
{ 0xA02A, 0xA02A, 0xA02A },
{ 0xA02B, 0xA02B, 0xA02B },
{ 0xA02C, 0xA02C, 0xA02C },
{ 0xA02D, 0xA02D, 0xA02D },
{ 0xA02E, 0xA02E, 0xA02E },
{ 0xA02F, 0xA02F, 0xA02F },
{ 0xA030, 0xA030, 0xA030 },
{ 0xA031, 0xA031, 0xA031 },
{ 0xA032, 0xA032, 0xA032 },
{ 0xA033, 0xA033, 0xA033 },
{ 0xA034, 0xA034, 0xA034 },
{ 0xA035, 0xA035, 0xA035 },
{ 0xA036, 0xA036, 0xA036 },
{ 0xA037, 0xA037, 0xA037 },
{ 0xA038, 0xA038, 0xA038 },
{ 0xA039, 0xA039, 0xA039 },
{ 0xA03A, 0xA03A, 0xA03A },
{ 0xA03B, 0xA03B, 0xA03B },
{ 0xA03C, 0xA03C, 0xA03C },
{ 0xA03D, 0xA03D, 0xA03D },
{ 0xA03E, 0xA03E, 0xA03E },
{ 0xA03F, 0xA03F, 0xA03F },
{ 0xA040, 0xA040, 0xA040 },
{ 0xA041, 0xA041, 0xA041 },
{ 0xA042, 0xA042, 0xA042 },
{ 0xA043, 0xA043, 0xA043 },
{ 0xA044, 0xA044, 0xA044 },
{ 0xA045, 0xA045, 0xA045 },
{ 0xA046, 0xA046, 0xA046 },
{ 0xA047, 0xA047, 0xA047 },
{ 0xA048, 0xA048, 0xA048 },
{ 0xA049, 0xA049, 0xA049 },
{ 0xA04A, 0xA04A, 0xA04A },
{ 0xA04B, 0xA04B, 0xA04B },
{ 0xA04C, 0xA04C, 0xA04C },
{ 0xA04D, 0xA04D, 0xA04D },
{ 0xA04E, 0xA04E, 0xA04E },
{ 0xA04F, 0xA04F, 0xA04F },
{ 0xA050, 0xA050, 0xA050 },
{ 0xA051, 0xA051, 0xA051 },
{ 0xA052, 0xA052, 0xA052 },
{ 0xA053, 0xA053, 0xA053 },
{ 0xA054, 0xA054, 0xA054 },
{ 0xA055, 0xA055, 0xA055 },
{ 0xA056, 0xA056, 0xA056 },
{ 0xA057, 0xA057, 0xA057 },
{ 0xA058, 0xA058, 0xA058 },
{ 0xA059, 0xA059, 0xA059 },
{ 0xA05A, 0xA05A, 0xA05A },
{ 0xA05B, 0xA05B, 0xA05B },
{ 0xA05C, 0xA05C, 0xA05C },
{ 0xA05D, 0xA05D, 0xA05D },
{ 0xA05E, 0xA05E, 0xA05E },
{ 0xA05F, 0xA05F, 0xA05F },
{ 0xA060, 0xA060, 0xA060 },
{ 0xA061, 0xA061, 0xA061 },
{ 0xA062, 0xA062, 0xA062 },
{ 0xA063, 0xA063, 0xA063 },
{ 0xA064, 0xA064, 0xA064 },
{ 0xA065, 0xA065, 0xA065 },
{ 0xA066, 0xA066, 0xA066 },
{ 0xA067, 0xA067, 0xA067 },
{ 0xA068, 0xA068, 0xA068 },
{ 0xA069, 0xA069, 0xA069 },
{ 0xA06A, 0xA06A, 0xA06A },
{ 0xA06B, 0xA06B, 0xA06B },
{ 0xA06C, 0xA06C, 0xA06C },
{ 0xA06D, 0xA06D, 0xA06D },
{ 0xA06E, 0xA06E, 0xA06E },
{ 0xA06F, 0xA06F, 0xA06F },
{ 0xA070, 0xA070, 0xA070 },
{ 0xA071, 0xA071, 0xA071 },
{ 0xA072, 0xA072, 0xA072 },
{ 0xA073, 0xA073, 0xA073 },
{ 0xA074, 0xA074, 0xA074 },
{ 0xA075, 0xA075, 0xA075 },
{ 0xA076, 0xA076, 0xA076 },
{ 0xA077, 0xA077, 0xA077 },
{ 0xA078, 0xA078, 0xA078 },
{ 0xA079, 0xA079, 0xA079 },
{ 0xA07A, 0xA07A, 0xA07A },
{ 0xA07B, 0xA07B, 0xA07B },
{ 0xA07C, 0xA07C, 0xA07C },
{ 0xA07D, 0xA07D, 0xA07D },
{ 0xA07E, 0xA07E, 0xA07E },
{ 0xA07F, 0xA07F, 0xA07F },
{ 0xA080, 0xA080, 0xA080 },
{ 0xA081, 0xA081, 0xA081 },
{ 0xA082, 0xA082, 0xA082 },
{ 0xA083, 0xA083, 0xA083 },
{ 0xA084, 0xA084, 0xA084 },
{ 0xA085, 0xA085, 0xA085 },
{ 0xA086, 0xA086, 0xA086 },
{ 0xA087, 0xA087, 0xA087 },
{ 0xA088, 0xA088, 0xA088 },
{ 0xA089, 0xA089, 0xA089 },
{ 0xA08A, 0xA08A, 0xA08A },
{ 0xA08B, 0xA08B, 0xA08B },
{ 0xA08C, 0xA08C, 0xA08C },
{ 0xA08D, 0xA08D, 0xA08D },
{ 0xA08E, 0xA08E, 0xA08E },
{ 0xA08F, 0xA08F, 0xA08F },
{ 0xA090, 0xA090, 0xA090 },
{ 0xA091, 0xA091, 0xA091 },
{ 0xA092, 0xA092, 0xA092 },
{ 0xA093, 0xA093, 0xA093 },
{ 0xA094, 0xA094, 0xA094 },
{ 0xA095, 0xA095, 0xA095 },
{ 0xA096, 0xA096, 0xA096 },
{ 0xA097, 0xA097, 0xA097 },
{ 0xA098, 0xA098, 0xA098 },
{ 0xA099, 0xA099, 0xA099 },
{ 0xA09A, 0xA09A, 0xA09A },
{ 0xA09B, 0xA09B, 0xA09B },
{ 0xA09C, 0xA09C, 0xA09C },
{ 0xA09D, 0xA09D, 0xA09D },
{ 0xA09E, 0xA09E, 0xA09E },
{ 0xA09F, 0xA09F, 0xA09F },
{ 0xA0A0, 0xA0A0, 0xA0A0 },
{ 0xA0A1, 0xA0A1, 0xA0A1 },
{ 0xA0A2, 0xA0A2, 0xA0A2 },
{ 0xA0A3, 0xA0A3, 0xA0A3 },
{ 0xA0A4, 0xA0A4, 0xA0A4 },
{ 0xA0A5, 0xA0A5, 0xA0A5 },
{ 0xA0A6, 0xA0A6, 0xA0A6 },
{ 0xA0A7, 0xA0A7, 0xA0A7 },
{ 0xA0A8, 0xA0A8, 0xA0A8 },
{ 0xA0A9, 0xA0A9, 0xA0A9 },
{ 0xA0AA, 0xA0AA, 0xA0AA },
{ 0xA0AB, 0xA0AB, 0xA0AB },
{ 0xA0AC, 0xA0AC, 0xA0AC },
{ 0xA0AD, 0xA0AD, 0xA0AD },
{ 0xA0AE, 0xA0AE, 0xA0AE },
{ 0xA0AF, 0xA0AF, 0xA0AF },
{ 0xA0B0, 0xA0B0, 0xA0B0 },
{ 0xA0B1, 0xA0B1, 0xA0B1 },
{ 0xA0B2, 0xA0B2, 0xA0B2 },
{ 0xA0B3, 0xA0B3, 0xA0B3 },
{ 0xA0B4, 0xA0B4, 0xA0B4 },
{ 0xA0B5, 0xA0B5, 0xA0B5 },
{ 0xA0B6, 0xA0B6, 0xA0B6 },
{ 0xA0B7, 0xA0B7, 0xA0B7 },
{ 0xA0B8, 0xA0B8, 0xA0B8 },
{ 0xA0B9, 0xA0B9, 0xA0B9 },
{ 0xA0BA, 0xA0BA, 0xA0BA },
{ 0xA0BB, 0xA0BB, 0xA0BB },
{ 0xA0BC, 0xA0BC, 0xA0BC },
{ 0xA0BD, 0xA0BD, 0xA0BD },
{ 0xA0BE, 0xA0BE, 0xA0BE },
{ 0xA0BF, 0xA0BF, 0xA0BF },
{ 0xA0C0, 0xA0C0, 0xA0C0 },
{ 0xA0C1, 0xA0C1, 0xA0C1 },
{ 0xA0C2, 0xA0C2, 0xA0C2 },
{ 0xA0C3, 0xA0C3, 0xA0C3 },
{ 0xA0C4, 0xA0C4, 0xA0C4 },
{ 0xA0C5, 0xA0C5, 0xA0C5 },
{ 0xA0C6, 0xA0C6, 0xA0C6 },
{ 0xA0C7, 0xA0C7, 0xA0C7 },
{ 0xA0C8, 0xA0C8, 0xA0C8 },
{ 0xA0C9, 0xA0C9, 0xA0C9 },
{ 0xA0CA, 0xA0CA, 0xA0CA },
{ 0xA0CB, 0xA0CB, 0xA0CB },
{ 0xA0CC, 0xA0CC, 0xA0CC },
{ 0xA0CD, 0xA0CD, 0xA0CD },
{ 0xA0CE, 0xA0CE, 0xA0CE },
{ 0xA0CF, 0xA0CF, 0xA0CF },
{ 0xA0D0, 0xA0D0, 0xA0D0 },
{ 0xA0D1, 0xA0D1, 0xA0D1 },
{ 0xA0D2, 0xA0D2, 0xA0D2 },
{ 0xA0D3, 0xA0D3, 0xA0D3 },
{ 0xA0D4, 0xA0D4, 0xA0D4 },
{ 0xA0D5, 0xA0D5, 0xA0D5 },
{ 0xA0D6, 0xA0D6, 0xA0D6 },
{ 0xA0D7, 0xA0D7, 0xA0D7 },
{ 0xA0D8, 0xA0D8, 0xA0D8 },
{ 0xA0D9, 0xA0D9, 0xA0D9 },
{ 0xA0DA, 0xA0DA, 0xA0DA },
{ 0xA0DB, 0xA0DB, 0xA0DB },
{ 0xA0DC, 0xA0DC, 0xA0DC },
{ 0xA0DD, 0xA0DD, 0xA0DD },
{ 0xA0DE, 0xA0DE, 0xA0DE },
{ 0xA0DF, 0xA0DF, 0xA0DF },
{ 0xA0E0, 0xA0E0, 0xA0E0 },
{ 0xA0E1, 0xA0E1, 0xA0E1 },
{ 0xA0E2, 0xA0E2, 0xA0E2 },
{ 0xA0E3, 0xA0E3, 0xA0E3 },
{ 0xA0E4, 0xA0E4, 0xA0E4 },
{ 0xA0E5, 0xA0E5, 0xA0E5 },
{ 0xA0E6, 0xA0E6, 0xA0E6 },
{ 0xA0E7, 0xA0E7, 0xA0E7 },
{ 0xA0E8, 0xA0E8, 0xA0E8 },
{ 0xA0E9, 0xA0E9, 0xA0E9 },
{ 0xA0EA, 0xA0EA, 0xA0EA },
{ 0xA0EB, 0xA0EB, 0xA0EB },
{ 0xA0EC, 0xA0EC, 0xA0EC },
{ 0xA0ED, 0xA0ED, 0xA0ED },
{ 0xA0EE, 0xA0EE, 0xA0EE },
{ 0xA0EF, 0xA0EF, 0xA0EF },
{ 0xA0F0, 0xA0F0, 0xA0F0 },
{ 0xA0F1, 0xA0F1, 0xA0F1 },
{ 0xA0F2, 0xA0F2, 0xA0F2 },
{ 0xA0F3, 0xA0F3, 0xA0F3 },
{ 0xA0F4, 0xA0F4, 0xA0F4 },
{ 0xA0F5, 0xA0F5, 0xA0F5 },
{ 0xA0F6, 0xA0F6, 0xA0F6 },
{ 0xA0F7, 0xA0F7, 0xA0F7 },
{ 0xA0F8, 0xA0F8, 0xA0F8 },
{ 0xA0F9, 0xA0F9, 0xA0F9 },
{ 0xA0FA, 0xA0FA, 0xA0FA },
{ 0xA0FB, 0xA0FB, 0xA0FB },
{ 0xA0FC, 0xA0FC, 0xA0FC },
{ 0xA0FD, 0xA0FD, 0xA0FD },
{ 0xA0FE, 0xA0FE, 0xA0FE },
{ 0xA0FF, 0xA0FF, 0xA0FF },
{ 0xA100, 0xA100, 0xA100 },
{ 0xA101, 0xA101, 0xA101 },
{ 0xA102, 0xA102, 0xA102 },
{ 0xA103, 0xA103, 0xA103 },
{ 0xA104, 0xA104, 0xA104 },
{ 0xA105, 0xA105, 0xA105 },
{ 0xA106, 0xA106, 0xA106 },
{ 0xA107, 0xA107, 0xA107 },
{ 0xA108, 0xA108, 0xA108 },
{ 0xA109, 0xA109, 0xA109 },
{ 0xA10A, 0xA10A, 0xA10A },
{ 0xA10B, 0xA10B, 0xA10B },
{ 0xA10C, 0xA10C, 0xA10C },
{ 0xA10D, 0xA10D, 0xA10D },
{ 0xA10E, 0xA10E, 0xA10E },
{ 0xA10F, 0xA10F, 0xA10F },
{ 0xA110, 0xA110, 0xA110 },
{ 0xA111, 0xA111, 0xA111 },
{ 0xA112, 0xA112, 0xA112 },
{ 0xA113, 0xA113, 0xA113 },
{ 0xA114, 0xA114, 0xA114 },
{ 0xA115, 0xA115, 0xA115 },
{ 0xA116, 0xA116, 0xA116 },
{ 0xA117, 0xA117, 0xA117 },
{ 0xA118, 0xA118, 0xA118 },
{ 0xA119, 0xA119, 0xA119 },
{ 0xA11A, 0xA11A, 0xA11A },
{ 0xA11B, 0xA11B, 0xA11B },
{ 0xA11C, 0xA11C, 0xA11C },
{ 0xA11D, 0xA11D, 0xA11D },
{ 0xA11E, 0xA11E, 0xA11E },
{ 0xA11F, 0xA11F, 0xA11F },
{ 0xA120, 0xA120, 0xA120 },
{ 0xA121, 0xA121, 0xA121 },
{ 0xA122, 0xA122, 0xA122 },
{ 0xA123, 0xA123, 0xA123 },
{ 0xA124, 0xA124, 0xA124 },
{ 0xA125, 0xA125, 0xA125 },
{ 0xA126, 0xA126, 0xA126 },
{ 0xA127, 0xA127, 0xA127 },
{ 0xA128, 0xA128, 0xA128 },
{ 0xA129, 0xA129, 0xA129 },
{ 0xA12A, 0xA12A, 0xA12A },
{ 0xA12B, 0xA12B, 0xA12B },
{ 0xA12C, 0xA12C, 0xA12C },
{ 0xA12D, 0xA12D, 0xA12D },
{ 0xA12E, 0xA12E, 0xA12E },
{ 0xA12F, 0xA12F, 0xA12F },
{ 0xA130, 0xA130, 0xA130 },
{ 0xA131, 0xA131, 0xA131 },
{ 0xA132, 0xA132, 0xA132 },
{ 0xA133, 0xA133, 0xA133 },
{ 0xA134, 0xA134, 0xA134 },
{ 0xA135, 0xA135, 0xA135 },
{ 0xA136, 0xA136, 0xA136 },
{ 0xA137, 0xA137, 0xA137 },
{ 0xA138, 0xA138, 0xA138 },
{ 0xA139, 0xA139, 0xA139 },
{ 0xA13A, 0xA13A, 0xA13A },
{ 0xA13B, 0xA13B, 0xA13B },
{ 0xA13C, 0xA13C, 0xA13C },
{ 0xA13D, 0xA13D, 0xA13D },
{ 0xA13E, 0xA13E, 0xA13E },
{ 0xA13F, 0xA13F, 0xA13F },
{ 0xA140, 0xA140, 0xA140 },
{ 0xA141, 0xA141, 0xA141 },
{ 0xA142, 0xA142, 0xA142 },
{ 0xA143, 0xA143, 0xA143 },
{ 0xA144, 0xA144, 0xA144 },
{ 0xA145, 0xA145, 0xA145 },
{ 0xA146, 0xA146, 0xA146 },
{ 0xA147, 0xA147, 0xA147 },
{ 0xA148, 0xA148, 0xA148 },
{ 0xA149, 0xA149, 0xA149 },
{ 0xA14A, 0xA14A, 0xA14A },
{ 0xA14B, 0xA14B, 0xA14B },
{ 0xA14C, 0xA14C, 0xA14C },
{ 0xA14D, 0xA14D, 0xA14D },
{ 0xA14E, 0xA14E, 0xA14E },
{ 0xA14F, 0xA14F, 0xA14F },
{ 0xA150, 0xA150, 0xA150 },
{ 0xA151, 0xA151, 0xA151 },
{ 0xA152, 0xA152, 0xA152 },
{ 0xA153, 0xA153, 0xA153 },
{ 0xA154, 0xA154, 0xA154 },
{ 0xA155, 0xA155, 0xA155 },
{ 0xA156, 0xA156, 0xA156 },
{ 0xA157, 0xA157, 0xA157 },
{ 0xA158, 0xA158, 0xA158 },
{ 0xA159, 0xA159, 0xA159 },
{ 0xA15A, 0xA15A, 0xA15A },
{ 0xA15B, 0xA15B, 0xA15B },
{ 0xA15C, 0xA15C, 0xA15C },
{ 0xA15D, 0xA15D, 0xA15D },
{ 0xA15E, 0xA15E, 0xA15E },
{ 0xA15F, 0xA15F, 0xA15F },
{ 0xA160, 0xA160, 0xA160 },
{ 0xA161, 0xA161, 0xA161 },
{ 0xA162, 0xA162, 0xA162 },
{ 0xA163, 0xA163, 0xA163 },
{ 0xA164, 0xA164, 0xA164 },
{ 0xA165, 0xA165, 0xA165 },
{ 0xA166, 0xA166, 0xA166 },
{ 0xA167, 0xA167, 0xA167 },
{ 0xA168, 0xA168, 0xA168 },
{ 0xA169, 0xA169, 0xA169 },
{ 0xA16A, 0xA16A, 0xA16A },
{ 0xA16B, 0xA16B, 0xA16B },
{ 0xA16C, 0xA16C, 0xA16C },
{ 0xA16D, 0xA16D, 0xA16D },
{ 0xA16E, 0xA16E, 0xA16E },
{ 0xA16F, 0xA16F, 0xA16F },
{ 0xA170, 0xA170, 0xA170 },
{ 0xA171, 0xA171, 0xA171 },
{ 0xA172, 0xA172, 0xA172 },
{ 0xA173, 0xA173, 0xA173 },
{ 0xA174, 0xA174, 0xA174 },
{ 0xA175, 0xA175, 0xA175 },
{ 0xA176, 0xA176, 0xA176 },
{ 0xA177, 0xA177, 0xA177 },
{ 0xA178, 0xA178, 0xA178 },
{ 0xA179, 0xA179, 0xA179 },
{ 0xA17A, 0xA17A, 0xA17A },
{ 0xA17B, 0xA17B, 0xA17B },
{ 0xA17C, 0xA17C, 0xA17C },
{ 0xA17D, 0xA17D, 0xA17D },
{ 0xA17E, 0xA17E, 0xA17E },
{ 0xA17F, 0xA17F, 0xA17F },
{ 0xA180, 0xA180, 0xA180 },
{ 0xA181, 0xA181, 0xA181 },
{ 0xA182, 0xA182, 0xA182 },
{ 0xA183, 0xA183, 0xA183 },
{ 0xA184, 0xA184, 0xA184 },
{ 0xA185, 0xA185, 0xA185 },
{ 0xA186, 0xA186, 0xA186 },
{ 0xA187, 0xA187, 0xA187 },
{ 0xA188, 0xA188, 0xA188 },
{ 0xA189, 0xA189, 0xA189 },
{ 0xA18A, 0xA18A, 0xA18A },
{ 0xA18B, 0xA18B, 0xA18B },
{ 0xA18C, 0xA18C, 0xA18C },
{ 0xA18D, 0xA18D, 0xA18D },
{ 0xA18E, 0xA18E, 0xA18E },
{ 0xA18F, 0xA18F, 0xA18F },
{ 0xA190, 0xA190, 0xA190 },
{ 0xA191, 0xA191, 0xA191 },
{ 0xA192, 0xA192, 0xA192 },
{ 0xA193, 0xA193, 0xA193 },
{ 0xA194, 0xA194, 0xA194 },
{ 0xA195, 0xA195, 0xA195 },
{ 0xA196, 0xA196, 0xA196 },
{ 0xA197, 0xA197, 0xA197 },
{ 0xA198, 0xA198, 0xA198 },
{ 0xA199, 0xA199, 0xA199 },
{ 0xA19A, 0xA19A, 0xA19A },
{ 0xA19B, 0xA19B, 0xA19B },
{ 0xA19C, 0xA19C, 0xA19C },
{ 0xA19D, 0xA19D, 0xA19D },
{ 0xA19E, 0xA19E, 0xA19E },
{ 0xA19F, 0xA19F, 0xA19F },
{ 0xA1A0, 0xA1A0, 0xA1A0 },
{ 0xA1A1, 0xA1A1, 0xA1A1 },
{ 0xA1A2, 0xA1A2, 0xA1A2 },
{ 0xA1A3, 0xA1A3, 0xA1A3 },
{ 0xA1A4, 0xA1A4, 0xA1A4 },
{ 0xA1A5, 0xA1A5, 0xA1A5 },
{ 0xA1A6, 0xA1A6, 0xA1A6 },
{ 0xA1A7, 0xA1A7, 0xA1A7 },
{ 0xA1A8, 0xA1A8, 0xA1A8 },
{ 0xA1A9, 0xA1A9, 0xA1A9 },
{ 0xA1AA, 0xA1AA, 0xA1AA },
{ 0xA1AB, 0xA1AB, 0xA1AB },
{ 0xA1AC, 0xA1AC, 0xA1AC },
{ 0xA1AD, 0xA1AD, 0xA1AD },
{ 0xA1AE, 0xA1AE, 0xA1AE },
{ 0xA1AF, 0xA1AF, 0xA1AF },
{ 0xA1B0, 0xA1B0, 0xA1B0 },
{ 0xA1B1, 0xA1B1, 0xA1B1 },
{ 0xA1B2, 0xA1B2, 0xA1B2 },
{ 0xA1B3, 0xA1B3, 0xA1B3 },
{ 0xA1B4, 0xA1B4, 0xA1B4 },
{ 0xA1B5, 0xA1B5, 0xA1B5 },
{ 0xA1B6, 0xA1B6, 0xA1B6 },
{ 0xA1B7, 0xA1B7, 0xA1B7 },
{ 0xA1B8, 0xA1B8, 0xA1B8 },
{ 0xA1B9, 0xA1B9, 0xA1B9 },
{ 0xA1BA, 0xA1BA, 0xA1BA },
{ 0xA1BB, 0xA1BB, 0xA1BB },
{ 0xA1BC, 0xA1BC, 0xA1BC },
{ 0xA1BD, 0xA1BD, 0xA1BD },
{ 0xA1BE, 0xA1BE, 0xA1BE },
{ 0xA1BF, 0xA1BF, 0xA1BF },
{ 0xA1C0, 0xA1C0, 0xA1C0 },
{ 0xA1C1, 0xA1C1, 0xA1C1 },
{ 0xA1C2, 0xA1C2, 0xA1C2 },
{ 0xA1C3, 0xA1C3, 0xA1C3 },
{ 0xA1C4, 0xA1C4, 0xA1C4 },
{ 0xA1C5, 0xA1C5, 0xA1C5 },
{ 0xA1C6, 0xA1C6, 0xA1C6 },
{ 0xA1C7, 0xA1C7, 0xA1C7 },
{ 0xA1C8, 0xA1C8, 0xA1C8 },
{ 0xA1C9, 0xA1C9, 0xA1C9 },
{ 0xA1CA, 0xA1CA, 0xA1CA },
{ 0xA1CB, 0xA1CB, 0xA1CB },
{ 0xA1CC, 0xA1CC, 0xA1CC },
{ 0xA1CD, 0xA1CD, 0xA1CD },
{ 0xA1CE, 0xA1CE, 0xA1CE },
{ 0xA1CF, 0xA1CF, 0xA1CF },
{ 0xA1D0, 0xA1D0, 0xA1D0 },
{ 0xA1D1, 0xA1D1, 0xA1D1 },
{ 0xA1D2, 0xA1D2, 0xA1D2 },
{ 0xA1D3, 0xA1D3, 0xA1D3 },
{ 0xA1D4, 0xA1D4, 0xA1D4 },
{ 0xA1D5, 0xA1D5, 0xA1D5 },
{ 0xA1D6, 0xA1D6, 0xA1D6 },
{ 0xA1D7, 0xA1D7, 0xA1D7 },
{ 0xA1D8, 0xA1D8, 0xA1D8 },
{ 0xA1D9, 0xA1D9, 0xA1D9 },
{ 0xA1DA, 0xA1DA, 0xA1DA },
{ 0xA1DB, 0xA1DB, 0xA1DB },
{ 0xA1DC, 0xA1DC, 0xA1DC },
{ 0xA1DD, 0xA1DD, 0xA1DD },
{ 0xA1DE, 0xA1DE, 0xA1DE },
{ 0xA1DF, 0xA1DF, 0xA1DF },
{ 0xA1E0, 0xA1E0, 0xA1E0 },
{ 0xA1E1, 0xA1E1, 0xA1E1 },
{ 0xA1E2, 0xA1E2, 0xA1E2 },
{ 0xA1E3, 0xA1E3, 0xA1E3 },
{ 0xA1E4, 0xA1E4, 0xA1E4 },
{ 0xA1E5, 0xA1E5, 0xA1E5 },
{ 0xA1E6, 0xA1E6, 0xA1E6 },
{ 0xA1E7, 0xA1E7, 0xA1E7 },
{ 0xA1E8, 0xA1E8, 0xA1E8 },
{ 0xA1E9, 0xA1E9, 0xA1E9 },
{ 0xA1EA, 0xA1EA, 0xA1EA },
{ 0xA1EB, 0xA1EB, 0xA1EB },
{ 0xA1EC, 0xA1EC, 0xA1EC },
{ 0xA1ED, 0xA1ED, 0xA1ED },
{ 0xA1EE, 0xA1EE, 0xA1EE },
{ 0xA1EF, 0xA1EF, 0xA1EF },
{ 0xA1F0, 0xA1F0, 0xA1F0 },
{ 0xA1F1, 0xA1F1, 0xA1F1 },
{ 0xA1F2, 0xA1F2, 0xA1F2 },
{ 0xA1F3, 0xA1F3, 0xA1F3 },
{ 0xA1F4, 0xA1F4, 0xA1F4 },
{ 0xA1F5, 0xA1F5, 0xA1F5 },
{ 0xA1F6, 0xA1F6, 0xA1F6 },
{ 0xA1F7, 0xA1F7, 0xA1F7 },
{ 0xA1F8, 0xA1F8, 0xA1F8 },
{ 0xA1F9, 0xA1F9, 0xA1F9 },
{ 0xA1FA, 0xA1FA, 0xA1FA },
{ 0xA1FB, 0xA1FB, 0xA1FB },
{ 0xA1FC, 0xA1FC, 0xA1FC },
{ 0xA1FD, 0xA1FD, 0xA1FD },
{ 0xA1FE, 0xA1FE, 0xA1FE },
{ 0xA1FF, 0xA1FF, 0xA1FF },
{ 0xA200, 0xA200, 0xA200 },
{ 0xA201, 0xA201, 0xA201 },
{ 0xA202, 0xA202, 0xA202 },
{ 0xA203, 0xA203, 0xA203 },
{ 0xA204, 0xA204, 0xA204 },
{ 0xA205, 0xA205, 0xA205 },
{ 0xA206, 0xA206, 0xA206 },
{ 0xA207, 0xA207, 0xA207 },
{ 0xA208, 0xA208, 0xA208 },
{ 0xA209, 0xA209, 0xA209 },
{ 0xA20A, 0xA20A, 0xA20A },
{ 0xA20B, 0xA20B, 0xA20B },
{ 0xA20C, 0xA20C, 0xA20C },
{ 0xA20D, 0xA20D, 0xA20D },
{ 0xA20E, 0xA20E, 0xA20E },
{ 0xA20F, 0xA20F, 0xA20F },
{ 0xA210, 0xA210, 0xA210 },
{ 0xA211, 0xA211, 0xA211 },
{ 0xA212, 0xA212, 0xA212 },
{ 0xA213, 0xA213, 0xA213 },
{ 0xA214, 0xA214, 0xA214 },
{ 0xA215, 0xA215, 0xA215 },
{ 0xA216, 0xA216, 0xA216 },
{ 0xA217, 0xA217, 0xA217 },
{ 0xA218, 0xA218, 0xA218 },
{ 0xA219, 0xA219, 0xA219 },
{ 0xA21A, 0xA21A, 0xA21A },
{ 0xA21B, 0xA21B, 0xA21B },
{ 0xA21C, 0xA21C, 0xA21C },
{ 0xA21D, 0xA21D, 0xA21D },
{ 0xA21E, 0xA21E, 0xA21E },
{ 0xA21F, 0xA21F, 0xA21F },
{ 0xA220, 0xA220, 0xA220 },
{ 0xA221, 0xA221, 0xA221 },
{ 0xA222, 0xA222, 0xA222 },
{ 0xA223, 0xA223, 0xA223 },
{ 0xA224, 0xA224, 0xA224 },
{ 0xA225, 0xA225, 0xA225 },
{ 0xA226, 0xA226, 0xA226 },
{ 0xA227, 0xA227, 0xA227 },
{ 0xA228, 0xA228, 0xA228 },
{ 0xA229, 0xA229, 0xA229 },
{ 0xA22A, 0xA22A, 0xA22A },
{ 0xA22B, 0xA22B, 0xA22B },
{ 0xA22C, 0xA22C, 0xA22C },
{ 0xA22D, 0xA22D, 0xA22D },
{ 0xA22E, 0xA22E, 0xA22E },
{ 0xA22F, 0xA22F, 0xA22F },
{ 0xA230, 0xA230, 0xA230 },
{ 0xA231, 0xA231, 0xA231 },
{ 0xA232, 0xA232, 0xA232 },
{ 0xA233, 0xA233, 0xA233 },
{ 0xA234, 0xA234, 0xA234 },
{ 0xA235, 0xA235, 0xA235 },
{ 0xA236, 0xA236, 0xA236 },
{ 0xA237, 0xA237, 0xA237 },
{ 0xA238, 0xA238, 0xA238 },
{ 0xA239, 0xA239, 0xA239 },
{ 0xA23A, 0xA23A, 0xA23A },
{ 0xA23B, 0xA23B, 0xA23B },
{ 0xA23C, 0xA23C, 0xA23C },
{ 0xA23D, 0xA23D, 0xA23D },
{ 0xA23E, 0xA23E, 0xA23E },
{ 0xA23F, 0xA23F, 0xA23F },
{ 0xA240, 0xA240, 0xA240 },
{ 0xA241, 0xA241, 0xA241 },
{ 0xA242, 0xA242, 0xA242 },
{ 0xA243, 0xA243, 0xA243 },
{ 0xA244, 0xA244, 0xA244 },
{ 0xA245, 0xA245, 0xA245 },
{ 0xA246, 0xA246, 0xA246 },
{ 0xA247, 0xA247, 0xA247 },
{ 0xA248, 0xA248, 0xA248 },
{ 0xA249, 0xA249, 0xA249 },
{ 0xA24A, 0xA24A, 0xA24A },
{ 0xA24B, 0xA24B, 0xA24B },
{ 0xA24C, 0xA24C, 0xA24C },
{ 0xA24D, 0xA24D, 0xA24D },
{ 0xA24E, 0xA24E, 0xA24E },
{ 0xA24F, 0xA24F, 0xA24F },
{ 0xA250, 0xA250, 0xA250 },
{ 0xA251, 0xA251, 0xA251 },
{ 0xA252, 0xA252, 0xA252 },
{ 0xA253, 0xA253, 0xA253 },
{ 0xA254, 0xA254, 0xA254 },
{ 0xA255, 0xA255, 0xA255 },
{ 0xA256, 0xA256, 0xA256 },
{ 0xA257, 0xA257, 0xA257 },
{ 0xA258, 0xA258, 0xA258 },
{ 0xA259, 0xA259, 0xA259 },
{ 0xA25A, 0xA25A, 0xA25A },
{ 0xA25B, 0xA25B, 0xA25B },
{ 0xA25C, 0xA25C, 0xA25C },
{ 0xA25D, 0xA25D, 0xA25D },
{ 0xA25E, 0xA25E, 0xA25E },
{ 0xA25F, 0xA25F, 0xA25F },
{ 0xA260, 0xA260, 0xA260 },
{ 0xA261, 0xA261, 0xA261 },
{ 0xA262, 0xA262, 0xA262 },
{ 0xA263, 0xA263, 0xA263 },
{ 0xA264, 0xA264, 0xA264 },
{ 0xA265, 0xA265, 0xA265 },
{ 0xA266, 0xA266, 0xA266 },
{ 0xA267, 0xA267, 0xA267 },
{ 0xA268, 0xA268, 0xA268 },
{ 0xA269, 0xA269, 0xA269 },
{ 0xA26A, 0xA26A, 0xA26A },
{ 0xA26B, 0xA26B, 0xA26B },
{ 0xA26C, 0xA26C, 0xA26C },
{ 0xA26D, 0xA26D, 0xA26D },
{ 0xA26E, 0xA26E, 0xA26E },
{ 0xA26F, 0xA26F, 0xA26F },
{ 0xA270, 0xA270, 0xA270 },
{ 0xA271, 0xA271, 0xA271 },
{ 0xA272, 0xA272, 0xA272 },
{ 0xA273, 0xA273, 0xA273 },
{ 0xA274, 0xA274, 0xA274 },
{ 0xA275, 0xA275, 0xA275 },
{ 0xA276, 0xA276, 0xA276 },
{ 0xA277, 0xA277, 0xA277 },
{ 0xA278, 0xA278, 0xA278 },
{ 0xA279, 0xA279, 0xA279 },
{ 0xA27A, 0xA27A, 0xA27A },
{ 0xA27B, 0xA27B, 0xA27B },
{ 0xA27C, 0xA27C, 0xA27C },
{ 0xA27D, 0xA27D, 0xA27D },
{ 0xA27E, 0xA27E, 0xA27E },
{ 0xA27F, 0xA27F, 0xA27F },
{ 0xA280, 0xA280, 0xA280 },
{ 0xA281, 0xA281, 0xA281 },
{ 0xA282, 0xA282, 0xA282 },
{ 0xA283, 0xA283, 0xA283 },
{ 0xA284, 0xA284, 0xA284 },
{ 0xA285, 0xA285, 0xA285 },
{ 0xA286, 0xA286, 0xA286 },
{ 0xA287, 0xA287, 0xA287 },
{ 0xA288, 0xA288, 0xA288 },
{ 0xA289, 0xA289, 0xA289 },
{ 0xA28A, 0xA28A, 0xA28A },
{ 0xA28B, 0xA28B, 0xA28B },
{ 0xA28C, 0xA28C, 0xA28C },
{ 0xA28D, 0xA28D, 0xA28D },
{ 0xA28E, 0xA28E, 0xA28E },
{ 0xA28F, 0xA28F, 0xA28F },
{ 0xA290, 0xA290, 0xA290 },
{ 0xA291, 0xA291, 0xA291 },
{ 0xA292, 0xA292, 0xA292 },
{ 0xA293, 0xA293, 0xA293 },
{ 0xA294, 0xA294, 0xA294 },
{ 0xA295, 0xA295, 0xA295 },
{ 0xA296, 0xA296, 0xA296 },
{ 0xA297, 0xA297, 0xA297 },
{ 0xA298, 0xA298, 0xA298 },
{ 0xA299, 0xA299, 0xA299 },
{ 0xA29A, 0xA29A, 0xA29A },
{ 0xA29B, 0xA29B, 0xA29B },
{ 0xA29C, 0xA29C, 0xA29C },
{ 0xA29D, 0xA29D, 0xA29D },
{ 0xA29E, 0xA29E, 0xA29E },
{ 0xA29F, 0xA29F, 0xA29F },
{ 0xA2A0, 0xA2A0, 0xA2A0 },
{ 0xA2A1, 0xA2A1, 0xA2A1 },
{ 0xA2A2, 0xA2A2, 0xA2A2 },
{ 0xA2A3, 0xA2A3, 0xA2A3 },
{ 0xA2A4, 0xA2A4, 0xA2A4 },
{ 0xA2A5, 0xA2A5, 0xA2A5 },
{ 0xA2A6, 0xA2A6, 0xA2A6 },
{ 0xA2A7, 0xA2A7, 0xA2A7 },
{ 0xA2A8, 0xA2A8, 0xA2A8 },
{ 0xA2A9, 0xA2A9, 0xA2A9 },
{ 0xA2AA, 0xA2AA, 0xA2AA },
{ 0xA2AB, 0xA2AB, 0xA2AB },
{ 0xA2AC, 0xA2AC, 0xA2AC },
{ 0xA2AD, 0xA2AD, 0xA2AD },
{ 0xA2AE, 0xA2AE, 0xA2AE },
{ 0xA2AF, 0xA2AF, 0xA2AF },
{ 0xA2B0, 0xA2B0, 0xA2B0 },
{ 0xA2B1, 0xA2B1, 0xA2B1 },
{ 0xA2B2, 0xA2B2, 0xA2B2 },
{ 0xA2B3, 0xA2B3, 0xA2B3 },
{ 0xA2B4, 0xA2B4, 0xA2B4 },
{ 0xA2B5, 0xA2B5, 0xA2B5 },
{ 0xA2B6, 0xA2B6, 0xA2B6 },
{ 0xA2B7, 0xA2B7, 0xA2B7 },
{ 0xA2B8, 0xA2B8, 0xA2B8 },
{ 0xA2B9, 0xA2B9, 0xA2B9 },
{ 0xA2BA, 0xA2BA, 0xA2BA },
{ 0xA2BB, 0xA2BB, 0xA2BB },
{ 0xA2BC, 0xA2BC, 0xA2BC },
{ 0xA2BD, 0xA2BD, 0xA2BD },
{ 0xA2BE, 0xA2BE, 0xA2BE },
{ 0xA2BF, 0xA2BF, 0xA2BF },
{ 0xA2C0, 0xA2C0, 0xA2C0 },
{ 0xA2C1, 0xA2C1, 0xA2C1 },
{ 0xA2C2, 0xA2C2, 0xA2C2 },
{ 0xA2C3, 0xA2C3, 0xA2C3 },
{ 0xA2C4, 0xA2C4, 0xA2C4 },
{ 0xA2C5, 0xA2C5, 0xA2C5 },
{ 0xA2C6, 0xA2C6, 0xA2C6 },
{ 0xA2C7, 0xA2C7, 0xA2C7 },
{ 0xA2C8, 0xA2C8, 0xA2C8 },
{ 0xA2C9, 0xA2C9, 0xA2C9 },
{ 0xA2CA, 0xA2CA, 0xA2CA },
{ 0xA2CB, 0xA2CB, 0xA2CB },
{ 0xA2CC, 0xA2CC, 0xA2CC },
{ 0xA2CD, 0xA2CD, 0xA2CD },
{ 0xA2CE, 0xA2CE, 0xA2CE },
{ 0xA2CF, 0xA2CF, 0xA2CF },
{ 0xA2D0, 0xA2D0, 0xA2D0 },
{ 0xA2D1, 0xA2D1, 0xA2D1 },
{ 0xA2D2, 0xA2D2, 0xA2D2 },
{ 0xA2D3, 0xA2D3, 0xA2D3 },
{ 0xA2D4, 0xA2D4, 0xA2D4 },
{ 0xA2D5, 0xA2D5, 0xA2D5 },
{ 0xA2D6, 0xA2D6, 0xA2D6 },
{ 0xA2D7, 0xA2D7, 0xA2D7 },
{ 0xA2D8, 0xA2D8, 0xA2D8 },
{ 0xA2D9, 0xA2D9, 0xA2D9 },
{ 0xA2DA, 0xA2DA, 0xA2DA },
{ 0xA2DB, 0xA2DB, 0xA2DB },
{ 0xA2DC, 0xA2DC, 0xA2DC },
{ 0xA2DD, 0xA2DD, 0xA2DD },
{ 0xA2DE, 0xA2DE, 0xA2DE },
{ 0xA2DF, 0xA2DF, 0xA2DF },
{ 0xA2E0, 0xA2E0, 0xA2E0 },
{ 0xA2E1, 0xA2E1, 0xA2E1 },
{ 0xA2E2, 0xA2E2, 0xA2E2 },
{ 0xA2E3, 0xA2E3, 0xA2E3 },
{ 0xA2E4, 0xA2E4, 0xA2E4 },
{ 0xA2E5, 0xA2E5, 0xA2E5 },
{ 0xA2E6, 0xA2E6, 0xA2E6 },
{ 0xA2E7, 0xA2E7, 0xA2E7 },
{ 0xA2E8, 0xA2E8, 0xA2E8 },
{ 0xA2E9, 0xA2E9, 0xA2E9 },
{ 0xA2EA, 0xA2EA, 0xA2EA },
{ 0xA2EB, 0xA2EB, 0xA2EB },
{ 0xA2EC, 0xA2EC, 0xA2EC },
{ 0xA2ED, 0xA2ED, 0xA2ED },
{ 0xA2EE, 0xA2EE, 0xA2EE },
{ 0xA2EF, 0xA2EF, 0xA2EF },
{ 0xA2F0, 0xA2F0, 0xA2F0 },
{ 0xA2F1, 0xA2F1, 0xA2F1 },
{ 0xA2F2, 0xA2F2, 0xA2F2 },
{ 0xA2F3, 0xA2F3, 0xA2F3 },
{ 0xA2F4, 0xA2F4, 0xA2F4 },
{ 0xA2F5, 0xA2F5, 0xA2F5 },
{ 0xA2F6, 0xA2F6, 0xA2F6 },
{ 0xA2F7, 0xA2F7, 0xA2F7 },
{ 0xA2F8, 0xA2F8, 0xA2F8 },
{ 0xA2F9, 0xA2F9, 0xA2F9 },
{ 0xA2FA, 0xA2FA, 0xA2FA },
{ 0xA2FB, 0xA2FB, 0xA2FB },
{ 0xA2FC, 0xA2FC, 0xA2FC },
{ 0xA2FD, 0xA2FD, 0xA2FD },
{ 0xA2FE, 0xA2FE, 0xA2FE },
{ 0xA2FF, 0xA2FF, 0xA2FF },
{ 0xA300, 0xA300, 0xA300 },
{ 0xA301, 0xA301, 0xA301 },
{ 0xA302, 0xA302, 0xA302 },
{ 0xA303, 0xA303, 0xA303 },
{ 0xA304, 0xA304, 0xA304 },
{ 0xA305, 0xA305, 0xA305 },
{ 0xA306, 0xA306, 0xA306 },
{ 0xA307, 0xA307, 0xA307 },
{ 0xA308, 0xA308, 0xA308 },
{ 0xA309, 0xA309, 0xA309 },
{ 0xA30A, 0xA30A, 0xA30A },
{ 0xA30B, 0xA30B, 0xA30B },
{ 0xA30C, 0xA30C, 0xA30C },
{ 0xA30D, 0xA30D, 0xA30D },
{ 0xA30E, 0xA30E, 0xA30E },
{ 0xA30F, 0xA30F, 0xA30F },
{ 0xA310, 0xA310, 0xA310 },
{ 0xA311, 0xA311, 0xA311 },
{ 0xA312, 0xA312, 0xA312 },
{ 0xA313, 0xA313, 0xA313 },
{ 0xA314, 0xA314, 0xA314 },
{ 0xA315, 0xA315, 0xA315 },
{ 0xA316, 0xA316, 0xA316 },
{ 0xA317, 0xA317, 0xA317 },
{ 0xA318, 0xA318, 0xA318 },
{ 0xA319, 0xA319, 0xA319 },
{ 0xA31A, 0xA31A, 0xA31A },
{ 0xA31B, 0xA31B, 0xA31B },
{ 0xA31C, 0xA31C, 0xA31C },
{ 0xA31D, 0xA31D, 0xA31D },
{ 0xA31E, 0xA31E, 0xA31E },
{ 0xA31F, 0xA31F, 0xA31F },
{ 0xA320, 0xA320, 0xA320 },
{ 0xA321, 0xA321, 0xA321 },
{ 0xA322, 0xA322, 0xA322 },
{ 0xA323, 0xA323, 0xA323 },
{ 0xA324, 0xA324, 0xA324 },
{ 0xA325, 0xA325, 0xA325 },
{ 0xA326, 0xA326, 0xA326 },
{ 0xA327, 0xA327, 0xA327 },
{ 0xA328, 0xA328, 0xA328 },
{ 0xA329, 0xA329, 0xA329 },
{ 0xA32A, 0xA32A, 0xA32A },
{ 0xA32B, 0xA32B, 0xA32B },
{ 0xA32C, 0xA32C, 0xA32C },
{ 0xA32D, 0xA32D, 0xA32D },
{ 0xA32E, 0xA32E, 0xA32E },
{ 0xA32F, 0xA32F, 0xA32F },
{ 0xA330, 0xA330, 0xA330 },
{ 0xA331, 0xA331, 0xA331 },
{ 0xA332, 0xA332, 0xA332 },
{ 0xA333, 0xA333, 0xA333 },
{ 0xA334, 0xA334, 0xA334 },
{ 0xA335, 0xA335, 0xA335 },
{ 0xA336, 0xA336, 0xA336 },
{ 0xA337, 0xA337, 0xA337 },
{ 0xA338, 0xA338, 0xA338 },
{ 0xA339, 0xA339, 0xA339 },
{ 0xA33A, 0xA33A, 0xA33A },
{ 0xA33B, 0xA33B, 0xA33B },
{ 0xA33C, 0xA33C, 0xA33C },
{ 0xA33D, 0xA33D, 0xA33D },
{ 0xA33E, 0xA33E, 0xA33E },
{ 0xA33F, 0xA33F, 0xA33F },
{ 0xA340, 0xA340, 0xA340 },
{ 0xA341, 0xA341, 0xA341 },
{ 0xA342, 0xA342, 0xA342 },
{ 0xA343, 0xA343, 0xA343 },
{ 0xA344, 0xA344, 0xA344 },
{ 0xA345, 0xA345, 0xA345 },
{ 0xA346, 0xA346, 0xA346 },
{ 0xA347, 0xA347, 0xA347 },
{ 0xA348, 0xA348, 0xA348 },
{ 0xA349, 0xA349, 0xA349 },
{ 0xA34A, 0xA34A, 0xA34A },
{ 0xA34B, 0xA34B, 0xA34B },
{ 0xA34C, 0xA34C, 0xA34C },
{ 0xA34D, 0xA34D, 0xA34D },
{ 0xA34E, 0xA34E, 0xA34E },
{ 0xA34F, 0xA34F, 0xA34F },
{ 0xA350, 0xA350, 0xA350 },
{ 0xA351, 0xA351, 0xA351 },
{ 0xA352, 0xA352, 0xA352 },
{ 0xA353, 0xA353, 0xA353 },
{ 0xA354, 0xA354, 0xA354 },
{ 0xA355, 0xA355, 0xA355 },
{ 0xA356, 0xA356, 0xA356 },
{ 0xA357, 0xA357, 0xA357 },
{ 0xA358, 0xA358, 0xA358 },
{ 0xA359, 0xA359, 0xA359 },
{ 0xA35A, 0xA35A, 0xA35A },
{ 0xA35B, 0xA35B, 0xA35B },
{ 0xA35C, 0xA35C, 0xA35C },
{ 0xA35D, 0xA35D, 0xA35D },
{ 0xA35E, 0xA35E, 0xA35E },
{ 0xA35F, 0xA35F, 0xA35F },
{ 0xA360, 0xA360, 0xA360 },
{ 0xA361, 0xA361, 0xA361 },
{ 0xA362, 0xA362, 0xA362 },
{ 0xA363, 0xA363, 0xA363 },
{ 0xA364, 0xA364, 0xA364 },
{ 0xA365, 0xA365, 0xA365 },
{ 0xA366, 0xA366, 0xA366 },
{ 0xA367, 0xA367, 0xA367 },
{ 0xA368, 0xA368, 0xA368 },
{ 0xA369, 0xA369, 0xA369 },
{ 0xA36A, 0xA36A, 0xA36A },
{ 0xA36B, 0xA36B, 0xA36B },
{ 0xA36C, 0xA36C, 0xA36C },
{ 0xA36D, 0xA36D, 0xA36D },
{ 0xA36E, 0xA36E, 0xA36E },
{ 0xA36F, 0xA36F, 0xA36F },
{ 0xA370, 0xA370, 0xA370 },
{ 0xA371, 0xA371, 0xA371 },
{ 0xA372, 0xA372, 0xA372 },
{ 0xA373, 0xA373, 0xA373 },
{ 0xA374, 0xA374, 0xA374 },
{ 0xA375, 0xA375, 0xA375 },
{ 0xA376, 0xA376, 0xA376 },
{ 0xA377, 0xA377, 0xA377 },
{ 0xA378, 0xA378, 0xA378 },
{ 0xA379, 0xA379, 0xA379 },
{ 0xA37A, 0xA37A, 0xA37A },
{ 0xA37B, 0xA37B, 0xA37B },
{ 0xA37C, 0xA37C, 0xA37C },
{ 0xA37D, 0xA37D, 0xA37D },
{ 0xA37E, 0xA37E, 0xA37E },
{ 0xA37F, 0xA37F, 0xA37F },
{ 0xA380, 0xA380, 0xA380 },
{ 0xA381, 0xA381, 0xA381 },
{ 0xA382, 0xA382, 0xA382 },
{ 0xA383, 0xA383, 0xA383 },
{ 0xA384, 0xA384, 0xA384 },
{ 0xA385, 0xA385, 0xA385 },
{ 0xA386, 0xA386, 0xA386 },
{ 0xA387, 0xA387, 0xA387 },
{ 0xA388, 0xA388, 0xA388 },
{ 0xA389, 0xA389, 0xA389 },
{ 0xA38A, 0xA38A, 0xA38A },
{ 0xA38B, 0xA38B, 0xA38B },
{ 0xA38C, 0xA38C, 0xA38C },
{ 0xA38D, 0xA38D, 0xA38D },
{ 0xA38E, 0xA38E, 0xA38E },
{ 0xA38F, 0xA38F, 0xA38F },
{ 0xA390, 0xA390, 0xA390 },
{ 0xA391, 0xA391, 0xA391 },
{ 0xA392, 0xA392, 0xA392 },
{ 0xA393, 0xA393, 0xA393 },
{ 0xA394, 0xA394, 0xA394 },
{ 0xA395, 0xA395, 0xA395 },
{ 0xA396, 0xA396, 0xA396 },
{ 0xA397, 0xA397, 0xA397 },
{ 0xA398, 0xA398, 0xA398 },
{ 0xA399, 0xA399, 0xA399 },
{ 0xA39A, 0xA39A, 0xA39A },
{ 0xA39B, 0xA39B, 0xA39B },
{ 0xA39C, 0xA39C, 0xA39C },
{ 0xA39D, 0xA39D, 0xA39D },
{ 0xA39E, 0xA39E, 0xA39E },
{ 0xA39F, 0xA39F, 0xA39F },
{ 0xA3A0, 0xA3A0, 0xA3A0 },
{ 0xA3A1, 0xA3A1, 0xA3A1 },
{ 0xA3A2, 0xA3A2, 0xA3A2 },
{ 0xA3A3, 0xA3A3, 0xA3A3 },
{ 0xA3A4, 0xA3A4, 0xA3A4 },
{ 0xA3A5, 0xA3A5, 0xA3A5 },
{ 0xA3A6, 0xA3A6, 0xA3A6 },
{ 0xA3A7, 0xA3A7, 0xA3A7 },
{ 0xA3A8, 0xA3A8, 0xA3A8 },
{ 0xA3A9, 0xA3A9, 0xA3A9 },
{ 0xA3AA, 0xA3AA, 0xA3AA },
{ 0xA3AB, 0xA3AB, 0xA3AB },
{ 0xA3AC, 0xA3AC, 0xA3AC },
{ 0xA3AD, 0xA3AD, 0xA3AD },
{ 0xA3AE, 0xA3AE, 0xA3AE },
{ 0xA3AF, 0xA3AF, 0xA3AF },
{ 0xA3B0, 0xA3B0, 0xA3B0 },
{ 0xA3B1, 0xA3B1, 0xA3B1 },
{ 0xA3B2, 0xA3B2, 0xA3B2 },
{ 0xA3B3, 0xA3B3, 0xA3B3 },
{ 0xA3B4, 0xA3B4, 0xA3B4 },
{ 0xA3B5, 0xA3B5, 0xA3B5 },
{ 0xA3B6, 0xA3B6, 0xA3B6 },
{ 0xA3B7, 0xA3B7, 0xA3B7 },
{ 0xA3B8, 0xA3B8, 0xA3B8 },
{ 0xA3B9, 0xA3B9, 0xA3B9 },
{ 0xA3BA, 0xA3BA, 0xA3BA },
{ 0xA3BB, 0xA3BB, 0xA3BB },
{ 0xA3BC, 0xA3BC, 0xA3BC },
{ 0xA3BD, 0xA3BD, 0xA3BD },
{ 0xA3BE, 0xA3BE, 0xA3BE },
{ 0xA3BF, 0xA3BF, 0xA3BF },
{ 0xA3C0, 0xA3C0, 0xA3C0 },
{ 0xA3C1, 0xA3C1, 0xA3C1 },
{ 0xA3C2, 0xA3C2, 0xA3C2 },
{ 0xA3C3, 0xA3C3, 0xA3C3 },
{ 0xA3C4, 0xA3C4, 0xA3C4 },
{ 0xA3C5, 0xA3C5, 0xA3C5 },
{ 0xA3C6, 0xA3C6, 0xA3C6 },
{ 0xA3C7, 0xA3C7, 0xA3C7 },
{ 0xA3C8, 0xA3C8, 0xA3C8 },
{ 0xA3C9, 0xA3C9, 0xA3C9 },
{ 0xA3CA, 0xA3CA, 0xA3CA },
{ 0xA3CB, 0xA3CB, 0xA3CB },
{ 0xA3CC, 0xA3CC, 0xA3CC },
{ 0xA3CD, 0xA3CD, 0xA3CD },
{ 0xA3CE, 0xA3CE, 0xA3CE },
{ 0xA3CF, 0xA3CF, 0xA3CF },
{ 0xA3D0, 0xA3D0, 0xA3D0 },
{ 0xA3D1, 0xA3D1, 0xA3D1 },
{ 0xA3D2, 0xA3D2, 0xA3D2 },
{ 0xA3D3, 0xA3D3, 0xA3D3 },
{ 0xA3D4, 0xA3D4, 0xA3D4 },
{ 0xA3D5, 0xA3D5, 0xA3D5 },
{ 0xA3D6, 0xA3D6, 0xA3D6 },
{ 0xA3D7, 0xA3D7, 0xA3D7 },
{ 0xA3D8, 0xA3D8, 0xA3D8 },
{ 0xA3D9, 0xA3D9, 0xA3D9 },
{ 0xA3DA, 0xA3DA, 0xA3DA },
{ 0xA3DB, 0xA3DB, 0xA3DB },
{ 0xA3DC, 0xA3DC, 0xA3DC },
{ 0xA3DD, 0xA3DD, 0xA3DD },
{ 0xA3DE, 0xA3DE, 0xA3DE },
{ 0xA3DF, 0xA3DF, 0xA3DF },
{ 0xA3E0, 0xA3E0, 0xA3E0 },
{ 0xA3E1, 0xA3E1, 0xA3E1 },
{ 0xA3E2, 0xA3E2, 0xA3E2 },
{ 0xA3E3, 0xA3E3, 0xA3E3 },
{ 0xA3E4, 0xA3E4, 0xA3E4 },
{ 0xA3E5, 0xA3E5, 0xA3E5 },
{ 0xA3E6, 0xA3E6, 0xA3E6 },
{ 0xA3E7, 0xA3E7, 0xA3E7 },
{ 0xA3E8, 0xA3E8, 0xA3E8 },
{ 0xA3E9, 0xA3E9, 0xA3E9 },
{ 0xA3EA, 0xA3EA, 0xA3EA },
{ 0xA3EB, 0xA3EB, 0xA3EB },
{ 0xA3EC, 0xA3EC, 0xA3EC },
{ 0xA3ED, 0xA3ED, 0xA3ED },
{ 0xA3EE, 0xA3EE, 0xA3EE },
{ 0xA3EF, 0xA3EF, 0xA3EF },
{ 0xA3F0, 0xA3F0, 0xA3F0 },
{ 0xA3F1, 0xA3F1, 0xA3F1 },
{ 0xA3F2, 0xA3F2, 0xA3F2 },
{ 0xA3F3, 0xA3F3, 0xA3F3 },
{ 0xA3F4, 0xA3F4, 0xA3F4 },
{ 0xA3F5, 0xA3F5, 0xA3F5 },
{ 0xA3F6, 0xA3F6, 0xA3F6 },
{ 0xA3F7, 0xA3F7, 0xA3F7 },
{ 0xA3F8, 0xA3F8, 0xA3F8 },
{ 0xA3F9, 0xA3F9, 0xA3F9 },
{ 0xA3FA, 0xA3FA, 0xA3FA },
{ 0xA3FB, 0xA3FB, 0xA3FB },
{ 0xA3FC, 0xA3FC, 0xA3FC },
{ 0xA3FD, 0xA3FD, 0xA3FD },
{ 0xA3FE, 0xA3FE, 0xA3FE },
{ 0xA3FF, 0xA3FF, 0xA3FF },
{ 0xA400, 0xA400, 0xA400 },
{ 0xA401, 0xA401, 0xA401 },
{ 0xA402, 0xA402, 0xA402 },
{ 0xA403, 0xA403, 0xA403 },
{ 0xA404, 0xA404, 0xA404 },
{ 0xA405, 0xA405, 0xA405 },
{ 0xA406, 0xA406, 0xA406 },
{ 0xA407, 0xA407, 0xA407 },
{ 0xA408, 0xA408, 0xA408 },
{ 0xA409, 0xA409, 0xA409 },
{ 0xA40A, 0xA40A, 0xA40A },
{ 0xA40B, 0xA40B, 0xA40B },
{ 0xA40C, 0xA40C, 0xA40C },
{ 0xA40D, 0xA40D, 0xA40D },
{ 0xA40E, 0xA40E, 0xA40E },
{ 0xA40F, 0xA40F, 0xA40F },
{ 0xA410, 0xA410, 0xA410 },
{ 0xA411, 0xA411, 0xA411 },
{ 0xA412, 0xA412, 0xA412 },
{ 0xA413, 0xA413, 0xA413 },
{ 0xA414, 0xA414, 0xA414 },
{ 0xA415, 0xA415, 0xA415 },
{ 0xA416, 0xA416, 0xA416 },
{ 0xA417, 0xA417, 0xA417 },
{ 0xA418, 0xA418, 0xA418 },
{ 0xA419, 0xA419, 0xA419 },
{ 0xA41A, 0xA41A, 0xA41A },
{ 0xA41B, 0xA41B, 0xA41B },
{ 0xA41C, 0xA41C, 0xA41C },
{ 0xA41D, 0xA41D, 0xA41D },
{ 0xA41E, 0xA41E, 0xA41E },
{ 0xA41F, 0xA41F, 0xA41F },
{ 0xA420, 0xA420, 0xA420 },
{ 0xA421, 0xA421, 0xA421 },
{ 0xA422, 0xA422, 0xA422 },
{ 0xA423, 0xA423, 0xA423 },
{ 0xA424, 0xA424, 0xA424 },
{ 0xA425, 0xA425, 0xA425 },
{ 0xA426, 0xA426, 0xA426 },
{ 0xA427, 0xA427, 0xA427 },
{ 0xA428, 0xA428, 0xA428 },
{ 0xA429, 0xA429, 0xA429 },
{ 0xA42A, 0xA42A, 0xA42A },
{ 0xA42B, 0xA42B, 0xA42B },
{ 0xA42C, 0xA42C, 0xA42C },
{ 0xA42D, 0xA42D, 0xA42D },
{ 0xA42E, 0xA42E, 0xA42E },
{ 0xA42F, 0xA42F, 0xA42F },
{ 0xA430, 0xA430, 0xA430 },
{ 0xA431, 0xA431, 0xA431 },
{ 0xA432, 0xA432, 0xA432 },
{ 0xA433, 0xA433, 0xA433 },
{ 0xA434, 0xA434, 0xA434 },
{ 0xA435, 0xA435, 0xA435 },
{ 0xA436, 0xA436, 0xA436 },
{ 0xA437, 0xA437, 0xA437 },
{ 0xA438, 0xA438, 0xA438 },
{ 0xA439, 0xA439, 0xA439 },
{ 0xA43A, 0xA43A, 0xA43A },
{ 0xA43B, 0xA43B, 0xA43B },
{ 0xA43C, 0xA43C, 0xA43C },
{ 0xA43D, 0xA43D, 0xA43D },
{ 0xA43E, 0xA43E, 0xA43E },
{ 0xA43F, 0xA43F, 0xA43F },
{ 0xA440, 0xA440, 0xA440 },
{ 0xA441, 0xA441, 0xA441 },
{ 0xA442, 0xA442, 0xA442 },
{ 0xA443, 0xA443, 0xA443 },
{ 0xA444, 0xA444, 0xA444 },
{ 0xA445, 0xA445, 0xA445 },
{ 0xA446, 0xA446, 0xA446 },
{ 0xA447, 0xA447, 0xA447 },
{ 0xA448, 0xA448, 0xA448 },
{ 0xA449, 0xA449, 0xA449 },
{ 0xA44A, 0xA44A, 0xA44A },
{ 0xA44B, 0xA44B, 0xA44B },
{ 0xA44C, 0xA44C, 0xA44C },
{ 0xA44D, 0xA44D, 0xA44D },
{ 0xA44E, 0xA44E, 0xA44E },
{ 0xA44F, 0xA44F, 0xA44F },
{ 0xA450, 0xA450, 0xA450 },
{ 0xA451, 0xA451, 0xA451 },
{ 0xA452, 0xA452, 0xA452 },
{ 0xA453, 0xA453, 0xA453 },
{ 0xA454, 0xA454, 0xA454 },
{ 0xA455, 0xA455, 0xA455 },
{ 0xA456, 0xA456, 0xA456 },
{ 0xA457, 0xA457, 0xA457 },
{ 0xA458, 0xA458, 0xA458 },
{ 0xA459, 0xA459, 0xA459 },
{ 0xA45A, 0xA45A, 0xA45A },
{ 0xA45B, 0xA45B, 0xA45B },
{ 0xA45C, 0xA45C, 0xA45C },
{ 0xA45D, 0xA45D, 0xA45D },
{ 0xA45E, 0xA45E, 0xA45E },
{ 0xA45F, 0xA45F, 0xA45F },
{ 0xA460, 0xA460, 0xA460 },
{ 0xA461, 0xA461, 0xA461 },
{ 0xA462, 0xA462, 0xA462 },
{ 0xA463, 0xA463, 0xA463 },
{ 0xA464, 0xA464, 0xA464 },
{ 0xA465, 0xA465, 0xA465 },
{ 0xA466, 0xA466, 0xA466 },
{ 0xA467, 0xA467, 0xA467 },
{ 0xA468, 0xA468, 0xA468 },
{ 0xA469, 0xA469, 0xA469 },
{ 0xA46A, 0xA46A, 0xA46A },
{ 0xA46B, 0xA46B, 0xA46B },
{ 0xA46C, 0xA46C, 0xA46C },
{ 0xA46D, 0xA46D, 0xA46D },
{ 0xA46E, 0xA46E, 0xA46E },
{ 0xA46F, 0xA46F, 0xA46F },
{ 0xA470, 0xA470, 0xA470 },
{ 0xA471, 0xA471, 0xA471 },
{ 0xA472, 0xA472, 0xA472 },
{ 0xA473, 0xA473, 0xA473 },
{ 0xA474, 0xA474, 0xA474 },
{ 0xA475, 0xA475, 0xA475 },
{ 0xA476, 0xA476, 0xA476 },
{ 0xA477, 0xA477, 0xA477 },
{ 0xA478, 0xA478, 0xA478 },
{ 0xA479, 0xA479, 0xA479 },
{ 0xA47A, 0xA47A, 0xA47A },
{ 0xA47B, 0xA47B, 0xA47B },
{ 0xA47C, 0xA47C, 0xA47C },
{ 0xA47D, 0xA47D, 0xA47D },
{ 0xA47E, 0xA47E, 0xA47E },
{ 0xA47F, 0xA47F, 0xA47F },
{ 0xA480, 0xA480, 0xA480 },
{ 0xA481, 0xA481, 0xA481 },
{ 0xA482, 0xA482, 0xA482 },
{ 0xA483, 0xA483, 0xA483 },
{ 0xA484, 0xA484, 0xA484 },
{ 0xA485, 0xA485, 0xA485 },
{ 0xA486, 0xA486, 0xA486 },
{ 0xA487, 0xA487, 0xA487 },
{ 0xA488, 0xA488, 0xA488 },
{ 0xA489, 0xA489, 0xA489 },
{ 0xA48A, 0xA48A, 0xA48A },
{ 0xA48B, 0xA48B, 0xA48B },
{ 0xA48C, 0xA48C, 0xA48C },
{ 0xA800, 0xA800, 0xA800 },
{ 0xA801, 0xA801, 0xA801 },
{ 0xA803, 0xA803, 0xA803 },
{ 0xA804, 0xA804, 0xA804 },
{ 0xA805, 0xA805, 0xA805 },
{ 0xA806, 0xA806, 0xA806 },
{ 0xA807, 0xA807, 0xA807 },
{ 0xA808, 0xA808, 0xA808 },
{ 0xA809, 0xA809, 0xA809 },
{ 0xA80A, 0xA80A, 0xA80A },
{ 0xA80B, 0xA80B, 0xA80B },
{ 0xA80C, 0xA80C, 0xA80C },
{ 0xA80D, 0xA80D, 0xA80D },
{ 0xA80E, 0xA80E, 0xA80E },
{ 0xA80F, 0xA80F, 0xA80F },
{ 0xA810, 0xA810, 0xA810 },
{ 0xA811, 0xA811, 0xA811 },
{ 0xA812, 0xA812, 0xA812 },
{ 0xA813, 0xA813, 0xA813 },
{ 0xA814, 0xA814, 0xA814 },
{ 0xA815, 0xA815, 0xA815 },
{ 0xA816, 0xA816, 0xA816 },
{ 0xA817, 0xA817, 0xA817 },
{ 0xA818, 0xA818, 0xA818 },
{ 0xA819, 0xA819, 0xA819 },
{ 0xA81A, 0xA81A, 0xA81A },
{ 0xA81B, 0xA81B, 0xA81B },
{ 0xA81C, 0xA81C, 0xA81C },
{ 0xA81D, 0xA81D, 0xA81D },
{ 0xA81E, 0xA81E, 0xA81E },
{ 0xA81F, 0xA81F, 0xA81F },
{ 0xA820, 0xA820, 0xA820 },
{ 0xA821, 0xA821, 0xA821 },
{ 0xA822, 0xA822, 0xA822 },
{ 0xA825, 0xA825, 0xA825 },
{ 0xA826, 0xA826, 0xA826 },
{ 0xAC00, 0xAC00, 0xAC00 },
{ 0xD7A3, 0xD7A3, 0xD7A3 },
{ 0xF900, 0xF900, 0xF900 },
{ 0xF901, 0xF901, 0xF901 },
{ 0xF902, 0xF902, 0xF902 },
{ 0xF903, 0xF903, 0xF903 },
{ 0xF904, 0xF904, 0xF904 },
{ 0xF905, 0xF905, 0xF905 },
{ 0xF906, 0xF906, 0xF906 },
{ 0xF907, 0xF907, 0xF907 },
{ 0xF908, 0xF908, 0xF908 },
{ 0xF909, 0xF909, 0xF909 },
{ 0xF90A, 0xF90A, 0xF90A },
{ 0xF90B, 0xF90B, 0xF90B },
{ 0xF90C, 0xF90C, 0xF90C },
{ 0xF90D, 0xF90D, 0xF90D },
{ 0xF90E, 0xF90E, 0xF90E },
{ 0xF90F, 0xF90F, 0xF90F },
{ 0xF910, 0xF910, 0xF910 },
{ 0xF911, 0xF911, 0xF911 },
{ 0xF912, 0xF912, 0xF912 },
{ 0xF913, 0xF913, 0xF913 },
{ 0xF914, 0xF914, 0xF914 },
{ 0xF915, 0xF915, 0xF915 },
{ 0xF916, 0xF916, 0xF916 },
{ 0xF917, 0xF917, 0xF917 },
{ 0xF918, 0xF918, 0xF918 },
{ 0xF919, 0xF919, 0xF919 },
{ 0xF91A, 0xF91A, 0xF91A },
{ 0xF91B, 0xF91B, 0xF91B },
{ 0xF91C, 0xF91C, 0xF91C },
{ 0xF91D, 0xF91D, 0xF91D },
{ 0xF91E, 0xF91E, 0xF91E },
{ 0xF91F, 0xF91F, 0xF91F },
{ 0xF920, 0xF920, 0xF920 },
{ 0xF921, 0xF921, 0xF921 },
{ 0xF922, 0xF922, 0xF922 },
{ 0xF923, 0xF923, 0xF923 },
{ 0xF924, 0xF924, 0xF924 },
{ 0xF925, 0xF925, 0xF925 },
{ 0xF926, 0xF926, 0xF926 },
{ 0xF927, 0xF927, 0xF927 },
{ 0xF928, 0xF928, 0xF928 },
{ 0xF929, 0xF929, 0xF929 },
{ 0xF92A, 0xF92A, 0xF92A },
{ 0xF92B, 0xF92B, 0xF92B },
{ 0xF92C, 0xF92C, 0xF92C },
{ 0xF92D, 0xF92D, 0xF92D },
{ 0xF92E, 0xF92E, 0xF92E },
{ 0xF92F, 0xF92F, 0xF92F },
{ 0xF930, 0xF930, 0xF930 },
{ 0xF931, 0xF931, 0xF931 },
{ 0xF932, 0xF932, 0xF932 },
{ 0xF933, 0xF933, 0xF933 },
{ 0xF934, 0xF934, 0xF934 },
{ 0xF935, 0xF935, 0xF935 },
{ 0xF936, 0xF936, 0xF936 },
{ 0xF937, 0xF937, 0xF937 },
{ 0xF938, 0xF938, 0xF938 },
{ 0xF939, 0xF939, 0xF939 },
{ 0xF93A, 0xF93A, 0xF93A },
{ 0xF93B, 0xF93B, 0xF93B },
{ 0xF93C, 0xF93C, 0xF93C },
{ 0xF93D, 0xF93D, 0xF93D },
{ 0xF93E, 0xF93E, 0xF93E },
{ 0xF93F, 0xF93F, 0xF93F },
{ 0xF940, 0xF940, 0xF940 },
{ 0xF941, 0xF941, 0xF941 },
{ 0xF942, 0xF942, 0xF942 },
{ 0xF943, 0xF943, 0xF943 },
{ 0xF944, 0xF944, 0xF944 },
{ 0xF945, 0xF945, 0xF945 },
{ 0xF946, 0xF946, 0xF946 },
{ 0xF947, 0xF947, 0xF947 },
{ 0xF948, 0xF948, 0xF948 },
{ 0xF949, 0xF949, 0xF949 },
{ 0xF94A, 0xF94A, 0xF94A },
{ 0xF94B, 0xF94B, 0xF94B },
{ 0xF94C, 0xF94C, 0xF94C },
{ 0xF94D, 0xF94D, 0xF94D },
{ 0xF94E, 0xF94E, 0xF94E },
{ 0xF94F, 0xF94F, 0xF94F },
{ 0xF950, 0xF950, 0xF950 },
{ 0xF951, 0xF951, 0xF951 },
{ 0xF952, 0xF952, 0xF952 },
{ 0xF953, 0xF953, 0xF953 },
{ 0xF954, 0xF954, 0xF954 },
{ 0xF955, 0xF955, 0xF955 },
{ 0xF956, 0xF956, 0xF956 },
{ 0xF957, 0xF957, 0xF957 },
{ 0xF958, 0xF958, 0xF958 },
{ 0xF959, 0xF959, 0xF959 },
{ 0xF95A, 0xF95A, 0xF95A },
{ 0xF95B, 0xF95B, 0xF95B },
{ 0xF95C, 0xF95C, 0xF95C },
{ 0xF95D, 0xF95D, 0xF95D },
{ 0xF95E, 0xF95E, 0xF95E },
{ 0xF95F, 0xF95F, 0xF95F },
{ 0xF960, 0xF960, 0xF960 },
{ 0xF961, 0xF961, 0xF961 },
{ 0xF962, 0xF962, 0xF962 },
{ 0xF963, 0xF963, 0xF963 },
{ 0xF964, 0xF964, 0xF964 },
{ 0xF965, 0xF965, 0xF965 },
{ 0xF966, 0xF966, 0xF966 },
{ 0xF967, 0xF967, 0xF967 },
{ 0xF968, 0xF968, 0xF968 },
{ 0xF969, 0xF969, 0xF969 },
{ 0xF96A, 0xF96A, 0xF96A },
{ 0xF96B, 0xF96B, 0xF96B },
{ 0xF96C, 0xF96C, 0xF96C },
{ 0xF96D, 0xF96D, 0xF96D },
{ 0xF96E, 0xF96E, 0xF96E },
{ 0xF96F, 0xF96F, 0xF96F },
{ 0xF970, 0xF970, 0xF970 },
{ 0xF971, 0xF971, 0xF971 },
{ 0xF972, 0xF972, 0xF972 },
{ 0xF973, 0xF973, 0xF973 },
{ 0xF974, 0xF974, 0xF974 },
{ 0xF975, 0xF975, 0xF975 },
{ 0xF976, 0xF976, 0xF976 },
{ 0xF977, 0xF977, 0xF977 },
{ 0xF978, 0xF978, 0xF978 },
{ 0xF979, 0xF979, 0xF979 },
{ 0xF97A, 0xF97A, 0xF97A },
{ 0xF97B, 0xF97B, 0xF97B },
{ 0xF97C, 0xF97C, 0xF97C },
{ 0xF97D, 0xF97D, 0xF97D },
{ 0xF97E, 0xF97E, 0xF97E },
{ 0xF97F, 0xF97F, 0xF97F },
{ 0xF980, 0xF980, 0xF980 },
{ 0xF981, 0xF981, 0xF981 },
{ 0xF982, 0xF982, 0xF982 },
{ 0xF983, 0xF983, 0xF983 },
{ 0xF984, 0xF984, 0xF984 },
{ 0xF985, 0xF985, 0xF985 },
{ 0xF986, 0xF986, 0xF986 },
{ 0xF987, 0xF987, 0xF987 },
{ 0xF988, 0xF988, 0xF988 },
{ 0xF989, 0xF989, 0xF989 },
{ 0xF98A, 0xF98A, 0xF98A },
{ 0xF98B, 0xF98B, 0xF98B },
{ 0xF98C, 0xF98C, 0xF98C },
{ 0xF98D, 0xF98D, 0xF98D },
{ 0xF98E, 0xF98E, 0xF98E },
{ 0xF98F, 0xF98F, 0xF98F },
{ 0xF990, 0xF990, 0xF990 },
{ 0xF991, 0xF991, 0xF991 },
{ 0xF992, 0xF992, 0xF992 },
{ 0xF993, 0xF993, 0xF993 },
{ 0xF994, 0xF994, 0xF994 },
{ 0xF995, 0xF995, 0xF995 },
{ 0xF996, 0xF996, 0xF996 },
{ 0xF997, 0xF997, 0xF997 },
{ 0xF998, 0xF998, 0xF998 },
{ 0xF999, 0xF999, 0xF999 },
{ 0xF99A, 0xF99A, 0xF99A },
{ 0xF99B, 0xF99B, 0xF99B },
{ 0xF99C, 0xF99C, 0xF99C },
{ 0xF99D, 0xF99D, 0xF99D },
{ 0xF99E, 0xF99E, 0xF99E },
{ 0xF99F, 0xF99F, 0xF99F },
{ 0xF9A0, 0xF9A0, 0xF9A0 },
{ 0xF9A1, 0xF9A1, 0xF9A1 },
{ 0xF9A2, 0xF9A2, 0xF9A2 },
{ 0xF9A3, 0xF9A3, 0xF9A3 },
{ 0xF9A4, 0xF9A4, 0xF9A4 },
{ 0xF9A5, 0xF9A5, 0xF9A5 },
{ 0xF9A6, 0xF9A6, 0xF9A6 },
{ 0xF9A7, 0xF9A7, 0xF9A7 },
{ 0xF9A8, 0xF9A8, 0xF9A8 },
{ 0xF9A9, 0xF9A9, 0xF9A9 },
{ 0xF9AA, 0xF9AA, 0xF9AA },
{ 0xF9AB, 0xF9AB, 0xF9AB },
{ 0xF9AC, 0xF9AC, 0xF9AC },
{ 0xF9AD, 0xF9AD, 0xF9AD },
{ 0xF9AE, 0xF9AE, 0xF9AE },
{ 0xF9AF, 0xF9AF, 0xF9AF },
{ 0xF9B0, 0xF9B0, 0xF9B0 },
{ 0xF9B1, 0xF9B1, 0xF9B1 },
{ 0xF9B2, 0xF9B2, 0xF9B2 },
{ 0xF9B3, 0xF9B3, 0xF9B3 },
{ 0xF9B4, 0xF9B4, 0xF9B4 },
{ 0xF9B5, 0xF9B5, 0xF9B5 },
{ 0xF9B6, 0xF9B6, 0xF9B6 },
{ 0xF9B7, 0xF9B7, 0xF9B7 },
{ 0xF9B8, 0xF9B8, 0xF9B8 },
{ 0xF9B9, 0xF9B9, 0xF9B9 },
{ 0xF9BA, 0xF9BA, 0xF9BA },
{ 0xF9BB, 0xF9BB, 0xF9BB },
{ 0xF9BC, 0xF9BC, 0xF9BC },
{ 0xF9BD, 0xF9BD, 0xF9BD },
{ 0xF9BE, 0xF9BE, 0xF9BE },
{ 0xF9BF, 0xF9BF, 0xF9BF },
{ 0xF9C0, 0xF9C0, 0xF9C0 },
{ 0xF9C1, 0xF9C1, 0xF9C1 },
{ 0xF9C2, 0xF9C2, 0xF9C2 },
{ 0xF9C3, 0xF9C3, 0xF9C3 },
{ 0xF9C4, 0xF9C4, 0xF9C4 },
{ 0xF9C5, 0xF9C5, 0xF9C5 },
{ 0xF9C6, 0xF9C6, 0xF9C6 },
{ 0xF9C7, 0xF9C7, 0xF9C7 },
{ 0xF9C8, 0xF9C8, 0xF9C8 },
{ 0xF9C9, 0xF9C9, 0xF9C9 },
{ 0xF9CA, 0xF9CA, 0xF9CA },
{ 0xF9CB, 0xF9CB, 0xF9CB },
{ 0xF9CC, 0xF9CC, 0xF9CC },
{ 0xF9CD, 0xF9CD, 0xF9CD },
{ 0xF9CE, 0xF9CE, 0xF9CE },
{ 0xF9CF, 0xF9CF, 0xF9CF },
{ 0xF9D0, 0xF9D0, 0xF9D0 },
{ 0xF9D1, 0xF9D1, 0xF9D1 },
{ 0xF9D2, 0xF9D2, 0xF9D2 },
{ 0xF9D3, 0xF9D3, 0xF9D3 },
{ 0xF9D4, 0xF9D4, 0xF9D4 },
{ 0xF9D5, 0xF9D5, 0xF9D5 },
{ 0xF9D6, 0xF9D6, 0xF9D6 },
{ 0xF9D7, 0xF9D7, 0xF9D7 },
{ 0xF9D8, 0xF9D8, 0xF9D8 },
{ 0xF9D9, 0xF9D9, 0xF9D9 },
{ 0xF9DA, 0xF9DA, 0xF9DA },
{ 0xF9DB, 0xF9DB, 0xF9DB },
{ 0xF9DC, 0xF9DC, 0xF9DC },
{ 0xF9DD, 0xF9DD, 0xF9DD },
{ 0xF9DE, 0xF9DE, 0xF9DE },
{ 0xF9DF, 0xF9DF, 0xF9DF },
{ 0xF9E0, 0xF9E0, 0xF9E0 },
{ 0xF9E1, 0xF9E1, 0xF9E1 },
{ 0xF9E2, 0xF9E2, 0xF9E2 },
{ 0xF9E3, 0xF9E3, 0xF9E3 },
{ 0xF9E4, 0xF9E4, 0xF9E4 },
{ 0xF9E5, 0xF9E5, 0xF9E5 },
{ 0xF9E6, 0xF9E6, 0xF9E6 },
{ 0xF9E7, 0xF9E7, 0xF9E7 },
{ 0xF9E8, 0xF9E8, 0xF9E8 },
{ 0xF9E9, 0xF9E9, 0xF9E9 },
{ 0xF9EA, 0xF9EA, 0xF9EA },
{ 0xF9EB, 0xF9EB, 0xF9EB },
{ 0xF9EC, 0xF9EC, 0xF9EC },
{ 0xF9ED, 0xF9ED, 0xF9ED },
{ 0xF9EE, 0xF9EE, 0xF9EE },
{ 0xF9EF, 0xF9EF, 0xF9EF },
{ 0xF9F0, 0xF9F0, 0xF9F0 },
{ 0xF9F1, 0xF9F1, 0xF9F1 },
{ 0xF9F2, 0xF9F2, 0xF9F2 },
{ 0xF9F3, 0xF9F3, 0xF9F3 },
{ 0xF9F4, 0xF9F4, 0xF9F4 },
{ 0xF9F5, 0xF9F5, 0xF9F5 },
{ 0xF9F6, 0xF9F6, 0xF9F6 },
{ 0xF9F7, 0xF9F7, 0xF9F7 },
{ 0xF9F8, 0xF9F8, 0xF9F8 },
{ 0xF9F9, 0xF9F9, 0xF9F9 },
{ 0xF9FA, 0xF9FA, 0xF9FA },
{ 0xF9FB, 0xF9FB, 0xF9FB },
{ 0xF9FC, 0xF9FC, 0xF9FC },
{ 0xF9FD, 0xF9FD, 0xF9FD },
{ 0xF9FE, 0xF9FE, 0xF9FE },
{ 0xF9FF, 0xF9FF, 0xF9FF },
{ 0xFA00, 0xFA00, 0xFA00 },
{ 0xFA01, 0xFA01, 0xFA01 },
{ 0xFA02, 0xFA02, 0xFA02 },
{ 0xFA03, 0xFA03, 0xFA03 },
{ 0xFA04, 0xFA04, 0xFA04 },
{ 0xFA05, 0xFA05, 0xFA05 },
{ 0xFA06, 0xFA06, 0xFA06 },
{ 0xFA07, 0xFA07, 0xFA07 },
{ 0xFA08, 0xFA08, 0xFA08 },
{ 0xFA09, 0xFA09, 0xFA09 },
{ 0xFA0A, 0xFA0A, 0xFA0A },
{ 0xFA0B, 0xFA0B, 0xFA0B },
{ 0xFA0C, 0xFA0C, 0xFA0C },
{ 0xFA0D, 0xFA0D, 0xFA0D },
{ 0xFA0E, 0xFA0E, 0xFA0E },
{ 0xFA0F, 0xFA0F, 0xFA0F },
{ 0xFA10, 0xFA10, 0xFA10 },
{ 0xFA11, 0xFA11, 0xFA11 },
{ 0xFA12, 0xFA12, 0xFA12 },
{ 0xFA13, 0xFA13, 0xFA13 },
{ 0xFA14, 0xFA14, 0xFA14 },
{ 0xFA15, 0xFA15, 0xFA15 },
{ 0xFA16, 0xFA16, 0xFA16 },
{ 0xFA17, 0xFA17, 0xFA17 },
{ 0xFA18, 0xFA18, 0xFA18 },
{ 0xFA19, 0xFA19, 0xFA19 },
{ 0xFA1A, 0xFA1A, 0xFA1A },
{ 0xFA1B, 0xFA1B, 0xFA1B },
{ 0xFA1C, 0xFA1C, 0xFA1C },
{ 0xFA1D, 0xFA1D, 0xFA1D },
{ 0xFA1E, 0xFA1E, 0xFA1E },
{ 0xFA1F, 0xFA1F, 0xFA1F },
{ 0xFA20, 0xFA20, 0xFA20 },
{ 0xFA21, 0xFA21, 0xFA21 },
{ 0xFA22, 0xFA22, 0xFA22 },
{ 0xFA23, 0xFA23, 0xFA23 },
{ 0xFA24, 0xFA24, 0xFA24 },
{ 0xFA25, 0xFA25, 0xFA25 },
{ 0xFA26, 0xFA26, 0xFA26 },
{ 0xFA27, 0xFA27, 0xFA27 },
{ 0xFA28, 0xFA28, 0xFA28 },
{ 0xFA29, 0xFA29, 0xFA29 },
{ 0xFA2A, 0xFA2A, 0xFA2A },
{ 0xFA2B, 0xFA2B, 0xFA2B },
{ 0xFA2C, 0xFA2C, 0xFA2C },
{ 0xFA2D, 0xFA2D, 0xFA2D },
{ 0xFA30, 0xFA30, 0xFA30 },
{ 0xFA31, 0xFA31, 0xFA31 },
{ 0xFA32, 0xFA32, 0xFA32 },
{ 0xFA33, 0xFA33, 0xFA33 },
{ 0xFA34, 0xFA34, 0xFA34 },
{ 0xFA35, 0xFA35, 0xFA35 },
{ 0xFA36, 0xFA36, 0xFA36 },
{ 0xFA37, 0xFA37, 0xFA37 },
{ 0xFA38, 0xFA38, 0xFA38 },
{ 0xFA39, 0xFA39, 0xFA39 },
{ 0xFA3A, 0xFA3A, 0xFA3A },
{ 0xFA3B, 0xFA3B, 0xFA3B },
{ 0xFA3C, 0xFA3C, 0xFA3C },
{ 0xFA3D, 0xFA3D, 0xFA3D },
{ 0xFA3E, 0xFA3E, 0xFA3E },
{ 0xFA3F, 0xFA3F, 0xFA3F },
{ 0xFA40, 0xFA40, 0xFA40 },
{ 0xFA41, 0xFA41, 0xFA41 },
{ 0xFA42, 0xFA42, 0xFA42 },
{ 0xFA43, 0xFA43, 0xFA43 },
{ 0xFA44, 0xFA44, 0xFA44 },
{ 0xFA45, 0xFA45, 0xFA45 },
{ 0xFA46, 0xFA46, 0xFA46 },
{ 0xFA47, 0xFA47, 0xFA47 },
{ 0xFA48, 0xFA48, 0xFA48 },
{ 0xFA49, 0xFA49, 0xFA49 },
{ 0xFA4A, 0xFA4A, 0xFA4A },
{ 0xFA4B, 0xFA4B, 0xFA4B },
{ 0xFA4C, 0xFA4C, 0xFA4C },
{ 0xFA4D, 0xFA4D, 0xFA4D },
{ 0xFA4E, 0xFA4E, 0xFA4E },
{ 0xFA4F, 0xFA4F, 0xFA4F },
{ 0xFA50, 0xFA50, 0xFA50 },
{ 0xFA51, 0xFA51, 0xFA51 },
{ 0xFA52, 0xFA52, 0xFA52 },
{ 0xFA53, 0xFA53, 0xFA53 },
{ 0xFA54, 0xFA54, 0xFA54 },
{ 0xFA55, 0xFA55, 0xFA55 },
{ 0xFA56, 0xFA56, 0xFA56 },
{ 0xFA57, 0xFA57, 0xFA57 },
{ 0xFA58, 0xFA58, 0xFA58 },
{ 0xFA59, 0xFA59, 0xFA59 },
{ 0xFA5A, 0xFA5A, 0xFA5A },
{ 0xFA5B, 0xFA5B, 0xFA5B },
{ 0xFA5C, 0xFA5C, 0xFA5C },
{ 0xFA5D, 0xFA5D, 0xFA5D },
{ 0xFA5E, 0xFA5E, 0xFA5E },
{ 0xFA5F, 0xFA5F, 0xFA5F },
{ 0xFA60, 0xFA60, 0xFA60 },
{ 0xFA61, 0xFA61, 0xFA61 },
{ 0xFA62, 0xFA62, 0xFA62 },
{ 0xFA63, 0xFA63, 0xFA63 },
{ 0xFA64, 0xFA64, 0xFA64 },
{ 0xFA65, 0xFA65, 0xFA65 },
{ 0xFA66, 0xFA66, 0xFA66 },
{ 0xFA67, 0xFA67, 0xFA67 },
{ 0xFA68, 0xFA68, 0xFA68 },
{ 0xFA69, 0xFA69, 0xFA69 },
{ 0xFA6A, 0xFA6A, 0xFA6A },
{ 0xFA70, 0xFA70, 0xFA70 },
{ 0xFA71, 0xFA71, 0xFA71 },
{ 0xFA72, 0xFA72, 0xFA72 },
{ 0xFA73, 0xFA73, 0xFA73 },
{ 0xFA74, 0xFA74, 0xFA74 },
{ 0xFA75, 0xFA75, 0xFA75 },
{ 0xFA76, 0xFA76, 0xFA76 },
{ 0xFA77, 0xFA77, 0xFA77 },
{ 0xFA78, 0xFA78, 0xFA78 },
{ 0xFA79, 0xFA79, 0xFA79 },
{ 0xFA7A, 0xFA7A, 0xFA7A },
{ 0xFA7B, 0xFA7B, 0xFA7B },
{ 0xFA7C, 0xFA7C, 0xFA7C },
{ 0xFA7D, 0xFA7D, 0xFA7D },
{ 0xFA7E, 0xFA7E, 0xFA7E },
{ 0xFA7F, 0xFA7F, 0xFA7F },
{ 0xFA80, 0xFA80, 0xFA80 },
{ 0xFA81, 0xFA81, 0xFA81 },
{ 0xFA82, 0xFA82, 0xFA82 },
{ 0xFA83, 0xFA83, 0xFA83 },
{ 0xFA84, 0xFA84, 0xFA84 },
{ 0xFA85, 0xFA85, 0xFA85 },
{ 0xFA86, 0xFA86, 0xFA86 },
{ 0xFA87, 0xFA87, 0xFA87 },
{ 0xFA88, 0xFA88, 0xFA88 },
{ 0xFA89, 0xFA89, 0xFA89 },
{ 0xFA8A, 0xFA8A, 0xFA8A },
{ 0xFA8B, 0xFA8B, 0xFA8B },
{ 0xFA8C, 0xFA8C, 0xFA8C },
{ 0xFA8D, 0xFA8D, 0xFA8D },
{ 0xFA8E, 0xFA8E, 0xFA8E },
{ 0xFA8F, 0xFA8F, 0xFA8F },
{ 0xFA90, 0xFA90, 0xFA90 },
{ 0xFA91, 0xFA91, 0xFA91 },
{ 0xFA92, 0xFA92, 0xFA92 },
{ 0xFA93, 0xFA93, 0xFA93 },
{ 0xFA94, 0xFA94, 0xFA94 },
{ 0xFA95, 0xFA95, 0xFA95 },
{ 0xFA96, 0xFA96, 0xFA96 },
{ 0xFA97, 0xFA97, 0xFA97 },
{ 0xFA98, 0xFA98, 0xFA98 },
{ 0xFA99, 0xFA99, 0xFA99 },
{ 0xFA9A, 0xFA9A, 0xFA9A },
{ 0xFA9B, 0xFA9B, 0xFA9B },
{ 0xFA9C, 0xFA9C, 0xFA9C },
{ 0xFA9D, 0xFA9D, 0xFA9D },
{ 0xFA9E, 0xFA9E, 0xFA9E },
{ 0xFA9F, 0xFA9F, 0xFA9F },
{ 0xFAA0, 0xFAA0, 0xFAA0 },
{ 0xFAA1, 0xFAA1, 0xFAA1 },
{ 0xFAA2, 0xFAA2, 0xFAA2 },
{ 0xFAA3, 0xFAA3, 0xFAA3 },
{ 0xFAA4, 0xFAA4, 0xFAA4 },
{ 0xFAA5, 0xFAA5, 0xFAA5 },
{ 0xFAA6, 0xFAA6, 0xFAA6 },
{ 0xFAA7, 0xFAA7, 0xFAA7 },
{ 0xFAA8, 0xFAA8, 0xFAA8 },
{ 0xFAA9, 0xFAA9, 0xFAA9 },
{ 0xFAAA, 0xFAAA, 0xFAAA },
{ 0xFAAB, 0xFAAB, 0xFAAB },
{ 0xFAAC, 0xFAAC, 0xFAAC },
{ 0xFAAD, 0xFAAD, 0xFAAD },
{ 0xFAAE, 0xFAAE, 0xFAAE },
{ 0xFAAF, 0xFAAF, 0xFAAF },
{ 0xFAB0, 0xFAB0, 0xFAB0 },
{ 0xFAB1, 0xFAB1, 0xFAB1 },
{ 0xFAB2, 0xFAB2, 0xFAB2 },
{ 0xFAB3, 0xFAB3, 0xFAB3 },
{ 0xFAB4, 0xFAB4, 0xFAB4 },
{ 0xFAB5, 0xFAB5, 0xFAB5 },
{ 0xFAB6, 0xFAB6, 0xFAB6 },
{ 0xFAB7, 0xFAB7, 0xFAB7 },
{ 0xFAB8, 0xFAB8, 0xFAB8 },
{ 0xFAB9, 0xFAB9, 0xFAB9 },
{ 0xFABA, 0xFABA, 0xFABA },
{ 0xFABB, 0xFABB, 0xFABB },
{ 0xFABC, 0xFABC, 0xFABC },
{ 0xFABD, 0xFABD, 0xFABD },
{ 0xFABE, 0xFABE, 0xFABE },
{ 0xFABF, 0xFABF, 0xFABF },
{ 0xFAC0, 0xFAC0, 0xFAC0 },
{ 0xFAC1, 0xFAC1, 0xFAC1 },
{ 0xFAC2, 0xFAC2, 0xFAC2 },
{ 0xFAC3, 0xFAC3, 0xFAC3 },
{ 0xFAC4, 0xFAC4, 0xFAC4 },
{ 0xFAC5, 0xFAC5, 0xFAC5 },
{ 0xFAC6, 0xFAC6, 0xFAC6 },
{ 0xFAC7, 0xFAC7, 0xFAC7 },
{ 0xFAC8, 0xFAC8, 0xFAC8 },
{ 0xFAC9, 0xFAC9, 0xFAC9 },
{ 0xFACA, 0xFACA, 0xFACA },
{ 0xFACB, 0xFACB, 0xFACB },
{ 0xFACC, 0xFACC, 0xFACC },
{ 0xFACD, 0xFACD, 0xFACD },
{ 0xFACE, 0xFACE, 0xFACE },
{ 0xFACF, 0xFACF, 0xFACF },
{ 0xFAD0, 0xFAD0, 0xFAD0 },
{ 0xFAD1, 0xFAD1, 0xFAD1 },
{ 0xFAD2, 0xFAD2, 0xFAD2 },
{ 0xFAD3, 0xFAD3, 0xFAD3 },
{ 0xFAD4, 0xFAD4, 0xFAD4 },
{ 0xFAD5, 0xFAD5, 0xFAD5 },
{ 0xFAD6, 0xFAD6, 0xFAD6 },
{ 0xFAD7, 0xFAD7, 0xFAD7 },
{ 0xFAD8, 0xFAD8, 0xFAD8 },
{ 0xFAD9, 0xFAD9, 0xFAD9 },
{ 0xFB00, 0xFB00, 0xFB00 },
{ 0xFB01, 0xFB01, 0xFB01 },
{ 0xFB02, 0xFB02, 0xFB02 },
{ 0xFB03, 0xFB03, 0xFB03 },
{ 0xFB04, 0xFB04, 0xFB04 },
{ 0xFB05, 0xFB05, 0xFB05 },
{ 0xFB06, 0xFB06, 0xFB06 },
{ 0xFB13, 0xFB13, 0xFB13 },
{ 0xFB14, 0xFB14, 0xFB14 },
{ 0xFB15, 0xFB15, 0xFB15 },
{ 0xFB16, 0xFB16, 0xFB16 },
{ 0xFB17, 0xFB17, 0xFB17 },
{ 0xFB1D, 0xFB1D, 0xFB1D },
{ 0xFB1E, 0xFB1E, 0xFB1E },
{ 0xFB1F, 0xFB1F, 0xFB1F },
{ 0xFB20, 0xFB20, 0xFB20 },
{ 0xFB21, 0xFB21, 0xFB21 },
{ 0xFB22, 0xFB22, 0xFB22 },
{ 0xFB23, 0xFB23, 0xFB23 },
{ 0xFB24, 0xFB24, 0xFB24 },
{ 0xFB25, 0xFB25, 0xFB25 },
{ 0xFB26, 0xFB26, 0xFB26 },
{ 0xFB27, 0xFB27, 0xFB27 },
{ 0xFB28, 0xFB28, 0xFB28 },
{ 0xFB2A, 0xFB2A, 0xFB2A },
{ 0xFB2B, 0xFB2B, 0xFB2B },
{ 0xFB2C, 0xFB2C, 0xFB2C },
{ 0xFB2D, 0xFB2D, 0xFB2D },
{ 0xFB2E, 0xFB2E, 0xFB2E },
{ 0xFB2F, 0xFB2F, 0xFB2F },
{ 0xFB30, 0xFB30, 0xFB30 },
{ 0xFB31, 0xFB31, 0xFB31 },
{ 0xFB32, 0xFB32, 0xFB32 },
{ 0xFB33, 0xFB33, 0xFB33 },
{ 0xFB34, 0xFB34, 0xFB34 },
{ 0xFB35, 0xFB35, 0xFB35 },
{ 0xFB36, 0xFB36, 0xFB36 },
{ 0xFB38, 0xFB38, 0xFB38 },
{ 0xFB39, 0xFB39, 0xFB39 },
{ 0xFB3A, 0xFB3A, 0xFB3A },
{ 0xFB3B, 0xFB3B, 0xFB3B },
{ 0xFB3C, 0xFB3C, 0xFB3C },
{ 0xFB3E, 0xFB3E, 0xFB3E },
{ 0xFB40, 0xFB40, 0xFB40 },
{ 0xFB41, 0xFB41, 0xFB41 },
{ 0xFB43, 0xFB43, 0xFB43 },
{ 0xFB44, 0xFB44, 0xFB44 },
{ 0xFB46, 0xFB46, 0xFB46 },
{ 0xFB47, 0xFB47, 0xFB47 },
{ 0xFB48, 0xFB48, 0xFB48 },
{ 0xFB49, 0xFB49, 0xFB49 },
{ 0xFB4A, 0xFB4A, 0xFB4A },
{ 0xFB4B, 0xFB4B, 0xFB4B },
{ 0xFB4C, 0xFB4C, 0xFB4C },
{ 0xFB4D, 0xFB4D, 0xFB4D },
{ 0xFB4E, 0xFB4E, 0xFB4E },
{ 0xFB4F, 0xFB4F, 0xFB4F },
{ 0xFB50, 0xFB50, 0xFB50 },
{ 0xFB51, 0xFB51, 0xFB51 },
{ 0xFB52, 0xFB52, 0xFB52 },
{ 0xFB53, 0xFB53, 0xFB53 },
{ 0xFB54, 0xFB54, 0xFB54 },
{ 0xFB55, 0xFB55, 0xFB55 },
{ 0xFB56, 0xFB56, 0xFB56 },
{ 0xFB57, 0xFB57, 0xFB57 },
{ 0xFB58, 0xFB58, 0xFB58 },
{ 0xFB59, 0xFB59, 0xFB59 },
{ 0xFB5A, 0xFB5A, 0xFB5A },
{ 0xFB5B, 0xFB5B, 0xFB5B },
{ 0xFB5C, 0xFB5C, 0xFB5C },
{ 0xFB5D, 0xFB5D, 0xFB5D },
{ 0xFB5E, 0xFB5E, 0xFB5E },
{ 0xFB5F, 0xFB5F, 0xFB5F },
{ 0xFB60, 0xFB60, 0xFB60 },
{ 0xFB61, 0xFB61, 0xFB61 },
{ 0xFB62, 0xFB62, 0xFB62 },
{ 0xFB63, 0xFB63, 0xFB63 },
{ 0xFB64, 0xFB64, 0xFB64 },
{ 0xFB65, 0xFB65, 0xFB65 },
{ 0xFB66, 0xFB66, 0xFB66 },
{ 0xFB67, 0xFB67, 0xFB67 },
{ 0xFB68, 0xFB68, 0xFB68 },
{ 0xFB69, 0xFB69, 0xFB69 },
{ 0xFB6A, 0xFB6A, 0xFB6A },
{ 0xFB6B, 0xFB6B, 0xFB6B },
{ 0xFB6C, 0xFB6C, 0xFB6C },
{ 0xFB6D, 0xFB6D, 0xFB6D },
{ 0xFB6E, 0xFB6E, 0xFB6E },
{ 0xFB6F, 0xFB6F, 0xFB6F },
{ 0xFB70, 0xFB70, 0xFB70 },
{ 0xFB71, 0xFB71, 0xFB71 },
{ 0xFB72, 0xFB72, 0xFB72 },
{ 0xFB73, 0xFB73, 0xFB73 },
{ 0xFB74, 0xFB74, 0xFB74 },
{ 0xFB75, 0xFB75, 0xFB75 },
{ 0xFB76, 0xFB76, 0xFB76 },
{ 0xFB77, 0xFB77, 0xFB77 },
{ 0xFB78, 0xFB78, 0xFB78 },
{ 0xFB79, 0xFB79, 0xFB79 },
{ 0xFB7A, 0xFB7A, 0xFB7A },
{ 0xFB7B, 0xFB7B, 0xFB7B },
{ 0xFB7C, 0xFB7C, 0xFB7C },
{ 0xFB7D, 0xFB7D, 0xFB7D },
{ 0xFB7E, 0xFB7E, 0xFB7E },
{ 0xFB7F, 0xFB7F, 0xFB7F },
{ 0xFB80, 0xFB80, 0xFB80 },
{ 0xFB81, 0xFB81, 0xFB81 },
{ 0xFB82, 0xFB82, 0xFB82 },
{ 0xFB83, 0xFB83, 0xFB83 },
{ 0xFB84, 0xFB84, 0xFB84 },
{ 0xFB85, 0xFB85, 0xFB85 },
{ 0xFB86, 0xFB86, 0xFB86 },
{ 0xFB87, 0xFB87, 0xFB87 },
{ 0xFB88, 0xFB88, 0xFB88 },
{ 0xFB89, 0xFB89, 0xFB89 },
{ 0xFB8A, 0xFB8A, 0xFB8A },
{ 0xFB8B, 0xFB8B, 0xFB8B },
{ 0xFB8C, 0xFB8C, 0xFB8C },
{ 0xFB8D, 0xFB8D, 0xFB8D },
{ 0xFB8E, 0xFB8E, 0xFB8E },
{ 0xFB8F, 0xFB8F, 0xFB8F },
{ 0xFB90, 0xFB90, 0xFB90 },
{ 0xFB91, 0xFB91, 0xFB91 },
{ 0xFB92, 0xFB92, 0xFB92 },
{ 0xFB93, 0xFB93, 0xFB93 },
{ 0xFB94, 0xFB94, 0xFB94 },
{ 0xFB95, 0xFB95, 0xFB95 },
{ 0xFB96, 0xFB96, 0xFB96 },
{ 0xFB97, 0xFB97, 0xFB97 },
{ 0xFB98, 0xFB98, 0xFB98 },
{ 0xFB99, 0xFB99, 0xFB99 },
{ 0xFB9A, 0xFB9A, 0xFB9A },
{ 0xFB9B, 0xFB9B, 0xFB9B },
{ 0xFB9C, 0xFB9C, 0xFB9C },
{ 0xFB9D, 0xFB9D, 0xFB9D },
{ 0xFB9E, 0xFB9E, 0xFB9E },
{ 0xFB9F, 0xFB9F, 0xFB9F },
{ 0xFBA0, 0xFBA0, 0xFBA0 },
{ 0xFBA1, 0xFBA1, 0xFBA1 },
{ 0xFBA2, 0xFBA2, 0xFBA2 },
{ 0xFBA3, 0xFBA3, 0xFBA3 },
{ 0xFBA4, 0xFBA4, 0xFBA4 },
{ 0xFBA5, 0xFBA5, 0xFBA5 },
{ 0xFBA6, 0xFBA6, 0xFBA6 },
{ 0xFBA7, 0xFBA7, 0xFBA7 },
{ 0xFBA8, 0xFBA8, 0xFBA8 },
{ 0xFBA9, 0xFBA9, 0xFBA9 },
{ 0xFBAA, 0xFBAA, 0xFBAA },
{ 0xFBAB, 0xFBAB, 0xFBAB },
{ 0xFBAC, 0xFBAC, 0xFBAC },
{ 0xFBAD, 0xFBAD, 0xFBAD },
{ 0xFBAE, 0xFBAE, 0xFBAE },
{ 0xFBAF, 0xFBAF, 0xFBAF },
{ 0xFBB0, 0xFBB0, 0xFBB0 },
{ 0xFBB1, 0xFBB1, 0xFBB1 },
{ 0xFBD3, 0xFBD3, 0xFBD3 },
{ 0xFBD4, 0xFBD4, 0xFBD4 },
{ 0xFBD5, 0xFBD5, 0xFBD5 },
{ 0xFBD6, 0xFBD6, 0xFBD6 },
{ 0xFBD7, 0xFBD7, 0xFBD7 },
{ 0xFBD8, 0xFBD8, 0xFBD8 },
{ 0xFBD9, 0xFBD9, 0xFBD9 },
{ 0xFBDA, 0xFBDA, 0xFBDA },
{ 0xFBDB, 0xFBDB, 0xFBDB },
{ 0xFBDC, 0xFBDC, 0xFBDC },
{ 0xFBDD, 0xFBDD, 0xFBDD },
{ 0xFBDE, 0xFBDE, 0xFBDE },
{ 0xFBDF, 0xFBDF, 0xFBDF },
{ 0xFBE0, 0xFBE0, 0xFBE0 },
{ 0xFBE1, 0xFBE1, 0xFBE1 },
{ 0xFBE2, 0xFBE2, 0xFBE2 },
{ 0xFBE3, 0xFBE3, 0xFBE3 },
{ 0xFBE4, 0xFBE4, 0xFBE4 },
{ 0xFBE5, 0xFBE5, 0xFBE5 },
{ 0xFBE6, 0xFBE6, 0xFBE6 },
{ 0xFBE7, 0xFBE7, 0xFBE7 },
{ 0xFBE8, 0xFBE8, 0xFBE8 },
{ 0xFBE9, 0xFBE9, 0xFBE9 },
{ 0xFBEA, 0xFBEA, 0xFBEA },
{ 0xFBEB, 0xFBEB, 0xFBEB },
{ 0xFBEC, 0xFBEC, 0xFBEC },
{ 0xFBED, 0xFBED, 0xFBED },
{ 0xFBEE, 0xFBEE, 0xFBEE },
{ 0xFBEF, 0xFBEF, 0xFBEF },
{ 0xFBF0, 0xFBF0, 0xFBF0 },
{ 0xFBF1, 0xFBF1, 0xFBF1 },
{ 0xFBF2, 0xFBF2, 0xFBF2 },
{ 0xFBF3, 0xFBF3, 0xFBF3 },
{ 0xFBF4, 0xFBF4, 0xFBF4 },
{ 0xFBF5, 0xFBF5, 0xFBF5 },
{ 0xFBF6, 0xFBF6, 0xFBF6 },
{ 0xFBF7, 0xFBF7, 0xFBF7 },
{ 0xFBF8, 0xFBF8, 0xFBF8 },
{ 0xFBF9, 0xFBF9, 0xFBF9 },
{ 0xFBFA, 0xFBFA, 0xFBFA },
{ 0xFBFB, 0xFBFB, 0xFBFB },
{ 0xFBFC, 0xFBFC, 0xFBFC },
{ 0xFBFD, 0xFBFD, 0xFBFD },
{ 0xFBFE, 0xFBFE, 0xFBFE },
{ 0xFBFF, 0xFBFF, 0xFBFF },
{ 0xFC00, 0xFC00, 0xFC00 },
{ 0xFC01, 0xFC01, 0xFC01 },
{ 0xFC02, 0xFC02, 0xFC02 },
{ 0xFC03, 0xFC03, 0xFC03 },
{ 0xFC04, 0xFC04, 0xFC04 },
{ 0xFC05, 0xFC05, 0xFC05 },
{ 0xFC06, 0xFC06, 0xFC06 },
{ 0xFC07, 0xFC07, 0xFC07 },
{ 0xFC08, 0xFC08, 0xFC08 },
{ 0xFC09, 0xFC09, 0xFC09 },
{ 0xFC0A, 0xFC0A, 0xFC0A },
{ 0xFC0B, 0xFC0B, 0xFC0B },
{ 0xFC0C, 0xFC0C, 0xFC0C },
{ 0xFC0D, 0xFC0D, 0xFC0D },
{ 0xFC0E, 0xFC0E, 0xFC0E },
{ 0xFC0F, 0xFC0F, 0xFC0F },
{ 0xFC10, 0xFC10, 0xFC10 },
{ 0xFC11, 0xFC11, 0xFC11 },
{ 0xFC12, 0xFC12, 0xFC12 },
{ 0xFC13, 0xFC13, 0xFC13 },
{ 0xFC14, 0xFC14, 0xFC14 },
{ 0xFC15, 0xFC15, 0xFC15 },
{ 0xFC16, 0xFC16, 0xFC16 },
{ 0xFC17, 0xFC17, 0xFC17 },
{ 0xFC18, 0xFC18, 0xFC18 },
{ 0xFC19, 0xFC19, 0xFC19 },
{ 0xFC1A, 0xFC1A, 0xFC1A },
{ 0xFC1B, 0xFC1B, 0xFC1B },
{ 0xFC1C, 0xFC1C, 0xFC1C },
{ 0xFC1D, 0xFC1D, 0xFC1D },
{ 0xFC1E, 0xFC1E, 0xFC1E },
{ 0xFC1F, 0xFC1F, 0xFC1F },
{ 0xFC20, 0xFC20, 0xFC20 },
{ 0xFC21, 0xFC21, 0xFC21 },
{ 0xFC22, 0xFC22, 0xFC22 },
{ 0xFC23, 0xFC23, 0xFC23 },
{ 0xFC24, 0xFC24, 0xFC24 },
{ 0xFC25, 0xFC25, 0xFC25 },
{ 0xFC26, 0xFC26, 0xFC26 },
{ 0xFC27, 0xFC27, 0xFC27 },
{ 0xFC28, 0xFC28, 0xFC28 },
{ 0xFC29, 0xFC29, 0xFC29 },
{ 0xFC2A, 0xFC2A, 0xFC2A },
{ 0xFC2B, 0xFC2B, 0xFC2B },
{ 0xFC2C, 0xFC2C, 0xFC2C },
{ 0xFC2D, 0xFC2D, 0xFC2D },
{ 0xFC2E, 0xFC2E, 0xFC2E },
{ 0xFC2F, 0xFC2F, 0xFC2F },
{ 0xFC30, 0xFC30, 0xFC30 },
{ 0xFC31, 0xFC31, 0xFC31 },
{ 0xFC32, 0xFC32, 0xFC32 },
{ 0xFC33, 0xFC33, 0xFC33 },
{ 0xFC34, 0xFC34, 0xFC34 },
{ 0xFC35, 0xFC35, 0xFC35 },
{ 0xFC36, 0xFC36, 0xFC36 },
{ 0xFC37, 0xFC37, 0xFC37 },
{ 0xFC38, 0xFC38, 0xFC38 },
{ 0xFC39, 0xFC39, 0xFC39 },
{ 0xFC3A, 0xFC3A, 0xFC3A },
{ 0xFC3B, 0xFC3B, 0xFC3B },
{ 0xFC3C, 0xFC3C, 0xFC3C },
{ 0xFC3D, 0xFC3D, 0xFC3D },
{ 0xFC3E, 0xFC3E, 0xFC3E },
{ 0xFC3F, 0xFC3F, 0xFC3F },
{ 0xFC40, 0xFC40, 0xFC40 },
{ 0xFC41, 0xFC41, 0xFC41 },
{ 0xFC42, 0xFC42, 0xFC42 },
{ 0xFC43, 0xFC43, 0xFC43 },
{ 0xFC44, 0xFC44, 0xFC44 },
{ 0xFC45, 0xFC45, 0xFC45 },
{ 0xFC46, 0xFC46, 0xFC46 },
{ 0xFC47, 0xFC47, 0xFC47 },
{ 0xFC48, 0xFC48, 0xFC48 },
{ 0xFC49, 0xFC49, 0xFC49 },
{ 0xFC4A, 0xFC4A, 0xFC4A },
{ 0xFC4B, 0xFC4B, 0xFC4B },
{ 0xFC4C, 0xFC4C, 0xFC4C },
{ 0xFC4D, 0xFC4D, 0xFC4D },
{ 0xFC4E, 0xFC4E, 0xFC4E },
{ 0xFC4F, 0xFC4F, 0xFC4F },
{ 0xFC50, 0xFC50, 0xFC50 },
{ 0xFC51, 0xFC51, 0xFC51 },
{ 0xFC52, 0xFC52, 0xFC52 },
{ 0xFC53, 0xFC53, 0xFC53 },
{ 0xFC54, 0xFC54, 0xFC54 },
{ 0xFC55, 0xFC55, 0xFC55 },
{ 0xFC56, 0xFC56, 0xFC56 },
{ 0xFC57, 0xFC57, 0xFC57 },
{ 0xFC58, 0xFC58, 0xFC58 },
{ 0xFC59, 0xFC59, 0xFC59 },
{ 0xFC5A, 0xFC5A, 0xFC5A },
{ 0xFC5B, 0xFC5B, 0xFC5B },
{ 0xFC5C, 0xFC5C, 0xFC5C },
{ 0xFC5D, 0xFC5D, 0xFC5D },
{ 0xFC5E, 0xFC5E, 0xFC5E },
{ 0xFC5F, 0xFC5F, 0xFC5F },
{ 0xFC60, 0xFC60, 0xFC60 },
{ 0xFC61, 0xFC61, 0xFC61 },
{ 0xFC62, 0xFC62, 0xFC62 },
{ 0xFC63, 0xFC63, 0xFC63 },
{ 0xFC64, 0xFC64, 0xFC64 },
{ 0xFC65, 0xFC65, 0xFC65 },
{ 0xFC66, 0xFC66, 0xFC66 },
{ 0xFC67, 0xFC67, 0xFC67 },
{ 0xFC68, 0xFC68, 0xFC68 },
{ 0xFC69, 0xFC69, 0xFC69 },
{ 0xFC6A, 0xFC6A, 0xFC6A },
{ 0xFC6B, 0xFC6B, 0xFC6B },
{ 0xFC6C, 0xFC6C, 0xFC6C },
{ 0xFC6D, 0xFC6D, 0xFC6D },
{ 0xFC6E, 0xFC6E, 0xFC6E },
{ 0xFC6F, 0xFC6F, 0xFC6F },
{ 0xFC70, 0xFC70, 0xFC70 },
{ 0xFC71, 0xFC71, 0xFC71 },
{ 0xFC72, 0xFC72, 0xFC72 },
{ 0xFC73, 0xFC73, 0xFC73 },
{ 0xFC74, 0xFC74, 0xFC74 },
{ 0xFC75, 0xFC75, 0xFC75 },
{ 0xFC76, 0xFC76, 0xFC76 },
{ 0xFC77, 0xFC77, 0xFC77 },
{ 0xFC78, 0xFC78, 0xFC78 },
{ 0xFC79, 0xFC79, 0xFC79 },
{ 0xFC7A, 0xFC7A, 0xFC7A },
{ 0xFC7B, 0xFC7B, 0xFC7B },
{ 0xFC7C, 0xFC7C, 0xFC7C },
{ 0xFC7D, 0xFC7D, 0xFC7D },
{ 0xFC7E, 0xFC7E, 0xFC7E },
{ 0xFC7F, 0xFC7F, 0xFC7F },
{ 0xFC80, 0xFC80, 0xFC80 },
{ 0xFC81, 0xFC81, 0xFC81 },
{ 0xFC82, 0xFC82, 0xFC82 },
{ 0xFC83, 0xFC83, 0xFC83 },
{ 0xFC84, 0xFC84, 0xFC84 },
{ 0xFC85, 0xFC85, 0xFC85 },
{ 0xFC86, 0xFC86, 0xFC86 },
{ 0xFC87, 0xFC87, 0xFC87 },
{ 0xFC88, 0xFC88, 0xFC88 },
{ 0xFC89, 0xFC89, 0xFC89 },
{ 0xFC8A, 0xFC8A, 0xFC8A },
{ 0xFC8B, 0xFC8B, 0xFC8B },
{ 0xFC8C, 0xFC8C, 0xFC8C },
{ 0xFC8D, 0xFC8D, 0xFC8D },
{ 0xFC8E, 0xFC8E, 0xFC8E },
{ 0xFC8F, 0xFC8F, 0xFC8F },
{ 0xFC90, 0xFC90, 0xFC90 },
{ 0xFC91, 0xFC91, 0xFC91 },
{ 0xFC92, 0xFC92, 0xFC92 },
{ 0xFC93, 0xFC93, 0xFC93 },
{ 0xFC94, 0xFC94, 0xFC94 },
{ 0xFC95, 0xFC95, 0xFC95 },
{ 0xFC96, 0xFC96, 0xFC96 },
{ 0xFC97, 0xFC97, 0xFC97 },
{ 0xFC98, 0xFC98, 0xFC98 },
{ 0xFC99, 0xFC99, 0xFC99 },
{ 0xFC9A, 0xFC9A, 0xFC9A },
{ 0xFC9B, 0xFC9B, 0xFC9B },
{ 0xFC9C, 0xFC9C, 0xFC9C },
{ 0xFC9D, 0xFC9D, 0xFC9D },
{ 0xFC9E, 0xFC9E, 0xFC9E },
{ 0xFC9F, 0xFC9F, 0xFC9F },
{ 0xFCA0, 0xFCA0, 0xFCA0 },
{ 0xFCA1, 0xFCA1, 0xFCA1 },
{ 0xFCA2, 0xFCA2, 0xFCA2 },
{ 0xFCA3, 0xFCA3, 0xFCA3 },
{ 0xFCA4, 0xFCA4, 0xFCA4 },
{ 0xFCA5, 0xFCA5, 0xFCA5 },
{ 0xFCA6, 0xFCA6, 0xFCA6 },
{ 0xFCA7, 0xFCA7, 0xFCA7 },
{ 0xFCA8, 0xFCA8, 0xFCA8 },
{ 0xFCA9, 0xFCA9, 0xFCA9 },
{ 0xFCAA, 0xFCAA, 0xFCAA },
{ 0xFCAB, 0xFCAB, 0xFCAB },
{ 0xFCAC, 0xFCAC, 0xFCAC },
{ 0xFCAD, 0xFCAD, 0xFCAD },
{ 0xFCAE, 0xFCAE, 0xFCAE },
{ 0xFCAF, 0xFCAF, 0xFCAF },
{ 0xFCB0, 0xFCB0, 0xFCB0 },
{ 0xFCB1, 0xFCB1, 0xFCB1 },
{ 0xFCB2, 0xFCB2, 0xFCB2 },
{ 0xFCB3, 0xFCB3, 0xFCB3 },
{ 0xFCB4, 0xFCB4, 0xFCB4 },
{ 0xFCB5, 0xFCB5, 0xFCB5 },
{ 0xFCB6, 0xFCB6, 0xFCB6 },
{ 0xFCB7, 0xFCB7, 0xFCB7 },
{ 0xFCB8, 0xFCB8, 0xFCB8 },
{ 0xFCB9, 0xFCB9, 0xFCB9 },
{ 0xFCBA, 0xFCBA, 0xFCBA },
{ 0xFCBB, 0xFCBB, 0xFCBB },
{ 0xFCBC, 0xFCBC, 0xFCBC },
{ 0xFCBD, 0xFCBD, 0xFCBD },
{ 0xFCBE, 0xFCBE, 0xFCBE },
{ 0xFCBF, 0xFCBF, 0xFCBF },
{ 0xFCC0, 0xFCC0, 0xFCC0 },
{ 0xFCC1, 0xFCC1, 0xFCC1 },
{ 0xFCC2, 0xFCC2, 0xFCC2 },
{ 0xFCC3, 0xFCC3, 0xFCC3 },
{ 0xFCC4, 0xFCC4, 0xFCC4 },
{ 0xFCC5, 0xFCC5, 0xFCC5 },
{ 0xFCC6, 0xFCC6, 0xFCC6 },
{ 0xFCC7, 0xFCC7, 0xFCC7 },
{ 0xFCC8, 0xFCC8, 0xFCC8 },
{ 0xFCC9, 0xFCC9, 0xFCC9 },
{ 0xFCCA, 0xFCCA, 0xFCCA },
{ 0xFCCB, 0xFCCB, 0xFCCB },
{ 0xFCCC, 0xFCCC, 0xFCCC },
{ 0xFCCD, 0xFCCD, 0xFCCD },
{ 0xFCCE, 0xFCCE, 0xFCCE },
{ 0xFCCF, 0xFCCF, 0xFCCF },
{ 0xFCD0, 0xFCD0, 0xFCD0 },
{ 0xFCD1, 0xFCD1, 0xFCD1 },
{ 0xFCD2, 0xFCD2, 0xFCD2 },
{ 0xFCD3, 0xFCD3, 0xFCD3 },
{ 0xFCD4, 0xFCD4, 0xFCD4 },
{ 0xFCD5, 0xFCD5, 0xFCD5 },
{ 0xFCD6, 0xFCD6, 0xFCD6 },
{ 0xFCD7, 0xFCD7, 0xFCD7 },
{ 0xFCD8, 0xFCD8, 0xFCD8 },
{ 0xFCD9, 0xFCD9, 0xFCD9 },
{ 0xFCDA, 0xFCDA, 0xFCDA },
{ 0xFCDB, 0xFCDB, 0xFCDB },
{ 0xFCDC, 0xFCDC, 0xFCDC },
{ 0xFCDD, 0xFCDD, 0xFCDD },
{ 0xFCDE, 0xFCDE, 0xFCDE },
{ 0xFCDF, 0xFCDF, 0xFCDF },
{ 0xFCE0, 0xFCE0, 0xFCE0 },
{ 0xFCE1, 0xFCE1, 0xFCE1 },
{ 0xFCE2, 0xFCE2, 0xFCE2 },
{ 0xFCE3, 0xFCE3, 0xFCE3 },
{ 0xFCE4, 0xFCE4, 0xFCE4 },
{ 0xFCE5, 0xFCE5, 0xFCE5 },
{ 0xFCE6, 0xFCE6, 0xFCE6 },
{ 0xFCE7, 0xFCE7, 0xFCE7 },
{ 0xFCE8, 0xFCE8, 0xFCE8 },
{ 0xFCE9, 0xFCE9, 0xFCE9 },
{ 0xFCEA, 0xFCEA, 0xFCEA },
{ 0xFCEB, 0xFCEB, 0xFCEB },
{ 0xFCEC, 0xFCEC, 0xFCEC },
{ 0xFCED, 0xFCED, 0xFCED },
{ 0xFCEE, 0xFCEE, 0xFCEE },
{ 0xFCEF, 0xFCEF, 0xFCEF },
{ 0xFCF0, 0xFCF0, 0xFCF0 },
{ 0xFCF1, 0xFCF1, 0xFCF1 },
{ 0xFCF2, 0xFCF2, 0xFCF2 },
{ 0xFCF3, 0xFCF3, 0xFCF3 },
{ 0xFCF4, 0xFCF4, 0xFCF4 },
{ 0xFCF5, 0xFCF5, 0xFCF5 },
{ 0xFCF6, 0xFCF6, 0xFCF6 },
{ 0xFCF7, 0xFCF7, 0xFCF7 },
{ 0xFCF8, 0xFCF8, 0xFCF8 },
{ 0xFCF9, 0xFCF9, 0xFCF9 },
{ 0xFCFA, 0xFCFA, 0xFCFA },
{ 0xFCFB, 0xFCFB, 0xFCFB },
{ 0xFCFC, 0xFCFC, 0xFCFC },
{ 0xFCFD, 0xFCFD, 0xFCFD },
{ 0xFCFE, 0xFCFE, 0xFCFE },
{ 0xFCFF, 0xFCFF, 0xFCFF },
{ 0xFD00, 0xFD00, 0xFD00 },
{ 0xFD01, 0xFD01, 0xFD01 },
{ 0xFD02, 0xFD02, 0xFD02 },
{ 0xFD03, 0xFD03, 0xFD03 },
{ 0xFD04, 0xFD04, 0xFD04 },
{ 0xFD05, 0xFD05, 0xFD05 },
{ 0xFD06, 0xFD06, 0xFD06 },
{ 0xFD07, 0xFD07, 0xFD07 },
{ 0xFD08, 0xFD08, 0xFD08 },
{ 0xFD09, 0xFD09, 0xFD09 },
{ 0xFD0A, 0xFD0A, 0xFD0A },
{ 0xFD0B, 0xFD0B, 0xFD0B },
{ 0xFD0C, 0xFD0C, 0xFD0C },
{ 0xFD0D, 0xFD0D, 0xFD0D },
{ 0xFD0E, 0xFD0E, 0xFD0E },
{ 0xFD0F, 0xFD0F, 0xFD0F },
{ 0xFD10, 0xFD10, 0xFD10 },
{ 0xFD11, 0xFD11, 0xFD11 },
{ 0xFD12, 0xFD12, 0xFD12 },
{ 0xFD13, 0xFD13, 0xFD13 },
{ 0xFD14, 0xFD14, 0xFD14 },
{ 0xFD15, 0xFD15, 0xFD15 },
{ 0xFD16, 0xFD16, 0xFD16 },
{ 0xFD17, 0xFD17, 0xFD17 },
{ 0xFD18, 0xFD18, 0xFD18 },
{ 0xFD19, 0xFD19, 0xFD19 },
{ 0xFD1A, 0xFD1A, 0xFD1A },
{ 0xFD1B, 0xFD1B, 0xFD1B },
{ 0xFD1C, 0xFD1C, 0xFD1C },
{ 0xFD1D, 0xFD1D, 0xFD1D },
{ 0xFD1E, 0xFD1E, 0xFD1E },
{ 0xFD1F, 0xFD1F, 0xFD1F },
{ 0xFD20, 0xFD20, 0xFD20 },
{ 0xFD21, 0xFD21, 0xFD21 },
{ 0xFD22, 0xFD22, 0xFD22 },
{ 0xFD23, 0xFD23, 0xFD23 },
{ 0xFD24, 0xFD24, 0xFD24 },
{ 0xFD25, 0xFD25, 0xFD25 },
{ 0xFD26, 0xFD26, 0xFD26 },
{ 0xFD27, 0xFD27, 0xFD27 },
{ 0xFD28, 0xFD28, 0xFD28 },
{ 0xFD29, 0xFD29, 0xFD29 },
{ 0xFD2A, 0xFD2A, 0xFD2A },
{ 0xFD2B, 0xFD2B, 0xFD2B },
{ 0xFD2C, 0xFD2C, 0xFD2C },
{ 0xFD2D, 0xFD2D, 0xFD2D },
{ 0xFD2E, 0xFD2E, 0xFD2E },
{ 0xFD2F, 0xFD2F, 0xFD2F },
{ 0xFD30, 0xFD30, 0xFD30 },
{ 0xFD31, 0xFD31, 0xFD31 },
{ 0xFD32, 0xFD32, 0xFD32 },
{ 0xFD33, 0xFD33, 0xFD33 },
{ 0xFD34, 0xFD34, 0xFD34 },
{ 0xFD35, 0xFD35, 0xFD35 },
{ 0xFD36, 0xFD36, 0xFD36 },
{ 0xFD37, 0xFD37, 0xFD37 },
{ 0xFD38, 0xFD38, 0xFD38 },
{ 0xFD39, 0xFD39, 0xFD39 },
{ 0xFD3A, 0xFD3A, 0xFD3A },
{ 0xFD3B, 0xFD3B, 0xFD3B },
{ 0xFD3C, 0xFD3C, 0xFD3C },
{ 0xFD3D, 0xFD3D, 0xFD3D },
{ 0xFD50, 0xFD50, 0xFD50 },
{ 0xFD51, 0xFD51, 0xFD51 },
{ 0xFD52, 0xFD52, 0xFD52 },
{ 0xFD53, 0xFD53, 0xFD53 },
{ 0xFD54, 0xFD54, 0xFD54 },
{ 0xFD55, 0xFD55, 0xFD55 },
{ 0xFD56, 0xFD56, 0xFD56 },
{ 0xFD57, 0xFD57, 0xFD57 },
{ 0xFD58, 0xFD58, 0xFD58 },
{ 0xFD59, 0xFD59, 0xFD59 },
{ 0xFD5A, 0xFD5A, 0xFD5A },
{ 0xFD5B, 0xFD5B, 0xFD5B },
{ 0xFD5C, 0xFD5C, 0xFD5C },
{ 0xFD5D, 0xFD5D, 0xFD5D },
{ 0xFD5E, 0xFD5E, 0xFD5E },
{ 0xFD5F, 0xFD5F, 0xFD5F },
{ 0xFD60, 0xFD60, 0xFD60 },
{ 0xFD61, 0xFD61, 0xFD61 },
{ 0xFD62, 0xFD62, 0xFD62 },
{ 0xFD63, 0xFD63, 0xFD63 },
{ 0xFD64, 0xFD64, 0xFD64 },
{ 0xFD65, 0xFD65, 0xFD65 },
{ 0xFD66, 0xFD66, 0xFD66 },
{ 0xFD67, 0xFD67, 0xFD67 },
{ 0xFD68, 0xFD68, 0xFD68 },
{ 0xFD69, 0xFD69, 0xFD69 },
{ 0xFD6A, 0xFD6A, 0xFD6A },
{ 0xFD6B, 0xFD6B, 0xFD6B },
{ 0xFD6C, 0xFD6C, 0xFD6C },
{ 0xFD6D, 0xFD6D, 0xFD6D },
{ 0xFD6E, 0xFD6E, 0xFD6E },
{ 0xFD6F, 0xFD6F, 0xFD6F },
{ 0xFD70, 0xFD70, 0xFD70 },
{ 0xFD71, 0xFD71, 0xFD71 },
{ 0xFD72, 0xFD72, 0xFD72 },
{ 0xFD73, 0xFD73, 0xFD73 },
{ 0xFD74, 0xFD74, 0xFD74 },
{ 0xFD75, 0xFD75, 0xFD75 },
{ 0xFD76, 0xFD76, 0xFD76 },
{ 0xFD77, 0xFD77, 0xFD77 },
{ 0xFD78, 0xFD78, 0xFD78 },
{ 0xFD79, 0xFD79, 0xFD79 },
{ 0xFD7A, 0xFD7A, 0xFD7A },
{ 0xFD7B, 0xFD7B, 0xFD7B },
{ 0xFD7C, 0xFD7C, 0xFD7C },
{ 0xFD7D, 0xFD7D, 0xFD7D },
{ 0xFD7E, 0xFD7E, 0xFD7E },
{ 0xFD7F, 0xFD7F, 0xFD7F },
{ 0xFD80, 0xFD80, 0xFD80 },
{ 0xFD81, 0xFD81, 0xFD81 },
{ 0xFD82, 0xFD82, 0xFD82 },
{ 0xFD83, 0xFD83, 0xFD83 },
{ 0xFD84, 0xFD84, 0xFD84 },
{ 0xFD85, 0xFD85, 0xFD85 },
{ 0xFD86, 0xFD86, 0xFD86 },
{ 0xFD87, 0xFD87, 0xFD87 },
{ 0xFD88, 0xFD88, 0xFD88 },
{ 0xFD89, 0xFD89, 0xFD89 },
{ 0xFD8A, 0xFD8A, 0xFD8A },
{ 0xFD8B, 0xFD8B, 0xFD8B },
{ 0xFD8C, 0xFD8C, 0xFD8C },
{ 0xFD8D, 0xFD8D, 0xFD8D },
{ 0xFD8E, 0xFD8E, 0xFD8E },
{ 0xFD8F, 0xFD8F, 0xFD8F },
{ 0xFD92, 0xFD92, 0xFD92 },
{ 0xFD93, 0xFD93, 0xFD93 },
{ 0xFD94, 0xFD94, 0xFD94 },
{ 0xFD95, 0xFD95, 0xFD95 },
{ 0xFD96, 0xFD96, 0xFD96 },
{ 0xFD97, 0xFD97, 0xFD97 },
{ 0xFD98, 0xFD98, 0xFD98 },
{ 0xFD99, 0xFD99, 0xFD99 },
{ 0xFD9A, 0xFD9A, 0xFD9A },
{ 0xFD9B, 0xFD9B, 0xFD9B },
{ 0xFD9C, 0xFD9C, 0xFD9C },
{ 0xFD9D, 0xFD9D, 0xFD9D },
{ 0xFD9E, 0xFD9E, 0xFD9E },
{ 0xFD9F, 0xFD9F, 0xFD9F },
{ 0xFDA0, 0xFDA0, 0xFDA0 },
{ 0xFDA1, 0xFDA1, 0xFDA1 },
{ 0xFDA2, 0xFDA2, 0xFDA2 },
{ 0xFDA3, 0xFDA3, 0xFDA3 },
{ 0xFDA4, 0xFDA4, 0xFDA4 },
{ 0xFDA5, 0xFDA5, 0xFDA5 },
{ 0xFDA6, 0xFDA6, 0xFDA6 },
{ 0xFDA7, 0xFDA7, 0xFDA7 },
{ 0xFDA8, 0xFDA8, 0xFDA8 },
{ 0xFDA9, 0xFDA9, 0xFDA9 },
{ 0xFDAA, 0xFDAA, 0xFDAA },
{ 0xFDAB, 0xFDAB, 0xFDAB },
{ 0xFDAC, 0xFDAC, 0xFDAC },
{ 0xFDAD, 0xFDAD, 0xFDAD },
{ 0xFDAE, 0xFDAE, 0xFDAE },
{ 0xFDAF, 0xFDAF, 0xFDAF },
{ 0xFDB0, 0xFDB0, 0xFDB0 },
{ 0xFDB1, 0xFDB1, 0xFDB1 },
{ 0xFDB2, 0xFDB2, 0xFDB2 },
{ 0xFDB3, 0xFDB3, 0xFDB3 },
{ 0xFDB4, 0xFDB4, 0xFDB4 },
{ 0xFDB5, 0xFDB5, 0xFDB5 },
{ 0xFDB6, 0xFDB6, 0xFDB6 },
{ 0xFDB7, 0xFDB7, 0xFDB7 },
{ 0xFDB8, 0xFDB8, 0xFDB8 },
{ 0xFDB9, 0xFDB9, 0xFDB9 },
{ 0xFDBA, 0xFDBA, 0xFDBA },
{ 0xFDBB, 0xFDBB, 0xFDBB },
{ 0xFDBC, 0xFDBC, 0xFDBC },
{ 0xFDBD, 0xFDBD, 0xFDBD },
{ 0xFDBE, 0xFDBE, 0xFDBE },
{ 0xFDBF, 0xFDBF, 0xFDBF },
{ 0xFDC0, 0xFDC0, 0xFDC0 },
{ 0xFDC1, 0xFDC1, 0xFDC1 },
{ 0xFDC2, 0xFDC2, 0xFDC2 },
{ 0xFDC3, 0xFDC3, 0xFDC3 },
{ 0xFDC4, 0xFDC4, 0xFDC4 },
{ 0xFDC5, 0xFDC5, 0xFDC5 },
{ 0xFDC6, 0xFDC6, 0xFDC6 },
{ 0xFDC7, 0xFDC7, 0xFDC7 },
{ 0xFDF0, 0xFDF0, 0xFDF0 },
{ 0xFDF1, 0xFDF1, 0xFDF1 },
{ 0xFDF2, 0xFDF2, 0xFDF2 },
{ 0xFDF3, 0xFDF3, 0xFDF3 },
{ 0xFDF4, 0xFDF4, 0xFDF4 },
{ 0xFDF5, 0xFDF5, 0xFDF5 },
{ 0xFDF6, 0xFDF6, 0xFDF6 },
{ 0xFDF7, 0xFDF7, 0xFDF7 },
{ 0xFDF8, 0xFDF8, 0xFDF8 },
{ 0xFDF9, 0xFDF9, 0xFDF9 },
{ 0xFDFA, 0xFDFA, 0xFDFA },
{ 0xFDFB, 0xFDFB, 0xFDFB },
{ 0xFE00, 0xFE00, 0xFE00 },
{ 0xFE01, 0xFE01, 0xFE01 },
{ 0xFE02, 0xFE02, 0xFE02 },
{ 0xFE03, 0xFE03, 0xFE03 },
{ 0xFE04, 0xFE04, 0xFE04 },
{ 0xFE05, 0xFE05, 0xFE05 },
{ 0xFE06, 0xFE06, 0xFE06 },
{ 0xFE07, 0xFE07, 0xFE07 },
{ 0xFE08, 0xFE08, 0xFE08 },
{ 0xFE09, 0xFE09, 0xFE09 },
{ 0xFE0A, 0xFE0A, 0xFE0A },
{ 0xFE0B, 0xFE0B, 0xFE0B },
{ 0xFE0C, 0xFE0C, 0xFE0C },
{ 0xFE0D, 0xFE0D, 0xFE0D },
{ 0xFE0E, 0xFE0E, 0xFE0E },
{ 0xFE0F, 0xFE0F, 0xFE0F },
{ 0xFE20, 0xFE20, 0xFE20 },
{ 0xFE21, 0xFE21, 0xFE21 },
{ 0xFE22, 0xFE22, 0xFE22 },
{ 0xFE23, 0xFE23, 0xFE23 },
{ 0xFE70, 0xFE70, 0xFE70 },
{ 0xFE71, 0xFE71, 0xFE71 },
{ 0xFE72, 0xFE72, 0xFE72 },
{ 0xFE73, 0xFE73, 0xFE73 },
{ 0xFE74, 0xFE74, 0xFE74 },
{ 0xFE76, 0xFE76, 0xFE76 },
{ 0xFE77, 0xFE77, 0xFE77 },
{ 0xFE78, 0xFE78, 0xFE78 },
{ 0xFE79, 0xFE79, 0xFE79 },
{ 0xFE7A, 0xFE7A, 0xFE7A },
{ 0xFE7B, 0xFE7B, 0xFE7B },
{ 0xFE7C, 0xFE7C, 0xFE7C },
{ 0xFE7D, 0xFE7D, 0xFE7D },
{ 0xFE7E, 0xFE7E, 0xFE7E },
{ 0xFE7F, 0xFE7F, 0xFE7F },
{ 0xFE80, 0xFE80, 0xFE80 },
{ 0xFE81, 0xFE81, 0xFE81 },
{ 0xFE82, 0xFE82, 0xFE82 },
{ 0xFE83, 0xFE83, 0xFE83 },
{ 0xFE84, 0xFE84, 0xFE84 },
{ 0xFE85, 0xFE85, 0xFE85 },
{ 0xFE86, 0xFE86, 0xFE86 },
{ 0xFE87, 0xFE87, 0xFE87 },
{ 0xFE88, 0xFE88, 0xFE88 },
{ 0xFE89, 0xFE89, 0xFE89 },
{ 0xFE8A, 0xFE8A, 0xFE8A },
{ 0xFE8B, 0xFE8B, 0xFE8B },
{ 0xFE8C, 0xFE8C, 0xFE8C },
{ 0xFE8D, 0xFE8D, 0xFE8D },
{ 0xFE8E, 0xFE8E, 0xFE8E },
{ 0xFE8F, 0xFE8F, 0xFE8F },
{ 0xFE90, 0xFE90, 0xFE90 },
{ 0xFE91, 0xFE91, 0xFE91 },
{ 0xFE92, 0xFE92, 0xFE92 },
{ 0xFE93, 0xFE93, 0xFE93 },
{ 0xFE94, 0xFE94, 0xFE94 },
{ 0xFE95, 0xFE95, 0xFE95 },
{ 0xFE96, 0xFE96, 0xFE96 },
{ 0xFE97, 0xFE97, 0xFE97 },
{ 0xFE98, 0xFE98, 0xFE98 },
{ 0xFE99, 0xFE99, 0xFE99 },
{ 0xFE9A, 0xFE9A, 0xFE9A },
{ 0xFE9B, 0xFE9B, 0xFE9B },
{ 0xFE9C, 0xFE9C, 0xFE9C },
{ 0xFE9D, 0xFE9D, 0xFE9D },
{ 0xFE9E, 0xFE9E, 0xFE9E },
{ 0xFE9F, 0xFE9F, 0xFE9F },
{ 0xFEA0, 0xFEA0, 0xFEA0 },
{ 0xFEA1, 0xFEA1, 0xFEA1 },
{ 0xFEA2, 0xFEA2, 0xFEA2 },
{ 0xFEA3, 0xFEA3, 0xFEA3 },
{ 0xFEA4, 0xFEA4, 0xFEA4 },
{ 0xFEA5, 0xFEA5, 0xFEA5 },
{ 0xFEA6, 0xFEA6, 0xFEA6 },
{ 0xFEA7, 0xFEA7, 0xFEA7 },
{ 0xFEA8, 0xFEA8, 0xFEA8 },
{ 0xFEA9, 0xFEA9, 0xFEA9 },
{ 0xFEAA, 0xFEAA, 0xFEAA },
{ 0xFEAB, 0xFEAB, 0xFEAB },
{ 0xFEAC, 0xFEAC, 0xFEAC },
{ 0xFEAD, 0xFEAD, 0xFEAD },
{ 0xFEAE, 0xFEAE, 0xFEAE },
{ 0xFEAF, 0xFEAF, 0xFEAF },
{ 0xFEB0, 0xFEB0, 0xFEB0 },
{ 0xFEB1, 0xFEB1, 0xFEB1 },
{ 0xFEB2, 0xFEB2, 0xFEB2 },
{ 0xFEB3, 0xFEB3, 0xFEB3 },
{ 0xFEB4, 0xFEB4, 0xFEB4 },
{ 0xFEB5, 0xFEB5, 0xFEB5 },
{ 0xFEB6, 0xFEB6, 0xFEB6 },
{ 0xFEB7, 0xFEB7, 0xFEB7 },
{ 0xFEB8, 0xFEB8, 0xFEB8 },
{ 0xFEB9, 0xFEB9, 0xFEB9 },
{ 0xFEBA, 0xFEBA, 0xFEBA },
{ 0xFEBB, 0xFEBB, 0xFEBB },
{ 0xFEBC, 0xFEBC, 0xFEBC },
{ 0xFEBD, 0xFEBD, 0xFEBD },
{ 0xFEBE, 0xFEBE, 0xFEBE },
{ 0xFEBF, 0xFEBF, 0xFEBF },
{ 0xFEC0, 0xFEC0, 0xFEC0 },
{ 0xFEC1, 0xFEC1, 0xFEC1 },
{ 0xFEC2, 0xFEC2, 0xFEC2 },
{ 0xFEC3, 0xFEC3, 0xFEC3 },
{ 0xFEC4, 0xFEC4, 0xFEC4 },
{ 0xFEC5, 0xFEC5, 0xFEC5 },
{ 0xFEC6, 0xFEC6, 0xFEC6 },
{ 0xFEC7, 0xFEC7, 0xFEC7 },
{ 0xFEC8, 0xFEC8, 0xFEC8 },
{ 0xFEC9, 0xFEC9, 0xFEC9 },
{ 0xFECA, 0xFECA, 0xFECA },
{ 0xFECB, 0xFECB, 0xFECB },
{ 0xFECC, 0xFECC, 0xFECC },
{ 0xFECD, 0xFECD, 0xFECD },
{ 0xFECE, 0xFECE, 0xFECE },
{ 0xFECF, 0xFECF, 0xFECF },
{ 0xFED0, 0xFED0, 0xFED0 },
{ 0xFED1, 0xFED1, 0xFED1 },
{ 0xFED2, 0xFED2, 0xFED2 },
{ 0xFED3, 0xFED3, 0xFED3 },
{ 0xFED4, 0xFED4, 0xFED4 },
{ 0xFED5, 0xFED5, 0xFED5 },
{ 0xFED6, 0xFED6, 0xFED6 },
{ 0xFED7, 0xFED7, 0xFED7 },
{ 0xFED8, 0xFED8, 0xFED8 },
{ 0xFED9, 0xFED9, 0xFED9 },
{ 0xFEDA, 0xFEDA, 0xFEDA },
{ 0xFEDB, 0xFEDB, 0xFEDB },
{ 0xFEDC, 0xFEDC, 0xFEDC },
{ 0xFEDD, 0xFEDD, 0xFEDD },
{ 0xFEDE, 0xFEDE, 0xFEDE },
{ 0xFEDF, 0xFEDF, 0xFEDF },
{ 0xFEE0, 0xFEE0, 0xFEE0 },
{ 0xFEE1, 0xFEE1, 0xFEE1 },
{ 0xFEE2, 0xFEE2, 0xFEE2 },
{ 0xFEE3, 0xFEE3, 0xFEE3 },
{ 0xFEE4, 0xFEE4, 0xFEE4 },
{ 0xFEE5, 0xFEE5, 0xFEE5 },
{ 0xFEE6, 0xFEE6, 0xFEE6 },
{ 0xFEE7, 0xFEE7, 0xFEE7 },
{ 0xFEE8, 0xFEE8, 0xFEE8 },
{ 0xFEE9, 0xFEE9, 0xFEE9 },
{ 0xFEEA, 0xFEEA, 0xFEEA },
{ 0xFEEB, 0xFEEB, 0xFEEB },
{ 0xFEEC, 0xFEEC, 0xFEEC },
{ 0xFEED, 0xFEED, 0xFEED },
{ 0xFEEE, 0xFEEE, 0xFEEE },
{ 0xFEEF, 0xFEEF, 0xFEEF },
{ 0xFEF0, 0xFEF0, 0xFEF0 },
{ 0xFEF1, 0xFEF1, 0xFEF1 },
{ 0xFEF2, 0xFEF2, 0xFEF2 },
{ 0xFEF3, 0xFEF3, 0xFEF3 },
{ 0xFEF4, 0xFEF4, 0xFEF4 },
{ 0xFEF5, 0xFEF5, 0xFEF5 },
{ 0xFEF6, 0xFEF6, 0xFEF6 },
{ 0xFEF7, 0xFEF7, 0xFEF7 },
{ 0xFEF8, 0xFEF8, 0xFEF8 },
{ 0xFEF9, 0xFEF9, 0xFEF9 },
{ 0xFEFA, 0xFEFA, 0xFEFA },
{ 0xFEFB, 0xFEFB, 0xFEFB },
{ 0xFEFC, 0xFEFC, 0xFEFC },
{ 0xFF21, 0xFF21, 0xFF41 },
{ 0xFF22, 0xFF22, 0xFF42 },
{ 0xFF23, 0xFF23, 0xFF43 },
{ 0xFF24, 0xFF24, 0xFF44 },
{ 0xFF25, 0xFF25, 0xFF45 },
{ 0xFF26, 0xFF26, 0xFF46 },
{ 0xFF27, 0xFF27, 0xFF47 },
{ 0xFF28, 0xFF28, 0xFF48 },
{ 0xFF29, 0xFF29, 0xFF49 },
{ 0xFF2A, 0xFF2A, 0xFF4A },
{ 0xFF2B, 0xFF2B, 0xFF4B },
{ 0xFF2C, 0xFF2C, 0xFF4C },
{ 0xFF2D, 0xFF2D, 0xFF4D },
{ 0xFF2E, 0xFF2E, 0xFF4E },
{ 0xFF2F, 0xFF2F, 0xFF4F },
{ 0xFF30, 0xFF30, 0xFF50 },
{ 0xFF31, 0xFF31, 0xFF51 },
{ 0xFF32, 0xFF32, 0xFF52 },
{ 0xFF33, 0xFF33, 0xFF53 },
{ 0xFF34, 0xFF34, 0xFF54 },
{ 0xFF35, 0xFF35, 0xFF55 },
{ 0xFF36, 0xFF36, 0xFF56 },
{ 0xFF37, 0xFF37, 0xFF57 },
{ 0xFF38, 0xFF38, 0xFF58 },
{ 0xFF39, 0xFF39, 0xFF59 },
{ 0xFF3A, 0xFF3A, 0xFF5A },
{ 0xFF41, 0xFF21, 0xFF41 },
{ 0xFF42, 0xFF22, 0xFF42 },
{ 0xFF43, 0xFF23, 0xFF43 },
{ 0xFF44, 0xFF24, 0xFF44 },
{ 0xFF45, 0xFF25, 0xFF45 },
{ 0xFF46, 0xFF26, 0xFF46 },
{ 0xFF47, 0xFF27, 0xFF47 },
{ 0xFF48, 0xFF28, 0xFF48 },
{ 0xFF49, 0xFF29, 0xFF49 },
{ 0xFF4A, 0xFF2A, 0xFF4A },
{ 0xFF4B, 0xFF2B, 0xFF4B },
{ 0xFF4C, 0xFF2C, 0xFF4C },
{ 0xFF4D, 0xFF2D, 0xFF4D },
{ 0xFF4E, 0xFF2E, 0xFF4E },
{ 0xFF4F, 0xFF2F, 0xFF4F },
{ 0xFF50, 0xFF30, 0xFF50 },
{ 0xFF51, 0xFF31, 0xFF51 },
{ 0xFF52, 0xFF32, 0xFF52 },
{ 0xFF53, 0xFF33, 0xFF53 },
{ 0xFF54, 0xFF34, 0xFF54 },
{ 0xFF55, 0xFF35, 0xFF55 },
{ 0xFF56, 0xFF36, 0xFF56 },
{ 0xFF57, 0xFF37, 0xFF57 },
{ 0xFF58, 0xFF38, 0xFF58 },
{ 0xFF59, 0xFF39, 0xFF59 },
{ 0xFF5A, 0xFF3A, 0xFF5A },
{ 0xFF66, 0xFF66, 0xFF66 },
{ 0xFF67, 0xFF67, 0xFF67 },
{ 0xFF68, 0xFF68, 0xFF68 },
{ 0xFF69, 0xFF69, 0xFF69 },
{ 0xFF6A, 0xFF6A, 0xFF6A },
{ 0xFF6B, 0xFF6B, 0xFF6B },
{ 0xFF6C, 0xFF6C, 0xFF6C },
{ 0xFF6D, 0xFF6D, 0xFF6D },
{ 0xFF6E, 0xFF6E, 0xFF6E },
{ 0xFF6F, 0xFF6F, 0xFF6F },
{ 0xFF70, 0xFF70, 0xFF70 },
{ 0xFF71, 0xFF71, 0xFF71 },
{ 0xFF72, 0xFF72, 0xFF72 },
{ 0xFF73, 0xFF73, 0xFF73 },
{ 0xFF74, 0xFF74, 0xFF74 },
{ 0xFF75, 0xFF75, 0xFF75 },
{ 0xFF76, 0xFF76, 0xFF76 },
{ 0xFF77, 0xFF77, 0xFF77 },
{ 0xFF78, 0xFF78, 0xFF78 },
{ 0xFF79, 0xFF79, 0xFF79 },
{ 0xFF7A, 0xFF7A, 0xFF7A },
{ 0xFF7B, 0xFF7B, 0xFF7B },
{ 0xFF7C, 0xFF7C, 0xFF7C },
{ 0xFF7D, 0xFF7D, 0xFF7D },
{ 0xFF7E, 0xFF7E, 0xFF7E },
{ 0xFF7F, 0xFF7F, 0xFF7F },
{ 0xFF80, 0xFF80, 0xFF80 },
{ 0xFF81, 0xFF81, 0xFF81 },
{ 0xFF82, 0xFF82, 0xFF82 },
{ 0xFF83, 0xFF83, 0xFF83 },
{ 0xFF84, 0xFF84, 0xFF84 },
{ 0xFF85, 0xFF85, 0xFF85 },
{ 0xFF86, 0xFF86, 0xFF86 },
{ 0xFF87, 0xFF87, 0xFF87 },
{ 0xFF88, 0xFF88, 0xFF88 },
{ 0xFF89, 0xFF89, 0xFF89 },
{ 0xFF8A, 0xFF8A, 0xFF8A },
{ 0xFF8B, 0xFF8B, 0xFF8B },
{ 0xFF8C, 0xFF8C, 0xFF8C },
{ 0xFF8D, 0xFF8D, 0xFF8D },
{ 0xFF8E, 0xFF8E, 0xFF8E },
{ 0xFF8F, 0xFF8F, 0xFF8F },
{ 0xFF90, 0xFF90, 0xFF90 },
{ 0xFF91, 0xFF91, 0xFF91 },
{ 0xFF92, 0xFF92, 0xFF92 },
{ 0xFF93, 0xFF93, 0xFF93 },
{ 0xFF94, 0xFF94, 0xFF94 },
{ 0xFF95, 0xFF95, 0xFF95 },
{ 0xFF96, 0xFF96, 0xFF96 },
{ 0xFF97, 0xFF97, 0xFF97 },
{ 0xFF98, 0xFF98, 0xFF98 },
{ 0xFF99, 0xFF99, 0xFF99 },
{ 0xFF9A, 0xFF9A, 0xFF9A },
{ 0xFF9B, 0xFF9B, 0xFF9B },
{ 0xFF9C, 0xFF9C, 0xFF9C },
{ 0xFF9D, 0xFF9D, 0xFF9D },
{ 0xFF9E, 0xFF9E, 0xFF9E },
{ 0xFF9F, 0xFF9F, 0xFF9F },
{ 0xFFA0, 0xFFA0, 0xFFA0 },
{ 0xFFA1, 0xFFA1, 0xFFA1 },
{ 0xFFA2, 0xFFA2, 0xFFA2 },
{ 0xFFA3, 0xFFA3, 0xFFA3 },
{ 0xFFA4, 0xFFA4, 0xFFA4 },
{ 0xFFA5, 0xFFA5, 0xFFA5 },
{ 0xFFA6, 0xFFA6, 0xFFA6 },
{ 0xFFA7, 0xFFA7, 0xFFA7 },
{ 0xFFA8, 0xFFA8, 0xFFA8 },
{ 0xFFA9, 0xFFA9, 0xFFA9 },
{ 0xFFAA, 0xFFAA, 0xFFAA },
{ 0xFFAB, 0xFFAB, 0xFFAB },
{ 0xFFAC, 0xFFAC, 0xFFAC },
{ 0xFFAD, 0xFFAD, 0xFFAD },
{ 0xFFAE, 0xFFAE, 0xFFAE },
{ 0xFFAF, 0xFFAF, 0xFFAF },
{ 0xFFB0, 0xFFB0, 0xFFB0 },
{ 0xFFB1, 0xFFB1, 0xFFB1 },
{ 0xFFB2, 0xFFB2, 0xFFB2 },
{ 0xFFB3, 0xFFB3, 0xFFB3 },
{ 0xFFB4, 0xFFB4, 0xFFB4 },
{ 0xFFB5, 0xFFB5, 0xFFB5 },
{ 0xFFB6, 0xFFB6, 0xFFB6 },
{ 0xFFB7, 0xFFB7, 0xFFB7 },
{ 0xFFB8, 0xFFB8, 0xFFB8 },
{ 0xFFB9, 0xFFB9, 0xFFB9 },
{ 0xFFBA, 0xFFBA, 0xFFBA },
{ 0xFFBB, 0xFFBB, 0xFFBB },
{ 0xFFBC, 0xFFBC, 0xFFBC },
{ 0xFFBD, 0xFFBD, 0xFFBD },
{ 0xFFBE, 0xFFBE, 0xFFBE },
{ 0xFFC2, 0xFFC2, 0xFFC2 },
{ 0xFFC3, 0xFFC3, 0xFFC3 },
{ 0xFFC4, 0xFFC4, 0xFFC4 },
{ 0xFFC5, 0xFFC5, 0xFFC5 },
{ 0xFFC6, 0xFFC6, 0xFFC6 },
{ 0xFFC7, 0xFFC7, 0xFFC7 },
{ 0xFFCA, 0xFFCA, 0xFFCA },
{ 0xFFCB, 0xFFCB, 0xFFCB },
{ 0xFFCC, 0xFFCC, 0xFFCC },
{ 0xFFCD, 0xFFCD, 0xFFCD },
{ 0xFFCE, 0xFFCE, 0xFFCE },
{ 0xFFCF, 0xFFCF, 0xFFCF },
{ 0xFFD2, 0xFFD2, 0xFFD2 },
{ 0xFFD3, 0xFFD3, 0xFFD3 },
{ 0xFFD4, 0xFFD4, 0xFFD4 },
{ 0xFFD5, 0xFFD5, 0xFFD5 },
{ 0xFFD6, 0xFFD6, 0xFFD6 },
{ 0xFFD7, 0xFFD7, 0xFFD7 },
{ 0xFFDA, 0xFFDA, 0xFFDA },
{ 0xFFDB, 0xFFDB, 0xFFDB },
{ 0xFFDC, 0xFFDC, 0xFFDC }
};
robojournal-0.4.2/ui/hunspell/phonet.cxx 0000644 0001750 0001750 00000027227 12211723646 017057 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* phonetic.c - generic replacement aglogithms for phonetic transformation
Copyright (C) 2000 Bjoern Jacke
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation;
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see
.
Changelog:
2000-01-05 Bjoern Jacke
Initial Release insprired by the article about phonetic
transformations out of c't 25/1999
2007-07-26 Bjoern Jacke
Released under MPL/GPL/LGPL tri-license for Hunspell
2007-08-23 Laszlo Nemeth
Porting from Aspell to Hunspell using C-like structs
*/
#ifndef MOZILLA_CLIENT
#include
#include
#include
#include
#else
#include
#include
#include
#include
#endif
#include "ui/hunspell/csutil.hxx"
#include "ui/hunspell/phonet.hxx"
void init_phonet_hash(phonetable & parms)
{
int i, k;
for (i = 0; i < HASHSIZE; i++) {
parms.hash[i] = -1;
}
for (i = 0; parms.rules[i][0] != '\0'; i += 2) {
/** set hash value **/
k = (unsigned char) parms.rules[i][0];
if (parms.hash[k] < 0) {
parms.hash[k] = i;
}
}
}
// like strcpy but safe if the strings overlap
// but only if dest < src
static inline void strmove(char * dest, char * src) {
while (*src)
*dest++ = *src++;
*dest = '\0';
}
/* phonetic transcription algorithm */
/* see: http://aspell.net/man-html/Phonetic-Code.html */
/* convert string to uppercase before this call */
int phonet (const char * inword, char * target,
int len,
phonetable & parms)
{
/** Do phonetic transformation. **/
/** "len" = length of "inword" incl. '\0'. **/
/** result: >= 0: length of "target" **/
/** otherwise: error **/
int i,j,k=0,n,p,z;
int k0,n0,p0=-333,z0;
char c, c0;
const char * s;
typedef unsigned char uchar;
char word[MAXPHONETUTF8LEN + 1];
if (len == -1) len = strlen(inword);
if (len > MAXPHONETUTF8LEN) return 0;
strcpy(word, inword);
/** check word **/
i = j = z = 0;
while ((c = word[i]) != '\0') {
n = parms.hash[(uchar) c];
z0 = 0;
if (n >= 0) {
/** check all rules for the same letter **/
while (parms.rules[n][0] == c) {
/** check whole string **/
k = 1; /** number of found letters **/
p = 5; /** default priority **/
s = parms.rules[n];
s++; /** important for (see below) "*(s-1)" **/
while (*s != '\0' && word[i+k] == *s
&& !isdigit (*s) && strchr ("(-<^$", *s) == NULL) {
k++;
s++;
}
if (*s == '(') {
/** check letters in "(..)" **/
if (isalpha(word[i+k]) // ...could be implied?
&& strchr(s+1, word[i+k]) != NULL) {
k++;
while (*s != ')')
s++;
s++;
}
}
p0 = (int) *s;
k0 = k;
while (*s == '-' && k > 1) {
k--;
s++;
}
if (*s == '<')
s++;
if (isdigit (*s)) {
/** determine priority **/
p = *s - '0';
s++;
}
if (*s == '^' && *(s+1) == '^')
s++;
if (*s == '\0'
|| (*s == '^'
&& (i == 0 || ! isalpha(word[i-1]))
&& (*(s+1) != '$'
|| (! isalpha(word[i+k0]) )))
|| (*s == '$' && i > 0
&& isalpha(word[i-1])
&& (! isalpha(word[i+k0]) )))
{
/** search for followup rules, if: **/
/** parms.followup and k > 1 and NO '-' in searchstring **/
c0 = word[i+k-1];
n0 = parms.hash[(uchar) c0];
// if (parms.followup && k > 1 && n0 >= 0
if (k > 1 && n0 >= 0
&& p0 != (int) '-' && word[i+k] != '\0') {
/** test follow-up rule for "word[i+k]" **/
while (parms.rules[n0][0] == c0) {
/** check whole string **/
k0 = k;
p0 = 5;
s = parms.rules[n0];
s++;
while (*s != '\0' && word[i+k0] == *s
&& ! isdigit(*s) && strchr("(-<^$",*s) == NULL) {
k0++;
s++;
}
if (*s == '(') {
/** check letters **/
if (isalpha(word[i+k0])
&& strchr (s+1, word[i+k0]) != NULL) {
k0++;
while (*s != ')' && *s != '\0')
s++;
if (*s == ')')
s++;
}
}
while (*s == '-') {
/** "k0" gets NOT reduced **/
/** because "if (k0 == k)" **/
s++;
}
if (*s == '<')
s++;
if (isdigit (*s)) {
p0 = *s - '0';
s++;
}
if (*s == '\0'
/** *s == '^' cuts **/
|| (*s == '$' && ! isalpha(word[i+k0])))
{
if (k0 == k) {
/** this is just a piece of the string **/
n0 += 2;
continue;
}
if (p0 < p) {
/** priority too low **/
n0 += 2;
continue;
}
/** rule fits; stop search **/
break;
}
n0 += 2;
} /** End of "while (parms.rules[n0][0] == c0)" **/
if (p0 >= p && parms.rules[n0][0] == c0) {
n += 2;
continue;
}
} /** end of follow-up stuff **/
/** replace string **/
s = parms.rules[n+1];
p0 = (parms.rules[n][0] != '\0'
&& strchr (parms.rules[n]+1,'<') != NULL) ? 1:0;
if (p0 == 1 && z == 0) {
/** rule with '<' is used **/
if (j > 0 && *s != '\0'
&& (target[j-1] == c || target[j-1] == *s)) {
j--;
}
z0 = 1;
z = 1;
k0 = 0;
while (*s != '\0' && word[i+k0] != '\0') {
word[i+k0] = *s;
k0++;
s++;
}
if (k > k0)
strmove (&word[0]+i+k0, &word[0]+i+k);
/** new "actual letter" **/
c = word[i];
}
else { /** no '<' rule used **/
i += k - 1;
z = 0;
while (*s != '\0'
&& *(s+1) != '\0' && j < len) {
if (j == 0 || target[j-1] != *s) {
target[j] = *s;
j++;
}
s++;
}
/** new "actual letter" **/
c = *s;
if (parms.rules[n][0] != '\0'
&& strstr (parms.rules[n]+1, "^^") != NULL) {
if (c != '\0') {
target[j] = c;
j++;
}
strmove (&word[0], &word[0]+i+1);
i = 0;
z0 = 1;
}
}
break;
} /** end of follow-up stuff **/
n += 2;
} /** end of while (parms.rules[n][0] == c) **/
} /** end of if (n >= 0) **/
if (z0 == 0) {
// if (k && (assert(p0!=-333),!p0) && j < len && c != '\0'
// && (!parms.collapse_result || j == 0 || target[j-1] != c)){
if (k && !p0 && j < len && c != '\0'
&& (1 || j == 0 || target[j-1] != c)){
/** condense only double letters **/
target[j] = c;
///printf("\n setting \n");
j++;
}
i++;
z = 0;
k=0;
}
} /** end of while ((c = word[i]) != '\0') **/
target[j] = '\0';
return (j);
} /** end of function "phonet" **/
robojournal-0.4.2/ui/hunspell/hunspell.hxx 0000644 0001750 0001750 00000020550 12211723646 017411 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ui/hunspell/hashmgr.hxx"
#include "ui/hunspell/affixmgr.hxx"
#include "ui/hunspell/suggestmgr.hxx"
#include "ui/hunspell/langnum.hxx"
#include "ui/hunspell/csutil.hxx"
#define SPELL_COMPOUND (1 << 0)
#define SPELL_FORBIDDEN (1 << 1)
#define SPELL_ALLCAP (1 << 2)
#define SPELL_NOCAP (1 << 3)
#define SPELL_INITCAP (1 << 4)
#define SPELL_XML ""
#define MAXDIC 20
#define MAXSUGGESTION 15
#define MAXSHARPS 5
#ifndef _MYSPELLMGR_HXX_
#define _MYSPELLMGR_HXX_
#ifdef HUNSPELL_STATIC
#define DLLEXPORT
#else
#ifdef HUNSPELL_EXPORTS
#define DLLEXPORT __declspec( dllexport )
#else
#define DLLEXPORT __declspec( dllimport )
#endif
#endif
#ifdef W32
class DLLEXPORT Hunspell
#else
class Hunspell
#endif
{
AffixMgr* pAMgr;
HashMgr* pHMgr[MAXDIC];
int maxdic;
SuggestMgr* pSMgr;
char * affixpath;
char * encoding;
struct cs_info * csconv;
int langnum;
int utf8;
int complexprefixes;
char** wordbreak;
public:
/* Hunspell(aff, dic) - constructor of Hunspell class
* input: path of affix file and dictionary file
*/
Hunspell(const char * affpath, const char * dpath, const char * key = NULL);
~Hunspell();
/* load extra dictionaries (only dic files) */
int add_dic(const char * dpath, const char * key = NULL);
/* spell(word) - spellcheck word
* output: 0 = bad word, not 0 = good word
*
* plus output:
* info: information bit array, fields:
* SPELL_COMPOUND = a compound word
* SPELL_FORBIDDEN = an explicit forbidden word
* root: root (stem), when input is a word with affix(es)
*/
int spell(const char * word, int * info = NULL, char ** root = NULL);
/* suggest(suggestions, word) - search suggestions
* input: pointer to an array of strings pointer and the (bad) word
* array of strings pointer (here *slst) may not be initialized
* output: number of suggestions in string array, and suggestions in
* a newly allocated array of strings (*slts will be NULL when number
* of suggestion equals 0.)
*/
int suggest(char*** slst, const char * word);
/* deallocate suggestion lists */
void free_list(char *** slst, int n);
char * get_dic_encoding();
/* morphological functions */
/* analyze(result, word) - morphological analysis of the word */
int analyze(char*** slst, const char * word);
/* stem(result, word) - stemmer function */
int stem(char*** slst, const char * word);
/* stem(result, analysis, n) - get stems from a morph. analysis
* example:
* char ** result, result2;
* int n1 = analyze(&result, "words");
* int n2 = stem(&result2, result, n1);
*/
int stem(char*** slst, char ** morph, int n);
/* generate(result, word, word2) - morphological generation by example(s) */
int generate(char*** slst, const char * word, const char * word2);
/* generate(result, word, desc, n) - generation by morph. description(s)
* example:
* char ** result;
* char * affix = "is:plural"; // description depends from dictionaries, too
* int n = generate(&result, "word", &affix, 1);
* for (int i = 0; i < n; i++) printf("%s\n", result[i]);
*/
int generate(char*** slst, const char * word, char ** desc, int n);
/* functions for run-time modification of the dictionary */
/* add word to the run-time dictionary */
int add(const char * word);
/* add word to the run-time dictionary with affix flags of
* the example (a dictionary word): Hunspell will recognize
* affixed forms of the new word, too.
*/
int add_with_affix(const char * word, const char * example);
/* remove word from the run-time dictionary */
int remove(const char * word);
/* other */
/* get extra word characters definied in affix file for tokenization */
const char * get_wordchars();
unsigned short * get_wordchars_utf16(int * len);
struct cs_info * get_csconv();
const char * get_version();
/* experimental and deprecated functions */
#ifdef HUNSPELL_EXPERIMENTAL
/* suffix is an affix flag string, similarly in dictionary files */
int put_word_suffix(const char * word, const char * suffix);
char * morph_with_correction(const char * word);
/* spec. suggestions */
int suggest_auto(char*** slst, const char * word);
int suggest_pos_stems(char*** slst, const char * word);
char * get_possible_root();
#endif
private:
int cleanword(char *, const char *, int * pcaptype, int * pabbrev);
int cleanword2(char *, const char *, w_char *, int * w_len, int * pcaptype, int * pabbrev);
void mkinitcap(char *);
int mkinitcap2(char * p, w_char * u, int nc);
int mkinitsmall2(char * p, w_char * u, int nc);
void mkallcap(char *);
int mkallcap2(char * p, w_char * u, int nc);
void mkallsmall(char *);
int mkallsmall2(char * p, w_char * u, int nc);
struct hentry * checkword(const char *, int * info, char **root);
char * sharps_u8_l1(char * dest, char * source);
hentry * spellsharps(char * base, char *, int, int, char * tmp, int * info, char **root);
int is_keepcase(const hentry * rv);
int insert_sug(char ***slst, char * word, int ns);
void cat_result(char * result, char * st);
char * stem_description(const char * desc);
int spellml(char*** slst, const char * word);
int get_xml_par(char * dest, const char * par, int maxl);
const char * get_xml_pos(const char * s, const char * attr);
int get_xml_list(char ***slst, char * list, char * tag);
int check_xml_par(char * q, char * attr, char * value);
};
#endif
robojournal-0.4.2/ui/hunspell/hunzip.cxx 0000644 0001750 0001750 00000020443 12211723646 017070 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_CLIENT
#include
#include
#include
#else
#include
#include
#include
#endif
#include "ui/hunspell/hunzip.hxx"
#define CODELEN 65536
#define BASEBITREC 5000
#define UNCOMPRESSED '\002'
#define MAGIC "hz0"
#define MAGIC_ENCRYPT "hz1"
#define MAGICLEN (sizeof(MAGIC) - 1)
int Hunzip::fail(const char * err, const char * par) {
fprintf(stderr, err, par);
return -1;
}
Hunzip::Hunzip(const char * file, const char * key) {
bufsiz = 0;
lastbit = 0;
inc = 0;
outc = 0;
dec = NULL;
filename = (char *) malloc(strlen(file) + 1);
if (filename) strcpy(filename, file);
if (getcode(key) == -1) bufsiz = -1;
else bufsiz = getbuf();
}
int Hunzip::getcode(const char * key) {
unsigned char c[2];
int i, j, n, p;
int allocatedbit = BASEBITREC;
const char * enc = key;
fin = fopen(filename, "rb");
if (!fin) return -1;
// read magic number
if ((fread(in, 1, 3, fin) < MAGICLEN)
|| !(strncmp(MAGIC, in, MAGICLEN) == 0 ||
strncmp(MAGIC_ENCRYPT, in, MAGICLEN) == 0)) {
return fail(MSG_FORMAT, filename);
}
// check encryption
if (strncmp(MAGIC_ENCRYPT, in, MAGICLEN) == 0) {
unsigned char cs;
if (!key) return fail(MSG_KEY, filename);
if (fread(&c, 1, 1, fin) < 1) return fail(MSG_FORMAT, filename);
for (cs = 0; *enc; enc++) cs ^= *enc;
if (cs != c[0]) return fail(MSG_KEY, filename);
enc = key;
} else key = NULL;
// read record count
if (fread(&c, 1, 2, fin) < 2) return fail(MSG_FORMAT, filename);
if (key) {
c[0] ^= *enc;
if (*(++enc) == '\0') enc = key;
c[1] ^= *enc;
}
n = ((int) c[0] << 8) + c[1];
dec = (struct bit *) malloc(BASEBITREC * sizeof(struct bit));
if (!dec) return fail(MSG_MEMORY, filename);
dec[0].v[0] = 0;
dec[0].v[1] = 0;
// read codes
for (i = 0; i < n; i++) {
unsigned char l;
if (fread(c, 1, 2, fin) < 2) return fail(MSG_FORMAT, filename);
if (key) {
if (*(++enc) == '\0') enc = key;
c[0] ^= *enc;
if (*(++enc) == '\0') enc = key;
c[1] ^= *enc;
}
if (fread(&l, 1, 1, fin) < 1) return fail(MSG_FORMAT, filename);
if (key) {
if (*(++enc) == '\0') enc = key;
l ^= *enc;
}
if (fread(in, 1, l/8+1, fin) < (size_t) l/8+1) return fail(MSG_FORMAT, filename);
if (key) for (j = 0; j <= l/8; j++) {
if (*(++enc) == '\0') enc = key;
in[j] ^= *enc;
}
p = 0;
for (j = 0; j < l; j++) {
int b = (in[j/8] & (1 << (7 - (j % 8)))) ? 1 : 0;
int oldp = p;
p = dec[p].v[b];
if (p == 0) {
lastbit++;
if (lastbit == allocatedbit) {
allocatedbit += BASEBITREC;
dec = (struct bit *) realloc(dec, allocatedbit * sizeof(struct bit));
}
dec[lastbit].v[0] = 0;
dec[lastbit].v[1] = 0;
dec[oldp].v[b] = lastbit;
p = lastbit;
}
}
dec[p].c[0] = c[0];
dec[p].c[1] = c[1];
}
return 0;
}
Hunzip::~Hunzip()
{
if (dec) free(dec);
if (fin) fclose(fin);
if (filename) free(filename);
}
int Hunzip::getbuf() {
int p = 0;
int o = 0;
do {
if (inc == 0) inbits = fread(in, 1, BUFSIZE, fin) * 8;
for (; inc < inbits; inc++) {
int b = (in[inc / 8] & (1 << (7 - (inc % 8)))) ? 1 : 0;
int oldp = p;
p = dec[p].v[b];
if (p == 0) {
if (oldp == lastbit) {
fclose(fin);
fin = NULL;
// add last odd byte
if (dec[lastbit].c[0]) out[o++] = dec[lastbit].c[1];
return o;
}
out[o++] = dec[oldp].c[0];
out[o++] = dec[oldp].c[1];
if (o == BUFSIZE) return o;
p = dec[p].v[b];
}
}
inc = 0;
} while (inbits == BUFSIZE * 8);
return fail(MSG_FORMAT, filename);
}
const char * Hunzip::getline() {
char linebuf[BUFSIZE];
int l = 0, eol = 0, left = 0, right = 0;
if (bufsiz == -1) return NULL;
while (l < bufsiz && !eol) {
linebuf[l++] = out[outc];
switch (out[outc]) {
case '\t': break;
case 31: { // escape
if (++outc == bufsiz) {
bufsiz = getbuf();
outc = 0;
}
linebuf[l - 1] = out[outc];
break;
}
case ' ': break;
default: if (((unsigned char) out[outc]) < 47) {
if (out[outc] > 32) {
right = out[outc] - 31;
if (++outc == bufsiz) {
bufsiz = getbuf();
outc = 0;
}
}
if (out[outc] == 30) left = 9; else left = out[outc];
linebuf[l-1] = '\n';
eol = 1;
}
}
if (++outc == bufsiz) {
outc = 0;
bufsiz = fin ? getbuf(): -1;
}
}
if (right) strcpy(linebuf + l - 1, line + strlen(line) - right - 1);
else linebuf[l] = '\0';
strcpy(line + left, linebuf);
return line;
}
robojournal-0.4.2/ui/hunspell/atypes.hxx 0000644 0001750 0001750 00000011050 12211723646 017057 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _ATYPES_HXX_
#define _ATYPES_HXX_
#ifndef HUNSPELL_WARNING
#ifdef HUNSPELL_WARNING_ON
#define HUNSPELL_WARNING fprintf
#else
// empty inline function to switch off warnings (instead of the C99 standard variadic macros)
static inline void HUNSPELL_WARNING(FILE *, const char *, ...) {}
#endif
#endif
// HUNSTEM def.
#define HUNSTEM
#include "ui/hunspell/hashmgr.hxx"
#include "ui/hunspell/w_char.hxx"
#define SETSIZE 256
#define CONTSIZE 65536
#define MAXWORDLEN 100
#define MAXWORDUTF8LEN 256
// affentry options
#define aeXPRODUCT (1 << 0)
#define aeUTF8 (1 << 1)
#define aeALIASF (1 << 2)
#define aeALIASM (1 << 3)
#define aeLONGCOND (1 << 4)
// compound options
#define IN_CPD_NOT 0
#define IN_CPD_BEGIN 1
#define IN_CPD_END 2
#define IN_CPD_OTHER 3
#define MAXLNLEN 8192
#define MINCPDLEN 3
#define MAXCOMPOUND 10
#define MAXCONDLEN 20
#define MAXCONDLEN_1 (MAXCONDLEN - sizeof(char *))
#define MAXACC 1000
#define FLAG unsigned short
#define FLAG_NULL 0x00
#define FREE_FLAG(a) a = 0
#define TESTAFF( a, b , c ) flag_bsearch((unsigned short *) a, (unsigned short) b, c)
struct affentry
{
char * strip;
char * appnd;
unsigned char stripl;
unsigned char appndl;
char numconds;
char opts;
unsigned short aflag;
unsigned short * contclass;
short contclasslen;
union {
char conds[MAXCONDLEN];
struct {
char conds1[MAXCONDLEN_1];
char * conds2;
} l;
} c;
char * morphcode;
};
struct guessword {
char * word;
bool allow;
char * orig;
};
struct mapentry {
char * set;
w_char * set_utf16;
int len;
};
struct flagentry {
FLAG * def;
int len;
};
#endif
robojournal-0.4.2/ui/hunspell/filemgr.cxx 0000644 0001750 0001750 00000007255 12211723646 017206 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include
#include
#include
#include "ui/hunspell/filemgr.hxx"
int FileMgr::fail(const char * err, const char * par) {
fprintf(stderr, err, par);
return -1;
}
FileMgr::FileMgr(const char * file, const char * key) {
hin = NULL;
fin = fopen(file, "r");
if (!fin) {
// check hzipped file
char * st = (char *) malloc(strlen(file) + strlen(HZIP_EXTENSION));
if (st) {
strcpy(st, file);
strcat(st, HZIP_EXTENSION);
hin = new Hunzip(st, key);
}
}
if (!fin && !hin) fail(MSG_OPEN, file);
}
FileMgr::~FileMgr()
{
if (fin) fclose(fin);
if (hin) delete hin;
}
char * FileMgr::getline() {
const char * l;
if (fin) return fgets(in, BUFSIZE - 1, fin);
if (hin && (l = hin->getline())) return strcpy(in, l);
return NULL;
}
robojournal-0.4.2/ui/hunspell/license.myspell 0000644 0001750 0001750 00000005540 12211723646 020061 0 ustar will will /*
* Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
* And Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. All modifications to the source code must be clearly marked as
* such. Binary redistributions based on modified source code
* must be clearly marked as modified versions in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS 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
* KEVIN B. HENDRICKS 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.
*
*
* NOTE: A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* An almost complete rewrite of MySpell for use by
* the Mozilla project has been developed by David Einstein
* (Deinst@world.std.com). David and I are now
* working on parallel development tracks to help
* our respective projects (Mozilla and OpenOffice.org
* and we will maintain full affix file and dictionary
* file compatibility and work on merging our versions
* of MySpell back into a single tree. David has been
* a significant help in improving MySpell.
*
* Special thanks also go to La'szlo' Ne'meth
* who is the author of the
* Hungarian dictionary and who developed and contributed
* the code to support compound words in MySpell
* and fixed numerous problems with the encoding
* case conversion tables.
*
*/
robojournal-0.4.2/ui/hunspell/phonet.hxx 0000644 0001750 0001750 00000010517 12211723646 017056 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* phonetic.c - generic replacement aglogithms for phonetic transformation
Copyright (C) 2000 Bjoern Jacke
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation;
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see
.
Changelog:
2000-01-05 Bjoern Jacke
Initial Release insprired by the article about phonetic
transformations out of c't 25/1999
2007-07-26 Bjoern Jacke
Released under MPL/GPL/LGPL tri-license for Hunspell
2007-08-23 Laszlo Nemeth
Porting from Aspell to Hunspell using C-like structs
*/
#ifndef __PHONETHXX__
#define __PHONETHXX__
#define HASHSIZE 256
#define MAXPHONETLEN 256
#define MAXPHONETUTF8LEN (MAXPHONETLEN * 4)
struct phonetable {
char utf8;
cs_info * lang;
int num;
char * * rules;
int hash[HASHSIZE];
};
void init_phonet_hash(phonetable & parms);
int phonet (const char * inword, char * target,
int len, phonetable & phone);
#endif
robojournal-0.4.2/ui/hunspell/affentry.cxx 0000644 0001750 0001750 00000114377 12211723646 017403 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "license.hunspell"
#include "license.myspell"
#ifndef MOZILLA_CLIENT
#include
#include
#include
#include
#else
#include
#include
#include
#include
#endif
#include "ui/hunspell/affentry.hxx"
#include "ui/hunspell/csutil.hxx"
#ifndef MOZILLA_CLIENT
#ifndef WIN32
using namespace std;
#endif
#endif
PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp)
{
// register affix manager
pmyMgr = pmgr;
// set up its intial values
aflag = dp->aflag; // flag
strip = dp->strip; // string to strip
appnd = dp->appnd; // string to append
stripl = dp->stripl; // length of strip string
appndl = dp->appndl; // length of append string
numconds = dp->numconds; // length of the condition
opts = dp->opts; // cross product flag
// then copy over all of the conditions
if (opts & aeLONGCOND) {
memcpy(c.conds, dp->c.l.conds1, MAXCONDLEN_1);
c.l.conds2 = dp->c.l.conds2;
} else memcpy(c.conds, dp->c.conds, MAXCONDLEN);
next = NULL;
nextne = NULL;
nexteq = NULL;
morphcode = dp->morphcode;
contclass = dp->contclass;
contclasslen = dp->contclasslen;
}
PfxEntry::~PfxEntry()
{
aflag = 0;
if (appnd) free(appnd);
if (strip) free(strip);
pmyMgr = NULL;
appnd = NULL;
strip = NULL;
if (opts & aeLONGCOND) free(c.l.conds2);
if (morphcode && !(opts & aeALIASM)) free(morphcode);
if (contclass && !(opts & aeALIASF)) free(contclass);
}
// add prefix to this word assuming conditions hold
char * PfxEntry::add(const char * word, int len)
{
char tword[MAXWORDUTF8LEN + 4];
if ((len > stripl) && (len >= numconds) && test_condition(word) &&
(!stripl || (strncmp(word, strip, stripl) == 0)) &&
((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
/* we have a match so add prefix */
char * pp = tword;
if (appndl) {
strcpy(tword,appnd);
pp += appndl;
}
strcpy(pp, (word + stripl));
return mystrdup(tword);
}
return NULL;
}
inline char * PfxEntry::nextchar(char * p) {
if (p) {
p++;
if (opts & aeLONGCOND) {
// jump to the 2nd part of the condition
if (p == c.conds + MAXCONDLEN_1) return c.l.conds2;
// end of the MAXCONDLEN length condition
} else if (p == c.conds + MAXCONDLEN) return NULL;
}
return p;
}
inline int PfxEntry::test_condition(const char * st)
{
const char * pos = NULL; // group with pos input position
bool neg = false; // complementer
bool ingroup = false; // character in the group
if (numconds == 0) return 1;
char * p = c.conds;
while (1) {
switch (*p) {
case '\0': return 1;
case '[': {
neg = false;
ingroup = false;
p = nextchar(p);
pos = st; break;
}
case '^': { p = nextchar(p); neg = true; break; }
case ']': {
if ((neg && ingroup) || (!neg && !ingroup)) return 0;
pos = NULL;
p = nextchar(p);
// skip the next character
if (!ingroup) for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++);
if (*st == '\0' && p && *p != '\0') return 0; // word <= condition
break;
}
case '.': if (!pos) { // dots are not metacharacters in groups: [.]
p = nextchar(p);
// skip the next character
for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++);
if (*st == '\0') return 0; // word <= condition
break;
}
default: {
if (*st == *p) {
st++;
p = nextchar(p);
if ((opts & aeUTF8) && (*(st - 1) & 0x80)) { // multibyte
while (p && (*p & 0xc0) == 0x80) { // character
if (*p != *st) {
if (!pos) return 0;
st = pos;
break;
}
p = nextchar(p);
st++;
}
if (pos && st != pos) {
ingroup = true;
while (p && *p != ']' && (p = nextchar(p)));
}
} else if (pos) {
ingroup = true;
while (p && *p != ']' && (p = nextchar(p)));
}
} else if (pos) { // group
p = nextchar(p);
} else return 0;
}
}
if (!p) return 1;
}
}
// check if this prefix entry matches
struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound, const FLAG needflag)
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry of root word or NULL
char tmpword[MAXWORDUTF8LEN + 4];
// on entry prefix is 0 length or already matches the beginning of the word.
// So if the remaining root word has positive length
// and if there are enough chars in root word and added back strip chars
// to meet the number of characters conditions, then test it
tmpl = len - appndl;
if (tmpl > 0) {
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
if (stripl) strcpy (tmpword, strip);
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
// are met. Please see the appendix at the end of
// this file for more info on exactly what is being
// tested
// if all conditions are met then check if resulting
// root word in the dictionary
if (test_condition(tmpword)) {
tmpl += stripl;
if ((he = pmyMgr->lookup(tmpword)) != NULL) {
do {
if (TESTAFF(he->astr, aflag, he->alen) &&
// forbid single prefixes with needaffix flag
! TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
// needflag
((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
(contclass && TESTAFF(contclass, needflag, contclasslen))))
return he;
he = he->next_homonym; // check homonyms
} while (he);
}
// prefix matched but no root word was found
// if aeXPRODUCT is allowed, try again but now
// ross checked combined with a suffix
//if ((opts & aeXPRODUCT) && in_compound) {
if ((opts & aeXPRODUCT)) {
he = pmyMgr->suffix_check(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, NULL,
0, NULL, FLAG_NULL, needflag, in_compound);
if (he) return he;
}
}
}
return NULL;
}
// check if this prefix entry matches
struct hentry * PfxEntry::check_twosfx(const char * word, int len,
char in_compound, const FLAG needflag)
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry of root word or NULL
char tmpword[MAXWORDUTF8LEN + 4];
// on entry prefix is 0 length or already matches the beginning of the word.
// So if the remaining root word has positive length
// and if there are enough chars in root word and added back strip chars
// to meet the number of characters conditions, then test it
tmpl = len - appndl;
if ((tmpl > 0) && (tmpl + stripl >= numconds)) {
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
if (stripl) strcpy (tmpword, strip);
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
// are met. Please see the appendix at the end of
// this file for more info on exactly what is being
// tested
// if all conditions are met then check if resulting
// root word in the dictionary
if (test_condition(tmpword)) {
tmpl += stripl;
// prefix matched but no root word was found
// if aeXPRODUCT is allowed, try again but now
// cross checked combined with a suffix
if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
he = pmyMgr->suffix_check_twosfx(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this, needflag);
if (he) return he;
}
}
}
return NULL;
}
// check if this prefix entry matches
char * PfxEntry::check_twosfx_morph(const char * word, int len,
char in_compound, const FLAG needflag)
{
int tmpl; // length of tmpword
char tmpword[MAXWORDUTF8LEN + 4];
// on entry prefix is 0 length or already matches the beginning of the word.
// So if the remaining root word has positive length
// and if there are enough chars in root word and added back strip chars
// to meet the number of characters conditions, then test it
tmpl = len - appndl;
if ((tmpl > 0) && (tmpl + stripl >= numconds)) {
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
if (stripl) strcpy (tmpword, strip);
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
// are met. Please see the appendix at the end of
// this file for more info on exactly what is being
// tested
// if all conditions are met then check if resulting
// root word in the dictionary
if (test_condition(tmpword)) {
tmpl += stripl;
// prefix matched but no root word was found
// if aeXPRODUCT is allowed, try again but now
// ross checked combined with a suffix
if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
return pmyMgr->suffix_check_twosfx_morph(tmpword, tmpl,
aeXPRODUCT, (AffEntry *)this, needflag);
}
}
}
return NULL;
}
// check if this prefix entry matches
char * PfxEntry::check_morph(const char * word, int len, char in_compound, const FLAG needflag)
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry of root word or NULL
char tmpword[MAXWORDUTF8LEN + 4];
char result[MAXLNLEN];
char * st;
*result = '\0';
// on entry prefix is 0 length or already matches the beginning of the word.
// So if the remaining root word has positive length
// and if there are enough chars in root word and added back strip chars
// to meet the number of characters conditions, then test it
tmpl = len - appndl;
if ((tmpl > 0) && (tmpl + stripl >= numconds)) {
// generate new root word by removing prefix and adding
// back any characters that would have been stripped
if (stripl) strcpy (tmpword, strip);
strcpy ((tmpword + stripl), (word + appndl));
// now make sure all of the conditions on characters
// are met. Please see the appendix at the end of
// this file for more info on exactly what is being
// tested
// if all conditions are met then check if resulting
// root word in the dictionary
if (test_condition(tmpword)) {
tmpl += stripl;
if ((he = pmyMgr->lookup(tmpword)) != NULL) {
do {
if (TESTAFF(he->astr, aflag, he->alen) &&
// forbid single prefixes with needaffix flag
! TESTAFF(contclass, pmyMgr->get_needaffix(), contclasslen) &&
// needflag
((!needflag) || TESTAFF(he->astr, needflag, he->alen) ||
(contclass && TESTAFF(contclass, needflag, contclasslen)))) {
if (morphcode) {
strcat(result, " ");
strcat(result, morphcode);
} else strcat(result,getKey());
if (!HENTRY_FIND(he, MORPH_STEM)) {
strcat(result, " ");
strcat(result, MORPH_STEM);
strcat(result, HENTRY_WORD(he));
}
// store the pointer of the hash entry
if (HENTRY_DATA(he)) {
strcat(result, " ");
strcat(result, HENTRY_DATA2(he));
} else {
// return with debug information
char * flag = pmyMgr->encode_flag(getFlag());
strcat(result, " ");
strcat(result, MORPH_FLAG);
strcat(result, flag);
free(flag);
}
strcat(result, "\n");
}
he = he->next_homonym;
} while (he);
}
// prefix matched but no root word was found
// if aeXPRODUCT is allowed, try again but now
// ross checked combined with a suffix
if ((opts & aeXPRODUCT) && (in_compound != IN_CPD_BEGIN)) {
st = pmyMgr->suffix_check_morph(tmpword, tmpl, aeXPRODUCT, (AffEntry *)this,
FLAG_NULL, needflag);
if (st) {
strcat(result, st);
free(st);
}
}
}
}
if (*result) return mystrdup(result);
return NULL;
}
SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp)
{
// register affix manager
pmyMgr = pmgr;
// set up its intial values
aflag = dp->aflag; // char flag
strip = dp->strip; // string to strip
appnd = dp->appnd; // string to append
stripl = dp->stripl; // length of strip string
appndl = dp->appndl; // length of append string
numconds = dp->numconds; // length of the condition
opts = dp->opts; // cross product flag
// then copy over all of the conditions
if (opts & aeLONGCOND) {
memcpy(c.l.conds1, dp->c.l.conds1, MAXCONDLEN_1);
c.l.conds2 = dp->c.l.conds2;
} else memcpy(c.conds, dp->c.conds, MAXCONDLEN);
rappnd = myrevstrdup(appnd);
morphcode = dp->morphcode;
contclass = dp->contclass;
contclasslen = dp->contclasslen;
}
SfxEntry::~SfxEntry()
{
aflag = 0;
if (appnd) free(appnd);
if (rappnd) free(rappnd);
if (strip) free(strip);
pmyMgr = NULL;
appnd = NULL;
strip = NULL;
if (opts & aeLONGCOND) free(c.l.conds2);
if (morphcode && !(opts & aeALIASM)) free(morphcode);
if (contclass && !(opts & aeALIASF)) free(contclass);
}
// add suffix to this word assuming conditions hold
char * SfxEntry::add(const char * word, int len)
{
char tword[MAXWORDUTF8LEN + 4];
/* make sure all conditions match */
if ((len > stripl) && (len >= numconds) && test_condition(word + len, word) &&
(!stripl || (strcmp(word + len - stripl, strip) == 0)) &&
((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
/* we have a match so add suffix */
strcpy(tword,word);
if (appndl) {
strcpy(tword + len - stripl, appnd);
} else {
*(tword + len - stripl) = '\0';
}
return mystrdup(tword);
}
return NULL;
}
inline char * SfxEntry::nextchar(char * p) {
p++;
if (opts & aeLONGCOND) {
// jump to the 2nd part of the condition
if (p == c.l.conds1 + MAXCONDLEN_1) return c.l.conds2;
// end of the MAXCONDLEN length condition
} else if (p == c.conds + MAXCONDLEN) return NULL;
return p;
}
inline int SfxEntry::test_condition(const char * st, const char * beg)
{
const char * pos = NULL; // group with pos input position
bool neg = false; // complementer
bool ingroup = false; // character in the group
if (numconds == 0) return 1;
char * p = c.conds;
st--;
int i = 1;
while (1) {
switch (*p) {
case '\0': return 1;
case '[': { p = nextchar(p); pos = st; break; }
case '^': { p = nextchar(p); neg = true; break; }
case ']': { if (!neg && !ingroup) return 0;
i++;
// skip the next character
if (!ingroup) {
for (; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
st--;
}
pos = NULL;
neg = false;
ingroup = false;
p = nextchar(p);
if (st < beg && p && *p != '\0') return 0; // word <= condition
break;
}
case '.': if (!pos) { // dots are not metacharacters in groups: [.]
p = nextchar(p);
// skip the next character
for (st--; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
if (st < beg) return 0; // word <= condition
if (*st & 0x80) { // head of the UTF-8 character
st--;
if (st < beg) return 0; // word <= condition
}
break;
}
default: {
if (*st == *p) {
p = nextchar(p);
if ((opts & aeUTF8) && (*st & 0x80)) {
st--;
while (p && (st >= beg)) {
if (*p != *st) {
if (!pos) return 0;
st = pos;
break;
}
// first byte of the UTF-8 multibyte character
if ((*p & 0xc0) != 0x80) break;
p = nextchar(p);
st--;
}
if (pos && st != pos) {
if (neg) return 0;
else if (i == numconds) return 1;
ingroup = true;
while (p && *p != ']' && (p = nextchar(p)));
}
if (p && *p != '\0') p = nextchar(p);
} else if (pos) {
if (neg) return 0;
else if (i == numconds) return 1;
ingroup = true;
st--;
}
if (!pos) {
i++;
st--;
if (st < beg && p && *p != '\0') return 0; // word <= condition
}
} else if (pos) { // group
p = nextchar(p);
} else return 0;
}
}
if (!p) return 1;
}
}
// see if this suffix is present in the word
struct hentry * SfxEntry::checkword(const char * word, int len, int optflags,
AffEntry* ppfx, char ** wlst, int maxSug, int * ns, const FLAG cclass, const FLAG needflag,
const FLAG badflag)
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry pointer
unsigned char * cp;
char tmpword[MAXWORDUTF8LEN + 4];
PfxEntry* ep = (PfxEntry *) ppfx;
// if this suffix is being cross checked with a prefix
// but it does not support cross products skip it
if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0))
return NULL;
// upon entry suffix is 0 length or already matches the end of the word.
// So if the remaining root word has positive length
// and if there are enough chars in root word and added back strip chars
// to meet the number of characters conditions, then test it
tmpl = len - appndl;
// the second condition is not enough for UTF-8 strings
// it checked in test_condition()
if ((tmpl > 0) && (tmpl + stripl >= numconds)) {
// generate new root word by removing suffix and adding
// back any characters that would have been stripped or
// or null terminating the shorter string
strcpy (tmpword, word);
cp = (unsigned char *)(tmpword + tmpl);
if (stripl) {
strcpy ((char *)cp, strip);
tmpl += stripl;
cp = (unsigned char *)(tmpword + tmpl);
} else *cp = '\0';
// now make sure all of the conditions on characters
// are met. Please see the appendix at the end of
// this file for more info on exactly what is being
// tested
// if all conditions are met then check if resulting
// root word in the dictionary
if (test_condition((char *) cp, (char *) tmpword)) {
#ifdef SZOSZABLYA_POSSIBLE_ROOTS
fprintf(stdout,"%s %s %c\n", word, tmpword, aflag);
#endif
if ((he = pmyMgr->lookup(tmpword)) != NULL) {
do {
// check conditional suffix (enabled by prefix)
if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() &&
TESTAFF(ep->getCont(), aflag, ep->getContLen()))) &&
(((optflags & aeXPRODUCT) == 0) ||
TESTAFF(he->astr, ep->getFlag(), he->alen) ||
// enabled by prefix
((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))
) &&
// handle cont. class
((!cclass) ||
((contclass) && TESTAFF(contclass, cclass, contclasslen))
) &&
// check only in compound homonyms (bad flags)
(!badflag || !TESTAFF(he->astr, badflag, he->alen)
) &&
// handle required flag
((!needflag) ||
(TESTAFF(he->astr, needflag, he->alen) ||
((contclass) && TESTAFF(contclass, needflag, contclasslen)))
)
) return he;
he = he->next_homonym; // check homonyms
} while (he);
// obsolote stemming code (used only by the
// experimental SuffixMgr:suggest_pos_stems)
// store resulting root in wlst
} else if (wlst && (*ns < maxSug)) {
int cwrd = 1;
for (int k=0; k < *ns; k++)
if (strcmp(tmpword, wlst[k]) == 0) cwrd = 0;
if (cwrd) {
wlst[*ns] = mystrdup(tmpword);
if (wlst[*ns] == NULL) {
for (int j=0; j<*ns; j++) free(wlst[j]);
*ns = -1;
return NULL;
}
(*ns)++;
}
}
}
}
return NULL;
}
// see if two-level suffix is present in the word
struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags,
AffEntry* ppfx, const FLAG needflag)
{
int tmpl; // length of tmpword
struct hentry * he; // hash entry pointer
unsigned char * cp;
char tmpword[MAXWORDUTF8LEN + 4];
PfxEntry* ep = (PfxEntry *) ppfx;
// if this suffix is being cross checked with a prefix
// but it does not support cross products skip it
if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0)
return NULL;
// upon entry suffix is 0 length or already matches the end of the word.
// So if the remaining root word has positive length
// and if there are enough chars in root word and added back strip chars
// to meet the number of characters conditions, then test it
tmpl = len - appndl;
if ((tmpl > 0) && (tmpl + stripl >= numconds)) {
// generate new root word by removing suffix and adding
// back any characters that would have been stripped or
// or null terminating the shorter string
strcpy (tmpword, word);
cp = (unsigned char *)(tmpword + tmpl);
if (stripl) {
strcpy ((char *)cp, strip);
tmpl += stripl;
cp = (unsigned char *)(tmpword + tmpl);
} else *cp = '\0';
// now make sure all of the conditions on characters
// are met. Please see the appendix at the end of
// this file for more info on exactly what is being
// tested
// if all conditions are met then recall suffix_check
if (test_condition((char *) cp, (char *) tmpword)) {
if (ppfx) {
// handle conditional suffix
if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))
he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag);
else
he = pmyMgr->suffix_check(tmpword, tmpl, optflags, ppfx, NULL, 0, NULL, (FLAG) aflag, needflag);
} else {
he = pmyMgr->suffix_check(tmpword, tmpl, 0, NULL, NULL, 0, NULL, (FLAG) aflag, needflag);
}
if (he) return he;
}
}
return NULL;
}
// see if two-level suffix is present in the word
char * SfxEntry::check_twosfx_morph(const char * word, int len, int optflags,
AffEntry* ppfx, const FLAG needflag)
{
int tmpl; // length of tmpword
unsigned char * cp;
char tmpword[MAXWORDUTF8LEN + 4];
PfxEntry* ep = (PfxEntry *) ppfx;
char * st;
char result[MAXLNLEN];
*result = '\0';
// if this suffix is being cross checked with a prefix
// but it does not support cross products skip it
if ((optflags & aeXPRODUCT) != 0 && (opts & aeXPRODUCT) == 0)
return NULL;
// upon entry suffix is 0 length or already matches the end of the word.
// So if the remaining root word has positive length
// and if there are enough chars in root word and added back strip chars
// to meet the number of characters conditions, then test it
tmpl = len - appndl;
if ((tmpl > 0) && (tmpl + stripl >= numconds)) {
// generate new root word by removing suffix and adding
// back any characters that would have been stripped or
// or null terminating the shorter string
strcpy (tmpword, word);
cp = (unsigned char *)(tmpword + tmpl);
if (stripl) {
strcpy ((char *)cp, strip);
tmpl += stripl;
cp = (unsigned char *)(tmpword + tmpl);
} else *cp = '\0';
// now make sure all of the conditions on characters
// are met. Please see the appendix at the end of
// this file for more info on exactly what is being
// tested
// if all conditions are met then recall suffix_check
if (test_condition((char *) cp, (char *) tmpword)) {
if (ppfx) {
// handle conditional suffix
if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) {
st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag);
if (st) {
if (((PfxEntry *) ppfx)->getMorph()) {
strcat(result, ((PfxEntry *) ppfx)->getMorph());
strcat(result, " ");
}
strcat(result,st);
free(st);
mychomp(result);
}
} else {
st = pmyMgr->suffix_check_morph(tmpword, tmpl, optflags, ppfx, aflag, needflag);
if (st) {
strcat(result, st);
free(st);
mychomp(result);
}
}
} else {
st = pmyMgr->suffix_check_morph(tmpword, tmpl, 0, NULL, aflag, needflag);
if (st) {
strcat(result, st);
free(st);
mychomp(result);
}
}
if (*result) return mystrdup(result);
}
}
return NULL;
}
// get next homonym with same affix
struct hentry * SfxEntry::get_next_homonym(struct hentry * he, int optflags, AffEntry* ppfx,
const FLAG cclass, const FLAG needflag)
{
PfxEntry* ep = (PfxEntry *) ppfx;
FLAG eFlag = ep ? ep->getFlag() : FLAG_NULL;
while (he->next_homonym) {
he = he->next_homonym;
if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() && TESTAFF(ep->getCont(), aflag, ep->getContLen()))) &&
((optflags & aeXPRODUCT) == 0 ||
TESTAFF(he->astr, eFlag, he->alen) ||
// handle conditional suffix
((contclass) && TESTAFF(contclass, eFlag, contclasslen))
) &&
// handle cont. class
((!cclass) ||
((contclass) && TESTAFF(contclass, cclass, contclasslen))
) &&
// handle required flag
((!needflag) ||
(TESTAFF(he->astr, needflag, he->alen) ||
((contclass) && TESTAFF(contclass, needflag, contclasslen)))
)
) return he;
}
return NULL;
}
#if 0
Appendix: Understanding Affix Code
An affix is either a prefix or a suffix attached to root words to make
other words.
Basically a Prefix or a Suffix is set of AffEntry objects
which store information about the prefix or suffix along
with supporting routines to check if a word has a particular
prefix or suffix or a combination.
The structure affentry is defined as follows:
struct affentry
{
unsigned short aflag; // ID used to represent the affix
char * strip; // string to strip before adding affix
char * appnd; // the affix string to add
unsigned char stripl; // length of the strip string
unsigned char appndl; // length of the affix string
char numconds; // the number of conditions that must be met
char opts; // flag: aeXPRODUCT- combine both prefix and suffix
char conds[SETSIZE]; // array which encodes the conditions to be met
};
Here is a suffix borrowed from the en_US.aff file. This file
is whitespace delimited.
SFX D Y 4
SFX D 0 e d
SFX D y ied [^aeiou]y
SFX D 0 ed [^ey]
SFX D 0 ed [aeiou]y
This information can be interpreted as follows:
In the first line has 4 fields
Field
-----
1 SFX - indicates this is a suffix
2 D - is the name of the character flag which represents this suffix
3 Y - indicates it can be combined with prefixes (cross product)
4 4 - indicates that sequence of 4 affentry structures are needed to
properly store the affix information
The remaining lines describe the unique information for the 4 SfxEntry
objects that make up this affix. Each line can be interpreted
as follows: (note fields 1 and 2 are as a check against line 1 info)
Field
-----
1 SFX - indicates this is a suffix
2 D - is the name of the character flag for this affix
3 y - the string of chars to strip off before adding affix
(a 0 here indicates the NULL string)
4 ied - the string of affix characters to add
5 [^aeiou]y - the conditions which must be met before the affix
can be applied
Field 5 is interesting. Since this is a suffix, field 5 tells us that
there are 2 conditions that must be met. The first condition is that
the next to the last character in the word must *NOT* be any of the
following "a", "e", "i", "o" or "u". The second condition is that
the last character of the word must end in "y".
So how can we encode this information concisely and be able to
test for both conditions in a fast manner? The answer is found
but studying the wonderful ispell code of Geoff Kuenning, et.al.
(now available under a normal BSD license).
If we set up a conds array of 256 bytes indexed (0 to 255) and access it
using a character (cast to an unsigned char) of a string, we have 8 bits
of information we can store about that character. Specifically we
could use each bit to say if that character is allowed in any of the
last (or first for prefixes) 8 characters of the word.
Basically, each character at one end of the word (up to the number
of conditions) is used to index into the conds array and the resulting
value found there says whether the that character is valid for a
specific character position in the word.
For prefixes, it does this by setting bit 0 if that char is valid
in the first position, bit 1 if valid in the second position, and so on.
If a bit is not set, then that char is not valid for that postion in the
word.
If working with suffixes bit 0 is used for the character closest
to the front, bit 1 for the next character towards the end, ...,
with bit numconds-1 representing the last char at the end of the string.
Note: since entries in the conds[] are 8 bits, only 8 conditions
(read that only 8 character positions) can be examined at one
end of a word (the beginning for prefixes and the end for suffixes.
So to make this clearer, lets encode the conds array values for the
first two affentries for the suffix D described earlier.
For the first affentry:
numconds = 1 (only examine the last character)
conds['e'] = (1 << 0) (the word must end in an E)
all others are all 0
For the second affentry:
numconds = 2 (only examine the last two characters)
conds[X] = conds[X] | (1 << 0) (aeiou are not allowed)
where X is all characters *but* a, e, i, o, or u
conds['y'] = (1 << 1) (the last char must be a y)
all other bits for all other entries in the conds array are zero
#endif
robojournal-0.4.2/ui/hunspell/csutil.cxx 0000644 0001750 0001750 00000374531 12211723646 017070 0 ustar will will /*
This file is part of RoboJournal.
Copyright (c) 2013 by Will Kraft .
MADE IN USA
RoboJournal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RoboJournal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RoboJournal. If not, see .
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Hunspell, based on MySpell.
*
* The Initial Developers of the Original Code are
* Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
* Portions created by the Initial Developers are Copyright (C) 2002-2005
* the Initial Developers. All Rights Reserved.
*
* Contributor(s):
* David Einstein
* Davide Prina
* Giuseppe Modugno
* Gianluca Turconi
* Simon Brouwer
* Noll Janos
* Biro Arpad
* Goldman Eleonora
* Sarlos Tamas
* Bencsath Boldizsar
* Halacsy Peter
* Dvornik Laszlo
* Gefferth Andras
* Nagy Viktor
* Varga Daniel
* Chris Halls
* Rene Engelhard
* Bram Moolenaar
* Dafydd Jones
* Harri Pitkanen
* Andras Timar
* Tor Lillqvist
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "license.hunspell"
#include "license.myspell"
#ifndef MOZILLA_CLIENT
#include
#include
#include
#include
#else
#include
#include