pax_global_header00006660000000000000000000000064133723623400014515gustar00rootroot0000000000000052 comment=4ddd8ed5ca6484b930b111aec50c2750a6119a0f hunspell-1.7.0/000077500000000000000000000000001337236234000133545ustar00rootroot00000000000000hunspell-1.7.0/.gitignore000066400000000000000000000021561337236234000153500ustar00rootroot00000000000000# autom4te /autom4te.cache # aclocal /aclocal.m4 # libtoolize https://www.gnu.org/software/libtool/ /ltmain.sh /m4/libtool.m4 /m4/ltoptions.m4 /m4/ltsugar.m4 /m4/ltversion.m4 /m4/lt~obsolete.m4 # http://www.gnu.org/software/autoconf /configure # autoheader /config.h.in # http://www.gnu.org/software/automake /compile /config.guess /config.sub /install-sh /missing /INSTALL /ar-lib /depcomp /mdate-sh /mkinstalldirs /py-compile /tap-driver.sh /test-driver /ylwrap /Makefile.in /src/**/Makefile.in /docs/**/Makefile.in /m4/**/Makefile.in /tests/**/Makefile.in # http://www.gnu.org/software/texinfo /texinfo.tex # autoscan /autoscan.log /autoscan-*.log /configure.scan # ./configure script /config.h /config.log /config.status /hunspell.pc /libtool /stamp-h1 /po/Makefile.in Makefile # make .deps/ .libs/ *.lo *.la *.exe *.o *.a *~ a.out # make dist hunspell-*.tar.gz # QtCreator /Makefile.am.user # https://vim.sourceforge.io/ .?*.swp # found during configuring /confdefs.h /confinc /confmf /configure.tmp /conftest /conftest.sh /conftest.c /conftest.cpp /conftest.err /conftest.er1 #MSVC /msvc/Hunspell.VC.VC.opendb hunspell-1.7.0/.travis.yml000066400000000000000000000017061337236234000154710ustar00rootroot00000000000000language: cpp compiler: - clang - gcc sudo: false os: - linux - osx before_install: - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; fi install: - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install gettext; brew link gettext --force; fi # Don't use real gcc on OS X, problems arise when # Hunspell built with gcc is linked with cppunit built with clang. # Homebrew builds are build with clang before_script: - if [ "$CXX" = "g++" ] && [ "$TRAVIS_OS_NAME" = "linux" ]; then export CXX="g++-5" CC="gcc-5"; fi script: - autoreconf -i && ./configure && make && make check # - if [ "$TRAVIS_OS_NAME" = "osx" ]; then autoreconf -i -I /usr/local/share/aclocal && ./configure && make && make check; fi # might be needed for future after_failure: - cat tests/test-suite.log addons: apt: sources: - ubuntu-toolchain-r-test packages: - autoconf - automake - autopoint - gcc-5 - g++-5 hunspell-1.7.0/ABOUT-NLS000066400000000000000000002674741337236234000146270ustar00rootroot000000000000001 Notes on the Free Translation Project *************************************** Free software is going international! The Free Translation Project is a way to get maintainers of free software, translators, and users all together, so that free software will gradually become able to speak many languages. A few packages already provide translations for their messages. If you found this 'ABOUT-NLS' file inside a distribution, you may assume that the distributed package does use GNU 'gettext' internally, itself available at your nearest GNU archive site. But you do _not_ need to install GNU 'gettext' prior to configuring, installing or using this package with messages translated. Installers will find here some useful hints. These notes also explain how users should proceed for getting the programs to use the available translations. They tell how people wanting to contribute and work on translations can contact the appropriate team. 1.1 INSTALL Matters =================== Some packages are "localizable" when properly installed; the programs they contain can be made to speak your own native language. Most such packages use GNU 'gettext'. Other packages have their own ways to internationalization, predating GNU 'gettext'. By default, this package will be installed to allow translation of messages. It will automatically detect whether the system already provides the GNU 'gettext' functions. Installers may use special options at configuration time for changing the default behaviour. The command: ./configure --disable-nls will _totally_ disable translation of messages. When you already have GNU 'gettext' installed on your system and run configure without an option for your new package, 'configure' will probably detect the previously built and installed 'libintl' library and will decide to use it. If not, you may have to to use the '--with-libintl-prefix' option to tell 'configure' where to look for it. Internationalized packages usually have many 'po/LL.po' files, where LL gives an ISO 639 two-letter code identifying the language. Unless translations have been forbidden at 'configure' time by using the '--disable-nls' switch, all available translations are installed together with the package. However, the environment variable 'LINGUAS' may be set, prior to configuration, to limit the installed set. 'LINGUAS' should then contain a space separated list of two-letter codes, stating which languages are allowed. 1.2 Using This Package ====================== As a user, if your language has been installed for this package, you only have to set the 'LANG' environment variable to the appropriate 'LL_CC' combination. If you happen to have the 'LC_ALL' or some other 'LC_xxx' environment variables set, you should unset them before setting 'LANG', otherwise the setting of 'LANG' will not have the desired effect. Here 'LL' is an ISO 639 two-letter language code, and 'CC' is an ISO 3166 two-letter country code. For example, let's suppose that you speak German and live in Germany. At the shell prompt, merely execute 'setenv LANG de_DE' (in 'csh'), 'export LANG; LANG=de_DE' (in 'sh') or 'export LANG=de_DE' (in 'bash'). This can be done from your '.login' or '.profile' file, once and for all. You might think that the country code specification is redundant. But in fact, some languages have dialects in different countries. For example, 'de_AT' is used for Austria, and 'pt_BR' for Brazil. The country code serves to distinguish the dialects. The locale naming convention of 'LL_CC', with 'LL' denoting the language and 'CC' denoting the country, is the one use on systems based on GNU libc. On other systems, some variations of this scheme are used, such as 'LL' or 'LL_CC.ENCODING'. You can get the list of locales supported by your system for your language by running the command 'locale -a | grep '^LL''. Not all programs have translations for all languages. By default, an English message is shown in place of a nonexistent translation. If you understand other languages, you can set up a priority list of languages. This is done through a different environment variable, called 'LANGUAGE'. GNU 'gettext' gives preference to 'LANGUAGE' over 'LANG' for the purpose of message handling, but you still need to have 'LANG' set to the primary language; this is required by other parts of the system libraries. For example, some Swedish users who would rather read translations in German than English for when Swedish is not available, set 'LANGUAGE' to 'sv:de' while leaving 'LANG' to 'sv_SE'. Special advice for Norwegian users: The language code for Norwegian bokma*l changed from 'no' to 'nb' recently (in 2003). During the transition period, while some message catalogs for this language are installed under 'nb' and some older ones under 'no', it's recommended for Norwegian users to set 'LANGUAGE' to 'nb:no' so that both newer and older translations are used. In the 'LANGUAGE' environment variable, but not in the 'LANG' environment variable, 'LL_CC' combinations can be abbreviated as 'LL' to denote the language's main dialect. For example, 'de' is equivalent to 'de_DE' (German as spoken in Germany), and 'pt' to 'pt_PT' (Portuguese as spoken in Portugal) in this context. 1.3 Translating Teams ===================== For the Free Translation Project to be a success, we need interested people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, 'http://translationproject.org/', in the "Teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. The subscribing address is _not_ the same as the list itself, it has '-request' appended. For example, speakers of Swedish can send a message to 'sv-request@li.org', having this message body: subscribe Keep in mind that team members are expected to participate _actively_ in translations, or at solving translational difficulties, rather than merely lurking around. If your team does not exist yet and you want to start one, or if you are unsure about what to do or how to get started, please write to 'coordinator@translationproject.org' to reach the coordinator for all translator teams. The English team is special. It works at improving and uniformizing the terminology in use. Proven linguistic skills are praised more than programming skills, here. 1.4 Available Packages ====================== Languages are not equally supported in all packages. The following matrix shows the current state of internationalization, as of Jun 2014. The matrix shows, in regard of each package, for which languages PO files have been submitted to translation coordination, with a translation percentage of at least 50%. Ready PO files af am an ar as ast az be bg bn bn_IN bs ca crh cs +---------------------------------------------------+ a2ps | [] [] [] | aegis | | anubis | | aspell | [] [] [] | bash | [] [] [] | bfd | | binutils | [] | bison | | bison-runtime | [] | buzztrax | [] | ccd2cue | | ccide | | cflow | | clisp | | coreutils | [] [] | cpio | | cppi | | cpplib | [] | cryptsetup | [] | datamash | | denemo | [] [] | dfarc | [] | dialog | [] [] [] | dico | | diffutils | [] | dink | [] | direvent | | doodle | [] | dos2unix | | dos2unix-man | | e2fsprogs | [] [] | enscript | [] | exif | [] | fetchmail | [] [] | findutils | [] | flex | [] | freedink | [] [] | fusionforge | | gas | | gawk | [] | gcal | [] | gcc | | gdbm | | gettext-examples | [] [] [] [] [] | gettext-runtime | [] [] [] | gettext-tools | [] [] | gjay | | glunarclock | [] [] [] | gnubiff | [] | gnubik | [] | gnucash | () () [] | gnuchess | | gnulib | [] | gnunet | | gnunet-gtk | | gold | | gphoto2 | [] | gprof | [] | gramadoir | | grep | [] [] [] | grub | [] | gsasl | | gss | | gst-plugins-bad | [] [] | gst-plugins-base | [] [] [] | gst-plugins-good | [] [] [] | gst-plugins-ugly | [] [] [] | gstreamer | [] [] [] [] | gtick | [] | gtkam | [] [] | gtkspell | [] [] [] [] [] | guix | | guix-packages | | gutenprint | [] | hello | [] | help2man | | help2man-texi | | hylafax | | idutils | | iso_15924 | [] | iso_3166 | [] [] [] [] [] [] [] [] [] [] | iso_3166_2 | | iso_4217 | [] | iso_639 | [] [] [] [] [] [] [] [] [] | iso_639_3 | [] [] | iso_639_5 | | jwhois | | kbd | [] | klavaro | [] [] [] [] [] | ld | [] | leafpad | [] [] [] [] | libc | [] [] [] | libexif | () | libextractor | | libgnutls | [] | libgphoto2 | [] | libgphoto2_port | [] | libgsasl | | libiconv | [] [] | libidn | [] | liferea | [] [] [] [] | lilypond | [] [] | lordsawar | [] | lprng | | lynx | [] [] | m4 | [] | mailfromd | | mailutils | | make | [] | man-db | [] [] | man-db-manpages | | midi-instruments | [] [] [] | minicom | [] | mkisofs | [] | myserver | [] | nano | [] [] [] | opcodes | | parted | [] | pies | | pnmixer | | popt | [] | procps-ng | | procps-ng-man | | psmisc | [] | pspp | [] | pushover | [] | pwdutils | | pyspread | | radius | [] | recode | [] [] [] | recutils | | rpm | | rush | | sarg | | sed | [] [] [] [] | sharutils | [] | shishi | | skribilo | | solfege | [] [] | solfege-manual | | spotmachine | | sudo | [] [] | sudoers | [] [] | sysstat | [] | tar | [] [] [] | texinfo | [] [] | texinfo_document | [] [] | tigervnc | [] | tin | | tin-man | | tracgoogleappsa... | | trader | | util-linux | [] | ve | | vice | | vmm | | vorbis-tools | [] | wastesedge | | wcd | | wcd-man | | wdiff | [] [] | wget | [] | wyslij-po | | xboard | | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] | +---------------------------------------------------+ af am an ar as ast az be bg bn bn_IN bs ca crh cs 4 0 2 5 3 11 0 8 25 3 3 1 55 4 74 da de el en en_GB en_ZA eo es et eu fa fi fr +--------------------------------------------------+ a2ps | [] [] [] [] [] [] [] [] [] | aegis | [] [] [] [] | anubis | [] [] [] [] [] | aspell | [] [] [] [] [] [] [] | bash | [] [] [] | bfd | [] [] [] [] | binutils | [] [] [] | bison | [] [] [] [] [] [] [] [] | bison-runtime | [] [] [] [] [] [] [] [] | buzztrax | [] [] [] [] | ccd2cue | [] [] [] [] | ccide | [] [] [] [] [] [] | cflow | [] [] [] [] [] | clisp | [] [] [] [] [] | coreutils | [] [] [] [] [] | cpio | [] [] [] [] [] | cppi | [] [] [] [] [] | cpplib | [] [] [] [] [] [] | cryptsetup | [] [] [] [] [] | datamash | [] [] [] [] | denemo | [] | dfarc | [] [] [] [] [] [] | dialog | [] [] [] [] [] [] [] [] [] | dico | [] [] [] [] | diffutils | [] [] [] [] [] [] | dink | [] [] [] [] [] [] | direvent | [] [] [] [] | doodle | [] [] [] [] | dos2unix | [] [] [] [] [] | dos2unix-man | [] [] [] | e2fsprogs | [] [] [] [] [] | enscript | [] [] [] [] [] [] | exif | [] [] [] [] [] [] | fetchmail | [] () [] [] [] [] [] | findutils | [] [] [] [] [] [] [] [] | flex | [] [] [] [] [] [] | freedink | [] [] [] [] [] [] [] [] | fusionforge | [] [] [] | gas | [] [] [] | gawk | [] [] [] [] [] | gcal | [] [] [] [] | gcc | [] | gdbm | [] [] [] [] [] | gettext-examples | [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] | gettext-tools | [] [] [] [] [] | gjay | [] [] [] [] | glunarclock | [] [] [] [] [] | gnubiff | () [] [] () | gnubik | [] [] [] [] [] | gnucash | [] () () () () () () | gnuchess | [] [] [] [] | gnulib | [] [] [] [] [] [] [] | gnunet | [] | gnunet-gtk | [] | gold | [] [] [] | gphoto2 | [] () [] [] | gprof | [] [] [] [] [] [] | gramadoir | [] [] [] [] [] | grep | [] [] [] [] [] [] [] | grub | [] [] [] [] [] | gsasl | [] [] [] [] [] | gss | [] [] [] [] [] | gst-plugins-bad | [] [] [] | gst-plugins-base | [] [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] [] [] | gstreamer | [] [] [] [] [] [] [] | gtick | [] () [] [] [] | gtkam | [] () [] [] [] [] | gtkspell | [] [] [] [] [] [] [] [] | guix | [] [] | guix-packages | | gutenprint | [] [] [] [] | hello | [] [] [] [] [] [] [] [] | help2man | [] [] [] [] [] [] [] | help2man-texi | [] [] [] | hylafax | [] [] | idutils | [] [] [] [] [] | iso_15924 | [] () [] [] () [] () | iso_3166 | [] () [] [] [] [] () [] () | iso_3166_2 | [] () () () | iso_4217 | [] () [] [] [] () [] () | iso_639 | [] () [] [] () [] () | iso_639_3 | () () () | iso_639_5 | () () () | jwhois | [] [] [] [] [] | kbd | [] [] [] [] [] [] | klavaro | [] [] [] [] [] [] [] | ld | [] [] [] [] | leafpad | [] [] [] [] [] [] [] [] | libc | [] [] [] [] [] | libexif | [] [] () [] [] | libextractor | [] | libgnutls | [] [] [] [] | libgphoto2 | [] () [] | libgphoto2_port | [] () [] [] [] [] | libgsasl | [] [] [] [] [] | libiconv | [] [] [] [] [] [] [] | libidn | [] [] [] [] [] | liferea | [] () [] [] [] [] [] | lilypond | [] [] [] [] [] [] | lordsawar | [] [] | lprng | | lynx | [] [] [] [] [] [] | m4 | [] [] [] [] [] [] | mailfromd | [] | mailutils | [] [] [] [] | make | [] [] [] [] [] | man-db | [] [] [] [] | man-db-manpages | [] [] | midi-instruments | [] [] [] [] [] [] [] [] [] | minicom | [] [] [] [] [] | mkisofs | [] [] [] | myserver | [] [] [] [] | nano | [] [] [] [] [] [] [] | opcodes | [] [] [] [] [] | parted | [] [] [] | pies | [] | pnmixer | [] [] | popt | [] [] [] [] [] [] | procps-ng | [] [] | procps-ng-man | [] [] | psmisc | [] [] [] [] [] [] [] | pspp | [] [] [] | pushover | () [] [] [] | pwdutils | [] [] [] | pyspread | [] [] [] | radius | [] [] | recode | [] [] [] [] [] [] [] | recutils | [] [] [] [] | rpm | [] [] [] [] [] | rush | [] [] [] | sarg | [] [] | sed | [] [] [] [] [] [] [] [] | sharutils | [] [] [] [] | shishi | [] [] [] | skribilo | [] [] [] | solfege | [] [] [] [] [] [] [] [] | solfege-manual | [] [] [] [] [] | spotmachine | [] [] [] [] [] | sudo | [] [] [] [] [] [] | sudoers | [] [] [] [] [] [] | sysstat | [] [] [] [] [] [] | tar | [] [] [] [] [] [] [] | texinfo | [] [] [] [] [] | texinfo_document | [] [] [] [] | tigervnc | [] [] [] [] [] [] | tin | [] [] [] [] | tin-man | [] | tracgoogleappsa... | [] [] [] [] [] | trader | [] [] [] [] [] [] | util-linux | [] [] [] [] | ve | [] [] [] [] [] | vice | () () () | vmm | [] [] | vorbis-tools | [] [] [] [] | wastesedge | [] | wcd | [] [] [] [] | wcd-man | [] | wdiff | [] [] [] [] [] [] [] | wget | [] [] [] [] [] [] | wyslij-po | [] [] [] [] | xboard | [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] [] [] [] | +--------------------------------------------------+ da de el en en_GB en_ZA eo es et eu fa fi fr 119 131 32 1 6 0 94 95 22 13 4 102 139 ga gd gl gu he hi hr hu hy ia id is it ja ka kk +-------------------------------------------------+ a2ps | [] [] [] [] | aegis | [] | anubis | [] [] [] [] | aspell | [] [] [] [] [] | bash | [] [] [] [] | bfd | [] [] | binutils | [] [] [] | bison | [] | bison-runtime | [] [] [] [] [] [] [] [] | buzztrax | | ccd2cue | [] | ccide | [] [] | cflow | [] [] [] | clisp | | coreutils | [] [] | cpio | [] [] [] [] [] [] | cppi | [] [] [] [] [] | cpplib | [] [] | cryptsetup | [] | datamash | | denemo | [] | dfarc | [] [] [] | dialog | [] [] [] [] [] [] [] [] [] [] | dico | | diffutils | [] [] [] [] | dink | [] | direvent | [] | doodle | [] [] | dos2unix | [] [] | dos2unix-man | | e2fsprogs | [] [] | enscript | [] [] [] | exif | [] [] [] [] [] [] | fetchmail | [] [] [] | findutils | [] [] [] [] [] [] [] | flex | [] | freedink | [] [] [] [] | fusionforge | | gas | [] | gawk | [] () [] | gcal | | gcc | | gdbm | | gettext-examples | [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] [] | gettext-tools | [] [] [] | gjay | [] | glunarclock | [] [] [] [] [] [] | gnubiff | [] [] () | gnubik | [] [] [] | gnucash | () () () () () | gnuchess | | gnulib | [] [] [] [] [] | gnunet | | gnunet-gtk | | gold | [] [] | gphoto2 | [] [] [] [] | gprof | [] [] [] [] | gramadoir | [] [] [] | grep | [] [] [] [] [] [] [] | grub | [] [] [] | gsasl | [] [] [] [] [] | gss | [] [] [] [] [] | gst-plugins-bad | [] [] [] | gst-plugins-base | [] [] [] [] | gst-plugins-good | [] [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] [] [] [] [] | gtkam | [] [] [] [] [] | gtkspell | [] [] [] [] [] [] [] [] [] [] | guix | | guix-packages | | gutenprint | [] [] [] | hello | [] [] [] [] [] | help2man | [] [] [] | help2man-texi | | hylafax | [] | idutils | [] [] | iso_15924 | [] [] [] [] [] [] | iso_3166 | [] [] [] [] [] [] [] [] [] [] [] [] [] | iso_3166_2 | [] [] | iso_4217 | [] [] [] [] [] [] | iso_639 | [] [] [] [] [] [] [] [] [] | iso_639_3 | [] [] | iso_639_5 | | jwhois | [] [] [] [] | kbd | [] [] [] | klavaro | [] [] [] [] [] | ld | [] [] [] [] | leafpad | [] [] [] [] [] [] [] () | libc | [] [] [] [] [] | libexif | [] | libextractor | | libgnutls | [] | libgphoto2 | [] [] | libgphoto2_port | [] [] | libgsasl | [] [] [] [] | libiconv | [] [] [] [] [] [] [] | libidn | [] [] [] [] | liferea | [] [] [] [] [] | lilypond | [] | lordsawar | | lprng | [] | lynx | [] [] [] [] | m4 | [] [] [] [] [] | mailfromd | | mailutils | | make | [] [] [] [] | man-db | [] [] | man-db-manpages | [] [] | midi-instruments | [] [] [] [] [] [] [] [] [] | minicom | [] [] [] | mkisofs | [] [] | myserver | [] | nano | [] [] [] [] [] [] | opcodes | [] [] [] | parted | [] [] [] [] [] | pies | | pnmixer | [] [] | popt | [] [] [] [] [] [] [] [] [] [] | procps-ng | | procps-ng-man | | psmisc | [] [] [] [] | pspp | [] [] | pushover | [] | pwdutils | [] | pyspread | | radius | [] | recode | [] [] [] [] [] [] [] | recutils | | rpm | [] | rush | [] | sarg | | sed | [] [] [] [] [] [] [] | sharutils | | shishi | | skribilo | [] | solfege | [] [] | solfege-manual | | spotmachine | | sudo | [] [] [] [] | sudoers | [] [] [] | sysstat | [] [] [] [] | tar | [] [] [] [] [] [] | texinfo | [] [] [] | texinfo_document | [] [] [] | tigervnc | | tin | | tin-man | | tracgoogleappsa... | [] [] [] [] | trader | [] [] | util-linux | [] | ve | [] | vice | () () | vmm | | vorbis-tools | [] [] | wastesedge | [] | wcd | | wcd-man | | wdiff | [] [] [] | wget | [] [] [] [] | wyslij-po | [] [] [] | xboard | | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] [] [] | +-------------------------------------------------+ ga gd gl gu he hi hr hu hy ia id is it ja ka kk 35 2 47 4 8 2 60 71 2 6 81 11 87 57 0 3 kn ko ku ky lg lt lv mk ml mn mr ms mt nb ne nl +--------------------------------------------------+ a2ps | [] [] | aegis | [] | anubis | [] [] [] | aspell | [] [] | bash | [] [] | bfd | | binutils | | bison | [] | bison-runtime | [] [] [] [] [] [] | buzztrax | | ccd2cue | | ccide | [] [] | cflow | [] | clisp | [] | coreutils | [] [] | cpio | [] | cppi | | cpplib | [] | cryptsetup | [] | datamash | [] [] | denemo | | dfarc | [] [] | dialog | [] [] [] [] [] [] | dico | | diffutils | [] [] [] | dink | [] | direvent | [] | doodle | [] | dos2unix | [] [] | dos2unix-man | [] | e2fsprogs | [] | enscript | [] | exif | [] [] [] | fetchmail | [] | findutils | [] [] | flex | [] | freedink | [] [] | fusionforge | | gas | | gawk | [] | gcal | | gcc | | gdbm | | gettext-examples | [] [] [] [] [] [] | gettext-runtime | [] [] [] | gettext-tools | [] | gjay | | glunarclock | [] [] | gnubiff | [] | gnubik | [] [] | gnucash | () () () () () () () [] | gnuchess | [] [] | gnulib | [] | gnunet | | gnunet-gtk | | gold | | gphoto2 | [] | gprof | [] [] | gramadoir | [] | grep | [] [] | grub | [] [] [] | gsasl | [] | gss | | gst-plugins-bad | [] [] [] | gst-plugins-base | [] [] [] | gst-plugins-good | [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] | gstreamer | [] [] [] | gtick | [] | gtkam | [] [] | gtkspell | [] [] [] [] [] [] [] | guix | | guix-packages | | gutenprint | [] | hello | [] [] [] | help2man | [] | help2man-texi | | hylafax | [] | idutils | [] | iso_15924 | () [] [] | iso_3166 | [] [] [] () [] [] [] [] [] [] | iso_3166_2 | () [] | iso_4217 | () [] [] [] | iso_639 | [] [] () [] [] [] [] | iso_639_3 | [] () [] | iso_639_5 | () | jwhois | [] [] | kbd | [] | klavaro | [] [] | ld | | leafpad | [] [] [] [] [] | libc | [] [] | libexif | [] | libextractor | [] | libgnutls | [] [] | libgphoto2 | [] | libgphoto2_port | [] | libgsasl | [] | libiconv | [] [] | libidn | [] | liferea | [] [] [] | lilypond | [] | lordsawar | | lprng | | lynx | [] | m4 | [] | mailfromd | | mailutils | | make | [] [] | man-db | [] | man-db-manpages | [] | midi-instruments | [] [] [] [] [] [] [] | minicom | [] | mkisofs | [] | myserver | | nano | [] [] [] | opcodes | [] | parted | [] [] | pies | | pnmixer | [] | popt | [] [] [] [] [] | procps-ng | | procps-ng-man | | psmisc | [] | pspp | [] [] | pushover | | pwdutils | [] | pyspread | | radius | [] | recode | [] [] | recutils | [] | rpm | [] | rush | [] | sarg | | sed | [] [] | sharutils | [] | shishi | | skribilo | | solfege | [] [] | solfege-manual | [] | spotmachine | [] | sudo | [] [] [] | sudoers | [] [] [] | sysstat | [] [] | tar | [] [] [] | texinfo | [] | texinfo_document | [] | tigervnc | [] | tin | | tin-man | | tracgoogleappsa... | [] [] [] | trader | [] | util-linux | [] | ve | [] | vice | [] | vmm | [] | vorbis-tools | [] | wastesedge | [] | wcd | [] | wcd-man | [] | wdiff | [] | wget | [] [] | wyslij-po | [] | xboard | [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] | +--------------------------------------------------+ kn ko ku ky lg lt lv mk ml mn mr ms mt nb ne nl 5 15 4 6 0 13 23 3 3 3 4 11 2 42 1 125 nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr +------------------------------------------------+ a2ps | [] [] [] [] [] [] [] | aegis | [] [] | anubis | [] [] [] | aspell | [] [] [] [] [] [] [] | bash | [] [] [] [] [] [] | bfd | [] [] | binutils | [] [] | bison | [] [] [] | bison-runtime | [] [] [] [] [] [] [] [] | buzztrax | [] | ccd2cue | [] [] | ccide | [] [] [] | cflow | [] [] [] | clisp | [] | coreutils | [] [] [] [] | cpio | [] [] [] | cppi | [] [] [] | cpplib | [] [] [] | cryptsetup | [] [] [] | datamash | [] [] | denemo | | dfarc | [] [] [] | dialog | [] [] [] [] [] [] [] | dico | [] | diffutils | [] [] [] | dink | | direvent | [] [] [] | doodle | [] [] | dos2unix | [] [] [] [] | dos2unix-man | [] [] | e2fsprogs | [] | enscript | [] [] [] [] [] [] | exif | [] [] [] [] [] [] | fetchmail | [] [] [] | findutils | [] [] [] [] [] [] | flex | [] [] [] [] [] | freedink | [] [] [] [] [] | fusionforge | | gas | | gawk | [] | gcal | | gcc | | gdbm | [] [] [] | gettext-examples | [] [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] [] [] [] | gettext-tools | [] [] [] [] [] [] [] | gjay | [] | glunarclock | [] [] [] [] [] [] | gnubiff | [] | gnubik | [] [] [] [] | gnucash | () () () () () [] | gnuchess | [] [] | gnulib | [] [] [] [] [] | gnunet | | gnunet-gtk | | gold | | gphoto2 | [] [] [] [] [] | gprof | [] [] [] [] | gramadoir | [] [] | grep | [] [] [] [] [] [] | grub | [] [] [] [] [] | gsasl | [] [] [] | gss | [] [] [] [] | gst-plugins-bad | [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] [] | gstreamer | [] [] [] [] [] [] [] | gtick | [] [] [] [] [] | gtkam | [] [] [] [] [] [] | gtkspell | [] [] [] [] [] [] [] [] [] | guix | | guix-packages | | gutenprint | [] [] | hello | [] [] [] [] [] [] | help2man | [] [] [] [] | help2man-texi | [] | hylafax | | idutils | [] [] [] | iso_15924 | [] () [] [] [] [] | iso_3166 | [] [] [] [] () [] [] [] [] [] [] [] [] | iso_3166_2 | [] () [] | iso_4217 | [] [] () [] [] [] [] [] | iso_639 | [] [] [] () [] [] [] [] [] [] | iso_639_3 | [] () | iso_639_5 | () [] | jwhois | [] [] [] [] | kbd | [] [] | klavaro | [] [] [] [] [] | ld | | leafpad | [] [] [] [] [] [] [] [] | libc | [] [] [] | libexif | [] () [] | libextractor | [] | libgnutls | [] | libgphoto2 | [] | libgphoto2_port | [] [] [] [] [] | libgsasl | [] [] [] [] | libiconv | [] [] [] [] [] | libidn | [] [] [] | liferea | [] [] [] [] () [] [] | lilypond | | lordsawar | | lprng | [] | lynx | [] [] | m4 | [] [] [] [] [] | mailfromd | [] | mailutils | [] | make | [] [] [] | man-db | [] [] [] | man-db-manpages | [] [] [] | midi-instruments | [] [] [] [] [] [] [] [] | minicom | [] [] [] [] | mkisofs | [] [] [] | myserver | [] [] | nano | [] [] [] [] [] [] | opcodes | | parted | [] [] [] [] [] [] | pies | [] | pnmixer | [] | popt | [] [] [] [] [] [] | procps-ng | [] | procps-ng-man | [] | psmisc | [] [] [] [] | pspp | [] [] | pushover | | pwdutils | [] | pyspread | [] [] | radius | [] [] | recode | [] [] [] [] [] [] [] [] | recutils | [] [] | rpm | [] | rush | [] [] [] | sarg | [] [] | sed | [] [] [] [] [] [] [] [] | sharutils | [] [] [] | shishi | [] [] | skribilo | [] | solfege | [] [] [] | solfege-manual | [] [] | spotmachine | [] [] | sudo | [] [] [] [] [] [] | sudoers | [] [] [] [] | sysstat | [] [] [] [] [] | tar | [] [] [] [] [] | texinfo | [] [] [] | texinfo_document | [] [] | tigervnc | [] [] [] | tin | [] | tin-man | | tracgoogleappsa... | [] [] [] [] | trader | [] [] | util-linux | [] [] | ve | [] [] [] | vice | | vmm | | vorbis-tools | [] [] [] | wastesedge | | wcd | | wcd-man | | wdiff | [] [] [] [] [] | wget | [] [] [] [] [] | wyslij-po | [] [] [] [] | xboard | [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] | +------------------------------------------------+ nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr 7 3 6 114 1 12 88 32 82 3 40 45 7 101 sv sw ta te tg th tr uk ur vi wa wo zh_CN +----------------------------------------------+ a2ps | [] [] [] [] [] | aegis | [] | anubis | [] [] [] [] | aspell | [] [] [] [] [] | bash | [] [] [] [] | bfd | [] [] [] | binutils | [] [] [] | bison | [] [] [] [] | bison-runtime | [] [] [] [] [] [] | buzztrax | [] [] [] | ccd2cue | [] [] [] | ccide | [] [] [] [] | cflow | [] [] [] [] | clisp | | coreutils | [] [] [] | cpio | [] [] [] [] [] | cppi | [] [] [] [] | cpplib | [] [] [] [] [] | cryptsetup | [] [] [] | datamash | [] [] [] | denemo | [] | dfarc | [] [] | dialog | [] [] [] [] [] [] | dico | [] | diffutils | [] [] [] [] [] | dink | [] | direvent | [] [] | doodle | [] [] | dos2unix | [] [] [] [] | dos2unix-man | [] [] [] | e2fsprogs | [] [] [] [] | enscript | [] [] [] [] | exif | [] [] [] [] [] | fetchmail | [] [] [] [] | findutils | [] [] [] [] [] | flex | [] [] [] [] | freedink | [] [] [] | fusionforge | | gas | [] | gawk | [] [] [] | gcal | [] [] [] | gcc | [] | gdbm | [] [] | gettext-examples | [] [] [] [] [] | gettext-runtime | [] [] [] [] [] | gettext-tools | [] [] [] [] [] | gjay | [] [] [] | glunarclock | [] [] [] [] | gnubiff | [] [] | gnubik | [] [] [] [] | gnucash | () () () () [] | gnuchess | [] [] [] | gnulib | [] [] [] [] | gnunet | | gnunet-gtk | | gold | [] [] | gphoto2 | [] [] [] [] | gprof | [] [] [] [] | gramadoir | [] [] [] | grep | [] [] [] [] [] | grub | [] [] [] [] | gsasl | [] [] [] [] | gss | [] [] [] | gst-plugins-bad | [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] [] [] | gtkam | [] [] [] [] | gtkspell | [] [] [] [] [] [] [] | guix | | guix-packages | | gutenprint | [] [] [] [] | hello | [] [] [] [] [] [] | help2man | [] [] [] | help2man-texi | [] | hylafax | [] | idutils | [] [] [] | iso_15924 | [] () [] [] () [] | iso_3166 | [] [] () [] [] () [] [] | iso_3166_2 | () [] [] () [] | iso_4217 | [] () [] [] () [] | iso_639 | [] [] [] () [] [] () [] [] | iso_639_3 | [] () [] [] () | iso_639_5 | () [] () | jwhois | [] [] [] [] | kbd | [] [] [] [] | klavaro | [] [] [] [] [] [] | ld | [] [] [] [] [] | leafpad | [] [] [] [] [] [] | libc | [] [] [] [] [] | libexif | [] [] () | libextractor | [] [] | libgnutls | [] [] [] [] | libgphoto2 | [] [] [] | libgphoto2_port | [] [] [] [] | libgsasl | [] [] [] [] | libiconv | [] [] [] [] [] | libidn | () [] [] [] | liferea | [] [] [] [] [] | lilypond | [] | lordsawar | | lprng | [] | lynx | [] [] [] [] | m4 | [] [] [] | mailfromd | [] [] | mailutils | [] | make | [] [] [] [] | man-db | [] [] [] | man-db-manpages | [] [] | midi-instruments | [] [] [] [] [] [] | minicom | [] [] | mkisofs | [] [] [] | myserver | [] | nano | [] [] [] [] | opcodes | [] [] [] | parted | [] [] [] [] [] | pies | [] [] | pnmixer | [] [] [] | popt | [] [] [] [] [] [] [] | procps-ng | [] [] | procps-ng-man | [] | psmisc | [] [] [] [] | pspp | [] [] [] | pushover | [] | pwdutils | [] [] | pyspread | [] | radius | [] [] | recode | [] [] [] [] | recutils | [] [] [] | rpm | [] [] [] [] | rush | [] [] | sarg | | sed | [] [] [] [] [] | sharutils | [] [] [] [] | shishi | [] [] | skribilo | [] [] | solfege | [] [] [] [] | solfege-manual | [] | spotmachine | [] [] [] | sudo | [] [] [] [] [] | sudoers | [] [] [] [] | sysstat | [] [] [] [] [] | tar | [] [] [] [] [] | texinfo | [] [] [] | texinfo_document | [] | tigervnc | [] [] [] | tin | [] | tin-man | | tracgoogleappsa... | [] [] [] [] [] | trader | [] | util-linux | [] [] [] [] | ve | [] [] [] [] | vice | () () | vmm | | vorbis-tools | [] [] | wastesedge | | wcd | [] [] [] | wcd-man | [] | wdiff | [] [] [] [] | wget | [] [] [] | wyslij-po | [] [] | xboard | [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] | +----------------------------------------------+ sv sw ta te tg th tr uk ur vi wa wo zh_CN 106 1 4 3 0 13 51 115 1 125 7 1 100 zh_HK zh_TW +-------------+ a2ps | | 30 aegis | | 9 anubis | | 19 aspell | | 29 bash | [] | 23 bfd | | 11 binutils | | 12 bison | [] | 18 bison-runtime | [] | 38 buzztrax | | 9 ccd2cue | | 10 ccide | | 17 cflow | | 16 clisp | | 10 coreutils | | 18 cpio | | 20 cppi | | 17 cpplib | [] | 19 cryptsetup | | 14 datamash | | 11 denemo | | 5 dfarc | | 17 dialog | [] | 42 dico | | 6 diffutils | | 22 dink | | 10 direvent | | 11 doodle | | 12 dos2unix | [] | 18 dos2unix-man | | 9 e2fsprogs | | 15 enscript | | 21 exif | | 27 fetchmail | | 19 findutils | | 29 flex | [] | 19 freedink | | 24 fusionforge | | 3 gas | | 5 gawk | | 13 gcal | | 8 gcc | | 2 gdbm | | 10 gettext-examples | [] [] | 40 gettext-runtime | [] [] | 35 gettext-tools | [] | 24 gjay | | 9 glunarclock | [] | 27 gnubiff | | 9 gnubik | | 19 gnucash | () | 6 gnuchess | | 11 gnulib | | 23 gnunet | | 1 gnunet-gtk | | 1 gold | | 7 gphoto2 | [] | 19 gprof | | 21 gramadoir | | 14 grep | [] | 31 grub | | 21 gsasl | [] | 19 gss | | 17 gst-plugins-bad | | 21 gst-plugins-base | | 27 gst-plugins-good | | 32 gst-plugins-ugly | | 34 gstreamer | [] | 32 gtick | | 19 gtkam | | 24 gtkspell | [] [] | 48 guix | | 2 guix-packages | | 0 gutenprint | | 15 hello | [] | 30 help2man | | 18 help2man-texi | | 5 hylafax | | 5 idutils | | 14 iso_15924 | [] | 23 iso_3166 | [] [] | 58 iso_3166_2 | | 9 iso_4217 | [] [] | 28 iso_639 | [] [] | 46 iso_639_3 | | 10 iso_639_5 | | 2 jwhois | [] | 20 kbd | | 17 klavaro | | 30 ld | [] | 15 leafpad | [] | 39 libc | [] | 24 libexif | | 10 libextractor | | 5 libgnutls | | 13 libgphoto2 | | 10 libgphoto2_port | [] | 19 libgsasl | | 18 libiconv | [] | 29 libidn | | 17 liferea | | 29 lilypond | | 11 lordsawar | | 3 lprng | | 3 lynx | | 19 m4 | [] | 22 mailfromd | | 4 mailutils | | 6 make | | 19 man-db | | 15 man-db-manpages | | 10 midi-instruments | [] | 43 minicom | [] | 17 mkisofs | | 13 myserver | | 9 nano | [] | 30 opcodes | | 12 parted | [] | 23 pies | | 4 pnmixer | | 9 popt | [] | 36 procps-ng | | 5 procps-ng-man | | 4 psmisc | [] | 22 pspp | | 13 pushover | | 6 pwdutils | | 8 pyspread | | 6 radius | | 9 recode | | 31 recutils | | 10 rpm | [] | 13 rush | | 10 sarg | | 4 sed | [] | 35 sharutils | | 13 shishi | | 7 skribilo | | 7 solfege | | 21 solfege-manual | | 9 spotmachine | | 11 sudo | | 26 sudoers | | 22 sysstat | | 23 tar | [] | 30 texinfo | | 17 texinfo_document | | 13 tigervnc | | 14 tin | [] | 7 tin-man | | 1 tracgoogleappsa... | [] | 22 trader | | 12 util-linux | | 13 ve | | 14 vice | | 1 vmm | | 3 vorbis-tools | | 13 wastesedge | | 3 wcd | | 8 wcd-man | | 3 wdiff | [] | 23 wget | | 21 wyslij-po | | 14 xboard | | 10 xdg-user-dirs | [] [] | 68 xkeyboard-config | [] | 28 +-------------+ 89 teams zh_HK zh_TW 166 domains 7 42 2809 Some counters in the preceding matrix are higher than the number of visible blocks let us expect. This is because a few extra PO files are used for implementing regional variants of languages, or language dialects. For a PO file in the matrix above to be effective, the package to which it applies should also have been internationalized and distributed as such by its maintainer. There might be an observable lag between the mere existence a PO file and its wide availability in a distribution. If Jun 2014 seems to be old, you may fetch a more recent copy of this 'ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at 'http://translationproject.org/extra/matrix.html'. 1.5 Using 'gettext' in new packages =================================== If you are writing a freely available program and want to internationalize it you are welcome to use GNU 'gettext' in your package. Of course you have to respect the GNU Lesser General Public License which covers the use of the GNU 'gettext' library. This means in particular that even non-free programs can use 'libintl' as a shared library, whereas only free software can use 'libintl' as a static library or use modified versions of 'libintl'. Once the sources are changed appropriately and the setup can handle the use of 'gettext' the only thing missing are the translations. The Free Translation Project is also available for packages which are not developed inside the GNU project. Therefore the information given above applies also for every other Free Software Project. Contact 'coordinator@translationproject.org' to make the '.pot' files available to the translation teams. hunspell-1.7.0/AUTHORS000066400000000000000000000013671337236234000144330ustar00rootroot00000000000000Author: László Németh MySpell's (Hunspell's code base) author: Kevin Hendricks Maintainer, distinguished contributor: Caolán McNamara Author of rule-based transformation code for phonetic suggestions (PHONE/phonet.cxx, used by English dictionaries): Björn Jacke Hunspell/MySpell code base is result of work of several contributors. See git log, ./THANKS, ./Changelog, ./Changelog.O, MySpell's README and CONTRIBUTORS files for their contributions. Note: Following contributors are not owners and not representatives of Hunspell, and they haven't got permission from Hunspell's author to act on the behalf of Hunspell project: Sander van Geloven, Dimitri Mijoski If you would like to support Hunspell, join the development or contact the author. hunspell-1.7.0/COPYING000066400000000000000000000432551337236234000144200ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. hunspell-1.7.0/COPYING.LESSER000066400000000000000000000636431337236234000154170ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! hunspell-1.7.0/COPYING.MPL000066400000000000000000000622331337236234000150440ustar00rootroot00000000000000 MOZILLA PUBLIC LICENSE Version 1.1 --------------- 1. Definitions. 1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. 1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. 1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. 1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. 1.5. "Executable" means Covered Code in any form other than Source Code. 1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. 1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 1.8. "License" means this document. 1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. B. Any new file that contains any part of the Original Code or previous Modifications. 1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. 1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. 1.12. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. Source Code License. 2.1. The Initial Developer Grant. The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. 2.2. Contributor Grant. Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Application of License. The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. 3.2. Availability of Source Code. Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. 3.3. Description of Modifications. You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. 3.4. Intellectual Property Matters (a) Third Party Claims. If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. (b) Contributor APIs. If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. (c) Representations. Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. 3.5. Required Notices. You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.6. Distribution of Executable Versions. You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.7. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. 4. Inability to Comply Due to Statute or Regulation. If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Application of this License. This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. 6. Versions of the License. 6.1. New Versions. Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. 6.2. Effect of New Versions. Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. 6.3. Derivative Works. If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) 7. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 8. TERMINATION. 8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: (a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. (b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. 8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. 8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 10. U.S. GOVERNMENT END USERS. The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 11. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. 12. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. 13. MULTIPLE-LICENSED CODE. Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the NPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. EXHIBIT A -Mozilla Public License. ``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 ______________________________________. The Initial Developer of the Original Code is ________________________. Portions created by ______________________ are Copyright (C) ______ _______________________. All Rights Reserved. Contributor(s): ______________________________________. Alternatively, the contents of this file may be used under the terms of the _____ license (the "[___] License"), in which case the provisions of [______] License are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the [___] License. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the [___] License." [NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] hunspell-1.7.0/ChangeLog000066400000000000000000002555461337236234000151470ustar00rootroot000000000000002016-04-29 Caolán McNamara : * deprecate old api and add new one old one remains implemented in terms of new one and will eventually be removed * shrink exposed api down to just hunspell.hxx * next major release is likely to require C++11 2016-04-15 Caolán McNamara : * generally using std::string and std::vector internally 2016-04-13 Caolán McNamara : * gh#371 drop experimental code 2015-09-11 Caolán McNamara : * rhbz#1261421 crash on mashing hangul korean keyboard 2014-12-03 Németh László : * tools/hunspell.cxx: security fixes of the Hunspell executable - secure file name handling, the problem (checking OpenDocument files with malicious file names) reported by Eric Sesterhenn - using tmpnam() only with system("mkdir tempname && ...") 2014-10-17 Caolán McNamara : * sf#245 Feature from Anish Patil -S mode to show suggestions for completion of correctly spelled words * sf#248 Fix manpage about how to include 2014-10-16 Caolán McNamara : * rhbz#915448, sf#57, sf#185 report character offset and not byte offset in ispell mode * sf#56 segv in experimental mode * sf#228 don't translate init string 2014-09-22 Németh László : * fix crash in morphological analysis of the Hungarian compound word 'művészegyéniség', reported by Gáspár Sinai 2014-08-26 Németh László : * unmunch separates flags of prefixes from the word, bug reported by Daniel Naber 2014-08-05 Németh László : * moz#318040 Mozzilla accepts abbreviations without dots * myfopen(): add _wfullpath to expand relative parts of absolute paths 2014-07-16 Caolán McNamara : * moz#675553 Switch from PRBool to bool * moz#690892 replace PR_TRUE/PR_FALSE with true/false * Silence the warning about empty while body loop in clang * moz#777292 Make nsresult an enum * moz#579517 Use stdint types in gecko * moz#784776 consistently use FLAG_NULL * moz#927728 Convert PRUnichar to char16_t * moz#943268 Remove nsCharsetAlias and nsCharsetConverterManager * Don't include config.h in license.hunspell if MOZILLA_CLIENT is set 2014-06-26 Caolán McNamara : * clang scan-build: Allocator sizeof operand mismatch * clang scan-build: other low hanging warnings * clang scan-build: significant warnings 2014-06-02 Németh László : * escape spaces in paths of ODF files 2014-05-28 Németh László : * add long path/Unicode path support in WIN32 environment: - hunspell#233 (reported by mahak gark) and LibreOffice fdo#48017 * flat ODF support, eg.: hunspell doc.fodt cat doc.fodt | hunspell -l -O * new options: - -X (XML) input format - -O (ODF or flat ODF) input format - --check-apostrophe: check and force Unicode apostrophe usage (ASCII or Unicode apostrophe has to be in the WORDCHARS section of the affix file) * fix ODF support: - break 1-line XML of ODT documents at , too, not only at (limiting tokenization problems, when fgets stops within an XML tag) - show ODF file path on the UI instead of the temporary file * fix XML support: - ', ", &, < and > in replacements converted to XML entities - recognize &apos at tokenization, depending from WORDCHARS - ' in tokens converted to ' before spell checking and in the output of the pipe interface * better apostrophe usage: - WORDCHARS only with one of the Unicode or ASCII apostrophe results extended word tokenization: both of them will be part of the words (if they are inside: eg. word's, but not words'). - convert Unicode apostrophes to ASCII ones for 8-bit dictionaries (eg. English dictionaries), or for UTF-8 dictionaries only with ASCII apostrophe supports (eg. French dictionaries). * updated manual: - hunspell.4 renamed to hunspell.5, see hunspell#241 reported by Cristopher Yeleighton - updated translations - note about long/Unicode paths in WIN32 (hunspell.3) 2014-04-25 Németh László : * OpenDocument support, eg. hunspell *.odt hunspell -l *.odt * always load default personal dictionary (fix filtering bad words - reduce this word list - using it as a personal dictionary workflow) * fix parsing/URL recognition problem (bad tokens with aposthrophes) 2013-07-25 pchang9@cs.wisc.edu * moz#897255 Wasted work in line_uniq * moz#897780 Wasted work in SuggestMgr::twowords 2013-07-25 Caolán McNamara : * hunspell#167 layout problems with long lines - based on the original fix by xorho adapted to HEAD * rhbz#925562 upgrade config.guess for aarch64 2013-07-24 pchang9@cs.wisc.edu * moz#896301 Wasted work in SfxEntry::checkword * moz#896844 Wasted work in AffixMgr::defcpd_check 2013-06-13 Konstantin Khlebniko * #49 HashMgr::add_word computes wrong size for struct hentry 2013-06-13 Ville Skyttä * #53 Man page syntax fixes 2013-04-19 John Thomson * win_api: add remove() of Hunspell API (hun#3606435) 2013-04-19 Rouslan Solomokhin * fix crash in suggestions for 99-character long words by extending arrays of SuggestMgr::forgotchar_* (hun#3595024, also http://crbug.com/130128), thanks to also Paweł Hajdan to report the patch 2013-04-01 Caolán McNamara : * hunspell: -Werror=undef 2013-03-13 Caolán McNamara : * rhbz#918938 crash in interaction with danish thesaurus 2012-09-18 Németh László : * src/hunspell/affixmgr.*: - fix morphological analysis of compound words (hun#3544994, reported by Dávid Nemeskey, fdo#55045) 2012-06-29 Caolán McNamara : * fix various coverity warnings 2012-01-10 Ehsan Akhgari * moz#710940 Firefox Crash [@ AffixMgr::parse_file(char const*, char const*) ] 2011-12-16 Jared Wein * moz#710967 Incorrect argument passed to strncmp in AffixMgr::parse_convtable 2011-12-06 Caolán McNamara : * rhbz#759647 fixed tempname of hunSPELL.bak collides with other users when multiple edits in one dir 2011-10-13 Caolán McNamara : * moz#694002 crash in hunspell affixmgr on exit with bad .aff * leak in hunspell affixmgr with bad .aff 2011-09-19 Caolán McNamara : * make libparsers.a not installed thanks to Tomáš Chvátal 2011-06-23 Caolán McNamara : * fix some windows compiler warnings 2011-05-24 Németh László : * src/hunspell/affixmgr.*: allow twofold suffixes in compounds by extended version of Arno Teigseth's patch, see hun#3288562. - new option for this feature: COMPOUNDMORESUFFIXES 2011-02-16 Németh László : * src/*/Makefile.am: fix library versioning, the probem reported by Rene Engerhald and Simon Brouwer. * man/hunspell.4: new version based on the revised version of Ruud Baars 2011-02-02 Németh László : * suggestngr.cxx: fix ngram PHONE suggestion for input words with diacritics using UTF-8 encoded dictionaries (add byte length to the 8-bit phonet() argument instead of character length) * suggestmgr.cxx: fix missing csconv problem with UTF-8 encoding dictionares, when the input contains non-BMP characters - tests/utf8_nonbmp.sug: test file * suggestmgr.cxx: mixed and keyboard based character suggestions don't forbid ngram suggestion search (optimized tests/suggestiontest) * affixmgr.cxx: fix hun#2999225: interfering compounding mechanisms, tested on Dutch word list and reported by Ruud Baars * affixmgr.cxx: allomorph fix for hun#2970240 (Hungarian compound "vadász+gép" was analyzed as vad+ász+gép, and rejected by the ss->s rep rule (verb "vadássz"), but the analysis didn't continue for the longer word parts (vadász+gép). * csutil.cxx: add lang code "az_AZ", "hu_HU", "tr_TR" for back compatibility (fixing Azeri and Turkish casing conversion, also Hungarian compound handling) * affixmgr.cxx: fix morphological analysis 2011-01-26 Németh László : * affixmgr.cxx: fix for moz#626195 (memcheck problem with FULLSTRIP). * affixmgr.*, suggestmgr.cxx: FORBIDWARN parameter (see manual) 2011-01-24 Németh László : * suffixmgr.cxx: fix bad suggestion of forbidden compound words, eg. "termijndoel" with the Dutch dictionary. Reported by Ruud Baars. * latexparser.cxx: fix double apostrophe TeX quoation mark tokenization (hun#3119776), reported by Wybodekker at SF.net. * tests/suggestiontest/*: multilanguage and single Hunspell version, see README * tests/suggestiontest/prepare2: for make -f Makefile.orig single 2011-01-22 Németh László : * affixmgr.*, suggestmgr.*: new features ONLYMAXDIFF: remove all bad ngram suggestions (default mode keeps one) NONGRAMSUGGEST: similar to NOSUGGEST, but it forbids to use the word in ngram based (more, than 1-character distance) suggestions. 2011-01-21 Németh László : * suggestmgr.*: limit wild suggestions (hun#2970237 by Ruud Baars) - limited compound word suggestions - improved and limited ngram based suggestions * tests/*.sug: modified test files - feature MAXCPDSUGS: MAXCPDSUGS 0 : no compound suggestion, suggested by Finn Gruwier Larsen in hunfeat#2836033 MAXCPDSUGS n : max. ~n compound suggestions - feature MAXDIFF: differency limit for ngram suggestions: 0-10 eg. MAXDIFF 5: normal (default) limit MAXDIFF 0: only one ngram suggestion MAXDIFF 10: ~maxngramsugs ngram suggestions * affixmgr.*, hunspell.*: add flag FORCEUCASE (hun#2999228), force capitalization of compound words, see Hunspell 4 manual), suggested by Ruud Baars test/forceucase.*: test files * affixmgr.*, hunspell.*: add flag WARN (hun#1808861), optional warning feature for rare words, suggested by Ruud Baars tests/warn: test files * tools/hunspell.cxx: add option -r for optional filtering of rare words * affixmgr.cxx: fix hun#3161359 (gcc warnings) reported by Ryan VanderMeulen. 2011-01-17 Németh László : * suggestmgr.cxx: fix hun#3158994 and hun#3159027 (missing csconv table using awkward 8bit capitalization of UTF-8 encoded dictionary words with PHONE suggestion, reported by benjarobin and dicollecte at SF.net). 2011-01-13 Németh László : * affixmgr.cxx: ONLYINCOMPOUND fix for hun#2999224 (fogemorphene was allowed in end position of compoundings). Reported by Ruud Baars. * tests/onlyincompound2.*: test files 2011-01-10 Ingo H. de Boer : * win_api/{hunspell,libhunspell, testparser}.vcproj: updated project files for the library and the executables. Compiling problem also reported by Don Walker. 2011-01-06 Németh László : * affixmgr.cxx: fix freedesktop#32850 (program halt during Hungarian spell checking of the word "6csillagocska6", reported by András Tímár) * tools/hunspell.cxx: add Mac OS X Hunspell dictionary paths, asked by Vidar Gundersen in hunfeat#3142010 2011-01-05 Caolán McNamara : * moz#620626 NS_UNICHARUTIL_CID doesn't support case conversion 2011-01-03 Németh László : * NEWS and THANKS: update for release 1.2.13 2010-12-20 Németh László : * affixmgr.cxx: hun#3140784 2010-12-16 Németh László : * affixmgr.cxx: - improved fix of hun#2970242 (supporting zero affixes, reported by Ruud Baars - tests/opentaal_cpdpat{,2}: test files - switching off default BREAK parameters by BREAK 0, reported by Ruud Baars - hun#2999225: interfering compounding mechanisms, reported by Ruud Baars 2010-12-11 Németh László : * affixmgr.cxx: fix hun#2970242 (CHECKCOMPOUNDPATTERN only with flags), the bug reported by Ruud Baars * tests/2970242.*: test files * tests/2970240.*: test files for CHECKCOMPOUNDPATTERN fix (check all boundaries in compound words, fixed by the previous CHECKCOMPOUNDREP fix), the bug reported by Ruud Baars * win_api/Makefile.cygwin: update 2010-12-09 Caolán McNamara : * moz#617953 fix leak 2010-11-08 Caolán McNamara : * rhbz#650503 crash in arabic dictionary 2010-11-05 Caolán McNamara : * rhbz#648740 don't warn on empty flagvector 2010-11-03 Caolán McNamara : * logically we shouldn't need a csconv table in utf-8 mode 2010-10-27 Németh László : * hun#3000055 (requested by Ruud Baars) add REP boundary specifiation: REP ^word$ xxxx REP ^wordstarting xxxx REP wordending$ xxxx * hun#3008434 (requested by Adrián Chaves Fernández) and hun#3018929 (requested by Ruud Baars): REP with more than 2 words: REP morethantwo more_than_two * suggestmgr.cxx: fix incomplete suggestion list for capitalized words, eg. missing Machtstrijd->Machtsstrijd in the Dutch dictionary (reported by Ruud Bars) * tests, man: related updates 2010-10-12 Caolán McNamara : * moz#603311 HashMgr::load_tables leaks dict when decode_flags fails * fix mem leak found with new tests * hun#3084340 allow underscores in html entity names 2010-10-07 Németh László : * affixmgr.cxx: - hun#2970239 fix bad suggestion of forbidden compound words - hun#2999224 fix keepcase feature on compound words (only partial fix for COMPOUNDRULE based compounding) - fix checkcompoundrep feature in compound words (check all boundaries, not only the last one) Problems reported by Ruud Baars. * tests/opentaal_forbiddenword[12]*, tests/opentaal_keepcase*: new test files for the previous fixes * tests/checkcompoundrep: extended test file. 2010-09-05 Caolán McNamara : * moz#583582 fix double buffer gcc fortify issue 2010-08-13 Caolán McNamara : * moz#586671 AffixMgr::parse_convtable leaks pattern/pattern2 if it can't create both * moz#586686 tidy up get_xml_list and friends 2010-08-10 Caolán McNamara : * hun#3022860 fix remove duplicate code 2010-07-17 Caolán McNamara : * remove ununsed get_default_enc and avoid potential misrecognition of three letter language ids * normalize encoding names before lookup 2010-07-05 Caolán McNamara : * hun#2286060 add Hangul syllables to unicode tables 2010-06-26 Caolán McNamara : * moz#571728 keep new[]/delete[] wrappers in sync for embedded in moz case 2010-06-13 Caolán McNamara : * moz#571728 keep new[]/delete[] wrappers in sync for embedded in moz case 2010-06-02 Caolán McNamara : * moz#569611 compile cleanly under win64 2010-05-22 Caolán McNamara : * moz#525581 apply mozilla's current preferred get_current_cs impl 2010-05-17 Németh László : * affixmgr.cxx: fix bad limitation of parenthesized flags at COMPOUNDRULEs. Windows crash reported by Ruud Baars and Simon Brouwer. 2010-05-05 Caolán McNamara : * rhbz#589326 malloc of int that should have been of char** * hun#2997388 fix ironic misspellings 2010-04-28 Caolán McNamara : * moz#550942 get_xml_list doesn't handle failure from get_xml_par 2010-04-27 Caolán McNamara : * moz#465612 mozilla-specific code leaks * moz#430900 phone is dereferenced before oom check * moz#418348 ckey_utf alloc is used unchecked in SuggestMgr::badcharkey_utf * CID#1487 pointer "rl" dereferenced before NULL check * CID#1464 Returned without freeing storage "ptr" * CID#1459 Avoid duplicate strchr * CID#1443 Avoid any chance of dereferencing *slst * CID#1442 Unsafe to have a null morph * CID#1440 Avoid null filenames * CID#1302 Dereferencing NULL value "apostrophe" * CID#1441 Avoid deferencing null ppfx 2010-04-16 Caolán McNamara : * hun#2344123 fix U)ncap in utf-8 locale * fix up hunspell text UI and lines wider than terminal 2010-04-15 Caolán McNamara : * hun#2613701 fix small leak in FileMgr::FileMgr * fix small leak in tools/hunspell * hun#2871300 avoid crash if def and words are NULL * hun#2904479 fix length of hzip file * hun#2986756 mingw build fix * hun#2986756 fix double-free * hun#2059896 fix crash in interactive mode without nls * hun#2917914 add some extra words to the latexparser * make some structs static * C-api has duped symbol names * regenerate gettext/intl with recent version * hun#2796772 build a .dll under MinGW * rhbz#502387 allow cross-compiling for MinGW target * hun#2467643 update .vcproj files to include replist.?xx * unify visiblity/dll_export support across platforms * hun#2831289 sizeof(short) typo * hun#2986756 add -u3 gcc style output 2010-04-14 Caolán McNamara : * hun#2813804 fix segfault on hu_HU stemming 2010-04-13 Caolán McNamara : * hun#2806689 fix ironic misspellings * hun#2836240 add Italian translations 2010-04-09 Caolán McNamara : * fix titchy possible leak in command-line spellchecker 2010-04-07 Caolán McNamara : * hun#2973827 apply win64 patch * hun#2005643 fix broken mystrdup 2010-03-04 Caolán McNamara : * ooo#107768 fix crash in long strings in spellml mode * hun#1999737 add some malloc checks * hun#1999769 drop old buffer on realloc failure * hun#2005643 tidy string functions * hun#2005643 micro-opt * hun#2006077 free strings on failed dict parse * hun#2110783 ispell-alike verbose mode implementation 2010-03-03 Németh László : * hunspell/(affixmgr, suggestmgr).cxx: add character sequence support for MAP suggestion, using parenthesized character groups in the syntax, eg. MAP ß(ss). * man/hunspell.4, tests/map*: documentation and test files 2010-02-25 Németh László : * hunspell/hunspell.cxx: add recursion limit for BREAK (fix OOo Issue 106267) * hunspell/hunspell.cxx: fix crash in morphological analysis of capitalized words with ending dashes * affixmgr.cxx: fix morphological analysis of long numbers combined with dash, eg. 45-00000045 (reported by a@freeblog.hu). 2010-02-23 Caolán McNamara : * hun#2314461 improve ispell-alike mode * hun#2784983 improve default language detection * hun#2812045 fix some compiler warnings * hun#2910695 survive missing HOME dir * hun#2934195 fix suggestmgr crash * hun#2921129 remove unused variables * hun#2826164 make sure make check uses the in-tree libhunspell * bump toolchain to support --disable-rpath * hun#2843984 fix coverity warning * hun#2843986 fix coverity warning * hun#2077630 add iconv lib * make gcc strict-aliasing warning free * make cppcheck warning free 2008-11-01 Németh László : * replist.*, hunspell.cxx, affixmgr.cxx: new input and output conversion support, see ICONV and OCONV keywords in the Hunspell(4) manual page and the test examples. The input/output conversion problem of syllabic languages reported by Daniel Yacob and Shewangizaw Gulilat. - tests/{iconv,oconv}.*: test examples * tools/wordforms: word generation script for dictionary developers (Hunspell version of the unmunch program) * hunspell/hunspell.cxx: extended BREAK feature: ^ and $ mean in break patterns the beginning and end of the word. - tests/BREAK.*: modified examples. * hunspell/hunspell.cxx: set default break at hyphen characters. The associated problem reported by S Page in Hunspell Bug 2174061. See Mozilla Bug ID 355178 and OOo Issue 64400, too. - tests/breakdefault.*: test data The following definition is equivalent of the default word break: BREAK 3 BREAK - BREAK ^- BREAK -$ * affixmgr.cxx: SIMPLIFIEDTRIPLE is a new affix file keyword to allow simplified forms of the compound words with triple repeating letters. It is useful for Swedish and Norwegian languages. * affixmgr.cxx: extend CHECKCOMPOUNDPATTERN to support alternations of compound words for example by sandhi feature of Indian and other languages. The problem reported by Kiran Chittella associated with Telugu writing system (see Telugu example in tests/checkcompoundpattern4.test). The new optional field of CHECKCOMPOUNDPATTERN definition is the replacement of the compound boundary defined by the previous fields: CHECKCOMPOUNDPATTERN ff f ff means ff|f compound boundary has been replaced by "ff", like in the (prereform) German Schiffahrt (Schiff+fahrt). - CHECKCOMPOUNDPATTERN supports also optional flag conditions now: CHECKCOMPOUNDPATTERN ff/A f/B ff means that the first word of the compound needs flag "A" and the second word of the compound needs flag "B" to the operation. * tools/hunspell.cxx: add empty lines as separators to the output of the stemming and morphological analysis. * affixmgr.cxx: fix condition checking algorithm. Bad suggestion generation reported by Mehmet Akin in SF.net Bug 2124186 with help of Eleonora Goldman. * affixmgr,cxx: fix COMPOUNDWORDMAX feature. The problem and its code details reported by Göran Andersson under SF.net Bug ID 2138001. * csutil.cxx: fix bad conditional code for Mozilla compilation. Patch by Serge Gautherie. The problem reported by Ryan VanderMeulen. * hunspell/hunspell.cxx: add missing ngram suggestion for HUHINITCAP (capitalized mixed case) words. * w_char.hxx: use GCC conditions for GCC related code. Patch by Ryan VanderMeulen. * affixmgr.cxx: check morphological description in morphgen() (fix potential program fault by incomplete morphological description of affix rules) * src/win_api: config.h: switch on warning messages on Windows * tools/affixcompress: extended help for -h (use LC_ALL=C sort for input word list) * man/hunspell.4: updated manual: - new and modified features (SIMPLIFIEDTRIPLE, ICONV, OCONV, BREAK, CHECKCOMPOUNDPATTERN). - note about costs of zero affixes, suggested by Olivier Ronez. * hunspell/hunspell.cxx: remove deprecated word breaking codes. 2008-08-15 Németh László : * affentry.cxx: add FULLSTRIP option. With FULLSTRIP, affix rules can strip full words, not only one less characters. Suggested by Davide Prina and other developers in OOo Issue 80145. * tests/fullstrip.*: Test data based on Davide Prina's example. * tools/unmunch.cxx: modified for FULLSTRIP. * affixmgr.cxx: COMPOUNDRULE now works with long and numerical flag types by parenthesized flags. Syntax: (flag)*, (flag)(flag)?(flag)*. * tests/compoundrule[78].*: tests with parenthesized COMPOUNDRULE definitions. * suggestmgr.cxx: modified badchar*(), forgotchar*() and extrachar*() 1-character distance suggestion algorithms: search a TRY character in all position instead of all TRY characters in a character position (it can give more readable suggestion order, also better suggestions in the first positions, when TRY characters are sorted by frequency.) For example, suggestions for "moze": ooze, doze, Roze, maze, more etc. (Hunspell 1.2.6), maze, more, mote, ooze, mole etc. (Hunspell 1.2.7). * suggestmgr.cxx: extended compound word checking for better COMPOUNDRULE related suggestions, for example English ordinal numbers: 121323th -> 121323rd (it needs also a th->rd REP definition). * phonet.cxx: cast unsigned char parameter of isdigit() and fix isalpha by myisalpha() (potential problems in Windows environment). Reported by Thomas Lange in OOo Issue 92736. * hunspell/csutil.*,hunspell/{affentry,affixmgr,hunspell,suggestmgr}.cxx: fix potential buffer overloading under morphological analysis by the new mystrcat() function. Reported by Molnár Andor (dolhpy at true dot hu) in SF.net Bug 2026203. * affixmgr.cxx: add recursion limit to defcpd(). Fix OOo Issue 76067: crash-like deceleration by checking hexadecimal numbers with long FFF sequence (combinatory explosion by the en_US words "f" and "ff"). Missing fix reported by Mathias Bauer. * affixmgr.cxx: fix the difference in the Unicode and non-Unicode parts of cpdcase_check(). Bug report by Brett Wilson. * filemgr.*, affixmgr.cxx, csutil.*, hashmgr.*: warning messages now contain line numbers (use --with-warnings configure option for warning messages). * hunspell.cxx: analyze(): fix case conversion of stemming and morphological analysis of UTF-8 encoded input. Reported by Ferenc Godó. * tools/hunspell.cxx: fix LaTeX Unicode support in filter mode. Reported by Jan Seeger in SF.net Bug 2039990. * affixmgr.hxx: 0.5 or in 64 bit environment, 1 MB (virtual) memory saving using only the requested size for sFlag and pFlag arrays. Bug report by Brett Wilson. * affixmgr.cxx,tools/hunspell.cxx: get_version() returns with full VERSION affix parameter instead of its first word. Fixes for Hunspell's header. Some problems with Hunspell header reported in SF.net Bug 2043080. 2008-07-15 Németh László : * affentry.cxx: fixes of the affix rule matching algorithm (affected only the sk_SK dictionary from all OpenOffice.org dictionaries): - fix dot pattern + accented letters matching (in non Unicode encoding) - word-length conditions work again * tests/condition.*: extended test for the fix. * hashmgr.cxx: load multiword expressions: spaces may be parts of the dictionary words again (but spaces also work as morphological field separators: word word2 -> "word word2", word po:noun -> "word"). * man/hunspell.4: updated manual * tools/hunspell.cxx: add iconv character conversion support to stemming and morphological analysis * tools/hunspell.cxx: add /usr/share/myspell/dicts search path for Ubuntu support 2008-07-09 Németh László : * affentry.cxx: fixes of the affix rule matching algorithm: - right ASCII character handling in bracket expression; - fault-tolerant nextchar() for bad rules. Problem with the en_GB dictionary and nextchar() with a detailed code analysis reported by John Winters in SF.net Bug ID 2012753. * tests/condition.*: extended test for the fix. * hunspell/hunspell.*, parsers/*, tools/hunspell.cxx: fix compiler warnings (deprecated const-free char consts) * win_api/hunspelldll.*: add hunspell_free_list(), the problem reported by Laurier Mercer. 2008-06-30 Török László : * tests/affixmgr.cxx: fix morphological analysis: strcat() on an uninitialized char array in suffix_check_morph(). 2008-06-18 Németh László : * src/hunspell/affixmgr.cxx: fix GCC compiler warnings (comparisons with string literal results in unspecified behaviour). The problem reported by Ladislav Michnovič. 2008-06-17 Németh László : * src/hunspell/{hunspell.cxx,hunspell.h}: add free_list() to the C and C++ interface to deallocate suggestion lists. The problem reported by Laurie Mercer and Christophe Paris. * csutil.cxx: fix freelist() to deallocate non-NULL list, when n = 0. * tools/{analyze,example,chmorph,hunspell}.cxx: use free_list(). * tools/hunspell.cxx: fix only --with-readline compiling problem. Reported by Volkov Peter in SF.net Bug 1995842. * man/hunspell.3,hunspell.hxx: fix analyze and generate examples in the manual and comments (using char*** parameter instead of char**). * tools/example.cxx: fix suggestion example. 2008-06-17 Németh László : * affentry.cxx: fix the new affix rule matching algorithm of Hunspell 1.2. Arabic dictionary problem reported by Khaled Hosny in SF.net Bug ID 1975530. Mohamed Kebdani also sent a prepared test data. * tests/{1975530,condition*}: tests for the fix 2008-06-13 Ingo H. de Boer : * src/hunspell/{affixmgr.cxx,hunspell.cxx}: add missing type cast to strstr() calls for VC8 compatibility. 2008-06-13 Németh László : * suggestmgr.cxx: add also part1-part2 suggestion with dash for bad part1part2 word forms, suggested by Ruud Baars. For example, now suggestion of "parttime": "part time" and "part-time". NOTE: this feature will work only when the TRY definition contains "-" or the letter "a". * hunspell.cxx: new XML API in spell() and suggest() (see hunspell(3)). * src/hunspell/*: fixes for OpenOffice.org build environment. * man/{hunspell.3,hzip.1,hunzip.1}: add new manual pages for Hunspell programming API and dictionary compression and encryption utilities. * src/hunspell/*: handle failed mystrdup() calls and other potential insufficient memory problems. The problem reported by Elio Voci in OpenOffice.org Issue 90604 and others. * src/tools/affixmgr.cxx: restore original behaviour of get_wordchars without conditional code. Problem reported by Ingo H. de Boer in SF.net Bug 1763105. * win_api/hunspelldll.h: put_word() renamed to add() in the (old) Windows DLL API bug reported in SF.net Bug 1943236. Also reported by Bartkó Zoltán. * tools/hunspell.cxx: fix chench() for environments without native language support (ENABLE_NLS 0 in config.h), PHP system_exec() bug reported by Michel Weimerskirch in SF.net Bug 1951087. * hunspell.cxx, affixmgr.cxx: remove "result" from the (result && *result) conditions, when "result" is a static variable. The problem and a possible solution reported by Ladislav Michnovič. * affixmgr.cxx: parse_affix(): print line instead of NULL in the warning message, when affix class header is bad. The problem reported by Ladislav Michnovič. 2008-06-01 Christian Lohmaier * configure.ac: patch to fix --with-readline, --with-ui logic. Reported in the SF.net Bug 981395. 2008-05-04: Volkov Peter * configure.ac: fix LibTool 2.22 incompatibility by removing unused LT_* macros. Report and patch in SF.net Bug 1957383. The problem reported and fixed by Ladislav Michnovič, too. 2008-04-23: Ladislav Michnovič * hunspell.pc.in: fix wrongly set directories. 2008-04-12 Németh László : * src/tools/hunspell.cxx: - Multilingual spell checking and special dictionary support with -d. Multilingual spell checking suggested by Khaled Hosny (SF.net Bug 1834280). Example for the new syntax: -d en_US,en_geo,en_med,de_DE,de_med en_US and de_DE are base dictionaries, and en_geo, en_med, de_med are special dictionaries (dictionaries without affix file). Special dictionaries are optional extension of the base dictionaries. There is no explicit naming convention for special dictionaries, only the ".dic" extension: dictionaries without affix file will be an extension of the preceding base dictionary. First dictionary in -d parameter must have an affix file (it must be a base dictionary). - new options for debugging, morphological analysis and stemming: -m: morphological analysis or flag debug mode (without affix rule data it signs the flag of the affix rules) -s: stemming mode -D: show also available dictionaries and search path (suggested by Aaron Digulla in SF.net Bug 1902133) - add missing refresh() to print bad words before the slower suggestion search in UI (better user experience) - fix tabulator problems (reported by ugli-kid-joe AT sf DOT net) - fix different encoding of dic and input, and suggestions - add per mille sign to LANG hu_HU section. - rewrite program messages. Concatenating multiple printfs for easier translation suggested by András Tímár and Gábor Kelemen. * src/hunspell/csutil.cxx: set static encds variable. Patch by Rene Engerhald. SF.net Bug 1896207 and 1939988. * src/hunspell/w_char.hxx,csutil.hxx: reorganizing w_char typedef and HENTRY_DATA, HENTRY_FIND consts * src/hunspell/hunzip.cxx: fopen(): using rb options instead of r (fix for Windows) * src/tools/affixmgr.cxx: restore original behaviour of get_wordchars in an #ifdef WINSHELL section. Problem reported by Ingo H. de Boer in SF.net Bug 1763105. * src/tools/chmorph.cxx: remove the experimental modifications * src/tools/hzip.c: fopen(): using wb options instead of w (fix for Windows) * src/tools/hunzip.cxx: add missing MOZILLA_CLIENT. Reported by Ryan VanderMeulen. * man/*, man/hu/*: updated manual * man/hunspell.4: fix formatting problem (missing header) * tools/makealias: now works with the extra data fields. * phonet.cxx: use HASHSIZE const * tests/rep.aff: fix REP count * src/win_api/Makefile.cygwin, README: native Windows compilation in Cygwin environment without cygwin1.dll dependency (see README for compiling instructions). 2008-04-08 Roland Smith : * src/parsers/latexparser.cxx: fix PATTERN_LEN for AMD64 and other platforms with different struct padding (SF.net Bug 1937995). 2008-04-03 Kelemen Gábor : * po/POTFILES.in: fix path of the source file * po/Makevars: add --from-code=UTF-8 gettext option * hunspell.cxx: add comments for shortkey translation 2008-02-04 Flemming Frandsen * src/hunspell.h: fix Windows DLL support - this patch also reported by Zoltán Bartkó. 2008-01-30 Mark McClain * src/hunspell.cxx: stem(): fix function call side effect for PPC platform (SF.net Bug 1882105). 2008-01-30 Németh László : * hunspell.cxx, csutil.cxx, hunspelldll.c: fix SF.et Bug 1851246, patch also by Ingo H. de Boer. * hunspell.h: fix SF.net Bug 1856572 (C prototype problem), patch by Mark de Does. * hunspell.pc.in: fix SF.net Bug 1857450 wrong prefix, reported by Mark de Does. * hunspell.pc.in: reset numbering scheme: libhunspell-1.2. Fix SF.net Bug 1857512 reported by Mark de Does, also by Rene Engelhard. * csutil.cxx: patches for ARM platform, signed_chars.dpatch by Rene Engelhard and arm_structure_alignment.dpatch by Steinar H. Gunderson * hunzip.*, hzip.c: new hzip compression format * tools/affixcompressor: affix compressor utility (similar to munch, but it generates affix table automatically), works with million-words dictionaries of agglutinative languages. * README: fix problems reported by Pham Ngoc Khanh. * csutil.cxx, suggestmgr: Warning-free in OOo builds. * hashmgr.*, csutil.*: fix protected memory problems with stored pointers on several not x86 platforms by store_pointer(), get_stored_pointer(). * src/tools/hunspell.cxx: fix iconv support on Solaris platform. * tests/IJ.good: add missing test file * csutil.cxx: fix const char* related errors. Compiling bug with Visual C++ reported by Ryan VanderMeulen and Ingo H. de Boer. 2008-01-03 Caolan McNamara : * csutil.cxx: SF.net Bug 1863239, notrailingcomma patch and optimization of get_currect_cs(). 2007-11-01 Németh László : * hunspell/*: new feature: morphological generation, also fix experimental morphological analysis and stemming. - new API functions and improved API: - analyze(word): (instead of morph()) morphological analysis - stem(word): stemming - stem(list): stemming based on the result of an analysis - generate(word, word2): morphological generation - generate(word, list): morphological generation - add(word): add word to the run-time dictionary (renamed put_word()) - add_with_affix(word, word2): (renamed put_word_pattern()): add word to the run-time dictionary with affix flags of the second parameter: all affixed forms of the user words will be recognised by the spell checker. Especially useful for agglutinative languages. - remove(word): remove word from the run-time dictionary (not implemented) - see manual and hunspell/hunspell.hxx header and tests/morph.* * tests/morph.*: test data, example for morphological analysis, stemming and generation * tools/analyze, tools/chmorph: extended and new demo applications: - analyze (originally hunmorph): analyses and stems input words, generates word forms from input word pairs. - chmorph: morphological transformation filter * configure.ac, hunspell/makefile.am: set library version number. Bug reported by Rene Engelhard. * affentry.cxx, affixmgr.cxx: new pattern matching algorithm in condition checking of affix rules instead of the Dömölki-algorithm: - Unlimited condition length (instead of max. 8 characters). - Less memory consumption, especially useful for affix rich languages: 5,4 MB memory savings with hu_HU dictionary. - Speed change depends from dictionaries and CPU caches: English spell checking is 4% faster on Linux words with en_US dictionary, Hungarian spell checking is 25% slower on most frequent words of Hungarian Webcorpus. * tests/sug.*, sugutf.*: updated test data (use "a" and "lot" dictionary items instead of "a lot".) * src/hunspell/hunspell.cxx: free(csconv) instead of delete csconv. Report and patch by Sylvain Paschein in Mozilla Issue 398268. * suggestmgr.cxx, tools/hunspell.cxx: bad spelling of "misspelled". Ubuntu Bug #134792, patch by Malcolm Parsons. * tests/base_utf.*: use Unicode apostrophe instead of 8-bit one. * hunspell.cxx, hashmgr.cxx: add(): use HashMgr::add() 2007-10-25 Pavel Janík : * hunspell/csutil.cxx: Fix type cast warnings on 64bit Linux in printing of character positions in u8_u16(). OOo issue 82984. 2007-09-05 Németh László : * win_api/Hunspell.vproj, parsers/testparser.cxx,textparser.hxx: warning fixes and removing unnecessary Windows project file. Reported by Ingo H. de Boer. * hashmgr.*, {affixmgr,suggestmgr}.cxx: optimized data structure for variable-count fields (only "ph" transliteration field in this version, see next item). Also less memory consumption: -13% (0.75 MB) with en_US dictionary, -6% (1 MB) with hu_HU. * suggestmgr.cxx: dictionary based phonetic suggestion for special or foreign pronounciation (see also rule-based PHONE in manual). Usage: tab separated field in dictionary lines, started with "ph:". The field contains a phonetic transliteration of the word: Marseille ph:maarsayl * tests/phone.*: test data for dictionary and rule based phonetic suggestion. * hunspell.cxx: fix potential bad memory access in allcap word capitalization in suggest() (bug of previous version). * hunspell.cxx, atypes.hxx: set correct limit for UTF-8 encoded input words (256 byte). * suggestmgr.cxx: improved REP suggestions with spaces: it works without dictionary modification. OOo issue 80147, reported by Davide Prina. * tests/rep.*: new test data: higher priority for "alot" -> "a lot", and Italian suggestion "un'alunno" -> "un alunno". * affixmgr.cxx: fix Unicode ngram suggestions in expand_rootword(). (Suggestions with bad affixes.) Bug reported by Vitaly Piryatinksy . * tests/ngram_utf_fix.*: test based on Vitaly Piryatinksy's data. * suggestmgr.cxx: fix twowords() for last UTF-8 multibyte character. (conditional jump or move depended on uninitialised value). 2007-08-29 Ingo H. de Boer : * win_api/{hunspell,libhunspell, testparser}.vcproj: new project files for the library and the executables. * Hunspell.rc, Hunspell.sln, config.h: updated versions. Version number problem also reported by András Tímár. 2007-08-27 Németh László : * suggestmgr.hxx: put fixed version. Bug report by Ingo H. de Boer. * suggestmgr.cxx: remove variable-length local character array reported by Ingo H. de Boer. 2007-08-27 Németh László : * suggestmgr.hxx: change bad time_t to clock_t in header, too. Bug reports or patches by Ingo H. de Boer under SF.net Bug ID 1781951, János Mohácsi and Gábor Zahemszky, András Tímár, OMax3 at SF.net under SF.net Bug ID 1781592. * phonet.*: change variable-length local character array to portable fixed size character array. Problem reported by Ingo H. de Boer under SF.net Bug ID 1781951 and Ryan VanderMeulen. * suggestmgr.cxx: remove debug message (also by Ingo H. de Boer). 2007-08-26 Ingo H. de Boer : * win_api/Hunspell.vcproj: updated version (with phonet.*) 2007-08-23 Németh László : * phonet.{c,h}xx, suggestmgr.cxx: PHONE parameter: pronounciation based suggestion using Björn Jacke's original Aspell phonetic transcription algorithm (http://aspell.net), relicensed under GPL/LGPL/MPL tri-license with the permission of the author. Usage: see manual. * affixmgr,suggestmgr.cxx: add KEY parameter for keyboard and input method error related suggestions. Example: KEY qwertyuiop|asdfghjkl|zxcvbnm * man/hunspell.4: description about PHONE and KEY suggestion parameters. * suggestmgr.cxx: enhancements for better suggestions: - Set ngram suggestions for badchar-type errors and only two word and compound word suggestions, too. - Separate not compound and compound word suggestions for MAP suggestion, too. - Double swap suggestions for short words. For example: ahev -> have, hwihc -> which. - Better time limits using clock() instead of time() (tenths of a second resolution instead of second ones). - leftcommonsubstring() weigth function. * htype.hxx, hashmgr.cxx: blen (byte length) and clen (character length) fields instead of wlen * affixmgr.cxx: fix get_syllable() for bad Unicode inputs. * tests/suggestiontest/*: test environment for suggestions 2007-08-07 Martijn Wargers: * csutil.cxx: fix Mingw build error associated with ToUpper() call. Report and patch in Mozilla Issue 391447. 2007-08-07 Robert Longson: * atypes.cxx: use empty inline function HUNSPELL_WARNING instead of variadic macros to switch of Hunspell warnings. Reported by Gavin Sharp in Mozilla Issue 391147. 2007-08-05 Ginn Chen: * hashmgr.cxx: Hunspell failed to compile on OpenSolaris (use stdio instead of csdio). Report and patch in Mozilla Issue 391040. 2007-07-25 Németh László : * parsers/*.cxx: Hunspell executable recognises and accepts URLs, e-mail addresses, directory paths, reported by Jeppe Bundsgaard. * src/tools/hunspell.cxx: --check-url: new option of Hunspell program. Use --check-url, if you want check URLs, e-mail addresses and paths. * parsers/textparser.cxx: strip colon at end of words for Finnish and Swedish (colon may be in words in Finnish and Swedish). Problem reported by Lars Aronsson. * tests/colons_in_words.*: test data * tests/digits_in_words.*: example for using digits in words (eg. 1-jährig, 112-jährig etc. in German), reported by Lars Aronsson. * hashmgr.cxx: Hunspell accepts allcaps forms of mixed case words of personal dictionaries (+allcaps custom dictionary words with allcaps affixes). Sf.net Bug ID 1755272, reported by Ellis Miller. * hashmgr.cxx: fix small memory leaks with alias compressed dictionaries (free flag vectors of affixed personal dictionary words and flag vectors of hidden capitalized forms of mixed case and allcaps words). * affixmgr.cxx: fix COMPOUNDRULE checking with affixed compounds. Sf.net Bug ID 1706659, reported by Björn Jacke. Also fixing for OOo Issue 76067 (crash-like deceleration for hexadecimal numbers with long FFFFFF sequence using en_US dictionary). * tools/hunspell.cxx: add missing return to save_privdic(). * man/hunspell.4: add information about affixation of personal words: "Personal dictionaries are simple word lists, but with optional word patterns for affixation, separated by a slash: foo Foo/Simpson In this example, "foo" and "Foo" are personal words, plus Foo will be recognised with affixes of Simpson (Foo's etc.)." 2007-07-18 Németh László : * src/win_api/: add missing resource files, reported by Ingo H. de Boer. 2007-07-16 Németh László : * hunspell.cxx: fix dot removing from UTF-8 encoded words in cleanword2() (Capitalised words with dots, as "Something." were not recognised using Unicode encoded dictionaries.) * tests/{base.*,base_utf.*}: extended and new test files for dot removing and Unicode support. * tools/hunspell.cxx: fix Cygwin, OS X compatibility using platform specifics iconv() header by ICONV_CONST macro of Autoconf. Sf.net Bug ID 1746030, reported by Mike Tian-Jian Jiang. Sf.net Bug ID 1753939, reported by Jean-Christophe Helary. * tools/hunspell.cxx: fix missing global path setting with -d option. * tests/test.sh: fix broken Valgrind checking (missing warnings with VALGRIND=memcheck make check). * csutil.cxx: fix condition in u8_u16() to avoid invalid read of not null-terminated character arrays (detected by Valgrind in Hunspell executable: associated with 8-bit character table conversion in tools/hunspell.cxx). * csutil.cxx: free_utf_tbl(): use utf_tbl_count-- instead of utf_tbl--. Memory leak in Hunspell executable detected by Valgrind. * hashmgr.cxx: add missing free_utf_tbl(), memory leak in Hunspell executable detected by Valgrind. * hashmgr.cxx: load_tables(): fix memory error in spec. capitalization. Use sizeof(unsigned short) instead of bad sizeof(unsigned short*). Invalid memory read detected by Valgrind. * hashmgr.cxx: add_word(): fix memory error in spec. capitalization. Update also affix array length of capitalized homonyms. Invalid memory read detected by Valgrind. * hunspell.cxx: suggest(): fix invalid memory write and leak. Bad realloc() and missing free() detected by Valgrind associated with suggestions for "something.The" type spelling errors. * {dictmgr,csutil,hashmgr,suggestmgr}.cxx: check memory allocation. Sf.net Bug ID 1747507, based on the patch by Jose da Silva. 2007-07-13 Ingo H. de Boer : * atypes.cxx: fix Visual C compatibility: Using "HUNSPELL_WARNING(a,b,...} {}" macro instead of empty "X(a,b...)". * hunspell.cxx: changes for Windows API. * win_api/Hunspell.*: new resource files * win_api/hunspelldll.*: set optional Hunspell and Borland spec. codes Sf.net Bug ID 1753802, patch by Ingo H. de Boer. See also Sf.net Bug ID 1751406, patch by Mike Tian-Jian Jiang. 2007-07-09 Caolan McNamara : * {hunspell,hashmgr,affentry}.cxx: fix warnings of Coverity program analyzer. Sf.net Bug ID, 1750219. 2007-07-06 Németh László : * atypes.cxx: warning-free swallowing of conditional warning messages and their parameters using empty HUNSPELL_WARNING(a,b...) macro. * {affixmgr,atypes,csutil}.cxx: fix unused variable warnings using WARNVAR macro for conditionally named variables. * hashmgr.cxx: fix unused variable warning in add_word() by cond. name * hunspell.cxx: fix shadowed declaration of captype var. in suggest() 2006-06-29 Caolan McNamara : * hunspell.cxx: patch to fix possible memory leak in analyze() of experimental morphological analyzer code. Sf.net Bug ID 1745263. 2007-06-29 Németh László : improvements: * src/hunspell/hunspell.cxx: check bad capitalisation of Dutch letter IJ. - Sf.net Feature Request ID 1640985, reported by Frank Fesevur. - Solution: FORBIDDENWORD for capitalised word forms (need an improved Dutch dictionary with forbidden words: Ijs/*, etc.). * tests/IJ.*: test data and example. * hashmgr.cxx, hunspell.cxx: check capitalization of special word forms - words with mixed capitalisation: OpenOffice.org - OPENOFFICE.ORG Sf.net Bug ID 1398550, reported by Dmitri Gabinski. - allcap words and suffixes: UNICEF's - UNICEF'S - prefixes with apostrophe and proper names: Sant'Elia - SANT'ELIA For Catalan, French and Italian languages. Reported by Davide Prina in OOo Issue 68568. * tests/allcaps*: tests for OPENOFFICE.ORG, UNICEF'S capitalization. * tests/i68568*: tests for SANT'ELIA capitalization. * hunspell/hunspell.cxx: suggestion for missing sentence spacing: something.The -> something. The * tools/hunspell.cxx: multiple character encoding support - -i option: custom input encoding Sf.net Bug ID 1610866, reported by Thobias Schlemmer. Sf.net Bug ID 1633413, reported by Dan Kenigsberg. See also hunspell-1.1.5-encoding.patch of Fedora from Caolan Mc'Namara. * tests/*.test: add input encodings * tools/hunspell.cxx: use locale data for default dictionary names. Sf.net Bug ID 1731630, report and patch from Bernhard Rosenkraenzer, See also hunspell-1.1.4-defaultdictfromlang.patch of Fedora Linux from Caolan McNamara. * tools/hunspell.cxx: fix 8-bit tokenization (letters without casing, like ß or Hebrew characters now are handled well) * tools/hunspell.cxx: dictionary search path - DICPATH environmental variable - -D option: show directory path of loaded dictionary - automatic detection of OpenOffice.org directories fixes: * affixmgr.cxx: fault-tolerant patch for REP and other affix table data problems. Problem with Hunspell and en_GB dictionary reported by Thomas Lange in OOo Issue 76098 and Stephan Bergmann in OOo Issue 76100. Sf.net Bug ID 1698240, reported by Ingo H. de Boer. * csutil.cxx: fix mkallcap_utf() for allcaps suggestion in UTF-8. * suggestmgr.cxx: fix bad movechar_utf() (missing strlen()). * hunspell.cxx: fix bad degree sign detection in Unicode hu_HU environment. * hunspell/hunspell.cxx: free allocated memory of csconv in ported Mozilla code. - Mozilla Bugzilla Bug 383564, report and Mozilla MySpell patch by Andrew Geul. Reported by Ryan VanderMeulen for Hunspell. * suggestmgr.cxx: fix minor difference in Unicode suggestion (ngram suggestion of allcaps words in Unicode). * hashmgr.cxx: close file handle after errors. Sf.net Bug ID 1736286, reported by John Nisly. * configure.ac: syntax error (shell variable with spaces). Sf.net Bug ID 1731625, reported by Bernhard Rosenkraenzer. * hunspell.cxx: check_word(): fix bad usage of info pointer. * hashmgr.cxx: fix de_DE related bug (accept words with leading dash). Sf.net Bug ID 1696134, reported by Björn Jacke. * suggestmgr.cxx, tests/1695964.*: fix NEEDAFFIX homonym suggestion. Sf.net Bug ID 1695964, reported by Björn Jacke. * tests/1463589*: capitalized ngram suggestion test data for Sf.net Bug ID 1463589, reported by Frederik Fouvry. * csutil.cxx, affixmgr.cxx: fix possible heap error with multiple instances of utf_tbl. Sf.net Bug ID 1693875, reported by Ingo H. de Boer. * affixmgr.cxx, suggestmgr.cxx, license.hunspell: convert to ASCII. Locale dependent compiling problems. Sf.net Bug ID 1694379, reported by Mike Tian-Jian Jiang. OOo Issue 78018 reported by Thomas Lange. * tests/test.sh: compatibility issues - fix Valgrind support (check shared library instead of shell wrapper) - remove deprecated "tail +2" syntax - set 8-bit locale for testing (LC_ALL=C) * hunspell.hxx: remove license.* and config.h dependencies. - hunspell-1.1.5-badheader.patch from Caolan McNamara 2007-03-21 Németh László : * tools/Makefile.am, munch.h, unmunch.h: add missing munch.h and unmunch.h Reported by Björn Jacke and Khaled Hosny (sf.net Bug ID 1684144) * hunspell/hunspell.cxx, hunspell.hxx: fix --with-ui compliling error (add get_csconv()) Reported by Khaled Hosny (sf.net Bug ID 1685010) 2007-03-19 Németh László : * csutil.cxx, hunspell/hunspell.cxx: Unicode non BMP area (>65K character range) support (except conditional patterns and strip characters of affix rules) * tests/utf8_nonbmp*: test data * src/hunspell/*: add Mozilla patches from David Einstein - run-time generated 8-bit character tables - other Mozilla related changes (see Mozilla Bugzilla Bug 319778) * csutil.cxx, affixmgr.cxx, hashmgr.cxx: optimized version of IGNORE feature - IGNORE works with affixes (except strip characters and affix conditions) * tests/ignore*: test data with latin characters * tests/ignoreutf*: Unicode test data with Arabic diacritics (Harakat) * src/hunspell/suggestmgr.cxx: new edit distance suggestion methods - capitalization: nasa -> NASA - long swap: permenant -> permanent - long mov.: Ghandi -> Gandhi - double two characters: vacacation -> vacation * tests/sug.*: test data * src/hunspell/affixmgr.cxx: space in REP strings (alot -> a lot) Note: Underline character signs the space in REP strings: REP alot a_lot, and put the expression with space ("a lot") into the dic file (see tests/sug). * hashmgr.cxx, affixmgr.cxx: ignore Unicode byte order mark (BOM sequence) * tests/utf8_bom*: test data * hunspell/*.cxx: OOo Issue 68903 - Make lingucomponent warning-free on wntmsci10 - fix Hunspell related warning messages on Windows platform (except some assignment within conditional expressions). Reported and started by Stephan Bergmann. * hunspell/affixmgr.cxx: fix OOo Issue 66683 - hunspell dmake debug=x fails - Reported by Stephan Bergmann. * src/hunspell/hunspell.[ch]xx: thread safe API for Hunspell executable (removing prev*() functions, new spell(word, info, root) function) * configure.ac, src/hunspell/*: HUNSPELL_EXPERIMENTAL code --with-experimental configure option (conditional compiling of morphological analyser and stemmer tools) * configure.ac, src/hunspell/*: conditional Hunspell warning messages --with-warnings configure option * affixmgr.cxx: new, optimized parsing functions * affixmgr.cxx: fix homonym handling for German dictionary project, reported by Björn Jacke (sf.net Bug ID 1592880). * tests/1592880.*: test data by Björn Jacke * src/hunspell/affixmgr.cxx: fix CIRCUMFIX suggestion Bug reported by Erdal Ronahi. * hunspell.cxx: reverse root word output (complex prefixes) Bug reported by Munzir Taha. * tools/hunspell.cxx: fix Emacs compatibility, patch by marot at sf.net - no % command in PIPE mode (SourceForge BugTracker 1595607) - fix HUNSPELL_VERSION string * suggestmgr.[hc]xx: rename check() functions to checkword() (OOo Issue 68296) adopt MySpell patch by Bryan Petty (tierra at ooo) for Hunspell source * csutil.cxx, munch.c, unmunch.c: adopt relevant parts of the MinGW patch (OOo Issue 42504) by tonal at ooo * affigmgr.cxx: remove double candidate_check() call, reported by Bram Moolenaar * tests/test.sh: add LC_ALL="C" environment. Locale dependency of make check reported by Gentoo project. * src/tools/hunspell.cxx: UTF-8 highlighting fix for console UI (not solved: breaking long UTF-8 lines) * src/tools/unmunch.c: fix bad generation if strip is shorter than condition, reported by Davide Prina * src/tools/unmunch.h: increase 5000 -> 500000 * src/tools/hunspell.cxx: fix memory error in suggestion (uninitialized parameter), Bug also reported by Björn Jacke in SourceForge Bug 1469957 * csutil.cxx, affixmgr.cxx: fix Caolan McNamara's patch for non OOo environment 2006-11-11 Caolan McNamara : * csutil.cxx, affixmgr.cxx: UTF-8 table patch (OOo Issue 71449) Description: memory optimization (OOo doesn't use the large UTF-8 table). * Makefile.am: shared library patch (Sourceforge ID 1610756) * hunspell.h, hunspell.cxx: C API patch (Sourceforge ID 1616353) * hunspell.pc: pkgconfig patch (Sourceforge ID 1639128) 2006-10-17 Ryan Jones : * affixmgr.cxx: missing fclose(affixlst) calls Reported by in OOo Issue 70408 2007-07-11 Taha Zerrouki : * affixmgr.cxx, hunspell.cxx, hashmgr.cxx, csutil.cxx: IGNORE feature to remove optional Arabic and other characters from input and dictionary words. * src/hunspell/langnum.hxx: add Arabic language number, lang_ar=96 * tests/ignore.*: test data 2006-05-28 Miha Vrhovnik : * src/win_api/*: C API for Windows DLLs - also Delphi text editor example (see on Hunspell Sourceforge page) 2006-05-18 Kevin F. Quinn : * utf_info.cxx: struct -> static struct Shared library patch also developed by Gentoo developers (Hanno Meyer-Thurow, Diego Pettenò, Kevin F. Quinn) 2006-02-02 Németh László : * src/hunspell/hunspell.cxx: suggest(): replace "fooBar" -> "foo bar" suggestions with "fooBar" ->"foo Bar" (missing spaces are typical OCR bugs). Bug reported by stowrob at OOo in Issue 58202. * src/hunspell/suggestmgr.cxx: twowords(): permit 1-character words. (restore MySpell's original behavior). Here: "aNew" -> "a New". * tests/i58202.*: test data * src/parsers/textparser.cxx: fix Unicode tokenization in is_wordchar() (extra word characters (WORDCHARS) didn't work on big-endian platforms). * src/hunspell/{csutil,affixmgr}.cxx: inline isSubset(), isRevSubset(): little speed optimalization for languages with rich morphology. * src/tools/hunspell.cxx: fix bad --with-ui and --with-readline compiling when (N)curses is missing. Reported by Daniel Naber. 2006-01-19 Tor Lillqvist * src/hunspell/csutil.cxx: mystrsep(): fix locale-dependent isspace() tokenization 2006-01-06 András Tímár * src/hunspell/{hashmgr.hxx,hunspell.cxx}: fix Visual C++ compiling errors 2006-01-05 Németh László : * COPYING: set GPL/LGPL/MPL tri-license for Mozilla integration. Rationale: Mozilla source code contains an old MySpell version with GPL/LGPL/MPL tri-license. (MPL license is a copyleft license, similar to the LGPL, but it acts on file level.) * COPYING.LGPL: GNU Lesser General Public License 2.1 (LGPL) * COPYING.MPL: Mozilla Public License 1.1 (MPL) * license.hunspell, src/hunspell/license.hunspell: GPL/LGPL/MPL tri-license * src/hunspell/{affixmgr,hashmgr}.*: AF, AM alias definitions in affix file: compression of flag sets and morphological descriptions (see manual, and tests/alias* test files). Rationale: Alias compression is also good for loading time and memory efficiency, not only smaller resources. * src/tools/makealias: alias compression utility (usage: ./makealias file.dic file.aff) * tests/alias{,2,3}: AF, AM tests * man/hunspell.4: add AF, AM documentation * src/hunspell/affentry.cxx, atypes.hxx: add new opts bits (aeALIASM, aeALIASF) * tools/hunspell, src/parser/*, src/hunspell/*: Hunspell program tokenizes Unicode texts (only with UTF-8 encoded dictionaries). Missing Unicode tokenization reported by Björn Jacke, Egmont Koblinger, Jess Body and others. Note: Curses interactive interface hasn't worked perfectly yet. * tests/*.tests: remove -1 parameters of Hunspell * tests/*.{good,wrong}: remove tabulators * src/hunspell/{hunspell,affixmgr}.cxx: BREAK option: break words at specified break points and checking word parts separately (see manual). Note: COMPOUNDRULE is better (or will be better) for handling dashes and other compound joining characters or character strings. Use BREAK, if you want check words with dashes or other joining characters and there is no time or possibility to describe precise compound rules with COMPOUNDRULE. * tests/break.*: BREAK example. * src/hunspell/{affixmgr,hunspell}.cxx: add CHECKSHARPS declaration instead of LANG de_DE definitions to handle German sharp s in both spelling and suggestion. * src/hunspell/hunspell.cxx: With CHECKSHARPS, uppercase words are valid with both lower sharp s (it's is optional for names in German legal texts) and SS (MÜßIG, MÜSSIG). Missing lower sharp s form reported by Björn Jacke. * src/hunspell/hunspell.cxx: KEEPCASE flag on a sharp s word has a special meaning with CHECKSHARPS declaration: KEEPCASE permits capitalisation and SS upper casing of a sharp s word (Müßig and MÜSSIG), but forbids the upper cased form with lower sharp s character(s): *MÜßIG. * tests/germancompounding*: add CHECKSHARPS, remove LANG * tests/checksharps*: add CHECKSHARPS and KEEPCASE, remove LANG * src/hunspell/hunspell.cxx: improved suggestions: - suggestions for pressed Caps Lock problems: macARONI -> macaroni - suggestions for long shift problems: MAcaroni -> Macaroni, macaroni - suggestions for KEEPCASE words: KG -> kg * src/hunspell/csutil.cxx: fix mystrrep() function: - suggestions for lower sharp s in uppercased words: MÜßIG -> MÜSSIG * tests/checksharps{,utf}.sug: add tests for mystrrep() fix * src/hunspell/hashmgr.cxx: Now dictionary words can contain slashes with the "\/" syntax. Problem reported by Frederik Fouvry. * src/hunspell/hunspell.cxx: fix bad duplicate filter in suggest(). (Suggesting some capitalised compound words caused program crash with Hungarian dictionary, OOo Issue 59055). * src/hunspell/affixmgr.cxx: fix bad defcpd_check() call in compound_check(). (Overlapping new COMPOUNDRULE and old compounding methods caused program crash at suggestion.) * src/hunspell/affixmgr.{cxx,hxx}: check affix flag duplication at affix classes. Suggested by Daniel Naber. * src/hunspell/affentry.cxx: remove unused variable declarations (OOo i58338). Compiler warnings reported by András Tímár and Martin Hollmichel. * src/hunspell/hunspell.cxx: morph(): not analyse bad mixed uppercased forms (fix Arabic morphological analysis with Buckwalter's Arabic transliteration) * src/hunspell/affentry.{cxx,hxx}, atypes.hxx: little memory optimization in affentry: - using unsigned char fields instead of short (stripl, appndl, numconds) - rename xpflg field to opts - removing utf8 field, use aeUTF8 bit of opts field * configure.ac: set tests/maputf.test to XFAILED on ARM platform. Fail reported by Rene Engelhard. * configure.ac: link Ncursesw library, if exists. * BUGS: add BUGS file * tests/complexprefixes2.*: test for morphological analysis with COMPLEXPREFIXES * src/hunspell/affixmgr.cxx: use "COMPOUNDRULE" instead of "COMPOUND". The new name suggested by Bram Moolenaar. * tests/compoundrule*: modified and renamed compound.* test files * man/hunspell.4: AF, AM, BREAK, CHECKSHARPS, COMPOUNDRULE, KEEPCASE. - also new addition to the documentation: Header of the dictionary file define approximate dictionary size: ``A dictionary file (*.dic) contains a list of words, one per line. The first line of the dictionaries (except personal dictionaries) contains the _approximate_ word count (for optimal hash memory size).'' Asked by Frederik Foudry. One-character replacements in REP definitions: ``It's very useful to define replacements for the most typical one-character mistakes, too: with REP you can add higher priority to a subset of the TRY suggestions (suggestion list begins with the REP suggestions).'' 2005-11-11 Németh László : * src/hunspell/affixmgr.*: fix Unicode MAP errors (sorted only n-1 characters instead of n ones in UTF-16 MAP character lists). Bug reported by Rene Engelhard. * src/hunspell/affixmgr.*: fix infinite COMPOUND matching (default char type is unsigned on PowerPC, s390 and ARM platforms and it will never be negative). Bug reported by Rene Engelhard. * src/hunspell/{affixmgr,suggestmgr}.cxx: fix bad ONLYINCOMPOUND word suggestions. * tests/onlyincompound.sug: empty test file to check this fix. Bug reported by Björn Jacke. * src/hunspell/affixmgr.cxx: fix backtracking in COMPOUND pattern matching. * tests/compound6.*: test files to check this fix. * csutil.cxx: set bigger range types in flag_qsort() and flag_bsearch(). * affixmgr.hxx: set better type for cont_classes[] Boolean data (short -> char) * configure.ac, tests/automake.am: set platform specific XFAIL test (flagutf8.test on ARM platform) 2005-11-09 Németh László : improvements: * src/hunspell/affixmgr.*: new and improved affix file parameters: - COMPOUND definitions: compound patterns with regexp-like matching. See manual and test files: tests/compound*.* Suggested by Bram Moolenaar. Also useful for simple word-level lexical scanning, for example analysing numbers or words with numbers (OOo Issue #53643): http://qa.openoffice.org/issues/show_bug.cgi?id=53643 Examples: tests/compound{4,5}.*. - NOSUGGEST flag: words signed with NOSUGGEST flag are not suggested. Proposed flag for vulgar and obscene words (OOo Issue #55498). Example: tests/nosuggest.*. Problem reported by bobharvey at OOo: http://qa.openoffice.org/issues/show_bug.cgi?id=55498 - KEEPCASE flag: Forbid capitalized and uppercased forms of words signed with KEEPCASE flags. Useful for special ortographies (measurements and currency often keep their case in uppercased texts) and other writing systems (eg. keeping lower case of IPA characters). - CHECKCOMPOUNDCASE: Forbid upper case characters at word bound in compounds. Examples: tests/checkcompoundcase* and tests/germancompounding.* - FLAG UTF-8: New flag type: Unicode character encoded with UTF-8. Example: tests/flagutf8.*. Rationale: Unicode character type can be more readable (in a Unicode text editor) than `long' or `num' flag type. bug fixes: * src/hunspell/hunspell.cxx: accept numbers and numbers with separators (i53643) Bug reported by skelet at OOo: http://qa.openoffice.org/issues/show_bug.cgi?id=53643 * src/hunspell/csutil.cxx: fix casing data in ISO 8859-13 character table. * src/hunspell/csutil.cxx: add ISO-8859-15 character encoding (i54980) Rationale: ISO-8859-15 is the default encoding of the French OpenOffice.org dictionary. ISO-8859-15 is a modified version of ISO-8859-1 (latin-1) character encoding with French œ ligatures and euro symbol. Problem reported by cbrunet at OOo in OOo Issue 54980: http://qa.openoffice.org/issues/show_bug.cgi?id=54980 * src/hunspell/affixmgr.cxx: fix zero-byte malloc after a bad affix header. Patch by Harri Pitkänen. * src/hunspell/suggestmgr.cxx: fix bad NEEDAFFIX word suggestion in ngram suggestions. Reported by Daniel Naber and Friedel Wolff. * src/hunspell/hashmgr.cxx: fix bad white space checking in affix files. src/hunspell/{csutil,affixmgr}.cxx: add other white space separators. Problems with tabulators reported by Frederik Fouvry. * src/hunspell/*: replace system-dependent #include parameters with quoted ones. Problem reported by Dafydd Jones. * src/hunspell/hunspell.cxx: fix missing morphological analysis of dot(s) Reported by Trón Viktor. changes: * src/hunspell/affixmgr.cxx: rename PSEUDOROOT to NEEDAFFIX. Suggested by Bram Moolenaar. * src/hunspell/suggestmgr.hxx: Increase default maximum of ngram suggestions (3->5). Suggested by Kevin Hendricks. * src/hunspell/htypes.hxx: Increase MAXDELEN for long affix flags. * src/hunspell/suggestmgr.cxx: modify (perhaps fix) Unicode map suggestion. tests/maputf test fail on ARM platform reported by Rene Engelhard. * src/hunspell/{affentry.cxx,atypes.hxx}: remove [PREFIX] and MISSING_DESCRIPTION messages from morphological analysis. Problems reported by Trón Viktor. * tests/germancompounding.{aff,good}: Add "Computer-Arbeit" test word. Suggested by Daniel Naber. * doc/man/hunspell.4: Proof-reading patch by Goldman Eleonóra. * doc/man/hunspell.4: Fix bad affix example (replace `move' with `work'). Bug reported by Frederik Fouvry. * tests/*: new test files: affixes.*: simple affix compression example from Hunspell 4 manual page checkcompoundcase.*, checkcompoundcase2.*, checkcompoundcaseutf.* compound.*, compound2.*, compound3.*, compound4.*, compound5.* compoundflag.* (former compound.*) flagutf8.*: test for FLAG UTF-8 germancompounding.*: simplification with CHECKCOMPOUNDCASE. germancompoundingold.* (former germancompounding.*) i53643.*: check numbers with separators i54980.*: ISO8859-15 test keepcase.*: test for KEEPCASE needaffix*.* (former pseudoroot*.* tests) nosuggest.*: test for NOSUGGEST 2005-09-19 Németh László : * src/hunspell/suggestmgr.cxx: improved ngram suggestion: - detect not neighboring swap characters (pernament -> permanent) Rationale: ngram method has a significant error with not neighboring swap characters, especially when swap is in the middle of the word. - suggest uppercase forms (unesco -> UNESCO, siggraph's -> SIGGRAPH's) - suggest only ngram swap character and uppercase form, if they exist. Rationale: swap character and casing equivalence give mutch better suggestions as any other (weighted) ngram suggestions. - add uppercase suggestion (PERMENANT -> PERMANENT) * src/hunspell/*: complete comparison with MySpell 3.2 (in OOo beta 2): - affixmgr.cxx: add missing numrep initialization - hashmgr.cxx: add_word(): don't allocate temporary records - hunspell.cxx: in suggest(): - check capitalized words first (better sug. order for proper names), - check pSMgr->suggest() return value - set pSMgr->suggest() call to not optional in HUHCAP - csutil.cxx: fix bad KOI8-U -> koi8r_tbl reference in enc_entry encds - csutil.cxx: fix casing data in ISO 8859-2, Windows 1251 and KOI8-U encoding tables. Bug reported by Dmitri Gabinski. * src/hunspell/affixmgr.*: improved compound word and other features - generalize hu_HU specific compound word features with new affix file parameters, suggested by Bram Moolenaar: - CHECKCOMPOUNDDUP: forbid word duplication in compounds (eg. foo|foo) - CHECKCOMPOUNDTRIPLE: forbid triple letters in compounds (eg. foo|obar) - CHECKCOMPOUNDPATTERN: forbid patterns at word bounds in compounds - CHECKCOMPOUNDREP: using REP replacement table, forbid presumably bad compounds (useful for languages with unlimited number of compounds) - ONLYINCOMPOUND flag works also with words (see tests/onlyincompound.*) Suggested by Daniel Naber, Björn Jacke, Trón Viktor & Bram Moolenaar. - PSEUDOROOT works also with prefixes and prefix + suffix combinations (see tests/pseudoroot5.*). Suggested by Trón Viktor. - man/hunspell.4: updated man page * src/hunspell/affixmgr.*: fix incomplete prefix handling with twofold suffixes (delete unnecessary contclasses[] conditions in prefix_check_twosfx() and prefix_check_twosfx_morph()). Bug reported by Trón Viktor. * src/hunspell/affixmgr.*: complete also *_morph() functions with conditions of new Hunspell features (circumfix, pseudoroot etc.). * src/hunspell/suggestmgr.cxx: - fix missing suggestions for words with crossed prefix and suffix - fix redundant non-compound word checking - fix losing suggestions problem. Bug reported by Dmitri Gabinski. * src/hunspell/dictmgr.*: - add new dictionary manager for Hunspell UNO modul Problems with eo_ANY Esperanto locale reported by Dmitri Gabinski. * src/hunspell/*: use precise constant sizes for 8-bit and 16-bit character arrays with MAXWORDUTF8LEN and MAXSWUTF8L macros. * src/hunspell/affixmgr.cxx: fix bad MAXNGRAMSUGS parameter handling * src/hunspell/affixmgr.cxx, src/tools/{un}munch.*: fix GCC 4.0 warnings on fgets(), reported by Dvornik László * po/hu.po: improved translation by Dvornik László * tests/test.sh: improved test environment - add suggestion testing (see tests/*.sug) - add memory debugging environment, based on the excellent Valgrind debugger. Usage on Linux and experimental platforms of Valgrind: VALGRIND=memcheck make check - rename test_hunmorph to test.sh * tests/*: new tests: - base.*: base example based on MySpell's checkme.lst. - map{,utf}.*, rep{,utf}: MAP and REP suggestion examples - tests on new CHECKCOMPOUND, ONLYINCOMPOUND and PSEUDOROOT features - i54633.*: capitalized suggestion test for Issue 54633 from OOo's Issuezilla - i35725.*: improved ngram suggestion test for Issue 35725 2005-08-26 Németh László : improvements: * src/hunspell/suggestmgr.cxx: Unicode support in related character map suggestion * src/hunspell/suggestmgr.cxx: Unicode support in ngram suggestion * src/hunspell/{suggestmgr,affixmgr,hunspell}.cxx: improve ngram suggestion. Fix http://qa.openoffice.org/issues/show_bug.cgi?id=35725. See release notes for examples. This problem reported by beccablain at OOo. - ngram suggestions now are case insensitive (see `Permenant' bug in Issuezilla) - weight ngram suggestions (with the longest common subsequent algorithm, also considering lengths of bad word and suggestion, identical first letters and almost completely identical character positions) - set strict affix congruency in expand_rootword(). Now ngram suggestions are good for languages with rich morphology and also better for English. Rationale: affixed forms of the first ngram suggestion very often suppress the second and subsequent root word suggestions. But faults in affixes are more uncommon, and can be fix without suggestions. We must prefer the more informative second and subsequent root word suggestions instead of the suggestions for bad affixes. - a better suggestion may not be substring of a less good suggestion Rationale: Suggesting affixed forms of a root word is unnecessary, when root word has got better weighted ngram value. (Checking substrings is a good approximation for this refinement.) - lesser ngram suggestions (default 3 maximum instead of 10) Rationale: For users need a big extra effort to check a lot of bad ngram suggestions, nine times out of ten unnecessarily. It is very distracting, because ngram suggestions could be very different. Usually Myspell and Hunspell suggest one or two suggestions with the old suggestion algorithms (maximum is 15), with ngram algorithm often gives maximum number suggestions. With strict affix congruency and other refinements, the good suggestion there is usually among the first three elements. - new affix parameter: MAXNGRAMSUG * src/hunspell/*: support agglutinative languages with rich prefix morphology or with right-to-left writing system (for example, Turkic and Austronesian languages with (modified) Arabic scripts). - new affix parameter: COMPLEXPREFIXES Set twofold prefix stripping (but single suffix stripping) * src/hunspell/affixmgr.cxx: - speed up prefix loading with tree sorting algorithm. * tests/complexprefixes.*, tests/complexprefixesutf.*: Coptic example posted by Moheb Mekhaiel * src/hunspell/hashmgr.cxx: check size attribute in dic file suggested by Daniel Naber Rationale: With missing size attribute Hunspell allocates too small and more slower hash memory, and Hunspell can lose first dictionary word. * src/hunspell/affixmgr.cxx: check stripping characters and condition compatibility in affix rules (bugs detected in cs_CZ, es_ES, es_NEW, es_MX, lt_LT, nn_NO, pt_PT, ro_RO and sk_SK dictionaries). See release notes of Hunspell 1.0.9 in NEWS. * src/hunspell/affixmgr.cxx: check unnecessary fields in affix rules (bugs detected in ro_RO and sv_SE dictionaries). See release notes. * src/hunspell/affixmgr.cxx: remove redundant condition checking in affix rules with stripping characters (redundancy in OpenOffice.org dictionaries reported by Eleonóra Goldman) Rationale: this is a little optimization, but it was excellent for detect the bad ngram affixation with bad or weak affix conditions. * tests/germancompounding.aff: improve compound definition - use dash prefix instead of language specific tokenizer Rationale: Using uniform approach is the right way to check and analyze compound words. Language specific word breaking is deprecated, need a sophisticated grammar checking for word-like word pairs (for example in Hungarian there is a substandard, but accepted syntax with dash for word pairs: cats, dogs -> kutyák-macskák (like cats/dogs in English). * test Hunspell with 54 OpenOffice.org dictionaries: see release notes bug fixes: * src/hunspell/suggestmgr.*: add time limit to exponential algorithm of the related character map suggestion Rationale: a long word in agglutinative languages or a special pattern (for example a horizontal rule) made of map characters can `crash' the spell checker. * src/hunspell/affentry.cxx: add() functions: fix bad word generation checking stripping characters (see similar bug in unmunch) * src/hunspell/affixmgr.cxx: parse_file(): fix unconditional getNext() call for ~AffixMgr() when affix file is corrupt. * src/hunspell/affixmgr.*: AffixMgr(), parse_cpdsyllable(): fix missing string duplications for ~AffixMgr() when affix file is corrupt. * src/hunspell/affixmgr.*: parse_affix(): fix fprintf() call when affix file is corrupt. Bug reported by Daniel Naber. * suggestmgr.cxx: replace single usage of 'strdup' with 'mystrdup' patch by Chris Halls (debian.org) * src/hunspell/makefile.mk: add makefile.mk for compiling in OpenOffice.org See README in Hunspell UNO modul. Problems with separated compiling reported by Rene Engelhard * src/hunspell/hunspell.cxx: fix pseudoroot support - search a not pseudoroot homonym in check() * tests/pseudoroot4.*: test this fix * src/tools/unmunch.c: fix bad word generation when conditions are shorter or incompatible with stripping characters in affix rules * src/tools/unmunch.c: fix mychomp() for de_AT.dic and other dic files without last new line character. other changes: * src/hunspell/suggestmgr.*: erase ACCENT suggestion Rationale: ACCENT suggestion was the same as Kevin Hendrick's map suggestion algorithm, but with a less good interface in affix file. * src/hunspell/suggestmgr.*: combine cycle number limit in badchar(), and forgotchar() with a time limit. * src/hunspell/affixmgr.*: remove NOMAPSUGS affix parameter * src/hunspell/{suggestmgr,hunspell}.*: strip periods from suggestions (restore MySpell's original behaviour) Rationale: OpenOffice.org has an automatic period handling mechanism and suggestions look better without periods. - new affix file parameter: SUGSWITHDOTS Add period(s) to suggestions, if input word terminates in period(s). (No need for OpenOffice.org dictionaries.) * tests/germancompounding.aff: improve bad german affix in affix example (computeren->computern). Suggested by Daniel Naber. * src/tools/example.cxx: add Myspell's example * src/tools/munch.cxx: add Myspell's munch * man{,/hu}/hunspell.4: refresh manual pages 2005-08-01 Németh László : * add missing MySpell files and features: - add MySpell license.readme, README and CONTRIBUTORS ({license,README,AUTHORS}.myspell) - add MySpell unmunch program (src/tools/unmunch.c) - add licenses to source (src/hunspell/license.{myspell,hunspell}) - port MAP suggestion (with imperfect UTF-8 support) - add NOSPLITSUGS affix parameter - add NOMAPSUGS affix parameter * src/man/man.4: MAP, COMPOUNDPERMITFLAG, NOSPLITSUGS, NOMAPSUGS * src/hunspell/aff{entry,ixmgr}.cxx: - improve compound word support - new affix parameter: COMPOUNDPERMITFLAG (see manual) * src/tests/compoundaffix{,2}.*: examples for COMPOUNDPERMITFLAG * src/tests/germancompounding.*: new solution for German compounding Problems with German compounding reported by Daniel Naber * src/hunspell/hunspell.cxx: fix German uppercase word spelling with the spellsharps() recursive algorithm. Default recursive depth is 5 (MAXSHARPS). * src/tests/germansharps*: extended German sharp s tests * src/tools/hunspell.cxx: fix fatal memory bug in non-interactive subshells without HOME environmental variable Bug detected with PHP by András Izsók. 2005-07-22 Németh László : * src/hunspell/csutil.hxx: utf16_u8() - fix 3-byte UTF-8 character conversion 2005-07-21 Németh László : * src/hunspell/csutil.hxx: hunspell_version() for OOo UNO modul 2005-07-19 Németh László : * renaming: - src/morphbase -> src/hunspell - src/hunspell, src/hunmorph -> src/tools - src/huntokens -> src/parsers * src/tools/hunstem.cxx: add stemmer example 2005-07-18 Németh László : * configure.ac: --with-ui, --with-readline configure options * src/hunspell/hunspell.cxx: fix conditional compiling * src/hunspell/hunspell.cxx: set HunSPELL.bak temporaly file in the same dictionary with the checked file. * src/morphbase/morphbase.cxx: - handling German sharp s (ß) - fix (temporaly) analyize() * tests: a lot of new tests * po/, intl/, m4/: add gettext from GNU hello * po/hu.po: add Hungarian translation * doc/, man/: rename doc to man 2005-07-04 Németh László : * src/morphbase/hashmgr.cxx: set FLAG attributum instead of FLAG_NUM and FLAG_LONG * doc/hunspell.4: manual in English 2005-06-30 Németh László : * src/morphbase/csutil.cxx: add character tables from csutil.cxx of OOo 1.1.4 * src/morphbase/affentry.cxx: fix Unicode condition checking * tests/{,utf}compound.*: tests compounding 2005-06-27 Németh László : * src/morphbase/*: fix Unicode compound handling 2005-06-23 Halácsy Péter: * src/hunmorph/hunmorph.cxx: delete spelling error message and suggest_auto() call 2005-06-21 Németh László : * src/morphbase: Unicode support * tests/utf8.*: SET UTF-8 test * src/morphbase: checking and fixing with Valgrind Memory handling error reported by Ferenc Szidarovszky 2005-05-26 Németh László : * suggestmgr.cxx: fix stemming * AUTHORS, COPYING, ChangeLog: set CC-LGPL free software license 2004-05-25 Varga Dániel * src/stemtool: new subproject 2005-05-25 Halácsy Péter * AUTHORS, COPYING: set CC Attribution license 2004-05-23 Varga Dániel * src: - modifications for compiling with Visual C++ * src/hunmorph/csutil.cxx: correcting header of flag_qsort(), * src/hunmorph/*: correct csutil include 2005-05-19 Németh László * csutil.cxx: fix loop condition in lineuniq() bug reported by Viktor Nagy (nagyv nyelvtud hu). * morphbase.cxx: handle PSEUDOROOT with zero affixes bug reported by Viktor Nagy (nagyv nyelvtud hu). * tests/zeroaffix.*: add zeroaffix tests 2005-04-09 Németh László * config.h.in: reset with autoheader * src/hunspell/hunspell.cxx: set version 2005-04-06 Németh László * tests: tests * src/morphbase: New optional parameters in affix file: - PSEUDOROOT: for forbidding root with not forbidden suffixed forms. - COMPOUNDWORDMAX: max. words in compounds (default is no limit) - COMPOUNDROOT: signs compounds in dictionary for handling special compound rules - remove COMPOUNDWORD, ONLYROOT 2005-03-21 Németh László * src/morphbase/*: - 2-byte flags, FLAG_NUM, FLAG_LONG - CIRCUMFIX: signed suffixes and prefixes can only occur together - ONLYINCOMPOUND for fogemorpheme (Swedish, Danish) or Flute-elements (German) - COMPOUNDBEGIN: allow signed roots, and roots with signed suffix in begin of compounds - COMPOUNDMIDDLE: like before, but middle of compounds - COMPOUNDEND: like before, but end of compounds - remove COMPOUNDFIRST, COMPOUNDLAST hunspell-1.7.0/ChangeLog.O000066400000000000000000000476071337236234000153410ustar00rootroot00000000000000Myspell has a lot of parallel development, that is not documented here. 2005-01-11: Nmeth Lszl * hunspell.cxx: - interaktv javtsnl hinyz j sor karakterek ptlsa. A hibt Gefferth Andrs s Khiraly jelezte. * csutil.cxx: - pontosvesszk trlse a GCC 3.4-es fordt ignyeinek megfelelen A hibt Dvornik Lszl jelezte. - i vltoz ismtelt deklarsnak trlse, ami helyenknt hibs fordtst eredmnyez. A hibt Ldoktor s Bencsth Boldizsr jelezte. * OLVASS.EL: - Windows alatti fordtsnl Langid.cxx mdostand. A hibt Ldoktor jelezte. 2004-12-15 Nmeth Lszl * src/morphbase/*: - handling K&R morphological encoding (remove plus signs from output) - LEMMA_PRESENT: put only morphological description to output - LANG parameter, langnum variable in source for writing language-dependent codes - remove HU_KOTOHANGZO - etc. * doc/hunspell.4: - adding some 2004-09-29 Halcsy Pter * doc/ : bemsoltam a hunspell.1 hunspell.4 man oldalakat * doc/hunspell.1: Kivettem a -s -m kapcsolkrl szl rszt 2004-09-28 Halcsy Pter * src/hunspell/hunspell.cxx (indexing_interface): Ezt kiszedtem a HunSpell-bol, mert nem ide valo. Ez egy kulon program lehet. (main): a hunstem zemmdot is kidobtam, ez se ide val (main): meg a hunmorph zemmdot is * src/morphbase/morphbase.cxx (MorphBase): tneveztem a MySpell osztlyt MorphBase-re (stems): tnevezten a suggest_stems metdust stem -re (mint to stem) 2004-08-25 Nmeth Lszl * src/hunbase/suggestmgr.cxx: tvezs visszalltsa, nem mkdik mg az igektk hozztoldsa a thz, tovbb a kivtelek kezelse (ehhez a 0.99.4-es sztr szksges mg). * src/hunbase/myspell.cxx: -s vissza a tvezshez * src/hunbase/atypes.hxx: HUNSTEM makr definilsa itt az affixmgr.cxx feltteles kdjhoz 2004-08-12 Halacsy Peter * src/misc/lexfilter.cxx : uj program, ami a szotar szureshez hasznalhato lecserelheti a mostani hunmorph, hunspell -G -1 funkciokat * src/hunbase/myspell.cxx (analyzer) : Uj metodust vettem fel, ami mar karaktertombben adja vissza az elemzes eredmenyet 2004-08-03 Halcsy Pter * src/hunspell/hunspell.cxx (HUNSPELL_VERSION): ttettem ide ennek definilst 2004-07-31 Halcsy Pter * src/hunbase/suggestmgr.cxx (fixstems): A fixstems mirt itt van s mirt gy hvjk. Ez mehetne egy kln osztlyba. 2004-07-31 Halcsy Pter * src/huntoken/htmlparser.cxx: Egyebkent az include-ok kezelese eleg zavaros. Peldaul itt minek a textparser.hxx includolasa? * src/huntoken/textparser.hxx (MAXLNLEN): thoztam ide a MAXLNLEN makrt az atypes.hxx-bol, hogy a fuggoseget megszuntessem * src/hunbase/myspell.cxx (suggest): Kivettem azt a rszt, ami visszaadja a HUNSPELL_VERSION stringet ha a VERSION_KEYWORD a bemeneti string. Csnya gnyolsnak tartottam 2004-07-27 Halcsy Pter * src/hunbase/myspell.cxx (morph_with_correction): * src/hunbase/baseaffix.hxx (class AffEntry): Allandora felvettem a morphcode mezot (last htypes.hxx) * src/hunbase/affentry.hxx: Kivettem a hunmorph felteteleket (last htypes.hxx) * src/hunbase/htypes.hxx (struct hentry): Kivettem a HUNMORPH feltetelt a char* description korul. Ertem, hogy hatekonyabb egy folosleges mutato nelkul, ha nincs morf info, de szerintem felesleges * src/hunbase/myspell.hxx: HUNSPELL_VERSION es VERSION_KEYWORD makrokat kivettem. Valamiert a hunspellnek kell majd * src/hunbase/config.hxx (FLAG): config.hxx torolve, helyet atveszi a kozponti config.h; FLAG definicioja az atypes.hxx-be ment * src/hunbase/atypes.hxx (FLAG): config.hxx megszuntetese erdekeben attettem ide a FLAG makro definialasat, ami az EXT_CLASS-tol fugg config.hxx include kicserelve a configure altal kezelt config.h-ra 2004-06-29: Nmeth Lszl * affixmgr.cxx: - csak utols tagknt megengedett szavak (compound3) toldalk nlkli elfordulsnak engedlyezse (pl. macskapr) - tbbszrsen sszetett szavak toldalkolt alakjainak morfolgiai elemzse * myspell.cxx: - rvidtsek, szmok, ktjeles sszetett szavak s a -e hatrozszt tartalmaz szavak morfolgiai elemzse * suggestmgr.cxx: suggest_morph_for_spelling_error() optimalizlsa (csak a felhasznlt egy javaslatot keresi meg, tbbet nem). * csutil.cxx: kimenetben szerepl res sorok trlse 2004-06-10: Nmeth Lszl * suggestmgr.cxx: sszetett szavak elemzsnek korltozsa - a tvezs mg nincs megvalstva a 0.9.9-es vltozatban (helyette a Hunspell 0.9.7 hasznland a Magyar Ispell 0.99.4-es vltozatval) 2004-05-19: Nmeth Lszl * 0.9.9f-alpha - morf. lers sztringkezelse jav. - EXT_CLASS: config.cxx-ben - nagybets alakok is elemezve (a hibt Tron Viktor jelezte) - szebb kimenet - rule119 trlve - firstparser.cxx javtva 2004-02-13: Nmeth Lszl * 0.9.8a: - MAXUSERWORD helyett USERWORD, nincs korlt - description \t-vel dic fjlba - homonimk kezelse - aff formtumbvts - konfixumok - _morpho fggvnyek - ketts szuffixum - hunmorph - lsd tests/hunmorph 2004-01-29: Nmeth Lszl * 0.9.7-sztaki: - memriakezelsi hibk javtsa 2003-12-17: Nmeth Lszl * 0.9.7-es vltozat: * affixmgr.cxx: - suffix_check() javts (tmpword kivltsa isRevSubSet() fggvnnyel - betlts optimalizlsa, build_pfxlist() helyett: - build_pfxtree() - process_sfx_tree_to_list(), process_sfx_inorder() * csutil.cxx: - isSubSet() gyorsabb vltozata - isRevSubSet() * langid.cxx, hunp.cxx: - nyelvfelismer osztly s program (l. man hunp) * man/hunp.1: - nyelvfelismer program lersa * firstparser.cxx: - csak a tabultorjelet tartalmaz sorokbl a tabultorjel eltti rszt adja vissza (l. man Hunspell, -1 kapcsol) * hunspell.cxx: - -u, -U, -u2 kapcsolk: tipikus hibk kijelzse; automatikus, illetve lektorlt javtsa. L. man hunspell. - -w kapcsol teljes sor vizsglathoz * hunspell.cxx: - spell(): javts (Valgrind hibajelzs alapjn) * hunspell.cxx: sprintf()-ek el strlen() felttelvizsglat * suggestmgr.cxx: - 0.99.4-es Hunspell sztrral bekerlt tvezsi hiba javtsa (nem produktv ragozs, sszetett szbam szerepl fneveknl lpett fel ez a problma). * OLVASS.EL: - bvts 2003-11-03: Nmeth Lszl * SuggestMgr::permute_accent(): - illeglis memriaolvassi hiba javtsa. * example.cxx:: - dupla free() a "" karakterlnc tvezse utn A hibkat Sarls Tams fedezte fel a figyelemre mlt Valgrind nyomkvet programmal (http://developer.kde.org/~sewardj/) 2003-10-22: Bencsth Boldizsr * affixmgr.[ch]xx, csutil.[ch]xx: Az eredeti MySpell foltjainak alkalmazsa az OpenOffice.org 1.1 kompatibilits rdekben. Itt karakterkezel segdfggvnyek lettek thelyezve elrhetbb helyre. * dictmgr.[ch]xx: Itt etype paramter hozzadsa. * makefile.mk: Itt angol sztrak megjegyzsbe ttele. 2003-10-04: Nmeth Lszl * 0.9.6.3-as vltozat: * myspell.cxx: suggest() fggvnyben hibs memriafoglals javtsa. A hiba a pontra vgzd helytelen szavakra adott javaslattevs sorn jelentkezett. A hibs mkdst Khiraly jelezte. 2003-09-15: Nmeth Lszl * 0.9.6.2-es vltozat: * latexparser.cxx: TeX elemz javtsa: - elemzsi hiba ({{}}}) - verb+ +, \verb stb. kezelse 2003-09-01: Nmeth Lszl * 0.9.6-os vltozat: * affentry.cxx: check2 trlse, lehetsges tvek trolsa * suggestmgr.cxx, myspell.cxx: suggest_pos_stems() az ismeretlen szavak nvszragjainak s jeleinek levlasztsra. * affixmgr.cxx, suggestmgr.cxx: suggest_stems() szlkezelshez mdostott s javtott fggvny * myspell.cxx: szmok tvezse (teszt: 5-nek) * myspell.cxx: egy karakter + sz javaslatok trlse (pldul cpak->cpa k) * affixmgr.cxx, myspell.cxx, hunspell.cxx: sztr verziszmnak kirsa * hunspell.cxx: \r karaktert tartalmaz sorok helyes megjelentse * myspell.cxx, hunspell.cxx: rvidts vgi pontok hozzadsa fggvnyknyvtr szinten * hunspell.cxx: pipe_interface(): standard bemenet tvezsnl hinyz memriafelszabadts ptlsa * Makefile: install javtsa, tbb felttelvizsglat deinstall szakasz 2003-07-22: Nmeth Lszl * 0.9.5-s vltozat * suggestmgr.cxx: marhalevl->lelevl tvezs javtsa * myspell.cxx: nagy kezdbets rvidtsek vizsglata (Bp., Btk.) - pontot tartalmaz szmok helyesnek val elfogadsa, ha: - az els pontot legalbb egy, - de legfeljebb hrom szmjegy elzi meg, - a pontok nem egyms mellett helyezkednek el, - az utols pont utn legfeljebb kt szmjegy van. Ezzel elfogadjuk az idpontokat (12.00-kor), a pontozsokat (1.1.2-ben), de kizrjuk a szkz nlkli hibs dtummegadsokat (2003.7.22.), valamint a tizedesvessz helyett ponttal rt tizedestrteket (3.456, 4563.34). - Javts a tiltott szavakra adott ktjeles javaslatoknl: Straussal->Strauss-szal, s nem ,,Strauss szal''. * hunspell.cxx: csak a -a kapcsol megadsval lnek a csfelleti parancsok. Ezrt most mr nincsenek figyelmen kvl hagyva pldul a ktjellel kezdd sorok, ha a -l kapcsolval hibs szavakat keresnk egy llomnyban. * man/hunspell.1: a -a kapcsol lersnak kiegsztse. 2003-06-13: Nmeth Lszl * 0.9.4-es vltozat * bin/*: makedb, lookdb segdprogramok az indexelshez * man/*: hunstem, makedb, lookdb * hunspell.cxx: pipe_interface: nyomkvet kirs trlse - LOG #ifdef-be 2003-06-11: Nmeth Lszl * 0.9.3-es vltozat * suggestmgr.cxx: nagybets javaslat tulajdonneveknl * hunspell.cxx: pipe_interface: hiba javtsa 2003-06-05: Nmeth Lszl * 0.9.2-es vltozat * hunspell.cxx: -s kapcsol * suggestmgr.cxx: suggest_stems() Sztvek ellltsa * example.cxx: plda a sztvek ellltsra 2003-05-13: Nmeth Lszl * 0.9.1-es vltozat * hunspell.cxx: - rl_escape(), stb.: a readline sorban ki lett kapcsolva a fjlnv-kiegszts, s helyette a kt Escape lenyoms megszaktja a szvegbevitelt. A Csere mveletnl is a readline() hvs tallhat most mr. - egy hibs sprintf() sor javtva lett * Makefile.unix: - belltsok elklntve az llomny elejn - Makefile most mr szimblikus kts * ooomagyarispellteszt.txt: tesztllomny 2003-04-28: Nmeth Lszl * affixmgr.cxx: - y vg szavak kezelse: bvebb lers a Magyar Ispell Changelog llomnyban. * *parser.cxx: ISO-8859-1 HTML karakterentitsok kzl a betrtkek (csak az ISO-8859-2-ben nem szereplk) felismerse s kezelse. 2003-04-21: Goldman Elenonra * *.dll fggvnyknyvtr ellltsa Windows alatt: - StdAfx.h - libmyspell.def - dlltest.cpp 2003-04-16: Nmeth Lszl * Hunspell.cxx, stb: a Mispell tnevezse Hunspell-l. A nevet Kornai Andrs javasolta. Knyvtrak: /usr/share/mispell -> /usr/share/myspell (korbban is ez volt). A /usr/share/hunmorph sztr a helye a specilis morfolgiai informcikat tartalmaz Hunmorph (bvtett Myspell sztrformtum) sztrllomnyoknak. * Licenc: LGPL * config.hxx: SZOSZABLYA_POSSIBLE_ROOTS Ha a makrt bekapcsoljuk, akkor kirsra kerlnek a lehetsges tvek is, az alkalmazott ragozsi szably osztlynak betjelvel, illetve az alapszval egytt. 2003-04-10: Nmeth Lszl : * affixmgr.cxx: - kthangzk helyes kezelse (hu_kotohangzo kapcsolval), l. mg Magyar Ispell Changelog 2003-03-24: Nmeth Lszl * mispell.cxx: pipe_interface(): az adatfjl szrsnl fellp memriaszivrgs megszntetse a kimaradt free(token) ptlsval * affixmgr.cxx: prefix_check(): leg-, legesleg- confixum ellenrzs - onlyroot kapcsol a csak tszt rint tiltshoz. L. Magyar Ispell Az affixum llomnyban j kapcsolt adhatunk meg az ONLYROOT paranccsal bevezetve. A kapcsol mdostja a tiltkapcsol mkdst. L. man 4 mispell * myspell.cxx: - spell(): nagybets tulajdonnevek ellenrzse (pl. BALATON) - onlyroot vizsglat forbiddenword mellett -> mangrove kezelse 2003-03-17: Goldman Elenonra * Windows port * makefile.Windows: 2003-03-04: Nmeth Lszl * firstparser.[ch]xx: adatfjlok szrshez (l. -1 kapcsol) * mispell.cxx: -L, -1, -G kapcsolk * man/mispell.1: -L, -1, -G kapcsolk 2003-03-03: Nmeth Lszl * mispell.cxx: -l, -p, WORDLIST * man/mispell.1: -l, -p, WORDLIST 2003-02-26: Nmeth Lszl * mispell.cxx: dialog_screen(): TILTOTT! (FORBIDDEN!) megjelentse a tiltott szsszettelek esetn. * suggestmgr.cxx: - check(): -, - kpzs igeneveket rint kd trlse - check_forbidden(): a 6 sztagnl hosszabb, tiltott sztvekre vonatkoz javaslatok nem ktjellel, hanem szkzzel elvlasztva tartalmazzk a szavakat, ehhez szksges a check_forbidden(). * man/*: j kziknyv oldal az llomnyok formtumrl (mispell(4)), a mispell(1) bvtse. * Makefile, mispell.mo: Br rpd javtsai 2003-02-18: Nmeth Lszl * mispell.cxx: interactive_interface() - nem nyeli el a MAXLNLEN-t meghalad mret sorokban a MAXLNLEN mret rszek hatrn lv karaktereket, s a nem jsor karakterre vgzd llomnyok utols karaktert. (Hibt viszont mg mindig jelez, ha a MAXLNLEN hatr feldarabol egy amgy helyes szt.) A MAXLNLEN 8192 karakter jelenleg. - readline fggvnyknyvtr hasznlata a bevitelnl - tfelvtelnl egy lehetsges t ellltsa, s a beviteli sorban val feltntetse. Az gy megjelen sz javthat. - --help kapcsol * Makefile: Javtsok az install szakaszban. A hibkat Br rpd jelezte. 2003-02-07: Nmeth Lszl * mispell.cxx: put_dots_to_suggestions() - realloc() cserje malloc()-ra ismeretlen eredet lefagys miatt. - lehetsges az Ispellhez hasonlan a kapcsolkat kzzel megadni a sajt sztrban a szavak utn egy perjelet kveten: pldul a valamicsnyasz/w sor megadsa utn a valamicsnyasz s toldalkolt vltozatai hibsak lesznek az ellenrzs alatt. (Tovbbi kapcsolk lersrt lsd a Magyar Ispell forrsban az aff/aff.fej llomnyt.) * affixmgr.cxx: compound_check() - repl_chars() hvsa a megfelel helyre lett tve, ezzel a javaslattevs sebessge ktszeresre ntt. - A dinamikus memriakezels lecserelse veremmemrira nem jrt lnyeges sebessgnvekedssel, de a kzeljvben ezzel elkerlhet az a memriaszivrgs, ami pldul itt a tiltott szavak kezelsnl volt az elz vltozatban (javtva). * affentry.cxx, affixmgr.cxx: szt-elllt kd megalapozsa: get_possible_root() metdus az utols toldalk-levlaszts eredmnyvel tr vissza. 2003-02-05: Nmeth Lszl * mispell.cxx: put_dots_to_suggestions(): amennyiben a felismert sz pontra, vagy pontokra vgzdik, a javaslatokat is bvti ezzel. - @, valamint 1-nl tbb pontot magba foglal (de nem arra vgzd) szavak ellenrzsnek tiltsa (e-mail, fjlnevek, mg nem opcionlis). - Hossz sorok helyes megjelentse. - Tabultorjelet tartalmaz sorok helyes megjelentse. - Mozaikszavak tfelvtelnl ktjeles alak automatikus rgztse Pl.: BKV//URH mellett BKV-//URH- is bekerl a sajt sztrba (a ragozott mozaikszavak felismerse teht automatikus lesz, kivve a nem trivilis -val/-vel toldalkos alakok, amit kln kell felvenni.) - PuT trlse (helyette MySpell::put_word(), put_word_suffix(), put_word_pattern() eljrsok a sajt sztr bvtsre) - dupla szavak ellenrzsnek trlse a MySpell kdbl (thelyezs majd a Mispell felletbe), hogy a MySpell meghvhat maradjon prhuzamosan fut szlakbl. 2002-12-30: Nmeth Lszl * *parser.cxx, *parser.hxx: elemz osztlyok a rgi s csnya kd helyett 2002-12-10: Nmeth Lszl * myspell.cxx: 35-os, 20%-kal kezelse * man/mispell.1: kziknyv 2002-12-04: Noll Jnos * spdaemon/: kiszolgl fellet, ld. README.spdaemon 2002-12-04: Nmeth Lszl * mispell.cxx: Emacs kompatibilitshoz hibk javtsa (pl. tbbszrs -d) * mispell.cxx: CURSES makrval kikapcsolhat az interaktv fellet + locale (Windows, Macintosh) 2002-11-30: Nmeth Lszl * affixmgr.cxx: get_checkdoublewords() 2002-11-25: Nmeth Lszl * affixmgr.cxx: mozgszably (hu_mov_rule) * myspell.cxx: mozgszably * affixmgr.cxx: kitljnekmacskt (affix is sszetettben, ha prefix) 2002-11-08 Nmeth Lszl * myspell.cxx: balatonnak->Balatonnak, balatoninak 2002-11-07 Nmeth Lszl * myspell: 0.6-os vltozat 2002-10-31 Nmeth Lszl * Egyszerbb nv: Magyar MySpell 0.5 utn -> MIspell 0.6 * mispell.cxx: tbbnyelv interaktv fellet (ncurses, locale) * Makefile: make install 2002-09-22 Nmeth Lszl * affixmgr.cxx: compound_check() macskaugom->macskaugrom, stb. javtsa * affixmgr.cxx: compound_check() szismtls (pl. macskamacska) tiltsa * myspell.cxx: szismtlds tiltsa (pl. kutya kutya) msodik rossz * suggestmgr.cxx: macskarat->macska rat mellett ->macskairat 2002-07-29 Nmeth Lszl * mispell Windowsra, teszt Emacs-szel (vagy Emacs-csal) * tiltott szavakat nem javasol, s sszetett szban sem fogad el * fonev_morfo, fonev_morfo2 lsztvek elutastsa (hzakmacska) * ktjeles szavak kezelse * szmok kezelse, ktjeles alakjaikkal egytt, CHECKNUM kapcsol 2002-07-17 Nmeth Lszl * mispell.cxx: MySpell Ispell cs interfsz 2002-07-04 Nmeth Lszl * mispell.cxx: MySpell Ispell cs interfsz * affxmgr.cxx: szszer kiszrse, * j funkcik: COMPOUNDFIRST: sz szerepelhet els tagknt a szszettelekben COMPOUNDLAST: sz szerepelhet utols tagknt a szszettelekben FORBIDDENWORD: tiltott szavak kapcsolja (ut, uta, stb.) 2002-06-25 Nmeth Lszl * myspell.cxx, suggestmgr.cxx: get_compound() char* helyett char * affxmgr.cxx: check_repl() a helyesnek tn, de hibs sszetett szavak kiszrsre (pl. tejles, szervz) A szsszettel elfogadsa eltt mg megnzzk, hogy a sz nem-e a cseretblzatban felvett hibt tartalmaz, ha igen, akkor a sz hibsnak minsl, hiba helyes szsszettel. * affxmgr.cxx, suggestmgr.xx: accent: kezetest. Lers: README.accent Tovbbi optimalizci: az kezet nlkli bet kezetes vltozatai szmnak fggvnyben 2002-06-05 Noll Jnos * myspell.cxx, suggestmgr.cxx: mem. szivrgs javtsa (a get_compound() felszabadts nlkl lett meghva). A hiba a GNU mtrace segtsgvel lett detektlva. 2002-06-03 Nmeth Lszl * Licenc: GPL * Lsd MYSPELL.HU * compound_check: 6-3 szably, stb. MySpell: 2002-xx-xx Kevin Hendricks * REP: ismtlsek kiszrse a javaslatokbl * COMPOUNDMIN 2002-xx-xx Nmeth Lszl * REP cseretblzat * COMPOUND, szsszettelkpzs 2002-xx-xx David Einstein * optimalizlt MySpell algoritmus 2001-xx-xx Kevin Hendricks * Mkd ellenrz, Ispell toldalktmrtsi algoritmussal hunspell-1.7.0/Makefile.am000066400000000000000000000003231337236234000154060ustar00rootroot00000000000000ACLOCAL_AMFLAGS = -I m4 SUBDIRS= po src man tests pkgconfdir = $(libdir)/pkgconfig pkgconf_DATA = hunspell.pc EXTRA_DIST = license.myspell license.hunspell \ ChangeLog.O COPYING.LESSER hunspell.pc.in hunspell-1.7.0/NEWS000066400000000000000000000671521337236234000140660ustar00rootroot000000000000002018-11-12: Hunspell 1.7.0 release: New features and bug fixes by Lszl Nmeth, supported by FSF.hu Foundation: - No annoying suggestion times any more, especially in languages with compound word handling and complex morphology. By adding balanced multi-level time limits, now the guaranteed suggestion time is there within half a second, not seconds (nor dozen of seconds or more in extreme cases) for longer misspellings, too. - add SPELLML support for run-time dictionary extension with optional affixation of user words. See new "Grammar By" feature of language-specific user dictionaries of LibreOffice 6.0: News: https://wiki.documentfoundation.org/ReleaseNotes/6.0#.E2.80.9CGrammar_By.E2.80.9D_spell_checking Screencast with English example: https://www.youtube.com/watch?v=EsS3gaBTfOo Screencast with German example: https://www.youtube.com/watch?v=aYVFDqCUb6I - Improved, highly customizable suggestions on level of dictionary words: Pronunciations and typical misspellings defined by optional "ph:" fields of the dictionary words are used not only in n-gram suggestions, but as elements of the REP replacement list getting the highest priority in normal suggestions, also giving the best suggestions for short words, too. More information: see "ph:" in man 5 hunspell. - Handling multiple word suggestions is much more easier. Like in a traditional spelling dictionary, for example, to get the correct suggestion "a lot" for the typical misspelling "alot" at the first place, now it's enough to put the following line to the dic(tionary) file: a lot - Limit compound overgeneration by dictionary based word pairs: Now it's possible to filter bad compound words by listing the correct word pairs with space in the dictionary, as in a traditional spelling dictionary. - clean-up suggestion: - no n-gram and compound word suggestions, if "good" suggestion exists, ie. uppercase, REP, ph: or dictionary word pair suggestions - word pairs are always suggested, if they exist in the dic file - word pairs have top priority in suggestions, and these are the only suggestions if there is no other good suggestion. - also dictionary word pairs separated by dash instead of space are handled specially in two-word suggestion (depending from the language) - limit bad suggestions by improved n-gram suggestion rules: don't suggest capitalized dictionary words for lower case misspellings in n-gram suggestions, except - PHONE usage, or - in the case of German, where not only proper nouns are capitalized, or - the capitalized word has special pronunciation and don't suggest if the difference of lengths of misspellings and suggestions is 5 or more characters. - Extend dotless i and dotted I rules to Crimean Tatar language Allow dotted I in dictionary, and disable bad capitalization of i. - BREAK: extended recursive word breaking algorithm to handle words or words with suffixes when they already contain word break characters, for example, "e-mail" is a dictionary word with a word break character, and it wasn't accepted before in compounds in some languages. - FORBIDDENWORD precedes BREAK: Now it's possible to forbid compound forms recognized by BREAK word breaking by adding the bad compounds to the dictionary with FORBIDDENWORD flags. - lower limit for "doubletwochars" suggestion algorithm: one of the typical misspellings recognized by Hunspell suggestion mechanism is the syllable duplication. Along the old pattern ABABA -> ABA, for example nutrITITIon -> nutrITIon, now also the simpler ABAB -> AB pattern is recognized in non-starting position, for example, regretTETEd -> regretTEd. - lower limit for longswapchar and movechar: recognized only max. 4-character distances to avoid slow and bad suggestions. - fix compound handling for new Hungarian orthography reform - Allow suggestion search for prefix + *two suffixes*: Remove artificial performance limit to get correct suggestions for relatively simple misspellings in Hungarian, etc., when the word form contains prefix and both derivative and inflectional suffixes, too: lefikszlsa -> lefixlsa Improvements for command-line Hunspell: - Remove false alarms during checking OpenDocument (ODF) documents by ignoring elements. (LibreOffice creates a lot of elements also within words during text reediting, resulted often huge amount of broken words before this fix.) - List filenames during filtering multiple files in command-line: Examples: $ hunspell -l *.odt a.odt: mispelling b.odt: egzample $ hunspell -l -G *.odt a.odt: good b.odt: words - Dictionary search by option -D doesn't wait for the standard input (fixed by Siva Mahadevan) Other improvements: - makealias dictionary compression: add option --minimize-diff to reuse free positions of alias lists to create minimal and readable diffs for alias compressed dictionaries stored in revision control systems, as dictionaries of LibreOffice. - Brazilian-Portuguese translation by Rafael Fontenelle - Catalan translation by robert dot buj at gmail - Minor bug fixes by several contributors, see git log 2017-09-03: Hunspell 1.6.2 release: - Library changes: no. Same as 1.6.1. - Command line tool: - Added German translation - Fixed bug with wrong output encoding, not respecting system locale. 2017-03-25: Hunspell 1.6.1 release: - Library changes: - Performance improvements in suggest() - Fixes regressions for Hungarian related to compounding. - Fixes regressions for Korean related to ICONV. - Command line tool: - Added Tajik translation - Fix regarding serching of OOo dicts installed in user folder - Manpages: - Fix microsoft-cp1251 to cp1251. Dicts should not use the first. - Typos. 2016-12-22: Hunspell 1.6.0 release: - Library changes: - Performance improvement in ngsuggest(), suggestions should be faster. - Revert MAXWORDLEN to 100 as in 1.3.3 for performance reasons. - MAXWORDLEN can be set during build time with -D defines. - Fix crash when word with 102 consecutive X is spelled. - Command line tool: - -D shows all loaded dictionares insted of only the first. - -D properly lists all available dictionaries on Windows. 2016-11-30: Hunspell 1.5.4 release: - Fixes the command COMPOUNDSYLLABLE used in Hungarian dictionary. 2016-11-28: Hunspell 1.5.3 release: - Removed a #include from hunspell.hxx that was creating trouble 2016-11-27: Hunspell 1.5.2 release: - Reverted full backward compatibility with 1.4 public API, again 2016-11-27: Hunspell 1.5.1 release: - Reverted full backward compatibility with 1.4 public API 2016-11-18: Hunspell 1.5.0 release: - Lot of stability fixes - Fixed compilation errors on various systems (Windows, FreeBSD) - Small performance improvement compared to 1.4.0 - The C++ API is updated to use modern C++ types (string, vector). Backward compatibility is kept for most of the functions except for the following: - get_wordchars(); - get_version(); - input_conv(string, string); - removed get_csconv(); 2016-04-15: Hunspell 1.4.0 release: - various abi changes due to moving away from char* to std::string 2014-06-02: Hunspell 1.3.3 release: - OpenDocument (ODF and Flat ODF) support (ODF needs unzip program) - various bug fixes 2011-02-02: Hunspell 1.3.2 release: - fix library versioning - improved manual 2011-02-02: Hunspell 1.3.1 release: - bug fixes 2011-01-26: Hunspell 1.2.15/1.3 release: - new features: MAXDIFF, ONLYMAXDIFF, MAXCPDSUGS, FORBIDWARN, see manual - bug fixes 2011-01-21: - new features: FORCEUCASE and WARN, see manual - new options: -r to filter potential mistakes (rare words signed by flag WARN in the dictionary) - limited and optimized suggestions 2011-01-06: Hunspell 1.2.14 release: - bug fix 2011-01-03: Hunspell 1.2.13 release: - bug fixes - improved compound handling and other improvements supported by OpenTaal Foundation, Netherlands 2010-07-15: Hunspell 1.2.12 release 2010-05-06: Hunspell 1.2.11 release: - Maintenance release bug fixes 2010-04-30: Hunspell 1.2.10 release: - Maintenance release bug fixes 2010-03-03: Hunspell 1.2.9 release: - Maintenance release bug fixes and warnings - MAP support for composed characters or character sequences 2008-11-01: Hunspell 1.2.8 release: - Default BREAK feature and better hyphenated word suggestion to accept and fix (compound) words with hyphen characters by spell checker instead of by work breaking code of OpenOffice.org. With this feature it's possible to accept hyphenated compound words, such as "scot-free", where "scot" is not a correct English word. - ICONV & OCONV: input and output conversion tables for optional character handling or using special inner format. Example: # Accepting de facto replacements of the Romanian comma acuted letters SET UTF-8 ICONV 4 ICONV ş ș ICONV ţ ț ICONV Ş Ș ICONV Ţ Ț Typical usage of ICONV/OCONV is to manage an inner format for a segmental writing system, like the Ethiopic script of the Amharic language. - Extended CHECKCOMPOUNDPATTERN to handle conpound word alternations, like sandhi feature of Telugu and other writing systems. - SIMPLIFIEDTRIPLE compound word feature: allow simplified Swedish and Norwegian compound word forms, like tillåta (till|låta) and bussjåfør (buss|sjåfør) - wordforms: word generator script for dictionary developers (Hunspell version of unmunch). - bug fixes 2008-08-15: Hunspell 1.2.7 release: - FULLSTRIP: new option for affix handling. With FULLSTRIP, affix rules can strip full words, not only one less characters. - COMPOUNDRULE works with all flag types. (COMPOUNDRULE is for pattern matching. For example, en_US dictionary of OpenOffice.org uses COMPOUNDRULE for ordinal number recognition: 1st, 2nd, 11th, 12th, 22nd, 112th, 1000122nd etc.). - optimized suggestions: - modified 1-character distance suggestion algorithms: search a TRY character in all position instead of all TRY characters in a character position (it can give more readable suggestion order, also better suggestions in the first positions, when TRY characters are sorted by frequency.) For example, suggestions for "moze": ooze, doze, Roze, maze, more etc. (Hunspell 1.2.6), maze, more, mote, ooze, mole etc. (Hunspell 1.2.7). - extended compound word checking for better COMPOUNDRULE related suggestions, for example English ordinal numbers: 121323th -> 121323rd (it needs also a th->rd REP definition). - bug fixes 2008-07-15: Hunspell 1.2.6 release: - bug fix release (fix affix rule condition checking of sk_SK dictionary, iconv support in stemming and morphological analysis of the Hunspell utility, see also Changelog) 2008-07-09: Hunspell 1.2.5 release: - bug fix release (fix affix rule condition checking of en_GB dictionary, also morphological analysis by dictionaries with two-level suffixes) 2008-06-18: Hunspell 1.2.4-2 release: - fix GCC compiler warnings 2008-06-17: Hunspell 1.2.4 release: - add free_list() for C, C++ interfaces to deallocate suggestion lists - bug fixes 2008-06-17: Hunspell 1.2.3 release: - extended XML interface to use morphological functions by standard spell checking interface, spell() and suggest(). See hunspell.3 manual page. - default dash suggestions for compound words: newword-> new word and new-word - new manual pages: hunspell.3, hzip.1, hunzip.1. - bug fixes 2008-04-12: Hunspell 1.2.2 release: - extended dictionary (dic file) support to use multiple base and special dictionaries. - new and improved options of command line hunspell: -m: morphological analysis or flag debug mode (without affix rule data it signs the flag of the affix rules) -s: stemming mode -D: list available dictionaries and search path -d: support extra dictionaries by comma separated list. Example: hunspell -d en_US,en_med,de_DE,de_med,de_geo UNESCO.txt - forbidding in personal dictionary (with asterisk, / signs affixation) - optional compressed dictionary format "hzip" for aff and dic files usage: hzip example.aff example.dic mv example.aff example.dic /tmp hunspell -d example hunzip example.aff.hz >example.aff hunzip example.dic.hz >example.dic - new affix compression tool "affixcompress": compression tool for large (millions of words) dictionaries. - support encrypted dictionaries for closed OpenOffice.org extensions or other commercial programs - improved manual - bug fixes 2007-11-01: Hunspell 1.2.1 release: - new memory efficient condition checking algorithm for affix rules - new morphological functions: - stem() for stemming - analyze() for morphological analysis - generate() for morphological generation - new demos: - analyze: stemming, morphological analysis and generation - chmorph: morphological conversion of texts 2007-09-05: Hunspell 1.1.12 release: - dictionary based phonetic suggestion for words with special or foreign pronounciation or alternative (bad) transliteration (see Changelog, tests/phone.* and manual). - improved data structure and memory optimization for dictionaries with variable count fields - bug fixes for Unicode encoding dictionaries and ngram suggestions - improved REP suggestions with space: it works without dictionary modification - updated and new project files for Windows API 2007-08-27: Hunspell 1.1.11 release: - portability fixes 2007-08-23: Hunspell 1.1.10 release: - pronounciation based suggestion using Bjrn Jacke's original Aspell phonetic transcription algorithm (http://aspell.net), relicensed under GPL/LGPL/MPL tri-license with the permission of the author - keyboard base suggestion by KEY (see manual) - better time limits for suggestion search - test environment for suggestion based on Wikipedia data - bug fixes for non standard Mozilla platforms etc. 2007-07-25: Hunspell 1.1.9 release: - better tokenization: - for URLs, mail addresses and directory paths (default: skip these tokens) - for colons in words (for Finnish and Swedish) - new examples: - affixation of personal dictionary words - digits in words - bug fixes (see ChangeLog) 2007-07-16: Hunspell 1.1.8 release: - better Mac OS X/Cygwin and Windows compatibility - fix Hunspell's Valgrind environment and memory handling errors detected by Valgrind - other bug fixes (see ChangeLog) 2007-07-06: Hunspell 1.1.7 release: - fix warning messages of OpenOffice.org build 2007-06-29: Hunspell 1.1.6 release: - check capitalization of the following word forms - words with mixed capitalisation: OpenOffice.org - OPENOFFICE.ORG - allcap words and suffixes: UNICEF's - UNICEF'S - prefixes with apostrophe and proper names: Sant'Elia - SANT'ELIA - suggestion for missing sentence spacing: something.The -> something. The - Hunspell executable: improved locale support - -i option: custom input encoding - use locale data for default dictionary names. - tools/hunspell.cxx: fix 8-bit tokenization (letters without casing, like ß or Hebrew characters now are handled well) - dictionary search path (automatic detection of OpenOffice.org directories) - DICPATH environmental variable - -D option: show directory path of loaded dictionary - patches and bug fixes for Mozilla, OpenOffice.org. 2007-03-19: Hunspell 1.1.5 release: - optimizations: 10-100% speed up, smaller code size and memory footprint (conditional experimental code and warning messages) - extended Unicode support: - non BMP Unicode characters in dictionary words and affixes (except affix rules and conditions) - support BOM sequence in aff and dic files - IGNORE feature for Arabic diacritics and other optional characters - New edit distance suggestion methods: - capitalisation: nasa -> NASA - long swap: permenant -> permanent - long move: Ghandi -> Gandhi, greatful -> grateful - double two characters: vacacation -> vacation - spaces in REP sug.: REP alot a_lot (NOTE: "a lot" must be a dictionary word) - patches and bug fixes for Mozilla, OpenOffice.org, Emacs, MinGW, Aqua, German and Arabic language, etc. 2006-02-01: Hunspell 1.1.4 release: - Improved suggestion for typical OCR bugs (missing spaces between capitalized words). For example: "aNew" -> "a New". http://qa.openoffice.org/issues/show_bug.cgi?id=58202 - tokenization fixes (fix incomplete tokenization of input texts on big-endian platforms, and locale-dependent tokenization of dictionary entries) 2006-01-06: Hunspell 1.1.3.2 release: - fix Visual C++ compiling errors 2006-01-05: Hunspell 1.1.3 release: - GPL/LGPL/MPL tri-license for Mozilla integration - Alias compression of flag sets and morphological descriptions. (For example, 16 MB Arabic dic file can be compressed to 1 MB.) - Improved suggestion. - Improved, language independent German sharp s casing with CHECKSHARPS declaration. - Unicode tokenization in Hunspell program. - Bug fixes (at new and old compound word handling methods), etc. 2005-11-11: Hunspell 1.1.2 release: - Bug fixes (MAP Unicode, COMPOUND pattern matching, ONLYINCOMPOUND suggestions) - Checked with 51 regression tests in Valgrind debugging environment, and tested with 52 OOo dictionaries on i686-pc-linux platform. 2005-11-09: Hunspell 1.1.1 release: - Compound word patterns for complex compound word handling and simple word-level lexical scanning. Ideal for checking Arabic and Roman numbers, ordinal numbers in English, affixed numbers in agglutinative languages, etc. http://qa.openoffice.org/issues/show_bug.cgi?id=53643 - Support ISO-8859-15 encoding for French (French oe ligatures are missing from the latin-1 encoding). http://qa.openoffice.org/issues/show_bug.cgi?id=54980 - Implemented a flag to forbid obscene word suggestion: http://qa.openoffice.org/issues/show_bug.cgi?id=55498 - Checked with 50 regression tests in Valgrind debugging environment, and tested with 52 OOo dictionaries. - other improvements and bug fixes (see ChangeLog) 2005-09-19: Hunspell 1.1.0 release * complete comparison with MySpell 3.2 (from OpenOffice.org 2 beta) * improved ngram suggestion with swap character detection and case insensitivity ------ examples for ngram improvement (input word and suggestions) ----- 1. pernament (instead of permanent) MySpell 3.2: tournaments, tournament, ornaments, ornament's, ornamenting, ornamented, ornament, ornamentals, ornamental, ornamentally Hunspell 1.0.9: ornamental, ornament, tournament Hunspell 1.1.0: permanent Note: swap character detection 2. PERNAMENT (instead of PERMANENT) MySpell 3.2: - Hunspell 1.0.9: - Hunspell 1.1.0: PERMANENT 3. Unesco (instead of UNESCO) MySpell 3.2: Genesco, Ionesco, Genesco's, Ionesco's, Frescoing, Fresco's, Frescoed, Fresco, Escorts, Escorting Hunspell 1.0.9: Genesco, Ionesco, Fresco Hunspell 1.1.0: UNESCO 4. siggraph's (instead of SIGGRAPH's) MySpell 3.2: serigraph's, photograph's, serigraphs, physiography's, physiography, digraphs, serigraph, stratigraphy's, stratigraphy epigraphs Hunspell 1.0.9: serigraph's, epigraph's, digraph's Hunspell 1.1.0: SIGGRAPH's --------------- end of examples -------------------- * improved testing environment with suggestion checking and memory debugging memory debugging of all tests with a simple command: VALGRIND=memcheck make check * lots of other improvements and bug fixes (see ChangeLog) 2005-08-26: Hunspell 1.0.9 release * improved related character map suggestion * improved ngram suggestion ------ examples for ngram improvement (O=old, N = new ngram suggestions) -- 1. Permenant (instead of Permanent) O: Endangerment, Ferment, Fermented, Deferment's, Empowerment, Ferment's, Ferments, Fermenting, Countermen, Weathermen N: Permanent, Supermen, Preferment Note: Ngram suggestions was case sensitive. 2. permenant (instead of permanent) O: supermen, newspapermen, empowerment, endangerment, preferments, preferment, permanent, preferment's, permanently, impermanent N: permanent, supermen, preferment Note: new suggestions are also weighted with longest common subsequence, first letter and common character positions 3. pernemant (instead of permanent) O: pimpernel's, pimpernel, pimpernels, permanently, permanents, permanent, supernatant, impermanent, semipermanent, impermanently N: permanent, supernatant, pimpernel Note: new method also prefers root word instead of not relevant affixes ('s, s and ly) 4. pernament (instead of permanent) O: tournaments, tournament, ornaments, ornament's, ornamenting, ornamented, ornament, ornamentals, ornamental, ornamentally N: ornamental, ornament, tournament Note: Both ngram methods misses here. 5. obvus (instad of obvious): O: obvious, Corvus, obverse, obviously, Jacobus, obtuser, obtuse, obviates, obviate, Travus N: obvious, obtuse, obverse Note: new method also prefers common first letters. 6. unambigus (instead of unambiguous) O: unambiguous, unambiguity, unambiguously, ambiguously, ambiguous, unambitious, ambiguities, ambiguousness N: unambiguous, unambiguity, unambitious 7. consecvence (instead of consequence) O: consecutive, consecutively, consecutiveness, nonconsecutive, consequence, consecutiveness's, convenience's, consistences, consistence N: consequence, consecutive, consecrates An example in a language with rich morphology: 8. Misisipiben (instead of Mississippiben [`in Mississippi' in Hungarian]): O: Misikdiben, Pisisediben, Misikiiben, Pisisekiben, Misikiben, Misikidiben, Misikkiben, Misikikiben, Misikimiben, Mississippiiben N: Mississippiben, Mississippiiben, Misiiben Note: Suggesting not relevant affixes was the biggest fault in ngram suggestion for languages with a lot of affixes. --------------- end of examples -------------------- * support twofold prefix cutting * lots of other improvements and bug fixes (see ChangeLog) * test Hunspell with 54 OpenOffice.org dictionaries: source: ftp://ftp.services.openoffice.org/pub/OpenOffice.org/contrib/dictionaries testing shell script: ------------------------------------------------------- for i in `ls *zip | grep '^[a-z]*_[A-Z]*[.]'` do dic=`basename $i .zip` mkdir $dic echo unzip $dic unzip -d $dic $i 2>/dev/null cd $dic echo unmunch and test $dic unmunch $dic.dic $dic.aff 2>/dev/null | awk '{print$0"\t"}' | hunspell -d $dic -l -1 >$dic.result 2>$dic.err || rm -f $dic.result cd .. done -------------------------------------------------------- test result (0 size is o.k.): $ for i in *_*/*.result; do wc -c $i; done 0 af_ZA/af_ZA.result 0 bg_BG/bg_BG.result 0 ca_ES/ca_ES.result 0 cy_GB/cy_GB.result 0 cs_CZ/cs_CZ.result 0 da_DK/da_DK.result 0 de_AT/de_AT.result 0 de_CH/de_CH.result 0 de_DE/de_DE.result 0 el_GR/el_GR.result 6 en_AU/en_AU.result 0 en_CA/en_CA.result 0 en_GB/en_GB.result 0 en_NZ/en_NZ.result 0 en_US/en_US.result 0 eo_EO/eo_EO.result 0 es_ES/es_ES.result 0 es_MX/es_MX.result 0 es_NEW/es_NEW.result 0 fo_FO/fo_FO.result 0 fr_FR/fr_FR.result 0 ga_IE/ga_IE.result 0 gd_GB/gd_GB.result 0 gl_ES/gl_ES.result 0 he_IL/he_IL.result 0 hr_HR/hr_HR.result 200694989 hu_HU/hu_HU.result 0 id_ID/id_ID.result 0 it_IT/it_IT.result 0 ku_TR/ku_TR.result 0 lt_LT/lt_LT.result 0 lv_LV/lv_LV.result 0 mg_MG/mg_MG.result 0 mi_NZ/mi_NZ.result 0 ms_MY/ms_MY.result 0 nb_NO/nb_NO.result 0 nl_NL/nl_NL.result 0 nn_NO/nn_NO.result 0 ny_MW/ny_MW.result 0 pl_PL/pl_PL.result 0 pt_BR/pt_BR.result 0 pt_PT/pt_PT.result 0 ro_RO/ro_RO.result 0 ru_RU/ru_RU.result 0 rw_RW/rw_RW.result 0 sk_SK/sk_SK.result 0 sl_SI/sl_SI.result 0 sv_SE/sv_SE.result 0 sw_KE/sw_KE.result 0 tet_ID/tet_ID.result 0 tl_PH/tl_PH.result 0 tn_ZA/tn_ZA.result 0 uk_UA/uk_UA.result 0 zu_ZA/zu_ZA.result In en_AU dictionary, there is an abbrevation with two dots (`eqn..'), but `eqn.' is missing. Presumably it is a dictionary bug. Myspell also haven't accepted it. Hungarian dictionary contains pseudoroots and forbidden words. Unmunch haven't supported these features yet, and generates bad words, too. * check affix rules and OOo dictionaries. Detected bugs in cs_CZ, es_ES, es_NEW, es_MX, lt_LT, nn_NO, pt_PT, ro_RO, sk_SK and sv_SE dictionaries). Details: -------------------------------------------------------- cs_CZ warning - incompatible stripping characters and condition: SFX D us ech [^ighk]os SFX D us y [^i]os SFX Q os ech [^ghk]es SFX M o ech [^ghkei]a SFX J m ej m SFX J m ejme m SFX J m ejte m SFX A ouit up oupit SFX A ouit upme oupit SFX A ouit upte oupit SFX A nout l [aeiouyr][^aeiouyrl][^aeiouy SFX A nout l [aeiouyr][^aeiouyrl][^aeiouy es_ES warning - incompatible stripping characters and condition: SFX W umar se [ae]husar SFX W emir iis eir es_NEW warning - incompatible stripping characters and condition: SFX I unan nen unar es_MX warning - incompatible stripping characters and condition: SFX A a ote e SFX W umar se [ae]husar SFX W emir iis eir lt_LT warning - incompatible stripping characters and condition: SFX U ti siuosi tis SFX U ti siuosi tis SFX U ti siesi tis SFX U ti siesi tis SFX U ti sis tis SFX U ti sis tis SFX U ti sims tis SFX U ti sims tis SFX U ti sits tis SFX U ti sits tis nn_NO warning - incompatible stripping characters and condition: SFX D ar rar [^fmk]er SFX U re orde ere SFX U re ort ere pt_PT warning - incompatible stripping characters and condition: SFX g os oas o SFX g os oas o ro_RO warning - bad field number: SFX L 0 le [^cg] i SFX L 0 i [cg] i SFX U 0 i [^i] ii warning - incompatible stripping characters and condition: SFX P l i l [<- there is an unnecessary tabulator here) SFX I a ii [gc] a warning - bad field number: SFX I a ii [gc] a SFX I a ei [^cg] a sk_SK warning - incompatible stripping characters and condition: SFX T a ol kla SFX T a olc kla SFX T sa l sla SFX T sa lc sla SFX R c liem c SFX R is tie mias SFX R iez iem [^i]ez SFX R iez ie [^i]ez SFX R iez ie [^i]ez SFX R iez eme [^i]ez SFX R iez ete [^i]ez SFX R iez [^i]ez SFX R iez c [^i]ez SFX R iez z [^i]ez SFX R iez me [^i]ez SFX R iez te [^i]ez sv_SE warning - bad field number: SFX C 0 net nets [^e]n -------------------------------------------------------- 2005-08-01: Hunspell 1.0.8 release - improved compound word support - fix German S handling - port MySpell files and MAP feature 2005-07-22: Hunspell 1.0.7 release 2005-07-21: new home page: http://hunspell.sourceforge.net hunspell-1.7.0/README000077700000000000000000000000001337236234000155062README.mdustar00rootroot00000000000000hunspell-1.7.0/README.md000066400000000000000000000232371337236234000146420ustar00rootroot00000000000000# About Hunspell Hunspell is a free spell checker and morphological analyzer library and command-line tool, licensed under LGPL/GPL/MPL tri-license. Hunspell is used by LibreOffice office suite, free browsers, like Mozilla Firefox and Google Chrome, and other tools and OSes, like Linux distributions and macOS. It is also a command-line tool for Linux, Unix-like and other OSes. It is designed for quick and high quality spell checking and correcting for languages with word-level writing system, including languages with rich morphology, complex word compounding and character encoding. Hunspell interfaces: Ispell-like terminal interface using Curses library, Ispell pipe interface, C++/C APIs and shared library, also with existing language bindings for other programming languages. Hunspell's code base comes from OpenOffice.org's MySpell library, developed by Kevin Hendricks (originally a C++ reimplementation of spell checking and affixation of Geoff Kuenning's International Ispell from scratch, later extended with eg. n-gram suggestions), see http://lingucomponent.openoffice.org/MySpell-3.zip, and its README, CONTRIBUTORS and license.readme (here: license.myspell) files. Main features of Hunspell library, developed by László Németh: - Unicode support - Highly customizable suggestions: word-part replacement tables and stem-level phonetic and other alternative transcriptions to recognize and fix all typical misspellings, don't suggest offensive words etc. - Complex morphology: dictionary and affix homonyms; twofold affix stripping to handle inflectional and derivational morpheme groups for agglutinative languages, like Azeri, Basque, Estonian, Finnish, Hungarian, Turkish; 64 thousand affix classes with arbitrary number of affixes; conditional affixes, circumfixes, fogemorphemes, zero morphemes, virtual dictionary stems, forbidden words to avoid overgeneration etc. - Handling complex compounds (for example, for Finno-Ugric, German and Indo-Aryan languages): recognizing compounds made of arbitrary number of words, handle affixation within compounds etc. - Custom dictionaries with affixation - Stemming - Morphological analysis (in custom item and arrangement style) - Morphological generation - SPELLML XML API over plain spell() API function for easier integration of stemming, morpological generation and custom dictionaries with affixation - Language specific algorithms, like special casing of Azeri or Turkish dotted i and German sharp s, and special compound rules of Hungarian. Main features of Hunspell command line tool, developed by László Németh: - Reimplementation of quick interactive interface of Geoff Kuenning's Ispell - Parsing formats: text, OpenDocument, TeX/LaTeX, HTML/SGML/XML, nroff/troff - Custom dictionaries with optional affixation, specified by a model word - Multiple dictionary usage (for example hunspell -d en_US,de_DE,de_medical) - Various filtering options (bad or good words/lines) - Morphological analysis (option -m) - Stemming (option -s) See man hunspell, man 3 hunspell, man 5 hunspell for complete manual. # Dependencies Build only dependencies: g++ make autoconf automake autopoint libtool Runtime dependencies: | | Mandatory | Optional | |---------------|------------------|------------------| |libhunspell | | | |hunspell tool | libiconv gettext | ncurses readline | # Compiling on GNU/Linux and Unixes We first need to download the dependencies. On Linux, `gettext` and `libiconv` are part of the standard library. On other Unixes we need to manually install them. For Ubuntu: sudo apt install autoconf automake autopoint libtool Then run the following commands: autoreconf -vfi ./configure make sudo make install sudo ldconfig For dictionary development, use the `--with-warnings` option of configure. For interactive user interface of Hunspell executable, use the `--with-ui option`. Optional developer packages: - ncurses (need for --with-ui), eg. libncursesw5 for UTF-8 - readline (for fancy input line editing, configure parameter: --with-readline) In Ubuntu, the packages are: libncurses5-dev libreadline-dev # Compiling on OSX and macOS On macOS for compiler always use `clang` and not `g++` because Homebrew dependencies are build with that. brew install autoconf automake libtool gettext brew link gettext --force Then run autoreconf, configure, make. See above. # Compiling on Windows ## Compiling with Mingw64 and MSYS2 Download Msys2, update everything and install the following packages: pacman -S base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-libtool Open Mingw-w64 Win64 prompt and compile the same way as on Linux, see above. ## Compiling in Cygwin environment Download and install Cygwin environment for Windows with the following extra packages: - make - automake - autoconf - libtool - gcc-g++ development package - ncurses, readline (for user interface) - iconv (character conversion) Then compile the same way as on Linux. Cygwin builds depend on Cygwin1.dll. # Debugging It is recommended to install a debug build of the standard library: libstdc++6-6-dbg For debugging we need to create a debug build and then we need to start `gdb`. ./configure CXXFLAGS='-g -O0 -Wall -Wextra' make ./libtool --mode=execute gdb src/tools/hunspell You can also pass the `CXXFLAGS` directly to `make` without calling `./configure`, but we don't recommend this way during long development sessions. If you like to develop and debug with an IDE, see documentation at https://github.com/hunspell/hunspell/wiki/IDE-Setup # Testing Testing Hunspell (see tests in tests/ subdirectory): make check or with Valgrind debugger: make check VALGRIND=[Valgrind_tool] make check For example: make check VALGRIND=memcheck make check # Documentation features and dictionary format: man 5 hunspell man hunspell hunspell -h http://hunspell.github.io/ # Usage After compiling and installing (see INSTALL) you can run the Hunspell spell checker (compiled with user interface) with a Hunspell or Myspell dictionary: hunspell -d en_US text.txt or without interface: hunspell hunspell -d en_GB -l Linking with Hunspell static library: g++ -lhunspell-1.7 example.cxx # or better, use pkg-config g++ $(pkg-config --cflags --libs hunspell) example.cxx ## Dictionaries Hunspell (MySpell) dictionaries: - https://wiki.documentfoundation.org/Language_support_of_LibreOffice - http://cgit.freedesktop.org/libreoffice/dictionaries - http://extensions.libreoffice.org - http://extensions.openoffice.org - http://wiki.services.openoffice.org/wiki/Dictionaries Aspell dictionaries (conversion: man 5 hunspell): - ftp://ftp.gnu.org/gnu/aspell/dict László Németh, nemeth at numbertext org hunspell-1.7.0/THANKS000066400000000000000000000116031337236234000142700ustar00rootroot00000000000000Many thanks to the following contributors and supporters: Mehmet Akin Göran Andersson Lars Aronsson Ruud Baars Bartkó Zoltán Mathias Bauer Bencsáth Boldizsár Bíró Árpád Ingo H. de Boer Simon Brouwer Jeppe Bundsgaard Ginn Chen Tomáš Chvátal Aaron Digulla Dmitri Gabinski Dvornik László David Einstein Rene Engelhard Frederik Fouvry Flemming Frandsen Serge Gautherie Marek Gleń Gavins at OOo Gefferth András Godó Ferenc Goldman Eleonóra Steinar H. Gunderson Halácsy Péter Chris Halls Khaled Hosny Izsók András Björn Jacke Mike Tian-Jian Jiang Dafydd Jones Ryan Jones Jean-Christophe Helary Kevin Hendricks Martin Hollmichel Pavel Janík John Winters Mohamed Kebdani Kelemen Gábor Shewangizaw Gulilat Kéménczy Kálmán Dan Kenigsberg Pham Ngoc Khanh Khiraly László Koblinger Egmont Kornai András Tor Lillqvist Christian Lohmaier Robert Longson Marot at SF dot net Mark McClain Caolan McNamara Michael Meeks Moheb Mekhaiel Laurie Mercer Ladislav Michnovič Ellis Miller Giuseppe Modugno János Mohácsi Bram Moolenaar Daniel Naber Nagy Viktor John Nisly Noll János S Page Christophe Paris Malcolm Parsons Sylvain Paschein Volkov Peter Bryan Petty Harri Pitkänen Davide Prina Kevin F. Quinn Erdal Ronahi Olivier Ronez Bernhard Rosenkraenzer Sarlós Tamás Thobias Schlemmer Jan Seeger Jose da Silva Paulo Ney de Souza Roland Smith Munzir Taha Timeless at bemail dot org Tímár András Tonal at OOo Török László Trón Viktor Gianluca Turconi Ryan VanderMeulen Varga Dániel Elio Voci Miha Vrhovnik Martijn Wargers Michel Weimerskirch Brett Wilson Friedel Wolff Daniel Yacob Gábor Zahemszky Taha Zerrouki and others (see also MySpell authors bellow) FSF.hu Foundation http://www.fsf.hu LibreOffice community http://www.libreoffice.org MOKK Research Centre Budapest University of Technology and Economics Sociology and Communications Department http://www.mokk.bme.hu Hungarian Ministry of Informatics and Telecommunications IMEDIA Kft. http://www.imedia.hu OpenOffice.org community http://www.openoffice.org OpenTaal Foundation, Netherlands and Dutch Language Union (Nederlandse Taalunie) http://opentaal.org UHU-Linux Kft. Thanks, Németh László nemeth at numbertext org -------------------------- MySpell Developer Credits: Special credit and thanks go to ispell's creator Geoff Kuenning. Ispell affix compression code was used as the basis for the affix code used in MySpell. Specifically Geoff's use of a conds[] array that makes it easy to check if the conditions required for a particular affix are present was very ingenious! Kudos to Geoff. Very nicely done. BTW: ispell is available under a BSD style license from Geoff Kuennings ispell website: http://www.cs.ucla.edu/ficus-members/geoff/ispell.html Kevin Hendricks is the original author and now maintainer of the MySpell codebase. Recent additions include ngram support, and related character maps to help improve and create suggestions for very poorly spelled words. Please send any and all contributions or improvements to him or to dev@lingucomponent.openoffice.org. David Einstein (Deinst@world.std.com) developed an almost complete rewrite of MySpell for use by the Mozilla project. 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. Németh László is the author of the Hungarian dictionary and he developed and contributed extensive changes to MySpell including ... * code to support compound words in MySpell * fixed numerous problems with encoding case conversion tables. * designed/developed replacement tables to improve suggestions * changed affix file parsing to trees to greatly speed loading * removed the need for malloc/free pairs in suffix_check which speeds up spell checking in suffix rich languages by 20% Davide Prina , Giuseppe Modugno , Gianluca Turconi all from the it_IT OpenOffice.org team performed an extremely detailed code review of MySpell and generated fixes for bugs, leaks, and speedup improvements. Simon Brouwer for fixes and enhancements that have greatly improved MySpell auggestions * n-gram suggestions for an initcap word have an init. cap. * fix for too many n-gram suggestions from specialized dictionary, * fix for long suggestions rather than close ones in case of dictionaries with many compound words (kompuuter) * optionally disabling split-word suggestions (controlled by NOSPLITSUGS line in affix file) Special Thanks to all others who have either contributed ideas or testing for MySpell Thanks, Kevin Hendricks kevin.hendricks@sympatico.ca hunspell-1.7.0/appveyor.yml000066400000000000000000000004771337236234000157540ustar00rootroot00000000000000environment: matrix: - MSYSTEM: MINGW64 BASH_PATH: C:\msys64\usr\bin\bash # - BASH_PATH: c:\cygwin\bin\bash install: - cmd: '%BASH_PATH% -lc "pacman --noconfirm -S mingw-w64-x86_64-boost"' build_script: - cmd: '%BASH_PATH% -lc "cd $APPVEYOR_BUILD_FOLDER; autoreconf -i && ./configure && make && make check"' hunspell-1.7.0/config.rpath000077500000000000000000000442161337236234000156730ustar00rootroot00000000000000#! /bin/sh # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # # Copyright 1996-2016 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Code taken from libtool.m4's _LT_CC_BASENAME. for cc_temp in $CC""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` # Code taken from libtool.m4's _LT_COMPILER_PIC. wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix*) wl='-Wl,' ;; mingw* | cygwin* | pw32* | os2* | cegcc*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6* | nonstopux*) wl='-Wl,' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in ecc*) wl='-Wl,' ;; icc* | ifort*) wl='-Wl,' ;; lf95*) wl='-Wl,' ;; nagfor*) wl='-Wl,-Wl,,' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) wl='-Wl,' ;; ccc*) wl='-Wl,' ;; xl* | bgxl* | bgf* | mpixl*) wl='-Wl,' ;; como) wl='-lopt=' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ F* | *Sun*Fortran*) wl= ;; *Sun\ C*) wl='-Wl,' ;; esac ;; esac ;; newsos6) ;; *nto* | *qnx*) ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; rdos*) ;; solaris*) case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) wl='-Qoption ld ' ;; *) wl='-Wl,' ;; esac ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3*) wl='-Wl,' ;; sysv4*MP*) ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) wl='-Wl,' ;; unicos*) wl='-Wl,' ;; uts4*) ;; esac fi # Code taken from libtool.m4's _LT_LINKER_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. # Unlike libtool, we use -rpath here, not --rpath, since the documented # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) case "$host_cpu" in powerpc) ;; m68k) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then : else ld_shlibs=no fi ;; haiku*) ;; interix[3-9]*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; netbsd*) ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' else ld_shlibs=no fi ;; esac ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then hardcode_libdir_flag_spec= fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. echo 'int main () { return 0; }' > conftest.c ${CC} ${LDFLAGS} conftest.c -o conftest aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` fi if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib" fi rm -f conftest.c conftest # End _LT_AC_SYS_LIBPATH_AIX. if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" fi fi ;; amigaos*) case "$host_cpu" in powerpc) ;; m68k) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=no if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then : else ld_shlibs=no fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; freebsd2.[01]*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd* | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; hpux10*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no ;; *) hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) case $host_vendor in sni) hardcode_direct=yes # is this really true??? ;; siemens) hardcode_direct=no ;; motorola) hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac ;; sysv4.3*) ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics # Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. # Unlike libtool.m4, here we don't care about _all_ names of the library, but # only about the one the linker finds when passed -lNAME. This is the last # element of library_names_spec in libtool.m4, or possibly two of them if the # linker has special search rules. library_names_spec= # the last element of library_names_spec in libtool.m4 libname_spec='lib$name' case "$host_os" in aix3*) library_names_spec='$libname.a' ;; aix[4-9]*) library_names_spec='$libname$shrext' ;; amigaos*) case "$host_cpu" in powerpc*) library_names_spec='$libname$shrext' ;; m68k) library_names_spec='$libname.a' ;; esac ;; beos*) library_names_spec='$libname$shrext' ;; bsdi[45]*) library_names_spec='$libname$shrext' ;; cygwin* | mingw* | pw32* | cegcc*) shrext=.dll library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib library_names_spec='$libname$shrext' ;; dgux*) library_names_spec='$libname$shrext' ;; freebsd[23].*) library_names_spec='$libname$shrext$versuffix' ;; freebsd* | dragonfly*) library_names_spec='$libname$shrext' ;; gnu*) library_names_spec='$libname$shrext' ;; haiku*) library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) case $host_cpu in ia64*) shrext=.so ;; hppa*64*) shrext=.sl ;; *) shrext=.sl ;; esac library_names_spec='$libname$shrext' ;; interix[3-9]*) library_names_spec='$libname$shrext' ;; irix5* | irix6* | nonstopux*) library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac ;; linux*oldld* | linux*aout* | linux*coff*) ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) library_names_spec='$libname$shrext' ;; knetbsd*-gnu) library_names_spec='$libname$shrext' ;; netbsd*) library_names_spec='$libname$shrext' ;; newsos6) library_names_spec='$libname$shrext' ;; *nto* | *qnx*) library_names_spec='$libname$shrext' ;; openbsd*) library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) library_names_spec='$libname$shrext' ;; rdos*) ;; solaris*) library_names_spec='$libname$shrext' ;; sunos4*) library_names_spec='$libname$shrext$versuffix' ;; sysv4 | sysv4.3*) library_names_spec='$libname$shrext' ;; sysv4*MP*) library_names_spec='$libname$shrext' ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) library_names_spec='$libname$shrext' ;; tpf*) library_names_spec='$libname$shrext' ;; uts4*) library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' < 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. * */ hunspell-1.7.0/m4/000077500000000000000000000000001337236234000136745ustar00rootroot00000000000000hunspell-1.7.0/m4/ChangeLog000066400000000000000000000052031337236234000154460ustar00rootroot000000000000002017-10-22 gettextize * gettext.m4: New file, from gettext-0.19.8.1. * iconv.m4: New file, from gettext-0.19.8.1. * lib-ld.m4: New file, from gettext-0.19.8.1. * lib-link.m4: New file, from gettext-0.19.8.1. * lib-prefix.m4: New file, from gettext-0.19.8.1. * nls.m4: New file, from gettext-0.19.8.1. * po.m4: New file, from gettext-0.19.8.1. * progtest.m4: New file, from gettext-0.19.8.1. * visibility.m4: from gettext-0.19.8.1, manually copied. 2016-11-02 gettextize * gettext.m4: Upgrade to gettext-0.19.8. Manually copied. * iconv.m4: Upgrade to gettext-0.19.7. * lib-ld.m4: Upgrade to gettext-0.19.7. * lib-link.m4: Upgrade to gettext-0.19.7. * lib-prefix.m4: Upgrade to gettext-0.19.7. * nls.m4: Upgrade to gettext-0.19.7. * po.m4: Upgrade to gettext-0.19.7. * progtest.m4: Upgrade to gettext-0.19.7. * codeset.m4: Upgrade to gettext-0.19.7. * fcntl-o.m4: Upgrade to gettext-0.19.7. * glibc2.m4: Upgrade to gettext-0.19.7. * glibc21.m4: Upgrade to gettext-0.19.7. * intdiv0.m4: Upgrade to gettext-0.19.7. * intl.m4: Upgrade to gettext-0.19.7. * intldir.m4: Upgrade to gettext-0.19.7. * intlmacosx.m4: Upgrade to gettext-0.19.7. * intmax.m4: Upgrade to gettext-0.19.7. * inttypes_h.m4: Upgrade to gettext-0.19.7. * inttypes-pri.m4: Upgrade to gettext-0.19.7. * lcmessage.m4: Upgrade to gettext-0.19.7. * lock.m4: Upgrade to gettext-0.19.7. * longlong.m4: Upgrade to gettext-0.19.7. * printf-posix.m4: Upgrade to gettext-0.19.7. * size_max.m4: Upgrade to gettext-0.19.7. * stdint_h.m4: Upgrade to gettext-0.19.7. * threadlib.m4: Upgrade to gettext-0.19.7. * uintmax_t.m4: Upgrade to gettext-0.19.7. * visibility.m4: Upgrade to gettext-0.19.7. * wchar_t.m4: Upgrade to gettext-0.19.7. * wint_t.m4: Upgrade to gettext-0.19.7. * xsize.m4: Upgrade to gettext-0.19.7. * Makefile.am (EXTRA_DIST): Add the new files. 2002-05-22 gettextize * gettext.m4: Upgrade to gettext-0.11.2. * isc-posix.m4: Upgrade to gettext-0.11.2. * lib-link.m4: Upgrade to gettext-0.11.2. 2002-01-25 gettextize * codeset.m4: New file, from gettext-0.11-pre5++. * gettext.m4: New file, from gettext-0.11-pre5++. * glibc21.m4: New file, from gettext-0.11-pre5++. * iconv.m4: New file, from gettext-0.11-pre5++. * isc-posix.m4: New file, from gettext-0.11-pre5++. * lcmessage.m4: New file, from gettext-0.11-pre5++. * lib-ld.m4: New file, from gettext-0.11-pre5++. * lib-link.m4: New file, from gettext-0.11-pre5++. * lib-prefix.m4: New file, from gettext-0.11-pre5++. * progtest.m4: New file, from gettext-0.11-pre5++. * Makefile.am: New file. hunspell-1.7.0/m4/README000066400000000000000000000003601337236234000145530ustar00rootroot00000000000000These files are used by a program called aclocal (part of the GNU automake package). aclocal uses these files to create aclocal.m4 which is in turn used by autoconf to create the configure script at the the top level in this distribution. hunspell-1.7.0/m4/gettext.m4000066400000000000000000000367631337236234000156410ustar00rootroot00000000000000# gettext.m4 serial 68 (gettext-0.19.8) dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2006, 2008-2010. dnl Macro to add for using GNU gettext. dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The dnl default (if it is not specified or empty) is 'no-libtool'. dnl INTLSYMBOL should be 'external' for packages with no intl directory, dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. dnl If INTLSYMBOL is 'use-libtool', then a libtool library dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, dnl depending on --{enable,disable}-{shared,static} and on the presence of dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library dnl $(top_builddir)/intl/libintl.a will be created. dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext dnl implementations (in libc or libintl) without the ngettext() function dnl will be ignored. If NEEDSYMBOL is specified and is dnl 'need-formatstring-macros', then GNU gettext implementations that don't dnl support the ISO C 99 formatstring macros will be ignored. dnl INTLDIR is used to find the intl libraries. If empty, dnl the value '$(top_builddir)/intl/' is used. dnl dnl The result of the configuration is one of three cases: dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled dnl and used. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 2) GNU gettext has been found in the system's C library. dnl Catalog format: GNU --> install in $(datadir) dnl Catalog extension: .mo after installation, .gmo in source tree dnl 3) No internationalization, always use English msgid. dnl Catalog format: none dnl Catalog extension: none dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. dnl The use of .gmo is historical (it was needed to avoid overwriting the dnl GNU format catalogs when building on a platform with an X/Open gettext), dnl but we keep it in order not to force irrelevant filename changes on the dnl maintainers. dnl AC_DEFUN([AM_GNU_GETTEXT], [ dnl Argument checking. ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT ])])])])]) ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])]) ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT ])])])]) define([gt_included_intl], ifelse([$1], [external], ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]), [yes])) define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) gt_NEEDS_INIT AM_GNU_GETTEXT_NEED([$2]) AC_REQUIRE([AM_PO_SUBDIRS])dnl ifelse(gt_included_intl, yes, [ AC_REQUIRE([AM_INTL_SUBDIR])dnl ]) dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Sometimes libintl requires libiconv, so first search for libiconv. dnl Ideally we would do this search only after the dnl if test "$USE_NLS" = "yes"; then dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT dnl the configure script would need to contain the same shell code dnl again, outside any 'if'. There are two solutions: dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not dnl documented, we avoid it. ifelse(gt_included_intl, yes, , [ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) ]) dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation. gt_INTL_MACOSX dnl Set USE_NLS. AC_REQUIRE([AM_NLS]) ifelse(gt_included_intl, yes, [ BUILD_INCLUDED_LIBINTL=no USE_INCLUDED_LIBINTL=no ]) LIBINTL= LTLIBINTL= POSUB= dnl Add a version number to the cache macros. case " $gt_needs " in *" need-formatstring-macros "*) gt_api_version=3 ;; *" need-ngettext "*) gt_api_version=2 ;; *) gt_api_version=1 ;; esac gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" dnl If we use NLS figure out what method if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no ifelse(gt_included_intl, yes, [ AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH([included-gettext], [ --with-included-gettext use the GNU gettext library included here], nls_cv_force_use_gnu_gettext=$withval, nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then ]) dnl User does not insist on using GNU NLS library. Figure out what dnl to use. If GNU gettext is available we use this. Else we have dnl to fall back to GNU NLS library. if test $gt_api_version -ge 3; then gt_revision_test_code=' #ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) #endif changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl ' else gt_revision_test_code= fi if test $gt_api_version -ge 2; then gt_expression_test_code=' + * ngettext ("", "", 0)' else gt_expression_test_code= fi AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], [AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; #define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) #else #define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 #endif $gt_revision_test_code ]], [[ bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ]])], [eval "$gt_func_gnugettext_libc=yes"], [eval "$gt_func_gnugettext_libc=no"])]) if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then dnl Sometimes libintl requires libiconv, so first search for libiconv. ifelse(gt_included_intl, yes, , [ AM_ICONV_LINK ]) dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) dnl because that would add "-liconv" to LIBINTL and LTLIBINTL dnl even if libiconv doesn't exist. AC_LIB_LINKFLAGS_BODY([intl]) AC_CACHE_CHECK([for GNU gettext in libintl], [$gt_func_gnugettext_libintl], [gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" dnl Now see whether libintl exists and does not depend on libiconv. AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); #define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) #else #define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 #endif $gt_revision_test_code ]], [[ bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ]])], [eval "$gt_func_gnugettext_libintl=yes"], [eval "$gt_func_gnugettext_libintl=no"]) dnl Now see whether libintl exists and depends on libiconv. if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); #define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) #else #define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 #endif $gt_revision_test_code ]], [[ bindtextdomain ("", ""); return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION ]])], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" eval "$gt_func_gnugettext_libintl=yes" ]) fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS"]) fi dnl If an already present or preinstalled GNU gettext() is found, dnl use it. But if this macro is used in GNU gettext, and GNU dnl gettext is already preinstalled in libintl, we update this dnl libintl. (Cf. the install rule in intl/Makefile.in.) if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else dnl Reset the values set by searching for libintl. LIBINTL= LTLIBINTL= INCINTL= fi ifelse(gt_included_intl, yes, [ if test "$gt_use_preinstalled_gnugettext" != "yes"; then dnl GNU gettext is not found in the C library. dnl Fall back on included GNU gettext library. nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions used to generate GNU NLS library. BUILD_INCLUDED_LIBINTL=yes USE_INCLUDED_LIBINTL=yes LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` fi CATOBJEXT= if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions to use GNU gettext tools. CATOBJEXT=.gmo fi ]) if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Some extra flags are needed during linking. LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then AC_DEFINE([ENABLE_NLS], [1], [Define to 1 if translation of program messages to the user's native language is requested.]) else USE_NLS=no fi fi AC_MSG_CHECKING([whether to use NLS]) AC_MSG_RESULT([$USE_NLS]) if test "$USE_NLS" = "yes"; then AC_MSG_CHECKING([where the gettext function comes from]) if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi AC_MSG_RESULT([$gt_source]) fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then AC_MSG_CHECKING([how to link with libintl]) AC_MSG_RESULT([$LIBINTL]) AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) fi dnl For backward compatibility. Some packages may be using this. AC_DEFINE([HAVE_GETTEXT], [1], [Define if the GNU gettext() function is already present or preinstalled.]) AC_DEFINE([HAVE_DCGETTEXT], [1], [Define if the GNU dcgettext() function is already present or preinstalled.]) fi dnl We need to process the po/ directory. POSUB=po fi ifelse(gt_included_intl, yes, [ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL dnl to 'yes' because some of the testsuite requires it. if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then BUILD_INCLUDED_LIBINTL=yes fi dnl Make all variables we use known to autoconf. AC_SUBST([BUILD_INCLUDED_LIBINTL]) AC_SUBST([USE_INCLUDED_LIBINTL]) AC_SUBST([CATOBJEXT]) dnl For backward compatibility. Some configure.ins may be using this. nls_cv_header_intl= nls_cv_header_libgt= dnl For backward compatibility. Some Makefiles may be using this. DATADIRNAME=share AC_SUBST([DATADIRNAME]) dnl For backward compatibility. Some Makefiles may be using this. INSTOBJEXT=.mo AC_SUBST([INSTOBJEXT]) dnl For backward compatibility. Some Makefiles may be using this. GENCAT=gencat AC_SUBST([GENCAT]) dnl For backward compatibility. Some Makefiles may be using this. INTLOBJS= if test "$USE_INCLUDED_LIBINTL" = yes; then INTLOBJS="\$(GETTOBJS)" fi AC_SUBST([INTLOBJS]) dnl Enable libtool support if the surrounding package wishes it. INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX]) ]) dnl For backward compatibility. Some Makefiles may be using this. INTLLIBS="$LIBINTL" AC_SUBST([INTLLIBS]) dnl Make all documented variables known to autoconf. AC_SUBST([LIBINTL]) AC_SUBST([LTLIBINTL]) AC_SUBST([POSUB]) ]) dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. m4_define([gt_NEEDS_INIT], [ m4_divert_text([DEFAULTS], [gt_needs=]) m4_define([gt_NEEDS_INIT], []) ]) dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) AC_DEFUN([AM_GNU_GETTEXT_NEED], [ m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) ]) dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) dnl Usage: AM_GNU_GETTEXT_REQUIRE_VERSION([gettext-version]) AC_DEFUN([AM_GNU_GETTEXT_REQUIRE_VERSION], []) hunspell-1.7.0/m4/iconv.m4000066400000000000000000000220721337236234000152570ustar00rootroot00000000000000# iconv.m4 serial 19 (gettext-0.18.2) dnl Copyright (C) 2000-2002, 2007-2014, 2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) AC_REQUIRE([AC_LIB_RPATH]) dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_LIB_LINKFLAGS_BODY([iconv]) ]) AC_DEFUN([AM_ICONV_LINK], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV dnl accordingly. AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) dnl Add $INCICONV to CPPFLAGS before performing the following checks, dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. am_save_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #include ]], [[iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);]])], [am_cv_func_iconv=yes]) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include #include ]], [[iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);]])], [am_cv_lib_iconv=yes] [am_cv_func_iconv=yes]) LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, dnl Solaris 10. am_save_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi am_cv_func_iconv_works=no for ac_iconv_const in '' 'const'; do AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include #include #ifndef ICONV_CONST # define ICONV_CONST $ac_iconv_const #endif ]], [[int result = 0; /* Test against AIX 5.1 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_utf8_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 1; iconv_close (cd_utf8_to_88591); } } /* Test against Solaris 10 bug: Failures are not distinguishable from successful returns. */ { iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); if (cd_ascii_to_88591 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\263"; char buf[10]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_ascii_to_88591, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) result |= 2; iconv_close (cd_ascii_to_88591); } } /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ { iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304"; static char buf[2] = { (char)0xDE, (char)0xAD }; ICONV_CONST char *inptr = input; size_t inbytesleft = 1; char *outptr = buf; size_t outbytesleft = 1; size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) result |= 4; iconv_close (cd_88591_to_utf8); } } #if 0 /* This bug could be worked around by the caller. */ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ { iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); if (cd_88591_to_utf8 != (iconv_t)(-1)) { static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; char buf[50]; ICONV_CONST char *inptr = input; size_t inbytesleft = strlen (input); char *outptr = buf; size_t outbytesleft = sizeof (buf); size_t res = iconv (cd_88591_to_utf8, &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) result |= 8; iconv_close (cd_88591_to_utf8); } } #endif /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is provided. */ if (/* Try standardized names. */ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) /* Try IRIX, OSF/1 names. */ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) /* Try AIX names. */ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) /* Try HP-UX names. */ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) result |= 16; return result; ]])], [am_cv_func_iconv_works=yes], , [case "$host_os" in aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; *) am_cv_func_iconv_works="guessing yes" ;; esac]) test "$am_cv_func_iconv_works" = no || break done LIBS="$am_save_LIBS" ]) case "$am_cv_func_iconv_works" in *no) am_func_iconv=no am_cv_lib_iconv=no ;; *) am_func_iconv=yes ;; esac else am_func_iconv=no am_cv_lib_iconv=no fi if test "$am_func_iconv" = yes; then AC_DEFINE([HAVE_ICONV], [1], [Define if you have the iconv() function and it works.]) fi if test "$am_cv_lib_iconv" = yes; then AC_MSG_CHECKING([how to link with libiconv]) AC_MSG_RESULT([$LIBICONV]) else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi AC_SUBST([LIBICONV]) AC_SUBST([LTLIBICONV]) ]) dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to dnl avoid warnings like dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". dnl This is tricky because of the way 'aclocal' is implemented: dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. dnl Otherwise aclocal's initial scan pass would miss the macro definition. dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. dnl Otherwise aclocal would emit many "Use of uninitialized value $1" dnl warnings. m4_define([gl_iconv_AC_DEFUN], m4_version_prereq([2.64], [[AC_DEFUN_ONCE( [$1], [$2])]], [m4_ifdef([gl_00GNULIB], [[AC_DEFUN_ONCE( [$1], [$2])]], [[AC_DEFUN( [$1], [$2])]])])) gl_iconv_AC_DEFUN([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL([am_cv_proto_iconv], [ AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ]], [[]])], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"]) am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([ $am_cv_proto_iconv]) AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], [Define as const if the declaration of iconv() needs const.]) dnl Also substitute ICONV_CONST in the gnulib generated . m4_ifdef([gl_ICONV_H_DEFAULTS], [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) if test -n "$am_cv_proto_iconv_arg1"; then ICONV_CONST="const" fi ]) fi ]) hunspell-1.7.0/m4/lib-ld.m4000066400000000000000000000071431337236234000153060ustar00rootroot00000000000000# lib-ld.m4 serial 6 dnl Copyright (C) 1996-2003, 2009-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl Subroutines of libtool.m4, dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid dnl collision with libtool.m4. dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. AC_DEFUN([AC_LIB_PROG_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], [# I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 /dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL([acl_cv_path_LD], [if test -z "$LD"; then acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$acl_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 = 1.10 to complain if config.rpath is missing. m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done ]) wl="$acl_cv_wl" acl_libext="$acl_cv_libext" acl_shlibext="$acl_cv_shlibext" acl_libname_spec="$acl_cv_libname_spec" acl_library_names_spec="$acl_cv_library_names_spec" acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" acl_hardcode_direct="$acl_cv_hardcode_direct" acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" dnl Determine whether the user wants rpath handling at all. AC_ARG_ENABLE([rpath], [ --disable-rpath do not hardcode runtime library paths], :, enable_rpath=yes) ]) dnl AC_LIB_FROMPACKAGE(name, package) dnl declares that libname comes from the given package. The configure file dnl will then not have a --with-libname-prefix option but a dnl --with-package-prefix option. Several libraries can come from the same dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar dnl macro call that searches for libname. AC_DEFUN([AC_LIB_FROMPACKAGE], [ pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) define([acl_frompackage_]NAME, [$2]) popdef([NAME]) pushdef([PACK],[$2]) pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) define([acl_libsinpackage_]PACKUP, m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) popdef([PACKUP]) popdef([PACK]) ]) dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and dnl the libraries corresponding to explicit and implicit dependencies. dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. AC_DEFUN([AC_LIB_LINKFLAGS_BODY], [ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) dnl Autoconf >= 2.61 supports dots in --with options. pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_ARG_WITH(P_A_C_K[-prefix], [[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" if test "$acl_libdirstem2" != "$acl_libdirstem" \ && ! test -d "$withval/$acl_libdirstem"; then additional_libdir="$withval/$acl_libdirstem2" fi fi fi ]) dnl Search the library and its dependencies in $additional_libdir and dnl $LDFLAGS. Using breadth-first-seach. LIB[]NAME= LTLIB[]NAME= INC[]NAME= LIB[]NAME[]_PREFIX= dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been dnl computed. So it has to be reset here. HAVE_LIB[]NAME= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='$1 $2' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" dnl See if it was already located by an earlier AC_LIB_LINKFLAGS dnl or AC_LIB_HAVE_LINKFLAGS call. uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" else dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined dnl that this library doesn't exist. So just drop it. : fi else dnl Search the library lib$name in $additional_libdir and $LDFLAGS dnl and the already constructed $LIBNAME/$LTLIBNAME. found_dir= found_la= found_so= found_a= eval libname=\"$acl_libname_spec\" # typically: libname=lib$name if test -n "$acl_shlibext"; then shrext=".$acl_shlibext" # typically: shrext=.so else shrext= fi if test $use_additional = yes; then dir="$additional_libdir" dnl The same code as in the loop below: dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` dnl First look for a shared library. if test -n "$acl_shlibext"; then if test -f "$dir/$libname$shrext"; then found_dir="$dir" found_so="$dir/$libname$shrext" else if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then ver=`(cd "$dir" && \ for f in "$libname$shrext".*; do echo "$f"; done \ | sed -e "s,^$libname$shrext\\\\.,," \ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ | sed 1q ) 2>/dev/null` if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then found_dir="$dir" found_so="$dir/$libname$shrext.$ver" fi else eval library_names=\"$acl_library_names_spec\" for f in $library_names; do if test -f "$dir/$f"; then found_dir="$dir" found_so="$dir/$f" break fi done fi fi fi dnl Then look for a static library. if test "X$found_dir" = "X"; then if test -f "$dir/$libname.$acl_libext"; then found_dir="$dir" found_a="$dir/$libname.$acl_libext" fi fi if test "X$found_dir" != "X"; then if test -f "$dir/$libname.la"; then found_la="$dir/$libname.la" fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then dnl Found the library. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then dnl Linking with a shared library. We attempt to hardcode its dnl directory into the executable's runpath, unless it's the dnl standard /usr/lib. if test "$enable_rpath" = no \ || test "X$found_dir" = "X/usr/$acl_libdirstem" \ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then dnl No hardcoding is needed. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl Use an explicit option to hardcode DIR into the resulting dnl binary. dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi dnl The hardcoding into $LIBNAME is system dependent. if test "$acl_hardcode_direct" = yes; then dnl Using DIR/libNAME.so during linking hardcodes DIR into the dnl resulting binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode DIR into the resulting dnl binary. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else dnl Rely on "-L$found_dir". dnl But don't add it if it's already contained in the LDFLAGS dnl or the already constructed $LIBNAME haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" fi if test "$acl_hardcode_minus_L" != no; then dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" else dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH dnl here, because this doesn't fit in flags passed to the dnl compiler. So give up. No hardcoding. This affects only dnl very old systems. dnl FIXME: Not sure whether we should use dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" dnl here. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then dnl Linking with a static library. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" else dnl We shouldn't come here, but anyway it's good to have a dnl fallback. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" fi fi dnl Assume the include files are nearby. additional_includedir= case "$found_dir" in */$acl_libdirstem | */$acl_libdirstem/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` if test "$name" = '$1'; then LIB[]NAME[]_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; */$acl_libdirstem2 | */$acl_libdirstem2/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` if test "$name" = '$1'; then LIB[]NAME[]_PREFIX="$basedir" fi additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then dnl Potentially add $additional_includedir to $INCNAME. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's /usr/local/include and we are using GCC on Linux, dnl 3. if it's already present in $CPPFLAGS or the already dnl constructed $INCNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INC[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $INCNAME. INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" fi fi fi fi fi dnl Look for dependencies. if test -n "$found_la"; then dnl Read the .la file. It defines the variables dnl dlname, library_names, old_library, dependency_libs, current, dnl age, revision, installed, dlopen, dlpreopen, libdir. save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" dnl We use only dependency_libs. for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's /usr/local/lib and we are using GCC on Linux, dnl 3. if it's already present in $LDFLAGS or the already dnl constructed $LIBNAME, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then haveit= if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LIBNAME. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIB[]NAME; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LTLIBNAME. LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then dnl Potentially add DIR to rpathdirs. dnl The rpathdirs will be appended to $LIBNAME at the end. haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi dnl Potentially add DIR to ltrpathdirs. dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) dnl Handle this in the next round. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) dnl Handle this in the next round. Throw away the .la's dnl directory; it is already contained in a preceding -L dnl option. names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) dnl Most likely an immediate library name. LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" ;; esac done fi else dnl Didn't find the library; assume it is in the system directories dnl known to the linker and runtime loader. (All the system dnl directories known to the linker should also be known to the dnl runtime loader, otherwise the system is severely misconfigured.) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user must dnl pass all path elements in one option. We can arrange that for a dnl single library, but not when more than one $LIBNAMEs are used. alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" done dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" else dnl The -rpath options are cumulative. for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then dnl When using libtool, the option that works for both libraries and dnl executables is -R. The -R options are cumulative. for found_dir in $ltrpathdirs; do LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" done fi popdef([P_A_C_K]) popdef([PACKLIBS]) popdef([PACKUP]) popdef([PACK]) popdef([NAME]) ]) dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, dnl unless already present in VAR. dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes dnl contains two or three consecutive elements that belong together. AC_DEFUN([AC_LIB_APPENDTOVAR], [ for element in [$2]; do haveit= for x in $[$1]; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then [$1]="${[$1]}${[$1]:+ }$element" fi done ]) dnl For those cases where a variable contains several -L and -l options dnl referring to unknown libraries and directories, this macro determines the dnl necessary additional linker options for the runtime path. dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) dnl sets LDADDVAR to linker options needed together with LIBSVALUE. dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, dnl otherwise linking without libtool is assumed. AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], [ AC_REQUIRE([AC_LIB_RPATH]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) $1= if test "$enable_rpath" != no; then if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then dnl Use an explicit option to hardcode directories into the resulting dnl binary. rpathdirs= next= for opt in $2; do if test -n "$next"; then dir="$next" dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ && test "X$dir" != "X/usr/$acl_libdirstem2"; then rpathdirs="$rpathdirs $dir" fi next= else case $opt in -L) next=yes ;; -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` dnl No need to hardcode the standard /usr/lib. if test "X$dir" != "X/usr/$acl_libdirstem" \ && test "X$dir" != "X/usr/$acl_libdirstem2"; then rpathdirs="$rpathdirs $dir" fi next= ;; *) next= ;; esac fi done if test "X$rpathdirs" != "X"; then if test -n ""$3""; then dnl libtool is used for linking. Use -R options. for dir in $rpathdirs; do $1="${$1}${$1:+ }-R$dir" done else dnl The linker is used for linking directly. if test -n "$acl_hardcode_libdir_separator"; then dnl Weird platform: only the last -rpath option counts, the user dnl must pass all path elements in one option. alldirs= for dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="$flag" else dnl The -rpath options are cumulative. for dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$dir" eval flag=\"$acl_hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" $1="${$1}${$1:+ }$flag" done fi fi fi fi fi AC_SUBST([$1]) ]) hunspell-1.7.0/m4/lib-prefix.m4000066400000000000000000000204221337236234000161770ustar00rootroot00000000000000# lib-prefix.m4 serial 7 (gettext-0.18) dnl Copyright (C) 2001-2005, 2008-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't dnl require excessive bracketing. ifdef([AC_HELP_STRING], [AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], [AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed dnl to access previously installed libraries. The basic assumption is that dnl a user will want packages to use other packages he previously installed dnl with the same --prefix option. dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate dnl libraries, but is otherwise very convenient. AC_DEFUN([AC_LIB_PREFIX], [ AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. use_additional=yes AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) AC_LIB_ARG_WITH([lib-prefix], [ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib --without-lib-prefix don't search for libraries in includedir and libdir], [ if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then AC_LIB_WITH_FINAL_PREFIX([ eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" ]) else additional_includedir="$withval/include" additional_libdir="$withval/$acl_libdirstem" fi fi ]) if test $use_additional = yes; then dnl Potentially add $additional_includedir to $CPPFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/include, dnl 2. if it's already present in $CPPFLAGS, dnl 3. if it's /usr/local/include and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_includedir" != "X/usr/include"; then haveit= for x in $CPPFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_includedir"; then dnl Really add $additional_includedir to $CPPFLAGS. CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" fi fi fi fi dnl Potentially add $additional_libdir to $LDFLAGS. dnl But don't add it dnl 1. if it's the standard /usr/lib, dnl 2. if it's already present in $LDFLAGS, dnl 3. if it's /usr/local/lib and we are using GCC on Linux, dnl 4. if it doesn't exist as a directory. if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then haveit= for x in $LDFLAGS; do AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then if test -n "$GCC"; then case $host_os in linux*) haveit=yes;; esac fi fi if test -z "$haveit"; then if test -d "$additional_libdir"; then dnl Really add $additional_libdir to $LDFLAGS. LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" fi fi fi fi fi ]) dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, dnl acl_final_exec_prefix, containing the values to which $prefix and dnl $exec_prefix will expand at the end of the configure script. AC_DEFUN([AC_LIB_PREPARE_PREFIX], [ dnl Unfortunately, prefix and exec_prefix get only finally determined dnl at the end of configure. if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" ]) dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the dnl variables prefix and exec_prefix bound to the values they will have dnl at the end of the configure script. AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], [ acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" $1 exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" ]) dnl AC_LIB_PREPARE_MULTILIB creates dnl - a variable acl_libdirstem, containing the basename of the libdir, either dnl "lib" or "lib64" or "lib/64", dnl - a variable acl_libdirstem2, as a secondary possible value for dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or dnl "lib/amd64". AC_DEFUN([AC_LIB_PREPARE_MULTILIB], [ dnl There is no formal standard regarding lib and lib64. dnl On glibc systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine dnl the compiler's default mode by looking at the compiler's library search dnl path. If at least one of its elements ends in /lib64 or points to a dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. dnl Otherwise we use the default, namely "lib". dnl On Solaris systems, the current practice is that on a system supporting dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. AC_REQUIRE([AC_CANONICAL_HOST]) acl_libdirstem=lib acl_libdirstem2= case "$host_os" in solaris*) dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment dnl . dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the dnl symlink is missing, so we set acl_libdirstem2 too. AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], [AC_EGREP_CPP([sixtyfour bits], [ #ifdef _LP64 sixtyfour bits #endif ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) ]) if test $gl_cv_solaris_64bit = yes; then acl_libdirstem=lib/64 case "$host_cpu" in sparc*) acl_libdirstem2=lib/sparcv9 ;; i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; esac fi ;; *) searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` if test -n "$searchpath"; then acl_save_IFS="${IFS= }"; IFS=":" for searchdir in $searchpath; do if test -d "$searchdir"; then case "$searchdir" in */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; */../ | */.. ) # Better ignore directories of this form. They are misleading. ;; *) searchdir=`cd "$searchdir" && pwd` case "$searchdir" in */lib64 ) acl_libdirstem=lib64 ;; esac ;; esac fi done IFS="$acl_save_IFS" fi ;; esac test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" ]) hunspell-1.7.0/m4/nls.m4000066400000000000000000000023071337236234000147340ustar00rootroot00000000000000# nls.m4 serial 5 (gettext-0.18) dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016 Free Software dnl Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. AC_PREREQ([2.50]) AC_DEFUN([AM_NLS], [ AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE([nls], [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT([$USE_NLS]) AC_SUBST([USE_NLS]) ]) hunspell-1.7.0/m4/po.m4000066400000000000000000000450311337236234000145570ustar00rootroot00000000000000# po.m4 serial 24 (gettext-0.19) dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1995-2000. dnl Bruno Haible , 2000-2003. AC_PREREQ([2.60]) dnl Checks for all prerequisites of the po subdirectory. AC_DEFUN([AM_PO_SUBDIRS], [ AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl AC_REQUIRE([AC_PROG_SED])dnl AC_REQUIRE([AM_NLS])dnl dnl Release version of the gettext macros. This is used to ensure that dnl the gettext macros and po/Makefile.in.in are in sync. AC_SUBST([GETTEXT_MACRO_VERSION], [0.19]) dnl Perform the following tests also if --disable-nls has been given, dnl because they are needed for "make dist" to work. dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) dnl Test whether it is GNU msgfmt >= 0.15. changequote(,)dnl case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; *) MSGFMT_015=$MSGFMT ;; esac changequote([,])dnl AC_SUBST([MSGFMT_015]) changequote(,)dnl case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; *) GMSGFMT_015=$GMSGFMT ;; esac changequote([,])dnl AC_SUBST([GMSGFMT_015]) dnl Search for GNU xgettext 0.12 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Test whether it is GNU xgettext >= 0.15. changequote(,)dnl case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; *) XGETTEXT_015=$XGETTEXT ;; esac changequote([,])dnl AC_SUBST([XGETTEXT_015]) dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) dnl Installation directories. dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we dnl have to define it here, so that it can be used in po/Makefile. test -n "$localedir" || localedir='${datadir}/locale' AC_SUBST([localedir]) dnl Support for AM_XGETTEXT_OPTION. test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) AC_CONFIG_COMMANDS([po-directories], [[ for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" gt_tab=`printf '\t'` cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. # Hide the ALL_LINGUAS assignment from automake < 1.5. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done]], [# Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake < 1.5. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" ]) ]) dnl Postprocesses a Makefile in a directory containing PO files. AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], [ # When this code is run, in config.status, two variables have already been # set: # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, # - LINGUAS is the value of the environment variable LINGUAS at configure # time. changequote(,)dnl # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Find a way to echo strings without interpreting backslash. if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then gt_echo='echo' else if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then gt_echo='printf %s\n' else echo_func () { cat < "$ac_file.tmp" tab=`printf '\t'` if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` cat >> "$ac_file.tmp" < /dev/null; then # Add dependencies that cannot be formulated as a simple suffix rule. for lang in $ALL_LINGUAS; do frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` cat >> "$ac_file.tmp" <> "$ac_file.tmp" <, 1996. AC_PREREQ([2.50]) # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [ # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which # contains only /bin. Note that ksh looks also at the FPATH variable, # so we have to set that as well for the test. PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ || PATH_SEPARATOR=';' } fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL([ac_cv_path_$1], [case "[$]$1" in [[\\/]]* | ?:[[\\/]]*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in ifelse([$5], , $PATH, [$5]); do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$][$1]) else AC_MSG_RESULT([no]) fi AC_SUBST([$1])dnl ]) hunspell-1.7.0/m4/visibility.m4000066400000000000000000000064271337236234000163360ustar00rootroot00000000000000# visibility.m4 serial 5 (gettext-0.18.2) dnl Copyright (C) 2005, 2008, 2010-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. dnl Tests whether the compiler supports the command-line option dnl -fvisibility=hidden and the function and variable attributes dnl __attribute__((__visibility__("hidden"))) and dnl __attribute__((__visibility__("default"))). dnl Does *not* test for __visibility__("protected") - which has tricky dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on dnl Mac OS X. dnl Does *not* test for __visibility__("internal") - which has processor dnl dependent semantics. dnl Does *not* test for #pragma GCC visibility push(hidden) - which is dnl "really only recommended for legacy code". dnl Set the variable CFLAG_VISIBILITY. dnl Defines and sets the variable HAVE_VISIBILITY. AC_DEFUN([gl_VISIBILITY], [ AC_REQUIRE([AC_PROG_CC]) CFLAG_VISIBILITY= HAVE_VISIBILITY=0 if test -n "$GCC"; then dnl First, check whether -Werror can be added to the command line, or dnl whether it leads to an error because of some other option that the dnl user has put into $CC $CFLAGS $CPPFLAGS. AC_MSG_CHECKING([whether the -Werror option is usable]) AC_CACHE_VAL([gl_cv_cc_vis_werror], [ gl_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]], [[]])], [gl_cv_cc_vis_werror=yes], [gl_cv_cc_vis_werror=no]) CFLAGS="$gl_save_CFLAGS"]) AC_MSG_RESULT([$gl_cv_cc_vis_werror]) dnl Now check whether visibility declarations are supported. AC_MSG_CHECKING([for simple visibility declarations]) AC_CACHE_VAL([gl_cv_cc_visibility], [ gl_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" dnl We use the option -Werror and a function dummyfunc, because on some dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning dnl "visibility attribute not supported in this configuration; ignored" dnl at the first function definition in every compilation unit, and we dnl don't want to use the option in this case. if test $gl_cv_cc_vis_werror = yes; then CFLAGS="$CFLAGS -Werror" fi AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; extern __attribute__((__visibility__("default"))) int exportedvar; extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); extern __attribute__((__visibility__("default"))) int exportedfunc (void); void dummyfunc (void) {} ]], [[]])], [gl_cv_cc_visibility=yes], [gl_cv_cc_visibility=no]) CFLAGS="$gl_save_CFLAGS"]) AC_MSG_RESULT([$gl_cv_cc_visibility]) if test $gl_cv_cc_visibility = yes; then CFLAG_VISIBILITY="-fvisibility=hidden" HAVE_VISIBILITY=1 fi fi AC_SUBST([CFLAG_VISIBILITY]) AC_SUBST([HAVE_VISIBILITY]) AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) ]) hunspell-1.7.0/man/000077500000000000000000000000001337236234000141275ustar00rootroot00000000000000hunspell-1.7.0/man/Makefile.am000066400000000000000000000001401337236234000161560ustar00rootroot00000000000000man_MANS = hunspell.1 hunspell.3 hunspell.5 hzip.1 hunzip.1 EXTRA_DIST = $(man_MANS) SUBDIRS=hu hunspell-1.7.0/man/hu/000077500000000000000000000000001337236234000145435ustar00rootroot00000000000000hunspell-1.7.0/man/hu/Makefile.am000066400000000000000000000002151337236234000165750ustar00rootroot00000000000000#mandir = $(DESTDIR)/share man1dir = $(mandir)/hu/man1 man4dir = $(mandir)/hu/man4 man_MANS = hunspell.1 hunspell.5 EXTRA_DIST = $(man_MANS) hunspell-1.7.0/man/hu/hunspell.1000066400000000000000000000406521337236234000164660ustar00rootroot00000000000000.hla hu .TH hunspell 1 "2014. május 27." .LO 1 .SH NÉV hunspell \- unicode-os helyesírás\-ellenőrző, szótövező és morfológiai elemző program .SH ÁTTEKINTÉS hunspell [\-1aDGHhLlmnOstvwX] [\-\-check\-url] [\-\-check\-apostrophe] [\-\-help] [\-i karakterkódolás] [\-d szótár[,...]] [\-p sajátszótár] [szöveges/OpenDocument/TeX/LaTeX/HTML/SGML/XML/nroff/troff állomány(ok)] .SH LEÍRÁS A .B hunspell felismeri és javítja az elütéseket és típushibákat egyszerű szöveges, OpenDocument, (La)TeX, XML, HTML és groff (kézikönyv oldal) állományokban. .PP Ha nem adunk meg állománynév-paramétert, a Hunspell az Ispell csőfelületéhez hasonlóan működik: a bemenet sorait szavakra bontja, és *, +, vagy - jellel kezdődő kimeneti sorral jelzi, ha egy szó jó, és # vagy & jellel, ha rossz. A csőfelület parancsait viszont az Ispellhez hasonlóan csak a .I \-a kapcsoló megadásával értelmezi. .PP Állománynév paraméter esetén elindul egy az Ispelléhez hasonló interaktív felület. .SH KAPCSOLÓK .TP .B \-1 Speciális formátum: a bemeneti állomány tabulátorjelet tartalmazó soraiból csak az első tabulátorjel előtti karaktersorozatot vizsgálja meg. .TP .B \-a Ispellhez csőfelület. A .I !, .I +, .I \-, .I \@, .I #, vagy .I ^ jellel kezdődő sorok a csőfelület parancsai, jelentésüket az Ispell kézikönyvoldal részletezi. A \-a kapcsoló hatására a kimenetben a jó szavakat csak csillaggal jelzi a Hunspell. Ez nagyobb kompatibilitást biztosít az Ispellt használó programok némelyikével (például a LyX-szel). Ekkor nem kell megadnunk a \-a kapcsolót, mivel az Ispellt használó programok automatikusan ezzel a kapcsolóval indítják el az Ispell nevében futó Hunspellt is. .TP .B \-d " szótár[,szótár2,...]" Beállítja a helyesírási szótárakat a kiterjesztés nélküli szótárnevek, útvonalak megadásával. Például a .PP hunspell \-d hu_HU,hu_geo,hu_med,de_DE,de_med .PP a magyar alapszótárat és kiegészítő szótárait, valamint német alapszótárat és annak egy kiegészítő szótárát tölti be. Az alapszótárak egy aff és egy dic kiterjesztésű állományból állnak, a kiegészítő szótárak csak dic állományból. A kiegészítő szótárak nevére vonatkozóan nincs szabály (csak a dic kiterjesztés), a szótárnevek sorrendje határozza meg, hogy melyik alapszótárhoz töltődnek be a kiegészítő szótárak (ami pedig meghatározza a javaslattevést). Az első szótár mindig alapszótár. .PP Az alapértelmezett szótár a környezet nyelvi beállításától függ az Unix rendszereken. Locale hiányában a .BR /usr/share/hunspell/default az alapértelmezett szótár. .PP A megadott útvonal lehet abszolút és relatív is. Relatív útvonal esetén először az aktuális, majd a .BR /usr/share/hunspell és még több más könyvtárban keresi a szótárt a program. L. \-D és a .BR PÉLDÁK. .TP .B \-D A keresési útvonalak, az elérhető és betöltött szótárak útvonalának kijelzése. .TP .B \-G A \-l, \-w, és \-L kapcsolókat kiegészítő kapcsoló. A standard bemenetről érkező hibás szavak, illetve sorok megjelenítése helyett a jó szavak és a hibátlan sorok megjelenítését kérhetjük vele. Ha mást nem adunk meg, a \-l kapcsoló hatásának megfelelően működik, csak a rossz helyett a jó szavakat írja a standard kimenetre. .TP .B \-h, \-\-help A beépített leírás megjelenítése. .TP .B \-H HTML bemeneti állományformátum beállítása. Ha az állomány nevének .html vagy .htm a kiterjesztése, ez automatikusan bekövetkezik. .TP .B \-l Kiírja a hibás szavakat a standard bemenetről érkező állományból. Használható a \-H, \-t, \-n, \-1 kapcsolókkal együtt is. A \-G kapcsoló megfordítja a Hunspell működését: csak a jó szavak kerülnek kiírásra. .TP .B \-L Csak a hibás szavakat tartalmazó sorokat írja ki a standard bemenetről érkező állományból. Használható a \-H, \-t, \-n, \-1 kapcsolókkal együtt is. A \-G kapcsoló megfordítja a működését: csak azok a sorok kerülnek kiírásra, amelyek egy hibás szót sem tartalmaznak. .TP .B \-m Elemző üzemmód: a bemeneti szövegszavak morfológia elemzése, illetve a szótári morfológiai leírás hiányában a toldalékolt szavak kapcsolóinak kijelzése (szótárfejlesztőknek). .TP .B \-n Nroff/troff bemeneti állományformátum beállítása, elsősorban a kézikönyvlapok ellenőrzésére. .TP .B \-O OpenDocument (ODF vagy flat ODF) bemeneti állományformátum beállítása. Ha az állomány nevének .odt, .ods, .odp, .odg, illetve ezek sablon (.ott, ...) vagy flat (.fodt, ...) változatainak megfelelő a kiterjesztése, ez automatikusan bekövetkezik. Ha még nem volna, telepítsük az unzip programot a kapcsoló használata előtt. .TP .B \-p " saját_szótár" A felhasználó saját szótárának beállítására szolgál. Az alapértelmezett saját szótár a .BR $HOME/.hunspell_default állomány. Ha szótárat is megadunk a .I \-d kapcsolóval, vagy a .I DICTIONARY környezeti változóval, a saját szótár a .BR $HOME/.hunspell_szótárnév lesz. Ha a saját szótár nem létezik, létrehozza. Ha az aktuális könyvtárban is van egy ugyanilyen nevű állomány, akkor annak tartalma is beolvasásra kerül, mint saját szótár, és az újonnan felvett szavak is ide kerülnek. A .I \-p , vagy a .I WORDLIST környezeti változó megadásával új saját szótárat jelölünk ki. A saját szótárat az aktuális könyvtárban, és a saját könyvtár gyökerében ($HOME) keresi a Hunspell. Ha nem található, akkor az újonnan felvett szavak mentésénél létrehozza a saját könyvtár gyökerében. .TP .B \-s Tövező üzemmód: a bemenő szövegszavak tövezése (a szótártól függő pontossággal). .TP .B \-t LaTeX bemeneti állományformátum beállítása. Ha az állomány nevének .tex a kiterjesztése, ez automatikusan bekövetkezik. .TP .B \-u Tipikus hibák kijelzése az állományból, cserejavaslattal. .TP .B \-u2 Tipikus hibák és javításuk kijelzése módosítható, és a sed programmal végrehajtatható formában. Irányítsuk a Hunspell kimenetét egy állományba. Törüljük azokat a sorokat az elmentett állományból, amelyek sed paranccsal megadott javítását nem szeretnénk. Mentsük el az állományt, és a \fIsed -f javítás eredeti_állomány >javított_állomány\fR paranccsal javíthatjuk az állományt gyorsan és egyszerűen. (A sok hibát tartalmazó állományok javítását gyorsítja meg ez a lehetőség.) .TP .B \-U Ha az -u kapcsolóval kapott javaslatokat mind el szeretnénk fogadni, akkor az \-U kapcsolóval a Hunspell automatikusan végrehajtja a cseréket, és a módosított állományt a szabványos kimenetre küldi. Példa a javításra: \fIhunspell -U eredeti_állomány >javított_állomány\fR. A hibakimeneten megjelennek a javítások is még egyszer, a -\u kapcsolóhoz hasonló módon. .TP .B \-v Verziószám. .TP .B \-vv Verziószám (Ispell kompatibilitás miatt). .TP .B \-w Csak a hibás szavakat írja ki a standard bemenetről érkező, soronként egy szót tartalmazó állományból. A sorok nincsenek szavakra bontva. A sorok szavakra bontása, és csak a hibás szavak kiírása a \-w kapcsolóval érhető el. A \-G kapcsoló megfordítja a Hunspell működését: csak a jó szavak kerülnek kiírásra. .TP .B \-X XML bemeneti állományformátum beállítása. Ha az állomány nevének .xml a kiterjesztése, ez automatikusan bekövetkezik. .SH INTERAKTÍV FELÜLET A felület legfelső sorában a hibás szóalakot, és az éppen vizsgált állomány nevét látjuk. Amennyiben egy szóalak szótári tiltás miatt nem kerül elfogadásra, a bal felső sarokban a TILTOTT! (FORBIDDEN!) üzenet is megjelenik. Ez az üzenet arra utal, hogy nem hiányos szókincs, hanem szándékos tiltás miatt nem került a szó elfogadásra. Az első sor alatt az állomány hibás szót tartalmazó sorát, és szövegkörnyezetét láthatjuk, majd ezt követik a javaslatok, ha vannak. .PP A használható billentyűkombinációk: .TP .B Szóköz Továbblépés javítás nélkül a következő hibás szóra. .TP .B Számok A megfelelő javaslat kiválasztása. .TP .B c Csere. A hibás szó cseréje a megadott szóra, vagy szavakra. Az Escape billentyű kétszeri lenyomásával megszakíthatjuk a a cserét. .TP .B j A szó elfogadása a program futásának befejeződéséig. .TP .B f A szó felvétele a saját szótárba. .TP .B k A szó kisbetűsként való felvétele a saját szótárba. .TP .B t Ragozott tőszó felvétele. A ragozás a másodikként megadott, mintául szolgáló szó alapján történik. Ha ez a szó nincs felvéve a szótárba, a tőszófelvételt elölről kell kezdeni. Példa: gyakran hiányoznak az idegen és a mozaikszavak. Vegyük fel a hiányzó OTP szót a tv köznévi mozaikszó toldalékaival! Lenyomjuk a t billentyűt, beírjuk, hogy OTP, leütjük az új sor billentyűt, beírjuk, hogy tv, és ismét új sor. A tv szó ugyanis már szerepel a szótárban, és ragozása mondja meg a programnak, hogy az OTP szót milyen toldalékokkal szeretnénk látni, pl. OTP\-hez, OTP\-met stb. a tv\-hez, tv\-met mintájára. A \-val/\-vel, \-vá/\-vé toldalékokat a kötőjellel kapcsolt toldalékú szavak esetében külön kell felvenni, de még így is sokkal kényelmesebb a speciális tőfelvétel, mint minden (akár több száz) toldalékos alakot külön\-külön felvenni. Egy kis segítség a minta kiválasztásához: első menetben a hangrend számít. Pl. mozaikszavaknál a mély hangrendű új szavak felvételénél használhatjuk a \fIMÁV\fR szót példaként, ajakréses magas hangrendnél pedig az említett \fItv\fR\-t. Ajakkerekítéses magas hangrend esetében a \fIHÖK\fR szót használhatjuk (amíg át nem lesz javítva a helyes hök\-re). Ha a hiányzó szó nem mozaikszó, hanem például tulajdonnév, a \fIPál\fR, \fIPéter\fR, \fIÖrs\fR szavakat adhatjuk meg példának a hangrendtől függően. Ha meg egyszerű köznévről van szó, akkor használjuk az \fIok\fR, \fIék\fR, \fIük\fR szavakat. Igéknél \fIáll\fR, \fIvél\fR, \fIül\fR, ikes igéknél \fIázik\fR, \fIvérzik\fR, \fInőzik\fR lehet a példa (remélhetőleg a következő változatokban egyszerűsödik ez a tőfelvétel). Az Escape billentyű kétszeri lenyomásával megszakíthatjuk ezt a műveletet. Az itt felvett szavak automatikusan a saját szótárba kerülnek. Ha ezt innen törölni szeretnénk, a programból kilépve a saját szótár kézi átszerkesztésével tehetjük meg. .TP .B m Kilépés a változtatások mentése nélkül. A program változtatás megléte esetén megerősítést kér. .TP .B v Az állomány ellenőrzésének megszakítása a változtatások mentésével. Ha van következő állomány, akkor a program annak ellenőrzését kezdi el. .TP .B ? Segítség. Hasonló rövid leírás megjelenítése a billentyűparancsokról. .SH CSŐFELÜLET A \fIHunspell \fR soronként dolgozza fel az állományokat, a helyes szavakat \fI*\fR (tőszó), \fI\-\fR (összetett szó), vagy .I + (ragozott szó) karakterrel jelöli, a helyteleneket .I # (nincs javaslat) , vagy .I & (van javaslat) karakterrel. A + jelet a kimenetben követi még a szótő. A # jel után a hibás szó, és kezdőpozíciója van feltüntetve. A & jelet követi a hibás szó; a javaslatok száma; a hibás szó kezdőpozíciója; majd kettőspont után a javaslatok, vesszővel elválasztva: .PP .RS .nf macska * macskabajusz - macskák + macska mcsk # mcsk 0 macka & macka 7 0: macska, maca, racka, packa, vacka, marka, mackó .fi .RS .SH PÉLDÁK .TP .B hunspell \-d en_US english.html Az amerikai angol helyesírási szótár kiválasztása (aktuális, vagy a .BR /usr/share/hunspell könyvtárból. .TP .B hunspell -l szöveg.html A megadott állomány hibás szavainak kiírása. .TP .B hunspell -l *.odt | sort | uniq >nem_ismert_szavak Az aktuális könyvtárban található összes OpenDocument szöveges állomány nem ismert szavainak állományba mentése (az ismétlődők kiszűrésével). .TP .B hunspell -p nem_ismert_szavak_de_jok *.odt Az aktuális könyvtárban található OpenDocument szöveges állományok interaktív ellenőrzése saját szótár megadásával. A példában szereplő saját szótár nem más, mint az előzőleg elmentett nem_ismert_szavak állománya, amelyekből kivettük azokat a szavakat, amelyeket most javítani szeretnénk. .SH KÖRNYEZET .TP .B DICTIONARY A szótár helyének megadására szolgál. Szerepe megegyezik a .I \-d kapcsolóval. .TP .B DICPATH A szótárkeresési útvonalat tartalmazó változó. .TP .B WORDLIST A saját szótár helyének megadására szolgál. Szerepe megegyezik a .I \-p kapcsolóval. .SH ÁLLOMÁNYOK .BI /usr/share/default.aff Az alapértelmezett ragozási táblázat. Lásd hunspell(4). .PP .BI /usr/share/default.dic Az alapértelmezett szótár az előző ragozási táblázathoz. Lásd hunspell(4). .BI $HOME/.hunspell_default Az alapértelmezett saját szótár. Az állományt létrehozza a Hunspell, ha nem létezik. Lásd ispell(1). .SH LÁSD MÉG .B hunspell (4), .B hunstem (1), .B makedb (1), .B lookdb (1), .B ispell (1), .B ispell (4), Magyar Ispell dokumentáció. .SH ELŐNYÖK A program a következő előnyöket nyújtja a hasonló célokat szolgáló \fIIspell\fR\-lel szemben: .IP \- Képzők átfogó ismerete. (Több tízezer helyes szóalak elfogadását tette lehetővé a tesztelésre használt 4 millió szavas gyakorisági szótárban.) .IP \- Homonimák kezelése (nincsenek például olyan alakok elfogadva, mint megvárban). .IP \- Helyes javaslatok a több karakter változásával járó tipikus hibákra (j/ly, íj/ijj, nyj/nny és még több tucatnyi tévesztés megvizsgálásával). Az \fIIspell\fR csak két karakter felcserélése; vagy egy karakter hiánya, cseréje, illetve felesleges jelenléte esetén ad helyes javaslatot. .IP \- Az összes helyes összetett szónak látszó, de tipikus hibával előálló alak tiltása (karvaj, színtű, súlytó stb.) .IP \- Javaslatok valószínűségi sorrendben jelennek meg (tipikus hibák, i/í, o/ó, u/ú tévesztések stb.). .IP \- Összetett szavak esetén 6–3\-as szabály alkalmazása (helyesírás\-ellenőrző, gépkocsi\-összeszerelés). .IP \- Mozgószabály alkalmazása (kiviteli engedély, kiviteliengedély\-kérés). .IP \- A magyar nyelv egyéb összetételi szabályainak alkalmazása (például hatlövetű, tizenkét lövetű, kéthavi, két hónapos, másodmagával). .IP \- Leg-, legesleg- és -bb confixum helyes kezelése (nincs pl. legédes, csak legédesebb). .IP \- Ragozható tőszófelvétel. Megkönnyíti egy új szó ragozott változatainak ellenőrzését, feleslegessé téve ezek külön\-külön történő felvételét a saját szótárba. .IP \- Javaslatok mássalhangzó\-triplázások (sakkkör, baletttáncos, dzsesszszak) esetén. (Ispell helyesnek fogadja el ezeket.) .IP \- Javaslatok szótagduplázások (oktatatás, igenenevet) esetén. .IP \- Javaslatok ékezet nélküli szövegre (tukorfurogep\->tükörfúrógép). .IP \- Kötőjeles szavak kezelése (unos\-untalan). .IP \- Toldalékolt számok (1\-jén, 11\-én, 5.\-et) kezelése. .IP \- °, %, és § jelek (%\-kal) toldalékolt alakjainak kezelése. .IP \- Mozaikszavak (MÁV\-osokat) kezelése. .IP \- Y-ra végződő szavak (boyjal, pennyvel) kezelése. .IP \- Idegen ejtésű szótagra végződő szavak (Anonymusszal, Voltaire\-nek) kezelése. .IP \- Két szóból álló földrajzi nevek (San Franciscó\-i) kezelése. .IP \- Hibás alakok tiltása (Babitssal, tanit, alkotóművész stb.) .IP \- Tiltások jelzése a felhasználói felületen. .IP \- Egyéb (például az Ispell ragozott utószó esetében bármilyen szóösszetételt elfogad: macskatekerem, kutyakavarom, ezt a Hunspell nem teszi meg). .IP \- Magyar nyelvű (illetve .B locale (7) függő) felület. .IP \- Hordozható szöveges szótárállományok, szemben az Ispell platform, és bináris Ispell fordítástól függően (nem) kezelhető adatállományaival. .SH SZERZŐ A Hunspell az OpenOffice.org MySpell függvénykönyvtárán továbbfejlesztése. A MySpell affixumtömörítésének mintája az International Ispell program volt. .PP A mintaként szolgáló International Ispell szerzője Geoff Kuenning, sok más elődje munkájára támaszkodva (l. ispell(1)). .PP A Myspellt Kevin Hendricks készítette a legjelentősebb nyílt forráskódú irodai csomaghoz, az OpenOffice.org-hoz 2001\-2002\-ben (l. http://hu.openoffice.org). .PP A Hunspell programkönyvtárat és parancssori programot Németh László készítette 2002\-2008\-ban. hunspell-1.7.0/man/hu/hunspell.5000066400000000000000000000465141337236234000164750ustar00rootroot00000000000000.hla hu .TH hunspell 5 "2014. május 26." .LO 1 .SH NÉV hunspell \- a Hunspell állományainak formátuma .SH LEÍRÁS A .IR Hunspell (1) két állományt igényel egy adott nyelven történő helyesírás\-ellenőrzéshez. Az első állomány egy szótárállomány, ami az adott nyelv szavait, és ezek kapcsolóit (attribútumait) tartalmazza. A második állomány egy ragozási (affixum) állomány, ami meghatározza az említett kapcsolók jelentését. .SH SZÓTÁRÁLLOMÁNY Egy hunspell .B szótárállomány (*.dic) első sora a szótárállományban lévő szavak közelítő számát tartalmazza (az optimális méretű memóriaterület lefoglalásához). A többi sor soronként egy szót tartalmaz. Minden szó után nem kötelezően egy perjel, és egy, vagy több kapcsoló következhet. A kapcsolók egybetűsek, és meghatározzák, hogy milyen toldalékokat kaphat a tőszó, illetve milyen egyéb speciális tulajdonságokkal rendelkezik. Például a .PP .RS .nf 1 hunspellezik/EeX .fi .RE .PP szótár egy szót tartalmaz (hunspell), ami a magyar ragozási állomány alapján alanyi és tárgyas igeragozást is vonz (E és e kapcsolók), valamint igekötő prefixumokat is kaphat. A példa szótárállomány és a magyar ragozási állomány alapján a \fImeghunspelleztétek\fR helyes szóként kerülne felismerésre. A szótári szavak perjelet is tartalmazhatnak, ha az fordított perjellel van bevezetve: "\/". A kapcsolók alapértelmezésként egy karakteresek, de ha több ragozási osztályt szeretnénk használni, ez több karakteresre vagy számra is módosítható. A Hunspell szótárállományok sorai kiegészítő adatmezőket is tartalmazhatnak, amelyek szóközökkel vagy tabulátorokkal vannak elválasztva (l. kiegészítő adatmezők). A személyes szótárak egyszerű szólisták. Megadhatunk perjellel elválasztott példaszavakat is a toldalékolás engedélyezésére: .PP .RS .nf Obama/Tamara .fi .RE .PP A példában a Tamara szó toldalékolását a személyes szótár Obama szavára is alkalmazza az ellenőrző, elfogadva az Obamáról, Obamáékat stb. alakokat is. .SH RAGOZÁSI ÁLLOMÁNY A .B "ragozási állomány" rendszerint kisebb méretű. Különféle definíciókat és ragozási szabályokat ad meg meghatározott kulcsszóival. Például a .B SET a karakterkódolás, a .B TRY javaslattevésnél módosítot betűk, a .B REP a javaslattevésnél módosított szórészletek, a .B PFX és az .B SFX pedig a szó elejére és végére illesztendő toldalékok megadására szolgál. A következő példa egy UTF\-8-as kódolású szótár affixumállományának definíciója. A TRY felsorolja a magyar betűket gyakorisági sorrendjükben, a LANG beállítja a magyar nyelvet, a WORDCHARS megadja azokat a karaktereket, amelyeket a parancssori Hunspell a szavak részeként fog kezelni. .PP .RS .nf SET UTF\-8 TRY íóúÍÓÚtaeslzánorhgkiédmyőpvöbucfjüűxwqTAESLZÁNORHGKIÉDMYŐPVÖBUCFJÜŰXWQ\-. LANG hu_HU WORDCHARS \-.§%‰°0123456789 REP 2 REP j ly REP ly j PFX X Y 3 PFX X 0 meg . PFX X 0 rá . PFX X 0 össze . SFX e Y 6 SFX e ik tük e[dz]ik SFX e ik tétek e[dz]ik SFX e ik ték e[dz]ik SFX e 0 tük e[dzt] SFX e 0 tétek e[dzt] SFX e 0 ték e[dzt] SFX f Y 2 SFX f ik het/e e[dz]ik SFX f ik tet/e e[dz]ik .fi .RE .PP A REP a j és ly felcserélése esetén ad jó és elöl rangsorolt javaslatokat. A PFX-ek pár igekötőt definiálnak, az SFX-ek pedig pár igeragot. Ezek nagyobb részénél a szó végi ik is levágásra kerül a toldalék illesztése előtt. Itt az illesztés feltétele, hogy az igék -edik vagy -ezik karaktersorozatra végződjenek, különben pedig az -ed, -ez vagy -et betűkre. Az f jelű toldalékolási osztály érdekessége, hogy a -het és -tet illesztése után még folytatódhat a toldalékolás az e jelű toldalékolási osztállyal (ezt a het/e ls tet/e határozza meg), így kaphat -hettük, -hettétek, -hették, -tettük, -tettétek, -tették toldalékokat a szótárban szereplő levelezik szó: .PP .RS .nf 1 levelezik/e .fi .RE .PP .SH "ÁLTALÁNOS PARAMÉTEREK" A Hunspell forrás több mint 80 példát tartalmaz a paraméterek használatára vonatkozóan. A következő leírás nem teljes, l. még az angol kézikönyvoldalt is. .IP "SET karakterkód" A szótár és affixumállomány karakterkódolásának beállítása. A lehetséges értékek: UTF-8, ISO8859\-1-től ISO8859\-10-ig, ISO8859\-13\-ISO8859\-15, KOI8-R, KOI8-U, cp1251, ISCII-DEVANAGARI. .IP "FLAG érték" A kapcsolók 1 karakteres alapbeállításának módosítása. (A ragozási osztályokat és egyéb tulajdonságokat jelölik a kapcsolók, amelyek alapértelmezés szerint 1 karakteresek, a pékdákban legtöbbször nagybetűvel szerepelnek). Az `UTF-8' értékkel Unicode karaktereket használhatunk kapcsolóként (UTF-8 kódolással és maximum 65 ezres karakterkódig), a `long' értékkel két karakteres kapcsolókat (több kapcsoló esetén sincs elválasztójel, a `num' értékkel vesszővel elválasztott decimális számokat 1-től 65 ezerig. .IP "COMPLEXPREFIXES" Kétszeres prefixumillesztést állít be (de csak egyszeres szuffixumokat az alapértelmezett kettő helyett.) Jobbról balra író ragasztó nyelveknél hasznos. .IP "LANG nyelvkód" Nyelv megadása (nyelvfüggő programrészek bekapcsolásához) az ISO nyelv- és régiókóddal (pl. hu_HU). .IP "IGNORE karakterek" A felsorolt karaktereket törli a szótári szavakból és toldalékokból, valamint a bemeneti szavakból. Hasznos az opcionális írásjelek, mint az arab vagy a héber mellékjelek kezelésére. .IP "AF a_következő_AF_sorok_száma" .IP "AF kapcsolók" A Hunspell program képes a kapcsolóhalmazokat egy természetes számmal helyettesíteni a szótárállományban és a többszörös toldalékásnál az affixumállományban (alias tömörítés), felgyorsítva ezzel a szótár betöltődését és csökkentve a program memóriaigényét. Egy rövid példa: .PP .RS .nf 3 hello try/1 work/2 .fi .RE .PP És a kapcsolódó AF definíciók az affixumállományban: .PP .RS .nf SET UTF-8 TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ' AF 2 AF A AF AB ... .fi .RE .PP Ami megfelel a következő szótárállománynak: .PP .RS .nf 3 hello try/A work/AB .fi .RE .PP Lásd még a tests/alias* példát a forrásban. Megjegyzés: az AF sorok nem előzhetik meg a FLAG paramétert. Alias tömörítésre szolgál a Hunspell makealias segédprogramja. .IP "AM a_következő_AM_sorok_száma" .IP "AM morfológiai_és_egyéb_adatmezők" A Hunspell program képes a kiegészítő adatmezőket egy természetes számmal helyettesíteni, az AF paraméterhez hasonlóan. Lásd még a tests/alias* példát a forrásban. .SH "JAVÍTÁSI PARAMÉTEREK" Az alapértelmezett n-gram, illetve betűcserén és -törlésen alapuló javaslatokat kiegészíthetjük a javítási paraméterekkel. A REP segít a tipikus hibák és javításuk megadásában. A PHONE a kiejtést kevésbé követő írásrendszereknél nyújt segítséget. .IP "KEY szomszédos_karakterek_opcionálisan_függőleges_vonallal_elválasztva" A nyelv alapértelmezett billentyűzetkiosztását adhatjuk meg a KEY paraméterrel, hogy a javaslatoknál a szomszédos betűk elütését felismerje a program. A nem szomszédos betűket függőleges vonallal választhatjuk el: .PP .RS .nf KEY öüó|qwertzuiopőú|asdfghjkléáű|íyxcvbnm .fi .RE .PP .IP "TRY karakterek" A javaslattevésnél az 1 karakteres próbálkozásoknál az itt felsorolt karakterekre cserél, illetve bővít. A paraméternél a kis- és nagybetűket külön kell megadni. .IP "NOSUGGEST kapcsoló" Az itt definiált kapcsolóval jelölt szavakat a program nem javasolja a hibajavításnál. Vulgáris és obszcén szavak esetében hasznos. .IP "MAXNGRAMSUGS" Az n-gram (n hosszú szórészletek megegyezősége alapján súlyozott) javaslatok maximális számának beállítása. Alapértelmezetten 5. A 0 érték kikapcsolja az n-gram javaslatokat. .IP "NOSPLITSUGS" Nem javasol szófelbontást a Hunspell ezzel a beállítással. Hiányzó összetettszó-kezelés esetén hasznos a hibás különírási javaslatok tiltására. .IP "SUGSWITHDOTS" Ha a hibás szó pont(ok)ra végződik, ezeket a javaslatok esetében is feltünteti. A LibreOffice szótárak számára nem szükséges ez a beállítás. .IP "REP szám" .IP "REP mit mire" A javítási cseretáblázat megadására szolgáló definíciók. Az első REP után adjuk meg a többi REP sor számát. Ezek a sorok már két paramétert várnak: először megadjuk a felismerendő mintát (hibás szórészletet), utána pedig azt a karaktersorozatot, amire a felismert mintát javítani szeretnénk. A helyesírás\-ellenőrző a cseretáblázat révén tud helyes javaslatot tenni többkarakteres eltérés (pl. j-ly) esetén. A szóköz aláhúzásjellel helyettesítendő a javaslatokban: .PP .RS .nf REP 1 REP végülis végül_is .fi .RE .PP A szervíz, szintű és a hasonló hibás összetett szavak letiltásában szintén a REP táblázat segít a CHECKCOMPOUNDREP megadásával (l. ott). .IP "MAP a_MAP_definíciók_száma" .IP "MAP karakterek" Rokon karaktereket adhatunk meg több sorban. A javaslattevésnél több rokon karakter cseréje is lehetséges, így például ékezet nélküli szavakat is képes ékezetesíteni a Hunspell a következő definíció mellett: .PP .RS .nf MAP 5 MAP aá MAP eé MAP ií MAP oóöő MAP uúüű .fi .RE .PP .IP "PHONE a_PHONE_definíciók_száma" .IP "PHONE karakterek" A PHONE egy táblázattal megadható fonetikus átírási algoritmust használ a kiejtési hasonlóság kiszámítására. Különösen hasznos azoknál a nyelveknél, ahol az írás nem tükrözi a kiejtést. A részletes dokumentáció az Aspell helyesírás-ellenőrző oldalán érhető el angol nyelven: http://aspell.net/man-html/Phonetic-Code.html. Megjegyzés: a szabályokban szereplő kapcsos zárójelek nem tartalmazhatnak még több byte-os UTF-8 karaktereket, ahogy a kötőjeles kifejezések is byte-ot jelölnek, nem karaktert Unicode szótár esetén is. .SH "SZÓ-ÖSSZETÉTELEZÉSI PARAMÉTEREK" .IP "BREAK a_BREAK_definíciók_száma" .IP "BREAK karakter_vagy_karaktersorozat" Ha a keresett szó nincs a szótárban, a felsorolt karaktereknél vagy karaktersorozatoknál felbontja és részenként ellenőrzi. Hasznos például a kis- és nagykötőjeles szavaknál a magyarban. .IP "COMPOUNDRULE" Reguláris kifejezésekhez hasonló összetételi szabályok megadása. .IP "COMPOUNDMIN szám" A legkisebb szóhossz, ami még összetett szóban szerepelhet. Alapértelmezés szerint 3 karakter. .IP "COMPOUNDFLAG kapcsoló" Itt adható meg a szóösszetételben való szereplést engedélyező kapcsoló. .IP "COMPOUNDBEGIN kapcsoló" A kapcsoló az összetett szavak első tagjaként engedélyezi a megjelölt szavakat. .IP "COMPOUNDLAST kapcsoló" A kapcsoló az összetett szavak utolsó tagjaként engedélyezi a megjelölt szavakat. Kombinálható az előző kapcsolóval. .IP "COMPOUNDMIDDLE kapcsoló" A kapcsoló az összetett szavak közbenső tagjaként engedélyezi a megjelölt szavakat. Kombinálható a két előző kapcsolóval. .IP "ONLYINCOMPOUND kapcsoló" Csak az összetett szavakban megjelenő ragozás jelölésére szolgáló kapcsoló (germán nyelvek esetében tipikus). .IP "CIRCUMFIX kapcsoló" Ezzel a kapcsolóval jelölt szuffixum csak ugyanilyen kapcsolóval jelölt prefixummal jelenhet meg egy tövön. (Pl. leg-édes-ebb). .IP "COMPOUNDPERMITFLAG kapcsoló" Alapértelmezés szerint a prefixumok és szuffixumok nem fordulhatnak elő az összetett szavak belsejében. A COMPOUNDPERMITFLAG kapcsolóval rendelkező affixumok viszont itt is megjelenhetnek. .IP "COMPOUNDFORBIDFLAG kapcsoló" Toldalékolt szavak szóösszetételben való szereplését tiltó kapcsoló. A tiltáshoz az adott SFX szabály folytatási osztályaként (l. később) adjuk meg ezt a kapcsolót. .IP "COMPOUNDROOT kapcsoló" A szótárba közvetlenül felvett összetett szavakat jelölő kapcsoló. A COMPOUNDWORDMAX, és így a magyar esetében a 6–3-as szabály működését befolyásolja azzal, hogy a COMPOUNDROOT kapcsolóval összetettnek jelölt szavak két szónak számítanak. .IP "COMPOUNDWORDMAX szám" A szóösszetételekben szereplő egyszerű tövek maximális száma. A magyar esetében 2 az érték, e fölötti szószámnál már életbe lép a 6–3-as szabály. .IP "COMPOUNDSYLLABLE szám karakterek" Két paramétert vár. Az első megadja az összetett szavak tövének maximális szótagszámát, ami a magyar helyesírás 6–3-as szabálya szerint 6. A második mező felsorolja a magánhangzókat, ami a szótagszám megállapításához szükséges. Ha hiányzik ez a definíció, akkor nincsen korlátozás az összetett szavak tövének szótagszámára vonatkozóan. .IP "SYLLABLENUM kapcsolók" Egy paramétert vár. A paraméterben megadhatóak azok a ragozási osztályok, amelyek ragozás esetén eggyel növelik az összetett szavak tövénél kiszámított szótagszámot. A magyarban ezek a melléknévképzők: kerékpárjavításainkról, de kerékpár\-javítási. A .IP "FORBIDDENWORD kapcsoló" A tiltott szavakat jelölő kapcsoló. A tiltott szótövek toldalékolt alakjai is letiltásra kerülnek. A tiltott szavak akár toldalékolási, vagy szóösszetételi szinonimaként sem kerülnek elfogadásra. .IP "PSEUDOROOT kapcsoló" A kapcsolóval jelölt szavak toldalékolt alakjai kerülnek csak elfogadásra. Fiktív tövek megadására szolgáló kapcsoló. A tő lehet még helyes szó, ha érvényes szinonimaként előáll vagy szerepel a szótárban. .IP "WORDCHARS karakterek" Paramétere azok a karakterek, amelyek a beállított kódolás (pl. a magyar esetében az ISO-8859-2) betűi mellett még az adott nyelv szavaiban előfordulhatnak. Ilyen például a magyarban a kötőjel, pont, százalékjel, fokjel, paragrafusjel és a nagykötőjel. Az utóbbi csak UTF-8, vagy microsoft-cp1250 karakterkészlet mellett lesz használható a magyar szótárban. .IP "PFX kapcsoló keresztkombinálódás szám" .IP "PFX kapcsoló levágás prefixum feltétel morfológia" Prefixum megadására szolgáló definíciók. A prefixumok egykarakteres névvel jelölt osztályokba vannak sorolva. A példában az X osztály definíciója látható. Az egyes osztályokra vonatkozó PFX fejléc tartalmazza a következőket: (1) az osztály betűjelét (a példában X) (2) a keresztbe való kombinálás engedélyezése, illetve tiltása (Y/N). Engedélyezés esetén az adott prefixum akkor is alkalmazható, ha a tőszó toldalékolt alakban fordul elő. Ehhez az is szükséges, hogy a toldalék (affixum) ragozási osztályában is legyen engedélyezve a kombinálás. (3) az osztályba tartozó bejegyzések számát A PFX fejlécet követő sorokban a PFX paraméterek jelentése a következő: (1) az osztály betűjele (2) a ragozásnál a szó elejéről leválasztandó karaktersorozat. Ha nem kell leválasztani, akkor 0. (3) a prefixum (például igekötő, vagy a leg\-, legesleg\- a mellékneveknél). Perjellel elválasztva kapcsolókat is megadhatunk (l. többszörös toldalékolás). (4) a minta, ami ha illeszkedik, alkalmazható a szabály. Például ha itt kutya szerepelne, akkor csak a kutya kezdetű szavak elé lehetne tenni az ebben a sorban megadott prefixumot. A minta megadásánál a pont (.) speciális jelentéssel bír: minden karakterre illeszkedik. Megadhatunk csak bizonyos karakterekre illeszkedő mintát is szögletes zárójelek segítségével. Például az [abcd] illeszkedik az a, b, c, illetve d karakterekre is. Ellentétben az Ispell\-lel, a kötőjel szerepe a szögletes zárójelek között nem speciális, vagyis kötőjelet jelent, és nem karaktertartományt. Ha a nyitó szögletes zárójel után kalap (^) karakter található, a karaktertartomány komplementerére illeszkedik a minta, hasonlóan a reguláris kifejezésekhez (l. .IR regex "(7))." (5) Morfológiai leírás. Szóközzel vagy tabulátorral elválasztott mezők. A mezőnevek és használatuk az angol kézikönyvoldalon található. .IP "SFX kapcsoló keresztkombinálódás szám" .IP "SFX kapcsoló szuffixum feltétel mofológiai_leírás" A PFX\-szel megegyező paramétereket kap, csak nem a szó eleji, hanem a szó végi toldalékok leírására szolgál. A példában szereplő definíciók jelentése: az \-edik, vagy \-ezik végű szavakra alkalmazható a három szabály. A rag illesztésénél levesszük a szó végi \-ik karaktersorozatot, és szabálytól függően illesztjük a \-tük, \-tétek, \-ték toldalékokat, végeredményben \-edtük, \-edtétek, \-edték, illetve -eztük, \-eztétek, \-ezték végű szavakat kapva. .IP "Többszörös toldalékolás" A PFX és az SFX szabályokban a toldalék perjellel elválasztva kapcsolókat is kaphat, hasonlóan a szótárállomány töveihez. A kapcsolók a következőek lehetnek: (1) SFX szabályban az SFX folytatás jelentése, hogy a toldalék még tovább ragozódhat a megadott kapcsolókkal (többszörös affixumleválasztás). A Hunspell esetében csak a kétszeres affixumleválasztás lett megvalósítva, tehát a folytatási osztály folytatását már nem veszi figyelembe a program. (2) SFX szabályban a PFX folytatás jelentése, hogy az adott prefixum is hozzájárulhat a tőhöz, feltéve, ha az SFX szabály is él. (3) PFX szabályban az SFX szabály jelentése, hogy a megjelölt SFX szabály a tőhöz járulhat, ha a PFX szabály is él. (4) ONLYINCOMPOUND kapcsoló megadásával az adott PFX vagy SFX toldalék csak szóösszetételben jelentkezhet. (5) CIRCUMFIX kapcsoló megadásával az adott SFX csak az ugyanilyen toldalékot kapó PFX-szel együtt fordulhat csak elő. (6) Az összetételi kapcsolók megadásával engedélyezhetjük vagy letilthatjuk (COMPOUNDFORBIDFLAG) az összetételben való szereplést. A összetett szavak utolsó tagja alapértelmezés szerint minden affixumot felvehet. A közbenső szavaknál viszont explixit módon engedélyezni kell ezt. .PP A ragozási állomány ezeken kívül még megjegyzéseket is tartalmazhat, ezért az adott szótár változatát, szerzőjét, felhasználási engedélyeit itt keressük. .SH SAJÁT SZÓTÁR A saját szótár formátuma közel megegyezik a szótárállomány formátumával. A különbségek a következőek: (1) Nem kell megadni az első sorban az állományban lévő szavak méretét. (2) A szóhoz nem kapcsolókat, hanem egy mintaszót adhatunk meg, ami alapján az ellenőrző a szó toldalékolt alakjait is felismeri. Például a Patyomkin/Ádám azt jelenti, hogy a Patyomkin szót az Ádáméval megegyező ragozással is el kell fogadni. (3) A csillag tiltást jelent: a csillaggal jelölt szavakat az ellenőrző akkor sem ismeri fel, ha az alapszótárban szerepelnek, pl. *kóricál. (4) Az állomány kézzel módosítható, és ezt időnként javasolt is megtenni, ha esetleg hibásan vettünk fel szavakat. .SH LÁSD MÉG .B angol nyelvű hunspell (5), .B hunspell (1), .B ispell (1), .B ispell (4), Magyar Ispell dokumentáció. .SH TÖRTÉNET A MySpell szótár\-, illetve ragozási állományának formátumát Kevin Hendricks készítette olyan céllal, hogy lehetővé tegye ezen állományok gyors, futás idejű feldolgozását. A COMPOUNDFLAG, REP és az egyéb Hunspell beállítási lehetőségeket Németh László készítette, elsősorban a jobb magyar nyelvű helyesírás\-ellenőrzés céljából. hunspell-1.7.0/man/hunspell.1000066400000000000000000000276421337236234000160560ustar00rootroot00000000000000.TH hunspell 1 "2014-05-27" .LO 1 .SH NAME hunspell \- spell checker, stemmer and morphological analyzer .SH SYNOPSIS hunspell [\-1aDGHhLlmnOrstvwX] [\-\-check\-url] [\-\-check\-apostrophe] [\-d dict[,dict2,...]] [\-\-help] [\-i enc] [\-p dict] [\-vv] [\-\-version] [text/OpenDocument/TeX/LaTeX/HTML/SGML/XML/nroff/troff file(s)] .SH DESCRIPTION .I Hunspell is fashioned after the .I Ispell program. The most common usage is "hunspell" or "hunspell filename". Without filename parameter, hunspell checks the standard input. Typing "cat" and "exsample" in two input lines, results an asterisk (it means "cat" is a correct word) and a line with corrections: .PP .RS .nf $ hunspell -d en_US Hunspell 1.2.3 * & exsample 4 0: example, examples, ex sample, ex-sample .fi .RE .PP Correct words signed with an '*', '+' or '-', unrecognized words signed with '#' or '&' in output lines (see later). (Close the standard input with Ctrl-d on Unix/Linux and Ctrl-Z Enter or Ctrl-C on Windows.) .PP With filename parameters, .I hunspell will display each word of the files which does not appear in the dictionary at the top of the screen and allow you to change it. If there are "near misses" in the dictionary, then they are also displayed on following lines. Finally, the line containing the word and the previous line are printed at the bottom of the screen. If your terminal can display in reverse video, the word itself is highlighted. You have the option of replacing the word completely, or choosing one of the suggested words. Commands are single characters as follows (case is ignored): .PP .RS .IP R Replace the misspelled word completely. .IP Space Accept the word this time only. .IP A Accept the word for the rest of this .I hunspell session. .IP I Accept the word, capitalized as it is in the file, and update private dictionary. .IP U Accept the word, and add an uncapitalized (actually, all lower-case) version to the private dictionary. .IP S Ask a stem and a model word and store them in the private dictionary. The stem will be accepted also with the affixes of the model word. .IP 0-\fIn\fR Replace with one of the suggested words. .IP X Write the rest of this file, ignoring misspellings, and start next file. .IP Q Exit immediately and leave the file unchanged. .IP ^Z Suspend hunspell. .IP ? Give help screen. .RE .SH OPTIONS .IP \fB\-1\fR Check only first field in lines (delimiter = tabulator). .IP \fB\-a\fR The .B \-a option is intended to be used from other programs through a pipe. In this mode, .I hunspell prints a one-line version identification message, and then begins reading lines of input. For each input line, a single line is written to the standard output for each word checked for spelling on the line. If the word was found in the main dictionary, or your personal dictionary, then the line contains only a '*'. If the word was found through affix removal, then the line contains a '+', a space, and the root word. If the word was found through compound formation (concatenation of two words, then the line contains only a '\-'. .IP "" If the word is not in the dictionary, but there are near misses, then the line contains an '&', a space, the misspelled word, a space, the number of near misses, the number of characters between the beginning of the line and the beginning of the misspelled word, a colon, another space, and a list of the near misses separated by commas and spaces. .IP "" Also, each near miss or guess is capitalized the same as the input word unless such capitalization is illegal; in the latter case each near miss is capitalized correctly according to the dictionary. .IP "" Finally, if the word does not appear in the dictionary, and there are no near misses, then the line contains a '#', a space, the misspelled word, a space, and the character offset from the beginning of the line. Each sentence of text input is terminated with an additional blank line, indicating that .I hunspell has completed processing the input line. .IP "" These output lines can be summarized as follows: .RS .IP OK: * .IP Root: + .IP Compound: \- .IP Miss: & : , , ... .IP None: # .RE .IP "" For example, a dummy dictionary containing the words "fray", "Frey", "fry", and "refried" might produce the following response to the command "echo 'frqy refries | hunspell \-a": .RS .nf (#) Hunspell 0.4.1 (beta), 2005-05-26 & frqy 3 0: fray, Frey, fry & refries 1 5: refried .fi .RE .IP "" This mode is also suitable for interactive use when you want to figure out the spelling of a single word (but this is the default behavior of hunspell without -a, too). .IP "" When in the .B \-a mode, .I hunspell will also accept lines of single words prefixed with any of '*', '&', '@', '+', '\-', '~', '#', '!', '%', '`', or '^'. A line starting with '*' tells .I hunspell to insert the word into the user's dictionary (similar to the I command). A line starting with '&' tells .I hunspell to insert an all-lowercase version of the word into the user's dictionary (similar to the U command). A line starting with '@' causes .I hunspell to accept this word in the future (similar to the A command). A line starting with '+', followed immediately by .B tex or .B nroff will cause .I hunspell to parse future input according the syntax of that formatter. A line consisting solely of a '+' will place .I hunspell in TeX/LaTeX mode (similar to the .B \-t option) and '\-' returns .I hunspell to nroff/troff mode (but these commands are obsolete). However, the string character type is .I not changed; the '~' command must be used to do this. A line starting with '~' causes .I hunspell to set internal parameters (in particular, the default string character type) based on the filename given in the rest of the line. (A file suffix is sufficient, but the period must be included. Instead of a file name or suffix, a unique name, as listed in the language affix file, may be specified.) However, the formatter parsing is .I not changed; the '+' command must be used to change the formatter. A line prefixed with '#' will cause the personal dictionary to be saved. A line prefixed with '!' will turn on .I terse mode (see below), and a line prefixed with '%' will return .I hunspell to normal (non-terse) mode. A line prefixed with '`' will turn on verbose-correction mode (see below); this mode can only be disabled by turning on terse mode with '%'. .IP "" Any input following the prefix characters '+', '\-', '#', '!', '%', or '`' is ignored, as is any input following the filename on a '~' line. To allow spell-checking of lines beginning with these characters, a line starting with '^' has that character removed before it is passed to the spell-checking code. It is recommended that programmatic interfaces prefix every data line with an uparrow to protect themselves against future changes in .IR hunspell . .IP "" To summarize these: .IP "" .RS .IP * Add to personal dictionary .IP @ Accept word, but leave out of dictionary .IP # Save current personal dictionary .IP ~ Set parameters based on filename .IP + Enter TeX mode .IP \- Exit TeX mode .IP ! Enter terse mode .IP % Exit terse mode .IP "`" Enter verbose-correction mode .IP ^ Spell-check rest of line .fi .RE .IP "" In .I terse mode, .I hunspell will not print lines beginning with '*', '+', or '\-', all of which indicate correct words. This significantly improves running speed when the driving program is going to ignore correct words anyway. .IP "" In .I verbose-correction mode, .I hunspell includes the original word immediately after the indicator character in output lines beginning with '*', '+', and '\-', which simplifies interaction for some programs. .IP \fB\-\-check\-apostrophe\fR Check and force Unicode apostrophes (U+2019), if one of the ASCII or Unicode apostrophes is specified by the spelling dictionary, as a word character (see WORDCHARS, ICONV and OCONV in hunspell(5)). .IP \fB\-\-check\-url\fR Check URLs, e-mail addresses and directory paths. .IP \fB\-D\fR Show detected path of the loaded dictionary, and list of the search path and the available dictionaries. .IP \fB\-d\ dict,dict2,...\fR Set dictionaries by their base names with or without paths. Example of the syntax: .PP \-d en_US,en_geo,en_med,de_DE,de_med .PP en_US and de_DE are base dictionaries, they consist of aff and dic file pairs: en_US.aff, en_US.dic and de_DE.aff, de_DE.dic. En_geo, en_med, de_med are special dictionaries: dictionaries without affix file. Special dictionaries are optional extension of the base dictionaries usually with special (medical, law etc.) terms. There is no naming convention for special dictionaries, only the ".dic" extension: dictionaries without affix file will be an extension of the preceding base dictionary (right order of the parameter list needs for good suggestions). First item of \-d parameter list must be a base dictionary. .IP \fB\-G\fR Print only correct words or lines. .IP \fB\-H\fR The input file is in SGML/HTML format. .IP \fB\-h,\ \-\-help\fR Short help. .IP \fB\-i\ enc\fR Set input encoding. .IP \fB\-L\fR Print lines with misspelled words. .IP \fB\-l\fR The "list" option is used to produce a list of misspelled words from the standard input. .IP \fB\-m\fR Analyze the words of the input text (see also hunspell(5) about morphological analysis). Without dictionary morphological data, signs the flags of the affixes of the word forms for dictionary developers. .IP \fB\-n\fR The input file is in nroff/troff format. .IP \fB\-O\fR The input file is in OpenDocument (ODF or Flat ODF) format. If unzip program is not installed, install it before using this option. .IP \fB\-P\ password\fR Set password for encrypted dictionaries. .IP \fB\-p\ dict\fR Set path of personal dictionary. The default dictionary depends on the locale settings. The following environment variables are searched: LC_ALL, LC_MESSAGES, and LANG. If none are set then the default personal dictionary is $HOME/.hunspell_default. Setting .I \-d or the .I DICTIONARY environmental variable, personal dictionary will be .BR $HOME/.hunspell_dicname .IP \fB\-r\fR Warn of the rare words, which are also potential spelling mistakes. .IP \fB\-s\fR Stem the words of the input text (see also hunspell(5) about stemming). It depends from the dictionary data. .IP \fB\-t\fR The input file is in TeX or LaTeX format. .IP \fB\-v,\ \-\-version\fR Print version number. .IP \fB\-vv\fR Print ispell(1) compatible version number. .IP \fB\-w\fR Print misspelled words (= lines) from one word/line input. .IP \fB\-X\fR The input file is in XML format. .SH EXAMPLES .TP .B hunspell example.html Interactive spell checking of an HTML file with the default dictionary. .TP .B hunspell \-d en_US example.html Interactive spell checking of an HTML file with the en_US dictionary. .TP .B hunspell \-d en_US,en_US_med medical.txt Interactive spell checking with multiple dictionaries. .TP .B hunspell *.odt Interactive spell checking of ODF documents. .TP .B hunspell \-l *.odt List bad words of ODF documents .TP .B hunspell \-l *.odt | sort | uniq >unrecognized Saving unrecognized words of ODF documents (filtering duplications). .TP .B hunspell -p unrecognized_but_good *.odt Interactive spell checking of ODF documents, using the previously saved and reduced word list, as a personal dictionary, to speed up spell checking. .TP .SH ENVIRONMENT .TP .B DICTIONARY Similar to .I \-d. .TP .B DICPATH Dictionary path. .TP .B WORDLIST Equivalent to .I \-p. .SH FILES The default dictionary depends on the locale settings. The following environment variables are searched: LC_ALL, LC_MESSAGES, and LANG. If none are set then the following fallbacks are used: .BI /usr/share/myspell/default.aff Path of default affix file. See hunspell(5). .PP .BI /usr/share/myspell/default.dic Path of default dictionary file. See hunspell(5). .PP .BI $HOME/.hunspell_default. Default path to personal dictionary. .SH SEE ALSO .B hunspell (3), hunspell(5) .SH AUTHOR Author of Hunspell executable is László Németh. For Hunspell library, see hunspell(3). .PP This manual based on Ispell's manual. See ispell(1). hunspell-1.7.0/man/hunspell.3000066400000000000000000000160371337236234000160540ustar00rootroot00000000000000.TH hunspell 3 "2017-11-20" .LO 1 .hy 0 .SH NAME \fBhunspell\fR - spell checking, stemming, morphological generation and analysis .SH SYNOPSIS \fB#include /* or */\fR .br \fB#include \fR .br .sp .BI "Hunspell(const char *" affpath ", const char *" dpath ); .sp .BI "Hunspell(const char *" affpath ", const char *" dpath ", const char * " key ); .sp .BI "~Hunspell(" ); .sp .BI "int add_dic(const char *" dpath ); .sp .BI "int add_dic(const char *" dpath ", const char *" key ); .sp .BI "int spell(const char *" word ); .sp .BI "int spell(const char *" word ", int *" info ", char **" root ); .sp .BI "int suggest(char***" slst ", const char *" word); .sp .BI "int analyze(char***" slst ", const char *" word); .sp .BI "int stem(char***" slst ", const char *" word); .sp .BI "int stem(char***" slst ", char **" morph ", int " n); .sp .BI "int generate(char***" slst ", const char *" word ", const char *" word2); .sp .BI "int generate(char***" slst ", const char *" word ", char **" desc ", int " n); .sp .BI "void free_list(char ***" slst ", int " n); .sp .BI "int add(const char *" word); .sp .BI "int add_with_affix(const char *" word ", const char *" example); .sp .BI "int remove(const char *" word); .sp .BI "char * get_dic_encoding(" ); .sp .BI "const char * get_wordchars(" ); .sp .BI "unsigned short * get_wordchars_utf16(int *" len); .sp .BI "struct cs_info * get_csconv(" ); .sp .BI "const char * get_version(" ); .SH DESCRIPTION The \fBHunspell\fR library routines give the user word-level linguistic functions: spell checking and correction, stemming, morphological generation and analysis in item-and-arrangement style. .PP The optional C header contains the C interface of the C++ library with Hunspell_create and Hunspell_destroy constructor and destructor, and an extra HunHandle parameter (the allocated object) in the wrapper functions (see in the C header file \fBhunspell.h\fR). .PP The basic spelling functions, \fBspell()\fR and \fBsuggest()\fR can be used for stemming, morphological generation and analysis by XML input texts (see XML API). . .SS Constructor and destructor Hunspell's constructor needs paths of the affix and dictionary files. (In WIN32 environment, use UTF-8 encoded paths started with the long path prefix \\\\?\\ to handle system-independent character encoding and very long path names, too.) See the \fBhunspell\fR(4) manual page for the dictionary format. Optional \fBkey\fR parameter is for dictionaries encrypted by the \fBhzip\fR tool of the Hunspell distribution. . .SS Extra dictionaries The add_dic() function load an extra dictionary file. The extra dictionaries use the affix file of the allocated Hunspell object. Maximal number of the extra dictionaries is limited in the source code (20). . .SS Spelling and correction The spell() function returns non-zero, if the input word is recognised by the spell checker, and a zero value if not. Optional reference variables return a bit array (info) and the root word of the input word. Info bits checked with the SPELL_COMPOUND, SPELL_FORBIDDEN or SPELL_WARN macros sign compound words, explicit forbidden and probably bad words. From version 1.3, the non-zero return value is 2 for the dictionary words with the flag "WARN" (probably bad words). .PP The suggest() function has two input parameters, a reference variable of the output suggestion list, and an input word. The function returns the number of the suggestions. The reference variable will contain the address of the newly allocated suggestion list or NULL, if the return value of suggest() is zero. Maximal number of the suggestions is limited in the source code. .PP The spell() and suggest() can recognize XML input, see the XML API section. . .SS Morphological functions The plain stem() and analyze() functions are similar to the suggest(), but instead of suggestions, return stems and results of the morphological analysis. The plain generate() waits a second word, too. This extra word and its affixation will be the model of the morphological generation of the requested forms of the first word. .PP The extended stem() and generate() use the results of a morphological analysis: .PP .RS .nf char ** result, result2; int n1 = analyze(&result, "words"); int n2 = stem(&result2, result, n1); .fi .RE .PP The morphological annotation of the Hunspell library has fixed (two letter and a colon) field identifiers, see the \fBhunspell\fR(4) manual page. .PP .RS .nf 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]); .fi .RE .PP .SS Memory deallocation The free_list() function frees the memory allocated by suggest(), analyze, generate and stem() functions. .SS Other functions The add(), add_with_affix() and remove() are helper functions of a personal dictionary implementation to add and remove words from the base dictionary in run-time. The add_with_affix() uses a second root word as the model of the enabled affixation and compounding of the new word. .PP The get_dic_encoding() function returns "ISO8859-1" or the character encoding defined in the affix file with the "SET" keyword. .PP The get_csconv() function returns the 8-bit character case table of the encoding of the dictionary. .PP The get_wordchars() and get_wordchars_utf16() return the extra word characters defined in affix file for tokenization by the "WORDCHARS" keyword. .PP The get_version() returns the version string of the library. .SS XML API The spell() function returns non-zero for the "" input indicating the XML API support. .PP The suggest() function stems, analyzes and generates the forms of the input word, if it was added by one of the following "SPELLML" syntaxes: .PP .RS .nf dogs .fi .RE .PP .PP .RS .nf dogs .fi .RE .PP .PP .RS .nf dog cats .fi .RE .PP .PP .RS .nf dog is:plis:poss .fi .RE .PP .PP .RS .nf word .fi .RE .PP .PP .RS .nf word model_word_for_affixation_and_compounding .fi .RE .PP The outputs of the type="stem" query and the stem() library function are the same. The output of the type="analyze" query is a string contained a result1result2... element. This element can be used in the second syntax of the type="generate" query. .SH EXAMPLE See analyze.cxx in the Hunspell distribution. .SH AUTHORS Hunspell based on Ispell's spell checking algorithms and OpenOffice.org's Myspell source code. .PP Author of International Ispell is Geoff Kuenning. .PP Author of MySpell is Kevin Hendricks. .PP Author of Hunspell is László Németh. .PP Author of the original C API is Caolan McNamara. .PP Author of the Aspell table-driven phonetic transcription algorithm and code is Björn Jacke. .PP See also THANKS and Changelog files of Hunspell distribution. hunspell-1.7.0/man/hunspell.5000066400000000000000000001104661337236234000160570ustar00rootroot00000000000000.TH hunspell 5 "2017-09-20" .LO 1 .SH NAME hunspell \- format of Hunspell dictionaries and affix files .SH DESCRIPTION .IR Hunspell (1) Hunspell requires two files to define the way a language is being spell checked: a dictionary file containing words and applicable flags, and an affix file that specifies how these flags will control spell checking. An optional file is the personal dictionary file. .SH Dictionary file A dictionary file (*.dic) contains a list of words, one per line. The first line of the dictionaries (except personal dictionaries) contains the approximate word count (for optimal hash memory size). Each word may optionally be followed by a slash ("/") and one or more flags, which represents the word attributes, for example affixes. Note: Dictionary words can contain also slashes when escaped like "\/" syntax. It's worth to add not only words, but word pairs to the dictionary to get correct suggestions for common misspellings with missing space, as in the following example, for the bad "alot" and "inspite" (see also "REP" and field "ph:" about correct suggestions for common misspellings): .PP .RS .nf 3 word a lot in spite .fi .RE .PP .SH Personal dictionary file Personal dictionaries are simple word lists. Asterisk at the first character position signs prohibition. A second word separated by a slash sets the affixation. .PP .RS .nf foo Foo/Simpson *bar .fi .RE .PP In this example, "foo" and "Foo" are personal words, plus Foo will be recognized with affixes of Simpson (Foo's etc.) and bar is a forbidden word. .SH Short example Dictionary file: .PP .RS .nf 3 hello try/B work/AB .fi .RE .PP The flags B and A specify attributes of these words. Affix file: .PP .RS .nf SET UTF-8 TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ' REP 2 REP f ph REP ph f PFX A Y 1 PFX A 0 re . SFX B Y 2 SFX B 0 ed [^y] SFX B y ied y .fi .RE .PP In the affix file, prefix A and suffix B have been defined. Flag A defines a `re-' prefix. Class B defines two `-ed' suffixes. First B suffix can be added to a word if the last character of the word isn't `y'. Second suffix can be added to the words terminated with an `y'. All accepted words with this dictionary and affix combination are: "hello", "try", "tried", "work", "worked", "rework", "reworked". .SH "AFFIX FILE GENERAL OPTIONS" Hunspell source distribution contains more than 80 examples for option usage. .IP "SET encoding" Set character encoding of words and morphemes in affix and dictionary files. Possible values: UTF-8, ISO8859\-1 \- ISO8859\-10, ISO8859\-13 \- ISO8859\-15, KOI8-R, KOI8-U, cp1251, ISCII-DEVANAGARI. .PP .RS .nf SET UTF-8 .fi .RE .PP .IP "FLAG value" Set flag type. Default type is the extended ASCII (8-bit) character. `UTF-8' parameter sets UTF-8 encoded Unicode character flags. The `long' value sets the double extended ASCII character flag type, the `num' sets the decimal number flag type. Decimal flags numbered from 1 to 65000, and in flag fields are separated by comma. BUG: UTF-8 flag type doesn't work on ARM platform. .PP .RS .nf FLAG long .fi .RE .PP .IP "COMPLEXPREFIXES" Set twofold prefix stripping (but single suffix stripping) eg. for morphologically complex languages with right-to-left writing system. .IP "LANG langcode" Set language code for language-specific functions of Hunspell. Use it to activate special casing of Azeri (LANG az), Turkish (LANG tr) and Crimean Tatar (LANG crh), also not generalized syllable-counting compounding rules of Hungarian (LANG hu). .IP "IGNORE characters" Sets characters to ignore dictionary words, affixes and input words. Useful for optional characters, as Arabic (harakat) or Hebrew (niqqud) diacritical marks (see tests/ignore.* test dictionary in Hunspell distribution). .IP "AF number_of_flag_vector_aliases" .IP "AF flag_vector" Hunspell can substitute affix flag sets with ordinal numbers in affix rules (alias compression, see makealias tool). First example with alias compression: .PP .RS .nf 3 hello try/1 work/2 .fi .RE .PP AF definitions in the affix file: .PP .RS .nf AF 2 AF A AF AB ... .fi .RE .PP It is equivalent of the following dic file: .PP .RS .nf 3 hello try/A work/AB .fi .RE .PP See also tests/alias* examples of the source distribution. Note I: If affix file contains the FLAG parameter, define it before the AF definitions. Note II: Use makealias utility in Hunspell distribution to compress aff and dic files. .IP "AM number_of_morphological_aliases" .IP "AM morphological_fields" Hunspell can substitute also morphological data with ordinal numbers in affix rules (alias compression). See tests/alias* examples. .SH "AFFIX FILE OPTIONS FOR SUGGESTION" Suggestion parameters can optimize the default n-gram (similarity search in the dictionary words based on the common 1, 2, 3, 4-character length common character-sequences), character swap and deletion suggestions of Hunspell. REP is suggested to fix the typical and especially bad language specific bugs, because the REP suggestions have the highest priority in the suggestion list. PHONE is for languages with not pronunciation based orthography. For short common misspellings, it's important to use the ph: field (see later) to give the best suggestions. .IP "KEY characters_separated_by_vertical_line_optionally" Hunspell searches and suggests words with one different character replaced by a neighbor KEY character. Not neighbor characters in KEY string separated by vertical line characters. Suggested KEY parameters for QWERTY and Dvorak keyboard layouts: .PP .RS .nf KEY qwertyuiop|asdfghjkl|zxcvbnm KEY pyfgcrl|aeouidhtns|qjkxbmwvz .fi .RE .PP Using the first QWERTY layout, Hunspell suggests "nude" and "node" for "*nide". A character may have more neighbors, too: .PP .RS .nf KEY qwertzuop|yxcvbnm|qaw|say|wse|dsx|sy|edr|fdc|dx|rft|gfv|fc|tgz|hgb|gv|zhu|jhn|hb|uji|kjm|jn|iko|lkm .fi .RE .PP .IP "TRY characters" Hunspell can suggest right word forms, when they differ from the bad input word by one TRY character. The parameter of TRY is case sensitive. .IP "NOSUGGEST flag" Words signed with NOSUGGEST flag are not suggested (but still accepted when typed correctly). Proposed flag for vulgar and obscene words (see also SUBSTANDARD). .IP "MAXCPDSUGS num" Set max. number of suggested compound words generated by compound rules. The number of the suggested compound words may be greater from the same 1-character distance type. .IP "MAXNGRAMSUGS num" Set max. number of n-gram suggestions. Value 0 switches off the n-gram suggestions (see also MAXDIFF). .IP "MAXDIFF [0-10]" Set the similarity factor for the n-gram based suggestions (5 = default value; 0 = fewer n-gram suggestions, but min. 1; 10 = MAXNGRAMSUGS n-gram suggestions). .IP "ONLYMAXDIFF" Remove all bad n-gram suggestions (default mode keeps one, see MAXDIFF). .IP "NOSPLITSUGS" Disable word suggestions with spaces. .IP "SUGSWITHDOTS" Add dot(s) to suggestions, if input word terminates in dot(s). (Not for LibreOffice dictionaries, because LibreOffice has an automatic dot expansion mechanism.) .IP "REP number_of_replacement_definitions" .IP "REP what replacement" This table specifies modifications to try first. First REP is the header of this table and one or more REP data line are following it. With this table, Hunspell can suggest the right forms for the typical spelling mistakes when the incorrect form differs by more than 1 letter from the right form (see also "ph:"). The search string supports the regex boundary signs (^ and $). For example a possible English replacement table definition to handle misspelled consonants: .PP .RS .nf REP 5 REP f ph REP ph f REP tion$ shun REP ^cooccurr co-occurr REP ^alot$ a_lot .fi .RE .PP Note I: It's very useful to define replacements for the most typical one-character mistakes, too: with REP you can add higher priority to a subset of the TRY suggestions (suggestion list begins with the REP suggestions). Note II: Suggesting separated words, specify spaces with underlines: .PP .RS .nf REP 1 REP onetwothree one_two_three .fi .RE .PP Note III: Replacement table can be used for a stricter compound word checking with the option CHECKCOMPOUNDREP. .IP "MAP number_of_map_definitions" .IP "MAP string_of_related_chars_or_parenthesized_character_sequences" We can define language-dependent information on characters and character sequences that should be considered related (i.e. nearer than other chars not in the set) in the affix file (.aff) by a map table. With this table, Hunspell can suggest the right forms for words, which incorrectly choose the wrong letter or letter groups from a related set more than once in a word (see REP). For example a possible mapping could be for the German umlauted ü versus the regular u; the word Frühstück really should be written with umlauted u's and not regular ones .PP .RS .nf MAP 1 MAP uü .fi .RE .PP Use parenthesized groups for character sequences (eg. for composed Unicode characters): .PP .RS .nf MAP 3 MAP ß(ss) (character sequence) MAP fi(fi) ("fi" compatibility characters for Unicode fi ligature) MAP (ọ́)o (composed Unicode character: ó with bottom dot) .fi .RE .PP .IP "PHONE number_of_phone_definitions" .IP "PHONE what replacement" PHONE uses a table-driven phonetic transcription algorithm borrowed from Aspell. It is useful for languages with not pronunciation based orthography. You can add a full alphabet conversion and other rules for conversion of special letter sequences. For detailed documentation see http://aspell.net/man-html/Phonetic-Code.html. Note: Multibyte UTF-8 characters have not worked with bracket expression yet. Dash expression has signed bytes and not UTF-8 characters yet. .IP "WARN flag" This flag is for rare words, which are also often spelling mistakes, see option -r of command line Hunspell and FORBIDWARN. .IP "FORBIDWARN" Words with flag WARN aren't accepted by the spell checker using this parameter. .SH "OPTIONS FOR COMPOUNDING" .IP "BREAK number_of_break_definitions" .IP "BREAK character_or_character_sequence" Define new break points for breaking words and checking word parts separately. Use ^ and $ to delete characters at end and start of the word. Rationale: useful for compounding with joining character or strings (for example, hyphen in English and German or hyphen and n-dash in Hungarian). Dashes are often bad break points for tokenization, because compounds with dashes may contain not valid parts, too.) With BREAK, Hunspell can check both side of these compounds, breaking the words at dashes and n-dashes: .PP .RS .nf BREAK 2 BREAK - BREAK \fB--\fR # n-dash .fi .RE .PP Breaking are recursive, so foo-bar, bar-foo and foo-foo\fB--\fRbar-bar would be valid compounds. Note: The default word break of Hunspell is equivalent of the following BREAK definition: .PP .RS .nf BREAK 3 BREAK - BREAK ^- BREAK -$ .fi .RE .PP Hunspell doesn't accept the "-word" and "word-" forms by this BREAK definition: .PP .RS .nf BREAK 1 BREAK - .fi .RE .PP Switching off the default values: .PP .RS .nf BREAK 0 .fi .RE .PP Note II: COMPOUNDRULE is better for handling dashes and other compound joining characters or character strings. Use BREAK, if you want to check words with dashes or other joining characters and there is no time or possibility to describe precise compound rules with COMPOUNDRULE (COMPOUNDRULE handles only the suffixation of the last word part of a compound word). Note III: For command line spell checking of words with extra characters, set WORDCHARS parameters: WORDCHARS -\fB--\fR (see tests/break.*) example .IP "COMPOUNDRULE number_of_compound_definitions" .IP "COMPOUNDRULE compound_pattern" Define custom compound patterns with a regex-like syntax. The first COMPOUNDRULE is a header with the number of the following COMPOUNDRULE definitions. Compound patterns consist compound flags, parentheses, star and question mark meta characters. A flag followed by a `*' matches a word sequence of 0 or more matches of words signed with this compound flag. A flag followed by a `?' matches a word sequence of 0 or 1 matches of a word signed with this compound flag. See tests/compound*.* examples. Note: en_US dictionary of OpenOffice.org uses COMPOUNDRULE for ordinal number recognition (1st, 2nd, 11th, 12th, 22nd, 112th, 1000122nd etc.). Note II: In the case of long and numerical flag types use only parenthesized flags: (1500)*(2000)? Note III: COMPOUNDRULE flags work completely separately from the compounding mechanisms using COMPOUNDFLAG, COMPOUNDBEGIN, etc. compound flags. (Use these flags on different entries for words). .IP "COMPOUNDMIN num" Minimum length of words used for compounding. Default value is 3 letters. .IP "COMPOUNDFLAG flag" Words signed with COMPOUNDFLAG may be in compound words (except when word shorter than COMPOUNDMIN). Affixes with COMPOUNDFLAG also permits compounding of affixed words. .IP "COMPOUNDBEGIN flag" Words signed with COMPOUNDBEGIN (or with a signed affix) may be first elements in compound words. .IP "COMPOUNDLAST flag" Words signed with COMPOUNDLAST (or with a signed affix) may be last elements in compound words. .IP "COMPOUNDMIDDLE flag" Words signed with COMPOUNDMIDDLE (or with a signed affix) may be middle elements in compound words. .IP "ONLYINCOMPOUND flag" Suffixes signed with ONLYINCOMPOUND flag may be only inside of compounds (Fuge-elements in German, fogemorphemes in Swedish). ONLYINCOMPOUND flag works also with words (see tests/onlyincompound.*). Note: also valuable to flag compounding parts which are not correct as a word by itself. .IP "COMPOUNDPERMITFLAG flag" Prefixes are allowed at the beginning of compounds, suffixes are allowed at the end of compounds by default. Affixes with COMPOUNDPERMITFLAG may be inside of compounds. .IP "COMPOUNDFORBIDFLAG flag" Suffixes with this flag forbid compounding of the affixed word. Dictionary words with this flag are removed from the beginning and middle of compound words, overriding the effect of COMPOUNDPERMITFLAG. .IP "COMPOUNDMORESUFFIXES" Allow twofold suffixes within compounds. .IP "COMPOUNDROOT flag" COMPOUNDROOT flag signs the compounds in the dictionary (Now it is used only in the Hungarian language specific code). .IP "COMPOUNDWORDMAX number" Set maximum word count in a compound word. (Default is unlimited.) .IP "CHECKCOMPOUNDDUP" Forbid word duplication in compounds (e.g. foofoo). .IP "CHECKCOMPOUNDREP" Forbid compounding, if the (usually bad) compound word may be a non-compound word with a REP fault. Useful for languages with `compound friendly' orthography. .IP "CHECKCOMPOUNDCASE" Forbid upper case characters at word boundaries in compounds. .IP "CHECKCOMPOUNDTRIPLE" Forbid compounding, if compound word contains triple repeating letters (e.g. foo|ox or xo|oof). Bug: missing multi-byte character support in UTF-8 encoding (works only for 7-bit ASCII characters). .IP "SIMPLIFIEDTRIPLE" Allow simplified 2-letter forms of the compounds forbidden by CHECKCOMPOUNDTRIPLE. It's useful for Swedish and Norwegian (and for the old German orthography: Schiff|fahrt -> Schiffahrt). .IP "CHECKCOMPOUNDPATTERN number_of_checkcompoundpattern_definitions" .IP "CHECKCOMPOUNDPATTERN endchars[/flag] beginchars[/flag] [replacement]" Forbid compounding, if the first word in the compound ends with endchars, and next word begins with beginchars and (optionally) they have the requested flags. The optional replacement parameter allows simplified compound form. The special "endchars" pattern 0 (zero) limits the rule to the unmodified stems (stems and stems with zero affixes): .PP .RS .nf CHECKCOMPOUNDPATTERN 0/x /y .fi .RE .PP Note: COMPOUNDMIN doesn't work correctly with the compound word alternation, so it may need to set COMPOUNDMIN to lower value. .IP "FORCEUCASE flag" Last word part of a compound with flag FORCEUCASE forces capitalization of the whole compound word. Eg. Dutch word "straat" (street) with FORCEUCASE flags will allowed only in capitalized compound forms, according to the Dutch spelling rules for proper names. .IP "COMPOUNDSYLLABLE max_syllable vowels" Need for special compounding rules in Hungarian. First parameter is the maximum syllable number, that may be in a compound, if words in compounds are more than COMPOUNDWORDMAX. Second parameter is the list of vowels (for calculating syllables). .IP "SYLLABLENUM flags" Need for special compounding rules in Hungarian. .SH "AFFIX FILE OPTIONS FOR AFFIX CREATION" .IP "PFX flag cross_product number" .IP "PFX flag stripping prefix [condition [morphological_fields...]]" .IP "SFX flag cross_product number" .IP "SFX flag stripping suffix [condition [morphological_fields...]]" An affix is either a prefix or a suffix attached to root words to make other words. We can define affix classes with arbitrary number affix rules. Affix classes are signed with affix flags. The first line of an affix class definition is the header. The fields of an affix class header: (0) Option name (PFX or SFX) (1) Flag (name of the affix class) (2) Cross product (permission to combine prefixes and suffixes). Possible values: Y (yes) or N (no) (3) Line count of the following rules. Fields of an affix rules: (0) Option name (1) Flag (2) stripping characters from beginning (at prefix rules) or end (at suffix rules) of the word (3) affix (optionally with flags of continuation classes, separated by a slash) (4) condition. Zero stripping or affix are indicated by zero. Zero condition is indicated by dot. Condition is a simplified, regular expression-like pattern, which must be met before the affix can be applied. (Dot signs an arbitrary character. Characters in braces sign an arbitrary character from the character subset. Dash hasn't got special meaning, but circumflex (^) next the first brace sets the complementer character set.) (5) Optional morphological fields separated by spaces or tabulators. .SH "AFFIX FILE OTHER OPTIONS" .IP "CIRCUMFIX flag" Affixes signed with CIRCUMFIX flag may be on a word when this word also has a prefix with CIRCUMFIX flag and vice versa (see circumfix.* test files in the source distribution). .IP "FORBIDDENWORD flag" This flag signs forbidden word form. Because affixed forms are also forbidden, we can subtract a subset from set of the accepted affixed and compound words. Note: usefull to forbid erroneous words, generated by the compounding mechanism. .IP "FULLSTRIP" With FULLSTRIP, affix rules can strip full words, not only one less characters, before adding the affixes, see fullstrip.* test files in the source distribution). Note: conditions may be word length without FULLSTRIP, too. .IP "KEEPCASE flag" Forbid uppercased and capitalized forms of words signed with KEEPCASE flags. Useful for special orthographies (measurements and currency often keep their case in uppercased texts) and writing systems (e.g. keeping lower case of IPA characters). Also valuable for words erroneously written in the wrong case. Note: With CHECKSHARPS declaration, words with sharp s and KEEPCASE flag may be capitalized and uppercased, but uppercased forms of these words may not contain sharp s, only SS. See germancompounding example in the tests directory of the Hunspell distribution. .IP "ICONV number_of_ICONV_definitions" .IP "ICONV pattern pattern2" Define input conversion table. Note: useful to convert one type of quote to another one, or change ligature. .IP "OCONV number_of_OCONV_definitions" .IP "OCONV pattern pattern2" Define output conversion table. .IP "LEMMA_PRESENT flag" Deprecated. Use "st:" field instead of LEMMA_PRESENT. .IP "NEEDAFFIX flag" This flag signs virtual stems in the dictionary, words only valid when affixed. Except, if the dictionary word has a homonym or a zero affix. NEEDAFFIX works also with prefixes and prefix + suffix combinations (see tests/needaffix5.*). .IP "PSEUDOROOT flag" Deprecated. (Former name of the NEEDAFFIX option.) .IP "SUBSTANDARD flag" SUBSTANDARD flag signs affix rules and dictionary words (allomorphs) not used in morphological generation and root words removed from suggestion. See also NOSUGGEST. .IP "WORDCHARS characters" WORDCHARS extends tokenizer of Hunspell command line interface with additional word character. For example, dot, dash, n-dash, numbers, percent sign are word character in Hungarian. .IP "CHECKSHARPS" SS letter pair in uppercased (German) words may be upper case sharp s (ß). Hunspell can handle this special casing with the CHECKSHARPS declaration (see also KEEPCASE flag and tests/germancompounding example) in both spelling and suggestion. .SH "Morphological analysis" Hunspell's dictionary items and affix rules may have optional space or tabulator separated morphological description fields, started with 3-character (two letters and a colon) field IDs: .PP .RS .nf word/flags po:noun is:nom .fi .RE .PP Example: We define a simple resource with morphological informations, a derivative suffix (ds:) and a part of speech category (po:): Affix file: .PP .RS .nf SFX X Y 1 SFX X 0 able . ds:able .fi .RE .PP Dictionary file: .PP .RS .nf drink/X po:verb .fi .RE .PP Test file: .PP .RS .nf drink drinkable .fi .RE .PP Test: .PP .RS .nf $ analyze test.aff test.dic test.txt > drink analyze(drink) = po:verb stem(drink) = po:verb > drinkable analyze(drinkable) = po:verb ds:able stem(drinkable) = drinkable .fi .RE .PP You can see in the example, that the analyzer concatenates the morphological fields in \fIitem and arrangement\fR style. .SH "Optional data fields" Default morphological and other IDs (used in suggestion, stemming and morphological generation): .IP "ph:" Alternative transliteration for better suggestions, ie. misspellings related to the special orthography and pronunciation of the word. The best way to handle common misspellings, so it's worth to add ph: field to the most affected few thousand dictionary words (or word pairs etc.) to get correct suggestions for their misspellings. For example: .PP .RS .nf Wednesday ph:wendsay ph:wensday Marseille ph:maarsayl .fi .RE .PP Hunspell adds all ph: transliterations to the inner REP table, so it will always suggest the correct word for the specified misspellings with the highest priority. The previous example is equivalent of the following REP definition: .PP .RS .nf REP 6 REP wendsay Wednesday REP Wendsay Wednesday REP wensday Wednesday REP Wensday Wednesday REP maarsayl Marseille REP Maarsayl Marseille .fi .RE .PP The asterisk at the end of the ph: pattern means stripping the terminating character both from the pattern and the word in the associated REP rule: .PP .RS .nf pretty ph:prity* .fi .RE .PP will result .PP .RS .nf REP 1 REP prit prett .fi .RE .PP REP rule, resulting the following correct suggestions .PP .RS .nf *prity -> pretty *pritier -> prettier *pritiest -> prettiest .fi .RE .PP Moreover, ph: fields can handle suggestions with more than two words, also different suggestions for the same misspelling: .PP .RS .nf do not know ph:dunno don't know ph:dunno .fi .RE .PP results .PP .RS .nf *dunno -> do not know, don't know .fi .RE .PP Note: if available, ph: is used in n-gram similarity, too. The ASCII arrow "->" in a ph: pattern means a REP rule (see REP), creating arbitrary replacement rule associated to the dictionary item: .PP .RS .nf happy/B ph:hepy ph:hepi->happi .fi .RE .PP results .PP .RS .nf *hepy -> happy *hepiest -> happiest .fi .RE .PP .IP "st:" Stem. Optional: default stem is the dictionary item in morphological analysis. Stem field is useful for virtual stems (dictionary words with NEEDAFFIX flag) and morphological exceptions instead of new, single used morphological rules. .PP .RS .nf feet st:foot is:plural mice st:mouse is:plural teeth st:tooth is:plural .fi .RE .PP Word forms with multiple stems need multiple dictionary items: .PP .RS .nf lay po:verb st:lie is:past_2 lay po:verb is:present lay po:noun .fi .RE .PP .IP "al:" Allomorph(s). A dictionary item is the stem of its allomorphs. Morphological generation needs stem, allomorph and affix fields. .PP .RS .nf sing al:sang al:sung sang st:sing sung st:sing .fi .RE .PP .IP "po:" Part of speech category. .IP "ds:" Derivational suffix(es). Stemming doesn't remove derivational suffixes. Morphological generation depends on the order of the suffix fields. In affix rules: .PP .RS .nf SFX Y Y 1 SFX Y 0 ly . ds:ly_adj .fi .RE .PP In the dictionary: .PP .RS .nf ably st:able ds:ly_adj able al:ably .fi .RE .PP .IP "is:" Inflectional suffix(es). All inflectional suffixes are removed by stemming. Morphological generation depends on the order of the suffix fields. .PP .RS .nf feet st:foot is:plural .fi .RE .PP .IP "ts:" Terminal suffix(es). Terminal suffix fields are inflectional suffix fields "removed" by additional (not terminal) suffixes. Useful for zero morphemes and affixes removed by splitting rules. .PP .RS .nf work/D ts:present .fi .RE .PP .PP .RS .nf SFX D Y 2 SFX D 0 ed . is:past_1 SFX D 0 ed . is:past_2 .fi .RE .PP Typical example of the terminal suffix is the zero morpheme of the nominative case. .IP "sp:" Surface prefix. Temporary solution for adding prefixes to the stems and generated word forms. See tests/morph.* example. .IP "pa:" Parts of the compound words. Output fields of morphological analysis for stemming. .IP "dp:" Planned: derivational prefix. .IP "ip:" Planned: inflectional prefix. .IP "tp:" Planned: terminal prefix. .SH "Twofold suffix stripping" Ispell's original algorithm strips only one suffix. Hunspell can strip another one yet (or a plus prefix in COMPLEXPREFIXES mode). The twofold suffix stripping is a significant improvement in handling of immense number of suffixes, that characterize agglutinative languages. A second `s' suffix (affix class Y) will be the continuation class of the suffix `able' in the following example: .PP .RS .nf SFX Y Y 1 SFX Y 0 s . SFX X Y 1 SFX X 0 able/Y . .fi .RE .PP Dictionary file: .PP .RS .nf drink/X .fi .RE .PP Test file: .PP .RS .nf drink drinkable drinkables .fi .RE .PP Test: .PP .RS .nf $ hunspell -m -d test drink drink[verb] drink[noun] > drinks drink[verb]+3SGV drink[noun]+PL > drinkable drink[verb]+DER_V_ADJ_ABLE > drinkables drink[verb]+DER_V_ADJ_ABLE+PL > undrinkable [prefix_un]+drink[verb]+DER_V_ADJ_ABLE > undrinkables [prefix_un]+drink[verb]+DER_V_ADJ_ABLE+PL > undrink Unknown word. > undrinks Unknown word. .fi .RE .PP .SH "Circumfix" Conditional affixes implemented by a continuation class are not enough for circumfixes, because a circumfix is one affix in morphology. We also need CIRCUMFIX option for correct morphological analysis. .PP .RS .nf # circumfixes: ~ obligate prefix/suffix combinations # superlative in Hungarian: leg- (prefix) AND -bb (suffix) # nagy, nagyobb, legnagyobb, legeslegnagyobb # (great, greater, greatest, most greatest) CIRCUMFIX X PFX A Y 1 PFX A 0 leg/X . PFX B Y 1 PFX B 0 legesleg/X . SFX C Y 3 SFX C 0 obb . +COMPARATIVE SFX C 0 obb/AX . +SUPERLATIVE SFX C 0 obb/BX . +SUPERSUPERLATIVE .fi .RE .PP Dictionary: .PP .RS .nf 1 nagy/C [MN] .fi .RE .PP Analysis: .PP .RS .nf > nagy nagy[MN] > nagyobb nagy[MN]+COMPARATIVE > legnagyobb nagy[MN]+SUPERLATIVE > legeslegnagyobb nagy[MN]+SUPERSUPERLATIVE .fi .RE .PP .SH "Compounds" Allowing free compounding yields decrease in precision of recognition, not to mention stemming and morphological analysis. Although lexical switches are introduced to license compounding of bases by \fBIspell\fR, this proves not to be restrictive enough. For example: .PP .RS .nf # affix file COMPOUNDFLAG X .fi .RE .PP .PP .RS .nf 2 foo/X bar/X .fi .RE .PP With this resource, \fIfoobar\fR and \fIbarfoo\fR also are accepted words. This has been improved upon with the introduction of direction-sensitive compounding, i.e., lexical features can specify separately whether a base can occur as leftmost or rightmost constituent in compounds. This, however, is still insufficient to handle the intricate patterns of compounding, not to mention idiosyncratic (and language specific) norms of hyphenation. The \fBHunspell\fR algorithm currently allows any affixed form of words, which are lexically marked as potential members of compounds. \fBHunspell\fR improved this, and its recursive compound checking rules makes it possible to implement the intricate spelling conventions of Hungarian compounds. For example, using COMPOUNDWORDMAX, COMPOUNDSYLLABLE, COMPOUNDROOT, SYLLABLENUM options can be set the noteworthy Hungarian `6-3' rule. Further example in Hungarian, derivate suffixes often modify compounding properties. Hunspell allows the compounding flags on the affixes, and there are two special flags (COMPOUNDPERMITFLAG and (COMPOUNDFORBIDFLAG) to permit or prohibit compounding of the derivations. Suffixes with this flag forbid compounding of the affixed word. We also need several Hunspell features for handling German compounding: .PP .RS .nf # German compounding # set language to handle special casing of German sharp s LANG de_DE # compound flags COMPOUNDBEGIN U COMPOUNDMIDDLE V COMPOUNDEND W # Prefixes are allowed at the beginning of compounds, # suffixes are allowed at the end of compounds by default: # (prefix)?(root)+(affix)? # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. COMPOUNDPERMITFLAG P # for German fogemorphemes (Fuge-element) # Hint: ONLYINCOMPOUND is not required everywhere, but the # checking will be a little faster with it. ONLYINCOMPOUND X # forbid uppercase characters at compound word bounds CHECKCOMPOUNDCASE # for handling Fuge-elements with dashes (Arbeits-) # dash will be a special word COMPOUNDMIN 1 WORDCHARS - # compound settings and fogemorpheme for `Arbeit' SFX A Y 3 SFX A 0 s/UPX . SFX A 0 s/VPDX . SFX A 0 0/WXD . SFX B Y 2 SFX B 0 0/UPX . SFX B 0 0/VWXDP . # a suffix for `Computer' SFX C Y 1 SFX C 0 n/WD . # for forbid exceptions (*Arbeitsnehmer) FORBIDDENWORD Z # dash prefix for compounds with dash (Arbeits-Computer) PFX - Y 1 PFX - 0 -/P . # decapitalizing prefix # circumfix for positioning in compounds PFX D Y 29 PFX D A a/PX A PFX D Ä ä/PX Ä . . PFX D Y y/PX Y PFX D Z z/PX Z .fi .RE .PP Example dictionary: .PP .RS .nf 4 Arbeit/A- Computer/BC- -/W Arbeitsnehmer/Z .fi .RE .PP Accepted compound compound words with the previous resource: .PP .RS .nf Computer Computern Arbeit Arbeits- Computerarbeit Computerarbeits- Arbeitscomputer Arbeitscomputern Computerarbeitscomputer Computerarbeitscomputern Arbeitscomputerarbeit Computerarbeits-Computer Computerarbeits-Computern .fi .RE .PP Not accepted compoundings: .PP .RS .nf computer arbeit Arbeits arbeits ComputerArbeit ComputerArbeits Arbeitcomputer ArbeitsComputer Computerarbeitcomputer ComputerArbeitcomputer ComputerArbeitscomputer Arbeitscomputerarbeits Computerarbeits-computer Arbeitsnehmer .fi .RE .PP This solution is still not ideal, however, and will be replaced by a pattern-based compound-checking algorithm which is closely integrated with input buffer tokenization. Patterns describing compounds come as a separate input resource that can refer to high-level properties of constituent parts (e.g. the number of syllables, affix flags, and containment of hyphens). The patterns are matched against potential segmentations of compounds to assess wellformedness. .SH "Unicode character encoding" Both \fBIspell\fR and \fBMyspell\fR use 8-bit ASCII character encoding, which is a major deficiency when it comes to scalability. Although a language like Hungarian has a standard ASCII character set (ISO 8859-2), it fails to allow a full implementation of Hungarian orthographic conventions. For instance, the '--' symbol (n-dash) is missing from this character set contrary to the fact that it is not only the official symbol to delimit parenthetic clauses in the language, but it can be in compound words as a special 'big' hyphen. MySpell has got some 8-bit encoding tables, but there are languages without standard 8-bit encoding, too. For example, a lot of African languages have non-latin or extended latin characters. Similarly, using the original spelling of certain foreign names like \fIÅngström\fR or \fIMolière\fR is encouraged by the Hungarian spelling norm, and, since characters 'Å' and 'è' are not part of ISO\ 8859-2, when they combine with inflections containing characters only in ISO\ 8859-2 (like elative \fI-ből\fR, allative \fI-től\fR or delative \fI-ről\fR with double acute), these result in words (like \fIÅngströmről\fR or \fIMolière-től.\fR) that can not be encoded using any single ASCII encoding scheme. The problems raised in relation to 8-bit ASCII encoding have long been recognized by proponents of Unicode. It is clear that trading efficiency for encoding-independence has its advantages when it comes a truly multi-lingual application. There is implemented a memory and time efficient Unicode handling in Hunspell. In non-UTF-8 character encodings Hunspell works with the original 8-bit strings. In UTF-8 encoding, affixes and words are stored in UTF-8, during the analysis are handled in mostly UTF-8, under condition checking and suggestion are converted to UTF-16. Unicode text analysis and spell checking have a minimal (0-20%) time overhead and minimal or reasonable memory overhead depends from the language (its UTF-8 encoding and affixation). .SH "Conversion of aspell dictionaries" Aspell dictionaries can be easily converted into hunspell. Conversion steps: \fBdictionary (xx.cwl -> xx.wl):\fR .nf preunzip xx.cwl wc -l < xx.wl > xx.dic cat xx.wl >> xx.dic .fi \fBaffix file\fR If the affix file exists, copy it: .nf cp xx_affix.dat xx.aff .fi If not, create it with the suitable character encoding (see xx.dat) .nf echo "SET ISO8859-x" > xx.aff .fi or .nf echo "SET UTF-8" > xx.aff .fi It's useful to add a TRY option with the characters of the dictionary with frequency order to set edit distance suggestions: .nf echo "TRY qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM" >>xx.aff .fi .SH "SEE ALSO" .B hunspell (1), .B ispell (1), .B ispell (4) hunspell-1.7.0/man/hunzip.1000066400000000000000000000011741337236234000155310ustar00rootroot00000000000000.TH hzip 1 "2008-06-12" .LO 1 .SH NAME hunzip \- decompress and decrypt hzip files to the standard output .SH SYNOPSIS hunzip [\-h] file.hz [password] .SH DESCRIPTION .I Hunzip is the decompression and decryption program of hzip format. .SH OPTIONS .IP \fB\-h\fR Display short help description. .SH EXAMPLE .sp .BI "hunzip file.hz >file" .SH NOTES Redirection of the standard output results platform-specific line terminating, so a compressed hzip file with new line terminators would be bigger with the extra CR characters of the decompression on Windows platforms. .SH SEE ALSO .B hunzip (1), hunspell(1) .SH AUTHOR László Németh. hunspell-1.7.0/man/hzip.1000066400000000000000000000013221337236234000151610ustar00rootroot00000000000000.TH hunzip 1 "2008-06-12" .LO 1 .SH NAME hunzip \- compress and encrypt dictionary files .SH SYNOPSIS hzip [\-h] [\-P password] [file(s)] .SH DESCRIPTION .I hunzip is a small utility for text file compression and encryption, especially for sorted dictionaries. "hunspell filename" creates the compressed file "filename.hz" without removing the original file. The compression algorithm uses 16-bit Huffman encoding and line-oriented prefix-suffix compression. It has good compression ratio for huge sorted word lists. .SH OPTIONS .IP \fB\-h\fR Display short help description. .IP \fB\-P\ password\fR Encrypted compression by an arbitrary length password. .SH SEE ALSO .B hzip (1), hunspell(1) .SH AUTHOR László Németh. hunspell-1.7.0/msvc/000077500000000000000000000000001337236234000143245ustar00rootroot00000000000000hunspell-1.7.0/msvc/.gitignore000066400000000000000000000001361337236234000163140ustar00rootroot00000000000000Makefile /Debug/ /Release/ /Backup*/ /x64/ /*.db /*.user *.sdf *.opensdf *.suo UpgradeLog.htm hunspell-1.7.0/msvc/Hunspell.rc000066400000000000000000000015271337236234000164510ustar00rootroot00000000000000 #include VS_VERSION_INFO VERSIONINFO FILEVERSION 1,7,0,0 PRODUCTVERSION 1,7,0,0 FILEFLAGSMASK 0x17L FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "Hunspell (http://hunspell.github.io/) by Lszl Nmeth" VALUE "CompanyName", "http://hunspell.github.io/" VALUE "FileDescription", "libhunspell" VALUE "FileVersion", "1.7.0" VALUE "InternalName", "libhunspell" VALUE "LegalCopyright", "Copyright (c) 2007-2018" VALUE "OriginalFilename", "libhunspell.dll" VALUE "ProductName", "Hunspell Dynamic Link Library" VALUE "ProductVersion", "1.7.0" END END END hunspell-1.7.0/msvc/Hunspell.sln000066400000000000000000000114171337236234000166400ustar00rootroot00000000000000 Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhunspell", "libhunspell.vcxproj", "{53609BB3-D874-465C-AF7B-DF626DB0D89B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testparser", "testparser.vcxproj", "{611BF6C7-332A-49BB-B2A3-80AFD5B785D9}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hunspell", "hunspell.vcxproj", "{6A0453F4-B12A-4810-B9A2-8AB059316ED7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_dll|Win32 = Debug_dll|Win32 Debug_dll|x64 = Debug_dll|x64 Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release_dll|Win32 = Release_dll|Win32 Release_dll|x64 = Release_dll|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug_dll|Win32.ActiveCfg = Debug_dll|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug_dll|Win32.Build.0 = Debug_dll|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug_dll|x64.ActiveCfg = Debug_dll|x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug_dll|x64.Build.0 = Debug_dll|x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug|Win32.ActiveCfg = Debug|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug|Win32.Build.0 = Debug|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug|x64.ActiveCfg = Debug|x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Debug|x64.Build.0 = Debug|x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release_dll|Win32.ActiveCfg = Release_dll|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release_dll|Win32.Build.0 = Release_dll|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release_dll|x64.ActiveCfg = Release_dll|x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release_dll|x64.Build.0 = Release_dll|x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release|Win32.ActiveCfg = Release|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release|Win32.Build.0 = Release|Win32 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release|x64.ActiveCfg = Release|x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B}.Release|x64.Build.0 = Release|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug_dll|Win32.ActiveCfg = Debug|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug_dll|Win32.Build.0 = Debug|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug_dll|x64.ActiveCfg = Debug|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug_dll|x64.Build.0 = Debug|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug|Win32.ActiveCfg = Debug|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug|Win32.Build.0 = Debug|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug|x64.ActiveCfg = Debug|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Debug|x64.Build.0 = Debug|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release_dll|Win32.ActiveCfg = Release|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release_dll|Win32.Build.0 = Release|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release_dll|x64.ActiveCfg = Release|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release_dll|x64.Build.0 = Release|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release|Win32.ActiveCfg = Release|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release|Win32.Build.0 = Release|Win32 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release|x64.ActiveCfg = Release|x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9}.Release|x64.Build.0 = Release|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug_dll|Win32.ActiveCfg = Debug|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug_dll|Win32.Build.0 = Debug|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug_dll|x64.ActiveCfg = Debug|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug_dll|x64.Build.0 = Debug|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug|Win32.ActiveCfg = Debug|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug|Win32.Build.0 = Debug|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug|x64.ActiveCfg = Debug|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Debug|x64.Build.0 = Debug|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release_dll|Win32.ActiveCfg = Release|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release_dll|Win32.Build.0 = Release|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release_dll|x64.ActiveCfg = Release|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release_dll|x64.Build.0 = Release|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release|Win32.ActiveCfg = Release|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release|Win32.Build.0 = Release|Win32 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release|x64.ActiveCfg = Release|x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal hunspell-1.7.0/msvc/config.h000066400000000000000000000130521337236234000157430ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #define CRAY_STACKSEG_END 1 /* Define to 1 if using `alloca.c'. */ #define C_ALLOCA 1 /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #define HAVE_ALLOCA_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARGZ_H 1 /* "Define if you have the header" */ #undef HAVE_CURSES_H /* Define if the GNU dcgettext() function is already present or preinstalled. */ #define HAVE_DCGETTEXT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERROR_H 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `feof_unlocked' function. */ #define HAVE_FEOF_UNLOCKED 1 /* Define to 1 if you have the `fgets_unlocked' function. */ #define HAVE_FGETS_UNLOCKED 1 /* Define to 1 if you have the `getcwd' function. */ #define HAVE_GETCWD 1 /* Define to 1 if you have the `getc_unlocked' function. */ #define HAVE_GETC_UNLOCKED 1 /* Define to 1 if you have the `getegid' function. */ #define HAVE_GETEGID 1 /* Define to 1 if you have the `geteuid' function. */ #define HAVE_GETEUID 1 /* Define to 1 if you have the `getgid' function. */ #define HAVE_GETGID 1 /* Define to 1 if you have the `getpagesize' function. */ #define HAVE_GETPAGESIZE 1 /* Define if the GNU gettext() function is already present or preinstalled. */ #define HAVE_GETTEXT 1 /* Define to 1 if you have the `getuid' function. */ #define HAVE_GETUID 1 /* Define if you have the iconv() function. */ #undef HAVE_ICONV /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define if you have and nl_langinfo(CODESET). */ #define HAVE_LANGINFO_CODESET 1 /* Define if your file defines LC_MESSAGES. */ #define HAVE_LC_MESSAGES 1 /* Define to 1 if you have the header file. */ #define HAVE_LIBINTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_LOCALE_H 1 /* Define to 1 if you have the `memchr' function. */ #define HAVE_MEMCHR 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `mempcpy' function. */ #define HAVE_MEMPCPY 1 /* Define to 1 if you have a working `mmap' system call. */ #define HAVE_MMAP 1 /* Define to 1 if you have the `munmap' function. */ #define HAVE_MUNMAP 1 /* "Define if you have the header" */ #define HAVE_NCURSESW_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NL_TYPES_H 1 /* Define to 1 if you have the `putenv' function. */ #define HAVE_PUTENV 1 /* "Define if you have fancy command input editing with Readline" */ #undef HAVE_READLINE /* Define to 1 if you have the `setenv' function. */ #define HAVE_SETENV 1 /* Define to 1 if you have the `setlocale' function. */ #define HAVE_SETLOCALE 1 /* Define to 1 if you have the header file. */ #define HAVE_STDDEF_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `stpcpy' function. */ #define HAVE_STPCPY 1 /* Define to 1 if you have the `strcasecmp' function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the `strchr' function. */ #define HAVE_STRCHR 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strstr' function. */ #define HAVE_STRSTR 1 /* Define to 1 if you have the `strtoul' function. */ #define HAVE_STRTOUL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the `tsearch' function. */ #define HAVE_TSEARCH 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the `__argz_count' function. */ #define HAVE___ARGZ_COUNT 1 /* Define to 1 if you have the `__argz_next' function. */ #define HAVE___ARGZ_NEXT 1 /* Define to 1 if you have the `__argz_stringify' function. */ #define HAVE___ARGZ_STRINGIFY 1 /* "Define if you need warning messages" */ #define HUNSPELL_WARNING_ON /* Define as const if the declaration of iconv() needs const. */ #define ICONV_CONST 1 /* Name of package */ #define PACKAGE /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT /* Define to the full name of this package. */ #define PACKAGE_NAME /* Define to the full name and version of this package. */ #define PACKAGE_STRING /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.0" #define VERSION "1.7.0" hunspell-1.7.0/msvc/hunspell.vcxproj000066400000000000000000000251201337236234000175730ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {6A0453F4-B12A-4810-B9A2-8AB059316ED7} hunspell Win32Proj 8.1 Application v140_xp MultiByte true Application v140_xp MultiByte true Application v140_xp MultiByte Application v140_xp MultiByte <_ProjectFileVersion>14.0.25420.1 $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Platform)\$(Configuration)\$(ProjectName)\ true true $(Platform)\$(Configuration)\$(ProjectName)\ $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Configuration)\$(ProjectName)\ false false $(Platform)\$(Configuration)\$(ProjectName)\ Disabled ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;_DEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL $(IntDir)$(ProjectName).pdb Level4 EditAndContinue 4127;4267;4706 true Console false MachineX86 Disabled ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;_DEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL Level4 ProgramDatabase $(IntDir)$(ProjectName).pdb 4127;4267;4706 true Console false Full AnySuitable ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;NDEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreadedDLL $(IntDir)$(ProjectName).pdb Level4 4127;4267;4706 true Console true true false MachineX86 Full AnySuitable ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;NDEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreadedDLL $(IntDir)$(ProjectName).pdb Level4 4127;4267;4706 true Console true true false {53609bb3-d874-465c-af7b-df626db0d89b} false hunspell-1.7.0/msvc/libhunspell.vcxproj000066400000000000000000000515101337236234000202640ustar00rootroot00000000000000 Debug_dll Win32 Debug_dll x64 Debug Win32 Debug x64 Release_dll Win32 Release_dll x64 Release Win32 Release x64 {53609BB3-D874-465C-AF7B-DF626DB0D89B} Hunspell Win32Proj 8.1 DynamicLibrary v140_xp false MultiByte DynamicLibrary v140_xp false MultiByte DynamicLibrary v140_xp false MultiByte true DynamicLibrary v140_xp false MultiByte true StaticLibrary v140_xp false MultiByte true StaticLibrary v140_xp false MultiByte true StaticLibrary v140_xp false MultiByte StaticLibrary v140_xp false MultiByte <_ProjectFileVersion>14.0.25420.1 $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Configuration)\$(ProjectName)\ $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Configuration)\$(ProjectName)\ $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Configuration)\$(ProjectName)\ $(Platform)\$(Configuration)\$(ProjectName)\ $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Configuration)\$(ProjectName)\ true true $(Platform)\$(Configuration)\$(ProjectName)\ $(Platform)\$(Configuration)\$(ProjectName)\ $(Platform)\$(Configuration)\$(ProjectName)\ echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Disabled ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDebugDLL $(IntDir)$(ProjectName).pdb Level4 EditAndContinue 4706;4251;4267 /MACHINE:X86 %(AdditionalOptions) echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Disabled ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDebugDLL Level4 ProgramDatabase 4706;4251;4267 echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Full AnySuitable ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreadedDLL true $(IntDir)$(ProjectName).pdb Level4 4706;4251;4267 NDEBUG;%(PreprocessorDefinitions) 0x0409 false echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Full AnySuitable ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreadedDLL true $(IntDir)$(ProjectName).pdb Level4 4706;4251;4267 NDEBUG;%(PreprocessorDefinitions) 0x0409 false echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Full AnySuitable ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;BUILDING_LIBHUNSPELL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) true MultiThreadedDLL true $(IntDir)$(ProjectName).pdb Level4 4706;4251;4267 NDEBUG;%(PreprocessorDefinitions) 0x0409 false Windows true true false echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Full AnySuitable ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_WINDOWS;_USRDLL;BUILDING_LIBHUNSPELL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) true MultiThreadedDLL true $(IntDir)$(ProjectName).pdb Level4 4706;4251;4267 NDEBUG;%(PreprocessorDefinitions) 0x0409 false true true false Windows echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Disabled ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;BUILDING_LIBHUNSPELL;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDebugDLL $(IntDir)$(ProjectName).pdb Level4 EditAndContinue 4706;4251;4267 true Windows false MachineX86 echo N | copy /-Y ..\src\hunspell\hunvisapi.h.in ..\src\hunspell\hunvisapi.h Disabled ..\src\hunspell;.;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;BUILDING_LIBHUNSPELL;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDebugDLL $(IntDir)$(ProjectName).pdb Level4 ProgramDatabase 4706;4251;4267 true Windows false hunspell-1.7.0/msvc/testparser.vcxproj000066400000000000000000000250411337236234000201370ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {611BF6C7-332A-49BB-B2A3-80AFD5B785D9} testparser Win32Proj 8.1 Application v140_xp MultiByte true Application v140_xp MultiByte true Application v140_xp MultiByte Application v140_xp MultiByte <_ProjectFileVersion>14.0.25420.1 $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Configuration)\$(ProjectName)\ true true $(Platform)\$(Configuration)\$(ProjectName)\ $(SolutionDir)$(Configuration)\$(ProjectName)\ $(Configuration)\$(ProjectName)\ false false $(Platform)\$(Configuration)\$(ProjectName)\ Disabled ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;_DEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL $(IntDir)$(ProjectName).pdb Level4 EditAndContinue 4706 true Console false MachineX86 Disabled ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;_DEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL Level4 ProgramDatabase $(IntDir)$(ProjectName).pdb 4706 true Console false Full AnySuitable ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;NDEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreadedDLL $(IntDir)$(ProjectName).pdb Level4 4706 true Console true true false MachineX86 Full AnySuitable ..\src\hunspell;..\src\parsers;.;%(AdditionalIncludeDirectories) W32;WIN32;NDEBUG;_CONSOLE;HUNSPELL_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreadedDLL $(IntDir)$(ProjectName).pdb Level4 4706 true Console true true false {53609bb3-d874-465c-af7b-df626db0d89b} false hunspell-1.7.0/po/000077500000000000000000000000001337236234000137725ustar00rootroot00000000000000hunspell-1.7.0/po/.gitignore000066400000000000000000000000431337236234000157570ustar00rootroot00000000000000POTFILES remove-potcdate.sed *.gmo hunspell-1.7.0/po/ChangeLog000066400000000000000000000003061337236234000155430ustar00rootroot000000000000002017-10-22 gettextize * Makefile.in.in: Upgrade to gettext-0.19.8.1. 2016-11-02 gettextize * Makefile.in.in: Upgrade to gettext-0.19.7. hunspell-1.7.0/po/LINGUAS000066400000000000000000000000711337236234000150150ustar00rootroot00000000000000# Set of available languages. ca de es hu it pl pt_BR tg hunspell-1.7.0/po/Makefile.in.in000066400000000000000000000422511337236234000164500ustar00rootroot00000000000000# Makefile for PO directory in any package using GNU gettext. # Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without any warranty. # # Origin: gettext-0.19.8 GETTEXT_MACRO_VERSION = 0.19 PACKAGE = @PACKAGE@ VERSION = @VERSION@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ SED = @SED@ SHELL = /bin/sh @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir = @datarootdir@ datadir = @datadir@ localedir = @localedir@ gettextsrcdir = $(datadir)/gettext/po INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ # We use $(mkdir_p). # In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as # "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, # @install_sh@ does not start with $(SHELL), so we add it. # In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined # either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake # versions, $(mkinstalldirs) and $(install_sh) are unused. mkinstalldirs = $(SHELL) @install_sh@ -d install_sh = $(SHELL) @install_sh@ MKDIR_P = @MKDIR_P@ mkdir_p = @mkdir_p@ # When building gettext-tools, we prefer to use the built programs # rather than installed programs. However, we can't do that when we # are cross compiling. CROSS_COMPILING = @CROSS_COMPILING@ GMSGFMT_ = @GMSGFMT@ GMSGFMT_no = @GMSGFMT@ GMSGFMT_yes = @GMSGFMT_015@ GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) MSGFMT_ = @MSGFMT@ MSGFMT_no = @MSGFMT@ MSGFMT_yes = @MSGFMT_015@ MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) XGETTEXT_ = @XGETTEXT@ XGETTEXT_no = @XGETTEXT@ XGETTEXT_yes = @XGETTEXT_015@ XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) MSGMERGE = msgmerge MSGMERGE_UPDATE = @MSGMERGE@ --update MSGINIT = msginit MSGCONV = msgconv MSGFILTER = msgfilter POFILES = @POFILES@ GMOFILES = @GMOFILES@ UPDATEPOFILES = @UPDATEPOFILES@ DUMMYPOFILES = @DUMMYPOFILES@ DISTFILES.common = Makefile.in.in remove-potcdate.sin \ $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ $(POFILES) $(GMOFILES) \ $(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) POTFILES = \ CATALOGS = @CATALOGS@ POFILESDEPS_ = $(srcdir)/$(DOMAIN).pot POFILESDEPS_yes = $(POFILESDEPS_) POFILESDEPS_no = POFILESDEPS = $(POFILESDEPS_$(PO_DEPENDS_ON_POT)) DISTFILESDEPS_ = update-po DISTFILESDEPS_yes = $(DISTFILESDEPS_) DISTFILESDEPS_no = DISTFILESDEPS = $(DISTFILESDEPS_$(DIST_DEPENDS_ON_UPDATE_PO)) # Makevars gets inserted here. (Don't remove this line!) .SUFFIXES: .SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update .po.mo: @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ .po.gmo: @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo .sin.sed: sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all: all-@USE_NLS@ all-yes: stamp-po all-no: # Ensure that the gettext macros and this Makefile.in.in are in sync. CHECK_MACRO_VERSION = \ test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ exit 1; \ } # $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no # internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because # we don't want to bother translators with empty POT files). We assume that # LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. # In this case, stamp-po is a nop (i.e. a phony target). # stamp-po is a timestamp denoting the last time at which the CATALOGS have # been loosely updated. Its purpose is that when a developer or translator # checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, # "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent # invocations of "make" will do nothing. This timestamp would not be necessary # if updating the $(CATALOGS) would always touch them; however, the rule for # $(POFILES) has been designed to not touch files that don't need to be # changed. stamp-po: $(srcdir)/$(DOMAIN).pot @$(CHECK_MACRO_VERSION) test ! -f $(srcdir)/$(DOMAIN).pot || \ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) @test ! -f $(srcdir)/$(DOMAIN).pot || { \ echo "touch stamp-po" && \ echo timestamp > stamp-poT && \ mv stamp-poT stamp-po; \ } # Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', # otherwise packages like GCC can not be built if only parts of the source # have been downloaded. # This target rebuilds $(DOMAIN).pot; it is an expensive operation. # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. # The determination of whether the package xyz is a GNU one is based on the # heuristic whether some file in the top level directory mentions "GNU xyz". # If GNU 'find' is available, we avoid grepping through monster files. $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed package_gnu="$(PACKAGE_GNU)"; \ test -n "$$package_gnu" || { \ if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f \ -size -10000000c -exec grep 'GNU @PACKAGE@' \ /dev/null '{}' ';' 2>/dev/null; \ else \ LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \ fi; \ } | grep -v 'libtool:' >/dev/null; then \ package_gnu=yes; \ else \ package_gnu=no; \ fi; \ }; \ if test "$$package_gnu" = "yes"; then \ package_prefix='GNU '; \ else \ package_prefix=''; \ fi; \ if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ else \ msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ fi; \ case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ --files-from=$(srcdir)/POTFILES.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --msgid-bugs-address="$$msgid_bugs_address" \ ;; \ *) \ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ --files-from=$(srcdir)/POTFILES.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --package-name="$${package_prefix}@PACKAGE@" \ --package-version='@VERSION@' \ --msgid-bugs-address="$$msgid_bugs_address" \ ;; \ esac test ! -f $(DOMAIN).po || { \ if test -f $(srcdir)/$(DOMAIN).pot-header; then \ sed -e '1,/^#$$/d' < $(DOMAIN).po > $(DOMAIN).1po && \ cat $(srcdir)/$(DOMAIN).pot-header $(DOMAIN).1po > $(DOMAIN).po; \ rm -f $(DOMAIN).1po; \ fi; \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ else \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ else \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ } # This rule has no dependencies: we don't need to update $(DOMAIN).pot at # every "make" invocation, only create it when it is missing. # Only "make $(DOMAIN).pot-update" or "make dist" will force an update. $(srcdir)/$(DOMAIN).pot: $(MAKE) $(DOMAIN).pot-update # This target rebuilds a PO file if $(DOMAIN).pot has changed. # Note that a PO file is not touched if it doesn't need to be changed. $(POFILES): $(POFILESDEPS) @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ if test -f "$(srcdir)/$${lang}.po"; then \ test -f $(srcdir)/$(DOMAIN).pot || $(MAKE) $(srcdir)/$(DOMAIN).pot; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ cd $(srcdir) \ && { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ *) \ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ esac; \ }; \ else \ $(MAKE) $${lang}.po-create; \ fi install: install-exec install-data install-exec: install-data: install-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ for file in $(DISTFILES.common) Makevars.template; do \ $(INSTALL_DATA) $(srcdir)/$$file \ $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ for file in Makevars; do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi install-data-no: all install-data-yes: all @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $(DESTDIR)$$dir; \ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ fi; \ done; \ done install-strip: install installdirs: installdirs-exec installdirs-data installdirs-exec: installdirs-data: installdirs-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ else \ : ; \ fi installdirs-data-no: installdirs-data-yes: @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $(DESTDIR)$$dir; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ fi; \ done; \ done # Define this as empty until I found a useful application. installcheck: uninstall: uninstall-exec uninstall-data uninstall-exec: uninstall-data: uninstall-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ for file in $(DISTFILES.common) Makevars.template; do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi uninstall-data-no: uninstall-data-yes: catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ done; \ done check: all info dvi ps pdf html tags TAGS ctags CTAGS ID: mostlyclean: rm -f remove-potcdate.sed rm -f stamp-poT rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po rm -fr *.o clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES *.mo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f stamp-po $(GMOFILES) distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: test -z "$(DISTFILESDEPS)" || $(MAKE) $(DISTFILESDEPS) @$(MAKE) dist2 # This is a separate target because 'update-po' must be executed before. dist2: stamp-po $(DISTFILES) dists="$(DISTFILES)"; \ if test "$(PACKAGE)" = "gettext-tools"; then \ dists="$$dists Makevars.template"; \ fi; \ if test -f $(srcdir)/$(DOMAIN).pot; then \ dists="$$dists $(DOMAIN).pot stamp-po"; \ fi; \ if test -f $(srcdir)/ChangeLog; then \ dists="$$dists ChangeLog"; \ fi; \ for i in 0 1 2 3 4 5 6 7 8 9; do \ if test -f $(srcdir)/ChangeLog.$$i; then \ dists="$$dists ChangeLog.$$i"; \ fi; \ done; \ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ for file in $$dists; do \ if test -f $$file; then \ cp -p $$file $(distdir) || exit 1; \ else \ cp -p $(srcdir)/$$file $(distdir) || exit 1; \ fi; \ done update-po: Makefile $(MAKE) $(DOMAIN).pot-update test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) $(MAKE) update-gmo # General rule for creating PO files. .nop.po-create: @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ exit 1 # General rule for updating PO files. .nop.po-update: @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ cd $(srcdir); \ if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ *) \ $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ esac; \ }; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi $(DUMMYPOFILES): update-gmo: Makefile $(GMOFILES) @: # Recreate Makefile by invoking config.status. Explicitly invoke the shell, # because execution permission bits may not work on the current file system. # Use @SHELL@, which is the shell determined by autoconf for the use by its # scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ cd $(top_builddir) \ && @SHELL@ ./config.status $(subdir)/$@.in po-directories force: # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hunspell-1.7.0/po/Makevars000066400000000000000000000065021337236234000154710ustar00rootroot00000000000000# Makefile variables for PO directory in any package using GNU gettext. # Usually the message domain is the same as the package name. DOMAIN = $(PACKAGE) # These two variables depend on the location of this directory. subdir = po top_builddir = .. # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --from-code=UTF-8 # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = Free Software Foundation, Inc. # This tells whether or not to prepend "GNU " prefix to the package # name that gets inserted into the header of the $(DOMAIN).pot file. # Possible values are "yes", "no", or empty. If it is empty, try to # detect it automatically by scanning the files in $(top_srcdir) for # "GNU packagename" string. PACKAGE_GNU = # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: # - Strings which are not entire sentences, see the maintainer guidelines # in the GNU gettext documentation, section 'Preparing Strings'. # - Strings which use unclear terms or require additional context to be # understood. # - Strings which make invalid assumptions about notation of date, time or # money. # - Pluralisation problems. # - Incorrect English spelling. # - Incorrect formatting. # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = # This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' # context. Possible values are "yes" and "no". Set this to yes if the # package uses functions taking also a message context, like pgettext(), or # if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. USE_MSGCTXT = no # These options get passed to msgmerge. # Useful options are in particular: # --previous to keep previous msgids of translated messages, # --quiet to reduce the verbosity. MSGMERGE_OPTIONS = # These options get passed to msginit. # If you want to disable line wrapping when writing PO files, add # --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and # MSGINIT_OPTIONS. MSGINIT_OPTIONS = # This tells whether or not to regenerate a PO file when $(DOMAIN).pot # has changed. Possible values are "yes" and "no". Set this to no if # the POT file is checked in the repository and the version control # program ignores timestamps. PO_DEPENDS_ON_POT = yes # This tells whether or not to forcibly update $(DOMAIN).pot and # regenerate PO files on "make dist". Possible values are "yes" and # "no". Set this to no if the POT file and PO files are maintained # externally. DIST_DEPENDS_ON_UPDATE_PO = yes hunspell-1.7.0/po/POTFILES.in000066400000000000000000000002731337236234000155510ustar00rootroot00000000000000# List of source files containing translatable strings. # Copyright (C) 1995, 1996 Free Software Foundation, Inc. # Package source files src/tools/hunspell.cxx # end of file POTFILE.in hunspell-1.7.0/po/Rules-quot000066400000000000000000000042331337236234000157770ustar00rootroot00000000000000# This file, Rules-quot, can be copied and used freely without restrictions. # Special Makefile rules for English message catalogs with quotation marks. DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot .SUFFIXES: .insert-header .po-update-en en@quot.po-create: $(MAKE) en@quot.po-update en@boldquot.po-create: $(MAKE) en@boldquot.po-update en@quot.po-update: en@quot.po-update-en en@boldquot.po-update: en@boldquot.po-update-en .insert-header.po-update-en: @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ if test "$(PACKAGE)" = "gettext-tools" && test "$(CROSS_COMPILING)" != "yes"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ ll=`echo $$lang | sed -e 's/@.*//'`; \ LC_ALL=C; export LC_ALL; \ cd $(srcdir); \ if $(MSGINIT) $(MSGINIT_OPTIONS) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null \ | $(SED) -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | \ { case `$(MSGFILTER) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-8] | 0.1[0-8].*) \ $(MSGFILTER) $(SED) -f `echo $$lang | sed -e 's/.*@//'`.sed \ ;; \ *) \ $(MSGFILTER) `echo $$lang | sed -e 's/.*@//'` \ ;; \ esac } 2>/dev/null > $$tmpdir/$$lang.new.po \ ; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "creation of $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi en@quot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header en@boldquot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header mostlyclean: mostlyclean-quot mostlyclean-quot: rm -f *.insert-header hunspell-1.7.0/po/boldquot.sed000066400000000000000000000003311337236234000163150ustar00rootroot00000000000000s/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g s/“/“/g s/”/”/g s/‘/‘/g s/’/’/g hunspell-1.7.0/po/ca.po000066400000000000000000000366561337236234000147350ustar00rootroot00000000000000# Catalan translation of hunspell. # Copyright (C) 2018 Free Software Foundation, Inc. # This file is distributed under the same license as the hunspell package. # Robert Antoni Buj Gelonch , 2018. # msgid "" msgstr "" "Project-Id-Version: hunspell 1.5.0\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2016-08-30 09:19+0100\n" "PO-Revision-Date: 2018-02-26 09:33+0000\n" "Last-Translator: Robert Antoni Buj Gelonch \n" "Language-Team: Catalan " "\n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 2.20-dev\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "error: iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:272 #, c-format msgid "error - iconv: %s -> %s\n" msgstr "error: iconv: %s -> %s\n" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "error: iconv_open: UTF-8 -> %s\n" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 msgid "Can't create tmp dir" msgstr "No es pot crear el directori temporal" #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 msgid "Can't open inputfile" msgstr "No es pot obrir el fitxer d'entrada" #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "No es pot obrir %s.\n" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "error: falta la variable HOME\n" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "Línia %d: %s -> " #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "PROHIBIT!" #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "Error ortogràfic?" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\t\tFitxer: %s\n" "\n" #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "[ESPAI] S)ubstitueix A)ccepta I)nsereix M)inúscules A(r)rel S(u)rt T)anca o " "? per a l'ajuda\n" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "Sempre que es trobi una paraula que no estigui al diccionari\n" "s'imprimeix a la primera línia de la pantalla. Si el diccionari\n" "conté paraules semblants, es llisten amb un número al\n" "costat de cadascuna. Teniu l'opció de substituir la paraula\n" "completament o triar una de les paraules suggerides.\n" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "Les ordres són:\n" "\n" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "R\tSubstitueix completament la paraula mal escrita.\n" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "Espai\tAccepta la paraula només aquesta vegada.\n" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "A\tAccepta la paraula per al que queda d'aquesta sessió.\n" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "I\tAccepta la paraula i la posa al vostre diccionari privat.\n" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "U\tAccepta i afegeix la versió en minúscules al diccionari privat.\n" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "S\tDemana una arrel i una paraula model i emmagatzema-ho al diccionari " "privat.\n" "\tL'arrel també serà acceptada amb els afixes de la paraula model.\n" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0-n\tSubstitueix amb una de les paraules suggerides.\n" #: src/tools/hunspell.cxx:1280 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "" "X\tEscriu el que queda d'aquest fitxer, ignorant els errors ortogràfics, i " "comença amb el següent fitxer.\n" #: src/tools/hunspell.cxx:1283 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "" "Q\tSurt immediatament. Demana la confirmació. Deixa el fitxer sense " "modificar.\n" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tSuspèn el programa. Reinicia amb l'ordre fg.\n" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "?\tMostra aquesta pantalla d'ajuda.\n" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "-- premeu espai per continuar -- \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "s" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "Substitueix amb: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "m" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "i" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "No es pot actualitzar el diccionari personal." #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "a" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "r" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "Paraula nova (arrel): " #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "Paraula model (similar a una paraula de diccionari): " #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "La paraula model ha d'estar al diccionari. Premeu qualsevol tecla!" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "t" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "u" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "Esteu segur que voleu llençar els vostres canvis? " #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "s" #: src/tools/hunspell.cxx:1611 msgid "Can't create tempfile" msgstr "No es pot crear el fitxer temporal" #: src/tools/hunspell.cxx:1656 msgid "Can't open outputfile" msgstr "No es pot obrir el fitxer de sortida" #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Ús: hunspell [OPCIÓ]... [FITXER]...\n" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Comprova l'ortografia per a cada FITXER. Sense el FITXER, comprova l'entrada " "estàndard.\n" "\n" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\tcomprova només el primer camp a les línies (delimitador = tabulador)" "\n" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tinterfície de canonada d'ispell\n" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr "" " --check-url\tcomprova les URL, les adreces de correu electrònic i els " "camins als directoris\n" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr " --check-apostrophe\tcomprova l'apòstrof tipogràfic d'Unicode\n" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d d[,d2,...]\tutilitza els diccionaris d (d2 etc.)\n" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\tmostra els diccionaris disponibles\n" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\timprimeix només les paraules o les línies correctes\n" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\tmostra aquesta ajuda i surt\n" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tformat de fitxer d'entrada HTML\n" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr " -i enc\tcodificació de l'entrada\n" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\timprimeix les paraules mal escrites\n" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\timprimeix les línies amb les paraules mal escrites\n" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tanalitza les paraules del text d'entrada\n" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tformat de fitxer d'entrada nroff/troff\n" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -O\t\tformat de fitxer d'entrada OpenDocument (ODF normal o pla)\n" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p dict\testableix dict com a diccionari personalitzat\n" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr " -r\t\tadverteix dels errors potencials (paraules estranyes)\n" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr "" " -P contrasenya\testableix la contrasenya per als diccionaris xifrats\n" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr " -s \t\tarrel de les paraules del text d'entrada\n" #: src/tools/hunspell.cxx:1856 msgid " -S \t\tsuffix words of the input text\n" msgstr " -S \t\tparaules de sufix del text d'entrada\n" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tformat de fitxer d'entrada TeX/LaTeX\n" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\timprimeix el número de versió\n" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\timprimeix el número de versió compatible d'Ispell\n" #: src/tools/hunspell.cxx:1861 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr "" " -w\t\timprimeix les paraules mal escrites (= línies) des d'una entrada de " "paraula/línia.\n" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -X\t\tformat de fitxer d'entrada XML\n" "\n" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" "Exemple: hunspell -d en_US file.txt # comprovació interactiva\n" " hunspell -i utf-8 file.txt # comprova el fitxer amb codificació " "UTF-8\n" " hunspell -l *.odt # imprimeix les paraules mal escrites " "dels fitxers ODF\n" "\n" " # Correcció ràpida dels documents ODF mitjançant la creació del " "diccionari personal\n" "\n" " # 1 Creeu una llista reduïda de les paraules mal escrites i " "desconegudes:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Elimineu les paraules mal escrites del fitxer amb un editor de " "text.\n" " # 3 Utilitzeu aquest diccionari personal per corregir les paraules " "eliminades:\n" "\n" " hunspell -p words *.odt\n" "\n" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Informes d'errors: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Drets d'autor (C) 2002-2014 László Németh. Llicència: MPL/GPL/LGPL.\n" "\n" "Està basat amb la biblioteca Myspell d'OpenOffice.org.\n" "Drets d'autor de Myspell (C) Kevin Hendricks, 2001-2002, Llicència: BSD.\n" "\n" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Aquest és programari lliure; vegeu el codi font per les condicions de còpia." "\n" "No hi ha CAP garantia; ni tan sols de COMERCIABILITAT o ADEQUACIÓ\n" "PER A UN PROPÒSIT PARTICULAR, en la mesura permesa per la llei.\n" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "CAMÍ DE CERCA:\n" "%s\n" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "DICCIONARIS DISPONIBLES (el camí no és obligatori per a l'opció -d):\n" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "DICCIONARI CARREGAT:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "error: %s supera el límit del diccionari.\n" #: src/tools/hunspell.cxx:2100 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "" "No es poden obrir els fitxers d'afix o de diccionari per al diccionari " "anomenat «%s».\n" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "Hunspell s'ha compilat sense la interfície d'usuari de Ncurses.\n" hunspell-1.7.0/po/de.po000066400000000000000000000366671337236234000147440ustar00rootroot00000000000000# German translation of hunspell. # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the hunspell package. # Benjamin Weis , 2017. # msgid "" msgstr "" "Project-Id-Version: hunspell 1.5.0\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2017-08-13 20:51+0200\n" "PO-Revision-Date: 2017-08-18 00:12+0200\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.3\n" "Last-Translator: Benjamin Weis \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Language: de\n" "X-Language: de_DE\n" "X-Source-Language: C\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "Fehler - iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:272 #, c-format msgid "error - iconv: %s -> %s\n" msgstr "Fehler - iconv: %s -> %s\n" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "Fehler - iconv_open: UTF-8 -> %s\n" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 msgid "Can't create tmp dir" msgstr "Verzeichnis tmp kann nicht erstellt werden" #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 msgid "Can't open inputfile" msgstr "Eingabedatei kann nicht geöffnet werden" #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "%s kann nicht geöffnet werden.\n" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "Fehler - fehlende HOME-Variable\n" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "Zeile %d: %s -> " #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "VERBOTEN!" #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "Rechtschreibfehler?" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\t\tDatei: %s\n" "\n" #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "[LEERTASTE] E)rsetzen A)nnehmen E(I)nfügen K)leinschreiben Ab(L)eiten " "S)chließen B)eenden oder ? für Hilfe\n" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "Immer wenn ein Wort gefunden wird, das nicht im Wörterbuch\n" "steht, wird es in der ersten Zeile des Bildschirms ausgegeben.\n" "Wenn das Wörterbuch irgendwelche ähnlichen Wörter enthält,\n" "wird jedes neben einer Nummer aufgelistet. Sie haben die\n" "Möglichkeit, das Wort vollständig zu ersetzen oder eines der\n" "vorgeschlagenen Wörter auszuwählen.\n" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "Befehle sind:\n" "\n" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "R\tFalsch geschriebenes Wort vollständig ersetzen.\n" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "Leertaste\tWort nur dieses Mal übernehmen.\n" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "A\tWort für den Rest dieser Sitzung übernehmen.\n" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "I\tWort übernehmen und in Ihr privates Wörterbuch legen.\n" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "" "k\tÜbernehmen und kleingeschriebene Version zum privaten Wörterbuch " "hinzufügen.\n" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "S\tNach einen Wortstamm und einem Musterwort fragen und im privaten " "Wörterbuch speichern.\n" "\tDer Wortstamm wird auch mit den Affixen des Musterwortes übernommen.\n" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0-n\tMit einem der vorgeschlagenen Wörter ersetzen.\n" #: src/tools/hunspell.cxx:1280 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "" "B\tRest dieser Datei schreiben, Rechtschreibfehler ignorieren und nächste " "Datei starten.\n" #: src/tools/hunspell.cxx:1283 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "" "S\tSofort schließen. Bittet um Bestätigung. Lässt Datei ungeändert zurück.\n" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tProgramm unterbrechen. Mit Befehl fg neu starten.\n" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "?\tDiesen Hilfebildschirm anzeigen.\n" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "-- Zum Fortfahren Leertaste drücken -- \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "e" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "Ersetzen mit: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "k" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "i" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "Persönliches Wörterbuch kann nicht aktualisiert werden." #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "a" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "l" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "Neues Wort (Wortstamm): " #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "Musterwort (ein ähnliches Wörterbuchwort): " #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "Musterwort muss im Wörterbuch sein. Drücken Sie eine beliebige Taste!" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "b" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "s" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "Sind Sie sicher, dass Sie Ihre Änderungen wegwerfen möchten? " #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "j" #: src/tools/hunspell.cxx:1611 msgid "Can't create tempfile" msgstr "Temporäre Datei kann nicht erstellt werden" #: src/tools/hunspell.cxx:1656 msgid "Can't open outputfile" msgstr "Ausgabedatei kann nicht erstellt werden" #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Aufruf: hunspell [OPTION]... [DATEI]...\n" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Rechtschreibung jeder DATEI überprüfen. Ohne DATEI die Standardeingabe " "überprüfen.\n" "\n" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\tnur das erste Feld bei Zeilen überprüfen (Trennzeichen = Tabulator)\n" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tPipe-Schnittstelle von Ispell\n" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr " --check-url\tURLs, E-Mail-Adressen und Verzeichnispfade überprüfen\n" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr " --check-apostrophe\tTypografischen Unicode-Apostroph überprüfen\n" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d d[,d2,...]\td (d2 usw.) Wörterbücher verwenden\n" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\tverfügbare Wörterbücher anzeigen\n" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\tnur korrekte Wörter oder Zeilen ausgeben\n" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\tdiese Hilfe anzeigen und beenden\n" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tHTML Eingabedateiformat\n" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr " -i enc\tEingabekodierung\n" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\tfalsch geschriebene Wörter ausgeben\n" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\tZeilen mit falsch geschriebenen Wörtern ausgeben\n" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tWörter des Eingabetextes analysieren\n" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tnroff/troff Eingabedateiformat\n" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -O\t\tOpenDocument (ODF oder Flat ODF) Eingabedateiformat\n" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p dict\tbenutzerdefiniertes Wörterbuch dict festlegen\n" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr " -r\t\tvor den möglichen Fehlern warnen (seltene Wörter)\n" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr " -P password\tPasswort für verschlüsselte Wörterbücher festlegen\n" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr " -s \t\tWorte des eingegebenen Textes ableiten\n" #: src/tools/hunspell.cxx:1856 msgid " -S \t\tsuffix words of the input text\n" msgstr " -S \t\tWörter des Eingabetextes anhängen\n" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tTeX/Latex Eingabedateiformat\n" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\tVersionsnummer ausgeben\n" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\tIspell-kompatible Versionsnummer ausgeben\n" #: src/tools/hunspell.cxx:1861 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr "" " -w\t\tfalsch geschriebene Wörter (= Zeilen) von einer Wort-/Zeileneingabe " "ausgeben.\n" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -X\t\tXML Eingabedateiformat\n" "\n" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" "Beispiel: hunspell -d en_US Datei.txt # interaktive Rechtschreibung\n" " hunspell -i utf-8 Datei.txt # UTF-8-kodierte Datei überprüfen\n" " hunspell -l *.odt # falsch geschriebene Wörter aus " "ODF-Dateien ausgeben\n" "\n" " # Schnelle Korrektur von ODF-Dokumenten durch persönliche " "Wörterbucherstellung\n" "\n" " # 1. Erstellen Sie eine reduzierte Liste aus falsch geschriebenen " "und unbekannten Wörtern:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2. Löschen Sie falsch geschriebene Wörter aus der Datei durch " "einen Texteditor.\n" " # 3. Verwenden Sie dieses persönliche Wörterbuch, um die gelöschten " "Wörter zu korrigieren:\n" "\n" " hunspell -p words *.odt\n" "\n" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Fehlerberichte: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Copyright (C) 2002-2014 László Németh. Lizenz: MPL/GPL/LGPL.\n" "\n" "Basiert auf der Myspell-Bibliothek von OpenOffice.org.\n" "Copyright von Myspell (C) Kevin Hendricks, 2001-2002, Lizenz: BSD.\n" "\n" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Dies ist freie Software; siehe die Quelle für Bedingungen zur " "Vervielfältigung.\n" "Es gibt keine Gewährleistung; nicht einmal für MARKTFÄHIGKEIT oder EIGNUNG " "FÜR\n" "EINEN BESTIMMTEN ZWECK, soweit gesetzlich zulässig.\n" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "PFAD SUCHEN:\n" "%s\n" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "" "VERFÜGBARE WÖRTERBÜCHER (Pfad ist für Option -d nicht zwingend " "erforderlich):\n" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "GELADENES WÖRTERBUCH:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "Fehler - %s überschreitet Wörterbuchbegrenzung.\n" #: src/tools/hunspell.cxx:2100 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "" "Affix oder Wörterbuchdateien für ein Wörterbuch namens \"%s\" können nicht " "geöffnet werden.\n" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "Hunspell wurde ohne Ncurses-Benutzeroberfläche kompiliert.\n" hunspell-1.7.0/po/en@boldquot.header000066400000000000000000000024711337236234000174240ustar00rootroot00000000000000# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # # This catalog furthermore displays the text between the quotation marks in # bold face, assuming the VT100/XTerm escape sequences. # hunspell-1.7.0/po/en@quot.header000066400000000000000000000022631337236234000165620ustar00rootroot00000000000000# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # hunspell-1.7.0/po/es.po000066400000000000000000000363501337236234000147500ustar00rootroot00000000000000# Spanish translation of hunspell. # Copyright (C) 2016 Free Software Foundation, Inc. # This file is distributed under the same license as the hunspell package. # Adolfo Jayme Barrientos , 2016. # msgid "" msgstr "" "Project-Id-Version: hunspell 1.5.0\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2016-08-30 09:19+0100\n" "PO-Revision-Date: 2016-07-21 02:15-0500\n" "Last-Translator: Adolfo Jayme Barrientos \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "error: iconv_open: %s → %s\n" #: src/tools/hunspell.cxx:272 #, c-format msgid "error - iconv: %s -> %s\n" msgstr "error: iconv: %s → %s\n" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "error: iconv_open: UTF-8 → %s\n" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 msgid "Can't create tmp dir" msgstr "No se puede crear la carpeta «tmp»" #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 msgid "Can't open inputfile" msgstr "No se puede abrir el archivo de entrada" #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "No se puede abrir «%s».\n" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "error: falta la variable HOME\n" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "Línea %d: %s → " #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "¡PROHIBIDO!" #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "¿Error ortográfico?" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\t\tArchivo: %s\n" "\n" #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "[ESP.] R)eemp. A)cepta I)nserta M)inús. B)ase T)ermina O)mite o ? para " "ayuda\n" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "Siempre que se halle una palabra que no esté en el diccionario\n" "esta aparecerá en el primer renglón de la pantalla. Si el diccionario\n" "contiene palabras similares, se enumerarán como opciones.\n" "Podrá elegir entre sustituir la palabra completamente,\n" "o bien, elegir una de las palabras sugeridas.\n" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "Las órdenes son:\n" "\n" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "R\tReemplazar la palabra mal escrita por completo.\n" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "Espacio\tAceptar la palabra solo por esta vez.\n" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "A\tAceptar la palabra por el resto de esta sesión.\n" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "I\tAceptar la palabra y añadirla a su diccionario privado.\n" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "M\tAceptar y añadir versión en minúsculas al diccionario privado.\n" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "B\tSolicitar una base (raíz o tema) y una palabra modelo y guardarlas en el " "dicc. privado.\n" "\tLa base se aceptará también con los afijos de la palabra modelo.\n" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0–n\tReemplazar por una de las palabras sugeridas.\n" #: src/tools/hunspell.cxx:1280 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "" "O\tGrabar el resto de este archivo saltándose los errores y comenzar con el " "próximo.\n" #: src/tools/hunspell.cxx:1283 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "" "T\tFinalizar de inmediato. Solicita confirmación. Deja el archivo sin " "modificar.\n" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tSuspender el programa. Reinícielo con la orden «fg».\n" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "?\tMostrar esta pantalla de ayuda.\n" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "-- Oprima Espacio para continuar -- \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "r" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "Reemplazar por: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "m" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "i" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "No se puede actualizar el diccionario personal." #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "a" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "b" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "Palabra nueva (base): " #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "Palabra modelo (una palabra de diccionario similar): " #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "" "La palabra modelo debe existir en el diccionario. Oprima cualquier tecla." #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "o" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "t" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "¿Confirma que quiere descartar sus cambios?" #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "s" #: src/tools/hunspell.cxx:1611 msgid "Can't create tempfile" msgstr "No se puede crear el archivo temporal" #: src/tools/hunspell.cxx:1656 msgid "Can't open outputfile" msgstr "No se puede abrir el archivo de salida" #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Uso: hunspell [OPCIÓN]… [ARCHIVO]…\n" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Revisar la ortografía del ARCHIVO. Sin ARCHIVO, revisar la entrada " "estándar.\n" "\n" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\trevisar solo el primer campo en los renglones (delimitador = " "tabulador)\n" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tInterfaz de canalización de Ispell\n" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr "" " --check-url\trevisar URL, direcciones de correo y rutas de carpetas\n" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr " --check-apostrophe\trevisar apóstrofo tipográfico de Unicode\n" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d d[,d2,…]\tusar diccionarios d (d2, etc.)\n" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\tmostrar los diccionarios disponibles\n" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\tmostrar solo palabras o renglones correctos\n" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\tmostrar esta ayuda y salir\n" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tformato de archivo de entrada HTML\n" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr " -i enc\tcodificación de entrada\n" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\tmostrar las palabras mal escritas\n" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\tmostrar renglones con palabras mal escritas\n" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tanalizar las palabras del texto de entrada\n" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tformato de archivo de entrada nroff/troff\n" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -O\t\tformato de archivo de ent. OpenDocument (ODF u ODF plano)\n" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p dict\testablecer diccionario personalizado dict\n" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr " -r\t\talertar de faltas posibles (palabras inusuales)\n" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr " -P password\testablecer contraseña para diccionarios cifrados\n" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr " -s \t\tseparar las bases en el texto de entrada\n" #: src/tools/hunspell.cxx:1856 msgid " -S \t\tsuffix words of the input text\n" msgstr " -S \t\tsufijar las palabras en el texto de entrada\n" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tformato de archivo de entrada TeX/LaTeX\n" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\tmostrar el número de versión\n" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\tmostrar número de versión compatible con Ispell\n" #: src/tools/hunspell.cxx:1861 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr "" " -w\t\tmostrar palabras mal escritas (= renglones) de una entrada de " "palabra/renglón.\n" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -X\t\tformato de archivo de entrada XML\n" "\n" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" "Ejemplo: hunspell -d es_MX archivo.txt # revisión interactiva\n" " hunspell -i utf-8 archivo.txt # revisar archivo codificado en " "UTF-8\n" " hunspell -l *.odt # ver palabras erróneas en archivos " "ODF\n" "\n" " # Corrección rápida de documentos ODF mediante creación de dicc. " "personales\n" "\n" " # 1 Haga una lista breve de palabras mal escritas y desconocidas:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Elimine las palabras mal escritas del archivo con un editor de " "textos.\n" " # 3 Use este diccionario personal para corregir las palabras " "eliminadas:\n" "\n" " hunspell -p words *.odt\n" "\n" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Informes de errores: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Derechos de autor © 2002–2014 László Németh. Licencia: MPL/GPL/LGPL.\n" "\n" "Basado en la biblioteca Myspell de OpenOffice.org.\n" "Derechos de autor de Myspell © Kevin Hendricks, 2001–2002; licencia: BSD.\n" "\n" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Este programa es libre; consulte las condiciones de copia en el código " "fuente. NO hay\n" "garantías, ni siquiera las de COMERCIABILIDAD o APTITUD PARA ALGÚN FIN " "PARTICULAR,\n" "en la medida en que lo permitan las leyes.\n" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "RUTA DE BÚSQUEDA:\n" "%s\n" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "DICCIONARIOS DISPONIBLES (ruta no obligatoria si usa la opción -d):\n" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "DICCIONARIO CARGADO:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "error: %s supera el límite del diccionario.\n" #: src/tools/hunspell.cxx:2100 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "No se pueden abrir los archivos de afijos o de diccionario de «%s».\n" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "Hunspell se ha compilado sin la interfaz de usuario Ncurses.\n" hunspell-1.7.0/po/hu.po000066400000000000000000000362471337236234000147620ustar00rootroot00000000000000# Hungarian translation of hunspell. # Copyright (C) 2005 Free Software Foundation, Inc. # This file is distributed under the same license as the hunspell package. # Laszlo Nemeth , 2005. # Laszlo Dvornik , 2005. # msgid "" msgstr "" "Project-Id-Version: hunspell\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2016-08-30 09:19+0100\n" "PO-Revision-Date: 2005-09-03 11:22+0200\n" "Last-Translator: László Németh \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "hiba - iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:272 #, fuzzy, c-format msgid "error - iconv: %s -> %s\n" msgstr "hiba - iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "hiba - iconv_open: UTF-8 -> %s\n" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 #, fuzzy msgid "Can't create tmp dir" msgstr "Nem lehet létrehozni átmeneti állományt." #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 msgid "Can't open inputfile" msgstr "Nem lehet megnyitni a bemeneti állományt." #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "Nem lehet megnyitni a(z) %s-t.\n" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "hiba - nincs definiálva a HOME környezeti változó\n" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "%d. sor: %s -> " #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "TILTOTT!" #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "Helyesírási hiba?" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\t\tÁllomány: %s\n" "\n" #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "Szóköz=tovább C)sere J)ó F)elvesz K)isbetűvel T)ő M)égsem V)ége ?" "=Súgó\n" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "A hibás, vagy fel nem ismert szavak az első sorban jelennek meg.\n" "Amennyiben van javítási javaslat, az számozott lista formájában\n" "jelenik meg. A sorszám leütésével választhatunk ki ezek közül\n" "egyet, de megadhatunk akár egy új szót is.\n" "Részletes leírás a program lehetőségeiről: man hunspell.\n" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "Billentyűparancsok: \n" "\n" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "C\tA hibás szó kicserélése egy megadott szóra.\n" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "Szóköz\tA szó egyszeri átugrása változtatás nélkül.\n" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "J\tA szó minden előfordulását jónak tekinti a program futása során.\n" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "" "F\tA szót felveszi a saját szótárba, így új indításkor is ismerni fogja.\n" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "K\tMint az előző, de a szót kisbetűsen veszi fel a saját szótárba.\n" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "T\tSzótő és mintaszó bekérése és saját szótárban való tárolása.\n" "\tA tő felveheti a mintául megadott szó toldalékait is.\n" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0-n\tA javasolt szavak közül az adott sorszámúra cserél.\n" #: src/tools/hunspell.cxx:1280 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "V\tMenti az eddigi javításokat, és rátér a következő állományra.\n" #: src/tools/hunspell.cxx:1283 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "M\tKilép a javítások mentése nélkül, de előtte megerősítést kér.\n" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tA program felfüggesztése. Újraindítás fg paranccsal.\n" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "?\tEnnek a leírásnak a megjelenítése.\n" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "-- Továbblépés a szóköz billentyű leütésével -- \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "c" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "Csere: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "k" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "f" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "Nem lehet frissíteni a saját szótárat." #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "j" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "t" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "Új szó(tő): " #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "Mintaszó (egy hasonló szótári szó): " #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "A minta csak szótári szó lehet! Továbblépés billentyűleütéssel." #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "v" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "m" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "Kilép a módosítások mentése nélkül (i/n)? " #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "i" #: src/tools/hunspell.cxx:1611 msgid "Can't create tempfile" msgstr "Nem lehet létrehozni átmeneti állományt." #: src/tools/hunspell.cxx:1656 msgid "Can't open outputfile" msgstr "Nem lehet megnyitni a kimeneti állományt." #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Használat: hunspell [KAPCSOLÓ]... [ÁLLOMÁNY]...\n" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Az ÁLLOMÁNY(OK) (ennek hiányában a szabványos bemenet) helyesírását " "ellenőrzi.\n" "\n" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\tcsak az első mezőt ellenőrzi a sorban (mezőhatároló = tabulátor)\n" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tIspell-szerű csőfelület\n" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr " --check-url\tURL-ek, e-mail címek és útvonalak ellenőrzése\n" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr " --check-apostrophe\tUnicode tipográfiai aposztróf ellenőrzése\n" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d d[,d2,...]\ta d (d2 stb.) nevű szótárat használja\n" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\taz elérhető szótárak kilistázása\n" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\tkiírja a bemenet helyes szavait vagy sorait\n" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\tkiírja ezt a leírást\n" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tHTML bemeneti formátum\n" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr " -i kód\tbemeneti karakterkódolás\n" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\tkiírja a hibás szavakat\n" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\tkiírja a hibás sorokat\n" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tszövegszavak morfológiai elemzése\n" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tnroff/troff bemeneti formátum\n" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -O\t\tOpenDocument (ODF vagy Flat ODF) bemeneti formátum\n" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p tár\ta tár nevű saját szótárat használja\n" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr " -r\t\tlehetséges hibák (ritka szavak) jelzése\n" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr " -P jelszó\tjelszó megadása a titkosított szótárakhoz\n" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr " -s \t\tszövegszavak tövezése\n" #: src/tools/hunspell.cxx:1856 #, fuzzy msgid " -S \t\tsuffix words of the input text\n" msgstr " -s \t\tszövegszavak tövezése\n" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tTeX/LaTeX bemeneti formátum\n" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\tkiírja a változat számát\n" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\tkiírja a változat számát Ispell-szerűen\n" #: src/tools/hunspell.cxx:1861 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr " -w\t\tkiírja a hibás szavakat a soronként egy szavas bemenetből.\n" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -X\t\tXML bemeneti formátum\n" "\n" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" "Példák: hunspell -d en_US szöveg.txt # interaktív helyesírás-ellenőrzés\n" " hunspell -i utf-8 szöveg.txt # UTF-8-as karakterkódolású állomány " "ellenőrzése\n" " hunspell -l *.odt # kiírja az ODF dokumentumok hibás " "szavait\n" "\n" " # ODF dokumentumok gyors javítása saját szótár létrehozásával\n" "\n" " # 1. Készítsünk csökkentett szólistát a hibás és ismeretlen " "szavakból:\n" "\n" " hunspell -l *.odt | sort | uniq >szavak\n" "\n" " # 2. Töröljük a hibás szavakat az állományból egy " "szövegszerkesztővel.\n" " # 3. Használjuk ezt saját szótárként a törölt szavak javításához:\n" "\n" " hunspell -p szavak *.odt\n" "\n" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Hibajelzés: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Copyright (C) 2002-2014 Németh László. Licenc: MPL/GPL/LGPL.\n" "\n" "Az OpenOffice.org Myspell programkönyvtárán alapul.\n" "MySpell copyright (C) Kevin Hendricks, 2001-2002, Licenc: BSD.\n" "\n" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Ez egy szabad szoftver: lásd a forráskódot a licencfeltételekről.\n" "NINCS garancia, még az eladhatóságra vagy valamely célra való\n" "alkalmazhatóságra sem.\n" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "KERESÉSI ÚTVONAL:\n" "%s\n" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "ELÉRHETŐ SZÓTÁRAK (az útvonal nem kötelező a -d kapcsolónál):\n" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "BETÖLTÖTT SZÓTÁR:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "hiba - %s meghaladja a szótárlimitet.\n" #: src/tools/hunspell.cxx:2100 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "Nem lehet megnyitni a ragozási vagy a szótárállományt (szótár: %s).\n" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "A Hunspell Ncurses felhasználói felület nélkül lett fordítva.\n" hunspell-1.7.0/po/hunspell.pot000066400000000000000000000244151337236234000163560ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the hunspell package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: hunspell 1.5.0\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2016-08-30 09:19+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "" #: src/tools/hunspell.cxx:272 #, c-format msgid "error - iconv: %s -> %s\n" msgstr "" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 msgid "Can't create tmp dir" msgstr "" #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 msgid "Can't open inputfile" msgstr "" #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "" #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "" #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "" #: src/tools/hunspell.cxx:1280 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "" #: src/tools/hunspell.cxx:1283 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "" #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "" #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "" #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "" #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "" #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "" #: src/tools/hunspell.cxx:1611 msgid "Can't create tempfile" msgstr "" #: src/tools/hunspell.cxx:1656 msgid "Can't open outputfile" msgstr "" #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr "" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr "" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr "" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr "" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr "" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr "" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr "" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr "" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr "" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr "" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr "" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr "" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr "" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr "" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr "" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr "" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr "" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr "" #: src/tools/hunspell.cxx:1856 msgid " -S \t\tsuffix words of the input text\n" msgstr "" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr "" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr "" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr "" #: src/tools/hunspell.cxx:1861 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr "" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "" #: src/tools/hunspell.cxx:2100 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "" hunspell-1.7.0/po/insert-header.sin000066400000000000000000000012401337236234000172340ustar00rootroot00000000000000# Sed script that inserts the file called HEADER before the header entry. # # At each occurrence of a line starting with "msgid ", we execute the following # commands. At the first occurrence, insert the file. At the following # occurrences, do nothing. The distinction between the first and the following # occurrences is achieved by looking at the hold space. /^msgid /{ x # Test if the hold space is empty. s/m/m/ ta # Yes it was empty. First occurrence. Read the file. r HEADER # Output the file's contents by reading the next line. But don't lose the # current line while doing this. g N bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } hunspell-1.7.0/po/it.po000066400000000000000000000360161337236234000147540ustar00rootroot00000000000000# Italian translation for hunspell # Copyright (c) 2007 Rosetta Contributors and Canonical Ltd 2007 # Copyright (C) 2009 The Free Software Foundation, Inc # This file is distributed under the same license as the hunspell package. # # Milo Casagrande , 2007, 2009. msgid "" msgstr "" "Project-Id-Version: hunspell\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2016-08-30 09:19+0100\n" "PO-Revision-Date: 2009-08-14 10:25+0200\n" "Last-Translator: Milo Casagrande \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2009-08-12 13:40+0000\n" "X-Generator: Launchpad (build Unknown)\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "errore - iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:272 #, fuzzy, c-format msgid "error - iconv: %s -> %s\n" msgstr "errore - iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "errore - iconv_open: UTF-8 -> %s\n" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 #, fuzzy msgid "Can't create tmp dir" msgstr "Impossibile creare il file temporaneo %s.\n" #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 #, fuzzy msgid "Can't open inputfile" msgstr "Impossibile aprire %s.\n" #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "Impossibile aprire %s.\n" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "errore - variabile HOME mancante\n" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "Riga %d: %s -> " #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "PROIBITO." #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\t\tFile: %s\n" "\n" # (ndt) # to stem -> to have or take origin -> Origine # to uncap -> togliere la 'capitalizzazione' delle parole, le lettere maiuscole #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "[SPAZIO] S)ost A)ccet I)nser T)ogli cap O)rig C)hiudi E)sci o ? per l'aiuto\n" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "Quando viene trovata una parola non presente nel dizionario\n" "viene stampata sulla prima riga dello schermo. Se il dizionario\n" "contiene parole simili, vengono elencate con un numero a fianco\n" "di ognuna. È possibile sostituire la parola completamente o\n" "scegliere uno dei suggerimenti.\n" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "I comandi sono:\n" "\n" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "R\tSostituisce la parola sbagliata\n" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "Spazio\tAccetta la parola solo per questa volta\n" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "A\tAccetta la parola per il resto di questa sessione\n" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "I\tAccetta la parola e la inserisce nel dizionario privato\n" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "" "U\tAccetta la parola e la inserisce in minuscolo nel dizionario privato\n" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "S\tChiede la parte principale e il modello di una parola e li archivia nel " "dizionario privato;\n" "\tla parte principale viene accettata anche con gli affissi della parola " "modello\n" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0-n\tSostituisce con una delle parole suggerite\n" #: src/tools/hunspell.cxx:1280 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "" "X\tScrive il resto del file ignorando gli errori e inizia con il file " "successivo\n" #: src/tools/hunspell.cxx:1283 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "" "Q\tChiude immediatamente, chiede conferma e lascia il file non modificato\n" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tSospende il programma; per riavviarlo, usare il comando fg\n" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "?\tMostra questo aiuto\n" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "-- Premere spazio per continuare -- \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "s" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "Sostituisci con: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "t" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "i" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "Impossibile aggiornare il dizionario personale" #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "a" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "o" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "Nuova parola (origine):" #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "Parola modello (una parola simile dal dizionario): " #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "La parola modello deve essere nel dizionario. Premere un tasto." #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "e" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "c" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "Scartare veramente le modifiche? " #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "s" #: src/tools/hunspell.cxx:1611 #, fuzzy msgid "Can't create tempfile" msgstr "Impossibile creare il file temporaneo %s.\n" #: src/tools/hunspell.cxx:1656 #, fuzzy msgid "Can't open outputfile" msgstr "Impossibile aprire %s.\n" #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Uso: hunspell [OPZIONI]... [FILE]...\n" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Controlla l'ortografia di ogni FILE. Senza FILE controlla lo standard " "input.\n" "\n" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\tControlla solo il primo campo nelle righe (delimitatore = " "tabulatore)\n" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tInterfaccia pipe di Ispell\n" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr "" " --check-url\tControlla gli URL, indirizzi email e i percorsi delle " "directory\n" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr "" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d d[,d2,...]\tUsa i dizionari d (d2 ecc...)\n" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\tMostra i dizionari disponibili\n" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\tStampa solo le righe o le parole corrette\n" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\tMostra questo aiuto ed esce\n" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tFormato del file di input HTML\n" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr " -i cod\tCodifica dell'input\n" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\tStampa le parole errate\n" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\tStampa le righe con le parole errate\n" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tAnalizza le parole del testo in input\n" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tFormato del file di input nroff/troff\n" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -n\t\tFormato del file di input ODF/Flat ODF\n" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p diz\tImposta diz come dizionario personalizzato\n" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr "" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr " -P password\tImposta la password per i dizionari cifrati\n" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr "" " -s \t\tRecupera la parte principale (stem) delle parole del testo di " "input\n" #: src/tools/hunspell.cxx:1856 #, fuzzy msgid " -S \t\tsuffix words of the input text\n" msgstr "" " -s \t\tRecupera la parte principale (stem) delle parole del testo di " "input\n" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tFormato del file di input TeX/LaTeX\n" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\tStampa il numero della versione\n" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\tStampa il numero della versione di compatibilità di Ispell\n" #: src/tools/hunspell.cxx:1861 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr "" " -w\t\tStampa le parole errate (= righe) da una parola o riga di input\n" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -H\t\tFormato del file di input XML\n" "\n" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Per segnalare bug: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Copyright © 2002-2014 László Németh. Licenza: MPL/GPL/LGPL.\n" "\n" "Basato sulla libreria Myspell di OpenOffice.org.\n" "Copyright di Myspell © Kevin Hendricks, 2001-2002, Licenza: BSD.\n" "\n" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Questo è software libero; consultare i sorgenti per le condizioni di copia. " "Non c'è ALCUNA\n" "garanzia, nemmeno quella di COMMERCIABILITÀ o PER UN PARTICOLARE SCOPO, nei " "limiti\n" "permessi dalla legge.\n" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "Percorso di ricerca:\n" "%s\n" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "" "Dizionari disponibili (il percorso non è obbligatorio per l'opzione -d):\n" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "Dizionario caricato:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "errore - %s supera il limite del dizionario.\n" #: src/tools/hunspell.cxx:2100 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "Impossibile aprire i file di affisso o dizionario (%s).\n" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "" "Hunspell è stato compilato senza il supporto per l'interfaccia Ncurses.\n" #~ msgid "" #~ "Example: hunspell -d en_US file.txt # interactive spelling\n" #~ " hunspell -l file.txt # print misspelled words\n" #~ " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" #~ "\n" #~ msgstr "" #~ "Esempio: hunspell -d en_US file.txt # controllo ortografico " #~ "interattivo\n" #~ " hunspell -l file.txt # stampa le parole errate\n" #~ " hunspell -i utf-8 file.txt # controlla il file codificato in " #~ "UTF-8\n" #~ "\n" hunspell-1.7.0/po/pl.po000066400000000000000000000365751337236234000147650ustar00rootroot00000000000000# Polish translation for hunspell. # Copyright © 2017 the hunspell authors. # This file is distributed under the same license as the hunspell package. # Piotr Drąg , 2017. # msgid "" msgstr "" "Project-Id-Version: hunspell\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-09-07 18:40+0200\n" "PO-Revision-Date: 2017-09-07 18:42+0200\n" "Last-Translator: Piotr Drąg \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #: src/tools/hunspell.cxx:265 src/tools/hunspell.cxx:383 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "błąd — iconv_open: %s → %s\n" #: src/tools/hunspell.cxx:279 #, c-format msgid "error - iconv: %s -> %s\n" msgstr "błąd — iconv: %s → %s\n" #: src/tools/hunspell.cxx:324 src/tools/hunspell.cxx:346 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "błąd — iconv_open: UTF-8 → %s\n" #: src/tools/hunspell.cxx:671 src/tools/hunspell.cxx:1578 msgid "Can't create tmp dir" msgstr "Nie można utworzyć katalogu tymczasowego" #: src/tools/hunspell.cxx:682 src/tools/hunspell.cxx:694 #: src/tools/hunspell.cxx:1561 src/tools/hunspell.cxx:1591 #: src/tools/hunspell.cxx:1604 msgid "Can't open inputfile" msgstr "Nie można otworzyć pliku wejściowego" #. first check (before time-consuming dic. load) #: src/tools/hunspell.cxx:684 src/tools/hunspell.cxx:1593 #: src/tools/hunspell.cxx:1994 src/tools/hunspell.cxx:2163 #: src/tools/hunspell.cxx:2180 #, c-format msgid "Can't open %s.\n" msgstr "Nie można otworzyć %s.\n" #: src/tools/hunspell.cxx:764 src/tools/hunspell.cxx:1348 #: src/tools/hunspell.cxx:1460 #, c-format msgid "error - missing HOME variable\n" msgstr "błąd — brak zmiennej HOME\n" #: src/tools/hunspell.cxx:849 #, c-format msgid "Line %d: %s -> " msgstr "%d. wiersz: %s → " #: src/tools/hunspell.cxx:1129 msgid "FORBIDDEN!" msgstr "ZABRONIONE" #: src/tools/hunspell.cxx:1131 msgid "Spelling mistake?" msgstr "Błąd pisowni?" #: src/tools/hunspell.cxx:1133 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\t\tPlik: %s\n" "\n" # FIXME!!! #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1192 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "[SPACJA] Z)astąp A)kceptuj W)staw M)ałe litery T)emat zaK)ończ wyjD)ź, ? " "wyświetli pomoc\n" #: src/tools/hunspell.cxx:1261 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "Po odnalezieniu słowa, którego nie ma w słowniku, jest ono\n" "wyświetlane w pierwszym wierszu ekranu. Jeśli słownik zawiera\n" "podobne słowa, to zostają one wyświetlone z numerami obok każdego.\n" "Można całkowicie zastąpić słowo lub wybrać jedno z proponowanych.\n" #: src/tools/hunspell.cxx:1267 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "Polecenia:\n" "\n" #: src/tools/hunspell.cxx:1268 msgid "R\tReplace the misspelled word completely.\n" msgstr "Z\tCałkowicie zastępuje słowo z błędem pisowni.\n" #: src/tools/hunspell.cxx:1269 msgid "Space\tAccept the word this time only.\n" msgstr "Spacja\tAkceptuje słowo tylko tym razem.\n" #: src/tools/hunspell.cxx:1271 msgid "A\tAccept the word for the rest of this session.\n" msgstr "A\tAkceptuje słowo na czas tej sesji.\n" #: src/tools/hunspell.cxx:1273 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "W\tAkceptuje słowo i umieszcza je w słowniku użytkownika.\n" #: src/tools/hunspell.cxx:1275 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "" "M\tAkceptuje i dodaje wersję z małymi literami do słownika użytkownika.\n" #: src/tools/hunspell.cxx:1277 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "T\tPyta o temat i słowo wzorcowe i umieszcza je w słowniku użytkownika.\n" "\tTemat zostanie przyjęty także z przyrostkami słowa wzorcowego.\n" #: src/tools/hunspell.cxx:1281 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0-n\tZastępuje jednym z proponowanych słów.\n" #: src/tools/hunspell.cxx:1283 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "" "D\tZapisuje resztę tego pliku, ignorując błędy pisowni, i rozpoczyna nowy " "plik.\n" #: src/tools/hunspell.cxx:1286 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "" "K\tKończy działanie. Pyta o potwierdzenie. Plik nie zostaje zmieniony.\n" #: src/tools/hunspell.cxx:1288 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tWstrzymuje program. Polecenie fg uruchamia go ponownie.\n" #: src/tools/hunspell.cxx:1289 msgid "?\tShow this help screen.\n" msgstr "?\tWyświetla ten ekran pomocy.\n" #: src/tools/hunspell.cxx:1290 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "— Spacja kontynuuje — \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1302 msgid "r" msgstr "z" #: src/tools/hunspell.cxx:1311 msgid "Replace with: " msgstr "Zamiana na: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. no break #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1335 src/tools/hunspell.cxx:1371 msgid "u" msgstr "m" #: src/tools/hunspell.cxx:1336 src/tools/hunspell.cxx:1371 msgid "i" msgstr "w" #: src/tools/hunspell.cxx:1364 src/tools/hunspell.cxx:1476 #, c-format msgid "Cannot update personal dictionary." msgstr "Nie można zaktualizować słownika użytkownika." #: src/tools/hunspell.cxx:1372 msgid "a" msgstr "a" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1380 msgid "s" msgstr "t" #: src/tools/hunspell.cxx:1395 msgid "New word (stem): " msgstr "Nowe słowo (temat): " #: src/tools/hunspell.cxx:1423 msgid "Model word (a similar dictionary word): " msgstr "Słowo wzorcowe (podobne słowo ze słownika): " #: src/tools/hunspell.cxx:1483 msgid "Model word must be in the dictionary. Press any key!" msgstr "Słowo wzorcowe musi być w słowniku. Proszę nacisnąć dowolny klawisz." #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1493 msgid "x" msgstr "d" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1499 msgid "q" msgstr "k" #: src/tools/hunspell.cxx:1502 msgid "Are you sure you want to throw away your changes? " msgstr "Na pewno odrzucić zmiany? " #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1505 msgid "y" msgstr "t" #: src/tools/hunspell.cxx:1614 msgid "Can't create tempfile" msgstr "Nie można utworzyć pliku tymczasowego" #: src/tools/hunspell.cxx:1659 msgid "Can't open outputfile" msgstr "Nie można otworzyć pliku wyjściowego" #: src/tools/hunspell.cxx:1814 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Użycie: hunspell [OPCJA]… [PLIK]…\n" #: src/tools/hunspell.cxx:1815 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Sprawdza pisownię każdego PLIKU. Jeśli nie podano PLIKU, to sprawdza " "standardowe wejście.\n" "\n" #: src/tools/hunspell.cxx:1817 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\tsprawdza tylko pierwsze pola w wierszach (rozdzielane tabulacjami)\n" #: src/tools/hunspell.cxx:1819 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tinterfejs (potok) biblioteki Ispell\n" #: src/tools/hunspell.cxx:1820 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr " --check-url\tsprawdza adresy URL, e-mail i ścieżki do katalogów\n" #: src/tools/hunspell.cxx:1825 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr " --check-apostrophe\tsprawdza apostrof typograficzny Unicode\n" #: src/tools/hunspell.cxx:1827 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d s[,s2,…]\tużywa słowniki s (s2 itd.)\n" #: src/tools/hunspell.cxx:1828 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\twyświetla dostępne słowniki\n" #: src/tools/hunspell.cxx:1829 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\twyświetla tylko poprawne słowa lub wiersze\n" #: src/tools/hunspell.cxx:1830 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\twyświetla tę pomoc i kończy działanie\n" #: src/tools/hunspell.cxx:1831 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tformat HTML pliku wejściowego\n" #: src/tools/hunspell.cxx:1832 msgid " -i enc\tinput encoding\n" msgstr " -i kodowanie\tkodowanie wejściowe\n" #: src/tools/hunspell.cxx:1833 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\twyświetla słowa z błędami pisowni\n" #: src/tools/hunspell.cxx:1834 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\twyświetla wiersze z błędami pisowni\n" #: src/tools/hunspell.cxx:1836 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tanalizuje słowa tekstu wejściowego\n" #: src/tools/hunspell.cxx:1837 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tformat nroff/troff pliku wejściowego\n" #: src/tools/hunspell.cxx:1841 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -O\t\tformat OpenDocument (ODF lub Flat ODF) pliku wejściowego\n" #: src/tools/hunspell.cxx:1842 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p DICT\tustawia słownik DICT użytkownika\n" #: src/tools/hunspell.cxx:1844 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr " -r\t\tostrzega o potencjalnych pomyłkach (rzadkie słowa)\n" #: src/tools/hunspell.cxx:1847 msgid " -P password\tset password for encrypted dictionaries\n" msgstr " -P hasło\tustawia hasło dla zaszyfrowanych słowników\n" #: src/tools/hunspell.cxx:1848 msgid " -s \t\tstem the words of the input text\n" msgstr " -s \t\twyodrębnia tematy słów tekstu wejściowego\n" #: src/tools/hunspell.cxx:1849 msgid " -S \t\tsuffix words of the input text\n" msgstr " -S \t\tprzyrostki tekstu wejściowego\n" #: src/tools/hunspell.cxx:1850 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tformat TeX/LaTeX pliku wejściowego\n" #: src/tools/hunspell.cxx:1851 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\twyświetla numer wersji\n" #: src/tools/hunspell.cxx:1853 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\twyświetla numer wersji zgodny z biblioteką Ispell\n" #: src/tools/hunspell.cxx:1854 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr " -w\t\twyświetla błędy pisowni (= wiersze) z jednego słowa/wiersza.\n" #: src/tools/hunspell.cxx:1856 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -X\t\tformat XML pliku wejściowego\n" "\n" #: src/tools/hunspell.cxx:1860 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" "Przykład: hunspell -d en_US plik.txt # interaktywne sprawdzanie pisowni\n" " hunspell -i utf-8 plik.txt # sprawdzanie pliku zakodowanego " "w UTF-8\n" " hunspell -l *.odt # wyświetlenie błędów pisowni plików " "ODF\n" "\n" " # Szybka poprawa dokumentu ODF przez utworzenie słownika " "użytkownika\n" "\n" " # 1. Utworzenie zmniejszonej listy z błędami pisowni i nieznanymi " "słowami:\n" "\n" " hunspell -l *.odt | sort | uniq >słowa\n" "\n" " # 2. Usunięcie słów z błędami pisowni z pliku za pomocą edytora " "tekstu.\n" " # 3. Użycie utworzonego słownika użytkownika do poprawy usuniętych " "słów:\n" "\n" " hunspell -p słowa *.odt\n" "\n" #: src/tools/hunspell.cxx:1875 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Zgłoszenia błędów: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1883 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Copyright © 2002-2014 László Németh. Licencja: MPL/GPL/LGPL.\n" "\n" "Na podstawie biblioteki Myspell projektu OpenOffice.org.\n" "Myspell — copyright © Kevin Hendricks, 2001-2002, Licencja: BSD.\n" "\n" #: src/tools/hunspell.cxx:1888 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Niniejszy program jest wolnym oprogramowaniem; proszę zobaczyć kod źródłowy\n" "w celu poznania warunków kopiowania. Niniejszy program rozprowadzany jest\n" "BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej gwarancji PRZYDATNOŚCI\n" "HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ, w zakresie\n" "dozwolonym przez prawo.\n" #: src/tools/hunspell.cxx:2063 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "ŚCIEŻKA WYSZUKIWANIA:\n" "%s\n" #: src/tools/hunspell.cxx:2067 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "DOSTĘPNE SŁOWNIKI (ścieżka nie jest wymagana dla opcji -d):\n" #: src/tools/hunspell.cxx:2081 src/tools/hunspell.cxx:2101 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "WCZYTANY SŁOWNIK:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2104 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "błąd — %s przekracza ograniczenie słownika.\n" #: src/tools/hunspell.cxx:2110 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "" "Nie można otworzyć plików przyrostków lub słowników dla słownika o nazwie " "„%s”.\n" #: src/tools/hunspell.cxx:2193 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "Skompilowano Hunspell bez interfejsu użytkownika ncurses.\n" hunspell-1.7.0/po/pt_BR.po000066400000000000000000000363641337236234000153540ustar00rootroot00000000000000# Brazilian Portuguese translations for hunspell package. # Copyright (C) 2017 Free Software Foundation, Inc. # This file is distributed under the same license as the hunspell package. # Rafael Fontenelle , 2017. msgid "" msgstr "" "Project-Id-Version: hunspell 1.6.2\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2016-08-30 09:19+0100\n" "PO-Revision-Date: 2017-09-04 21:29-0200\n" "Last-Translator: Rafael Fontenelle \n" "Language-Team: \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Virtaal 1.0.0-beta1\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "erro - iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:272 #, c-format msgid "error - iconv: %s -> %s\n" msgstr "erro - iconv: %s -> %s\n" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "erro - iconv_open: UTF-8 -> %s\n" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 msgid "Can't create tmp dir" msgstr "Não foi possível criar diretório temp" #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 msgid "Can't open inputfile" msgstr "Não foi possível abrir o arquivo de entrada" #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "Não foi possível abrir %s.\n" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "erro - faltando a variável HOME\n" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "Linha %d: %s -> " #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "PROIBIDO!" #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "Erro ortográfico?" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\tArquivo: %s\n" "\n" #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "[ESPAÇO] S)ubst A)ceit I)nserir min(U)s R)aiz S)air (T)erminar ou ? para ajuda\n" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "Sempre que se descobre que uma palavra não está no dicionário,\n" "ela é impressa na primeira linha da tela. Se o dicionário\n" "contiver quaisquer palavras similares, elas são listadas com\n" "um número ao lado de cada uma. Você tem a opção de substituir\n" "completamente a palavra, ou escolher uma das palavras sugeridas.\n" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "Os comandos são:\n" "\n" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "S\tSubstitui completamente a palavra com erro ortográfico.\n" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "Espaço\tAceita a palavra somente dessa vez.\n" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "A\tAceita a palavra para o resto dessa sessão.\n" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "I\tAceita a palavra e a coloca em seu dicionário privado.\n" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "U\tAceita e adiciona a versão minúscula ao dicionário privado.\n" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "S\tPede uma raiz e uma palavra modelo e as armazena no dicionário privado.\n" " \tA raiz também será aceita com afixos da palavra modelo.\n" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0-n\tSubstitui com uma das palavras sugeridas.\n" #: src/tools/hunspell.cxx:1280 msgid "X\tWrite the rest of this file, ignoring misspellings, and start next file.\n" msgstr "" "T\tEscreve o resto deste arquivo, ignorando erros de escrita\n" "\t e inicia o próximo arquivo.\n" #: src/tools/hunspell.cxx:1283 msgid "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "S\tSai imediatamente. Pede por confirmação. Deixa o arquivo inalterado.\n" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tSuspende o programa. Reinicie com o comando fg.\n" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "?\tMostra essa tela de ajuda.\n" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "-- Pressione espaço para continuar -- \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "s" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "Substituir por: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "u" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "i" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "Não foi possível atualizar o dicionário pessoal." #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "a" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "r" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "Nova palavra (raiz): " #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "Palavra modelo (uma palavra similar do dicionário): " #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "A palavra modelo deve estar no dicionário. Pressione qualquer tecla!" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "t" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "s" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "Tem certeza que você deseja descartar suas alterações? " #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "s" #: src/tools/hunspell.cxx:1611 msgid "Can't create tempfile" msgstr "Não foi possível criar o arquivo temp" #: src/tools/hunspell.cxx:1656 msgid "Can't open outputfile" msgstr "Não foi possível abrir o arquivo de saída" #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Uso: hunspell [OPÇÃO]... [ARQUIVO]...\n" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Verifica a ortografia de cada ARQUIVO. Sem ARQUIVO, verifica a entrada padrão.\n" "\n" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\tverifica apenas o primeiro campo em linhas\n" " \t\t (delimitador = tabulação)\n" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tinterface pipe do Ispell\n" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr " --check-url\tverifica URLs, endereços de e-mail e caminhos de diretórios\n" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr " --check-apostrophe\tverifica apóstrofo tipográfico de Unicode\n" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d d[,d2,...]\tusa os dicionários d (d2 etc.)\n" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\tmostra os dicionários disponíveis\n" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\texibe apenas palavras ou linhas corretas\n" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\texibe esta ajuda e sai\n" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tformato de arquivo de entrada HTML\n" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr " -i cod\tcodificação de entrada\n" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\texibe palavras com erro ortográfico\n" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\texibe linhas com erro ortográfico\n" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tanalisa as palavras do texto de entrada\n" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tformato de arquivo de entrada nroff/troff\n" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -O\t\tformato de arquivo de entrada OpenDocument (ODF ou Flat ODF)\n" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p dic\tdefine um dicionário personalizado\n" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr " -r\t\tavisa sobre possíveis erros (palavras raras)\n" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr " -P senha\tdefine senha para dicionários criptografados\n" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr " -s \t\tenraíza as palavras do texto de entrada\n" #: src/tools/hunspell.cxx:1856 msgid " -S \t\tsuffix words of the input text\n" msgstr " -S \t\tsufixa palavras do texto de entrada\n" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tformato de arquivo de entrada TeX/LaTeX\n" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\texibe o número de versão\n" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\texibe o número de versão compatível com Ispell\n" #: src/tools/hunspell.cxx:1861 msgid " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr "" " -w\t\texibe palavras (= linhas) com erro ortográfico de entrada\n" " \t\t de uma palavra/linha.\n" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -X\t\tformato de arquivo de entrada XML\n" "\n" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" "Exemplo: hunspell -d pt_BR arq.txt # verificação ortográfica interativa\n" " hunspell -i utf-8 arq.txt # verifica arquivo codificado em UTF-8\n" " hunspell -l *.odt # exibe erros ortográficos em arquivos ODF\n" "\n" " # Correção rápida de documentos ODF por criação de dicionário pessoal\n" "\n" " # 1 Faça uma lista reduzida de palavras com erro de escrita\n" " e desconhecidas:\n" "\n" " hunspell -l *.odt | sort | uniq >palavras\n" "\n" " # 2 Exclua palavras com erros ortográficos do arquivo\n" " por um editor de texto.\n" " # 3 Use esse dicionário pessoal para corrigir as palavras excluídas:\n" "\n" " hunspell -p palavras *.odt\n" "\n" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Relatórios de erro: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Copyright (C) 2002-2014 László Németh. Licença: MPL/GPL/LGPL.\n" "\n" "Baseado na biblioteca Myspell do OpenOffice.org.\n" "Copyright do Myspell (C) Kevin Hendricks, 2001-2002, Licença: BSD.\n" "\n" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Esse é um software livre; veja o código-fonte para condições de cópia.\n" "Há NENHUMA garantia; nem mesmo para COMERCIABILIDADE ou ADEQUAÇÃO PARA\n" "UM PROPÓSITO PARTICULAR, na extensão permitida pela lei.\n" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "CAMINHO DE PESQUISA:\n" "%s\n" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "DICIONÁRIOS DISPONÍVEIS (caminho não é obrigatório para opção -d):\n" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "DICIONÁRIO CARREGADO:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "erro - %s excede o limite de dicionários.\n" #: src/tools/hunspell.cxx:2100 #, c-format msgid "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "Não foi possível arquivos de dicionário ou afixos para o diretório chamado \"%s\".\n" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "Hunspell foi compilado sem a interface de usuário Ncurses.\n" hunspell-1.7.0/po/quot.sed000066400000000000000000000002311337236234000154530ustar00rootroot00000000000000s/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g hunspell-1.7.0/po/remove-potcdate.sin000066400000000000000000000006601337236234000176050ustar00rootroot00000000000000# Sed script that remove the POT-Creation-Date line in the header entry # from a POT file. # # The distinction between the first and the following occurrences of the # pattern is achieved by looking at the hold space. /^"POT-Creation-Date: .*"$/{ x # Test if the hold space is empty. s/P/P/ ta # Yes it was empty. First occurrence. Remove the line. g d bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } hunspell-1.7.0/po/stamp-po000066400000000000000000000000121337236234000154460ustar00rootroot00000000000000timestamp hunspell-1.7.0/po/tg.po000066400000000000000000000436741337236234000147620ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the hunspell package. # Victor Ibragimov , 2017. # msgid "" msgstr "" "Project-Id-Version: Tajik Hunspell\n" "Report-Msgid-Bugs-To: nemeth@numbertext.org\n" "POT-Creation-Date: 2017-03-24 10:22+0500\n" "PO-Revision-Date: 2017-03-24 16:56+0500\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.4\n" "Last-Translator: Victor Ibragimov \n" "Language-Team: Tajik Hunspell \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Language: tg\n" #: src/tools/hunspell.cxx:260 src/tools/hunspell.cxx:376 #, c-format msgid "error - iconv_open: %s -> %s\n" msgstr "хато - iconv_open: %s -> %s\n" #: src/tools/hunspell.cxx:272 #, c-format msgid "error - iconv: %s -> %s\n" msgstr "хато - iconv: %s -> %s\n" #: src/tools/hunspell.cxx:317 src/tools/hunspell.cxx:339 #, c-format msgid "error - iconv_open: UTF-8 -> %s\n" msgstr "хато - iconv_open: UTF-8 -> %s\n" #: src/tools/hunspell.cxx:666 src/tools/hunspell.cxx:1575 msgid "Can't create tmp dir" msgstr "Феҳристи tmp эҷод карда намешавад" #: src/tools/hunspell.cxx:677 src/tools/hunspell.cxx:689 #: src/tools/hunspell.cxx:1558 src/tools/hunspell.cxx:1588 #: src/tools/hunspell.cxx:1601 msgid "Can't open inputfile" msgstr "Файли inputfile кушода намешавад" #: src/tools/hunspell.cxx:679 src/tools/hunspell.cxx:1590 #: src/tools/hunspell.cxx:2001 src/tools/hunspell.cxx:2153 #: src/tools/hunspell.cxx:2170 #, c-format msgid "Can't open %s.\n" msgstr "%s кушода намешавад.\n" #: src/tools/hunspell.cxx:759 src/tools/hunspell.cxx:1345 #: src/tools/hunspell.cxx:1457 #, c-format msgid "error - missing HOME variable\n" msgstr "хато - тағйирёбандаи HOME вуҷуд надорад\n" #: src/tools/hunspell.cxx:844 #, c-format msgid "Line %d: %s -> " msgstr "Хати %d: %s -> " #: src/tools/hunspell.cxx:1124 msgid "FORBIDDEN!" msgstr "МАМНӮЪ!" #: src/tools/hunspell.cxx:1126 msgid "Spelling mistake?" msgstr "Имло хато дорад?" #: src/tools/hunspell.cxx:1128 #, c-format msgid "" "\t%s\t\tFile: %s\n" "\n" msgstr "" "\t%s\t\tФайл: %s\n" "\n" #. TRANSLATORS: the capital letters are shortcuts, mark one letter similarly #. in your translation and translate the standalone letter accordingly later #. #: src/tools/hunspell.cxx:1187 msgid "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" msgstr "" "\n" "[SPACE] R)epl A)ccept I)nsert U)ncap S)tem Q)uit e(X)it or ? for help\n" #: src/tools/hunspell.cxx:1258 msgid "" "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n" msgstr "" "Ҳар вақте ки калима берун аз луғат пайдо мешавад,\n" "он дар якум сатри экран чоп карда мешавад. Агар луғат\n" "дорои калимаҳои монанд бошад, онҳо бо рақам дар рӯйхат\n" "намоиш дода мешаванд. Шумо метавонед калимаро комилан иваз кунед\n" "ё ин ки онро бо яке аз калимаҳои пешниҳодшуда иваз намоед.\n" #: src/tools/hunspell.cxx:1264 msgid "" "\n" "Commands are:\n" "\n" msgstr "" "\n" "Фармонҳо:\n" "\n" #: src/tools/hunspell.cxx:1265 msgid "R\tReplace the misspelled word completely.\n" msgstr "И\tИваз кардани ҳамаи калимаҳо бо хатоҳо.\n" #: src/tools/hunspell.cxx:1266 msgid "Space\tAccept the word this time only.\n" msgstr "Фосила\tКалимаро танҳо ин дафъа қабул кунед.\n" #: src/tools/hunspell.cxx:1268 msgid "A\tAccept the word for the rest of this session.\n" msgstr "К\tКалимаро танҳо то анҷоми ин ҷаласа қабул кунед.\n" #: src/tools/hunspell.cxx:1270 msgid "I\tAccept the word, and put it in your private dictionary.\n" msgstr "I\tКалимаро қабул кунед ва онро ба луғати шахсӣ гузоред.\n" #: src/tools/hunspell.cxx:1272 msgid "U\tAccept and add lowercase version to private dictionary.\n" msgstr "" "U\tВариантҳоро бо калимаҳои хурд қабул кунед ва ба луғати шахсӣ " "гузоред.\n" #: src/tools/hunspell.cxx:1274 msgid "" "S\tAsk a stem and a model word and store them in the private " "dictionary.\n" "\tThe stem will be accepted also with the affixes of the model word.\n" msgstr "" "S\tКалимаҳои асосӣ ва намунавиро дархост кунед ва онҳоро ба луғати " "шахсӣ гузоред.\n" "\tКалимаҳои асосӣ инчунин бо аффиксҳои калимаҳои намунавӣ қабул карда " "мешаванд.\n" #: src/tools/hunspell.cxx:1278 msgid "0-n\tReplace with one of the suggested words.\n" msgstr "0-n\tИваз кардан бо яке аз калимаҳои пешниҳодшуда.\n" #: src/tools/hunspell.cxx:1280 msgid "" "X\tWrite the rest of this file, ignoring misspellings, and start next " "file.\n" msgstr "" "X\tФайлро то охир сабт намоед, хатоҳои имлоро нодида гузаронед ва файли " "навбатиро кушоед.\n" #: src/tools/hunspell.cxx:1283 msgid "" "Q\tQuit immediately. Asks for confirmation. Leaves file unchanged.\n" msgstr "" "Х\tДарҳол хомӯш кунед. Тасдиқкуниро дархост мекунад. Файлро бетағйир " "мемонад.\n" #: src/tools/hunspell.cxx:1285 msgid "^Z\tSuspend program. Restart with fg command.\n" msgstr "^Z\tТаваққуф кардани барнома. Бо фармони fg бозоғозӣ кунед.\n" #: src/tools/hunspell.cxx:1286 msgid "?\tShow this help screen.\n" msgstr "?\tНамоиш додани ин экрани кумакрасон.\n" #: src/tools/hunspell.cxx:1287 msgid "" "\n" "-- Type space to continue -- \n" msgstr "" "\n" "-- Барои идома тугмаи ФОСИЛА-ро пахш намоед -- \n" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "R)epl" before #: src/tools/hunspell.cxx:1299 msgid "r" msgstr "r" #: src/tools/hunspell.cxx:1308 msgid "Replace with: " msgstr "Иваз кардан бо: " #. TRANSLATORS: translate these letters according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "U)ncap" and I)nsert before #: src/tools/hunspell.cxx:1332 src/tools/hunspell.cxx:1368 msgid "u" msgstr "u" #: src/tools/hunspell.cxx:1333 src/tools/hunspell.cxx:1368 msgid "i" msgstr "i" #: src/tools/hunspell.cxx:1361 src/tools/hunspell.cxx:1473 #, c-format msgid "Cannot update personal dictionary." msgstr "Луғати шахсӣ нав карда намешавад." #: src/tools/hunspell.cxx:1369 msgid "a" msgstr "a" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "S)tem" before #: src/tools/hunspell.cxx:1377 msgid "s" msgstr "s" #: src/tools/hunspell.cxx:1392 msgid "New word (stem): " msgstr "Калимаи нав (асос): " #: src/tools/hunspell.cxx:1420 msgid "Model word (a similar dictionary word): " msgstr "Калимаи намунавӣ (калимаи намунавии луғат): " #: src/tools/hunspell.cxx:1480 msgid "Model word must be in the dictionary. Press any key!" msgstr "Калимаи намунавӣ бояд дар луғат бошад. Ягон тугмаро пахш намоед!" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "e(X)it" before #: src/tools/hunspell.cxx:1490 msgid "x" msgstr "x" #. TRANSLATORS: translate this letter according to the shortcut letter #. used #. previously in the translation of "Q)uit" before #: src/tools/hunspell.cxx:1496 msgid "q" msgstr "q" #: src/tools/hunspell.cxx:1499 msgid "Are you sure you want to throw away your changes? " msgstr "Шумо мутмин ҳастед, ки мехоҳед тағйироти худро бекор кунед? " #. TRANSLATORS: translate this letter according to the shortcut #. * letter y)es #: src/tools/hunspell.cxx:1502 msgid "y" msgstr "y" #: src/tools/hunspell.cxx:1611 msgid "Can't create tempfile" msgstr "Файли tempfile эҷод карда намешавад" #: src/tools/hunspell.cxx:1656 msgid "Can't open outputfile" msgstr "Файли outputfile эҷод карда намешавад" #: src/tools/hunspell.cxx:1821 msgid "Usage: hunspell [OPTION]... [FILE]...\n" msgstr "Тарзи истифода: hunspell [OPTION]... [FILE]...\n" #: src/tools/hunspell.cxx:1822 msgid "" "Check spelling of each FILE. Without FILE, check standard input.\n" "\n" msgstr "" "Санҷиши имло дар ҳар як ФАЙЛ. Бе ФАЙЛ, вуруди стандартиро санҷед.\n" "\n" #: src/tools/hunspell.cxx:1824 msgid " -1\t\tcheck only first field in lines (delimiter = tabulator)\n" msgstr "" " -1\t\tтанҳо майдони якуми сатрҳоро санҷед (маҳдудкунанда= табулятор)\n" #: src/tools/hunspell.cxx:1826 msgid " -a\t\tIspell's pipe interface\n" msgstr " -a\t\tИнтерфейси хати Ispell\n" #: src/tools/hunspell.cxx:1827 msgid " --check-url\tcheck URLs, e-mail addresses and directory paths\n" msgstr "" " --check-url\tсуроғаҳои URL, суроғаҳои почтаи электронӣ ва масирҳои " "луғатҳоро тафтиш мекунад\n" #: src/tools/hunspell.cxx:1832 msgid " --check-apostrophe\tcheck Unicode typographic apostrophe\n" msgstr "" " --check-apostrophe\tапострофи матбаавии Unicode-ро тафтиш мекунад\n" #: src/tools/hunspell.cxx:1834 msgid " -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n" msgstr " -d d[,d2,...]\tлуғатҳоро (d2 ва ғайра) истифода мебарад\n" #: src/tools/hunspell.cxx:1835 msgid " -D\t\tshow available dictionaries\n" msgstr " -D\t\tлуғатҳои дастрасро намоиш медиҳад\n" #: src/tools/hunspell.cxx:1836 msgid " -G\t\tprint only correct words or lines\n" msgstr " -G\t\tтанҳо сатрҳо ё калимаҳои дурустро чоп мекунад\n" #: src/tools/hunspell.cxx:1837 msgid " -h, --help\tdisplay this help and exit\n" msgstr " -h, --help\tин кумакро намоиш диҳед ва бароед\n" #: src/tools/hunspell.cxx:1838 msgid " -H\t\tHTML input file format\n" msgstr " -H\t\tФормати файли вурудии HTML\n" #: src/tools/hunspell.cxx:1839 msgid " -i enc\tinput encoding\n" msgstr " -i enc\tрамзгузории вуруд\n" #: src/tools/hunspell.cxx:1840 msgid " -l\t\tprint misspelled words\n" msgstr " -l\t\tкалимаҳоро бо хатоҳо чоп мекунад\n" #: src/tools/hunspell.cxx:1841 msgid " -L\t\tprint lines with misspelled words\n" msgstr " -L\t\tсатрҳоро бо хатоҳо чоп мекунад\n" #: src/tools/hunspell.cxx:1843 msgid " -m \t\tanalyze the words of the input text\n" msgstr " -m \t\tкалимаҳои матни вурудиро таҳлил мекунад\n" #: src/tools/hunspell.cxx:1844 msgid " -n\t\tnroff/troff input file format\n" msgstr " -n\t\tФормати файли вурудии nroff/troff\n" #: src/tools/hunspell.cxx:1848 msgid " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n" msgstr " -O\t\tФайли формати вурудии OpenDocument (ODF ё ODF Оддӣ)\n" #: src/tools/hunspell.cxx:1849 msgid " -p dict\tset dict custom dictionary\n" msgstr " -p dict\tлуғати фармоишии dict-ро танзим мекунад\n" #: src/tools/hunspell.cxx:1851 msgid " -r\t\twarn of the potential mistakes (rare words)\n" msgstr "" " -r\t\tдар бораи хатоҳои имконпазир (калимаҳои камёб) ҳушдор мекунад\n" #: src/tools/hunspell.cxx:1854 msgid " -P password\tset password for encrypted dictionaries\n" msgstr " -P password\tбарои луғатҳои рамздор паролро танзим мекунад\n" #: src/tools/hunspell.cxx:1855 msgid " -s \t\tstem the words of the input text\n" msgstr " -s \t\tкалимаҳоро аз матни вурудӣ ба вуҷуд меорад\n" #: src/tools/hunspell.cxx:1856 msgid " -S \t\tsuffix words of the input text\n" msgstr " -S \t\tба калимаҳо аз матни вурудӣ пасвандҳоро илова мекунад\n" #: src/tools/hunspell.cxx:1857 msgid " -t\t\tTeX/LaTeX input file format\n" msgstr " -t\t\tФормати файли вурудии TeX/LaTeX\n" #: src/tools/hunspell.cxx:1858 msgid " -v, --version\tprint version number\n" msgstr " -v, --version\tрақами версияро чоп мекунад\n" #: src/tools/hunspell.cxx:1860 msgid " -vv\t\tprint Ispell compatible version number\n" msgstr " -vv\t\tрақами версияи мувофиқи Ispell-ро чоп мекунад\n" #: src/tools/hunspell.cxx:1861 msgid "" " -w\t\tprint misspelled words (= lines) from one word/line input.\n" msgstr "" " -w\t\tкалимаҳоро бо хатоҳо (= хатҳо) яз як калима/хати вурудӣ чоп " "мекунад.\n" #: src/tools/hunspell.cxx:1863 msgid "" " -X\t\tXML input file format\n" "\n" msgstr "" " -X\t\tФормати файли вурудии XML\n" "\n" #: src/tools/hunspell.cxx:1867 msgid "" "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded file\n" " hunspell -l *.odt # print misspelled words of ODF " "files\n" "\n" " # Quick fix of ODF documents by personal dictionary creation\n" "\n" " # 1 Make a reduced list from misspelled and unknown words:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Delete misspelled words of the file by a text editor.\n" " # 3 Use this personal dictionary to fix the deleted words:\n" "\n" " hunspell -p words *.odt\n" "\n" msgstr "" "Мисол: hunspell -d en_US file.txt # санҷиши имлои интерактивӣ\n" " hunspell -i utf-8 file.txt # файли рамздори UTF-8-ро тафтиш " "мекунад\n" " hunspell -l *.odt # калимаҳоро бо хатоҳо аз " "файлҳои ODF оп мекунад\n" "\n" " # Ислоҳи тезкор дар ҳуҷҷатҳои ODF тавассути эҷодкунии " "луғатҳои шахсӣ\n" "\n" " # 1 Рӯйхати кутоҳро аз калимаҳои номаълум ё хатоҳо эҷод " "кунед:\n" "\n" " hunspell -l *.odt | sort | uniq >words\n" "\n" " # 2 Калимаҳоро бо хатоҳо аз файл тавассути муҳаррири матн нест " "кунед.\n" " # 3 Барои ислоҳ кардани калимаҳои нестшуда аз ин луғати шахсӣ " "истифода баред:\n" "\n" " hunspell -p words *.odt\n" "\n" #: src/tools/hunspell.cxx:1882 msgid "Bug reports: http://hunspell.github.io/\n" msgstr "Гузоришҳо дар бораи хатоҳо: http://hunspell.github.io/\n" #: src/tools/hunspell.cxx:1890 msgid "" "\n" "Copyright (C) 2002-2014 László Németh. License: MPL/GPL/LGPL.\n" "\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, License: BSD.\n" "\n" msgstr "" "\n" "Ҳуқуқи муаллиф (C) 2002-2014 László Németh. Иҷозатнома: MPL/GPL/LGPL.\n" "\n" "Дар асоси китобхонаи Myspell аз OpenOffice.org.\n" "Ҳуқуқи муаллифи Myspell (C) Kevin Hendricks, 2001-2002, Иҷозатнома: " "BSD.\n" "\n" #: src/tools/hunspell.cxx:1895 msgid "" "This is free software; see the source for copying conditions. There is " "NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR " "PURPOSE,\n" "to the extent permitted by law.\n" msgstr "" "Ин нарамафзори ройгон аст. Барои қоидаҳои нусхабардорӣ ба манбаъ " "нигаред. Ягон\n" "кафолат дода намешавад; ва инчунин барои мақсадҳои ФУРӮШӢ ё МУВОФИҚАТ " "БА МАҚСАДИ МАХСУС,\n" "дар ҳудуди қонунгузорӣ, ягон кафолат дода намешавад.\n" #: src/tools/hunspell.cxx:2056 #, c-format msgid "" "SEARCH PATH:\n" "%s\n" msgstr "" "МАСИРИ ҶУСТУҶӮ:\n" "%s\n" #: src/tools/hunspell.cxx:2060 msgid "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n" msgstr "ЛУҒАТҲОИ ДАСТРАС (масир барои имкони -d ҳатмӣ нест):\n" #: src/tools/hunspell.cxx:2074 #, c-format msgid "" "LOADED DICTIONARY:\n" "%s\n" "%s\n" msgstr "" "ЛУҒАЛИ БОРШУДА:\n" "%s\n" "%s\n" #: src/tools/hunspell.cxx:2094 #, c-format msgid "error - %s exceeds dictionary limit.\n" msgstr "хато - %s маҳдудияти луғатро меафзояд.\n" #: src/tools/hunspell.cxx:2100 #, c-format msgid "" "Can't open affix or dictionary files for dictionary named \"%s\".\n" msgstr "Файлҳо affix ё dic барои луғати \"%s\" кушода намешавад.\n" #: src/tools/hunspell.cxx:2183 msgid "Hunspell has been compiled without Ncurses user interface.\n" msgstr "Hunspell бе интерфейси графикии Ncurses таҳия карда шудааст.\n" hunspell-1.7.0/src/000077500000000000000000000000001337236234000141435ustar00rootroot00000000000000hunspell-1.7.0/src/Makefile.am000066400000000000000000000000371337236234000161770ustar00rootroot00000000000000SUBDIRS=hunspell parsers tools hunspell-1.7.0/src/hunspell/000077500000000000000000000000001337236234000157755ustar00rootroot00000000000000hunspell-1.7.0/src/hunspell/Makefile.am000066400000000000000000000015771337236234000200430ustar00rootroot00000000000000lib_LTLIBRARIES = libhunspell-1.7.la libhunspell_1_7_includedir = $(includedir)/hunspell libhunspell_1_7_la_SOURCES=affentry.cxx affentry.hxx affixmgr.cxx affixmgr.hxx \ atypes.hxx baseaffix.hxx csutil.cxx csutil.hxx \ filemgr.cxx filemgr.hxx hashmgr.cxx hashmgr.hxx \ htypes.hxx hunspell.cxx hunspell.h hunspell.hxx \ hunzip.cxx hunzip.hxx langnum.hxx \ phonet.cxx phonet.hxx replist.cxx replist.hxx \ suggestmgr.cxx suggestmgr.hxx utf_info.hxx w_char.hxx nodist_libhunspell_1_7_la_SOURCES=hunvisapi.h libhunspell_1_7_include_HEADERS=hunspell.hxx hunspell.h hunvisapi.h \ w_char.hxx atypes.hxx libhunspell_1_7_la_LDFLAGS=-no-undefined -version-info 0:1:0 AM_CXXFLAGS=$(CFLAG_VISIBILITY) -DBUILDING_LIBHUNSPELL hunspell-1.7.0/src/hunspell/affentry.cxx000066400000000000000000001026051337236234000203430ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include #include "affentry.hxx" #include "csutil.hxx" AffEntry::~AffEntry() { if (opts & aeLONGCOND) free(c.l.conds2); if (morphcode && !(opts & aeALIASM)) free(morphcode); if (contclass && !(opts & aeALIASF)) free(contclass); } PfxEntry::PfxEntry(AffixMgr* pmgr) // register affix manager : pmyMgr(pmgr), next(NULL), nexteq(NULL), nextne(NULL), flgnxt(NULL) { } // add prefix to this word assuming conditions hold std::string PfxEntry::add(const char* word, size_t len) { std::string result; if ((len > strip.size() || (len == 0 && pmyMgr->get_fullstrip())) && (len >= numconds) && test_condition(word) && (!strip.size() || (strncmp(word, strip.c_str(), strip.size()) == 0))) { /* we have a match so add prefix */ result.assign(appnd); result.append(word + strip.size()); } return result; } 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 ? p : NULL; } return NULL; } 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 && *st) for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++) ; if (*st == '\0' && p) 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' && p) return 0; // word <= condition break; } /* FALLTHROUGH */ 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)) != NULL)) { } } } else if (pos) { ingroup = true; while (p && *p != ']' && ((p = nextchar(p)) != NULL)) { } } } 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) { struct hentry* he; // hash entry of root word or NULL // 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 int tmpl = len - appnd.size(); // length of tmpword if (tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) { // generate new root word by removing prefix and adding // back any characters that would have been stripped std::string tmpword(strip); tmpword.append(word + appnd.size()); // 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.c_str())) { tmpl += strip.size(); if ((he = pmyMgr->lookup(tmpword.c_str())) != 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.c_str(), tmpl, aeXPRODUCT, this, 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) { // 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 int tmpl = len - appnd.size(); // length of tmpword if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) && (tmpl + strip.size() >= numconds)) { // generate new root word by removing prefix and adding // back any characters that would have been stripped std::string tmpword(strip); tmpword.append(word + appnd.size()); // 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.c_str())) { tmpl += strip.size(); // 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)) { // hash entry of root word or NULL struct hentry* he = pmyMgr->suffix_check_twosfx(tmpword.c_str(), tmpl, aeXPRODUCT, this, needflag); if (he) return he; } } } return NULL; } // check if this prefix entry matches std::string PfxEntry::check_twosfx_morph(const char* word, int len, char in_compound, const FLAG needflag) { std::string result; // 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 int tmpl = len - appnd.size(); // length of tmpword if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) && (tmpl + strip.size() >= numconds)) { // generate new root word by removing prefix and adding // back any characters that would have been stripped std::string tmpword(strip); tmpword.append(word + appnd.size()); // 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.c_str())) { tmpl += strip.size(); // 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)) { result = pmyMgr->suffix_check_twosfx_morph(tmpword.c_str(), tmpl, aeXPRODUCT, this, needflag); } } } return result; } // check if this prefix entry matches std::string PfxEntry::check_morph(const char* word, int len, char in_compound, const FLAG needflag) { std::string result; // 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 int tmpl = len - appnd.size(); // length of tmpword if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) && (tmpl + strip.size() >= numconds)) { // generate new root word by removing prefix and adding // back any characters that would have been stripped std::string tmpword(strip); tmpword.append(word + appnd.size()); // 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.c_str())) { tmpl += strip.size(); struct hentry* he; // hash entry of root word or NULL if ((he = pmyMgr->lookup(tmpword.c_str())) != 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) { result.push_back(MSEP_FLD); result.append(morphcode); } else result.append(getKey()); if (!HENTRY_FIND(he, MORPH_STEM)) { result.push_back(MSEP_FLD); result.append(MORPH_STEM); result.append(HENTRY_WORD(he)); } // store the pointer of the hash entry if (HENTRY_DATA(he)) { result.push_back(MSEP_FLD); result.append(HENTRY_DATA2(he)); } else { // return with debug information char* flag = pmyMgr->encode_flag(getFlag()); result.push_back(MSEP_FLD); result.append(MORPH_FLAG); result.append(flag); free(flag); } result.push_back(MSEP_REC); } 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)) { std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, aeXPRODUCT, this, FLAG_NULL, needflag); if (!st.empty()) { result.append(st); } } } } return result; } SfxEntry::SfxEntry(AffixMgr* pmgr) : pmyMgr(pmgr) // register affix manager , next(NULL), nexteq(NULL), nextne(NULL), flgnxt(NULL), l_morph(NULL), r_morph(NULL), eq_morph(NULL) { } // add suffix to this word assuming conditions hold std::string SfxEntry::add(const char* word, size_t len) { std::string result; /* make sure all conditions match */ if ((len > strip.size() || (len == 0 && pmyMgr->get_fullstrip())) && (len >= numconds) && test_condition(word + len, word) && (!strip.size() || (strcmp(word + len - strip.size(), strip.c_str()) == 0))) { result.assign(word); /* we have a match so add suffix */ result.replace(len - strip.size(), std::string::npos, appnd); } return result; } inline char* SfxEntry::nextchar(char* p) { if (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 ? p : NULL; } return NULL; } 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) 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) { // word <= condition if (p) return 0; else return 1; } if ((opts & aeUTF8) && (*st & 0x80)) { // head of the UTF-8 character st--; if (st < beg) { // word <= condition if (p) return 0; else return 1; } } break; } /* FALLTHROUGH */ 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)) != NULL)) { } st--; } if (p && *p != ']') p = nextchar(p); } else if (pos) { if (neg) return 0; else if (i == numconds) return 1; ingroup = true; while (p && *p != ']' && ((p = nextchar(p)) != NULL)) { } // if (p && *p != ']') p = nextchar(p); st--; } if (!pos) { i++; st--; } if (st < beg && p && *p != ']') 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, PfxEntry* ppfx, const FLAG cclass, const FLAG needflag, const FLAG badflag) { struct hentry* he; // hash entry pointer PfxEntry* ep = 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 int tmpl = len - appnd.size(); // length of tmpword // the second condition is not enough for UTF-8 strings // it checked in test_condition() if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) && (tmpl + strip.size() >= 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 std::string tmpstring(word, tmpl); if (strip.size()) { tmpstring.append(strip); } const char* tmpword = tmpstring.c_str(); const char* endword = tmpword + tmpstring.size(); // 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(endword, 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) || (ep && TESTAFF(he->astr, ep->getFlag(), he->alen)) || // enabled by prefix ((contclass) && (ep && 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); } } } return NULL; } // see if two-level suffix is present in the word struct hentry* SfxEntry::check_twosfx(const char* word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag) { PfxEntry* ep = 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 int tmpl = len - appnd.size(); // length of tmpword if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) && (tmpl + strip.size() >= 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 std::string tmpword(word); tmpword.resize(tmpl); tmpword.append(strip); tmpl += strip.size(); const char* beg = tmpword.c_str(); const char* end = beg + tmpl; // 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(end, beg)) { struct hentry* he; // hash entry pointer if (ppfx) { // handle conditional suffix if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) he = pmyMgr->suffix_check(tmpword.c_str(), tmpl, 0, NULL, (FLAG)aflag, needflag, IN_CPD_NOT); else he = pmyMgr->suffix_check(tmpword.c_str(), tmpl, optflags, ppfx, (FLAG)aflag, needflag, IN_CPD_NOT); } else { he = pmyMgr->suffix_check(tmpword.c_str(), tmpl, 0, NULL, (FLAG)aflag, needflag, IN_CPD_NOT); } if (he) return he; } } return NULL; } // see if two-level suffix is present in the word std::string SfxEntry::check_twosfx_morph(const char* word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag) { PfxEntry* ep = ppfx; std::string result; // 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 result; // 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 int tmpl = len - appnd.size(); // length of tmpword if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) && (tmpl + strip.size() >= 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 std::string tmpword(word); tmpword.resize(tmpl); tmpword.append(strip); tmpl += strip.size(); const char* beg = tmpword.c_str(); const char* end = beg + tmpl; // 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(end, beg)) { if (ppfx) { // handle conditional suffix if ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen)) { std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, 0, NULL, aflag, needflag); if (!st.empty()) { if (ppfx->getMorph()) { result.append(ppfx->getMorph()); result.push_back(MSEP_FLD); } result.append(st); mychomp(result); } } else { std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, optflags, ppfx, aflag, needflag); if (!st.empty()) { result.append(st); mychomp(result); } } } else { std::string st = pmyMgr->suffix_check_morph(tmpword.c_str(), tmpl, 0, NULL, aflag, needflag); if (!st.empty()) { result.append(st); mychomp(result); } } } } return result; } // get next homonym with same affix struct hentry* SfxEntry::get_next_homonym(struct hentry* he, int optflags, PfxEntry* ppfx, const FLAG cclass, const FLAG needflag) { PfxEntry* ep = 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; } void SfxEntry::initReverseWord() { rappnd = appnd; reverseword(rappnd); } #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 std::string strip; // string to strip before adding affix std::string appnd; // the affix string to add 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 hunspell-1.7.0/src/hunspell/affentry.hxx000066400000000000000000000203361337236234000203500ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #ifndef AFFIX_HXX_ #define AFFIX_HXX_ #include "atypes.hxx" #include "baseaffix.hxx" #include "affixmgr.hxx" /* A Prefix Entry */ class PfxEntry : public AffEntry { private: PfxEntry(const PfxEntry&); PfxEntry& operator=(const PfxEntry&); private: AffixMgr* pmyMgr; PfxEntry* next; PfxEntry* nexteq; PfxEntry* nextne; PfxEntry* flgnxt; public: explicit PfxEntry(AffixMgr* pmgr); bool allowCross() const { 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 = FLAG_NULL); std::string check_morph(const char* word, int len, char in_compound, const FLAG needflag = FLAG_NULL); std::string check_twosfx_morph(const char* word, int len, char in_compound, const FLAG needflag = FLAG_NULL); FLAG getFlag() { return aflag; } const char* getKey() { return appnd.c_str(); } std::string add(const char* word, size_t len); inline short getKeyLen() { return appnd.size(); } 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 { private: SfxEntry(const SfxEntry&); SfxEntry& operator=(const SfxEntry&); private: AffixMgr* pmyMgr; std::string rappnd; SfxEntry* next; SfxEntry* nexteq; SfxEntry* nextne; SfxEntry* flgnxt; SfxEntry* l_morph; SfxEntry* r_morph; SfxEntry* eq_morph; public: explicit SfxEntry(AffixMgr* pmgr); bool allowCross() const { return ((opts & aeXPRODUCT) != 0); } struct hentry* checkword(const char* word, int len, int optflags, PfxEntry* ppfx, const FLAG cclass, const FLAG needflag, const FLAG badflag); struct hentry* check_twosfx(const char* word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = FLAG_NULL); std::string check_twosfx_morph(const char* word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = FLAG_NULL); struct hentry* get_next_homonym(struct hentry* he); struct hentry* get_next_homonym(struct hentry* word, int optflags, PfxEntry* ppfx, const FLAG cclass, const FLAG needflag); FLAG getFlag() { return aflag; } const char* getKey() { return rappnd.c_str(); } std::string add(const char* word, size_t 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.c_str(); } inline short getKeyLen() { return appnd.size(); } 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; } void initReverseWord(); inline char* nextchar(char* p); inline int test_condition(const char* st, const char* begin); }; #endif hunspell-1.7.0/src/hunspell/affixmgr.cxx000066400000000000000000004510141337236234000203310ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include #include #include #include #include #include #include "affixmgr.hxx" #include "affentry.hxx" #include "langnum.hxx" #include "csutil.hxx" AffixMgr::AffixMgr(const char* affpath, const std::vector& ptr, const char* key) : alldic(ptr) , pHMgr(ptr[0]) { // register hash manager and load affix data from aff file csconv = NULL; utf8 = 0; complexprefixes = 0; parsedmaptable = false; parsedbreaktable = false; iconvtable = NULL; oconvtable = NULL; // allow simplified compound forms (see 3rd field of CHECKCOMPOUNDPATTERN) simplifiedcpd = 0; parsedcheckcpd = false; parseddefcpd = false; 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 compoundmoresuffixes = 0; // allow more suffixes within compound words 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 simplifiedtriple = 0; // allow simplified triple letters in compounds // (Schiff+fahrt -> Schiffahrt) forbiddenword = FORBIDDENWORD; // forbidden word signing flag nosuggest = FLAG_NULL; // don't suggest words signed with NOSUGGEST flag nongramsuggest = FLAG_NULL; 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 pfxappnd = NULL; // previous prefix for counting syllables of the prefix BUG sfxappnd = NULL; // previous suffix for counting syllables of the suffix BUG sfxextra = 0; // modifier for syllable count of sfxappnd BUG checknum = 0; // checking numbers, and word with numbers 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; maxngramsugs = -1; // undefined maxdiff = -1; // undefined onlymaxdiff = 0; maxcpdsugs = -1; // undefined nosplitsugs = 0; sugswithdots = 0; keepcase = 0; forceucase = 0; warn = 0; forbidwarn = 0; checksharps = 0; substandard = FLAG_NULL; fullstrip = 0; 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 = 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 = sStart[j]; SfxEntry* nptr = NULL; while (ptr) { nptr = ptr->getNext(); delete (ptr); ptr = nptr; nptr = NULL; } sStart[j] = NULL; } delete iconvtable; delete oconvtable; delete phone; 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(nongramsuggest); FREE_FLAG(needaffix); FREE_FLAG(lemma_present); FREE_FLAG(circumfix); FREE_FLAG(onlyincompound); cpdwordmax = 0; pHMgr = NULL; cpdmin = 0; cpdmaxsyllable = 0; free_utf_tbl(); checknum = 0; #ifdef MOZILLA_CLIENT delete[] csconv; #endif } void AffixMgr::finishFileMgr(FileMgr* afflst) { delete afflst; // convert affix trees to sorted list process_pfx_tree_to_list(); process_sfx_tree_to_list(); } // read in aff file and build up prefix and suffix entry objects int AffixMgr::parse_file(const char* affpath, const char* key) { // 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 std::string line; while (afflst->getline(line)) { mychomp(line); /* remove byte order mark */ if (firstline) { firstline = 0; // Affix file begins with byte order mark: possible incompatibility with // old Hunspell versions if (line.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) { line.erase(0, 3); } } /* parse in the keyboard string */ if (line.compare(0, 3, "KEY", 3) == 0) { if (!parse_string(line, keystring, afflst->getlinenum())) { finishFileMgr(afflst); return 1; } } /* parse in the try string */ if (line.compare(0, 3, "TRY", 3) == 0) { if (!parse_string(line, trystring, afflst->getlinenum())) { finishFileMgr(afflst); return 1; } } /* parse in the name of the character set used by the .dict and .aff */ if (line.compare(0, 3, "SET", 3) == 0) { if (!parse_string(line, encoding, afflst->getlinenum())) { finishFileMgr(afflst); return 1; } if (encoding == "UTF-8") { utf8 = 1; #ifndef OPENOFFICEORG #ifndef MOZILLA_CLIENT initialize_utf_tbl(); #endif #endif } } /* parse COMPLEXPREFIXES for agglutinative languages with right-to-left * writing system */ if (line.compare(0, 15, "COMPLEXPREFIXES", 15) == 0) complexprefixes = 1; /* parse in the flag used by the controlled compound words */ if (line.compare(0, 12, "COMPOUNDFLAG", 12) == 0) { if (!parse_flag(line, &compoundflag, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by compound words */ if (line.compare(0, 13, "COMPOUNDBEGIN", 13) == 0) { if (complexprefixes) { if (!parse_flag(line, &compoundend, afflst)) { finishFileMgr(afflst); return 1; } } else { if (!parse_flag(line, &compoundbegin, afflst)) { finishFileMgr(afflst); return 1; } } } /* parse in the flag used by compound words */ if (line.compare(0, 14, "COMPOUNDMIDDLE", 14) == 0) { if (!parse_flag(line, &compoundmiddle, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by compound words */ if (line.compare(0, 11, "COMPOUNDEND", 11) == 0) { if (complexprefixes) { if (!parse_flag(line, &compoundbegin, afflst)) { finishFileMgr(afflst); return 1; } } else { if (!parse_flag(line, &compoundend, afflst)) { finishFileMgr(afflst); return 1; } } } /* parse in the data used by compound_check() method */ if (line.compare(0, 15, "COMPOUNDWORDMAX", 15) == 0) { if (!parse_num(line, &cpdwordmax, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag sign compounds in dictionary */ if (line.compare(0, 12, "COMPOUNDROOT", 12) == 0) { if (!parse_flag(line, &compoundroot, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by compound_check() method */ if (line.compare(0, 18, "COMPOUNDPERMITFLAG", 18) == 0) { if (!parse_flag(line, &compoundpermitflag, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by compound_check() method */ if (line.compare(0, 18, "COMPOUNDFORBIDFLAG", 18) == 0) { if (!parse_flag(line, &compoundforbidflag, afflst)) { finishFileMgr(afflst); return 1; } } if (line.compare(0, 20, "COMPOUNDMORESUFFIXES", 20) == 0) { compoundmoresuffixes = 1; } if (line.compare(0, 16, "CHECKCOMPOUNDDUP", 16) == 0) { checkcompounddup = 1; } if (line.compare(0, 16, "CHECKCOMPOUNDREP", 16) == 0) { checkcompoundrep = 1; } if (line.compare(0, 19, "CHECKCOMPOUNDTRIPLE", 19) == 0) { checkcompoundtriple = 1; } if (line.compare(0, 16, "SIMPLIFIEDTRIPLE", 16) == 0) { simplifiedtriple = 1; } if (line.compare(0, 17, "CHECKCOMPOUNDCASE", 17) == 0) { checkcompoundcase = 1; } if (line.compare(0, 9, "NOSUGGEST", 9) == 0) { if (!parse_flag(line, &nosuggest, afflst)) { finishFileMgr(afflst); return 1; } } if (line.compare(0, 14, "NONGRAMSUGGEST", 14) == 0) { if (!parse_flag(line, &nongramsuggest, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by forbidden words */ if (line.compare(0, 13, "FORBIDDENWORD", 13) == 0) { if (!parse_flag(line, &forbiddenword, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by forbidden words (is deprecated) */ if (line.compare(0, 13, "LEMMA_PRESENT", 13) == 0) { if (!parse_flag(line, &lemma_present, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by circumfixes */ if (line.compare(0, 9, "CIRCUMFIX", 9) == 0) { if (!parse_flag(line, &circumfix, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by fogemorphemes */ if (line.compare(0, 14, "ONLYINCOMPOUND", 14) == 0) { if (!parse_flag(line, &onlyincompound, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by `needaffixs' (is deprecated) */ if (line.compare(0, 10, "PSEUDOROOT", 10) == 0) { if (!parse_flag(line, &needaffix, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by `needaffixs' */ if (line.compare(0, 9, "NEEDAFFIX", 9) == 0) { if (!parse_flag(line, &needaffix, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the minimal length for words in compounds */ if (line.compare(0, 11, "COMPOUNDMIN", 11) == 0) { if (!parse_num(line, &cpdmin, afflst)) { finishFileMgr(afflst); return 1; } if (cpdmin < 1) cpdmin = 1; } /* parse in the max. words and syllables in compounds */ if (line.compare(0, 16, "COMPOUNDSYLLABLE", 16) == 0) { if (!parse_cpdsyllable(line, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by compound_check() method */ if (line.compare(0, 11, "SYLLABLENUM", 11) == 0) { if (!parse_string(line, cpdsyllablenum, afflst->getlinenum())) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by the controlled compound words */ if (line.compare(0, 8, "CHECKNUM", 8) == 0) { checknum = 1; } /* parse in the extra word characters */ if (line.compare(0, 9, "WORDCHARS", 9) == 0) { if (!parse_array(line, wordchars, wordchars_utf16, utf8, afflst->getlinenum())) { finishFileMgr(afflst); return 1; } } /* parse in the ignored characters (for example, Arabic optional diacretics * charachters */ if (line.compare(0, 6, "IGNORE", 6) == 0) { if (!parse_array(line, ignorechars, ignorechars_utf16, utf8, afflst->getlinenum())) { finishFileMgr(afflst); return 1; } } /* parse in the input conversion table */ if (line.compare(0, 5, "ICONV", 5) == 0) { if (!parse_convtable(line, afflst, &iconvtable, "ICONV")) { finishFileMgr(afflst); return 1; } } /* parse in the output conversion table */ if (line.compare(0, 5, "OCONV", 5) == 0) { if (!parse_convtable(line, afflst, &oconvtable, "OCONV")) { finishFileMgr(afflst); return 1; } } /* parse in the phonetic translation table */ if (line.compare(0, 5, "PHONE", 5) == 0) { if (!parse_phonetable(line, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the checkcompoundpattern table */ if (line.compare(0, 20, "CHECKCOMPOUNDPATTERN", 20) == 0) { if (!parse_checkcpdtable(line, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the defcompound table */ if (line.compare(0, 12, "COMPOUNDRULE", 12) == 0) { if (!parse_defcpdtable(line, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the related character map table */ if (line.compare(0, 3, "MAP", 3) == 0) { if (!parse_maptable(line, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the word breakpoints table */ if (line.compare(0, 5, "BREAK", 5) == 0) { if (!parse_breaktable(line, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the language for language specific codes */ if (line.compare(0, 4, "LANG", 4) == 0) { if (!parse_string(line, lang, afflst->getlinenum())) { finishFileMgr(afflst); return 1; } langnum = get_lang_num(lang); } if (line.compare(0, 7, "VERSION", 7) == 0) { size_t startpos = line.find_first_not_of(" \t", 7); if (startpos != std::string::npos) { version = line.substr(startpos); } } if (line.compare(0, 12, "MAXNGRAMSUGS", 12) == 0) { if (!parse_num(line, &maxngramsugs, afflst)) { finishFileMgr(afflst); return 1; } } if (line.compare(0, 11, "ONLYMAXDIFF", 11) == 0) onlymaxdiff = 1; if (line.compare(0, 7, "MAXDIFF", 7) == 0) { if (!parse_num(line, &maxdiff, afflst)) { finishFileMgr(afflst); return 1; } } if (line.compare(0, 10, "MAXCPDSUGS", 10) == 0) { if (!parse_num(line, &maxcpdsugs, afflst)) { finishFileMgr(afflst); return 1; } } if (line.compare(0, 11, "NOSPLITSUGS", 11) == 0) { nosplitsugs = 1; } if (line.compare(0, 9, "FULLSTRIP", 9) == 0) { fullstrip = 1; } if (line.compare(0, 12, "SUGSWITHDOTS", 12) == 0) { sugswithdots = 1; } /* parse in the flag used by forbidden words */ if (line.compare(0, 8, "KEEPCASE", 8) == 0) { if (!parse_flag(line, &keepcase, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by `forceucase' */ if (line.compare(0, 10, "FORCEUCASE", 10) == 0) { if (!parse_flag(line, &forceucase, afflst)) { finishFileMgr(afflst); return 1; } } /* parse in the flag used by `warn' */ if (line.compare(0, 4, "WARN", 4) == 0) { if (!parse_flag(line, &warn, afflst)) { finishFileMgr(afflst); return 1; } } if (line.compare(0, 10, "FORBIDWARN", 10) == 0) { forbidwarn = 1; } /* parse in the flag used by the affix generator */ if (line.compare(0, 11, "SUBSTANDARD", 11) == 0) { if (!parse_flag(line, &substandard, afflst)) { finishFileMgr(afflst); return 1; } } if (line.compare(0, 11, "CHECKSHARPS", 11) == 0) { checksharps = 1; } /* parse this affix: P - prefix, S - suffix */ // affix type char ft = ' '; if (line.compare(0, 3, "PFX", 3) == 0) ft = complexprefixes ? 'S' : 'P'; if (line.compare(0, 3, "SFX", 3) == 0) ft = complexprefixes ? 'P' : 'S'; if (ft != ' ') { if (dupflags_ini) { memset(dupflags, 0, sizeof(dupflags)); dupflags_ini = 0; } if (!parse_affix(line, ft, afflst, dupflags)) { finishFileMgr(afflst); return 1; } } } finishFileMgr(afflst); // affix trees are sorted now // 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 // initialize // the nextne and nexteq pointers that relate them process_pfx_order(); process_sfx_order(); /* get encoding for CHECKCOMPOUNDCASE */ if (!utf8) { csconv = get_current_cs(get_encoding()); for (int i = 0; i <= 255; i++) { if ((csconv[i].cupper != csconv[i].clower) && (wordchars.find((char)i) == std::string::npos)) { wordchars.push_back((char)i); } } } // default BREAK definition if (!parsedbreaktable) { breaktable.push_back("-"); breaktable.push_back("^-"); breaktable.push_back("-$"); parsedbreaktable = true; } 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(PfxEntry* pfxptr) { PfxEntry* ptr; PfxEntry* pptr; PfxEntry* ep = 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 = pFlag[flg]; ep->setFlgNxt(ptr); pFlag[flg] = ep; // handle the special case of null affix string if (strlen(key) == 0) { // always inset them at head of list at element 0 ptr = pStart[0]; ep->setNext(ptr); pStart[0] = ep; return 0; } // now handle the normal case ep->setNextEQ(NULL); ep->setNextNE(NULL); unsigned char sp = *((const unsigned char*)key); ptr = pStart[sp]; // handle the first insert if (!ptr) { pStart[sp] = 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(SfxEntry* sfxptr) { sfxptr->initReverseWord(); SfxEntry* ptr; SfxEntry* pptr; SfxEntry* ep = 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 = sFlag[flg]; ep->setFlgNxt(ptr); sFlag[flg] = 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 = sStart[0]; ep->setNext(ptr); sStart[0] = ep; return 0; } // now handle the normal case ep->setNextEQ(NULL); ep->setNextNE(NULL); unsigned char sp = *((const unsigned char*)key); ptr = sStart[sp]; // handle the first insert if (!ptr) { sStart[sp] = 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; } PfxEntry* AffixMgr::process_pfx_in_order(PfxEntry* ptr, PfxEntry* nptr) { if (ptr) { nptr = process_pfx_in_order(ptr->getNextNE(), nptr); ptr->setNext(nptr); nptr = process_pfx_in_order(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; } SfxEntry* AffixMgr::process_sfx_in_order(SfxEntry* ptr, SfxEntry* nptr) { if (ptr) { nptr = process_sfx_in_order(ptr->getNextNE(), nptr); ptr->setNext(nptr); nptr = process_sfx_in_order(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 = 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 = 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 = 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 = 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 std::string& AffixMgr::debugflag(std::string& result, unsigned short flag) { char* st = encode_flag(flag); result.push_back(MSEP_FLD); result.append(MORPH_FLAG); if (st) { result.append(st); free(st); } return result; } // calculate the character length of the condition int AffixMgr::condlen(const 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(AffEntry& entry, const char* cs) { if (strcmp(cs, ".") != 0) { entry.numconds = (char)condlen(cs); const size_t cslen = strlen(cs); const size_t short_part = std::min(MAXCONDLEN, cslen); memcpy(entry.c.conds, cs, short_part); if (short_part < MAXCONDLEN) { //blank out the remaining space memset(entry.c.conds + short_part, 0, MAXCONDLEN - short_part); } else if (cs[MAXCONDLEN]) { //there is more conditions than fit in fixed space, so its //a long condition entry.opts += aeLONGCOND; entry.c.l.conds2 = mystrdup(cs + MAXCONDLEN_1); if (!entry.c.l.conds2) return 1; } } else { entry.numconds = 0; entry.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; sfxextra = 0; // first handle the special case of 0 length prefixes PfxEntry* pe = 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 = pe; // BUG: pfx not stateless return rv; } } pe = pe->getNext(); } // now handle the general case unsigned char sp = *((const unsigned char*)word); PfxEntry* pptr = 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 = pptr; // BUG: pfx not stateless return rv; } } pptr = pptr->getNextEQ(); } else { pptr = pptr->getNextNE(); } } return NULL; } // check word for prefixes and two-level suffixes 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; sfxextra = 0; // first handle the special case of 0 length prefixes PfxEntry* pe = 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 = pStart[sp]; while (pptr) { if (isSubset(pptr->getKey(), word)) { rv = pptr->check_twosfx(word, len, in_compound, needflag); if (rv) { pfx = pptr; return rv; } pptr = pptr->getNextEQ(); } else { pptr = pptr->getNextNE(); } } return NULL; } // check word for prefixes and morph std::string AffixMgr::prefix_check_morph(const char* word, int len, char in_compound, const FLAG needflag) { std::string result; pfx = NULL; sfxappnd = NULL; sfxextra = 0; // first handle the special case of 0 length prefixes PfxEntry* pe = pStart[0]; while (pe) { std::string st = pe->check_morph(word, len, in_compound, needflag); if (!st.empty()) { result.append(st); } pe = pe->getNext(); } // now handle the general case unsigned char sp = *((const unsigned char*)word); PfxEntry* pptr = pStart[sp]; while (pptr) { if (isSubset(pptr->getKey(), word)) { std::string st = pptr->check_morph(word, len, in_compound, needflag); if (!st.empty()) { // fogemorpheme if ((in_compound != IN_CPD_NOT) || !((pptr->getCont() && (TESTAFF(pptr->getCont(), onlyincompound, pptr->getContLen()))))) { result.append(st); pfx = pptr; } } pptr = pptr->getNextEQ(); } else { pptr = pptr->getNextNE(); } } return result; } // check word for prefixes and morph and two-level suffixes std::string AffixMgr::prefix_check_twosfx_morph(const char* word, int len, char in_compound, const FLAG needflag) { std::string result; pfx = NULL; sfxappnd = NULL; sfxextra = 0; // first handle the special case of 0 length prefixes PfxEntry* pe = pStart[0]; while (pe) { std::string st = pe->check_twosfx_morph(word, len, in_compound, needflag); if (!st.empty()) { result.append(st); } pe = pe->getNext(); } // now handle the general case unsigned char sp = *((const unsigned char*)word); PfxEntry* pptr = pStart[sp]; while (pptr) { if (isSubset(pptr->getKey(), word)) { std::string st = pptr->check_twosfx_morph(word, len, in_compound, needflag); if (!st.empty()) { result.append(st); pfx = pptr; } pptr = pptr->getNextEQ(); } else { pptr = pptr->getNextNE(); } } return result; } // Is word a non-compound with a REP substitution (see checkcompoundrep)? int AffixMgr::cpdrep_check(const char* word, int wl) { if ((wl < 2) || get_reptable().empty()) return 0; for (size_t i = 0; i < get_reptable().size(); ++i) { // use only available mid patterns if (!get_reptable()[i].outstrings[0].empty()) { const char* r = word; const size_t lenp = get_reptable()[i].pattern.size(); // search every occurence of the pattern in the word while ((r = strstr(r, get_reptable()[i].pattern.c_str())) != NULL) { std::string candidate(word); candidate.replace(r - word, lenp, get_reptable()[i].outstrings[0]); if (candidate_check(candidate.c_str(), candidate.size())) return 1; ++r; // search for the next letter } } } return 0; } // forbid compound words, if they are in the dictionary as a // word pair separated by space int AffixMgr::cpdwordpair_check(const char * word, int wl) { if (wl > 2) { std::string candidate(word); for (size_t i = 1; i < candidate.size(); i++) { // go to end of the UTF-8 character if (utf8 && ((word[i] & 0xc0) == 0x80)) continue; candidate.insert(i, 1, ' '); if (candidate_check(candidate.c_str(), candidate.size())) return 1; candidate.erase(i, 1); } } return 0; } // forbid compoundings when there are special patterns at word bound int AffixMgr::cpdpat_check(const char* word, int pos, hentry* r1, hentry* r2, const char /*affixed*/) { for (size_t i = 0; i < checkcpdtable.size(); ++i) { size_t len; if (isSubset(checkcpdtable[i].pattern2.c_str(), word + pos) && (!r1 || !checkcpdtable[i].cond || (r1->astr && TESTAFF(r1->astr, checkcpdtable[i].cond, r1->alen))) && (!r2 || !checkcpdtable[i].cond2 || (r2->astr && TESTAFF(r2->astr, checkcpdtable[i].cond2, r2->alen))) && // zero length pattern => only TESTAFF // zero pattern (0/flag) => unmodified stem (zero affixes allowed) (checkcpdtable[i].pattern.empty() || ((checkcpdtable[i].pattern[0] == '0' && r1->blen <= pos && strncmp(word + pos - r1->blen, r1->word, r1->blen) == 0) || (checkcpdtable[i].pattern[0] != '0' && ((len = checkcpdtable[i].pattern.size()) != 0) && strncmp(word + pos - len, checkcpdtable[i].pattern.c_str(), 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) { const char* p; for (p = word + pos - 1; (*p & 0xc0) == 0x80; p--) ; std::string pair(p); std::vector pair_u; u8_u16(pair_u, pair); unsigned short a = pair_u.size() > 1 ? ((pair_u[1].h << 8) + pair_u[1].l) : 0; unsigned short b = !pair_u.empty() ? ((pair_u[0].h << 8) + pair_u[0].l) : 0; if (((unicodetoupper(a, langnum) == a) || (unicodetoupper(b, langnum) == b)) && (a != '-') && (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; } struct metachar_data { signed short btpp; // metacharacter (*, ?) position for backtracking signed short btwp; // word position for metacharacters int btnum; // number of matched characters in metacharacter }; // check compound patterns int AffixMgr::defcpd_check(hentry*** words, short wnum, hentry* rv, hentry** def, char all) { int w = 0; if (!*words) { w = 1; *words = def; } if (!*words) { return 0; } std::vector btinfo(1); short bt = 0; (*words)[wnum] = rv; // has the last word COMPOUNDRULE flag? if (rv->alen == 0) { (*words)[wnum] = NULL; if (w) *words = NULL; return 0; } int ok = 0; for (size_t i = 0; i < defcpdtable.size(); ++i) { for (size_t j = 0; j < defcpdtable[i].size(); ++j) { if (defcpdtable[i][j] != '*' && defcpdtable[i][j] != '?' && TESTAFF(rv->astr, defcpdtable[i][j], rv->alen)) { ok = 1; break; } } } if (ok == 0) { (*words)[wnum] = NULL; if (w) *words = NULL; return 0; } for (size_t i = 0; i < defcpdtable.size(); ++i) { size_t pp = 0; // pattern position signed short wp = 0; // "words" position int ok2; ok = 1; ok2 = 1; do { while ((pp < defcpdtable[i].size()) && (wp <= wnum)) { if (((pp + 1) < defcpdtable[i].size()) && ((defcpdtable[i][pp + 1] == '*') || (defcpdtable[i][pp + 1] == '?'))) { int wend = (defcpdtable[i][pp + 1] == '?') ? wp : wnum; ok2 = 1; pp += 2; btinfo[bt].btpp = pp; btinfo[bt].btwp = wp; while (wp <= wend) { if (!(*words)[wp]->alen || !TESTAFF((*words)[wp]->astr, defcpdtable[i][pp - 2], (*words)[wp]->alen)) { ok2 = 0; break; } wp++; } if (wp <= wnum) ok2 = 0; btinfo[bt].btnum = wp - btinfo[bt].btwp; if (btinfo[bt].btnum > 0) { ++bt; btinfo.resize(bt+1); } if (ok2) break; } else { ok2 = 1; if (!(*words)[wp] || !(*words)[wp]->alen || !TESTAFF((*words)[wp]->astr, defcpdtable[i][pp], (*words)[wp]->alen)) { ok = 0; break; } pp++; wp++; if ((defcpdtable[i].size() == pp) && !(wp > wnum)) ok = 0; } } if (ok && ok2) { size_t r = pp; while ((defcpdtable[i].size() > r) && ((r + 1) < defcpdtable[i].size()) && ((defcpdtable[i][r + 1] == '*') || (defcpdtable[i][r + 1] == '?'))) r += 2; if (defcpdtable[i].size() <= r) return 1; } // backtrack if (bt) do { ok = 1; btinfo[bt - 1].btnum--; pp = btinfo[bt - 1].btpp; wp = btinfo[bt - 1].btwp + (signed short)btinfo[bt - 1].btnum; } while ((btinfo[bt - 1].btnum < 0) && --bt); } while (bt); if (ok && ok2 && (!all || (defcpdtable[i].size() <= pp))) return 1; // check zero ending while (ok && ok2 && (defcpdtable[i].size() > pp) && ((pp + 1) < defcpdtable[i].size()) && ((defcpdtable[i][pp + 1] == '*') || (defcpdtable[i][pp + 1] == '?'))) pp += 2; if (ok && ok2 && (defcpdtable[i].size() <= 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 = 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 std::string& word) { if (cpdmaxsyllable == 0) return 0; short num = 0; if (!utf8) { for (size_t i = 0; i < word.size(); ++i) { if (std::binary_search(cpdvowels.begin(), cpdvowels.end(), word[i])) { ++num; } } } else if (!cpdvowels_utf16.empty()) { std::vector w; u8_u16(w, word); for (size_t i = 0; i < w.size(); ++i) { if (std::binary_search(cpdvowels_utf16.begin(), cpdvowels_utf16.end(), w[i])) { ++num; } } } return num; } void AffixMgr::setcminmax(int* cmin, int* cmax, const char* word, int len) { if (utf8) { int i; for (*cmin = 0, i = 0; (i < cpdmin) && *cmin < len; i++) { for ((*cmin)++; *cmin < len && (word[*cmin] & 0xc0) == 0x80; (*cmin)++) ; } for (*cmax = len, i = 0; (i < (cpdmin - 1)) && *cmax >= 0; i++) { for ((*cmax)--; *cmax >= 0 && (word[*cmax] & 0xc0) == 0x80; (*cmax)--) ; } } else { *cmin = cpdmin; *cmax = len - cpdmin + 1; } } // check if compound word is correctly spelled // hu_mov_rule = spec. Hungarian rule (XXX) struct hentry* AffixMgr::compound_check(const std::string& word, short wordnum, short numsyllable, short maxwordnum, short wnum, hentry** words = NULL, hentry** rwords = NULL, char hu_mov_rule = 0, char is_sug = 0, int* info = NULL) { int i; short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2; struct hentry* rv = NULL; struct hentry* rv_first; std::string st; char ch = '\0'; int cmin; int cmax; int striple = 0; size_t scpd = 0; int soldi = 0; int oldcmin = 0; int oldcmax = 0; int oldlen = 0; int checkedstriple = 0; char affixed = 0; hentry** oldwords = words; size_t len = word.size(); int checked_prefix; // add a time limit to handle possible // combinatorical explosion of the overlapping words HUNSPELL_THREAD_LOCAL clock_t timelimit; if (wordnum == 0) timelimit = clock(); else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) { timelimit = 0; } setcminmax(&cmin, &cmax, word.c_str(), len); st.assign(word); for (i = cmin; i < cmax; i++) { // go to end of the UTF-8 character if (utf8) { for (; (st[i] & 0xc0) == 0x80; i++) ; if (i >= cmax) return NULL; } words = oldwords; int onlycpdrule = (words) ? 1 : 0; do { // onlycpdrule loop oldnumsyllable = numsyllable; oldwordnum = wordnum; checked_prefix = 0; do { // simplified checkcompoundpattern loop if (timelimit == 0) return 0; if (scpd > 0) { for (; scpd <= checkcpdtable.size() && (checkcpdtable[scpd - 1].pattern3.empty() || strncmp(word.c_str() + i, checkcpdtable[scpd - 1].pattern3.c_str(), checkcpdtable[scpd - 1].pattern3.size()) != 0); scpd++) ; if (scpd > checkcpdtable.size()) break; // break simplified checkcompoundpattern loop st.replace(i, std::string::npos, checkcpdtable[scpd - 1].pattern); soldi = i; i += checkcpdtable[scpd - 1].pattern.size(); st.replace(i, std::string::npos, checkcpdtable[scpd - 1].pattern2); st.replace(i + checkcpdtable[scpd - 1].pattern2.size(), std::string::npos, word.substr(soldi + checkcpdtable[scpd - 1].pattern3.size())); oldlen = len; len += checkcpdtable[scpd - 1].pattern.size() + checkcpdtable[scpd - 1].pattern2.size() - checkcpdtable[scpd - 1].pattern3.size(); oldcmin = cmin; oldcmax = cmax; setcminmax(&cmin, &cmax, st.c_str(), len); cmax = len - cpdmin + 1; } ch = st[i]; st[i] = '\0'; sfx = NULL; pfx = NULL; // FIRST WORD affixed = 1; rv = lookup(st.c_str()); // perhaps without prefix // forbid dictionary stems with COMPOUNDFORBIDFLAG in // compound words, overriding the effect of COMPOUNDPERMITFLAG if ((rv) && compoundforbidflag && TESTAFF(rv->astr, compoundforbidflag, rv->alen) && !hu_mov_rule) continue; // search homonym with compound flag while ((rv) && !hu_mov_rule && ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) || !((compoundflag && !words && !onlycpdrule && TESTAFF(rv->astr, compoundflag, rv->alen)) || (compoundbegin && !wordnum && !onlycpdrule && TESTAFF(rv->astr, compoundbegin, rv->alen)) || (compoundmiddle && wordnum && !words && !onlycpdrule && TESTAFF(rv->astr, compoundmiddle, rv->alen)) || (!defcpdtable.empty() && onlycpdrule && ((!words && !wordnum && defcpd_check(&words, wnum, rv, rwords, 0)) || (words && defcpd_check(&words, wnum, rv, rwords, 0))))) || (scpd != 0 && checkcpdtable[scpd - 1].cond != FLAG_NULL && !TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond, rv->alen)))) { rv = rv->next_homonym; } if (rv) affixed = 0; if (!rv) { if (onlycpdrule) break; if (compoundflag && !(rv = prefix_check(st.c_str(), i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) { if (((rv = suffix_check( st.c_str(), i, 0, NULL, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || (compoundmoresuffixes && (rv = suffix_check_twosfx(st.c_str(), i, 0, NULL, compoundflag)))) && !hu_mov_rule && sfx->getCont() && ((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())) || (compoundend && TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) { rv = NULL; } } if (rv || (((wordnum == 0) && compoundbegin && ((rv = suffix_check( st.c_str(), i, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || (compoundmoresuffixes && (rv = suffix_check_twosfx( st.c_str(), i, 0, NULL, compoundbegin))) || // twofold suffixes + compound (rv = prefix_check(st.c_str(), i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) || ((wordnum > 0) && compoundmiddle && ((rv = suffix_check( st.c_str(), i, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || (compoundmoresuffixes && (rv = suffix_check_twosfx( st.c_str(), i, 0, NULL, compoundmiddle))) || // twofold suffixes + compound (rv = prefix_check(st.c_str(), 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) || TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) || (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen)))) { st[i] = ch; // continue; break; } // check non_compound flag in suffix and prefix if ((rv) && !hu_mov_rule && ((pfx && pfx->getCont() && TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())))) { rv = NULL; } // check compoundend flag in suffix and prefix if ((rv) && !checked_prefix && compoundend && !hu_mov_rule && ((pfx && pfx->getCont() && TESTAFF(pfx->getCont(), compoundend, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) { rv = NULL; } // check compoundmiddle flag in suffix and prefix if ((rv) && !checked_prefix && (wordnum == 0) && compoundmiddle && !hu_mov_rule && ((pfx && pfx->getCont() && TESTAFF(pfx->getCont(), compoundmiddle, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundmiddle, sfx->getContLen())))) { rv = NULL; } // check forbiddenwords if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || TESTAFF(rv->astr, ONLYUPCASEFLAG, 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)) // 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 ) && ( // test CHECKCOMPOUNDPATTERN conditions scpd == 0 || checkcpdtable[scpd - 1].cond == FLAG_NULL || TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond, rv->alen)) && !((checkcompoundtriple && scpd == 0 && !words && // 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' )) || (checkcompoundcase && scpd == 0 && !words && cpdcase_check(word.c_str(), i)))) // LANG_hu section: spec. Hungarian rule || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st.c_str(), i)) && (sfx && sfx->getCont() && ( // XXX hardwired Hungarian dic. codes TESTAFF(sfx->getCont(), (unsigned short)'x', sfx->getContLen()) || TESTAFF( sfx->getCont(), (unsigned short)'%', sfx->getContLen()))))) { // first word is ok condition // LANG_hu section: spec. Hungarian rule if (langnum == LANG_hu) { // calculate syllable number of the word numsyllable += get_syllable(st.substr(0, i)); // + 1 word, if syllable number of the prefix > 1 (hungarian // convention) if (pfx && (get_syllable(pfx->getKey()) > 1)) wordnum++; } // END of LANG_hu section // NEXT WORD(S) rv_first = rv; st[i] = ch; do { // striple loop // check simplifiedtriple if (simplifiedtriple) { if (striple) { checkedstriple = 1; i--; // check "fahrt" instead of "ahrt" in "Schiffahrt" } else if (i > 2 && word[i - 1] == word[i - 2]) striple = 1; } rv = lookup(st.c_str() + 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)) || (!defcpdtable.empty() && words && defcpd_check(&words, wnum + 1, rv, NULL, 1))) || (scpd != 0 && checkcpdtable[scpd - 1].cond2 != FLAG_NULL && !TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen)))) { rv = rv->next_homonym; } // check FORCEUCASE if (rv && forceucase && (rv) && (TESTAFF(rv->astr, forceucase, rv->alen)) && !(info && *info & SPELL_ORIGCAP)) rv = NULL; if (rv && words && words[wnum + 1]) return rv_first; 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) || TESTAFF(rv->astr, ONLYUPCASEFLAG, 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 + 1 < cpdwordmax)) || ((cpdmaxsyllable != 0) && (numsyllable + get_syllable(std::string(HENTRY_WORD(rv), rv->blen)) <= cpdmaxsyllable))) && ( // test CHECKCOMPOUNDPATTERN checkcpdtable.empty() || scpd != 0 || !cpdpat_check(word.c_str(), i, rv_first, rv, 0)) && ((!checkcompounddup || (rv != rv_first))) // test CHECKCOMPOUNDPATTERN conditions && (scpd == 0 || checkcpdtable[scpd - 1].cond2 == FLAG_NULL || TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen))) { // forbid compound word, if it is a non-compound word with typical // fault if ((checkcompoundrep && cpdrep_check(word.c_str(), len)) || cpdwordpair_check(word.c_str(), len)) return NULL; return rv_first; } numsyllable = oldnumsyllable2; wordnum = oldwordnum2; // perhaps second word has prefix or/and suffix sfx = NULL; sfxflag = FLAG_NULL; rv = (compoundflag && !onlycpdrule) ? affix_check((word.c_str() + i), strlen(word.c_str() + i), compoundflag, IN_CPD_END) : NULL; if (!rv && compoundend && !onlycpdrule) { sfx = NULL; pfx = NULL; rv = affix_check((word.c_str() + i), strlen(word.c_str() + i), compoundend, IN_CPD_END); } if (!rv && !defcpdtable.empty() && words) { rv = affix_check((word.c_str() + i), strlen(word.c_str() + i), 0, IN_CPD_END); if (rv && defcpd_check(&words, wnum + 1, rv, NULL, 1)) return rv_first; rv = NULL; } // test CHECKCOMPOUNDPATTERN conditions (allowed forms) if (rv && !(scpd == 0 || checkcpdtable[scpd - 1].cond2 == FLAG_NULL || TESTAFF(rv->astr, checkcpdtable[scpd - 1].cond2, rv->alen))) rv = NULL; // test CHECKCOMPOUNDPATTERN conditions (forbidden compounds) if (rv && !checkcpdtable.empty() && scpd == 0 && cpdpat_check(word.c_str(), i, rv_first, rv, affixed)) rv = NULL; // check non_compound flag in suffix and prefix if ((rv) && ((pfx && pfx->getCont() && TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())))) { rv = NULL; } // check FORCEUCASE if (rv && forceucase && (rv) && (TESTAFF(rv->astr, forceucase, rv->alen)) && !(info && *info & SPELL_ORIGCAP)) rv = NULL; // check forbiddenwords if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || TESTAFF(rv->astr, ONLYUPCASEFLAG, 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.c_str() + i); // - affix syllable num. // XXX only second suffix (inflections, not derivations) if (sfxappnd) { std::string tmp(sfxappnd); reverseword(tmp); numsyllable -= short(get_syllable(tmp) + sfxextra); } else { numsyllable -= short(sfxextra); } // + 1 word, if syllable number of the prefix > 1 (hungarian // convention) if (pfx && (get_syllable(pfx->getKey()) > 1)) wordnum++; // increment syllable num, if last word has a SYLLABLENUM flag // and the suffix is beginning `s' if (!cpdsyllablenum.empty()) { 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 < 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.c_str(), len)) || cpdwordpair_check(word.c_str(), len)) return NULL; return rv_first; } numsyllable = oldnumsyllable2; wordnum = oldwordnum2; // perhaps second word is a compound word (recursive call) if (wordnum + 2 < maxwordnum) { rv = compound_check(st.substr(i), wordnum + 1, numsyllable, maxwordnum, wnum + 1, words, rwords, 0, is_sug, info); if (rv && !checkcpdtable.empty() && ((scpd == 0 && cpdpat_check(word.c_str(), i, rv_first, rv, affixed)) || (scpd != 0 && !cpdpat_check(word.c_str(), i, rv_first, rv, affixed)))) rv = NULL; } else { rv = NULL; } if (rv) { // forbid compound word, if it is a non-compound word with typical // fault, or a dictionary word pair if (cpdwordpair_check(word.c_str(), len)) return NULL; if (checkcompoundrep || forbiddenword) { if (checkcompoundrep && cpdrep_check(word.c_str(), len)) return NULL; // check first part if (strncmp(rv->word, word.c_str() + i, rv->blen) == 0) { char r = st[i + rv->blen]; st[i + rv->blen] = '\0'; if ((checkcompoundrep && cpdrep_check(st.c_str(), i + rv->blen)) || cpdwordpair_check(st.c_str(), i + rv->blen)) { st[ + i + rv->blen] = r; continue; } if (forbiddenword) { struct hentry* rv2 = lookup(word.c_str()); if (!rv2) rv2 = affix_check(word.c_str(), len); if (rv2 && rv2->astr && TESTAFF(rv2->astr, forbiddenword, rv2->alen) && (strncmp(rv2->word, st.c_str(), i + rv->blen) == 0)) { return NULL; } } st[i + rv->blen] = r; } } return rv_first; } } while (striple && !checkedstriple); // end of striple loop if (checkedstriple) { i++; checkedstriple = 0; striple = 0; } } // first word is ok condition if (soldi != 0) { i = soldi; soldi = 0; len = oldlen; cmin = oldcmin; cmax = oldcmax; } scpd++; } while (!onlycpdrule && simplifiedcpd && scpd <= checkcpdtable.size()); // end of simplifiedcpd loop scpd = 0; wordnum = oldwordnum; numsyllable = oldnumsyllable; if (soldi != 0) { i = soldi; st.assign(word); // XXX add more optim. soldi = 0; } else st[i] = ch; } while (!defcpdtable.empty() && oldwordnum == 0 && onlycpdrule++ < 1); // end of onlycpd loop } 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, hentry** rwords, char hu_mov_rule, std::string& result, const std::string* partresult) { int i; short oldnumsyllable, oldnumsyllable2, oldwordnum, oldwordnum2; int ok = 0; struct hentry* rv = NULL; struct hentry* rv_first; std::string st; char ch; int checked_prefix; std::string presult; int cmin; int cmax; char affixed = 0; hentry** oldwords = words; // add a time limit to handle possible // combinatorical explosion of the overlapping words HUNSPELL_THREAD_LOCAL clock_t timelimit; if (wordnum == 0) timelimit = clock(); else if (timelimit != 0 && (clock() > timelimit + TIMELIMIT)) { timelimit = 0; } setcminmax(&cmin, &cmax, word, len); st.assign(word); for (i = cmin; i < cmax; i++) { // go to end of the UTF-8 character if (utf8) { for (; (st[i] & 0xc0) == 0x80; i++) ; if (i >= cmax) return 0; } words = oldwords; int onlycpdrule = (words) ? 1 : 0; do { // onlycpdrule loop if (timelimit == 0) return 0; oldnumsyllable = numsyllable; oldwordnum = wordnum; checked_prefix = 0; ch = st[i]; st[i] = '\0'; sfx = NULL; // FIRST WORD affixed = 1; presult.clear(); if (partresult) presult.append(*partresult); rv = lookup(st.c_str()); // perhaps without prefix // forbid dictionary stems with COMPOUNDFORBIDFLAG in // compound words, overriding the effect of COMPOUNDPERMITFLAG if ((rv) && compoundforbidflag && TESTAFF(rv->astr, compoundforbidflag, rv->alen) && !hu_mov_rule) continue; // search homonym with compound flag while ((rv) && !hu_mov_rule && ((needaffix && TESTAFF(rv->astr, needaffix, rv->alen)) || !((compoundflag && !words && !onlycpdrule && TESTAFF(rv->astr, compoundflag, rv->alen)) || (compoundbegin && !wordnum && !onlycpdrule && TESTAFF(rv->astr, compoundbegin, rv->alen)) || (compoundmiddle && wordnum && !words && !onlycpdrule && TESTAFF(rv->astr, compoundmiddle, rv->alen)) || (!defcpdtable.empty() && onlycpdrule && ((!words && !wordnum && defcpd_check(&words, wnum, rv, rwords, 0)) || (words && defcpd_check(&words, wnum, rv, rwords, 0))))))) { rv = rv->next_homonym; } if (timelimit == 0) return 0; if (rv) affixed = 0; if (rv) { presult.push_back(MSEP_FLD); presult.append(MORPH_PART); presult.append(st.c_str()); if (!HENTRY_FIND(rv, MORPH_STEM)) { presult.push_back(MSEP_FLD); presult.append(MORPH_STEM); presult.append(st.c_str()); } if (HENTRY_DATA(rv)) { presult.push_back(MSEP_FLD); presult.append(HENTRY_DATA2(rv)); } } if (!rv) { if (compoundflag && !(rv = prefix_check(st.c_str(), i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) { if (((rv = suffix_check(st.c_str(), i, 0, NULL, FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || (compoundmoresuffixes && (rv = suffix_check_twosfx(st.c_str(), i, 0, NULL, compoundflag)))) && !hu_mov_rule && sfx->getCont() && ((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())) || (compoundend && TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) { rv = NULL; } } if (rv || (((wordnum == 0) && compoundbegin && ((rv = suffix_check(st.c_str(), i, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || (compoundmoresuffixes && (rv = suffix_check_twosfx( st.c_str(), i, 0, NULL, compoundbegin))) || // twofold suffix+compound (rv = prefix_check(st.c_str(), i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) || ((wordnum > 0) && compoundmiddle && ((rv = suffix_check(st.c_str(), i, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || (compoundmoresuffixes && (rv = suffix_check_twosfx( st.c_str(), i, 0, NULL, compoundmiddle))) || // twofold suffix+compound (rv = prefix_check(st.c_str(), i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))) { std::string p; if (compoundflag) p = affix_check_morph(st.c_str(), i, compoundflag); if (p.empty()) { if ((wordnum == 0) && compoundbegin) { p = affix_check_morph(st.c_str(), i, compoundbegin); } else if ((wordnum > 0) && compoundmiddle) { p = affix_check_morph(st.c_str(), i, compoundmiddle); } } if (!p.empty()) { presult.push_back(MSEP_FLD); presult.append(MORPH_PART); presult.append(st.c_str()); line_uniq_app(p, MSEP_REC); presult.append(p); } checked_prefix = 1; } // else check forbiddenwords } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) || TESTAFF(rv->astr, ONLYUPCASEFLAG, 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 && pfx->getCont() && TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())))) { continue; } // check compoundend flag in suffix and prefix if ((rv) && !checked_prefix && compoundend && !hu_mov_rule && ((pfx && pfx->getCont() && TESTAFF(pfx->getCont(), compoundend, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundend, sfx->getContLen())))) { continue; } // check compoundmiddle flag in suffix and prefix if ((rv) && !checked_prefix && (wordnum == 0) && compoundmiddle && !hu_mov_rule && ((pfx && pfx->getCont() && TESTAFF(pfx->getCont(), compoundmiddle, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundmiddle, sfx->getContLen())))) { rv = NULL; } // check forbiddenwords if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || TESTAFF(rv->astr, ONLYUPCASEFLAG, 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 && !words && // 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 !checkcpdtable.empty() && !words && cpdpat_check(word, i, rv, NULL, affixed)) || (checkcompoundcase && !words && cpdcase_check(word, i)))) // LANG_hu section: spec. Hungarian rule || ((!rv) && (langnum == LANG_hu) && hu_mov_rule && (rv = affix_check(st.c_str(), i)) && (sfx && sfx->getCont() && (TESTAFF(sfx->getCont(), (unsigned short)'x', sfx->getContLen()) || TESTAFF(sfx->getCont(), (unsigned short)'%', 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.substr(0, i)); // + 1 word, if syllable number of the prefix > 1 (hungarian // convention) if (pfx && (get_syllable(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)) || (!defcpdtable.empty() && words && defcpd_check(&words, wnum + 1, rv, NULL, 1))))) { rv = rv->next_homonym; } if (rv && words && words[wnum + 1]) { result.append(presult); result.push_back(MSEP_FLD); result.append(MORPH_PART); result.append(word + i); if (complexprefixes && HENTRY_DATA(rv)) result.append(HENTRY_DATA2(rv)); if (!HENTRY_FIND(rv, MORPH_STEM)) { result.push_back(MSEP_FLD); result.append(MORPH_STEM); result.append(HENTRY_WORD(rv)); } // store the pointer of the hash entry if (!complexprefixes && HENTRY_DATA(rv)) { result.push_back(MSEP_FLD); result.append(HENTRY_DATA2(rv)); } result.push_back(MSEP_REC); 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) || TESTAFF(rv->astr, ONLYUPCASEFLAG, 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 + 1 < cpdwordmax)) || ((cpdmaxsyllable != 0) && (numsyllable + get_syllable(std::string(HENTRY_WORD(rv), rv->blen)) <= cpdmaxsyllable))) && ((!checkcompounddup || (rv != rv_first)))) { // bad compound word result.append(presult); result.push_back(MSEP_FLD); result.append(MORPH_PART); result.append(word + i); if (HENTRY_DATA(rv)) { if (complexprefixes) result.append(HENTRY_DATA2(rv)); if (!HENTRY_FIND(rv, MORPH_STEM)) { result.push_back(MSEP_FLD); result.append(MORPH_STEM); result.append(HENTRY_WORD(rv)); } // store the pointer of the hash entry if (!complexprefixes) { result.push_back(MSEP_FLD); result.append(HENTRY_DATA2(rv)); } } result.push_back(MSEP_REC); ok = 1; } numsyllable = oldnumsyllable2; wordnum = oldwordnum2; // perhaps second word has prefix or/and suffix sfx = NULL; sfxflag = FLAG_NULL; if (compoundflag && !onlycpdrule) rv = affix_check((word + i), strlen(word + i), compoundflag); else rv = NULL; if (!rv && compoundend && !onlycpdrule) { sfx = NULL; pfx = NULL; rv = affix_check((word + i), strlen(word + i), compoundend); } if (!rv && !defcpdtable.empty() && words) { rv = affix_check((word + i), strlen(word + i), 0, IN_CPD_END); if (rv && words && defcpd_check(&words, wnum + 1, rv, NULL, 1)) { std::string m; if (compoundflag) m = affix_check_morph((word + i), strlen(word + i), compoundflag); if (m.empty() && compoundend) { m = affix_check_morph((word + i), strlen(word + i), compoundend); } result.append(presult); if (!m.empty()) { result.push_back(MSEP_FLD); result.append(MORPH_PART); result.append(word + i); line_uniq_app(m, MSEP_REC); result.append(m); } result.push_back(MSEP_REC); ok = 1; } } // check non_compound flag in suffix and prefix if ((rv) && ((pfx && pfx->getCont() && TESTAFF(pfx->getCont(), compoundforbidflag, pfx->getContLen())) || (sfx && sfx->getCont() && TESTAFF(sfx->getCont(), compoundforbidflag, sfx->getContLen())))) { rv = NULL; } // check forbiddenwords if ((rv) && (rv->astr) && (TESTAFF(rv->astr, forbiddenword, rv->alen) || TESTAFF(rv->astr, ONLYUPCASEFLAG, 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); // - affix syllable num. // XXX only second suffix (inflections, not derivations) if (sfxappnd) { std::string tmp(sfxappnd); reverseword(tmp); numsyllable -= short(get_syllable(tmp) + sfxextra); } else { numsyllable -= short(sfxextra); } // + 1 word, if syllable number of the prefix > 1 (hungarian // convention) if (pfx && (get_syllable(pfx->getKey()) > 1)) wordnum++; // increment syllable num, if last word has a SYLLABLENUM flag // and the suffix is beginning `s' if (!cpdsyllablenum.empty()) { 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 < cpdwordmax)) || ((cpdmaxsyllable != 0) && (numsyllable <= cpdmaxsyllable))) && ((!checkcompounddup || (rv != rv_first)))) { std::string m; if (compoundflag) m = affix_check_morph((word + i), strlen(word + i), compoundflag); if (m.empty() && compoundend) { m = affix_check_morph((word + i), strlen(word + i), compoundend); } result.append(presult); if (!m.empty()) { result.push_back(MSEP_FLD); result.append(MORPH_PART); result.append(word + i); line_uniq_app(m, MSEP_REC); result.push_back(MSEP_FLD); result.append(m); } result.push_back(MSEP_REC); ok = 1; } numsyllable = oldnumsyllable2; wordnum = oldwordnum2; // perhaps second word is a compound word (recursive call) if ((wordnum + 2 < maxwordnum) && (ok == 0)) { compound_check_morph((word + i), strlen(word + i), wordnum + 1, numsyllable, maxwordnum, wnum + 1, words, rwords, 0, result, &presult); } else { rv = NULL; } } st[i] = ch; wordnum = oldwordnum; numsyllable = oldnumsyllable; } while (!defcpdtable.empty() && oldwordnum == 0 && onlycpdrule++ < 1); // end of onlycpd loop } return 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, PfxEntry* ppfx, const FLAG cclass, const FLAG needflag, char in_compound) { struct hentry* rv = NULL; PfxEntry* ep = ppfx; // first handle the special case of 0 length suffixes SfxEntry* se = 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, (FLAG)cclass, needflag, (in_compound ? 0 : onlyincompound)); if (rv) { sfx = se; // BUG: sfx not stateless return rv; } } } se = se->getNext(); } // now handle the general case if (len == 0) return NULL; // FULLSTRIP unsigned char sp = *((const unsigned char*)(word + len - 1)); SfxEntry* sptr = 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()))))) if (in_compound != IN_CPD_END || ppfx || !(sptr->getCont() && TESTAFF(sptr->getCont(), onlyincompound, sptr->getContLen()))) { rv = sptr->checkword(word, len, sfxopts, ppfx, cclass, needflag, (in_compound ? 0 : onlyincompound)); if (rv) { sfx = sptr; // BUG: sfx not stateless sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless if (!sptr->getCont()) sfxappnd = sptr->getKey(); // BUG: sfxappnd not stateless // LANG_hu section: spec. Hungarian rule else if (langnum == LANG_hu && sptr->getKeyLen() && sptr->getKey()[0] == 'i' && sptr->getKey()[1] != 'y' && sptr->getKey()[1] != 't') { sfxextra = 1; } // END of LANG_hu section 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, PfxEntry* ppfx, const FLAG needflag) { struct hentry* rv = NULL; // first handle the special case of 0 length suffixes SfxEntry* se = 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 if (len == 0) return NULL; // FULLSTRIP unsigned char sp = *((const unsigned char*)(word + len - 1)); SfxEntry* sptr = 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; } // check word for two-level suffixes and morph std::string AffixMgr::suffix_check_twosfx_morph(const char* word, int len, int sfxopts, PfxEntry* ppfx, const FLAG needflag) { std::string result; std::string result2; std::string result3; // first handle the special case of 0 length suffixes SfxEntry* se = sStart[0]; while (se) { if (contclasses[se->getFlag()]) { std::string st = se->check_twosfx_morph(word, len, sfxopts, ppfx, needflag); if (!st.empty()) { if (ppfx) { if (ppfx->getMorph()) { result.append(ppfx->getMorph()); result.push_back(MSEP_FLD); } else debugflag(result, ppfx->getFlag()); } result.append(st); if (se->getMorph()) { result.push_back(MSEP_FLD); result.append(se->getMorph()); } else debugflag(result, se->getFlag()); result.push_back(MSEP_REC); } } se = se->getNext(); } // now handle the general case if (len == 0) return std::string(); // FULLSTRIP unsigned char sp = *((const unsigned char*)(word + len - 1)); SfxEntry* sptr = sStart[sp]; while (sptr) { if (isRevSubset(sptr->getKey(), word + len - 1, len)) { if (contclasses[sptr->getFlag()]) { std::string st = sptr->check_twosfx_morph(word, len, sfxopts, ppfx, needflag); if (!st.empty()) { sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless if (!sptr->getCont()) sfxappnd = sptr->getKey(); // BUG: sfxappnd not stateless result2.assign(st); result3.clear(); if (sptr->getMorph()) { result3.push_back(MSEP_FLD); result3.append(sptr->getMorph()); } else debugflag(result3, sptr->getFlag()); strlinecat(result2, result3); result2.push_back(MSEP_REC); result.append(result2); } } sptr = sptr->getNextEQ(); } else { sptr = sptr->getNextNE(); } } return result; } std::string AffixMgr::suffix_check_morph(const char* word, int len, int sfxopts, PfxEntry* ppfx, const FLAG cclass, const FLAG needflag, char in_compound) { std::string result; struct hentry* rv = NULL; PfxEntry* ep = ppfx; // first handle the special case of 0 length suffixes SfxEntry* se = 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, cclass, needflag, FLAG_NULL); while (rv) { if (ppfx) { if (ppfx->getMorph()) { result.append(ppfx->getMorph()); result.push_back(MSEP_FLD); } else debugflag(result, ppfx->getFlag()); } if (complexprefixes && HENTRY_DATA(rv)) result.append(HENTRY_DATA2(rv)); if (!HENTRY_FIND(rv, MORPH_STEM)) { result.push_back(MSEP_FLD); result.append(MORPH_STEM); result.append(HENTRY_WORD(rv)); } if (!complexprefixes && HENTRY_DATA(rv)) { result.push_back(MSEP_FLD); result.append(HENTRY_DATA2(rv)); } if (se->getMorph()) { result.push_back(MSEP_FLD); result.append(se->getMorph()); } else debugflag(result, se->getFlag()); result.push_back(MSEP_REC); rv = se->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag); } } se = se->getNext(); } // now handle the general case if (len == 0) return std::string(); // FULLSTRIP unsigned char sp = *((const unsigned char*)(word + len - 1)); SfxEntry* sptr = 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, cclass, needflag, FLAG_NULL); while (rv) { if (ppfx) { if (ppfx->getMorph()) { result.append(ppfx->getMorph()); result.push_back(MSEP_FLD); } else debugflag(result, ppfx->getFlag()); } if (complexprefixes && HENTRY_DATA(rv)) result.append(HENTRY_DATA2(rv)); if (!HENTRY_FIND(rv, MORPH_STEM)) { result.push_back(MSEP_FLD); result.append(MORPH_STEM); result.append(HENTRY_WORD(rv)); } if (!complexprefixes && HENTRY_DATA(rv)) { result.push_back(MSEP_FLD); result.append(HENTRY_DATA2(rv)); } if (sptr->getMorph()) { result.push_back(MSEP_FLD); result.append(sptr->getMorph()); } else debugflag(result, sptr->getFlag()); result.push_back(MSEP_REC); rv = sptr->get_next_homonym(rv, sfxopts, ppfx, cclass, needflag); } sptr = sptr->getNextEQ(); } else { sptr = sptr->getNextNE(); } } return result; } // check if word with affixes is correctly spelled struct hentry* AffixMgr::affix_check(const char* word, int len, const FLAG needflag, char in_compound) { // check all prefixes (also crossed with suffixes if allowed) struct hentry* 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, 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 std::string AffixMgr::affix_check_morph(const char* word, int len, const FLAG needflag, char in_compound) { std::string result; // check all prefixes (also crossed with suffixes if allowed) std::string st = prefix_check_morph(word, len, in_compound); if (!st.empty()) { result.append(st); } // if still not found check all suffixes st = suffix_check_morph(word, len, 0, NULL, '\0', needflag, in_compound); if (!st.empty()) { result.append(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.empty()) { result.append(st); } // if still not found check all two-level suffixes st = prefix_check_twosfx_morph(word, len, IN_CPD_NOT, needflag); if (!st.empty()) { result.append(st); } } return result; } // morphcmp(): compare MORPH_DERI_SFX, MORPH_INFL_SFX and MORPH_TERM_SFX fields // in the first line of the inputs // return 0, if inputs equal // return 1, if inputs may equal with a secondary suffix // otherwise return -1 static int morphcmp(const char* s, const char* t) { int se = 0; int te = 0; const char* sl; const char* tl; const char* olds; const char* oldt; if (!s || !t) return 1; olds = s; sl = strchr(s, '\n'); s = strstr(s, MORPH_DERI_SFX); if (!s || (sl && sl < s)) s = strstr(olds, MORPH_INFL_SFX); if (!s || (sl && sl < s)) { s = strstr(olds, MORPH_TERM_SFX); olds = NULL; } oldt = t; tl = strchr(t, '\n'); t = strstr(t, MORPH_DERI_SFX); if (!t || (tl && tl < t)) t = strstr(oldt, MORPH_INFL_SFX); if (!t || (tl && tl < t)) { t = strstr(oldt, MORPH_TERM_SFX); oldt = NULL; } while (s && t && (!sl || sl > s) && (!tl || tl > t)) { s += MORPH_TAG_LEN; t += MORPH_TAG_LEN; se = 0; te = 0; while ((*s == *t) && !se && !te) { s++; t++; switch (*s) { case ' ': case '\n': case '\t': case '\0': se = 1; } switch (*t) { case ' ': case '\n': case '\t': case '\0': te = 1; } } if (!se || !te) { // not terminal suffix difference if (olds) return -1; return 1; } olds = s; s = strstr(s, MORPH_DERI_SFX); if (!s || (sl && sl < s)) s = strstr(olds, MORPH_INFL_SFX); if (!s || (sl && sl < s)) { s = strstr(olds, MORPH_TERM_SFX); olds = NULL; } oldt = t; t = strstr(t, MORPH_DERI_SFX); if (!t || (tl && tl < t)) t = strstr(oldt, MORPH_INFL_SFX); if (!t || (tl && tl < t)) { t = strstr(oldt, MORPH_TERM_SFX); oldt = NULL; } } if (!s && !t && se && te) return 0; return 1; } std::string AffixMgr::morphgen(const char* ts, int wl, const unsigned short* ap, unsigned short al, const char* morph, const char* targetmorph, int level) { // handle suffixes if (!morph) return std::string(); // check substandard flag if (TESTAFF(ap, substandard, al)) return std::string(); if (morphcmp(morph, targetmorph) == 0) return ts; size_t stemmorphcatpos; std::string mymorph; // use input suffix fields, if exist if (strstr(morph, MORPH_INFL_SFX) || strstr(morph, MORPH_DERI_SFX)) { mymorph.assign(morph); mymorph.push_back(MSEP_FLD); stemmorphcatpos = mymorph.size(); } else { stemmorphcatpos = std::string::npos; } for (int i = 0; i < al; i++) { const unsigned char c = (unsigned char)(ap[i] & 0x00FF); SfxEntry* sptr = sFlag[c]; while (sptr) { if (sptr->getFlag() == ap[i] && sptr->getMorph() && ((sptr->getContLen() == 0) || // don't generate forms with substandard affixes !TESTAFF(sptr->getCont(), substandard, sptr->getContLen()))) { const char* stemmorph; if (stemmorphcatpos != std::string::npos) { mymorph.replace(stemmorphcatpos, std::string::npos, sptr->getMorph()); stemmorph = mymorph.c_str(); } else { stemmorph = sptr->getMorph(); } int cmp = morphcmp(stemmorph, targetmorph); if (cmp == 0) { std::string newword = sptr->add(ts, wl); if (!newword.empty()) { hentry* check = pHMgr->lookup(newword.c_str()); // XXX extra dic if (!check || !check->astr || !(TESTAFF(check->astr, forbiddenword, check->alen) || TESTAFF(check->astr, ONLYUPCASEFLAG, check->alen))) { return newword; } } } // recursive call for secondary suffixes if ((level == 0) && (cmp == 1) && (sptr->getContLen() > 0) && !TESTAFF(sptr->getCont(), substandard, sptr->getContLen())) { std::string newword = sptr->add(ts, wl); if (!newword.empty()) { std::string newword2 = morphgen(newword.c_str(), newword.size(), sptr->getCont(), sptr->getContLen(), stemmorph, targetmorph, 1); if (!newword2.empty()) { return newword2; } } } } sptr = sptr->getFlgNxt(); } } return std::string(); } int AffixMgr::expand_rootword(struct guessword* wlst, int maxn, const char* ts, int wl, const unsigned short* ap, unsigned short al, const char* bad, int badl, const 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 = false; 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 = false; 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 = 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()))))) { std::string newword = sptr->add(ts, wl); if (!newword.empty()) { if (nh < maxn) { wlst[nh].word = mystrdup(newword.c_str()); wlst[nh].allow = sptr->allowCross(); wlst[nh].orig = NULL; nh++; // add special phonetic version if (phon && (nh < maxn)) { std::string prefix(phon); std::string key(sptr->getKey()); reverseword(key); prefix.append(key); wlst[nh].word = mystrdup(prefix.c_str()); if (!wlst[nh].word) return nh - 1; wlst[nh].allow = false; wlst[nh].orig = mystrdup(newword.c_str()); if (!wlst[nh].orig) return nh - 1; nh++; } } } } sptr = sptr->getFlgNxt(); } } int n = nh; // handle cross products of prefixes and suffixes for (int j = 1; j < n; j++) if (wlst[j].allow) { for (int k = 0; k < al; k++) { const unsigned char c = (unsigned char)(ap[k] & 0x00FF); PfxEntry* cptr = pFlag[c]; while (cptr) { if ((cptr->getFlag() == ap[k]) && cptr->allowCross() && (!cptr->getKeyLen() || ((badl > cptr->getKeyLen()) && (strncmp(cptr->getKey(), bad, cptr->getKeyLen()) == 0)))) { int l1 = strlen(wlst[j].word); std::string newword = cptr->add(wlst[j].word, l1); if (!newword.empty()) { if (nh < maxn) { wlst[nh].word = mystrdup(newword.c_str()); wlst[nh].allow = cptr->allowCross(); wlst[nh].orig = NULL; nh++; } } } cptr = cptr->getFlgNxt(); } } } // now handle pure prefixes for (int m = 0; m < al; m++) { const unsigned char c = (unsigned char)(ap[m] & 0x00FF); PfxEntry* ptr = 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()))))) { std::string newword = ptr->add(ts, wl); if (!newword.empty()) { if (nh < maxn) { wlst[nh].word = mystrdup(newword.c_str()); wlst[nh].allow = ptr->allowCross(); wlst[nh].orig = NULL; nh++; } } } ptr = ptr->getFlgNxt(); } } return nh; } // return replacing table const std::vector& AffixMgr::get_reptable() const { return pHMgr->get_reptable(); } // return iconv table RepList* AffixMgr::get_iconvtable() const { if (!iconvtable) return NULL; return iconvtable; } // return oconv table RepList* AffixMgr::get_oconvtable() const { if (!oconvtable) return NULL; return oconvtable; } // return replacing table struct phonetable* AffixMgr::get_phonetable() const { if (!phone) return NULL; return phone; } // return character map table const std::vector& AffixMgr::get_maptable() const { return maptable; } // return character map table const std::vector& AffixMgr::get_breaktable() const { return breaktable; } // return text encoding of dictionary const std::string& AffixMgr::get_encoding() { if (encoding.empty()) encoding = SPELL_ENCODING; return encoding; } // return text encoding of dictionary int AffixMgr::get_langnum() const { return langnum; } // return double prefix option int AffixMgr::get_complexprefixes() const { return complexprefixes; } // return FULLSTRIP option int AffixMgr::get_fullstrip() const { return fullstrip; } FLAG AffixMgr::get_keepcase() const { return keepcase; } FLAG AffixMgr::get_forceucase() const { return forceucase; } FLAG AffixMgr::get_warn() const { return warn; } int AffixMgr::get_forbidwarn() const { return forbidwarn; } int AffixMgr::get_checksharps() const { return checksharps; } char* AffixMgr::encode_flag(unsigned short aflag) const { return pHMgr->encode_flag(aflag); } // return the preferred ignore string for suggestions const char* AffixMgr::get_ignore() const { if (ignorechars.empty()) return NULL; return ignorechars.c_str(); } // return the preferred ignore string for suggestions const std::vector& AffixMgr::get_ignore_utf16() const { return ignorechars_utf16; } // return the keyboard string for suggestions char* AffixMgr::get_key_string() { if (keystring.empty()) keystring = SPELL_KEYSTRING; return mystrdup(keystring.c_str()); } // return the preferred try string for suggestions char* AffixMgr::get_try_string() const { if (trystring.empty()) return NULL; return mystrdup(trystring.c_str()); } // return the preferred try string for suggestions const std::string& AffixMgr::get_wordchars() const { return wordchars; } const std::vector& AffixMgr::get_wordchars_utf16() const { return wordchars_utf16; } // is there compounding? int AffixMgr::get_compound() const { return compoundflag || compoundbegin || !defcpdtable.empty(); } // return the compound words control flag FLAG AffixMgr::get_compoundflag() const { return compoundflag; } // return the forbidden words control flag FLAG AffixMgr::get_forbiddenword() const { return forbiddenword; } // return the forbidden words control flag FLAG AffixMgr::get_nosuggest() const { return nosuggest; } // return the forbidden words control flag FLAG AffixMgr::get_nongramsuggest() const { return nongramsuggest; } // return the substandard root/affix control flag FLAG AffixMgr::get_substandard() const { return substandard; } // return the forbidden words flag modify flag FLAG AffixMgr::get_needaffix() const { return needaffix; } // return the onlyincompound flag FLAG AffixMgr::get_onlyincompound() const { return onlyincompound; } // return the value of suffix const std::string& AffixMgr::get_version() const { return version; } // utility method to look up root words in hash table struct hentry* AffixMgr::lookup(const char* word) { struct hentry* he = NULL; for (size_t i = 0; i < alldic.size() && !he; ++i) { he = alldic[i]->lookup(word); } return he; } // return the value of suffix int AffixMgr::have_contclass() const { return havecontclass; } // return utf8 int AffixMgr::get_utf8() const { return utf8; } int AffixMgr::get_maxngramsugs(void) const { return maxngramsugs; } int AffixMgr::get_maxcpdsugs(void) const { return maxcpdsugs; } int AffixMgr::get_maxdiff(void) const { return maxdiff; } int AffixMgr::get_onlymaxdiff(void) const { return onlymaxdiff; } // return nosplitsugs int AffixMgr::get_nosplitsugs(void) const { return nosplitsugs; } // return sugswithdots int AffixMgr::get_sugswithdots(void) const { return sugswithdots; } /* parse flag */ bool AffixMgr::parse_flag(const std::string& line, unsigned short* out, FileMgr* af) { if (*out != FLAG_NULL && !(*out >= DEFAULTFLAGS)) { HUNSPELL_WARNING( stderr, "error: line %d: multiple definitions of an affix file parameter\n", af->getlinenum()); return false; } std::string s; if (!parse_string(line, s, af->getlinenum())) return false; *out = pHMgr->decode_flag(s.c_str()); return true; } /* parse num */ bool AffixMgr::parse_num(const std::string& line, int* out, FileMgr* af) { if (*out != -1) { HUNSPELL_WARNING( stderr, "error: line %d: multiple definitions of an affix file parameter\n", af->getlinenum()); return false; } std::string s; if (!parse_string(line, s, af->getlinenum())) return false; *out = atoi(s.c_str()); return true; } /* parse in the max syllablecount of compound words and */ bool AffixMgr::parse_cpdsyllable(const std::string& line, FileMgr* af) { int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { cpdmaxsyllable = atoi(std::string(start_piece, iter).c_str()); np++; break; } case 2: { if (!utf8) { cpdvowels.assign(start_piece, iter); std::sort(cpdvowels.begin(), cpdvowels.end()); } else { std::string piece(start_piece, iter); u8_u16(cpdvowels_utf16, piece); std::sort(cpdvowels_utf16.begin(), cpdvowels_utf16.end()); } np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np < 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing compoundsyllable information\n", af->getlinenum()); return false; } if (np == 2) cpdvowels = "AEIOUaeiou"; return true; } bool AffixMgr::parse_convtable(const std::string& line, FileMgr* af, RepList** rl, const std::string& keyword) { if (*rl) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } int i = 0; int np = 0; int numrl = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { numrl = atoi(std::string(start_piece, iter).c_str()); if (numrl < 1) { HUNSPELL_WARNING(stderr, "error: line %d: incorrect entry number\n", af->getlinenum()); return false; } *rl = new RepList(numrl); if (!*rl) return false; np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the num lines to read in the remainder of the table */ for (int j = 0; j < numrl; j++) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); i = 0; std::string pattern; std::string pattern2; iter = nl.begin(); start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), keyword.size(), keyword, 0, keyword.size()) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); delete *rl; *rl = NULL; return false; } break; } case 1: { pattern.assign(start_piece, iter); break; } case 2: { pattern2.assign(start_piece, iter); break; } default: break; } ++i; } start_piece = mystrsep(nl, iter); } if (pattern.empty() || pattern2.empty()) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } (*rl)->add(pattern, pattern2); } return true; } /* parse in the typical fault correcting table */ bool AffixMgr::parse_phonetable(const std::string& line, FileMgr* af) { if (phone) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } int num = -1; int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { num = atoi(std::string(start_piece, iter).c_str()); if (num < 1) { HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); return false; } phone = new phonetable; phone->utf8 = (char)utf8; np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the phone->num lines to read in the remainder of the table */ for (int j = 0; j < num; ++j) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); i = 0; const size_t old_size = phone->rules.size(); iter = nl.begin(); start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 5, "PHONE", 5) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } break; } case 1: { phone->rules.push_back(std::string(start_piece, iter)); break; } case 2: { phone->rules.push_back(std::string(start_piece, iter)); mystrrep(phone->rules.back(), "_", ""); break; } default: break; } ++i; } start_piece = mystrsep(nl, iter); } if (phone->rules.size() != old_size + 2) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); phone->rules.clear(); return false; } } phone->rules.push_back(""); phone->rules.push_back(""); init_phonet_hash(*phone); return true; } /* parse in the checkcompoundpattern table */ bool AffixMgr::parse_checkcpdtable(const std::string& line, FileMgr* af) { if (parsedcheckcpd) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } parsedcheckcpd = true; int numcheckcpd = -1; int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { numcheckcpd = atoi(std::string(start_piece, iter).c_str()); if (numcheckcpd < 1) { HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); return false; } checkcpdtable.reserve(numcheckcpd); np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the numcheckcpd lines to read in the remainder of the table */ for (int j = 0; j < numcheckcpd; ++j) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); i = 0; checkcpdtable.push_back(patentry()); iter = nl.begin(); start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 20, "CHECKCOMPOUNDPATTERN", 20) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } break; } case 1: { checkcpdtable.back().pattern.assign(start_piece, iter); size_t slash_pos = checkcpdtable.back().pattern.find('/'); if (slash_pos != std::string::npos) { std::string chunk(checkcpdtable.back().pattern, slash_pos + 1); checkcpdtable.back().pattern.resize(slash_pos); checkcpdtable.back().cond = pHMgr->decode_flag(chunk.c_str()); } break; } case 2: { checkcpdtable.back().pattern2.assign(start_piece, iter); size_t slash_pos = checkcpdtable.back().pattern2.find('/'); if (slash_pos != std::string::npos) { std::string chunk(checkcpdtable.back().pattern2, slash_pos + 1); checkcpdtable.back().pattern2.resize(slash_pos); checkcpdtable.back().cond2 = pHMgr->decode_flag(chunk.c_str()); } break; } case 3: { checkcpdtable.back().pattern3.assign(start_piece, iter); simplifiedcpd = 1; break; } default: break; } i++; start_piece = mystrsep(nl, iter); } } return true; } /* parse in the compound rule table */ bool AffixMgr::parse_defcpdtable(const std::string& line, FileMgr* af) { if (parseddefcpd) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } parseddefcpd = true; int numdefcpd = -1; int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { numdefcpd = atoi(std::string(start_piece, iter).c_str()); if (numdefcpd < 1) { HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); return false; } defcpdtable.reserve(numdefcpd); np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the numdefcpd lines to read in the remainder of the table */ for (int j = 0; j < numdefcpd; ++j) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); i = 0; defcpdtable.push_back(flagentry()); iter = nl.begin(); start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 12, "COMPOUNDRULE", 12) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); numdefcpd = 0; return false; } break; } case 1: { // handle parenthesized flags if (std::find(start_piece, iter, '(') != iter) { for (std::string::const_iterator k = start_piece; k != iter; ++k) { std::string::const_iterator chb = k; std::string::const_iterator che = k + 1; if (*k == '(') { std::string::const_iterator parpos = std::find(k, iter, ')'); if (parpos != iter) { chb = k + 1; che = parpos; k = parpos; } } if (*chb == '*' || *chb == '?') { defcpdtable.back().push_back((FLAG)*chb); } else { pHMgr->decode_flags(defcpdtable.back(), std::string(chb, che), af); } } } else { pHMgr->decode_flags(defcpdtable.back(), std::string(start_piece, iter), af); } break; } default: break; } ++i; start_piece = mystrsep(nl, iter); } if (defcpdtable.back().empty()) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } } return true; } /* parse in the character map table */ bool AffixMgr::parse_maptable(const std::string& line, FileMgr* af) { if (parsedmaptable) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } parsedmaptable = true; int nummap = -1; int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { nummap = atoi(std::string(start_piece, iter).c_str()); if (nummap < 1) { HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); return false; } maptable.reserve(nummap); np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the nummap lines to read in the remainder of the table */ for (int j = 0; j < nummap; ++j) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); i = 0; maptable.push_back(mapentry()); iter = nl.begin(); start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 3, "MAP", 3) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); nummap = 0; return false; } break; } case 1: { for (std::string::const_iterator k = start_piece; k != iter; ++k) { std::string::const_iterator chb = k; std::string::const_iterator che = k + 1; if (*k == '(') { std::string::const_iterator parpos = std::find(k, iter, ')'); if (parpos != iter) { chb = k + 1; che = parpos; k = parpos; } } else { if (utf8 && (*k & 0xc0) == 0xc0) { ++k; while (k != iter && (*k & 0xc0) == 0x80) ++k; che = k; --k; } } maptable.back().push_back(std::string(chb, che)); } break; } default: break; } ++i; start_piece = mystrsep(nl, iter); } if (maptable.back().empty()) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } } return true; } /* parse in the word breakpoint table */ bool AffixMgr::parse_breaktable(const std::string& line, FileMgr* af) { if (parsedbreaktable) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } parsedbreaktable = true; int numbreak = -1; int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { numbreak = atoi(std::string(start_piece, iter).c_str()); if (numbreak < 0) { HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); return false; } if (numbreak == 0) return true; breaktable.reserve(numbreak); np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the numbreak lines to read in the remainder of the table */ for (int j = 0; j < numbreak; ++j) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); i = 0; iter = nl.begin(); start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 5, "BREAK", 5) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); numbreak = 0; return false; } break; } case 1: { breaktable.push_back(std::string(start_piece, iter)); break; } default: break; } ++i; start_piece = mystrsep(nl, iter); } } if (breaktable.size() != static_cast(numbreak)) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } return true; } void AffixMgr::reverse_condition(std::string& piece) { if (piece.empty()) return; int neg = 0; for (std::string::reverse_iterator k = piece.rbegin(); k != piece.rend(); ++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; } } } } class entries_container { std::vector entries; AffixMgr* m_mgr; char m_at; public: entries_container(char at, AffixMgr* mgr) : m_mgr(mgr) , m_at(at) { } void release() { entries.clear(); } void initialize(int numents, char opts, unsigned short aflag) { entries.reserve(numents); if (m_at == 'P') { entries.push_back(new PfxEntry(m_mgr)); } else { entries.push_back(new SfxEntry(m_mgr)); } entries.back()->opts = opts; entries.back()->aflag = aflag; } AffEntry* add_entry(char opts) { if (m_at == 'P') { entries.push_back(new PfxEntry(m_mgr)); } else { entries.push_back(new SfxEntry(m_mgr)); } AffEntry* ret = entries.back(); ret->opts = entries[0]->opts & opts; return ret; } AffEntry* first_entry() { return entries.empty() ? NULL : entries[0]; } ~entries_container() { for (size_t i = 0; i < entries.size(); ++i) { delete entries[i]; } } std::vector::iterator begin() { return entries.begin(); } std::vector::iterator end() { return entries.end(); } }; bool AffixMgr::parse_affix(const std::string& 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; entries_container affentries(at, this); int i = 0; // checking lines with bad syntax #ifdef DEBUG int basefieldnum = 0; #endif // split affix header line into pieces int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { // piece 1 - is type of affix case 0: { np++; break; } // piece 2 - is affix char case 1: { np++; aflag = pHMgr->decode_flag(std::string(start_piece, iter).c_str()); if (((at == 'S') && (dupflags[aflag] & dupSFX)) || ((at == 'P') && (dupflags[aflag] & dupPFX))) { HUNSPELL_WARNING( stderr, "error: line %d: multiple definitions of an affix flag\n", af->getlinenum()); } dupflags[aflag] += (char)((at == 'S') ? dupSFX : dupPFX); break; } // piece 3 - is cross product indicator case 2: { np++; if (*start_piece == 'Y') ff = aeXPRODUCT; break; } // piece 4 - is number of affentries case 3: { np++; numents = atoi(std::string(start_piece, iter).c_str()); if ((numents <= 0) || ((std::numeric_limits::max() / sizeof(AffEntry)) < static_cast(numents))) { char* err = pHMgr->encode_flag(aflag); if (err) { HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); free(err); } return false; } char opts = ff; if (utf8) opts += aeUTF8; if (pHMgr->is_aliasf()) opts += aeALIASF; if (pHMgr->is_aliasm()) opts += aeALIASM; affentries.initialize(numents, opts, aflag); } default: break; } ++i; start_piece = mystrsep(line, iter); } // check to make sure we parsed enough pieces if (np != 4) { char* err = pHMgr->encode_flag(aflag); if (err) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); free(err); } return false; } // now parse numents affentries for this affix AffEntry* entry = affentries.first_entry(); for (int ent = 0; ent < numents; ++ent) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); iter = nl.begin(); i = 0; np = 0; // split line into pieces start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { // piece 1 - is type case 0: { np++; if (ent != 0) entry = affentries.add_entry((char)(aeXPRODUCT + aeUTF8 + aeALIASF + aeALIASM)); break; } // piece 2 - is affix char case 1: { np++; std::string chunk(start_piece, iter); if (pHMgr->decode_flag(chunk.c_str()) != aflag) { char* err = pHMgr->encode_flag(aflag); if (err) { HUNSPELL_WARNING(stderr, "error: line %d: affix %s is corrupt\n", af->getlinenum(), err); free(err); } return false; } if (ent != 0) { AffEntry* start_entry = affentries.first_entry(); entry->aflag = start_entry->aflag; } break; } // piece 3 - is string to strip or 0 for null case 2: { np++; entry->strip = std::string(start_piece, iter); if (complexprefixes) { if (utf8) reverseword_utf(entry->strip); else reverseword(entry->strip); } if (entry->strip.compare("0") == 0) { entry->strip.clear(); } break; } // piece 4 - is affix string or 0 for null case 3: { entry->morphcode = NULL; entry->contclass = NULL; entry->contclasslen = 0; np++; std::string::const_iterator dash = std::find(start_piece, iter, '/'); if (dash != iter) { entry->appnd = std::string(start_piece, dash); std::string dash_str(dash + 1, iter); if (!ignorechars.empty() && !has_no_ignored_chars(entry->appnd, ignorechars)) { if (utf8) { remove_ignored_chars_utf(entry->appnd, ignorechars_utf16); } else { remove_ignored_chars(entry->appnd, ignorechars); } } if (complexprefixes) { if (utf8) reverseword_utf(entry->appnd); else reverseword(entry->appnd); } if (pHMgr->is_aliasf()) { int index = atoi(dash_str.c_str()); entry->contclasslen = (unsigned short)pHMgr->get_aliasf( index, &(entry->contclass), af); if (!entry->contclasslen) HUNSPELL_WARNING(stderr, "error: bad affix flag alias: \"%s\"\n", dash_str.c_str()); } else { entry->contclasslen = (unsigned short)pHMgr->decode_flags( &(entry->contclass), dash_str.c_str(), af); std::sort(entry->contclass, entry->contclass + entry->contclasslen); } havecontclass = 1; for (unsigned short _i = 0; _i < entry->contclasslen; _i++) { contclasses[(entry->contclass)[_i]] = 1; } } else { entry->appnd = std::string(start_piece, iter); if (!ignorechars.empty() && !has_no_ignored_chars(entry->appnd, ignorechars)) { if (utf8) { remove_ignored_chars_utf(entry->appnd, ignorechars_utf16); } else { remove_ignored_chars(entry->appnd, ignorechars); } } if (complexprefixes) { if (utf8) reverseword_utf(entry->appnd); else reverseword(entry->appnd); } } if (entry->appnd.compare("0") == 0) { entry->appnd.clear(); } break; } // piece 5 - is the conditions descriptions case 4: { std::string chunk(start_piece, iter); np++; if (complexprefixes) { if (utf8) reverseword_utf(chunk); else reverseword(chunk); reverse_condition(chunk); } if (!entry->strip.empty() && chunk != "." && redundant_condition(at, entry->strip.c_str(), entry->strip.size(), chunk.c_str(), af->getlinenum())) chunk = "."; if (at == 'S') { reverseword(chunk); reverse_condition(chunk); } if (encodeit(*entry, chunk.c_str())) return false; break; } case 5: { std::string chunk(start_piece, iter); np++; if (pHMgr->is_aliasm()) { int index = atoi(chunk.c_str()); entry->morphcode = pHMgr->get_aliasm(index); } else { if (complexprefixes) { // XXX - fix me for morph. gen. if (utf8) reverseword_utf(chunk); else reverseword(chunk); } // add the remaining of the line std::string::const_iterator end = nl.end(); if (iter != end) { chunk.append(iter, end); } entry->morphcode = mystrdup(chunk.c_str()); if (!entry->morphcode) return false; } break; } default: break; } i++; start_piece = mystrsep(nl, iter); } // check to make sure we parsed enough pieces if (np < 4) { char* err = pHMgr->encode_flag(aflag); if (err) { HUNSPELL_WARNING(stderr, "error: line %d: affix %s is corrupt\n", af->getlinenum(), err); free(err); } return false; } #ifdef DEBUG // detect unnecessary fields, excepting comments if (basefieldnum) { int fieldnum = !(entry->morphcode) ? 5 : ((*(entry->morphcode) == '#') ? 5 : 6); if (fieldnum != basefieldnum) HUNSPELL_WARNING(stderr, "warning: line %d: bad field number\n", af->getlinenum()); } else { basefieldnum = !(entry->morphcode) ? 5 : ((*(entry->morphcode) == '#') ? 5 : 6); } #endif } // now create SfxEntry or PfxEntry objects and use links to // build an ordered (sorted by affix string) list std::vector::iterator start = affentries.begin(); std::vector::iterator end = affentries.end(); for (std::vector::iterator affentry = start; affentry != end; ++affentry) { if (at == 'P') { build_pfxtree(static_cast(*affentry)); } else { build_sfxtree(static_cast(*affentry)); } } //contents belong to AffixMgr now affentries.release(); return true; } int AffixMgr::redundant_condition(char ft, const char* strip, int stripl, const char* cond, int linenum) { 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: line %d: incompatible stripping " "characters and condition\n", linenum); return 0; } } 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: line %d: missing ] in condition:\n%s\n", linenum, cond); return 0; } if ((!neg && !in) || (neg && in)) { HUNSPELL_WARNING(stderr, "warning: line %d: incompatible stripping " "characters and condition\n", linenum); 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: line %d: incompatible stripping " "characters and condition\n", linenum); return 0; } } 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: line: %d: missing ] in condition:\n%s\n", linenum, cond); return 0; } neg = (cond[j + 1] == '^') ? 1 : 0; if ((!neg && !in) || (neg && in)) { HUNSPELL_WARNING(stderr, "warning: line %d: incompatible stripping " "characters and condition\n", linenum); return 0; } } } if (j < 0) return 1; } } return 0; } std::vector AffixMgr::get_suffix_words(short unsigned* suff, int len, const char* root_word) { std::vector slst; short unsigned* start_ptr = suff; for (int j = 0; j < SETSIZE; j++) { SfxEntry* ptr = sStart[j]; while (ptr) { suff = start_ptr; for (int i = 0; i < len; i++) { if ((*suff) == ptr->getFlag()) { std::string nw(root_word); nw.append(ptr->getAffix()); hentry* ht = ptr->checkword(nw.c_str(), nw.size(), 0, NULL, 0, 0, 0); if (ht) { slst.push_back(nw); } } suff++; } ptr = ptr->getNext(); } } return slst; } hunspell-1.7.0/src/hunspell/affixmgr.hxx000066400000000000000000000345541337236234000203440ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #ifndef AFFIXMGR_HXX_ #define AFFIXMGR_HXX_ #include #include #include #include "atypes.hxx" #include "baseaffix.hxx" #include "hashmgr.hxx" #include "phonet.hxx" #include "replist.hxx" // check flag duplication #define dupSFX (1 << 0) #define dupPFX (1 << 1) class PfxEntry; class SfxEntry; class AffixMgr { PfxEntry* pStart[SETSIZE]; SfxEntry* sStart[SETSIZE]; PfxEntry* pFlag[SETSIZE]; SfxEntry* sFlag[SETSIZE]; const std::vector& alldic; const HashMgr* pHMgr; std::string keystring; std::string trystring; std::string encoding; struct cs_info* csconv; int utf8; int complexprefixes; FLAG compoundflag; FLAG compoundbegin; FLAG compoundmiddle; FLAG compoundend; FLAG compoundroot; FLAG compoundforbidflag; FLAG compoundpermitflag; int compoundmoresuffixes; int checkcompounddup; int checkcompoundrep; int checkcompoundcase; int checkcompoundtriple; int simplifiedtriple; FLAG forbiddenword; FLAG nosuggest; FLAG nongramsuggest; FLAG needaffix; int cpdmin; RepList* iconvtable; RepList* oconvtable; bool parsedmaptable; std::vector maptable; bool parsedbreaktable; std::vector breaktable; bool parsedcheckcpd; std::vector checkcpdtable; int simplifiedcpd; bool parseddefcpd; std::vector defcpdtable; phonetable* phone; int maxngramsugs; int maxcpdsugs; int maxdiff; int onlymaxdiff; int nosplitsugs; int sugswithdots; int cpdwordmax; int cpdmaxsyllable; std::string cpdvowels; // vowels (for calculating of Hungarian compounding limit, std::vector cpdvowels_utf16; //vowels for UTF-8 encoding std::string cpdsyllablenum; // syllable count incrementing flag const char* pfxappnd; // BUG: not stateless const char* sfxappnd; // BUG: not stateless int sfxextra; // BUG: not stateless FLAG sfxflag; // BUG: not stateless char* derived; // BUG: not stateless SfxEntry* sfx; // BUG: not stateless PfxEntry* pfx; // BUG: not stateless int checknum; std::string wordchars; // letters + spec. word characters std::vector wordchars_utf16; std::string ignorechars; // letters + spec. word characters std::vector ignorechars_utf16; std::string version; // affix and dictionary file version string std::string lang; // language int langnum; FLAG lemma_present; FLAG circumfix; FLAG onlyincompound; FLAG keepcase; FLAG forceucase; FLAG warn; int forbidwarn; FLAG substandard; int checksharps; int fullstrip; int havecontclass; // boolean variable char contclasses[CONTSIZE]; // flags of possible continuing classes (twofold // affix) public: AffixMgr(const char* affpath, const std::vector& ptr, 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, PfxEntry* ppfx, 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, PfxEntry* ppfx, const FLAG needflag = FLAG_NULL); std::string affix_check_morph(const char* word, int len, const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); std::string prefix_check_morph(const char* word, int len, char in_compound, const FLAG needflag = FLAG_NULL); std::string suffix_check_morph(const char* word, int len, int sfxopts, PfxEntry* ppfx, const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound = IN_CPD_NOT); std::string prefix_check_twosfx_morph(const char* word, int len, char in_compound, const FLAG needflag = FLAG_NULL); std::string suffix_check_twosfx_morph(const char* word, int len, int sfxopts, PfxEntry* ppfx, const FLAG needflag = FLAG_NULL); std::string morphgen(const char* ts, int wl, const unsigned short* ap, unsigned short al, const char* morph, const char* targetmorph, int level); int expand_rootword(struct guessword* wlst, int maxn, const char* ts, int wl, const unsigned short* ap, unsigned short al, const char* bad, int, const char*); short get_syllable(const std::string& word); int cpdrep_check(const char* word, int len); int cpdwordpair_check(const char * word, int len); int cpdpat_check(const char* word, int len, hentry* r1, hentry* r2, const char affixed); 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); void setcminmax(int* cmin, int* cmax, const char* word, int len); struct hentry* compound_check(const std::string& word, short wordnum, short numsyllable, short maxwordnum, short wnum, hentry** words, hentry** rwords, char hu_mov_rule, char is_sug, int* info); int compound_check_morph(const char* word, int len, short wordnum, short numsyllable, short maxwordnum, short wnum, hentry** words, hentry** rwords, char hu_mov_rule, std::string& result, const std::string* partresult); std::vector get_suffix_words(short unsigned* suff, int len, const char* root_word); struct hentry* lookup(const char* word); const std::vector& get_reptable() const; RepList* get_iconvtable() const; RepList* get_oconvtable() const; struct phonetable* get_phonetable() const; const std::vector& get_maptable() const; const std::vector& get_breaktable() const; const std::string& get_encoding(); int get_langnum() const; char* get_key_string(); char* get_try_string() const; const std::string& get_wordchars() const; const std::vector& get_wordchars_utf16() const; const char* get_ignore() const; const std::vector& get_ignore_utf16() const; int get_compound() const; FLAG get_compoundflag() const; FLAG get_forbiddenword() const; FLAG get_nosuggest() const; FLAG get_nongramsuggest() const; FLAG get_substandard() const; FLAG get_needaffix() const; FLAG get_onlyincompound() const; const char* get_derived() const; const std::string& get_version() const; int have_contclass() const; int get_utf8() const; int get_complexprefixes() const; char* get_suffixed(char) const; int get_maxngramsugs() const; int get_maxcpdsugs() const; int get_maxdiff() const; int get_onlymaxdiff() const; int get_nosplitsugs() const; int get_sugswithdots(void) const; FLAG get_keepcase(void) const; FLAG get_forceucase(void) const; FLAG get_warn(void) const; int get_forbidwarn(void) const; int get_checksharps(void) const; char* encode_flag(unsigned short aflag) const; int get_fullstrip() const; private: int parse_file(const char* affpath, const char* key); bool parse_flag(const std::string& line, unsigned short* out, FileMgr* af); bool parse_num(const std::string& line, int* out, FileMgr* af); bool parse_cpdsyllable(const std::string& line, FileMgr* af); bool parse_convtable(const std::string& line, FileMgr* af, RepList** rl, const std::string& keyword); bool parse_phonetable(const std::string& line, FileMgr* af); bool parse_maptable(const std::string& line, FileMgr* af); bool parse_breaktable(const std::string& line, FileMgr* af); bool parse_checkcpdtable(const std::string& line, FileMgr* af); bool parse_defcpdtable(const std::string& line, FileMgr* af); bool parse_affix(const std::string& line, const char at, FileMgr* af, char* dupflags); void reverse_condition(std::string&); std::string& debugflag(std::string& result, unsigned short flag); int condlen(const char*); int encodeit(AffEntry& entry, const char* cs); int build_pfxtree(PfxEntry* pfxptr); int build_sfxtree(SfxEntry* sfxptr); int process_pfx_order(); int process_sfx_order(); PfxEntry* process_pfx_in_order(PfxEntry* ptr, PfxEntry* nptr); SfxEntry* process_sfx_in_order(SfxEntry* ptr, SfxEntry* nptr); int process_pfx_tree_to_list(); int process_sfx_tree_to_list(); int redundant_condition(char, const char* strip, int stripl, const char* cond, int); void finishFileMgr(FileMgr* afflst); }; #endif hunspell-1.7.0/src/hunspell/atypes.hxx000066400000000000000000000075011337236234000200360ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 #include #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 "w_char.hxx" #include #include #include #define SETSIZE 256 #define CONTSIZE 65536 // 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 // info options #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_ORIGCAP (1 << 5) #define SPELL_WARN (1 << 6) #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) (std::binary_search(a, a + c, b)) // timelimit: max. ~1/4 sec (process time on Linux) for // for a suggestion, including max. ~/10 sec for a case // sensitive plain or compound word suggestion, within // ~1/20 sec long time consuming suggestion functions #define TIMELIMIT_GLOBAL (CLOCKS_PER_SEC / 4) #define TIMELIMIT_SUGGESTION (CLOCKS_PER_SEC / 10) #define TIMELIMIT (CLOCKS_PER_SEC / 20) #define MINTIMER 100 #define MAXPLUSTIMER 100 struct guessword { char* word; bool allow; char* orig; }; typedef std::vector mapentry; typedef std::vector flagentry; struct patentry { std::string pattern; std::string pattern2; std::string pattern3; FLAG cond; FLAG cond2; patentry() : cond(FLAG_NULL) , cond2(FLAG_NULL) { } }; #endif hunspell-1.7.0/src/hunspell/baseaffix.hxx000066400000000000000000000047661337236234000204730ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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_ #include class AffEntry { private: AffEntry(const AffEntry&); AffEntry& operator=(const AffEntry&); public: AffEntry() : numconds(0), opts(0), aflag(0), morphcode(0), contclass(NULL), contclasslen(0) {} virtual ~AffEntry(); std::string appnd; std::string strip; unsigned 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 hunspell-1.7.0/src/hunspell/csutil.cxx000066400000000000000000003741711337236234000200410ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include #include #include #include #include "csutil.hxx" #include "atypes.hxx" #include "langnum.hxx" #ifdef _WIN32 #include #include #endif #ifdef OPENOFFICEORG #include #else #ifndef MOZILLA_CLIENT #include "utf_info.hxx" #define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info))) #endif #endif #ifdef MOZILLA_CLIENT #include "nsCOMPtr.h" #include "nsUnicharUtils.h" #include "mozilla/Encoding.h" using namespace mozilla; #endif struct unicode_info2 { char cletter; unsigned short cupper; unsigned short clower; }; static struct unicode_info2* utf_tbl = NULL; static int utf_tbl_count = 0; // utf_tbl can be used by multiple Hunspell instances void myopen(std::ifstream& stream, const char* path, std::ios_base::openmode mode) { #if defined(_WIN32) && defined(_MSC_VER) #define WIN32_LONG_PATH_PREFIX "\\\\?\\" if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) { int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); wchar_t* buff = new wchar_t[len]; wchar_t* buff2 = new wchar_t[len]; MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len); if (_wfullpath(buff2, buff, len) != NULL) { stream.open(buff2, mode); } delete [] buff; delete [] buff2; } else #endif stream.open(path, mode); } std::string& u16_u8(std::string& dest, const std::vector& src) { dest.clear(); std::vector::const_iterator u2 = src.begin(); std::vector::const_iterator u2_max = src.end(); while (u2 < u2_max) { signed char u8; if (u2->h) { // > 0xFF // XXX 4-byte haven't implemented yet. if (u2->h >= 0x08) { // >= 0x800 (3-byte UTF-8 character) u8 = 0xe0 + (u2->h >> 4); dest.push_back(u8); u8 = 0x80 + ((u2->h & 0xf) << 2) + (u2->l >> 6); dest.push_back(u8); u8 = 0x80 + (u2->l & 0x3f); dest.push_back(u8); } else { // < 0x800 (2-byte UTF-8 character) u8 = 0xc0 + (u2->h << 2) + (u2->l >> 6); dest.push_back(u8); u8 = 0x80 + (u2->l & 0x3f); dest.push_back(u8); } } else { // <= 0xFF if (u2->l & 0x80) { // >0x80 (2-byte UTF-8 character) u8 = 0xc0 + (u2->l >> 6); dest.push_back(u8); u8 = 0x80 + (u2->l & 0x3f); dest.push_back(u8); } else { // < 0x80 (1-byte UTF-8 character) u8 = u2->l; dest.push_back(u8); } } ++u2; } return dest; } int u8_u16(std::vector& dest, const std::string& src) { dest.clear(); std::string::const_iterator u8 = src.begin(); std::string::const_iterator u8_max = src.end(); while (u8 < u8_max) { w_char u2; switch ((*u8) & 0xf0) { case 0x00: case 0x10: case 0x20: case 0x30: case 0x40: case 0x50: case 0x60: case 0x70: { u2.h = 0; u2.l = *u8; break; } case 0x80: case 0x90: case 0xa0: case 0xb0: { HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Unexpected continuation bytes " "in %ld. character position\n%s\n", static_cast(std::distance(src.begin(), u8)), src.c_str()); u2.h = 0xff; u2.l = 0xfd; break; } case 0xc0: case 0xd0: { // 2-byte UTF-8 codes if ((*(u8 + 1) & 0xc0) == 0x80) { u2.h = (*u8 & 0x1f) >> 2; u2.l = (static_cast(*u8) << 6) + (*(u8 + 1) & 0x3f); ++u8; } else { HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in " "%ld. character position:\n%s\n", static_cast(std::distance(src.begin(), u8)), src.c_str()); u2.h = 0xff; u2.l = 0xfd; } break; } case 0xe0: { // 3-byte UTF-8 codes if ((*(u8 + 1) & 0xc0) == 0x80) { u2.h = ((*u8 & 0x0f) << 4) + ((*(u8 + 1) & 0x3f) >> 2); ++u8; if ((*(u8 + 1) & 0xc0) == 0x80) { u2.l = (static_cast(*u8) << 6) + (*(u8 + 1) & 0x3f); ++u8; } else { HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte " "in %ld. character position:\n%s\n", static_cast(std::distance(src.begin(), u8)), src.c_str()); u2.h = 0xff; u2.l = 0xfd; } } else { HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in " "%ld. character position:\n%s\n", static_cast(std::distance(src.begin(), u8)), src.c_str()); u2.h = 0xff; u2.l = 0xfd; } break; } case 0xf0: { // 4 or more byte UTF-8 codes HUNSPELL_WARNING(stderr, "This UTF-8 encoding can't convert to UTF-16:\n%s\n", src.c_str()); u2.h = 0xff; u2.l = 0xfd; dest.push_back(u2); return -1; } } dest.push_back(u2); ++u8; } return dest.size(); } namespace { class is_any_of { public: explicit is_any_of(const std::string& in) : chars(in) {} bool operator()(char c) { return chars.find(c) != std::string::npos; } private: std::string chars; }; } std::string::const_iterator mystrsep(const std::string &str, std::string::const_iterator& start) { std::string::const_iterator end = str.end(); is_any_of op(" \t"); // don't use isspace() here, the string can be in some random charset // that's way different than the locale's std::string::const_iterator sp = start; while (sp != end && op(*sp)) ++sp; std::string::const_iterator dp = sp; while (dp != end && !op(*dp)) ++dp; start = dp; return sp; } // replaces strdup with ansi version char* mystrdup(const char* s) { char* d = NULL; if (s) { size_t sl = strlen(s) + 1; d = (char*)malloc(sl); if (d) { memcpy(d, s, sl); } else { HUNSPELL_WARNING(stderr, "Can't allocate memory.\n"); } } return d; } // remove cross-platform text line end characters void mychomp(std::string& s) { size_t k = s.size(); size_t newsize = k; if ((k > 0) && ((s[k - 1] == '\r') || (s[k - 1] == '\n'))) --newsize; if ((k > 1) && (s[k - 2] == '\r')) --newsize; s.resize(newsize); } // break text to lines std::vector line_tok(const std::string& text, char breakchar) { std::vector ret; if (text.empty()) { return ret; } std::stringstream ss(text); std::string tok; while(std::getline(ss, tok, breakchar)) { if (!tok.empty()) { ret.push_back(tok); } } return ret; } // uniq line in place void line_uniq(std::string& text, char breakchar) { std::vector lines = line_tok(text, breakchar); text.clear(); if (lines.empty()) { return; } text = lines[0]; for (size_t i = 1; i < lines.size(); ++i) { bool dup = false; for (size_t j = 0; j < i; ++j) { if (lines[i] == lines[j]) { dup = true; break; } } if (!dup) { if (!text.empty()) text.push_back(breakchar); text.append(lines[i]); } } } // uniq and boundary for compound analysis: "1\n\2\n\1" -> " ( \1 | \2 ) " void line_uniq_app(std::string& text, char breakchar) { if (text.find(breakchar) == std::string::npos) { return; } std::vector lines = line_tok(text, breakchar); text.clear(); if (lines.empty()) { return; } text = lines[0]; for (size_t i = 1; i < lines.size(); ++i) { bool dup = false; for (size_t j = 0; j < i; ++j) { if (lines[i] == lines[j]) { dup = true; break; } } if (!dup) { if (!text.empty()) text.push_back(breakchar); text.append(lines[i]); } } if (lines.size() == 1) { text = lines[0]; return; } text.assign(" ( "); for (size_t i = 0; i < lines.size(); ++i) { text.append(lines[i]); text.append(" | "); } text[text.size() - 2] = ')'; // " ) " } // append s to ends of every lines in text std::string& strlinecat(std::string& str, const std::string& apd) { size_t pos = 0; while ((pos = str.find('\n', pos)) != std::string::npos) { str.insert(pos, apd); pos += apd.length() + 1; } str.append(apd); return str; } int fieldlen(const char* r) { int n = 0; while (r && *r != ' ' && *r != '\t' && *r != '\0' && *r != '\n') { r++; n++; } return n; } bool copy_field(std::string& dest, const std::string& morph, const std::string& var) { if (morph.empty()) return false; size_t pos = morph.find(var); if (pos == std::string::npos) return false; dest.clear(); std::string beg(morph.substr(pos + MORPH_TAG_LEN, std::string::npos)); for (size_t i = 0; i < beg.size(); ++i) { const char c(beg[i]); if (c == ' ' || c == '\t' || c == '\n') break; dest.push_back(c); } return true; } std::string& mystrrep(std::string& str, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = str.find(search, pos)) != std::string::npos) { str.replace(pos, search.length(), replace); pos += replace.length(); } return str; } // reverse word size_t reverseword(std::string& word) { std::reverse(word.begin(), word.end()); return word.size(); } // reverse word size_t reverseword_utf(std::string& word) { std::vector w; u8_u16(w, word); std::reverse(w.begin(), w.end()); u16_u8(word, w); return w.size(); } void uniqlist(std::vector& list) { if (list.size() < 2) return; std::vector ret; ret.push_back(list[0]); for (size_t i = 1; i < list.size(); ++i) { if (std::find(ret.begin(), ret.end(), list[i]) == ret.end()) ret.push_back(list[i]); } list.swap(ret); } namespace { unsigned char cupper(const struct cs_info* csconv, int nIndex) { assert(nIndex >= 0 && nIndex <= 255); return csconv[nIndex].cupper; } unsigned char clower(const struct cs_info* csconv, int nIndex) { assert(nIndex >= 0 && nIndex <= 255); return csconv[nIndex].clower; } unsigned char ccase(const struct cs_info* csconv, int nIndex) { assert(nIndex >= 0 && nIndex <= 255); return csconv[nIndex].ccase; } } w_char upper_utf(w_char u, int langnum) { unsigned short idx = (u.h << 8) + u.l; unsigned short upridx = unicodetoupper(idx, langnum); if (idx != upridx) { u.h = (unsigned char)(upridx >> 8); u.l = (unsigned char)(upridx & 0x00FF); } return u; } w_char lower_utf(w_char u, int langnum) { unsigned short idx = (u.h << 8) + u.l; unsigned short lwridx = unicodetolower(idx, langnum); if (idx != lwridx) { u.h = (unsigned char)(lwridx >> 8); u.l = (unsigned char)(lwridx & 0x00FF); } return u; } // convert std::string to all caps std::string& mkallcap(std::string& s, const struct cs_info* csconv) { for (std::string::iterator aI = s.begin(), aEnd = s.end(); aI != aEnd; ++aI) { *aI = cupper(csconv, static_cast(*aI)); } return s; } // convert std::string to all little std::string& mkallsmall(std::string& s, const struct cs_info* csconv) { for (std::string::iterator aI = s.begin(), aEnd = s.end(); aI != aEnd; ++aI) { *aI = clower(csconv, static_cast(*aI)); } return s; } std::vector& mkallsmall_utf(std::vector& u, int langnum) { for (size_t i = 0; i < u.size(); ++i) { unsigned short idx = (u[i].h << 8) + u[i].l; unsigned short lwridx = unicodetolower(idx, langnum); if (idx != lwridx) { u[i].h = (unsigned char)(lwridx >> 8); u[i].l = (unsigned char)(lwridx & 0x00FF); } } return u; } std::vector& mkallcap_utf(std::vector& u, int langnum) { for (size_t i = 0; i < u.size(); i++) { unsigned short idx = (u[i].h << 8) + u[i].l; unsigned short upridx = unicodetoupper(idx, langnum); if (idx != upridx) { u[i].h = (unsigned char)(upridx >> 8); u[i].l = (unsigned char)(upridx & 0x00FF); } } return u; } std::string& mkinitcap(std::string& s, const struct cs_info* csconv) { if (!s.empty()) { s[0] = cupper(csconv, static_cast(s[0])); } return s; } std::vector& mkinitcap_utf(std::vector& u, int langnum) { if (!u.empty()) { unsigned short idx = (u[0].h << 8) + u[0].l; unsigned short upridx = unicodetoupper(idx, langnum); if (idx != upridx) { u[0].h = (unsigned char)(upridx >> 8); u[0].l = (unsigned char)(upridx & 0x00FF); } } return u; } std::string& mkinitsmall(std::string& s, const struct cs_info* csconv) { if (!s.empty()) { s[0] = clower(csconv, static_cast(s[0])); } return s; } std::vector& mkinitsmall_utf(std::vector& u, int langnum) { if (!u.empty()) { unsigned short idx = (u[0].h << 8) + u[0].l; unsigned short lwridx = unicodetolower(idx, langnum); if (idx != lwridx) { u[0].h = (unsigned char)(lwridx >> 8); u[0].l = (unsigned char)(lwridx & 0x00FF); } } return u; } // conversion function for protected memory void store_pointer(char* dest, char* source) { memcpy(dest, &source, sizeof(char*)); } // conversion function for protected memory char* get_stored_pointer(const char* s) { char* p; memcpy(&p, s, sizeof(char*)); return p; } #ifndef MOZILLA_CLIENT // these are simple character mappings for the // encodings supported // supplying isupper, tolower, and toupper static struct cs_info iso1_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd}, {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xff}}; static struct cs_info iso2_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xb1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x01, 0xb3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x01, 0xb5, 0xa5}, {0x01, 0xb6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x01, 0xb9, 0xa9}, {0x01, 0xba, 0xaa}, {0x01, 0xbb, 0xab}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad}, {0x01, 0xbe, 0xae}, {0x01, 0xbf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xa1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xa3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xa5}, {0x00, 0xb6, 0xa6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xa9}, {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xab}, {0x00, 0xbc, 0xac}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xae}, {0x00, 0xbf, 0xaf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd}, {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xff}}; static struct cs_info iso3_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xb1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x01, 0xb6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x01, 0x69, 0xa9}, {0x01, 0xba, 0xaa}, {0x01, 0xbb, 0xab}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x01, 0xbf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xa1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xa6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0x49}, {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xab}, {0x00, 0xbc, 0xac}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xaf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x00, 0xc3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x00, 0xd0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd}, {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xe3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xff}}; static struct cs_info iso4_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xb1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x01, 0xb3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x01, 0xb5, 0xa5}, {0x01, 0xb6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x01, 0xb9, 0xa9}, {0x01, 0xba, 0xaa}, {0x01, 0xbb, 0xab}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad}, {0x01, 0xbe, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xa1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xa3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xa5}, {0x00, 0xb6, 0xa6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xa9}, {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xab}, {0x00, 0xbc, 0xac}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xae}, {0x00, 0xbf, 0xbf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd}, {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xff}}; static struct cs_info iso5_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xf1, 0xa1}, {0x01, 0xf2, 0xa2}, {0x01, 0xf3, 0xa3}, {0x01, 0xf4, 0xa4}, {0x01, 0xf5, 0xa5}, {0x01, 0xf6, 0xa6}, {0x01, 0xf7, 0xa7}, {0x01, 0xf8, 0xa8}, {0x01, 0xf9, 0xa9}, {0x01, 0xfa, 0xaa}, {0x01, 0xfb, 0xab}, {0x01, 0xfc, 0xac}, {0x00, 0xad, 0xad}, {0x01, 0xfe, 0xae}, {0x01, 0xff, 0xaf}, {0x01, 0xd0, 0xb0}, {0x01, 0xd1, 0xb1}, {0x01, 0xd2, 0xb2}, {0x01, 0xd3, 0xb3}, {0x01, 0xd4, 0xb4}, {0x01, 0xd5, 0xb5}, {0x01, 0xd6, 0xb6}, {0x01, 0xd7, 0xb7}, {0x01, 0xd8, 0xb8}, {0x01, 0xd9, 0xb9}, {0x01, 0xda, 0xba}, {0x01, 0xdb, 0xbb}, {0x01, 0xdc, 0xbc}, {0x01, 0xdd, 0xbd}, {0x01, 0xde, 0xbe}, {0x01, 0xdf, 0xbf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x00, 0xd0, 0xb0}, {0x00, 0xd1, 0xb1}, {0x00, 0xd2, 0xb2}, {0x00, 0xd3, 0xb3}, {0x00, 0xd4, 0xb4}, {0x00, 0xd5, 0xb5}, {0x00, 0xd6, 0xb6}, {0x00, 0xd7, 0xb7}, {0x00, 0xd8, 0xb8}, {0x00, 0xd9, 0xb9}, {0x00, 0xda, 0xba}, {0x00, 0xdb, 0xbb}, {0x00, 0xdc, 0xbc}, {0x00, 0xdd, 0xbd}, {0x00, 0xde, 0xbe}, {0x00, 0xdf, 0xbf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xa1}, {0x00, 0xf2, 0xa2}, {0x00, 0xf3, 0xa3}, {0x00, 0xf4, 0xa4}, {0x00, 0xf5, 0xa5}, {0x00, 0xf6, 0xa6}, {0x00, 0xf7, 0xa7}, {0x00, 0xf8, 0xa8}, {0x00, 0xf9, 0xa9}, {0x00, 0xfa, 0xaa}, {0x00, 0xfb, 0xab}, {0x00, 0xfc, 0xac}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xae}, {0x00, 0xff, 0xaf}}; static struct cs_info iso6_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2}, {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5}, {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8}, {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb}, {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce}, {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1}, {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4}, {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda}, {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd}, {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0}, {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3}, {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6}, {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9}, {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec}, {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef}, {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2}, {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5}, {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8}, {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb}, {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe}, {0x00, 0xff, 0xff}}; static struct cs_info iso7_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x01, 0xdc, 0xb6}, {0x00, 0xb7, 0xb7}, {0x01, 0xdd, 0xb8}, {0x01, 0xde, 0xb9}, {0x01, 0xdf, 0xba}, {0x00, 0xbb, 0xbb}, {0x01, 0xfc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x01, 0xfd, 0xbe}, {0x01, 0xfe, 0xbf}, {0x00, 0xc0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x00, 0xd2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x01, 0xf7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x00, 0xdc, 0xb6}, {0x00, 0xdd, 0xb8}, {0x00, 0xde, 0xb9}, {0x00, 0xdf, 0xba}, {0x00, 0xe0, 0xe0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd3}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xd7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xbc}, {0x00, 0xfd, 0xbe}, {0x00, 0xfe, 0xbf}, {0x00, 0xff, 0xff}}; static struct cs_info iso8_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2}, {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5}, {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8}, {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb}, {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce}, {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1}, {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4}, {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda}, {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd}, {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0}, {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3}, {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6}, {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9}, {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec}, {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef}, {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2}, {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5}, {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8}, {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb}, {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe}, {0x00, 0xff, 0xff}}; static struct cs_info iso9_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0xfd, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0xdd}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0x69, 0xdd}, {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0x49}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xff}}; static struct cs_info iso10_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2}, {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5}, {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8}, {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb}, {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce}, {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1}, {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4}, {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda}, {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd}, {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0}, {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3}, {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6}, {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9}, {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec}, {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef}, {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2}, {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5}, {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8}, {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb}, {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe}, {0x00, 0xff, 0xff}}; static struct cs_info koi8r_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xb3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x01, 0xa3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xe0}, {0x00, 0xc1, 0xe1}, {0x00, 0xc2, 0xe2}, {0x00, 0xc3, 0xe3}, {0x00, 0xc4, 0xe4}, {0x00, 0xc5, 0xe5}, {0x00, 0xc6, 0xe6}, {0x00, 0xc7, 0xe7}, {0x00, 0xc8, 0xe8}, {0x00, 0xc9, 0xe9}, {0x00, 0xca, 0xea}, {0x00, 0xcb, 0xeb}, {0x00, 0xcc, 0xec}, {0x00, 0xcd, 0xed}, {0x00, 0xce, 0xee}, {0x00, 0xcf, 0xef}, {0x00, 0xd0, 0xf0}, {0x00, 0xd1, 0xf1}, {0x00, 0xd2, 0xf2}, {0x00, 0xd3, 0xf3}, {0x00, 0xd4, 0xf4}, {0x00, 0xd5, 0xf5}, {0x00, 0xd6, 0xf6}, {0x00, 0xd7, 0xf7}, {0x00, 0xd8, 0xf8}, {0x00, 0xd9, 0xf9}, {0x00, 0xda, 0xfa}, {0x00, 0xdb, 0xfb}, {0x00, 0xdc, 0xfc}, {0x00, 0xdd, 0xfd}, {0x00, 0xde, 0xfe}, {0x00, 0xdf, 0xff}, {0x01, 0xc0, 0xe0}, {0x01, 0xc1, 0xe1}, {0x01, 0xc2, 0xe2}, {0x01, 0xc3, 0xe3}, {0x01, 0xc4, 0xe4}, {0x01, 0xc5, 0xe5}, {0x01, 0xc6, 0xe6}, {0x01, 0xc7, 0xe7}, {0x01, 0xc8, 0xe8}, {0x01, 0xc9, 0xe9}, {0x01, 0xca, 0xea}, {0x01, 0xcb, 0xeb}, {0x01, 0xcc, 0xec}, {0x01, 0xcd, 0xed}, {0x01, 0xce, 0xee}, {0x01, 0xcf, 0xef}, {0x01, 0xd0, 0xf0}, {0x01, 0xd1, 0xf1}, {0x01, 0xd2, 0xf2}, {0x01, 0xd3, 0xf3}, {0x01, 0xd4, 0xf4}, {0x01, 0xd5, 0xf5}, {0x01, 0xd6, 0xf6}, {0x01, 0xd7, 0xf7}, {0x01, 0xd8, 0xf8}, {0x01, 0xd9, 0xf9}, {0x01, 0xda, 0xfa}, {0x01, 0xdb, 0xfb}, {0x01, 0xdc, 0xfc}, {0x01, 0xdd, 0xfd}, {0x01, 0xde, 0xfe}, {0x01, 0xdf, 0xff}}; static struct cs_info koi8u_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xb3}, {0x00, 0xa4, 0xb4}, /* ie */ {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xb6}, /* i */ {0x00, 0xa7, 0xb7}, /* ii */ {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xbd}, /* g'' */ {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x01, 0xa3, 0xb3}, {0x00, 0xb4, 0xb4}, /* IE */ {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, /* I */ {0x00, 0xb7, 0xb7}, /* II */ {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xe0}, {0x00, 0xc1, 0xe1}, {0x00, 0xc2, 0xe2}, {0x00, 0xc3, 0xe3}, {0x00, 0xc4, 0xe4}, {0x00, 0xc5, 0xe5}, {0x00, 0xc6, 0xe6}, {0x00, 0xc7, 0xe7}, {0x00, 0xc8, 0xe8}, {0x00, 0xc9, 0xe9}, {0x00, 0xca, 0xea}, {0x00, 0xcb, 0xeb}, {0x00, 0xcc, 0xec}, {0x00, 0xcd, 0xed}, {0x00, 0xce, 0xee}, {0x00, 0xcf, 0xef}, {0x00, 0xd0, 0xf0}, {0x00, 0xd1, 0xf1}, {0x00, 0xd2, 0xf2}, {0x00, 0xd3, 0xf3}, {0x00, 0xd4, 0xf4}, {0x00, 0xd5, 0xf5}, {0x00, 0xd6, 0xf6}, {0x00, 0xd7, 0xf7}, {0x00, 0xd8, 0xf8}, {0x00, 0xd9, 0xf9}, {0x00, 0xda, 0xfa}, {0x00, 0xdb, 0xfb}, {0x00, 0xdc, 0xfc}, {0x00, 0xdd, 0xfd}, {0x00, 0xde, 0xfe}, {0x00, 0xdf, 0xff}, {0x01, 0xc0, 0xe0}, {0x01, 0xc1, 0xe1}, {0x01, 0xc2, 0xe2}, {0x01, 0xc3, 0xe3}, {0x01, 0xc4, 0xe4}, {0x01, 0xc5, 0xe5}, {0x01, 0xc6, 0xe6}, {0x01, 0xc7, 0xe7}, {0x01, 0xc8, 0xe8}, {0x01, 0xc9, 0xe9}, {0x01, 0xca, 0xea}, {0x01, 0xcb, 0xeb}, {0x01, 0xcc, 0xec}, {0x01, 0xcd, 0xed}, {0x01, 0xce, 0xee}, {0x01, 0xcf, 0xef}, {0x01, 0xd0, 0xf0}, {0x01, 0xd1, 0xf1}, {0x01, 0xd2, 0xf2}, {0x01, 0xd3, 0xf3}, {0x01, 0xd4, 0xf4}, {0x01, 0xd5, 0xf5}, {0x01, 0xd6, 0xf6}, {0x01, 0xd7, 0xf7}, {0x01, 0xd8, 0xf8}, {0x01, 0xd9, 0xf9}, {0x01, 0xda, 0xfa}, {0x01, 0xdb, 0xfb}, {0x01, 0xdc, 0xfc}, {0x01, 0xdd, 0xfd}, {0x01, 0xde, 0xfe}, {0x01, 0xdf, 0xff}}; static struct cs_info cp1251_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x01, 0x90, 0x80}, {0x01, 0x83, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x81}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x01, 0x9a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x01, 0x9c, 0x8c}, {0x01, 0x9d, 0x8d}, {0x01, 0x9e, 0x8e}, {0x01, 0x9f, 0x8f}, {0x00, 0x90, 0x80}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x8a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x8c}, {0x00, 0x9d, 0x8d}, {0x00, 0x9e, 0x8e}, {0x00, 0x9f, 0x8f}, {0x00, 0xa0, 0xa0}, {0x01, 0xa2, 0xa1}, {0x00, 0xa2, 0xa1}, {0x01, 0xbc, 0xa3}, {0x00, 0xa4, 0xa4}, {0x01, 0xb4, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x01, 0xb8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x01, 0xba, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x01, 0xbf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x01, 0xb3, 0xb2}, {0x00, 0xb3, 0xb2}, {0x00, 0xb4, 0xa5}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xa8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xaa}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xa3}, {0x01, 0xbe, 0xbd}, {0x00, 0xbe, 0xbd}, {0x00, 0xbf, 0xaf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x01, 0xf7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd}, {0x01, 0xfe, 0xde}, {0x01, 0xff, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xd7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xdf}}; static struct cs_info iso13_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0A, 0x0A}, {0x00, 0x0B, 0x0B}, {0x00, 0x0C, 0x0C}, {0x00, 0x0D, 0x0D}, {0x00, 0x0E, 0x0E}, {0x00, 0x0F, 0x0F}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1A, 0x1A}, {0x00, 0x1B, 0x1B}, {0x00, 0x1C, 0x1C}, {0x00, 0x1D, 0x1D}, {0x00, 0x1E, 0x1E}, {0x00, 0x1F, 0x1F}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2A, 0x2A}, {0x00, 0x2B, 0x2B}, {0x00, 0x2C, 0x2C}, {0x00, 0x2D, 0x2D}, {0x00, 0x2E, 0x2E}, {0x00, 0x2F, 0x2F}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3A, 0x3A}, {0x00, 0x3B, 0x3B}, {0x00, 0x3C, 0x3C}, {0x00, 0x3D, 0x3D}, {0x00, 0x3E, 0x3E}, {0x00, 0x3F, 0x3F}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6A, 0x4A}, {0x01, 0x6B, 0x4B}, {0x01, 0x6C, 0x4C}, {0x01, 0x6D, 0x4D}, {0x01, 0x6E, 0x4E}, {0x01, 0x6F, 0x4F}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7A, 0x5A}, {0x00, 0x5B, 0x5B}, {0x00, 0x5C, 0x5C}, {0x00, 0x5D, 0x5D}, {0x00, 0x5E, 0x5E}, {0x00, 0x5F, 0x5F}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6A, 0x4A}, {0x00, 0x6B, 0x4B}, {0x00, 0x6C, 0x4C}, {0x00, 0x6D, 0x4D}, {0x00, 0x6E, 0x4E}, {0x00, 0x6F, 0x4F}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7A, 0x5A}, {0x00, 0x7B, 0x7B}, {0x00, 0x7C, 0x7C}, {0x00, 0x7D, 0x7D}, {0x00, 0x7E, 0x7E}, {0x00, 0x7F, 0x7F}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8A, 0x8A}, {0x00, 0x8B, 0x8B}, {0x00, 0x8C, 0x8C}, {0x00, 0x8D, 0x8D}, {0x00, 0x8E, 0x8E}, {0x00, 0x8F, 0x8F}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9A, 0x9A}, {0x00, 0x9B, 0x9B}, {0x00, 0x9C, 0x9C}, {0x00, 0x9D, 0x9D}, {0x00, 0x9E, 0x9E}, {0x00, 0x9F, 0x9F}, {0x00, 0xA0, 0xA0}, {0x00, 0xA1, 0xA1}, {0x00, 0xA2, 0xA2}, {0x00, 0xA3, 0xA3}, {0x00, 0xA4, 0xA4}, {0x00, 0xA5, 0xA5}, {0x00, 0xA6, 0xA6}, {0x00, 0xA7, 0xA7}, {0x01, 0xB8, 0xA8}, {0x00, 0xA9, 0xA9}, {0x01, 0xBA, 0xAA}, {0x00, 0xAB, 0xAB}, {0x00, 0xAC, 0xAC}, {0x00, 0xAD, 0xAD}, {0x00, 0xAE, 0xAE}, {0x01, 0xBF, 0xAF}, {0x00, 0xB0, 0xB0}, {0x00, 0xB1, 0xB1}, {0x00, 0xB2, 0xB2}, {0x00, 0xB3, 0xB3}, {0x00, 0xB4, 0xB4}, {0x00, 0xB5, 0xB5}, {0x00, 0xB6, 0xB6}, {0x00, 0xB7, 0xB7}, {0x00, 0xB8, 0xA8}, {0x00, 0xB9, 0xB9}, {0x00, 0xBA, 0xAA}, {0x00, 0xBB, 0xBB}, {0x00, 0xBC, 0xBC}, {0x00, 0xBD, 0xBD}, {0x00, 0xBE, 0xBE}, {0x00, 0xBF, 0xAF}, {0x01, 0xE0, 0xC0}, {0x01, 0xE1, 0xC1}, {0x01, 0xE2, 0xC2}, {0x01, 0xE3, 0xC3}, {0x01, 0xE4, 0xC4}, {0x01, 0xE5, 0xC5}, {0x01, 0xE6, 0xC6}, {0x01, 0xE7, 0xC7}, {0x01, 0xE8, 0xC8}, {0x01, 0xE9, 0xC9}, {0x01, 0xEA, 0xCA}, {0x01, 0xEB, 0xCB}, {0x01, 0xEC, 0xCC}, {0x01, 0xED, 0xCD}, {0x01, 0xEE, 0xCE}, {0x01, 0xEF, 0xCF}, {0x01, 0xF0, 0xD0}, {0x01, 0xF1, 0xD1}, {0x01, 0xF2, 0xD2}, {0x01, 0xF3, 0xD3}, {0x01, 0xF4, 0xD4}, {0x01, 0xF5, 0xD5}, {0x01, 0xF6, 0xD6}, {0x00, 0xD7, 0xD7}, {0x01, 0xF8, 0xD8}, {0x01, 0xF9, 0xD9}, {0x01, 0xFA, 0xDA}, {0x01, 0xFB, 0xDB}, {0x01, 0xFC, 0xDC}, {0x01, 0xFD, 0xDD}, {0x01, 0xFE, 0xDE}, {0x00, 0xDF, 0xDF}, {0x00, 0xE0, 0xC0}, {0x00, 0xE1, 0xC1}, {0x00, 0xE2, 0xC2}, {0x00, 0xE3, 0xC3}, {0x00, 0xE4, 0xC4}, {0x00, 0xE5, 0xC5}, {0x00, 0xE6, 0xC6}, {0x00, 0xE7, 0xC7}, {0x00, 0xE8, 0xC8}, {0x00, 0xE9, 0xC9}, {0x00, 0xEA, 0xCA}, {0x00, 0xEB, 0xCB}, {0x00, 0xEC, 0xCC}, {0x00, 0xED, 0xCD}, {0x00, 0xEE, 0xCE}, {0x00, 0xEF, 0xCF}, {0x00, 0xF0, 0xD0}, {0x00, 0xF1, 0xD1}, {0x00, 0xF2, 0xD2}, {0x00, 0xF3, 0xD3}, {0x00, 0xF4, 0xD4}, {0x00, 0xF5, 0xD5}, {0x00, 0xF6, 0xD6}, {0x00, 0xF7, 0xF7}, {0x00, 0xF8, 0xD8}, {0x00, 0xF9, 0xD9}, {0x00, 0xFA, 0xDA}, {0x00, 0xFB, 0xDB}, {0x00, 0xFC, 0xDC}, {0x00, 0xFD, 0xDD}, {0x00, 0xFE, 0xDE}, {0x00, 0xFF, 0xFF}}; static struct cs_info iso14_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x01, 0xa2, 0xa1}, {0x00, 0xa2, 0xa1}, {0x00, 0xa3, 0xa3}, {0x01, 0xa5, 0xa4}, {0x00, 0xa5, 0xa4}, {0x01, 0xa6, 0xab}, {0x00, 0xa7, 0xa7}, {0x01, 0xb8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x01, 0xba, 0xaa}, {0x00, 0xab, 0xa6}, {0x01, 0xbc, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x01, 0xff, 0xaf}, {0x01, 0xb1, 0xb0}, {0x00, 0xb1, 0xb0}, {0x01, 0xb3, 0xb2}, {0x00, 0xb3, 0xb2}, {0x01, 0xb5, 0xb4}, {0x00, 0xb5, 0xb4}, {0x00, 0xb6, 0xb6}, {0x01, 0xb9, 0xb7}, {0x00, 0xb8, 0xa8}, {0x00, 0xb9, 0xb6}, {0x00, 0xba, 0xaa}, {0x01, 0xbf, 0xbb}, {0x00, 0xbc, 0xac}, {0x01, 0xbe, 0xbd}, {0x00, 0xbe, 0xbd}, {0x00, 0xbf, 0xbb}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x01, 0xf7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd}, {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xd7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xff}}; static struct cs_info iso15_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x01, 0xa8, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa6}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x01, 0xb8, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb4}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x01, 0xbd, 0xbc}, {0x00, 0xbd, 0xbc}, {0x01, 0xff, 0xbe}, {0x00, 0xbf, 0xbf}, {0x01, 0xe0, 0xc0}, {0x01, 0xe1, 0xc1}, {0x01, 0xe2, 0xc2}, {0x01, 0xe3, 0xc3}, {0x01, 0xe4, 0xc4}, {0x01, 0xe5, 0xc5}, {0x01, 0xe6, 0xc6}, {0x01, 0xe7, 0xc7}, {0x01, 0xe8, 0xc8}, {0x01, 0xe9, 0xc9}, {0x01, 0xea, 0xca}, {0x01, 0xeb, 0xcb}, {0x01, 0xec, 0xcc}, {0x01, 0xed, 0xcd}, {0x01, 0xee, 0xce}, {0x01, 0xef, 0xcf}, {0x01, 0xf0, 0xd0}, {0x01, 0xf1, 0xd1}, {0x01, 0xf2, 0xd2}, {0x01, 0xf3, 0xd3}, {0x01, 0xf4, 0xd4}, {0x01, 0xf5, 0xd5}, {0x01, 0xf6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x01, 0xf8, 0xd8}, {0x01, 0xf9, 0xd9}, {0x01, 0xfa, 0xda}, {0x01, 0xfb, 0xdb}, {0x01, 0xfc, 0xdc}, {0x01, 0xfd, 0xdd}, {0x01, 0xfe, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xc0}, {0x00, 0xe1, 0xc1}, {0x00, 0xe2, 0xc2}, {0x00, 0xe3, 0xc3}, {0x00, 0xe4, 0xc4}, {0x00, 0xe5, 0xc5}, {0x00, 0xe6, 0xc6}, {0x00, 0xe7, 0xc7}, {0x00, 0xe8, 0xc8}, {0x00, 0xe9, 0xc9}, {0x00, 0xea, 0xca}, {0x00, 0xeb, 0xcb}, {0x00, 0xec, 0xcc}, {0x00, 0xed, 0xcd}, {0x00, 0xee, 0xce}, {0x00, 0xef, 0xcf}, {0x00, 0xf0, 0xd0}, {0x00, 0xf1, 0xd1}, {0x00, 0xf2, 0xd2}, {0x00, 0xf3, 0xd3}, {0x00, 0xf4, 0xd4}, {0x00, 0xf5, 0xd5}, {0x00, 0xf6, 0xd6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xd8}, {0x00, 0xf9, 0xd9}, {0x00, 0xfa, 0xda}, {0x00, 0xfb, 0xdb}, {0x00, 0xfc, 0xdc}, {0x00, 0xfd, 0xdd}, {0x00, 0xfe, 0xde}, {0x00, 0xff, 0xbe}}; static struct cs_info iscii_devanagari_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2}, {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5}, {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8}, {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb}, {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce}, {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1}, {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4}, {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda}, {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd}, {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0}, {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3}, {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6}, {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9}, {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec}, {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef}, {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2}, {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5}, {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8}, {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb}, {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe}, {0x00, 0xff, 0xff}}; static struct cs_info tis620_tbl[] = { {0x00, 0x00, 0x00}, {0x00, 0x01, 0x01}, {0x00, 0x02, 0x02}, {0x00, 0x03, 0x03}, {0x00, 0x04, 0x04}, {0x00, 0x05, 0x05}, {0x00, 0x06, 0x06}, {0x00, 0x07, 0x07}, {0x00, 0x08, 0x08}, {0x00, 0x09, 0x09}, {0x00, 0x0a, 0x0a}, {0x00, 0x0b, 0x0b}, {0x00, 0x0c, 0x0c}, {0x00, 0x0d, 0x0d}, {0x00, 0x0e, 0x0e}, {0x00, 0x0f, 0x0f}, {0x00, 0x10, 0x10}, {0x00, 0x11, 0x11}, {0x00, 0x12, 0x12}, {0x00, 0x13, 0x13}, {0x00, 0x14, 0x14}, {0x00, 0x15, 0x15}, {0x00, 0x16, 0x16}, {0x00, 0x17, 0x17}, {0x00, 0x18, 0x18}, {0x00, 0x19, 0x19}, {0x00, 0x1a, 0x1a}, {0x00, 0x1b, 0x1b}, {0x00, 0x1c, 0x1c}, {0x00, 0x1d, 0x1d}, {0x00, 0x1e, 0x1e}, {0x00, 0x1f, 0x1f}, {0x00, 0x20, 0x20}, {0x00, 0x21, 0x21}, {0x00, 0x22, 0x22}, {0x00, 0x23, 0x23}, {0x00, 0x24, 0x24}, {0x00, 0x25, 0x25}, {0x00, 0x26, 0x26}, {0x00, 0x27, 0x27}, {0x00, 0x28, 0x28}, {0x00, 0x29, 0x29}, {0x00, 0x2a, 0x2a}, {0x00, 0x2b, 0x2b}, {0x00, 0x2c, 0x2c}, {0x00, 0x2d, 0x2d}, {0x00, 0x2e, 0x2e}, {0x00, 0x2f, 0x2f}, {0x00, 0x30, 0x30}, {0x00, 0x31, 0x31}, {0x00, 0x32, 0x32}, {0x00, 0x33, 0x33}, {0x00, 0x34, 0x34}, {0x00, 0x35, 0x35}, {0x00, 0x36, 0x36}, {0x00, 0x37, 0x37}, {0x00, 0x38, 0x38}, {0x00, 0x39, 0x39}, {0x00, 0x3a, 0x3a}, {0x00, 0x3b, 0x3b}, {0x00, 0x3c, 0x3c}, {0x00, 0x3d, 0x3d}, {0x00, 0x3e, 0x3e}, {0x00, 0x3f, 0x3f}, {0x00, 0x40, 0x40}, {0x01, 0x61, 0x41}, {0x01, 0x62, 0x42}, {0x01, 0x63, 0x43}, {0x01, 0x64, 0x44}, {0x01, 0x65, 0x45}, {0x01, 0x66, 0x46}, {0x01, 0x67, 0x47}, {0x01, 0x68, 0x48}, {0x01, 0x69, 0x49}, {0x01, 0x6a, 0x4a}, {0x01, 0x6b, 0x4b}, {0x01, 0x6c, 0x4c}, {0x01, 0x6d, 0x4d}, {0x01, 0x6e, 0x4e}, {0x01, 0x6f, 0x4f}, {0x01, 0x70, 0x50}, {0x01, 0x71, 0x51}, {0x01, 0x72, 0x52}, {0x01, 0x73, 0x53}, {0x01, 0x74, 0x54}, {0x01, 0x75, 0x55}, {0x01, 0x76, 0x56}, {0x01, 0x77, 0x57}, {0x01, 0x78, 0x58}, {0x01, 0x79, 0x59}, {0x01, 0x7a, 0x5a}, {0x00, 0x5b, 0x5b}, {0x00, 0x5c, 0x5c}, {0x00, 0x5d, 0x5d}, {0x00, 0x5e, 0x5e}, {0x00, 0x5f, 0x5f}, {0x00, 0x60, 0x60}, {0x00, 0x61, 0x41}, {0x00, 0x62, 0x42}, {0x00, 0x63, 0x43}, {0x00, 0x64, 0x44}, {0x00, 0x65, 0x45}, {0x00, 0x66, 0x46}, {0x00, 0x67, 0x47}, {0x00, 0x68, 0x48}, {0x00, 0x69, 0x49}, {0x00, 0x6a, 0x4a}, {0x00, 0x6b, 0x4b}, {0x00, 0x6c, 0x4c}, {0x00, 0x6d, 0x4d}, {0x00, 0x6e, 0x4e}, {0x00, 0x6f, 0x4f}, {0x00, 0x70, 0x50}, {0x00, 0x71, 0x51}, {0x00, 0x72, 0x52}, {0x00, 0x73, 0x53}, {0x00, 0x74, 0x54}, {0x00, 0x75, 0x55}, {0x00, 0x76, 0x56}, {0x00, 0x77, 0x57}, {0x00, 0x78, 0x58}, {0x00, 0x79, 0x59}, {0x00, 0x7a, 0x5a}, {0x00, 0x7b, 0x7b}, {0x00, 0x7c, 0x7c}, {0x00, 0x7d, 0x7d}, {0x00, 0x7e, 0x7e}, {0x00, 0x7f, 0x7f}, {0x00, 0x80, 0x80}, {0x00, 0x81, 0x81}, {0x00, 0x82, 0x82}, {0x00, 0x83, 0x83}, {0x00, 0x84, 0x84}, {0x00, 0x85, 0x85}, {0x00, 0x86, 0x86}, {0x00, 0x87, 0x87}, {0x00, 0x88, 0x88}, {0x00, 0x89, 0x89}, {0x00, 0x8a, 0x8a}, {0x00, 0x8b, 0x8b}, {0x00, 0x8c, 0x8c}, {0x00, 0x8d, 0x8d}, {0x00, 0x8e, 0x8e}, {0x00, 0x8f, 0x8f}, {0x00, 0x90, 0x90}, {0x00, 0x91, 0x91}, {0x00, 0x92, 0x92}, {0x00, 0x93, 0x93}, {0x00, 0x94, 0x94}, {0x00, 0x95, 0x95}, {0x00, 0x96, 0x96}, {0x00, 0x97, 0x97}, {0x00, 0x98, 0x98}, {0x00, 0x99, 0x99}, {0x00, 0x9a, 0x9a}, {0x00, 0x9b, 0x9b}, {0x00, 0x9c, 0x9c}, {0x00, 0x9d, 0x9d}, {0x00, 0x9e, 0x9e}, {0x00, 0x9f, 0x9f}, {0x00, 0xa0, 0xa0}, {0x00, 0xa1, 0xa1}, {0x00, 0xa2, 0xa2}, {0x00, 0xa3, 0xa3}, {0x00, 0xa4, 0xa4}, {0x00, 0xa5, 0xa5}, {0x00, 0xa6, 0xa6}, {0x00, 0xa7, 0xa7}, {0x00, 0xa8, 0xa8}, {0x00, 0xa9, 0xa9}, {0x00, 0xaa, 0xaa}, {0x00, 0xab, 0xab}, {0x00, 0xac, 0xac}, {0x00, 0xad, 0xad}, {0x00, 0xae, 0xae}, {0x00, 0xaf, 0xaf}, {0x00, 0xb0, 0xb0}, {0x00, 0xb1, 0xb1}, {0x00, 0xb2, 0xb2}, {0x00, 0xb3, 0xb3}, {0x00, 0xb4, 0xb4}, {0x00, 0xb5, 0xb5}, {0x00, 0xb6, 0xb6}, {0x00, 0xb7, 0xb7}, {0x00, 0xb8, 0xb8}, {0x00, 0xb9, 0xb9}, {0x00, 0xba, 0xba}, {0x00, 0xbb, 0xbb}, {0x00, 0xbc, 0xbc}, {0x00, 0xbd, 0xbd}, {0x00, 0xbe, 0xbe}, {0x00, 0xbf, 0xbf}, {0x00, 0xc0, 0xc0}, {0x00, 0xc1, 0xc1}, {0x00, 0xc2, 0xc2}, {0x00, 0xc3, 0xc3}, {0x00, 0xc4, 0xc4}, {0x00, 0xc5, 0xc5}, {0x00, 0xc6, 0xc6}, {0x00, 0xc7, 0xc7}, {0x00, 0xc8, 0xc8}, {0x00, 0xc9, 0xc9}, {0x00, 0xca, 0xca}, {0x00, 0xcb, 0xcb}, {0x00, 0xcc, 0xcc}, {0x00, 0xcd, 0xcd}, {0x00, 0xce, 0xce}, {0x00, 0xcf, 0xcf}, {0x00, 0xd0, 0xd0}, {0x00, 0xd1, 0xd1}, {0x00, 0xd2, 0xd2}, {0x00, 0xd3, 0xd3}, {0x00, 0xd4, 0xd4}, {0x00, 0xd5, 0xd5}, {0x00, 0xd6, 0xd6}, {0x00, 0xd7, 0xd7}, {0x00, 0xd8, 0xd8}, {0x00, 0xd9, 0xd9}, {0x00, 0xda, 0xda}, {0x00, 0xdb, 0xdb}, {0x00, 0xdc, 0xdc}, {0x00, 0xdd, 0xdd}, {0x00, 0xde, 0xde}, {0x00, 0xdf, 0xdf}, {0x00, 0xe0, 0xe0}, {0x00, 0xe1, 0xe1}, {0x00, 0xe2, 0xe2}, {0x00, 0xe3, 0xe3}, {0x00, 0xe4, 0xe4}, {0x00, 0xe5, 0xe5}, {0x00, 0xe6, 0xe6}, {0x00, 0xe7, 0xe7}, {0x00, 0xe8, 0xe8}, {0x00, 0xe9, 0xe9}, {0x00, 0xea, 0xea}, {0x00, 0xeb, 0xeb}, {0x00, 0xec, 0xec}, {0x00, 0xed, 0xed}, {0x00, 0xee, 0xee}, {0x00, 0xef, 0xef}, {0x00, 0xf0, 0xf0}, {0x00, 0xf1, 0xf1}, {0x00, 0xf2, 0xf2}, {0x00, 0xf3, 0xf3}, {0x00, 0xf4, 0xf4}, {0x00, 0xf5, 0xf5}, {0x00, 0xf6, 0xf6}, {0x00, 0xf7, 0xf7}, {0x00, 0xf8, 0xf8}, {0x00, 0xf9, 0xf9}, {0x00, 0xfa, 0xfa}, {0x00, 0xfb, 0xfb}, {0x00, 0xfc, 0xfc}, {0x00, 0xfd, 0xfd}, {0x00, 0xfe, 0xfe}, {0x00, 0xff, 0xff}}; struct enc_entry { const char* enc_name; struct cs_info* cs_table; }; static struct enc_entry encds[] = { {"iso88591", iso1_tbl}, // ISO-8859-1 {"iso88592", iso2_tbl}, // ISO-8859-2 {"iso88593", iso3_tbl}, // ISO-8859-3 {"iso88594", iso4_tbl}, // ISO-8859-4 {"iso88595", iso5_tbl}, // ISO-8859-5 {"iso88596", iso6_tbl}, // ISO-8859-6 {"iso88597", iso7_tbl}, // ISO-8859-7 {"iso88598", iso8_tbl}, // ISO-8859-8 {"iso88599", iso9_tbl}, // ISO-8859-9 {"iso885910", iso10_tbl}, // ISO-8859-10 {"tis620", tis620_tbl}, // TIS-620/ISO-8859-11 {"tis6202533", tis620_tbl}, // TIS-620/ISO-8859-11 {"iso885911", tis620_tbl}, // TIS-620/ISO-8859-11 {"iso885913", iso13_tbl}, // ISO-8859-13 {"iso885914", iso14_tbl}, // ISO-8859-14 {"iso885915", iso15_tbl}, // ISO-8859-15 {"koi8r", koi8r_tbl}, // KOI8-R {"koi8u", koi8u_tbl}, // KOI8-U {"cp1251", cp1251_tbl}, // CP-1251 {"microsoftcp1251", cp1251_tbl}, // microsoft-cp1251 {"xisciias", iscii_devanagari_tbl}, // x-iscii-as {"isciidevanagari", iscii_devanagari_tbl} // ISCII-DEVANAGARI }; /* map to lower case and remove non alphanumeric chars */ static void toAsciiLowerAndRemoveNonAlphanumeric(const char* pName, char* pBuf) { while (*pName) { /* A-Z */ if ((*pName >= 0x41) && (*pName <= 0x5A)) { *pBuf = (*pName) + 0x20; /* toAsciiLower */ pBuf++; } /* a-z, 0-9 */ else if (((*pName >= 0x61) && (*pName <= 0x7A)) || ((*pName >= 0x30) && (*pName <= 0x39))) { *pBuf = *pName; pBuf++; } pName++; } *pBuf = '\0'; } struct cs_info* get_current_cs(const std::string& es) { char* normalized_encoding = new char[es.size() + 1]; toAsciiLowerAndRemoveNonAlphanumeric(es.c_str(), normalized_encoding); struct cs_info* ccs = NULL; int n = sizeof(encds) / sizeof(encds[0]); for (int i = 0; i < n; i++) { if (strcmp(normalized_encoding, encds[i].enc_name) == 0) { ccs = encds[i].cs_table; break; } } delete[] normalized_encoding; if (!ccs) { HUNSPELL_WARNING(stderr, "error: unknown encoding %s: using %s as fallback\n", es.c_str(), encds[0].enc_name); ccs = encds[0].cs_table; } return ccs; } #else // XXX This function was rewritten for mozilla. Instead of storing the // conversion tables static in this file, create them when needed // with help the mozilla backend. struct cs_info* get_current_cs(const std::string& es) { struct cs_info* ccs = new cs_info[256]; // Initialze the array with dummy data so that we wouldn't need // to return null in case of failures. for (int i = 0; i <= 0xff; ++i) { ccs[i].ccase = false; ccs[i].clower = i; ccs[i].cupper = i; } auto encoding = Encoding::ForLabelNoReplacement(es); if (!encoding) { return ccs; } auto encoder = encoding->NewEncoder(); auto decoder = encoding->NewDecoderWithoutBOMHandling(); for (unsigned int i = 0; i <= 0xff; ++i) { bool success = false; // We want to find the upper/lowercase equivalents of each byte // in this 1-byte character encoding. Call our encoding/decoding // APIs separately for each byte since they may reject some of the // bytes, and we want to handle errors separately for each byte. uint8_t lower, upper; do { if (i == 0) break; uint8_t source = uint8_t(i); char16_t uni[2]; char16_t uniCased; uint8_t destination[4]; auto src1 = MakeSpan(&source, 1); auto dst1 = MakeSpan(uni); auto src2 = MakeSpan(&uniCased, 1); auto dst2 = MakeSpan(destination); uint32_t result; size_t read; size_t written; Tie(result, read, written) = decoder->DecodeToUTF16WithoutReplacement(src1, dst1, true); if (result != kInputEmpty || read != 1 || written != 1) { break; } uniCased = ToLowerCase(uni[0]); Tie(result, read, written) = encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true); if (result != kInputEmpty || read != 1 || written != 1) { break; } lower = destination[0]; uniCased = ToUpperCase(uni[0]); Tie(result, read, written) = encoder->EncodeFromUTF16WithoutReplacement(src2, dst2, true); if (result != kInputEmpty || read != 1 || written != 1) { break; } upper = destination[0]; success = true; } while (0); encoding->NewEncoderInto(*encoder); encoding->NewDecoderWithoutBOMHandlingInto(*decoder); if (success) { ccs[i].cupper = upper; ccs[i].clower = lower; } else { ccs[i].cupper = i; ccs[i].clower = i; } if (ccs[i].clower != (unsigned char)i) ccs[i].ccase = true; else ccs[i].ccase = false; } return ccs; } #endif // primitive isalpha() replacement for tokenization std::string get_casechars(const char* enc) { struct cs_info* csconv = get_current_cs(enc); std::string expw; for (int i = 0; i <= 255; ++i) { if (cupper(csconv, i) != clower(csconv, i)) { expw.push_back(static_cast(i)); } } #ifdef MOZILLA_CLIENT delete[] csconv; #endif return expw; } // language to encoding default map struct lang_map { const char* lang; int num; }; static struct lang_map lang2enc[] = {{"ar", LANG_ar}, {"az", LANG_az}, {"az_AZ", LANG_az}, // for back-compatibility {"bg", LANG_bg}, {"ca", LANG_ca}, {"crh", LANG_crh}, {"cs", LANG_cs}, {"da", LANG_da}, {"de", LANG_de}, {"el", LANG_el}, {"en", LANG_en}, {"es", LANG_es}, {"eu", LANG_eu}, {"gl", LANG_gl}, {"fr", LANG_fr}, {"hr", LANG_hr}, {"hu", LANG_hu}, {"hu_HU", LANG_hu}, // for back-compatibility {"it", LANG_it}, {"la", LANG_la}, {"lv", LANG_lv}, {"nl", LANG_nl}, {"pl", LANG_pl}, {"pt", LANG_pt}, {"sv", LANG_sv}, {"tr", LANG_tr}, {"tr_TR", LANG_tr}, // for back-compatibility {"ru", LANG_ru}, {"uk", LANG_uk}}; int get_lang_num(const std::string& lang) { int n = sizeof(lang2enc) / sizeof(lang2enc[0]); for (int i = 0; i < n; i++) { if (strcmp(lang.c_str(), lang2enc[i].lang) == 0) { return lang2enc[i].num; } } return LANG_xx; } #ifndef OPENOFFICEORG #ifndef MOZILLA_CLIENT void initialize_utf_tbl() { utf_tbl_count++; if (utf_tbl) return; utf_tbl = new unicode_info2[CONTSIZE]; for (size_t j = 0; j < CONTSIZE; ++j) { utf_tbl[j].cletter = 0; utf_tbl[j].clower = (unsigned short)j; utf_tbl[j].cupper = (unsigned short)j; } for (size_t j = 0; j < UTF_LST_LEN; ++j) { utf_tbl[utf_lst[j].c].cletter = 1; utf_tbl[utf_lst[j].c].clower = utf_lst[j].clower; utf_tbl[utf_lst[j].c].cupper = utf_lst[j].cupper; } } #endif #endif void free_utf_tbl() { if (utf_tbl_count > 0) utf_tbl_count--; if (utf_tbl && (utf_tbl_count == 0)) { delete[] utf_tbl; utf_tbl = NULL; } } unsigned short unicodetoupper(unsigned short c, int langnum) { // In Azeri and Turkish, I and i dictinct letters: // There are a dotless lower case i pair of upper `I', // and an upper I with dot pair of lower `i'. if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh))) return 0x0130; #ifdef OPENOFFICEORG return static_cast(u_toupper(c)); #else #ifdef MOZILLA_CLIENT return ToUpperCase((char16_t)c); #else return (utf_tbl) ? utf_tbl[c].cupper : c; #endif #endif } unsigned short unicodetolower(unsigned short c, int langnum) { // In Azeri and Turkish, I and i dictinct letters: // There are a dotless lower case i pair of upper `I', // and an upper I with dot pair of lower `i'. if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr) || (langnum == LANG_crh))) return 0x0131; #ifdef OPENOFFICEORG return static_cast(u_tolower(c)); #else #ifdef MOZILLA_CLIENT return ToLowerCase((char16_t)c); #else return (utf_tbl) ? utf_tbl[c].clower : c; #endif #endif } int unicodeisalpha(unsigned short c) { #ifdef OPENOFFICEORG return u_isalpha(c); #else return (utf_tbl) ? utf_tbl[c].cletter : 0; #endif } /* get type of capitalization */ int get_captype(const std::string& word, cs_info* csconv) { // now determine the capitalization type of the first nl letters size_t ncap = 0; size_t nneutral = 0; size_t firstcap = 0; if (csconv == NULL) return NOCAP; for (std::string::const_iterator q = word.begin(); q != word.end(); ++q) { unsigned char nIndex = static_cast(*q); if (ccase(csconv, nIndex)) ncap++; if (cupper(csconv, nIndex) == clower(csconv, nIndex)) nneutral++; } if (ncap) { unsigned char nIndex = static_cast(word[0]); firstcap = csconv[nIndex].ccase; } // now finally set the captype if (ncap == 0) { return NOCAP; } else if ((ncap == 1) && firstcap) { return INITCAP; } else if ((ncap == word.size()) || ((ncap + nneutral) == word.size())) { return ALLCAP; } else if ((ncap > 1) && firstcap) { return HUHINITCAP; } return HUHCAP; } int get_captype_utf8(const std::vector& word, int langnum) { // now determine the capitalization type of the first nl letters size_t ncap = 0; size_t nneutral = 0; size_t firstcap = 0; std::vector::const_iterator it = word.begin(); std::vector::const_iterator it_end = word.end(); while (it != it_end) { unsigned short idx = (it->h << 8) + it->l; unsigned short lwridx = unicodetolower(idx, langnum); if (idx != lwridx) ncap++; if (unicodetoupper(idx, langnum) == lwridx) nneutral++; ++it; } if (ncap) { unsigned short idx = (word[0].h << 8) + word[0].l; firstcap = (idx != unicodetolower(idx, langnum)); } // now finally set the captype if (ncap == 0) { return NOCAP; } else if ((ncap == 1) && firstcap) { return INITCAP; } else if ((ncap == word.size()) || ((ncap + nneutral) == word.size())) { return ALLCAP; } else if ((ncap > 1) && firstcap) { return HUHINITCAP; } return HUHCAP; } // strip all ignored characters in the string size_t remove_ignored_chars_utf(std::string& word, const std::vector& ignored_chars) { std::vector w; std::vector w2; u8_u16(w, word); for (size_t i = 0; i < w.size(); ++i) { if (!std::binary_search(ignored_chars.begin(), ignored_chars.end(), w[i])) { w2.push_back(w[i]); } } u16_u8(word, w2); return w2.size(); } // strip all ignored characters in the string size_t remove_ignored_chars(std::string& word, const std::string& ignored_chars) { word.erase( std::remove_if(word.begin(), word.end(), is_any_of(ignored_chars)), word.end()); return word.size(); } bool parse_string(const std::string& line, std::string& out, int ln) { if (!out.empty()) { HUNSPELL_WARNING(stderr, "error: line %d: multiple definitions\n", ln); return false; } int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { out.assign(start_piece, iter); np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", ln); return false; } return true; } bool parse_array(const std::string& line, std::string& out, std::vector& out_utf16, int utf8, int ln) { if (!parse_string(line, out, ln)) return false; if (utf8) { u8_u16(out_utf16, out); std::sort(out_utf16.begin(), out_utf16.end()); } return true; } hunspell-1.7.0/src/hunspell/csutil.hxx000066400000000000000000000301701337236234000200320ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #ifndef CSUTIL_HXX_ #define CSUTIL_HXX_ #include "hunvisapi.h" // First some base level utility routines #include #include #include #include #include "w_char.hxx" #include "htypes.hxx" #ifdef MOZILLA_CLIENT #include "nscore.h" // for mozalloc headers #endif // casing #define NOCAP 0 #define INITCAP 1 #define ALLCAP 2 #define HUHCAP 3 #define HUHINITCAP 4 // default encoding and keystring #define SPELL_ENCODING "ISO8859-1" #define SPELL_KEYSTRING "qwertyuiop|asdfghjkl|zxcvbnm" // default morphological fields #define MORPH_STEM "st:" #define MORPH_ALLOMORPH "al:" #define MORPH_POS "po:" #define MORPH_DERI_PFX "dp:" #define MORPH_INFL_PFX "ip:" #define MORPH_TERM_PFX "tp:" #define MORPH_DERI_SFX "ds:" #define MORPH_INFL_SFX "is:" #define MORPH_TERM_SFX "ts:" #define MORPH_SURF_PFX "sp:" #define MORPH_FREQ "fr:" #define MORPH_PHON "ph:" #define MORPH_HYPH "hy:" #define MORPH_PART "pa:" #define MORPH_FLAG "fl:" #define MORPH_HENTRY "_H:" #define MORPH_TAG_LEN strlen(MORPH_STEM) #define MSEP_FLD ' ' #define MSEP_REC '\n' #define MSEP_ALT '\v' // default flags #define DEFAULTFLAGS 65510 #define FORBIDDENWORD 65510 #define ONLYUPCASEFLAG 65511 // fix long pathname problem of WIN32 by using w_char std::fstream::open override LIBHUNSPELL_DLL_EXPORTED void myopen(std::ifstream& stream, const char* path, std::ios_base::openmode mode); // convert UTF-16 characters to UTF-8 LIBHUNSPELL_DLL_EXPORTED std::string& u16_u8(std::string& dest, const std::vector& src); // convert UTF-8 characters to UTF-16 LIBHUNSPELL_DLL_EXPORTED int u8_u16(std::vector& dest, const std::string& src); // remove end of line char(s) LIBHUNSPELL_DLL_EXPORTED void mychomp(std::string& s); // duplicate string LIBHUNSPELL_DLL_EXPORTED char* mystrdup(const char* s); // parse into tokens with char delimiter LIBHUNSPELL_DLL_EXPORTED std::string::const_iterator mystrsep(const std::string &str, std::string::const_iterator& start); // replace pat by rep in word and return word LIBHUNSPELL_DLL_EXPORTED std::string& mystrrep(std::string& str, const std::string& search, const std::string& replace); // append s to ends of every lines in text LIBHUNSPELL_DLL_EXPORTED std::string& strlinecat(std::string& str, const std::string& apd); // tokenize into lines with new line LIBHUNSPELL_DLL_EXPORTED std::vector line_tok(const std::string& text, char breakchar); // tokenize into lines with new line and uniq in place LIBHUNSPELL_DLL_EXPORTED void line_uniq(std::string& text, char breakchar); LIBHUNSPELL_DLL_EXPORTED void line_uniq_app(std::string& text, char breakchar); // reverse word LIBHUNSPELL_DLL_EXPORTED size_t reverseword(std::string& word); // reverse word LIBHUNSPELL_DLL_EXPORTED size_t reverseword_utf(std::string&); // remove duplicates LIBHUNSPELL_DLL_EXPORTED void uniqlist(std::vector& list); // character encoding information struct cs_info { unsigned char ccase; unsigned char clower; unsigned char cupper; }; LIBHUNSPELL_DLL_EXPORTED void initialize_utf_tbl(); LIBHUNSPELL_DLL_EXPORTED void free_utf_tbl(); LIBHUNSPELL_DLL_EXPORTED unsigned short unicodetoupper(unsigned short c, int langnum); LIBHUNSPELL_DLL_EXPORTED w_char upper_utf(w_char u, int langnum); LIBHUNSPELL_DLL_EXPORTED w_char lower_utf(w_char u, int langnum); LIBHUNSPELL_DLL_EXPORTED unsigned short unicodetolower(unsigned short c, int langnum); LIBHUNSPELL_DLL_EXPORTED int unicodeisalpha(unsigned short c); LIBHUNSPELL_DLL_EXPORTED struct cs_info* get_current_cs(const std::string& es); // get language identifiers of language codes LIBHUNSPELL_DLL_EXPORTED int get_lang_num(const std::string& lang); // get characters of the given 8bit encoding with lower- and uppercase forms LIBHUNSPELL_DLL_EXPORTED std::string get_casechars(const char* enc); // convert std::string to all caps LIBHUNSPELL_DLL_EXPORTED std::string& mkallcap(std::string& s, const struct cs_info* csconv); // convert null terminated string to all little LIBHUNSPELL_DLL_EXPORTED std::string& mkallsmall(std::string& s, const struct cs_info* csconv); // convert first letter of string to little LIBHUNSPELL_DLL_EXPORTED std::string& mkinitsmall(std::string& s, const struct cs_info* csconv); // convert first letter of string to capital LIBHUNSPELL_DLL_EXPORTED std::string& mkinitcap(std::string& s, const struct cs_info* csconv); // convert first letter of UTF-8 string to capital LIBHUNSPELL_DLL_EXPORTED std::vector& mkinitcap_utf(std::vector& u, int langnum); // convert UTF-8 string to little LIBHUNSPELL_DLL_EXPORTED std::vector& mkallsmall_utf(std::vector& u, int langnum); // convert first letter of UTF-8 string to little LIBHUNSPELL_DLL_EXPORTED std::vector& mkinitsmall_utf(std::vector& u, int langnum); // convert UTF-8 string to capital LIBHUNSPELL_DLL_EXPORTED std::vector& mkallcap_utf(std::vector& u, int langnum); // get type of capitalization LIBHUNSPELL_DLL_EXPORTED int get_captype(const std::string& q, cs_info*); // get type of capitalization (UTF-8) LIBHUNSPELL_DLL_EXPORTED int get_captype_utf8(const std::vector& q, int langnum); // strip all ignored characters in the string LIBHUNSPELL_DLL_EXPORTED size_t remove_ignored_chars_utf( std::string& word, const std::vector& ignored_chars); // strip all ignored characters in the string LIBHUNSPELL_DLL_EXPORTED size_t remove_ignored_chars( std::string& word, const std::string& ignored_chars); LIBHUNSPELL_DLL_EXPORTED bool parse_string(const std::string& line, std::string& out, int ln); LIBHUNSPELL_DLL_EXPORTED bool parse_array(const std::string& line, std::string& out, std::vector& out_utf16, int utf8, int ln); LIBHUNSPELL_DLL_EXPORTED int fieldlen(const char* r); LIBHUNSPELL_DLL_EXPORTED bool copy_field(std::string& dest, const std::string& morph, const std::string& var); // conversion function for protected memory LIBHUNSPELL_DLL_EXPORTED void store_pointer(char* dest, char* source); // conversion function for protected memory LIBHUNSPELL_DLL_EXPORTED char* get_stored_pointer(const char* s); // to avoid unnecessary string copies and Unicode conversions // we simply check the ignored_chars characters in the word // (in the case of UTF-8 encoded strings, "false" means // "likely false", if ignored_chars characters are not ASCII) inline bool has_no_ignored_chars(const std::string& word, const std::string& ignored_chars) { for (std::string::const_iterator it = ignored_chars.begin(), end = ignored_chars.end(); it != end; ++it) if (word.find(*it) != std::string::npos) return false; return true; } // hash entry macros inline char* HENTRY_DATA(struct hentry* h) { char* ret; if (!(h->var & H_OPT)) ret = NULL; else if (h->var & H_OPT_ALIASM) ret = get_stored_pointer(HENTRY_WORD(h) + h->blen + 1); else ret = HENTRY_WORD(h) + h->blen + 1; return ret; } inline const char* HENTRY_DATA( const struct hentry* h) { const char* ret; if (!(h->var & H_OPT)) ret = NULL; else if (h->var & H_OPT_ALIASM) ret = get_stored_pointer(HENTRY_WORD(h) + h->blen + 1); else ret = HENTRY_WORD(h) + h->blen + 1; return ret; } // NULL-free version for warning-free OOo build inline const char* HENTRY_DATA2( const struct hentry* h) { const char* ret; if (!(h->var & H_OPT)) ret = ""; else if (h->var & H_OPT_ALIASM) ret = get_stored_pointer(HENTRY_WORD(h) + h->blen + 1); else ret = HENTRY_WORD(h) + h->blen + 1; return ret; } inline char* HENTRY_FIND(struct hentry* h, const char* p) { return (HENTRY_DATA(h) ? strstr(HENTRY_DATA(h), p) : NULL); } #endif hunspell-1.7.0/src/hunspell/filemgr.cxx000066400000000000000000000106521337236234000201520ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include "filemgr.hxx" #include "csutil.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), linenum(0) { in[0] = '\0'; myopen(fin, file, std::ios_base::in); if (!fin.is_open()) { // check hzipped file std::string st(file); st.append(HZIP_EXTENSION); hin = new Hunzip(st.c_str(), key); } if (!fin.is_open() && !hin->is_open()) fail(MSG_OPEN, file); } FileMgr::~FileMgr() { delete hin; } bool FileMgr::getline(std::string& dest) { bool ret = false; ++linenum; if (fin.is_open()) { ret = static_cast(std::getline(fin, dest)); } else if (hin->is_open()) { ret = hin->getline(dest); } if (!ret) { --linenum; } return ret; } int FileMgr::getlinenum() { return linenum; } hunspell-1.7.0/src/hunspell/filemgr.hxx000066400000000000000000000101341337236234000201520ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ /* file manager class - read lines of files [filename] OR [filename.hz] */ #ifndef FILEMGR_HXX_ #define FILEMGR_HXX_ #include "hunzip.hxx" #include #include #include class FileMgr { private: FileMgr(const FileMgr&); FileMgr& operator=(const FileMgr&); protected: std::ifstream fin; Hunzip* hin; char in[BUFSIZE + 50]; // input buffer int fail(const char* err, const char* par); int linenum; public: FileMgr(const char* filename, const char* key = NULL); ~FileMgr(); bool getline(std::string&); int getlinenum(); }; #endif hunspell-1.7.0/src/hunspell/hashmgr.cxx000066400000000000000000001236311337236234000201600ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include #include #include #include "hashmgr.hxx" #include "csutil.hxx" #include "atypes.hxx" #include "langnum.hxx" // build a hash table from a munched word list HashMgr::HashMgr(const char* tpath, const char* apath, const char* key) : tablesize(0), tableptr(NULL), flag_mode(FLAG_CHAR), complexprefixes(0), utf8(0), forbiddenword(FORBIDDENWORD) // forbidden word signing flag , numaliasf(0), aliasf(NULL), aliasflen(0), numaliasm(0), aliasm(NULL) { langnum = 0; csconv = 0; load_config(apath, key); int ec = load_tables(tpath, key); if (ec) { /* error condition - what should we do here */ HUNSPELL_WARNING(stderr, "Hash Manager Error : %d\n", ec); free(tableptr); //keep tablesize to 1 to fix possible division with zero tablesize = 1; tableptr = (struct hentry**)calloc(tablesize, sizeof(struct hentry*)); if (!tableptr) { tablesize = 0; } } } HashMgr::~HashMgr() { if (tableptr) { // now pass through hash table freeing up everything // go through column by column of the table for (int i = 0; i < tablesize; i++) { struct hentry* pt = tableptr[i]; struct hentry* nt = NULL; while (pt) { nt = pt->next; if (pt->astr && (!aliasf || TESTAFF(pt->astr, ONLYUPCASEFLAG, pt->alen))) free(pt->astr); free(pt); pt = nt; } } free(tableptr); } tablesize = 0; if (aliasf) { for (int j = 0; j < (numaliasf); j++) free(aliasf[j]); free(aliasf); aliasf = NULL; if (aliasflen) { free(aliasflen); aliasflen = NULL; } } if (aliasm) { for (int j = 0; j < (numaliasm); j++) free(aliasm[j]); free(aliasm); aliasm = NULL; } #ifndef OPENOFFICEORG #ifndef MOZILLA_CLIENT if (utf8) free_utf_tbl(); #endif #endif #ifdef MOZILLA_CLIENT delete[] csconv; #endif } // lookup a root word in the hashtable struct hentry* HashMgr::lookup(const char* word) const { struct hentry* dp; if (tableptr) { dp = tableptr[hash(word)]; if (!dp) return NULL; for (; dp != NULL; dp = dp->next) { if (strcmp(word, dp->word) == 0) return dp; } } return NULL; } // add a word to the hash table (private) int HashMgr::add_word(const std::string& in_word, int wcl, unsigned short* aff, int al, const std::string* in_desc, bool onlyupcase, int captype) { const std::string* word = &in_word; const std::string* desc = in_desc; std::string *word_copy = NULL; std::string *desc_copy = NULL; if ((!ignorechars.empty() && !has_no_ignored_chars(in_word, ignorechars)) || complexprefixes) { word_copy = new std::string(in_word); if (!ignorechars.empty()) { if (utf8) { wcl = remove_ignored_chars_utf(*word_copy, ignorechars_utf16); } else { remove_ignored_chars(*word_copy, ignorechars); } } if (complexprefixes) { if (utf8) wcl = reverseword_utf(*word_copy); else reverseword(*word_copy); if (in_desc && !aliasm) { desc_copy = new std::string(*in_desc); if (complexprefixes) { if (utf8) reverseword_utf(*desc_copy); else reverseword(*desc_copy); } desc = desc_copy; } } word = word_copy; } bool upcasehomonym = false; int descl = desc ? (aliasm ? sizeof(char*) : desc->size() + 1) : 0; // variable-length hash record with word and optional fields struct hentry* hp = (struct hentry*)malloc(sizeof(struct hentry) + word->size() + descl); if (!hp) { delete desc_copy; delete word_copy; return 1; } char* hpw = hp->word; strcpy(hpw, word->c_str()); int i = hash(hpw); hp->blen = (unsigned char)word->size(); hp->clen = (unsigned char)wcl; hp->alen = (short)al; hp->astr = aff; hp->next = NULL; hp->next_homonym = NULL; hp->var = (captype == INITCAP) ? H_OPT_INITCAP : 0; // store the description string or its pointer if (desc) { hp->var += H_OPT; if (aliasm) { hp->var += H_OPT_ALIASM; store_pointer(hpw + word->size() + 1, get_aliasm(atoi(desc->c_str()))); } else { strcpy(hpw + word->size() + 1, desc->c_str()); } if (strstr(HENTRY_DATA(hp), MORPH_PHON)) { hp->var += H_OPT_PHON; // store ph: fields (pronounciation, misspellings, old orthography etc.) // of a morphological description in reptable to use in REP replacements. if (reptable.capacity() < (unsigned int)(tablesize/MORPH_PHON_RATIO)) reptable.reserve(tablesize/MORPH_PHON_RATIO); std::string fields = HENTRY_DATA(hp); std::string::const_iterator iter = fields.begin(); std::string::const_iterator start_piece = mystrsep(fields, iter); while (start_piece != fields.end()) { if (std::string(start_piece, iter).find(MORPH_PHON) == 0) { std::string ph = std::string(start_piece, iter).substr(sizeof MORPH_PHON - 1); if (ph.size() > 0) { std::vector w; size_t strippatt; std::string wordpart; // dictionary based REP replacement, separated by "->" // for example "pretty ph:prity ph:priti->pretti" to handle // both prity -> pretty and pritier -> prettiest suggestions. if (((strippatt = ph.find("->")) != std::string::npos) && (strippatt > 0) && (strippatt < ph.size() - 2)) { wordpart = ph.substr(strippatt + 2); ph.erase(ph.begin() + strippatt, ph.end()); } else wordpart = in_word; // when the ph: field ends with the character *, // strip last character of the pattern and the replacement // to match in REP suggestions also at character changes, // for example, "pretty ph:prity*" results "prit->prett" // REP replacement instead of "prity->pretty", to get // prity->pretty and pritiest->prettiest suggestions. if (ph.at(ph.size()-1) == '*') { strippatt = 1; size_t stripword = 0; if (utf8) { while ((strippatt < ph.size()) && ((ph.at(ph.size()-strippatt-1) & 0xc0) == 0x80)) ++strippatt; while ((stripword < wordpart.size()) && ((wordpart.at(wordpart.size()-stripword-1) & 0xc0) == 0x80)) ++stripword; } ++strippatt; ++stripword; if ((ph.size() > strippatt) && (wordpart.size() > stripword)) { ph.erase(ph.size()-strippatt, strippatt); wordpart.erase(in_word.size()-stripword, stripword); } } // capitalize lowercase pattern for capitalized words to support // good suggestions also for capitalized misspellings, eg. // Wednesday ph:wendsay // results wendsay -> Wednesday and Wendsay -> Wednesday, too. if (captype==INITCAP) { std::string ph_capitalized; if (utf8) { u8_u16(w, ph); if (get_captype_utf8(w, langnum) == NOCAP) { mkinitcap_utf(w, langnum); u16_u8(ph_capitalized, w); } } else if (get_captype(ph, csconv) == NOCAP) mkinitcap(ph_capitalized, csconv); if (ph_capitalized.size() > 0) { // add also lowercase word in the case of German or // Hungarian to support lowercase suggestions lowercased by // compound word generation or derivational suffixes // (for example by adjectival suffix "-i" of geographical // names in Hungarian: // Massachusetts ph:messzecsuzec // messzecsuzeci -> massachusettsi (adjective) // For lowercasing by conditional PFX rules, see // tests/germancompounding test example or the // Hungarian dictionary.) if (langnum == LANG_de || langnum == LANG_hu) { std::string wordpart_lower(wordpart); if (utf8) { u8_u16(w, wordpart_lower); mkallsmall_utf(w, langnum); u16_u8(wordpart_lower, w); } else { mkallsmall(wordpart_lower, csconv); } reptable.push_back(replentry()); reptable.back().pattern.assign(ph); reptable.back().outstrings[0].assign(wordpart_lower); } reptable.push_back(replentry()); reptable.back().pattern.assign(ph_capitalized); reptable.back().outstrings[0].assign(wordpart); } } reptable.push_back(replentry()); reptable.back().pattern.assign(ph); reptable.back().outstrings[0].assign(wordpart); } } start_piece = mystrsep(fields, iter); } } } struct hentry* dp = tableptr[i]; if (!dp) { tableptr[i] = hp; delete desc_copy; delete word_copy; return 0; } while (dp->next != NULL) { if ((!dp->next_homonym) && (strcmp(hp->word, dp->word) == 0)) { // remove hidden onlyupcase homonym if (!onlyupcase) { if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) { free(dp->astr); dp->astr = hp->astr; dp->alen = hp->alen; free(hp); delete desc_copy; delete word_copy; return 0; } else { dp->next_homonym = hp; } } else { upcasehomonym = true; } } dp = dp->next; } if (strcmp(hp->word, dp->word) == 0) { // remove hidden onlyupcase homonym if (!onlyupcase) { if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) { free(dp->astr); dp->astr = hp->astr; dp->alen = hp->alen; free(hp); delete desc_copy; delete word_copy; return 0; } else { dp->next_homonym = hp; } } else { upcasehomonym = true; } } if (!upcasehomonym) { dp->next = hp; } else { // remove hidden onlyupcase homonym if (hp->astr) free(hp->astr); free(hp); } delete desc_copy; delete word_copy; return 0; } int HashMgr::add_hidden_capitalized_word(const std::string& word, int wcl, unsigned short* flags, int flagslen, const std::string* dp, int captype) { if (flags == NULL) flagslen = 0; // add inner capitalized forms to handle the following allcap forms: // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG // Allcaps with suffixes: CIA's -> CIA'S if (((captype == HUHCAP) || (captype == HUHINITCAP) || ((captype == ALLCAP) && (flagslen != 0))) && !((flagslen != 0) && TESTAFF(flags, forbiddenword, flagslen))) { unsigned short* flags2 = (unsigned short*)malloc(sizeof(unsigned short) * (flagslen + 1)); if (!flags2) return 1; if (flagslen) memcpy(flags2, flags, flagslen * sizeof(unsigned short)); flags2[flagslen] = ONLYUPCASEFLAG; if (utf8) { std::string st; std::vector w; u8_u16(w, word); mkallsmall_utf(w, langnum); mkinitcap_utf(w, langnum); u16_u8(st, w); return add_word(st, wcl, flags2, flagslen + 1, dp, true, INITCAP); } else { std::string new_word(word); mkallsmall(new_word, csconv); mkinitcap(new_word, csconv); int ret = add_word(new_word, wcl, flags2, flagslen + 1, dp, true, INITCAP); return ret; } } return 0; } // detect captype and modify word length for UTF-8 encoding int HashMgr::get_clen_and_captype(const std::string& word, int* captype, std::vector &workbuf) { int len; if (utf8) { len = u8_u16(workbuf, word); *captype = get_captype_utf8(workbuf, langnum); } else { len = word.size(); *captype = get_captype(word, csconv); } return len; } int HashMgr::get_clen_and_captype(const std::string& word, int* captype) { std::vector workbuf; return get_clen_and_captype(word, captype, workbuf); } // remove word (personal dictionary function for standalone applications) int HashMgr::remove(const std::string& word) { struct hentry* dp = lookup(word.c_str()); while (dp) { if (dp->alen == 0 || !TESTAFF(dp->astr, forbiddenword, dp->alen)) { unsigned short* flags = (unsigned short*)malloc(sizeof(unsigned short) * (dp->alen + 1)); if (!flags) return 1; for (int i = 0; i < dp->alen; i++) flags[i] = dp->astr[i]; flags[dp->alen] = forbiddenword; free(dp->astr); dp->astr = flags; dp->alen++; std::sort(flags, flags + dp->alen); } dp = dp->next_homonym; } return 0; } /* remove forbidden flag to add a personal word to the hash */ int HashMgr::remove_forbidden_flag(const std::string& word) { struct hentry* dp = lookup(word.c_str()); if (!dp) return 1; while (dp) { if (dp->astr && TESTAFF(dp->astr, forbiddenword, dp->alen)) dp->alen = 0; // XXX forbidden words of personal dic. dp = dp->next_homonym; } return 0; } // add a custom dic. word to the hash table (public) int HashMgr::add(const std::string& word) { if (remove_forbidden_flag(word)) { int captype; int al = 0; unsigned short* flags = NULL; int wcl = get_clen_and_captype(word, &captype); add_word(word, wcl, flags, al, NULL, false, captype); return add_hidden_capitalized_word(word, wcl, flags, al, NULL, captype); } return 0; } int HashMgr::add_with_affix(const std::string& word, const std::string& example) { // detect captype and modify word length for UTF-8 encoding struct hentry* dp = lookup(example.c_str()); remove_forbidden_flag(word); if (dp && dp->astr) { int captype; int wcl = get_clen_and_captype(word, &captype); if (aliasf) { add_word(word, wcl, dp->astr, dp->alen, NULL, false, captype); } else { unsigned short* flags = (unsigned short*)malloc(dp->alen * sizeof(unsigned short)); if (flags) { memcpy((void*)flags, (void*)dp->astr, dp->alen * sizeof(unsigned short)); add_word(word, wcl, flags, dp->alen, NULL, false, captype); } else return 1; } return add_hidden_capitalized_word(word, wcl, dp->astr, dp->alen, NULL, captype); } return 1; } // walk the hash table entry by entry - null at end // initialize: col=-1; hp = NULL; hp = walk_hashtable(&col, hp); struct hentry* HashMgr::walk_hashtable(int& col, struct hentry* hp) const { if (hp && hp->next != NULL) return hp->next; for (col++; col < tablesize; col++) { if (tableptr[col]) return tableptr[col]; } // null at end and reset to start col = -1; return NULL; } // load a munched word list and build a hash table on the fly int HashMgr::load_tables(const char* tpath, const char* key) { // open dictionary file FileMgr* dict = new FileMgr(tpath, key); if (dict == NULL) return 1; // first read the first line of file to get hash table size */ std::string ts; if (!dict->getline(ts)) { HUNSPELL_WARNING(stderr, "error: empty dic file %s\n", tpath); delete dict; return 2; } mychomp(ts); /* remove byte order mark */ if (ts.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) { ts.erase(0, 3); } tablesize = atoi(ts.c_str()); int nExtra = 5 + USERWORD; if (tablesize <= 0 || (tablesize >= (std::numeric_limits::max() - 1 - nExtra) / int(sizeof(struct hentry*)))) { HUNSPELL_WARNING( stderr, "error: line 1: missing or bad word count in the dic file\n"); delete dict; return 4; } tablesize += nExtra; if ((tablesize % 2) == 0) tablesize++; // allocate the hash table tableptr = (struct hentry**)calloc(tablesize, sizeof(struct hentry*)); if (!tableptr) { delete dict; return 3; } // loop through all words on much list and add to hash // table and create word and affix strings std::vector workbuf; while (dict->getline(ts)) { mychomp(ts); // split each line into word and morphological description size_t dp_pos = 0; while ((dp_pos = ts.find(':', dp_pos)) != std::string::npos) { if ((dp_pos > 3) && (ts[dp_pos - 3] == ' ' || ts[dp_pos - 3] == '\t')) { for (dp_pos -= 3; dp_pos > 0 && (ts[dp_pos-1] == ' ' || ts[dp_pos-1] == '\t'); --dp_pos) ; if (dp_pos == 0) { // missing word dp_pos = std::string::npos; } else { ++dp_pos; } break; } ++dp_pos; } // tabulator is the old morphological field separator size_t dp2_pos = ts.find('\t'); if (dp2_pos != std::string::npos && (dp_pos == std::string::npos || dp2_pos < dp_pos)) { dp_pos = dp2_pos + 1; } std::string dp; if (dp_pos != std::string::npos) { dp.assign(ts.substr(dp_pos)); ts.resize(dp_pos - 1); } // split each line into word and affix char strings // "\/" signs slash in words (not affix separator) // "/" at beginning of the line is word character (not affix separator) size_t ap_pos = ts.find('/'); while (ap_pos != std::string::npos) { if (ap_pos == 0) { ++ap_pos; continue; } else if (ts[ap_pos - 1] != '\\') break; // replace "\/" with "/" ts.erase(ap_pos - 1, 1); ap_pos = ts.find('/', ap_pos); } unsigned short* flags; int al; if (ap_pos != std::string::npos && ap_pos != ts.size()) { std::string ap(ts.substr(ap_pos + 1)); ts.resize(ap_pos); if (aliasf) { int index = atoi(ap.c_str()); al = get_aliasf(index, &flags, dict); if (!al) { HUNSPELL_WARNING(stderr, "error: line %d: bad flag vector alias\n", dict->getlinenum()); } } else { al = decode_flags(&flags, ap.c_str(), dict); if (al == -1) { HUNSPELL_WARNING(stderr, "Can't allocate memory.\n"); delete dict; return 6; } std::sort(flags, flags + al); } } else { al = 0; flags = NULL; } int captype; int wcl = get_clen_and_captype(ts, &captype, workbuf); const std::string *dp_str = dp.empty() ? NULL : &dp; // add the word and its index plus its capitalized form optionally if (add_word(ts, wcl, flags, al, dp_str, false, captype) || add_hidden_capitalized_word(ts, wcl, flags, al, dp_str, captype)) { delete dict; return 5; } } delete dict; return 0; } // the hash function is a simple load and rotate // algorithm borrowed int HashMgr::hash(const char* word) const { unsigned long hv = 0; for (int i = 0; i < 4 && *word != 0; i++) hv = (hv << 8) | (*word++); while (*word != 0) { ROTATE(hv, ROTATE_LEN); hv ^= (*word++); } return (unsigned long)hv % tablesize; } int HashMgr::decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const { int len; if (flags.empty()) { *result = NULL; return 0; } switch (flag_mode) { case FLAG_LONG: { // two-character flags (1x2yZz -> 1x 2y Zz) len = flags.size(); if (len % 2 == 1) HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n", af->getlinenum()); len /= 2; *result = (unsigned short*)malloc(len * sizeof(unsigned short)); if (!*result) return -1; for (int i = 0; i < len; i++) { (*result)[i] = ((unsigned short)((unsigned char)flags[i * 2]) << 8) + (unsigned char)flags[i * 2 + 1]; } break; } case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521 // 23 233) len = 1; unsigned short* dest; for (size_t i = 0; i < flags.size(); ++i) { if (flags[i] == ',') len++; } *result = (unsigned short*)malloc(len * sizeof(unsigned short)); if (!*result) return -1; dest = *result; const char* src = flags.c_str(); for (const char* p = src; *p; p++) { if (*p == ',') { int i = atoi(src); if (i >= DEFAULTFLAGS) HUNSPELL_WARNING( stderr, "error: line %d: flag id %d is too large (max: %d)\n", af->getlinenum(), i, DEFAULTFLAGS - 1); *dest = (unsigned short)i; if (*dest == 0) HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n", af->getlinenum()); src = p + 1; dest++; } } int i = atoi(src); if (i >= DEFAULTFLAGS) HUNSPELL_WARNING(stderr, "error: line %d: flag id %d is too large (max: %d)\n", af->getlinenum(), i, DEFAULTFLAGS - 1); *dest = (unsigned short)i; if (*dest == 0) HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n", af->getlinenum()); break; } case FLAG_UNI: { // UTF-8 characters std::vector w; u8_u16(w, flags); len = w.size(); *result = (unsigned short*)malloc(len * sizeof(unsigned short)); if (!*result) return -1; memcpy(*result, &w[0], len * sizeof(short)); break; } default: { // Ispell's one-character flags (erfg -> e r f g) unsigned short* dest; len = flags.size(); *result = (unsigned short*)malloc(len * sizeof(unsigned short)); if (!*result) return -1; dest = *result; for (size_t i = 0; i < flags.size(); ++i) { *dest = (unsigned char)flags[i]; dest++; } } } return len; } bool HashMgr::decode_flags(std::vector& result, const std::string& flags, FileMgr* af) const { if (flags.empty()) { return false; } switch (flag_mode) { case FLAG_LONG: { // two-character flags (1x2yZz -> 1x 2y Zz) size_t len = flags.size(); if (len % 2 == 1) HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n", af->getlinenum()); len /= 2; result.reserve(result.size() + len); for (size_t i = 0; i < len; ++i) { result.push_back(((unsigned short)((unsigned char)flags[i * 2]) << 8) + (unsigned char)flags[i * 2 + 1]); } break; } case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521 // 23 233) const char* src = flags.c_str(); for (const char* p = src; *p; p++) { if (*p == ',') { int i = atoi(src); if (i >= DEFAULTFLAGS) HUNSPELL_WARNING( stderr, "error: line %d: flag id %d is too large (max: %d)\n", af->getlinenum(), i, DEFAULTFLAGS - 1); result.push_back((unsigned short)i); if (result.back() == 0) HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n", af->getlinenum()); src = p + 1; } } int i = atoi(src); if (i >= DEFAULTFLAGS) HUNSPELL_WARNING(stderr, "error: line %d: flag id %d is too large (max: %d)\n", af->getlinenum(), i, DEFAULTFLAGS - 1); result.push_back((unsigned short)i); if (result.back() == 0) HUNSPELL_WARNING(stderr, "error: line %d: 0 is wrong flag id\n", af->getlinenum()); break; } case FLAG_UNI: { // UTF-8 characters std::vector w; u8_u16(w, flags); size_t len = w.size(); size_t origsize = result.size(); result.resize(origsize + len); memcpy(&result[origsize], &w[0], len * sizeof(short)); break; } default: { // Ispell's one-character flags (erfg -> e r f g) result.reserve(flags.size()); for (size_t i = 0; i < flags.size(); ++i) { result.push_back((unsigned char)flags[i]); } } } return true; } unsigned short HashMgr::decode_flag(const char* f) const { unsigned short s = 0; int i; switch (flag_mode) { case FLAG_LONG: s = ((unsigned short)((unsigned char)f[0]) << 8) + (unsigned char)f[1]; break; case FLAG_NUM: i = atoi(f); if (i >= DEFAULTFLAGS) HUNSPELL_WARNING(stderr, "error: flag id %d is too large (max: %d)\n", i, DEFAULTFLAGS - 1); s = (unsigned short)i; break; case FLAG_UNI: { std::vector w; u8_u16(w, f); if (!w.empty()) memcpy(&s, &w[0], 1 * sizeof(short)); break; } default: s = *(unsigned char*)f; } if (s == 0) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n"); return s; } char* HashMgr::encode_flag(unsigned short f) const { if (f == 0) return mystrdup("(NULL)"); std::string ch; if (flag_mode == FLAG_LONG) { ch.push_back((unsigned char)(f >> 8)); ch.push_back((unsigned char)(f - ((f >> 8) << 8))); } else if (flag_mode == FLAG_NUM) { std::ostringstream stream; stream << f; ch = stream.str(); } else if (flag_mode == FLAG_UNI) { const w_char* w_c = (const w_char*)&f; std::vector w(w_c, w_c + 1); u16_u8(ch, w); } else { ch.push_back((unsigned char)(f)); } return mystrdup(ch.c_str()); } // read in aff file and set flag mode int HashMgr::load_config(const char* affpath, const char* key) { 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; } // read in each line ignoring any that do not // start with a known line type indicator std::string line; while (afflst->getline(line)) { mychomp(line); /* remove byte order mark */ if (firstline) { firstline = 0; if (line.compare(0, 3, "\xEF\xBB\xBF", 3) == 0) { line.erase(0, 3); } } /* parse in the try string */ if ((line.compare(0, 4, "FLAG", 4) == 0) && line.size() > 4 && isspace(line[4])) { if (flag_mode != FLAG_CHAR) { HUNSPELL_WARNING(stderr, "error: line %d: multiple definitions of the FLAG " "affix file parameter\n", afflst->getlinenum()); } if (line.find("long") != std::string::npos) flag_mode = FLAG_LONG; if (line.find("num") != std::string::npos) flag_mode = FLAG_NUM; if (line.find("UTF-8") != std::string::npos) flag_mode = FLAG_UNI; if (flag_mode == FLAG_CHAR) { HUNSPELL_WARNING( stderr, "error: line %d: FLAG needs `num', `long' or `UTF-8' parameter\n", afflst->getlinenum()); } } if (line.compare(0, 13, "FORBIDDENWORD", 13) == 0) { std::string st; if (!parse_string(line, st, afflst->getlinenum())) { delete afflst; return 1; } forbiddenword = decode_flag(st.c_str()); } if (line.compare(0, 3, "SET", 3) == 0) { if (!parse_string(line, enc, afflst->getlinenum())) { delete afflst; return 1; } if (enc == "UTF-8") { utf8 = 1; #ifndef OPENOFFICEORG #ifndef MOZILLA_CLIENT initialize_utf_tbl(); #endif #endif } else csconv = get_current_cs(enc); } if (line.compare(0, 4, "LANG", 4) == 0) { if (!parse_string(line, lang, afflst->getlinenum())) { delete afflst; return 1; } langnum = get_lang_num(lang); } /* parse in the ignored characters (for example, Arabic optional diacritics * characters */ if (line.compare(0, 6, "IGNORE", 6) == 0) { if (!parse_array(line, ignorechars, ignorechars_utf16, utf8, afflst->getlinenum())) { delete afflst; return 1; } } if ((line.compare(0, 2, "AF", 2) == 0) && line.size() > 2 && isspace(line[2])) { if (!parse_aliasf(line, afflst)) { delete afflst; return 1; } } if ((line.compare(0, 2, "AM", 2) == 0) && line.size() > 2 && isspace(line[2])) { if (!parse_aliasm(line, afflst)) { delete afflst; return 1; } } if (line.compare(0, 15, "COMPLEXPREFIXES", 15) == 0) complexprefixes = 1; /* parse in the typical fault correcting table */ if (line.compare(0, 3, "REP", 3) == 0) { if (!parse_reptable(line, afflst)) { delete afflst; return 1; } } // don't check the full affix file, yet if (((line.compare(0, 3, "SFX", 3) == 0) || (line.compare(0, 3, "PFX", 3) == 0)) && line.size() > 3 && isspace(line[3]) && !reptable.empty()) // (REP table is in the end of Afrikaans aff file) break; } if (csconv == NULL) csconv = get_current_cs(SPELL_ENCODING); delete afflst; return 0; } /* parse in the ALIAS table */ bool HashMgr::parse_aliasf(const std::string& line, FileMgr* af) { if (numaliasf != 0) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { numaliasf = atoi(std::string(start_piece, iter).c_str()); if (numaliasf < 1) { numaliasf = 0; aliasf = NULL; aliasflen = NULL; HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); return false; } aliasf = (unsigned short**)malloc(numaliasf * sizeof(unsigned short*)); aliasflen = (unsigned short*)malloc(numaliasf * sizeof(unsigned short)); if (!aliasf || !aliasflen) { numaliasf = 0; if (aliasf) free(aliasf); if (aliasflen) free(aliasflen); aliasf = NULL; aliasflen = NULL; return false; } np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { numaliasf = 0; free(aliasf); free(aliasflen); aliasf = NULL; aliasflen = NULL; HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the numaliasf lines to read in the remainder of the table */ for (int j = 0; j < numaliasf; j++) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); i = 0; aliasf[j] = NULL; aliasflen[j] = 0; iter = nl.begin(); start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 2, "AF", 2) != 0) { numaliasf = 0; free(aliasf); free(aliasflen); aliasf = NULL; aliasflen = NULL; HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } break; } case 1: { std::string piece(start_piece, iter); aliasflen[j] = (unsigned short)decode_flags(&(aliasf[j]), piece, af); std::sort(aliasf[j], aliasf[j] + aliasflen[j]); break; } default: break; } ++i; start_piece = mystrsep(nl, iter); } if (!aliasf[j]) { free(aliasf); free(aliasflen); aliasf = NULL; aliasflen = NULL; numaliasf = 0; HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } } return true; } int HashMgr::is_aliasf() const { return (aliasf != NULL); } int HashMgr::get_aliasf(int index, unsigned short** fvec, FileMgr* af) const { if ((index > 0) && (index <= numaliasf)) { *fvec = aliasf[index - 1]; return aliasflen[index - 1]; } HUNSPELL_WARNING(stderr, "error: line %d: bad flag alias index: %d\n", af->getlinenum(), index); *fvec = NULL; return 0; } /* parse morph alias definitions */ bool HashMgr::parse_aliasm(const std::string& line, FileMgr* af) { if (numaliasm != 0) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { numaliasm = atoi(std::string(start_piece, iter).c_str()); if (numaliasm < 1) { HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum()); return false; } aliasm = (char**)malloc(numaliasm * sizeof(char*)); if (!aliasm) { numaliasm = 0; return false; } np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { numaliasm = 0; free(aliasm); aliasm = NULL; HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the numaliasm lines to read in the remainder of the table */ for (int j = 0; j < numaliasm; j++) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); aliasm[j] = NULL; iter = nl.begin(); i = 0; start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 2, "AM", 2) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); numaliasm = 0; free(aliasm); aliasm = NULL; return false; } break; } case 1: { // add the remaining of the line std::string::const_iterator end = nl.end(); std::string chunk(start_piece, end); if (complexprefixes) { if (utf8) reverseword_utf(chunk); else reverseword(chunk); } aliasm[j] = mystrdup(chunk.c_str()); break; } default: break; } ++i; start_piece = mystrsep(nl, iter); } if (!aliasm[j]) { numaliasm = 0; free(aliasm); aliasm = NULL; HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); return false; } } return true; } int HashMgr::is_aliasm() const { return (aliasm != NULL); } char* HashMgr::get_aliasm(int index) const { if ((index > 0) && (index <= numaliasm)) return aliasm[index - 1]; HUNSPELL_WARNING(stderr, "error: bad morph. alias index: %d\n", index); return NULL; } /* parse in the typical fault correcting table */ bool HashMgr::parse_reptable(const std::string& line, FileMgr* af) { if (!reptable.empty()) { HUNSPELL_WARNING(stderr, "error: line %d: multiple table definitions\n", af->getlinenum()); return false; } int numrep = -1; int i = 0; int np = 0; std::string::const_iterator iter = line.begin(); std::string::const_iterator start_piece = mystrsep(line, iter); while (start_piece != line.end()) { switch (i) { case 0: { np++; break; } case 1: { numrep = atoi(std::string(start_piece, iter).c_str()); if (numrep < 1) { HUNSPELL_WARNING(stderr, "error: line %d: incorrect entry number\n", af->getlinenum()); return false; } reptable.reserve(numrep); np++; break; } default: break; } ++i; start_piece = mystrsep(line, iter); } if (np != 2) { HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum()); return false; } /* now parse the numrep lines to read in the remainder of the table */ for (int j = 0; j < numrep; ++j) { std::string nl; if (!af->getline(nl)) return false; mychomp(nl); reptable.push_back(replentry()); iter = nl.begin(); i = 0; int type = 0; start_piece = mystrsep(nl, iter); while (start_piece != nl.end()) { switch (i) { case 0: { if (nl.compare(start_piece - nl.begin(), 3, "REP", 3) != 0) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); reptable.clear(); return false; } break; } case 1: { if (*start_piece == '^') type = 1; reptable.back().pattern.assign(start_piece + type, iter); mystrrep(reptable.back().pattern, "_", " "); if (!reptable.back().pattern.empty() && reptable.back().pattern[reptable.back().pattern.size() - 1] == '$') { type += 2; reptable.back().pattern.resize(reptable.back().pattern.size() - 1); } break; } case 2: { reptable.back().outstrings[type].assign(start_piece, iter); mystrrep(reptable.back().outstrings[type], "_", " "); break; } default: break; } ++i; start_piece = mystrsep(nl, iter); } if (reptable.back().pattern.empty() || reptable.back().outstrings[type].empty()) { HUNSPELL_WARNING(stderr, "error: line %d: table is corrupt\n", af->getlinenum()); reptable.clear(); return false; } } return true; } // return replacing table const std::vector& HashMgr::get_reptable() const { return reptable; } hunspell-1.7.0/src/hunspell/hashmgr.hxx000066400000000000000000000152261337236234000201650ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #ifndef HASHMGR_HXX_ #define HASHMGR_HXX_ #include #include #include #include "htypes.hxx" #include "filemgr.hxx" #include "w_char.hxx" enum flag { FLAG_CHAR, FLAG_LONG, FLAG_NUM, FLAG_UNI }; // morphological description of a dictionary item can contain // arbitrary number "ph:" (MORPH_PHON) fields to store typical // phonetic or other misspellings of that word. // ratio of lines/lines with "ph:" in the dic file: 1/MORPH_PHON_RATIO #define MORPH_PHON_RATIO 500 class HashMgr { int tablesize; struct hentry** tableptr; flag flag_mode; int complexprefixes; int utf8; unsigned short forbiddenword; int langnum; std::string enc; std::string lang; struct cs_info* csconv; std::string ignorechars; std::vector ignorechars_utf16; int numaliasf; // flag vector `compression' with aliases unsigned short** aliasf; unsigned short* aliasflen; int numaliasm; // morphological desciption `compression' with aliases char** aliasm; // reptable created from REP table of aff file and from "ph:" fields // of the dic file. It contains phonetic and other common misspellings // (letters, letter groups and words) for better suggestions std::vector reptable; public: HashMgr(const char* tpath, const char* apath, const char* key = NULL); ~HashMgr(); struct hentry* lookup(const char*) const; int hash(const char*) const; struct hentry* walk_hashtable(int& col, struct hentry* hp) const; int add(const std::string& word); int add_with_affix(const std::string& word, const std::string& pattern); int remove(const std::string& word); int decode_flags(unsigned short** result, const std::string& flags, FileMgr* af) const; bool decode_flags(std::vector& result, const std::string& flags, FileMgr* af) const; unsigned short decode_flag(const char* flag) const; char* encode_flag(unsigned short flag) const; int is_aliasf() const; int get_aliasf(int index, unsigned short** fvec, FileMgr* af) const; int is_aliasm() const; char* get_aliasm(int index) const; const std::vector& get_reptable() const; private: int get_clen_and_captype(const std::string& word, int* captype); int get_clen_and_captype(const std::string& word, int* captype, std::vector &workbuf); int load_tables(const char* tpath, const char* key); int add_word(const std::string& word, int wcl, unsigned short* ap, int al, const std::string* desc, bool onlyupcase, int captype); int load_config(const char* affpath, const char* key); bool parse_aliasf(const std::string& line, FileMgr* af); int add_hidden_capitalized_word(const std::string& word, int wcl, unsigned short* flags, int al, const std::string* dp, int captype); bool parse_aliasm(const std::string& line, FileMgr* af); bool parse_reptable(const std::string& line, FileMgr* af); int remove_forbidden_flag(const std::string& word); }; #endif hunspell-1.7.0/src/hunspell/htypes.hxx000066400000000000000000000061371337236234000200510ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 HTYPES_HXX_ #define HTYPES_HXX_ #define ROTATE_LEN 5 #define ROTATE(v, q) \ (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q)) - 1)); // hentry options #define H_OPT (1 << 0) // is there optional morphological data? #define H_OPT_ALIASM (1 << 1) // using alias compression? #define H_OPT_PHON (1 << 2) // is there ph: field in the morphological data? #define H_OPT_INITCAP (1 << 3) // is dictionary word capitalized? // see also csutil.hxx #define HENTRY_WORD(h) &(h->word[0]) // approx. number of user defined words #define USERWORD 1000 #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) # define HUNSPELL_THREAD_LOCAL thread_local #else # define HUNSPELL_THREAD_LOCAL static #endif struct hentry { unsigned char blen; // word length in bytes unsigned char clen; // word length in characters (different for UTF-8 enc.) short alen; // length of affix flag vector unsigned short* astr; // affix flag vector struct hentry* next; // next word with same hash code struct hentry* next_homonym; // next homonym word (with same hash code) char var; // bit vector of H_OPT hentry options char word[1]; // variable-length word (8-bit or UTF-8 encoding) }; #endif hunspell-1.7.0/src/hunspell/hunspell.cxx000066400000000000000000002004401337236234000203530ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include #include "affixmgr.hxx" #include "hunspell.hxx" #include "suggestmgr.hxx" #include "hunspell.h" #include "csutil.hxx" #include #include #define MAXWORDUTF8LEN (MAXWORDLEN * 3) class HunspellImpl { public: HunspellImpl(const char* affpath, const char* dpath, const char* key = NULL); ~HunspellImpl(); int add_dic(const char* dpath, const char* key = NULL); std::vector suffix_suggest(const std::string& root_word); std::vector generate(const std::string& word, const std::vector& pl); std::vector generate(const std::string& word, const std::string& pattern); std::vector stem(const std::string& word); std::vector stem(const std::vector& morph); std::vector analyze(const std::string& word); int get_langnum() const; bool input_conv(const std::string& word, std::string& dest); bool spell(const std::string& word, int* info = NULL, std::string* root = NULL); std::vector suggest(const std::string& word); const std::string& get_wordchars_cpp() const; const std::vector& get_wordchars_utf16() const; const std::string& get_dict_encoding() const; int add(const std::string& word); int add_with_affix(const std::string& word, const std::string& example); int remove(const std::string& word); const std::string& get_version_cpp() const; struct cs_info* get_csconv(); int spell(const char* word, int* info = NULL, char** root = NULL); int suggest(char*** slst, const char* word); int suffix_suggest(char*** slst, const char* root_word); void free_list(char*** slst, int n); char* get_dic_encoding(); int analyze(char*** slst, const char* word); int stem(char*** slst, const char* word); int stem(char*** slst, char** morph, int n); int generate(char*** slst, const char* word, const char* word2); int generate(char*** slst, const char* word, char** desc, int n); const char* get_wordchars() const; const char* get_version() const; int input_conv(const char* word, char* dest, size_t destsize); private: AffixMgr* pAMgr; std::vector m_HMgrs; SuggestMgr* pSMgr; char* affixpath; std::string encoding; struct cs_info* csconv; int langnum; int utf8; int complexprefixes; std::vector wordbreak; private: std::vector analyze_internal(const std::string& word); bool spell_internal(const std::string& word, int* info = NULL, std::string* root = NULL); std::vector suggest_internal(const std::string& word, bool& capitalized, size_t& abbreviated, int& captype); void cleanword(std::string& dest, const std::string&, int* pcaptype, int* pabbrev); size_t cleanword2(std::string& dest, std::vector& dest_u, const std::string& src, int* pcaptype, size_t* pabbrev); void clean_ignore(std::string& dest, const std::string& src); void mkinitcap(std::string& u8); int mkinitcap2(std::string& u8, std::vector& u16); int mkinitsmall2(std::string& u8, std::vector& u16); void mkallcap(std::string& u8); int mkallsmall2(std::string& u8, std::vector& u16); struct hentry* checkword(const std::string& source, int* info, std::string* root); std::string sharps_u8_l1(const std::string& source); hentry* spellsharps(std::string& base, size_t start_pos, int, int, int* info, std::string* root); int is_keepcase(const hentry* rv); void insert_sug(std::vector& slst, const std::string& word); void cat_result(std::string& result, const std::string& st); std::vector spellml(const std::string& word); std::string get_xml_par(const char* par); const char* get_xml_pos(const char* s, const char* attr); std::vector get_xml_list(const char* list, const char* tag); int check_xml_par(const char* q, const char* attr, const char* value); private: HunspellImpl(const HunspellImpl&); HunspellImpl& operator=(const HunspellImpl&); }; HunspellImpl::HunspellImpl(const char* affpath, const char* dpath, const char* key) { csconv = NULL; utf8 = 0; complexprefixes = 0; affixpath = mystrdup(affpath); /* first set up the hash manager */ m_HMgrs.push_back(new HashMgr(dpath, affpath, key)); /* next set up the affix manager */ /* it needs access to the hash manager lookup methods */ pAMgr = new AffixMgr(affpath, m_HMgrs, key); /* get the preferred try string and the dictionary */ /* encoding from the Affix Manager for that dictionary */ char* try_string = pAMgr->get_try_string(); encoding = pAMgr->get_encoding(); langnum = pAMgr->get_langnum(); utf8 = pAMgr->get_utf8(); if (!utf8) csconv = get_current_cs(encoding); complexprefixes = pAMgr->get_complexprefixes(); wordbreak = pAMgr->get_breaktable(); /* and finally set up the suggestion manager */ pSMgr = new SuggestMgr(try_string, MAXSUGGESTION, pAMgr); if (try_string) free(try_string); } HunspellImpl::~HunspellImpl() { delete pSMgr; delete pAMgr; for (size_t i = 0; i < m_HMgrs.size(); ++i) delete m_HMgrs[i]; pSMgr = NULL; pAMgr = NULL; #ifdef MOZILLA_CLIENT delete[] csconv; #endif csconv = NULL; if (affixpath) free(affixpath); affixpath = NULL; } // load extra dictionaries int HunspellImpl::add_dic(const char* dpath, const char* key) { if (!affixpath) return 1; m_HMgrs.push_back(new HashMgr(dpath, affixpath, key)); return 0; } // make a copy of src at dest while removing all characters // specified in IGNORE rule void HunspellImpl::clean_ignore(std::string& dest, const std::string& src) { dest.clear(); dest.assign(src); const char* ignoredchars = pAMgr ? pAMgr->get_ignore() : NULL; if (ignoredchars != NULL) { if (utf8) { const std::vector& ignoredchars_utf16 = pAMgr->get_ignore_utf16(); remove_ignored_chars_utf(dest, ignoredchars_utf16); } else { remove_ignored_chars(dest, ignoredchars); } } } // make a copy of src at destination while removing all leading // blanks and removing any trailing periods after recording // their presence with the abbreviation flag // also since already going through character by character, // set the capitalization type // return the length of the "cleaned" (and UTF-8 encoded) word size_t HunspellImpl::cleanword2(std::string& dest, std::vector& dest_utf, const std::string& src, int* pcaptype, size_t* pabbrev) { dest.clear(); dest_utf.clear(); // remove IGNORE characters from the string std::string w2; clean_ignore(w2, src); const char* q = w2.c_str(); // first skip over any leading blanks while (*q == ' ') ++q; // now strip off any trailing periods (recording their presence) *pabbrev = 0; int nl = strlen(q); while ((nl > 0) && (*(q + nl - 1) == '.')) { nl--; (*pabbrev)++; } // if no characters are left it can't be capitalized if (nl <= 0) { *pcaptype = NOCAP; return 0; } dest.append(q, nl); nl = dest.size(); if (utf8) { u8_u16(dest_utf, dest); *pcaptype = get_captype_utf8(dest_utf, langnum); } else { *pcaptype = get_captype(dest, csconv); } return nl; } void HunspellImpl::cleanword(std::string& dest, const std::string& src, int* pcaptype, int* pabbrev) { dest.clear(); const unsigned char* q = (const unsigned char*)src.c_str(); int firstcap = 0; // first skip over any leading blanks while (*q == ' ') ++q; // now strip off any trailing periods (recording their presence) *pabbrev = 0; int nl = strlen((const char*)q); while ((nl > 0) && (*(q + nl - 1) == '.')) { nl--; (*pabbrev)++; } // if no characters are left it can't be capitalized if (nl <= 0) { *pcaptype = NOCAP; return; } // now determine the capitalization type of the first nl letters int ncap = 0; int nneutral = 0; int nc = 0; if (!utf8) { while (nl > 0) { nc++; if (csconv[(*q)].ccase) ncap++; if (csconv[(*q)].cupper == csconv[(*q)].clower) nneutral++; dest.push_back(*q++); nl--; } // remember to terminate the destination string firstcap = csconv[static_cast(dest[0])].ccase; } else { std::vector t; u8_u16(t, src); for (size_t i = 0; i < t.size(); ++i) { unsigned short idx = (t[i].h << 8) + t[i].l; unsigned short low = unicodetolower(idx, langnum); if (idx != low) ncap++; if (unicodetoupper(idx, langnum) == low) nneutral++; } u16_u8(dest, t); if (ncap) { unsigned short idx = (t[0].h << 8) + t[0].l; firstcap = (idx != unicodetolower(idx, langnum)); } } // now finally set the captype if (ncap == 0) { *pcaptype = NOCAP; } else if ((ncap == 1) && firstcap) { *pcaptype = INITCAP; } else if ((ncap == nc) || ((ncap + nneutral) == nc)) { *pcaptype = ALLCAP; } else if ((ncap > 1) && firstcap) { *pcaptype = HUHINITCAP; } else { *pcaptype = HUHCAP; } } void HunspellImpl::mkallcap(std::string& u8) { if (utf8) { std::vector u16; u8_u16(u16, u8); ::mkallcap_utf(u16, langnum); u16_u8(u8, u16); } else { ::mkallcap(u8, csconv); } } int HunspellImpl::mkallsmall2(std::string& u8, std::vector& u16) { if (utf8) { ::mkallsmall_utf(u16, langnum); u16_u8(u8, u16); } else { ::mkallsmall(u8, csconv); } return u8.size(); } // convert UTF-8 sharp S codes to latin 1 std::string HunspellImpl::sharps_u8_l1(const std::string& source) { std::string dest(source); mystrrep(dest, "\xC3\x9F", "\xDF"); return dest; } // recursive search for right ss - sharp s permutations hentry* HunspellImpl::spellsharps(std::string& base, size_t n_pos, int n, int repnum, int* info, std::string* root) { size_t pos = base.find("ss", n_pos); if (pos != std::string::npos && (n < MAXSHARPS)) { base[pos] = '\xC3'; base[pos + 1] = '\x9F'; hentry* h = spellsharps(base, pos + 2, n + 1, repnum + 1, info, root); if (h) return h; base[pos] = 's'; base[pos + 1] = 's'; h = spellsharps(base, pos + 2, n + 1, repnum, info, root); if (h) return h; } else if (repnum > 0) { if (utf8) return checkword(base, info, root); std::string tmp(sharps_u8_l1(base)); return checkword(tmp, info, root); } return NULL; } int HunspellImpl::is_keepcase(const hentry* rv) { return pAMgr && rv->astr && pAMgr->get_keepcase() && TESTAFF(rv->astr, pAMgr->get_keepcase(), rv->alen); } /* insert a word to the beginning of the suggestion array */ void HunspellImpl::insert_sug(std::vector& slst, const std::string& word) { slst.insert(slst.begin(), word); } bool HunspellImpl::spell(const std::string& word, int* info, std::string* root) { bool r = spell_internal(word, info, root); if (r && root) { // output conversion RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL; if (rl) { std::string wspace; if (rl->conv(*root, wspace)) { *root = wspace; } } } return r; } bool HunspellImpl::spell_internal(const std::string& word, int* info, std::string* root) { struct hentry* rv = NULL; int info2 = 0; if (!info) info = &info2; else *info = 0; // Hunspell supports XML input of the simplified API (see manual) if (word == SPELL_XML) return true; if (utf8) { if (word.size() >= MAXWORDUTF8LEN) return false; } else { if (word.size() >= MAXWORDLEN) return false; } int captype = NOCAP; size_t abbv = 0; size_t wl = 0; std::string scw; std::vector sunicw; // input conversion RepList* rl = pAMgr ? pAMgr->get_iconvtable() : NULL; { std::string wspace; bool convstatus = rl ? rl->conv(word, wspace) : false; if (convstatus) wl = cleanword2(scw, sunicw, wspace, &captype, &abbv); else wl = cleanword2(scw, sunicw, word, &captype, &abbv); } #ifdef MOZILLA_CLIENT // accept the abbreviated words without dots // workaround for the incomplete tokenization of Mozilla abbv = 1; #endif if (wl == 0 || m_HMgrs.empty()) return true; if (root) root->clear(); // allow numbers with dots, dashes and commas (but forbid double separators: // "..", "--" etc.) enum { NBEGIN, NNUM, NSEP }; int nstate = NBEGIN; size_t i; for (i = 0; (i < wl); i++) { if ((scw[i] <= '9') && (scw[i] >= '0')) { nstate = NNUM; } else if ((scw[i] == ',') || (scw[i] == '.') || (scw[i] == '-')) { if ((nstate == NSEP) || (i == 0)) break; nstate = NSEP; } else break; } if ((i == wl) && (nstate == NNUM)) return true; switch (captype) { case HUHCAP: /* FALLTHROUGH */ case HUHINITCAP: *info += SPELL_ORIGCAP; /* FALLTHROUGH */ case NOCAP: rv = checkword(scw, info, root); if ((abbv) && !(rv)) { std::string u8buffer(scw); u8buffer.push_back('.'); rv = checkword(u8buffer, info, root); } break; case ALLCAP: { *info += SPELL_ORIGCAP; rv = checkword(scw, info, root); if (rv) break; if (abbv) { std::string u8buffer(scw); u8buffer.push_back('.'); rv = checkword(u8buffer, info, root); if (rv) break; } // Spec. prefix handling for Catalan, French, Italian: // prefixes separated by apostrophe (SANT'ELIA -> Sant'+Elia). size_t apos = pAMgr ? scw.find('\'') : std::string::npos; if (apos != std::string::npos) { mkallsmall2(scw, sunicw); //conversion may result in string with different len to pre-mkallsmall2 //so re-scan if (apos != std::string::npos && apos < scw.size() - 1) { std::string part1 = scw.substr(0, apos+1); std::string part2 = scw.substr(apos+1); if (utf8) { std::vector part1u, part2u; u8_u16(part1u, part1); u8_u16(part2u, part2); mkinitcap2(part2, part2u); scw = part1 + part2; sunicw = part1u; sunicw.insert(sunicw.end(), part2u.begin(), part2u.end()); rv = checkword(scw, info, root); if (rv) break; } else { mkinitcap2(part2, sunicw); scw = part1 + part2; rv = checkword(scw, info, root); if (rv) break; } mkinitcap2(scw, sunicw); rv = checkword(scw, info, root); if (rv) break; } } if (pAMgr && pAMgr->get_checksharps() && scw.find("SS") != std::string::npos) { mkallsmall2(scw, sunicw); std::string u8buffer(scw); rv = spellsharps(u8buffer, 0, 0, 0, info, root); if (!rv) { mkinitcap2(scw, sunicw); rv = spellsharps(scw, 0, 0, 0, info, root); } if ((abbv) && !(rv)) { u8buffer.push_back('.'); rv = spellsharps(u8buffer, 0, 0, 0, info, root); if (!rv) { u8buffer = std::string(scw); u8buffer.push_back('.'); rv = spellsharps(u8buffer, 0, 0, 0, info, root); } } if (rv) break; } } /* FALLTHROUGH */ case INITCAP: { // handle special capitalization of dotted I bool Idot = (utf8 && (unsigned char) scw[0] == 0xc4 && (unsigned char) scw[1] == 0xb0); *info += SPELL_ORIGCAP; if (captype == ALLCAP) { mkallsmall2(scw, sunicw); mkinitcap2(scw, sunicw); if (Idot) scw.replace(0, 1, "\xc4\xb0"); } if (captype == INITCAP) *info += SPELL_INITCAP; rv = checkword(scw, info, root); if (captype == INITCAP) *info -= SPELL_INITCAP; // forbid bad capitalization // (for example, ijs -> Ijs instead of IJs in Dutch) // use explicit forms in dic: Ijs/F (F = FORBIDDENWORD flag) if (*info & SPELL_FORBIDDEN) { rv = NULL; break; } if (rv && is_keepcase(rv) && (captype == ALLCAP)) rv = NULL; if (rv || (Idot && langnum != LANG_az && langnum != LANG_tr && langnum != LANG_crh)) break; mkallsmall2(scw, sunicw); std::string u8buffer(scw); mkinitcap2(scw, sunicw); rv = checkword(u8buffer, info, root); if (abbv && !rv) { u8buffer.push_back('.'); rv = checkword(u8buffer, info, root); if (!rv) { u8buffer = scw; u8buffer.push_back('.'); if (captype == INITCAP) *info += SPELL_INITCAP; rv = checkword(u8buffer, info, root); if (captype == INITCAP) *info -= SPELL_INITCAP; if (rv && is_keepcase(rv) && (captype == ALLCAP)) rv = NULL; break; } } if (rv && is_keepcase(rv) && ((captype == ALLCAP) || // if CHECKSHARPS: KEEPCASE words with \xDF are allowed // in INITCAP form, too. !(pAMgr->get_checksharps() && ((utf8 && u8buffer.find("\xC3\x9F") != std::string::npos) || (!utf8 && u8buffer.find('\xDF') != std::string::npos))))) rv = NULL; break; } } if (rv) { if (pAMgr && pAMgr->get_warn() && rv->astr && TESTAFF(rv->astr, pAMgr->get_warn(), rv->alen)) { *info += SPELL_WARN; if (pAMgr->get_forbidwarn()) return false; return true; } return true; } // recursive breaking at break points if (!wordbreak.empty() && !(*info & SPELL_FORBIDDEN)) { int nbr = 0; wl = scw.size(); // calculate break points for recursion limit for (size_t j = 0; j < wordbreak.size(); ++j) { size_t pos = 0; while ((pos = scw.find(wordbreak[j], pos)) != std::string::npos) { ++nbr; pos += wordbreak[j].size(); } } if (nbr >= 10) return false; // check boundary patterns (^begin and end$) for (size_t j = 0; j < wordbreak.size(); ++j) { size_t plen = wordbreak[j].size(); if (plen == 1 || plen > wl) continue; if (wordbreak[j][0] == '^' && scw.compare(0, plen - 1, wordbreak[j], 1, plen -1) == 0 && spell(scw.substr(plen - 1))) return true; if (wordbreak[j][plen - 1] == '$' && scw.compare(wl - plen + 1, plen - 1, wordbreak[j], 0, plen - 1) == 0) { std::string suffix(scw.substr(wl - plen + 1)); scw.resize(wl - plen + 1); if (spell(scw)) return true; scw.append(suffix); } } // other patterns for (size_t j = 0; j < wordbreak.size(); ++j) { size_t plen = wordbreak[j].size(); size_t found = scw.find(wordbreak[j]); if ((found > 0) && (found < wl - plen)) { size_t found2 = scw.find(wordbreak[j], found + 1); // try to break at the second occurance // to recognize dictionary words with wordbreak if (found2 > 0 && (found2 < wl - plen)) found = found2; if (!spell(scw.substr(found + plen))) continue; std::string suffix(scw.substr(found)); scw.resize(found); // examine 2 sides of the break point if (spell(scw)) return true; scw.append(suffix); // LANG_hu: spec. dash rule if (langnum == LANG_hu && wordbreak[j] == "-") { suffix = scw.substr(found + 1); scw.resize(found + 1); if (spell(scw)) return true; // check the first part with dash scw.append(suffix); } // end of LANG specific region } } // other patterns (break at first break point) for (size_t j = 0; j < wordbreak.size(); ++j) { size_t plen = wordbreak[j].size(); size_t found = scw.find(wordbreak[j]); if ((found > 0) && (found < wl - plen)) { if (!spell(scw.substr(found + plen))) continue; std::string suffix(scw.substr(found)); scw.resize(found); // examine 2 sides of the break point if (spell(scw)) return true; scw.append(suffix); // LANG_hu: spec. dash rule if (langnum == LANG_hu && wordbreak[j] == "-") { suffix = scw.substr(found + 1); scw.resize(found + 1); if (spell(scw)) return true; // check the first part with dash scw.append(suffix); } // end of LANG specific region } } } return false; } struct hentry* HunspellImpl::checkword(const std::string& w, int* info, std::string* root) { bool usebuffer = false; std::string w2; const char* word; int len; // remove IGNORE characters from the string clean_ignore(w2, w); word = w2.c_str(); len = w2.size(); usebuffer = true; if (!len) return NULL; // word reversing wrapper for complex prefixes if (complexprefixes) { if (!usebuffer) { w2.assign(word); usebuffer = true; } if (utf8) reverseword_utf(w2); else reverseword(w2); } if (usebuffer) { word = w2.c_str(); } // look word in hash table struct hentry* he = NULL; for (size_t i = 0; (i < m_HMgrs.size()) && !he; ++i) { he = m_HMgrs[i]->lookup(word); // check forbidden and onlyincompound words if ((he) && (he->astr) && (pAMgr) && TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) { if (info) *info += SPELL_FORBIDDEN; // LANG_hu section: set dash information for suggestions if (langnum == LANG_hu) { if (pAMgr->get_compoundflag() && TESTAFF(he->astr, pAMgr->get_compoundflag(), he->alen)) { if (info) *info += SPELL_COMPOUND; } } return NULL; } // he = next not needaffix, onlyincompound homonym or onlyupcase word while (he && (he->astr) && pAMgr && ((pAMgr->get_needaffix() && TESTAFF(he->astr, pAMgr->get_needaffix(), he->alen)) || (pAMgr->get_onlyincompound() && TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) || (info && (*info & SPELL_INITCAP) && TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)))) he = he->next_homonym; } // check with affixes if (!he && pAMgr) { // try stripping off affixes */ he = pAMgr->affix_check(word, len, 0); // check compound restriction and onlyupcase if (he && he->astr && ((pAMgr->get_onlyincompound() && TESTAFF(he->astr, pAMgr->get_onlyincompound(), he->alen)) || (info && (*info & SPELL_INITCAP) && TESTAFF(he->astr, ONLYUPCASEFLAG, he->alen)))) { he = NULL; } if (he) { if ((he->astr) && (pAMgr) && TESTAFF(he->astr, pAMgr->get_forbiddenword(), he->alen)) { if (info) *info += SPELL_FORBIDDEN; return NULL; } if (root) { root->assign(he->word); if (complexprefixes) { if (utf8) reverseword_utf(*root); else reverseword(*root); } } // try check compound word } else if (pAMgr->get_compound()) { struct hentry* rwords[100]; // buffer for COMPOUND pattern checking he = pAMgr->compound_check(word, 0, 0, 100, 0, NULL, (hentry**)&rwords, 0, 0, info); // LANG_hu section: `moving rule' with last dash if ((!he) && (langnum == LANG_hu) && (word[len - 1] == '-')) { std::string dup(word, len - 1); he = pAMgr->compound_check(dup, -5, 0, 100, 0, NULL, (hentry**)&rwords, 1, 0, info); } // end of LANG specific region if (he) { if (root) { root->assign(he->word); if (complexprefixes) { if (utf8) reverseword_utf(*root); else reverseword(*root); } } if (info) *info += SPELL_COMPOUND; } } } return he; } std::vector HunspellImpl::suggest(const std::string& word) { bool capwords; size_t abbv; int captype; std::vector slst = suggest_internal(word, capwords, abbv, captype); // word reversing wrapper for complex prefixes if (complexprefixes) { for (size_t j = 0; j < slst.size(); ++j) { if (utf8) reverseword_utf(slst[j]); else reverseword(slst[j]); } } // capitalize if (capwords) for (size_t j = 0; j < slst.size(); ++j) { mkinitcap(slst[j]); } // expand suggestions with dot(s) if (abbv && pAMgr && pAMgr->get_sugswithdots()) { for (size_t j = 0; j < slst.size(); ++j) { slst[j].append(word.substr(word.size() - abbv)); } } // remove bad capitalized and forbidden forms if (pAMgr && (pAMgr->get_keepcase() || pAMgr->get_forbiddenword())) { switch (captype) { case INITCAP: case ALLCAP: { size_t l = 0; for (size_t j = 0; j < slst.size(); ++j) { if (slst[j].find(' ') == std::string::npos && !spell(slst[j])) { std::string s; std::vector w; if (utf8) { u8_u16(w, slst[j]); } else { s = slst[j]; } mkallsmall2(s, w); if (spell(s)) { slst[l] = s; ++l; } else { mkinitcap2(s, w); if (spell(s)) { slst[l] = s; ++l; } } } else { slst[l] = slst[j]; ++l; } } slst.resize(l); } } } // remove duplications size_t l = 0; for (size_t j = 0; j < slst.size(); ++j) { slst[l] = slst[j]; for (size_t k = 0; k < l; ++k) { if (slst[k] == slst[j]) { --l; break; } } ++l; } slst.resize(l); // output conversion RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL; if (rl) { for (size_t i = 0; rl && i < slst.size(); ++i) { std::string wspace; if (rl->conv(slst[i], wspace)) { slst[i] = wspace; } } } return slst; } std::vector HunspellImpl::suggest_internal(const std::string& word, bool& capwords, size_t& abbv, int& captype) { captype = NOCAP; abbv = 0; capwords = false; std::vector slst; int onlycmpdsug = 0; if (!pSMgr || m_HMgrs.empty()) return slst; // process XML input of the simplified API (see manual) if (word.compare(0, sizeof(SPELL_XML) - 3, SPELL_XML, sizeof(SPELL_XML) - 3) == 0) { return spellml(word); } if (utf8) { if (word.size() >= MAXWORDUTF8LEN) return slst; } else { if (word.size() >= MAXWORDLEN) return slst; } size_t wl = 0; std::string scw; std::vector sunicw; // input conversion RepList* rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL; { std::string wspace; bool convstatus = rl ? rl->conv(word, wspace) : false; if (convstatus) wl = cleanword2(scw, sunicw, wspace, &captype, &abbv); else wl = cleanword2(scw, sunicw, word, &captype, &abbv); if (wl == 0) return slst; } bool good = false; clock_t timelimit; // initialize in every suggestion call timelimit = clock(); // check capitalized form for FORCEUCASE if (pAMgr && captype == NOCAP && pAMgr->get_forceucase()) { int info = SPELL_ORIGCAP; if (checkword(scw, &info, NULL)) { std::string form(scw); mkinitcap(form); slst.push_back(form); return slst; } } switch (captype) { case NOCAP: { good |= pSMgr->suggest(slst, scw.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; if (abbv) { std::string wspace(scw); wspace.push_back('.'); good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; } break; } case INITCAP: { capwords = true; good |= pSMgr->suggest(slst, scw.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; std::string wspace(scw); mkallsmall2(wspace, sunicw); good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; break; } case HUHINITCAP: capwords = true; /* FALLTHROUGH */ case HUHCAP: { good |= pSMgr->suggest(slst, scw.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; // something.The -> something. The size_t dot_pos = scw.find('.'); if (dot_pos != std::string::npos) { std::string postdot = scw.substr(dot_pos + 1); int captype_; if (utf8) { std::vector postdotu; u8_u16(postdotu, postdot); captype_ = get_captype_utf8(postdotu, langnum); } else { captype_ = get_captype(postdot, csconv); } if (captype_ == INITCAP) { std::string str(scw); str.insert(dot_pos + 1, 1, ' '); insert_sug(slst, str); } } std::string wspace; if (captype == HUHINITCAP) { // TheOpenOffice.org -> The OpenOffice.org wspace = scw; mkinitsmall2(wspace, sunicw); good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; } wspace = scw; mkallsmall2(wspace, sunicw); if (spell(wspace.c_str())) insert_sug(slst, wspace); size_t prevns = slst.size(); good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; if (captype == HUHINITCAP) { mkinitcap2(wspace, sunicw); if (spell(wspace.c_str())) insert_sug(slst, wspace); good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; } // aNew -> "a New" (instead of "a new") for (size_t j = prevns; j < slst.size(); ++j) { const char* space = strchr(slst[j].c_str(), ' '); if (space) { size_t slen = strlen(space + 1); // different case after space (need capitalisation) if ((slen < wl) && strcmp(scw.c_str() + wl - slen, space + 1)) { std::string first(slst[j].c_str(), space + 1); std::string second(space + 1); std::vector w; if (utf8) u8_u16(w, second); mkinitcap2(second, w); // set as first suggestion slst.erase(slst.begin() + j); slst.insert(slst.begin(), first + second); } } } break; } case ALLCAP: { std::string wspace(scw); mkallsmall2(wspace, sunicw); good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; if (pAMgr && pAMgr->get_keepcase() && spell(wspace.c_str())) insert_sug(slst, wspace); mkinitcap2(wspace, sunicw); good |= pSMgr->suggest(slst, wspace.c_str(), &onlycmpdsug); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; for (size_t j = 0; j < slst.size(); ++j) { mkallcap(slst[j]); if (pAMgr && pAMgr->get_checksharps()) { if (utf8) { mystrrep(slst[j], "\xC3\x9F", "SS"); } else { mystrrep(slst[j], "\xDF", "SS"); } } } break; } } // LANG_hu section: replace '-' with ' ' in Hungarian if (langnum == LANG_hu) { for (size_t j = 0; j < slst.size(); ++j) { size_t pos = slst[j].find('-'); if (pos != std::string::npos) { int info; std::string w(slst[j].substr(0, pos)); w.append(slst[j].substr(pos + 1)); (void)spell(w, &info, NULL); if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) { slst[j][pos] = ' '; } else slst[j][pos] = '-'; } } } // END OF LANG_hu section // try ngram approach since found nothing good suggestion if (!good && pAMgr && (slst.empty() || onlycmpdsug) && (pAMgr->get_maxngramsugs() != 0)) { switch (captype) { case NOCAP: { pSMgr->ngsuggest(slst, scw.c_str(), m_HMgrs, NOCAP); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; break; } /* FALLTHROUGH */ case HUHINITCAP: capwords = true; /* FALLTHROUGH */ case HUHCAP: { std::string wspace(scw); mkallsmall2(wspace, sunicw); pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, HUHCAP); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; break; } case INITCAP: { capwords = true; std::string wspace(scw); mkallsmall2(wspace, sunicw); pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, INITCAP); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; break; } case ALLCAP: { std::string wspace(scw); mkallsmall2(wspace, sunicw); size_t oldns = slst.size(); pSMgr->ngsuggest(slst, wspace.c_str(), m_HMgrs, ALLCAP); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; for (size_t j = oldns; j < slst.size(); ++j) { mkallcap(slst[j]); } break; } } } // try dash suggestion (Afo-American -> Afro-American) // Note: LibreOffice was modified to treat dashes as word // characters to check "scot-free" etc. word forms, but // we need to handle suggestions for "Afo-American", etc., // while "Afro-American" is missing from the dictionary. // TODO avoid possible overgeneration size_t dash_pos = scw.find('-'); if (dash_pos != std::string::npos) { int nodashsug = 1; for (size_t j = 0; j < slst.size() && nodashsug == 1; ++j) { if (slst[j].find('-') != std::string::npos) nodashsug = 0; } size_t prev_pos = 0; bool last = false; while (!good && nodashsug && !last) { if (dash_pos == scw.size()) last = 1; std::string chunk = scw.substr(prev_pos, dash_pos - prev_pos); if (!spell(chunk.c_str())) { std::vector nlst = suggest(chunk.c_str()); if (clock() > timelimit + TIMELIMIT_GLOBAL) return slst; for (std::vector::reverse_iterator j = nlst.rbegin(); j != nlst.rend(); ++j) { std::string wspace = scw.substr(0, prev_pos); wspace.append(*j); if (!last) { wspace.append("-"); wspace.append(scw.substr(dash_pos + 1)); } int info = 0; if (pAMgr && pAMgr->get_forbiddenword()) checkword(wspace, &info, NULL); if (!(info & SPELL_FORBIDDEN)) insert_sug(slst, wspace); } nodashsug = 0; } if (!last) { prev_pos = dash_pos + 1; dash_pos = scw.find('-', prev_pos); } if (dash_pos == std::string::npos) dash_pos = scw.size(); } } return slst; } const std::string& HunspellImpl::get_dict_encoding() const { return encoding; } std::vector HunspellImpl::stem(const std::vector& desc) { std::vector slst; std::string result2; if (desc.empty()) return slst; for (size_t i = 0; i < desc.size(); ++i) { std::string result; // add compound word parts (except the last one) const char* s = desc[i].c_str(); const char* part = strstr(s, MORPH_PART); if (part) { const char* nextpart = strstr(part + 1, MORPH_PART); while (nextpart) { std::string field; copy_field(field, part, MORPH_PART); result.append(field); part = nextpart; nextpart = strstr(part + 1, MORPH_PART); } s = part; } std::string tok(s); size_t alt = 0; while ((alt = tok.find(" | ", alt)) != std::string::npos) { tok[alt + 1] = MSEP_ALT; } std::vector pl = line_tok(tok, MSEP_ALT); for (size_t k = 0; k < pl.size(); ++k) { // add derivational suffixes if (pl[k].find(MORPH_DERI_SFX) != std::string::npos) { // remove inflectional suffixes const size_t is = pl[k].find(MORPH_INFL_SFX); if (is != std::string::npos) pl[k].resize(is); std::vector singlepl; singlepl.push_back(pl[k]); std::string sg = pSMgr->suggest_gen(singlepl, pl[k]); if (!sg.empty()) { std::vector gen = line_tok(sg, MSEP_REC); for (size_t j = 0; j < gen.size(); ++j) { result2.push_back(MSEP_REC); result2.append(result); result2.append(gen[j]); } } } else { result2.push_back(MSEP_REC); result2.append(result); if (pl[k].find(MORPH_SURF_PFX) != std::string::npos) { std::string field; copy_field(field, pl[k], MORPH_SURF_PFX); result2.append(field); } std::string field; copy_field(field, pl[k], MORPH_STEM); result2.append(field); } } } slst = line_tok(result2, MSEP_REC); uniqlist(slst); return slst; } std::vector HunspellImpl::stem(const std::string& word) { return stem(analyze(word)); } const std::string& HunspellImpl::get_wordchars_cpp() const { return pAMgr->get_wordchars(); } const std::vector& HunspellImpl::get_wordchars_utf16() const { return pAMgr->get_wordchars_utf16(); } void HunspellImpl::mkinitcap(std::string& u8) { if (utf8) { std::vector u16; u8_u16(u16, u8); ::mkinitcap_utf(u16, langnum); u16_u8(u8, u16); } else { ::mkinitcap(u8, csconv); } } int HunspellImpl::mkinitcap2(std::string& u8, std::vector& u16) { if (utf8) { ::mkinitcap_utf(u16, langnum); u16_u8(u8, u16); } else { ::mkinitcap(u8, csconv); } return u8.size(); } int HunspellImpl::mkinitsmall2(std::string& u8, std::vector& u16) { if (utf8) { ::mkinitsmall_utf(u16, langnum); u16_u8(u8, u16); } else { ::mkinitsmall(u8, csconv); } return u8.size(); } int HunspellImpl::add(const std::string& word) { if (!m_HMgrs.empty()) return m_HMgrs[0]->add(word); return 0; } int HunspellImpl::add_with_affix(const std::string& word, const std::string& example) { if (!m_HMgrs.empty()) return m_HMgrs[0]->add_with_affix(word, example); return 0; } int HunspellImpl::remove(const std::string& word) { if (!m_HMgrs.empty()) return m_HMgrs[0]->remove(word); return 0; } const std::string& HunspellImpl::get_version_cpp() const { return pAMgr->get_version(); } struct cs_info* HunspellImpl::get_csconv() { return csconv; } void HunspellImpl::cat_result(std::string& result, const std::string& st) { if (!st.empty()) { if (!result.empty()) result.append("\n"); result.append(st); } } std::vector HunspellImpl::analyze(const std::string& word) { std::vector slst = analyze_internal(word); // output conversion RepList* rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL; if (rl) { for (size_t i = 0; rl && i < slst.size(); ++i) { std::string wspace; if (rl->conv(slst[i], wspace)) { slst[i] = wspace; } } } return slst; } std::vector HunspellImpl::analyze_internal(const std::string& word) { std::vector slst; if (!pSMgr || m_HMgrs.empty()) return slst; if (utf8) { if (word.size() >= MAXWORDUTF8LEN) return slst; } else { if (word.size() >= MAXWORDLEN) return slst; } int captype = NOCAP; size_t abbv = 0; size_t wl = 0; std::string scw; std::vector sunicw; // input conversion RepList* rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL; { std::string wspace; bool convstatus = rl ? rl->conv(word, wspace) : false; if (convstatus) wl = cleanword2(scw, sunicw, wspace, &captype, &abbv); else wl = cleanword2(scw, sunicw, word, &captype, &abbv); } if (wl == 0) { if (abbv) { scw.clear(); for (wl = 0; wl < abbv; wl++) scw.push_back('.'); abbv = 0; } else return slst; } std::string result; size_t n = 0; // test numbers // LANG_hu section: set dash information for suggestions if (langnum == LANG_hu) { size_t n2 = 0; size_t n3 = 0; while ((n < wl) && (((scw[n] <= '9') && (scw[n] >= '0')) || (((scw[n] == '.') || (scw[n] == ',')) && (n > 0)))) { n++; if ((scw[n] == '.') || (scw[n] == ',')) { if (((n2 == 0) && (n > 3)) || ((n2 > 0) && ((scw[n - 1] == '.') || (scw[n - 1] == ',')))) break; n2++; n3 = n; } } if ((n == wl) && (n3 > 0) && (n - n3 > 3)) return slst; if ((n == wl) || ((n > 0) && ((scw[n] == '%') || (scw[n] == '\xB0')) && checkword(scw.substr(n), NULL, NULL))) { result.append(scw); result.resize(n - 1); if (n == wl) cat_result(result, pSMgr->suggest_morph(scw.substr(n - 1))); else { std::string chunk = scw.substr(n - 1, 1); cat_result(result, pSMgr->suggest_morph(chunk)); result.push_back('+'); // XXX SPEC. MORPHCODE cat_result(result, pSMgr->suggest_morph(scw.substr(n))); } return line_tok(result, MSEP_REC); } } // END OF LANG_hu section switch (captype) { case HUHCAP: case HUHINITCAP: case NOCAP: { cat_result(result, pSMgr->suggest_morph(scw)); if (abbv) { std::string u8buffer(scw); u8buffer.push_back('.'); cat_result(result, pSMgr->suggest_morph(u8buffer)); } break; } case INITCAP: { mkallsmall2(scw, sunicw); std::string u8buffer(scw); mkinitcap2(scw, sunicw); cat_result(result, pSMgr->suggest_morph(u8buffer)); cat_result(result, pSMgr->suggest_morph(scw)); if (abbv) { u8buffer.push_back('.'); cat_result(result, pSMgr->suggest_morph(u8buffer)); u8buffer = scw; u8buffer.push_back('.'); cat_result(result, pSMgr->suggest_morph(u8buffer)); } break; } case ALLCAP: { cat_result(result, pSMgr->suggest_morph(scw)); if (abbv) { std::string u8buffer(scw); u8buffer.push_back('.'); cat_result(result, pSMgr->suggest_morph(u8buffer)); } mkallsmall2(scw, sunicw); std::string u8buffer(scw); mkinitcap2(scw, sunicw); cat_result(result, pSMgr->suggest_morph(u8buffer)); cat_result(result, pSMgr->suggest_morph(scw)); if (abbv) { u8buffer.push_back('.'); cat_result(result, pSMgr->suggest_morph(u8buffer)); u8buffer = scw; u8buffer.push_back('.'); cat_result(result, pSMgr->suggest_morph(u8buffer)); } break; } } if (!result.empty()) { // word reversing wrapper for complex prefixes if (complexprefixes) { if (utf8) reverseword_utf(result); else reverseword(result); } return line_tok(result, MSEP_REC); } // compound word with dash (HU) I18n // LANG_hu section: set dash information for suggestions size_t dash_pos = langnum == LANG_hu ? scw.find('-') : std::string::npos; if (dash_pos != std::string::npos) { int nresult = 0; std::string part1 = scw.substr(0, dash_pos); std::string part2 = scw.substr(dash_pos+1); // examine 2 sides of the dash if (part2.empty()) { // base word ending with dash if (spell(part1)) { std::string p = pSMgr->suggest_morph(part1); if (!p.empty()) { slst = line_tok(p, MSEP_REC); return slst; } } } else if (part2.size() == 1 && part2[0] == 'e') { // XXX (HU) -e hat. if (spell(part1) && (spell("-e"))) { std::string st = pSMgr->suggest_morph(part1); if (!st.empty()) { result.append(st); } result.push_back('+'); // XXX spec. separator in MORPHCODE st = pSMgr->suggest_morph("-e"); if (!st.empty()) { result.append(st); } return line_tok(result, MSEP_REC); } } else { // first word ending with dash: word- XXX ??? part1.push_back(' '); nresult = spell(part1); part1.erase(part1.size() - 1); if (nresult && spell(part2) && ((part2.size() > 1) || ((part2[0] > '0') && (part2[0] < '9')))) { std::string st = pSMgr->suggest_morph(part1); if (!st.empty()) { result.append(st); result.push_back('+'); // XXX spec. separator in MORPHCODE } st = pSMgr->suggest_morph(part2); if (!st.empty()) { result.append(st); } return line_tok(result, MSEP_REC); } } // affixed number in correct word if (nresult && (dash_pos > 0) && (((scw[dash_pos - 1] <= '9') && (scw[dash_pos - 1] >= '0')) || (scw[dash_pos - 1] == '.'))) { n = 1; if (scw[dash_pos - n] == '.') n++; // search first not a number character to left from dash while ((dash_pos >= n) && ((scw[dash_pos - n] == '0') || (n < 3)) && (n < 6)) { n++; } if (dash_pos < n) n--; // numbers: valami1000000-hoz // examine 100000-hoz, 10000-hoz 1000-hoz, 10-hoz, // 56-hoz, 6-hoz for (; n >= 1; n--) { if (scw[dash_pos - n] < '0' || scw[dash_pos - n] > '9') { continue; } std::string chunk = scw.substr(dash_pos - n); if (checkword(chunk, NULL, NULL)) { result.append(chunk); std::string st = pSMgr->suggest_morph(chunk); if (!st.empty()) { result.append(st); } return line_tok(result, MSEP_REC); } } } } return slst; } std::vector HunspellImpl::generate(const std::string& word, const std::vector& pl) { std::vector slst; if (!pSMgr || pl.empty()) return slst; std::vector pl2 = analyze(word); int captype = NOCAP; int abbv = 0; std::string cw; cleanword(cw, word, &captype, &abbv); std::string result; for (size_t i = 0; i < pl.size(); ++i) { cat_result(result, pSMgr->suggest_gen(pl2, pl[i])); } if (!result.empty()) { // allcap if (captype == ALLCAP) mkallcap(result); // line split slst = line_tok(result, MSEP_REC); // capitalize if (captype == INITCAP || captype == HUHINITCAP) { for (size_t j = 0; j < slst.size(); ++j) { mkinitcap(slst[j]); } } // temporary filtering of prefix related errors (eg. // generate("undrinkable", "eats") --> "undrinkables" and "*undrinks") std::vector::iterator it = slst.begin(); while (it != slst.end()) { if (!spell(*it)) { it = slst.erase(it); } else { ++it; } } } return slst; } std::vector HunspellImpl::generate(const std::string& word, const std::string& pattern) { std::vector pl = analyze(pattern); std::vector slst = generate(word, pl); uniqlist(slst); return slst; } // minimal XML parser functions std::string HunspellImpl::get_xml_par(const char* par) { std::string dest; if (!par) return dest; char end = *par; if (end == '>') end = '<'; else if (end != '\'' && end != '"') return dest; // bad XML for (par++; *par != '\0' && *par != end; ++par) { dest.push_back(*par); } mystrrep(dest, "<", "<"); mystrrep(dest, "&", "&"); return dest; } int HunspellImpl::get_langnum() const { return langnum; } bool HunspellImpl::input_conv(const std::string& word, std::string& dest) { RepList* rl = pAMgr ? pAMgr->get_iconvtable() : NULL; if (rl) { return rl->conv(word, dest); } dest.assign(word); return false; } // return the beginning of the element (attr == NULL) or the attribute const char* HunspellImpl::get_xml_pos(const char* s, const char* attr) { const char* end = strchr(s, '>'); if (attr == NULL) return end; const char* p = s; while (1) { p = strstr(p, attr); if (!p || p >= end) return 0; if (*(p - 1) == ' ' || *(p - 1) == '\n') break; p += strlen(attr); } return p + strlen(attr); } int HunspellImpl::check_xml_par(const char* q, const char* attr, const char* value) { std::string cw = get_xml_par(get_xml_pos(q, attr)); if (cw == value) return 1; return 0; } std::vector HunspellImpl::get_xml_list(const char* list, const char* tag) { std::vector slst; if (!list) return slst; const char* p = list; for (size_t n = 0; ((p = strstr(p, tag)) != NULL); ++p, ++n) { std::string cw = get_xml_par(p + strlen(tag) - 1); if (cw.empty()) { break; } slst.push_back(cw); } return slst; } std::vector HunspellImpl::spellml(const std::string& in_word) { std::vector slst; const char* word = in_word.c_str(); const char* q = strstr(word, "'); if (!q2) return slst; // bad XML input q2 = strstr(q2, "')); if (!cw.empty()) slst = analyze(cw); if (slst.empty()) return slst; // convert the result to ana1ana2 format std::string r; r.append(""); for (size_t i = 0; i < slst.size(); ++i) { r.append(""); std::string entry(slst[i]); mystrrep(entry, "\t", " "); mystrrep(entry, "&", "&"); mystrrep(entry, "<", "<"); r.append(entry); r.append(""); } r.append(""); slst.clear(); slst.push_back(r); return slst; } else if (check_xml_par(q, "type=", "stem")) { std::string cw = get_xml_par(strchr(q2, '>')); if (!cw.empty()) return stem(cw); } else if (check_xml_par(q, "type=", "generate")) { std::string cw = get_xml_par(strchr(q2, '>')); if (cw.empty()) return slst; const char* q3 = strstr(q2 + 1, "')); if (!cw2.empty()) { return generate(cw, cw2); } } else { if ((q2 = strstr(q2 + 1, " slst2 = get_xml_list(strchr(q2, '>'), ""); if (!slst2.empty()) { slst = generate(cw, slst2); uniqlist(slst); return slst; } } } } else if (check_xml_par(q, "type=", "add")) { std::string cw = get_xml_par(strchr(q2, '>')); if (cw.empty()) return slst; const char* q3 = strstr(q2 + 1, "')); if (!cw2.empty()) { add_with_affix(cw, cw2); } else { add(cw); } } else { add(cw); } } return slst; } std::vector HunspellImpl::suffix_suggest(const std::string& root_word) { std::vector slst; struct hentry* he = NULL; int len; std::string w2; const char* word; const char* ignoredchars = pAMgr->get_ignore(); if (ignoredchars != NULL) { w2.assign(root_word); if (utf8) { const std::vector& ignoredchars_utf16 = pAMgr->get_ignore_utf16(); remove_ignored_chars_utf(w2, ignoredchars_utf16); } else { remove_ignored_chars(w2, ignoredchars); } word = w2.c_str(); } else word = root_word.c_str(); len = strlen(word); if (!len) return slst; for (size_t i = 0; (i < m_HMgrs.size()) && !he; ++i) { he = m_HMgrs[i]->lookup(word); } if (he) { slst = pAMgr->get_suffix_words(he->astr, he->alen, root_word.c_str()); } return slst; } namespace { int munge_vector(char*** slst, const std::vector& items) { if (items.empty()) { *slst = NULL; return 0; } else { *slst = (char**)malloc(sizeof(char*) * items.size()); if (!*slst) return 0; for (size_t i = 0; i < items.size(); ++i) (*slst)[i] = mystrdup(items[i].c_str()); } return items.size(); } } int HunspellImpl::spell(const char* word, int* info, char** root) { std::string sroot; bool ret = spell(word, info, root ? &sroot : NULL); if (root) { if (sroot.empty()) { *root = NULL; } else { *root = mystrdup(sroot.c_str()); } } return ret; } int HunspellImpl::suggest(char*** slst, const char* word) { std::vector suggests = suggest(word); return munge_vector(slst, suggests); } int HunspellImpl::suffix_suggest(char*** slst, const char* root_word) { std::vector stems = suffix_suggest(root_word); return munge_vector(slst, stems); } void HunspellImpl::free_list(char*** slst, int n) { if (slst && *slst) { for (int i = 0; i < n; i++) free((*slst)[i]); free(*slst); *slst = NULL; } } char* HunspellImpl::get_dic_encoding() { return &encoding[0]; } int HunspellImpl::analyze(char*** slst, const char* word) { std::vector stems = analyze(word); return munge_vector(slst, stems); } int HunspellImpl::stem(char*** slst, const char* word) { std::vector stems = stem(word); return munge_vector(slst, stems); } int HunspellImpl::stem(char*** slst, char** desc, int n) { std::vector morph; for (int i = 0; i < n; ++i) morph.push_back(desc[i]); std::vector stems = stem(morph); return munge_vector(slst, stems); } int HunspellImpl::generate(char*** slst, const char* word, const char* pattern) { std::vector stems = generate(word, pattern); return munge_vector(slst, stems); } int HunspellImpl::generate(char*** slst, const char* word, char** pl, int pln) { std::vector morph; for (int i = 0; i < pln; ++i) morph.push_back(pl[i]); std::vector stems = generate(word, morph); return munge_vector(slst, stems); } const char* HunspellImpl::get_wordchars() const { return get_wordchars_cpp().c_str(); } const char* HunspellImpl::get_version() const { return get_version_cpp().c_str(); } int HunspellImpl::input_conv(const char* word, char* dest, size_t destsize) { std::string d; bool ret = input_conv(word, d); if (ret && d.size() < destsize) { strncpy(dest, d.c_str(), destsize); return 1; } return 0; } Hunspell::Hunspell(const char* affpath, const char* dpath, const char* key) : m_Impl(new HunspellImpl(affpath, dpath, key)) { } Hunspell::~Hunspell() { delete m_Impl; } // load extra dictionaries int Hunspell::add_dic(const char* dpath, const char* key) { return m_Impl->add_dic(dpath, key); } bool Hunspell::spell(const std::string& word, int* info, std::string* root) { return m_Impl->spell(word, info, root); } std::vector Hunspell::suggest(const std::string& word) { return m_Impl->suggest(word); } std::vector Hunspell::suffix_suggest(const std::string& root_word) { return m_Impl->suffix_suggest(root_word); } const std::string& Hunspell::get_dict_encoding() const { return m_Impl->get_dict_encoding(); } std::vector Hunspell::stem(const std::vector& desc) { return m_Impl->stem(desc); } std::vector Hunspell::stem(const std::string& word) { return m_Impl->stem(word); } const std::string& Hunspell::get_wordchars_cpp() const { return m_Impl->get_wordchars_cpp(); } const std::vector& Hunspell::get_wordchars_utf16() const { return m_Impl->get_wordchars_utf16(); } int Hunspell::add(const std::string& word) { return m_Impl->add(word); } int Hunspell::add_with_affix(const std::string& word, const std::string& example) { return m_Impl->add_with_affix(word, example); } int Hunspell::remove(const std::string& word) { return m_Impl->remove(word); } const std::string& Hunspell::get_version_cpp() const { return m_Impl->get_version_cpp(); } struct cs_info* Hunspell::get_csconv() { return m_Impl->get_csconv(); } std::vector Hunspell::analyze(const std::string& word) { return m_Impl->analyze(word); } std::vector Hunspell::generate(const std::string& word, const std::vector& pl) { return m_Impl->generate(word, pl); } std::vector Hunspell::generate(const std::string& word, const std::string& pattern) { return m_Impl->generate(word, pattern); } int Hunspell::get_langnum() const { return m_Impl->get_langnum(); } bool Hunspell::input_conv(const std::string& word, std::string& dest) { return m_Impl->input_conv(word, dest); } int Hunspell::spell(const char* word, int* info, char** root) { return m_Impl->spell(word, info, root); } int Hunspell::suggest(char*** slst, const char* word) { return m_Impl->suggest(slst, word); } int Hunspell::suffix_suggest(char*** slst, const char* root_word) { return m_Impl->suffix_suggest(slst, root_word); } void Hunspell::free_list(char*** slst, int n) { m_Impl->free_list(slst, n); } char* Hunspell::get_dic_encoding() { return m_Impl->get_dic_encoding(); } int Hunspell::analyze(char*** slst, const char* word) { return m_Impl->analyze(slst, word); } int Hunspell::stem(char*** slst, const char* word) { return m_Impl->stem(slst, word); } int Hunspell::stem(char*** slst, char** desc, int n) { return m_Impl->stem(slst, desc, n); } int Hunspell::generate(char*** slst, const char* word, const char* pattern) { return m_Impl->generate(slst, word, pattern); } int Hunspell::generate(char*** slst, const char* word, char** pl, int pln) { return m_Impl->generate(slst, word, pl, pln); } const char* Hunspell::get_wordchars() const { return m_Impl->get_wordchars(); } const char* Hunspell::get_version() const { return m_Impl->get_version(); } int Hunspell::input_conv(const char* word, char* dest, size_t destsize) { return m_Impl->input_conv(word, dest, destsize); } Hunhandle* Hunspell_create(const char* affpath, const char* dpath) { return reinterpret_cast(new HunspellImpl(affpath, dpath)); } Hunhandle* Hunspell_create_key(const char* affpath, const char* dpath, const char* key) { return reinterpret_cast(new HunspellImpl(affpath, dpath, key)); } void Hunspell_destroy(Hunhandle* pHunspell) { delete reinterpret_cast(pHunspell); } int Hunspell_add_dic(Hunhandle* pHunspell, const char* dpath) { return reinterpret_cast(pHunspell)->add_dic(dpath); } int Hunspell_spell(Hunhandle* pHunspell, const char* word) { return reinterpret_cast(pHunspell)->spell(word); } char* Hunspell_get_dic_encoding(Hunhandle* pHunspell) { return reinterpret_cast(pHunspell)->get_dic_encoding(); } int Hunspell_suggest(Hunhandle* pHunspell, char*** slst, const char* word) { return reinterpret_cast(pHunspell)->suggest(slst, word); } int Hunspell_analyze(Hunhandle* pHunspell, char*** slst, const char* word) { return reinterpret_cast(pHunspell)->analyze(slst, word); } int Hunspell_stem(Hunhandle* pHunspell, char*** slst, const char* word) { return reinterpret_cast(pHunspell)->stem(slst, word); } int Hunspell_stem2(Hunhandle* pHunspell, char*** slst, char** desc, int n) { return reinterpret_cast(pHunspell)->stem(slst, desc, n); } int Hunspell_generate(Hunhandle* pHunspell, char*** slst, const char* word, const char* pattern) { return reinterpret_cast(pHunspell)->generate(slst, word, pattern); } int Hunspell_generate2(Hunhandle* pHunspell, char*** slst, const char* word, char** desc, int n) { return reinterpret_cast(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 reinterpret_cast(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 reinterpret_cast(pHunspell)->add_with_affix(word, example); } /* remove word from the run-time dictionary */ int Hunspell_remove(Hunhandle* pHunspell, const char* word) { return reinterpret_cast(pHunspell)->remove(word); } void Hunspell_free_list(Hunhandle* pHunspell, char*** list, int n) { reinterpret_cast(pHunspell)->free_list(list, n); } hunspell-1.7.0/src/hunspell/hunspell.h000066400000000000000000000150431337236234000200030ustar00rootroot00000000000000/* ***** 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 Németh László (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 János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 MYSPELLMGR_H_ #define MYSPELLMGR_H_ #include "hunvisapi.h" #ifdef __cplusplus extern "C" { #endif typedef struct Hunhandle Hunhandle; LIBHUNSPELL_DLL_EXPORTED Hunhandle* Hunspell_create(const char* affpath, const char* dpath); LIBHUNSPELL_DLL_EXPORTED Hunhandle* Hunspell_create_key(const char* affpath, const char* dpath, const char* key); LIBHUNSPELL_DLL_EXPORTED void Hunspell_destroy(Hunhandle* pHunspell); /* load extra dictionaries (only dic files) * output: 0 = additional dictionary slots available, 1 = slots are now full*/ LIBHUNSPELL_DLL_EXPORTED int Hunspell_add_dic(Hunhandle* pHunspell, const char* dpath); /* spell(word) - spellcheck word * output: 0 = bad word, not 0 = good word */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_spell(Hunhandle* pHunspell, const char*); LIBHUNSPELL_DLL_EXPORTED char* Hunspell_get_dic_encoding(Hunhandle* pHunspell); /* 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.) */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_suggest(Hunhandle* pHunspell, char*** slst, const char* word); /* morphological functions */ /* analyze(result, word) - morphological analysis of the word */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_analyze(Hunhandle* pHunspell, char*** slst, const char* word); /* stem(result, word) - stemmer function */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_stem(Hunhandle* pHunspell, char*** slst, const char* word); /* stem(result, analysis, n) - get stems from a morph. analysis * example: * char ** result, result2; * int n1 = Hunspell_analyze(result, "words"); * int n2 = Hunspell_stem2(result2, result, n1); */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_stem2(Hunhandle* pHunspell, char*** slst, char** desc, int n); /* generate(result, word, word2) - morphological generation by example(s) */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_generate(Hunhandle* pHunspell, 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 = Hunspell_generate2(result, "word", &affix, 1); * for (int i = 0; i < n; i++) printf("%s\n", result[i]); */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_generate2(Hunhandle* pHunspell, char*** slst, const char* word, char** desc, int n); /* functions for run-time modification of the dictionary */ /* add word to the run-time dictionary */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_add(Hunhandle* pHunspell, 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. */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_add_with_affix(Hunhandle* pHunspell, const char* word, const char* example); /* remove word from the run-time dictionary */ LIBHUNSPELL_DLL_EXPORTED int Hunspell_remove(Hunhandle* pHunspell, const char* word); /* free suggestion lists */ LIBHUNSPELL_DLL_EXPORTED void Hunspell_free_list(Hunhandle* pHunspell, char*** slst, int n); #ifdef __cplusplus } #endif #endif hunspell-1.7.0/src/hunspell/hunspell.hxx000066400000000000000000000216271337236234000203700ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #ifndef MYSPELLMGR_HXX_ #define MYSPELLMGR_HXX_ #include "hunvisapi.h" #include "w_char.hxx" #include "atypes.hxx" #include #include #define SPELL_XML "" #define MAXSUGGESTION 15 #define MAXSHARPS 5 #ifndef MAXWORDLEN #define MAXWORDLEN 100 #endif #if defined __GNUC__ && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) # define H_DEPRECATED __attribute__((__deprecated__)) #elif defined(_MSC_VER) && (_MSC_VER >= 1300) # define H_DEPRECATED __declspec(deprecated) #else # define H_DEPRECATED #endif class HunspellImpl; class LIBHUNSPELL_DLL_EXPORTED Hunspell { private: Hunspell(const Hunspell&); Hunspell& operator=(const Hunspell&); private: HunspellImpl* m_Impl; public: /* Hunspell(aff, dic) - constructor of Hunspell class * input: path of affix file and dictionary file * * In WIN32 environment, use UTF-8 encoded paths started with the long path * prefix \\\\?\\ to handle system-independent character encoding and very * long path names (without the long path prefix Hunspell will use fopen() * with system-dependent character encoding instead of _wfopen()). */ 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: false = bad word, true = 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) */ bool spell(const std::string& word, int* info = NULL, std::string* root = NULL); H_DEPRECATED 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.) */ std::vector suggest(const std::string& word); H_DEPRECATED int suggest(char*** slst, const char* word); /* Suggest words from suffix rules * suffix_suggest(suggestions, root_word) * input: pointer to an array of strings pointer and the 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.) */ std::vector suffix_suggest(const std::string& root_word); H_DEPRECATED int suffix_suggest(char*** slst, const char* root_word); /* deallocate suggestion lists */ H_DEPRECATED void free_list(char*** slst, int n); const std::string& get_dict_encoding() const; char* get_dic_encoding(); /* morphological functions */ /* analyze(result, word) - morphological analysis of the word */ std::vector analyze(const std::string& word); H_DEPRECATED int analyze(char*** slst, const char* word); /* stem(word) - stemmer function */ std::vector stem(const std::string& word); H_DEPRECATED int stem(char*** slst, const char* word); /* stem(analysis, n) - get stems from a morph. analysis * example: * char ** result, result2; * int n1 = analyze(&result, "words"); * int n2 = stem(&result2, result, n1); */ std::vector stem(const std::vector& morph); H_DEPRECATED int stem(char*** slst, char** morph, int n); /* generate(result, word, word2) - morphological generation by example(s) */ std::vector generate(const std::string& word, const std::string& word2); H_DEPRECATED 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]); */ std::vector generate(const std::string& word, const std::vector& pl); H_DEPRECATED 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 std::string& 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 std::string& word, const std::string& example); /* remove word from the run-time dictionary */ int remove(const std::string& word); /* other */ /* get extra word characters definied in affix file for tokenization */ const char* get_wordchars() const; const std::string& get_wordchars_cpp() const; const std::vector& get_wordchars_utf16() const; struct cs_info* get_csconv(); const char* get_version() const; const std::string& get_version_cpp() const; int get_langnum() const; /* need for putdic */ bool input_conv(const std::string& word, std::string& dest); H_DEPRECATED int input_conv(const char* word, char* dest, size_t destsize); }; #endif hunspell-1.7.0/src/hunspell/hunvisapi.h000066400000000000000000000007571337236234000201650ustar00rootroot00000000000000#ifndef HUNSPELL_VISIBILITY_H_ #define HUNSPELL_VISIBILITY_H_ #if defined(HUNSPELL_STATIC) # define LIBHUNSPELL_DLL_EXPORTED #elif defined(_WIN32) # if defined(BUILDING_LIBHUNSPELL) # define LIBHUNSPELL_DLL_EXPORTED __declspec(dllexport) # else # define LIBHUNSPELL_DLL_EXPORTED __declspec(dllimport) # endif #elif defined(BUILDING_LIBHUNSPELL) && 1 # define LIBHUNSPELL_DLL_EXPORTED __attribute__((__visibility__("default"))) #else # define LIBHUNSPELL_DLL_EXPORTED #endif #endif hunspell-1.7.0/src/hunspell/hunvisapi.h.in000066400000000000000000000007771337236234000205740ustar00rootroot00000000000000#ifndef HUNSPELL_VISIBILITY_H_ #define HUNSPELL_VISIBILITY_H_ #if defined(HUNSPELL_STATIC) # define LIBHUNSPELL_DLL_EXPORTED #elif defined(_WIN32) # if defined(BUILDING_LIBHUNSPELL) # define LIBHUNSPELL_DLL_EXPORTED __declspec(dllexport) # else # define LIBHUNSPELL_DLL_EXPORTED __declspec(dllimport) # endif #elif defined(BUILDING_LIBHUNSPELL) && @HAVE_VISIBILITY@ # define LIBHUNSPELL_DLL_EXPORTED __attribute__((__visibility__("default"))) #else # define LIBHUNSPELL_DLL_EXPORTED #endif #endif hunspell-1.7.0/src/hunspell/hunzip.cxx000066400000000000000000000152731337236234000200460ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "hunzip.hxx" #include "csutil.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), inbits(0), outc(0) { in[0] = out[0] = line[0] = '\0'; filename = mystrdup(file); if (getcode(key) == -1) bufsiz = -1; else bufsiz = getbuf(); } int Hunzip::getcode(const char* key) { unsigned char c[2]; int i, j, n; int allocatedbit = BASEBITREC; const char* enc = key; if (!filename) return -1; myopen(fin, filename, std::ios_base::in | std::ios_base::binary); if (!fin.is_open()) return -1; // read magic number if (!fin.read(in, 3) || !(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 (!fin.read(reinterpret_cast(c), 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 (!fin.read(reinterpret_cast(c), 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.resize(BASEBITREC); dec[0].v[0] = 0; dec[0].v[1] = 0; // read codes for (i = 0; i < n; i++) { unsigned char l; if (!fin.read(reinterpret_cast(c), 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 (!fin.read(reinterpret_cast(&l), 1)) return fail(MSG_FORMAT, filename); if (key) { if (*(++enc) == '\0') enc = key; l ^= *enc; } if (!fin.read(in, 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; } int 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.resize(allocatedbit); } 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 (filename) free(filename); } int Hunzip::getbuf() { int p = 0; int o = 0; do { if (inc == 0) { fin.read(in, BUFSIZE); inbits = int(fin.gcount() * 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) { fin.close(); // 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); } bool Hunzip::getline(std::string& dest) { char linebuf[BUFSIZE]; int l = 0, eol = 0, left = 0, right = 0; if (bufsiz == -1) return false; 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.is_open() ? getbuf() : -1; } } if (right) strcpy(linebuf + l - 1, line + strlen(line) - right - 1); else linebuf[l] = '\0'; strcpy(line + left, linebuf); dest.assign(line); return true; } hunspell-1.7.0/src/hunspell/hunzip.hxx000066400000000000000000000061011337236234000200410ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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_ #include "hunvisapi.h" #include #include #include #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 LIBHUNSPELL_DLL_EXPORTED Hunzip { private: Hunzip(const Hunzip&); Hunzip& operator=(const Hunzip&); protected: char* filename; std::ifstream fin; int bufsiz, lastbit, inc, inbits, outc; std::vector 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(); bool is_open() { return fin.is_open(); } bool getline(std::string& dest); }; #endif hunspell-1.7.0/src/hunspell/langnum.hxx000066400000000000000000000050561337236234000201750ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 https://wiki.openoffice.org/w/index.php?title=Languages&oldid=230199 */ enum { LANG_ar = 96, LANG_az = 100, // custom number LANG_bg = 41, LANG_ca = 37, LANG_crh = 102, // custom number 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 hunspell-1.7.0/src/hunspell/phonet.cxx000066400000000000000000000204011337236234000200130ustar00rootroot00000000000000/* 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 */ #include #include #include #include #include "csutil.hxx" #include "phonet.hxx" void init_phonet_hash(phonetable& parms) { for (int i = 0; i < HASHSIZE; i++) { parms.hash[i] = -1; } for (int i = 0; parms.rules[i][0] != '\0'; i += 2) { /** set hash value **/ int 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'; } static int myisalpha(char ch) { if ((unsigned char)ch < 128) return isalpha(ch); return 1; } /* Do phonetic transformation. */ /* phonetic transcription algorithm */ /* see: http://aspell.net/man-html/Phonetic-Code.html */ /* convert string to uppercase before this call */ std::string phonet(const std::string& inword, phonetable& parms) { int i, k = 0, p, z; int k0, n0, p0 = -333; char c; typedef unsigned char uchar; size_t len = inword.size(); if (len > MAXPHONETUTF8LEN) return std::string(); char word[MAXPHONETUTF8LEN + 1]; strncpy(word, inword.c_str(), MAXPHONETUTF8LEN); word[MAXPHONETUTF8LEN] = '\0'; std::string target; /** check word **/ i = z = 0; while ((c = word[i]) != '\0') { int n = parms.hash[(uchar)c]; int z0 = 0; if (n >= 0 && !parms.rules[n].empty()) { /** 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 **/ const char*s = parms.rules[n].c_str(); s++; /** important for (see below) "*(s-1)" **/ while (*s != '\0' && word[i + k] == *s && !isdigit((unsigned char)*s) && strchr("(-<^$", *s) == NULL) { k++; s++; } if (*s == '(') { /** check letters in "(..)" **/ if (myisalpha(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((unsigned char)*s)) { /** determine priority **/ p = *s - '0'; s++; } if (*s == '^' && *(s + 1) == '^') s++; if (*s == '\0' || (*s == '^' && (i == 0 || !myisalpha(word[i - 1])) && (*(s + 1) != '$' || (!myisalpha(word[i + k0])))) || (*s == '$' && i > 0 && myisalpha(word[i - 1]) && (!myisalpha(word[i + k0])))) { /** search for followup rules, if: **/ /** parms.followup and k > 1 and NO '-' in searchstring **/ char 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' && !parms.rules[n0].empty()) { /** 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].c_str(); s++; while (*s != '\0' && word[i + k0] == *s && !isdigit((unsigned char)*s) && strchr("(-<^$", *s) == NULL) { k0++; s++; } if (*s == '(') { /** check letters **/ if (myisalpha(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((unsigned char)*s)) { p0 = *s - '0'; s++; } if (*s == '\0' /** *s == '^' cuts **/ || (*s == '$' && !myisalpha(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].c_str(); p0 = (!parms.rules[n].empty() && strchr(parms.rules[n].c_str() + 1, '<') != NULL) ? 1 : 0; if (p0 == 1 && z == 0) { /** rule with '<' is used **/ if (!target.empty() && *s != '\0' && (target[target.size()-1] == c || target[target.size()-1] == *s)) { target.erase(target.size() - 1); } 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' && target.size() < len) { if (target.empty() || target[target.size()-1] != *s) { target.push_back(*s); } s++; } /** new "actual letter" **/ c = *s; if (!parms.rules[n].empty() && strstr(parms.rules[n].c_str() + 1, "^^") != NULL) { if (c != '\0') { target.push_back(c); } 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 && !p0 && target.size() < len && c != '\0') { /** condense only double letters **/ target.push_back(c); /// printf("\n setting \n"); } i++; z = 0; k = 0; } } /** end of while ((c = word[i]) != '\0') **/ return target; } /** end of function "phonet" **/ hunspell-1.7.0/src/hunspell/phonet.hxx000066400000000000000000000031131337236234000200210ustar00rootroot00000000000000/* 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 PHONET_HXX_ #define PHONET_HXX_ #define HASHSIZE 256 #define MAXPHONETLEN 256 #define MAXPHONETUTF8LEN (MAXPHONETLEN * 4) #include "hunvisapi.h" struct phonetable { char utf8; std::vector rules; int hash[HASHSIZE]; }; LIBHUNSPELL_DLL_EXPORTED void init_phonet_hash(phonetable& parms); LIBHUNSPELL_DLL_EXPORTED std::string phonet(const std::string& inword, phonetable& phone); #endif hunspell-1.7.0/src/hunspell/replist.cxx000066400000000000000000000143741337236234000202140ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include #include "replist.hxx" #include "csutil.hxx" RepList::RepList(int n) { dat = (replentry**)malloc(sizeof(replentry*) * n); if (dat == 0) size = 0; else size = n; pos = 0; } RepList::~RepList() { for (int i = 0; i < pos; i++) { delete dat[i]; } free(dat); } replentry* RepList::item(int n) { return dat[n]; } int RepList::find(const char* word) { int p1 = 0; int p2 = pos - 1; int ret = -1; while (p1 <= p2) { int m = ((unsigned)p1 + (unsigned)p2) >> 1; int c = strncmp(word, dat[m]->pattern.c_str(), dat[m]->pattern.size()); if (c < 0) p2 = m - 1; else if (c > 0) p1 = m + 1; else { // scan in the right half for a longer match ret = m; p1 = m + 1; } } return ret; } std::string RepList::replace(const char* word, int ind, bool atstart) { int type = atstart ? 1 : 0; if (ind < 0) return std::string(); if (strlen(word) == dat[ind]->pattern.size()) type = atstart ? 3 : 2; while (type && dat[ind]->outstrings[type].empty()) type = (type == 2 && !atstart) ? 0 : type - 1; return dat[ind]->outstrings[type]; } int RepList::add(const std::string& in_pat1, const std::string& pat2) { if (pos >= size || in_pat1.empty() || pat2.empty()) { return 1; } // analyse word context int type = 0; std::string pat1(in_pat1); if (pat1[0] == '_') { pat1.erase(0, 1); type = 1; } if (!pat1.empty() && pat1[pat1.size() - 1] == '_') { type = type + 2; pat1.erase(pat1.size() - 1); } mystrrep(pat1, "_", " "); // find existing entry int m = find(pat1.c_str()); if (m >= 0 && dat[m]->pattern == pat1) { // since already used dat[m]->outstrings[type] = pat2; mystrrep(dat[m]->outstrings[type], "_", " "); return 0; } // make a new entry if none exists replentry* r = new replentry; if (r == NULL) return 1; r->pattern = pat1; r->outstrings[type] = pat2; mystrrep(r->outstrings[type], "_", " "); dat[pos++] = r; // sort to the right place in the list int i; for (i = pos - 1; i > 0; i--) { if (strcmp(r->pattern.c_str(), dat[i - 1]->pattern.c_str()) < 0) { dat[i] = dat[i - 1]; } else break; } dat[i] = r; return 0; } bool RepList::conv(const std::string& in_word, std::string& dest) { dest.clear(); size_t wordlen = in_word.size(); const char* word = in_word.c_str(); bool change = false; for (size_t i = 0; i < wordlen; ++i) { int n = find(word + i); std::string l = replace(word + i, n, i == 0); if (!l.empty()) { dest.append(l); i += dat[n]->pattern.size() - 1; change = true; } else { dest.push_back(word[i]); } } return change; } hunspell-1.7.0/src/hunspell/replist.hxx000066400000000000000000000101361337236234000202110ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ /* string replacement list class */ #ifndef REPLIST_HXX_ #define REPLIST_HXX_ #include "w_char.hxx" #include #include class RepList { private: RepList(const RepList&); RepList& operator=(const RepList&); protected: replentry** dat; int size; int pos; public: explicit RepList(int n); ~RepList(); int add(const std::string& pat1, const std::string& pat2); replentry* item(int n); int find(const char* word); std::string replace(const char* word, int n, bool atstart); bool conv(const std::string& word, std::string& dest); }; #endif hunspell-1.7.0/src/hunspell/suggestmgr.cxx000066400000000000000000002103761337236234000207210ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #include #include #include #include #include #include "suggestmgr.hxx" #include "htypes.hxx" #include "csutil.hxx" const w_char W_VLINE = {'\0', '|'}; #define MAX_CHAR_DISTANCE 4 SuggestMgr::SuggestMgr(const char* tryme, unsigned int maxn, AffixMgr* aptr) { // register affix manager and check in string of chars to // try when building candidate suggestions pAMgr = aptr; csconv = NULL; ckeyl = 0; ckey = NULL; ctryl = 0; ctry = NULL; utf8 = 0; langnum = 0; complexprefixes = 0; maxSug = maxn; nosplitsugs = 0; maxngramsugs = MAXNGRAMSUGS; maxcpdsugs = MAXCOMPOUNDSUGS; if (pAMgr) { 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(); if (pAMgr->get_maxcpdsugs() >= 0) maxcpdsugs = pAMgr->get_maxcpdsugs(); if (!utf8) { csconv = get_current_cs(pAMgr->get_encoding()); } complexprefixes = pAMgr->get_complexprefixes(); } if (ckey) { if (utf8) { ckeyl = u8_u16(ckey_utf, ckey); } else { ckeyl = strlen(ckey); } } if (tryme) { ctry = mystrdup(tryme); if (ctry) ctryl = strlen(ctry); if (ctry && utf8) { ctryl = u8_u16(ctry_utf, tryme); } } // language with possible dash usage // (latin letters or dash in TRY characters) lang_with_dash_usage = (ctry && ((strchr(ctry, '-') != NULL) || (strchr(ctry, 'a') != NULL))); } SuggestMgr::~SuggestMgr() { pAMgr = NULL; if (ckey) free(ckey); ckey = NULL; ckeyl = 0; if (ctry) free(ctry); ctry = NULL; ctryl = 0; maxSug = 0; #ifdef MOZILLA_CLIENT delete[] csconv; #endif } void SuggestMgr::testsug(std::vector& wlst, const std::string& candidate, int cpdsuggest, int* timer, clock_t* timelimit) { int cwrd = 1; if (wlst.size() == maxSug) return; for (size_t k = 0; k < wlst.size(); ++k) { if (wlst[k] == candidate) { cwrd = 0; break; } } if ((cwrd) && checkword(candidate, cpdsuggest, timer, timelimit)) { wlst.push_back(candidate); } } /* generate suggestions for a misspelled word * pass in address of array of char * pointers * onlycompoundsug: probably bad suggestions (need for ngram sugs, too) * return value: true, if there is a good suggestion * (REP, ph: or a dictionary word pair) */ bool SuggestMgr::suggest(std::vector& slst, const char* w, int* onlycompoundsug) { int nocompoundtwowords = 0; std::vector word_utf; int wl = 0; size_t nsugorig = slst.size(); std::string w2; const char* word = w; size_t oldSug = 0; bool good_suggestion = false; // word reversing wrapper for complex prefixes if (complexprefixes) { w2.assign(w); if (utf8) reverseword_utf(w2); else reverseword(w2); word = w2.c_str(); } if (utf8) { wl = u8_u16(word_utf, word); if (wl == -1) { return false; } } for (int cpdsuggest = 0; (cpdsuggest < 2) && (nocompoundtwowords == 0) && !good_suggestion; cpdsuggest++) { clock_t timelimit; // initialize both in non-compound and compound cycles timelimit = clock(); // limit compound suggestion if (cpdsuggest > 0) oldSug = slst.size(); // suggestions for an uppercase word (html -> HTML) if (slst.size() < maxSug) { size_t i = slst.size(); if (utf8) capchars_utf(slst, &word_utf[0], wl, cpdsuggest); else capchars(slst, word, cpdsuggest); if (slst.size() > i) good_suggestion = true; } // perhaps we made a typical fault of spelling if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { size_t i = slst.size(); replchars(slst, word, cpdsuggest); if (slst.size() > i) good_suggestion = true; } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // perhaps we made chose the wrong char from a related set if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { mapchars(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // only suggest compound words when no other suggestion if ((cpdsuggest == 0) && (slst.size() > nsugorig)) nocompoundtwowords = 1; // did we swap the order of chars by mistake if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) swapchar_utf(slst, &word_utf[0], wl, cpdsuggest); else swapchar(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // did we swap the order of non adjacent chars by mistake if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) longswapchar_utf(slst, &word_utf[0], wl, cpdsuggest); else longswapchar(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // did we just hit the wrong key in place of a good char (case and keyboard) if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) badcharkey_utf(slst, &word_utf[0], wl, cpdsuggest); else badcharkey(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // did we add a char that should not be there if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) extrachar_utf(slst, &word_utf[0], wl, cpdsuggest); else extrachar(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // did we forgot a char if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) forgotchar_utf(slst, &word_utf[0], wl, cpdsuggest); else forgotchar(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // did we move a char if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) movechar_utf(slst, &word_utf[0], wl, cpdsuggest); else movechar(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // did we just hit the wrong key in place of a good char if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) badchar_utf(slst, &word_utf[0], wl, cpdsuggest); else badchar(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // did we double two characters if ((slst.size() < maxSug) && (!cpdsuggest || (slst.size() < oldSug + maxcpdsugs))) { if (utf8) doubletwochars_utf(slst, &word_utf[0], wl, cpdsuggest); else doubletwochars(slst, word, cpdsuggest); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; // perhaps we forgot to hit space and two words ran together // (dictionary word pairs have top priority here, so // we always suggest them, in despite of nosplitsugs, and // drop compound word and other suggestions) if (!cpdsuggest || (!nosplitsugs && slst.size() < oldSug + maxcpdsugs)) { good_suggestion = twowords(slst, word, cpdsuggest, good_suggestion); } if (clock() > timelimit + TIMELIMIT_SUGGESTION) return good_suggestion; } // repeating ``for'' statement compounding support if (!nocompoundtwowords && (!slst.empty()) && onlycompoundsug) *onlycompoundsug = 1; return good_suggestion; } // suggestions for an uppercase word (html -> HTML) void SuggestMgr::capchars_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::vector candidate_utf(word, word + wl); mkallcap_utf(candidate_utf, langnum); std::string candidate; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } // suggestions for an uppercase word (html -> HTML) void SuggestMgr::capchars(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate(word); mkallcap(candidate, csconv); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } // suggestions for when chose the wrong char out of a related set int SuggestMgr::mapchars(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate; clock_t timelimit; int timer; int wl = strlen(word); if (wl < 2 || !pAMgr) return wlst.size(); const std::vector& maptable = pAMgr->get_maptable(); if (maptable.empty()) return wlst.size(); timelimit = clock(); timer = MINTIMER; return map_related(word, candidate, 0, wlst, cpdsuggest, maptable, &timer, &timelimit); } int SuggestMgr::map_related(const char* word, std::string& candidate, int wn, std::vector& wlst, int cpdsuggest, const std::vector& maptable, int* timer, clock_t* timelimit) { if (*(word + wn) == '\0') { int cwrd = 1; for (size_t m = 0; m < wlst.size(); ++m) { if (wlst[m] == candidate) { cwrd = 0; break; } } if ((cwrd) && checkword(candidate, cpdsuggest, timer, timelimit)) { if (wlst.size() < maxSug) { wlst.push_back(candidate); } } return wlst.size(); } int in_map = 0; for (size_t j = 0; j < maptable.size(); ++j) { for (size_t k = 0; k < maptable[j].size(); ++k) { size_t len = maptable[j][k].size(); if (strncmp(maptable[j][k].c_str(), word + wn, len) == 0) { in_map = 1; size_t cn = candidate.size(); for (size_t l = 0; l < maptable[j].size(); ++l) { candidate.resize(cn); candidate.append(maptable[j][l]); map_related(word, candidate, wn + len, wlst, cpdsuggest, maptable, timer, timelimit); if (!(*timer)) return wlst.size(); } } } } if (!in_map) { candidate.push_back(*(word + wn)); map_related(word, candidate, wn + 1, wlst, cpdsuggest, maptable, timer, timelimit); } return wlst.size(); } // suggestions for a typical fault of spelling, that // differs with more, than 1 letter from the right form. int SuggestMgr::replchars(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate; int wl = strlen(word); if (wl < 2 || !pAMgr) return wlst.size(); const std::vector& reptable = pAMgr->get_reptable(); for (size_t i = 0; i < reptable.size(); ++i) { const char* r = word; // search every occurence of the pattern in the word while ((r = strstr(r, reptable[i].pattern.c_str())) != NULL) { int type = (r == word) ? 1 : 0; if (r - word + reptable[i].pattern.size() == strlen(word)) type += 2; while (type && reptable[i].outstrings[type].empty()) type = (type == 2 && r != word) ? 0 : type - 1; const std::string&out = reptable[i].outstrings[type]; if (out.empty()) { ++r; continue; } candidate.assign(word); candidate.resize(r - word); candidate.append(reptable[i].outstrings[type]); candidate.append(r + reptable[i].pattern.size()); testsug(wlst, candidate, cpdsuggest, NULL, NULL); // check REP suggestions with space size_t sp = candidate.find(' '); if (sp != std::string::npos) { size_t prev = 0; while (sp != std::string::npos) { std::string prev_chunk = candidate.substr(prev, sp - prev); if (checkword(prev_chunk, 0, NULL, NULL)) { size_t oldns = wlst.size(); std::string post_chunk = candidate.substr(sp + 1); testsug(wlst, post_chunk, cpdsuggest, NULL, NULL); if (oldns < wlst.size()) { wlst[wlst.size() - 1] = candidate; } } prev = sp + 1; sp = candidate.find(' ', prev); } } r++; // search for the next letter } } return wlst.size(); } // perhaps we doubled two characters // (for example vacation -> vacacation) // The recognized pattern with regex back-references: // "(.)(.)\1\2\1" or "..(.)(.)\1\2" int SuggestMgr::doubletwochars(std::vector& wlst, const char* word, int cpdsuggest) { int state = 0; int wl = strlen(word); if (wl < 5 || !pAMgr) return wlst.size(); for (int i = 2; i < wl; i++) { if (word[i] == word[i - 2]) { state++; if (state == 3 || (state == 2 && i >= 4)) { std::string candidate(word, word + i - 1); candidate.insert(candidate.end(), word + i + 1, word + wl); testsug(wlst, candidate, cpdsuggest, NULL, NULL); state = 0; } } else { state = 0; } } return wlst.size(); } // perhaps we doubled two characters // (for example vacation -> vacacation) // The recognized pattern with regex back-references: // "(.)(.)\1\2\1" or "..(.)(.)\1\2" int SuggestMgr::doubletwochars_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { int state = 0; if (wl < 5 || !pAMgr) return wlst.size(); for (int i = 2; i < wl; i++) { if (word[i] == word[i - 2]) { state++; if (state == 3 || (state == 2 && i >= 4)) { std::vector candidate_utf(word, word + i - 1); candidate_utf.insert(candidate_utf.end(), word + i + 1, word + wl); std::string candidate; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); state = 0; } } else { state = 0; } } return wlst.size(); } // error is wrong char in place of correct one (case and keyboard related // version) int SuggestMgr::badcharkey(std::vector& wlst, const char* word, int cpdsuggest) { std::string 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 (size_t i = 0; i < candidate.size(); ++i) { char tmpc = candidate[i]; // check with uppercase letters candidate[i] = csconv[((unsigned char)tmpc)].cupper; if (tmpc != candidate[i]) { testsug(wlst, candidate, cpdsuggest, NULL, NULL); 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); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } if ((*(loc + 1) != '|') && (*(loc + 1) != '\0')) { candidate[i] = *(loc + 1); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } loc = strchr(loc + 1, tmpc); } candidate[i] = tmpc; } return wlst.size(); } // error is wrong char in place of correct one (case and keyboard related // version) int SuggestMgr::badcharkey_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::string candidate; std::vector candidate_utf(word, word + wl); // 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++) { w_char tmpc = candidate_utf[i]; // check with uppercase letters candidate_utf[i] = upper_utf(candidate_utf[i], 1); if (tmpc != candidate_utf[i]) { u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); candidate_utf[i] = tmpc; } // check neighbor characters in keyboard string if (!ckey) continue; size_t loc = 0; while ((loc < ckeyl) && ckey_utf[loc] != tmpc) ++loc; while (loc < ckeyl) { if ((loc > 0) && ckey_utf[loc - 1] != W_VLINE) { candidate_utf[i] = ckey_utf[loc - 1]; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } if (((loc + 1) < ckeyl) && (ckey_utf[loc + 1] != W_VLINE)) { candidate_utf[i] = ckey_utf[loc + 1]; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } do { loc++; } while ((loc < ckeyl) && ckey_utf[loc] != tmpc); } candidate_utf[i] = tmpc; } return wlst.size(); } // error is wrong char in place of correct one int SuggestMgr::badchar(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate(word); clock_t timelimit = clock(); int timer = MINTIMER; // 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 (size_t j = 0; j < ctryl; ++j) { for (std::string::reverse_iterator aI = candidate.rbegin(), aEnd = candidate.rend(); aI != aEnd; ++aI) { char tmpc = *aI; if (ctry[j] == tmpc) continue; *aI = ctry[j]; testsug(wlst, candidate, cpdsuggest, &timer, &timelimit); if (!timer) return wlst.size(); *aI = tmpc; } } return wlst.size(); } // error is wrong char in place of correct one int SuggestMgr::badchar_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::vector candidate_utf(word, word + wl); std::string candidate; clock_t timelimit = clock(); int timer = MINTIMER; // 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 (size_t j = 0; j < ctryl; ++j) { for (int i = wl - 1; i >= 0; i--) { w_char tmpc = candidate_utf[i]; if (tmpc == ctry_utf[j]) continue; candidate_utf[i] = ctry_utf[j]; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, &timer, &timelimit); if (!timer) return wlst.size(); candidate_utf[i] = tmpc; } } return wlst.size(); } // error is word has an extra letter it does not need int SuggestMgr::extrachar_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::vector candidate_utf(word, word + wl); if (candidate_utf.size() < 2) return wlst.size(); // try omitting one char of word at a time for (size_t i = 0; i < candidate_utf.size(); ++i) { size_t index = candidate_utf.size() - 1 - i; w_char tmpc = candidate_utf[index]; candidate_utf.erase(candidate_utf.begin() + index); std::string candidate; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); candidate_utf.insert(candidate_utf.begin() + index, tmpc); } return wlst.size(); } // error is word has an extra letter it does not need int SuggestMgr::extrachar(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate(word); if (candidate.size() < 2) return wlst.size(); // try omitting one char of word at a time for (size_t i = 0; i < candidate.size(); ++i) { size_t index = candidate.size() - 1 - i; char tmpc = candidate[index]; candidate.erase(candidate.begin() + index); testsug(wlst, candidate, cpdsuggest, NULL, NULL); candidate.insert(candidate.begin() + index, tmpc); } return wlst.size(); } // error is missing a letter it needs int SuggestMgr::forgotchar(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate(word); clock_t timelimit = clock(); int timer = MINTIMER; // try inserting a tryme character before every letter (and the null // terminator) for (size_t k = 0; k < ctryl; ++k) { for (size_t i = 0; i <= candidate.size(); ++i) { size_t index = candidate.size() - i; candidate.insert(candidate.begin() + index, ctry[k]); testsug(wlst, candidate, cpdsuggest, &timer, &timelimit); if (!timer) return wlst.size(); candidate.erase(candidate.begin() + index); } } return wlst.size(); } // error is missing a letter it needs int SuggestMgr::forgotchar_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::vector candidate_utf(word, word + wl); clock_t timelimit = clock(); int timer = MINTIMER; // try inserting a tryme character at the end of the word and before every // letter for (size_t k = 0; k < ctryl; ++k) { for (size_t i = 0; i <= candidate_utf.size(); ++i) { size_t index = candidate_utf.size() - i; candidate_utf.insert(candidate_utf.begin() + index, ctry_utf[k]); std::string candidate; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, &timer, &timelimit); if (!timer) return wlst.size(); candidate_utf.erase(candidate_utf.begin() + index); } } return wlst.size(); } /* error is should have been two words * return value is true, if there is a dictionary word pair, * or there was already a good suggestion before calling * this function. */ bool SuggestMgr::twowords(std::vector& wlst, const char* word, int cpdsuggest, bool good) { int c2; int forbidden = 0; int cwrd; int wl = strlen(word); if (wl < 3) return false; if (langnum == LANG_hu) forbidden = check_forbidden(word, wl); char* candidate = (char*)malloc(wl + 2); strcpy(candidate + 1, word); // split the string into two pieces after every char // if both pieces are good words make them a suggestion for (char* 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 // Suggest only word pairs, if they are listed in the dictionary. // For example, adding "a lot" to the English dic file will // result only "alot" -> "a lot" suggestion instead of // "alto, slot, alt, lot, allot, aloft, aloe, clot, plot, blot, a lot". // Note: using "ph:alot" keeps the other suggestions: // a lot ph:alot // alot -> a lot, alto, slot... *p = ' '; if (!cpdsuggest && checkword(candidate, cpdsuggest, NULL, NULL)) { // remove not word pair suggestions if (!good) { good = true; wlst.clear(); } wlst.insert(wlst.begin(), candidate); } // word pairs with dash? if (lang_with_dash_usage) { *p = '-'; if (!cpdsuggest && checkword(candidate, cpdsuggest, NULL, NULL)) { // remove not word pair suggestions if (!good) { good = true; wlst.clear(); } wlst.insert(wlst.begin(), candidate); } } if (wlst.size() < maxSug && !nosplitsugs && !good) { *p = '\0'; int c1 = checkword(candidate, cpdsuggest, NULL, NULL); if (c1) { c2 = checkword((p + 1), cpdsuggest, NULL, NULL); if (c2) { // spec. Hungarian code (TODO 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 = '-'; else *p = ' '; cwrd = 1; for (size_t k = 0; k < wlst.size(); ++k) { if (wlst[k] == candidate) { cwrd = 0; break; } } if (cwrd && (wlst.size() < maxSug)) wlst.push_back(candidate); // add two word suggestion with dash, depending on the language // Note that cwrd doesn't modified for REP twoword sugg. if ( !nosplitsugs && lang_with_dash_usage && mystrlen(p + 1) > 1 && mystrlen(candidate) - mystrlen(p) > 1) { *p = '-'; for (size_t k = 0; k < wlst.size(); ++k) { if (wlst[k] == candidate) { cwrd = 0; break; } } if ((wlst.size() < maxSug) && cwrd) wlst.push_back(candidate); } } } } } free(candidate); return good; } // error is adjacent letter were swapped int SuggestMgr::swapchar(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate(word); if (candidate.size() < 2) return wlst.size(); // try swapping adjacent chars one by one for (size_t i = 0; i < candidate.size() - 1; ++i) { std::swap(candidate[i], candidate[i+1]); testsug(wlst, candidate, cpdsuggest, NULL, NULL); std::swap(candidate[i], candidate[i+1]); } // try double swaps for short words // ahev -> have, owudl -> would if (candidate.size() == 4 || candidate.size() == 5) { candidate[0] = word[1]; candidate[1] = word[0]; candidate[2] = word[2]; candidate[candidate.size() - 2] = word[candidate.size() - 1]; candidate[candidate.size() - 1] = word[candidate.size() - 2]; testsug(wlst, candidate, cpdsuggest, NULL, NULL); if (candidate.size() == 5) { candidate[0] = word[0]; candidate[1] = word[2]; candidate[2] = word[1]; testsug(wlst, candidate, cpdsuggest, NULL, NULL); } } return wlst.size(); } // error is adjacent letter were swapped int SuggestMgr::swapchar_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::vector candidate_utf(word, word + wl); if (candidate_utf.size() < 2) return wlst.size(); std::string candidate; // try swapping adjacent chars one by one for (size_t i = 0; i < candidate_utf.size() - 1; ++i) { std::swap(candidate_utf[i], candidate_utf[i+1]); u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); std::swap(candidate_utf[i], candidate_utf[i+1]); } // try double swaps for short words // ahev -> have, owudl -> would, suodn -> sound if (candidate_utf.size() == 4 || candidate_utf.size() == 5) { candidate_utf[0] = word[1]; candidate_utf[1] = word[0]; candidate_utf[2] = word[2]; candidate_utf[candidate_utf.size() - 2] = word[candidate_utf.size() - 1]; candidate_utf[candidate_utf.size() - 1] = word[candidate_utf.size() - 2]; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); if (candidate_utf.size() == 5) { candidate_utf[0] = word[0]; candidate_utf[1] = word[2]; candidate_utf[2] = word[1]; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } } return wlst.size(); } // error is not adjacent letter were swapped int SuggestMgr::longswapchar(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate(word); // try swapping not adjacent chars one by one for (std::string::iterator p = candidate.begin(); p < candidate.end(); ++p) { for (std::string::iterator q = candidate.begin(); q < candidate.end(); ++q) { size_t distance = std::abs(std::distance(q, p)); if (distance > 1 && distance <= MAX_CHAR_DISTANCE) { std::swap(*p, *q); testsug(wlst, candidate, cpdsuggest, NULL, NULL); std::swap(*p, *q); } } } return wlst.size(); } // error is adjacent letter were swapped int SuggestMgr::longswapchar_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::vector candidate_utf(word, word + wl); // try swapping not adjacent chars for (std::vector::iterator p = candidate_utf.begin(); p < candidate_utf.end(); ++p) { for (std::vector::iterator q = candidate_utf.begin(); q < candidate_utf.end(); ++q) { size_t distance = std::abs(std::distance(q, p)); if (distance > 1 && distance <= MAX_CHAR_DISTANCE) { std::swap(*p, *q); std::string candidate; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); std::swap(*p, *q); } } } return wlst.size(); } // error is a letter was moved int SuggestMgr::movechar(std::vector& wlst, const char* word, int cpdsuggest) { std::string candidate(word); if (candidate.size() < 2) return wlst.size(); // try moving a char for (std::string::iterator p = candidate.begin(); p < candidate.end(); ++p) { for (std::string::iterator q = p + 1; q < candidate.end() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) { std::swap(*q, *(q - 1)); if (std::distance(p, q) < 2) continue; // omit swap char testsug(wlst, candidate, cpdsuggest, NULL, NULL); } std::copy(word, word + candidate.size(), candidate.begin()); } for (std::string::reverse_iterator p = candidate.rbegin(), pEnd = candidate.rend() - 1; p != pEnd; ++p) { for (std::string::reverse_iterator q = p + 1, qEnd = candidate.rend(); q != qEnd && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) { std::swap(*q, *(q - 1)); if (std::distance(p, q) < 2) continue; // omit swap char testsug(wlst, candidate, cpdsuggest, NULL, NULL); } std::copy(word, word + candidate.size(), candidate.begin()); } return wlst.size(); } // error is a letter was moved int SuggestMgr::movechar_utf(std::vector& wlst, const w_char* word, int wl, int cpdsuggest) { std::vector candidate_utf(word, word + wl); if (candidate_utf.size() < 2) return wlst.size(); // try moving a char for (std::vector::iterator p = candidate_utf.begin(); p < candidate_utf.end(); ++p) { for (std::vector::iterator q = p + 1; q < candidate_utf.end() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) { std::swap(*q, *(q - 1)); if (std::distance(p, q) < 2) continue; // omit swap char std::string candidate; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } std::copy(word, word + candidate_utf.size(), candidate_utf.begin()); } for (std::vector::reverse_iterator p = candidate_utf.rbegin(); p < candidate_utf.rend(); ++p) { for (std::vector::reverse_iterator q = p + 1; q < candidate_utf.rend() && std::distance(p, q) <= MAX_CHAR_DISTANCE; ++q) { std::swap(*q, *(q - 1)); if (std::distance(p, q) < 2) continue; // omit swap char std::string candidate; u16_u8(candidate, candidate_utf); testsug(wlst, candidate, cpdsuggest, NULL, NULL); } std::copy(word, word + candidate_utf.size(), candidate_utf.begin()); } return wlst.size(); } // generate a set of suggestions for very poorly spelled words void SuggestMgr::ngsuggest(std::vector& wlst, const char* w, const std::vector& rHMgr, int captype) { int lval; int sc; 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 (int 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; int low = NGRAM_LOWERING; std::string w2; const char* word = w; // word reversing wrapper for complex prefixes if (complexprefixes) { w2.assign(w); if (utf8) reverseword_utf(w2); else reverseword(w2); word = w2.c_str(); } std::vector u8; int nc = strlen(word); int n = (utf8) ? u8_u16(u8, word) : nc; // set character based ngram suggestion for words with non-BMP Unicode // characters if (n == -1) { utf8 = 0; // XXX not state-free n = nc; nonbmp = 1; low = 0; } struct hentry* hp = NULL; int col = -1; phonetable* ph = (pAMgr) ? pAMgr->get_phonetable() : NULL; std::string target; std::string candidate; std::vector w_candidate; if (ph) { if (utf8) { u8_u16(w_candidate, word); mkallcap_utf(w_candidate, langnum); u16_u8(candidate, w_candidate); } else { candidate.assign(word); if (!nonbmp) mkallcap(candidate, csconv); } target = phonet(candidate, *ph); // XXX phonet() is 8-bit (nc, not n) } FLAG forbiddenword = pAMgr ? pAMgr->get_forbiddenword() : FLAG_NULL; FLAG nosuggest = pAMgr ? pAMgr->get_nosuggest() : FLAG_NULL; FLAG nongramsuggest = pAMgr ? pAMgr->get_nongramsuggest() : FLAG_NULL; FLAG onlyincompound = pAMgr ? pAMgr->get_onlyincompound() : FLAG_NULL; std::vector w_word, w_target; if (utf8) { u8_u16(w_word, word); u8_u16(w_target, target); } std::string f; std::vector w_f; for (size_t i = 0; i < rHMgr.size(); ++i) { while (0 != (hp = rHMgr[i]->walk_hashtable(col, hp))) { // skip exceptions if ( // skip it, if the word length different by 5 or // more characters (to avoid strange suggestions) // (except Unicode characters over BMP) (((abs(n - hp->clen) > 4) && !nonbmp)) || // don't suggest capitalized dictionary words for // lower case misspellings in ngram suggestions, except // - PHONE usage, or // - in the case of German, where not only proper // nouns are capitalized, or // - the capitalized word has special pronunciation ((captype == NOCAP) && (hp->var & H_OPT_INITCAP) && !ph && (langnum != LANG_de) && !(hp->var & H_OPT_PHON)) || // or it has one of the following special flags ((hp->astr) && (pAMgr) && (TESTAFF(hp->astr, forbiddenword, hp->alen) || TESTAFF(hp->astr, ONLYUPCASEFLAG, hp->alen) || TESTAFF(hp->astr, nosuggest, hp->alen) || TESTAFF(hp->astr, nongramsuggest, hp->alen) || TESTAFF(hp->astr, onlyincompound, hp->alen))) ) continue; if (utf8) { u8_u16(w_f, HENTRY_WORD(hp)); int leftcommon = leftcommonsubstring(w_word, w_f); if (low) { // lowering dictionary word mkallsmall_utf(w_f, langnum); } sc = ngram(3, w_word, w_f, NGRAM_LONGER_WORSE) + leftcommon; } else { f.assign(HENTRY_WORD(hp)); int leftcommon = leftcommonsubstring(word, f.c_str()); if (low) { // lowering dictionary word mkallsmall(f, csconv); } sc = ngram(3, word, f, NGRAM_LONGER_WORSE) + leftcommon; } // check special pronunciation f.clear(); if ((hp->var & H_OPT_PHON) && copy_field(f, HENTRY_DATA(hp), MORPH_PHON)) { int sc2; if (utf8) { u8_u16(w_f, f); int leftcommon = leftcommonsubstring(w_word, w_f); if (low) { // lowering dictionary word mkallsmall_utf(w_f, langnum); } sc2 = ngram(3, w_word, w_f, NGRAM_LONGER_WORSE) + leftcommon; } else { int leftcommon = leftcommonsubstring(word, f.c_str()); if (low) { // lowering dictionary word mkallsmall(f, csconv); } sc2 = ngram(3, word, f, NGRAM_LONGER_WORSE) + leftcommon; } if (sc2 > sc) sc = sc2; } int scphon = -20000; if (ph && (sc > 2) && (abs(n - (int)hp->clen) <= 3)) { if (utf8) { u8_u16(w_candidate, HENTRY_WORD(hp)); mkallcap_utf(w_candidate, langnum); u16_u8(candidate, w_candidate); } else { candidate = HENTRY_WORD(hp); mkallcap(candidate, csconv); } f = phonet(candidate, *ph); if (utf8) { u8_u16(w_f, f); scphon = 2 * ngram(3, w_target, w_f, NGRAM_LONGER_WORSE); } else { scphon = 2 * ngram(3, target, f, NGRAM_LONGER_WORSE); } } if (sc > scores[lp]) { scores[lp] = sc; roots[lp] = hp; lval = sc; for (int 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 (int j = 0; j < MAX_ROOTS; j++) if (scoresphon[j] < lval) { lpphon = j; lval = scoresphon[j]; } } } } // find minimum threshold for a passable suggestion // mangle original word three differnt ways // and score them to generate a minimum acceptable score std::vector w_mw; int thresh = 0; for (int sp = 1; sp < 4; sp++) { if (utf8) { w_mw = w_word; for (int k = sp; k < n; k += 4) { w_mw[k].l = '*'; w_mw[k].h = 0; } if (low) { // lowering dictionary word mkallsmall_utf(w_mw, langnum); } thresh += ngram(n, w_word, w_mw, NGRAM_ANY_MISMATCH); } else { std::string mw = word; for (int k = sp; k < n; k += 4) mw[k] = '*'; if (low) { // lowering dictionary word mkallsmall(mw, csconv); } thresh += ngram(n, word, mw, NGRAM_ANY_MISMATCH); } } 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 (int i = 0; i < MAX_GUESS; i++) { guess[i] = NULL; guessorig[i] = NULL; gscore[i] = -100 * i; } lp = MAX_GUESS - 1; struct guessword* glst; glst = (struct guessword*)calloc(MAX_WORDS, sizeof(struct guessword)); if (!glst) { if (nonbmp) utf8 = 1; return; } for (int i = 0; i < MAX_ROOTS; i++) { if (roots[i]) { struct hentry* rp = roots[i]; f.clear(); const char *field = NULL; if ((rp->var & H_OPT_PHON) && copy_field(f, HENTRY_DATA(rp), MORPH_PHON)) field = f.c_str(); int nw = pAMgr->expand_rootword( glst, MAX_WORDS, HENTRY_WORD(rp), rp->blen, rp->astr, rp->alen, word, nc, field); for (int k = 0; k < nw; k++) { if (utf8) { u8_u16(w_f, glst[k].word); int leftcommon = leftcommonsubstring(w_word, w_f); if (low) { // lowering dictionary word mkallsmall_utf(w_f, langnum); } sc = ngram(n, w_word, w_f, NGRAM_ANY_MISMATCH) + leftcommon; } else { f = glst[k].word; int leftcommon = leftcommonsubstring(word, f.c_str()); if (low) { // lowering dictionary word mkallsmall(f, csconv); } sc = ngram(n, word, f, NGRAM_ANY_MISMATCH) + leftcommon; } 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 (int 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 = 0; int re = 0; double fact = 1.0; if (pAMgr) { int maxd = pAMgr->get_maxdiff(); if (maxd >= 0) fact = (10.0 - maxd) / 5.0; } std::vector w_gl; for (int i = 0; i < MAX_GUESS; i++) { if (guess[i]) { // lowering guess[i] std::string gl; int len; if (utf8) { len = u8_u16(w_gl, guess[i]); mkallsmall_utf(w_gl, langnum); u16_u8(gl, w_gl); } else { gl.assign(guess[i]); if (!nonbmp) mkallsmall(gl, csconv); len = strlen(guess[i]); } int _lcs = lcslen(word, gl.c_str()); // same characters with different casing if ((n == len) && (n == _lcs)) { gscore[i] += 2000; break; } // using 2-gram instead of 3, and other weightening if (utf8) { u8_u16(w_gl, gl); //w_gl is lowercase already at this point re = ngram(2, w_word, w_gl, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED); if (low) { w_f = w_word; // lowering dictionary word mkallsmall_utf(w_f, langnum); re += ngram(2, w_gl, w_f, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED); } else { re += ngram(2, w_gl, w_word, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED); } } else { //gl is lowercase already at this point re = ngram(2, word, gl, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED); if (low) { f = word; // lowering dictionary word mkallsmall(f, csconv); re += ngram(2, gl, f, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED); } else { re += ngram(2, gl, word, NGRAM_ANY_MISMATCH + NGRAM_WEIGHTED); } } int ngram_score, leftcommon_score; if (utf8) { //w_gl is lowercase already at this point ngram_score = ngram(4, w_word, w_gl, NGRAM_ANY_MISMATCH); leftcommon_score = leftcommonsubstring(w_word, w_gl); } else { //gl is lowercase already at this point ngram_score = ngram(4, word, gl, NGRAM_ANY_MISMATCH); leftcommon_score = leftcommonsubstring(word, gl.c_str()); } gscore[i] = // length of longest common subsequent minus length difference 2 * _lcs - abs((int)(n - len)) + // weight length of the left common substring leftcommon_score + // weight equal character positions (!nonbmp && commoncharacterpositions(word, gl.c_str(), &is_swap) ? 1 : 0) + // swap character (not neighboring) ((is_swap) ? 10 : 0) + // ngram ngram_score + // weighted ngrams re + // different limit for dictionaries with PHONE rules (ph ? (re < len * fact ? -1000 : 0) : (re < (n + len) * fact ? -1000 : 0)); } } bubblesort(&guess[0], &guessorig[0], &gscore[0], MAX_GUESS); // phonetic version if (ph) for (int i = 0; i < MAX_ROOTS; i++) { if (rootsphon[i]) { // lowering rootphon[i] std::string gl; int len; if (utf8) { len = u8_u16(w_gl, rootsphon[i]); mkallsmall_utf(w_gl, langnum); u16_u8(gl, w_gl); } else { gl.assign(rootsphon[i]); if (!nonbmp) mkallsmall(gl, csconv); len = strlen(rootsphon[i]); } // weight length of the left common substring int leftcommon_score; if (utf8) leftcommon_score = leftcommonsubstring(w_word, w_gl); else leftcommon_score = leftcommonsubstring(word, gl.c_str()); // heuristic weigthing of ngram scores scoresphon[i] += 2 * lcslen(word, gl) - abs((int)(n - len)) + leftcommon_score; } } if (ph) bubblesort(&rootsphon[0], NULL, &scoresphon[0], MAX_ROOTS); // copy over size_t oldns = wlst.size(); int same = 0; for (int i = 0; i < MAX_GUESS; i++) { if (guess[i]) { if ((wlst.size() < oldns + maxngramsugs) && (wlst.size() < maxSug) && (!same || (gscore[i] > 1000))) { int unique = 1; // leave only excellent suggestions, if exists if (gscore[i] > 1000) same = 1; else if (gscore[i] < -100) { same = 1; // keep the best ngram suggestions, unless in ONLYMAXDIFF mode if (wlst.size() > oldns || (pAMgr && pAMgr->get_onlymaxdiff())) { free(guess[i]); if (guessorig[i]) free(guessorig[i]); continue; } } for (size_t j = 0; j < wlst.size(); ++j) { // don't suggest previous suggestions or a previous suggestion with // prefixes or affixes if ((!guessorig[i] && strstr(guess[i], wlst[j].c_str())) || (guessorig[i] && strstr(guessorig[i], wlst[j].c_str())) || // check forbidden words !checkword(guess[i], 0, NULL, NULL)) { unique = 0; break; } } if (unique) { if (guessorig[i]) { wlst.push_back(guessorig[i]); } else { wlst.push_back(guess[i]); } } free(guess[i]); if (guessorig[i]) free(guessorig[i]); } else { free(guess[i]); if (guessorig[i]) free(guessorig[i]); } } } oldns = wlst.size(); if (ph) for (int i = 0; i < MAX_ROOTS; i++) { if (rootsphon[i]) { if ((wlst.size() < oldns + MAXPHONSUGS) && (wlst.size() < maxSug)) { int unique = 1; for (size_t j = 0; j < wlst.size(); ++j) { // don't suggest previous suggestions or a previous suggestion with // prefixes or affixes if (strstr(rootsphon[i], wlst[j].c_str()) || // check forbidden words !checkword(rootsphon[i], 0, NULL, NULL)) { unique = 0; break; } } if (unique) { wlst.push_back(rootsphon[i]); } } } } if (nonbmp) utf8 = 1; } // 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 std::string& word, int cpdsuggest, int* timer, clock_t* timelimit) { // check time limit if (timer) { (*timer)--; if (!(*timer) && timelimit) { if ((clock() - *timelimit) > TIMELIMIT) return 0; *timer = MAXPLUSTIMER; } } if (pAMgr) { struct hentry* rv = NULL; int nosuffix = 0; if (cpdsuggest == 1) { if (pAMgr->get_compound()) { struct hentry* rv2 = NULL; struct hentry* rwords[100]; // buffer for COMPOUND pattern checking rv = pAMgr->compound_check(word, 0, 0, 100, 0, NULL, (hentry**)&rwords, 0, 1, 0); // EXT if (rv && (!(rv2 = pAMgr->lookup(word.c_str())) || !rv2->astr || !(TESTAFF(rv2->astr, pAMgr->get_forbiddenword(), rv2->alen) || TESTAFF(rv2->astr, pAMgr->get_nosuggest(), rv2->alen)))) return 3; // XXX obsolote categorisation + only ICONV needs affix // flag check? } return 0; } rv = pAMgr->lookup(word.c_str()); if (rv) { if ((rv->astr) && (TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen) || TESTAFF(rv->astr, pAMgr->get_nosuggest(), rv->alen) || TESTAFF(rv->astr, pAMgr->get_substandard(), 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.c_str(), word.size(), 0); // only prefix, and prefix + suffix XXX if (rv) { nosuffix = 1; } else { rv = pAMgr->suffix_check(word.c_str(), word.size(), 0, NULL, FLAG_NULL, FLAG_NULL, IN_CPD_NOT); // only suffix } if (!rv && pAMgr->have_contclass()) { rv = pAMgr->suffix_check_twosfx(word.c_str(), word.size(), 0, NULL, FLAG_NULL); if (!rv) rv = pAMgr->prefix_check_twosfx(word.c_str(), word.size(), 0, 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) { if (pAMgr) { struct hentry* 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, FLAG_NULL, FLAG_NULL, IN_CPD_NOT); // prefix+suffix, suffix // check forbidden words if ((rv) && (rv->astr) && TESTAFF(rv->astr, pAMgr->get_forbiddenword(), rv->alen)) return 1; } return 0; } std::string SuggestMgr::suggest_morph(const std::string& in_w) { std::string result; struct hentry* rv = NULL; if (!pAMgr) return std::string(); std::string w(in_w); // word reversing wrapper for complex prefixes if (complexprefixes) { if (utf8) reverseword_utf(w); else reverseword(w); } rv = pAMgr->lookup(w.c_str()); 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)) { result.push_back(MSEP_FLD); result.append(MORPH_STEM); result.append(w); } if (HENTRY_DATA(rv)) { result.push_back(MSEP_FLD); result.append(HENTRY_DATA2(rv)); } result.push_back(MSEP_REC); } rv = rv->next_homonym; } std::string st = pAMgr->affix_check_morph(w.c_str(), w.size()); if (!st.empty()) { result.append(st); } if (pAMgr->get_compound() && result.empty()) { struct hentry* rwords[100]; // buffer for COMPOUND pattern checking pAMgr->compound_check_morph(w.c_str(), w.size(), 0, 0, 100, 0, NULL, (hentry**)&rwords, 0, result, NULL); } line_uniq(result, MSEP_REC); return result; } static int get_sfxcount(const char* morph) { if (!morph || !*morph) return 0; int n = 0; const char* old = morph; morph = strstr(morph, MORPH_DERI_SFX); if (!morph) morph = strstr(old, MORPH_INFL_SFX); if (!morph) morph = strstr(old, MORPH_TERM_SFX); while (morph) { n++; old = morph; morph = strstr(morph + 1, MORPH_DERI_SFX); if (!morph) morph = strstr(old + 1, MORPH_INFL_SFX); if (!morph) morph = strstr(old + 1, MORPH_TERM_SFX); } return n; } /* affixation */ std::string SuggestMgr::suggest_hentry_gen(hentry* rv, const char* pattern) { std::string result; int sfxcount = get_sfxcount(pattern); if (get_sfxcount(HENTRY_DATA(rv)) > sfxcount) return result; if (HENTRY_DATA(rv)) { std::string aff = pAMgr->morphgen(HENTRY_WORD(rv), rv->blen, rv->astr, rv->alen, HENTRY_DATA(rv), pattern, 0); if (!aff.empty()) { result.append(aff); result.push_back(MSEP_REC); } } // check all allomorphs char* p = NULL; if (HENTRY_DATA(rv)) p = (char*)strstr(HENTRY_DATA2(rv), MORPH_ALLOMORPH); while (p) { p += MORPH_TAG_LEN; int plen = fieldlen(p); std::string allomorph(p, plen); struct hentry* rv2 = pAMgr->lookup(allomorph.c_str()); 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)) { std::string aff = pAMgr->morphgen(HENTRY_WORD(rv2), rv2->blen, rv2->astr, rv2->alen, HENTRY_DATA(rv2), pattern, 0); if (!aff.empty()) { result.append(aff); result.push_back(MSEP_REC); } } } rv2 = rv2->next_homonym; } p = strstr(p + plen, MORPH_ALLOMORPH); } return result; } std::string SuggestMgr::suggest_gen(const std::vector& desc, const std::string& in_pattern) { if (desc.empty() || !pAMgr) return std::string(); const char* pattern = in_pattern.c_str(); std::string result2; std::string newpattern; struct hentry* rv = NULL; // search affixed forms with and without derivational suffixes while (1) { for (size_t k = 0; k < desc.size(); ++k) { std::string result; // add compound word parts (except the last one) const char* s = desc[k].c_str(); const char* part = strstr(s, MORPH_PART); if (part) { const char* nextpart = strstr(part + 1, MORPH_PART); while (nextpart) { std::string field; copy_field(field, part, MORPH_PART); result.append(field); part = nextpart; nextpart = strstr(part + 1, MORPH_PART); } s = part; } std::string tok(s); size_t pos = tok.find(" | "); while (pos != std::string::npos) { tok[pos + 1] = MSEP_ALT; pos = tok.find(" | ", pos); } std::vector pl = line_tok(tok, MSEP_ALT); for (size_t i = 0; i < pl.size(); ++i) { // remove inflectional and terminal suffixes size_t is = pl[i].find(MORPH_INFL_SFX); if (is != std::string::npos) pl[i].resize(is); size_t ts = pl[i].find(MORPH_TERM_SFX); while (ts != std::string::npos) { pl[i][ts] = '_'; ts = pl[i].find(MORPH_TERM_SFX); } const char* st = strstr(s, MORPH_STEM); if (st) { copy_field(tok, st, MORPH_STEM); rv = pAMgr->lookup(tok.c_str()); while (rv) { std::string newpat(pl[i]); newpat.append(pattern); std::string sg = suggest_hentry_gen(rv, newpat.c_str()); if (sg.empty()) sg = suggest_hentry_gen(rv, pattern); if (!sg.empty()) { std::vector gen = line_tok(sg, MSEP_REC); for (size_t j = 0; j < gen.size(); ++j) { result2.push_back(MSEP_REC); result2.append(result); if (pl[i].find(MORPH_SURF_PFX) != std::string::npos) { std::string field; copy_field(field, pl[i], MORPH_SURF_PFX); result2.append(field); } result2.append(gen[j]); } } rv = rv->next_homonym; } } } } if (!result2.empty() || !strstr(pattern, MORPH_DERI_SFX)) break; newpattern.assign(pattern); mystrrep(newpattern, MORPH_DERI_SFX, MORPH_TERM_SFX); pattern = newpattern.c_str(); } return result2; } // generate an n-gram score comparing s1 and s2, UTF16 version int SuggestMgr::ngram(int n, const std::vector& su1, const std::vector& su2, int opt) { int nscore = 0; int ns; int l1; int l2; int test = 0; l1 = su1.size(); l2 = su2.size(); if (l2 == 0) return 0; for (int j = 1; j <= n; j++) { ns = 0; for (int i = 0; i <= (l1 - j); i++) { int k = 0; for (int l = 0; l <= (l2 - j); l++) { for (k = 0; k < j; k++) { const w_char& c1 = su1[i + k]; const w_char& c2 = su2[l + k]; if ((c1.l != c2.l) || (c1.h != c2.h)) break; } if (k == j) { ns++; break; } } if (k != j && opt & NGRAM_WEIGHTED) { ns--; test++; if (i == 0 || i == l1 - j) ns--; // side weight } } nscore = nscore + ns; if (ns < 2 && !(opt & NGRAM_WEIGHTED)) 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; } // generate an n-gram score comparing s1 and s2, non-UTF16 version int SuggestMgr::ngram(int n, const std::string& s1, const std::string& s2, int opt) { int nscore = 0; int ns; int l1; int l2; int test = 0; l2 = s2.size(); if (l2 == 0) return 0; l1 = s1.size(); for (int j = 1; j <= n; j++) { ns = 0; for (int i = 0; i <= (l1 - j); i++) { //s2 is haystack, s1[i..i+j) is needle if (s2.find(s1.c_str()+i, 0, j) != std::string::npos) { ns++; } else if (opt & NGRAM_WEIGHTED) { ns--; test++; if (i == 0 || i == l1 - j) ns--; // side weight } } nscore = nscore + ns; if (ns < 2 && !(opt & NGRAM_WEIGHTED)) 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, UTF version int SuggestMgr::leftcommonsubstring( const std::vector& su1, const std::vector& su2) { int l1 = su1.size(); int l2 = su2.size(); // decapitalize dictionary word if (complexprefixes) { if (su1[l1 - 1] == su2[l2 - 1]) return 1; } else { unsigned short idx = su2.empty() ? 0 : (su2[0].h << 8) + su2[0].l; unsigned short otheridx = su1.empty() ? 0 : (su1[0].h << 8) + su1[0].l; if (otheridx != idx && (otheridx != unicodetolower(idx, langnum))) return 0; int i; for (i = 1; (i < l1) && (i < l2) && (su1[i].l == su2[i].l) && (su1[i].h == su2[i].h); i++) ; return i; } return 0; } // length of the left common substring of s1 and (decapitalised) s2, non-UTF int SuggestMgr::leftcommonsubstring( const char* s1, const char* s2) { if (complexprefixes) { int l1 = strlen(s1); int l2 = strlen(s2); if (l1 <= l2 && s2[l1 - 1] == s2[l2 - 1]) return 1; } else if (csconv) { const 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 (int)(s1 - olds); } return 0; } int SuggestMgr::commoncharacterpositions(const char* s1, const char* s2, int* is_swap) { int num = 0; int diff = 0; int diffpos[2]; *is_swap = 0; if (utf8) { std::vector su1; std::vector su2; int l1 = u8_u16(su1, s1); int l2 = u8_u16(su2, s2); if (l1 <= 0 || l2 <= 0) return 0; // decapitalize dictionary word if (complexprefixes) { su2[l2 - 1] = lower_utf(su2[l2 - 1], langnum); } else { su2[0] = lower_utf(su2[0], langnum); } for (int i = 0; (i < l1) && (i < l2); i++) { if (su1[i] == su2[i]) { num++; } else { if (diff < 2) diffpos[diff] = i; diff++; } } if ((diff == 2) && (l1 == l2) && (su1[diffpos[0]] == su2[diffpos[1]]) && (su1[diffpos[1]] == su2[diffpos[0]])) *is_swap = 1; } else { size_t i; std::string t(s2); // decapitalize dictionary word if (complexprefixes) { size_t l2 = t.size(); t[l2 - 1] = csconv[(unsigned char)t[l2 - 1]].clower; } else { mkallsmall(t, csconv); } for (i = 0; i < t.size() && (*(s1 + i) != 0); ++i) { if (*(s1 + i) == t[i]) { num++; } else { if (diff < 2) diffpos[diff] = i; diff++; } } if ((diff == 2) && (*(s1 + i) == 0) && i == t.size() && (*(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) { std::vector w; return u8_u16(w, 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; std::vector su; std::vector su2; char* b; char* c; int i; int j; if (utf8) { m = u8_u16(su, s); n = u8_u16(su2, 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) && (su[i - 1] == 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; } int SuggestMgr::lcslen(const std::string& s, const std::string& s2) { return lcslen(s.c_str(), s2.c_str()); } hunspell-1.7.0/src/hunspell/suggestmgr.hxx000066400000000000000000000171001337236234000207140ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* * 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. */ #ifndef SUGGESTMGR_HXX_ #define SUGGESTMGR_HXX_ #define MAX_ROOTS 100 #define MAX_WORDS 100 #define MAX_GUESS 200 #define MAXNGRAMSUGS 4 #define MAXPHONSUGS 2 #define MAXCOMPOUNDSUGS 3 #define NGRAM_LONGER_WORSE (1 << 0) #define NGRAM_ANY_MISMATCH (1 << 1) #define NGRAM_LOWERING (1 << 2) #define NGRAM_WEIGHTED (1 << 3) #include "atypes.hxx" #include "affixmgr.hxx" #include "hashmgr.hxx" #include "langnum.hxx" enum { LCS_UP, LCS_LEFT, LCS_UPLEFT }; class SuggestMgr { private: SuggestMgr(const SuggestMgr&); SuggestMgr& operator=(const SuggestMgr&); private: char* ckey; size_t ckeyl; std::vector ckey_utf; char* ctry; size_t ctryl; std::vector ctry_utf; bool lang_with_dash_usage; AffixMgr* pAMgr; unsigned int maxSug; struct cs_info* csconv; int utf8; int langnum; int nosplitsugs; int maxngramsugs; int maxcpdsugs; int complexprefixes; public: SuggestMgr(const char* tryme, unsigned int maxn, AffixMgr* aptr); ~SuggestMgr(); bool suggest(std::vector& slst, const char* word, int* onlycmpdsug); void ngsuggest(std::vector& slst, const char* word, const std::vector& rHMgr, int captype); std::string suggest_morph(const std::string& word); std::string suggest_gen(const std::vector& pl, const std::string& pattern); private: void testsug(std::vector& wlst, const std::string& candidate, int cpdsuggest, int* timer, clock_t* timelimit); int checkword(const std::string& word, int, int*, clock_t*); int check_forbidden(const char*, int); void capchars(std::vector&, const char*, int); int replchars(std::vector&, const char*, int); int doubletwochars(std::vector&, const char*, int); int forgotchar(std::vector&, const char*, int); int swapchar(std::vector&, const char*, int); int longswapchar(std::vector&, const char*, int); int movechar(std::vector&, const char*, int); int extrachar(std::vector&, const char*, int); int badcharkey(std::vector&, const char*, int); int badchar(std::vector&, const char*, int); bool twowords(std::vector&, const char*, int, bool); void capchars_utf(std::vector&, const w_char*, int wl, int); int doubletwochars_utf(std::vector&, const w_char*, int wl, int); int forgotchar_utf(std::vector&, const w_char*, int wl, int); int extrachar_utf(std::vector&, const w_char*, int wl, int); int badcharkey_utf(std::vector&, const w_char*, int wl, int); int badchar_utf(std::vector&, const w_char*, int wl, int); int swapchar_utf(std::vector&, const w_char*, int wl, int); int longswapchar_utf(std::vector&, const w_char*, int, int); int movechar_utf(std::vector&, const w_char*, int, int); int mapchars(std::vector&, const char*, int); int map_related(const char*, std::string&, int, std::vector& wlst, int, const std::vector&, int*, clock_t*); int ngram(int n, const std::vector& su1, const std::vector& su2, int opt); int ngram(int n, const std::string& s1, const std::string& s2, int opt); int mystrlen(const char* word); int leftcommonsubstring(const std::vector& su1, const std::vector& su2); int leftcommonsubstring(const char* s1, const char* s2); int commoncharacterpositions(const 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); int lcslen(const std::string& s, const std::string& s2); std::string suggest_hentry_gen(hentry* rv, const char* pattern); }; #endif hunspell-1.7.0/src/hunspell/utf_info.hxx000066400000000000000000020677771337236234000203710ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ // Unicode character encoding information struct unicode_info { unsigned short c; unsigned short cupper; unsigned short clower; }; /* fields: Unicode letter, toupper, tolower */ static const 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}, {0xAC01, 0xAC01, 0xAC01}, {0xAC02, 0xAC02, 0xAC02}, {0xAC03, 0xAC03, 0xAC03}, {0xAC04, 0xAC04, 0xAC04}, {0xAC05, 0xAC05, 0xAC05}, {0xAC06, 0xAC06, 0xAC06}, {0xAC07, 0xAC07, 0xAC07}, {0xAC08, 0xAC08, 0xAC08}, {0xAC09, 0xAC09, 0xAC09}, {0xAC0A, 0xAC0A, 0xAC0A}, {0xAC0B, 0xAC0B, 0xAC0B}, {0xAC0C, 0xAC0C, 0xAC0C}, {0xAC0D, 0xAC0D, 0xAC0D}, {0xAC0E, 0xAC0E, 0xAC0E}, {0xAC0F, 0xAC0F, 0xAC0F}, {0xAC10, 0xAC10, 0xAC10}, {0xAC11, 0xAC11, 0xAC11}, {0xAC12, 0xAC12, 0xAC12}, {0xAC13, 0xAC13, 0xAC13}, {0xAC14, 0xAC14, 0xAC14}, {0xAC15, 0xAC15, 0xAC15}, {0xAC16, 0xAC16, 0xAC16}, {0xAC17, 0xAC17, 0xAC17}, {0xAC18, 0xAC18, 0xAC18}, {0xAC19, 0xAC19, 0xAC19}, {0xAC1A, 0xAC1A, 0xAC1A}, {0xAC1B, 0xAC1B, 0xAC1B}, {0xAC1C, 0xAC1C, 0xAC1C}, {0xAC1D, 0xAC1D, 0xAC1D}, {0xAC1E, 0xAC1E, 0xAC1E}, {0xAC1F, 0xAC1F, 0xAC1F}, {0xAC20, 0xAC20, 0xAC20}, {0xAC21, 0xAC21, 0xAC21}, {0xAC22, 0xAC22, 0xAC22}, {0xAC23, 0xAC23, 0xAC23}, {0xAC24, 0xAC24, 0xAC24}, {0xAC25, 0xAC25, 0xAC25}, {0xAC26, 0xAC26, 0xAC26}, {0xAC27, 0xAC27, 0xAC27}, {0xAC28, 0xAC28, 0xAC28}, {0xAC29, 0xAC29, 0xAC29}, {0xAC2A, 0xAC2A, 0xAC2A}, {0xAC2B, 0xAC2B, 0xAC2B}, {0xAC2C, 0xAC2C, 0xAC2C}, {0xAC2D, 0xAC2D, 0xAC2D}, {0xAC2E, 0xAC2E, 0xAC2E}, {0xAC2F, 0xAC2F, 0xAC2F}, {0xAC30, 0xAC30, 0xAC30}, {0xAC31, 0xAC31, 0xAC31}, {0xAC32, 0xAC32, 0xAC32}, {0xAC33, 0xAC33, 0xAC33}, {0xAC34, 0xAC34, 0xAC34}, {0xAC35, 0xAC35, 0xAC35}, {0xAC36, 0xAC36, 0xAC36}, {0xAC37, 0xAC37, 0xAC37}, {0xAC38, 0xAC38, 0xAC38}, {0xAC39, 0xAC39, 0xAC39}, {0xAC3A, 0xAC3A, 0xAC3A}, {0xAC3B, 0xAC3B, 0xAC3B}, {0xAC3C, 0xAC3C, 0xAC3C}, {0xAC3D, 0xAC3D, 0xAC3D}, {0xAC3E, 0xAC3E, 0xAC3E}, {0xAC3F, 0xAC3F, 0xAC3F}, {0xAC40, 0xAC40, 0xAC40}, {0xAC41, 0xAC41, 0xAC41}, {0xAC42, 0xAC42, 0xAC42}, {0xAC43, 0xAC43, 0xAC43}, {0xAC44, 0xAC44, 0xAC44}, {0xAC45, 0xAC45, 0xAC45}, {0xAC46, 0xAC46, 0xAC46}, {0xAC47, 0xAC47, 0xAC47}, {0xAC48, 0xAC48, 0xAC48}, {0xAC49, 0xAC49, 0xAC49}, {0xAC4A, 0xAC4A, 0xAC4A}, {0xAC4B, 0xAC4B, 0xAC4B}, {0xAC4C, 0xAC4C, 0xAC4C}, {0xAC4D, 0xAC4D, 0xAC4D}, {0xAC4E, 0xAC4E, 0xAC4E}, {0xAC4F, 0xAC4F, 0xAC4F}, {0xAC50, 0xAC50, 0xAC50}, {0xAC51, 0xAC51, 0xAC51}, {0xAC52, 0xAC52, 0xAC52}, {0xAC53, 0xAC53, 0xAC53}, {0xAC54, 0xAC54, 0xAC54}, {0xAC55, 0xAC55, 0xAC55}, {0xAC56, 0xAC56, 0xAC56}, {0xAC57, 0xAC57, 0xAC57}, {0xAC58, 0xAC58, 0xAC58}, {0xAC59, 0xAC59, 0xAC59}, {0xAC5A, 0xAC5A, 0xAC5A}, {0xAC5B, 0xAC5B, 0xAC5B}, {0xAC5C, 0xAC5C, 0xAC5C}, {0xAC5D, 0xAC5D, 0xAC5D}, {0xAC5E, 0xAC5E, 0xAC5E}, {0xAC5F, 0xAC5F, 0xAC5F}, {0xAC60, 0xAC60, 0xAC60}, {0xAC61, 0xAC61, 0xAC61}, {0xAC62, 0xAC62, 0xAC62}, {0xAC63, 0xAC63, 0xAC63}, {0xAC64, 0xAC64, 0xAC64}, {0xAC65, 0xAC65, 0xAC65}, {0xAC66, 0xAC66, 0xAC66}, {0xAC67, 0xAC67, 0xAC67}, {0xAC68, 0xAC68, 0xAC68}, {0xAC69, 0xAC69, 0xAC69}, {0xAC6A, 0xAC6A, 0xAC6A}, {0xAC6B, 0xAC6B, 0xAC6B}, {0xAC6C, 0xAC6C, 0xAC6C}, {0xAC6D, 0xAC6D, 0xAC6D}, {0xAC6E, 0xAC6E, 0xAC6E}, {0xAC6F, 0xAC6F, 0xAC6F}, {0xAC70, 0xAC70, 0xAC70}, {0xAC71, 0xAC71, 0xAC71}, {0xAC72, 0xAC72, 0xAC72}, {0xAC73, 0xAC73, 0xAC73}, {0xAC74, 0xAC74, 0xAC74}, {0xAC75, 0xAC75, 0xAC75}, {0xAC76, 0xAC76, 0xAC76}, {0xAC77, 0xAC77, 0xAC77}, {0xAC78, 0xAC78, 0xAC78}, {0xAC79, 0xAC79, 0xAC79}, {0xAC7A, 0xAC7A, 0xAC7A}, {0xAC7B, 0xAC7B, 0xAC7B}, {0xAC7C, 0xAC7C, 0xAC7C}, {0xAC7D, 0xAC7D, 0xAC7D}, {0xAC7E, 0xAC7E, 0xAC7E}, {0xAC7F, 0xAC7F, 0xAC7F}, {0xAC80, 0xAC80, 0xAC80}, {0xAC81, 0xAC81, 0xAC81}, {0xAC82, 0xAC82, 0xAC82}, {0xAC83, 0xAC83, 0xAC83}, {0xAC84, 0xAC84, 0xAC84}, {0xAC85, 0xAC85, 0xAC85}, {0xAC86, 0xAC86, 0xAC86}, {0xAC87, 0xAC87, 0xAC87}, {0xAC88, 0xAC88, 0xAC88}, {0xAC89, 0xAC89, 0xAC89}, {0xAC8A, 0xAC8A, 0xAC8A}, {0xAC8B, 0xAC8B, 0xAC8B}, {0xAC8C, 0xAC8C, 0xAC8C}, {0xAC8D, 0xAC8D, 0xAC8D}, {0xAC8E, 0xAC8E, 0xAC8E}, {0xAC8F, 0xAC8F, 0xAC8F}, {0xAC90, 0xAC90, 0xAC90}, {0xAC91, 0xAC91, 0xAC91}, {0xAC92, 0xAC92, 0xAC92}, {0xAC93, 0xAC93, 0xAC93}, {0xAC94, 0xAC94, 0xAC94}, {0xAC95, 0xAC95, 0xAC95}, {0xAC96, 0xAC96, 0xAC96}, {0xAC97, 0xAC97, 0xAC97}, {0xAC98, 0xAC98, 0xAC98}, {0xAC99, 0xAC99, 0xAC99}, {0xAC9A, 0xAC9A, 0xAC9A}, {0xAC9B, 0xAC9B, 0xAC9B}, {0xAC9C, 0xAC9C, 0xAC9C}, {0xAC9D, 0xAC9D, 0xAC9D}, {0xAC9E, 0xAC9E, 0xAC9E}, {0xAC9F, 0xAC9F, 0xAC9F}, {0xACA0, 0xACA0, 0xACA0}, {0xACA1, 0xACA1, 0xACA1}, {0xACA2, 0xACA2, 0xACA2}, {0xACA3, 0xACA3, 0xACA3}, {0xACA4, 0xACA4, 0xACA4}, {0xACA5, 0xACA5, 0xACA5}, {0xACA6, 0xACA6, 0xACA6}, {0xACA7, 0xACA7, 0xACA7}, {0xACA8, 0xACA8, 0xACA8}, {0xACA9, 0xACA9, 0xACA9}, {0xACAA, 0xACAA, 0xACAA}, {0xACAB, 0xACAB, 0xACAB}, {0xACAC, 0xACAC, 0xACAC}, {0xACAD, 0xACAD, 0xACAD}, {0xACAE, 0xACAE, 0xACAE}, {0xACAF, 0xACAF, 0xACAF}, {0xACB0, 0xACB0, 0xACB0}, {0xACB1, 0xACB1, 0xACB1}, {0xACB2, 0xACB2, 0xACB2}, {0xACB3, 0xACB3, 0xACB3}, {0xACB4, 0xACB4, 0xACB4}, {0xACB5, 0xACB5, 0xACB5}, {0xACB6, 0xACB6, 0xACB6}, {0xACB7, 0xACB7, 0xACB7}, {0xACB8, 0xACB8, 0xACB8}, {0xACB9, 0xACB9, 0xACB9}, {0xACBA, 0xACBA, 0xACBA}, {0xACBB, 0xACBB, 0xACBB}, {0xACBC, 0xACBC, 0xACBC}, {0xACBD, 0xACBD, 0xACBD}, {0xACBE, 0xACBE, 0xACBE}, {0xACBF, 0xACBF, 0xACBF}, {0xACC0, 0xACC0, 0xACC0}, {0xACC1, 0xACC1, 0xACC1}, {0xACC2, 0xACC2, 0xACC2}, {0xACC3, 0xACC3, 0xACC3}, {0xACC4, 0xACC4, 0xACC4}, {0xACC5, 0xACC5, 0xACC5}, {0xACC6, 0xACC6, 0xACC6}, {0xACC7, 0xACC7, 0xACC7}, {0xACC8, 0xACC8, 0xACC8}, {0xACC9, 0xACC9, 0xACC9}, {0xACCA, 0xACCA, 0xACCA}, {0xACCB, 0xACCB, 0xACCB}, {0xACCC, 0xACCC, 0xACCC}, {0xACCD, 0xACCD, 0xACCD}, {0xACCE, 0xACCE, 0xACCE}, {0xACCF, 0xACCF, 0xACCF}, {0xACD0, 0xACD0, 0xACD0}, {0xACD1, 0xACD1, 0xACD1}, {0xACD2, 0xACD2, 0xACD2}, {0xACD3, 0xACD3, 0xACD3}, {0xACD4, 0xACD4, 0xACD4}, {0xACD5, 0xACD5, 0xACD5}, {0xACD6, 0xACD6, 0xACD6}, {0xACD7, 0xACD7, 0xACD7}, {0xACD8, 0xACD8, 0xACD8}, {0xACD9, 0xACD9, 0xACD9}, {0xACDA, 0xACDA, 0xACDA}, {0xACDB, 0xACDB, 0xACDB}, {0xACDC, 0xACDC, 0xACDC}, {0xACDD, 0xACDD, 0xACDD}, {0xACDE, 0xACDE, 0xACDE}, {0xACDF, 0xACDF, 0xACDF}, {0xACE0, 0xACE0, 0xACE0}, {0xACE1, 0xACE1, 0xACE1}, {0xACE2, 0xACE2, 0xACE2}, {0xACE3, 0xACE3, 0xACE3}, {0xACE4, 0xACE4, 0xACE4}, {0xACE5, 0xACE5, 0xACE5}, {0xACE6, 0xACE6, 0xACE6}, {0xACE7, 0xACE7, 0xACE7}, {0xACE8, 0xACE8, 0xACE8}, {0xACE9, 0xACE9, 0xACE9}, {0xACEA, 0xACEA, 0xACEA}, {0xACEB, 0xACEB, 0xACEB}, {0xACEC, 0xACEC, 0xACEC}, {0xACED, 0xACED, 0xACED}, {0xACEE, 0xACEE, 0xACEE}, {0xACEF, 0xACEF, 0xACEF}, {0xACF0, 0xACF0, 0xACF0}, {0xACF1, 0xACF1, 0xACF1}, {0xACF2, 0xACF2, 0xACF2}, {0xACF3, 0xACF3, 0xACF3}, {0xACF4, 0xACF4, 0xACF4}, {0xACF5, 0xACF5, 0xACF5}, {0xACF6, 0xACF6, 0xACF6}, {0xACF7, 0xACF7, 0xACF7}, {0xACF8, 0xACF8, 0xACF8}, {0xACF9, 0xACF9, 0xACF9}, {0xACFA, 0xACFA, 0xACFA}, {0xACFB, 0xACFB, 0xACFB}, {0xACFC, 0xACFC, 0xACFC}, {0xACFD, 0xACFD, 0xACFD}, {0xACFE, 0xACFE, 0xACFE}, {0xACFF, 0xACFF, 0xACFF}, {0xAD00, 0xAD00, 0xAD00}, {0xAD01, 0xAD01, 0xAD01}, {0xAD02, 0xAD02, 0xAD02}, {0xAD03, 0xAD03, 0xAD03}, {0xAD04, 0xAD04, 0xAD04}, {0xAD05, 0xAD05, 0xAD05}, {0xAD06, 0xAD06, 0xAD06}, {0xAD07, 0xAD07, 0xAD07}, {0xAD08, 0xAD08, 0xAD08}, {0xAD09, 0xAD09, 0xAD09}, {0xAD0A, 0xAD0A, 0xAD0A}, {0xAD0B, 0xAD0B, 0xAD0B}, {0xAD0C, 0xAD0C, 0xAD0C}, {0xAD0D, 0xAD0D, 0xAD0D}, {0xAD0E, 0xAD0E, 0xAD0E}, {0xAD0F, 0xAD0F, 0xAD0F}, {0xAD10, 0xAD10, 0xAD10}, {0xAD11, 0xAD11, 0xAD11}, {0xAD12, 0xAD12, 0xAD12}, {0xAD13, 0xAD13, 0xAD13}, {0xAD14, 0xAD14, 0xAD14}, {0xAD15, 0xAD15, 0xAD15}, {0xAD16, 0xAD16, 0xAD16}, {0xAD17, 0xAD17, 0xAD17}, {0xAD18, 0xAD18, 0xAD18}, {0xAD19, 0xAD19, 0xAD19}, {0xAD1A, 0xAD1A, 0xAD1A}, {0xAD1B, 0xAD1B, 0xAD1B}, {0xAD1C, 0xAD1C, 0xAD1C}, {0xAD1D, 0xAD1D, 0xAD1D}, {0xAD1E, 0xAD1E, 0xAD1E}, {0xAD1F, 0xAD1F, 0xAD1F}, {0xAD20, 0xAD20, 0xAD20}, {0xAD21, 0xAD21, 0xAD21}, {0xAD22, 0xAD22, 0xAD22}, {0xAD23, 0xAD23, 0xAD23}, {0xAD24, 0xAD24, 0xAD24}, {0xAD25, 0xAD25, 0xAD25}, {0xAD26, 0xAD26, 0xAD26}, {0xAD27, 0xAD27, 0xAD27}, {0xAD28, 0xAD28, 0xAD28}, {0xAD29, 0xAD29, 0xAD29}, {0xAD2A, 0xAD2A, 0xAD2A}, {0xAD2B, 0xAD2B, 0xAD2B}, {0xAD2C, 0xAD2C, 0xAD2C}, {0xAD2D, 0xAD2D, 0xAD2D}, {0xAD2E, 0xAD2E, 0xAD2E}, {0xAD2F, 0xAD2F, 0xAD2F}, {0xAD30, 0xAD30, 0xAD30}, {0xAD31, 0xAD31, 0xAD31}, {0xAD32, 0xAD32, 0xAD32}, {0xAD33, 0xAD33, 0xAD33}, {0xAD34, 0xAD34, 0xAD34}, {0xAD35, 0xAD35, 0xAD35}, {0xAD36, 0xAD36, 0xAD36}, {0xAD37, 0xAD37, 0xAD37}, {0xAD38, 0xAD38, 0xAD38}, {0xAD39, 0xAD39, 0xAD39}, {0xAD3A, 0xAD3A, 0xAD3A}, {0xAD3B, 0xAD3B, 0xAD3B}, {0xAD3C, 0xAD3C, 0xAD3C}, {0xAD3D, 0xAD3D, 0xAD3D}, {0xAD3E, 0xAD3E, 0xAD3E}, {0xAD3F, 0xAD3F, 0xAD3F}, {0xAD40, 0xAD40, 0xAD40}, {0xAD41, 0xAD41, 0xAD41}, {0xAD42, 0xAD42, 0xAD42}, {0xAD43, 0xAD43, 0xAD43}, {0xAD44, 0xAD44, 0xAD44}, {0xAD45, 0xAD45, 0xAD45}, {0xAD46, 0xAD46, 0xAD46}, {0xAD47, 0xAD47, 0xAD47}, {0xAD48, 0xAD48, 0xAD48}, {0xAD49, 0xAD49, 0xAD49}, {0xAD4A, 0xAD4A, 0xAD4A}, {0xAD4B, 0xAD4B, 0xAD4B}, {0xAD4C, 0xAD4C, 0xAD4C}, {0xAD4D, 0xAD4D, 0xAD4D}, {0xAD4E, 0xAD4E, 0xAD4E}, {0xAD4F, 0xAD4F, 0xAD4F}, {0xAD50, 0xAD50, 0xAD50}, {0xAD51, 0xAD51, 0xAD51}, {0xAD52, 0xAD52, 0xAD52}, {0xAD53, 0xAD53, 0xAD53}, {0xAD54, 0xAD54, 0xAD54}, {0xAD55, 0xAD55, 0xAD55}, {0xAD56, 0xAD56, 0xAD56}, {0xAD57, 0xAD57, 0xAD57}, {0xAD58, 0xAD58, 0xAD58}, {0xAD59, 0xAD59, 0xAD59}, {0xAD5A, 0xAD5A, 0xAD5A}, {0xAD5B, 0xAD5B, 0xAD5B}, {0xAD5C, 0xAD5C, 0xAD5C}, {0xAD5D, 0xAD5D, 0xAD5D}, {0xAD5E, 0xAD5E, 0xAD5E}, {0xAD5F, 0xAD5F, 0xAD5F}, {0xAD60, 0xAD60, 0xAD60}, {0xAD61, 0xAD61, 0xAD61}, {0xAD62, 0xAD62, 0xAD62}, {0xAD63, 0xAD63, 0xAD63}, {0xAD64, 0xAD64, 0xAD64}, {0xAD65, 0xAD65, 0xAD65}, {0xAD66, 0xAD66, 0xAD66}, {0xAD67, 0xAD67, 0xAD67}, {0xAD68, 0xAD68, 0xAD68}, {0xAD69, 0xAD69, 0xAD69}, {0xAD6A, 0xAD6A, 0xAD6A}, {0xAD6B, 0xAD6B, 0xAD6B}, {0xAD6C, 0xAD6C, 0xAD6C}, {0xAD6D, 0xAD6D, 0xAD6D}, {0xAD6E, 0xAD6E, 0xAD6E}, {0xAD6F, 0xAD6F, 0xAD6F}, {0xAD70, 0xAD70, 0xAD70}, {0xAD71, 0xAD71, 0xAD71}, {0xAD72, 0xAD72, 0xAD72}, {0xAD73, 0xAD73, 0xAD73}, {0xAD74, 0xAD74, 0xAD74}, {0xAD75, 0xAD75, 0xAD75}, {0xAD76, 0xAD76, 0xAD76}, {0xAD77, 0xAD77, 0xAD77}, {0xAD78, 0xAD78, 0xAD78}, {0xAD79, 0xAD79, 0xAD79}, {0xAD7A, 0xAD7A, 0xAD7A}, {0xAD7B, 0xAD7B, 0xAD7B}, {0xAD7C, 0xAD7C, 0xAD7C}, {0xAD7D, 0xAD7D, 0xAD7D}, {0xAD7E, 0xAD7E, 0xAD7E}, {0xAD7F, 0xAD7F, 0xAD7F}, {0xAD80, 0xAD80, 0xAD80}, {0xAD81, 0xAD81, 0xAD81}, {0xAD82, 0xAD82, 0xAD82}, {0xAD83, 0xAD83, 0xAD83}, {0xAD84, 0xAD84, 0xAD84}, {0xAD85, 0xAD85, 0xAD85}, {0xAD86, 0xAD86, 0xAD86}, {0xAD87, 0xAD87, 0xAD87}, {0xAD88, 0xAD88, 0xAD88}, {0xAD89, 0xAD89, 0xAD89}, {0xAD8A, 0xAD8A, 0xAD8A}, {0xAD8B, 0xAD8B, 0xAD8B}, {0xAD8C, 0xAD8C, 0xAD8C}, {0xAD8D, 0xAD8D, 0xAD8D}, {0xAD8E, 0xAD8E, 0xAD8E}, {0xAD8F, 0xAD8F, 0xAD8F}, {0xAD90, 0xAD90, 0xAD90}, {0xAD91, 0xAD91, 0xAD91}, {0xAD92, 0xAD92, 0xAD92}, {0xAD93, 0xAD93, 0xAD93}, {0xAD94, 0xAD94, 0xAD94}, {0xAD95, 0xAD95, 0xAD95}, {0xAD96, 0xAD96, 0xAD96}, {0xAD97, 0xAD97, 0xAD97}, {0xAD98, 0xAD98, 0xAD98}, {0xAD99, 0xAD99, 0xAD99}, {0xAD9A, 0xAD9A, 0xAD9A}, {0xAD9B, 0xAD9B, 0xAD9B}, {0xAD9C, 0xAD9C, 0xAD9C}, {0xAD9D, 0xAD9D, 0xAD9D}, {0xAD9E, 0xAD9E, 0xAD9E}, {0xAD9F, 0xAD9F, 0xAD9F}, {0xADA0, 0xADA0, 0xADA0}, {0xADA1, 0xADA1, 0xADA1}, {0xADA2, 0xADA2, 0xADA2}, {0xADA3, 0xADA3, 0xADA3}, {0xADA4, 0xADA4, 0xADA4}, {0xADA5, 0xADA5, 0xADA5}, {0xADA6, 0xADA6, 0xADA6}, {0xADA7, 0xADA7, 0xADA7}, {0xADA8, 0xADA8, 0xADA8}, {0xADA9, 0xADA9, 0xADA9}, {0xADAA, 0xADAA, 0xADAA}, {0xADAB, 0xADAB, 0xADAB}, {0xADAC, 0xADAC, 0xADAC}, {0xADAD, 0xADAD, 0xADAD}, {0xADAE, 0xADAE, 0xADAE}, {0xADAF, 0xADAF, 0xADAF}, {0xADB0, 0xADB0, 0xADB0}, {0xADB1, 0xADB1, 0xADB1}, {0xADB2, 0xADB2, 0xADB2}, {0xADB3, 0xADB3, 0xADB3}, {0xADB4, 0xADB4, 0xADB4}, {0xADB5, 0xADB5, 0xADB5}, {0xADB6, 0xADB6, 0xADB6}, {0xADB7, 0xADB7, 0xADB7}, {0xADB8, 0xADB8, 0xADB8}, {0xADB9, 0xADB9, 0xADB9}, {0xADBA, 0xADBA, 0xADBA}, {0xADBB, 0xADBB, 0xADBB}, {0xADBC, 0xADBC, 0xADBC}, {0xADBD, 0xADBD, 0xADBD}, {0xADBE, 0xADBE, 0xADBE}, {0xADBF, 0xADBF, 0xADBF}, {0xADC0, 0xADC0, 0xADC0}, {0xADC1, 0xADC1, 0xADC1}, {0xADC2, 0xADC2, 0xADC2}, {0xADC3, 0xADC3, 0xADC3}, {0xADC4, 0xADC4, 0xADC4}, {0xADC5, 0xADC5, 0xADC5}, {0xADC6, 0xADC6, 0xADC6}, {0xADC7, 0xADC7, 0xADC7}, {0xADC8, 0xADC8, 0xADC8}, {0xADC9, 0xADC9, 0xADC9}, {0xADCA, 0xADCA, 0xADCA}, {0xADCB, 0xADCB, 0xADCB}, {0xADCC, 0xADCC, 0xADCC}, {0xADCD, 0xADCD, 0xADCD}, {0xADCE, 0xADCE, 0xADCE}, {0xADCF, 0xADCF, 0xADCF}, {0xADD0, 0xADD0, 0xADD0}, {0xADD1, 0xADD1, 0xADD1}, {0xADD2, 0xADD2, 0xADD2}, {0xADD3, 0xADD3, 0xADD3}, {0xADD4, 0xADD4, 0xADD4}, {0xADD5, 0xADD5, 0xADD5}, {0xADD6, 0xADD6, 0xADD6}, {0xADD7, 0xADD7, 0xADD7}, {0xADD8, 0xADD8, 0xADD8}, {0xADD9, 0xADD9, 0xADD9}, {0xADDA, 0xADDA, 0xADDA}, {0xADDB, 0xADDB, 0xADDB}, {0xADDC, 0xADDC, 0xADDC}, {0xADDD, 0xADDD, 0xADDD}, {0xADDE, 0xADDE, 0xADDE}, {0xADDF, 0xADDF, 0xADDF}, {0xADE0, 0xADE0, 0xADE0}, {0xADE1, 0xADE1, 0xADE1}, {0xADE2, 0xADE2, 0xADE2}, {0xADE3, 0xADE3, 0xADE3}, {0xADE4, 0xADE4, 0xADE4}, {0xADE5, 0xADE5, 0xADE5}, {0xADE6, 0xADE6, 0xADE6}, {0xADE7, 0xADE7, 0xADE7}, {0xADE8, 0xADE8, 0xADE8}, {0xADE9, 0xADE9, 0xADE9}, {0xADEA, 0xADEA, 0xADEA}, {0xADEB, 0xADEB, 0xADEB}, {0xADEC, 0xADEC, 0xADEC}, {0xADED, 0xADED, 0xADED}, {0xADEE, 0xADEE, 0xADEE}, {0xADEF, 0xADEF, 0xADEF}, {0xADF0, 0xADF0, 0xADF0}, {0xADF1, 0xADF1, 0xADF1}, {0xADF2, 0xADF2, 0xADF2}, {0xADF3, 0xADF3, 0xADF3}, {0xADF4, 0xADF4, 0xADF4}, {0xADF5, 0xADF5, 0xADF5}, {0xADF6, 0xADF6, 0xADF6}, {0xADF7, 0xADF7, 0xADF7}, {0xADF8, 0xADF8, 0xADF8}, {0xADF9, 0xADF9, 0xADF9}, {0xADFA, 0xADFA, 0xADFA}, {0xADFB, 0xADFB, 0xADFB}, {0xADFC, 0xADFC, 0xADFC}, {0xADFD, 0xADFD, 0xADFD}, {0xADFE, 0xADFE, 0xADFE}, {0xADFF, 0xADFF, 0xADFF}, {0xAE00, 0xAE00, 0xAE00}, {0xAE01, 0xAE01, 0xAE01}, {0xAE02, 0xAE02, 0xAE02}, {0xAE03, 0xAE03, 0xAE03}, {0xAE04, 0xAE04, 0xAE04}, {0xAE05, 0xAE05, 0xAE05}, {0xAE06, 0xAE06, 0xAE06}, {0xAE07, 0xAE07, 0xAE07}, {0xAE08, 0xAE08, 0xAE08}, {0xAE09, 0xAE09, 0xAE09}, {0xAE0A, 0xAE0A, 0xAE0A}, {0xAE0B, 0xAE0B, 0xAE0B}, {0xAE0C, 0xAE0C, 0xAE0C}, {0xAE0D, 0xAE0D, 0xAE0D}, {0xAE0E, 0xAE0E, 0xAE0E}, {0xAE0F, 0xAE0F, 0xAE0F}, {0xAE10, 0xAE10, 0xAE10}, {0xAE11, 0xAE11, 0xAE11}, {0xAE12, 0xAE12, 0xAE12}, {0xAE13, 0xAE13, 0xAE13}, {0xAE14, 0xAE14, 0xAE14}, {0xAE15, 0xAE15, 0xAE15}, {0xAE16, 0xAE16, 0xAE16}, {0xAE17, 0xAE17, 0xAE17}, {0xAE18, 0xAE18, 0xAE18}, {0xAE19, 0xAE19, 0xAE19}, {0xAE1A, 0xAE1A, 0xAE1A}, {0xAE1B, 0xAE1B, 0xAE1B}, {0xAE1C, 0xAE1C, 0xAE1C}, {0xAE1D, 0xAE1D, 0xAE1D}, {0xAE1E, 0xAE1E, 0xAE1E}, {0xAE1F, 0xAE1F, 0xAE1F}, {0xAE20, 0xAE20, 0xAE20}, {0xAE21, 0xAE21, 0xAE21}, {0xAE22, 0xAE22, 0xAE22}, {0xAE23, 0xAE23, 0xAE23}, {0xAE24, 0xAE24, 0xAE24}, {0xAE25, 0xAE25, 0xAE25}, {0xAE26, 0xAE26, 0xAE26}, {0xAE27, 0xAE27, 0xAE27}, {0xAE28, 0xAE28, 0xAE28}, {0xAE29, 0xAE29, 0xAE29}, {0xAE2A, 0xAE2A, 0xAE2A}, {0xAE2B, 0xAE2B, 0xAE2B}, {0xAE2C, 0xAE2C, 0xAE2C}, {0xAE2D, 0xAE2D, 0xAE2D}, {0xAE2E, 0xAE2E, 0xAE2E}, {0xAE2F, 0xAE2F, 0xAE2F}, {0xAE30, 0xAE30, 0xAE30}, {0xAE31, 0xAE31, 0xAE31}, {0xAE32, 0xAE32, 0xAE32}, {0xAE33, 0xAE33, 0xAE33}, {0xAE34, 0xAE34, 0xAE34}, {0xAE35, 0xAE35, 0xAE35}, {0xAE36, 0xAE36, 0xAE36}, {0xAE37, 0xAE37, 0xAE37}, {0xAE38, 0xAE38, 0xAE38}, {0xAE39, 0xAE39, 0xAE39}, {0xAE3A, 0xAE3A, 0xAE3A}, {0xAE3B, 0xAE3B, 0xAE3B}, {0xAE3C, 0xAE3C, 0xAE3C}, {0xAE3D, 0xAE3D, 0xAE3D}, {0xAE3E, 0xAE3E, 0xAE3E}, {0xAE3F, 0xAE3F, 0xAE3F}, {0xAE40, 0xAE40, 0xAE40}, {0xAE41, 0xAE41, 0xAE41}, {0xAE42, 0xAE42, 0xAE42}, {0xAE43, 0xAE43, 0xAE43}, {0xAE44, 0xAE44, 0xAE44}, {0xAE45, 0xAE45, 0xAE45}, {0xAE46, 0xAE46, 0xAE46}, {0xAE47, 0xAE47, 0xAE47}, {0xAE48, 0xAE48, 0xAE48}, {0xAE49, 0xAE49, 0xAE49}, {0xAE4A, 0xAE4A, 0xAE4A}, {0xAE4B, 0xAE4B, 0xAE4B}, {0xAE4C, 0xAE4C, 0xAE4C}, {0xAE4D, 0xAE4D, 0xAE4D}, {0xAE4E, 0xAE4E, 0xAE4E}, {0xAE4F, 0xAE4F, 0xAE4F}, {0xAE50, 0xAE50, 0xAE50}, {0xAE51, 0xAE51, 0xAE51}, {0xAE52, 0xAE52, 0xAE52}, {0xAE53, 0xAE53, 0xAE53}, {0xAE54, 0xAE54, 0xAE54}, {0xAE55, 0xAE55, 0xAE55}, {0xAE56, 0xAE56, 0xAE56}, {0xAE57, 0xAE57, 0xAE57}, {0xAE58, 0xAE58, 0xAE58}, {0xAE59, 0xAE59, 0xAE59}, {0xAE5A, 0xAE5A, 0xAE5A}, {0xAE5B, 0xAE5B, 0xAE5B}, {0xAE5C, 0xAE5C, 0xAE5C}, {0xAE5D, 0xAE5D, 0xAE5D}, {0xAE5E, 0xAE5E, 0xAE5E}, {0xAE5F, 0xAE5F, 0xAE5F}, {0xAE60, 0xAE60, 0xAE60}, {0xAE61, 0xAE61, 0xAE61}, {0xAE62, 0xAE62, 0xAE62}, {0xAE63, 0xAE63, 0xAE63}, {0xAE64, 0xAE64, 0xAE64}, {0xAE65, 0xAE65, 0xAE65}, {0xAE66, 0xAE66, 0xAE66}, {0xAE67, 0xAE67, 0xAE67}, {0xAE68, 0xAE68, 0xAE68}, {0xAE69, 0xAE69, 0xAE69}, {0xAE6A, 0xAE6A, 0xAE6A}, {0xAE6B, 0xAE6B, 0xAE6B}, {0xAE6C, 0xAE6C, 0xAE6C}, {0xAE6D, 0xAE6D, 0xAE6D}, {0xAE6E, 0xAE6E, 0xAE6E}, {0xAE6F, 0xAE6F, 0xAE6F}, {0xAE70, 0xAE70, 0xAE70}, {0xAE71, 0xAE71, 0xAE71}, {0xAE72, 0xAE72, 0xAE72}, {0xAE73, 0xAE73, 0xAE73}, {0xAE74, 0xAE74, 0xAE74}, {0xAE75, 0xAE75, 0xAE75}, {0xAE76, 0xAE76, 0xAE76}, {0xAE77, 0xAE77, 0xAE77}, {0xAE78, 0xAE78, 0xAE78}, {0xAE79, 0xAE79, 0xAE79}, {0xAE7A, 0xAE7A, 0xAE7A}, {0xAE7B, 0xAE7B, 0xAE7B}, {0xAE7C, 0xAE7C, 0xAE7C}, {0xAE7D, 0xAE7D, 0xAE7D}, {0xAE7E, 0xAE7E, 0xAE7E}, {0xAE7F, 0xAE7F, 0xAE7F}, {0xAE80, 0xAE80, 0xAE80}, {0xAE81, 0xAE81, 0xAE81}, {0xAE82, 0xAE82, 0xAE82}, {0xAE83, 0xAE83, 0xAE83}, {0xAE84, 0xAE84, 0xAE84}, {0xAE85, 0xAE85, 0xAE85}, {0xAE86, 0xAE86, 0xAE86}, {0xAE87, 0xAE87, 0xAE87}, {0xAE88, 0xAE88, 0xAE88}, {0xAE89, 0xAE89, 0xAE89}, {0xAE8A, 0xAE8A, 0xAE8A}, {0xAE8B, 0xAE8B, 0xAE8B}, {0xAE8C, 0xAE8C, 0xAE8C}, {0xAE8D, 0xAE8D, 0xAE8D}, {0xAE8E, 0xAE8E, 0xAE8E}, {0xAE8F, 0xAE8F, 0xAE8F}, {0xAE90, 0xAE90, 0xAE90}, {0xAE91, 0xAE91, 0xAE91}, {0xAE92, 0xAE92, 0xAE92}, {0xAE93, 0xAE93, 0xAE93}, {0xAE94, 0xAE94, 0xAE94}, {0xAE95, 0xAE95, 0xAE95}, {0xAE96, 0xAE96, 0xAE96}, {0xAE97, 0xAE97, 0xAE97}, {0xAE98, 0xAE98, 0xAE98}, {0xAE99, 0xAE99, 0xAE99}, {0xAE9A, 0xAE9A, 0xAE9A}, {0xAE9B, 0xAE9B, 0xAE9B}, {0xAE9C, 0xAE9C, 0xAE9C}, {0xAE9D, 0xAE9D, 0xAE9D}, {0xAE9E, 0xAE9E, 0xAE9E}, {0xAE9F, 0xAE9F, 0xAE9F}, {0xAEA0, 0xAEA0, 0xAEA0}, {0xAEA1, 0xAEA1, 0xAEA1}, {0xAEA2, 0xAEA2, 0xAEA2}, {0xAEA3, 0xAEA3, 0xAEA3}, {0xAEA4, 0xAEA4, 0xAEA4}, {0xAEA5, 0xAEA5, 0xAEA5}, {0xAEA6, 0xAEA6, 0xAEA6}, {0xAEA7, 0xAEA7, 0xAEA7}, {0xAEA8, 0xAEA8, 0xAEA8}, {0xAEA9, 0xAEA9, 0xAEA9}, {0xAEAA, 0xAEAA, 0xAEAA}, {0xAEAB, 0xAEAB, 0xAEAB}, {0xAEAC, 0xAEAC, 0xAEAC}, {0xAEAD, 0xAEAD, 0xAEAD}, {0xAEAE, 0xAEAE, 0xAEAE}, {0xAEAF, 0xAEAF, 0xAEAF}, {0xAEB0, 0xAEB0, 0xAEB0}, {0xAEB1, 0xAEB1, 0xAEB1}, {0xAEB2, 0xAEB2, 0xAEB2}, {0xAEB3, 0xAEB3, 0xAEB3}, {0xAEB4, 0xAEB4, 0xAEB4}, {0xAEB5, 0xAEB5, 0xAEB5}, {0xAEB6, 0xAEB6, 0xAEB6}, {0xAEB7, 0xAEB7, 0xAEB7}, {0xAEB8, 0xAEB8, 0xAEB8}, {0xAEB9, 0xAEB9, 0xAEB9}, {0xAEBA, 0xAEBA, 0xAEBA}, {0xAEBB, 0xAEBB, 0xAEBB}, {0xAEBC, 0xAEBC, 0xAEBC}, {0xAEBD, 0xAEBD, 0xAEBD}, {0xAEBE, 0xAEBE, 0xAEBE}, {0xAEBF, 0xAEBF, 0xAEBF}, {0xAEC0, 0xAEC0, 0xAEC0}, {0xAEC1, 0xAEC1, 0xAEC1}, {0xAEC2, 0xAEC2, 0xAEC2}, {0xAEC3, 0xAEC3, 0xAEC3}, {0xAEC4, 0xAEC4, 0xAEC4}, {0xAEC5, 0xAEC5, 0xAEC5}, {0xAEC6, 0xAEC6, 0xAEC6}, {0xAEC7, 0xAEC7, 0xAEC7}, {0xAEC8, 0xAEC8, 0xAEC8}, {0xAEC9, 0xAEC9, 0xAEC9}, {0xAECA, 0xAECA, 0xAECA}, {0xAECB, 0xAECB, 0xAECB}, {0xAECC, 0xAECC, 0xAECC}, {0xAECD, 0xAECD, 0xAECD}, {0xAECE, 0xAECE, 0xAECE}, {0xAECF, 0xAECF, 0xAECF}, {0xAED0, 0xAED0, 0xAED0}, {0xAED1, 0xAED1, 0xAED1}, {0xAED2, 0xAED2, 0xAED2}, {0xAED3, 0xAED3, 0xAED3}, {0xAED4, 0xAED4, 0xAED4}, {0xAED5, 0xAED5, 0xAED5}, {0xAED6, 0xAED6, 0xAED6}, {0xAED7, 0xAED7, 0xAED7}, {0xAED8, 0xAED8, 0xAED8}, {0xAED9, 0xAED9, 0xAED9}, {0xAEDA, 0xAEDA, 0xAEDA}, {0xAEDB, 0xAEDB, 0xAEDB}, {0xAEDC, 0xAEDC, 0xAEDC}, {0xAEDD, 0xAEDD, 0xAEDD}, {0xAEDE, 0xAEDE, 0xAEDE}, {0xAEDF, 0xAEDF, 0xAEDF}, {0xAEE0, 0xAEE0, 0xAEE0}, {0xAEE1, 0xAEE1, 0xAEE1}, {0xAEE2, 0xAEE2, 0xAEE2}, {0xAEE3, 0xAEE3, 0xAEE3}, {0xAEE4, 0xAEE4, 0xAEE4}, {0xAEE5, 0xAEE5, 0xAEE5}, {0xAEE6, 0xAEE6, 0xAEE6}, {0xAEE7, 0xAEE7, 0xAEE7}, {0xAEE8, 0xAEE8, 0xAEE8}, {0xAEE9, 0xAEE9, 0xAEE9}, {0xAEEA, 0xAEEA, 0xAEEA}, {0xAEEB, 0xAEEB, 0xAEEB}, {0xAEEC, 0xAEEC, 0xAEEC}, {0xAEED, 0xAEED, 0xAEED}, {0xAEEE, 0xAEEE, 0xAEEE}, {0xAEEF, 0xAEEF, 0xAEEF}, {0xAEF0, 0xAEF0, 0xAEF0}, {0xAEF1, 0xAEF1, 0xAEF1}, {0xAEF2, 0xAEF2, 0xAEF2}, {0xAEF3, 0xAEF3, 0xAEF3}, {0xAEF4, 0xAEF4, 0xAEF4}, {0xAEF5, 0xAEF5, 0xAEF5}, {0xAEF6, 0xAEF6, 0xAEF6}, {0xAEF7, 0xAEF7, 0xAEF7}, {0xAEF8, 0xAEF8, 0xAEF8}, {0xAEF9, 0xAEF9, 0xAEF9}, {0xAEFA, 0xAEFA, 0xAEFA}, {0xAEFB, 0xAEFB, 0xAEFB}, {0xAEFC, 0xAEFC, 0xAEFC}, {0xAEFD, 0xAEFD, 0xAEFD}, {0xAEFE, 0xAEFE, 0xAEFE}, {0xAEFF, 0xAEFF, 0xAEFF}, {0xAF00, 0xAF00, 0xAF00}, {0xAF01, 0xAF01, 0xAF01}, {0xAF02, 0xAF02, 0xAF02}, {0xAF03, 0xAF03, 0xAF03}, {0xAF04, 0xAF04, 0xAF04}, {0xAF05, 0xAF05, 0xAF05}, {0xAF06, 0xAF06, 0xAF06}, {0xAF07, 0xAF07, 0xAF07}, {0xAF08, 0xAF08, 0xAF08}, {0xAF09, 0xAF09, 0xAF09}, {0xAF0A, 0xAF0A, 0xAF0A}, {0xAF0B, 0xAF0B, 0xAF0B}, {0xAF0C, 0xAF0C, 0xAF0C}, {0xAF0D, 0xAF0D, 0xAF0D}, {0xAF0E, 0xAF0E, 0xAF0E}, {0xAF0F, 0xAF0F, 0xAF0F}, {0xAF10, 0xAF10, 0xAF10}, {0xAF11, 0xAF11, 0xAF11}, {0xAF12, 0xAF12, 0xAF12}, {0xAF13, 0xAF13, 0xAF13}, {0xAF14, 0xAF14, 0xAF14}, {0xAF15, 0xAF15, 0xAF15}, {0xAF16, 0xAF16, 0xAF16}, {0xAF17, 0xAF17, 0xAF17}, {0xAF18, 0xAF18, 0xAF18}, {0xAF19, 0xAF19, 0xAF19}, {0xAF1A, 0xAF1A, 0xAF1A}, {0xAF1B, 0xAF1B, 0xAF1B}, {0xAF1C, 0xAF1C, 0xAF1C}, {0xAF1D, 0xAF1D, 0xAF1D}, {0xAF1E, 0xAF1E, 0xAF1E}, {0xAF1F, 0xAF1F, 0xAF1F}, {0xAF20, 0xAF20, 0xAF20}, {0xAF21, 0xAF21, 0xAF21}, {0xAF22, 0xAF22, 0xAF22}, {0xAF23, 0xAF23, 0xAF23}, {0xAF24, 0xAF24, 0xAF24}, {0xAF25, 0xAF25, 0xAF25}, {0xAF26, 0xAF26, 0xAF26}, {0xAF27, 0xAF27, 0xAF27}, {0xAF28, 0xAF28, 0xAF28}, {0xAF29, 0xAF29, 0xAF29}, {0xAF2A, 0xAF2A, 0xAF2A}, {0xAF2B, 0xAF2B, 0xAF2B}, {0xAF2C, 0xAF2C, 0xAF2C}, {0xAF2D, 0xAF2D, 0xAF2D}, {0xAF2E, 0xAF2E, 0xAF2E}, {0xAF2F, 0xAF2F, 0xAF2F}, {0xAF30, 0xAF30, 0xAF30}, {0xAF31, 0xAF31, 0xAF31}, {0xAF32, 0xAF32, 0xAF32}, {0xAF33, 0xAF33, 0xAF33}, {0xAF34, 0xAF34, 0xAF34}, {0xAF35, 0xAF35, 0xAF35}, {0xAF36, 0xAF36, 0xAF36}, {0xAF37, 0xAF37, 0xAF37}, {0xAF38, 0xAF38, 0xAF38}, {0xAF39, 0xAF39, 0xAF39}, {0xAF3A, 0xAF3A, 0xAF3A}, {0xAF3B, 0xAF3B, 0xAF3B}, {0xAF3C, 0xAF3C, 0xAF3C}, {0xAF3D, 0xAF3D, 0xAF3D}, {0xAF3E, 0xAF3E, 0xAF3E}, {0xAF3F, 0xAF3F, 0xAF3F}, {0xAF40, 0xAF40, 0xAF40}, {0xAF41, 0xAF41, 0xAF41}, {0xAF42, 0xAF42, 0xAF42}, {0xAF43, 0xAF43, 0xAF43}, {0xAF44, 0xAF44, 0xAF44}, {0xAF45, 0xAF45, 0xAF45}, {0xAF46, 0xAF46, 0xAF46}, {0xAF47, 0xAF47, 0xAF47}, {0xAF48, 0xAF48, 0xAF48}, {0xAF49, 0xAF49, 0xAF49}, {0xAF4A, 0xAF4A, 0xAF4A}, {0xAF4B, 0xAF4B, 0xAF4B}, {0xAF4C, 0xAF4C, 0xAF4C}, {0xAF4D, 0xAF4D, 0xAF4D}, {0xAF4E, 0xAF4E, 0xAF4E}, {0xAF4F, 0xAF4F, 0xAF4F}, {0xAF50, 0xAF50, 0xAF50}, {0xAF51, 0xAF51, 0xAF51}, {0xAF52, 0xAF52, 0xAF52}, {0xAF53, 0xAF53, 0xAF53}, {0xAF54, 0xAF54, 0xAF54}, {0xAF55, 0xAF55, 0xAF55}, {0xAF56, 0xAF56, 0xAF56}, {0xAF57, 0xAF57, 0xAF57}, {0xAF58, 0xAF58, 0xAF58}, {0xAF59, 0xAF59, 0xAF59}, {0xAF5A, 0xAF5A, 0xAF5A}, {0xAF5B, 0xAF5B, 0xAF5B}, {0xAF5C, 0xAF5C, 0xAF5C}, {0xAF5D, 0xAF5D, 0xAF5D}, {0xAF5E, 0xAF5E, 0xAF5E}, {0xAF5F, 0xAF5F, 0xAF5F}, {0xAF60, 0xAF60, 0xAF60}, {0xAF61, 0xAF61, 0xAF61}, {0xAF62, 0xAF62, 0xAF62}, {0xAF63, 0xAF63, 0xAF63}, {0xAF64, 0xAF64, 0xAF64}, {0xAF65, 0xAF65, 0xAF65}, {0xAF66, 0xAF66, 0xAF66}, {0xAF67, 0xAF67, 0xAF67}, {0xAF68, 0xAF68, 0xAF68}, {0xAF69, 0xAF69, 0xAF69}, {0xAF6A, 0xAF6A, 0xAF6A}, {0xAF6B, 0xAF6B, 0xAF6B}, {0xAF6C, 0xAF6C, 0xAF6C}, {0xAF6D, 0xAF6D, 0xAF6D}, {0xAF6E, 0xAF6E, 0xAF6E}, {0xAF6F, 0xAF6F, 0xAF6F}, {0xAF70, 0xAF70, 0xAF70}, {0xAF71, 0xAF71, 0xAF71}, {0xAF72, 0xAF72, 0xAF72}, {0xAF73, 0xAF73, 0xAF73}, {0xAF74, 0xAF74, 0xAF74}, {0xAF75, 0xAF75, 0xAF75}, {0xAF76, 0xAF76, 0xAF76}, {0xAF77, 0xAF77, 0xAF77}, {0xAF78, 0xAF78, 0xAF78}, {0xAF79, 0xAF79, 0xAF79}, {0xAF7A, 0xAF7A, 0xAF7A}, {0xAF7B, 0xAF7B, 0xAF7B}, {0xAF7C, 0xAF7C, 0xAF7C}, {0xAF7D, 0xAF7D, 0xAF7D}, {0xAF7E, 0xAF7E, 0xAF7E}, {0xAF7F, 0xAF7F, 0xAF7F}, {0xAF80, 0xAF80, 0xAF80}, {0xAF81, 0xAF81, 0xAF81}, {0xAF82, 0xAF82, 0xAF82}, {0xAF83, 0xAF83, 0xAF83}, {0xAF84, 0xAF84, 0xAF84}, {0xAF85, 0xAF85, 0xAF85}, {0xAF86, 0xAF86, 0xAF86}, {0xAF87, 0xAF87, 0xAF87}, {0xAF88, 0xAF88, 0xAF88}, {0xAF89, 0xAF89, 0xAF89}, {0xAF8A, 0xAF8A, 0xAF8A}, {0xAF8B, 0xAF8B, 0xAF8B}, {0xAF8C, 0xAF8C, 0xAF8C}, {0xAF8D, 0xAF8D, 0xAF8D}, {0xAF8E, 0xAF8E, 0xAF8E}, {0xAF8F, 0xAF8F, 0xAF8F}, {0xAF90, 0xAF90, 0xAF90}, {0xAF91, 0xAF91, 0xAF91}, {0xAF92, 0xAF92, 0xAF92}, {0xAF93, 0xAF93, 0xAF93}, {0xAF94, 0xAF94, 0xAF94}, {0xAF95, 0xAF95, 0xAF95}, {0xAF96, 0xAF96, 0xAF96}, {0xAF97, 0xAF97, 0xAF97}, {0xAF98, 0xAF98, 0xAF98}, {0xAF99, 0xAF99, 0xAF99}, {0xAF9A, 0xAF9A, 0xAF9A}, {0xAF9B, 0xAF9B, 0xAF9B}, {0xAF9C, 0xAF9C, 0xAF9C}, {0xAF9D, 0xAF9D, 0xAF9D}, {0xAF9E, 0xAF9E, 0xAF9E}, {0xAF9F, 0xAF9F, 0xAF9F}, {0xAFA0, 0xAFA0, 0xAFA0}, {0xAFA1, 0xAFA1, 0xAFA1}, {0xAFA2, 0xAFA2, 0xAFA2}, {0xAFA3, 0xAFA3, 0xAFA3}, {0xAFA4, 0xAFA4, 0xAFA4}, {0xAFA5, 0xAFA5, 0xAFA5}, {0xAFA6, 0xAFA6, 0xAFA6}, {0xAFA7, 0xAFA7, 0xAFA7}, {0xAFA8, 0xAFA8, 0xAFA8}, {0xAFA9, 0xAFA9, 0xAFA9}, {0xAFAA, 0xAFAA, 0xAFAA}, {0xAFAB, 0xAFAB, 0xAFAB}, {0xAFAC, 0xAFAC, 0xAFAC}, {0xAFAD, 0xAFAD, 0xAFAD}, {0xAFAE, 0xAFAE, 0xAFAE}, {0xAFAF, 0xAFAF, 0xAFAF}, {0xAFB0, 0xAFB0, 0xAFB0}, {0xAFB1, 0xAFB1, 0xAFB1}, {0xAFB2, 0xAFB2, 0xAFB2}, {0xAFB3, 0xAFB3, 0xAFB3}, {0xAFB4, 0xAFB4, 0xAFB4}, {0xAFB5, 0xAFB5, 0xAFB5}, {0xAFB6, 0xAFB6, 0xAFB6}, {0xAFB7, 0xAFB7, 0xAFB7}, {0xAFB8, 0xAFB8, 0xAFB8}, {0xAFB9, 0xAFB9, 0xAFB9}, {0xAFBA, 0xAFBA, 0xAFBA}, {0xAFBB, 0xAFBB, 0xAFBB}, {0xAFBC, 0xAFBC, 0xAFBC}, {0xAFBD, 0xAFBD, 0xAFBD}, {0xAFBE, 0xAFBE, 0xAFBE}, {0xAFBF, 0xAFBF, 0xAFBF}, {0xAFC0, 0xAFC0, 0xAFC0}, {0xAFC1, 0xAFC1, 0xAFC1}, {0xAFC2, 0xAFC2, 0xAFC2}, {0xAFC3, 0xAFC3, 0xAFC3}, {0xAFC4, 0xAFC4, 0xAFC4}, {0xAFC5, 0xAFC5, 0xAFC5}, {0xAFC6, 0xAFC6, 0xAFC6}, {0xAFC7, 0xAFC7, 0xAFC7}, {0xAFC8, 0xAFC8, 0xAFC8}, {0xAFC9, 0xAFC9, 0xAFC9}, {0xAFCA, 0xAFCA, 0xAFCA}, {0xAFCB, 0xAFCB, 0xAFCB}, {0xAFCC, 0xAFCC, 0xAFCC}, {0xAFCD, 0xAFCD, 0xAFCD}, {0xAFCE, 0xAFCE, 0xAFCE}, {0xAFCF, 0xAFCF, 0xAFCF}, {0xAFD0, 0xAFD0, 0xAFD0}, {0xAFD1, 0xAFD1, 0xAFD1}, {0xAFD2, 0xAFD2, 0xAFD2}, {0xAFD3, 0xAFD3, 0xAFD3}, {0xAFD4, 0xAFD4, 0xAFD4}, {0xAFD5, 0xAFD5, 0xAFD5}, {0xAFD6, 0xAFD6, 0xAFD6}, {0xAFD7, 0xAFD7, 0xAFD7}, {0xAFD8, 0xAFD8, 0xAFD8}, {0xAFD9, 0xAFD9, 0xAFD9}, {0xAFDA, 0xAFDA, 0xAFDA}, {0xAFDB, 0xAFDB, 0xAFDB}, {0xAFDC, 0xAFDC, 0xAFDC}, {0xAFDD, 0xAFDD, 0xAFDD}, {0xAFDE, 0xAFDE, 0xAFDE}, {0xAFDF, 0xAFDF, 0xAFDF}, {0xAFE0, 0xAFE0, 0xAFE0}, {0xAFE1, 0xAFE1, 0xAFE1}, {0xAFE2, 0xAFE2, 0xAFE2}, {0xAFE3, 0xAFE3, 0xAFE3}, {0xAFE4, 0xAFE4, 0xAFE4}, {0xAFE5, 0xAFE5, 0xAFE5}, {0xAFE6, 0xAFE6, 0xAFE6}, {0xAFE7, 0xAFE7, 0xAFE7}, {0xAFE8, 0xAFE8, 0xAFE8}, {0xAFE9, 0xAFE9, 0xAFE9}, {0xAFEA, 0xAFEA, 0xAFEA}, {0xAFEB, 0xAFEB, 0xAFEB}, {0xAFEC, 0xAFEC, 0xAFEC}, {0xAFED, 0xAFED, 0xAFED}, {0xAFEE, 0xAFEE, 0xAFEE}, {0xAFEF, 0xAFEF, 0xAFEF}, {0xAFF0, 0xAFF0, 0xAFF0}, {0xAFF1, 0xAFF1, 0xAFF1}, {0xAFF2, 0xAFF2, 0xAFF2}, {0xAFF3, 0xAFF3, 0xAFF3}, {0xAFF4, 0xAFF4, 0xAFF4}, {0xAFF5, 0xAFF5, 0xAFF5}, {0xAFF6, 0xAFF6, 0xAFF6}, {0xAFF7, 0xAFF7, 0xAFF7}, {0xAFF8, 0xAFF8, 0xAFF8}, {0xAFF9, 0xAFF9, 0xAFF9}, {0xAFFA, 0xAFFA, 0xAFFA}, {0xAFFB, 0xAFFB, 0xAFFB}, {0xAFFC, 0xAFFC, 0xAFFC}, {0xAFFD, 0xAFFD, 0xAFFD}, {0xAFFE, 0xAFFE, 0xAFFE}, {0xAFFF, 0xAFFF, 0xAFFF}, {0xB000, 0xB000, 0xB000}, {0xB001, 0xB001, 0xB001}, {0xB002, 0xB002, 0xB002}, {0xB003, 0xB003, 0xB003}, {0xB004, 0xB004, 0xB004}, {0xB005, 0xB005, 0xB005}, {0xB006, 0xB006, 0xB006}, {0xB007, 0xB007, 0xB007}, {0xB008, 0xB008, 0xB008}, {0xB009, 0xB009, 0xB009}, {0xB00A, 0xB00A, 0xB00A}, {0xB00B, 0xB00B, 0xB00B}, {0xB00C, 0xB00C, 0xB00C}, {0xB00D, 0xB00D, 0xB00D}, {0xB00E, 0xB00E, 0xB00E}, {0xB00F, 0xB00F, 0xB00F}, {0xB010, 0xB010, 0xB010}, {0xB011, 0xB011, 0xB011}, {0xB012, 0xB012, 0xB012}, {0xB013, 0xB013, 0xB013}, {0xB014, 0xB014, 0xB014}, {0xB015, 0xB015, 0xB015}, {0xB016, 0xB016, 0xB016}, {0xB017, 0xB017, 0xB017}, {0xB018, 0xB018, 0xB018}, {0xB019, 0xB019, 0xB019}, {0xB01A, 0xB01A, 0xB01A}, {0xB01B, 0xB01B, 0xB01B}, {0xB01C, 0xB01C, 0xB01C}, {0xB01D, 0xB01D, 0xB01D}, {0xB01E, 0xB01E, 0xB01E}, {0xB01F, 0xB01F, 0xB01F}, {0xB020, 0xB020, 0xB020}, {0xB021, 0xB021, 0xB021}, {0xB022, 0xB022, 0xB022}, {0xB023, 0xB023, 0xB023}, {0xB024, 0xB024, 0xB024}, {0xB025, 0xB025, 0xB025}, {0xB026, 0xB026, 0xB026}, {0xB027, 0xB027, 0xB027}, {0xB028, 0xB028, 0xB028}, {0xB029, 0xB029, 0xB029}, {0xB02A, 0xB02A, 0xB02A}, {0xB02B, 0xB02B, 0xB02B}, {0xB02C, 0xB02C, 0xB02C}, {0xB02D, 0xB02D, 0xB02D}, {0xB02E, 0xB02E, 0xB02E}, {0xB02F, 0xB02F, 0xB02F}, {0xB030, 0xB030, 0xB030}, {0xB031, 0xB031, 0xB031}, {0xB032, 0xB032, 0xB032}, {0xB033, 0xB033, 0xB033}, {0xB034, 0xB034, 0xB034}, {0xB035, 0xB035, 0xB035}, {0xB036, 0xB036, 0xB036}, {0xB037, 0xB037, 0xB037}, {0xB038, 0xB038, 0xB038}, {0xB039, 0xB039, 0xB039}, {0xB03A, 0xB03A, 0xB03A}, {0xB03B, 0xB03B, 0xB03B}, {0xB03C, 0xB03C, 0xB03C}, {0xB03D, 0xB03D, 0xB03D}, {0xB03E, 0xB03E, 0xB03E}, {0xB03F, 0xB03F, 0xB03F}, {0xB040, 0xB040, 0xB040}, {0xB041, 0xB041, 0xB041}, {0xB042, 0xB042, 0xB042}, {0xB043, 0xB043, 0xB043}, {0xB044, 0xB044, 0xB044}, {0xB045, 0xB045, 0xB045}, {0xB046, 0xB046, 0xB046}, {0xB047, 0xB047, 0xB047}, {0xB048, 0xB048, 0xB048}, {0xB049, 0xB049, 0xB049}, {0xB04A, 0xB04A, 0xB04A}, {0xB04B, 0xB04B, 0xB04B}, {0xB04C, 0xB04C, 0xB04C}, {0xB04D, 0xB04D, 0xB04D}, {0xB04E, 0xB04E, 0xB04E}, {0xB04F, 0xB04F, 0xB04F}, {0xB050, 0xB050, 0xB050}, {0xB051, 0xB051, 0xB051}, {0xB052, 0xB052, 0xB052}, {0xB053, 0xB053, 0xB053}, {0xB054, 0xB054, 0xB054}, {0xB055, 0xB055, 0xB055}, {0xB056, 0xB056, 0xB056}, {0xB057, 0xB057, 0xB057}, {0xB058, 0xB058, 0xB058}, {0xB059, 0xB059, 0xB059}, {0xB05A, 0xB05A, 0xB05A}, {0xB05B, 0xB05B, 0xB05B}, {0xB05C, 0xB05C, 0xB05C}, {0xB05D, 0xB05D, 0xB05D}, {0xB05E, 0xB05E, 0xB05E}, {0xB05F, 0xB05F, 0xB05F}, {0xB060, 0xB060, 0xB060}, {0xB061, 0xB061, 0xB061}, {0xB062, 0xB062, 0xB062}, {0xB063, 0xB063, 0xB063}, {0xB064, 0xB064, 0xB064}, {0xB065, 0xB065, 0xB065}, {0xB066, 0xB066, 0xB066}, {0xB067, 0xB067, 0xB067}, {0xB068, 0xB068, 0xB068}, {0xB069, 0xB069, 0xB069}, {0xB06A, 0xB06A, 0xB06A}, {0xB06B, 0xB06B, 0xB06B}, {0xB06C, 0xB06C, 0xB06C}, {0xB06D, 0xB06D, 0xB06D}, {0xB06E, 0xB06E, 0xB06E}, {0xB06F, 0xB06F, 0xB06F}, {0xB070, 0xB070, 0xB070}, {0xB071, 0xB071, 0xB071}, {0xB072, 0xB072, 0xB072}, {0xB073, 0xB073, 0xB073}, {0xB074, 0xB074, 0xB074}, {0xB075, 0xB075, 0xB075}, {0xB076, 0xB076, 0xB076}, {0xB077, 0xB077, 0xB077}, {0xB078, 0xB078, 0xB078}, {0xB079, 0xB079, 0xB079}, {0xB07A, 0xB07A, 0xB07A}, {0xB07B, 0xB07B, 0xB07B}, {0xB07C, 0xB07C, 0xB07C}, {0xB07D, 0xB07D, 0xB07D}, {0xB07E, 0xB07E, 0xB07E}, {0xB07F, 0xB07F, 0xB07F}, {0xB080, 0xB080, 0xB080}, {0xB081, 0xB081, 0xB081}, {0xB082, 0xB082, 0xB082}, {0xB083, 0xB083, 0xB083}, {0xB084, 0xB084, 0xB084}, {0xB085, 0xB085, 0xB085}, {0xB086, 0xB086, 0xB086}, {0xB087, 0xB087, 0xB087}, {0xB088, 0xB088, 0xB088}, {0xB089, 0xB089, 0xB089}, {0xB08A, 0xB08A, 0xB08A}, {0xB08B, 0xB08B, 0xB08B}, {0xB08C, 0xB08C, 0xB08C}, {0xB08D, 0xB08D, 0xB08D}, {0xB08E, 0xB08E, 0xB08E}, {0xB08F, 0xB08F, 0xB08F}, {0xB090, 0xB090, 0xB090}, {0xB091, 0xB091, 0xB091}, {0xB092, 0xB092, 0xB092}, {0xB093, 0xB093, 0xB093}, {0xB094, 0xB094, 0xB094}, {0xB095, 0xB095, 0xB095}, {0xB096, 0xB096, 0xB096}, {0xB097, 0xB097, 0xB097}, {0xB098, 0xB098, 0xB098}, {0xB099, 0xB099, 0xB099}, {0xB09A, 0xB09A, 0xB09A}, {0xB09B, 0xB09B, 0xB09B}, {0xB09C, 0xB09C, 0xB09C}, {0xB09D, 0xB09D, 0xB09D}, {0xB09E, 0xB09E, 0xB09E}, {0xB09F, 0xB09F, 0xB09F}, {0xB0A0, 0xB0A0, 0xB0A0}, {0xB0A1, 0xB0A1, 0xB0A1}, {0xB0A2, 0xB0A2, 0xB0A2}, {0xB0A3, 0xB0A3, 0xB0A3}, {0xB0A4, 0xB0A4, 0xB0A4}, {0xB0A5, 0xB0A5, 0xB0A5}, {0xB0A6, 0xB0A6, 0xB0A6}, {0xB0A7, 0xB0A7, 0xB0A7}, {0xB0A8, 0xB0A8, 0xB0A8}, {0xB0A9, 0xB0A9, 0xB0A9}, {0xB0AA, 0xB0AA, 0xB0AA}, {0xB0AB, 0xB0AB, 0xB0AB}, {0xB0AC, 0xB0AC, 0xB0AC}, {0xB0AD, 0xB0AD, 0xB0AD}, {0xB0AE, 0xB0AE, 0xB0AE}, {0xB0AF, 0xB0AF, 0xB0AF}, {0xB0B0, 0xB0B0, 0xB0B0}, {0xB0B1, 0xB0B1, 0xB0B1}, {0xB0B2, 0xB0B2, 0xB0B2}, {0xB0B3, 0xB0B3, 0xB0B3}, {0xB0B4, 0xB0B4, 0xB0B4}, {0xB0B5, 0xB0B5, 0xB0B5}, {0xB0B6, 0xB0B6, 0xB0B6}, {0xB0B7, 0xB0B7, 0xB0B7}, {0xB0B8, 0xB0B8, 0xB0B8}, {0xB0B9, 0xB0B9, 0xB0B9}, {0xB0BA, 0xB0BA, 0xB0BA}, {0xB0BB, 0xB0BB, 0xB0BB}, {0xB0BC, 0xB0BC, 0xB0BC}, {0xB0BD, 0xB0BD, 0xB0BD}, {0xB0BE, 0xB0BE, 0xB0BE}, {0xB0BF, 0xB0BF, 0xB0BF}, {0xB0C0, 0xB0C0, 0xB0C0}, {0xB0C1, 0xB0C1, 0xB0C1}, {0xB0C2, 0xB0C2, 0xB0C2}, {0xB0C3, 0xB0C3, 0xB0C3}, {0xB0C4, 0xB0C4, 0xB0C4}, {0xB0C5, 0xB0C5, 0xB0C5}, {0xB0C6, 0xB0C6, 0xB0C6}, {0xB0C7, 0xB0C7, 0xB0C7}, {0xB0C8, 0xB0C8, 0xB0C8}, {0xB0C9, 0xB0C9, 0xB0C9}, {0xB0CA, 0xB0CA, 0xB0CA}, {0xB0CB, 0xB0CB, 0xB0CB}, {0xB0CC, 0xB0CC, 0xB0CC}, {0xB0CD, 0xB0CD, 0xB0CD}, {0xB0CE, 0xB0CE, 0xB0CE}, {0xB0CF, 0xB0CF, 0xB0CF}, {0xB0D0, 0xB0D0, 0xB0D0}, {0xB0D1, 0xB0D1, 0xB0D1}, {0xB0D2, 0xB0D2, 0xB0D2}, {0xB0D3, 0xB0D3, 0xB0D3}, {0xB0D4, 0xB0D4, 0xB0D4}, {0xB0D5, 0xB0D5, 0xB0D5}, {0xB0D6, 0xB0D6, 0xB0D6}, {0xB0D7, 0xB0D7, 0xB0D7}, {0xB0D8, 0xB0D8, 0xB0D8}, {0xB0D9, 0xB0D9, 0xB0D9}, {0xB0DA, 0xB0DA, 0xB0DA}, {0xB0DB, 0xB0DB, 0xB0DB}, {0xB0DC, 0xB0DC, 0xB0DC}, {0xB0DD, 0xB0DD, 0xB0DD}, {0xB0DE, 0xB0DE, 0xB0DE}, {0xB0DF, 0xB0DF, 0xB0DF}, {0xB0E0, 0xB0E0, 0xB0E0}, {0xB0E1, 0xB0E1, 0xB0E1}, {0xB0E2, 0xB0E2, 0xB0E2}, {0xB0E3, 0xB0E3, 0xB0E3}, {0xB0E4, 0xB0E4, 0xB0E4}, {0xB0E5, 0xB0E5, 0xB0E5}, {0xB0E6, 0xB0E6, 0xB0E6}, {0xB0E7, 0xB0E7, 0xB0E7}, {0xB0E8, 0xB0E8, 0xB0E8}, {0xB0E9, 0xB0E9, 0xB0E9}, {0xB0EA, 0xB0EA, 0xB0EA}, {0xB0EB, 0xB0EB, 0xB0EB}, {0xB0EC, 0xB0EC, 0xB0EC}, {0xB0ED, 0xB0ED, 0xB0ED}, {0xB0EE, 0xB0EE, 0xB0EE}, {0xB0EF, 0xB0EF, 0xB0EF}, {0xB0F0, 0xB0F0, 0xB0F0}, {0xB0F1, 0xB0F1, 0xB0F1}, {0xB0F2, 0xB0F2, 0xB0F2}, {0xB0F3, 0xB0F3, 0xB0F3}, {0xB0F4, 0xB0F4, 0xB0F4}, {0xB0F5, 0xB0F5, 0xB0F5}, {0xB0F6, 0xB0F6, 0xB0F6}, {0xB0F7, 0xB0F7, 0xB0F7}, {0xB0F8, 0xB0F8, 0xB0F8}, {0xB0F9, 0xB0F9, 0xB0F9}, {0xB0FA, 0xB0FA, 0xB0FA}, {0xB0FB, 0xB0FB, 0xB0FB}, {0xB0FC, 0xB0FC, 0xB0FC}, {0xB0FD, 0xB0FD, 0xB0FD}, {0xB0FE, 0xB0FE, 0xB0FE}, {0xB0FF, 0xB0FF, 0xB0FF}, {0xB100, 0xB100, 0xB100}, {0xB101, 0xB101, 0xB101}, {0xB102, 0xB102, 0xB102}, {0xB103, 0xB103, 0xB103}, {0xB104, 0xB104, 0xB104}, {0xB105, 0xB105, 0xB105}, {0xB106, 0xB106, 0xB106}, {0xB107, 0xB107, 0xB107}, {0xB108, 0xB108, 0xB108}, {0xB109, 0xB109, 0xB109}, {0xB10A, 0xB10A, 0xB10A}, {0xB10B, 0xB10B, 0xB10B}, {0xB10C, 0xB10C, 0xB10C}, {0xB10D, 0xB10D, 0xB10D}, {0xB10E, 0xB10E, 0xB10E}, {0xB10F, 0xB10F, 0xB10F}, {0xB110, 0xB110, 0xB110}, {0xB111, 0xB111, 0xB111}, {0xB112, 0xB112, 0xB112}, {0xB113, 0xB113, 0xB113}, {0xB114, 0xB114, 0xB114}, {0xB115, 0xB115, 0xB115}, {0xB116, 0xB116, 0xB116}, {0xB117, 0xB117, 0xB117}, {0xB118, 0xB118, 0xB118}, {0xB119, 0xB119, 0xB119}, {0xB11A, 0xB11A, 0xB11A}, {0xB11B, 0xB11B, 0xB11B}, {0xB11C, 0xB11C, 0xB11C}, {0xB11D, 0xB11D, 0xB11D}, {0xB11E, 0xB11E, 0xB11E}, {0xB11F, 0xB11F, 0xB11F}, {0xB120, 0xB120, 0xB120}, {0xB121, 0xB121, 0xB121}, {0xB122, 0xB122, 0xB122}, {0xB123, 0xB123, 0xB123}, {0xB124, 0xB124, 0xB124}, {0xB125, 0xB125, 0xB125}, {0xB126, 0xB126, 0xB126}, {0xB127, 0xB127, 0xB127}, {0xB128, 0xB128, 0xB128}, {0xB129, 0xB129, 0xB129}, {0xB12A, 0xB12A, 0xB12A}, {0xB12B, 0xB12B, 0xB12B}, {0xB12C, 0xB12C, 0xB12C}, {0xB12D, 0xB12D, 0xB12D}, {0xB12E, 0xB12E, 0xB12E}, {0xB12F, 0xB12F, 0xB12F}, {0xB130, 0xB130, 0xB130}, {0xB131, 0xB131, 0xB131}, {0xB132, 0xB132, 0xB132}, {0xB133, 0xB133, 0xB133}, {0xB134, 0xB134, 0xB134}, {0xB135, 0xB135, 0xB135}, {0xB136, 0xB136, 0xB136}, {0xB137, 0xB137, 0xB137}, {0xB138, 0xB138, 0xB138}, {0xB139, 0xB139, 0xB139}, {0xB13A, 0xB13A, 0xB13A}, {0xB13B, 0xB13B, 0xB13B}, {0xB13C, 0xB13C, 0xB13C}, {0xB13D, 0xB13D, 0xB13D}, {0xB13E, 0xB13E, 0xB13E}, {0xB13F, 0xB13F, 0xB13F}, {0xB140, 0xB140, 0xB140}, {0xB141, 0xB141, 0xB141}, {0xB142, 0xB142, 0xB142}, {0xB143, 0xB143, 0xB143}, {0xB144, 0xB144, 0xB144}, {0xB145, 0xB145, 0xB145}, {0xB146, 0xB146, 0xB146}, {0xB147, 0xB147, 0xB147}, {0xB148, 0xB148, 0xB148}, {0xB149, 0xB149, 0xB149}, {0xB14A, 0xB14A, 0xB14A}, {0xB14B, 0xB14B, 0xB14B}, {0xB14C, 0xB14C, 0xB14C}, {0xB14D, 0xB14D, 0xB14D}, {0xB14E, 0xB14E, 0xB14E}, {0xB14F, 0xB14F, 0xB14F}, {0xB150, 0xB150, 0xB150}, {0xB151, 0xB151, 0xB151}, {0xB152, 0xB152, 0xB152}, {0xB153, 0xB153, 0xB153}, {0xB154, 0xB154, 0xB154}, {0xB155, 0xB155, 0xB155}, {0xB156, 0xB156, 0xB156}, {0xB157, 0xB157, 0xB157}, {0xB158, 0xB158, 0xB158}, {0xB159, 0xB159, 0xB159}, {0xB15A, 0xB15A, 0xB15A}, {0xB15B, 0xB15B, 0xB15B}, {0xB15C, 0xB15C, 0xB15C}, {0xB15D, 0xB15D, 0xB15D}, {0xB15E, 0xB15E, 0xB15E}, {0xB15F, 0xB15F, 0xB15F}, {0xB160, 0xB160, 0xB160}, {0xB161, 0xB161, 0xB161}, {0xB162, 0xB162, 0xB162}, {0xB163, 0xB163, 0xB163}, {0xB164, 0xB164, 0xB164}, {0xB165, 0xB165, 0xB165}, {0xB166, 0xB166, 0xB166}, {0xB167, 0xB167, 0xB167}, {0xB168, 0xB168, 0xB168}, {0xB169, 0xB169, 0xB169}, {0xB16A, 0xB16A, 0xB16A}, {0xB16B, 0xB16B, 0xB16B}, {0xB16C, 0xB16C, 0xB16C}, {0xB16D, 0xB16D, 0xB16D}, {0xB16E, 0xB16E, 0xB16E}, {0xB16F, 0xB16F, 0xB16F}, {0xB170, 0xB170, 0xB170}, {0xB171, 0xB171, 0xB171}, {0xB172, 0xB172, 0xB172}, {0xB173, 0xB173, 0xB173}, {0xB174, 0xB174, 0xB174}, {0xB175, 0xB175, 0xB175}, {0xB176, 0xB176, 0xB176}, {0xB177, 0xB177, 0xB177}, {0xB178, 0xB178, 0xB178}, {0xB179, 0xB179, 0xB179}, {0xB17A, 0xB17A, 0xB17A}, {0xB17B, 0xB17B, 0xB17B}, {0xB17C, 0xB17C, 0xB17C}, {0xB17D, 0xB17D, 0xB17D}, {0xB17E, 0xB17E, 0xB17E}, {0xB17F, 0xB17F, 0xB17F}, {0xB180, 0xB180, 0xB180}, {0xB181, 0xB181, 0xB181}, {0xB182, 0xB182, 0xB182}, {0xB183, 0xB183, 0xB183}, {0xB184, 0xB184, 0xB184}, {0xB185, 0xB185, 0xB185}, {0xB186, 0xB186, 0xB186}, {0xB187, 0xB187, 0xB187}, {0xB188, 0xB188, 0xB188}, {0xB189, 0xB189, 0xB189}, {0xB18A, 0xB18A, 0xB18A}, {0xB18B, 0xB18B, 0xB18B}, {0xB18C, 0xB18C, 0xB18C}, {0xB18D, 0xB18D, 0xB18D}, {0xB18E, 0xB18E, 0xB18E}, {0xB18F, 0xB18F, 0xB18F}, {0xB190, 0xB190, 0xB190}, {0xB191, 0xB191, 0xB191}, {0xB192, 0xB192, 0xB192}, {0xB193, 0xB193, 0xB193}, {0xB194, 0xB194, 0xB194}, {0xB195, 0xB195, 0xB195}, {0xB196, 0xB196, 0xB196}, {0xB197, 0xB197, 0xB197}, {0xB198, 0xB198, 0xB198}, {0xB199, 0xB199, 0xB199}, {0xB19A, 0xB19A, 0xB19A}, {0xB19B, 0xB19B, 0xB19B}, {0xB19C, 0xB19C, 0xB19C}, {0xB19D, 0xB19D, 0xB19D}, {0xB19E, 0xB19E, 0xB19E}, {0xB19F, 0xB19F, 0xB19F}, {0xB1A0, 0xB1A0, 0xB1A0}, {0xB1A1, 0xB1A1, 0xB1A1}, {0xB1A2, 0xB1A2, 0xB1A2}, {0xB1A3, 0xB1A3, 0xB1A3}, {0xB1A4, 0xB1A4, 0xB1A4}, {0xB1A5, 0xB1A5, 0xB1A5}, {0xB1A6, 0xB1A6, 0xB1A6}, {0xB1A7, 0xB1A7, 0xB1A7}, {0xB1A8, 0xB1A8, 0xB1A8}, {0xB1A9, 0xB1A9, 0xB1A9}, {0xB1AA, 0xB1AA, 0xB1AA}, {0xB1AB, 0xB1AB, 0xB1AB}, {0xB1AC, 0xB1AC, 0xB1AC}, {0xB1AD, 0xB1AD, 0xB1AD}, {0xB1AE, 0xB1AE, 0xB1AE}, {0xB1AF, 0xB1AF, 0xB1AF}, {0xB1B0, 0xB1B0, 0xB1B0}, {0xB1B1, 0xB1B1, 0xB1B1}, {0xB1B2, 0xB1B2, 0xB1B2}, {0xB1B3, 0xB1B3, 0xB1B3}, {0xB1B4, 0xB1B4, 0xB1B4}, {0xB1B5, 0xB1B5, 0xB1B5}, {0xB1B6, 0xB1B6, 0xB1B6}, {0xB1B7, 0xB1B7, 0xB1B7}, {0xB1B8, 0xB1B8, 0xB1B8}, {0xB1B9, 0xB1B9, 0xB1B9}, {0xB1BA, 0xB1BA, 0xB1BA}, {0xB1BB, 0xB1BB, 0xB1BB}, {0xB1BC, 0xB1BC, 0xB1BC}, {0xB1BD, 0xB1BD, 0xB1BD}, {0xB1BE, 0xB1BE, 0xB1BE}, {0xB1BF, 0xB1BF, 0xB1BF}, {0xB1C0, 0xB1C0, 0xB1C0}, {0xB1C1, 0xB1C1, 0xB1C1}, {0xB1C2, 0xB1C2, 0xB1C2}, {0xB1C3, 0xB1C3, 0xB1C3}, {0xB1C4, 0xB1C4, 0xB1C4}, {0xB1C5, 0xB1C5, 0xB1C5}, {0xB1C6, 0xB1C6, 0xB1C6}, {0xB1C7, 0xB1C7, 0xB1C7}, {0xB1C8, 0xB1C8, 0xB1C8}, {0xB1C9, 0xB1C9, 0xB1C9}, {0xB1CA, 0xB1CA, 0xB1CA}, {0xB1CB, 0xB1CB, 0xB1CB}, {0xB1CC, 0xB1CC, 0xB1CC}, {0xB1CD, 0xB1CD, 0xB1CD}, {0xB1CE, 0xB1CE, 0xB1CE}, {0xB1CF, 0xB1CF, 0xB1CF}, {0xB1D0, 0xB1D0, 0xB1D0}, {0xB1D1, 0xB1D1, 0xB1D1}, {0xB1D2, 0xB1D2, 0xB1D2}, {0xB1D3, 0xB1D3, 0xB1D3}, {0xB1D4, 0xB1D4, 0xB1D4}, {0xB1D5, 0xB1D5, 0xB1D5}, {0xB1D6, 0xB1D6, 0xB1D6}, {0xB1D7, 0xB1D7, 0xB1D7}, {0xB1D8, 0xB1D8, 0xB1D8}, {0xB1D9, 0xB1D9, 0xB1D9}, {0xB1DA, 0xB1DA, 0xB1DA}, {0xB1DB, 0xB1DB, 0xB1DB}, {0xB1DC, 0xB1DC, 0xB1DC}, {0xB1DD, 0xB1DD, 0xB1DD}, {0xB1DE, 0xB1DE, 0xB1DE}, {0xB1DF, 0xB1DF, 0xB1DF}, {0xB1E0, 0xB1E0, 0xB1E0}, {0xB1E1, 0xB1E1, 0xB1E1}, {0xB1E2, 0xB1E2, 0xB1E2}, {0xB1E3, 0xB1E3, 0xB1E3}, {0xB1E4, 0xB1E4, 0xB1E4}, {0xB1E5, 0xB1E5, 0xB1E5}, {0xB1E6, 0xB1E6, 0xB1E6}, {0xB1E7, 0xB1E7, 0xB1E7}, {0xB1E8, 0xB1E8, 0xB1E8}, {0xB1E9, 0xB1E9, 0xB1E9}, {0xB1EA, 0xB1EA, 0xB1EA}, {0xB1EB, 0xB1EB, 0xB1EB}, {0xB1EC, 0xB1EC, 0xB1EC}, {0xB1ED, 0xB1ED, 0xB1ED}, {0xB1EE, 0xB1EE, 0xB1EE}, {0xB1EF, 0xB1EF, 0xB1EF}, {0xB1F0, 0xB1F0, 0xB1F0}, {0xB1F1, 0xB1F1, 0xB1F1}, {0xB1F2, 0xB1F2, 0xB1F2}, {0xB1F3, 0xB1F3, 0xB1F3}, {0xB1F4, 0xB1F4, 0xB1F4}, {0xB1F5, 0xB1F5, 0xB1F5}, {0xB1F6, 0xB1F6, 0xB1F6}, {0xB1F7, 0xB1F7, 0xB1F7}, {0xB1F8, 0xB1F8, 0xB1F8}, {0xB1F9, 0xB1F9, 0xB1F9}, {0xB1FA, 0xB1FA, 0xB1FA}, {0xB1FB, 0xB1FB, 0xB1FB}, {0xB1FC, 0xB1FC, 0xB1FC}, {0xB1FD, 0xB1FD, 0xB1FD}, {0xB1FE, 0xB1FE, 0xB1FE}, {0xB1FF, 0xB1FF, 0xB1FF}, {0xB200, 0xB200, 0xB200}, {0xB201, 0xB201, 0xB201}, {0xB202, 0xB202, 0xB202}, {0xB203, 0xB203, 0xB203}, {0xB204, 0xB204, 0xB204}, {0xB205, 0xB205, 0xB205}, {0xB206, 0xB206, 0xB206}, {0xB207, 0xB207, 0xB207}, {0xB208, 0xB208, 0xB208}, {0xB209, 0xB209, 0xB209}, {0xB20A, 0xB20A, 0xB20A}, {0xB20B, 0xB20B, 0xB20B}, {0xB20C, 0xB20C, 0xB20C}, {0xB20D, 0xB20D, 0xB20D}, {0xB20E, 0xB20E, 0xB20E}, {0xB20F, 0xB20F, 0xB20F}, {0xB210, 0xB210, 0xB210}, {0xB211, 0xB211, 0xB211}, {0xB212, 0xB212, 0xB212}, {0xB213, 0xB213, 0xB213}, {0xB214, 0xB214, 0xB214}, {0xB215, 0xB215, 0xB215}, {0xB216, 0xB216, 0xB216}, {0xB217, 0xB217, 0xB217}, {0xB218, 0xB218, 0xB218}, {0xB219, 0xB219, 0xB219}, {0xB21A, 0xB21A, 0xB21A}, {0xB21B, 0xB21B, 0xB21B}, {0xB21C, 0xB21C, 0xB21C}, {0xB21D, 0xB21D, 0xB21D}, {0xB21E, 0xB21E, 0xB21E}, {0xB21F, 0xB21F, 0xB21F}, {0xB220, 0xB220, 0xB220}, {0xB221, 0xB221, 0xB221}, {0xB222, 0xB222, 0xB222}, {0xB223, 0xB223, 0xB223}, {0xB224, 0xB224, 0xB224}, {0xB225, 0xB225, 0xB225}, {0xB226, 0xB226, 0xB226}, {0xB227, 0xB227, 0xB227}, {0xB228, 0xB228, 0xB228}, {0xB229, 0xB229, 0xB229}, {0xB22A, 0xB22A, 0xB22A}, {0xB22B, 0xB22B, 0xB22B}, {0xB22C, 0xB22C, 0xB22C}, {0xB22D, 0xB22D, 0xB22D}, {0xB22E, 0xB22E, 0xB22E}, {0xB22F, 0xB22F, 0xB22F}, {0xB230, 0xB230, 0xB230}, {0xB231, 0xB231, 0xB231}, {0xB232, 0xB232, 0xB232}, {0xB233, 0xB233, 0xB233}, {0xB234, 0xB234, 0xB234}, {0xB235, 0xB235, 0xB235}, {0xB236, 0xB236, 0xB236}, {0xB237, 0xB237, 0xB237}, {0xB238, 0xB238, 0xB238}, {0xB239, 0xB239, 0xB239}, {0xB23A, 0xB23A, 0xB23A}, {0xB23B, 0xB23B, 0xB23B}, {0xB23C, 0xB23C, 0xB23C}, {0xB23D, 0xB23D, 0xB23D}, {0xB23E, 0xB23E, 0xB23E}, {0xB23F, 0xB23F, 0xB23F}, {0xB240, 0xB240, 0xB240}, {0xB241, 0xB241, 0xB241}, {0xB242, 0xB242, 0xB242}, {0xB243, 0xB243, 0xB243}, {0xB244, 0xB244, 0xB244}, {0xB245, 0xB245, 0xB245}, {0xB246, 0xB246, 0xB246}, {0xB247, 0xB247, 0xB247}, {0xB248, 0xB248, 0xB248}, {0xB249, 0xB249, 0xB249}, {0xB24A, 0xB24A, 0xB24A}, {0xB24B, 0xB24B, 0xB24B}, {0xB24C, 0xB24C, 0xB24C}, {0xB24D, 0xB24D, 0xB24D}, {0xB24E, 0xB24E, 0xB24E}, {0xB24F, 0xB24F, 0xB24F}, {0xB250, 0xB250, 0xB250}, {0xB251, 0xB251, 0xB251}, {0xB252, 0xB252, 0xB252}, {0xB253, 0xB253, 0xB253}, {0xB254, 0xB254, 0xB254}, {0xB255, 0xB255, 0xB255}, {0xB256, 0xB256, 0xB256}, {0xB257, 0xB257, 0xB257}, {0xB258, 0xB258, 0xB258}, {0xB259, 0xB259, 0xB259}, {0xB25A, 0xB25A, 0xB25A}, {0xB25B, 0xB25B, 0xB25B}, {0xB25C, 0xB25C, 0xB25C}, {0xB25D, 0xB25D, 0xB25D}, {0xB25E, 0xB25E, 0xB25E}, {0xB25F, 0xB25F, 0xB25F}, {0xB260, 0xB260, 0xB260}, {0xB261, 0xB261, 0xB261}, {0xB262, 0xB262, 0xB262}, {0xB263, 0xB263, 0xB263}, {0xB264, 0xB264, 0xB264}, {0xB265, 0xB265, 0xB265}, {0xB266, 0xB266, 0xB266}, {0xB267, 0xB267, 0xB267}, {0xB268, 0xB268, 0xB268}, {0xB269, 0xB269, 0xB269}, {0xB26A, 0xB26A, 0xB26A}, {0xB26B, 0xB26B, 0xB26B}, {0xB26C, 0xB26C, 0xB26C}, {0xB26D, 0xB26D, 0xB26D}, {0xB26E, 0xB26E, 0xB26E}, {0xB26F, 0xB26F, 0xB26F}, {0xB270, 0xB270, 0xB270}, {0xB271, 0xB271, 0xB271}, {0xB272, 0xB272, 0xB272}, {0xB273, 0xB273, 0xB273}, {0xB274, 0xB274, 0xB274}, {0xB275, 0xB275, 0xB275}, {0xB276, 0xB276, 0xB276}, {0xB277, 0xB277, 0xB277}, {0xB278, 0xB278, 0xB278}, {0xB279, 0xB279, 0xB279}, {0xB27A, 0xB27A, 0xB27A}, {0xB27B, 0xB27B, 0xB27B}, {0xB27C, 0xB27C, 0xB27C}, {0xB27D, 0xB27D, 0xB27D}, {0xB27E, 0xB27E, 0xB27E}, {0xB27F, 0xB27F, 0xB27F}, {0xB280, 0xB280, 0xB280}, {0xB281, 0xB281, 0xB281}, {0xB282, 0xB282, 0xB282}, {0xB283, 0xB283, 0xB283}, {0xB284, 0xB284, 0xB284}, {0xB285, 0xB285, 0xB285}, {0xB286, 0xB286, 0xB286}, {0xB287, 0xB287, 0xB287}, {0xB288, 0xB288, 0xB288}, {0xB289, 0xB289, 0xB289}, {0xB28A, 0xB28A, 0xB28A}, {0xB28B, 0xB28B, 0xB28B}, {0xB28C, 0xB28C, 0xB28C}, {0xB28D, 0xB28D, 0xB28D}, {0xB28E, 0xB28E, 0xB28E}, {0xB28F, 0xB28F, 0xB28F}, {0xB290, 0xB290, 0xB290}, {0xB291, 0xB291, 0xB291}, {0xB292, 0xB292, 0xB292}, {0xB293, 0xB293, 0xB293}, {0xB294, 0xB294, 0xB294}, {0xB295, 0xB295, 0xB295}, {0xB296, 0xB296, 0xB296}, {0xB297, 0xB297, 0xB297}, {0xB298, 0xB298, 0xB298}, {0xB299, 0xB299, 0xB299}, {0xB29A, 0xB29A, 0xB29A}, {0xB29B, 0xB29B, 0xB29B}, {0xB29C, 0xB29C, 0xB29C}, {0xB29D, 0xB29D, 0xB29D}, {0xB29E, 0xB29E, 0xB29E}, {0xB29F, 0xB29F, 0xB29F}, {0xB2A0, 0xB2A0, 0xB2A0}, {0xB2A1, 0xB2A1, 0xB2A1}, {0xB2A2, 0xB2A2, 0xB2A2}, {0xB2A3, 0xB2A3, 0xB2A3}, {0xB2A4, 0xB2A4, 0xB2A4}, {0xB2A5, 0xB2A5, 0xB2A5}, {0xB2A6, 0xB2A6, 0xB2A6}, {0xB2A7, 0xB2A7, 0xB2A7}, {0xB2A8, 0xB2A8, 0xB2A8}, {0xB2A9, 0xB2A9, 0xB2A9}, {0xB2AA, 0xB2AA, 0xB2AA}, {0xB2AB, 0xB2AB, 0xB2AB}, {0xB2AC, 0xB2AC, 0xB2AC}, {0xB2AD, 0xB2AD, 0xB2AD}, {0xB2AE, 0xB2AE, 0xB2AE}, {0xB2AF, 0xB2AF, 0xB2AF}, {0xB2B0, 0xB2B0, 0xB2B0}, {0xB2B1, 0xB2B1, 0xB2B1}, {0xB2B2, 0xB2B2, 0xB2B2}, {0xB2B3, 0xB2B3, 0xB2B3}, {0xB2B4, 0xB2B4, 0xB2B4}, {0xB2B5, 0xB2B5, 0xB2B5}, {0xB2B6, 0xB2B6, 0xB2B6}, {0xB2B7, 0xB2B7, 0xB2B7}, {0xB2B8, 0xB2B8, 0xB2B8}, {0xB2B9, 0xB2B9, 0xB2B9}, {0xB2BA, 0xB2BA, 0xB2BA}, {0xB2BB, 0xB2BB, 0xB2BB}, {0xB2BC, 0xB2BC, 0xB2BC}, {0xB2BD, 0xB2BD, 0xB2BD}, {0xB2BE, 0xB2BE, 0xB2BE}, {0xB2BF, 0xB2BF, 0xB2BF}, {0xB2C0, 0xB2C0, 0xB2C0}, {0xB2C1, 0xB2C1, 0xB2C1}, {0xB2C2, 0xB2C2, 0xB2C2}, {0xB2C3, 0xB2C3, 0xB2C3}, {0xB2C4, 0xB2C4, 0xB2C4}, {0xB2C5, 0xB2C5, 0xB2C5}, {0xB2C6, 0xB2C6, 0xB2C6}, {0xB2C7, 0xB2C7, 0xB2C7}, {0xB2C8, 0xB2C8, 0xB2C8}, {0xB2C9, 0xB2C9, 0xB2C9}, {0xB2CA, 0xB2CA, 0xB2CA}, {0xB2CB, 0xB2CB, 0xB2CB}, {0xB2CC, 0xB2CC, 0xB2CC}, {0xB2CD, 0xB2CD, 0xB2CD}, {0xB2CE, 0xB2CE, 0xB2CE}, {0xB2CF, 0xB2CF, 0xB2CF}, {0xB2D0, 0xB2D0, 0xB2D0}, {0xB2D1, 0xB2D1, 0xB2D1}, {0xB2D2, 0xB2D2, 0xB2D2}, {0xB2D3, 0xB2D3, 0xB2D3}, {0xB2D4, 0xB2D4, 0xB2D4}, {0xB2D5, 0xB2D5, 0xB2D5}, {0xB2D6, 0xB2D6, 0xB2D6}, {0xB2D7, 0xB2D7, 0xB2D7}, {0xB2D8, 0xB2D8, 0xB2D8}, {0xB2D9, 0xB2D9, 0xB2D9}, {0xB2DA, 0xB2DA, 0xB2DA}, {0xB2DB, 0xB2DB, 0xB2DB}, {0xB2DC, 0xB2DC, 0xB2DC}, {0xB2DD, 0xB2DD, 0xB2DD}, {0xB2DE, 0xB2DE, 0xB2DE}, {0xB2DF, 0xB2DF, 0xB2DF}, {0xB2E0, 0xB2E0, 0xB2E0}, {0xB2E1, 0xB2E1, 0xB2E1}, {0xB2E2, 0xB2E2, 0xB2E2}, {0xB2E3, 0xB2E3, 0xB2E3}, {0xB2E4, 0xB2E4, 0xB2E4}, {0xB2E5, 0xB2E5, 0xB2E5}, {0xB2E6, 0xB2E6, 0xB2E6}, {0xB2E7, 0xB2E7, 0xB2E7}, {0xB2E8, 0xB2E8, 0xB2E8}, {0xB2E9, 0xB2E9, 0xB2E9}, {0xB2EA, 0xB2EA, 0xB2EA}, {0xB2EB, 0xB2EB, 0xB2EB}, {0xB2EC, 0xB2EC, 0xB2EC}, {0xB2ED, 0xB2ED, 0xB2ED}, {0xB2EE, 0xB2EE, 0xB2EE}, {0xB2EF, 0xB2EF, 0xB2EF}, {0xB2F0, 0xB2F0, 0xB2F0}, {0xB2F1, 0xB2F1, 0xB2F1}, {0xB2F2, 0xB2F2, 0xB2F2}, {0xB2F3, 0xB2F3, 0xB2F3}, {0xB2F4, 0xB2F4, 0xB2F4}, {0xB2F5, 0xB2F5, 0xB2F5}, {0xB2F6, 0xB2F6, 0xB2F6}, {0xB2F7, 0xB2F7, 0xB2F7}, {0xB2F8, 0xB2F8, 0xB2F8}, {0xB2F9, 0xB2F9, 0xB2F9}, {0xB2FA, 0xB2FA, 0xB2FA}, {0xB2FB, 0xB2FB, 0xB2FB}, {0xB2FC, 0xB2FC, 0xB2FC}, {0xB2FD, 0xB2FD, 0xB2FD}, {0xB2FE, 0xB2FE, 0xB2FE}, {0xB2FF, 0xB2FF, 0xB2FF}, {0xB300, 0xB300, 0xB300}, {0xB301, 0xB301, 0xB301}, {0xB302, 0xB302, 0xB302}, {0xB303, 0xB303, 0xB303}, {0xB304, 0xB304, 0xB304}, {0xB305, 0xB305, 0xB305}, {0xB306, 0xB306, 0xB306}, {0xB307, 0xB307, 0xB307}, {0xB308, 0xB308, 0xB308}, {0xB309, 0xB309, 0xB309}, {0xB30A, 0xB30A, 0xB30A}, {0xB30B, 0xB30B, 0xB30B}, {0xB30C, 0xB30C, 0xB30C}, {0xB30D, 0xB30D, 0xB30D}, {0xB30E, 0xB30E, 0xB30E}, {0xB30F, 0xB30F, 0xB30F}, {0xB310, 0xB310, 0xB310}, {0xB311, 0xB311, 0xB311}, {0xB312, 0xB312, 0xB312}, {0xB313, 0xB313, 0xB313}, {0xB314, 0xB314, 0xB314}, {0xB315, 0xB315, 0xB315}, {0xB316, 0xB316, 0xB316}, {0xB317, 0xB317, 0xB317}, {0xB318, 0xB318, 0xB318}, {0xB319, 0xB319, 0xB319}, {0xB31A, 0xB31A, 0xB31A}, {0xB31B, 0xB31B, 0xB31B}, {0xB31C, 0xB31C, 0xB31C}, {0xB31D, 0xB31D, 0xB31D}, {0xB31E, 0xB31E, 0xB31E}, {0xB31F, 0xB31F, 0xB31F}, {0xB320, 0xB320, 0xB320}, {0xB321, 0xB321, 0xB321}, {0xB322, 0xB322, 0xB322}, {0xB323, 0xB323, 0xB323}, {0xB324, 0xB324, 0xB324}, {0xB325, 0xB325, 0xB325}, {0xB326, 0xB326, 0xB326}, {0xB327, 0xB327, 0xB327}, {0xB328, 0xB328, 0xB328}, {0xB329, 0xB329, 0xB329}, {0xB32A, 0xB32A, 0xB32A}, {0xB32B, 0xB32B, 0xB32B}, {0xB32C, 0xB32C, 0xB32C}, {0xB32D, 0xB32D, 0xB32D}, {0xB32E, 0xB32E, 0xB32E}, {0xB32F, 0xB32F, 0xB32F}, {0xB330, 0xB330, 0xB330}, {0xB331, 0xB331, 0xB331}, {0xB332, 0xB332, 0xB332}, {0xB333, 0xB333, 0xB333}, {0xB334, 0xB334, 0xB334}, {0xB335, 0xB335, 0xB335}, {0xB336, 0xB336, 0xB336}, {0xB337, 0xB337, 0xB337}, {0xB338, 0xB338, 0xB338}, {0xB339, 0xB339, 0xB339}, {0xB33A, 0xB33A, 0xB33A}, {0xB33B, 0xB33B, 0xB33B}, {0xB33C, 0xB33C, 0xB33C}, {0xB33D, 0xB33D, 0xB33D}, {0xB33E, 0xB33E, 0xB33E}, {0xB33F, 0xB33F, 0xB33F}, {0xB340, 0xB340, 0xB340}, {0xB341, 0xB341, 0xB341}, {0xB342, 0xB342, 0xB342}, {0xB343, 0xB343, 0xB343}, {0xB344, 0xB344, 0xB344}, {0xB345, 0xB345, 0xB345}, {0xB346, 0xB346, 0xB346}, {0xB347, 0xB347, 0xB347}, {0xB348, 0xB348, 0xB348}, {0xB349, 0xB349, 0xB349}, {0xB34A, 0xB34A, 0xB34A}, {0xB34B, 0xB34B, 0xB34B}, {0xB34C, 0xB34C, 0xB34C}, {0xB34D, 0xB34D, 0xB34D}, {0xB34E, 0xB34E, 0xB34E}, {0xB34F, 0xB34F, 0xB34F}, {0xB350, 0xB350, 0xB350}, {0xB351, 0xB351, 0xB351}, {0xB352, 0xB352, 0xB352}, {0xB353, 0xB353, 0xB353}, {0xB354, 0xB354, 0xB354}, {0xB355, 0xB355, 0xB355}, {0xB356, 0xB356, 0xB356}, {0xB357, 0xB357, 0xB357}, {0xB358, 0xB358, 0xB358}, {0xB359, 0xB359, 0xB359}, {0xB35A, 0xB35A, 0xB35A}, {0xB35B, 0xB35B, 0xB35B}, {0xB35C, 0xB35C, 0xB35C}, {0xB35D, 0xB35D, 0xB35D}, {0xB35E, 0xB35E, 0xB35E}, {0xB35F, 0xB35F, 0xB35F}, {0xB360, 0xB360, 0xB360}, {0xB361, 0xB361, 0xB361}, {0xB362, 0xB362, 0xB362}, {0xB363, 0xB363, 0xB363}, {0xB364, 0xB364, 0xB364}, {0xB365, 0xB365, 0xB365}, {0xB366, 0xB366, 0xB366}, {0xB367, 0xB367, 0xB367}, {0xB368, 0xB368, 0xB368}, {0xB369, 0xB369, 0xB369}, {0xB36A, 0xB36A, 0xB36A}, {0xB36B, 0xB36B, 0xB36B}, {0xB36C, 0xB36C, 0xB36C}, {0xB36D, 0xB36D, 0xB36D}, {0xB36E, 0xB36E, 0xB36E}, {0xB36F, 0xB36F, 0xB36F}, {0xB370, 0xB370, 0xB370}, {0xB371, 0xB371, 0xB371}, {0xB372, 0xB372, 0xB372}, {0xB373, 0xB373, 0xB373}, {0xB374, 0xB374, 0xB374}, {0xB375, 0xB375, 0xB375}, {0xB376, 0xB376, 0xB376}, {0xB377, 0xB377, 0xB377}, {0xB378, 0xB378, 0xB378}, {0xB379, 0xB379, 0xB379}, {0xB37A, 0xB37A, 0xB37A}, {0xB37B, 0xB37B, 0xB37B}, {0xB37C, 0xB37C, 0xB37C}, {0xB37D, 0xB37D, 0xB37D}, {0xB37E, 0xB37E, 0xB37E}, {0xB37F, 0xB37F, 0xB37F}, {0xB380, 0xB380, 0xB380}, {0xB381, 0xB381, 0xB381}, {0xB382, 0xB382, 0xB382}, {0xB383, 0xB383, 0xB383}, {0xB384, 0xB384, 0xB384}, {0xB385, 0xB385, 0xB385}, {0xB386, 0xB386, 0xB386}, {0xB387, 0xB387, 0xB387}, {0xB388, 0xB388, 0xB388}, {0xB389, 0xB389, 0xB389}, {0xB38A, 0xB38A, 0xB38A}, {0xB38B, 0xB38B, 0xB38B}, {0xB38C, 0xB38C, 0xB38C}, {0xB38D, 0xB38D, 0xB38D}, {0xB38E, 0xB38E, 0xB38E}, {0xB38F, 0xB38F, 0xB38F}, {0xB390, 0xB390, 0xB390}, {0xB391, 0xB391, 0xB391}, {0xB392, 0xB392, 0xB392}, {0xB393, 0xB393, 0xB393}, {0xB394, 0xB394, 0xB394}, {0xB395, 0xB395, 0xB395}, {0xB396, 0xB396, 0xB396}, {0xB397, 0xB397, 0xB397}, {0xB398, 0xB398, 0xB398}, {0xB399, 0xB399, 0xB399}, {0xB39A, 0xB39A, 0xB39A}, {0xB39B, 0xB39B, 0xB39B}, {0xB39C, 0xB39C, 0xB39C}, {0xB39D, 0xB39D, 0xB39D}, {0xB39E, 0xB39E, 0xB39E}, {0xB39F, 0xB39F, 0xB39F}, {0xB3A0, 0xB3A0, 0xB3A0}, {0xB3A1, 0xB3A1, 0xB3A1}, {0xB3A2, 0xB3A2, 0xB3A2}, {0xB3A3, 0xB3A3, 0xB3A3}, {0xB3A4, 0xB3A4, 0xB3A4}, {0xB3A5, 0xB3A5, 0xB3A5}, {0xB3A6, 0xB3A6, 0xB3A6}, {0xB3A7, 0xB3A7, 0xB3A7}, {0xB3A8, 0xB3A8, 0xB3A8}, {0xB3A9, 0xB3A9, 0xB3A9}, {0xB3AA, 0xB3AA, 0xB3AA}, {0xB3AB, 0xB3AB, 0xB3AB}, {0xB3AC, 0xB3AC, 0xB3AC}, {0xB3AD, 0xB3AD, 0xB3AD}, {0xB3AE, 0xB3AE, 0xB3AE}, {0xB3AF, 0xB3AF, 0xB3AF}, {0xB3B0, 0xB3B0, 0xB3B0}, {0xB3B1, 0xB3B1, 0xB3B1}, {0xB3B2, 0xB3B2, 0xB3B2}, {0xB3B3, 0xB3B3, 0xB3B3}, {0xB3B4, 0xB3B4, 0xB3B4}, {0xB3B5, 0xB3B5, 0xB3B5}, {0xB3B6, 0xB3B6, 0xB3B6}, {0xB3B7, 0xB3B7, 0xB3B7}, {0xB3B8, 0xB3B8, 0xB3B8}, {0xB3B9, 0xB3B9, 0xB3B9}, {0xB3BA, 0xB3BA, 0xB3BA}, {0xB3BB, 0xB3BB, 0xB3BB}, {0xB3BC, 0xB3BC, 0xB3BC}, {0xB3BD, 0xB3BD, 0xB3BD}, {0xB3BE, 0xB3BE, 0xB3BE}, {0xB3BF, 0xB3BF, 0xB3BF}, {0xB3C0, 0xB3C0, 0xB3C0}, {0xB3C1, 0xB3C1, 0xB3C1}, {0xB3C2, 0xB3C2, 0xB3C2}, {0xB3C3, 0xB3C3, 0xB3C3}, {0xB3C4, 0xB3C4, 0xB3C4}, {0xB3C5, 0xB3C5, 0xB3C5}, {0xB3C6, 0xB3C6, 0xB3C6}, {0xB3C7, 0xB3C7, 0xB3C7}, {0xB3C8, 0xB3C8, 0xB3C8}, {0xB3C9, 0xB3C9, 0xB3C9}, {0xB3CA, 0xB3CA, 0xB3CA}, {0xB3CB, 0xB3CB, 0xB3CB}, {0xB3CC, 0xB3CC, 0xB3CC}, {0xB3CD, 0xB3CD, 0xB3CD}, {0xB3CE, 0xB3CE, 0xB3CE}, {0xB3CF, 0xB3CF, 0xB3CF}, {0xB3D0, 0xB3D0, 0xB3D0}, {0xB3D1, 0xB3D1, 0xB3D1}, {0xB3D2, 0xB3D2, 0xB3D2}, {0xB3D3, 0xB3D3, 0xB3D3}, {0xB3D4, 0xB3D4, 0xB3D4}, {0xB3D5, 0xB3D5, 0xB3D5}, {0xB3D6, 0xB3D6, 0xB3D6}, {0xB3D7, 0xB3D7, 0xB3D7}, {0xB3D8, 0xB3D8, 0xB3D8}, {0xB3D9, 0xB3D9, 0xB3D9}, {0xB3DA, 0xB3DA, 0xB3DA}, {0xB3DB, 0xB3DB, 0xB3DB}, {0xB3DC, 0xB3DC, 0xB3DC}, {0xB3DD, 0xB3DD, 0xB3DD}, {0xB3DE, 0xB3DE, 0xB3DE}, {0xB3DF, 0xB3DF, 0xB3DF}, {0xB3E0, 0xB3E0, 0xB3E0}, {0xB3E1, 0xB3E1, 0xB3E1}, {0xB3E2, 0xB3E2, 0xB3E2}, {0xB3E3, 0xB3E3, 0xB3E3}, {0xB3E4, 0xB3E4, 0xB3E4}, {0xB3E5, 0xB3E5, 0xB3E5}, {0xB3E6, 0xB3E6, 0xB3E6}, {0xB3E7, 0xB3E7, 0xB3E7}, {0xB3E8, 0xB3E8, 0xB3E8}, {0xB3E9, 0xB3E9, 0xB3E9}, {0xB3EA, 0xB3EA, 0xB3EA}, {0xB3EB, 0xB3EB, 0xB3EB}, {0xB3EC, 0xB3EC, 0xB3EC}, {0xB3ED, 0xB3ED, 0xB3ED}, {0xB3EE, 0xB3EE, 0xB3EE}, {0xB3EF, 0xB3EF, 0xB3EF}, {0xB3F0, 0xB3F0, 0xB3F0}, {0xB3F1, 0xB3F1, 0xB3F1}, {0xB3F2, 0xB3F2, 0xB3F2}, {0xB3F3, 0xB3F3, 0xB3F3}, {0xB3F4, 0xB3F4, 0xB3F4}, {0xB3F5, 0xB3F5, 0xB3F5}, {0xB3F6, 0xB3F6, 0xB3F6}, {0xB3F7, 0xB3F7, 0xB3F7}, {0xB3F8, 0xB3F8, 0xB3F8}, {0xB3F9, 0xB3F9, 0xB3F9}, {0xB3FA, 0xB3FA, 0xB3FA}, {0xB3FB, 0xB3FB, 0xB3FB}, {0xB3FC, 0xB3FC, 0xB3FC}, {0xB3FD, 0xB3FD, 0xB3FD}, {0xB3FE, 0xB3FE, 0xB3FE}, {0xB3FF, 0xB3FF, 0xB3FF}, {0xB400, 0xB400, 0xB400}, {0xB401, 0xB401, 0xB401}, {0xB402, 0xB402, 0xB402}, {0xB403, 0xB403, 0xB403}, {0xB404, 0xB404, 0xB404}, {0xB405, 0xB405, 0xB405}, {0xB406, 0xB406, 0xB406}, {0xB407, 0xB407, 0xB407}, {0xB408, 0xB408, 0xB408}, {0xB409, 0xB409, 0xB409}, {0xB40A, 0xB40A, 0xB40A}, {0xB40B, 0xB40B, 0xB40B}, {0xB40C, 0xB40C, 0xB40C}, {0xB40D, 0xB40D, 0xB40D}, {0xB40E, 0xB40E, 0xB40E}, {0xB40F, 0xB40F, 0xB40F}, {0xB410, 0xB410, 0xB410}, {0xB411, 0xB411, 0xB411}, {0xB412, 0xB412, 0xB412}, {0xB413, 0xB413, 0xB413}, {0xB414, 0xB414, 0xB414}, {0xB415, 0xB415, 0xB415}, {0xB416, 0xB416, 0xB416}, {0xB417, 0xB417, 0xB417}, {0xB418, 0xB418, 0xB418}, {0xB419, 0xB419, 0xB419}, {0xB41A, 0xB41A, 0xB41A}, {0xB41B, 0xB41B, 0xB41B}, {0xB41C, 0xB41C, 0xB41C}, {0xB41D, 0xB41D, 0xB41D}, {0xB41E, 0xB41E, 0xB41E}, {0xB41F, 0xB41F, 0xB41F}, {0xB420, 0xB420, 0xB420}, {0xB421, 0xB421, 0xB421}, {0xB422, 0xB422, 0xB422}, {0xB423, 0xB423, 0xB423}, {0xB424, 0xB424, 0xB424}, {0xB425, 0xB425, 0xB425}, {0xB426, 0xB426, 0xB426}, {0xB427, 0xB427, 0xB427}, {0xB428, 0xB428, 0xB428}, {0xB429, 0xB429, 0xB429}, {0xB42A, 0xB42A, 0xB42A}, {0xB42B, 0xB42B, 0xB42B}, {0xB42C, 0xB42C, 0xB42C}, {0xB42D, 0xB42D, 0xB42D}, {0xB42E, 0xB42E, 0xB42E}, {0xB42F, 0xB42F, 0xB42F}, {0xB430, 0xB430, 0xB430}, {0xB431, 0xB431, 0xB431}, {0xB432, 0xB432, 0xB432}, {0xB433, 0xB433, 0xB433}, {0xB434, 0xB434, 0xB434}, {0xB435, 0xB435, 0xB435}, {0xB436, 0xB436, 0xB436}, {0xB437, 0xB437, 0xB437}, {0xB438, 0xB438, 0xB438}, {0xB439, 0xB439, 0xB439}, {0xB43A, 0xB43A, 0xB43A}, {0xB43B, 0xB43B, 0xB43B}, {0xB43C, 0xB43C, 0xB43C}, {0xB43D, 0xB43D, 0xB43D}, {0xB43E, 0xB43E, 0xB43E}, {0xB43F, 0xB43F, 0xB43F}, {0xB440, 0xB440, 0xB440}, {0xB441, 0xB441, 0xB441}, {0xB442, 0xB442, 0xB442}, {0xB443, 0xB443, 0xB443}, {0xB444, 0xB444, 0xB444}, {0xB445, 0xB445, 0xB445}, {0xB446, 0xB446, 0xB446}, {0xB447, 0xB447, 0xB447}, {0xB448, 0xB448, 0xB448}, {0xB449, 0xB449, 0xB449}, {0xB44A, 0xB44A, 0xB44A}, {0xB44B, 0xB44B, 0xB44B}, {0xB44C, 0xB44C, 0xB44C}, {0xB44D, 0xB44D, 0xB44D}, {0xB44E, 0xB44E, 0xB44E}, {0xB44F, 0xB44F, 0xB44F}, {0xB450, 0xB450, 0xB450}, {0xB451, 0xB451, 0xB451}, {0xB452, 0xB452, 0xB452}, {0xB453, 0xB453, 0xB453}, {0xB454, 0xB454, 0xB454}, {0xB455, 0xB455, 0xB455}, {0xB456, 0xB456, 0xB456}, {0xB457, 0xB457, 0xB457}, {0xB458, 0xB458, 0xB458}, {0xB459, 0xB459, 0xB459}, {0xB45A, 0xB45A, 0xB45A}, {0xB45B, 0xB45B, 0xB45B}, {0xB45C, 0xB45C, 0xB45C}, {0xB45D, 0xB45D, 0xB45D}, {0xB45E, 0xB45E, 0xB45E}, {0xB45F, 0xB45F, 0xB45F}, {0xB460, 0xB460, 0xB460}, {0xB461, 0xB461, 0xB461}, {0xB462, 0xB462, 0xB462}, {0xB463, 0xB463, 0xB463}, {0xB464, 0xB464, 0xB464}, {0xB465, 0xB465, 0xB465}, {0xB466, 0xB466, 0xB466}, {0xB467, 0xB467, 0xB467}, {0xB468, 0xB468, 0xB468}, {0xB469, 0xB469, 0xB469}, {0xB46A, 0xB46A, 0xB46A}, {0xB46B, 0xB46B, 0xB46B}, {0xB46C, 0xB46C, 0xB46C}, {0xB46D, 0xB46D, 0xB46D}, {0xB46E, 0xB46E, 0xB46E}, {0xB46F, 0xB46F, 0xB46F}, {0xB470, 0xB470, 0xB470}, {0xB471, 0xB471, 0xB471}, {0xB472, 0xB472, 0xB472}, {0xB473, 0xB473, 0xB473}, {0xB474, 0xB474, 0xB474}, {0xB475, 0xB475, 0xB475}, {0xB476, 0xB476, 0xB476}, {0xB477, 0xB477, 0xB477}, {0xB478, 0xB478, 0xB478}, {0xB479, 0xB479, 0xB479}, {0xB47A, 0xB47A, 0xB47A}, {0xB47B, 0xB47B, 0xB47B}, {0xB47C, 0xB47C, 0xB47C}, {0xB47D, 0xB47D, 0xB47D}, {0xB47E, 0xB47E, 0xB47E}, {0xB47F, 0xB47F, 0xB47F}, {0xB480, 0xB480, 0xB480}, {0xB481, 0xB481, 0xB481}, {0xB482, 0xB482, 0xB482}, {0xB483, 0xB483, 0xB483}, {0xB484, 0xB484, 0xB484}, {0xB485, 0xB485, 0xB485}, {0xB486, 0xB486, 0xB486}, {0xB487, 0xB487, 0xB487}, {0xB488, 0xB488, 0xB488}, {0xB489, 0xB489, 0xB489}, {0xB48A, 0xB48A, 0xB48A}, {0xB48B, 0xB48B, 0xB48B}, {0xB48C, 0xB48C, 0xB48C}, {0xB48D, 0xB48D, 0xB48D}, {0xB48E, 0xB48E, 0xB48E}, {0xB48F, 0xB48F, 0xB48F}, {0xB490, 0xB490, 0xB490}, {0xB491, 0xB491, 0xB491}, {0xB492, 0xB492, 0xB492}, {0xB493, 0xB493, 0xB493}, {0xB494, 0xB494, 0xB494}, {0xB495, 0xB495, 0xB495}, {0xB496, 0xB496, 0xB496}, {0xB497, 0xB497, 0xB497}, {0xB498, 0xB498, 0xB498}, {0xB499, 0xB499, 0xB499}, {0xB49A, 0xB49A, 0xB49A}, {0xB49B, 0xB49B, 0xB49B}, {0xB49C, 0xB49C, 0xB49C}, {0xB49D, 0xB49D, 0xB49D}, {0xB49E, 0xB49E, 0xB49E}, {0xB49F, 0xB49F, 0xB49F}, {0xB4A0, 0xB4A0, 0xB4A0}, {0xB4A1, 0xB4A1, 0xB4A1}, {0xB4A2, 0xB4A2, 0xB4A2}, {0xB4A3, 0xB4A3, 0xB4A3}, {0xB4A4, 0xB4A4, 0xB4A4}, {0xB4A5, 0xB4A5, 0xB4A5}, {0xB4A6, 0xB4A6, 0xB4A6}, {0xB4A7, 0xB4A7, 0xB4A7}, {0xB4A8, 0xB4A8, 0xB4A8}, {0xB4A9, 0xB4A9, 0xB4A9}, {0xB4AA, 0xB4AA, 0xB4AA}, {0xB4AB, 0xB4AB, 0xB4AB}, {0xB4AC, 0xB4AC, 0xB4AC}, {0xB4AD, 0xB4AD, 0xB4AD}, {0xB4AE, 0xB4AE, 0xB4AE}, {0xB4AF, 0xB4AF, 0xB4AF}, {0xB4B0, 0xB4B0, 0xB4B0}, {0xB4B1, 0xB4B1, 0xB4B1}, {0xB4B2, 0xB4B2, 0xB4B2}, {0xB4B3, 0xB4B3, 0xB4B3}, {0xB4B4, 0xB4B4, 0xB4B4}, {0xB4B5, 0xB4B5, 0xB4B5}, {0xB4B6, 0xB4B6, 0xB4B6}, {0xB4B7, 0xB4B7, 0xB4B7}, {0xB4B8, 0xB4B8, 0xB4B8}, {0xB4B9, 0xB4B9, 0xB4B9}, {0xB4BA, 0xB4BA, 0xB4BA}, {0xB4BB, 0xB4BB, 0xB4BB}, {0xB4BC, 0xB4BC, 0xB4BC}, {0xB4BD, 0xB4BD, 0xB4BD}, {0xB4BE, 0xB4BE, 0xB4BE}, {0xB4BF, 0xB4BF, 0xB4BF}, {0xB4C0, 0xB4C0, 0xB4C0}, {0xB4C1, 0xB4C1, 0xB4C1}, {0xB4C2, 0xB4C2, 0xB4C2}, {0xB4C3, 0xB4C3, 0xB4C3}, {0xB4C4, 0xB4C4, 0xB4C4}, {0xB4C5, 0xB4C5, 0xB4C5}, {0xB4C6, 0xB4C6, 0xB4C6}, {0xB4C7, 0xB4C7, 0xB4C7}, {0xB4C8, 0xB4C8, 0xB4C8}, {0xB4C9, 0xB4C9, 0xB4C9}, {0xB4CA, 0xB4CA, 0xB4CA}, {0xB4CB, 0xB4CB, 0xB4CB}, {0xB4CC, 0xB4CC, 0xB4CC}, {0xB4CD, 0xB4CD, 0xB4CD}, {0xB4CE, 0xB4CE, 0xB4CE}, {0xB4CF, 0xB4CF, 0xB4CF}, {0xB4D0, 0xB4D0, 0xB4D0}, {0xB4D1, 0xB4D1, 0xB4D1}, {0xB4D2, 0xB4D2, 0xB4D2}, {0xB4D3, 0xB4D3, 0xB4D3}, {0xB4D4, 0xB4D4, 0xB4D4}, {0xB4D5, 0xB4D5, 0xB4D5}, {0xB4D6, 0xB4D6, 0xB4D6}, {0xB4D7, 0xB4D7, 0xB4D7}, {0xB4D8, 0xB4D8, 0xB4D8}, {0xB4D9, 0xB4D9, 0xB4D9}, {0xB4DA, 0xB4DA, 0xB4DA}, {0xB4DB, 0xB4DB, 0xB4DB}, {0xB4DC, 0xB4DC, 0xB4DC}, {0xB4DD, 0xB4DD, 0xB4DD}, {0xB4DE, 0xB4DE, 0xB4DE}, {0xB4DF, 0xB4DF, 0xB4DF}, {0xB4E0, 0xB4E0, 0xB4E0}, {0xB4E1, 0xB4E1, 0xB4E1}, {0xB4E2, 0xB4E2, 0xB4E2}, {0xB4E3, 0xB4E3, 0xB4E3}, {0xB4E4, 0xB4E4, 0xB4E4}, {0xB4E5, 0xB4E5, 0xB4E5}, {0xB4E6, 0xB4E6, 0xB4E6}, {0xB4E7, 0xB4E7, 0xB4E7}, {0xB4E8, 0xB4E8, 0xB4E8}, {0xB4E9, 0xB4E9, 0xB4E9}, {0xB4EA, 0xB4EA, 0xB4EA}, {0xB4EB, 0xB4EB, 0xB4EB}, {0xB4EC, 0xB4EC, 0xB4EC}, {0xB4ED, 0xB4ED, 0xB4ED}, {0xB4EE, 0xB4EE, 0xB4EE}, {0xB4EF, 0xB4EF, 0xB4EF}, {0xB4F0, 0xB4F0, 0xB4F0}, {0xB4F1, 0xB4F1, 0xB4F1}, {0xB4F2, 0xB4F2, 0xB4F2}, {0xB4F3, 0xB4F3, 0xB4F3}, {0xB4F4, 0xB4F4, 0xB4F4}, {0xB4F5, 0xB4F5, 0xB4F5}, {0xB4F6, 0xB4F6, 0xB4F6}, {0xB4F7, 0xB4F7, 0xB4F7}, {0xB4F8, 0xB4F8, 0xB4F8}, {0xB4F9, 0xB4F9, 0xB4F9}, {0xB4FA, 0xB4FA, 0xB4FA}, {0xB4FB, 0xB4FB, 0xB4FB}, {0xB4FC, 0xB4FC, 0xB4FC}, {0xB4FD, 0xB4FD, 0xB4FD}, {0xB4FE, 0xB4FE, 0xB4FE}, {0xB4FF, 0xB4FF, 0xB4FF}, {0xB500, 0xB500, 0xB500}, {0xB501, 0xB501, 0xB501}, {0xB502, 0xB502, 0xB502}, {0xB503, 0xB503, 0xB503}, {0xB504, 0xB504, 0xB504}, {0xB505, 0xB505, 0xB505}, {0xB506, 0xB506, 0xB506}, {0xB507, 0xB507, 0xB507}, {0xB508, 0xB508, 0xB508}, {0xB509, 0xB509, 0xB509}, {0xB50A, 0xB50A, 0xB50A}, {0xB50B, 0xB50B, 0xB50B}, {0xB50C, 0xB50C, 0xB50C}, {0xB50D, 0xB50D, 0xB50D}, {0xB50E, 0xB50E, 0xB50E}, {0xB50F, 0xB50F, 0xB50F}, {0xB510, 0xB510, 0xB510}, {0xB511, 0xB511, 0xB511}, {0xB512, 0xB512, 0xB512}, {0xB513, 0xB513, 0xB513}, {0xB514, 0xB514, 0xB514}, {0xB515, 0xB515, 0xB515}, {0xB516, 0xB516, 0xB516}, {0xB517, 0xB517, 0xB517}, {0xB518, 0xB518, 0xB518}, {0xB519, 0xB519, 0xB519}, {0xB51A, 0xB51A, 0xB51A}, {0xB51B, 0xB51B, 0xB51B}, {0xB51C, 0xB51C, 0xB51C}, {0xB51D, 0xB51D, 0xB51D}, {0xB51E, 0xB51E, 0xB51E}, {0xB51F, 0xB51F, 0xB51F}, {0xB520, 0xB520, 0xB520}, {0xB521, 0xB521, 0xB521}, {0xB522, 0xB522, 0xB522}, {0xB523, 0xB523, 0xB523}, {0xB524, 0xB524, 0xB524}, {0xB525, 0xB525, 0xB525}, {0xB526, 0xB526, 0xB526}, {0xB527, 0xB527, 0xB527}, {0xB528, 0xB528, 0xB528}, {0xB529, 0xB529, 0xB529}, {0xB52A, 0xB52A, 0xB52A}, {0xB52B, 0xB52B, 0xB52B}, {0xB52C, 0xB52C, 0xB52C}, {0xB52D, 0xB52D, 0xB52D}, {0xB52E, 0xB52E, 0xB52E}, {0xB52F, 0xB52F, 0xB52F}, {0xB530, 0xB530, 0xB530}, {0xB531, 0xB531, 0xB531}, {0xB532, 0xB532, 0xB532}, {0xB533, 0xB533, 0xB533}, {0xB534, 0xB534, 0xB534}, {0xB535, 0xB535, 0xB535}, {0xB536, 0xB536, 0xB536}, {0xB537, 0xB537, 0xB537}, {0xB538, 0xB538, 0xB538}, {0xB539, 0xB539, 0xB539}, {0xB53A, 0xB53A, 0xB53A}, {0xB53B, 0xB53B, 0xB53B}, {0xB53C, 0xB53C, 0xB53C}, {0xB53D, 0xB53D, 0xB53D}, {0xB53E, 0xB53E, 0xB53E}, {0xB53F, 0xB53F, 0xB53F}, {0xB540, 0xB540, 0xB540}, {0xB541, 0xB541, 0xB541}, {0xB542, 0xB542, 0xB542}, {0xB543, 0xB543, 0xB543}, {0xB544, 0xB544, 0xB544}, {0xB545, 0xB545, 0xB545}, {0xB546, 0xB546, 0xB546}, {0xB547, 0xB547, 0xB547}, {0xB548, 0xB548, 0xB548}, {0xB549, 0xB549, 0xB549}, {0xB54A, 0xB54A, 0xB54A}, {0xB54B, 0xB54B, 0xB54B}, {0xB54C, 0xB54C, 0xB54C}, {0xB54D, 0xB54D, 0xB54D}, {0xB54E, 0xB54E, 0xB54E}, {0xB54F, 0xB54F, 0xB54F}, {0xB550, 0xB550, 0xB550}, {0xB551, 0xB551, 0xB551}, {0xB552, 0xB552, 0xB552}, {0xB553, 0xB553, 0xB553}, {0xB554, 0xB554, 0xB554}, {0xB555, 0xB555, 0xB555}, {0xB556, 0xB556, 0xB556}, {0xB557, 0xB557, 0xB557}, {0xB558, 0xB558, 0xB558}, {0xB559, 0xB559, 0xB559}, {0xB55A, 0xB55A, 0xB55A}, {0xB55B, 0xB55B, 0xB55B}, {0xB55C, 0xB55C, 0xB55C}, {0xB55D, 0xB55D, 0xB55D}, {0xB55E, 0xB55E, 0xB55E}, {0xB55F, 0xB55F, 0xB55F}, {0xB560, 0xB560, 0xB560}, {0xB561, 0xB561, 0xB561}, {0xB562, 0xB562, 0xB562}, {0xB563, 0xB563, 0xB563}, {0xB564, 0xB564, 0xB564}, {0xB565, 0xB565, 0xB565}, {0xB566, 0xB566, 0xB566}, {0xB567, 0xB567, 0xB567}, {0xB568, 0xB568, 0xB568}, {0xB569, 0xB569, 0xB569}, {0xB56A, 0xB56A, 0xB56A}, {0xB56B, 0xB56B, 0xB56B}, {0xB56C, 0xB56C, 0xB56C}, {0xB56D, 0xB56D, 0xB56D}, {0xB56E, 0xB56E, 0xB56E}, {0xB56F, 0xB56F, 0xB56F}, {0xB570, 0xB570, 0xB570}, {0xB571, 0xB571, 0xB571}, {0xB572, 0xB572, 0xB572}, {0xB573, 0xB573, 0xB573}, {0xB574, 0xB574, 0xB574}, {0xB575, 0xB575, 0xB575}, {0xB576, 0xB576, 0xB576}, {0xB577, 0xB577, 0xB577}, {0xB578, 0xB578, 0xB578}, {0xB579, 0xB579, 0xB579}, {0xB57A, 0xB57A, 0xB57A}, {0xB57B, 0xB57B, 0xB57B}, {0xB57C, 0xB57C, 0xB57C}, {0xB57D, 0xB57D, 0xB57D}, {0xB57E, 0xB57E, 0xB57E}, {0xB57F, 0xB57F, 0xB57F}, {0xB580, 0xB580, 0xB580}, {0xB581, 0xB581, 0xB581}, {0xB582, 0xB582, 0xB582}, {0xB583, 0xB583, 0xB583}, {0xB584, 0xB584, 0xB584}, {0xB585, 0xB585, 0xB585}, {0xB586, 0xB586, 0xB586}, {0xB587, 0xB587, 0xB587}, {0xB588, 0xB588, 0xB588}, {0xB589, 0xB589, 0xB589}, {0xB58A, 0xB58A, 0xB58A}, {0xB58B, 0xB58B, 0xB58B}, {0xB58C, 0xB58C, 0xB58C}, {0xB58D, 0xB58D, 0xB58D}, {0xB58E, 0xB58E, 0xB58E}, {0xB58F, 0xB58F, 0xB58F}, {0xB590, 0xB590, 0xB590}, {0xB591, 0xB591, 0xB591}, {0xB592, 0xB592, 0xB592}, {0xB593, 0xB593, 0xB593}, {0xB594, 0xB594, 0xB594}, {0xB595, 0xB595, 0xB595}, {0xB596, 0xB596, 0xB596}, {0xB597, 0xB597, 0xB597}, {0xB598, 0xB598, 0xB598}, {0xB599, 0xB599, 0xB599}, {0xB59A, 0xB59A, 0xB59A}, {0xB59B, 0xB59B, 0xB59B}, {0xB59C, 0xB59C, 0xB59C}, {0xB59D, 0xB59D, 0xB59D}, {0xB59E, 0xB59E, 0xB59E}, {0xB59F, 0xB59F, 0xB59F}, {0xB5A0, 0xB5A0, 0xB5A0}, {0xB5A1, 0xB5A1, 0xB5A1}, {0xB5A2, 0xB5A2, 0xB5A2}, {0xB5A3, 0xB5A3, 0xB5A3}, {0xB5A4, 0xB5A4, 0xB5A4}, {0xB5A5, 0xB5A5, 0xB5A5}, {0xB5A6, 0xB5A6, 0xB5A6}, {0xB5A7, 0xB5A7, 0xB5A7}, {0xB5A8, 0xB5A8, 0xB5A8}, {0xB5A9, 0xB5A9, 0xB5A9}, {0xB5AA, 0xB5AA, 0xB5AA}, {0xB5AB, 0xB5AB, 0xB5AB}, {0xB5AC, 0xB5AC, 0xB5AC}, {0xB5AD, 0xB5AD, 0xB5AD}, {0xB5AE, 0xB5AE, 0xB5AE}, {0xB5AF, 0xB5AF, 0xB5AF}, {0xB5B0, 0xB5B0, 0xB5B0}, {0xB5B1, 0xB5B1, 0xB5B1}, {0xB5B2, 0xB5B2, 0xB5B2}, {0xB5B3, 0xB5B3, 0xB5B3}, {0xB5B4, 0xB5B4, 0xB5B4}, {0xB5B5, 0xB5B5, 0xB5B5}, {0xB5B6, 0xB5B6, 0xB5B6}, {0xB5B7, 0xB5B7, 0xB5B7}, {0xB5B8, 0xB5B8, 0xB5B8}, {0xB5B9, 0xB5B9, 0xB5B9}, {0xB5BA, 0xB5BA, 0xB5BA}, {0xB5BB, 0xB5BB, 0xB5BB}, {0xB5BC, 0xB5BC, 0xB5BC}, {0xB5BD, 0xB5BD, 0xB5BD}, {0xB5BE, 0xB5BE, 0xB5BE}, {0xB5BF, 0xB5BF, 0xB5BF}, {0xB5C0, 0xB5C0, 0xB5C0}, {0xB5C1, 0xB5C1, 0xB5C1}, {0xB5C2, 0xB5C2, 0xB5C2}, {0xB5C3, 0xB5C3, 0xB5C3}, {0xB5C4, 0xB5C4, 0xB5C4}, {0xB5C5, 0xB5C5, 0xB5C5}, {0xB5C6, 0xB5C6, 0xB5C6}, {0xB5C7, 0xB5C7, 0xB5C7}, {0xB5C8, 0xB5C8, 0xB5C8}, {0xB5C9, 0xB5C9, 0xB5C9}, {0xB5CA, 0xB5CA, 0xB5CA}, {0xB5CB, 0xB5CB, 0xB5CB}, {0xB5CC, 0xB5CC, 0xB5CC}, {0xB5CD, 0xB5CD, 0xB5CD}, {0xB5CE, 0xB5CE, 0xB5CE}, {0xB5CF, 0xB5CF, 0xB5CF}, {0xB5D0, 0xB5D0, 0xB5D0}, {0xB5D1, 0xB5D1, 0xB5D1}, {0xB5D2, 0xB5D2, 0xB5D2}, {0xB5D3, 0xB5D3, 0xB5D3}, {0xB5D4, 0xB5D4, 0xB5D4}, {0xB5D5, 0xB5D5, 0xB5D5}, {0xB5D6, 0xB5D6, 0xB5D6}, {0xB5D7, 0xB5D7, 0xB5D7}, {0xB5D8, 0xB5D8, 0xB5D8}, {0xB5D9, 0xB5D9, 0xB5D9}, {0xB5DA, 0xB5DA, 0xB5DA}, {0xB5DB, 0xB5DB, 0xB5DB}, {0xB5DC, 0xB5DC, 0xB5DC}, {0xB5DD, 0xB5DD, 0xB5DD}, {0xB5DE, 0xB5DE, 0xB5DE}, {0xB5DF, 0xB5DF, 0xB5DF}, {0xB5E0, 0xB5E0, 0xB5E0}, {0xB5E1, 0xB5E1, 0xB5E1}, {0xB5E2, 0xB5E2, 0xB5E2}, {0xB5E3, 0xB5E3, 0xB5E3}, {0xB5E4, 0xB5E4, 0xB5E4}, {0xB5E5, 0xB5E5, 0xB5E5}, {0xB5E6, 0xB5E6, 0xB5E6}, {0xB5E7, 0xB5E7, 0xB5E7}, {0xB5E8, 0xB5E8, 0xB5E8}, {0xB5E9, 0xB5E9, 0xB5E9}, {0xB5EA, 0xB5EA, 0xB5EA}, {0xB5EB, 0xB5EB, 0xB5EB}, {0xB5EC, 0xB5EC, 0xB5EC}, {0xB5ED, 0xB5ED, 0xB5ED}, {0xB5EE, 0xB5EE, 0xB5EE}, {0xB5EF, 0xB5EF, 0xB5EF}, {0xB5F0, 0xB5F0, 0xB5F0}, {0xB5F1, 0xB5F1, 0xB5F1}, {0xB5F2, 0xB5F2, 0xB5F2}, {0xB5F3, 0xB5F3, 0xB5F3}, {0xB5F4, 0xB5F4, 0xB5F4}, {0xB5F5, 0xB5F5, 0xB5F5}, {0xB5F6, 0xB5F6, 0xB5F6}, {0xB5F7, 0xB5F7, 0xB5F7}, {0xB5F8, 0xB5F8, 0xB5F8}, {0xB5F9, 0xB5F9, 0xB5F9}, {0xB5FA, 0xB5FA, 0xB5FA}, {0xB5FB, 0xB5FB, 0xB5FB}, {0xB5FC, 0xB5FC, 0xB5FC}, {0xB5FD, 0xB5FD, 0xB5FD}, {0xB5FE, 0xB5FE, 0xB5FE}, {0xB5FF, 0xB5FF, 0xB5FF}, {0xB600, 0xB600, 0xB600}, {0xB601, 0xB601, 0xB601}, {0xB602, 0xB602, 0xB602}, {0xB603, 0xB603, 0xB603}, {0xB604, 0xB604, 0xB604}, {0xB605, 0xB605, 0xB605}, {0xB606, 0xB606, 0xB606}, {0xB607, 0xB607, 0xB607}, {0xB608, 0xB608, 0xB608}, {0xB609, 0xB609, 0xB609}, {0xB60A, 0xB60A, 0xB60A}, {0xB60B, 0xB60B, 0xB60B}, {0xB60C, 0xB60C, 0xB60C}, {0xB60D, 0xB60D, 0xB60D}, {0xB60E, 0xB60E, 0xB60E}, {0xB60F, 0xB60F, 0xB60F}, {0xB610, 0xB610, 0xB610}, {0xB611, 0xB611, 0xB611}, {0xB612, 0xB612, 0xB612}, {0xB613, 0xB613, 0xB613}, {0xB614, 0xB614, 0xB614}, {0xB615, 0xB615, 0xB615}, {0xB616, 0xB616, 0xB616}, {0xB617, 0xB617, 0xB617}, {0xB618, 0xB618, 0xB618}, {0xB619, 0xB619, 0xB619}, {0xB61A, 0xB61A, 0xB61A}, {0xB61B, 0xB61B, 0xB61B}, {0xB61C, 0xB61C, 0xB61C}, {0xB61D, 0xB61D, 0xB61D}, {0xB61E, 0xB61E, 0xB61E}, {0xB61F, 0xB61F, 0xB61F}, {0xB620, 0xB620, 0xB620}, {0xB621, 0xB621, 0xB621}, {0xB622, 0xB622, 0xB622}, {0xB623, 0xB623, 0xB623}, {0xB624, 0xB624, 0xB624}, {0xB625, 0xB625, 0xB625}, {0xB626, 0xB626, 0xB626}, {0xB627, 0xB627, 0xB627}, {0xB628, 0xB628, 0xB628}, {0xB629, 0xB629, 0xB629}, {0xB62A, 0xB62A, 0xB62A}, {0xB62B, 0xB62B, 0xB62B}, {0xB62C, 0xB62C, 0xB62C}, {0xB62D, 0xB62D, 0xB62D}, {0xB62E, 0xB62E, 0xB62E}, {0xB62F, 0xB62F, 0xB62F}, {0xB630, 0xB630, 0xB630}, {0xB631, 0xB631, 0xB631}, {0xB632, 0xB632, 0xB632}, {0xB633, 0xB633, 0xB633}, {0xB634, 0xB634, 0xB634}, {0xB635, 0xB635, 0xB635}, {0xB636, 0xB636, 0xB636}, {0xB637, 0xB637, 0xB637}, {0xB638, 0xB638, 0xB638}, {0xB639, 0xB639, 0xB639}, {0xB63A, 0xB63A, 0xB63A}, {0xB63B, 0xB63B, 0xB63B}, {0xB63C, 0xB63C, 0xB63C}, {0xB63D, 0xB63D, 0xB63D}, {0xB63E, 0xB63E, 0xB63E}, {0xB63F, 0xB63F, 0xB63F}, {0xB640, 0xB640, 0xB640}, {0xB641, 0xB641, 0xB641}, {0xB642, 0xB642, 0xB642}, {0xB643, 0xB643, 0xB643}, {0xB644, 0xB644, 0xB644}, {0xB645, 0xB645, 0xB645}, {0xB646, 0xB646, 0xB646}, {0xB647, 0xB647, 0xB647}, {0xB648, 0xB648, 0xB648}, {0xB649, 0xB649, 0xB649}, {0xB64A, 0xB64A, 0xB64A}, {0xB64B, 0xB64B, 0xB64B}, {0xB64C, 0xB64C, 0xB64C}, {0xB64D, 0xB64D, 0xB64D}, {0xB64E, 0xB64E, 0xB64E}, {0xB64F, 0xB64F, 0xB64F}, {0xB650, 0xB650, 0xB650}, {0xB651, 0xB651, 0xB651}, {0xB652, 0xB652, 0xB652}, {0xB653, 0xB653, 0xB653}, {0xB654, 0xB654, 0xB654}, {0xB655, 0xB655, 0xB655}, {0xB656, 0xB656, 0xB656}, {0xB657, 0xB657, 0xB657}, {0xB658, 0xB658, 0xB658}, {0xB659, 0xB659, 0xB659}, {0xB65A, 0xB65A, 0xB65A}, {0xB65B, 0xB65B, 0xB65B}, {0xB65C, 0xB65C, 0xB65C}, {0xB65D, 0xB65D, 0xB65D}, {0xB65E, 0xB65E, 0xB65E}, {0xB65F, 0xB65F, 0xB65F}, {0xB660, 0xB660, 0xB660}, {0xB661, 0xB661, 0xB661}, {0xB662, 0xB662, 0xB662}, {0xB663, 0xB663, 0xB663}, {0xB664, 0xB664, 0xB664}, {0xB665, 0xB665, 0xB665}, {0xB666, 0xB666, 0xB666}, {0xB667, 0xB667, 0xB667}, {0xB668, 0xB668, 0xB668}, {0xB669, 0xB669, 0xB669}, {0xB66A, 0xB66A, 0xB66A}, {0xB66B, 0xB66B, 0xB66B}, {0xB66C, 0xB66C, 0xB66C}, {0xB66D, 0xB66D, 0xB66D}, {0xB66E, 0xB66E, 0xB66E}, {0xB66F, 0xB66F, 0xB66F}, {0xB670, 0xB670, 0xB670}, {0xB671, 0xB671, 0xB671}, {0xB672, 0xB672, 0xB672}, {0xB673, 0xB673, 0xB673}, {0xB674, 0xB674, 0xB674}, {0xB675, 0xB675, 0xB675}, {0xB676, 0xB676, 0xB676}, {0xB677, 0xB677, 0xB677}, {0xB678, 0xB678, 0xB678}, {0xB679, 0xB679, 0xB679}, {0xB67A, 0xB67A, 0xB67A}, {0xB67B, 0xB67B, 0xB67B}, {0xB67C, 0xB67C, 0xB67C}, {0xB67D, 0xB67D, 0xB67D}, {0xB67E, 0xB67E, 0xB67E}, {0xB67F, 0xB67F, 0xB67F}, {0xB680, 0xB680, 0xB680}, {0xB681, 0xB681, 0xB681}, {0xB682, 0xB682, 0xB682}, {0xB683, 0xB683, 0xB683}, {0xB684, 0xB684, 0xB684}, {0xB685, 0xB685, 0xB685}, {0xB686, 0xB686, 0xB686}, {0xB687, 0xB687, 0xB687}, {0xB688, 0xB688, 0xB688}, {0xB689, 0xB689, 0xB689}, {0xB68A, 0xB68A, 0xB68A}, {0xB68B, 0xB68B, 0xB68B}, {0xB68C, 0xB68C, 0xB68C}, {0xB68D, 0xB68D, 0xB68D}, {0xB68E, 0xB68E, 0xB68E}, {0xB68F, 0xB68F, 0xB68F}, {0xB690, 0xB690, 0xB690}, {0xB691, 0xB691, 0xB691}, {0xB692, 0xB692, 0xB692}, {0xB693, 0xB693, 0xB693}, {0xB694, 0xB694, 0xB694}, {0xB695, 0xB695, 0xB695}, {0xB696, 0xB696, 0xB696}, {0xB697, 0xB697, 0xB697}, {0xB698, 0xB698, 0xB698}, {0xB699, 0xB699, 0xB699}, {0xB69A, 0xB69A, 0xB69A}, {0xB69B, 0xB69B, 0xB69B}, {0xB69C, 0xB69C, 0xB69C}, {0xB69D, 0xB69D, 0xB69D}, {0xB69E, 0xB69E, 0xB69E}, {0xB69F, 0xB69F, 0xB69F}, {0xB6A0, 0xB6A0, 0xB6A0}, {0xB6A1, 0xB6A1, 0xB6A1}, {0xB6A2, 0xB6A2, 0xB6A2}, {0xB6A3, 0xB6A3, 0xB6A3}, {0xB6A4, 0xB6A4, 0xB6A4}, {0xB6A5, 0xB6A5, 0xB6A5}, {0xB6A6, 0xB6A6, 0xB6A6}, {0xB6A7, 0xB6A7, 0xB6A7}, {0xB6A8, 0xB6A8, 0xB6A8}, {0xB6A9, 0xB6A9, 0xB6A9}, {0xB6AA, 0xB6AA, 0xB6AA}, {0xB6AB, 0xB6AB, 0xB6AB}, {0xB6AC, 0xB6AC, 0xB6AC}, {0xB6AD, 0xB6AD, 0xB6AD}, {0xB6AE, 0xB6AE, 0xB6AE}, {0xB6AF, 0xB6AF, 0xB6AF}, {0xB6B0, 0xB6B0, 0xB6B0}, {0xB6B1, 0xB6B1, 0xB6B1}, {0xB6B2, 0xB6B2, 0xB6B2}, {0xB6B3, 0xB6B3, 0xB6B3}, {0xB6B4, 0xB6B4, 0xB6B4}, {0xB6B5, 0xB6B5, 0xB6B5}, {0xB6B6, 0xB6B6, 0xB6B6}, {0xB6B7, 0xB6B7, 0xB6B7}, {0xB6B8, 0xB6B8, 0xB6B8}, {0xB6B9, 0xB6B9, 0xB6B9}, {0xB6BA, 0xB6BA, 0xB6BA}, {0xB6BB, 0xB6BB, 0xB6BB}, {0xB6BC, 0xB6BC, 0xB6BC}, {0xB6BD, 0xB6BD, 0xB6BD}, {0xB6BE, 0xB6BE, 0xB6BE}, {0xB6BF, 0xB6BF, 0xB6BF}, {0xB6C0, 0xB6C0, 0xB6C0}, {0xB6C1, 0xB6C1, 0xB6C1}, {0xB6C2, 0xB6C2, 0xB6C2}, {0xB6C3, 0xB6C3, 0xB6C3}, {0xB6C4, 0xB6C4, 0xB6C4}, {0xB6C5, 0xB6C5, 0xB6C5}, {0xB6C6, 0xB6C6, 0xB6C6}, {0xB6C7, 0xB6C7, 0xB6C7}, {0xB6C8, 0xB6C8, 0xB6C8}, {0xB6C9, 0xB6C9, 0xB6C9}, {0xB6CA, 0xB6CA, 0xB6CA}, {0xB6CB, 0xB6CB, 0xB6CB}, {0xB6CC, 0xB6CC, 0xB6CC}, {0xB6CD, 0xB6CD, 0xB6CD}, {0xB6CE, 0xB6CE, 0xB6CE}, {0xB6CF, 0xB6CF, 0xB6CF}, {0xB6D0, 0xB6D0, 0xB6D0}, {0xB6D1, 0xB6D1, 0xB6D1}, {0xB6D2, 0xB6D2, 0xB6D2}, {0xB6D3, 0xB6D3, 0xB6D3}, {0xB6D4, 0xB6D4, 0xB6D4}, {0xB6D5, 0xB6D5, 0xB6D5}, {0xB6D6, 0xB6D6, 0xB6D6}, {0xB6D7, 0xB6D7, 0xB6D7}, {0xB6D8, 0xB6D8, 0xB6D8}, {0xB6D9, 0xB6D9, 0xB6D9}, {0xB6DA, 0xB6DA, 0xB6DA}, {0xB6DB, 0xB6DB, 0xB6DB}, {0xB6DC, 0xB6DC, 0xB6DC}, {0xB6DD, 0xB6DD, 0xB6DD}, {0xB6DE, 0xB6DE, 0xB6DE}, {0xB6DF, 0xB6DF, 0xB6DF}, {0xB6E0, 0xB6E0, 0xB6E0}, {0xB6E1, 0xB6E1, 0xB6E1}, {0xB6E2, 0xB6E2, 0xB6E2}, {0xB6E3, 0xB6E3, 0xB6E3}, {0xB6E4, 0xB6E4, 0xB6E4}, {0xB6E5, 0xB6E5, 0xB6E5}, {0xB6E6, 0xB6E6, 0xB6E6}, {0xB6E7, 0xB6E7, 0xB6E7}, {0xB6E8, 0xB6E8, 0xB6E8}, {0xB6E9, 0xB6E9, 0xB6E9}, {0xB6EA, 0xB6EA, 0xB6EA}, {0xB6EB, 0xB6EB, 0xB6EB}, {0xB6EC, 0xB6EC, 0xB6EC}, {0xB6ED, 0xB6ED, 0xB6ED}, {0xB6EE, 0xB6EE, 0xB6EE}, {0xB6EF, 0xB6EF, 0xB6EF}, {0xB6F0, 0xB6F0, 0xB6F0}, {0xB6F1, 0xB6F1, 0xB6F1}, {0xB6F2, 0xB6F2, 0xB6F2}, {0xB6F3, 0xB6F3, 0xB6F3}, {0xB6F4, 0xB6F4, 0xB6F4}, {0xB6F5, 0xB6F5, 0xB6F5}, {0xB6F6, 0xB6F6, 0xB6F6}, {0xB6F7, 0xB6F7, 0xB6F7}, {0xB6F8, 0xB6F8, 0xB6F8}, {0xB6F9, 0xB6F9, 0xB6F9}, {0xB6FA, 0xB6FA, 0xB6FA}, {0xB6FB, 0xB6FB, 0xB6FB}, {0xB6FC, 0xB6FC, 0xB6FC}, {0xB6FD, 0xB6FD, 0xB6FD}, {0xB6FE, 0xB6FE, 0xB6FE}, {0xB6FF, 0xB6FF, 0xB6FF}, {0xB700, 0xB700, 0xB700}, {0xB701, 0xB701, 0xB701}, {0xB702, 0xB702, 0xB702}, {0xB703, 0xB703, 0xB703}, {0xB704, 0xB704, 0xB704}, {0xB705, 0xB705, 0xB705}, {0xB706, 0xB706, 0xB706}, {0xB707, 0xB707, 0xB707}, {0xB708, 0xB708, 0xB708}, {0xB709, 0xB709, 0xB709}, {0xB70A, 0xB70A, 0xB70A}, {0xB70B, 0xB70B, 0xB70B}, {0xB70C, 0xB70C, 0xB70C}, {0xB70D, 0xB70D, 0xB70D}, {0xB70E, 0xB70E, 0xB70E}, {0xB70F, 0xB70F, 0xB70F}, {0xB710, 0xB710, 0xB710}, {0xB711, 0xB711, 0xB711}, {0xB712, 0xB712, 0xB712}, {0xB713, 0xB713, 0xB713}, {0xB714, 0xB714, 0xB714}, {0xB715, 0xB715, 0xB715}, {0xB716, 0xB716, 0xB716}, {0xB717, 0xB717, 0xB717}, {0xB718, 0xB718, 0xB718}, {0xB719, 0xB719, 0xB719}, {0xB71A, 0xB71A, 0xB71A}, {0xB71B, 0xB71B, 0xB71B}, {0xB71C, 0xB71C, 0xB71C}, {0xB71D, 0xB71D, 0xB71D}, {0xB71E, 0xB71E, 0xB71E}, {0xB71F, 0xB71F, 0xB71F}, {0xB720, 0xB720, 0xB720}, {0xB721, 0xB721, 0xB721}, {0xB722, 0xB722, 0xB722}, {0xB723, 0xB723, 0xB723}, {0xB724, 0xB724, 0xB724}, {0xB725, 0xB725, 0xB725}, {0xB726, 0xB726, 0xB726}, {0xB727, 0xB727, 0xB727}, {0xB728, 0xB728, 0xB728}, {0xB729, 0xB729, 0xB729}, {0xB72A, 0xB72A, 0xB72A}, {0xB72B, 0xB72B, 0xB72B}, {0xB72C, 0xB72C, 0xB72C}, {0xB72D, 0xB72D, 0xB72D}, {0xB72E, 0xB72E, 0xB72E}, {0xB72F, 0xB72F, 0xB72F}, {0xB730, 0xB730, 0xB730}, {0xB731, 0xB731, 0xB731}, {0xB732, 0xB732, 0xB732}, {0xB733, 0xB733, 0xB733}, {0xB734, 0xB734, 0xB734}, {0xB735, 0xB735, 0xB735}, {0xB736, 0xB736, 0xB736}, {0xB737, 0xB737, 0xB737}, {0xB738, 0xB738, 0xB738}, {0xB739, 0xB739, 0xB739}, {0xB73A, 0xB73A, 0xB73A}, {0xB73B, 0xB73B, 0xB73B}, {0xB73C, 0xB73C, 0xB73C}, {0xB73D, 0xB73D, 0xB73D}, {0xB73E, 0xB73E, 0xB73E}, {0xB73F, 0xB73F, 0xB73F}, {0xB740, 0xB740, 0xB740}, {0xB741, 0xB741, 0xB741}, {0xB742, 0xB742, 0xB742}, {0xB743, 0xB743, 0xB743}, {0xB744, 0xB744, 0xB744}, {0xB745, 0xB745, 0xB745}, {0xB746, 0xB746, 0xB746}, {0xB747, 0xB747, 0xB747}, {0xB748, 0xB748, 0xB748}, {0xB749, 0xB749, 0xB749}, {0xB74A, 0xB74A, 0xB74A}, {0xB74B, 0xB74B, 0xB74B}, {0xB74C, 0xB74C, 0xB74C}, {0xB74D, 0xB74D, 0xB74D}, {0xB74E, 0xB74E, 0xB74E}, {0xB74F, 0xB74F, 0xB74F}, {0xB750, 0xB750, 0xB750}, {0xB751, 0xB751, 0xB751}, {0xB752, 0xB752, 0xB752}, {0xB753, 0xB753, 0xB753}, {0xB754, 0xB754, 0xB754}, {0xB755, 0xB755, 0xB755}, {0xB756, 0xB756, 0xB756}, {0xB757, 0xB757, 0xB757}, {0xB758, 0xB758, 0xB758}, {0xB759, 0xB759, 0xB759}, {0xB75A, 0xB75A, 0xB75A}, {0xB75B, 0xB75B, 0xB75B}, {0xB75C, 0xB75C, 0xB75C}, {0xB75D, 0xB75D, 0xB75D}, {0xB75E, 0xB75E, 0xB75E}, {0xB75F, 0xB75F, 0xB75F}, {0xB760, 0xB760, 0xB760}, {0xB761, 0xB761, 0xB761}, {0xB762, 0xB762, 0xB762}, {0xB763, 0xB763, 0xB763}, {0xB764, 0xB764, 0xB764}, {0xB765, 0xB765, 0xB765}, {0xB766, 0xB766, 0xB766}, {0xB767, 0xB767, 0xB767}, {0xB768, 0xB768, 0xB768}, {0xB769, 0xB769, 0xB769}, {0xB76A, 0xB76A, 0xB76A}, {0xB76B, 0xB76B, 0xB76B}, {0xB76C, 0xB76C, 0xB76C}, {0xB76D, 0xB76D, 0xB76D}, {0xB76E, 0xB76E, 0xB76E}, {0xB76F, 0xB76F, 0xB76F}, {0xB770, 0xB770, 0xB770}, {0xB771, 0xB771, 0xB771}, {0xB772, 0xB772, 0xB772}, {0xB773, 0xB773, 0xB773}, {0xB774, 0xB774, 0xB774}, {0xB775, 0xB775, 0xB775}, {0xB776, 0xB776, 0xB776}, {0xB777, 0xB777, 0xB777}, {0xB778, 0xB778, 0xB778}, {0xB779, 0xB779, 0xB779}, {0xB77A, 0xB77A, 0xB77A}, {0xB77B, 0xB77B, 0xB77B}, {0xB77C, 0xB77C, 0xB77C}, {0xB77D, 0xB77D, 0xB77D}, {0xB77E, 0xB77E, 0xB77E}, {0xB77F, 0xB77F, 0xB77F}, {0xB780, 0xB780, 0xB780}, {0xB781, 0xB781, 0xB781}, {0xB782, 0xB782, 0xB782}, {0xB783, 0xB783, 0xB783}, {0xB784, 0xB784, 0xB784}, {0xB785, 0xB785, 0xB785}, {0xB786, 0xB786, 0xB786}, {0xB787, 0xB787, 0xB787}, {0xB788, 0xB788, 0xB788}, {0xB789, 0xB789, 0xB789}, {0xB78A, 0xB78A, 0xB78A}, {0xB78B, 0xB78B, 0xB78B}, {0xB78C, 0xB78C, 0xB78C}, {0xB78D, 0xB78D, 0xB78D}, {0xB78E, 0xB78E, 0xB78E}, {0xB78F, 0xB78F, 0xB78F}, {0xB790, 0xB790, 0xB790}, {0xB791, 0xB791, 0xB791}, {0xB792, 0xB792, 0xB792}, {0xB793, 0xB793, 0xB793}, {0xB794, 0xB794, 0xB794}, {0xB795, 0xB795, 0xB795}, {0xB796, 0xB796, 0xB796}, {0xB797, 0xB797, 0xB797}, {0xB798, 0xB798, 0xB798}, {0xB799, 0xB799, 0xB799}, {0xB79A, 0xB79A, 0xB79A}, {0xB79B, 0xB79B, 0xB79B}, {0xB79C, 0xB79C, 0xB79C}, {0xB79D, 0xB79D, 0xB79D}, {0xB79E, 0xB79E, 0xB79E}, {0xB79F, 0xB79F, 0xB79F}, {0xB7A0, 0xB7A0, 0xB7A0}, {0xB7A1, 0xB7A1, 0xB7A1}, {0xB7A2, 0xB7A2, 0xB7A2}, {0xB7A3, 0xB7A3, 0xB7A3}, {0xB7A4, 0xB7A4, 0xB7A4}, {0xB7A5, 0xB7A5, 0xB7A5}, {0xB7A6, 0xB7A6, 0xB7A6}, {0xB7A7, 0xB7A7, 0xB7A7}, {0xB7A8, 0xB7A8, 0xB7A8}, {0xB7A9, 0xB7A9, 0xB7A9}, {0xB7AA, 0xB7AA, 0xB7AA}, {0xB7AB, 0xB7AB, 0xB7AB}, {0xB7AC, 0xB7AC, 0xB7AC}, {0xB7AD, 0xB7AD, 0xB7AD}, {0xB7AE, 0xB7AE, 0xB7AE}, {0xB7AF, 0xB7AF, 0xB7AF}, {0xB7B0, 0xB7B0, 0xB7B0}, {0xB7B1, 0xB7B1, 0xB7B1}, {0xB7B2, 0xB7B2, 0xB7B2}, {0xB7B3, 0xB7B3, 0xB7B3}, {0xB7B4, 0xB7B4, 0xB7B4}, {0xB7B5, 0xB7B5, 0xB7B5}, {0xB7B6, 0xB7B6, 0xB7B6}, {0xB7B7, 0xB7B7, 0xB7B7}, {0xB7B8, 0xB7B8, 0xB7B8}, {0xB7B9, 0xB7B9, 0xB7B9}, {0xB7BA, 0xB7BA, 0xB7BA}, {0xB7BB, 0xB7BB, 0xB7BB}, {0xB7BC, 0xB7BC, 0xB7BC}, {0xB7BD, 0xB7BD, 0xB7BD}, {0xB7BE, 0xB7BE, 0xB7BE}, {0xB7BF, 0xB7BF, 0xB7BF}, {0xB7C0, 0xB7C0, 0xB7C0}, {0xB7C1, 0xB7C1, 0xB7C1}, {0xB7C2, 0xB7C2, 0xB7C2}, {0xB7C3, 0xB7C3, 0xB7C3}, {0xB7C4, 0xB7C4, 0xB7C4}, {0xB7C5, 0xB7C5, 0xB7C5}, {0xB7C6, 0xB7C6, 0xB7C6}, {0xB7C7, 0xB7C7, 0xB7C7}, {0xB7C8, 0xB7C8, 0xB7C8}, {0xB7C9, 0xB7C9, 0xB7C9}, {0xB7CA, 0xB7CA, 0xB7CA}, {0xB7CB, 0xB7CB, 0xB7CB}, {0xB7CC, 0xB7CC, 0xB7CC}, {0xB7CD, 0xB7CD, 0xB7CD}, {0xB7CE, 0xB7CE, 0xB7CE}, {0xB7CF, 0xB7CF, 0xB7CF}, {0xB7D0, 0xB7D0, 0xB7D0}, {0xB7D1, 0xB7D1, 0xB7D1}, {0xB7D2, 0xB7D2, 0xB7D2}, {0xB7D3, 0xB7D3, 0xB7D3}, {0xB7D4, 0xB7D4, 0xB7D4}, {0xB7D5, 0xB7D5, 0xB7D5}, {0xB7D6, 0xB7D6, 0xB7D6}, {0xB7D7, 0xB7D7, 0xB7D7}, {0xB7D8, 0xB7D8, 0xB7D8}, {0xB7D9, 0xB7D9, 0xB7D9}, {0xB7DA, 0xB7DA, 0xB7DA}, {0xB7DB, 0xB7DB, 0xB7DB}, {0xB7DC, 0xB7DC, 0xB7DC}, {0xB7DD, 0xB7DD, 0xB7DD}, {0xB7DE, 0xB7DE, 0xB7DE}, {0xB7DF, 0xB7DF, 0xB7DF}, {0xB7E0, 0xB7E0, 0xB7E0}, {0xB7E1, 0xB7E1, 0xB7E1}, {0xB7E2, 0xB7E2, 0xB7E2}, {0xB7E3, 0xB7E3, 0xB7E3}, {0xB7E4, 0xB7E4, 0xB7E4}, {0xB7E5, 0xB7E5, 0xB7E5}, {0xB7E6, 0xB7E6, 0xB7E6}, {0xB7E7, 0xB7E7, 0xB7E7}, {0xB7E8, 0xB7E8, 0xB7E8}, {0xB7E9, 0xB7E9, 0xB7E9}, {0xB7EA, 0xB7EA, 0xB7EA}, {0xB7EB, 0xB7EB, 0xB7EB}, {0xB7EC, 0xB7EC, 0xB7EC}, {0xB7ED, 0xB7ED, 0xB7ED}, {0xB7EE, 0xB7EE, 0xB7EE}, {0xB7EF, 0xB7EF, 0xB7EF}, {0xB7F0, 0xB7F0, 0xB7F0}, {0xB7F1, 0xB7F1, 0xB7F1}, {0xB7F2, 0xB7F2, 0xB7F2}, {0xB7F3, 0xB7F3, 0xB7F3}, {0xB7F4, 0xB7F4, 0xB7F4}, {0xB7F5, 0xB7F5, 0xB7F5}, {0xB7F6, 0xB7F6, 0xB7F6}, {0xB7F7, 0xB7F7, 0xB7F7}, {0xB7F8, 0xB7F8, 0xB7F8}, {0xB7F9, 0xB7F9, 0xB7F9}, {0xB7FA, 0xB7FA, 0xB7FA}, {0xB7FB, 0xB7FB, 0xB7FB}, {0xB7FC, 0xB7FC, 0xB7FC}, {0xB7FD, 0xB7FD, 0xB7FD}, {0xB7FE, 0xB7FE, 0xB7FE}, {0xB7FF, 0xB7FF, 0xB7FF}, {0xB800, 0xB800, 0xB800}, {0xB801, 0xB801, 0xB801}, {0xB802, 0xB802, 0xB802}, {0xB803, 0xB803, 0xB803}, {0xB804, 0xB804, 0xB804}, {0xB805, 0xB805, 0xB805}, {0xB806, 0xB806, 0xB806}, {0xB807, 0xB807, 0xB807}, {0xB808, 0xB808, 0xB808}, {0xB809, 0xB809, 0xB809}, {0xB80A, 0xB80A, 0xB80A}, {0xB80B, 0xB80B, 0xB80B}, {0xB80C, 0xB80C, 0xB80C}, {0xB80D, 0xB80D, 0xB80D}, {0xB80E, 0xB80E, 0xB80E}, {0xB80F, 0xB80F, 0xB80F}, {0xB810, 0xB810, 0xB810}, {0xB811, 0xB811, 0xB811}, {0xB812, 0xB812, 0xB812}, {0xB813, 0xB813, 0xB813}, {0xB814, 0xB814, 0xB814}, {0xB815, 0xB815, 0xB815}, {0xB816, 0xB816, 0xB816}, {0xB817, 0xB817, 0xB817}, {0xB818, 0xB818, 0xB818}, {0xB819, 0xB819, 0xB819}, {0xB81A, 0xB81A, 0xB81A}, {0xB81B, 0xB81B, 0xB81B}, {0xB81C, 0xB81C, 0xB81C}, {0xB81D, 0xB81D, 0xB81D}, {0xB81E, 0xB81E, 0xB81E}, {0xB81F, 0xB81F, 0xB81F}, {0xB820, 0xB820, 0xB820}, {0xB821, 0xB821, 0xB821}, {0xB822, 0xB822, 0xB822}, {0xB823, 0xB823, 0xB823}, {0xB824, 0xB824, 0xB824}, {0xB825, 0xB825, 0xB825}, {0xB826, 0xB826, 0xB826}, {0xB827, 0xB827, 0xB827}, {0xB828, 0xB828, 0xB828}, {0xB829, 0xB829, 0xB829}, {0xB82A, 0xB82A, 0xB82A}, {0xB82B, 0xB82B, 0xB82B}, {0xB82C, 0xB82C, 0xB82C}, {0xB82D, 0xB82D, 0xB82D}, {0xB82E, 0xB82E, 0xB82E}, {0xB82F, 0xB82F, 0xB82F}, {0xB830, 0xB830, 0xB830}, {0xB831, 0xB831, 0xB831}, {0xB832, 0xB832, 0xB832}, {0xB833, 0xB833, 0xB833}, {0xB834, 0xB834, 0xB834}, {0xB835, 0xB835, 0xB835}, {0xB836, 0xB836, 0xB836}, {0xB837, 0xB837, 0xB837}, {0xB838, 0xB838, 0xB838}, {0xB839, 0xB839, 0xB839}, {0xB83A, 0xB83A, 0xB83A}, {0xB83B, 0xB83B, 0xB83B}, {0xB83C, 0xB83C, 0xB83C}, {0xB83D, 0xB83D, 0xB83D}, {0xB83E, 0xB83E, 0xB83E}, {0xB83F, 0xB83F, 0xB83F}, {0xB840, 0xB840, 0xB840}, {0xB841, 0xB841, 0xB841}, {0xB842, 0xB842, 0xB842}, {0xB843, 0xB843, 0xB843}, {0xB844, 0xB844, 0xB844}, {0xB845, 0xB845, 0xB845}, {0xB846, 0xB846, 0xB846}, {0xB847, 0xB847, 0xB847}, {0xB848, 0xB848, 0xB848}, {0xB849, 0xB849, 0xB849}, {0xB84A, 0xB84A, 0xB84A}, {0xB84B, 0xB84B, 0xB84B}, {0xB84C, 0xB84C, 0xB84C}, {0xB84D, 0xB84D, 0xB84D}, {0xB84E, 0xB84E, 0xB84E}, {0xB84F, 0xB84F, 0xB84F}, {0xB850, 0xB850, 0xB850}, {0xB851, 0xB851, 0xB851}, {0xB852, 0xB852, 0xB852}, {0xB853, 0xB853, 0xB853}, {0xB854, 0xB854, 0xB854}, {0xB855, 0xB855, 0xB855}, {0xB856, 0xB856, 0xB856}, {0xB857, 0xB857, 0xB857}, {0xB858, 0xB858, 0xB858}, {0xB859, 0xB859, 0xB859}, {0xB85A, 0xB85A, 0xB85A}, {0xB85B, 0xB85B, 0xB85B}, {0xB85C, 0xB85C, 0xB85C}, {0xB85D, 0xB85D, 0xB85D}, {0xB85E, 0xB85E, 0xB85E}, {0xB85F, 0xB85F, 0xB85F}, {0xB860, 0xB860, 0xB860}, {0xB861, 0xB861, 0xB861}, {0xB862, 0xB862, 0xB862}, {0xB863, 0xB863, 0xB863}, {0xB864, 0xB864, 0xB864}, {0xB865, 0xB865, 0xB865}, {0xB866, 0xB866, 0xB866}, {0xB867, 0xB867, 0xB867}, {0xB868, 0xB868, 0xB868}, {0xB869, 0xB869, 0xB869}, {0xB86A, 0xB86A, 0xB86A}, {0xB86B, 0xB86B, 0xB86B}, {0xB86C, 0xB86C, 0xB86C}, {0xB86D, 0xB86D, 0xB86D}, {0xB86E, 0xB86E, 0xB86E}, {0xB86F, 0xB86F, 0xB86F}, {0xB870, 0xB870, 0xB870}, {0xB871, 0xB871, 0xB871}, {0xB872, 0xB872, 0xB872}, {0xB873, 0xB873, 0xB873}, {0xB874, 0xB874, 0xB874}, {0xB875, 0xB875, 0xB875}, {0xB876, 0xB876, 0xB876}, {0xB877, 0xB877, 0xB877}, {0xB878, 0xB878, 0xB878}, {0xB879, 0xB879, 0xB879}, {0xB87A, 0xB87A, 0xB87A}, {0xB87B, 0xB87B, 0xB87B}, {0xB87C, 0xB87C, 0xB87C}, {0xB87D, 0xB87D, 0xB87D}, {0xB87E, 0xB87E, 0xB87E}, {0xB87F, 0xB87F, 0xB87F}, {0xB880, 0xB880, 0xB880}, {0xB881, 0xB881, 0xB881}, {0xB882, 0xB882, 0xB882}, {0xB883, 0xB883, 0xB883}, {0xB884, 0xB884, 0xB884}, {0xB885, 0xB885, 0xB885}, {0xB886, 0xB886, 0xB886}, {0xB887, 0xB887, 0xB887}, {0xB888, 0xB888, 0xB888}, {0xB889, 0xB889, 0xB889}, {0xB88A, 0xB88A, 0xB88A}, {0xB88B, 0xB88B, 0xB88B}, {0xB88C, 0xB88C, 0xB88C}, {0xB88D, 0xB88D, 0xB88D}, {0xB88E, 0xB88E, 0xB88E}, {0xB88F, 0xB88F, 0xB88F}, {0xB890, 0xB890, 0xB890}, {0xB891, 0xB891, 0xB891}, {0xB892, 0xB892, 0xB892}, {0xB893, 0xB893, 0xB893}, {0xB894, 0xB894, 0xB894}, {0xB895, 0xB895, 0xB895}, {0xB896, 0xB896, 0xB896}, {0xB897, 0xB897, 0xB897}, {0xB898, 0xB898, 0xB898}, {0xB899, 0xB899, 0xB899}, {0xB89A, 0xB89A, 0xB89A}, {0xB89B, 0xB89B, 0xB89B}, {0xB89C, 0xB89C, 0xB89C}, {0xB89D, 0xB89D, 0xB89D}, {0xB89E, 0xB89E, 0xB89E}, {0xB89F, 0xB89F, 0xB89F}, {0xB8A0, 0xB8A0, 0xB8A0}, {0xB8A1, 0xB8A1, 0xB8A1}, {0xB8A2, 0xB8A2, 0xB8A2}, {0xB8A3, 0xB8A3, 0xB8A3}, {0xB8A4, 0xB8A4, 0xB8A4}, {0xB8A5, 0xB8A5, 0xB8A5}, {0xB8A6, 0xB8A6, 0xB8A6}, {0xB8A7, 0xB8A7, 0xB8A7}, {0xB8A8, 0xB8A8, 0xB8A8}, {0xB8A9, 0xB8A9, 0xB8A9}, {0xB8AA, 0xB8AA, 0xB8AA}, {0xB8AB, 0xB8AB, 0xB8AB}, {0xB8AC, 0xB8AC, 0xB8AC}, {0xB8AD, 0xB8AD, 0xB8AD}, {0xB8AE, 0xB8AE, 0xB8AE}, {0xB8AF, 0xB8AF, 0xB8AF}, {0xB8B0, 0xB8B0, 0xB8B0}, {0xB8B1, 0xB8B1, 0xB8B1}, {0xB8B2, 0xB8B2, 0xB8B2}, {0xB8B3, 0xB8B3, 0xB8B3}, {0xB8B4, 0xB8B4, 0xB8B4}, {0xB8B5, 0xB8B5, 0xB8B5}, {0xB8B6, 0xB8B6, 0xB8B6}, {0xB8B7, 0xB8B7, 0xB8B7}, {0xB8B8, 0xB8B8, 0xB8B8}, {0xB8B9, 0xB8B9, 0xB8B9}, {0xB8BA, 0xB8BA, 0xB8BA}, {0xB8BB, 0xB8BB, 0xB8BB}, {0xB8BC, 0xB8BC, 0xB8BC}, {0xB8BD, 0xB8BD, 0xB8BD}, {0xB8BE, 0xB8BE, 0xB8BE}, {0xB8BF, 0xB8BF, 0xB8BF}, {0xB8C0, 0xB8C0, 0xB8C0}, {0xB8C1, 0xB8C1, 0xB8C1}, {0xB8C2, 0xB8C2, 0xB8C2}, {0xB8C3, 0xB8C3, 0xB8C3}, {0xB8C4, 0xB8C4, 0xB8C4}, {0xB8C5, 0xB8C5, 0xB8C5}, {0xB8C6, 0xB8C6, 0xB8C6}, {0xB8C7, 0xB8C7, 0xB8C7}, {0xB8C8, 0xB8C8, 0xB8C8}, {0xB8C9, 0xB8C9, 0xB8C9}, {0xB8CA, 0xB8CA, 0xB8CA}, {0xB8CB, 0xB8CB, 0xB8CB}, {0xB8CC, 0xB8CC, 0xB8CC}, {0xB8CD, 0xB8CD, 0xB8CD}, {0xB8CE, 0xB8CE, 0xB8CE}, {0xB8CF, 0xB8CF, 0xB8CF}, {0xB8D0, 0xB8D0, 0xB8D0}, {0xB8D1, 0xB8D1, 0xB8D1}, {0xB8D2, 0xB8D2, 0xB8D2}, {0xB8D3, 0xB8D3, 0xB8D3}, {0xB8D4, 0xB8D4, 0xB8D4}, {0xB8D5, 0xB8D5, 0xB8D5}, {0xB8D6, 0xB8D6, 0xB8D6}, {0xB8D7, 0xB8D7, 0xB8D7}, {0xB8D8, 0xB8D8, 0xB8D8}, {0xB8D9, 0xB8D9, 0xB8D9}, {0xB8DA, 0xB8DA, 0xB8DA}, {0xB8DB, 0xB8DB, 0xB8DB}, {0xB8DC, 0xB8DC, 0xB8DC}, {0xB8DD, 0xB8DD, 0xB8DD}, {0xB8DE, 0xB8DE, 0xB8DE}, {0xB8DF, 0xB8DF, 0xB8DF}, {0xB8E0, 0xB8E0, 0xB8E0}, {0xB8E1, 0xB8E1, 0xB8E1}, {0xB8E2, 0xB8E2, 0xB8E2}, {0xB8E3, 0xB8E3, 0xB8E3}, {0xB8E4, 0xB8E4, 0xB8E4}, {0xB8E5, 0xB8E5, 0xB8E5}, {0xB8E6, 0xB8E6, 0xB8E6}, {0xB8E7, 0xB8E7, 0xB8E7}, {0xB8E8, 0xB8E8, 0xB8E8}, {0xB8E9, 0xB8E9, 0xB8E9}, {0xB8EA, 0xB8EA, 0xB8EA}, {0xB8EB, 0xB8EB, 0xB8EB}, {0xB8EC, 0xB8EC, 0xB8EC}, {0xB8ED, 0xB8ED, 0xB8ED}, {0xB8EE, 0xB8EE, 0xB8EE}, {0xB8EF, 0xB8EF, 0xB8EF}, {0xB8F0, 0xB8F0, 0xB8F0}, {0xB8F1, 0xB8F1, 0xB8F1}, {0xB8F2, 0xB8F2, 0xB8F2}, {0xB8F3, 0xB8F3, 0xB8F3}, {0xB8F4, 0xB8F4, 0xB8F4}, {0xB8F5, 0xB8F5, 0xB8F5}, {0xB8F6, 0xB8F6, 0xB8F6}, {0xB8F7, 0xB8F7, 0xB8F7}, {0xB8F8, 0xB8F8, 0xB8F8}, {0xB8F9, 0xB8F9, 0xB8F9}, {0xB8FA, 0xB8FA, 0xB8FA}, {0xB8FB, 0xB8FB, 0xB8FB}, {0xB8FC, 0xB8FC, 0xB8FC}, {0xB8FD, 0xB8FD, 0xB8FD}, {0xB8FE, 0xB8FE, 0xB8FE}, {0xB8FF, 0xB8FF, 0xB8FF}, {0xB900, 0xB900, 0xB900}, {0xB901, 0xB901, 0xB901}, {0xB902, 0xB902, 0xB902}, {0xB903, 0xB903, 0xB903}, {0xB904, 0xB904, 0xB904}, {0xB905, 0xB905, 0xB905}, {0xB906, 0xB906, 0xB906}, {0xB907, 0xB907, 0xB907}, {0xB908, 0xB908, 0xB908}, {0xB909, 0xB909, 0xB909}, {0xB90A, 0xB90A, 0xB90A}, {0xB90B, 0xB90B, 0xB90B}, {0xB90C, 0xB90C, 0xB90C}, {0xB90D, 0xB90D, 0xB90D}, {0xB90E, 0xB90E, 0xB90E}, {0xB90F, 0xB90F, 0xB90F}, {0xB910, 0xB910, 0xB910}, {0xB911, 0xB911, 0xB911}, {0xB912, 0xB912, 0xB912}, {0xB913, 0xB913, 0xB913}, {0xB914, 0xB914, 0xB914}, {0xB915, 0xB915, 0xB915}, {0xB916, 0xB916, 0xB916}, {0xB917, 0xB917, 0xB917}, {0xB918, 0xB918, 0xB918}, {0xB919, 0xB919, 0xB919}, {0xB91A, 0xB91A, 0xB91A}, {0xB91B, 0xB91B, 0xB91B}, {0xB91C, 0xB91C, 0xB91C}, {0xB91D, 0xB91D, 0xB91D}, {0xB91E, 0xB91E, 0xB91E}, {0xB91F, 0xB91F, 0xB91F}, {0xB920, 0xB920, 0xB920}, {0xB921, 0xB921, 0xB921}, {0xB922, 0xB922, 0xB922}, {0xB923, 0xB923, 0xB923}, {0xB924, 0xB924, 0xB924}, {0xB925, 0xB925, 0xB925}, {0xB926, 0xB926, 0xB926}, {0xB927, 0xB927, 0xB927}, {0xB928, 0xB928, 0xB928}, {0xB929, 0xB929, 0xB929}, {0xB92A, 0xB92A, 0xB92A}, {0xB92B, 0xB92B, 0xB92B}, {0xB92C, 0xB92C, 0xB92C}, {0xB92D, 0xB92D, 0xB92D}, {0xB92E, 0xB92E, 0xB92E}, {0xB92F, 0xB92F, 0xB92F}, {0xB930, 0xB930, 0xB930}, {0xB931, 0xB931, 0xB931}, {0xB932, 0xB932, 0xB932}, {0xB933, 0xB933, 0xB933}, {0xB934, 0xB934, 0xB934}, {0xB935, 0xB935, 0xB935}, {0xB936, 0xB936, 0xB936}, {0xB937, 0xB937, 0xB937}, {0xB938, 0xB938, 0xB938}, {0xB939, 0xB939, 0xB939}, {0xB93A, 0xB93A, 0xB93A}, {0xB93B, 0xB93B, 0xB93B}, {0xB93C, 0xB93C, 0xB93C}, {0xB93D, 0xB93D, 0xB93D}, {0xB93E, 0xB93E, 0xB93E}, {0xB93F, 0xB93F, 0xB93F}, {0xB940, 0xB940, 0xB940}, {0xB941, 0xB941, 0xB941}, {0xB942, 0xB942, 0xB942}, {0xB943, 0xB943, 0xB943}, {0xB944, 0xB944, 0xB944}, {0xB945, 0xB945, 0xB945}, {0xB946, 0xB946, 0xB946}, {0xB947, 0xB947, 0xB947}, {0xB948, 0xB948, 0xB948}, {0xB949, 0xB949, 0xB949}, {0xB94A, 0xB94A, 0xB94A}, {0xB94B, 0xB94B, 0xB94B}, {0xB94C, 0xB94C, 0xB94C}, {0xB94D, 0xB94D, 0xB94D}, {0xB94E, 0xB94E, 0xB94E}, {0xB94F, 0xB94F, 0xB94F}, {0xB950, 0xB950, 0xB950}, {0xB951, 0xB951, 0xB951}, {0xB952, 0xB952, 0xB952}, {0xB953, 0xB953, 0xB953}, {0xB954, 0xB954, 0xB954}, {0xB955, 0xB955, 0xB955}, {0xB956, 0xB956, 0xB956}, {0xB957, 0xB957, 0xB957}, {0xB958, 0xB958, 0xB958}, {0xB959, 0xB959, 0xB959}, {0xB95A, 0xB95A, 0xB95A}, {0xB95B, 0xB95B, 0xB95B}, {0xB95C, 0xB95C, 0xB95C}, {0xB95D, 0xB95D, 0xB95D}, {0xB95E, 0xB95E, 0xB95E}, {0xB95F, 0xB95F, 0xB95F}, {0xB960, 0xB960, 0xB960}, {0xB961, 0xB961, 0xB961}, {0xB962, 0xB962, 0xB962}, {0xB963, 0xB963, 0xB963}, {0xB964, 0xB964, 0xB964}, {0xB965, 0xB965, 0xB965}, {0xB966, 0xB966, 0xB966}, {0xB967, 0xB967, 0xB967}, {0xB968, 0xB968, 0xB968}, {0xB969, 0xB969, 0xB969}, {0xB96A, 0xB96A, 0xB96A}, {0xB96B, 0xB96B, 0xB96B}, {0xB96C, 0xB96C, 0xB96C}, {0xB96D, 0xB96D, 0xB96D}, {0xB96E, 0xB96E, 0xB96E}, {0xB96F, 0xB96F, 0xB96F}, {0xB970, 0xB970, 0xB970}, {0xB971, 0xB971, 0xB971}, {0xB972, 0xB972, 0xB972}, {0xB973, 0xB973, 0xB973}, {0xB974, 0xB974, 0xB974}, {0xB975, 0xB975, 0xB975}, {0xB976, 0xB976, 0xB976}, {0xB977, 0xB977, 0xB977}, {0xB978, 0xB978, 0xB978}, {0xB979, 0xB979, 0xB979}, {0xB97A, 0xB97A, 0xB97A}, {0xB97B, 0xB97B, 0xB97B}, {0xB97C, 0xB97C, 0xB97C}, {0xB97D, 0xB97D, 0xB97D}, {0xB97E, 0xB97E, 0xB97E}, {0xB97F, 0xB97F, 0xB97F}, {0xB980, 0xB980, 0xB980}, {0xB981, 0xB981, 0xB981}, {0xB982, 0xB982, 0xB982}, {0xB983, 0xB983, 0xB983}, {0xB984, 0xB984, 0xB984}, {0xB985, 0xB985, 0xB985}, {0xB986, 0xB986, 0xB986}, {0xB987, 0xB987, 0xB987}, {0xB988, 0xB988, 0xB988}, {0xB989, 0xB989, 0xB989}, {0xB98A, 0xB98A, 0xB98A}, {0xB98B, 0xB98B, 0xB98B}, {0xB98C, 0xB98C, 0xB98C}, {0xB98D, 0xB98D, 0xB98D}, {0xB98E, 0xB98E, 0xB98E}, {0xB98F, 0xB98F, 0xB98F}, {0xB990, 0xB990, 0xB990}, {0xB991, 0xB991, 0xB991}, {0xB992, 0xB992, 0xB992}, {0xB993, 0xB993, 0xB993}, {0xB994, 0xB994, 0xB994}, {0xB995, 0xB995, 0xB995}, {0xB996, 0xB996, 0xB996}, {0xB997, 0xB997, 0xB997}, {0xB998, 0xB998, 0xB998}, {0xB999, 0xB999, 0xB999}, {0xB99A, 0xB99A, 0xB99A}, {0xB99B, 0xB99B, 0xB99B}, {0xB99C, 0xB99C, 0xB99C}, {0xB99D, 0xB99D, 0xB99D}, {0xB99E, 0xB99E, 0xB99E}, {0xB99F, 0xB99F, 0xB99F}, {0xB9A0, 0xB9A0, 0xB9A0}, {0xB9A1, 0xB9A1, 0xB9A1}, {0xB9A2, 0xB9A2, 0xB9A2}, {0xB9A3, 0xB9A3, 0xB9A3}, {0xB9A4, 0xB9A4, 0xB9A4}, {0xB9A5, 0xB9A5, 0xB9A5}, {0xB9A6, 0xB9A6, 0xB9A6}, {0xB9A7, 0xB9A7, 0xB9A7}, {0xB9A8, 0xB9A8, 0xB9A8}, {0xB9A9, 0xB9A9, 0xB9A9}, {0xB9AA, 0xB9AA, 0xB9AA}, {0xB9AB, 0xB9AB, 0xB9AB}, {0xB9AC, 0xB9AC, 0xB9AC}, {0xB9AD, 0xB9AD, 0xB9AD}, {0xB9AE, 0xB9AE, 0xB9AE}, {0xB9AF, 0xB9AF, 0xB9AF}, {0xB9B0, 0xB9B0, 0xB9B0}, {0xB9B1, 0xB9B1, 0xB9B1}, {0xB9B2, 0xB9B2, 0xB9B2}, {0xB9B3, 0xB9B3, 0xB9B3}, {0xB9B4, 0xB9B4, 0xB9B4}, {0xB9B5, 0xB9B5, 0xB9B5}, {0xB9B6, 0xB9B6, 0xB9B6}, {0xB9B7, 0xB9B7, 0xB9B7}, {0xB9B8, 0xB9B8, 0xB9B8}, {0xB9B9, 0xB9B9, 0xB9B9}, {0xB9BA, 0xB9BA, 0xB9BA}, {0xB9BB, 0xB9BB, 0xB9BB}, {0xB9BC, 0xB9BC, 0xB9BC}, {0xB9BD, 0xB9BD, 0xB9BD}, {0xB9BE, 0xB9BE, 0xB9BE}, {0xB9BF, 0xB9BF, 0xB9BF}, {0xB9C0, 0xB9C0, 0xB9C0}, {0xB9C1, 0xB9C1, 0xB9C1}, {0xB9C2, 0xB9C2, 0xB9C2}, {0xB9C3, 0xB9C3, 0xB9C3}, {0xB9C4, 0xB9C4, 0xB9C4}, {0xB9C5, 0xB9C5, 0xB9C5}, {0xB9C6, 0xB9C6, 0xB9C6}, {0xB9C7, 0xB9C7, 0xB9C7}, {0xB9C8, 0xB9C8, 0xB9C8}, {0xB9C9, 0xB9C9, 0xB9C9}, {0xB9CA, 0xB9CA, 0xB9CA}, {0xB9CB, 0xB9CB, 0xB9CB}, {0xB9CC, 0xB9CC, 0xB9CC}, {0xB9CD, 0xB9CD, 0xB9CD}, {0xB9CE, 0xB9CE, 0xB9CE}, {0xB9CF, 0xB9CF, 0xB9CF}, {0xB9D0, 0xB9D0, 0xB9D0}, {0xB9D1, 0xB9D1, 0xB9D1}, {0xB9D2, 0xB9D2, 0xB9D2}, {0xB9D3, 0xB9D3, 0xB9D3}, {0xB9D4, 0xB9D4, 0xB9D4}, {0xB9D5, 0xB9D5, 0xB9D5}, {0xB9D6, 0xB9D6, 0xB9D6}, {0xB9D7, 0xB9D7, 0xB9D7}, {0xB9D8, 0xB9D8, 0xB9D8}, {0xB9D9, 0xB9D9, 0xB9D9}, {0xB9DA, 0xB9DA, 0xB9DA}, {0xB9DB, 0xB9DB, 0xB9DB}, {0xB9DC, 0xB9DC, 0xB9DC}, {0xB9DD, 0xB9DD, 0xB9DD}, {0xB9DE, 0xB9DE, 0xB9DE}, {0xB9DF, 0xB9DF, 0xB9DF}, {0xB9E0, 0xB9E0, 0xB9E0}, {0xB9E1, 0xB9E1, 0xB9E1}, {0xB9E2, 0xB9E2, 0xB9E2}, {0xB9E3, 0xB9E3, 0xB9E3}, {0xB9E4, 0xB9E4, 0xB9E4}, {0xB9E5, 0xB9E5, 0xB9E5}, {0xB9E6, 0xB9E6, 0xB9E6}, {0xB9E7, 0xB9E7, 0xB9E7}, {0xB9E8, 0xB9E8, 0xB9E8}, {0xB9E9, 0xB9E9, 0xB9E9}, {0xB9EA, 0xB9EA, 0xB9EA}, {0xB9EB, 0xB9EB, 0xB9EB}, {0xB9EC, 0xB9EC, 0xB9EC}, {0xB9ED, 0xB9ED, 0xB9ED}, {0xB9EE, 0xB9EE, 0xB9EE}, {0xB9EF, 0xB9EF, 0xB9EF}, {0xB9F0, 0xB9F0, 0xB9F0}, {0xB9F1, 0xB9F1, 0xB9F1}, {0xB9F2, 0xB9F2, 0xB9F2}, {0xB9F3, 0xB9F3, 0xB9F3}, {0xB9F4, 0xB9F4, 0xB9F4}, {0xB9F5, 0xB9F5, 0xB9F5}, {0xB9F6, 0xB9F6, 0xB9F6}, {0xB9F7, 0xB9F7, 0xB9F7}, {0xB9F8, 0xB9F8, 0xB9F8}, {0xB9F9, 0xB9F9, 0xB9F9}, {0xB9FA, 0xB9FA, 0xB9FA}, {0xB9FB, 0xB9FB, 0xB9FB}, {0xB9FC, 0xB9FC, 0xB9FC}, {0xB9FD, 0xB9FD, 0xB9FD}, {0xB9FE, 0xB9FE, 0xB9FE}, {0xB9FF, 0xB9FF, 0xB9FF}, {0xBA00, 0xBA00, 0xBA00}, {0xBA01, 0xBA01, 0xBA01}, {0xBA02, 0xBA02, 0xBA02}, {0xBA03, 0xBA03, 0xBA03}, {0xBA04, 0xBA04, 0xBA04}, {0xBA05, 0xBA05, 0xBA05}, {0xBA06, 0xBA06, 0xBA06}, {0xBA07, 0xBA07, 0xBA07}, {0xBA08, 0xBA08, 0xBA08}, {0xBA09, 0xBA09, 0xBA09}, {0xBA0A, 0xBA0A, 0xBA0A}, {0xBA0B, 0xBA0B, 0xBA0B}, {0xBA0C, 0xBA0C, 0xBA0C}, {0xBA0D, 0xBA0D, 0xBA0D}, {0xBA0E, 0xBA0E, 0xBA0E}, {0xBA0F, 0xBA0F, 0xBA0F}, {0xBA10, 0xBA10, 0xBA10}, {0xBA11, 0xBA11, 0xBA11}, {0xBA12, 0xBA12, 0xBA12}, {0xBA13, 0xBA13, 0xBA13}, {0xBA14, 0xBA14, 0xBA14}, {0xBA15, 0xBA15, 0xBA15}, {0xBA16, 0xBA16, 0xBA16}, {0xBA17, 0xBA17, 0xBA17}, {0xBA18, 0xBA18, 0xBA18}, {0xBA19, 0xBA19, 0xBA19}, {0xBA1A, 0xBA1A, 0xBA1A}, {0xBA1B, 0xBA1B, 0xBA1B}, {0xBA1C, 0xBA1C, 0xBA1C}, {0xBA1D, 0xBA1D, 0xBA1D}, {0xBA1E, 0xBA1E, 0xBA1E}, {0xBA1F, 0xBA1F, 0xBA1F}, {0xBA20, 0xBA20, 0xBA20}, {0xBA21, 0xBA21, 0xBA21}, {0xBA22, 0xBA22, 0xBA22}, {0xBA23, 0xBA23, 0xBA23}, {0xBA24, 0xBA24, 0xBA24}, {0xBA25, 0xBA25, 0xBA25}, {0xBA26, 0xBA26, 0xBA26}, {0xBA27, 0xBA27, 0xBA27}, {0xBA28, 0xBA28, 0xBA28}, {0xBA29, 0xBA29, 0xBA29}, {0xBA2A, 0xBA2A, 0xBA2A}, {0xBA2B, 0xBA2B, 0xBA2B}, {0xBA2C, 0xBA2C, 0xBA2C}, {0xBA2D, 0xBA2D, 0xBA2D}, {0xBA2E, 0xBA2E, 0xBA2E}, {0xBA2F, 0xBA2F, 0xBA2F}, {0xBA30, 0xBA30, 0xBA30}, {0xBA31, 0xBA31, 0xBA31}, {0xBA32, 0xBA32, 0xBA32}, {0xBA33, 0xBA33, 0xBA33}, {0xBA34, 0xBA34, 0xBA34}, {0xBA35, 0xBA35, 0xBA35}, {0xBA36, 0xBA36, 0xBA36}, {0xBA37, 0xBA37, 0xBA37}, {0xBA38, 0xBA38, 0xBA38}, {0xBA39, 0xBA39, 0xBA39}, {0xBA3A, 0xBA3A, 0xBA3A}, {0xBA3B, 0xBA3B, 0xBA3B}, {0xBA3C, 0xBA3C, 0xBA3C}, {0xBA3D, 0xBA3D, 0xBA3D}, {0xBA3E, 0xBA3E, 0xBA3E}, {0xBA3F, 0xBA3F, 0xBA3F}, {0xBA40, 0xBA40, 0xBA40}, {0xBA41, 0xBA41, 0xBA41}, {0xBA42, 0xBA42, 0xBA42}, {0xBA43, 0xBA43, 0xBA43}, {0xBA44, 0xBA44, 0xBA44}, {0xBA45, 0xBA45, 0xBA45}, {0xBA46, 0xBA46, 0xBA46}, {0xBA47, 0xBA47, 0xBA47}, {0xBA48, 0xBA48, 0xBA48}, {0xBA49, 0xBA49, 0xBA49}, {0xBA4A, 0xBA4A, 0xBA4A}, {0xBA4B, 0xBA4B, 0xBA4B}, {0xBA4C, 0xBA4C, 0xBA4C}, {0xBA4D, 0xBA4D, 0xBA4D}, {0xBA4E, 0xBA4E, 0xBA4E}, {0xBA4F, 0xBA4F, 0xBA4F}, {0xBA50, 0xBA50, 0xBA50}, {0xBA51, 0xBA51, 0xBA51}, {0xBA52, 0xBA52, 0xBA52}, {0xBA53, 0xBA53, 0xBA53}, {0xBA54, 0xBA54, 0xBA54}, {0xBA55, 0xBA55, 0xBA55}, {0xBA56, 0xBA56, 0xBA56}, {0xBA57, 0xBA57, 0xBA57}, {0xBA58, 0xBA58, 0xBA58}, {0xBA59, 0xBA59, 0xBA59}, {0xBA5A, 0xBA5A, 0xBA5A}, {0xBA5B, 0xBA5B, 0xBA5B}, {0xBA5C, 0xBA5C, 0xBA5C}, {0xBA5D, 0xBA5D, 0xBA5D}, {0xBA5E, 0xBA5E, 0xBA5E}, {0xBA5F, 0xBA5F, 0xBA5F}, {0xBA60, 0xBA60, 0xBA60}, {0xBA61, 0xBA61, 0xBA61}, {0xBA62, 0xBA62, 0xBA62}, {0xBA63, 0xBA63, 0xBA63}, {0xBA64, 0xBA64, 0xBA64}, {0xBA65, 0xBA65, 0xBA65}, {0xBA66, 0xBA66, 0xBA66}, {0xBA67, 0xBA67, 0xBA67}, {0xBA68, 0xBA68, 0xBA68}, {0xBA69, 0xBA69, 0xBA69}, {0xBA6A, 0xBA6A, 0xBA6A}, {0xBA6B, 0xBA6B, 0xBA6B}, {0xBA6C, 0xBA6C, 0xBA6C}, {0xBA6D, 0xBA6D, 0xBA6D}, {0xBA6E, 0xBA6E, 0xBA6E}, {0xBA6F, 0xBA6F, 0xBA6F}, {0xBA70, 0xBA70, 0xBA70}, {0xBA71, 0xBA71, 0xBA71}, {0xBA72, 0xBA72, 0xBA72}, {0xBA73, 0xBA73, 0xBA73}, {0xBA74, 0xBA74, 0xBA74}, {0xBA75, 0xBA75, 0xBA75}, {0xBA76, 0xBA76, 0xBA76}, {0xBA77, 0xBA77, 0xBA77}, {0xBA78, 0xBA78, 0xBA78}, {0xBA79, 0xBA79, 0xBA79}, {0xBA7A, 0xBA7A, 0xBA7A}, {0xBA7B, 0xBA7B, 0xBA7B}, {0xBA7C, 0xBA7C, 0xBA7C}, {0xBA7D, 0xBA7D, 0xBA7D}, {0xBA7E, 0xBA7E, 0xBA7E}, {0xBA7F, 0xBA7F, 0xBA7F}, {0xBA80, 0xBA80, 0xBA80}, {0xBA81, 0xBA81, 0xBA81}, {0xBA82, 0xBA82, 0xBA82}, {0xBA83, 0xBA83, 0xBA83}, {0xBA84, 0xBA84, 0xBA84}, {0xBA85, 0xBA85, 0xBA85}, {0xBA86, 0xBA86, 0xBA86}, {0xBA87, 0xBA87, 0xBA87}, {0xBA88, 0xBA88, 0xBA88}, {0xBA89, 0xBA89, 0xBA89}, {0xBA8A, 0xBA8A, 0xBA8A}, {0xBA8B, 0xBA8B, 0xBA8B}, {0xBA8C, 0xBA8C, 0xBA8C}, {0xBA8D, 0xBA8D, 0xBA8D}, {0xBA8E, 0xBA8E, 0xBA8E}, {0xBA8F, 0xBA8F, 0xBA8F}, {0xBA90, 0xBA90, 0xBA90}, {0xBA91, 0xBA91, 0xBA91}, {0xBA92, 0xBA92, 0xBA92}, {0xBA93, 0xBA93, 0xBA93}, {0xBA94, 0xBA94, 0xBA94}, {0xBA95, 0xBA95, 0xBA95}, {0xBA96, 0xBA96, 0xBA96}, {0xBA97, 0xBA97, 0xBA97}, {0xBA98, 0xBA98, 0xBA98}, {0xBA99, 0xBA99, 0xBA99}, {0xBA9A, 0xBA9A, 0xBA9A}, {0xBA9B, 0xBA9B, 0xBA9B}, {0xBA9C, 0xBA9C, 0xBA9C}, {0xBA9D, 0xBA9D, 0xBA9D}, {0xBA9E, 0xBA9E, 0xBA9E}, {0xBA9F, 0xBA9F, 0xBA9F}, {0xBAA0, 0xBAA0, 0xBAA0}, {0xBAA1, 0xBAA1, 0xBAA1}, {0xBAA2, 0xBAA2, 0xBAA2}, {0xBAA3, 0xBAA3, 0xBAA3}, {0xBAA4, 0xBAA4, 0xBAA4}, {0xBAA5, 0xBAA5, 0xBAA5}, {0xBAA6, 0xBAA6, 0xBAA6}, {0xBAA7, 0xBAA7, 0xBAA7}, {0xBAA8, 0xBAA8, 0xBAA8}, {0xBAA9, 0xBAA9, 0xBAA9}, {0xBAAA, 0xBAAA, 0xBAAA}, {0xBAAB, 0xBAAB, 0xBAAB}, {0xBAAC, 0xBAAC, 0xBAAC}, {0xBAAD, 0xBAAD, 0xBAAD}, {0xBAAE, 0xBAAE, 0xBAAE}, {0xBAAF, 0xBAAF, 0xBAAF}, {0xBAB0, 0xBAB0, 0xBAB0}, {0xBAB1, 0xBAB1, 0xBAB1}, {0xBAB2, 0xBAB2, 0xBAB2}, {0xBAB3, 0xBAB3, 0xBAB3}, {0xBAB4, 0xBAB4, 0xBAB4}, {0xBAB5, 0xBAB5, 0xBAB5}, {0xBAB6, 0xBAB6, 0xBAB6}, {0xBAB7, 0xBAB7, 0xBAB7}, {0xBAB8, 0xBAB8, 0xBAB8}, {0xBAB9, 0xBAB9, 0xBAB9}, {0xBABA, 0xBABA, 0xBABA}, {0xBABB, 0xBABB, 0xBABB}, {0xBABC, 0xBABC, 0xBABC}, {0xBABD, 0xBABD, 0xBABD}, {0xBABE, 0xBABE, 0xBABE}, {0xBABF, 0xBABF, 0xBABF}, {0xBAC0, 0xBAC0, 0xBAC0}, {0xBAC1, 0xBAC1, 0xBAC1}, {0xBAC2, 0xBAC2, 0xBAC2}, {0xBAC3, 0xBAC3, 0xBAC3}, {0xBAC4, 0xBAC4, 0xBAC4}, {0xBAC5, 0xBAC5, 0xBAC5}, {0xBAC6, 0xBAC6, 0xBAC6}, {0xBAC7, 0xBAC7, 0xBAC7}, {0xBAC8, 0xBAC8, 0xBAC8}, {0xBAC9, 0xBAC9, 0xBAC9}, {0xBACA, 0xBACA, 0xBACA}, {0xBACB, 0xBACB, 0xBACB}, {0xBACC, 0xBACC, 0xBACC}, {0xBACD, 0xBACD, 0xBACD}, {0xBACE, 0xBACE, 0xBACE}, {0xBACF, 0xBACF, 0xBACF}, {0xBAD0, 0xBAD0, 0xBAD0}, {0xBAD1, 0xBAD1, 0xBAD1}, {0xBAD2, 0xBAD2, 0xBAD2}, {0xBAD3, 0xBAD3, 0xBAD3}, {0xBAD4, 0xBAD4, 0xBAD4}, {0xBAD5, 0xBAD5, 0xBAD5}, {0xBAD6, 0xBAD6, 0xBAD6}, {0xBAD7, 0xBAD7, 0xBAD7}, {0xBAD8, 0xBAD8, 0xBAD8}, {0xBAD9, 0xBAD9, 0xBAD9}, {0xBADA, 0xBADA, 0xBADA}, {0xBADB, 0xBADB, 0xBADB}, {0xBADC, 0xBADC, 0xBADC}, {0xBADD, 0xBADD, 0xBADD}, {0xBADE, 0xBADE, 0xBADE}, {0xBADF, 0xBADF, 0xBADF}, {0xBAE0, 0xBAE0, 0xBAE0}, {0xBAE1, 0xBAE1, 0xBAE1}, {0xBAE2, 0xBAE2, 0xBAE2}, {0xBAE3, 0xBAE3, 0xBAE3}, {0xBAE4, 0xBAE4, 0xBAE4}, {0xBAE5, 0xBAE5, 0xBAE5}, {0xBAE6, 0xBAE6, 0xBAE6}, {0xBAE7, 0xBAE7, 0xBAE7}, {0xBAE8, 0xBAE8, 0xBAE8}, {0xBAE9, 0xBAE9, 0xBAE9}, {0xBAEA, 0xBAEA, 0xBAEA}, {0xBAEB, 0xBAEB, 0xBAEB}, {0xBAEC, 0xBAEC, 0xBAEC}, {0xBAED, 0xBAED, 0xBAED}, {0xBAEE, 0xBAEE, 0xBAEE}, {0xBAEF, 0xBAEF, 0xBAEF}, {0xBAF0, 0xBAF0, 0xBAF0}, {0xBAF1, 0xBAF1, 0xBAF1}, {0xBAF2, 0xBAF2, 0xBAF2}, {0xBAF3, 0xBAF3, 0xBAF3}, {0xBAF4, 0xBAF4, 0xBAF4}, {0xBAF5, 0xBAF5, 0xBAF5}, {0xBAF6, 0xBAF6, 0xBAF6}, {0xBAF7, 0xBAF7, 0xBAF7}, {0xBAF8, 0xBAF8, 0xBAF8}, {0xBAF9, 0xBAF9, 0xBAF9}, {0xBAFA, 0xBAFA, 0xBAFA}, {0xBAFB, 0xBAFB, 0xBAFB}, {0xBAFC, 0xBAFC, 0xBAFC}, {0xBAFD, 0xBAFD, 0xBAFD}, {0xBAFE, 0xBAFE, 0xBAFE}, {0xBAFF, 0xBAFF, 0xBAFF}, {0xBB00, 0xBB00, 0xBB00}, {0xBB01, 0xBB01, 0xBB01}, {0xBB02, 0xBB02, 0xBB02}, {0xBB03, 0xBB03, 0xBB03}, {0xBB04, 0xBB04, 0xBB04}, {0xBB05, 0xBB05, 0xBB05}, {0xBB06, 0xBB06, 0xBB06}, {0xBB07, 0xBB07, 0xBB07}, {0xBB08, 0xBB08, 0xBB08}, {0xBB09, 0xBB09, 0xBB09}, {0xBB0A, 0xBB0A, 0xBB0A}, {0xBB0B, 0xBB0B, 0xBB0B}, {0xBB0C, 0xBB0C, 0xBB0C}, {0xBB0D, 0xBB0D, 0xBB0D}, {0xBB0E, 0xBB0E, 0xBB0E}, {0xBB0F, 0xBB0F, 0xBB0F}, {0xBB10, 0xBB10, 0xBB10}, {0xBB11, 0xBB11, 0xBB11}, {0xBB12, 0xBB12, 0xBB12}, {0xBB13, 0xBB13, 0xBB13}, {0xBB14, 0xBB14, 0xBB14}, {0xBB15, 0xBB15, 0xBB15}, {0xBB16, 0xBB16, 0xBB16}, {0xBB17, 0xBB17, 0xBB17}, {0xBB18, 0xBB18, 0xBB18}, {0xBB19, 0xBB19, 0xBB19}, {0xBB1A, 0xBB1A, 0xBB1A}, {0xBB1B, 0xBB1B, 0xBB1B}, {0xBB1C, 0xBB1C, 0xBB1C}, {0xBB1D, 0xBB1D, 0xBB1D}, {0xBB1E, 0xBB1E, 0xBB1E}, {0xBB1F, 0xBB1F, 0xBB1F}, {0xBB20, 0xBB20, 0xBB20}, {0xBB21, 0xBB21, 0xBB21}, {0xBB22, 0xBB22, 0xBB22}, {0xBB23, 0xBB23, 0xBB23}, {0xBB24, 0xBB24, 0xBB24}, {0xBB25, 0xBB25, 0xBB25}, {0xBB26, 0xBB26, 0xBB26}, {0xBB27, 0xBB27, 0xBB27}, {0xBB28, 0xBB28, 0xBB28}, {0xBB29, 0xBB29, 0xBB29}, {0xBB2A, 0xBB2A, 0xBB2A}, {0xBB2B, 0xBB2B, 0xBB2B}, {0xBB2C, 0xBB2C, 0xBB2C}, {0xBB2D, 0xBB2D, 0xBB2D}, {0xBB2E, 0xBB2E, 0xBB2E}, {0xBB2F, 0xBB2F, 0xBB2F}, {0xBB30, 0xBB30, 0xBB30}, {0xBB31, 0xBB31, 0xBB31}, {0xBB32, 0xBB32, 0xBB32}, {0xBB33, 0xBB33, 0xBB33}, {0xBB34, 0xBB34, 0xBB34}, {0xBB35, 0xBB35, 0xBB35}, {0xBB36, 0xBB36, 0xBB36}, {0xBB37, 0xBB37, 0xBB37}, {0xBB38, 0xBB38, 0xBB38}, {0xBB39, 0xBB39, 0xBB39}, {0xBB3A, 0xBB3A, 0xBB3A}, {0xBB3B, 0xBB3B, 0xBB3B}, {0xBB3C, 0xBB3C, 0xBB3C}, {0xBB3D, 0xBB3D, 0xBB3D}, {0xBB3E, 0xBB3E, 0xBB3E}, {0xBB3F, 0xBB3F, 0xBB3F}, {0xBB40, 0xBB40, 0xBB40}, {0xBB41, 0xBB41, 0xBB41}, {0xBB42, 0xBB42, 0xBB42}, {0xBB43, 0xBB43, 0xBB43}, {0xBB44, 0xBB44, 0xBB44}, {0xBB45, 0xBB45, 0xBB45}, {0xBB46, 0xBB46, 0xBB46}, {0xBB47, 0xBB47, 0xBB47}, {0xBB48, 0xBB48, 0xBB48}, {0xBB49, 0xBB49, 0xBB49}, {0xBB4A, 0xBB4A, 0xBB4A}, {0xBB4B, 0xBB4B, 0xBB4B}, {0xBB4C, 0xBB4C, 0xBB4C}, {0xBB4D, 0xBB4D, 0xBB4D}, {0xBB4E, 0xBB4E, 0xBB4E}, {0xBB4F, 0xBB4F, 0xBB4F}, {0xBB50, 0xBB50, 0xBB50}, {0xBB51, 0xBB51, 0xBB51}, {0xBB52, 0xBB52, 0xBB52}, {0xBB53, 0xBB53, 0xBB53}, {0xBB54, 0xBB54, 0xBB54}, {0xBB55, 0xBB55, 0xBB55}, {0xBB56, 0xBB56, 0xBB56}, {0xBB57, 0xBB57, 0xBB57}, {0xBB58, 0xBB58, 0xBB58}, {0xBB59, 0xBB59, 0xBB59}, {0xBB5A, 0xBB5A, 0xBB5A}, {0xBB5B, 0xBB5B, 0xBB5B}, {0xBB5C, 0xBB5C, 0xBB5C}, {0xBB5D, 0xBB5D, 0xBB5D}, {0xBB5E, 0xBB5E, 0xBB5E}, {0xBB5F, 0xBB5F, 0xBB5F}, {0xBB60, 0xBB60, 0xBB60}, {0xBB61, 0xBB61, 0xBB61}, {0xBB62, 0xBB62, 0xBB62}, {0xBB63, 0xBB63, 0xBB63}, {0xBB64, 0xBB64, 0xBB64}, {0xBB65, 0xBB65, 0xBB65}, {0xBB66, 0xBB66, 0xBB66}, {0xBB67, 0xBB67, 0xBB67}, {0xBB68, 0xBB68, 0xBB68}, {0xBB69, 0xBB69, 0xBB69}, {0xBB6A, 0xBB6A, 0xBB6A}, {0xBB6B, 0xBB6B, 0xBB6B}, {0xBB6C, 0xBB6C, 0xBB6C}, {0xBB6D, 0xBB6D, 0xBB6D}, {0xBB6E, 0xBB6E, 0xBB6E}, {0xBB6F, 0xBB6F, 0xBB6F}, {0xBB70, 0xBB70, 0xBB70}, {0xBB71, 0xBB71, 0xBB71}, {0xBB72, 0xBB72, 0xBB72}, {0xBB73, 0xBB73, 0xBB73}, {0xBB74, 0xBB74, 0xBB74}, {0xBB75, 0xBB75, 0xBB75}, {0xBB76, 0xBB76, 0xBB76}, {0xBB77, 0xBB77, 0xBB77}, {0xBB78, 0xBB78, 0xBB78}, {0xBB79, 0xBB79, 0xBB79}, {0xBB7A, 0xBB7A, 0xBB7A}, {0xBB7B, 0xBB7B, 0xBB7B}, {0xBB7C, 0xBB7C, 0xBB7C}, {0xBB7D, 0xBB7D, 0xBB7D}, {0xBB7E, 0xBB7E, 0xBB7E}, {0xBB7F, 0xBB7F, 0xBB7F}, {0xBB80, 0xBB80, 0xBB80}, {0xBB81, 0xBB81, 0xBB81}, {0xBB82, 0xBB82, 0xBB82}, {0xBB83, 0xBB83, 0xBB83}, {0xBB84, 0xBB84, 0xBB84}, {0xBB85, 0xBB85, 0xBB85}, {0xBB86, 0xBB86, 0xBB86}, {0xBB87, 0xBB87, 0xBB87}, {0xBB88, 0xBB88, 0xBB88}, {0xBB89, 0xBB89, 0xBB89}, {0xBB8A, 0xBB8A, 0xBB8A}, {0xBB8B, 0xBB8B, 0xBB8B}, {0xBB8C, 0xBB8C, 0xBB8C}, {0xBB8D, 0xBB8D, 0xBB8D}, {0xBB8E, 0xBB8E, 0xBB8E}, {0xBB8F, 0xBB8F, 0xBB8F}, {0xBB90, 0xBB90, 0xBB90}, {0xBB91, 0xBB91, 0xBB91}, {0xBB92, 0xBB92, 0xBB92}, {0xBB93, 0xBB93, 0xBB93}, {0xBB94, 0xBB94, 0xBB94}, {0xBB95, 0xBB95, 0xBB95}, {0xBB96, 0xBB96, 0xBB96}, {0xBB97, 0xBB97, 0xBB97}, {0xBB98, 0xBB98, 0xBB98}, {0xBB99, 0xBB99, 0xBB99}, {0xBB9A, 0xBB9A, 0xBB9A}, {0xBB9B, 0xBB9B, 0xBB9B}, {0xBB9C, 0xBB9C, 0xBB9C}, {0xBB9D, 0xBB9D, 0xBB9D}, {0xBB9E, 0xBB9E, 0xBB9E}, {0xBB9F, 0xBB9F, 0xBB9F}, {0xBBA0, 0xBBA0, 0xBBA0}, {0xBBA1, 0xBBA1, 0xBBA1}, {0xBBA2, 0xBBA2, 0xBBA2}, {0xBBA3, 0xBBA3, 0xBBA3}, {0xBBA4, 0xBBA4, 0xBBA4}, {0xBBA5, 0xBBA5, 0xBBA5}, {0xBBA6, 0xBBA6, 0xBBA6}, {0xBBA7, 0xBBA7, 0xBBA7}, {0xBBA8, 0xBBA8, 0xBBA8}, {0xBBA9, 0xBBA9, 0xBBA9}, {0xBBAA, 0xBBAA, 0xBBAA}, {0xBBAB, 0xBBAB, 0xBBAB}, {0xBBAC, 0xBBAC, 0xBBAC}, {0xBBAD, 0xBBAD, 0xBBAD}, {0xBBAE, 0xBBAE, 0xBBAE}, {0xBBAF, 0xBBAF, 0xBBAF}, {0xBBB0, 0xBBB0, 0xBBB0}, {0xBBB1, 0xBBB1, 0xBBB1}, {0xBBB2, 0xBBB2, 0xBBB2}, {0xBBB3, 0xBBB3, 0xBBB3}, {0xBBB4, 0xBBB4, 0xBBB4}, {0xBBB5, 0xBBB5, 0xBBB5}, {0xBBB6, 0xBBB6, 0xBBB6}, {0xBBB7, 0xBBB7, 0xBBB7}, {0xBBB8, 0xBBB8, 0xBBB8}, {0xBBB9, 0xBBB9, 0xBBB9}, {0xBBBA, 0xBBBA, 0xBBBA}, {0xBBBB, 0xBBBB, 0xBBBB}, {0xBBBC, 0xBBBC, 0xBBBC}, {0xBBBD, 0xBBBD, 0xBBBD}, {0xBBBE, 0xBBBE, 0xBBBE}, {0xBBBF, 0xBBBF, 0xBBBF}, {0xBBC0, 0xBBC0, 0xBBC0}, {0xBBC1, 0xBBC1, 0xBBC1}, {0xBBC2, 0xBBC2, 0xBBC2}, {0xBBC3, 0xBBC3, 0xBBC3}, {0xBBC4, 0xBBC4, 0xBBC4}, {0xBBC5, 0xBBC5, 0xBBC5}, {0xBBC6, 0xBBC6, 0xBBC6}, {0xBBC7, 0xBBC7, 0xBBC7}, {0xBBC8, 0xBBC8, 0xBBC8}, {0xBBC9, 0xBBC9, 0xBBC9}, {0xBBCA, 0xBBCA, 0xBBCA}, {0xBBCB, 0xBBCB, 0xBBCB}, {0xBBCC, 0xBBCC, 0xBBCC}, {0xBBCD, 0xBBCD, 0xBBCD}, {0xBBCE, 0xBBCE, 0xBBCE}, {0xBBCF, 0xBBCF, 0xBBCF}, {0xBBD0, 0xBBD0, 0xBBD0}, {0xBBD1, 0xBBD1, 0xBBD1}, {0xBBD2, 0xBBD2, 0xBBD2}, {0xBBD3, 0xBBD3, 0xBBD3}, {0xBBD4, 0xBBD4, 0xBBD4}, {0xBBD5, 0xBBD5, 0xBBD5}, {0xBBD6, 0xBBD6, 0xBBD6}, {0xBBD7, 0xBBD7, 0xBBD7}, {0xBBD8, 0xBBD8, 0xBBD8}, {0xBBD9, 0xBBD9, 0xBBD9}, {0xBBDA, 0xBBDA, 0xBBDA}, {0xBBDB, 0xBBDB, 0xBBDB}, {0xBBDC, 0xBBDC, 0xBBDC}, {0xBBDD, 0xBBDD, 0xBBDD}, {0xBBDE, 0xBBDE, 0xBBDE}, {0xBBDF, 0xBBDF, 0xBBDF}, {0xBBE0, 0xBBE0, 0xBBE0}, {0xBBE1, 0xBBE1, 0xBBE1}, {0xBBE2, 0xBBE2, 0xBBE2}, {0xBBE3, 0xBBE3, 0xBBE3}, {0xBBE4, 0xBBE4, 0xBBE4}, {0xBBE5, 0xBBE5, 0xBBE5}, {0xBBE6, 0xBBE6, 0xBBE6}, {0xBBE7, 0xBBE7, 0xBBE7}, {0xBBE8, 0xBBE8, 0xBBE8}, {0xBBE9, 0xBBE9, 0xBBE9}, {0xBBEA, 0xBBEA, 0xBBEA}, {0xBBEB, 0xBBEB, 0xBBEB}, {0xBBEC, 0xBBEC, 0xBBEC}, {0xBBED, 0xBBED, 0xBBED}, {0xBBEE, 0xBBEE, 0xBBEE}, {0xBBEF, 0xBBEF, 0xBBEF}, {0xBBF0, 0xBBF0, 0xBBF0}, {0xBBF1, 0xBBF1, 0xBBF1}, {0xBBF2, 0xBBF2, 0xBBF2}, {0xBBF3, 0xBBF3, 0xBBF3}, {0xBBF4, 0xBBF4, 0xBBF4}, {0xBBF5, 0xBBF5, 0xBBF5}, {0xBBF6, 0xBBF6, 0xBBF6}, {0xBBF7, 0xBBF7, 0xBBF7}, {0xBBF8, 0xBBF8, 0xBBF8}, {0xBBF9, 0xBBF9, 0xBBF9}, {0xBBFA, 0xBBFA, 0xBBFA}, {0xBBFB, 0xBBFB, 0xBBFB}, {0xBBFC, 0xBBFC, 0xBBFC}, {0xBBFD, 0xBBFD, 0xBBFD}, {0xBBFE, 0xBBFE, 0xBBFE}, {0xBBFF, 0xBBFF, 0xBBFF}, {0xBC00, 0xBC00, 0xBC00}, {0xBC01, 0xBC01, 0xBC01}, {0xBC02, 0xBC02, 0xBC02}, {0xBC03, 0xBC03, 0xBC03}, {0xBC04, 0xBC04, 0xBC04}, {0xBC05, 0xBC05, 0xBC05}, {0xBC06, 0xBC06, 0xBC06}, {0xBC07, 0xBC07, 0xBC07}, {0xBC08, 0xBC08, 0xBC08}, {0xBC09, 0xBC09, 0xBC09}, {0xBC0A, 0xBC0A, 0xBC0A}, {0xBC0B, 0xBC0B, 0xBC0B}, {0xBC0C, 0xBC0C, 0xBC0C}, {0xBC0D, 0xBC0D, 0xBC0D}, {0xBC0E, 0xBC0E, 0xBC0E}, {0xBC0F, 0xBC0F, 0xBC0F}, {0xBC10, 0xBC10, 0xBC10}, {0xBC11, 0xBC11, 0xBC11}, {0xBC12, 0xBC12, 0xBC12}, {0xBC13, 0xBC13, 0xBC13}, {0xBC14, 0xBC14, 0xBC14}, {0xBC15, 0xBC15, 0xBC15}, {0xBC16, 0xBC16, 0xBC16}, {0xBC17, 0xBC17, 0xBC17}, {0xBC18, 0xBC18, 0xBC18}, {0xBC19, 0xBC19, 0xBC19}, {0xBC1A, 0xBC1A, 0xBC1A}, {0xBC1B, 0xBC1B, 0xBC1B}, {0xBC1C, 0xBC1C, 0xBC1C}, {0xBC1D, 0xBC1D, 0xBC1D}, {0xBC1E, 0xBC1E, 0xBC1E}, {0xBC1F, 0xBC1F, 0xBC1F}, {0xBC20, 0xBC20, 0xBC20}, {0xBC21, 0xBC21, 0xBC21}, {0xBC22, 0xBC22, 0xBC22}, {0xBC23, 0xBC23, 0xBC23}, {0xBC24, 0xBC24, 0xBC24}, {0xBC25, 0xBC25, 0xBC25}, {0xBC26, 0xBC26, 0xBC26}, {0xBC27, 0xBC27, 0xBC27}, {0xBC28, 0xBC28, 0xBC28}, {0xBC29, 0xBC29, 0xBC29}, {0xBC2A, 0xBC2A, 0xBC2A}, {0xBC2B, 0xBC2B, 0xBC2B}, {0xBC2C, 0xBC2C, 0xBC2C}, {0xBC2D, 0xBC2D, 0xBC2D}, {0xBC2E, 0xBC2E, 0xBC2E}, {0xBC2F, 0xBC2F, 0xBC2F}, {0xBC30, 0xBC30, 0xBC30}, {0xBC31, 0xBC31, 0xBC31}, {0xBC32, 0xBC32, 0xBC32}, {0xBC33, 0xBC33, 0xBC33}, {0xBC34, 0xBC34, 0xBC34}, {0xBC35, 0xBC35, 0xBC35}, {0xBC36, 0xBC36, 0xBC36}, {0xBC37, 0xBC37, 0xBC37}, {0xBC38, 0xBC38, 0xBC38}, {0xBC39, 0xBC39, 0xBC39}, {0xBC3A, 0xBC3A, 0xBC3A}, {0xBC3B, 0xBC3B, 0xBC3B}, {0xBC3C, 0xBC3C, 0xBC3C}, {0xBC3D, 0xBC3D, 0xBC3D}, {0xBC3E, 0xBC3E, 0xBC3E}, {0xBC3F, 0xBC3F, 0xBC3F}, {0xBC40, 0xBC40, 0xBC40}, {0xBC41, 0xBC41, 0xBC41}, {0xBC42, 0xBC42, 0xBC42}, {0xBC43, 0xBC43, 0xBC43}, {0xBC44, 0xBC44, 0xBC44}, {0xBC45, 0xBC45, 0xBC45}, {0xBC46, 0xBC46, 0xBC46}, {0xBC47, 0xBC47, 0xBC47}, {0xBC48, 0xBC48, 0xBC48}, {0xBC49, 0xBC49, 0xBC49}, {0xBC4A, 0xBC4A, 0xBC4A}, {0xBC4B, 0xBC4B, 0xBC4B}, {0xBC4C, 0xBC4C, 0xBC4C}, {0xBC4D, 0xBC4D, 0xBC4D}, {0xBC4E, 0xBC4E, 0xBC4E}, {0xBC4F, 0xBC4F, 0xBC4F}, {0xBC50, 0xBC50, 0xBC50}, {0xBC51, 0xBC51, 0xBC51}, {0xBC52, 0xBC52, 0xBC52}, {0xBC53, 0xBC53, 0xBC53}, {0xBC54, 0xBC54, 0xBC54}, {0xBC55, 0xBC55, 0xBC55}, {0xBC56, 0xBC56, 0xBC56}, {0xBC57, 0xBC57, 0xBC57}, {0xBC58, 0xBC58, 0xBC58}, {0xBC59, 0xBC59, 0xBC59}, {0xBC5A, 0xBC5A, 0xBC5A}, {0xBC5B, 0xBC5B, 0xBC5B}, {0xBC5C, 0xBC5C, 0xBC5C}, {0xBC5D, 0xBC5D, 0xBC5D}, {0xBC5E, 0xBC5E, 0xBC5E}, {0xBC5F, 0xBC5F, 0xBC5F}, {0xBC60, 0xBC60, 0xBC60}, {0xBC61, 0xBC61, 0xBC61}, {0xBC62, 0xBC62, 0xBC62}, {0xBC63, 0xBC63, 0xBC63}, {0xBC64, 0xBC64, 0xBC64}, {0xBC65, 0xBC65, 0xBC65}, {0xBC66, 0xBC66, 0xBC66}, {0xBC67, 0xBC67, 0xBC67}, {0xBC68, 0xBC68, 0xBC68}, {0xBC69, 0xBC69, 0xBC69}, {0xBC6A, 0xBC6A, 0xBC6A}, {0xBC6B, 0xBC6B, 0xBC6B}, {0xBC6C, 0xBC6C, 0xBC6C}, {0xBC6D, 0xBC6D, 0xBC6D}, {0xBC6E, 0xBC6E, 0xBC6E}, {0xBC6F, 0xBC6F, 0xBC6F}, {0xBC70, 0xBC70, 0xBC70}, {0xBC71, 0xBC71, 0xBC71}, {0xBC72, 0xBC72, 0xBC72}, {0xBC73, 0xBC73, 0xBC73}, {0xBC74, 0xBC74, 0xBC74}, {0xBC75, 0xBC75, 0xBC75}, {0xBC76, 0xBC76, 0xBC76}, {0xBC77, 0xBC77, 0xBC77}, {0xBC78, 0xBC78, 0xBC78}, {0xBC79, 0xBC79, 0xBC79}, {0xBC7A, 0xBC7A, 0xBC7A}, {0xBC7B, 0xBC7B, 0xBC7B}, {0xBC7C, 0xBC7C, 0xBC7C}, {0xBC7D, 0xBC7D, 0xBC7D}, {0xBC7E, 0xBC7E, 0xBC7E}, {0xBC7F, 0xBC7F, 0xBC7F}, {0xBC80, 0xBC80, 0xBC80}, {0xBC81, 0xBC81, 0xBC81}, {0xBC82, 0xBC82, 0xBC82}, {0xBC83, 0xBC83, 0xBC83}, {0xBC84, 0xBC84, 0xBC84}, {0xBC85, 0xBC85, 0xBC85}, {0xBC86, 0xBC86, 0xBC86}, {0xBC87, 0xBC87, 0xBC87}, {0xBC88, 0xBC88, 0xBC88}, {0xBC89, 0xBC89, 0xBC89}, {0xBC8A, 0xBC8A, 0xBC8A}, {0xBC8B, 0xBC8B, 0xBC8B}, {0xBC8C, 0xBC8C, 0xBC8C}, {0xBC8D, 0xBC8D, 0xBC8D}, {0xBC8E, 0xBC8E, 0xBC8E}, {0xBC8F, 0xBC8F, 0xBC8F}, {0xBC90, 0xBC90, 0xBC90}, {0xBC91, 0xBC91, 0xBC91}, {0xBC92, 0xBC92, 0xBC92}, {0xBC93, 0xBC93, 0xBC93}, {0xBC94, 0xBC94, 0xBC94}, {0xBC95, 0xBC95, 0xBC95}, {0xBC96, 0xBC96, 0xBC96}, {0xBC97, 0xBC97, 0xBC97}, {0xBC98, 0xBC98, 0xBC98}, {0xBC99, 0xBC99, 0xBC99}, {0xBC9A, 0xBC9A, 0xBC9A}, {0xBC9B, 0xBC9B, 0xBC9B}, {0xBC9C, 0xBC9C, 0xBC9C}, {0xBC9D, 0xBC9D, 0xBC9D}, {0xBC9E, 0xBC9E, 0xBC9E}, {0xBC9F, 0xBC9F, 0xBC9F}, {0xBCA0, 0xBCA0, 0xBCA0}, {0xBCA1, 0xBCA1, 0xBCA1}, {0xBCA2, 0xBCA2, 0xBCA2}, {0xBCA3, 0xBCA3, 0xBCA3}, {0xBCA4, 0xBCA4, 0xBCA4}, {0xBCA5, 0xBCA5, 0xBCA5}, {0xBCA6, 0xBCA6, 0xBCA6}, {0xBCA7, 0xBCA7, 0xBCA7}, {0xBCA8, 0xBCA8, 0xBCA8}, {0xBCA9, 0xBCA9, 0xBCA9}, {0xBCAA, 0xBCAA, 0xBCAA}, {0xBCAB, 0xBCAB, 0xBCAB}, {0xBCAC, 0xBCAC, 0xBCAC}, {0xBCAD, 0xBCAD, 0xBCAD}, {0xBCAE, 0xBCAE, 0xBCAE}, {0xBCAF, 0xBCAF, 0xBCAF}, {0xBCB0, 0xBCB0, 0xBCB0}, {0xBCB1, 0xBCB1, 0xBCB1}, {0xBCB2, 0xBCB2, 0xBCB2}, {0xBCB3, 0xBCB3, 0xBCB3}, {0xBCB4, 0xBCB4, 0xBCB4}, {0xBCB5, 0xBCB5, 0xBCB5}, {0xBCB6, 0xBCB6, 0xBCB6}, {0xBCB7, 0xBCB7, 0xBCB7}, {0xBCB8, 0xBCB8, 0xBCB8}, {0xBCB9, 0xBCB9, 0xBCB9}, {0xBCBA, 0xBCBA, 0xBCBA}, {0xBCBB, 0xBCBB, 0xBCBB}, {0xBCBC, 0xBCBC, 0xBCBC}, {0xBCBD, 0xBCBD, 0xBCBD}, {0xBCBE, 0xBCBE, 0xBCBE}, {0xBCBF, 0xBCBF, 0xBCBF}, {0xBCC0, 0xBCC0, 0xBCC0}, {0xBCC1, 0xBCC1, 0xBCC1}, {0xBCC2, 0xBCC2, 0xBCC2}, {0xBCC3, 0xBCC3, 0xBCC3}, {0xBCC4, 0xBCC4, 0xBCC4}, {0xBCC5, 0xBCC5, 0xBCC5}, {0xBCC6, 0xBCC6, 0xBCC6}, {0xBCC7, 0xBCC7, 0xBCC7}, {0xBCC8, 0xBCC8, 0xBCC8}, {0xBCC9, 0xBCC9, 0xBCC9}, {0xBCCA, 0xBCCA, 0xBCCA}, {0xBCCB, 0xBCCB, 0xBCCB}, {0xBCCC, 0xBCCC, 0xBCCC}, {0xBCCD, 0xBCCD, 0xBCCD}, {0xBCCE, 0xBCCE, 0xBCCE}, {0xBCCF, 0xBCCF, 0xBCCF}, {0xBCD0, 0xBCD0, 0xBCD0}, {0xBCD1, 0xBCD1, 0xBCD1}, {0xBCD2, 0xBCD2, 0xBCD2}, {0xBCD3, 0xBCD3, 0xBCD3}, {0xBCD4, 0xBCD4, 0xBCD4}, {0xBCD5, 0xBCD5, 0xBCD5}, {0xBCD6, 0xBCD6, 0xBCD6}, {0xBCD7, 0xBCD7, 0xBCD7}, {0xBCD8, 0xBCD8, 0xBCD8}, {0xBCD9, 0xBCD9, 0xBCD9}, {0xBCDA, 0xBCDA, 0xBCDA}, {0xBCDB, 0xBCDB, 0xBCDB}, {0xBCDC, 0xBCDC, 0xBCDC}, {0xBCDD, 0xBCDD, 0xBCDD}, {0xBCDE, 0xBCDE, 0xBCDE}, {0xBCDF, 0xBCDF, 0xBCDF}, {0xBCE0, 0xBCE0, 0xBCE0}, {0xBCE1, 0xBCE1, 0xBCE1}, {0xBCE2, 0xBCE2, 0xBCE2}, {0xBCE3, 0xBCE3, 0xBCE3}, {0xBCE4, 0xBCE4, 0xBCE4}, {0xBCE5, 0xBCE5, 0xBCE5}, {0xBCE6, 0xBCE6, 0xBCE6}, {0xBCE7, 0xBCE7, 0xBCE7}, {0xBCE8, 0xBCE8, 0xBCE8}, {0xBCE9, 0xBCE9, 0xBCE9}, {0xBCEA, 0xBCEA, 0xBCEA}, {0xBCEB, 0xBCEB, 0xBCEB}, {0xBCEC, 0xBCEC, 0xBCEC}, {0xBCED, 0xBCED, 0xBCED}, {0xBCEE, 0xBCEE, 0xBCEE}, {0xBCEF, 0xBCEF, 0xBCEF}, {0xBCF0, 0xBCF0, 0xBCF0}, {0xBCF1, 0xBCF1, 0xBCF1}, {0xBCF2, 0xBCF2, 0xBCF2}, {0xBCF3, 0xBCF3, 0xBCF3}, {0xBCF4, 0xBCF4, 0xBCF4}, {0xBCF5, 0xBCF5, 0xBCF5}, {0xBCF6, 0xBCF6, 0xBCF6}, {0xBCF7, 0xBCF7, 0xBCF7}, {0xBCF8, 0xBCF8, 0xBCF8}, {0xBCF9, 0xBCF9, 0xBCF9}, {0xBCFA, 0xBCFA, 0xBCFA}, {0xBCFB, 0xBCFB, 0xBCFB}, {0xBCFC, 0xBCFC, 0xBCFC}, {0xBCFD, 0xBCFD, 0xBCFD}, {0xBCFE, 0xBCFE, 0xBCFE}, {0xBCFF, 0xBCFF, 0xBCFF}, {0xBD00, 0xBD00, 0xBD00}, {0xBD01, 0xBD01, 0xBD01}, {0xBD02, 0xBD02, 0xBD02}, {0xBD03, 0xBD03, 0xBD03}, {0xBD04, 0xBD04, 0xBD04}, {0xBD05, 0xBD05, 0xBD05}, {0xBD06, 0xBD06, 0xBD06}, {0xBD07, 0xBD07, 0xBD07}, {0xBD08, 0xBD08, 0xBD08}, {0xBD09, 0xBD09, 0xBD09}, {0xBD0A, 0xBD0A, 0xBD0A}, {0xBD0B, 0xBD0B, 0xBD0B}, {0xBD0C, 0xBD0C, 0xBD0C}, {0xBD0D, 0xBD0D, 0xBD0D}, {0xBD0E, 0xBD0E, 0xBD0E}, {0xBD0F, 0xBD0F, 0xBD0F}, {0xBD10, 0xBD10, 0xBD10}, {0xBD11, 0xBD11, 0xBD11}, {0xBD12, 0xBD12, 0xBD12}, {0xBD13, 0xBD13, 0xBD13}, {0xBD14, 0xBD14, 0xBD14}, {0xBD15, 0xBD15, 0xBD15}, {0xBD16, 0xBD16, 0xBD16}, {0xBD17, 0xBD17, 0xBD17}, {0xBD18, 0xBD18, 0xBD18}, {0xBD19, 0xBD19, 0xBD19}, {0xBD1A, 0xBD1A, 0xBD1A}, {0xBD1B, 0xBD1B, 0xBD1B}, {0xBD1C, 0xBD1C, 0xBD1C}, {0xBD1D, 0xBD1D, 0xBD1D}, {0xBD1E, 0xBD1E, 0xBD1E}, {0xBD1F, 0xBD1F, 0xBD1F}, {0xBD20, 0xBD20, 0xBD20}, {0xBD21, 0xBD21, 0xBD21}, {0xBD22, 0xBD22, 0xBD22}, {0xBD23, 0xBD23, 0xBD23}, {0xBD24, 0xBD24, 0xBD24}, {0xBD25, 0xBD25, 0xBD25}, {0xBD26, 0xBD26, 0xBD26}, {0xBD27, 0xBD27, 0xBD27}, {0xBD28, 0xBD28, 0xBD28}, {0xBD29, 0xBD29, 0xBD29}, {0xBD2A, 0xBD2A, 0xBD2A}, {0xBD2B, 0xBD2B, 0xBD2B}, {0xBD2C, 0xBD2C, 0xBD2C}, {0xBD2D, 0xBD2D, 0xBD2D}, {0xBD2E, 0xBD2E, 0xBD2E}, {0xBD2F, 0xBD2F, 0xBD2F}, {0xBD30, 0xBD30, 0xBD30}, {0xBD31, 0xBD31, 0xBD31}, {0xBD32, 0xBD32, 0xBD32}, {0xBD33, 0xBD33, 0xBD33}, {0xBD34, 0xBD34, 0xBD34}, {0xBD35, 0xBD35, 0xBD35}, {0xBD36, 0xBD36, 0xBD36}, {0xBD37, 0xBD37, 0xBD37}, {0xBD38, 0xBD38, 0xBD38}, {0xBD39, 0xBD39, 0xBD39}, {0xBD3A, 0xBD3A, 0xBD3A}, {0xBD3B, 0xBD3B, 0xBD3B}, {0xBD3C, 0xBD3C, 0xBD3C}, {0xBD3D, 0xBD3D, 0xBD3D}, {0xBD3E, 0xBD3E, 0xBD3E}, {0xBD3F, 0xBD3F, 0xBD3F}, {0xBD40, 0xBD40, 0xBD40}, {0xBD41, 0xBD41, 0xBD41}, {0xBD42, 0xBD42, 0xBD42}, {0xBD43, 0xBD43, 0xBD43}, {0xBD44, 0xBD44, 0xBD44}, {0xBD45, 0xBD45, 0xBD45}, {0xBD46, 0xBD46, 0xBD46}, {0xBD47, 0xBD47, 0xBD47}, {0xBD48, 0xBD48, 0xBD48}, {0xBD49, 0xBD49, 0xBD49}, {0xBD4A, 0xBD4A, 0xBD4A}, {0xBD4B, 0xBD4B, 0xBD4B}, {0xBD4C, 0xBD4C, 0xBD4C}, {0xBD4D, 0xBD4D, 0xBD4D}, {0xBD4E, 0xBD4E, 0xBD4E}, {0xBD4F, 0xBD4F, 0xBD4F}, {0xBD50, 0xBD50, 0xBD50}, {0xBD51, 0xBD51, 0xBD51}, {0xBD52, 0xBD52, 0xBD52}, {0xBD53, 0xBD53, 0xBD53}, {0xBD54, 0xBD54, 0xBD54}, {0xBD55, 0xBD55, 0xBD55}, {0xBD56, 0xBD56, 0xBD56}, {0xBD57, 0xBD57, 0xBD57}, {0xBD58, 0xBD58, 0xBD58}, {0xBD59, 0xBD59, 0xBD59}, {0xBD5A, 0xBD5A, 0xBD5A}, {0xBD5B, 0xBD5B, 0xBD5B}, {0xBD5C, 0xBD5C, 0xBD5C}, {0xBD5D, 0xBD5D, 0xBD5D}, {0xBD5E, 0xBD5E, 0xBD5E}, {0xBD5F, 0xBD5F, 0xBD5F}, {0xBD60, 0xBD60, 0xBD60}, {0xBD61, 0xBD61, 0xBD61}, {0xBD62, 0xBD62, 0xBD62}, {0xBD63, 0xBD63, 0xBD63}, {0xBD64, 0xBD64, 0xBD64}, {0xBD65, 0xBD65, 0xBD65}, {0xBD66, 0xBD66, 0xBD66}, {0xBD67, 0xBD67, 0xBD67}, {0xBD68, 0xBD68, 0xBD68}, {0xBD69, 0xBD69, 0xBD69}, {0xBD6A, 0xBD6A, 0xBD6A}, {0xBD6B, 0xBD6B, 0xBD6B}, {0xBD6C, 0xBD6C, 0xBD6C}, {0xBD6D, 0xBD6D, 0xBD6D}, {0xBD6E, 0xBD6E, 0xBD6E}, {0xBD6F, 0xBD6F, 0xBD6F}, {0xBD70, 0xBD70, 0xBD70}, {0xBD71, 0xBD71, 0xBD71}, {0xBD72, 0xBD72, 0xBD72}, {0xBD73, 0xBD73, 0xBD73}, {0xBD74, 0xBD74, 0xBD74}, {0xBD75, 0xBD75, 0xBD75}, {0xBD76, 0xBD76, 0xBD76}, {0xBD77, 0xBD77, 0xBD77}, {0xBD78, 0xBD78, 0xBD78}, {0xBD79, 0xBD79, 0xBD79}, {0xBD7A, 0xBD7A, 0xBD7A}, {0xBD7B, 0xBD7B, 0xBD7B}, {0xBD7C, 0xBD7C, 0xBD7C}, {0xBD7D, 0xBD7D, 0xBD7D}, {0xBD7E, 0xBD7E, 0xBD7E}, {0xBD7F, 0xBD7F, 0xBD7F}, {0xBD80, 0xBD80, 0xBD80}, {0xBD81, 0xBD81, 0xBD81}, {0xBD82, 0xBD82, 0xBD82}, {0xBD83, 0xBD83, 0xBD83}, {0xBD84, 0xBD84, 0xBD84}, {0xBD85, 0xBD85, 0xBD85}, {0xBD86, 0xBD86, 0xBD86}, {0xBD87, 0xBD87, 0xBD87}, {0xBD88, 0xBD88, 0xBD88}, {0xBD89, 0xBD89, 0xBD89}, {0xBD8A, 0xBD8A, 0xBD8A}, {0xBD8B, 0xBD8B, 0xBD8B}, {0xBD8C, 0xBD8C, 0xBD8C}, {0xBD8D, 0xBD8D, 0xBD8D}, {0xBD8E, 0xBD8E, 0xBD8E}, {0xBD8F, 0xBD8F, 0xBD8F}, {0xBD90, 0xBD90, 0xBD90}, {0xBD91, 0xBD91, 0xBD91}, {0xBD92, 0xBD92, 0xBD92}, {0xBD93, 0xBD93, 0xBD93}, {0xBD94, 0xBD94, 0xBD94}, {0xBD95, 0xBD95, 0xBD95}, {0xBD96, 0xBD96, 0xBD96}, {0xBD97, 0xBD97, 0xBD97}, {0xBD98, 0xBD98, 0xBD98}, {0xBD99, 0xBD99, 0xBD99}, {0xBD9A, 0xBD9A, 0xBD9A}, {0xBD9B, 0xBD9B, 0xBD9B}, {0xBD9C, 0xBD9C, 0xBD9C}, {0xBD9D, 0xBD9D, 0xBD9D}, {0xBD9E, 0xBD9E, 0xBD9E}, {0xBD9F, 0xBD9F, 0xBD9F}, {0xBDA0, 0xBDA0, 0xBDA0}, {0xBDA1, 0xBDA1, 0xBDA1}, {0xBDA2, 0xBDA2, 0xBDA2}, {0xBDA3, 0xBDA3, 0xBDA3}, {0xBDA4, 0xBDA4, 0xBDA4}, {0xBDA5, 0xBDA5, 0xBDA5}, {0xBDA6, 0xBDA6, 0xBDA6}, {0xBDA7, 0xBDA7, 0xBDA7}, {0xBDA8, 0xBDA8, 0xBDA8}, {0xBDA9, 0xBDA9, 0xBDA9}, {0xBDAA, 0xBDAA, 0xBDAA}, {0xBDAB, 0xBDAB, 0xBDAB}, {0xBDAC, 0xBDAC, 0xBDAC}, {0xBDAD, 0xBDAD, 0xBDAD}, {0xBDAE, 0xBDAE, 0xBDAE}, {0xBDAF, 0xBDAF, 0xBDAF}, {0xBDB0, 0xBDB0, 0xBDB0}, {0xBDB1, 0xBDB1, 0xBDB1}, {0xBDB2, 0xBDB2, 0xBDB2}, {0xBDB3, 0xBDB3, 0xBDB3}, {0xBDB4, 0xBDB4, 0xBDB4}, {0xBDB5, 0xBDB5, 0xBDB5}, {0xBDB6, 0xBDB6, 0xBDB6}, {0xBDB7, 0xBDB7, 0xBDB7}, {0xBDB8, 0xBDB8, 0xBDB8}, {0xBDB9, 0xBDB9, 0xBDB9}, {0xBDBA, 0xBDBA, 0xBDBA}, {0xBDBB, 0xBDBB, 0xBDBB}, {0xBDBC, 0xBDBC, 0xBDBC}, {0xBDBD, 0xBDBD, 0xBDBD}, {0xBDBE, 0xBDBE, 0xBDBE}, {0xBDBF, 0xBDBF, 0xBDBF}, {0xBDC0, 0xBDC0, 0xBDC0}, {0xBDC1, 0xBDC1, 0xBDC1}, {0xBDC2, 0xBDC2, 0xBDC2}, {0xBDC3, 0xBDC3, 0xBDC3}, {0xBDC4, 0xBDC4, 0xBDC4}, {0xBDC5, 0xBDC5, 0xBDC5}, {0xBDC6, 0xBDC6, 0xBDC6}, {0xBDC7, 0xBDC7, 0xBDC7}, {0xBDC8, 0xBDC8, 0xBDC8}, {0xBDC9, 0xBDC9, 0xBDC9}, {0xBDCA, 0xBDCA, 0xBDCA}, {0xBDCB, 0xBDCB, 0xBDCB}, {0xBDCC, 0xBDCC, 0xBDCC}, {0xBDCD, 0xBDCD, 0xBDCD}, {0xBDCE, 0xBDCE, 0xBDCE}, {0xBDCF, 0xBDCF, 0xBDCF}, {0xBDD0, 0xBDD0, 0xBDD0}, {0xBDD1, 0xBDD1, 0xBDD1}, {0xBDD2, 0xBDD2, 0xBDD2}, {0xBDD3, 0xBDD3, 0xBDD3}, {0xBDD4, 0xBDD4, 0xBDD4}, {0xBDD5, 0xBDD5, 0xBDD5}, {0xBDD6, 0xBDD6, 0xBDD6}, {0xBDD7, 0xBDD7, 0xBDD7}, {0xBDD8, 0xBDD8, 0xBDD8}, {0xBDD9, 0xBDD9, 0xBDD9}, {0xBDDA, 0xBDDA, 0xBDDA}, {0xBDDB, 0xBDDB, 0xBDDB}, {0xBDDC, 0xBDDC, 0xBDDC}, {0xBDDD, 0xBDDD, 0xBDDD}, {0xBDDE, 0xBDDE, 0xBDDE}, {0xBDDF, 0xBDDF, 0xBDDF}, {0xBDE0, 0xBDE0, 0xBDE0}, {0xBDE1, 0xBDE1, 0xBDE1}, {0xBDE2, 0xBDE2, 0xBDE2}, {0xBDE3, 0xBDE3, 0xBDE3}, {0xBDE4, 0xBDE4, 0xBDE4}, {0xBDE5, 0xBDE5, 0xBDE5}, {0xBDE6, 0xBDE6, 0xBDE6}, {0xBDE7, 0xBDE7, 0xBDE7}, {0xBDE8, 0xBDE8, 0xBDE8}, {0xBDE9, 0xBDE9, 0xBDE9}, {0xBDEA, 0xBDEA, 0xBDEA}, {0xBDEB, 0xBDEB, 0xBDEB}, {0xBDEC, 0xBDEC, 0xBDEC}, {0xBDED, 0xBDED, 0xBDED}, {0xBDEE, 0xBDEE, 0xBDEE}, {0xBDEF, 0xBDEF, 0xBDEF}, {0xBDF0, 0xBDF0, 0xBDF0}, {0xBDF1, 0xBDF1, 0xBDF1}, {0xBDF2, 0xBDF2, 0xBDF2}, {0xBDF3, 0xBDF3, 0xBDF3}, {0xBDF4, 0xBDF4, 0xBDF4}, {0xBDF5, 0xBDF5, 0xBDF5}, {0xBDF6, 0xBDF6, 0xBDF6}, {0xBDF7, 0xBDF7, 0xBDF7}, {0xBDF8, 0xBDF8, 0xBDF8}, {0xBDF9, 0xBDF9, 0xBDF9}, {0xBDFA, 0xBDFA, 0xBDFA}, {0xBDFB, 0xBDFB, 0xBDFB}, {0xBDFC, 0xBDFC, 0xBDFC}, {0xBDFD, 0xBDFD, 0xBDFD}, {0xBDFE, 0xBDFE, 0xBDFE}, {0xBDFF, 0xBDFF, 0xBDFF}, {0xBE00, 0xBE00, 0xBE00}, {0xBE01, 0xBE01, 0xBE01}, {0xBE02, 0xBE02, 0xBE02}, {0xBE03, 0xBE03, 0xBE03}, {0xBE04, 0xBE04, 0xBE04}, {0xBE05, 0xBE05, 0xBE05}, {0xBE06, 0xBE06, 0xBE06}, {0xBE07, 0xBE07, 0xBE07}, {0xBE08, 0xBE08, 0xBE08}, {0xBE09, 0xBE09, 0xBE09}, {0xBE0A, 0xBE0A, 0xBE0A}, {0xBE0B, 0xBE0B, 0xBE0B}, {0xBE0C, 0xBE0C, 0xBE0C}, {0xBE0D, 0xBE0D, 0xBE0D}, {0xBE0E, 0xBE0E, 0xBE0E}, {0xBE0F, 0xBE0F, 0xBE0F}, {0xBE10, 0xBE10, 0xBE10}, {0xBE11, 0xBE11, 0xBE11}, {0xBE12, 0xBE12, 0xBE12}, {0xBE13, 0xBE13, 0xBE13}, {0xBE14, 0xBE14, 0xBE14}, {0xBE15, 0xBE15, 0xBE15}, {0xBE16, 0xBE16, 0xBE16}, {0xBE17, 0xBE17, 0xBE17}, {0xBE18, 0xBE18, 0xBE18}, {0xBE19, 0xBE19, 0xBE19}, {0xBE1A, 0xBE1A, 0xBE1A}, {0xBE1B, 0xBE1B, 0xBE1B}, {0xBE1C, 0xBE1C, 0xBE1C}, {0xBE1D, 0xBE1D, 0xBE1D}, {0xBE1E, 0xBE1E, 0xBE1E}, {0xBE1F, 0xBE1F, 0xBE1F}, {0xBE20, 0xBE20, 0xBE20}, {0xBE21, 0xBE21, 0xBE21}, {0xBE22, 0xBE22, 0xBE22}, {0xBE23, 0xBE23, 0xBE23}, {0xBE24, 0xBE24, 0xBE24}, {0xBE25, 0xBE25, 0xBE25}, {0xBE26, 0xBE26, 0xBE26}, {0xBE27, 0xBE27, 0xBE27}, {0xBE28, 0xBE28, 0xBE28}, {0xBE29, 0xBE29, 0xBE29}, {0xBE2A, 0xBE2A, 0xBE2A}, {0xBE2B, 0xBE2B, 0xBE2B}, {0xBE2C, 0xBE2C, 0xBE2C}, {0xBE2D, 0xBE2D, 0xBE2D}, {0xBE2E, 0xBE2E, 0xBE2E}, {0xBE2F, 0xBE2F, 0xBE2F}, {0xBE30, 0xBE30, 0xBE30}, {0xBE31, 0xBE31, 0xBE31}, {0xBE32, 0xBE32, 0xBE32}, {0xBE33, 0xBE33, 0xBE33}, {0xBE34, 0xBE34, 0xBE34}, {0xBE35, 0xBE35, 0xBE35}, {0xBE36, 0xBE36, 0xBE36}, {0xBE37, 0xBE37, 0xBE37}, {0xBE38, 0xBE38, 0xBE38}, {0xBE39, 0xBE39, 0xBE39}, {0xBE3A, 0xBE3A, 0xBE3A}, {0xBE3B, 0xBE3B, 0xBE3B}, {0xBE3C, 0xBE3C, 0xBE3C}, {0xBE3D, 0xBE3D, 0xBE3D}, {0xBE3E, 0xBE3E, 0xBE3E}, {0xBE3F, 0xBE3F, 0xBE3F}, {0xBE40, 0xBE40, 0xBE40}, {0xBE41, 0xBE41, 0xBE41}, {0xBE42, 0xBE42, 0xBE42}, {0xBE43, 0xBE43, 0xBE43}, {0xBE44, 0xBE44, 0xBE44}, {0xBE45, 0xBE45, 0xBE45}, {0xBE46, 0xBE46, 0xBE46}, {0xBE47, 0xBE47, 0xBE47}, {0xBE48, 0xBE48, 0xBE48}, {0xBE49, 0xBE49, 0xBE49}, {0xBE4A, 0xBE4A, 0xBE4A}, {0xBE4B, 0xBE4B, 0xBE4B}, {0xBE4C, 0xBE4C, 0xBE4C}, {0xBE4D, 0xBE4D, 0xBE4D}, {0xBE4E, 0xBE4E, 0xBE4E}, {0xBE4F, 0xBE4F, 0xBE4F}, {0xBE50, 0xBE50, 0xBE50}, {0xBE51, 0xBE51, 0xBE51}, {0xBE52, 0xBE52, 0xBE52}, {0xBE53, 0xBE53, 0xBE53}, {0xBE54, 0xBE54, 0xBE54}, {0xBE55, 0xBE55, 0xBE55}, {0xBE56, 0xBE56, 0xBE56}, {0xBE57, 0xBE57, 0xBE57}, {0xBE58, 0xBE58, 0xBE58}, {0xBE59, 0xBE59, 0xBE59}, {0xBE5A, 0xBE5A, 0xBE5A}, {0xBE5B, 0xBE5B, 0xBE5B}, {0xBE5C, 0xBE5C, 0xBE5C}, {0xBE5D, 0xBE5D, 0xBE5D}, {0xBE5E, 0xBE5E, 0xBE5E}, {0xBE5F, 0xBE5F, 0xBE5F}, {0xBE60, 0xBE60, 0xBE60}, {0xBE61, 0xBE61, 0xBE61}, {0xBE62, 0xBE62, 0xBE62}, {0xBE63, 0xBE63, 0xBE63}, {0xBE64, 0xBE64, 0xBE64}, {0xBE65, 0xBE65, 0xBE65}, {0xBE66, 0xBE66, 0xBE66}, {0xBE67, 0xBE67, 0xBE67}, {0xBE68, 0xBE68, 0xBE68}, {0xBE69, 0xBE69, 0xBE69}, {0xBE6A, 0xBE6A, 0xBE6A}, {0xBE6B, 0xBE6B, 0xBE6B}, {0xBE6C, 0xBE6C, 0xBE6C}, {0xBE6D, 0xBE6D, 0xBE6D}, {0xBE6E, 0xBE6E, 0xBE6E}, {0xBE6F, 0xBE6F, 0xBE6F}, {0xBE70, 0xBE70, 0xBE70}, {0xBE71, 0xBE71, 0xBE71}, {0xBE72, 0xBE72, 0xBE72}, {0xBE73, 0xBE73, 0xBE73}, {0xBE74, 0xBE74, 0xBE74}, {0xBE75, 0xBE75, 0xBE75}, {0xBE76, 0xBE76, 0xBE76}, {0xBE77, 0xBE77, 0xBE77}, {0xBE78, 0xBE78, 0xBE78}, {0xBE79, 0xBE79, 0xBE79}, {0xBE7A, 0xBE7A, 0xBE7A}, {0xBE7B, 0xBE7B, 0xBE7B}, {0xBE7C, 0xBE7C, 0xBE7C}, {0xBE7D, 0xBE7D, 0xBE7D}, {0xBE7E, 0xBE7E, 0xBE7E}, {0xBE7F, 0xBE7F, 0xBE7F}, {0xBE80, 0xBE80, 0xBE80}, {0xBE81, 0xBE81, 0xBE81}, {0xBE82, 0xBE82, 0xBE82}, {0xBE83, 0xBE83, 0xBE83}, {0xBE84, 0xBE84, 0xBE84}, {0xBE85, 0xBE85, 0xBE85}, {0xBE86, 0xBE86, 0xBE86}, {0xBE87, 0xBE87, 0xBE87}, {0xBE88, 0xBE88, 0xBE88}, {0xBE89, 0xBE89, 0xBE89}, {0xBE8A, 0xBE8A, 0xBE8A}, {0xBE8B, 0xBE8B, 0xBE8B}, {0xBE8C, 0xBE8C, 0xBE8C}, {0xBE8D, 0xBE8D, 0xBE8D}, {0xBE8E, 0xBE8E, 0xBE8E}, {0xBE8F, 0xBE8F, 0xBE8F}, {0xBE90, 0xBE90, 0xBE90}, {0xBE91, 0xBE91, 0xBE91}, {0xBE92, 0xBE92, 0xBE92}, {0xBE93, 0xBE93, 0xBE93}, {0xBE94, 0xBE94, 0xBE94}, {0xBE95, 0xBE95, 0xBE95}, {0xBE96, 0xBE96, 0xBE96}, {0xBE97, 0xBE97, 0xBE97}, {0xBE98, 0xBE98, 0xBE98}, {0xBE99, 0xBE99, 0xBE99}, {0xBE9A, 0xBE9A, 0xBE9A}, {0xBE9B, 0xBE9B, 0xBE9B}, {0xBE9C, 0xBE9C, 0xBE9C}, {0xBE9D, 0xBE9D, 0xBE9D}, {0xBE9E, 0xBE9E, 0xBE9E}, {0xBE9F, 0xBE9F, 0xBE9F}, {0xBEA0, 0xBEA0, 0xBEA0}, {0xBEA1, 0xBEA1, 0xBEA1}, {0xBEA2, 0xBEA2, 0xBEA2}, {0xBEA3, 0xBEA3, 0xBEA3}, {0xBEA4, 0xBEA4, 0xBEA4}, {0xBEA5, 0xBEA5, 0xBEA5}, {0xBEA6, 0xBEA6, 0xBEA6}, {0xBEA7, 0xBEA7, 0xBEA7}, {0xBEA8, 0xBEA8, 0xBEA8}, {0xBEA9, 0xBEA9, 0xBEA9}, {0xBEAA, 0xBEAA, 0xBEAA}, {0xBEAB, 0xBEAB, 0xBEAB}, {0xBEAC, 0xBEAC, 0xBEAC}, {0xBEAD, 0xBEAD, 0xBEAD}, {0xBEAE, 0xBEAE, 0xBEAE}, {0xBEAF, 0xBEAF, 0xBEAF}, {0xBEB0, 0xBEB0, 0xBEB0}, {0xBEB1, 0xBEB1, 0xBEB1}, {0xBEB2, 0xBEB2, 0xBEB2}, {0xBEB3, 0xBEB3, 0xBEB3}, {0xBEB4, 0xBEB4, 0xBEB4}, {0xBEB5, 0xBEB5, 0xBEB5}, {0xBEB6, 0xBEB6, 0xBEB6}, {0xBEB7, 0xBEB7, 0xBEB7}, {0xBEB8, 0xBEB8, 0xBEB8}, {0xBEB9, 0xBEB9, 0xBEB9}, {0xBEBA, 0xBEBA, 0xBEBA}, {0xBEBB, 0xBEBB, 0xBEBB}, {0xBEBC, 0xBEBC, 0xBEBC}, {0xBEBD, 0xBEBD, 0xBEBD}, {0xBEBE, 0xBEBE, 0xBEBE}, {0xBEBF, 0xBEBF, 0xBEBF}, {0xBEC0, 0xBEC0, 0xBEC0}, {0xBEC1, 0xBEC1, 0xBEC1}, {0xBEC2, 0xBEC2, 0xBEC2}, {0xBEC3, 0xBEC3, 0xBEC3}, {0xBEC4, 0xBEC4, 0xBEC4}, {0xBEC5, 0xBEC5, 0xBEC5}, {0xBEC6, 0xBEC6, 0xBEC6}, {0xBEC7, 0xBEC7, 0xBEC7}, {0xBEC8, 0xBEC8, 0xBEC8}, {0xBEC9, 0xBEC9, 0xBEC9}, {0xBECA, 0xBECA, 0xBECA}, {0xBECB, 0xBECB, 0xBECB}, {0xBECC, 0xBECC, 0xBECC}, {0xBECD, 0xBECD, 0xBECD}, {0xBECE, 0xBECE, 0xBECE}, {0xBECF, 0xBECF, 0xBECF}, {0xBED0, 0xBED0, 0xBED0}, {0xBED1, 0xBED1, 0xBED1}, {0xBED2, 0xBED2, 0xBED2}, {0xBED3, 0xBED3, 0xBED3}, {0xBED4, 0xBED4, 0xBED4}, {0xBED5, 0xBED5, 0xBED5}, {0xBED6, 0xBED6, 0xBED6}, {0xBED7, 0xBED7, 0xBED7}, {0xBED8, 0xBED8, 0xBED8}, {0xBED9, 0xBED9, 0xBED9}, {0xBEDA, 0xBEDA, 0xBEDA}, {0xBEDB, 0xBEDB, 0xBEDB}, {0xBEDC, 0xBEDC, 0xBEDC}, {0xBEDD, 0xBEDD, 0xBEDD}, {0xBEDE, 0xBEDE, 0xBEDE}, {0xBEDF, 0xBEDF, 0xBEDF}, {0xBEE0, 0xBEE0, 0xBEE0}, {0xBEE1, 0xBEE1, 0xBEE1}, {0xBEE2, 0xBEE2, 0xBEE2}, {0xBEE3, 0xBEE3, 0xBEE3}, {0xBEE4, 0xBEE4, 0xBEE4}, {0xBEE5, 0xBEE5, 0xBEE5}, {0xBEE6, 0xBEE6, 0xBEE6}, {0xBEE7, 0xBEE7, 0xBEE7}, {0xBEE8, 0xBEE8, 0xBEE8}, {0xBEE9, 0xBEE9, 0xBEE9}, {0xBEEA, 0xBEEA, 0xBEEA}, {0xBEEB, 0xBEEB, 0xBEEB}, {0xBEEC, 0xBEEC, 0xBEEC}, {0xBEED, 0xBEED, 0xBEED}, {0xBEEE, 0xBEEE, 0xBEEE}, {0xBEEF, 0xBEEF, 0xBEEF}, {0xBEF0, 0xBEF0, 0xBEF0}, {0xBEF1, 0xBEF1, 0xBEF1}, {0xBEF2, 0xBEF2, 0xBEF2}, {0xBEF3, 0xBEF3, 0xBEF3}, {0xBEF4, 0xBEF4, 0xBEF4}, {0xBEF5, 0xBEF5, 0xBEF5}, {0xBEF6, 0xBEF6, 0xBEF6}, {0xBEF7, 0xBEF7, 0xBEF7}, {0xBEF8, 0xBEF8, 0xBEF8}, {0xBEF9, 0xBEF9, 0xBEF9}, {0xBEFA, 0xBEFA, 0xBEFA}, {0xBEFB, 0xBEFB, 0xBEFB}, {0xBEFC, 0xBEFC, 0xBEFC}, {0xBEFD, 0xBEFD, 0xBEFD}, {0xBEFE, 0xBEFE, 0xBEFE}, {0xBEFF, 0xBEFF, 0xBEFF}, {0xBF00, 0xBF00, 0xBF00}, {0xBF01, 0xBF01, 0xBF01}, {0xBF02, 0xBF02, 0xBF02}, {0xBF03, 0xBF03, 0xBF03}, {0xBF04, 0xBF04, 0xBF04}, {0xBF05, 0xBF05, 0xBF05}, {0xBF06, 0xBF06, 0xBF06}, {0xBF07, 0xBF07, 0xBF07}, {0xBF08, 0xBF08, 0xBF08}, {0xBF09, 0xBF09, 0xBF09}, {0xBF0A, 0xBF0A, 0xBF0A}, {0xBF0B, 0xBF0B, 0xBF0B}, {0xBF0C, 0xBF0C, 0xBF0C}, {0xBF0D, 0xBF0D, 0xBF0D}, {0xBF0E, 0xBF0E, 0xBF0E}, {0xBF0F, 0xBF0F, 0xBF0F}, {0xBF10, 0xBF10, 0xBF10}, {0xBF11, 0xBF11, 0xBF11}, {0xBF12, 0xBF12, 0xBF12}, {0xBF13, 0xBF13, 0xBF13}, {0xBF14, 0xBF14, 0xBF14}, {0xBF15, 0xBF15, 0xBF15}, {0xBF16, 0xBF16, 0xBF16}, {0xBF17, 0xBF17, 0xBF17}, {0xBF18, 0xBF18, 0xBF18}, {0xBF19, 0xBF19, 0xBF19}, {0xBF1A, 0xBF1A, 0xBF1A}, {0xBF1B, 0xBF1B, 0xBF1B}, {0xBF1C, 0xBF1C, 0xBF1C}, {0xBF1D, 0xBF1D, 0xBF1D}, {0xBF1E, 0xBF1E, 0xBF1E}, {0xBF1F, 0xBF1F, 0xBF1F}, {0xBF20, 0xBF20, 0xBF20}, {0xBF21, 0xBF21, 0xBF21}, {0xBF22, 0xBF22, 0xBF22}, {0xBF23, 0xBF23, 0xBF23}, {0xBF24, 0xBF24, 0xBF24}, {0xBF25, 0xBF25, 0xBF25}, {0xBF26, 0xBF26, 0xBF26}, {0xBF27, 0xBF27, 0xBF27}, {0xBF28, 0xBF28, 0xBF28}, {0xBF29, 0xBF29, 0xBF29}, {0xBF2A, 0xBF2A, 0xBF2A}, {0xBF2B, 0xBF2B, 0xBF2B}, {0xBF2C, 0xBF2C, 0xBF2C}, {0xBF2D, 0xBF2D, 0xBF2D}, {0xBF2E, 0xBF2E, 0xBF2E}, {0xBF2F, 0xBF2F, 0xBF2F}, {0xBF30, 0xBF30, 0xBF30}, {0xBF31, 0xBF31, 0xBF31}, {0xBF32, 0xBF32, 0xBF32}, {0xBF33, 0xBF33, 0xBF33}, {0xBF34, 0xBF34, 0xBF34}, {0xBF35, 0xBF35, 0xBF35}, {0xBF36, 0xBF36, 0xBF36}, {0xBF37, 0xBF37, 0xBF37}, {0xBF38, 0xBF38, 0xBF38}, {0xBF39, 0xBF39, 0xBF39}, {0xBF3A, 0xBF3A, 0xBF3A}, {0xBF3B, 0xBF3B, 0xBF3B}, {0xBF3C, 0xBF3C, 0xBF3C}, {0xBF3D, 0xBF3D, 0xBF3D}, {0xBF3E, 0xBF3E, 0xBF3E}, {0xBF3F, 0xBF3F, 0xBF3F}, {0xBF40, 0xBF40, 0xBF40}, {0xBF41, 0xBF41, 0xBF41}, {0xBF42, 0xBF42, 0xBF42}, {0xBF43, 0xBF43, 0xBF43}, {0xBF44, 0xBF44, 0xBF44}, {0xBF45, 0xBF45, 0xBF45}, {0xBF46, 0xBF46, 0xBF46}, {0xBF47, 0xBF47, 0xBF47}, {0xBF48, 0xBF48, 0xBF48}, {0xBF49, 0xBF49, 0xBF49}, {0xBF4A, 0xBF4A, 0xBF4A}, {0xBF4B, 0xBF4B, 0xBF4B}, {0xBF4C, 0xBF4C, 0xBF4C}, {0xBF4D, 0xBF4D, 0xBF4D}, {0xBF4E, 0xBF4E, 0xBF4E}, {0xBF4F, 0xBF4F, 0xBF4F}, {0xBF50, 0xBF50, 0xBF50}, {0xBF51, 0xBF51, 0xBF51}, {0xBF52, 0xBF52, 0xBF52}, {0xBF53, 0xBF53, 0xBF53}, {0xBF54, 0xBF54, 0xBF54}, {0xBF55, 0xBF55, 0xBF55}, {0xBF56, 0xBF56, 0xBF56}, {0xBF57, 0xBF57, 0xBF57}, {0xBF58, 0xBF58, 0xBF58}, {0xBF59, 0xBF59, 0xBF59}, {0xBF5A, 0xBF5A, 0xBF5A}, {0xBF5B, 0xBF5B, 0xBF5B}, {0xBF5C, 0xBF5C, 0xBF5C}, {0xBF5D, 0xBF5D, 0xBF5D}, {0xBF5E, 0xBF5E, 0xBF5E}, {0xBF5F, 0xBF5F, 0xBF5F}, {0xBF60, 0xBF60, 0xBF60}, {0xBF61, 0xBF61, 0xBF61}, {0xBF62, 0xBF62, 0xBF62}, {0xBF63, 0xBF63, 0xBF63}, {0xBF64, 0xBF64, 0xBF64}, {0xBF65, 0xBF65, 0xBF65}, {0xBF66, 0xBF66, 0xBF66}, {0xBF67, 0xBF67, 0xBF67}, {0xBF68, 0xBF68, 0xBF68}, {0xBF69, 0xBF69, 0xBF69}, {0xBF6A, 0xBF6A, 0xBF6A}, {0xBF6B, 0xBF6B, 0xBF6B}, {0xBF6C, 0xBF6C, 0xBF6C}, {0xBF6D, 0xBF6D, 0xBF6D}, {0xBF6E, 0xBF6E, 0xBF6E}, {0xBF6F, 0xBF6F, 0xBF6F}, {0xBF70, 0xBF70, 0xBF70}, {0xBF71, 0xBF71, 0xBF71}, {0xBF72, 0xBF72, 0xBF72}, {0xBF73, 0xBF73, 0xBF73}, {0xBF74, 0xBF74, 0xBF74}, {0xBF75, 0xBF75, 0xBF75}, {0xBF76, 0xBF76, 0xBF76}, {0xBF77, 0xBF77, 0xBF77}, {0xBF78, 0xBF78, 0xBF78}, {0xBF79, 0xBF79, 0xBF79}, {0xBF7A, 0xBF7A, 0xBF7A}, {0xBF7B, 0xBF7B, 0xBF7B}, {0xBF7C, 0xBF7C, 0xBF7C}, {0xBF7D, 0xBF7D, 0xBF7D}, {0xBF7E, 0xBF7E, 0xBF7E}, {0xBF7F, 0xBF7F, 0xBF7F}, {0xBF80, 0xBF80, 0xBF80}, {0xBF81, 0xBF81, 0xBF81}, {0xBF82, 0xBF82, 0xBF82}, {0xBF83, 0xBF83, 0xBF83}, {0xBF84, 0xBF84, 0xBF84}, {0xBF85, 0xBF85, 0xBF85}, {0xBF86, 0xBF86, 0xBF86}, {0xBF87, 0xBF87, 0xBF87}, {0xBF88, 0xBF88, 0xBF88}, {0xBF89, 0xBF89, 0xBF89}, {0xBF8A, 0xBF8A, 0xBF8A}, {0xBF8B, 0xBF8B, 0xBF8B}, {0xBF8C, 0xBF8C, 0xBF8C}, {0xBF8D, 0xBF8D, 0xBF8D}, {0xBF8E, 0xBF8E, 0xBF8E}, {0xBF8F, 0xBF8F, 0xBF8F}, {0xBF90, 0xBF90, 0xBF90}, {0xBF91, 0xBF91, 0xBF91}, {0xBF92, 0xBF92, 0xBF92}, {0xBF93, 0xBF93, 0xBF93}, {0xBF94, 0xBF94, 0xBF94}, {0xBF95, 0xBF95, 0xBF95}, {0xBF96, 0xBF96, 0xBF96}, {0xBF97, 0xBF97, 0xBF97}, {0xBF98, 0xBF98, 0xBF98}, {0xBF99, 0xBF99, 0xBF99}, {0xBF9A, 0xBF9A, 0xBF9A}, {0xBF9B, 0xBF9B, 0xBF9B}, {0xBF9C, 0xBF9C, 0xBF9C}, {0xBF9D, 0xBF9D, 0xBF9D}, {0xBF9E, 0xBF9E, 0xBF9E}, {0xBF9F, 0xBF9F, 0xBF9F}, {0xBFA0, 0xBFA0, 0xBFA0}, {0xBFA1, 0xBFA1, 0xBFA1}, {0xBFA2, 0xBFA2, 0xBFA2}, {0xBFA3, 0xBFA3, 0xBFA3}, {0xBFA4, 0xBFA4, 0xBFA4}, {0xBFA5, 0xBFA5, 0xBFA5}, {0xBFA6, 0xBFA6, 0xBFA6}, {0xBFA7, 0xBFA7, 0xBFA7}, {0xBFA8, 0xBFA8, 0xBFA8}, {0xBFA9, 0xBFA9, 0xBFA9}, {0xBFAA, 0xBFAA, 0xBFAA}, {0xBFAB, 0xBFAB, 0xBFAB}, {0xBFAC, 0xBFAC, 0xBFAC}, {0xBFAD, 0xBFAD, 0xBFAD}, {0xBFAE, 0xBFAE, 0xBFAE}, {0xBFAF, 0xBFAF, 0xBFAF}, {0xBFB0, 0xBFB0, 0xBFB0}, {0xBFB1, 0xBFB1, 0xBFB1}, {0xBFB2, 0xBFB2, 0xBFB2}, {0xBFB3, 0xBFB3, 0xBFB3}, {0xBFB4, 0xBFB4, 0xBFB4}, {0xBFB5, 0xBFB5, 0xBFB5}, {0xBFB6, 0xBFB6, 0xBFB6}, {0xBFB7, 0xBFB7, 0xBFB7}, {0xBFB8, 0xBFB8, 0xBFB8}, {0xBFB9, 0xBFB9, 0xBFB9}, {0xBFBA, 0xBFBA, 0xBFBA}, {0xBFBB, 0xBFBB, 0xBFBB}, {0xBFBC, 0xBFBC, 0xBFBC}, {0xBFBD, 0xBFBD, 0xBFBD}, {0xBFBE, 0xBFBE, 0xBFBE}, {0xBFBF, 0xBFBF, 0xBFBF}, {0xBFC0, 0xBFC0, 0xBFC0}, {0xBFC1, 0xBFC1, 0xBFC1}, {0xBFC2, 0xBFC2, 0xBFC2}, {0xBFC3, 0xBFC3, 0xBFC3}, {0xBFC4, 0xBFC4, 0xBFC4}, {0xBFC5, 0xBFC5, 0xBFC5}, {0xBFC6, 0xBFC6, 0xBFC6}, {0xBFC7, 0xBFC7, 0xBFC7}, {0xBFC8, 0xBFC8, 0xBFC8}, {0xBFC9, 0xBFC9, 0xBFC9}, {0xBFCA, 0xBFCA, 0xBFCA}, {0xBFCB, 0xBFCB, 0xBFCB}, {0xBFCC, 0xBFCC, 0xBFCC}, {0xBFCD, 0xBFCD, 0xBFCD}, {0xBFCE, 0xBFCE, 0xBFCE}, {0xBFCF, 0xBFCF, 0xBFCF}, {0xBFD0, 0xBFD0, 0xBFD0}, {0xBFD1, 0xBFD1, 0xBFD1}, {0xBFD2, 0xBFD2, 0xBFD2}, {0xBFD3, 0xBFD3, 0xBFD3}, {0xBFD4, 0xBFD4, 0xBFD4}, {0xBFD5, 0xBFD5, 0xBFD5}, {0xBFD6, 0xBFD6, 0xBFD6}, {0xBFD7, 0xBFD7, 0xBFD7}, {0xBFD8, 0xBFD8, 0xBFD8}, {0xBFD9, 0xBFD9, 0xBFD9}, {0xBFDA, 0xBFDA, 0xBFDA}, {0xBFDB, 0xBFDB, 0xBFDB}, {0xBFDC, 0xBFDC, 0xBFDC}, {0xBFDD, 0xBFDD, 0xBFDD}, {0xBFDE, 0xBFDE, 0xBFDE}, {0xBFDF, 0xBFDF, 0xBFDF}, {0xBFE0, 0xBFE0, 0xBFE0}, {0xBFE1, 0xBFE1, 0xBFE1}, {0xBFE2, 0xBFE2, 0xBFE2}, {0xBFE3, 0xBFE3, 0xBFE3}, {0xBFE4, 0xBFE4, 0xBFE4}, {0xBFE5, 0xBFE5, 0xBFE5}, {0xBFE6, 0xBFE6, 0xBFE6}, {0xBFE7, 0xBFE7, 0xBFE7}, {0xBFE8, 0xBFE8, 0xBFE8}, {0xBFE9, 0xBFE9, 0xBFE9}, {0xBFEA, 0xBFEA, 0xBFEA}, {0xBFEB, 0xBFEB, 0xBFEB}, {0xBFEC, 0xBFEC, 0xBFEC}, {0xBFED, 0xBFED, 0xBFED}, {0xBFEE, 0xBFEE, 0xBFEE}, {0xBFEF, 0xBFEF, 0xBFEF}, {0xBFF0, 0xBFF0, 0xBFF0}, {0xBFF1, 0xBFF1, 0xBFF1}, {0xBFF2, 0xBFF2, 0xBFF2}, {0xBFF3, 0xBFF3, 0xBFF3}, {0xBFF4, 0xBFF4, 0xBFF4}, {0xBFF5, 0xBFF5, 0xBFF5}, {0xBFF6, 0xBFF6, 0xBFF6}, {0xBFF7, 0xBFF7, 0xBFF7}, {0xBFF8, 0xBFF8, 0xBFF8}, {0xBFF9, 0xBFF9, 0xBFF9}, {0xBFFA, 0xBFFA, 0xBFFA}, {0xBFFB, 0xBFFB, 0xBFFB}, {0xBFFC, 0xBFFC, 0xBFFC}, {0xBFFD, 0xBFFD, 0xBFFD}, {0xBFFE, 0xBFFE, 0xBFFE}, {0xBFFF, 0xBFFF, 0xBFFF}, {0xC000, 0xC000, 0xC000}, {0xC001, 0xC001, 0xC001}, {0xC002, 0xC002, 0xC002}, {0xC003, 0xC003, 0xC003}, {0xC004, 0xC004, 0xC004}, {0xC005, 0xC005, 0xC005}, {0xC006, 0xC006, 0xC006}, {0xC007, 0xC007, 0xC007}, {0xC008, 0xC008, 0xC008}, {0xC009, 0xC009, 0xC009}, {0xC00A, 0xC00A, 0xC00A}, {0xC00B, 0xC00B, 0xC00B}, {0xC00C, 0xC00C, 0xC00C}, {0xC00D, 0xC00D, 0xC00D}, {0xC00E, 0xC00E, 0xC00E}, {0xC00F, 0xC00F, 0xC00F}, {0xC010, 0xC010, 0xC010}, {0xC011, 0xC011, 0xC011}, {0xC012, 0xC012, 0xC012}, {0xC013, 0xC013, 0xC013}, {0xC014, 0xC014, 0xC014}, {0xC015, 0xC015, 0xC015}, {0xC016, 0xC016, 0xC016}, {0xC017, 0xC017, 0xC017}, {0xC018, 0xC018, 0xC018}, {0xC019, 0xC019, 0xC019}, {0xC01A, 0xC01A, 0xC01A}, {0xC01B, 0xC01B, 0xC01B}, {0xC01C, 0xC01C, 0xC01C}, {0xC01D, 0xC01D, 0xC01D}, {0xC01E, 0xC01E, 0xC01E}, {0xC01F, 0xC01F, 0xC01F}, {0xC020, 0xC020, 0xC020}, {0xC021, 0xC021, 0xC021}, {0xC022, 0xC022, 0xC022}, {0xC023, 0xC023, 0xC023}, {0xC024, 0xC024, 0xC024}, {0xC025, 0xC025, 0xC025}, {0xC026, 0xC026, 0xC026}, {0xC027, 0xC027, 0xC027}, {0xC028, 0xC028, 0xC028}, {0xC029, 0xC029, 0xC029}, {0xC02A, 0xC02A, 0xC02A}, {0xC02B, 0xC02B, 0xC02B}, {0xC02C, 0xC02C, 0xC02C}, {0xC02D, 0xC02D, 0xC02D}, {0xC02E, 0xC02E, 0xC02E}, {0xC02F, 0xC02F, 0xC02F}, {0xC030, 0xC030, 0xC030}, {0xC031, 0xC031, 0xC031}, {0xC032, 0xC032, 0xC032}, {0xC033, 0xC033, 0xC033}, {0xC034, 0xC034, 0xC034}, {0xC035, 0xC035, 0xC035}, {0xC036, 0xC036, 0xC036}, {0xC037, 0xC037, 0xC037}, {0xC038, 0xC038, 0xC038}, {0xC039, 0xC039, 0xC039}, {0xC03A, 0xC03A, 0xC03A}, {0xC03B, 0xC03B, 0xC03B}, {0xC03C, 0xC03C, 0xC03C}, {0xC03D, 0xC03D, 0xC03D}, {0xC03E, 0xC03E, 0xC03E}, {0xC03F, 0xC03F, 0xC03F}, {0xC040, 0xC040, 0xC040}, {0xC041, 0xC041, 0xC041}, {0xC042, 0xC042, 0xC042}, {0xC043, 0xC043, 0xC043}, {0xC044, 0xC044, 0xC044}, {0xC045, 0xC045, 0xC045}, {0xC046, 0xC046, 0xC046}, {0xC047, 0xC047, 0xC047}, {0xC048, 0xC048, 0xC048}, {0xC049, 0xC049, 0xC049}, {0xC04A, 0xC04A, 0xC04A}, {0xC04B, 0xC04B, 0xC04B}, {0xC04C, 0xC04C, 0xC04C}, {0xC04D, 0xC04D, 0xC04D}, {0xC04E, 0xC04E, 0xC04E}, {0xC04F, 0xC04F, 0xC04F}, {0xC050, 0xC050, 0xC050}, {0xC051, 0xC051, 0xC051}, {0xC052, 0xC052, 0xC052}, {0xC053, 0xC053, 0xC053}, {0xC054, 0xC054, 0xC054}, {0xC055, 0xC055, 0xC055}, {0xC056, 0xC056, 0xC056}, {0xC057, 0xC057, 0xC057}, {0xC058, 0xC058, 0xC058}, {0xC059, 0xC059, 0xC059}, {0xC05A, 0xC05A, 0xC05A}, {0xC05B, 0xC05B, 0xC05B}, {0xC05C, 0xC05C, 0xC05C}, {0xC05D, 0xC05D, 0xC05D}, {0xC05E, 0xC05E, 0xC05E}, {0xC05F, 0xC05F, 0xC05F}, {0xC060, 0xC060, 0xC060}, {0xC061, 0xC061, 0xC061}, {0xC062, 0xC062, 0xC062}, {0xC063, 0xC063, 0xC063}, {0xC064, 0xC064, 0xC064}, {0xC065, 0xC065, 0xC065}, {0xC066, 0xC066, 0xC066}, {0xC067, 0xC067, 0xC067}, {0xC068, 0xC068, 0xC068}, {0xC069, 0xC069, 0xC069}, {0xC06A, 0xC06A, 0xC06A}, {0xC06B, 0xC06B, 0xC06B}, {0xC06C, 0xC06C, 0xC06C}, {0xC06D, 0xC06D, 0xC06D}, {0xC06E, 0xC06E, 0xC06E}, {0xC06F, 0xC06F, 0xC06F}, {0xC070, 0xC070, 0xC070}, {0xC071, 0xC071, 0xC071}, {0xC072, 0xC072, 0xC072}, {0xC073, 0xC073, 0xC073}, {0xC074, 0xC074, 0xC074}, {0xC075, 0xC075, 0xC075}, {0xC076, 0xC076, 0xC076}, {0xC077, 0xC077, 0xC077}, {0xC078, 0xC078, 0xC078}, {0xC079, 0xC079, 0xC079}, {0xC07A, 0xC07A, 0xC07A}, {0xC07B, 0xC07B, 0xC07B}, {0xC07C, 0xC07C, 0xC07C}, {0xC07D, 0xC07D, 0xC07D}, {0xC07E, 0xC07E, 0xC07E}, {0xC07F, 0xC07F, 0xC07F}, {0xC080, 0xC080, 0xC080}, {0xC081, 0xC081, 0xC081}, {0xC082, 0xC082, 0xC082}, {0xC083, 0xC083, 0xC083}, {0xC084, 0xC084, 0xC084}, {0xC085, 0xC085, 0xC085}, {0xC086, 0xC086, 0xC086}, {0xC087, 0xC087, 0xC087}, {0xC088, 0xC088, 0xC088}, {0xC089, 0xC089, 0xC089}, {0xC08A, 0xC08A, 0xC08A}, {0xC08B, 0xC08B, 0xC08B}, {0xC08C, 0xC08C, 0xC08C}, {0xC08D, 0xC08D, 0xC08D}, {0xC08E, 0xC08E, 0xC08E}, {0xC08F, 0xC08F, 0xC08F}, {0xC090, 0xC090, 0xC090}, {0xC091, 0xC091, 0xC091}, {0xC092, 0xC092, 0xC092}, {0xC093, 0xC093, 0xC093}, {0xC094, 0xC094, 0xC094}, {0xC095, 0xC095, 0xC095}, {0xC096, 0xC096, 0xC096}, {0xC097, 0xC097, 0xC097}, {0xC098, 0xC098, 0xC098}, {0xC099, 0xC099, 0xC099}, {0xC09A, 0xC09A, 0xC09A}, {0xC09B, 0xC09B, 0xC09B}, {0xC09C, 0xC09C, 0xC09C}, {0xC09D, 0xC09D, 0xC09D}, {0xC09E, 0xC09E, 0xC09E}, {0xC09F, 0xC09F, 0xC09F}, {0xC0A0, 0xC0A0, 0xC0A0}, {0xC0A1, 0xC0A1, 0xC0A1}, {0xC0A2, 0xC0A2, 0xC0A2}, {0xC0A3, 0xC0A3, 0xC0A3}, {0xC0A4, 0xC0A4, 0xC0A4}, {0xC0A5, 0xC0A5, 0xC0A5}, {0xC0A6, 0xC0A6, 0xC0A6}, {0xC0A7, 0xC0A7, 0xC0A7}, {0xC0A8, 0xC0A8, 0xC0A8}, {0xC0A9, 0xC0A9, 0xC0A9}, {0xC0AA, 0xC0AA, 0xC0AA}, {0xC0AB, 0xC0AB, 0xC0AB}, {0xC0AC, 0xC0AC, 0xC0AC}, {0xC0AD, 0xC0AD, 0xC0AD}, {0xC0AE, 0xC0AE, 0xC0AE}, {0xC0AF, 0xC0AF, 0xC0AF}, {0xC0B0, 0xC0B0, 0xC0B0}, {0xC0B1, 0xC0B1, 0xC0B1}, {0xC0B2, 0xC0B2, 0xC0B2}, {0xC0B3, 0xC0B3, 0xC0B3}, {0xC0B4, 0xC0B4, 0xC0B4}, {0xC0B5, 0xC0B5, 0xC0B5}, {0xC0B6, 0xC0B6, 0xC0B6}, {0xC0B7, 0xC0B7, 0xC0B7}, {0xC0B8, 0xC0B8, 0xC0B8}, {0xC0B9, 0xC0B9, 0xC0B9}, {0xC0BA, 0xC0BA, 0xC0BA}, {0xC0BB, 0xC0BB, 0xC0BB}, {0xC0BC, 0xC0BC, 0xC0BC}, {0xC0BD, 0xC0BD, 0xC0BD}, {0xC0BE, 0xC0BE, 0xC0BE}, {0xC0BF, 0xC0BF, 0xC0BF}, {0xC0C0, 0xC0C0, 0xC0C0}, {0xC0C1, 0xC0C1, 0xC0C1}, {0xC0C2, 0xC0C2, 0xC0C2}, {0xC0C3, 0xC0C3, 0xC0C3}, {0xC0C4, 0xC0C4, 0xC0C4}, {0xC0C5, 0xC0C5, 0xC0C5}, {0xC0C6, 0xC0C6, 0xC0C6}, {0xC0C7, 0xC0C7, 0xC0C7}, {0xC0C8, 0xC0C8, 0xC0C8}, {0xC0C9, 0xC0C9, 0xC0C9}, {0xC0CA, 0xC0CA, 0xC0CA}, {0xC0CB, 0xC0CB, 0xC0CB}, {0xC0CC, 0xC0CC, 0xC0CC}, {0xC0CD, 0xC0CD, 0xC0CD}, {0xC0CE, 0xC0CE, 0xC0CE}, {0xC0CF, 0xC0CF, 0xC0CF}, {0xC0D0, 0xC0D0, 0xC0D0}, {0xC0D1, 0xC0D1, 0xC0D1}, {0xC0D2, 0xC0D2, 0xC0D2}, {0xC0D3, 0xC0D3, 0xC0D3}, {0xC0D4, 0xC0D4, 0xC0D4}, {0xC0D5, 0xC0D5, 0xC0D5}, {0xC0D6, 0xC0D6, 0xC0D6}, {0xC0D7, 0xC0D7, 0xC0D7}, {0xC0D8, 0xC0D8, 0xC0D8}, {0xC0D9, 0xC0D9, 0xC0D9}, {0xC0DA, 0xC0DA, 0xC0DA}, {0xC0DB, 0xC0DB, 0xC0DB}, {0xC0DC, 0xC0DC, 0xC0DC}, {0xC0DD, 0xC0DD, 0xC0DD}, {0xC0DE, 0xC0DE, 0xC0DE}, {0xC0DF, 0xC0DF, 0xC0DF}, {0xC0E0, 0xC0E0, 0xC0E0}, {0xC0E1, 0xC0E1, 0xC0E1}, {0xC0E2, 0xC0E2, 0xC0E2}, {0xC0E3, 0xC0E3, 0xC0E3}, {0xC0E4, 0xC0E4, 0xC0E4}, {0xC0E5, 0xC0E5, 0xC0E5}, {0xC0E6, 0xC0E6, 0xC0E6}, {0xC0E7, 0xC0E7, 0xC0E7}, {0xC0E8, 0xC0E8, 0xC0E8}, {0xC0E9, 0xC0E9, 0xC0E9}, {0xC0EA, 0xC0EA, 0xC0EA}, {0xC0EB, 0xC0EB, 0xC0EB}, {0xC0EC, 0xC0EC, 0xC0EC}, {0xC0ED, 0xC0ED, 0xC0ED}, {0xC0EE, 0xC0EE, 0xC0EE}, {0xC0EF, 0xC0EF, 0xC0EF}, {0xC0F0, 0xC0F0, 0xC0F0}, {0xC0F1, 0xC0F1, 0xC0F1}, {0xC0F2, 0xC0F2, 0xC0F2}, {0xC0F3, 0xC0F3, 0xC0F3}, {0xC0F4, 0xC0F4, 0xC0F4}, {0xC0F5, 0xC0F5, 0xC0F5}, {0xC0F6, 0xC0F6, 0xC0F6}, {0xC0F7, 0xC0F7, 0xC0F7}, {0xC0F8, 0xC0F8, 0xC0F8}, {0xC0F9, 0xC0F9, 0xC0F9}, {0xC0FA, 0xC0FA, 0xC0FA}, {0xC0FB, 0xC0FB, 0xC0FB}, {0xC0FC, 0xC0FC, 0xC0FC}, {0xC0FD, 0xC0FD, 0xC0FD}, {0xC0FE, 0xC0FE, 0xC0FE}, {0xC0FF, 0xC0FF, 0xC0FF}, {0xC100, 0xC100, 0xC100}, {0xC101, 0xC101, 0xC101}, {0xC102, 0xC102, 0xC102}, {0xC103, 0xC103, 0xC103}, {0xC104, 0xC104, 0xC104}, {0xC105, 0xC105, 0xC105}, {0xC106, 0xC106, 0xC106}, {0xC107, 0xC107, 0xC107}, {0xC108, 0xC108, 0xC108}, {0xC109, 0xC109, 0xC109}, {0xC10A, 0xC10A, 0xC10A}, {0xC10B, 0xC10B, 0xC10B}, {0xC10C, 0xC10C, 0xC10C}, {0xC10D, 0xC10D, 0xC10D}, {0xC10E, 0xC10E, 0xC10E}, {0xC10F, 0xC10F, 0xC10F}, {0xC110, 0xC110, 0xC110}, {0xC111, 0xC111, 0xC111}, {0xC112, 0xC112, 0xC112}, {0xC113, 0xC113, 0xC113}, {0xC114, 0xC114, 0xC114}, {0xC115, 0xC115, 0xC115}, {0xC116, 0xC116, 0xC116}, {0xC117, 0xC117, 0xC117}, {0xC118, 0xC118, 0xC118}, {0xC119, 0xC119, 0xC119}, {0xC11A, 0xC11A, 0xC11A}, {0xC11B, 0xC11B, 0xC11B}, {0xC11C, 0xC11C, 0xC11C}, {0xC11D, 0xC11D, 0xC11D}, {0xC11E, 0xC11E, 0xC11E}, {0xC11F, 0xC11F, 0xC11F}, {0xC120, 0xC120, 0xC120}, {0xC121, 0xC121, 0xC121}, {0xC122, 0xC122, 0xC122}, {0xC123, 0xC123, 0xC123}, {0xC124, 0xC124, 0xC124}, {0xC125, 0xC125, 0xC125}, {0xC126, 0xC126, 0xC126}, {0xC127, 0xC127, 0xC127}, {0xC128, 0xC128, 0xC128}, {0xC129, 0xC129, 0xC129}, {0xC12A, 0xC12A, 0xC12A}, {0xC12B, 0xC12B, 0xC12B}, {0xC12C, 0xC12C, 0xC12C}, {0xC12D, 0xC12D, 0xC12D}, {0xC12E, 0xC12E, 0xC12E}, {0xC12F, 0xC12F, 0xC12F}, {0xC130, 0xC130, 0xC130}, {0xC131, 0xC131, 0xC131}, {0xC132, 0xC132, 0xC132}, {0xC133, 0xC133, 0xC133}, {0xC134, 0xC134, 0xC134}, {0xC135, 0xC135, 0xC135}, {0xC136, 0xC136, 0xC136}, {0xC137, 0xC137, 0xC137}, {0xC138, 0xC138, 0xC138}, {0xC139, 0xC139, 0xC139}, {0xC13A, 0xC13A, 0xC13A}, {0xC13B, 0xC13B, 0xC13B}, {0xC13C, 0xC13C, 0xC13C}, {0xC13D, 0xC13D, 0xC13D}, {0xC13E, 0xC13E, 0xC13E}, {0xC13F, 0xC13F, 0xC13F}, {0xC140, 0xC140, 0xC140}, {0xC141, 0xC141, 0xC141}, {0xC142, 0xC142, 0xC142}, {0xC143, 0xC143, 0xC143}, {0xC144, 0xC144, 0xC144}, {0xC145, 0xC145, 0xC145}, {0xC146, 0xC146, 0xC146}, {0xC147, 0xC147, 0xC147}, {0xC148, 0xC148, 0xC148}, {0xC149, 0xC149, 0xC149}, {0xC14A, 0xC14A, 0xC14A}, {0xC14B, 0xC14B, 0xC14B}, {0xC14C, 0xC14C, 0xC14C}, {0xC14D, 0xC14D, 0xC14D}, {0xC14E, 0xC14E, 0xC14E}, {0xC14F, 0xC14F, 0xC14F}, {0xC150, 0xC150, 0xC150}, {0xC151, 0xC151, 0xC151}, {0xC152, 0xC152, 0xC152}, {0xC153, 0xC153, 0xC153}, {0xC154, 0xC154, 0xC154}, {0xC155, 0xC155, 0xC155}, {0xC156, 0xC156, 0xC156}, {0xC157, 0xC157, 0xC157}, {0xC158, 0xC158, 0xC158}, {0xC159, 0xC159, 0xC159}, {0xC15A, 0xC15A, 0xC15A}, {0xC15B, 0xC15B, 0xC15B}, {0xC15C, 0xC15C, 0xC15C}, {0xC15D, 0xC15D, 0xC15D}, {0xC15E, 0xC15E, 0xC15E}, {0xC15F, 0xC15F, 0xC15F}, {0xC160, 0xC160, 0xC160}, {0xC161, 0xC161, 0xC161}, {0xC162, 0xC162, 0xC162}, {0xC163, 0xC163, 0xC163}, {0xC164, 0xC164, 0xC164}, {0xC165, 0xC165, 0xC165}, {0xC166, 0xC166, 0xC166}, {0xC167, 0xC167, 0xC167}, {0xC168, 0xC168, 0xC168}, {0xC169, 0xC169, 0xC169}, {0xC16A, 0xC16A, 0xC16A}, {0xC16B, 0xC16B, 0xC16B}, {0xC16C, 0xC16C, 0xC16C}, {0xC16D, 0xC16D, 0xC16D}, {0xC16E, 0xC16E, 0xC16E}, {0xC16F, 0xC16F, 0xC16F}, {0xC170, 0xC170, 0xC170}, {0xC171, 0xC171, 0xC171}, {0xC172, 0xC172, 0xC172}, {0xC173, 0xC173, 0xC173}, {0xC174, 0xC174, 0xC174}, {0xC175, 0xC175, 0xC175}, {0xC176, 0xC176, 0xC176}, {0xC177, 0xC177, 0xC177}, {0xC178, 0xC178, 0xC178}, {0xC179, 0xC179, 0xC179}, {0xC17A, 0xC17A, 0xC17A}, {0xC17B, 0xC17B, 0xC17B}, {0xC17C, 0xC17C, 0xC17C}, {0xC17D, 0xC17D, 0xC17D}, {0xC17E, 0xC17E, 0xC17E}, {0xC17F, 0xC17F, 0xC17F}, {0xC180, 0xC180, 0xC180}, {0xC181, 0xC181, 0xC181}, {0xC182, 0xC182, 0xC182}, {0xC183, 0xC183, 0xC183}, {0xC184, 0xC184, 0xC184}, {0xC185, 0xC185, 0xC185}, {0xC186, 0xC186, 0xC186}, {0xC187, 0xC187, 0xC187}, {0xC188, 0xC188, 0xC188}, {0xC189, 0xC189, 0xC189}, {0xC18A, 0xC18A, 0xC18A}, {0xC18B, 0xC18B, 0xC18B}, {0xC18C, 0xC18C, 0xC18C}, {0xC18D, 0xC18D, 0xC18D}, {0xC18E, 0xC18E, 0xC18E}, {0xC18F, 0xC18F, 0xC18F}, {0xC190, 0xC190, 0xC190}, {0xC191, 0xC191, 0xC191}, {0xC192, 0xC192, 0xC192}, {0xC193, 0xC193, 0xC193}, {0xC194, 0xC194, 0xC194}, {0xC195, 0xC195, 0xC195}, {0xC196, 0xC196, 0xC196}, {0xC197, 0xC197, 0xC197}, {0xC198, 0xC198, 0xC198}, {0xC199, 0xC199, 0xC199}, {0xC19A, 0xC19A, 0xC19A}, {0xC19B, 0xC19B, 0xC19B}, {0xC19C, 0xC19C, 0xC19C}, {0xC19D, 0xC19D, 0xC19D}, {0xC19E, 0xC19E, 0xC19E}, {0xC19F, 0xC19F, 0xC19F}, {0xC1A0, 0xC1A0, 0xC1A0}, {0xC1A1, 0xC1A1, 0xC1A1}, {0xC1A2, 0xC1A2, 0xC1A2}, {0xC1A3, 0xC1A3, 0xC1A3}, {0xC1A4, 0xC1A4, 0xC1A4}, {0xC1A5, 0xC1A5, 0xC1A5}, {0xC1A6, 0xC1A6, 0xC1A6}, {0xC1A7, 0xC1A7, 0xC1A7}, {0xC1A8, 0xC1A8, 0xC1A8}, {0xC1A9, 0xC1A9, 0xC1A9}, {0xC1AA, 0xC1AA, 0xC1AA}, {0xC1AB, 0xC1AB, 0xC1AB}, {0xC1AC, 0xC1AC, 0xC1AC}, {0xC1AD, 0xC1AD, 0xC1AD}, {0xC1AE, 0xC1AE, 0xC1AE}, {0xC1AF, 0xC1AF, 0xC1AF}, {0xC1B0, 0xC1B0, 0xC1B0}, {0xC1B1, 0xC1B1, 0xC1B1}, {0xC1B2, 0xC1B2, 0xC1B2}, {0xC1B3, 0xC1B3, 0xC1B3}, {0xC1B4, 0xC1B4, 0xC1B4}, {0xC1B5, 0xC1B5, 0xC1B5}, {0xC1B6, 0xC1B6, 0xC1B6}, {0xC1B7, 0xC1B7, 0xC1B7}, {0xC1B8, 0xC1B8, 0xC1B8}, {0xC1B9, 0xC1B9, 0xC1B9}, {0xC1BA, 0xC1BA, 0xC1BA}, {0xC1BB, 0xC1BB, 0xC1BB}, {0xC1BC, 0xC1BC, 0xC1BC}, {0xC1BD, 0xC1BD, 0xC1BD}, {0xC1BE, 0xC1BE, 0xC1BE}, {0xC1BF, 0xC1BF, 0xC1BF}, {0xC1C0, 0xC1C0, 0xC1C0}, {0xC1C1, 0xC1C1, 0xC1C1}, {0xC1C2, 0xC1C2, 0xC1C2}, {0xC1C3, 0xC1C3, 0xC1C3}, {0xC1C4, 0xC1C4, 0xC1C4}, {0xC1C5, 0xC1C5, 0xC1C5}, {0xC1C6, 0xC1C6, 0xC1C6}, {0xC1C7, 0xC1C7, 0xC1C7}, {0xC1C8, 0xC1C8, 0xC1C8}, {0xC1C9, 0xC1C9, 0xC1C9}, {0xC1CA, 0xC1CA, 0xC1CA}, {0xC1CB, 0xC1CB, 0xC1CB}, {0xC1CC, 0xC1CC, 0xC1CC}, {0xC1CD, 0xC1CD, 0xC1CD}, {0xC1CE, 0xC1CE, 0xC1CE}, {0xC1CF, 0xC1CF, 0xC1CF}, {0xC1D0, 0xC1D0, 0xC1D0}, {0xC1D1, 0xC1D1, 0xC1D1}, {0xC1D2, 0xC1D2, 0xC1D2}, {0xC1D3, 0xC1D3, 0xC1D3}, {0xC1D4, 0xC1D4, 0xC1D4}, {0xC1D5, 0xC1D5, 0xC1D5}, {0xC1D6, 0xC1D6, 0xC1D6}, {0xC1D7, 0xC1D7, 0xC1D7}, {0xC1D8, 0xC1D8, 0xC1D8}, {0xC1D9, 0xC1D9, 0xC1D9}, {0xC1DA, 0xC1DA, 0xC1DA}, {0xC1DB, 0xC1DB, 0xC1DB}, {0xC1DC, 0xC1DC, 0xC1DC}, {0xC1DD, 0xC1DD, 0xC1DD}, {0xC1DE, 0xC1DE, 0xC1DE}, {0xC1DF, 0xC1DF, 0xC1DF}, {0xC1E0, 0xC1E0, 0xC1E0}, {0xC1E1, 0xC1E1, 0xC1E1}, {0xC1E2, 0xC1E2, 0xC1E2}, {0xC1E3, 0xC1E3, 0xC1E3}, {0xC1E4, 0xC1E4, 0xC1E4}, {0xC1E5, 0xC1E5, 0xC1E5}, {0xC1E6, 0xC1E6, 0xC1E6}, {0xC1E7, 0xC1E7, 0xC1E7}, {0xC1E8, 0xC1E8, 0xC1E8}, {0xC1E9, 0xC1E9, 0xC1E9}, {0xC1EA, 0xC1EA, 0xC1EA}, {0xC1EB, 0xC1EB, 0xC1EB}, {0xC1EC, 0xC1EC, 0xC1EC}, {0xC1ED, 0xC1ED, 0xC1ED}, {0xC1EE, 0xC1EE, 0xC1EE}, {0xC1EF, 0xC1EF, 0xC1EF}, {0xC1F0, 0xC1F0, 0xC1F0}, {0xC1F1, 0xC1F1, 0xC1F1}, {0xC1F2, 0xC1F2, 0xC1F2}, {0xC1F3, 0xC1F3, 0xC1F3}, {0xC1F4, 0xC1F4, 0xC1F4}, {0xC1F5, 0xC1F5, 0xC1F5}, {0xC1F6, 0xC1F6, 0xC1F6}, {0xC1F7, 0xC1F7, 0xC1F7}, {0xC1F8, 0xC1F8, 0xC1F8}, {0xC1F9, 0xC1F9, 0xC1F9}, {0xC1FA, 0xC1FA, 0xC1FA}, {0xC1FB, 0xC1FB, 0xC1FB}, {0xC1FC, 0xC1FC, 0xC1FC}, {0xC1FD, 0xC1FD, 0xC1FD}, {0xC1FE, 0xC1FE, 0xC1FE}, {0xC1FF, 0xC1FF, 0xC1FF}, {0xC200, 0xC200, 0xC200}, {0xC201, 0xC201, 0xC201}, {0xC202, 0xC202, 0xC202}, {0xC203, 0xC203, 0xC203}, {0xC204, 0xC204, 0xC204}, {0xC205, 0xC205, 0xC205}, {0xC206, 0xC206, 0xC206}, {0xC207, 0xC207, 0xC207}, {0xC208, 0xC208, 0xC208}, {0xC209, 0xC209, 0xC209}, {0xC20A, 0xC20A, 0xC20A}, {0xC20B, 0xC20B, 0xC20B}, {0xC20C, 0xC20C, 0xC20C}, {0xC20D, 0xC20D, 0xC20D}, {0xC20E, 0xC20E, 0xC20E}, {0xC20F, 0xC20F, 0xC20F}, {0xC210, 0xC210, 0xC210}, {0xC211, 0xC211, 0xC211}, {0xC212, 0xC212, 0xC212}, {0xC213, 0xC213, 0xC213}, {0xC214, 0xC214, 0xC214}, {0xC215, 0xC215, 0xC215}, {0xC216, 0xC216, 0xC216}, {0xC217, 0xC217, 0xC217}, {0xC218, 0xC218, 0xC218}, {0xC219, 0xC219, 0xC219}, {0xC21A, 0xC21A, 0xC21A}, {0xC21B, 0xC21B, 0xC21B}, {0xC21C, 0xC21C, 0xC21C}, {0xC21D, 0xC21D, 0xC21D}, {0xC21E, 0xC21E, 0xC21E}, {0xC21F, 0xC21F, 0xC21F}, {0xC220, 0xC220, 0xC220}, {0xC221, 0xC221, 0xC221}, {0xC222, 0xC222, 0xC222}, {0xC223, 0xC223, 0xC223}, {0xC224, 0xC224, 0xC224}, {0xC225, 0xC225, 0xC225}, {0xC226, 0xC226, 0xC226}, {0xC227, 0xC227, 0xC227}, {0xC228, 0xC228, 0xC228}, {0xC229, 0xC229, 0xC229}, {0xC22A, 0xC22A, 0xC22A}, {0xC22B, 0xC22B, 0xC22B}, {0xC22C, 0xC22C, 0xC22C}, {0xC22D, 0xC22D, 0xC22D}, {0xC22E, 0xC22E, 0xC22E}, {0xC22F, 0xC22F, 0xC22F}, {0xC230, 0xC230, 0xC230}, {0xC231, 0xC231, 0xC231}, {0xC232, 0xC232, 0xC232}, {0xC233, 0xC233, 0xC233}, {0xC234, 0xC234, 0xC234}, {0xC235, 0xC235, 0xC235}, {0xC236, 0xC236, 0xC236}, {0xC237, 0xC237, 0xC237}, {0xC238, 0xC238, 0xC238}, {0xC239, 0xC239, 0xC239}, {0xC23A, 0xC23A, 0xC23A}, {0xC23B, 0xC23B, 0xC23B}, {0xC23C, 0xC23C, 0xC23C}, {0xC23D, 0xC23D, 0xC23D}, {0xC23E, 0xC23E, 0xC23E}, {0xC23F, 0xC23F, 0xC23F}, {0xC240, 0xC240, 0xC240}, {0xC241, 0xC241, 0xC241}, {0xC242, 0xC242, 0xC242}, {0xC243, 0xC243, 0xC243}, {0xC244, 0xC244, 0xC244}, {0xC245, 0xC245, 0xC245}, {0xC246, 0xC246, 0xC246}, {0xC247, 0xC247, 0xC247}, {0xC248, 0xC248, 0xC248}, {0xC249, 0xC249, 0xC249}, {0xC24A, 0xC24A, 0xC24A}, {0xC24B, 0xC24B, 0xC24B}, {0xC24C, 0xC24C, 0xC24C}, {0xC24D, 0xC24D, 0xC24D}, {0xC24E, 0xC24E, 0xC24E}, {0xC24F, 0xC24F, 0xC24F}, {0xC250, 0xC250, 0xC250}, {0xC251, 0xC251, 0xC251}, {0xC252, 0xC252, 0xC252}, {0xC253, 0xC253, 0xC253}, {0xC254, 0xC254, 0xC254}, {0xC255, 0xC255, 0xC255}, {0xC256, 0xC256, 0xC256}, {0xC257, 0xC257, 0xC257}, {0xC258, 0xC258, 0xC258}, {0xC259, 0xC259, 0xC259}, {0xC25A, 0xC25A, 0xC25A}, {0xC25B, 0xC25B, 0xC25B}, {0xC25C, 0xC25C, 0xC25C}, {0xC25D, 0xC25D, 0xC25D}, {0xC25E, 0xC25E, 0xC25E}, {0xC25F, 0xC25F, 0xC25F}, {0xC260, 0xC260, 0xC260}, {0xC261, 0xC261, 0xC261}, {0xC262, 0xC262, 0xC262}, {0xC263, 0xC263, 0xC263}, {0xC264, 0xC264, 0xC264}, {0xC265, 0xC265, 0xC265}, {0xC266, 0xC266, 0xC266}, {0xC267, 0xC267, 0xC267}, {0xC268, 0xC268, 0xC268}, {0xC269, 0xC269, 0xC269}, {0xC26A, 0xC26A, 0xC26A}, {0xC26B, 0xC26B, 0xC26B}, {0xC26C, 0xC26C, 0xC26C}, {0xC26D, 0xC26D, 0xC26D}, {0xC26E, 0xC26E, 0xC26E}, {0xC26F, 0xC26F, 0xC26F}, {0xC270, 0xC270, 0xC270}, {0xC271, 0xC271, 0xC271}, {0xC272, 0xC272, 0xC272}, {0xC273, 0xC273, 0xC273}, {0xC274, 0xC274, 0xC274}, {0xC275, 0xC275, 0xC275}, {0xC276, 0xC276, 0xC276}, {0xC277, 0xC277, 0xC277}, {0xC278, 0xC278, 0xC278}, {0xC279, 0xC279, 0xC279}, {0xC27A, 0xC27A, 0xC27A}, {0xC27B, 0xC27B, 0xC27B}, {0xC27C, 0xC27C, 0xC27C}, {0xC27D, 0xC27D, 0xC27D}, {0xC27E, 0xC27E, 0xC27E}, {0xC27F, 0xC27F, 0xC27F}, {0xC280, 0xC280, 0xC280}, {0xC281, 0xC281, 0xC281}, {0xC282, 0xC282, 0xC282}, {0xC283, 0xC283, 0xC283}, {0xC284, 0xC284, 0xC284}, {0xC285, 0xC285, 0xC285}, {0xC286, 0xC286, 0xC286}, {0xC287, 0xC287, 0xC287}, {0xC288, 0xC288, 0xC288}, {0xC289, 0xC289, 0xC289}, {0xC28A, 0xC28A, 0xC28A}, {0xC28B, 0xC28B, 0xC28B}, {0xC28C, 0xC28C, 0xC28C}, {0xC28D, 0xC28D, 0xC28D}, {0xC28E, 0xC28E, 0xC28E}, {0xC28F, 0xC28F, 0xC28F}, {0xC290, 0xC290, 0xC290}, {0xC291, 0xC291, 0xC291}, {0xC292, 0xC292, 0xC292}, {0xC293, 0xC293, 0xC293}, {0xC294, 0xC294, 0xC294}, {0xC295, 0xC295, 0xC295}, {0xC296, 0xC296, 0xC296}, {0xC297, 0xC297, 0xC297}, {0xC298, 0xC298, 0xC298}, {0xC299, 0xC299, 0xC299}, {0xC29A, 0xC29A, 0xC29A}, {0xC29B, 0xC29B, 0xC29B}, {0xC29C, 0xC29C, 0xC29C}, {0xC29D, 0xC29D, 0xC29D}, {0xC29E, 0xC29E, 0xC29E}, {0xC29F, 0xC29F, 0xC29F}, {0xC2A0, 0xC2A0, 0xC2A0}, {0xC2A1, 0xC2A1, 0xC2A1}, {0xC2A2, 0xC2A2, 0xC2A2}, {0xC2A3, 0xC2A3, 0xC2A3}, {0xC2A4, 0xC2A4, 0xC2A4}, {0xC2A5, 0xC2A5, 0xC2A5}, {0xC2A6, 0xC2A6, 0xC2A6}, {0xC2A7, 0xC2A7, 0xC2A7}, {0xC2A8, 0xC2A8, 0xC2A8}, {0xC2A9, 0xC2A9, 0xC2A9}, {0xC2AA, 0xC2AA, 0xC2AA}, {0xC2AB, 0xC2AB, 0xC2AB}, {0xC2AC, 0xC2AC, 0xC2AC}, {0xC2AD, 0xC2AD, 0xC2AD}, {0xC2AE, 0xC2AE, 0xC2AE}, {0xC2AF, 0xC2AF, 0xC2AF}, {0xC2B0, 0xC2B0, 0xC2B0}, {0xC2B1, 0xC2B1, 0xC2B1}, {0xC2B2, 0xC2B2, 0xC2B2}, {0xC2B3, 0xC2B3, 0xC2B3}, {0xC2B4, 0xC2B4, 0xC2B4}, {0xC2B5, 0xC2B5, 0xC2B5}, {0xC2B6, 0xC2B6, 0xC2B6}, {0xC2B7, 0xC2B7, 0xC2B7}, {0xC2B8, 0xC2B8, 0xC2B8}, {0xC2B9, 0xC2B9, 0xC2B9}, {0xC2BA, 0xC2BA, 0xC2BA}, {0xC2BB, 0xC2BB, 0xC2BB}, {0xC2BC, 0xC2BC, 0xC2BC}, {0xC2BD, 0xC2BD, 0xC2BD}, {0xC2BE, 0xC2BE, 0xC2BE}, {0xC2BF, 0xC2BF, 0xC2BF}, {0xC2C0, 0xC2C0, 0xC2C0}, {0xC2C1, 0xC2C1, 0xC2C1}, {0xC2C2, 0xC2C2, 0xC2C2}, {0xC2C3, 0xC2C3, 0xC2C3}, {0xC2C4, 0xC2C4, 0xC2C4}, {0xC2C5, 0xC2C5, 0xC2C5}, {0xC2C6, 0xC2C6, 0xC2C6}, {0xC2C7, 0xC2C7, 0xC2C7}, {0xC2C8, 0xC2C8, 0xC2C8}, {0xC2C9, 0xC2C9, 0xC2C9}, {0xC2CA, 0xC2CA, 0xC2CA}, {0xC2CB, 0xC2CB, 0xC2CB}, {0xC2CC, 0xC2CC, 0xC2CC}, {0xC2CD, 0xC2CD, 0xC2CD}, {0xC2CE, 0xC2CE, 0xC2CE}, {0xC2CF, 0xC2CF, 0xC2CF}, {0xC2D0, 0xC2D0, 0xC2D0}, {0xC2D1, 0xC2D1, 0xC2D1}, {0xC2D2, 0xC2D2, 0xC2D2}, {0xC2D3, 0xC2D3, 0xC2D3}, {0xC2D4, 0xC2D4, 0xC2D4}, {0xC2D5, 0xC2D5, 0xC2D5}, {0xC2D6, 0xC2D6, 0xC2D6}, {0xC2D7, 0xC2D7, 0xC2D7}, {0xC2D8, 0xC2D8, 0xC2D8}, {0xC2D9, 0xC2D9, 0xC2D9}, {0xC2DA, 0xC2DA, 0xC2DA}, {0xC2DB, 0xC2DB, 0xC2DB}, {0xC2DC, 0xC2DC, 0xC2DC}, {0xC2DD, 0xC2DD, 0xC2DD}, {0xC2DE, 0xC2DE, 0xC2DE}, {0xC2DF, 0xC2DF, 0xC2DF}, {0xC2E0, 0xC2E0, 0xC2E0}, {0xC2E1, 0xC2E1, 0xC2E1}, {0xC2E2, 0xC2E2, 0xC2E2}, {0xC2E3, 0xC2E3, 0xC2E3}, {0xC2E4, 0xC2E4, 0xC2E4}, {0xC2E5, 0xC2E5, 0xC2E5}, {0xC2E6, 0xC2E6, 0xC2E6}, {0xC2E7, 0xC2E7, 0xC2E7}, {0xC2E8, 0xC2E8, 0xC2E8}, {0xC2E9, 0xC2E9, 0xC2E9}, {0xC2EA, 0xC2EA, 0xC2EA}, {0xC2EB, 0xC2EB, 0xC2EB}, {0xC2EC, 0xC2EC, 0xC2EC}, {0xC2ED, 0xC2ED, 0xC2ED}, {0xC2EE, 0xC2EE, 0xC2EE}, {0xC2EF, 0xC2EF, 0xC2EF}, {0xC2F0, 0xC2F0, 0xC2F0}, {0xC2F1, 0xC2F1, 0xC2F1}, {0xC2F2, 0xC2F2, 0xC2F2}, {0xC2F3, 0xC2F3, 0xC2F3}, {0xC2F4, 0xC2F4, 0xC2F4}, {0xC2F5, 0xC2F5, 0xC2F5}, {0xC2F6, 0xC2F6, 0xC2F6}, {0xC2F7, 0xC2F7, 0xC2F7}, {0xC2F8, 0xC2F8, 0xC2F8}, {0xC2F9, 0xC2F9, 0xC2F9}, {0xC2FA, 0xC2FA, 0xC2FA}, {0xC2FB, 0xC2FB, 0xC2FB}, {0xC2FC, 0xC2FC, 0xC2FC}, {0xC2FD, 0xC2FD, 0xC2FD}, {0xC2FE, 0xC2FE, 0xC2FE}, {0xC2FF, 0xC2FF, 0xC2FF}, {0xC300, 0xC300, 0xC300}, {0xC301, 0xC301, 0xC301}, {0xC302, 0xC302, 0xC302}, {0xC303, 0xC303, 0xC303}, {0xC304, 0xC304, 0xC304}, {0xC305, 0xC305, 0xC305}, {0xC306, 0xC306, 0xC306}, {0xC307, 0xC307, 0xC307}, {0xC308, 0xC308, 0xC308}, {0xC309, 0xC309, 0xC309}, {0xC30A, 0xC30A, 0xC30A}, {0xC30B, 0xC30B, 0xC30B}, {0xC30C, 0xC30C, 0xC30C}, {0xC30D, 0xC30D, 0xC30D}, {0xC30E, 0xC30E, 0xC30E}, {0xC30F, 0xC30F, 0xC30F}, {0xC310, 0xC310, 0xC310}, {0xC311, 0xC311, 0xC311}, {0xC312, 0xC312, 0xC312}, {0xC313, 0xC313, 0xC313}, {0xC314, 0xC314, 0xC314}, {0xC315, 0xC315, 0xC315}, {0xC316, 0xC316, 0xC316}, {0xC317, 0xC317, 0xC317}, {0xC318, 0xC318, 0xC318}, {0xC319, 0xC319, 0xC319}, {0xC31A, 0xC31A, 0xC31A}, {0xC31B, 0xC31B, 0xC31B}, {0xC31C, 0xC31C, 0xC31C}, {0xC31D, 0xC31D, 0xC31D}, {0xC31E, 0xC31E, 0xC31E}, {0xC31F, 0xC31F, 0xC31F}, {0xC320, 0xC320, 0xC320}, {0xC321, 0xC321, 0xC321}, {0xC322, 0xC322, 0xC322}, {0xC323, 0xC323, 0xC323}, {0xC324, 0xC324, 0xC324}, {0xC325, 0xC325, 0xC325}, {0xC326, 0xC326, 0xC326}, {0xC327, 0xC327, 0xC327}, {0xC328, 0xC328, 0xC328}, {0xC329, 0xC329, 0xC329}, {0xC32A, 0xC32A, 0xC32A}, {0xC32B, 0xC32B, 0xC32B}, {0xC32C, 0xC32C, 0xC32C}, {0xC32D, 0xC32D, 0xC32D}, {0xC32E, 0xC32E, 0xC32E}, {0xC32F, 0xC32F, 0xC32F}, {0xC330, 0xC330, 0xC330}, {0xC331, 0xC331, 0xC331}, {0xC332, 0xC332, 0xC332}, {0xC333, 0xC333, 0xC333}, {0xC334, 0xC334, 0xC334}, {0xC335, 0xC335, 0xC335}, {0xC336, 0xC336, 0xC336}, {0xC337, 0xC337, 0xC337}, {0xC338, 0xC338, 0xC338}, {0xC339, 0xC339, 0xC339}, {0xC33A, 0xC33A, 0xC33A}, {0xC33B, 0xC33B, 0xC33B}, {0xC33C, 0xC33C, 0xC33C}, {0xC33D, 0xC33D, 0xC33D}, {0xC33E, 0xC33E, 0xC33E}, {0xC33F, 0xC33F, 0xC33F}, {0xC340, 0xC340, 0xC340}, {0xC341, 0xC341, 0xC341}, {0xC342, 0xC342, 0xC342}, {0xC343, 0xC343, 0xC343}, {0xC344, 0xC344, 0xC344}, {0xC345, 0xC345, 0xC345}, {0xC346, 0xC346, 0xC346}, {0xC347, 0xC347, 0xC347}, {0xC348, 0xC348, 0xC348}, {0xC349, 0xC349, 0xC349}, {0xC34A, 0xC34A, 0xC34A}, {0xC34B, 0xC34B, 0xC34B}, {0xC34C, 0xC34C, 0xC34C}, {0xC34D, 0xC34D, 0xC34D}, {0xC34E, 0xC34E, 0xC34E}, {0xC34F, 0xC34F, 0xC34F}, {0xC350, 0xC350, 0xC350}, {0xC351, 0xC351, 0xC351}, {0xC352, 0xC352, 0xC352}, {0xC353, 0xC353, 0xC353}, {0xC354, 0xC354, 0xC354}, {0xC355, 0xC355, 0xC355}, {0xC356, 0xC356, 0xC356}, {0xC357, 0xC357, 0xC357}, {0xC358, 0xC358, 0xC358}, {0xC359, 0xC359, 0xC359}, {0xC35A, 0xC35A, 0xC35A}, {0xC35B, 0xC35B, 0xC35B}, {0xC35C, 0xC35C, 0xC35C}, {0xC35D, 0xC35D, 0xC35D}, {0xC35E, 0xC35E, 0xC35E}, {0xC35F, 0xC35F, 0xC35F}, {0xC360, 0xC360, 0xC360}, {0xC361, 0xC361, 0xC361}, {0xC362, 0xC362, 0xC362}, {0xC363, 0xC363, 0xC363}, {0xC364, 0xC364, 0xC364}, {0xC365, 0xC365, 0xC365}, {0xC366, 0xC366, 0xC366}, {0xC367, 0xC367, 0xC367}, {0xC368, 0xC368, 0xC368}, {0xC369, 0xC369, 0xC369}, {0xC36A, 0xC36A, 0xC36A}, {0xC36B, 0xC36B, 0xC36B}, {0xC36C, 0xC36C, 0xC36C}, {0xC36D, 0xC36D, 0xC36D}, {0xC36E, 0xC36E, 0xC36E}, {0xC36F, 0xC36F, 0xC36F}, {0xC370, 0xC370, 0xC370}, {0xC371, 0xC371, 0xC371}, {0xC372, 0xC372, 0xC372}, {0xC373, 0xC373, 0xC373}, {0xC374, 0xC374, 0xC374}, {0xC375, 0xC375, 0xC375}, {0xC376, 0xC376, 0xC376}, {0xC377, 0xC377, 0xC377}, {0xC378, 0xC378, 0xC378}, {0xC379, 0xC379, 0xC379}, {0xC37A, 0xC37A, 0xC37A}, {0xC37B, 0xC37B, 0xC37B}, {0xC37C, 0xC37C, 0xC37C}, {0xC37D, 0xC37D, 0xC37D}, {0xC37E, 0xC37E, 0xC37E}, {0xC37F, 0xC37F, 0xC37F}, {0xC380, 0xC380, 0xC380}, {0xC381, 0xC381, 0xC381}, {0xC382, 0xC382, 0xC382}, {0xC383, 0xC383, 0xC383}, {0xC384, 0xC384, 0xC384}, {0xC385, 0xC385, 0xC385}, {0xC386, 0xC386, 0xC386}, {0xC387, 0xC387, 0xC387}, {0xC388, 0xC388, 0xC388}, {0xC389, 0xC389, 0xC389}, {0xC38A, 0xC38A, 0xC38A}, {0xC38B, 0xC38B, 0xC38B}, {0xC38C, 0xC38C, 0xC38C}, {0xC38D, 0xC38D, 0xC38D}, {0xC38E, 0xC38E, 0xC38E}, {0xC38F, 0xC38F, 0xC38F}, {0xC390, 0xC390, 0xC390}, {0xC391, 0xC391, 0xC391}, {0xC392, 0xC392, 0xC392}, {0xC393, 0xC393, 0xC393}, {0xC394, 0xC394, 0xC394}, {0xC395, 0xC395, 0xC395}, {0xC396, 0xC396, 0xC396}, {0xC397, 0xC397, 0xC397}, {0xC398, 0xC398, 0xC398}, {0xC399, 0xC399, 0xC399}, {0xC39A, 0xC39A, 0xC39A}, {0xC39B, 0xC39B, 0xC39B}, {0xC39C, 0xC39C, 0xC39C}, {0xC39D, 0xC39D, 0xC39D}, {0xC39E, 0xC39E, 0xC39E}, {0xC39F, 0xC39F, 0xC39F}, {0xC3A0, 0xC3A0, 0xC3A0}, {0xC3A1, 0xC3A1, 0xC3A1}, {0xC3A2, 0xC3A2, 0xC3A2}, {0xC3A3, 0xC3A3, 0xC3A3}, {0xC3A4, 0xC3A4, 0xC3A4}, {0xC3A5, 0xC3A5, 0xC3A5}, {0xC3A6, 0xC3A6, 0xC3A6}, {0xC3A7, 0xC3A7, 0xC3A7}, {0xC3A8, 0xC3A8, 0xC3A8}, {0xC3A9, 0xC3A9, 0xC3A9}, {0xC3AA, 0xC3AA, 0xC3AA}, {0xC3AB, 0xC3AB, 0xC3AB}, {0xC3AC, 0xC3AC, 0xC3AC}, {0xC3AD, 0xC3AD, 0xC3AD}, {0xC3AE, 0xC3AE, 0xC3AE}, {0xC3AF, 0xC3AF, 0xC3AF}, {0xC3B0, 0xC3B0, 0xC3B0}, {0xC3B1, 0xC3B1, 0xC3B1}, {0xC3B2, 0xC3B2, 0xC3B2}, {0xC3B3, 0xC3B3, 0xC3B3}, {0xC3B4, 0xC3B4, 0xC3B4}, {0xC3B5, 0xC3B5, 0xC3B5}, {0xC3B6, 0xC3B6, 0xC3B6}, {0xC3B7, 0xC3B7, 0xC3B7}, {0xC3B8, 0xC3B8, 0xC3B8}, {0xC3B9, 0xC3B9, 0xC3B9}, {0xC3BA, 0xC3BA, 0xC3BA}, {0xC3BB, 0xC3BB, 0xC3BB}, {0xC3BC, 0xC3BC, 0xC3BC}, {0xC3BD, 0xC3BD, 0xC3BD}, {0xC3BE, 0xC3BE, 0xC3BE}, {0xC3BF, 0xC3BF, 0xC3BF}, {0xC3C0, 0xC3C0, 0xC3C0}, {0xC3C1, 0xC3C1, 0xC3C1}, {0xC3C2, 0xC3C2, 0xC3C2}, {0xC3C3, 0xC3C3, 0xC3C3}, {0xC3C4, 0xC3C4, 0xC3C4}, {0xC3C5, 0xC3C5, 0xC3C5}, {0xC3C6, 0xC3C6, 0xC3C6}, {0xC3C7, 0xC3C7, 0xC3C7}, {0xC3C8, 0xC3C8, 0xC3C8}, {0xC3C9, 0xC3C9, 0xC3C9}, {0xC3CA, 0xC3CA, 0xC3CA}, {0xC3CB, 0xC3CB, 0xC3CB}, {0xC3CC, 0xC3CC, 0xC3CC}, {0xC3CD, 0xC3CD, 0xC3CD}, {0xC3CE, 0xC3CE, 0xC3CE}, {0xC3CF, 0xC3CF, 0xC3CF}, {0xC3D0, 0xC3D0, 0xC3D0}, {0xC3D1, 0xC3D1, 0xC3D1}, {0xC3D2, 0xC3D2, 0xC3D2}, {0xC3D3, 0xC3D3, 0xC3D3}, {0xC3D4, 0xC3D4, 0xC3D4}, {0xC3D5, 0xC3D5, 0xC3D5}, {0xC3D6, 0xC3D6, 0xC3D6}, {0xC3D7, 0xC3D7, 0xC3D7}, {0xC3D8, 0xC3D8, 0xC3D8}, {0xC3D9, 0xC3D9, 0xC3D9}, {0xC3DA, 0xC3DA, 0xC3DA}, {0xC3DB, 0xC3DB, 0xC3DB}, {0xC3DC, 0xC3DC, 0xC3DC}, {0xC3DD, 0xC3DD, 0xC3DD}, {0xC3DE, 0xC3DE, 0xC3DE}, {0xC3DF, 0xC3DF, 0xC3DF}, {0xC3E0, 0xC3E0, 0xC3E0}, {0xC3E1, 0xC3E1, 0xC3E1}, {0xC3E2, 0xC3E2, 0xC3E2}, {0xC3E3, 0xC3E3, 0xC3E3}, {0xC3E4, 0xC3E4, 0xC3E4}, {0xC3E5, 0xC3E5, 0xC3E5}, {0xC3E6, 0xC3E6, 0xC3E6}, {0xC3E7, 0xC3E7, 0xC3E7}, {0xC3E8, 0xC3E8, 0xC3E8}, {0xC3E9, 0xC3E9, 0xC3E9}, {0xC3EA, 0xC3EA, 0xC3EA}, {0xC3EB, 0xC3EB, 0xC3EB}, {0xC3EC, 0xC3EC, 0xC3EC}, {0xC3ED, 0xC3ED, 0xC3ED}, {0xC3EE, 0xC3EE, 0xC3EE}, {0xC3EF, 0xC3EF, 0xC3EF}, {0xC3F0, 0xC3F0, 0xC3F0}, {0xC3F1, 0xC3F1, 0xC3F1}, {0xC3F2, 0xC3F2, 0xC3F2}, {0xC3F3, 0xC3F3, 0xC3F3}, {0xC3F4, 0xC3F4, 0xC3F4}, {0xC3F5, 0xC3F5, 0xC3F5}, {0xC3F6, 0xC3F6, 0xC3F6}, {0xC3F7, 0xC3F7, 0xC3F7}, {0xC3F8, 0xC3F8, 0xC3F8}, {0xC3F9, 0xC3F9, 0xC3F9}, {0xC3FA, 0xC3FA, 0xC3FA}, {0xC3FB, 0xC3FB, 0xC3FB}, {0xC3FC, 0xC3FC, 0xC3FC}, {0xC3FD, 0xC3FD, 0xC3FD}, {0xC3FE, 0xC3FE, 0xC3FE}, {0xC3FF, 0xC3FF, 0xC3FF}, {0xC400, 0xC400, 0xC400}, {0xC401, 0xC401, 0xC401}, {0xC402, 0xC402, 0xC402}, {0xC403, 0xC403, 0xC403}, {0xC404, 0xC404, 0xC404}, {0xC405, 0xC405, 0xC405}, {0xC406, 0xC406, 0xC406}, {0xC407, 0xC407, 0xC407}, {0xC408, 0xC408, 0xC408}, {0xC409, 0xC409, 0xC409}, {0xC40A, 0xC40A, 0xC40A}, {0xC40B, 0xC40B, 0xC40B}, {0xC40C, 0xC40C, 0xC40C}, {0xC40D, 0xC40D, 0xC40D}, {0xC40E, 0xC40E, 0xC40E}, {0xC40F, 0xC40F, 0xC40F}, {0xC410, 0xC410, 0xC410}, {0xC411, 0xC411, 0xC411}, {0xC412, 0xC412, 0xC412}, {0xC413, 0xC413, 0xC413}, {0xC414, 0xC414, 0xC414}, {0xC415, 0xC415, 0xC415}, {0xC416, 0xC416, 0xC416}, {0xC417, 0xC417, 0xC417}, {0xC418, 0xC418, 0xC418}, {0xC419, 0xC419, 0xC419}, {0xC41A, 0xC41A, 0xC41A}, {0xC41B, 0xC41B, 0xC41B}, {0xC41C, 0xC41C, 0xC41C}, {0xC41D, 0xC41D, 0xC41D}, {0xC41E, 0xC41E, 0xC41E}, {0xC41F, 0xC41F, 0xC41F}, {0xC420, 0xC420, 0xC420}, {0xC421, 0xC421, 0xC421}, {0xC422, 0xC422, 0xC422}, {0xC423, 0xC423, 0xC423}, {0xC424, 0xC424, 0xC424}, {0xC425, 0xC425, 0xC425}, {0xC426, 0xC426, 0xC426}, {0xC427, 0xC427, 0xC427}, {0xC428, 0xC428, 0xC428}, {0xC429, 0xC429, 0xC429}, {0xC42A, 0xC42A, 0xC42A}, {0xC42B, 0xC42B, 0xC42B}, {0xC42C, 0xC42C, 0xC42C}, {0xC42D, 0xC42D, 0xC42D}, {0xC42E, 0xC42E, 0xC42E}, {0xC42F, 0xC42F, 0xC42F}, {0xC430, 0xC430, 0xC430}, {0xC431, 0xC431, 0xC431}, {0xC432, 0xC432, 0xC432}, {0xC433, 0xC433, 0xC433}, {0xC434, 0xC434, 0xC434}, {0xC435, 0xC435, 0xC435}, {0xC436, 0xC436, 0xC436}, {0xC437, 0xC437, 0xC437}, {0xC438, 0xC438, 0xC438}, {0xC439, 0xC439, 0xC439}, {0xC43A, 0xC43A, 0xC43A}, {0xC43B, 0xC43B, 0xC43B}, {0xC43C, 0xC43C, 0xC43C}, {0xC43D, 0xC43D, 0xC43D}, {0xC43E, 0xC43E, 0xC43E}, {0xC43F, 0xC43F, 0xC43F}, {0xC440, 0xC440, 0xC440}, {0xC441, 0xC441, 0xC441}, {0xC442, 0xC442, 0xC442}, {0xC443, 0xC443, 0xC443}, {0xC444, 0xC444, 0xC444}, {0xC445, 0xC445, 0xC445}, {0xC446, 0xC446, 0xC446}, {0xC447, 0xC447, 0xC447}, {0xC448, 0xC448, 0xC448}, {0xC449, 0xC449, 0xC449}, {0xC44A, 0xC44A, 0xC44A}, {0xC44B, 0xC44B, 0xC44B}, {0xC44C, 0xC44C, 0xC44C}, {0xC44D, 0xC44D, 0xC44D}, {0xC44E, 0xC44E, 0xC44E}, {0xC44F, 0xC44F, 0xC44F}, {0xC450, 0xC450, 0xC450}, {0xC451, 0xC451, 0xC451}, {0xC452, 0xC452, 0xC452}, {0xC453, 0xC453, 0xC453}, {0xC454, 0xC454, 0xC454}, {0xC455, 0xC455, 0xC455}, {0xC456, 0xC456, 0xC456}, {0xC457, 0xC457, 0xC457}, {0xC458, 0xC458, 0xC458}, {0xC459, 0xC459, 0xC459}, {0xC45A, 0xC45A, 0xC45A}, {0xC45B, 0xC45B, 0xC45B}, {0xC45C, 0xC45C, 0xC45C}, {0xC45D, 0xC45D, 0xC45D}, {0xC45E, 0xC45E, 0xC45E}, {0xC45F, 0xC45F, 0xC45F}, {0xC460, 0xC460, 0xC460}, {0xC461, 0xC461, 0xC461}, {0xC462, 0xC462, 0xC462}, {0xC463, 0xC463, 0xC463}, {0xC464, 0xC464, 0xC464}, {0xC465, 0xC465, 0xC465}, {0xC466, 0xC466, 0xC466}, {0xC467, 0xC467, 0xC467}, {0xC468, 0xC468, 0xC468}, {0xC469, 0xC469, 0xC469}, {0xC46A, 0xC46A, 0xC46A}, {0xC46B, 0xC46B, 0xC46B}, {0xC46C, 0xC46C, 0xC46C}, {0xC46D, 0xC46D, 0xC46D}, {0xC46E, 0xC46E, 0xC46E}, {0xC46F, 0xC46F, 0xC46F}, {0xC470, 0xC470, 0xC470}, {0xC471, 0xC471, 0xC471}, {0xC472, 0xC472, 0xC472}, {0xC473, 0xC473, 0xC473}, {0xC474, 0xC474, 0xC474}, {0xC475, 0xC475, 0xC475}, {0xC476, 0xC476, 0xC476}, {0xC477, 0xC477, 0xC477}, {0xC478, 0xC478, 0xC478}, {0xC479, 0xC479, 0xC479}, {0xC47A, 0xC47A, 0xC47A}, {0xC47B, 0xC47B, 0xC47B}, {0xC47C, 0xC47C, 0xC47C}, {0xC47D, 0xC47D, 0xC47D}, {0xC47E, 0xC47E, 0xC47E}, {0xC47F, 0xC47F, 0xC47F}, {0xC480, 0xC480, 0xC480}, {0xC481, 0xC481, 0xC481}, {0xC482, 0xC482, 0xC482}, {0xC483, 0xC483, 0xC483}, {0xC484, 0xC484, 0xC484}, {0xC485, 0xC485, 0xC485}, {0xC486, 0xC486, 0xC486}, {0xC487, 0xC487, 0xC487}, {0xC488, 0xC488, 0xC488}, {0xC489, 0xC489, 0xC489}, {0xC48A, 0xC48A, 0xC48A}, {0xC48B, 0xC48B, 0xC48B}, {0xC48C, 0xC48C, 0xC48C}, {0xC48D, 0xC48D, 0xC48D}, {0xC48E, 0xC48E, 0xC48E}, {0xC48F, 0xC48F, 0xC48F}, {0xC490, 0xC490, 0xC490}, {0xC491, 0xC491, 0xC491}, {0xC492, 0xC492, 0xC492}, {0xC493, 0xC493, 0xC493}, {0xC494, 0xC494, 0xC494}, {0xC495, 0xC495, 0xC495}, {0xC496, 0xC496, 0xC496}, {0xC497, 0xC497, 0xC497}, {0xC498, 0xC498, 0xC498}, {0xC499, 0xC499, 0xC499}, {0xC49A, 0xC49A, 0xC49A}, {0xC49B, 0xC49B, 0xC49B}, {0xC49C, 0xC49C, 0xC49C}, {0xC49D, 0xC49D, 0xC49D}, {0xC49E, 0xC49E, 0xC49E}, {0xC49F, 0xC49F, 0xC49F}, {0xC4A0, 0xC4A0, 0xC4A0}, {0xC4A1, 0xC4A1, 0xC4A1}, {0xC4A2, 0xC4A2, 0xC4A2}, {0xC4A3, 0xC4A3, 0xC4A3}, {0xC4A4, 0xC4A4, 0xC4A4}, {0xC4A5, 0xC4A5, 0xC4A5}, {0xC4A6, 0xC4A6, 0xC4A6}, {0xC4A7, 0xC4A7, 0xC4A7}, {0xC4A8, 0xC4A8, 0xC4A8}, {0xC4A9, 0xC4A9, 0xC4A9}, {0xC4AA, 0xC4AA, 0xC4AA}, {0xC4AB, 0xC4AB, 0xC4AB}, {0xC4AC, 0xC4AC, 0xC4AC}, {0xC4AD, 0xC4AD, 0xC4AD}, {0xC4AE, 0xC4AE, 0xC4AE}, {0xC4AF, 0xC4AF, 0xC4AF}, {0xC4B0, 0xC4B0, 0xC4B0}, {0xC4B1, 0xC4B1, 0xC4B1}, {0xC4B2, 0xC4B2, 0xC4B2}, {0xC4B3, 0xC4B3, 0xC4B3}, {0xC4B4, 0xC4B4, 0xC4B4}, {0xC4B5, 0xC4B5, 0xC4B5}, {0xC4B6, 0xC4B6, 0xC4B6}, {0xC4B7, 0xC4B7, 0xC4B7}, {0xC4B8, 0xC4B8, 0xC4B8}, {0xC4B9, 0xC4B9, 0xC4B9}, {0xC4BA, 0xC4BA, 0xC4BA}, {0xC4BB, 0xC4BB, 0xC4BB}, {0xC4BC, 0xC4BC, 0xC4BC}, {0xC4BD, 0xC4BD, 0xC4BD}, {0xC4BE, 0xC4BE, 0xC4BE}, {0xC4BF, 0xC4BF, 0xC4BF}, {0xC4C0, 0xC4C0, 0xC4C0}, {0xC4C1, 0xC4C1, 0xC4C1}, {0xC4C2, 0xC4C2, 0xC4C2}, {0xC4C3, 0xC4C3, 0xC4C3}, {0xC4C4, 0xC4C4, 0xC4C4}, {0xC4C5, 0xC4C5, 0xC4C5}, {0xC4C6, 0xC4C6, 0xC4C6}, {0xC4C7, 0xC4C7, 0xC4C7}, {0xC4C8, 0xC4C8, 0xC4C8}, {0xC4C9, 0xC4C9, 0xC4C9}, {0xC4CA, 0xC4CA, 0xC4CA}, {0xC4CB, 0xC4CB, 0xC4CB}, {0xC4CC, 0xC4CC, 0xC4CC}, {0xC4CD, 0xC4CD, 0xC4CD}, {0xC4CE, 0xC4CE, 0xC4CE}, {0xC4CF, 0xC4CF, 0xC4CF}, {0xC4D0, 0xC4D0, 0xC4D0}, {0xC4D1, 0xC4D1, 0xC4D1}, {0xC4D2, 0xC4D2, 0xC4D2}, {0xC4D3, 0xC4D3, 0xC4D3}, {0xC4D4, 0xC4D4, 0xC4D4}, {0xC4D5, 0xC4D5, 0xC4D5}, {0xC4D6, 0xC4D6, 0xC4D6}, {0xC4D7, 0xC4D7, 0xC4D7}, {0xC4D8, 0xC4D8, 0xC4D8}, {0xC4D9, 0xC4D9, 0xC4D9}, {0xC4DA, 0xC4DA, 0xC4DA}, {0xC4DB, 0xC4DB, 0xC4DB}, {0xC4DC, 0xC4DC, 0xC4DC}, {0xC4DD, 0xC4DD, 0xC4DD}, {0xC4DE, 0xC4DE, 0xC4DE}, {0xC4DF, 0xC4DF, 0xC4DF}, {0xC4E0, 0xC4E0, 0xC4E0}, {0xC4E1, 0xC4E1, 0xC4E1}, {0xC4E2, 0xC4E2, 0xC4E2}, {0xC4E3, 0xC4E3, 0xC4E3}, {0xC4E4, 0xC4E4, 0xC4E4}, {0xC4E5, 0xC4E5, 0xC4E5}, {0xC4E6, 0xC4E6, 0xC4E6}, {0xC4E7, 0xC4E7, 0xC4E7}, {0xC4E8, 0xC4E8, 0xC4E8}, {0xC4E9, 0xC4E9, 0xC4E9}, {0xC4EA, 0xC4EA, 0xC4EA}, {0xC4EB, 0xC4EB, 0xC4EB}, {0xC4EC, 0xC4EC, 0xC4EC}, {0xC4ED, 0xC4ED, 0xC4ED}, {0xC4EE, 0xC4EE, 0xC4EE}, {0xC4EF, 0xC4EF, 0xC4EF}, {0xC4F0, 0xC4F0, 0xC4F0}, {0xC4F1, 0xC4F1, 0xC4F1}, {0xC4F2, 0xC4F2, 0xC4F2}, {0xC4F3, 0xC4F3, 0xC4F3}, {0xC4F4, 0xC4F4, 0xC4F4}, {0xC4F5, 0xC4F5, 0xC4F5}, {0xC4F6, 0xC4F6, 0xC4F6}, {0xC4F7, 0xC4F7, 0xC4F7}, {0xC4F8, 0xC4F8, 0xC4F8}, {0xC4F9, 0xC4F9, 0xC4F9}, {0xC4FA, 0xC4FA, 0xC4FA}, {0xC4FB, 0xC4FB, 0xC4FB}, {0xC4FC, 0xC4FC, 0xC4FC}, {0xC4FD, 0xC4FD, 0xC4FD}, {0xC4FE, 0xC4FE, 0xC4FE}, {0xC4FF, 0xC4FF, 0xC4FF}, {0xC500, 0xC500, 0xC500}, {0xC501, 0xC501, 0xC501}, {0xC502, 0xC502, 0xC502}, {0xC503, 0xC503, 0xC503}, {0xC504, 0xC504, 0xC504}, {0xC505, 0xC505, 0xC505}, {0xC506, 0xC506, 0xC506}, {0xC507, 0xC507, 0xC507}, {0xC508, 0xC508, 0xC508}, {0xC509, 0xC509, 0xC509}, {0xC50A, 0xC50A, 0xC50A}, {0xC50B, 0xC50B, 0xC50B}, {0xC50C, 0xC50C, 0xC50C}, {0xC50D, 0xC50D, 0xC50D}, {0xC50E, 0xC50E, 0xC50E}, {0xC50F, 0xC50F, 0xC50F}, {0xC510, 0xC510, 0xC510}, {0xC511, 0xC511, 0xC511}, {0xC512, 0xC512, 0xC512}, {0xC513, 0xC513, 0xC513}, {0xC514, 0xC514, 0xC514}, {0xC515, 0xC515, 0xC515}, {0xC516, 0xC516, 0xC516}, {0xC517, 0xC517, 0xC517}, {0xC518, 0xC518, 0xC518}, {0xC519, 0xC519, 0xC519}, {0xC51A, 0xC51A, 0xC51A}, {0xC51B, 0xC51B, 0xC51B}, {0xC51C, 0xC51C, 0xC51C}, {0xC51D, 0xC51D, 0xC51D}, {0xC51E, 0xC51E, 0xC51E}, {0xC51F, 0xC51F, 0xC51F}, {0xC520, 0xC520, 0xC520}, {0xC521, 0xC521, 0xC521}, {0xC522, 0xC522, 0xC522}, {0xC523, 0xC523, 0xC523}, {0xC524, 0xC524, 0xC524}, {0xC525, 0xC525, 0xC525}, {0xC526, 0xC526, 0xC526}, {0xC527, 0xC527, 0xC527}, {0xC528, 0xC528, 0xC528}, {0xC529, 0xC529, 0xC529}, {0xC52A, 0xC52A, 0xC52A}, {0xC52B, 0xC52B, 0xC52B}, {0xC52C, 0xC52C, 0xC52C}, {0xC52D, 0xC52D, 0xC52D}, {0xC52E, 0xC52E, 0xC52E}, {0xC52F, 0xC52F, 0xC52F}, {0xC530, 0xC530, 0xC530}, {0xC531, 0xC531, 0xC531}, {0xC532, 0xC532, 0xC532}, {0xC533, 0xC533, 0xC533}, {0xC534, 0xC534, 0xC534}, {0xC535, 0xC535, 0xC535}, {0xC536, 0xC536, 0xC536}, {0xC537, 0xC537, 0xC537}, {0xC538, 0xC538, 0xC538}, {0xC539, 0xC539, 0xC539}, {0xC53A, 0xC53A, 0xC53A}, {0xC53B, 0xC53B, 0xC53B}, {0xC53C, 0xC53C, 0xC53C}, {0xC53D, 0xC53D, 0xC53D}, {0xC53E, 0xC53E, 0xC53E}, {0xC53F, 0xC53F, 0xC53F}, {0xC540, 0xC540, 0xC540}, {0xC541, 0xC541, 0xC541}, {0xC542, 0xC542, 0xC542}, {0xC543, 0xC543, 0xC543}, {0xC544, 0xC544, 0xC544}, {0xC545, 0xC545, 0xC545}, {0xC546, 0xC546, 0xC546}, {0xC547, 0xC547, 0xC547}, {0xC548, 0xC548, 0xC548}, {0xC549, 0xC549, 0xC549}, {0xC54A, 0xC54A, 0xC54A}, {0xC54B, 0xC54B, 0xC54B}, {0xC54C, 0xC54C, 0xC54C}, {0xC54D, 0xC54D, 0xC54D}, {0xC54E, 0xC54E, 0xC54E}, {0xC54F, 0xC54F, 0xC54F}, {0xC550, 0xC550, 0xC550}, {0xC551, 0xC551, 0xC551}, {0xC552, 0xC552, 0xC552}, {0xC553, 0xC553, 0xC553}, {0xC554, 0xC554, 0xC554}, {0xC555, 0xC555, 0xC555}, {0xC556, 0xC556, 0xC556}, {0xC557, 0xC557, 0xC557}, {0xC558, 0xC558, 0xC558}, {0xC559, 0xC559, 0xC559}, {0xC55A, 0xC55A, 0xC55A}, {0xC55B, 0xC55B, 0xC55B}, {0xC55C, 0xC55C, 0xC55C}, {0xC55D, 0xC55D, 0xC55D}, {0xC55E, 0xC55E, 0xC55E}, {0xC55F, 0xC55F, 0xC55F}, {0xC560, 0xC560, 0xC560}, {0xC561, 0xC561, 0xC561}, {0xC562, 0xC562, 0xC562}, {0xC563, 0xC563, 0xC563}, {0xC564, 0xC564, 0xC564}, {0xC565, 0xC565, 0xC565}, {0xC566, 0xC566, 0xC566}, {0xC567, 0xC567, 0xC567}, {0xC568, 0xC568, 0xC568}, {0xC569, 0xC569, 0xC569}, {0xC56A, 0xC56A, 0xC56A}, {0xC56B, 0xC56B, 0xC56B}, {0xC56C, 0xC56C, 0xC56C}, {0xC56D, 0xC56D, 0xC56D}, {0xC56E, 0xC56E, 0xC56E}, {0xC56F, 0xC56F, 0xC56F}, {0xC570, 0xC570, 0xC570}, {0xC571, 0xC571, 0xC571}, {0xC572, 0xC572, 0xC572}, {0xC573, 0xC573, 0xC573}, {0xC574, 0xC574, 0xC574}, {0xC575, 0xC575, 0xC575}, {0xC576, 0xC576, 0xC576}, {0xC577, 0xC577, 0xC577}, {0xC578, 0xC578, 0xC578}, {0xC579, 0xC579, 0xC579}, {0xC57A, 0xC57A, 0xC57A}, {0xC57B, 0xC57B, 0xC57B}, {0xC57C, 0xC57C, 0xC57C}, {0xC57D, 0xC57D, 0xC57D}, {0xC57E, 0xC57E, 0xC57E}, {0xC57F, 0xC57F, 0xC57F}, {0xC580, 0xC580, 0xC580}, {0xC581, 0xC581, 0xC581}, {0xC582, 0xC582, 0xC582}, {0xC583, 0xC583, 0xC583}, {0xC584, 0xC584, 0xC584}, {0xC585, 0xC585, 0xC585}, {0xC586, 0xC586, 0xC586}, {0xC587, 0xC587, 0xC587}, {0xC588, 0xC588, 0xC588}, {0xC589, 0xC589, 0xC589}, {0xC58A, 0xC58A, 0xC58A}, {0xC58B, 0xC58B, 0xC58B}, {0xC58C, 0xC58C, 0xC58C}, {0xC58D, 0xC58D, 0xC58D}, {0xC58E, 0xC58E, 0xC58E}, {0xC58F, 0xC58F, 0xC58F}, {0xC590, 0xC590, 0xC590}, {0xC591, 0xC591, 0xC591}, {0xC592, 0xC592, 0xC592}, {0xC593, 0xC593, 0xC593}, {0xC594, 0xC594, 0xC594}, {0xC595, 0xC595, 0xC595}, {0xC596, 0xC596, 0xC596}, {0xC597, 0xC597, 0xC597}, {0xC598, 0xC598, 0xC598}, {0xC599, 0xC599, 0xC599}, {0xC59A, 0xC59A, 0xC59A}, {0xC59B, 0xC59B, 0xC59B}, {0xC59C, 0xC59C, 0xC59C}, {0xC59D, 0xC59D, 0xC59D}, {0xC59E, 0xC59E, 0xC59E}, {0xC59F, 0xC59F, 0xC59F}, {0xC5A0, 0xC5A0, 0xC5A0}, {0xC5A1, 0xC5A1, 0xC5A1}, {0xC5A2, 0xC5A2, 0xC5A2}, {0xC5A3, 0xC5A3, 0xC5A3}, {0xC5A4, 0xC5A4, 0xC5A4}, {0xC5A5, 0xC5A5, 0xC5A5}, {0xC5A6, 0xC5A6, 0xC5A6}, {0xC5A7, 0xC5A7, 0xC5A7}, {0xC5A8, 0xC5A8, 0xC5A8}, {0xC5A9, 0xC5A9, 0xC5A9}, {0xC5AA, 0xC5AA, 0xC5AA}, {0xC5AB, 0xC5AB, 0xC5AB}, {0xC5AC, 0xC5AC, 0xC5AC}, {0xC5AD, 0xC5AD, 0xC5AD}, {0xC5AE, 0xC5AE, 0xC5AE}, {0xC5AF, 0xC5AF, 0xC5AF}, {0xC5B0, 0xC5B0, 0xC5B0}, {0xC5B1, 0xC5B1, 0xC5B1}, {0xC5B2, 0xC5B2, 0xC5B2}, {0xC5B3, 0xC5B3, 0xC5B3}, {0xC5B4, 0xC5B4, 0xC5B4}, {0xC5B5, 0xC5B5, 0xC5B5}, {0xC5B6, 0xC5B6, 0xC5B6}, {0xC5B7, 0xC5B7, 0xC5B7}, {0xC5B8, 0xC5B8, 0xC5B8}, {0xC5B9, 0xC5B9, 0xC5B9}, {0xC5BA, 0xC5BA, 0xC5BA}, {0xC5BB, 0xC5BB, 0xC5BB}, {0xC5BC, 0xC5BC, 0xC5BC}, {0xC5BD, 0xC5BD, 0xC5BD}, {0xC5BE, 0xC5BE, 0xC5BE}, {0xC5BF, 0xC5BF, 0xC5BF}, {0xC5C0, 0xC5C0, 0xC5C0}, {0xC5C1, 0xC5C1, 0xC5C1}, {0xC5C2, 0xC5C2, 0xC5C2}, {0xC5C3, 0xC5C3, 0xC5C3}, {0xC5C4, 0xC5C4, 0xC5C4}, {0xC5C5, 0xC5C5, 0xC5C5}, {0xC5C6, 0xC5C6, 0xC5C6}, {0xC5C7, 0xC5C7, 0xC5C7}, {0xC5C8, 0xC5C8, 0xC5C8}, {0xC5C9, 0xC5C9, 0xC5C9}, {0xC5CA, 0xC5CA, 0xC5CA}, {0xC5CB, 0xC5CB, 0xC5CB}, {0xC5CC, 0xC5CC, 0xC5CC}, {0xC5CD, 0xC5CD, 0xC5CD}, {0xC5CE, 0xC5CE, 0xC5CE}, {0xC5CF, 0xC5CF, 0xC5CF}, {0xC5D0, 0xC5D0, 0xC5D0}, {0xC5D1, 0xC5D1, 0xC5D1}, {0xC5D2, 0xC5D2, 0xC5D2}, {0xC5D3, 0xC5D3, 0xC5D3}, {0xC5D4, 0xC5D4, 0xC5D4}, {0xC5D5, 0xC5D5, 0xC5D5}, {0xC5D6, 0xC5D6, 0xC5D6}, {0xC5D7, 0xC5D7, 0xC5D7}, {0xC5D8, 0xC5D8, 0xC5D8}, {0xC5D9, 0xC5D9, 0xC5D9}, {0xC5DA, 0xC5DA, 0xC5DA}, {0xC5DB, 0xC5DB, 0xC5DB}, {0xC5DC, 0xC5DC, 0xC5DC}, {0xC5DD, 0xC5DD, 0xC5DD}, {0xC5DE, 0xC5DE, 0xC5DE}, {0xC5DF, 0xC5DF, 0xC5DF}, {0xC5E0, 0xC5E0, 0xC5E0}, {0xC5E1, 0xC5E1, 0xC5E1}, {0xC5E2, 0xC5E2, 0xC5E2}, {0xC5E3, 0xC5E3, 0xC5E3}, {0xC5E4, 0xC5E4, 0xC5E4}, {0xC5E5, 0xC5E5, 0xC5E5}, {0xC5E6, 0xC5E6, 0xC5E6}, {0xC5E7, 0xC5E7, 0xC5E7}, {0xC5E8, 0xC5E8, 0xC5E8}, {0xC5E9, 0xC5E9, 0xC5E9}, {0xC5EA, 0xC5EA, 0xC5EA}, {0xC5EB, 0xC5EB, 0xC5EB}, {0xC5EC, 0xC5EC, 0xC5EC}, {0xC5ED, 0xC5ED, 0xC5ED}, {0xC5EE, 0xC5EE, 0xC5EE}, {0xC5EF, 0xC5EF, 0xC5EF}, {0xC5F0, 0xC5F0, 0xC5F0}, {0xC5F1, 0xC5F1, 0xC5F1}, {0xC5F2, 0xC5F2, 0xC5F2}, {0xC5F3, 0xC5F3, 0xC5F3}, {0xC5F4, 0xC5F4, 0xC5F4}, {0xC5F5, 0xC5F5, 0xC5F5}, {0xC5F6, 0xC5F6, 0xC5F6}, {0xC5F7, 0xC5F7, 0xC5F7}, {0xC5F8, 0xC5F8, 0xC5F8}, {0xC5F9, 0xC5F9, 0xC5F9}, {0xC5FA, 0xC5FA, 0xC5FA}, {0xC5FB, 0xC5FB, 0xC5FB}, {0xC5FC, 0xC5FC, 0xC5FC}, {0xC5FD, 0xC5FD, 0xC5FD}, {0xC5FE, 0xC5FE, 0xC5FE}, {0xC5FF, 0xC5FF, 0xC5FF}, {0xC600, 0xC600, 0xC600}, {0xC601, 0xC601, 0xC601}, {0xC602, 0xC602, 0xC602}, {0xC603, 0xC603, 0xC603}, {0xC604, 0xC604, 0xC604}, {0xC605, 0xC605, 0xC605}, {0xC606, 0xC606, 0xC606}, {0xC607, 0xC607, 0xC607}, {0xC608, 0xC608, 0xC608}, {0xC609, 0xC609, 0xC609}, {0xC60A, 0xC60A, 0xC60A}, {0xC60B, 0xC60B, 0xC60B}, {0xC60C, 0xC60C, 0xC60C}, {0xC60D, 0xC60D, 0xC60D}, {0xC60E, 0xC60E, 0xC60E}, {0xC60F, 0xC60F, 0xC60F}, {0xC610, 0xC610, 0xC610}, {0xC611, 0xC611, 0xC611}, {0xC612, 0xC612, 0xC612}, {0xC613, 0xC613, 0xC613}, {0xC614, 0xC614, 0xC614}, {0xC615, 0xC615, 0xC615}, {0xC616, 0xC616, 0xC616}, {0xC617, 0xC617, 0xC617}, {0xC618, 0xC618, 0xC618}, {0xC619, 0xC619, 0xC619}, {0xC61A, 0xC61A, 0xC61A}, {0xC61B, 0xC61B, 0xC61B}, {0xC61C, 0xC61C, 0xC61C}, {0xC61D, 0xC61D, 0xC61D}, {0xC61E, 0xC61E, 0xC61E}, {0xC61F, 0xC61F, 0xC61F}, {0xC620, 0xC620, 0xC620}, {0xC621, 0xC621, 0xC621}, {0xC622, 0xC622, 0xC622}, {0xC623, 0xC623, 0xC623}, {0xC624, 0xC624, 0xC624}, {0xC625, 0xC625, 0xC625}, {0xC626, 0xC626, 0xC626}, {0xC627, 0xC627, 0xC627}, {0xC628, 0xC628, 0xC628}, {0xC629, 0xC629, 0xC629}, {0xC62A, 0xC62A, 0xC62A}, {0xC62B, 0xC62B, 0xC62B}, {0xC62C, 0xC62C, 0xC62C}, {0xC62D, 0xC62D, 0xC62D}, {0xC62E, 0xC62E, 0xC62E}, {0xC62F, 0xC62F, 0xC62F}, {0xC630, 0xC630, 0xC630}, {0xC631, 0xC631, 0xC631}, {0xC632, 0xC632, 0xC632}, {0xC633, 0xC633, 0xC633}, {0xC634, 0xC634, 0xC634}, {0xC635, 0xC635, 0xC635}, {0xC636, 0xC636, 0xC636}, {0xC637, 0xC637, 0xC637}, {0xC638, 0xC638, 0xC638}, {0xC639, 0xC639, 0xC639}, {0xC63A, 0xC63A, 0xC63A}, {0xC63B, 0xC63B, 0xC63B}, {0xC63C, 0xC63C, 0xC63C}, {0xC63D, 0xC63D, 0xC63D}, {0xC63E, 0xC63E, 0xC63E}, {0xC63F, 0xC63F, 0xC63F}, {0xC640, 0xC640, 0xC640}, {0xC641, 0xC641, 0xC641}, {0xC642, 0xC642, 0xC642}, {0xC643, 0xC643, 0xC643}, {0xC644, 0xC644, 0xC644}, {0xC645, 0xC645, 0xC645}, {0xC646, 0xC646, 0xC646}, {0xC647, 0xC647, 0xC647}, {0xC648, 0xC648, 0xC648}, {0xC649, 0xC649, 0xC649}, {0xC64A, 0xC64A, 0xC64A}, {0xC64B, 0xC64B, 0xC64B}, {0xC64C, 0xC64C, 0xC64C}, {0xC64D, 0xC64D, 0xC64D}, {0xC64E, 0xC64E, 0xC64E}, {0xC64F, 0xC64F, 0xC64F}, {0xC650, 0xC650, 0xC650}, {0xC651, 0xC651, 0xC651}, {0xC652, 0xC652, 0xC652}, {0xC653, 0xC653, 0xC653}, {0xC654, 0xC654, 0xC654}, {0xC655, 0xC655, 0xC655}, {0xC656, 0xC656, 0xC656}, {0xC657, 0xC657, 0xC657}, {0xC658, 0xC658, 0xC658}, {0xC659, 0xC659, 0xC659}, {0xC65A, 0xC65A, 0xC65A}, {0xC65B, 0xC65B, 0xC65B}, {0xC65C, 0xC65C, 0xC65C}, {0xC65D, 0xC65D, 0xC65D}, {0xC65E, 0xC65E, 0xC65E}, {0xC65F, 0xC65F, 0xC65F}, {0xC660, 0xC660, 0xC660}, {0xC661, 0xC661, 0xC661}, {0xC662, 0xC662, 0xC662}, {0xC663, 0xC663, 0xC663}, {0xC664, 0xC664, 0xC664}, {0xC665, 0xC665, 0xC665}, {0xC666, 0xC666, 0xC666}, {0xC667, 0xC667, 0xC667}, {0xC668, 0xC668, 0xC668}, {0xC669, 0xC669, 0xC669}, {0xC66A, 0xC66A, 0xC66A}, {0xC66B, 0xC66B, 0xC66B}, {0xC66C, 0xC66C, 0xC66C}, {0xC66D, 0xC66D, 0xC66D}, {0xC66E, 0xC66E, 0xC66E}, {0xC66F, 0xC66F, 0xC66F}, {0xC670, 0xC670, 0xC670}, {0xC671, 0xC671, 0xC671}, {0xC672, 0xC672, 0xC672}, {0xC673, 0xC673, 0xC673}, {0xC674, 0xC674, 0xC674}, {0xC675, 0xC675, 0xC675}, {0xC676, 0xC676, 0xC676}, {0xC677, 0xC677, 0xC677}, {0xC678, 0xC678, 0xC678}, {0xC679, 0xC679, 0xC679}, {0xC67A, 0xC67A, 0xC67A}, {0xC67B, 0xC67B, 0xC67B}, {0xC67C, 0xC67C, 0xC67C}, {0xC67D, 0xC67D, 0xC67D}, {0xC67E, 0xC67E, 0xC67E}, {0xC67F, 0xC67F, 0xC67F}, {0xC680, 0xC680, 0xC680}, {0xC681, 0xC681, 0xC681}, {0xC682, 0xC682, 0xC682}, {0xC683, 0xC683, 0xC683}, {0xC684, 0xC684, 0xC684}, {0xC685, 0xC685, 0xC685}, {0xC686, 0xC686, 0xC686}, {0xC687, 0xC687, 0xC687}, {0xC688, 0xC688, 0xC688}, {0xC689, 0xC689, 0xC689}, {0xC68A, 0xC68A, 0xC68A}, {0xC68B, 0xC68B, 0xC68B}, {0xC68C, 0xC68C, 0xC68C}, {0xC68D, 0xC68D, 0xC68D}, {0xC68E, 0xC68E, 0xC68E}, {0xC68F, 0xC68F, 0xC68F}, {0xC690, 0xC690, 0xC690}, {0xC691, 0xC691, 0xC691}, {0xC692, 0xC692, 0xC692}, {0xC693, 0xC693, 0xC693}, {0xC694, 0xC694, 0xC694}, {0xC695, 0xC695, 0xC695}, {0xC696, 0xC696, 0xC696}, {0xC697, 0xC697, 0xC697}, {0xC698, 0xC698, 0xC698}, {0xC699, 0xC699, 0xC699}, {0xC69A, 0xC69A, 0xC69A}, {0xC69B, 0xC69B, 0xC69B}, {0xC69C, 0xC69C, 0xC69C}, {0xC69D, 0xC69D, 0xC69D}, {0xC69E, 0xC69E, 0xC69E}, {0xC69F, 0xC69F, 0xC69F}, {0xC6A0, 0xC6A0, 0xC6A0}, {0xC6A1, 0xC6A1, 0xC6A1}, {0xC6A2, 0xC6A2, 0xC6A2}, {0xC6A3, 0xC6A3, 0xC6A3}, {0xC6A4, 0xC6A4, 0xC6A4}, {0xC6A5, 0xC6A5, 0xC6A5}, {0xC6A6, 0xC6A6, 0xC6A6}, {0xC6A7, 0xC6A7, 0xC6A7}, {0xC6A8, 0xC6A8, 0xC6A8}, {0xC6A9, 0xC6A9, 0xC6A9}, {0xC6AA, 0xC6AA, 0xC6AA}, {0xC6AB, 0xC6AB, 0xC6AB}, {0xC6AC, 0xC6AC, 0xC6AC}, {0xC6AD, 0xC6AD, 0xC6AD}, {0xC6AE, 0xC6AE, 0xC6AE}, {0xC6AF, 0xC6AF, 0xC6AF}, {0xC6B0, 0xC6B0, 0xC6B0}, {0xC6B1, 0xC6B1, 0xC6B1}, {0xC6B2, 0xC6B2, 0xC6B2}, {0xC6B3, 0xC6B3, 0xC6B3}, {0xC6B4, 0xC6B4, 0xC6B4}, {0xC6B5, 0xC6B5, 0xC6B5}, {0xC6B6, 0xC6B6, 0xC6B6}, {0xC6B7, 0xC6B7, 0xC6B7}, {0xC6B8, 0xC6B8, 0xC6B8}, {0xC6B9, 0xC6B9, 0xC6B9}, {0xC6BA, 0xC6BA, 0xC6BA}, {0xC6BB, 0xC6BB, 0xC6BB}, {0xC6BC, 0xC6BC, 0xC6BC}, {0xC6BD, 0xC6BD, 0xC6BD}, {0xC6BE, 0xC6BE, 0xC6BE}, {0xC6BF, 0xC6BF, 0xC6BF}, {0xC6C0, 0xC6C0, 0xC6C0}, {0xC6C1, 0xC6C1, 0xC6C1}, {0xC6C2, 0xC6C2, 0xC6C2}, {0xC6C3, 0xC6C3, 0xC6C3}, {0xC6C4, 0xC6C4, 0xC6C4}, {0xC6C5, 0xC6C5, 0xC6C5}, {0xC6C6, 0xC6C6, 0xC6C6}, {0xC6C7, 0xC6C7, 0xC6C7}, {0xC6C8, 0xC6C8, 0xC6C8}, {0xC6C9, 0xC6C9, 0xC6C9}, {0xC6CA, 0xC6CA, 0xC6CA}, {0xC6CB, 0xC6CB, 0xC6CB}, {0xC6CC, 0xC6CC, 0xC6CC}, {0xC6CD, 0xC6CD, 0xC6CD}, {0xC6CE, 0xC6CE, 0xC6CE}, {0xC6CF, 0xC6CF, 0xC6CF}, {0xC6D0, 0xC6D0, 0xC6D0}, {0xC6D1, 0xC6D1, 0xC6D1}, {0xC6D2, 0xC6D2, 0xC6D2}, {0xC6D3, 0xC6D3, 0xC6D3}, {0xC6D4, 0xC6D4, 0xC6D4}, {0xC6D5, 0xC6D5, 0xC6D5}, {0xC6D6, 0xC6D6, 0xC6D6}, {0xC6D7, 0xC6D7, 0xC6D7}, {0xC6D8, 0xC6D8, 0xC6D8}, {0xC6D9, 0xC6D9, 0xC6D9}, {0xC6DA, 0xC6DA, 0xC6DA}, {0xC6DB, 0xC6DB, 0xC6DB}, {0xC6DC, 0xC6DC, 0xC6DC}, {0xC6DD, 0xC6DD, 0xC6DD}, {0xC6DE, 0xC6DE, 0xC6DE}, {0xC6DF, 0xC6DF, 0xC6DF}, {0xC6E0, 0xC6E0, 0xC6E0}, {0xC6E1, 0xC6E1, 0xC6E1}, {0xC6E2, 0xC6E2, 0xC6E2}, {0xC6E3, 0xC6E3, 0xC6E3}, {0xC6E4, 0xC6E4, 0xC6E4}, {0xC6E5, 0xC6E5, 0xC6E5}, {0xC6E6, 0xC6E6, 0xC6E6}, {0xC6E7, 0xC6E7, 0xC6E7}, {0xC6E8, 0xC6E8, 0xC6E8}, {0xC6E9, 0xC6E9, 0xC6E9}, {0xC6EA, 0xC6EA, 0xC6EA}, {0xC6EB, 0xC6EB, 0xC6EB}, {0xC6EC, 0xC6EC, 0xC6EC}, {0xC6ED, 0xC6ED, 0xC6ED}, {0xC6EE, 0xC6EE, 0xC6EE}, {0xC6EF, 0xC6EF, 0xC6EF}, {0xC6F0, 0xC6F0, 0xC6F0}, {0xC6F1, 0xC6F1, 0xC6F1}, {0xC6F2, 0xC6F2, 0xC6F2}, {0xC6F3, 0xC6F3, 0xC6F3}, {0xC6F4, 0xC6F4, 0xC6F4}, {0xC6F5, 0xC6F5, 0xC6F5}, {0xC6F6, 0xC6F6, 0xC6F6}, {0xC6F7, 0xC6F7, 0xC6F7}, {0xC6F8, 0xC6F8, 0xC6F8}, {0xC6F9, 0xC6F9, 0xC6F9}, {0xC6FA, 0xC6FA, 0xC6FA}, {0xC6FB, 0xC6FB, 0xC6FB}, {0xC6FC, 0xC6FC, 0xC6FC}, {0xC6FD, 0xC6FD, 0xC6FD}, {0xC6FE, 0xC6FE, 0xC6FE}, {0xC6FF, 0xC6FF, 0xC6FF}, {0xC700, 0xC700, 0xC700}, {0xC701, 0xC701, 0xC701}, {0xC702, 0xC702, 0xC702}, {0xC703, 0xC703, 0xC703}, {0xC704, 0xC704, 0xC704}, {0xC705, 0xC705, 0xC705}, {0xC706, 0xC706, 0xC706}, {0xC707, 0xC707, 0xC707}, {0xC708, 0xC708, 0xC708}, {0xC709, 0xC709, 0xC709}, {0xC70A, 0xC70A, 0xC70A}, {0xC70B, 0xC70B, 0xC70B}, {0xC70C, 0xC70C, 0xC70C}, {0xC70D, 0xC70D, 0xC70D}, {0xC70E, 0xC70E, 0xC70E}, {0xC70F, 0xC70F, 0xC70F}, {0xC710, 0xC710, 0xC710}, {0xC711, 0xC711, 0xC711}, {0xC712, 0xC712, 0xC712}, {0xC713, 0xC713, 0xC713}, {0xC714, 0xC714, 0xC714}, {0xC715, 0xC715, 0xC715}, {0xC716, 0xC716, 0xC716}, {0xC717, 0xC717, 0xC717}, {0xC718, 0xC718, 0xC718}, {0xC719, 0xC719, 0xC719}, {0xC71A, 0xC71A, 0xC71A}, {0xC71B, 0xC71B, 0xC71B}, {0xC71C, 0xC71C, 0xC71C}, {0xC71D, 0xC71D, 0xC71D}, {0xC71E, 0xC71E, 0xC71E}, {0xC71F, 0xC71F, 0xC71F}, {0xC720, 0xC720, 0xC720}, {0xC721, 0xC721, 0xC721}, {0xC722, 0xC722, 0xC722}, {0xC723, 0xC723, 0xC723}, {0xC724, 0xC724, 0xC724}, {0xC725, 0xC725, 0xC725}, {0xC726, 0xC726, 0xC726}, {0xC727, 0xC727, 0xC727}, {0xC728, 0xC728, 0xC728}, {0xC729, 0xC729, 0xC729}, {0xC72A, 0xC72A, 0xC72A}, {0xC72B, 0xC72B, 0xC72B}, {0xC72C, 0xC72C, 0xC72C}, {0xC72D, 0xC72D, 0xC72D}, {0xC72E, 0xC72E, 0xC72E}, {0xC72F, 0xC72F, 0xC72F}, {0xC730, 0xC730, 0xC730}, {0xC731, 0xC731, 0xC731}, {0xC732, 0xC732, 0xC732}, {0xC733, 0xC733, 0xC733}, {0xC734, 0xC734, 0xC734}, {0xC735, 0xC735, 0xC735}, {0xC736, 0xC736, 0xC736}, {0xC737, 0xC737, 0xC737}, {0xC738, 0xC738, 0xC738}, {0xC739, 0xC739, 0xC739}, {0xC73A, 0xC73A, 0xC73A}, {0xC73B, 0xC73B, 0xC73B}, {0xC73C, 0xC73C, 0xC73C}, {0xC73D, 0xC73D, 0xC73D}, {0xC73E, 0xC73E, 0xC73E}, {0xC73F, 0xC73F, 0xC73F}, {0xC740, 0xC740, 0xC740}, {0xC741, 0xC741, 0xC741}, {0xC742, 0xC742, 0xC742}, {0xC743, 0xC743, 0xC743}, {0xC744, 0xC744, 0xC744}, {0xC745, 0xC745, 0xC745}, {0xC746, 0xC746, 0xC746}, {0xC747, 0xC747, 0xC747}, {0xC748, 0xC748, 0xC748}, {0xC749, 0xC749, 0xC749}, {0xC74A, 0xC74A, 0xC74A}, {0xC74B, 0xC74B, 0xC74B}, {0xC74C, 0xC74C, 0xC74C}, {0xC74D, 0xC74D, 0xC74D}, {0xC74E, 0xC74E, 0xC74E}, {0xC74F, 0xC74F, 0xC74F}, {0xC750, 0xC750, 0xC750}, {0xC751, 0xC751, 0xC751}, {0xC752, 0xC752, 0xC752}, {0xC753, 0xC753, 0xC753}, {0xC754, 0xC754, 0xC754}, {0xC755, 0xC755, 0xC755}, {0xC756, 0xC756, 0xC756}, {0xC757, 0xC757, 0xC757}, {0xC758, 0xC758, 0xC758}, {0xC759, 0xC759, 0xC759}, {0xC75A, 0xC75A, 0xC75A}, {0xC75B, 0xC75B, 0xC75B}, {0xC75C, 0xC75C, 0xC75C}, {0xC75D, 0xC75D, 0xC75D}, {0xC75E, 0xC75E, 0xC75E}, {0xC75F, 0xC75F, 0xC75F}, {0xC760, 0xC760, 0xC760}, {0xC761, 0xC761, 0xC761}, {0xC762, 0xC762, 0xC762}, {0xC763, 0xC763, 0xC763}, {0xC764, 0xC764, 0xC764}, {0xC765, 0xC765, 0xC765}, {0xC766, 0xC766, 0xC766}, {0xC767, 0xC767, 0xC767}, {0xC768, 0xC768, 0xC768}, {0xC769, 0xC769, 0xC769}, {0xC76A, 0xC76A, 0xC76A}, {0xC76B, 0xC76B, 0xC76B}, {0xC76C, 0xC76C, 0xC76C}, {0xC76D, 0xC76D, 0xC76D}, {0xC76E, 0xC76E, 0xC76E}, {0xC76F, 0xC76F, 0xC76F}, {0xC770, 0xC770, 0xC770}, {0xC771, 0xC771, 0xC771}, {0xC772, 0xC772, 0xC772}, {0xC773, 0xC773, 0xC773}, {0xC774, 0xC774, 0xC774}, {0xC775, 0xC775, 0xC775}, {0xC776, 0xC776, 0xC776}, {0xC777, 0xC777, 0xC777}, {0xC778, 0xC778, 0xC778}, {0xC779, 0xC779, 0xC779}, {0xC77A, 0xC77A, 0xC77A}, {0xC77B, 0xC77B, 0xC77B}, {0xC77C, 0xC77C, 0xC77C}, {0xC77D, 0xC77D, 0xC77D}, {0xC77E, 0xC77E, 0xC77E}, {0xC77F, 0xC77F, 0xC77F}, {0xC780, 0xC780, 0xC780}, {0xC781, 0xC781, 0xC781}, {0xC782, 0xC782, 0xC782}, {0xC783, 0xC783, 0xC783}, {0xC784, 0xC784, 0xC784}, {0xC785, 0xC785, 0xC785}, {0xC786, 0xC786, 0xC786}, {0xC787, 0xC787, 0xC787}, {0xC788, 0xC788, 0xC788}, {0xC789, 0xC789, 0xC789}, {0xC78A, 0xC78A, 0xC78A}, {0xC78B, 0xC78B, 0xC78B}, {0xC78C, 0xC78C, 0xC78C}, {0xC78D, 0xC78D, 0xC78D}, {0xC78E, 0xC78E, 0xC78E}, {0xC78F, 0xC78F, 0xC78F}, {0xC790, 0xC790, 0xC790}, {0xC791, 0xC791, 0xC791}, {0xC792, 0xC792, 0xC792}, {0xC793, 0xC793, 0xC793}, {0xC794, 0xC794, 0xC794}, {0xC795, 0xC795, 0xC795}, {0xC796, 0xC796, 0xC796}, {0xC797, 0xC797, 0xC797}, {0xC798, 0xC798, 0xC798}, {0xC799, 0xC799, 0xC799}, {0xC79A, 0xC79A, 0xC79A}, {0xC79B, 0xC79B, 0xC79B}, {0xC79C, 0xC79C, 0xC79C}, {0xC79D, 0xC79D, 0xC79D}, {0xC79E, 0xC79E, 0xC79E}, {0xC79F, 0xC79F, 0xC79F}, {0xC7A0, 0xC7A0, 0xC7A0}, {0xC7A1, 0xC7A1, 0xC7A1}, {0xC7A2, 0xC7A2, 0xC7A2}, {0xC7A3, 0xC7A3, 0xC7A3}, {0xC7A4, 0xC7A4, 0xC7A4}, {0xC7A5, 0xC7A5, 0xC7A5}, {0xC7A6, 0xC7A6, 0xC7A6}, {0xC7A7, 0xC7A7, 0xC7A7}, {0xC7A8, 0xC7A8, 0xC7A8}, {0xC7A9, 0xC7A9, 0xC7A9}, {0xC7AA, 0xC7AA, 0xC7AA}, {0xC7AB, 0xC7AB, 0xC7AB}, {0xC7AC, 0xC7AC, 0xC7AC}, {0xC7AD, 0xC7AD, 0xC7AD}, {0xC7AE, 0xC7AE, 0xC7AE}, {0xC7AF, 0xC7AF, 0xC7AF}, {0xC7B0, 0xC7B0, 0xC7B0}, {0xC7B1, 0xC7B1, 0xC7B1}, {0xC7B2, 0xC7B2, 0xC7B2}, {0xC7B3, 0xC7B3, 0xC7B3}, {0xC7B4, 0xC7B4, 0xC7B4}, {0xC7B5, 0xC7B5, 0xC7B5}, {0xC7B6, 0xC7B6, 0xC7B6}, {0xC7B7, 0xC7B7, 0xC7B7}, {0xC7B8, 0xC7B8, 0xC7B8}, {0xC7B9, 0xC7B9, 0xC7B9}, {0xC7BA, 0xC7BA, 0xC7BA}, {0xC7BB, 0xC7BB, 0xC7BB}, {0xC7BC, 0xC7BC, 0xC7BC}, {0xC7BD, 0xC7BD, 0xC7BD}, {0xC7BE, 0xC7BE, 0xC7BE}, {0xC7BF, 0xC7BF, 0xC7BF}, {0xC7C0, 0xC7C0, 0xC7C0}, {0xC7C1, 0xC7C1, 0xC7C1}, {0xC7C2, 0xC7C2, 0xC7C2}, {0xC7C3, 0xC7C3, 0xC7C3}, {0xC7C4, 0xC7C4, 0xC7C4}, {0xC7C5, 0xC7C5, 0xC7C5}, {0xC7C6, 0xC7C6, 0xC7C6}, {0xC7C7, 0xC7C7, 0xC7C7}, {0xC7C8, 0xC7C8, 0xC7C8}, {0xC7C9, 0xC7C9, 0xC7C9}, {0xC7CA, 0xC7CA, 0xC7CA}, {0xC7CB, 0xC7CB, 0xC7CB}, {0xC7CC, 0xC7CC, 0xC7CC}, {0xC7CD, 0xC7CD, 0xC7CD}, {0xC7CE, 0xC7CE, 0xC7CE}, {0xC7CF, 0xC7CF, 0xC7CF}, {0xC7D0, 0xC7D0, 0xC7D0}, {0xC7D1, 0xC7D1, 0xC7D1}, {0xC7D2, 0xC7D2, 0xC7D2}, {0xC7D3, 0xC7D3, 0xC7D3}, {0xC7D4, 0xC7D4, 0xC7D4}, {0xC7D5, 0xC7D5, 0xC7D5}, {0xC7D6, 0xC7D6, 0xC7D6}, {0xC7D7, 0xC7D7, 0xC7D7}, {0xC7D8, 0xC7D8, 0xC7D8}, {0xC7D9, 0xC7D9, 0xC7D9}, {0xC7DA, 0xC7DA, 0xC7DA}, {0xC7DB, 0xC7DB, 0xC7DB}, {0xC7DC, 0xC7DC, 0xC7DC}, {0xC7DD, 0xC7DD, 0xC7DD}, {0xC7DE, 0xC7DE, 0xC7DE}, {0xC7DF, 0xC7DF, 0xC7DF}, {0xC7E0, 0xC7E0, 0xC7E0}, {0xC7E1, 0xC7E1, 0xC7E1}, {0xC7E2, 0xC7E2, 0xC7E2}, {0xC7E3, 0xC7E3, 0xC7E3}, {0xC7E4, 0xC7E4, 0xC7E4}, {0xC7E5, 0xC7E5, 0xC7E5}, {0xC7E6, 0xC7E6, 0xC7E6}, {0xC7E7, 0xC7E7, 0xC7E7}, {0xC7E8, 0xC7E8, 0xC7E8}, {0xC7E9, 0xC7E9, 0xC7E9}, {0xC7EA, 0xC7EA, 0xC7EA}, {0xC7EB, 0xC7EB, 0xC7EB}, {0xC7EC, 0xC7EC, 0xC7EC}, {0xC7ED, 0xC7ED, 0xC7ED}, {0xC7EE, 0xC7EE, 0xC7EE}, {0xC7EF, 0xC7EF, 0xC7EF}, {0xC7F0, 0xC7F0, 0xC7F0}, {0xC7F1, 0xC7F1, 0xC7F1}, {0xC7F2, 0xC7F2, 0xC7F2}, {0xC7F3, 0xC7F3, 0xC7F3}, {0xC7F4, 0xC7F4, 0xC7F4}, {0xC7F5, 0xC7F5, 0xC7F5}, {0xC7F6, 0xC7F6, 0xC7F6}, {0xC7F7, 0xC7F7, 0xC7F7}, {0xC7F8, 0xC7F8, 0xC7F8}, {0xC7F9, 0xC7F9, 0xC7F9}, {0xC7FA, 0xC7FA, 0xC7FA}, {0xC7FB, 0xC7FB, 0xC7FB}, {0xC7FC, 0xC7FC, 0xC7FC}, {0xC7FD, 0xC7FD, 0xC7FD}, {0xC7FE, 0xC7FE, 0xC7FE}, {0xC7FF, 0xC7FF, 0xC7FF}, {0xC800, 0xC800, 0xC800}, {0xC801, 0xC801, 0xC801}, {0xC802, 0xC802, 0xC802}, {0xC803, 0xC803, 0xC803}, {0xC804, 0xC804, 0xC804}, {0xC805, 0xC805, 0xC805}, {0xC806, 0xC806, 0xC806}, {0xC807, 0xC807, 0xC807}, {0xC808, 0xC808, 0xC808}, {0xC809, 0xC809, 0xC809}, {0xC80A, 0xC80A, 0xC80A}, {0xC80B, 0xC80B, 0xC80B}, {0xC80C, 0xC80C, 0xC80C}, {0xC80D, 0xC80D, 0xC80D}, {0xC80E, 0xC80E, 0xC80E}, {0xC80F, 0xC80F, 0xC80F}, {0xC810, 0xC810, 0xC810}, {0xC811, 0xC811, 0xC811}, {0xC812, 0xC812, 0xC812}, {0xC813, 0xC813, 0xC813}, {0xC814, 0xC814, 0xC814}, {0xC815, 0xC815, 0xC815}, {0xC816, 0xC816, 0xC816}, {0xC817, 0xC817, 0xC817}, {0xC818, 0xC818, 0xC818}, {0xC819, 0xC819, 0xC819}, {0xC81A, 0xC81A, 0xC81A}, {0xC81B, 0xC81B, 0xC81B}, {0xC81C, 0xC81C, 0xC81C}, {0xC81D, 0xC81D, 0xC81D}, {0xC81E, 0xC81E, 0xC81E}, {0xC81F, 0xC81F, 0xC81F}, {0xC820, 0xC820, 0xC820}, {0xC821, 0xC821, 0xC821}, {0xC822, 0xC822, 0xC822}, {0xC823, 0xC823, 0xC823}, {0xC824, 0xC824, 0xC824}, {0xC825, 0xC825, 0xC825}, {0xC826, 0xC826, 0xC826}, {0xC827, 0xC827, 0xC827}, {0xC828, 0xC828, 0xC828}, {0xC829, 0xC829, 0xC829}, {0xC82A, 0xC82A, 0xC82A}, {0xC82B, 0xC82B, 0xC82B}, {0xC82C, 0xC82C, 0xC82C}, {0xC82D, 0xC82D, 0xC82D}, {0xC82E, 0xC82E, 0xC82E}, {0xC82F, 0xC82F, 0xC82F}, {0xC830, 0xC830, 0xC830}, {0xC831, 0xC831, 0xC831}, {0xC832, 0xC832, 0xC832}, {0xC833, 0xC833, 0xC833}, {0xC834, 0xC834, 0xC834}, {0xC835, 0xC835, 0xC835}, {0xC836, 0xC836, 0xC836}, {0xC837, 0xC837, 0xC837}, {0xC838, 0xC838, 0xC838}, {0xC839, 0xC839, 0xC839}, {0xC83A, 0xC83A, 0xC83A}, {0xC83B, 0xC83B, 0xC83B}, {0xC83C, 0xC83C, 0xC83C}, {0xC83D, 0xC83D, 0xC83D}, {0xC83E, 0xC83E, 0xC83E}, {0xC83F, 0xC83F, 0xC83F}, {0xC840, 0xC840, 0xC840}, {0xC841, 0xC841, 0xC841}, {0xC842, 0xC842, 0xC842}, {0xC843, 0xC843, 0xC843}, {0xC844, 0xC844, 0xC844}, {0xC845, 0xC845, 0xC845}, {0xC846, 0xC846, 0xC846}, {0xC847, 0xC847, 0xC847}, {0xC848, 0xC848, 0xC848}, {0xC849, 0xC849, 0xC849}, {0xC84A, 0xC84A, 0xC84A}, {0xC84B, 0xC84B, 0xC84B}, {0xC84C, 0xC84C, 0xC84C}, {0xC84D, 0xC84D, 0xC84D}, {0xC84E, 0xC84E, 0xC84E}, {0xC84F, 0xC84F, 0xC84F}, {0xC850, 0xC850, 0xC850}, {0xC851, 0xC851, 0xC851}, {0xC852, 0xC852, 0xC852}, {0xC853, 0xC853, 0xC853}, {0xC854, 0xC854, 0xC854}, {0xC855, 0xC855, 0xC855}, {0xC856, 0xC856, 0xC856}, {0xC857, 0xC857, 0xC857}, {0xC858, 0xC858, 0xC858}, {0xC859, 0xC859, 0xC859}, {0xC85A, 0xC85A, 0xC85A}, {0xC85B, 0xC85B, 0xC85B}, {0xC85C, 0xC85C, 0xC85C}, {0xC85D, 0xC85D, 0xC85D}, {0xC85E, 0xC85E, 0xC85E}, {0xC85F, 0xC85F, 0xC85F}, {0xC860, 0xC860, 0xC860}, {0xC861, 0xC861, 0xC861}, {0xC862, 0xC862, 0xC862}, {0xC863, 0xC863, 0xC863}, {0xC864, 0xC864, 0xC864}, {0xC865, 0xC865, 0xC865}, {0xC866, 0xC866, 0xC866}, {0xC867, 0xC867, 0xC867}, {0xC868, 0xC868, 0xC868}, {0xC869, 0xC869, 0xC869}, {0xC86A, 0xC86A, 0xC86A}, {0xC86B, 0xC86B, 0xC86B}, {0xC86C, 0xC86C, 0xC86C}, {0xC86D, 0xC86D, 0xC86D}, {0xC86E, 0xC86E, 0xC86E}, {0xC86F, 0xC86F, 0xC86F}, {0xC870, 0xC870, 0xC870}, {0xC871, 0xC871, 0xC871}, {0xC872, 0xC872, 0xC872}, {0xC873, 0xC873, 0xC873}, {0xC874, 0xC874, 0xC874}, {0xC875, 0xC875, 0xC875}, {0xC876, 0xC876, 0xC876}, {0xC877, 0xC877, 0xC877}, {0xC878, 0xC878, 0xC878}, {0xC879, 0xC879, 0xC879}, {0xC87A, 0xC87A, 0xC87A}, {0xC87B, 0xC87B, 0xC87B}, {0xC87C, 0xC87C, 0xC87C}, {0xC87D, 0xC87D, 0xC87D}, {0xC87E, 0xC87E, 0xC87E}, {0xC87F, 0xC87F, 0xC87F}, {0xC880, 0xC880, 0xC880}, {0xC881, 0xC881, 0xC881}, {0xC882, 0xC882, 0xC882}, {0xC883, 0xC883, 0xC883}, {0xC884, 0xC884, 0xC884}, {0xC885, 0xC885, 0xC885}, {0xC886, 0xC886, 0xC886}, {0xC887, 0xC887, 0xC887}, {0xC888, 0xC888, 0xC888}, {0xC889, 0xC889, 0xC889}, {0xC88A, 0xC88A, 0xC88A}, {0xC88B, 0xC88B, 0xC88B}, {0xC88C, 0xC88C, 0xC88C}, {0xC88D, 0xC88D, 0xC88D}, {0xC88E, 0xC88E, 0xC88E}, {0xC88F, 0xC88F, 0xC88F}, {0xC890, 0xC890, 0xC890}, {0xC891, 0xC891, 0xC891}, {0xC892, 0xC892, 0xC892}, {0xC893, 0xC893, 0xC893}, {0xC894, 0xC894, 0xC894}, {0xC895, 0xC895, 0xC895}, {0xC896, 0xC896, 0xC896}, {0xC897, 0xC897, 0xC897}, {0xC898, 0xC898, 0xC898}, {0xC899, 0xC899, 0xC899}, {0xC89A, 0xC89A, 0xC89A}, {0xC89B, 0xC89B, 0xC89B}, {0xC89C, 0xC89C, 0xC89C}, {0xC89D, 0xC89D, 0xC89D}, {0xC89E, 0xC89E, 0xC89E}, {0xC89F, 0xC89F, 0xC89F}, {0xC8A0, 0xC8A0, 0xC8A0}, {0xC8A1, 0xC8A1, 0xC8A1}, {0xC8A2, 0xC8A2, 0xC8A2}, {0xC8A3, 0xC8A3, 0xC8A3}, {0xC8A4, 0xC8A4, 0xC8A4}, {0xC8A5, 0xC8A5, 0xC8A5}, {0xC8A6, 0xC8A6, 0xC8A6}, {0xC8A7, 0xC8A7, 0xC8A7}, {0xC8A8, 0xC8A8, 0xC8A8}, {0xC8A9, 0xC8A9, 0xC8A9}, {0xC8AA, 0xC8AA, 0xC8AA}, {0xC8AB, 0xC8AB, 0xC8AB}, {0xC8AC, 0xC8AC, 0xC8AC}, {0xC8AD, 0xC8AD, 0xC8AD}, {0xC8AE, 0xC8AE, 0xC8AE}, {0xC8AF, 0xC8AF, 0xC8AF}, {0xC8B0, 0xC8B0, 0xC8B0}, {0xC8B1, 0xC8B1, 0xC8B1}, {0xC8B2, 0xC8B2, 0xC8B2}, {0xC8B3, 0xC8B3, 0xC8B3}, {0xC8B4, 0xC8B4, 0xC8B4}, {0xC8B5, 0xC8B5, 0xC8B5}, {0xC8B6, 0xC8B6, 0xC8B6}, {0xC8B7, 0xC8B7, 0xC8B7}, {0xC8B8, 0xC8B8, 0xC8B8}, {0xC8B9, 0xC8B9, 0xC8B9}, {0xC8BA, 0xC8BA, 0xC8BA}, {0xC8BB, 0xC8BB, 0xC8BB}, {0xC8BC, 0xC8BC, 0xC8BC}, {0xC8BD, 0xC8BD, 0xC8BD}, {0xC8BE, 0xC8BE, 0xC8BE}, {0xC8BF, 0xC8BF, 0xC8BF}, {0xC8C0, 0xC8C0, 0xC8C0}, {0xC8C1, 0xC8C1, 0xC8C1}, {0xC8C2, 0xC8C2, 0xC8C2}, {0xC8C3, 0xC8C3, 0xC8C3}, {0xC8C4, 0xC8C4, 0xC8C4}, {0xC8C5, 0xC8C5, 0xC8C5}, {0xC8C6, 0xC8C6, 0xC8C6}, {0xC8C7, 0xC8C7, 0xC8C7}, {0xC8C8, 0xC8C8, 0xC8C8}, {0xC8C9, 0xC8C9, 0xC8C9}, {0xC8CA, 0xC8CA, 0xC8CA}, {0xC8CB, 0xC8CB, 0xC8CB}, {0xC8CC, 0xC8CC, 0xC8CC}, {0xC8CD, 0xC8CD, 0xC8CD}, {0xC8CE, 0xC8CE, 0xC8CE}, {0xC8CF, 0xC8CF, 0xC8CF}, {0xC8D0, 0xC8D0, 0xC8D0}, {0xC8D1, 0xC8D1, 0xC8D1}, {0xC8D2, 0xC8D2, 0xC8D2}, {0xC8D3, 0xC8D3, 0xC8D3}, {0xC8D4, 0xC8D4, 0xC8D4}, {0xC8D5, 0xC8D5, 0xC8D5}, {0xC8D6, 0xC8D6, 0xC8D6}, {0xC8D7, 0xC8D7, 0xC8D7}, {0xC8D8, 0xC8D8, 0xC8D8}, {0xC8D9, 0xC8D9, 0xC8D9}, {0xC8DA, 0xC8DA, 0xC8DA}, {0xC8DB, 0xC8DB, 0xC8DB}, {0xC8DC, 0xC8DC, 0xC8DC}, {0xC8DD, 0xC8DD, 0xC8DD}, {0xC8DE, 0xC8DE, 0xC8DE}, {0xC8DF, 0xC8DF, 0xC8DF}, {0xC8E0, 0xC8E0, 0xC8E0}, {0xC8E1, 0xC8E1, 0xC8E1}, {0xC8E2, 0xC8E2, 0xC8E2}, {0xC8E3, 0xC8E3, 0xC8E3}, {0xC8E4, 0xC8E4, 0xC8E4}, {0xC8E5, 0xC8E5, 0xC8E5}, {0xC8E6, 0xC8E6, 0xC8E6}, {0xC8E7, 0xC8E7, 0xC8E7}, {0xC8E8, 0xC8E8, 0xC8E8}, {0xC8E9, 0xC8E9, 0xC8E9}, {0xC8EA, 0xC8EA, 0xC8EA}, {0xC8EB, 0xC8EB, 0xC8EB}, {0xC8EC, 0xC8EC, 0xC8EC}, {0xC8ED, 0xC8ED, 0xC8ED}, {0xC8EE, 0xC8EE, 0xC8EE}, {0xC8EF, 0xC8EF, 0xC8EF}, {0xC8F0, 0xC8F0, 0xC8F0}, {0xC8F1, 0xC8F1, 0xC8F1}, {0xC8F2, 0xC8F2, 0xC8F2}, {0xC8F3, 0xC8F3, 0xC8F3}, {0xC8F4, 0xC8F4, 0xC8F4}, {0xC8F5, 0xC8F5, 0xC8F5}, {0xC8F6, 0xC8F6, 0xC8F6}, {0xC8F7, 0xC8F7, 0xC8F7}, {0xC8F8, 0xC8F8, 0xC8F8}, {0xC8F9, 0xC8F9, 0xC8F9}, {0xC8FA, 0xC8FA, 0xC8FA}, {0xC8FB, 0xC8FB, 0xC8FB}, {0xC8FC, 0xC8FC, 0xC8FC}, {0xC8FD, 0xC8FD, 0xC8FD}, {0xC8FE, 0xC8FE, 0xC8FE}, {0xC8FF, 0xC8FF, 0xC8FF}, {0xC900, 0xC900, 0xC900}, {0xC901, 0xC901, 0xC901}, {0xC902, 0xC902, 0xC902}, {0xC903, 0xC903, 0xC903}, {0xC904, 0xC904, 0xC904}, {0xC905, 0xC905, 0xC905}, {0xC906, 0xC906, 0xC906}, {0xC907, 0xC907, 0xC907}, {0xC908, 0xC908, 0xC908}, {0xC909, 0xC909, 0xC909}, {0xC90A, 0xC90A, 0xC90A}, {0xC90B, 0xC90B, 0xC90B}, {0xC90C, 0xC90C, 0xC90C}, {0xC90D, 0xC90D, 0xC90D}, {0xC90E, 0xC90E, 0xC90E}, {0xC90F, 0xC90F, 0xC90F}, {0xC910, 0xC910, 0xC910}, {0xC911, 0xC911, 0xC911}, {0xC912, 0xC912, 0xC912}, {0xC913, 0xC913, 0xC913}, {0xC914, 0xC914, 0xC914}, {0xC915, 0xC915, 0xC915}, {0xC916, 0xC916, 0xC916}, {0xC917, 0xC917, 0xC917}, {0xC918, 0xC918, 0xC918}, {0xC919, 0xC919, 0xC919}, {0xC91A, 0xC91A, 0xC91A}, {0xC91B, 0xC91B, 0xC91B}, {0xC91C, 0xC91C, 0xC91C}, {0xC91D, 0xC91D, 0xC91D}, {0xC91E, 0xC91E, 0xC91E}, {0xC91F, 0xC91F, 0xC91F}, {0xC920, 0xC920, 0xC920}, {0xC921, 0xC921, 0xC921}, {0xC922, 0xC922, 0xC922}, {0xC923, 0xC923, 0xC923}, {0xC924, 0xC924, 0xC924}, {0xC925, 0xC925, 0xC925}, {0xC926, 0xC926, 0xC926}, {0xC927, 0xC927, 0xC927}, {0xC928, 0xC928, 0xC928}, {0xC929, 0xC929, 0xC929}, {0xC92A, 0xC92A, 0xC92A}, {0xC92B, 0xC92B, 0xC92B}, {0xC92C, 0xC92C, 0xC92C}, {0xC92D, 0xC92D, 0xC92D}, {0xC92E, 0xC92E, 0xC92E}, {0xC92F, 0xC92F, 0xC92F}, {0xC930, 0xC930, 0xC930}, {0xC931, 0xC931, 0xC931}, {0xC932, 0xC932, 0xC932}, {0xC933, 0xC933, 0xC933}, {0xC934, 0xC934, 0xC934}, {0xC935, 0xC935, 0xC935}, {0xC936, 0xC936, 0xC936}, {0xC937, 0xC937, 0xC937}, {0xC938, 0xC938, 0xC938}, {0xC939, 0xC939, 0xC939}, {0xC93A, 0xC93A, 0xC93A}, {0xC93B, 0xC93B, 0xC93B}, {0xC93C, 0xC93C, 0xC93C}, {0xC93D, 0xC93D, 0xC93D}, {0xC93E, 0xC93E, 0xC93E}, {0xC93F, 0xC93F, 0xC93F}, {0xC940, 0xC940, 0xC940}, {0xC941, 0xC941, 0xC941}, {0xC942, 0xC942, 0xC942}, {0xC943, 0xC943, 0xC943}, {0xC944, 0xC944, 0xC944}, {0xC945, 0xC945, 0xC945}, {0xC946, 0xC946, 0xC946}, {0xC947, 0xC947, 0xC947}, {0xC948, 0xC948, 0xC948}, {0xC949, 0xC949, 0xC949}, {0xC94A, 0xC94A, 0xC94A}, {0xC94B, 0xC94B, 0xC94B}, {0xC94C, 0xC94C, 0xC94C}, {0xC94D, 0xC94D, 0xC94D}, {0xC94E, 0xC94E, 0xC94E}, {0xC94F, 0xC94F, 0xC94F}, {0xC950, 0xC950, 0xC950}, {0xC951, 0xC951, 0xC951}, {0xC952, 0xC952, 0xC952}, {0xC953, 0xC953, 0xC953}, {0xC954, 0xC954, 0xC954}, {0xC955, 0xC955, 0xC955}, {0xC956, 0xC956, 0xC956}, {0xC957, 0xC957, 0xC957}, {0xC958, 0xC958, 0xC958}, {0xC959, 0xC959, 0xC959}, {0xC95A, 0xC95A, 0xC95A}, {0xC95B, 0xC95B, 0xC95B}, {0xC95C, 0xC95C, 0xC95C}, {0xC95D, 0xC95D, 0xC95D}, {0xC95E, 0xC95E, 0xC95E}, {0xC95F, 0xC95F, 0xC95F}, {0xC960, 0xC960, 0xC960}, {0xC961, 0xC961, 0xC961}, {0xC962, 0xC962, 0xC962}, {0xC963, 0xC963, 0xC963}, {0xC964, 0xC964, 0xC964}, {0xC965, 0xC965, 0xC965}, {0xC966, 0xC966, 0xC966}, {0xC967, 0xC967, 0xC967}, {0xC968, 0xC968, 0xC968}, {0xC969, 0xC969, 0xC969}, {0xC96A, 0xC96A, 0xC96A}, {0xC96B, 0xC96B, 0xC96B}, {0xC96C, 0xC96C, 0xC96C}, {0xC96D, 0xC96D, 0xC96D}, {0xC96E, 0xC96E, 0xC96E}, {0xC96F, 0xC96F, 0xC96F}, {0xC970, 0xC970, 0xC970}, {0xC971, 0xC971, 0xC971}, {0xC972, 0xC972, 0xC972}, {0xC973, 0xC973, 0xC973}, {0xC974, 0xC974, 0xC974}, {0xC975, 0xC975, 0xC975}, {0xC976, 0xC976, 0xC976}, {0xC977, 0xC977, 0xC977}, {0xC978, 0xC978, 0xC978}, {0xC979, 0xC979, 0xC979}, {0xC97A, 0xC97A, 0xC97A}, {0xC97B, 0xC97B, 0xC97B}, {0xC97C, 0xC97C, 0xC97C}, {0xC97D, 0xC97D, 0xC97D}, {0xC97E, 0xC97E, 0xC97E}, {0xC97F, 0xC97F, 0xC97F}, {0xC980, 0xC980, 0xC980}, {0xC981, 0xC981, 0xC981}, {0xC982, 0xC982, 0xC982}, {0xC983, 0xC983, 0xC983}, {0xC984, 0xC984, 0xC984}, {0xC985, 0xC985, 0xC985}, {0xC986, 0xC986, 0xC986}, {0xC987, 0xC987, 0xC987}, {0xC988, 0xC988, 0xC988}, {0xC989, 0xC989, 0xC989}, {0xC98A, 0xC98A, 0xC98A}, {0xC98B, 0xC98B, 0xC98B}, {0xC98C, 0xC98C, 0xC98C}, {0xC98D, 0xC98D, 0xC98D}, {0xC98E, 0xC98E, 0xC98E}, {0xC98F, 0xC98F, 0xC98F}, {0xC990, 0xC990, 0xC990}, {0xC991, 0xC991, 0xC991}, {0xC992, 0xC992, 0xC992}, {0xC993, 0xC993, 0xC993}, {0xC994, 0xC994, 0xC994}, {0xC995, 0xC995, 0xC995}, {0xC996, 0xC996, 0xC996}, {0xC997, 0xC997, 0xC997}, {0xC998, 0xC998, 0xC998}, {0xC999, 0xC999, 0xC999}, {0xC99A, 0xC99A, 0xC99A}, {0xC99B, 0xC99B, 0xC99B}, {0xC99C, 0xC99C, 0xC99C}, {0xC99D, 0xC99D, 0xC99D}, {0xC99E, 0xC99E, 0xC99E}, {0xC99F, 0xC99F, 0xC99F}, {0xC9A0, 0xC9A0, 0xC9A0}, {0xC9A1, 0xC9A1, 0xC9A1}, {0xC9A2, 0xC9A2, 0xC9A2}, {0xC9A3, 0xC9A3, 0xC9A3}, {0xC9A4, 0xC9A4, 0xC9A4}, {0xC9A5, 0xC9A5, 0xC9A5}, {0xC9A6, 0xC9A6, 0xC9A6}, {0xC9A7, 0xC9A7, 0xC9A7}, {0xC9A8, 0xC9A8, 0xC9A8}, {0xC9A9, 0xC9A9, 0xC9A9}, {0xC9AA, 0xC9AA, 0xC9AA}, {0xC9AB, 0xC9AB, 0xC9AB}, {0xC9AC, 0xC9AC, 0xC9AC}, {0xC9AD, 0xC9AD, 0xC9AD}, {0xC9AE, 0xC9AE, 0xC9AE}, {0xC9AF, 0xC9AF, 0xC9AF}, {0xC9B0, 0xC9B0, 0xC9B0}, {0xC9B1, 0xC9B1, 0xC9B1}, {0xC9B2, 0xC9B2, 0xC9B2}, {0xC9B3, 0xC9B3, 0xC9B3}, {0xC9B4, 0xC9B4, 0xC9B4}, {0xC9B5, 0xC9B5, 0xC9B5}, {0xC9B6, 0xC9B6, 0xC9B6}, {0xC9B7, 0xC9B7, 0xC9B7}, {0xC9B8, 0xC9B8, 0xC9B8}, {0xC9B9, 0xC9B9, 0xC9B9}, {0xC9BA, 0xC9BA, 0xC9BA}, {0xC9BB, 0xC9BB, 0xC9BB}, {0xC9BC, 0xC9BC, 0xC9BC}, {0xC9BD, 0xC9BD, 0xC9BD}, {0xC9BE, 0xC9BE, 0xC9BE}, {0xC9BF, 0xC9BF, 0xC9BF}, {0xC9C0, 0xC9C0, 0xC9C0}, {0xC9C1, 0xC9C1, 0xC9C1}, {0xC9C2, 0xC9C2, 0xC9C2}, {0xC9C3, 0xC9C3, 0xC9C3}, {0xC9C4, 0xC9C4, 0xC9C4}, {0xC9C5, 0xC9C5, 0xC9C5}, {0xC9C6, 0xC9C6, 0xC9C6}, {0xC9C7, 0xC9C7, 0xC9C7}, {0xC9C8, 0xC9C8, 0xC9C8}, {0xC9C9, 0xC9C9, 0xC9C9}, {0xC9CA, 0xC9CA, 0xC9CA}, {0xC9CB, 0xC9CB, 0xC9CB}, {0xC9CC, 0xC9CC, 0xC9CC}, {0xC9CD, 0xC9CD, 0xC9CD}, {0xC9CE, 0xC9CE, 0xC9CE}, {0xC9CF, 0xC9CF, 0xC9CF}, {0xC9D0, 0xC9D0, 0xC9D0}, {0xC9D1, 0xC9D1, 0xC9D1}, {0xC9D2, 0xC9D2, 0xC9D2}, {0xC9D3, 0xC9D3, 0xC9D3}, {0xC9D4, 0xC9D4, 0xC9D4}, {0xC9D5, 0xC9D5, 0xC9D5}, {0xC9D6, 0xC9D6, 0xC9D6}, {0xC9D7, 0xC9D7, 0xC9D7}, {0xC9D8, 0xC9D8, 0xC9D8}, {0xC9D9, 0xC9D9, 0xC9D9}, {0xC9DA, 0xC9DA, 0xC9DA}, {0xC9DB, 0xC9DB, 0xC9DB}, {0xC9DC, 0xC9DC, 0xC9DC}, {0xC9DD, 0xC9DD, 0xC9DD}, {0xC9DE, 0xC9DE, 0xC9DE}, {0xC9DF, 0xC9DF, 0xC9DF}, {0xC9E0, 0xC9E0, 0xC9E0}, {0xC9E1, 0xC9E1, 0xC9E1}, {0xC9E2, 0xC9E2, 0xC9E2}, {0xC9E3, 0xC9E3, 0xC9E3}, {0xC9E4, 0xC9E4, 0xC9E4}, {0xC9E5, 0xC9E5, 0xC9E5}, {0xC9E6, 0xC9E6, 0xC9E6}, {0xC9E7, 0xC9E7, 0xC9E7}, {0xC9E8, 0xC9E8, 0xC9E8}, {0xC9E9, 0xC9E9, 0xC9E9}, {0xC9EA, 0xC9EA, 0xC9EA}, {0xC9EB, 0xC9EB, 0xC9EB}, {0xC9EC, 0xC9EC, 0xC9EC}, {0xC9ED, 0xC9ED, 0xC9ED}, {0xC9EE, 0xC9EE, 0xC9EE}, {0xC9EF, 0xC9EF, 0xC9EF}, {0xC9F0, 0xC9F0, 0xC9F0}, {0xC9F1, 0xC9F1, 0xC9F1}, {0xC9F2, 0xC9F2, 0xC9F2}, {0xC9F3, 0xC9F3, 0xC9F3}, {0xC9F4, 0xC9F4, 0xC9F4}, {0xC9F5, 0xC9F5, 0xC9F5}, {0xC9F6, 0xC9F6, 0xC9F6}, {0xC9F7, 0xC9F7, 0xC9F7}, {0xC9F8, 0xC9F8, 0xC9F8}, {0xC9F9, 0xC9F9, 0xC9F9}, {0xC9FA, 0xC9FA, 0xC9FA}, {0xC9FB, 0xC9FB, 0xC9FB}, {0xC9FC, 0xC9FC, 0xC9FC}, {0xC9FD, 0xC9FD, 0xC9FD}, {0xC9FE, 0xC9FE, 0xC9FE}, {0xC9FF, 0xC9FF, 0xC9FF}, {0xCA00, 0xCA00, 0xCA00}, {0xCA01, 0xCA01, 0xCA01}, {0xCA02, 0xCA02, 0xCA02}, {0xCA03, 0xCA03, 0xCA03}, {0xCA04, 0xCA04, 0xCA04}, {0xCA05, 0xCA05, 0xCA05}, {0xCA06, 0xCA06, 0xCA06}, {0xCA07, 0xCA07, 0xCA07}, {0xCA08, 0xCA08, 0xCA08}, {0xCA09, 0xCA09, 0xCA09}, {0xCA0A, 0xCA0A, 0xCA0A}, {0xCA0B, 0xCA0B, 0xCA0B}, {0xCA0C, 0xCA0C, 0xCA0C}, {0xCA0D, 0xCA0D, 0xCA0D}, {0xCA0E, 0xCA0E, 0xCA0E}, {0xCA0F, 0xCA0F, 0xCA0F}, {0xCA10, 0xCA10, 0xCA10}, {0xCA11, 0xCA11, 0xCA11}, {0xCA12, 0xCA12, 0xCA12}, {0xCA13, 0xCA13, 0xCA13}, {0xCA14, 0xCA14, 0xCA14}, {0xCA15, 0xCA15, 0xCA15}, {0xCA16, 0xCA16, 0xCA16}, {0xCA17, 0xCA17, 0xCA17}, {0xCA18, 0xCA18, 0xCA18}, {0xCA19, 0xCA19, 0xCA19}, {0xCA1A, 0xCA1A, 0xCA1A}, {0xCA1B, 0xCA1B, 0xCA1B}, {0xCA1C, 0xCA1C, 0xCA1C}, {0xCA1D, 0xCA1D, 0xCA1D}, {0xCA1E, 0xCA1E, 0xCA1E}, {0xCA1F, 0xCA1F, 0xCA1F}, {0xCA20, 0xCA20, 0xCA20}, {0xCA21, 0xCA21, 0xCA21}, {0xCA22, 0xCA22, 0xCA22}, {0xCA23, 0xCA23, 0xCA23}, {0xCA24, 0xCA24, 0xCA24}, {0xCA25, 0xCA25, 0xCA25}, {0xCA26, 0xCA26, 0xCA26}, {0xCA27, 0xCA27, 0xCA27}, {0xCA28, 0xCA28, 0xCA28}, {0xCA29, 0xCA29, 0xCA29}, {0xCA2A, 0xCA2A, 0xCA2A}, {0xCA2B, 0xCA2B, 0xCA2B}, {0xCA2C, 0xCA2C, 0xCA2C}, {0xCA2D, 0xCA2D, 0xCA2D}, {0xCA2E, 0xCA2E, 0xCA2E}, {0xCA2F, 0xCA2F, 0xCA2F}, {0xCA30, 0xCA30, 0xCA30}, {0xCA31, 0xCA31, 0xCA31}, {0xCA32, 0xCA32, 0xCA32}, {0xCA33, 0xCA33, 0xCA33}, {0xCA34, 0xCA34, 0xCA34}, {0xCA35, 0xCA35, 0xCA35}, {0xCA36, 0xCA36, 0xCA36}, {0xCA37, 0xCA37, 0xCA37}, {0xCA38, 0xCA38, 0xCA38}, {0xCA39, 0xCA39, 0xCA39}, {0xCA3A, 0xCA3A, 0xCA3A}, {0xCA3B, 0xCA3B, 0xCA3B}, {0xCA3C, 0xCA3C, 0xCA3C}, {0xCA3D, 0xCA3D, 0xCA3D}, {0xCA3E, 0xCA3E, 0xCA3E}, {0xCA3F, 0xCA3F, 0xCA3F}, {0xCA40, 0xCA40, 0xCA40}, {0xCA41, 0xCA41, 0xCA41}, {0xCA42, 0xCA42, 0xCA42}, {0xCA43, 0xCA43, 0xCA43}, {0xCA44, 0xCA44, 0xCA44}, {0xCA45, 0xCA45, 0xCA45}, {0xCA46, 0xCA46, 0xCA46}, {0xCA47, 0xCA47, 0xCA47}, {0xCA48, 0xCA48, 0xCA48}, {0xCA49, 0xCA49, 0xCA49}, {0xCA4A, 0xCA4A, 0xCA4A}, {0xCA4B, 0xCA4B, 0xCA4B}, {0xCA4C, 0xCA4C, 0xCA4C}, {0xCA4D, 0xCA4D, 0xCA4D}, {0xCA4E, 0xCA4E, 0xCA4E}, {0xCA4F, 0xCA4F, 0xCA4F}, {0xCA50, 0xCA50, 0xCA50}, {0xCA51, 0xCA51, 0xCA51}, {0xCA52, 0xCA52, 0xCA52}, {0xCA53, 0xCA53, 0xCA53}, {0xCA54, 0xCA54, 0xCA54}, {0xCA55, 0xCA55, 0xCA55}, {0xCA56, 0xCA56, 0xCA56}, {0xCA57, 0xCA57, 0xCA57}, {0xCA58, 0xCA58, 0xCA58}, {0xCA59, 0xCA59, 0xCA59}, {0xCA5A, 0xCA5A, 0xCA5A}, {0xCA5B, 0xCA5B, 0xCA5B}, {0xCA5C, 0xCA5C, 0xCA5C}, {0xCA5D, 0xCA5D, 0xCA5D}, {0xCA5E, 0xCA5E, 0xCA5E}, {0xCA5F, 0xCA5F, 0xCA5F}, {0xCA60, 0xCA60, 0xCA60}, {0xCA61, 0xCA61, 0xCA61}, {0xCA62, 0xCA62, 0xCA62}, {0xCA63, 0xCA63, 0xCA63}, {0xCA64, 0xCA64, 0xCA64}, {0xCA65, 0xCA65, 0xCA65}, {0xCA66, 0xCA66, 0xCA66}, {0xCA67, 0xCA67, 0xCA67}, {0xCA68, 0xCA68, 0xCA68}, {0xCA69, 0xCA69, 0xCA69}, {0xCA6A, 0xCA6A, 0xCA6A}, {0xCA6B, 0xCA6B, 0xCA6B}, {0xCA6C, 0xCA6C, 0xCA6C}, {0xCA6D, 0xCA6D, 0xCA6D}, {0xCA6E, 0xCA6E, 0xCA6E}, {0xCA6F, 0xCA6F, 0xCA6F}, {0xCA70, 0xCA70, 0xCA70}, {0xCA71, 0xCA71, 0xCA71}, {0xCA72, 0xCA72, 0xCA72}, {0xCA73, 0xCA73, 0xCA73}, {0xCA74, 0xCA74, 0xCA74}, {0xCA75, 0xCA75, 0xCA75}, {0xCA76, 0xCA76, 0xCA76}, {0xCA77, 0xCA77, 0xCA77}, {0xCA78, 0xCA78, 0xCA78}, {0xCA79, 0xCA79, 0xCA79}, {0xCA7A, 0xCA7A, 0xCA7A}, {0xCA7B, 0xCA7B, 0xCA7B}, {0xCA7C, 0xCA7C, 0xCA7C}, {0xCA7D, 0xCA7D, 0xCA7D}, {0xCA7E, 0xCA7E, 0xCA7E}, {0xCA7F, 0xCA7F, 0xCA7F}, {0xCA80, 0xCA80, 0xCA80}, {0xCA81, 0xCA81, 0xCA81}, {0xCA82, 0xCA82, 0xCA82}, {0xCA83, 0xCA83, 0xCA83}, {0xCA84, 0xCA84, 0xCA84}, {0xCA85, 0xCA85, 0xCA85}, {0xCA86, 0xCA86, 0xCA86}, {0xCA87, 0xCA87, 0xCA87}, {0xCA88, 0xCA88, 0xCA88}, {0xCA89, 0xCA89, 0xCA89}, {0xCA8A, 0xCA8A, 0xCA8A}, {0xCA8B, 0xCA8B, 0xCA8B}, {0xCA8C, 0xCA8C, 0xCA8C}, {0xCA8D, 0xCA8D, 0xCA8D}, {0xCA8E, 0xCA8E, 0xCA8E}, {0xCA8F, 0xCA8F, 0xCA8F}, {0xCA90, 0xCA90, 0xCA90}, {0xCA91, 0xCA91, 0xCA91}, {0xCA92, 0xCA92, 0xCA92}, {0xCA93, 0xCA93, 0xCA93}, {0xCA94, 0xCA94, 0xCA94}, {0xCA95, 0xCA95, 0xCA95}, {0xCA96, 0xCA96, 0xCA96}, {0xCA97, 0xCA97, 0xCA97}, {0xCA98, 0xCA98, 0xCA98}, {0xCA99, 0xCA99, 0xCA99}, {0xCA9A, 0xCA9A, 0xCA9A}, {0xCA9B, 0xCA9B, 0xCA9B}, {0xCA9C, 0xCA9C, 0xCA9C}, {0xCA9D, 0xCA9D, 0xCA9D}, {0xCA9E, 0xCA9E, 0xCA9E}, {0xCA9F, 0xCA9F, 0xCA9F}, {0xCAA0, 0xCAA0, 0xCAA0}, {0xCAA1, 0xCAA1, 0xCAA1}, {0xCAA2, 0xCAA2, 0xCAA2}, {0xCAA3, 0xCAA3, 0xCAA3}, {0xCAA4, 0xCAA4, 0xCAA4}, {0xCAA5, 0xCAA5, 0xCAA5}, {0xCAA6, 0xCAA6, 0xCAA6}, {0xCAA7, 0xCAA7, 0xCAA7}, {0xCAA8, 0xCAA8, 0xCAA8}, {0xCAA9, 0xCAA9, 0xCAA9}, {0xCAAA, 0xCAAA, 0xCAAA}, {0xCAAB, 0xCAAB, 0xCAAB}, {0xCAAC, 0xCAAC, 0xCAAC}, {0xCAAD, 0xCAAD, 0xCAAD}, {0xCAAE, 0xCAAE, 0xCAAE}, {0xCAAF, 0xCAAF, 0xCAAF}, {0xCAB0, 0xCAB0, 0xCAB0}, {0xCAB1, 0xCAB1, 0xCAB1}, {0xCAB2, 0xCAB2, 0xCAB2}, {0xCAB3, 0xCAB3, 0xCAB3}, {0xCAB4, 0xCAB4, 0xCAB4}, {0xCAB5, 0xCAB5, 0xCAB5}, {0xCAB6, 0xCAB6, 0xCAB6}, {0xCAB7, 0xCAB7, 0xCAB7}, {0xCAB8, 0xCAB8, 0xCAB8}, {0xCAB9, 0xCAB9, 0xCAB9}, {0xCABA, 0xCABA, 0xCABA}, {0xCABB, 0xCABB, 0xCABB}, {0xCABC, 0xCABC, 0xCABC}, {0xCABD, 0xCABD, 0xCABD}, {0xCABE, 0xCABE, 0xCABE}, {0xCABF, 0xCABF, 0xCABF}, {0xCAC0, 0xCAC0, 0xCAC0}, {0xCAC1, 0xCAC1, 0xCAC1}, {0xCAC2, 0xCAC2, 0xCAC2}, {0xCAC3, 0xCAC3, 0xCAC3}, {0xCAC4, 0xCAC4, 0xCAC4}, {0xCAC5, 0xCAC5, 0xCAC5}, {0xCAC6, 0xCAC6, 0xCAC6}, {0xCAC7, 0xCAC7, 0xCAC7}, {0xCAC8, 0xCAC8, 0xCAC8}, {0xCAC9, 0xCAC9, 0xCAC9}, {0xCACA, 0xCACA, 0xCACA}, {0xCACB, 0xCACB, 0xCACB}, {0xCACC, 0xCACC, 0xCACC}, {0xCACD, 0xCACD, 0xCACD}, {0xCACE, 0xCACE, 0xCACE}, {0xCACF, 0xCACF, 0xCACF}, {0xCAD0, 0xCAD0, 0xCAD0}, {0xCAD1, 0xCAD1, 0xCAD1}, {0xCAD2, 0xCAD2, 0xCAD2}, {0xCAD3, 0xCAD3, 0xCAD3}, {0xCAD4, 0xCAD4, 0xCAD4}, {0xCAD5, 0xCAD5, 0xCAD5}, {0xCAD6, 0xCAD6, 0xCAD6}, {0xCAD7, 0xCAD7, 0xCAD7}, {0xCAD8, 0xCAD8, 0xCAD8}, {0xCAD9, 0xCAD9, 0xCAD9}, {0xCADA, 0xCADA, 0xCADA}, {0xCADB, 0xCADB, 0xCADB}, {0xCADC, 0xCADC, 0xCADC}, {0xCADD, 0xCADD, 0xCADD}, {0xCADE, 0xCADE, 0xCADE}, {0xCADF, 0xCADF, 0xCADF}, {0xCAE0, 0xCAE0, 0xCAE0}, {0xCAE1, 0xCAE1, 0xCAE1}, {0xCAE2, 0xCAE2, 0xCAE2}, {0xCAE3, 0xCAE3, 0xCAE3}, {0xCAE4, 0xCAE4, 0xCAE4}, {0xCAE5, 0xCAE5, 0xCAE5}, {0xCAE6, 0xCAE6, 0xCAE6}, {0xCAE7, 0xCAE7, 0xCAE7}, {0xCAE8, 0xCAE8, 0xCAE8}, {0xCAE9, 0xCAE9, 0xCAE9}, {0xCAEA, 0xCAEA, 0xCAEA}, {0xCAEB, 0xCAEB, 0xCAEB}, {0xCAEC, 0xCAEC, 0xCAEC}, {0xCAED, 0xCAED, 0xCAED}, {0xCAEE, 0xCAEE, 0xCAEE}, {0xCAEF, 0xCAEF, 0xCAEF}, {0xCAF0, 0xCAF0, 0xCAF0}, {0xCAF1, 0xCAF1, 0xCAF1}, {0xCAF2, 0xCAF2, 0xCAF2}, {0xCAF3, 0xCAF3, 0xCAF3}, {0xCAF4, 0xCAF4, 0xCAF4}, {0xCAF5, 0xCAF5, 0xCAF5}, {0xCAF6, 0xCAF6, 0xCAF6}, {0xCAF7, 0xCAF7, 0xCAF7}, {0xCAF8, 0xCAF8, 0xCAF8}, {0xCAF9, 0xCAF9, 0xCAF9}, {0xCAFA, 0xCAFA, 0xCAFA}, {0xCAFB, 0xCAFB, 0xCAFB}, {0xCAFC, 0xCAFC, 0xCAFC}, {0xCAFD, 0xCAFD, 0xCAFD}, {0xCAFE, 0xCAFE, 0xCAFE}, {0xCAFF, 0xCAFF, 0xCAFF}, {0xCB00, 0xCB00, 0xCB00}, {0xCB01, 0xCB01, 0xCB01}, {0xCB02, 0xCB02, 0xCB02}, {0xCB03, 0xCB03, 0xCB03}, {0xCB04, 0xCB04, 0xCB04}, {0xCB05, 0xCB05, 0xCB05}, {0xCB06, 0xCB06, 0xCB06}, {0xCB07, 0xCB07, 0xCB07}, {0xCB08, 0xCB08, 0xCB08}, {0xCB09, 0xCB09, 0xCB09}, {0xCB0A, 0xCB0A, 0xCB0A}, {0xCB0B, 0xCB0B, 0xCB0B}, {0xCB0C, 0xCB0C, 0xCB0C}, {0xCB0D, 0xCB0D, 0xCB0D}, {0xCB0E, 0xCB0E, 0xCB0E}, {0xCB0F, 0xCB0F, 0xCB0F}, {0xCB10, 0xCB10, 0xCB10}, {0xCB11, 0xCB11, 0xCB11}, {0xCB12, 0xCB12, 0xCB12}, {0xCB13, 0xCB13, 0xCB13}, {0xCB14, 0xCB14, 0xCB14}, {0xCB15, 0xCB15, 0xCB15}, {0xCB16, 0xCB16, 0xCB16}, {0xCB17, 0xCB17, 0xCB17}, {0xCB18, 0xCB18, 0xCB18}, {0xCB19, 0xCB19, 0xCB19}, {0xCB1A, 0xCB1A, 0xCB1A}, {0xCB1B, 0xCB1B, 0xCB1B}, {0xCB1C, 0xCB1C, 0xCB1C}, {0xCB1D, 0xCB1D, 0xCB1D}, {0xCB1E, 0xCB1E, 0xCB1E}, {0xCB1F, 0xCB1F, 0xCB1F}, {0xCB20, 0xCB20, 0xCB20}, {0xCB21, 0xCB21, 0xCB21}, {0xCB22, 0xCB22, 0xCB22}, {0xCB23, 0xCB23, 0xCB23}, {0xCB24, 0xCB24, 0xCB24}, {0xCB25, 0xCB25, 0xCB25}, {0xCB26, 0xCB26, 0xCB26}, {0xCB27, 0xCB27, 0xCB27}, {0xCB28, 0xCB28, 0xCB28}, {0xCB29, 0xCB29, 0xCB29}, {0xCB2A, 0xCB2A, 0xCB2A}, {0xCB2B, 0xCB2B, 0xCB2B}, {0xCB2C, 0xCB2C, 0xCB2C}, {0xCB2D, 0xCB2D, 0xCB2D}, {0xCB2E, 0xCB2E, 0xCB2E}, {0xCB2F, 0xCB2F, 0xCB2F}, {0xCB30, 0xCB30, 0xCB30}, {0xCB31, 0xCB31, 0xCB31}, {0xCB32, 0xCB32, 0xCB32}, {0xCB33, 0xCB33, 0xCB33}, {0xCB34, 0xCB34, 0xCB34}, {0xCB35, 0xCB35, 0xCB35}, {0xCB36, 0xCB36, 0xCB36}, {0xCB37, 0xCB37, 0xCB37}, {0xCB38, 0xCB38, 0xCB38}, {0xCB39, 0xCB39, 0xCB39}, {0xCB3A, 0xCB3A, 0xCB3A}, {0xCB3B, 0xCB3B, 0xCB3B}, {0xCB3C, 0xCB3C, 0xCB3C}, {0xCB3D, 0xCB3D, 0xCB3D}, {0xCB3E, 0xCB3E, 0xCB3E}, {0xCB3F, 0xCB3F, 0xCB3F}, {0xCB40, 0xCB40, 0xCB40}, {0xCB41, 0xCB41, 0xCB41}, {0xCB42, 0xCB42, 0xCB42}, {0xCB43, 0xCB43, 0xCB43}, {0xCB44, 0xCB44, 0xCB44}, {0xCB45, 0xCB45, 0xCB45}, {0xCB46, 0xCB46, 0xCB46}, {0xCB47, 0xCB47, 0xCB47}, {0xCB48, 0xCB48, 0xCB48}, {0xCB49, 0xCB49, 0xCB49}, {0xCB4A, 0xCB4A, 0xCB4A}, {0xCB4B, 0xCB4B, 0xCB4B}, {0xCB4C, 0xCB4C, 0xCB4C}, {0xCB4D, 0xCB4D, 0xCB4D}, {0xCB4E, 0xCB4E, 0xCB4E}, {0xCB4F, 0xCB4F, 0xCB4F}, {0xCB50, 0xCB50, 0xCB50}, {0xCB51, 0xCB51, 0xCB51}, {0xCB52, 0xCB52, 0xCB52}, {0xCB53, 0xCB53, 0xCB53}, {0xCB54, 0xCB54, 0xCB54}, {0xCB55, 0xCB55, 0xCB55}, {0xCB56, 0xCB56, 0xCB56}, {0xCB57, 0xCB57, 0xCB57}, {0xCB58, 0xCB58, 0xCB58}, {0xCB59, 0xCB59, 0xCB59}, {0xCB5A, 0xCB5A, 0xCB5A}, {0xCB5B, 0xCB5B, 0xCB5B}, {0xCB5C, 0xCB5C, 0xCB5C}, {0xCB5D, 0xCB5D, 0xCB5D}, {0xCB5E, 0xCB5E, 0xCB5E}, {0xCB5F, 0xCB5F, 0xCB5F}, {0xCB60, 0xCB60, 0xCB60}, {0xCB61, 0xCB61, 0xCB61}, {0xCB62, 0xCB62, 0xCB62}, {0xCB63, 0xCB63, 0xCB63}, {0xCB64, 0xCB64, 0xCB64}, {0xCB65, 0xCB65, 0xCB65}, {0xCB66, 0xCB66, 0xCB66}, {0xCB67, 0xCB67, 0xCB67}, {0xCB68, 0xCB68, 0xCB68}, {0xCB69, 0xCB69, 0xCB69}, {0xCB6A, 0xCB6A, 0xCB6A}, {0xCB6B, 0xCB6B, 0xCB6B}, {0xCB6C, 0xCB6C, 0xCB6C}, {0xCB6D, 0xCB6D, 0xCB6D}, {0xCB6E, 0xCB6E, 0xCB6E}, {0xCB6F, 0xCB6F, 0xCB6F}, {0xCB70, 0xCB70, 0xCB70}, {0xCB71, 0xCB71, 0xCB71}, {0xCB72, 0xCB72, 0xCB72}, {0xCB73, 0xCB73, 0xCB73}, {0xCB74, 0xCB74, 0xCB74}, {0xCB75, 0xCB75, 0xCB75}, {0xCB76, 0xCB76, 0xCB76}, {0xCB77, 0xCB77, 0xCB77}, {0xCB78, 0xCB78, 0xCB78}, {0xCB79, 0xCB79, 0xCB79}, {0xCB7A, 0xCB7A, 0xCB7A}, {0xCB7B, 0xCB7B, 0xCB7B}, {0xCB7C, 0xCB7C, 0xCB7C}, {0xCB7D, 0xCB7D, 0xCB7D}, {0xCB7E, 0xCB7E, 0xCB7E}, {0xCB7F, 0xCB7F, 0xCB7F}, {0xCB80, 0xCB80, 0xCB80}, {0xCB81, 0xCB81, 0xCB81}, {0xCB82, 0xCB82, 0xCB82}, {0xCB83, 0xCB83, 0xCB83}, {0xCB84, 0xCB84, 0xCB84}, {0xCB85, 0xCB85, 0xCB85}, {0xCB86, 0xCB86, 0xCB86}, {0xCB87, 0xCB87, 0xCB87}, {0xCB88, 0xCB88, 0xCB88}, {0xCB89, 0xCB89, 0xCB89}, {0xCB8A, 0xCB8A, 0xCB8A}, {0xCB8B, 0xCB8B, 0xCB8B}, {0xCB8C, 0xCB8C, 0xCB8C}, {0xCB8D, 0xCB8D, 0xCB8D}, {0xCB8E, 0xCB8E, 0xCB8E}, {0xCB8F, 0xCB8F, 0xCB8F}, {0xCB90, 0xCB90, 0xCB90}, {0xCB91, 0xCB91, 0xCB91}, {0xCB92, 0xCB92, 0xCB92}, {0xCB93, 0xCB93, 0xCB93}, {0xCB94, 0xCB94, 0xCB94}, {0xCB95, 0xCB95, 0xCB95}, {0xCB96, 0xCB96, 0xCB96}, {0xCB97, 0xCB97, 0xCB97}, {0xCB98, 0xCB98, 0xCB98}, {0xCB99, 0xCB99, 0xCB99}, {0xCB9A, 0xCB9A, 0xCB9A}, {0xCB9B, 0xCB9B, 0xCB9B}, {0xCB9C, 0xCB9C, 0xCB9C}, {0xCB9D, 0xCB9D, 0xCB9D}, {0xCB9E, 0xCB9E, 0xCB9E}, {0xCB9F, 0xCB9F, 0xCB9F}, {0xCBA0, 0xCBA0, 0xCBA0}, {0xCBA1, 0xCBA1, 0xCBA1}, {0xCBA2, 0xCBA2, 0xCBA2}, {0xCBA3, 0xCBA3, 0xCBA3}, {0xCBA4, 0xCBA4, 0xCBA4}, {0xCBA5, 0xCBA5, 0xCBA5}, {0xCBA6, 0xCBA6, 0xCBA6}, {0xCBA7, 0xCBA7, 0xCBA7}, {0xCBA8, 0xCBA8, 0xCBA8}, {0xCBA9, 0xCBA9, 0xCBA9}, {0xCBAA, 0xCBAA, 0xCBAA}, {0xCBAB, 0xCBAB, 0xCBAB}, {0xCBAC, 0xCBAC, 0xCBAC}, {0xCBAD, 0xCBAD, 0xCBAD}, {0xCBAE, 0xCBAE, 0xCBAE}, {0xCBAF, 0xCBAF, 0xCBAF}, {0xCBB0, 0xCBB0, 0xCBB0}, {0xCBB1, 0xCBB1, 0xCBB1}, {0xCBB2, 0xCBB2, 0xCBB2}, {0xCBB3, 0xCBB3, 0xCBB3}, {0xCBB4, 0xCBB4, 0xCBB4}, {0xCBB5, 0xCBB5, 0xCBB5}, {0xCBB6, 0xCBB6, 0xCBB6}, {0xCBB7, 0xCBB7, 0xCBB7}, {0xCBB8, 0xCBB8, 0xCBB8}, {0xCBB9, 0xCBB9, 0xCBB9}, {0xCBBA, 0xCBBA, 0xCBBA}, {0xCBBB, 0xCBBB, 0xCBBB}, {0xCBBC, 0xCBBC, 0xCBBC}, {0xCBBD, 0xCBBD, 0xCBBD}, {0xCBBE, 0xCBBE, 0xCBBE}, {0xCBBF, 0xCBBF, 0xCBBF}, {0xCBC0, 0xCBC0, 0xCBC0}, {0xCBC1, 0xCBC1, 0xCBC1}, {0xCBC2, 0xCBC2, 0xCBC2}, {0xCBC3, 0xCBC3, 0xCBC3}, {0xCBC4, 0xCBC4, 0xCBC4}, {0xCBC5, 0xCBC5, 0xCBC5}, {0xCBC6, 0xCBC6, 0xCBC6}, {0xCBC7, 0xCBC7, 0xCBC7}, {0xCBC8, 0xCBC8, 0xCBC8}, {0xCBC9, 0xCBC9, 0xCBC9}, {0xCBCA, 0xCBCA, 0xCBCA}, {0xCBCB, 0xCBCB, 0xCBCB}, {0xCBCC, 0xCBCC, 0xCBCC}, {0xCBCD, 0xCBCD, 0xCBCD}, {0xCBCE, 0xCBCE, 0xCBCE}, {0xCBCF, 0xCBCF, 0xCBCF}, {0xCBD0, 0xCBD0, 0xCBD0}, {0xCBD1, 0xCBD1, 0xCBD1}, {0xCBD2, 0xCBD2, 0xCBD2}, {0xCBD3, 0xCBD3, 0xCBD3}, {0xCBD4, 0xCBD4, 0xCBD4}, {0xCBD5, 0xCBD5, 0xCBD5}, {0xCBD6, 0xCBD6, 0xCBD6}, {0xCBD7, 0xCBD7, 0xCBD7}, {0xCBD8, 0xCBD8, 0xCBD8}, {0xCBD9, 0xCBD9, 0xCBD9}, {0xCBDA, 0xCBDA, 0xCBDA}, {0xCBDB, 0xCBDB, 0xCBDB}, {0xCBDC, 0xCBDC, 0xCBDC}, {0xCBDD, 0xCBDD, 0xCBDD}, {0xCBDE, 0xCBDE, 0xCBDE}, {0xCBDF, 0xCBDF, 0xCBDF}, {0xCBE0, 0xCBE0, 0xCBE0}, {0xCBE1, 0xCBE1, 0xCBE1}, {0xCBE2, 0xCBE2, 0xCBE2}, {0xCBE3, 0xCBE3, 0xCBE3}, {0xCBE4, 0xCBE4, 0xCBE4}, {0xCBE5, 0xCBE5, 0xCBE5}, {0xCBE6, 0xCBE6, 0xCBE6}, {0xCBE7, 0xCBE7, 0xCBE7}, {0xCBE8, 0xCBE8, 0xCBE8}, {0xCBE9, 0xCBE9, 0xCBE9}, {0xCBEA, 0xCBEA, 0xCBEA}, {0xCBEB, 0xCBEB, 0xCBEB}, {0xCBEC, 0xCBEC, 0xCBEC}, {0xCBED, 0xCBED, 0xCBED}, {0xCBEE, 0xCBEE, 0xCBEE}, {0xCBEF, 0xCBEF, 0xCBEF}, {0xCBF0, 0xCBF0, 0xCBF0}, {0xCBF1, 0xCBF1, 0xCBF1}, {0xCBF2, 0xCBF2, 0xCBF2}, {0xCBF3, 0xCBF3, 0xCBF3}, {0xCBF4, 0xCBF4, 0xCBF4}, {0xCBF5, 0xCBF5, 0xCBF5}, {0xCBF6, 0xCBF6, 0xCBF6}, {0xCBF7, 0xCBF7, 0xCBF7}, {0xCBF8, 0xCBF8, 0xCBF8}, {0xCBF9, 0xCBF9, 0xCBF9}, {0xCBFA, 0xCBFA, 0xCBFA}, {0xCBFB, 0xCBFB, 0xCBFB}, {0xCBFC, 0xCBFC, 0xCBFC}, {0xCBFD, 0xCBFD, 0xCBFD}, {0xCBFE, 0xCBFE, 0xCBFE}, {0xCBFF, 0xCBFF, 0xCBFF}, {0xCC00, 0xCC00, 0xCC00}, {0xCC01, 0xCC01, 0xCC01}, {0xCC02, 0xCC02, 0xCC02}, {0xCC03, 0xCC03, 0xCC03}, {0xCC04, 0xCC04, 0xCC04}, {0xCC05, 0xCC05, 0xCC05}, {0xCC06, 0xCC06, 0xCC06}, {0xCC07, 0xCC07, 0xCC07}, {0xCC08, 0xCC08, 0xCC08}, {0xCC09, 0xCC09, 0xCC09}, {0xCC0A, 0xCC0A, 0xCC0A}, {0xCC0B, 0xCC0B, 0xCC0B}, {0xCC0C, 0xCC0C, 0xCC0C}, {0xCC0D, 0xCC0D, 0xCC0D}, {0xCC0E, 0xCC0E, 0xCC0E}, {0xCC0F, 0xCC0F, 0xCC0F}, {0xCC10, 0xCC10, 0xCC10}, {0xCC11, 0xCC11, 0xCC11}, {0xCC12, 0xCC12, 0xCC12}, {0xCC13, 0xCC13, 0xCC13}, {0xCC14, 0xCC14, 0xCC14}, {0xCC15, 0xCC15, 0xCC15}, {0xCC16, 0xCC16, 0xCC16}, {0xCC17, 0xCC17, 0xCC17}, {0xCC18, 0xCC18, 0xCC18}, {0xCC19, 0xCC19, 0xCC19}, {0xCC1A, 0xCC1A, 0xCC1A}, {0xCC1B, 0xCC1B, 0xCC1B}, {0xCC1C, 0xCC1C, 0xCC1C}, {0xCC1D, 0xCC1D, 0xCC1D}, {0xCC1E, 0xCC1E, 0xCC1E}, {0xCC1F, 0xCC1F, 0xCC1F}, {0xCC20, 0xCC20, 0xCC20}, {0xCC21, 0xCC21, 0xCC21}, {0xCC22, 0xCC22, 0xCC22}, {0xCC23, 0xCC23, 0xCC23}, {0xCC24, 0xCC24, 0xCC24}, {0xCC25, 0xCC25, 0xCC25}, {0xCC26, 0xCC26, 0xCC26}, {0xCC27, 0xCC27, 0xCC27}, {0xCC28, 0xCC28, 0xCC28}, {0xCC29, 0xCC29, 0xCC29}, {0xCC2A, 0xCC2A, 0xCC2A}, {0xCC2B, 0xCC2B, 0xCC2B}, {0xCC2C, 0xCC2C, 0xCC2C}, {0xCC2D, 0xCC2D, 0xCC2D}, {0xCC2E, 0xCC2E, 0xCC2E}, {0xCC2F, 0xCC2F, 0xCC2F}, {0xCC30, 0xCC30, 0xCC30}, {0xCC31, 0xCC31, 0xCC31}, {0xCC32, 0xCC32, 0xCC32}, {0xCC33, 0xCC33, 0xCC33}, {0xCC34, 0xCC34, 0xCC34}, {0xCC35, 0xCC35, 0xCC35}, {0xCC36, 0xCC36, 0xCC36}, {0xCC37, 0xCC37, 0xCC37}, {0xCC38, 0xCC38, 0xCC38}, {0xCC39, 0xCC39, 0xCC39}, {0xCC3A, 0xCC3A, 0xCC3A}, {0xCC3B, 0xCC3B, 0xCC3B}, {0xCC3C, 0xCC3C, 0xCC3C}, {0xCC3D, 0xCC3D, 0xCC3D}, {0xCC3E, 0xCC3E, 0xCC3E}, {0xCC3F, 0xCC3F, 0xCC3F}, {0xCC40, 0xCC40, 0xCC40}, {0xCC41, 0xCC41, 0xCC41}, {0xCC42, 0xCC42, 0xCC42}, {0xCC43, 0xCC43, 0xCC43}, {0xCC44, 0xCC44, 0xCC44}, {0xCC45, 0xCC45, 0xCC45}, {0xCC46, 0xCC46, 0xCC46}, {0xCC47, 0xCC47, 0xCC47}, {0xCC48, 0xCC48, 0xCC48}, {0xCC49, 0xCC49, 0xCC49}, {0xCC4A, 0xCC4A, 0xCC4A}, {0xCC4B, 0xCC4B, 0xCC4B}, {0xCC4C, 0xCC4C, 0xCC4C}, {0xCC4D, 0xCC4D, 0xCC4D}, {0xCC4E, 0xCC4E, 0xCC4E}, {0xCC4F, 0xCC4F, 0xCC4F}, {0xCC50, 0xCC50, 0xCC50}, {0xCC51, 0xCC51, 0xCC51}, {0xCC52, 0xCC52, 0xCC52}, {0xCC53, 0xCC53, 0xCC53}, {0xCC54, 0xCC54, 0xCC54}, {0xCC55, 0xCC55, 0xCC55}, {0xCC56, 0xCC56, 0xCC56}, {0xCC57, 0xCC57, 0xCC57}, {0xCC58, 0xCC58, 0xCC58}, {0xCC59, 0xCC59, 0xCC59}, {0xCC5A, 0xCC5A, 0xCC5A}, {0xCC5B, 0xCC5B, 0xCC5B}, {0xCC5C, 0xCC5C, 0xCC5C}, {0xCC5D, 0xCC5D, 0xCC5D}, {0xCC5E, 0xCC5E, 0xCC5E}, {0xCC5F, 0xCC5F, 0xCC5F}, {0xCC60, 0xCC60, 0xCC60}, {0xCC61, 0xCC61, 0xCC61}, {0xCC62, 0xCC62, 0xCC62}, {0xCC63, 0xCC63, 0xCC63}, {0xCC64, 0xCC64, 0xCC64}, {0xCC65, 0xCC65, 0xCC65}, {0xCC66, 0xCC66, 0xCC66}, {0xCC67, 0xCC67, 0xCC67}, {0xCC68, 0xCC68, 0xCC68}, {0xCC69, 0xCC69, 0xCC69}, {0xCC6A, 0xCC6A, 0xCC6A}, {0xCC6B, 0xCC6B, 0xCC6B}, {0xCC6C, 0xCC6C, 0xCC6C}, {0xCC6D, 0xCC6D, 0xCC6D}, {0xCC6E, 0xCC6E, 0xCC6E}, {0xCC6F, 0xCC6F, 0xCC6F}, {0xCC70, 0xCC70, 0xCC70}, {0xCC71, 0xCC71, 0xCC71}, {0xCC72, 0xCC72, 0xCC72}, {0xCC73, 0xCC73, 0xCC73}, {0xCC74, 0xCC74, 0xCC74}, {0xCC75, 0xCC75, 0xCC75}, {0xCC76, 0xCC76, 0xCC76}, {0xCC77, 0xCC77, 0xCC77}, {0xCC78, 0xCC78, 0xCC78}, {0xCC79, 0xCC79, 0xCC79}, {0xCC7A, 0xCC7A, 0xCC7A}, {0xCC7B, 0xCC7B, 0xCC7B}, {0xCC7C, 0xCC7C, 0xCC7C}, {0xCC7D, 0xCC7D, 0xCC7D}, {0xCC7E, 0xCC7E, 0xCC7E}, {0xCC7F, 0xCC7F, 0xCC7F}, {0xCC80, 0xCC80, 0xCC80}, {0xCC81, 0xCC81, 0xCC81}, {0xCC82, 0xCC82, 0xCC82}, {0xCC83, 0xCC83, 0xCC83}, {0xCC84, 0xCC84, 0xCC84}, {0xCC85, 0xCC85, 0xCC85}, {0xCC86, 0xCC86, 0xCC86}, {0xCC87, 0xCC87, 0xCC87}, {0xCC88, 0xCC88, 0xCC88}, {0xCC89, 0xCC89, 0xCC89}, {0xCC8A, 0xCC8A, 0xCC8A}, {0xCC8B, 0xCC8B, 0xCC8B}, {0xCC8C, 0xCC8C, 0xCC8C}, {0xCC8D, 0xCC8D, 0xCC8D}, {0xCC8E, 0xCC8E, 0xCC8E}, {0xCC8F, 0xCC8F, 0xCC8F}, {0xCC90, 0xCC90, 0xCC90}, {0xCC91, 0xCC91, 0xCC91}, {0xCC92, 0xCC92, 0xCC92}, {0xCC93, 0xCC93, 0xCC93}, {0xCC94, 0xCC94, 0xCC94}, {0xCC95, 0xCC95, 0xCC95}, {0xCC96, 0xCC96, 0xCC96}, {0xCC97, 0xCC97, 0xCC97}, {0xCC98, 0xCC98, 0xCC98}, {0xCC99, 0xCC99, 0xCC99}, {0xCC9A, 0xCC9A, 0xCC9A}, {0xCC9B, 0xCC9B, 0xCC9B}, {0xCC9C, 0xCC9C, 0xCC9C}, {0xCC9D, 0xCC9D, 0xCC9D}, {0xCC9E, 0xCC9E, 0xCC9E}, {0xCC9F, 0xCC9F, 0xCC9F}, {0xCCA0, 0xCCA0, 0xCCA0}, {0xCCA1, 0xCCA1, 0xCCA1}, {0xCCA2, 0xCCA2, 0xCCA2}, {0xCCA3, 0xCCA3, 0xCCA3}, {0xCCA4, 0xCCA4, 0xCCA4}, {0xCCA5, 0xCCA5, 0xCCA5}, {0xCCA6, 0xCCA6, 0xCCA6}, {0xCCA7, 0xCCA7, 0xCCA7}, {0xCCA8, 0xCCA8, 0xCCA8}, {0xCCA9, 0xCCA9, 0xCCA9}, {0xCCAA, 0xCCAA, 0xCCAA}, {0xCCAB, 0xCCAB, 0xCCAB}, {0xCCAC, 0xCCAC, 0xCCAC}, {0xCCAD, 0xCCAD, 0xCCAD}, {0xCCAE, 0xCCAE, 0xCCAE}, {0xCCAF, 0xCCAF, 0xCCAF}, {0xCCB0, 0xCCB0, 0xCCB0}, {0xCCB1, 0xCCB1, 0xCCB1}, {0xCCB2, 0xCCB2, 0xCCB2}, {0xCCB3, 0xCCB3, 0xCCB3}, {0xCCB4, 0xCCB4, 0xCCB4}, {0xCCB5, 0xCCB5, 0xCCB5}, {0xCCB6, 0xCCB6, 0xCCB6}, {0xCCB7, 0xCCB7, 0xCCB7}, {0xCCB8, 0xCCB8, 0xCCB8}, {0xCCB9, 0xCCB9, 0xCCB9}, {0xCCBA, 0xCCBA, 0xCCBA}, {0xCCBB, 0xCCBB, 0xCCBB}, {0xCCBC, 0xCCBC, 0xCCBC}, {0xCCBD, 0xCCBD, 0xCCBD}, {0xCCBE, 0xCCBE, 0xCCBE}, {0xCCBF, 0xCCBF, 0xCCBF}, {0xCCC0, 0xCCC0, 0xCCC0}, {0xCCC1, 0xCCC1, 0xCCC1}, {0xCCC2, 0xCCC2, 0xCCC2}, {0xCCC3, 0xCCC3, 0xCCC3}, {0xCCC4, 0xCCC4, 0xCCC4}, {0xCCC5, 0xCCC5, 0xCCC5}, {0xCCC6, 0xCCC6, 0xCCC6}, {0xCCC7, 0xCCC7, 0xCCC7}, {0xCCC8, 0xCCC8, 0xCCC8}, {0xCCC9, 0xCCC9, 0xCCC9}, {0xCCCA, 0xCCCA, 0xCCCA}, {0xCCCB, 0xCCCB, 0xCCCB}, {0xCCCC, 0xCCCC, 0xCCCC}, {0xCCCD, 0xCCCD, 0xCCCD}, {0xCCCE, 0xCCCE, 0xCCCE}, {0xCCCF, 0xCCCF, 0xCCCF}, {0xCCD0, 0xCCD0, 0xCCD0}, {0xCCD1, 0xCCD1, 0xCCD1}, {0xCCD2, 0xCCD2, 0xCCD2}, {0xCCD3, 0xCCD3, 0xCCD3}, {0xCCD4, 0xCCD4, 0xCCD4}, {0xCCD5, 0xCCD5, 0xCCD5}, {0xCCD6, 0xCCD6, 0xCCD6}, {0xCCD7, 0xCCD7, 0xCCD7}, {0xCCD8, 0xCCD8, 0xCCD8}, {0xCCD9, 0xCCD9, 0xCCD9}, {0xCCDA, 0xCCDA, 0xCCDA}, {0xCCDB, 0xCCDB, 0xCCDB}, {0xCCDC, 0xCCDC, 0xCCDC}, {0xCCDD, 0xCCDD, 0xCCDD}, {0xCCDE, 0xCCDE, 0xCCDE}, {0xCCDF, 0xCCDF, 0xCCDF}, {0xCCE0, 0xCCE0, 0xCCE0}, {0xCCE1, 0xCCE1, 0xCCE1}, {0xCCE2, 0xCCE2, 0xCCE2}, {0xCCE3, 0xCCE3, 0xCCE3}, {0xCCE4, 0xCCE4, 0xCCE4}, {0xCCE5, 0xCCE5, 0xCCE5}, {0xCCE6, 0xCCE6, 0xCCE6}, {0xCCE7, 0xCCE7, 0xCCE7}, {0xCCE8, 0xCCE8, 0xCCE8}, {0xCCE9, 0xCCE9, 0xCCE9}, {0xCCEA, 0xCCEA, 0xCCEA}, {0xCCEB, 0xCCEB, 0xCCEB}, {0xCCEC, 0xCCEC, 0xCCEC}, {0xCCED, 0xCCED, 0xCCED}, {0xCCEE, 0xCCEE, 0xCCEE}, {0xCCEF, 0xCCEF, 0xCCEF}, {0xCCF0, 0xCCF0, 0xCCF0}, {0xCCF1, 0xCCF1, 0xCCF1}, {0xCCF2, 0xCCF2, 0xCCF2}, {0xCCF3, 0xCCF3, 0xCCF3}, {0xCCF4, 0xCCF4, 0xCCF4}, {0xCCF5, 0xCCF5, 0xCCF5}, {0xCCF6, 0xCCF6, 0xCCF6}, {0xCCF7, 0xCCF7, 0xCCF7}, {0xCCF8, 0xCCF8, 0xCCF8}, {0xCCF9, 0xCCF9, 0xCCF9}, {0xCCFA, 0xCCFA, 0xCCFA}, {0xCCFB, 0xCCFB, 0xCCFB}, {0xCCFC, 0xCCFC, 0xCCFC}, {0xCCFD, 0xCCFD, 0xCCFD}, {0xCCFE, 0xCCFE, 0xCCFE}, {0xCCFF, 0xCCFF, 0xCCFF}, {0xCD00, 0xCD00, 0xCD00}, {0xCD01, 0xCD01, 0xCD01}, {0xCD02, 0xCD02, 0xCD02}, {0xCD03, 0xCD03, 0xCD03}, {0xCD04, 0xCD04, 0xCD04}, {0xCD05, 0xCD05, 0xCD05}, {0xCD06, 0xCD06, 0xCD06}, {0xCD07, 0xCD07, 0xCD07}, {0xCD08, 0xCD08, 0xCD08}, {0xCD09, 0xCD09, 0xCD09}, {0xCD0A, 0xCD0A, 0xCD0A}, {0xCD0B, 0xCD0B, 0xCD0B}, {0xCD0C, 0xCD0C, 0xCD0C}, {0xCD0D, 0xCD0D, 0xCD0D}, {0xCD0E, 0xCD0E, 0xCD0E}, {0xCD0F, 0xCD0F, 0xCD0F}, {0xCD10, 0xCD10, 0xCD10}, {0xCD11, 0xCD11, 0xCD11}, {0xCD12, 0xCD12, 0xCD12}, {0xCD13, 0xCD13, 0xCD13}, {0xCD14, 0xCD14, 0xCD14}, {0xCD15, 0xCD15, 0xCD15}, {0xCD16, 0xCD16, 0xCD16}, {0xCD17, 0xCD17, 0xCD17}, {0xCD18, 0xCD18, 0xCD18}, {0xCD19, 0xCD19, 0xCD19}, {0xCD1A, 0xCD1A, 0xCD1A}, {0xCD1B, 0xCD1B, 0xCD1B}, {0xCD1C, 0xCD1C, 0xCD1C}, {0xCD1D, 0xCD1D, 0xCD1D}, {0xCD1E, 0xCD1E, 0xCD1E}, {0xCD1F, 0xCD1F, 0xCD1F}, {0xCD20, 0xCD20, 0xCD20}, {0xCD21, 0xCD21, 0xCD21}, {0xCD22, 0xCD22, 0xCD22}, {0xCD23, 0xCD23, 0xCD23}, {0xCD24, 0xCD24, 0xCD24}, {0xCD25, 0xCD25, 0xCD25}, {0xCD26, 0xCD26, 0xCD26}, {0xCD27, 0xCD27, 0xCD27}, {0xCD28, 0xCD28, 0xCD28}, {0xCD29, 0xCD29, 0xCD29}, {0xCD2A, 0xCD2A, 0xCD2A}, {0xCD2B, 0xCD2B, 0xCD2B}, {0xCD2C, 0xCD2C, 0xCD2C}, {0xCD2D, 0xCD2D, 0xCD2D}, {0xCD2E, 0xCD2E, 0xCD2E}, {0xCD2F, 0xCD2F, 0xCD2F}, {0xCD30, 0xCD30, 0xCD30}, {0xCD31, 0xCD31, 0xCD31}, {0xCD32, 0xCD32, 0xCD32}, {0xCD33, 0xCD33, 0xCD33}, {0xCD34, 0xCD34, 0xCD34}, {0xCD35, 0xCD35, 0xCD35}, {0xCD36, 0xCD36, 0xCD36}, {0xCD37, 0xCD37, 0xCD37}, {0xCD38, 0xCD38, 0xCD38}, {0xCD39, 0xCD39, 0xCD39}, {0xCD3A, 0xCD3A, 0xCD3A}, {0xCD3B, 0xCD3B, 0xCD3B}, {0xCD3C, 0xCD3C, 0xCD3C}, {0xCD3D, 0xCD3D, 0xCD3D}, {0xCD3E, 0xCD3E, 0xCD3E}, {0xCD3F, 0xCD3F, 0xCD3F}, {0xCD40, 0xCD40, 0xCD40}, {0xCD41, 0xCD41, 0xCD41}, {0xCD42, 0xCD42, 0xCD42}, {0xCD43, 0xCD43, 0xCD43}, {0xCD44, 0xCD44, 0xCD44}, {0xCD45, 0xCD45, 0xCD45}, {0xCD46, 0xCD46, 0xCD46}, {0xCD47, 0xCD47, 0xCD47}, {0xCD48, 0xCD48, 0xCD48}, {0xCD49, 0xCD49, 0xCD49}, {0xCD4A, 0xCD4A, 0xCD4A}, {0xCD4B, 0xCD4B, 0xCD4B}, {0xCD4C, 0xCD4C, 0xCD4C}, {0xCD4D, 0xCD4D, 0xCD4D}, {0xCD4E, 0xCD4E, 0xCD4E}, {0xCD4F, 0xCD4F, 0xCD4F}, {0xCD50, 0xCD50, 0xCD50}, {0xCD51, 0xCD51, 0xCD51}, {0xCD52, 0xCD52, 0xCD52}, {0xCD53, 0xCD53, 0xCD53}, {0xCD54, 0xCD54, 0xCD54}, {0xCD55, 0xCD55, 0xCD55}, {0xCD56, 0xCD56, 0xCD56}, {0xCD57, 0xCD57, 0xCD57}, {0xCD58, 0xCD58, 0xCD58}, {0xCD59, 0xCD59, 0xCD59}, {0xCD5A, 0xCD5A, 0xCD5A}, {0xCD5B, 0xCD5B, 0xCD5B}, {0xCD5C, 0xCD5C, 0xCD5C}, {0xCD5D, 0xCD5D, 0xCD5D}, {0xCD5E, 0xCD5E, 0xCD5E}, {0xCD5F, 0xCD5F, 0xCD5F}, {0xCD60, 0xCD60, 0xCD60}, {0xCD61, 0xCD61, 0xCD61}, {0xCD62, 0xCD62, 0xCD62}, {0xCD63, 0xCD63, 0xCD63}, {0xCD64, 0xCD64, 0xCD64}, {0xCD65, 0xCD65, 0xCD65}, {0xCD66, 0xCD66, 0xCD66}, {0xCD67, 0xCD67, 0xCD67}, {0xCD68, 0xCD68, 0xCD68}, {0xCD69, 0xCD69, 0xCD69}, {0xCD6A, 0xCD6A, 0xCD6A}, {0xCD6B, 0xCD6B, 0xCD6B}, {0xCD6C, 0xCD6C, 0xCD6C}, {0xCD6D, 0xCD6D, 0xCD6D}, {0xCD6E, 0xCD6E, 0xCD6E}, {0xCD6F, 0xCD6F, 0xCD6F}, {0xCD70, 0xCD70, 0xCD70}, {0xCD71, 0xCD71, 0xCD71}, {0xCD72, 0xCD72, 0xCD72}, {0xCD73, 0xCD73, 0xCD73}, {0xCD74, 0xCD74, 0xCD74}, {0xCD75, 0xCD75, 0xCD75}, {0xCD76, 0xCD76, 0xCD76}, {0xCD77, 0xCD77, 0xCD77}, {0xCD78, 0xCD78, 0xCD78}, {0xCD79, 0xCD79, 0xCD79}, {0xCD7A, 0xCD7A, 0xCD7A}, {0xCD7B, 0xCD7B, 0xCD7B}, {0xCD7C, 0xCD7C, 0xCD7C}, {0xCD7D, 0xCD7D, 0xCD7D}, {0xCD7E, 0xCD7E, 0xCD7E}, {0xCD7F, 0xCD7F, 0xCD7F}, {0xCD80, 0xCD80, 0xCD80}, {0xCD81, 0xCD81, 0xCD81}, {0xCD82, 0xCD82, 0xCD82}, {0xCD83, 0xCD83, 0xCD83}, {0xCD84, 0xCD84, 0xCD84}, {0xCD85, 0xCD85, 0xCD85}, {0xCD86, 0xCD86, 0xCD86}, {0xCD87, 0xCD87, 0xCD87}, {0xCD88, 0xCD88, 0xCD88}, {0xCD89, 0xCD89, 0xCD89}, {0xCD8A, 0xCD8A, 0xCD8A}, {0xCD8B, 0xCD8B, 0xCD8B}, {0xCD8C, 0xCD8C, 0xCD8C}, {0xCD8D, 0xCD8D, 0xCD8D}, {0xCD8E, 0xCD8E, 0xCD8E}, {0xCD8F, 0xCD8F, 0xCD8F}, {0xCD90, 0xCD90, 0xCD90}, {0xCD91, 0xCD91, 0xCD91}, {0xCD92, 0xCD92, 0xCD92}, {0xCD93, 0xCD93, 0xCD93}, {0xCD94, 0xCD94, 0xCD94}, {0xCD95, 0xCD95, 0xCD95}, {0xCD96, 0xCD96, 0xCD96}, {0xCD97, 0xCD97, 0xCD97}, {0xCD98, 0xCD98, 0xCD98}, {0xCD99, 0xCD99, 0xCD99}, {0xCD9A, 0xCD9A, 0xCD9A}, {0xCD9B, 0xCD9B, 0xCD9B}, {0xCD9C, 0xCD9C, 0xCD9C}, {0xCD9D, 0xCD9D, 0xCD9D}, {0xCD9E, 0xCD9E, 0xCD9E}, {0xCD9F, 0xCD9F, 0xCD9F}, {0xCDA0, 0xCDA0, 0xCDA0}, {0xCDA1, 0xCDA1, 0xCDA1}, {0xCDA2, 0xCDA2, 0xCDA2}, {0xCDA3, 0xCDA3, 0xCDA3}, {0xCDA4, 0xCDA4, 0xCDA4}, {0xCDA5, 0xCDA5, 0xCDA5}, {0xCDA6, 0xCDA6, 0xCDA6}, {0xCDA7, 0xCDA7, 0xCDA7}, {0xCDA8, 0xCDA8, 0xCDA8}, {0xCDA9, 0xCDA9, 0xCDA9}, {0xCDAA, 0xCDAA, 0xCDAA}, {0xCDAB, 0xCDAB, 0xCDAB}, {0xCDAC, 0xCDAC, 0xCDAC}, {0xCDAD, 0xCDAD, 0xCDAD}, {0xCDAE, 0xCDAE, 0xCDAE}, {0xCDAF, 0xCDAF, 0xCDAF}, {0xCDB0, 0xCDB0, 0xCDB0}, {0xCDB1, 0xCDB1, 0xCDB1}, {0xCDB2, 0xCDB2, 0xCDB2}, {0xCDB3, 0xCDB3, 0xCDB3}, {0xCDB4, 0xCDB4, 0xCDB4}, {0xCDB5, 0xCDB5, 0xCDB5}, {0xCDB6, 0xCDB6, 0xCDB6}, {0xCDB7, 0xCDB7, 0xCDB7}, {0xCDB8, 0xCDB8, 0xCDB8}, {0xCDB9, 0xCDB9, 0xCDB9}, {0xCDBA, 0xCDBA, 0xCDBA}, {0xCDBB, 0xCDBB, 0xCDBB}, {0xCDBC, 0xCDBC, 0xCDBC}, {0xCDBD, 0xCDBD, 0xCDBD}, {0xCDBE, 0xCDBE, 0xCDBE}, {0xCDBF, 0xCDBF, 0xCDBF}, {0xCDC0, 0xCDC0, 0xCDC0}, {0xCDC1, 0xCDC1, 0xCDC1}, {0xCDC2, 0xCDC2, 0xCDC2}, {0xCDC3, 0xCDC3, 0xCDC3}, {0xCDC4, 0xCDC4, 0xCDC4}, {0xCDC5, 0xCDC5, 0xCDC5}, {0xCDC6, 0xCDC6, 0xCDC6}, {0xCDC7, 0xCDC7, 0xCDC7}, {0xCDC8, 0xCDC8, 0xCDC8}, {0xCDC9, 0xCDC9, 0xCDC9}, {0xCDCA, 0xCDCA, 0xCDCA}, {0xCDCB, 0xCDCB, 0xCDCB}, {0xCDCC, 0xCDCC, 0xCDCC}, {0xCDCD, 0xCDCD, 0xCDCD}, {0xCDCE, 0xCDCE, 0xCDCE}, {0xCDCF, 0xCDCF, 0xCDCF}, {0xCDD0, 0xCDD0, 0xCDD0}, {0xCDD1, 0xCDD1, 0xCDD1}, {0xCDD2, 0xCDD2, 0xCDD2}, {0xCDD3, 0xCDD3, 0xCDD3}, {0xCDD4, 0xCDD4, 0xCDD4}, {0xCDD5, 0xCDD5, 0xCDD5}, {0xCDD6, 0xCDD6, 0xCDD6}, {0xCDD7, 0xCDD7, 0xCDD7}, {0xCDD8, 0xCDD8, 0xCDD8}, {0xCDD9, 0xCDD9, 0xCDD9}, {0xCDDA, 0xCDDA, 0xCDDA}, {0xCDDB, 0xCDDB, 0xCDDB}, {0xCDDC, 0xCDDC, 0xCDDC}, {0xCDDD, 0xCDDD, 0xCDDD}, {0xCDDE, 0xCDDE, 0xCDDE}, {0xCDDF, 0xCDDF, 0xCDDF}, {0xCDE0, 0xCDE0, 0xCDE0}, {0xCDE1, 0xCDE1, 0xCDE1}, {0xCDE2, 0xCDE2, 0xCDE2}, {0xCDE3, 0xCDE3, 0xCDE3}, {0xCDE4, 0xCDE4, 0xCDE4}, {0xCDE5, 0xCDE5, 0xCDE5}, {0xCDE6, 0xCDE6, 0xCDE6}, {0xCDE7, 0xCDE7, 0xCDE7}, {0xCDE8, 0xCDE8, 0xCDE8}, {0xCDE9, 0xCDE9, 0xCDE9}, {0xCDEA, 0xCDEA, 0xCDEA}, {0xCDEB, 0xCDEB, 0xCDEB}, {0xCDEC, 0xCDEC, 0xCDEC}, {0xCDED, 0xCDED, 0xCDED}, {0xCDEE, 0xCDEE, 0xCDEE}, {0xCDEF, 0xCDEF, 0xCDEF}, {0xCDF0, 0xCDF0, 0xCDF0}, {0xCDF1, 0xCDF1, 0xCDF1}, {0xCDF2, 0xCDF2, 0xCDF2}, {0xCDF3, 0xCDF3, 0xCDF3}, {0xCDF4, 0xCDF4, 0xCDF4}, {0xCDF5, 0xCDF5, 0xCDF5}, {0xCDF6, 0xCDF6, 0xCDF6}, {0xCDF7, 0xCDF7, 0xCDF7}, {0xCDF8, 0xCDF8, 0xCDF8}, {0xCDF9, 0xCDF9, 0xCDF9}, {0xCDFA, 0xCDFA, 0xCDFA}, {0xCDFB, 0xCDFB, 0xCDFB}, {0xCDFC, 0xCDFC, 0xCDFC}, {0xCDFD, 0xCDFD, 0xCDFD}, {0xCDFE, 0xCDFE, 0xCDFE}, {0xCDFF, 0xCDFF, 0xCDFF}, {0xCE00, 0xCE00, 0xCE00}, {0xCE01, 0xCE01, 0xCE01}, {0xCE02, 0xCE02, 0xCE02}, {0xCE03, 0xCE03, 0xCE03}, {0xCE04, 0xCE04, 0xCE04}, {0xCE05, 0xCE05, 0xCE05}, {0xCE06, 0xCE06, 0xCE06}, {0xCE07, 0xCE07, 0xCE07}, {0xCE08, 0xCE08, 0xCE08}, {0xCE09, 0xCE09, 0xCE09}, {0xCE0A, 0xCE0A, 0xCE0A}, {0xCE0B, 0xCE0B, 0xCE0B}, {0xCE0C, 0xCE0C, 0xCE0C}, {0xCE0D, 0xCE0D, 0xCE0D}, {0xCE0E, 0xCE0E, 0xCE0E}, {0xCE0F, 0xCE0F, 0xCE0F}, {0xCE10, 0xCE10, 0xCE10}, {0xCE11, 0xCE11, 0xCE11}, {0xCE12, 0xCE12, 0xCE12}, {0xCE13, 0xCE13, 0xCE13}, {0xCE14, 0xCE14, 0xCE14}, {0xCE15, 0xCE15, 0xCE15}, {0xCE16, 0xCE16, 0xCE16}, {0xCE17, 0xCE17, 0xCE17}, {0xCE18, 0xCE18, 0xCE18}, {0xCE19, 0xCE19, 0xCE19}, {0xCE1A, 0xCE1A, 0xCE1A}, {0xCE1B, 0xCE1B, 0xCE1B}, {0xCE1C, 0xCE1C, 0xCE1C}, {0xCE1D, 0xCE1D, 0xCE1D}, {0xCE1E, 0xCE1E, 0xCE1E}, {0xCE1F, 0xCE1F, 0xCE1F}, {0xCE20, 0xCE20, 0xCE20}, {0xCE21, 0xCE21, 0xCE21}, {0xCE22, 0xCE22, 0xCE22}, {0xCE23, 0xCE23, 0xCE23}, {0xCE24, 0xCE24, 0xCE24}, {0xCE25, 0xCE25, 0xCE25}, {0xCE26, 0xCE26, 0xCE26}, {0xCE27, 0xCE27, 0xCE27}, {0xCE28, 0xCE28, 0xCE28}, {0xCE29, 0xCE29, 0xCE29}, {0xCE2A, 0xCE2A, 0xCE2A}, {0xCE2B, 0xCE2B, 0xCE2B}, {0xCE2C, 0xCE2C, 0xCE2C}, {0xCE2D, 0xCE2D, 0xCE2D}, {0xCE2E, 0xCE2E, 0xCE2E}, {0xCE2F, 0xCE2F, 0xCE2F}, {0xCE30, 0xCE30, 0xCE30}, {0xCE31, 0xCE31, 0xCE31}, {0xCE32, 0xCE32, 0xCE32}, {0xCE33, 0xCE33, 0xCE33}, {0xCE34, 0xCE34, 0xCE34}, {0xCE35, 0xCE35, 0xCE35}, {0xCE36, 0xCE36, 0xCE36}, {0xCE37, 0xCE37, 0xCE37}, {0xCE38, 0xCE38, 0xCE38}, {0xCE39, 0xCE39, 0xCE39}, {0xCE3A, 0xCE3A, 0xCE3A}, {0xCE3B, 0xCE3B, 0xCE3B}, {0xCE3C, 0xCE3C, 0xCE3C}, {0xCE3D, 0xCE3D, 0xCE3D}, {0xCE3E, 0xCE3E, 0xCE3E}, {0xCE3F, 0xCE3F, 0xCE3F}, {0xCE40, 0xCE40, 0xCE40}, {0xCE41, 0xCE41, 0xCE41}, {0xCE42, 0xCE42, 0xCE42}, {0xCE43, 0xCE43, 0xCE43}, {0xCE44, 0xCE44, 0xCE44}, {0xCE45, 0xCE45, 0xCE45}, {0xCE46, 0xCE46, 0xCE46}, {0xCE47, 0xCE47, 0xCE47}, {0xCE48, 0xCE48, 0xCE48}, {0xCE49, 0xCE49, 0xCE49}, {0xCE4A, 0xCE4A, 0xCE4A}, {0xCE4B, 0xCE4B, 0xCE4B}, {0xCE4C, 0xCE4C, 0xCE4C}, {0xCE4D, 0xCE4D, 0xCE4D}, {0xCE4E, 0xCE4E, 0xCE4E}, {0xCE4F, 0xCE4F, 0xCE4F}, {0xCE50, 0xCE50, 0xCE50}, {0xCE51, 0xCE51, 0xCE51}, {0xCE52, 0xCE52, 0xCE52}, {0xCE53, 0xCE53, 0xCE53}, {0xCE54, 0xCE54, 0xCE54}, {0xCE55, 0xCE55, 0xCE55}, {0xCE56, 0xCE56, 0xCE56}, {0xCE57, 0xCE57, 0xCE57}, {0xCE58, 0xCE58, 0xCE58}, {0xCE59, 0xCE59, 0xCE59}, {0xCE5A, 0xCE5A, 0xCE5A}, {0xCE5B, 0xCE5B, 0xCE5B}, {0xCE5C, 0xCE5C, 0xCE5C}, {0xCE5D, 0xCE5D, 0xCE5D}, {0xCE5E, 0xCE5E, 0xCE5E}, {0xCE5F, 0xCE5F, 0xCE5F}, {0xCE60, 0xCE60, 0xCE60}, {0xCE61, 0xCE61, 0xCE61}, {0xCE62, 0xCE62, 0xCE62}, {0xCE63, 0xCE63, 0xCE63}, {0xCE64, 0xCE64, 0xCE64}, {0xCE65, 0xCE65, 0xCE65}, {0xCE66, 0xCE66, 0xCE66}, {0xCE67, 0xCE67, 0xCE67}, {0xCE68, 0xCE68, 0xCE68}, {0xCE69, 0xCE69, 0xCE69}, {0xCE6A, 0xCE6A, 0xCE6A}, {0xCE6B, 0xCE6B, 0xCE6B}, {0xCE6C, 0xCE6C, 0xCE6C}, {0xCE6D, 0xCE6D, 0xCE6D}, {0xCE6E, 0xCE6E, 0xCE6E}, {0xCE6F, 0xCE6F, 0xCE6F}, {0xCE70, 0xCE70, 0xCE70}, {0xCE71, 0xCE71, 0xCE71}, {0xCE72, 0xCE72, 0xCE72}, {0xCE73, 0xCE73, 0xCE73}, {0xCE74, 0xCE74, 0xCE74}, {0xCE75, 0xCE75, 0xCE75}, {0xCE76, 0xCE76, 0xCE76}, {0xCE77, 0xCE77, 0xCE77}, {0xCE78, 0xCE78, 0xCE78}, {0xCE79, 0xCE79, 0xCE79}, {0xCE7A, 0xCE7A, 0xCE7A}, {0xCE7B, 0xCE7B, 0xCE7B}, {0xCE7C, 0xCE7C, 0xCE7C}, {0xCE7D, 0xCE7D, 0xCE7D}, {0xCE7E, 0xCE7E, 0xCE7E}, {0xCE7F, 0xCE7F, 0xCE7F}, {0xCE80, 0xCE80, 0xCE80}, {0xCE81, 0xCE81, 0xCE81}, {0xCE82, 0xCE82, 0xCE82}, {0xCE83, 0xCE83, 0xCE83}, {0xCE84, 0xCE84, 0xCE84}, {0xCE85, 0xCE85, 0xCE85}, {0xCE86, 0xCE86, 0xCE86}, {0xCE87, 0xCE87, 0xCE87}, {0xCE88, 0xCE88, 0xCE88}, {0xCE89, 0xCE89, 0xCE89}, {0xCE8A, 0xCE8A, 0xCE8A}, {0xCE8B, 0xCE8B, 0xCE8B}, {0xCE8C, 0xCE8C, 0xCE8C}, {0xCE8D, 0xCE8D, 0xCE8D}, {0xCE8E, 0xCE8E, 0xCE8E}, {0xCE8F, 0xCE8F, 0xCE8F}, {0xCE90, 0xCE90, 0xCE90}, {0xCE91, 0xCE91, 0xCE91}, {0xCE92, 0xCE92, 0xCE92}, {0xCE93, 0xCE93, 0xCE93}, {0xCE94, 0xCE94, 0xCE94}, {0xCE95, 0xCE95, 0xCE95}, {0xCE96, 0xCE96, 0xCE96}, {0xCE97, 0xCE97, 0xCE97}, {0xCE98, 0xCE98, 0xCE98}, {0xCE99, 0xCE99, 0xCE99}, {0xCE9A, 0xCE9A, 0xCE9A}, {0xCE9B, 0xCE9B, 0xCE9B}, {0xCE9C, 0xCE9C, 0xCE9C}, {0xCE9D, 0xCE9D, 0xCE9D}, {0xCE9E, 0xCE9E, 0xCE9E}, {0xCE9F, 0xCE9F, 0xCE9F}, {0xCEA0, 0xCEA0, 0xCEA0}, {0xCEA1, 0xCEA1, 0xCEA1}, {0xCEA2, 0xCEA2, 0xCEA2}, {0xCEA3, 0xCEA3, 0xCEA3}, {0xCEA4, 0xCEA4, 0xCEA4}, {0xCEA5, 0xCEA5, 0xCEA5}, {0xCEA6, 0xCEA6, 0xCEA6}, {0xCEA7, 0xCEA7, 0xCEA7}, {0xCEA8, 0xCEA8, 0xCEA8}, {0xCEA9, 0xCEA9, 0xCEA9}, {0xCEAA, 0xCEAA, 0xCEAA}, {0xCEAB, 0xCEAB, 0xCEAB}, {0xCEAC, 0xCEAC, 0xCEAC}, {0xCEAD, 0xCEAD, 0xCEAD}, {0xCEAE, 0xCEAE, 0xCEAE}, {0xCEAF, 0xCEAF, 0xCEAF}, {0xCEB0, 0xCEB0, 0xCEB0}, {0xCEB1, 0xCEB1, 0xCEB1}, {0xCEB2, 0xCEB2, 0xCEB2}, {0xCEB3, 0xCEB3, 0xCEB3}, {0xCEB4, 0xCEB4, 0xCEB4}, {0xCEB5, 0xCEB5, 0xCEB5}, {0xCEB6, 0xCEB6, 0xCEB6}, {0xCEB7, 0xCEB7, 0xCEB7}, {0xCEB8, 0xCEB8, 0xCEB8}, {0xCEB9, 0xCEB9, 0xCEB9}, {0xCEBA, 0xCEBA, 0xCEBA}, {0xCEBB, 0xCEBB, 0xCEBB}, {0xCEBC, 0xCEBC, 0xCEBC}, {0xCEBD, 0xCEBD, 0xCEBD}, {0xCEBE, 0xCEBE, 0xCEBE}, {0xCEBF, 0xCEBF, 0xCEBF}, {0xCEC0, 0xCEC0, 0xCEC0}, {0xCEC1, 0xCEC1, 0xCEC1}, {0xCEC2, 0xCEC2, 0xCEC2}, {0xCEC3, 0xCEC3, 0xCEC3}, {0xCEC4, 0xCEC4, 0xCEC4}, {0xCEC5, 0xCEC5, 0xCEC5}, {0xCEC6, 0xCEC6, 0xCEC6}, {0xCEC7, 0xCEC7, 0xCEC7}, {0xCEC8, 0xCEC8, 0xCEC8}, {0xCEC9, 0xCEC9, 0xCEC9}, {0xCECA, 0xCECA, 0xCECA}, {0xCECB, 0xCECB, 0xCECB}, {0xCECC, 0xCECC, 0xCECC}, {0xCECD, 0xCECD, 0xCECD}, {0xCECE, 0xCECE, 0xCECE}, {0xCECF, 0xCECF, 0xCECF}, {0xCED0, 0xCED0, 0xCED0}, {0xCED1, 0xCED1, 0xCED1}, {0xCED2, 0xCED2, 0xCED2}, {0xCED3, 0xCED3, 0xCED3}, {0xCED4, 0xCED4, 0xCED4}, {0xCED5, 0xCED5, 0xCED5}, {0xCED6, 0xCED6, 0xCED6}, {0xCED7, 0xCED7, 0xCED7}, {0xCED8, 0xCED8, 0xCED8}, {0xCED9, 0xCED9, 0xCED9}, {0xCEDA, 0xCEDA, 0xCEDA}, {0xCEDB, 0xCEDB, 0xCEDB}, {0xCEDC, 0xCEDC, 0xCEDC}, {0xCEDD, 0xCEDD, 0xCEDD}, {0xCEDE, 0xCEDE, 0xCEDE}, {0xCEDF, 0xCEDF, 0xCEDF}, {0xCEE0, 0xCEE0, 0xCEE0}, {0xCEE1, 0xCEE1, 0xCEE1}, {0xCEE2, 0xCEE2, 0xCEE2}, {0xCEE3, 0xCEE3, 0xCEE3}, {0xCEE4, 0xCEE4, 0xCEE4}, {0xCEE5, 0xCEE5, 0xCEE5}, {0xCEE6, 0xCEE6, 0xCEE6}, {0xCEE7, 0xCEE7, 0xCEE7}, {0xCEE8, 0xCEE8, 0xCEE8}, {0xCEE9, 0xCEE9, 0xCEE9}, {0xCEEA, 0xCEEA, 0xCEEA}, {0xCEEB, 0xCEEB, 0xCEEB}, {0xCEEC, 0xCEEC, 0xCEEC}, {0xCEED, 0xCEED, 0xCEED}, {0xCEEE, 0xCEEE, 0xCEEE}, {0xCEEF, 0xCEEF, 0xCEEF}, {0xCEF0, 0xCEF0, 0xCEF0}, {0xCEF1, 0xCEF1, 0xCEF1}, {0xCEF2, 0xCEF2, 0xCEF2}, {0xCEF3, 0xCEF3, 0xCEF3}, {0xCEF4, 0xCEF4, 0xCEF4}, {0xCEF5, 0xCEF5, 0xCEF5}, {0xCEF6, 0xCEF6, 0xCEF6}, {0xCEF7, 0xCEF7, 0xCEF7}, {0xCEF8, 0xCEF8, 0xCEF8}, {0xCEF9, 0xCEF9, 0xCEF9}, {0xCEFA, 0xCEFA, 0xCEFA}, {0xCEFB, 0xCEFB, 0xCEFB}, {0xCEFC, 0xCEFC, 0xCEFC}, {0xCEFD, 0xCEFD, 0xCEFD}, {0xCEFE, 0xCEFE, 0xCEFE}, {0xCEFF, 0xCEFF, 0xCEFF}, {0xCF00, 0xCF00, 0xCF00}, {0xCF01, 0xCF01, 0xCF01}, {0xCF02, 0xCF02, 0xCF02}, {0xCF03, 0xCF03, 0xCF03}, {0xCF04, 0xCF04, 0xCF04}, {0xCF05, 0xCF05, 0xCF05}, {0xCF06, 0xCF06, 0xCF06}, {0xCF07, 0xCF07, 0xCF07}, {0xCF08, 0xCF08, 0xCF08}, {0xCF09, 0xCF09, 0xCF09}, {0xCF0A, 0xCF0A, 0xCF0A}, {0xCF0B, 0xCF0B, 0xCF0B}, {0xCF0C, 0xCF0C, 0xCF0C}, {0xCF0D, 0xCF0D, 0xCF0D}, {0xCF0E, 0xCF0E, 0xCF0E}, {0xCF0F, 0xCF0F, 0xCF0F}, {0xCF10, 0xCF10, 0xCF10}, {0xCF11, 0xCF11, 0xCF11}, {0xCF12, 0xCF12, 0xCF12}, {0xCF13, 0xCF13, 0xCF13}, {0xCF14, 0xCF14, 0xCF14}, {0xCF15, 0xCF15, 0xCF15}, {0xCF16, 0xCF16, 0xCF16}, {0xCF17, 0xCF17, 0xCF17}, {0xCF18, 0xCF18, 0xCF18}, {0xCF19, 0xCF19, 0xCF19}, {0xCF1A, 0xCF1A, 0xCF1A}, {0xCF1B, 0xCF1B, 0xCF1B}, {0xCF1C, 0xCF1C, 0xCF1C}, {0xCF1D, 0xCF1D, 0xCF1D}, {0xCF1E, 0xCF1E, 0xCF1E}, {0xCF1F, 0xCF1F, 0xCF1F}, {0xCF20, 0xCF20, 0xCF20}, {0xCF21, 0xCF21, 0xCF21}, {0xCF22, 0xCF22, 0xCF22}, {0xCF23, 0xCF23, 0xCF23}, {0xCF24, 0xCF24, 0xCF24}, {0xCF25, 0xCF25, 0xCF25}, {0xCF26, 0xCF26, 0xCF26}, {0xCF27, 0xCF27, 0xCF27}, {0xCF28, 0xCF28, 0xCF28}, {0xCF29, 0xCF29, 0xCF29}, {0xCF2A, 0xCF2A, 0xCF2A}, {0xCF2B, 0xCF2B, 0xCF2B}, {0xCF2C, 0xCF2C, 0xCF2C}, {0xCF2D, 0xCF2D, 0xCF2D}, {0xCF2E, 0xCF2E, 0xCF2E}, {0xCF2F, 0xCF2F, 0xCF2F}, {0xCF30, 0xCF30, 0xCF30}, {0xCF31, 0xCF31, 0xCF31}, {0xCF32, 0xCF32, 0xCF32}, {0xCF33, 0xCF33, 0xCF33}, {0xCF34, 0xCF34, 0xCF34}, {0xCF35, 0xCF35, 0xCF35}, {0xCF36, 0xCF36, 0xCF36}, {0xCF37, 0xCF37, 0xCF37}, {0xCF38, 0xCF38, 0xCF38}, {0xCF39, 0xCF39, 0xCF39}, {0xCF3A, 0xCF3A, 0xCF3A}, {0xCF3B, 0xCF3B, 0xCF3B}, {0xCF3C, 0xCF3C, 0xCF3C}, {0xCF3D, 0xCF3D, 0xCF3D}, {0xCF3E, 0xCF3E, 0xCF3E}, {0xCF3F, 0xCF3F, 0xCF3F}, {0xCF40, 0xCF40, 0xCF40}, {0xCF41, 0xCF41, 0xCF41}, {0xCF42, 0xCF42, 0xCF42}, {0xCF43, 0xCF43, 0xCF43}, {0xCF44, 0xCF44, 0xCF44}, {0xCF45, 0xCF45, 0xCF45}, {0xCF46, 0xCF46, 0xCF46}, {0xCF47, 0xCF47, 0xCF47}, {0xCF48, 0xCF48, 0xCF48}, {0xCF49, 0xCF49, 0xCF49}, {0xCF4A, 0xCF4A, 0xCF4A}, {0xCF4B, 0xCF4B, 0xCF4B}, {0xCF4C, 0xCF4C, 0xCF4C}, {0xCF4D, 0xCF4D, 0xCF4D}, {0xCF4E, 0xCF4E, 0xCF4E}, {0xCF4F, 0xCF4F, 0xCF4F}, {0xCF50, 0xCF50, 0xCF50}, {0xCF51, 0xCF51, 0xCF51}, {0xCF52, 0xCF52, 0xCF52}, {0xCF53, 0xCF53, 0xCF53}, {0xCF54, 0xCF54, 0xCF54}, {0xCF55, 0xCF55, 0xCF55}, {0xCF56, 0xCF56, 0xCF56}, {0xCF57, 0xCF57, 0xCF57}, {0xCF58, 0xCF58, 0xCF58}, {0xCF59, 0xCF59, 0xCF59}, {0xCF5A, 0xCF5A, 0xCF5A}, {0xCF5B, 0xCF5B, 0xCF5B}, {0xCF5C, 0xCF5C, 0xCF5C}, {0xCF5D, 0xCF5D, 0xCF5D}, {0xCF5E, 0xCF5E, 0xCF5E}, {0xCF5F, 0xCF5F, 0xCF5F}, {0xCF60, 0xCF60, 0xCF60}, {0xCF61, 0xCF61, 0xCF61}, {0xCF62, 0xCF62, 0xCF62}, {0xCF63, 0xCF63, 0xCF63}, {0xCF64, 0xCF64, 0xCF64}, {0xCF65, 0xCF65, 0xCF65}, {0xCF66, 0xCF66, 0xCF66}, {0xCF67, 0xCF67, 0xCF67}, {0xCF68, 0xCF68, 0xCF68}, {0xCF69, 0xCF69, 0xCF69}, {0xCF6A, 0xCF6A, 0xCF6A}, {0xCF6B, 0xCF6B, 0xCF6B}, {0xCF6C, 0xCF6C, 0xCF6C}, {0xCF6D, 0xCF6D, 0xCF6D}, {0xCF6E, 0xCF6E, 0xCF6E}, {0xCF6F, 0xCF6F, 0xCF6F}, {0xCF70, 0xCF70, 0xCF70}, {0xCF71, 0xCF71, 0xCF71}, {0xCF72, 0xCF72, 0xCF72}, {0xCF73, 0xCF73, 0xCF73}, {0xCF74, 0xCF74, 0xCF74}, {0xCF75, 0xCF75, 0xCF75}, {0xCF76, 0xCF76, 0xCF76}, {0xCF77, 0xCF77, 0xCF77}, {0xCF78, 0xCF78, 0xCF78}, {0xCF79, 0xCF79, 0xCF79}, {0xCF7A, 0xCF7A, 0xCF7A}, {0xCF7B, 0xCF7B, 0xCF7B}, {0xCF7C, 0xCF7C, 0xCF7C}, {0xCF7D, 0xCF7D, 0xCF7D}, {0xCF7E, 0xCF7E, 0xCF7E}, {0xCF7F, 0xCF7F, 0xCF7F}, {0xCF80, 0xCF80, 0xCF80}, {0xCF81, 0xCF81, 0xCF81}, {0xCF82, 0xCF82, 0xCF82}, {0xCF83, 0xCF83, 0xCF83}, {0xCF84, 0xCF84, 0xCF84}, {0xCF85, 0xCF85, 0xCF85}, {0xCF86, 0xCF86, 0xCF86}, {0xCF87, 0xCF87, 0xCF87}, {0xCF88, 0xCF88, 0xCF88}, {0xCF89, 0xCF89, 0xCF89}, {0xCF8A, 0xCF8A, 0xCF8A}, {0xCF8B, 0xCF8B, 0xCF8B}, {0xCF8C, 0xCF8C, 0xCF8C}, {0xCF8D, 0xCF8D, 0xCF8D}, {0xCF8E, 0xCF8E, 0xCF8E}, {0xCF8F, 0xCF8F, 0xCF8F}, {0xCF90, 0xCF90, 0xCF90}, {0xCF91, 0xCF91, 0xCF91}, {0xCF92, 0xCF92, 0xCF92}, {0xCF93, 0xCF93, 0xCF93}, {0xCF94, 0xCF94, 0xCF94}, {0xCF95, 0xCF95, 0xCF95}, {0xCF96, 0xCF96, 0xCF96}, {0xCF97, 0xCF97, 0xCF97}, {0xCF98, 0xCF98, 0xCF98}, {0xCF99, 0xCF99, 0xCF99}, {0xCF9A, 0xCF9A, 0xCF9A}, {0xCF9B, 0xCF9B, 0xCF9B}, {0xCF9C, 0xCF9C, 0xCF9C}, {0xCF9D, 0xCF9D, 0xCF9D}, {0xCF9E, 0xCF9E, 0xCF9E}, {0xCF9F, 0xCF9F, 0xCF9F}, {0xCFA0, 0xCFA0, 0xCFA0}, {0xCFA1, 0xCFA1, 0xCFA1}, {0xCFA2, 0xCFA2, 0xCFA2}, {0xCFA3, 0xCFA3, 0xCFA3}, {0xCFA4, 0xCFA4, 0xCFA4}, {0xCFA5, 0xCFA5, 0xCFA5}, {0xCFA6, 0xCFA6, 0xCFA6}, {0xCFA7, 0xCFA7, 0xCFA7}, {0xCFA8, 0xCFA8, 0xCFA8}, {0xCFA9, 0xCFA9, 0xCFA9}, {0xCFAA, 0xCFAA, 0xCFAA}, {0xCFAB, 0xCFAB, 0xCFAB}, {0xCFAC, 0xCFAC, 0xCFAC}, {0xCFAD, 0xCFAD, 0xCFAD}, {0xCFAE, 0xCFAE, 0xCFAE}, {0xCFAF, 0xCFAF, 0xCFAF}, {0xCFB0, 0xCFB0, 0xCFB0}, {0xCFB1, 0xCFB1, 0xCFB1}, {0xCFB2, 0xCFB2, 0xCFB2}, {0xCFB3, 0xCFB3, 0xCFB3}, {0xCFB4, 0xCFB4, 0xCFB4}, {0xCFB5, 0xCFB5, 0xCFB5}, {0xCFB6, 0xCFB6, 0xCFB6}, {0xCFB7, 0xCFB7, 0xCFB7}, {0xCFB8, 0xCFB8, 0xCFB8}, {0xCFB9, 0xCFB9, 0xCFB9}, {0xCFBA, 0xCFBA, 0xCFBA}, {0xCFBB, 0xCFBB, 0xCFBB}, {0xCFBC, 0xCFBC, 0xCFBC}, {0xCFBD, 0xCFBD, 0xCFBD}, {0xCFBE, 0xCFBE, 0xCFBE}, {0xCFBF, 0xCFBF, 0xCFBF}, {0xCFC0, 0xCFC0, 0xCFC0}, {0xCFC1, 0xCFC1, 0xCFC1}, {0xCFC2, 0xCFC2, 0xCFC2}, {0xCFC3, 0xCFC3, 0xCFC3}, {0xCFC4, 0xCFC4, 0xCFC4}, {0xCFC5, 0xCFC5, 0xCFC5}, {0xCFC6, 0xCFC6, 0xCFC6}, {0xCFC7, 0xCFC7, 0xCFC7}, {0xCFC8, 0xCFC8, 0xCFC8}, {0xCFC9, 0xCFC9, 0xCFC9}, {0xCFCA, 0xCFCA, 0xCFCA}, {0xCFCB, 0xCFCB, 0xCFCB}, {0xCFCC, 0xCFCC, 0xCFCC}, {0xCFCD, 0xCFCD, 0xCFCD}, {0xCFCE, 0xCFCE, 0xCFCE}, {0xCFCF, 0xCFCF, 0xCFCF}, {0xCFD0, 0xCFD0, 0xCFD0}, {0xCFD1, 0xCFD1, 0xCFD1}, {0xCFD2, 0xCFD2, 0xCFD2}, {0xCFD3, 0xCFD3, 0xCFD3}, {0xCFD4, 0xCFD4, 0xCFD4}, {0xCFD5, 0xCFD5, 0xCFD5}, {0xCFD6, 0xCFD6, 0xCFD6}, {0xCFD7, 0xCFD7, 0xCFD7}, {0xCFD8, 0xCFD8, 0xCFD8}, {0xCFD9, 0xCFD9, 0xCFD9}, {0xCFDA, 0xCFDA, 0xCFDA}, {0xCFDB, 0xCFDB, 0xCFDB}, {0xCFDC, 0xCFDC, 0xCFDC}, {0xCFDD, 0xCFDD, 0xCFDD}, {0xCFDE, 0xCFDE, 0xCFDE}, {0xCFDF, 0xCFDF, 0xCFDF}, {0xCFE0, 0xCFE0, 0xCFE0}, {0xCFE1, 0xCFE1, 0xCFE1}, {0xCFE2, 0xCFE2, 0xCFE2}, {0xCFE3, 0xCFE3, 0xCFE3}, {0xCFE4, 0xCFE4, 0xCFE4}, {0xCFE5, 0xCFE5, 0xCFE5}, {0xCFE6, 0xCFE6, 0xCFE6}, {0xCFE7, 0xCFE7, 0xCFE7}, {0xCFE8, 0xCFE8, 0xCFE8}, {0xCFE9, 0xCFE9, 0xCFE9}, {0xCFEA, 0xCFEA, 0xCFEA}, {0xCFEB, 0xCFEB, 0xCFEB}, {0xCFEC, 0xCFEC, 0xCFEC}, {0xCFED, 0xCFED, 0xCFED}, {0xCFEE, 0xCFEE, 0xCFEE}, {0xCFEF, 0xCFEF, 0xCFEF}, {0xCFF0, 0xCFF0, 0xCFF0}, {0xCFF1, 0xCFF1, 0xCFF1}, {0xCFF2, 0xCFF2, 0xCFF2}, {0xCFF3, 0xCFF3, 0xCFF3}, {0xCFF4, 0xCFF4, 0xCFF4}, {0xCFF5, 0xCFF5, 0xCFF5}, {0xCFF6, 0xCFF6, 0xCFF6}, {0xCFF7, 0xCFF7, 0xCFF7}, {0xCFF8, 0xCFF8, 0xCFF8}, {0xCFF9, 0xCFF9, 0xCFF9}, {0xCFFA, 0xCFFA, 0xCFFA}, {0xCFFB, 0xCFFB, 0xCFFB}, {0xCFFC, 0xCFFC, 0xCFFC}, {0xCFFD, 0xCFFD, 0xCFFD}, {0xCFFE, 0xCFFE, 0xCFFE}, {0xCFFF, 0xCFFF, 0xCFFF}, {0xD000, 0xD000, 0xD000}, {0xD001, 0xD001, 0xD001}, {0xD002, 0xD002, 0xD002}, {0xD003, 0xD003, 0xD003}, {0xD004, 0xD004, 0xD004}, {0xD005, 0xD005, 0xD005}, {0xD006, 0xD006, 0xD006}, {0xD007, 0xD007, 0xD007}, {0xD008, 0xD008, 0xD008}, {0xD009, 0xD009, 0xD009}, {0xD00A, 0xD00A, 0xD00A}, {0xD00B, 0xD00B, 0xD00B}, {0xD00C, 0xD00C, 0xD00C}, {0xD00D, 0xD00D, 0xD00D}, {0xD00E, 0xD00E, 0xD00E}, {0xD00F, 0xD00F, 0xD00F}, {0xD010, 0xD010, 0xD010}, {0xD011, 0xD011, 0xD011}, {0xD012, 0xD012, 0xD012}, {0xD013, 0xD013, 0xD013}, {0xD014, 0xD014, 0xD014}, {0xD015, 0xD015, 0xD015}, {0xD016, 0xD016, 0xD016}, {0xD017, 0xD017, 0xD017}, {0xD018, 0xD018, 0xD018}, {0xD019, 0xD019, 0xD019}, {0xD01A, 0xD01A, 0xD01A}, {0xD01B, 0xD01B, 0xD01B}, {0xD01C, 0xD01C, 0xD01C}, {0xD01D, 0xD01D, 0xD01D}, {0xD01E, 0xD01E, 0xD01E}, {0xD01F, 0xD01F, 0xD01F}, {0xD020, 0xD020, 0xD020}, {0xD021, 0xD021, 0xD021}, {0xD022, 0xD022, 0xD022}, {0xD023, 0xD023, 0xD023}, {0xD024, 0xD024, 0xD024}, {0xD025, 0xD025, 0xD025}, {0xD026, 0xD026, 0xD026}, {0xD027, 0xD027, 0xD027}, {0xD028, 0xD028, 0xD028}, {0xD029, 0xD029, 0xD029}, {0xD02A, 0xD02A, 0xD02A}, {0xD02B, 0xD02B, 0xD02B}, {0xD02C, 0xD02C, 0xD02C}, {0xD02D, 0xD02D, 0xD02D}, {0xD02E, 0xD02E, 0xD02E}, {0xD02F, 0xD02F, 0xD02F}, {0xD030, 0xD030, 0xD030}, {0xD031, 0xD031, 0xD031}, {0xD032, 0xD032, 0xD032}, {0xD033, 0xD033, 0xD033}, {0xD034, 0xD034, 0xD034}, {0xD035, 0xD035, 0xD035}, {0xD036, 0xD036, 0xD036}, {0xD037, 0xD037, 0xD037}, {0xD038, 0xD038, 0xD038}, {0xD039, 0xD039, 0xD039}, {0xD03A, 0xD03A, 0xD03A}, {0xD03B, 0xD03B, 0xD03B}, {0xD03C, 0xD03C, 0xD03C}, {0xD03D, 0xD03D, 0xD03D}, {0xD03E, 0xD03E, 0xD03E}, {0xD03F, 0xD03F, 0xD03F}, {0xD040, 0xD040, 0xD040}, {0xD041, 0xD041, 0xD041}, {0xD042, 0xD042, 0xD042}, {0xD043, 0xD043, 0xD043}, {0xD044, 0xD044, 0xD044}, {0xD045, 0xD045, 0xD045}, {0xD046, 0xD046, 0xD046}, {0xD047, 0xD047, 0xD047}, {0xD048, 0xD048, 0xD048}, {0xD049, 0xD049, 0xD049}, {0xD04A, 0xD04A, 0xD04A}, {0xD04B, 0xD04B, 0xD04B}, {0xD04C, 0xD04C, 0xD04C}, {0xD04D, 0xD04D, 0xD04D}, {0xD04E, 0xD04E, 0xD04E}, {0xD04F, 0xD04F, 0xD04F}, {0xD050, 0xD050, 0xD050}, {0xD051, 0xD051, 0xD051}, {0xD052, 0xD052, 0xD052}, {0xD053, 0xD053, 0xD053}, {0xD054, 0xD054, 0xD054}, {0xD055, 0xD055, 0xD055}, {0xD056, 0xD056, 0xD056}, {0xD057, 0xD057, 0xD057}, {0xD058, 0xD058, 0xD058}, {0xD059, 0xD059, 0xD059}, {0xD05A, 0xD05A, 0xD05A}, {0xD05B, 0xD05B, 0xD05B}, {0xD05C, 0xD05C, 0xD05C}, {0xD05D, 0xD05D, 0xD05D}, {0xD05E, 0xD05E, 0xD05E}, {0xD05F, 0xD05F, 0xD05F}, {0xD060, 0xD060, 0xD060}, {0xD061, 0xD061, 0xD061}, {0xD062, 0xD062, 0xD062}, {0xD063, 0xD063, 0xD063}, {0xD064, 0xD064, 0xD064}, {0xD065, 0xD065, 0xD065}, {0xD066, 0xD066, 0xD066}, {0xD067, 0xD067, 0xD067}, {0xD068, 0xD068, 0xD068}, {0xD069, 0xD069, 0xD069}, {0xD06A, 0xD06A, 0xD06A}, {0xD06B, 0xD06B, 0xD06B}, {0xD06C, 0xD06C, 0xD06C}, {0xD06D, 0xD06D, 0xD06D}, {0xD06E, 0xD06E, 0xD06E}, {0xD06F, 0xD06F, 0xD06F}, {0xD070, 0xD070, 0xD070}, {0xD071, 0xD071, 0xD071}, {0xD072, 0xD072, 0xD072}, {0xD073, 0xD073, 0xD073}, {0xD074, 0xD074, 0xD074}, {0xD075, 0xD075, 0xD075}, {0xD076, 0xD076, 0xD076}, {0xD077, 0xD077, 0xD077}, {0xD078, 0xD078, 0xD078}, {0xD079, 0xD079, 0xD079}, {0xD07A, 0xD07A, 0xD07A}, {0xD07B, 0xD07B, 0xD07B}, {0xD07C, 0xD07C, 0xD07C}, {0xD07D, 0xD07D, 0xD07D}, {0xD07E, 0xD07E, 0xD07E}, {0xD07F, 0xD07F, 0xD07F}, {0xD080, 0xD080, 0xD080}, {0xD081, 0xD081, 0xD081}, {0xD082, 0xD082, 0xD082}, {0xD083, 0xD083, 0xD083}, {0xD084, 0xD084, 0xD084}, {0xD085, 0xD085, 0xD085}, {0xD086, 0xD086, 0xD086}, {0xD087, 0xD087, 0xD087}, {0xD088, 0xD088, 0xD088}, {0xD089, 0xD089, 0xD089}, {0xD08A, 0xD08A, 0xD08A}, {0xD08B, 0xD08B, 0xD08B}, {0xD08C, 0xD08C, 0xD08C}, {0xD08D, 0xD08D, 0xD08D}, {0xD08E, 0xD08E, 0xD08E}, {0xD08F, 0xD08F, 0xD08F}, {0xD090, 0xD090, 0xD090}, {0xD091, 0xD091, 0xD091}, {0xD092, 0xD092, 0xD092}, {0xD093, 0xD093, 0xD093}, {0xD094, 0xD094, 0xD094}, {0xD095, 0xD095, 0xD095}, {0xD096, 0xD096, 0xD096}, {0xD097, 0xD097, 0xD097}, {0xD098, 0xD098, 0xD098}, {0xD099, 0xD099, 0xD099}, {0xD09A, 0xD09A, 0xD09A}, {0xD09B, 0xD09B, 0xD09B}, {0xD09C, 0xD09C, 0xD09C}, {0xD09D, 0xD09D, 0xD09D}, {0xD09E, 0xD09E, 0xD09E}, {0xD09F, 0xD09F, 0xD09F}, {0xD0A0, 0xD0A0, 0xD0A0}, {0xD0A1, 0xD0A1, 0xD0A1}, {0xD0A2, 0xD0A2, 0xD0A2}, {0xD0A3, 0xD0A3, 0xD0A3}, {0xD0A4, 0xD0A4, 0xD0A4}, {0xD0A5, 0xD0A5, 0xD0A5}, {0xD0A6, 0xD0A6, 0xD0A6}, {0xD0A7, 0xD0A7, 0xD0A7}, {0xD0A8, 0xD0A8, 0xD0A8}, {0xD0A9, 0xD0A9, 0xD0A9}, {0xD0AA, 0xD0AA, 0xD0AA}, {0xD0AB, 0xD0AB, 0xD0AB}, {0xD0AC, 0xD0AC, 0xD0AC}, {0xD0AD, 0xD0AD, 0xD0AD}, {0xD0AE, 0xD0AE, 0xD0AE}, {0xD0AF, 0xD0AF, 0xD0AF}, {0xD0B0, 0xD0B0, 0xD0B0}, {0xD0B1, 0xD0B1, 0xD0B1}, {0xD0B2, 0xD0B2, 0xD0B2}, {0xD0B3, 0xD0B3, 0xD0B3}, {0xD0B4, 0xD0B4, 0xD0B4}, {0xD0B5, 0xD0B5, 0xD0B5}, {0xD0B6, 0xD0B6, 0xD0B6}, {0xD0B7, 0xD0B7, 0xD0B7}, {0xD0B8, 0xD0B8, 0xD0B8}, {0xD0B9, 0xD0B9, 0xD0B9}, {0xD0BA, 0xD0BA, 0xD0BA}, {0xD0BB, 0xD0BB, 0xD0BB}, {0xD0BC, 0xD0BC, 0xD0BC}, {0xD0BD, 0xD0BD, 0xD0BD}, {0xD0BE, 0xD0BE, 0xD0BE}, {0xD0BF, 0xD0BF, 0xD0BF}, {0xD0C0, 0xD0C0, 0xD0C0}, {0xD0C1, 0xD0C1, 0xD0C1}, {0xD0C2, 0xD0C2, 0xD0C2}, {0xD0C3, 0xD0C3, 0xD0C3}, {0xD0C4, 0xD0C4, 0xD0C4}, {0xD0C5, 0xD0C5, 0xD0C5}, {0xD0C6, 0xD0C6, 0xD0C6}, {0xD0C7, 0xD0C7, 0xD0C7}, {0xD0C8, 0xD0C8, 0xD0C8}, {0xD0C9, 0xD0C9, 0xD0C9}, {0xD0CA, 0xD0CA, 0xD0CA}, {0xD0CB, 0xD0CB, 0xD0CB}, {0xD0CC, 0xD0CC, 0xD0CC}, {0xD0CD, 0xD0CD, 0xD0CD}, {0xD0CE, 0xD0CE, 0xD0CE}, {0xD0CF, 0xD0CF, 0xD0CF}, {0xD0D0, 0xD0D0, 0xD0D0}, {0xD0D1, 0xD0D1, 0xD0D1}, {0xD0D2, 0xD0D2, 0xD0D2}, {0xD0D3, 0xD0D3, 0xD0D3}, {0xD0D4, 0xD0D4, 0xD0D4}, {0xD0D5, 0xD0D5, 0xD0D5}, {0xD0D6, 0xD0D6, 0xD0D6}, {0xD0D7, 0xD0D7, 0xD0D7}, {0xD0D8, 0xD0D8, 0xD0D8}, {0xD0D9, 0xD0D9, 0xD0D9}, {0xD0DA, 0xD0DA, 0xD0DA}, {0xD0DB, 0xD0DB, 0xD0DB}, {0xD0DC, 0xD0DC, 0xD0DC}, {0xD0DD, 0xD0DD, 0xD0DD}, {0xD0DE, 0xD0DE, 0xD0DE}, {0xD0DF, 0xD0DF, 0xD0DF}, {0xD0E0, 0xD0E0, 0xD0E0}, {0xD0E1, 0xD0E1, 0xD0E1}, {0xD0E2, 0xD0E2, 0xD0E2}, {0xD0E3, 0xD0E3, 0xD0E3}, {0xD0E4, 0xD0E4, 0xD0E4}, {0xD0E5, 0xD0E5, 0xD0E5}, {0xD0E6, 0xD0E6, 0xD0E6}, {0xD0E7, 0xD0E7, 0xD0E7}, {0xD0E8, 0xD0E8, 0xD0E8}, {0xD0E9, 0xD0E9, 0xD0E9}, {0xD0EA, 0xD0EA, 0xD0EA}, {0xD0EB, 0xD0EB, 0xD0EB}, {0xD0EC, 0xD0EC, 0xD0EC}, {0xD0ED, 0xD0ED, 0xD0ED}, {0xD0EE, 0xD0EE, 0xD0EE}, {0xD0EF, 0xD0EF, 0xD0EF}, {0xD0F0, 0xD0F0, 0xD0F0}, {0xD0F1, 0xD0F1, 0xD0F1}, {0xD0F2, 0xD0F2, 0xD0F2}, {0xD0F3, 0xD0F3, 0xD0F3}, {0xD0F4, 0xD0F4, 0xD0F4}, {0xD0F5, 0xD0F5, 0xD0F5}, {0xD0F6, 0xD0F6, 0xD0F6}, {0xD0F7, 0xD0F7, 0xD0F7}, {0xD0F8, 0xD0F8, 0xD0F8}, {0xD0F9, 0xD0F9, 0xD0F9}, {0xD0FA, 0xD0FA, 0xD0FA}, {0xD0FB, 0xD0FB, 0xD0FB}, {0xD0FC, 0xD0FC, 0xD0FC}, {0xD0FD, 0xD0FD, 0xD0FD}, {0xD0FE, 0xD0FE, 0xD0FE}, {0xD0FF, 0xD0FF, 0xD0FF}, {0xD100, 0xD100, 0xD100}, {0xD101, 0xD101, 0xD101}, {0xD102, 0xD102, 0xD102}, {0xD103, 0xD103, 0xD103}, {0xD104, 0xD104, 0xD104}, {0xD105, 0xD105, 0xD105}, {0xD106, 0xD106, 0xD106}, {0xD107, 0xD107, 0xD107}, {0xD108, 0xD108, 0xD108}, {0xD109, 0xD109, 0xD109}, {0xD10A, 0xD10A, 0xD10A}, {0xD10B, 0xD10B, 0xD10B}, {0xD10C, 0xD10C, 0xD10C}, {0xD10D, 0xD10D, 0xD10D}, {0xD10E, 0xD10E, 0xD10E}, {0xD10F, 0xD10F, 0xD10F}, {0xD110, 0xD110, 0xD110}, {0xD111, 0xD111, 0xD111}, {0xD112, 0xD112, 0xD112}, {0xD113, 0xD113, 0xD113}, {0xD114, 0xD114, 0xD114}, {0xD115, 0xD115, 0xD115}, {0xD116, 0xD116, 0xD116}, {0xD117, 0xD117, 0xD117}, {0xD118, 0xD118, 0xD118}, {0xD119, 0xD119, 0xD119}, {0xD11A, 0xD11A, 0xD11A}, {0xD11B, 0xD11B, 0xD11B}, {0xD11C, 0xD11C, 0xD11C}, {0xD11D, 0xD11D, 0xD11D}, {0xD11E, 0xD11E, 0xD11E}, {0xD11F, 0xD11F, 0xD11F}, {0xD120, 0xD120, 0xD120}, {0xD121, 0xD121, 0xD121}, {0xD122, 0xD122, 0xD122}, {0xD123, 0xD123, 0xD123}, {0xD124, 0xD124, 0xD124}, {0xD125, 0xD125, 0xD125}, {0xD126, 0xD126, 0xD126}, {0xD127, 0xD127, 0xD127}, {0xD128, 0xD128, 0xD128}, {0xD129, 0xD129, 0xD129}, {0xD12A, 0xD12A, 0xD12A}, {0xD12B, 0xD12B, 0xD12B}, {0xD12C, 0xD12C, 0xD12C}, {0xD12D, 0xD12D, 0xD12D}, {0xD12E, 0xD12E, 0xD12E}, {0xD12F, 0xD12F, 0xD12F}, {0xD130, 0xD130, 0xD130}, {0xD131, 0xD131, 0xD131}, {0xD132, 0xD132, 0xD132}, {0xD133, 0xD133, 0xD133}, {0xD134, 0xD134, 0xD134}, {0xD135, 0xD135, 0xD135}, {0xD136, 0xD136, 0xD136}, {0xD137, 0xD137, 0xD137}, {0xD138, 0xD138, 0xD138}, {0xD139, 0xD139, 0xD139}, {0xD13A, 0xD13A, 0xD13A}, {0xD13B, 0xD13B, 0xD13B}, {0xD13C, 0xD13C, 0xD13C}, {0xD13D, 0xD13D, 0xD13D}, {0xD13E, 0xD13E, 0xD13E}, {0xD13F, 0xD13F, 0xD13F}, {0xD140, 0xD140, 0xD140}, {0xD141, 0xD141, 0xD141}, {0xD142, 0xD142, 0xD142}, {0xD143, 0xD143, 0xD143}, {0xD144, 0xD144, 0xD144}, {0xD145, 0xD145, 0xD145}, {0xD146, 0xD146, 0xD146}, {0xD147, 0xD147, 0xD147}, {0xD148, 0xD148, 0xD148}, {0xD149, 0xD149, 0xD149}, {0xD14A, 0xD14A, 0xD14A}, {0xD14B, 0xD14B, 0xD14B}, {0xD14C, 0xD14C, 0xD14C}, {0xD14D, 0xD14D, 0xD14D}, {0xD14E, 0xD14E, 0xD14E}, {0xD14F, 0xD14F, 0xD14F}, {0xD150, 0xD150, 0xD150}, {0xD151, 0xD151, 0xD151}, {0xD152, 0xD152, 0xD152}, {0xD153, 0xD153, 0xD153}, {0xD154, 0xD154, 0xD154}, {0xD155, 0xD155, 0xD155}, {0xD156, 0xD156, 0xD156}, {0xD157, 0xD157, 0xD157}, {0xD158, 0xD158, 0xD158}, {0xD159, 0xD159, 0xD159}, {0xD15A, 0xD15A, 0xD15A}, {0xD15B, 0xD15B, 0xD15B}, {0xD15C, 0xD15C, 0xD15C}, {0xD15D, 0xD15D, 0xD15D}, {0xD15E, 0xD15E, 0xD15E}, {0xD15F, 0xD15F, 0xD15F}, {0xD160, 0xD160, 0xD160}, {0xD161, 0xD161, 0xD161}, {0xD162, 0xD162, 0xD162}, {0xD163, 0xD163, 0xD163}, {0xD164, 0xD164, 0xD164}, {0xD165, 0xD165, 0xD165}, {0xD166, 0xD166, 0xD166}, {0xD167, 0xD167, 0xD167}, {0xD168, 0xD168, 0xD168}, {0xD169, 0xD169, 0xD169}, {0xD16A, 0xD16A, 0xD16A}, {0xD16B, 0xD16B, 0xD16B}, {0xD16C, 0xD16C, 0xD16C}, {0xD16D, 0xD16D, 0xD16D}, {0xD16E, 0xD16E, 0xD16E}, {0xD16F, 0xD16F, 0xD16F}, {0xD170, 0xD170, 0xD170}, {0xD171, 0xD171, 0xD171}, {0xD172, 0xD172, 0xD172}, {0xD173, 0xD173, 0xD173}, {0xD174, 0xD174, 0xD174}, {0xD175, 0xD175, 0xD175}, {0xD176, 0xD176, 0xD176}, {0xD177, 0xD177, 0xD177}, {0xD178, 0xD178, 0xD178}, {0xD179, 0xD179, 0xD179}, {0xD17A, 0xD17A, 0xD17A}, {0xD17B, 0xD17B, 0xD17B}, {0xD17C, 0xD17C, 0xD17C}, {0xD17D, 0xD17D, 0xD17D}, {0xD17E, 0xD17E, 0xD17E}, {0xD17F, 0xD17F, 0xD17F}, {0xD180, 0xD180, 0xD180}, {0xD181, 0xD181, 0xD181}, {0xD182, 0xD182, 0xD182}, {0xD183, 0xD183, 0xD183}, {0xD184, 0xD184, 0xD184}, {0xD185, 0xD185, 0xD185}, {0xD186, 0xD186, 0xD186}, {0xD187, 0xD187, 0xD187}, {0xD188, 0xD188, 0xD188}, {0xD189, 0xD189, 0xD189}, {0xD18A, 0xD18A, 0xD18A}, {0xD18B, 0xD18B, 0xD18B}, {0xD18C, 0xD18C, 0xD18C}, {0xD18D, 0xD18D, 0xD18D}, {0xD18E, 0xD18E, 0xD18E}, {0xD18F, 0xD18F, 0xD18F}, {0xD190, 0xD190, 0xD190}, {0xD191, 0xD191, 0xD191}, {0xD192, 0xD192, 0xD192}, {0xD193, 0xD193, 0xD193}, {0xD194, 0xD194, 0xD194}, {0xD195, 0xD195, 0xD195}, {0xD196, 0xD196, 0xD196}, {0xD197, 0xD197, 0xD197}, {0xD198, 0xD198, 0xD198}, {0xD199, 0xD199, 0xD199}, {0xD19A, 0xD19A, 0xD19A}, {0xD19B, 0xD19B, 0xD19B}, {0xD19C, 0xD19C, 0xD19C}, {0xD19D, 0xD19D, 0xD19D}, {0xD19E, 0xD19E, 0xD19E}, {0xD19F, 0xD19F, 0xD19F}, {0xD1A0, 0xD1A0, 0xD1A0}, {0xD1A1, 0xD1A1, 0xD1A1}, {0xD1A2, 0xD1A2, 0xD1A2}, {0xD1A3, 0xD1A3, 0xD1A3}, {0xD1A4, 0xD1A4, 0xD1A4}, {0xD1A5, 0xD1A5, 0xD1A5}, {0xD1A6, 0xD1A6, 0xD1A6}, {0xD1A7, 0xD1A7, 0xD1A7}, {0xD1A8, 0xD1A8, 0xD1A8}, {0xD1A9, 0xD1A9, 0xD1A9}, {0xD1AA, 0xD1AA, 0xD1AA}, {0xD1AB, 0xD1AB, 0xD1AB}, {0xD1AC, 0xD1AC, 0xD1AC}, {0xD1AD, 0xD1AD, 0xD1AD}, {0xD1AE, 0xD1AE, 0xD1AE}, {0xD1AF, 0xD1AF, 0xD1AF}, {0xD1B0, 0xD1B0, 0xD1B0}, {0xD1B1, 0xD1B1, 0xD1B1}, {0xD1B2, 0xD1B2, 0xD1B2}, {0xD1B3, 0xD1B3, 0xD1B3}, {0xD1B4, 0xD1B4, 0xD1B4}, {0xD1B5, 0xD1B5, 0xD1B5}, {0xD1B6, 0xD1B6, 0xD1B6}, {0xD1B7, 0xD1B7, 0xD1B7}, {0xD1B8, 0xD1B8, 0xD1B8}, {0xD1B9, 0xD1B9, 0xD1B9}, {0xD1BA, 0xD1BA, 0xD1BA}, {0xD1BB, 0xD1BB, 0xD1BB}, {0xD1BC, 0xD1BC, 0xD1BC}, {0xD1BD, 0xD1BD, 0xD1BD}, {0xD1BE, 0xD1BE, 0xD1BE}, {0xD1BF, 0xD1BF, 0xD1BF}, {0xD1C0, 0xD1C0, 0xD1C0}, {0xD1C1, 0xD1C1, 0xD1C1}, {0xD1C2, 0xD1C2, 0xD1C2}, {0xD1C3, 0xD1C3, 0xD1C3}, {0xD1C4, 0xD1C4, 0xD1C4}, {0xD1C5, 0xD1C5, 0xD1C5}, {0xD1C6, 0xD1C6, 0xD1C6}, {0xD1C7, 0xD1C7, 0xD1C7}, {0xD1C8, 0xD1C8, 0xD1C8}, {0xD1C9, 0xD1C9, 0xD1C9}, {0xD1CA, 0xD1CA, 0xD1CA}, {0xD1CB, 0xD1CB, 0xD1CB}, {0xD1CC, 0xD1CC, 0xD1CC}, {0xD1CD, 0xD1CD, 0xD1CD}, {0xD1CE, 0xD1CE, 0xD1CE}, {0xD1CF, 0xD1CF, 0xD1CF}, {0xD1D0, 0xD1D0, 0xD1D0}, {0xD1D1, 0xD1D1, 0xD1D1}, {0xD1D2, 0xD1D2, 0xD1D2}, {0xD1D3, 0xD1D3, 0xD1D3}, {0xD1D4, 0xD1D4, 0xD1D4}, {0xD1D5, 0xD1D5, 0xD1D5}, {0xD1D6, 0xD1D6, 0xD1D6}, {0xD1D7, 0xD1D7, 0xD1D7}, {0xD1D8, 0xD1D8, 0xD1D8}, {0xD1D9, 0xD1D9, 0xD1D9}, {0xD1DA, 0xD1DA, 0xD1DA}, {0xD1DB, 0xD1DB, 0xD1DB}, {0xD1DC, 0xD1DC, 0xD1DC}, {0xD1DD, 0xD1DD, 0xD1DD}, {0xD1DE, 0xD1DE, 0xD1DE}, {0xD1DF, 0xD1DF, 0xD1DF}, {0xD1E0, 0xD1E0, 0xD1E0}, {0xD1E1, 0xD1E1, 0xD1E1}, {0xD1E2, 0xD1E2, 0xD1E2}, {0xD1E3, 0xD1E3, 0xD1E3}, {0xD1E4, 0xD1E4, 0xD1E4}, {0xD1E5, 0xD1E5, 0xD1E5}, {0xD1E6, 0xD1E6, 0xD1E6}, {0xD1E7, 0xD1E7, 0xD1E7}, {0xD1E8, 0xD1E8, 0xD1E8}, {0xD1E9, 0xD1E9, 0xD1E9}, {0xD1EA, 0xD1EA, 0xD1EA}, {0xD1EB, 0xD1EB, 0xD1EB}, {0xD1EC, 0xD1EC, 0xD1EC}, {0xD1ED, 0xD1ED, 0xD1ED}, {0xD1EE, 0xD1EE, 0xD1EE}, {0xD1EF, 0xD1EF, 0xD1EF}, {0xD1F0, 0xD1F0, 0xD1F0}, {0xD1F1, 0xD1F1, 0xD1F1}, {0xD1F2, 0xD1F2, 0xD1F2}, {0xD1F3, 0xD1F3, 0xD1F3}, {0xD1F4, 0xD1F4, 0xD1F4}, {0xD1F5, 0xD1F5, 0xD1F5}, {0xD1F6, 0xD1F6, 0xD1F6}, {0xD1F7, 0xD1F7, 0xD1F7}, {0xD1F8, 0xD1F8, 0xD1F8}, {0xD1F9, 0xD1F9, 0xD1F9}, {0xD1FA, 0xD1FA, 0xD1FA}, {0xD1FB, 0xD1FB, 0xD1FB}, {0xD1FC, 0xD1FC, 0xD1FC}, {0xD1FD, 0xD1FD, 0xD1FD}, {0xD1FE, 0xD1FE, 0xD1FE}, {0xD1FF, 0xD1FF, 0xD1FF}, {0xD200, 0xD200, 0xD200}, {0xD201, 0xD201, 0xD201}, {0xD202, 0xD202, 0xD202}, {0xD203, 0xD203, 0xD203}, {0xD204, 0xD204, 0xD204}, {0xD205, 0xD205, 0xD205}, {0xD206, 0xD206, 0xD206}, {0xD207, 0xD207, 0xD207}, {0xD208, 0xD208, 0xD208}, {0xD209, 0xD209, 0xD209}, {0xD20A, 0xD20A, 0xD20A}, {0xD20B, 0xD20B, 0xD20B}, {0xD20C, 0xD20C, 0xD20C}, {0xD20D, 0xD20D, 0xD20D}, {0xD20E, 0xD20E, 0xD20E}, {0xD20F, 0xD20F, 0xD20F}, {0xD210, 0xD210, 0xD210}, {0xD211, 0xD211, 0xD211}, {0xD212, 0xD212, 0xD212}, {0xD213, 0xD213, 0xD213}, {0xD214, 0xD214, 0xD214}, {0xD215, 0xD215, 0xD215}, {0xD216, 0xD216, 0xD216}, {0xD217, 0xD217, 0xD217}, {0xD218, 0xD218, 0xD218}, {0xD219, 0xD219, 0xD219}, {0xD21A, 0xD21A, 0xD21A}, {0xD21B, 0xD21B, 0xD21B}, {0xD21C, 0xD21C, 0xD21C}, {0xD21D, 0xD21D, 0xD21D}, {0xD21E, 0xD21E, 0xD21E}, {0xD21F, 0xD21F, 0xD21F}, {0xD220, 0xD220, 0xD220}, {0xD221, 0xD221, 0xD221}, {0xD222, 0xD222, 0xD222}, {0xD223, 0xD223, 0xD223}, {0xD224, 0xD224, 0xD224}, {0xD225, 0xD225, 0xD225}, {0xD226, 0xD226, 0xD226}, {0xD227, 0xD227, 0xD227}, {0xD228, 0xD228, 0xD228}, {0xD229, 0xD229, 0xD229}, {0xD22A, 0xD22A, 0xD22A}, {0xD22B, 0xD22B, 0xD22B}, {0xD22C, 0xD22C, 0xD22C}, {0xD22D, 0xD22D, 0xD22D}, {0xD22E, 0xD22E, 0xD22E}, {0xD22F, 0xD22F, 0xD22F}, {0xD230, 0xD230, 0xD230}, {0xD231, 0xD231, 0xD231}, {0xD232, 0xD232, 0xD232}, {0xD233, 0xD233, 0xD233}, {0xD234, 0xD234, 0xD234}, {0xD235, 0xD235, 0xD235}, {0xD236, 0xD236, 0xD236}, {0xD237, 0xD237, 0xD237}, {0xD238, 0xD238, 0xD238}, {0xD239, 0xD239, 0xD239}, {0xD23A, 0xD23A, 0xD23A}, {0xD23B, 0xD23B, 0xD23B}, {0xD23C, 0xD23C, 0xD23C}, {0xD23D, 0xD23D, 0xD23D}, {0xD23E, 0xD23E, 0xD23E}, {0xD23F, 0xD23F, 0xD23F}, {0xD240, 0xD240, 0xD240}, {0xD241, 0xD241, 0xD241}, {0xD242, 0xD242, 0xD242}, {0xD243, 0xD243, 0xD243}, {0xD244, 0xD244, 0xD244}, {0xD245, 0xD245, 0xD245}, {0xD246, 0xD246, 0xD246}, {0xD247, 0xD247, 0xD247}, {0xD248, 0xD248, 0xD248}, {0xD249, 0xD249, 0xD249}, {0xD24A, 0xD24A, 0xD24A}, {0xD24B, 0xD24B, 0xD24B}, {0xD24C, 0xD24C, 0xD24C}, {0xD24D, 0xD24D, 0xD24D}, {0xD24E, 0xD24E, 0xD24E}, {0xD24F, 0xD24F, 0xD24F}, {0xD250, 0xD250, 0xD250}, {0xD251, 0xD251, 0xD251}, {0xD252, 0xD252, 0xD252}, {0xD253, 0xD253, 0xD253}, {0xD254, 0xD254, 0xD254}, {0xD255, 0xD255, 0xD255}, {0xD256, 0xD256, 0xD256}, {0xD257, 0xD257, 0xD257}, {0xD258, 0xD258, 0xD258}, {0xD259, 0xD259, 0xD259}, {0xD25A, 0xD25A, 0xD25A}, {0xD25B, 0xD25B, 0xD25B}, {0xD25C, 0xD25C, 0xD25C}, {0xD25D, 0xD25D, 0xD25D}, {0xD25E, 0xD25E, 0xD25E}, {0xD25F, 0xD25F, 0xD25F}, {0xD260, 0xD260, 0xD260}, {0xD261, 0xD261, 0xD261}, {0xD262, 0xD262, 0xD262}, {0xD263, 0xD263, 0xD263}, {0xD264, 0xD264, 0xD264}, {0xD265, 0xD265, 0xD265}, {0xD266, 0xD266, 0xD266}, {0xD267, 0xD267, 0xD267}, {0xD268, 0xD268, 0xD268}, {0xD269, 0xD269, 0xD269}, {0xD26A, 0xD26A, 0xD26A}, {0xD26B, 0xD26B, 0xD26B}, {0xD26C, 0xD26C, 0xD26C}, {0xD26D, 0xD26D, 0xD26D}, {0xD26E, 0xD26E, 0xD26E}, {0xD26F, 0xD26F, 0xD26F}, {0xD270, 0xD270, 0xD270}, {0xD271, 0xD271, 0xD271}, {0xD272, 0xD272, 0xD272}, {0xD273, 0xD273, 0xD273}, {0xD274, 0xD274, 0xD274}, {0xD275, 0xD275, 0xD275}, {0xD276, 0xD276, 0xD276}, {0xD277, 0xD277, 0xD277}, {0xD278, 0xD278, 0xD278}, {0xD279, 0xD279, 0xD279}, {0xD27A, 0xD27A, 0xD27A}, {0xD27B, 0xD27B, 0xD27B}, {0xD27C, 0xD27C, 0xD27C}, {0xD27D, 0xD27D, 0xD27D}, {0xD27E, 0xD27E, 0xD27E}, {0xD27F, 0xD27F, 0xD27F}, {0xD280, 0xD280, 0xD280}, {0xD281, 0xD281, 0xD281}, {0xD282, 0xD282, 0xD282}, {0xD283, 0xD283, 0xD283}, {0xD284, 0xD284, 0xD284}, {0xD285, 0xD285, 0xD285}, {0xD286, 0xD286, 0xD286}, {0xD287, 0xD287, 0xD287}, {0xD288, 0xD288, 0xD288}, {0xD289, 0xD289, 0xD289}, {0xD28A, 0xD28A, 0xD28A}, {0xD28B, 0xD28B, 0xD28B}, {0xD28C, 0xD28C, 0xD28C}, {0xD28D, 0xD28D, 0xD28D}, {0xD28E, 0xD28E, 0xD28E}, {0xD28F, 0xD28F, 0xD28F}, {0xD290, 0xD290, 0xD290}, {0xD291, 0xD291, 0xD291}, {0xD292, 0xD292, 0xD292}, {0xD293, 0xD293, 0xD293}, {0xD294, 0xD294, 0xD294}, {0xD295, 0xD295, 0xD295}, {0xD296, 0xD296, 0xD296}, {0xD297, 0xD297, 0xD297}, {0xD298, 0xD298, 0xD298}, {0xD299, 0xD299, 0xD299}, {0xD29A, 0xD29A, 0xD29A}, {0xD29B, 0xD29B, 0xD29B}, {0xD29C, 0xD29C, 0xD29C}, {0xD29D, 0xD29D, 0xD29D}, {0xD29E, 0xD29E, 0xD29E}, {0xD29F, 0xD29F, 0xD29F}, {0xD2A0, 0xD2A0, 0xD2A0}, {0xD2A1, 0xD2A1, 0xD2A1}, {0xD2A2, 0xD2A2, 0xD2A2}, {0xD2A3, 0xD2A3, 0xD2A3}, {0xD2A4, 0xD2A4, 0xD2A4}, {0xD2A5, 0xD2A5, 0xD2A5}, {0xD2A6, 0xD2A6, 0xD2A6}, {0xD2A7, 0xD2A7, 0xD2A7}, {0xD2A8, 0xD2A8, 0xD2A8}, {0xD2A9, 0xD2A9, 0xD2A9}, {0xD2AA, 0xD2AA, 0xD2AA}, {0xD2AB, 0xD2AB, 0xD2AB}, {0xD2AC, 0xD2AC, 0xD2AC}, {0xD2AD, 0xD2AD, 0xD2AD}, {0xD2AE, 0xD2AE, 0xD2AE}, {0xD2AF, 0xD2AF, 0xD2AF}, {0xD2B0, 0xD2B0, 0xD2B0}, {0xD2B1, 0xD2B1, 0xD2B1}, {0xD2B2, 0xD2B2, 0xD2B2}, {0xD2B3, 0xD2B3, 0xD2B3}, {0xD2B4, 0xD2B4, 0xD2B4}, {0xD2B5, 0xD2B5, 0xD2B5}, {0xD2B6, 0xD2B6, 0xD2B6}, {0xD2B7, 0xD2B7, 0xD2B7}, {0xD2B8, 0xD2B8, 0xD2B8}, {0xD2B9, 0xD2B9, 0xD2B9}, {0xD2BA, 0xD2BA, 0xD2BA}, {0xD2BB, 0xD2BB, 0xD2BB}, {0xD2BC, 0xD2BC, 0xD2BC}, {0xD2BD, 0xD2BD, 0xD2BD}, {0xD2BE, 0xD2BE, 0xD2BE}, {0xD2BF, 0xD2BF, 0xD2BF}, {0xD2C0, 0xD2C0, 0xD2C0}, {0xD2C1, 0xD2C1, 0xD2C1}, {0xD2C2, 0xD2C2, 0xD2C2}, {0xD2C3, 0xD2C3, 0xD2C3}, {0xD2C4, 0xD2C4, 0xD2C4}, {0xD2C5, 0xD2C5, 0xD2C5}, {0xD2C6, 0xD2C6, 0xD2C6}, {0xD2C7, 0xD2C7, 0xD2C7}, {0xD2C8, 0xD2C8, 0xD2C8}, {0xD2C9, 0xD2C9, 0xD2C9}, {0xD2CA, 0xD2CA, 0xD2CA}, {0xD2CB, 0xD2CB, 0xD2CB}, {0xD2CC, 0xD2CC, 0xD2CC}, {0xD2CD, 0xD2CD, 0xD2CD}, {0xD2CE, 0xD2CE, 0xD2CE}, {0xD2CF, 0xD2CF, 0xD2CF}, {0xD2D0, 0xD2D0, 0xD2D0}, {0xD2D1, 0xD2D1, 0xD2D1}, {0xD2D2, 0xD2D2, 0xD2D2}, {0xD2D3, 0xD2D3, 0xD2D3}, {0xD2D4, 0xD2D4, 0xD2D4}, {0xD2D5, 0xD2D5, 0xD2D5}, {0xD2D6, 0xD2D6, 0xD2D6}, {0xD2D7, 0xD2D7, 0xD2D7}, {0xD2D8, 0xD2D8, 0xD2D8}, {0xD2D9, 0xD2D9, 0xD2D9}, {0xD2DA, 0xD2DA, 0xD2DA}, {0xD2DB, 0xD2DB, 0xD2DB}, {0xD2DC, 0xD2DC, 0xD2DC}, {0xD2DD, 0xD2DD, 0xD2DD}, {0xD2DE, 0xD2DE, 0xD2DE}, {0xD2DF, 0xD2DF, 0xD2DF}, {0xD2E0, 0xD2E0, 0xD2E0}, {0xD2E1, 0xD2E1, 0xD2E1}, {0xD2E2, 0xD2E2, 0xD2E2}, {0xD2E3, 0xD2E3, 0xD2E3}, {0xD2E4, 0xD2E4, 0xD2E4}, {0xD2E5, 0xD2E5, 0xD2E5}, {0xD2E6, 0xD2E6, 0xD2E6}, {0xD2E7, 0xD2E7, 0xD2E7}, {0xD2E8, 0xD2E8, 0xD2E8}, {0xD2E9, 0xD2E9, 0xD2E9}, {0xD2EA, 0xD2EA, 0xD2EA}, {0xD2EB, 0xD2EB, 0xD2EB}, {0xD2EC, 0xD2EC, 0xD2EC}, {0xD2ED, 0xD2ED, 0xD2ED}, {0xD2EE, 0xD2EE, 0xD2EE}, {0xD2EF, 0xD2EF, 0xD2EF}, {0xD2F0, 0xD2F0, 0xD2F0}, {0xD2F1, 0xD2F1, 0xD2F1}, {0xD2F2, 0xD2F2, 0xD2F2}, {0xD2F3, 0xD2F3, 0xD2F3}, {0xD2F4, 0xD2F4, 0xD2F4}, {0xD2F5, 0xD2F5, 0xD2F5}, {0xD2F6, 0xD2F6, 0xD2F6}, {0xD2F7, 0xD2F7, 0xD2F7}, {0xD2F8, 0xD2F8, 0xD2F8}, {0xD2F9, 0xD2F9, 0xD2F9}, {0xD2FA, 0xD2FA, 0xD2FA}, {0xD2FB, 0xD2FB, 0xD2FB}, {0xD2FC, 0xD2FC, 0xD2FC}, {0xD2FD, 0xD2FD, 0xD2FD}, {0xD2FE, 0xD2FE, 0xD2FE}, {0xD2FF, 0xD2FF, 0xD2FF}, {0xD300, 0xD300, 0xD300}, {0xD301, 0xD301, 0xD301}, {0xD302, 0xD302, 0xD302}, {0xD303, 0xD303, 0xD303}, {0xD304, 0xD304, 0xD304}, {0xD305, 0xD305, 0xD305}, {0xD306, 0xD306, 0xD306}, {0xD307, 0xD307, 0xD307}, {0xD308, 0xD308, 0xD308}, {0xD309, 0xD309, 0xD309}, {0xD30A, 0xD30A, 0xD30A}, {0xD30B, 0xD30B, 0xD30B}, {0xD30C, 0xD30C, 0xD30C}, {0xD30D, 0xD30D, 0xD30D}, {0xD30E, 0xD30E, 0xD30E}, {0xD30F, 0xD30F, 0xD30F}, {0xD310, 0xD310, 0xD310}, {0xD311, 0xD311, 0xD311}, {0xD312, 0xD312, 0xD312}, {0xD313, 0xD313, 0xD313}, {0xD314, 0xD314, 0xD314}, {0xD315, 0xD315, 0xD315}, {0xD316, 0xD316, 0xD316}, {0xD317, 0xD317, 0xD317}, {0xD318, 0xD318, 0xD318}, {0xD319, 0xD319, 0xD319}, {0xD31A, 0xD31A, 0xD31A}, {0xD31B, 0xD31B, 0xD31B}, {0xD31C, 0xD31C, 0xD31C}, {0xD31D, 0xD31D, 0xD31D}, {0xD31E, 0xD31E, 0xD31E}, {0xD31F, 0xD31F, 0xD31F}, {0xD320, 0xD320, 0xD320}, {0xD321, 0xD321, 0xD321}, {0xD322, 0xD322, 0xD322}, {0xD323, 0xD323, 0xD323}, {0xD324, 0xD324, 0xD324}, {0xD325, 0xD325, 0xD325}, {0xD326, 0xD326, 0xD326}, {0xD327, 0xD327, 0xD327}, {0xD328, 0xD328, 0xD328}, {0xD329, 0xD329, 0xD329}, {0xD32A, 0xD32A, 0xD32A}, {0xD32B, 0xD32B, 0xD32B}, {0xD32C, 0xD32C, 0xD32C}, {0xD32D, 0xD32D, 0xD32D}, {0xD32E, 0xD32E, 0xD32E}, {0xD32F, 0xD32F, 0xD32F}, {0xD330, 0xD330, 0xD330}, {0xD331, 0xD331, 0xD331}, {0xD332, 0xD332, 0xD332}, {0xD333, 0xD333, 0xD333}, {0xD334, 0xD334, 0xD334}, {0xD335, 0xD335, 0xD335}, {0xD336, 0xD336, 0xD336}, {0xD337, 0xD337, 0xD337}, {0xD338, 0xD338, 0xD338}, {0xD339, 0xD339, 0xD339}, {0xD33A, 0xD33A, 0xD33A}, {0xD33B, 0xD33B, 0xD33B}, {0xD33C, 0xD33C, 0xD33C}, {0xD33D, 0xD33D, 0xD33D}, {0xD33E, 0xD33E, 0xD33E}, {0xD33F, 0xD33F, 0xD33F}, {0xD340, 0xD340, 0xD340}, {0xD341, 0xD341, 0xD341}, {0xD342, 0xD342, 0xD342}, {0xD343, 0xD343, 0xD343}, {0xD344, 0xD344, 0xD344}, {0xD345, 0xD345, 0xD345}, {0xD346, 0xD346, 0xD346}, {0xD347, 0xD347, 0xD347}, {0xD348, 0xD348, 0xD348}, {0xD349, 0xD349, 0xD349}, {0xD34A, 0xD34A, 0xD34A}, {0xD34B, 0xD34B, 0xD34B}, {0xD34C, 0xD34C, 0xD34C}, {0xD34D, 0xD34D, 0xD34D}, {0xD34E, 0xD34E, 0xD34E}, {0xD34F, 0xD34F, 0xD34F}, {0xD350, 0xD350, 0xD350}, {0xD351, 0xD351, 0xD351}, {0xD352, 0xD352, 0xD352}, {0xD353, 0xD353, 0xD353}, {0xD354, 0xD354, 0xD354}, {0xD355, 0xD355, 0xD355}, {0xD356, 0xD356, 0xD356}, {0xD357, 0xD357, 0xD357}, {0xD358, 0xD358, 0xD358}, {0xD359, 0xD359, 0xD359}, {0xD35A, 0xD35A, 0xD35A}, {0xD35B, 0xD35B, 0xD35B}, {0xD35C, 0xD35C, 0xD35C}, {0xD35D, 0xD35D, 0xD35D}, {0xD35E, 0xD35E, 0xD35E}, {0xD35F, 0xD35F, 0xD35F}, {0xD360, 0xD360, 0xD360}, {0xD361, 0xD361, 0xD361}, {0xD362, 0xD362, 0xD362}, {0xD363, 0xD363, 0xD363}, {0xD364, 0xD364, 0xD364}, {0xD365, 0xD365, 0xD365}, {0xD366, 0xD366, 0xD366}, {0xD367, 0xD367, 0xD367}, {0xD368, 0xD368, 0xD368}, {0xD369, 0xD369, 0xD369}, {0xD36A, 0xD36A, 0xD36A}, {0xD36B, 0xD36B, 0xD36B}, {0xD36C, 0xD36C, 0xD36C}, {0xD36D, 0xD36D, 0xD36D}, {0xD36E, 0xD36E, 0xD36E}, {0xD36F, 0xD36F, 0xD36F}, {0xD370, 0xD370, 0xD370}, {0xD371, 0xD371, 0xD371}, {0xD372, 0xD372, 0xD372}, {0xD373, 0xD373, 0xD373}, {0xD374, 0xD374, 0xD374}, {0xD375, 0xD375, 0xD375}, {0xD376, 0xD376, 0xD376}, {0xD377, 0xD377, 0xD377}, {0xD378, 0xD378, 0xD378}, {0xD379, 0xD379, 0xD379}, {0xD37A, 0xD37A, 0xD37A}, {0xD37B, 0xD37B, 0xD37B}, {0xD37C, 0xD37C, 0xD37C}, {0xD37D, 0xD37D, 0xD37D}, {0xD37E, 0xD37E, 0xD37E}, {0xD37F, 0xD37F, 0xD37F}, {0xD380, 0xD380, 0xD380}, {0xD381, 0xD381, 0xD381}, {0xD382, 0xD382, 0xD382}, {0xD383, 0xD383, 0xD383}, {0xD384, 0xD384, 0xD384}, {0xD385, 0xD385, 0xD385}, {0xD386, 0xD386, 0xD386}, {0xD387, 0xD387, 0xD387}, {0xD388, 0xD388, 0xD388}, {0xD389, 0xD389, 0xD389}, {0xD38A, 0xD38A, 0xD38A}, {0xD38B, 0xD38B, 0xD38B}, {0xD38C, 0xD38C, 0xD38C}, {0xD38D, 0xD38D, 0xD38D}, {0xD38E, 0xD38E, 0xD38E}, {0xD38F, 0xD38F, 0xD38F}, {0xD390, 0xD390, 0xD390}, {0xD391, 0xD391, 0xD391}, {0xD392, 0xD392, 0xD392}, {0xD393, 0xD393, 0xD393}, {0xD394, 0xD394, 0xD394}, {0xD395, 0xD395, 0xD395}, {0xD396, 0xD396, 0xD396}, {0xD397, 0xD397, 0xD397}, {0xD398, 0xD398, 0xD398}, {0xD399, 0xD399, 0xD399}, {0xD39A, 0xD39A, 0xD39A}, {0xD39B, 0xD39B, 0xD39B}, {0xD39C, 0xD39C, 0xD39C}, {0xD39D, 0xD39D, 0xD39D}, {0xD39E, 0xD39E, 0xD39E}, {0xD39F, 0xD39F, 0xD39F}, {0xD3A0, 0xD3A0, 0xD3A0}, {0xD3A1, 0xD3A1, 0xD3A1}, {0xD3A2, 0xD3A2, 0xD3A2}, {0xD3A3, 0xD3A3, 0xD3A3}, {0xD3A4, 0xD3A4, 0xD3A4}, {0xD3A5, 0xD3A5, 0xD3A5}, {0xD3A6, 0xD3A6, 0xD3A6}, {0xD3A7, 0xD3A7, 0xD3A7}, {0xD3A8, 0xD3A8, 0xD3A8}, {0xD3A9, 0xD3A9, 0xD3A9}, {0xD3AA, 0xD3AA, 0xD3AA}, {0xD3AB, 0xD3AB, 0xD3AB}, {0xD3AC, 0xD3AC, 0xD3AC}, {0xD3AD, 0xD3AD, 0xD3AD}, {0xD3AE, 0xD3AE, 0xD3AE}, {0xD3AF, 0xD3AF, 0xD3AF}, {0xD3B0, 0xD3B0, 0xD3B0}, {0xD3B1, 0xD3B1, 0xD3B1}, {0xD3B2, 0xD3B2, 0xD3B2}, {0xD3B3, 0xD3B3, 0xD3B3}, {0xD3B4, 0xD3B4, 0xD3B4}, {0xD3B5, 0xD3B5, 0xD3B5}, {0xD3B6, 0xD3B6, 0xD3B6}, {0xD3B7, 0xD3B7, 0xD3B7}, {0xD3B8, 0xD3B8, 0xD3B8}, {0xD3B9, 0xD3B9, 0xD3B9}, {0xD3BA, 0xD3BA, 0xD3BA}, {0xD3BB, 0xD3BB, 0xD3BB}, {0xD3BC, 0xD3BC, 0xD3BC}, {0xD3BD, 0xD3BD, 0xD3BD}, {0xD3BE, 0xD3BE, 0xD3BE}, {0xD3BF, 0xD3BF, 0xD3BF}, {0xD3C0, 0xD3C0, 0xD3C0}, {0xD3C1, 0xD3C1, 0xD3C1}, {0xD3C2, 0xD3C2, 0xD3C2}, {0xD3C3, 0xD3C3, 0xD3C3}, {0xD3C4, 0xD3C4, 0xD3C4}, {0xD3C5, 0xD3C5, 0xD3C5}, {0xD3C6, 0xD3C6, 0xD3C6}, {0xD3C7, 0xD3C7, 0xD3C7}, {0xD3C8, 0xD3C8, 0xD3C8}, {0xD3C9, 0xD3C9, 0xD3C9}, {0xD3CA, 0xD3CA, 0xD3CA}, {0xD3CB, 0xD3CB, 0xD3CB}, {0xD3CC, 0xD3CC, 0xD3CC}, {0xD3CD, 0xD3CD, 0xD3CD}, {0xD3CE, 0xD3CE, 0xD3CE}, {0xD3CF, 0xD3CF, 0xD3CF}, {0xD3D0, 0xD3D0, 0xD3D0}, {0xD3D1, 0xD3D1, 0xD3D1}, {0xD3D2, 0xD3D2, 0xD3D2}, {0xD3D3, 0xD3D3, 0xD3D3}, {0xD3D4, 0xD3D4, 0xD3D4}, {0xD3D5, 0xD3D5, 0xD3D5}, {0xD3D6, 0xD3D6, 0xD3D6}, {0xD3D7, 0xD3D7, 0xD3D7}, {0xD3D8, 0xD3D8, 0xD3D8}, {0xD3D9, 0xD3D9, 0xD3D9}, {0xD3DA, 0xD3DA, 0xD3DA}, {0xD3DB, 0xD3DB, 0xD3DB}, {0xD3DC, 0xD3DC, 0xD3DC}, {0xD3DD, 0xD3DD, 0xD3DD}, {0xD3DE, 0xD3DE, 0xD3DE}, {0xD3DF, 0xD3DF, 0xD3DF}, {0xD3E0, 0xD3E0, 0xD3E0}, {0xD3E1, 0xD3E1, 0xD3E1}, {0xD3E2, 0xD3E2, 0xD3E2}, {0xD3E3, 0xD3E3, 0xD3E3}, {0xD3E4, 0xD3E4, 0xD3E4}, {0xD3E5, 0xD3E5, 0xD3E5}, {0xD3E6, 0xD3E6, 0xD3E6}, {0xD3E7, 0xD3E7, 0xD3E7}, {0xD3E8, 0xD3E8, 0xD3E8}, {0xD3E9, 0xD3E9, 0xD3E9}, {0xD3EA, 0xD3EA, 0xD3EA}, {0xD3EB, 0xD3EB, 0xD3EB}, {0xD3EC, 0xD3EC, 0xD3EC}, {0xD3ED, 0xD3ED, 0xD3ED}, {0xD3EE, 0xD3EE, 0xD3EE}, {0xD3EF, 0xD3EF, 0xD3EF}, {0xD3F0, 0xD3F0, 0xD3F0}, {0xD3F1, 0xD3F1, 0xD3F1}, {0xD3F2, 0xD3F2, 0xD3F2}, {0xD3F3, 0xD3F3, 0xD3F3}, {0xD3F4, 0xD3F4, 0xD3F4}, {0xD3F5, 0xD3F5, 0xD3F5}, {0xD3F6, 0xD3F6, 0xD3F6}, {0xD3F7, 0xD3F7, 0xD3F7}, {0xD3F8, 0xD3F8, 0xD3F8}, {0xD3F9, 0xD3F9, 0xD3F9}, {0xD3FA, 0xD3FA, 0xD3FA}, {0xD3FB, 0xD3FB, 0xD3FB}, {0xD3FC, 0xD3FC, 0xD3FC}, {0xD3FD, 0xD3FD, 0xD3FD}, {0xD3FE, 0xD3FE, 0xD3FE}, {0xD3FF, 0xD3FF, 0xD3FF}, {0xD400, 0xD400, 0xD400}, {0xD401, 0xD401, 0xD401}, {0xD402, 0xD402, 0xD402}, {0xD403, 0xD403, 0xD403}, {0xD404, 0xD404, 0xD404}, {0xD405, 0xD405, 0xD405}, {0xD406, 0xD406, 0xD406}, {0xD407, 0xD407, 0xD407}, {0xD408, 0xD408, 0xD408}, {0xD409, 0xD409, 0xD409}, {0xD40A, 0xD40A, 0xD40A}, {0xD40B, 0xD40B, 0xD40B}, {0xD40C, 0xD40C, 0xD40C}, {0xD40D, 0xD40D, 0xD40D}, {0xD40E, 0xD40E, 0xD40E}, {0xD40F, 0xD40F, 0xD40F}, {0xD410, 0xD410, 0xD410}, {0xD411, 0xD411, 0xD411}, {0xD412, 0xD412, 0xD412}, {0xD413, 0xD413, 0xD413}, {0xD414, 0xD414, 0xD414}, {0xD415, 0xD415, 0xD415}, {0xD416, 0xD416, 0xD416}, {0xD417, 0xD417, 0xD417}, {0xD418, 0xD418, 0xD418}, {0xD419, 0xD419, 0xD419}, {0xD41A, 0xD41A, 0xD41A}, {0xD41B, 0xD41B, 0xD41B}, {0xD41C, 0xD41C, 0xD41C}, {0xD41D, 0xD41D, 0xD41D}, {0xD41E, 0xD41E, 0xD41E}, {0xD41F, 0xD41F, 0xD41F}, {0xD420, 0xD420, 0xD420}, {0xD421, 0xD421, 0xD421}, {0xD422, 0xD422, 0xD422}, {0xD423, 0xD423, 0xD423}, {0xD424, 0xD424, 0xD424}, {0xD425, 0xD425, 0xD425}, {0xD426, 0xD426, 0xD426}, {0xD427, 0xD427, 0xD427}, {0xD428, 0xD428, 0xD428}, {0xD429, 0xD429, 0xD429}, {0xD42A, 0xD42A, 0xD42A}, {0xD42B, 0xD42B, 0xD42B}, {0xD42C, 0xD42C, 0xD42C}, {0xD42D, 0xD42D, 0xD42D}, {0xD42E, 0xD42E, 0xD42E}, {0xD42F, 0xD42F, 0xD42F}, {0xD430, 0xD430, 0xD430}, {0xD431, 0xD431, 0xD431}, {0xD432, 0xD432, 0xD432}, {0xD433, 0xD433, 0xD433}, {0xD434, 0xD434, 0xD434}, {0xD435, 0xD435, 0xD435}, {0xD436, 0xD436, 0xD436}, {0xD437, 0xD437, 0xD437}, {0xD438, 0xD438, 0xD438}, {0xD439, 0xD439, 0xD439}, {0xD43A, 0xD43A, 0xD43A}, {0xD43B, 0xD43B, 0xD43B}, {0xD43C, 0xD43C, 0xD43C}, {0xD43D, 0xD43D, 0xD43D}, {0xD43E, 0xD43E, 0xD43E}, {0xD43F, 0xD43F, 0xD43F}, {0xD440, 0xD440, 0xD440}, {0xD441, 0xD441, 0xD441}, {0xD442, 0xD442, 0xD442}, {0xD443, 0xD443, 0xD443}, {0xD444, 0xD444, 0xD444}, {0xD445, 0xD445, 0xD445}, {0xD446, 0xD446, 0xD446}, {0xD447, 0xD447, 0xD447}, {0xD448, 0xD448, 0xD448}, {0xD449, 0xD449, 0xD449}, {0xD44A, 0xD44A, 0xD44A}, {0xD44B, 0xD44B, 0xD44B}, {0xD44C, 0xD44C, 0xD44C}, {0xD44D, 0xD44D, 0xD44D}, {0xD44E, 0xD44E, 0xD44E}, {0xD44F, 0xD44F, 0xD44F}, {0xD450, 0xD450, 0xD450}, {0xD451, 0xD451, 0xD451}, {0xD452, 0xD452, 0xD452}, {0xD453, 0xD453, 0xD453}, {0xD454, 0xD454, 0xD454}, {0xD455, 0xD455, 0xD455}, {0xD456, 0xD456, 0xD456}, {0xD457, 0xD457, 0xD457}, {0xD458, 0xD458, 0xD458}, {0xD459, 0xD459, 0xD459}, {0xD45A, 0xD45A, 0xD45A}, {0xD45B, 0xD45B, 0xD45B}, {0xD45C, 0xD45C, 0xD45C}, {0xD45D, 0xD45D, 0xD45D}, {0xD45E, 0xD45E, 0xD45E}, {0xD45F, 0xD45F, 0xD45F}, {0xD460, 0xD460, 0xD460}, {0xD461, 0xD461, 0xD461}, {0xD462, 0xD462, 0xD462}, {0xD463, 0xD463, 0xD463}, {0xD464, 0xD464, 0xD464}, {0xD465, 0xD465, 0xD465}, {0xD466, 0xD466, 0xD466}, {0xD467, 0xD467, 0xD467}, {0xD468, 0xD468, 0xD468}, {0xD469, 0xD469, 0xD469}, {0xD46A, 0xD46A, 0xD46A}, {0xD46B, 0xD46B, 0xD46B}, {0xD46C, 0xD46C, 0xD46C}, {0xD46D, 0xD46D, 0xD46D}, {0xD46E, 0xD46E, 0xD46E}, {0xD46F, 0xD46F, 0xD46F}, {0xD470, 0xD470, 0xD470}, {0xD471, 0xD471, 0xD471}, {0xD472, 0xD472, 0xD472}, {0xD473, 0xD473, 0xD473}, {0xD474, 0xD474, 0xD474}, {0xD475, 0xD475, 0xD475}, {0xD476, 0xD476, 0xD476}, {0xD477, 0xD477, 0xD477}, {0xD478, 0xD478, 0xD478}, {0xD479, 0xD479, 0xD479}, {0xD47A, 0xD47A, 0xD47A}, {0xD47B, 0xD47B, 0xD47B}, {0xD47C, 0xD47C, 0xD47C}, {0xD47D, 0xD47D, 0xD47D}, {0xD47E, 0xD47E, 0xD47E}, {0xD47F, 0xD47F, 0xD47F}, {0xD480, 0xD480, 0xD480}, {0xD481, 0xD481, 0xD481}, {0xD482, 0xD482, 0xD482}, {0xD483, 0xD483, 0xD483}, {0xD484, 0xD484, 0xD484}, {0xD485, 0xD485, 0xD485}, {0xD486, 0xD486, 0xD486}, {0xD487, 0xD487, 0xD487}, {0xD488, 0xD488, 0xD488}, {0xD489, 0xD489, 0xD489}, {0xD48A, 0xD48A, 0xD48A}, {0xD48B, 0xD48B, 0xD48B}, {0xD48C, 0xD48C, 0xD48C}, {0xD48D, 0xD48D, 0xD48D}, {0xD48E, 0xD48E, 0xD48E}, {0xD48F, 0xD48F, 0xD48F}, {0xD490, 0xD490, 0xD490}, {0xD491, 0xD491, 0xD491}, {0xD492, 0xD492, 0xD492}, {0xD493, 0xD493, 0xD493}, {0xD494, 0xD494, 0xD494}, {0xD495, 0xD495, 0xD495}, {0xD496, 0xD496, 0xD496}, {0xD497, 0xD497, 0xD497}, {0xD498, 0xD498, 0xD498}, {0xD499, 0xD499, 0xD499}, {0xD49A, 0xD49A, 0xD49A}, {0xD49B, 0xD49B, 0xD49B}, {0xD49C, 0xD49C, 0xD49C}, {0xD49D, 0xD49D, 0xD49D}, {0xD49E, 0xD49E, 0xD49E}, {0xD49F, 0xD49F, 0xD49F}, {0xD4A0, 0xD4A0, 0xD4A0}, {0xD4A1, 0xD4A1, 0xD4A1}, {0xD4A2, 0xD4A2, 0xD4A2}, {0xD4A3, 0xD4A3, 0xD4A3}, {0xD4A4, 0xD4A4, 0xD4A4}, {0xD4A5, 0xD4A5, 0xD4A5}, {0xD4A6, 0xD4A6, 0xD4A6}, {0xD4A7, 0xD4A7, 0xD4A7}, {0xD4A8, 0xD4A8, 0xD4A8}, {0xD4A9, 0xD4A9, 0xD4A9}, {0xD4AA, 0xD4AA, 0xD4AA}, {0xD4AB, 0xD4AB, 0xD4AB}, {0xD4AC, 0xD4AC, 0xD4AC}, {0xD4AD, 0xD4AD, 0xD4AD}, {0xD4AE, 0xD4AE, 0xD4AE}, {0xD4AF, 0xD4AF, 0xD4AF}, {0xD4B0, 0xD4B0, 0xD4B0}, {0xD4B1, 0xD4B1, 0xD4B1}, {0xD4B2, 0xD4B2, 0xD4B2}, {0xD4B3, 0xD4B3, 0xD4B3}, {0xD4B4, 0xD4B4, 0xD4B4}, {0xD4B5, 0xD4B5, 0xD4B5}, {0xD4B6, 0xD4B6, 0xD4B6}, {0xD4B7, 0xD4B7, 0xD4B7}, {0xD4B8, 0xD4B8, 0xD4B8}, {0xD4B9, 0xD4B9, 0xD4B9}, {0xD4BA, 0xD4BA, 0xD4BA}, {0xD4BB, 0xD4BB, 0xD4BB}, {0xD4BC, 0xD4BC, 0xD4BC}, {0xD4BD, 0xD4BD, 0xD4BD}, {0xD4BE, 0xD4BE, 0xD4BE}, {0xD4BF, 0xD4BF, 0xD4BF}, {0xD4C0, 0xD4C0, 0xD4C0}, {0xD4C1, 0xD4C1, 0xD4C1}, {0xD4C2, 0xD4C2, 0xD4C2}, {0xD4C3, 0xD4C3, 0xD4C3}, {0xD4C4, 0xD4C4, 0xD4C4}, {0xD4C5, 0xD4C5, 0xD4C5}, {0xD4C6, 0xD4C6, 0xD4C6}, {0xD4C7, 0xD4C7, 0xD4C7}, {0xD4C8, 0xD4C8, 0xD4C8}, {0xD4C9, 0xD4C9, 0xD4C9}, {0xD4CA, 0xD4CA, 0xD4CA}, {0xD4CB, 0xD4CB, 0xD4CB}, {0xD4CC, 0xD4CC, 0xD4CC}, {0xD4CD, 0xD4CD, 0xD4CD}, {0xD4CE, 0xD4CE, 0xD4CE}, {0xD4CF, 0xD4CF, 0xD4CF}, {0xD4D0, 0xD4D0, 0xD4D0}, {0xD4D1, 0xD4D1, 0xD4D1}, {0xD4D2, 0xD4D2, 0xD4D2}, {0xD4D3, 0xD4D3, 0xD4D3}, {0xD4D4, 0xD4D4, 0xD4D4}, {0xD4D5, 0xD4D5, 0xD4D5}, {0xD4D6, 0xD4D6, 0xD4D6}, {0xD4D7, 0xD4D7, 0xD4D7}, {0xD4D8, 0xD4D8, 0xD4D8}, {0xD4D9, 0xD4D9, 0xD4D9}, {0xD4DA, 0xD4DA, 0xD4DA}, {0xD4DB, 0xD4DB, 0xD4DB}, {0xD4DC, 0xD4DC, 0xD4DC}, {0xD4DD, 0xD4DD, 0xD4DD}, {0xD4DE, 0xD4DE, 0xD4DE}, {0xD4DF, 0xD4DF, 0xD4DF}, {0xD4E0, 0xD4E0, 0xD4E0}, {0xD4E1, 0xD4E1, 0xD4E1}, {0xD4E2, 0xD4E2, 0xD4E2}, {0xD4E3, 0xD4E3, 0xD4E3}, {0xD4E4, 0xD4E4, 0xD4E4}, {0xD4E5, 0xD4E5, 0xD4E5}, {0xD4E6, 0xD4E6, 0xD4E6}, {0xD4E7, 0xD4E7, 0xD4E7}, {0xD4E8, 0xD4E8, 0xD4E8}, {0xD4E9, 0xD4E9, 0xD4E9}, {0xD4EA, 0xD4EA, 0xD4EA}, {0xD4EB, 0xD4EB, 0xD4EB}, {0xD4EC, 0xD4EC, 0xD4EC}, {0xD4ED, 0xD4ED, 0xD4ED}, {0xD4EE, 0xD4EE, 0xD4EE}, {0xD4EF, 0xD4EF, 0xD4EF}, {0xD4F0, 0xD4F0, 0xD4F0}, {0xD4F1, 0xD4F1, 0xD4F1}, {0xD4F2, 0xD4F2, 0xD4F2}, {0xD4F3, 0xD4F3, 0xD4F3}, {0xD4F4, 0xD4F4, 0xD4F4}, {0xD4F5, 0xD4F5, 0xD4F5}, {0xD4F6, 0xD4F6, 0xD4F6}, {0xD4F7, 0xD4F7, 0xD4F7}, {0xD4F8, 0xD4F8, 0xD4F8}, {0xD4F9, 0xD4F9, 0xD4F9}, {0xD4FA, 0xD4FA, 0xD4FA}, {0xD4FB, 0xD4FB, 0xD4FB}, {0xD4FC, 0xD4FC, 0xD4FC}, {0xD4FD, 0xD4FD, 0xD4FD}, {0xD4FE, 0xD4FE, 0xD4FE}, {0xD4FF, 0xD4FF, 0xD4FF}, {0xD500, 0xD500, 0xD500}, {0xD501, 0xD501, 0xD501}, {0xD502, 0xD502, 0xD502}, {0xD503, 0xD503, 0xD503}, {0xD504, 0xD504, 0xD504}, {0xD505, 0xD505, 0xD505}, {0xD506, 0xD506, 0xD506}, {0xD507, 0xD507, 0xD507}, {0xD508, 0xD508, 0xD508}, {0xD509, 0xD509, 0xD509}, {0xD50A, 0xD50A, 0xD50A}, {0xD50B, 0xD50B, 0xD50B}, {0xD50C, 0xD50C, 0xD50C}, {0xD50D, 0xD50D, 0xD50D}, {0xD50E, 0xD50E, 0xD50E}, {0xD50F, 0xD50F, 0xD50F}, {0xD510, 0xD510, 0xD510}, {0xD511, 0xD511, 0xD511}, {0xD512, 0xD512, 0xD512}, {0xD513, 0xD513, 0xD513}, {0xD514, 0xD514, 0xD514}, {0xD515, 0xD515, 0xD515}, {0xD516, 0xD516, 0xD516}, {0xD517, 0xD517, 0xD517}, {0xD518, 0xD518, 0xD518}, {0xD519, 0xD519, 0xD519}, {0xD51A, 0xD51A, 0xD51A}, {0xD51B, 0xD51B, 0xD51B}, {0xD51C, 0xD51C, 0xD51C}, {0xD51D, 0xD51D, 0xD51D}, {0xD51E, 0xD51E, 0xD51E}, {0xD51F, 0xD51F, 0xD51F}, {0xD520, 0xD520, 0xD520}, {0xD521, 0xD521, 0xD521}, {0xD522, 0xD522, 0xD522}, {0xD523, 0xD523, 0xD523}, {0xD524, 0xD524, 0xD524}, {0xD525, 0xD525, 0xD525}, {0xD526, 0xD526, 0xD526}, {0xD527, 0xD527, 0xD527}, {0xD528, 0xD528, 0xD528}, {0xD529, 0xD529, 0xD529}, {0xD52A, 0xD52A, 0xD52A}, {0xD52B, 0xD52B, 0xD52B}, {0xD52C, 0xD52C, 0xD52C}, {0xD52D, 0xD52D, 0xD52D}, {0xD52E, 0xD52E, 0xD52E}, {0xD52F, 0xD52F, 0xD52F}, {0xD530, 0xD530, 0xD530}, {0xD531, 0xD531, 0xD531}, {0xD532, 0xD532, 0xD532}, {0xD533, 0xD533, 0xD533}, {0xD534, 0xD534, 0xD534}, {0xD535, 0xD535, 0xD535}, {0xD536, 0xD536, 0xD536}, {0xD537, 0xD537, 0xD537}, {0xD538, 0xD538, 0xD538}, {0xD539, 0xD539, 0xD539}, {0xD53A, 0xD53A, 0xD53A}, {0xD53B, 0xD53B, 0xD53B}, {0xD53C, 0xD53C, 0xD53C}, {0xD53D, 0xD53D, 0xD53D}, {0xD53E, 0xD53E, 0xD53E}, {0xD53F, 0xD53F, 0xD53F}, {0xD540, 0xD540, 0xD540}, {0xD541, 0xD541, 0xD541}, {0xD542, 0xD542, 0xD542}, {0xD543, 0xD543, 0xD543}, {0xD544, 0xD544, 0xD544}, {0xD545, 0xD545, 0xD545}, {0xD546, 0xD546, 0xD546}, {0xD547, 0xD547, 0xD547}, {0xD548, 0xD548, 0xD548}, {0xD549, 0xD549, 0xD549}, {0xD54A, 0xD54A, 0xD54A}, {0xD54B, 0xD54B, 0xD54B}, {0xD54C, 0xD54C, 0xD54C}, {0xD54D, 0xD54D, 0xD54D}, {0xD54E, 0xD54E, 0xD54E}, {0xD54F, 0xD54F, 0xD54F}, {0xD550, 0xD550, 0xD550}, {0xD551, 0xD551, 0xD551}, {0xD552, 0xD552, 0xD552}, {0xD553, 0xD553, 0xD553}, {0xD554, 0xD554, 0xD554}, {0xD555, 0xD555, 0xD555}, {0xD556, 0xD556, 0xD556}, {0xD557, 0xD557, 0xD557}, {0xD558, 0xD558, 0xD558}, {0xD559, 0xD559, 0xD559}, {0xD55A, 0xD55A, 0xD55A}, {0xD55B, 0xD55B, 0xD55B}, {0xD55C, 0xD55C, 0xD55C}, {0xD55D, 0xD55D, 0xD55D}, {0xD55E, 0xD55E, 0xD55E}, {0xD55F, 0xD55F, 0xD55F}, {0xD560, 0xD560, 0xD560}, {0xD561, 0xD561, 0xD561}, {0xD562, 0xD562, 0xD562}, {0xD563, 0xD563, 0xD563}, {0xD564, 0xD564, 0xD564}, {0xD565, 0xD565, 0xD565}, {0xD566, 0xD566, 0xD566}, {0xD567, 0xD567, 0xD567}, {0xD568, 0xD568, 0xD568}, {0xD569, 0xD569, 0xD569}, {0xD56A, 0xD56A, 0xD56A}, {0xD56B, 0xD56B, 0xD56B}, {0xD56C, 0xD56C, 0xD56C}, {0xD56D, 0xD56D, 0xD56D}, {0xD56E, 0xD56E, 0xD56E}, {0xD56F, 0xD56F, 0xD56F}, {0xD570, 0xD570, 0xD570}, {0xD571, 0xD571, 0xD571}, {0xD572, 0xD572, 0xD572}, {0xD573, 0xD573, 0xD573}, {0xD574, 0xD574, 0xD574}, {0xD575, 0xD575, 0xD575}, {0xD576, 0xD576, 0xD576}, {0xD577, 0xD577, 0xD577}, {0xD578, 0xD578, 0xD578}, {0xD579, 0xD579, 0xD579}, {0xD57A, 0xD57A, 0xD57A}, {0xD57B, 0xD57B, 0xD57B}, {0xD57C, 0xD57C, 0xD57C}, {0xD57D, 0xD57D, 0xD57D}, {0xD57E, 0xD57E, 0xD57E}, {0xD57F, 0xD57F, 0xD57F}, {0xD580, 0xD580, 0xD580}, {0xD581, 0xD581, 0xD581}, {0xD582, 0xD582, 0xD582}, {0xD583, 0xD583, 0xD583}, {0xD584, 0xD584, 0xD584}, {0xD585, 0xD585, 0xD585}, {0xD586, 0xD586, 0xD586}, {0xD587, 0xD587, 0xD587}, {0xD588, 0xD588, 0xD588}, {0xD589, 0xD589, 0xD589}, {0xD58A, 0xD58A, 0xD58A}, {0xD58B, 0xD58B, 0xD58B}, {0xD58C, 0xD58C, 0xD58C}, {0xD58D, 0xD58D, 0xD58D}, {0xD58E, 0xD58E, 0xD58E}, {0xD58F, 0xD58F, 0xD58F}, {0xD590, 0xD590, 0xD590}, {0xD591, 0xD591, 0xD591}, {0xD592, 0xD592, 0xD592}, {0xD593, 0xD593, 0xD593}, {0xD594, 0xD594, 0xD594}, {0xD595, 0xD595, 0xD595}, {0xD596, 0xD596, 0xD596}, {0xD597, 0xD597, 0xD597}, {0xD598, 0xD598, 0xD598}, {0xD599, 0xD599, 0xD599}, {0xD59A, 0xD59A, 0xD59A}, {0xD59B, 0xD59B, 0xD59B}, {0xD59C, 0xD59C, 0xD59C}, {0xD59D, 0xD59D, 0xD59D}, {0xD59E, 0xD59E, 0xD59E}, {0xD59F, 0xD59F, 0xD59F}, {0xD5A0, 0xD5A0, 0xD5A0}, {0xD5A1, 0xD5A1, 0xD5A1}, {0xD5A2, 0xD5A2, 0xD5A2}, {0xD5A3, 0xD5A3, 0xD5A3}, {0xD5A4, 0xD5A4, 0xD5A4}, {0xD5A5, 0xD5A5, 0xD5A5}, {0xD5A6, 0xD5A6, 0xD5A6}, {0xD5A7, 0xD5A7, 0xD5A7}, {0xD5A8, 0xD5A8, 0xD5A8}, {0xD5A9, 0xD5A9, 0xD5A9}, {0xD5AA, 0xD5AA, 0xD5AA}, {0xD5AB, 0xD5AB, 0xD5AB}, {0xD5AC, 0xD5AC, 0xD5AC}, {0xD5AD, 0xD5AD, 0xD5AD}, {0xD5AE, 0xD5AE, 0xD5AE}, {0xD5AF, 0xD5AF, 0xD5AF}, {0xD5B0, 0xD5B0, 0xD5B0}, {0xD5B1, 0xD5B1, 0xD5B1}, {0xD5B2, 0xD5B2, 0xD5B2}, {0xD5B3, 0xD5B3, 0xD5B3}, {0xD5B4, 0xD5B4, 0xD5B4}, {0xD5B5, 0xD5B5, 0xD5B5}, {0xD5B6, 0xD5B6, 0xD5B6}, {0xD5B7, 0xD5B7, 0xD5B7}, {0xD5B8, 0xD5B8, 0xD5B8}, {0xD5B9, 0xD5B9, 0xD5B9}, {0xD5BA, 0xD5BA, 0xD5BA}, {0xD5BB, 0xD5BB, 0xD5BB}, {0xD5BC, 0xD5BC, 0xD5BC}, {0xD5BD, 0xD5BD, 0xD5BD}, {0xD5BE, 0xD5BE, 0xD5BE}, {0xD5BF, 0xD5BF, 0xD5BF}, {0xD5C0, 0xD5C0, 0xD5C0}, {0xD5C1, 0xD5C1, 0xD5C1}, {0xD5C2, 0xD5C2, 0xD5C2}, {0xD5C3, 0xD5C3, 0xD5C3}, {0xD5C4, 0xD5C4, 0xD5C4}, {0xD5C5, 0xD5C5, 0xD5C5}, {0xD5C6, 0xD5C6, 0xD5C6}, {0xD5C7, 0xD5C7, 0xD5C7}, {0xD5C8, 0xD5C8, 0xD5C8}, {0xD5C9, 0xD5C9, 0xD5C9}, {0xD5CA, 0xD5CA, 0xD5CA}, {0xD5CB, 0xD5CB, 0xD5CB}, {0xD5CC, 0xD5CC, 0xD5CC}, {0xD5CD, 0xD5CD, 0xD5CD}, {0xD5CE, 0xD5CE, 0xD5CE}, {0xD5CF, 0xD5CF, 0xD5CF}, {0xD5D0, 0xD5D0, 0xD5D0}, {0xD5D1, 0xD5D1, 0xD5D1}, {0xD5D2, 0xD5D2, 0xD5D2}, {0xD5D3, 0xD5D3, 0xD5D3}, {0xD5D4, 0xD5D4, 0xD5D4}, {0xD5D5, 0xD5D5, 0xD5D5}, {0xD5D6, 0xD5D6, 0xD5D6}, {0xD5D7, 0xD5D7, 0xD5D7}, {0xD5D8, 0xD5D8, 0xD5D8}, {0xD5D9, 0xD5D9, 0xD5D9}, {0xD5DA, 0xD5DA, 0xD5DA}, {0xD5DB, 0xD5DB, 0xD5DB}, {0xD5DC, 0xD5DC, 0xD5DC}, {0xD5DD, 0xD5DD, 0xD5DD}, {0xD5DE, 0xD5DE, 0xD5DE}, {0xD5DF, 0xD5DF, 0xD5DF}, {0xD5E0, 0xD5E0, 0xD5E0}, {0xD5E1, 0xD5E1, 0xD5E1}, {0xD5E2, 0xD5E2, 0xD5E2}, {0xD5E3, 0xD5E3, 0xD5E3}, {0xD5E4, 0xD5E4, 0xD5E4}, {0xD5E5, 0xD5E5, 0xD5E5}, {0xD5E6, 0xD5E6, 0xD5E6}, {0xD5E7, 0xD5E7, 0xD5E7}, {0xD5E8, 0xD5E8, 0xD5E8}, {0xD5E9, 0xD5E9, 0xD5E9}, {0xD5EA, 0xD5EA, 0xD5EA}, {0xD5EB, 0xD5EB, 0xD5EB}, {0xD5EC, 0xD5EC, 0xD5EC}, {0xD5ED, 0xD5ED, 0xD5ED}, {0xD5EE, 0xD5EE, 0xD5EE}, {0xD5EF, 0xD5EF, 0xD5EF}, {0xD5F0, 0xD5F0, 0xD5F0}, {0xD5F1, 0xD5F1, 0xD5F1}, {0xD5F2, 0xD5F2, 0xD5F2}, {0xD5F3, 0xD5F3, 0xD5F3}, {0xD5F4, 0xD5F4, 0xD5F4}, {0xD5F5, 0xD5F5, 0xD5F5}, {0xD5F6, 0xD5F6, 0xD5F6}, {0xD5F7, 0xD5F7, 0xD5F7}, {0xD5F8, 0xD5F8, 0xD5F8}, {0xD5F9, 0xD5F9, 0xD5F9}, {0xD5FA, 0xD5FA, 0xD5FA}, {0xD5FB, 0xD5FB, 0xD5FB}, {0xD5FC, 0xD5FC, 0xD5FC}, {0xD5FD, 0xD5FD, 0xD5FD}, {0xD5FE, 0xD5FE, 0xD5FE}, {0xD5FF, 0xD5FF, 0xD5FF}, {0xD600, 0xD600, 0xD600}, {0xD601, 0xD601, 0xD601}, {0xD602, 0xD602, 0xD602}, {0xD603, 0xD603, 0xD603}, {0xD604, 0xD604, 0xD604}, {0xD605, 0xD605, 0xD605}, {0xD606, 0xD606, 0xD606}, {0xD607, 0xD607, 0xD607}, {0xD608, 0xD608, 0xD608}, {0xD609, 0xD609, 0xD609}, {0xD60A, 0xD60A, 0xD60A}, {0xD60B, 0xD60B, 0xD60B}, {0xD60C, 0xD60C, 0xD60C}, {0xD60D, 0xD60D, 0xD60D}, {0xD60E, 0xD60E, 0xD60E}, {0xD60F, 0xD60F, 0xD60F}, {0xD610, 0xD610, 0xD610}, {0xD611, 0xD611, 0xD611}, {0xD612, 0xD612, 0xD612}, {0xD613, 0xD613, 0xD613}, {0xD614, 0xD614, 0xD614}, {0xD615, 0xD615, 0xD615}, {0xD616, 0xD616, 0xD616}, {0xD617, 0xD617, 0xD617}, {0xD618, 0xD618, 0xD618}, {0xD619, 0xD619, 0xD619}, {0xD61A, 0xD61A, 0xD61A}, {0xD61B, 0xD61B, 0xD61B}, {0xD61C, 0xD61C, 0xD61C}, {0xD61D, 0xD61D, 0xD61D}, {0xD61E, 0xD61E, 0xD61E}, {0xD61F, 0xD61F, 0xD61F}, {0xD620, 0xD620, 0xD620}, {0xD621, 0xD621, 0xD621}, {0xD622, 0xD622, 0xD622}, {0xD623, 0xD623, 0xD623}, {0xD624, 0xD624, 0xD624}, {0xD625, 0xD625, 0xD625}, {0xD626, 0xD626, 0xD626}, {0xD627, 0xD627, 0xD627}, {0xD628, 0xD628, 0xD628}, {0xD629, 0xD629, 0xD629}, {0xD62A, 0xD62A, 0xD62A}, {0xD62B, 0xD62B, 0xD62B}, {0xD62C, 0xD62C, 0xD62C}, {0xD62D, 0xD62D, 0xD62D}, {0xD62E, 0xD62E, 0xD62E}, {0xD62F, 0xD62F, 0xD62F}, {0xD630, 0xD630, 0xD630}, {0xD631, 0xD631, 0xD631}, {0xD632, 0xD632, 0xD632}, {0xD633, 0xD633, 0xD633}, {0xD634, 0xD634, 0xD634}, {0xD635, 0xD635, 0xD635}, {0xD636, 0xD636, 0xD636}, {0xD637, 0xD637, 0xD637}, {0xD638, 0xD638, 0xD638}, {0xD639, 0xD639, 0xD639}, {0xD63A, 0xD63A, 0xD63A}, {0xD63B, 0xD63B, 0xD63B}, {0xD63C, 0xD63C, 0xD63C}, {0xD63D, 0xD63D, 0xD63D}, {0xD63E, 0xD63E, 0xD63E}, {0xD63F, 0xD63F, 0xD63F}, {0xD640, 0xD640, 0xD640}, {0xD641, 0xD641, 0xD641}, {0xD642, 0xD642, 0xD642}, {0xD643, 0xD643, 0xD643}, {0xD644, 0xD644, 0xD644}, {0xD645, 0xD645, 0xD645}, {0xD646, 0xD646, 0xD646}, {0xD647, 0xD647, 0xD647}, {0xD648, 0xD648, 0xD648}, {0xD649, 0xD649, 0xD649}, {0xD64A, 0xD64A, 0xD64A}, {0xD64B, 0xD64B, 0xD64B}, {0xD64C, 0xD64C, 0xD64C}, {0xD64D, 0xD64D, 0xD64D}, {0xD64E, 0xD64E, 0xD64E}, {0xD64F, 0xD64F, 0xD64F}, {0xD650, 0xD650, 0xD650}, {0xD651, 0xD651, 0xD651}, {0xD652, 0xD652, 0xD652}, {0xD653, 0xD653, 0xD653}, {0xD654, 0xD654, 0xD654}, {0xD655, 0xD655, 0xD655}, {0xD656, 0xD656, 0xD656}, {0xD657, 0xD657, 0xD657}, {0xD658, 0xD658, 0xD658}, {0xD659, 0xD659, 0xD659}, {0xD65A, 0xD65A, 0xD65A}, {0xD65B, 0xD65B, 0xD65B}, {0xD65C, 0xD65C, 0xD65C}, {0xD65D, 0xD65D, 0xD65D}, {0xD65E, 0xD65E, 0xD65E}, {0xD65F, 0xD65F, 0xD65F}, {0xD660, 0xD660, 0xD660}, {0xD661, 0xD661, 0xD661}, {0xD662, 0xD662, 0xD662}, {0xD663, 0xD663, 0xD663}, {0xD664, 0xD664, 0xD664}, {0xD665, 0xD665, 0xD665}, {0xD666, 0xD666, 0xD666}, {0xD667, 0xD667, 0xD667}, {0xD668, 0xD668, 0xD668}, {0xD669, 0xD669, 0xD669}, {0xD66A, 0xD66A, 0xD66A}, {0xD66B, 0xD66B, 0xD66B}, {0xD66C, 0xD66C, 0xD66C}, {0xD66D, 0xD66D, 0xD66D}, {0xD66E, 0xD66E, 0xD66E}, {0xD66F, 0xD66F, 0xD66F}, {0xD670, 0xD670, 0xD670}, {0xD671, 0xD671, 0xD671}, {0xD672, 0xD672, 0xD672}, {0xD673, 0xD673, 0xD673}, {0xD674, 0xD674, 0xD674}, {0xD675, 0xD675, 0xD675}, {0xD676, 0xD676, 0xD676}, {0xD677, 0xD677, 0xD677}, {0xD678, 0xD678, 0xD678}, {0xD679, 0xD679, 0xD679}, {0xD67A, 0xD67A, 0xD67A}, {0xD67B, 0xD67B, 0xD67B}, {0xD67C, 0xD67C, 0xD67C}, {0xD67D, 0xD67D, 0xD67D}, {0xD67E, 0xD67E, 0xD67E}, {0xD67F, 0xD67F, 0xD67F}, {0xD680, 0xD680, 0xD680}, {0xD681, 0xD681, 0xD681}, {0xD682, 0xD682, 0xD682}, {0xD683, 0xD683, 0xD683}, {0xD684, 0xD684, 0xD684}, {0xD685, 0xD685, 0xD685}, {0xD686, 0xD686, 0xD686}, {0xD687, 0xD687, 0xD687}, {0xD688, 0xD688, 0xD688}, {0xD689, 0xD689, 0xD689}, {0xD68A, 0xD68A, 0xD68A}, {0xD68B, 0xD68B, 0xD68B}, {0xD68C, 0xD68C, 0xD68C}, {0xD68D, 0xD68D, 0xD68D}, {0xD68E, 0xD68E, 0xD68E}, {0xD68F, 0xD68F, 0xD68F}, {0xD690, 0xD690, 0xD690}, {0xD691, 0xD691, 0xD691}, {0xD692, 0xD692, 0xD692}, {0xD693, 0xD693, 0xD693}, {0xD694, 0xD694, 0xD694}, {0xD695, 0xD695, 0xD695}, {0xD696, 0xD696, 0xD696}, {0xD697, 0xD697, 0xD697}, {0xD698, 0xD698, 0xD698}, {0xD699, 0xD699, 0xD699}, {0xD69A, 0xD69A, 0xD69A}, {0xD69B, 0xD69B, 0xD69B}, {0xD69C, 0xD69C, 0xD69C}, {0xD69D, 0xD69D, 0xD69D}, {0xD69E, 0xD69E, 0xD69E}, {0xD69F, 0xD69F, 0xD69F}, {0xD6A0, 0xD6A0, 0xD6A0}, {0xD6A1, 0xD6A1, 0xD6A1}, {0xD6A2, 0xD6A2, 0xD6A2}, {0xD6A3, 0xD6A3, 0xD6A3}, {0xD6A4, 0xD6A4, 0xD6A4}, {0xD6A5, 0xD6A5, 0xD6A5}, {0xD6A6, 0xD6A6, 0xD6A6}, {0xD6A7, 0xD6A7, 0xD6A7}, {0xD6A8, 0xD6A8, 0xD6A8}, {0xD6A9, 0xD6A9, 0xD6A9}, {0xD6AA, 0xD6AA, 0xD6AA}, {0xD6AB, 0xD6AB, 0xD6AB}, {0xD6AC, 0xD6AC, 0xD6AC}, {0xD6AD, 0xD6AD, 0xD6AD}, {0xD6AE, 0xD6AE, 0xD6AE}, {0xD6AF, 0xD6AF, 0xD6AF}, {0xD6B0, 0xD6B0, 0xD6B0}, {0xD6B1, 0xD6B1, 0xD6B1}, {0xD6B2, 0xD6B2, 0xD6B2}, {0xD6B3, 0xD6B3, 0xD6B3}, {0xD6B4, 0xD6B4, 0xD6B4}, {0xD6B5, 0xD6B5, 0xD6B5}, {0xD6B6, 0xD6B6, 0xD6B6}, {0xD6B7, 0xD6B7, 0xD6B7}, {0xD6B8, 0xD6B8, 0xD6B8}, {0xD6B9, 0xD6B9, 0xD6B9}, {0xD6BA, 0xD6BA, 0xD6BA}, {0xD6BB, 0xD6BB, 0xD6BB}, {0xD6BC, 0xD6BC, 0xD6BC}, {0xD6BD, 0xD6BD, 0xD6BD}, {0xD6BE, 0xD6BE, 0xD6BE}, {0xD6BF, 0xD6BF, 0xD6BF}, {0xD6C0, 0xD6C0, 0xD6C0}, {0xD6C1, 0xD6C1, 0xD6C1}, {0xD6C2, 0xD6C2, 0xD6C2}, {0xD6C3, 0xD6C3, 0xD6C3}, {0xD6C4, 0xD6C4, 0xD6C4}, {0xD6C5, 0xD6C5, 0xD6C5}, {0xD6C6, 0xD6C6, 0xD6C6}, {0xD6C7, 0xD6C7, 0xD6C7}, {0xD6C8, 0xD6C8, 0xD6C8}, {0xD6C9, 0xD6C9, 0xD6C9}, {0xD6CA, 0xD6CA, 0xD6CA}, {0xD6CB, 0xD6CB, 0xD6CB}, {0xD6CC, 0xD6CC, 0xD6CC}, {0xD6CD, 0xD6CD, 0xD6CD}, {0xD6CE, 0xD6CE, 0xD6CE}, {0xD6CF, 0xD6CF, 0xD6CF}, {0xD6D0, 0xD6D0, 0xD6D0}, {0xD6D1, 0xD6D1, 0xD6D1}, {0xD6D2, 0xD6D2, 0xD6D2}, {0xD6D3, 0xD6D3, 0xD6D3}, {0xD6D4, 0xD6D4, 0xD6D4}, {0xD6D5, 0xD6D5, 0xD6D5}, {0xD6D6, 0xD6D6, 0xD6D6}, {0xD6D7, 0xD6D7, 0xD6D7}, {0xD6D8, 0xD6D8, 0xD6D8}, {0xD6D9, 0xD6D9, 0xD6D9}, {0xD6DA, 0xD6DA, 0xD6DA}, {0xD6DB, 0xD6DB, 0xD6DB}, {0xD6DC, 0xD6DC, 0xD6DC}, {0xD6DD, 0xD6DD, 0xD6DD}, {0xD6DE, 0xD6DE, 0xD6DE}, {0xD6DF, 0xD6DF, 0xD6DF}, {0xD6E0, 0xD6E0, 0xD6E0}, {0xD6E1, 0xD6E1, 0xD6E1}, {0xD6E2, 0xD6E2, 0xD6E2}, {0xD6E3, 0xD6E3, 0xD6E3}, {0xD6E4, 0xD6E4, 0xD6E4}, {0xD6E5, 0xD6E5, 0xD6E5}, {0xD6E6, 0xD6E6, 0xD6E6}, {0xD6E7, 0xD6E7, 0xD6E7}, {0xD6E8, 0xD6E8, 0xD6E8}, {0xD6E9, 0xD6E9, 0xD6E9}, {0xD6EA, 0xD6EA, 0xD6EA}, {0xD6EB, 0xD6EB, 0xD6EB}, {0xD6EC, 0xD6EC, 0xD6EC}, {0xD6ED, 0xD6ED, 0xD6ED}, {0xD6EE, 0xD6EE, 0xD6EE}, {0xD6EF, 0xD6EF, 0xD6EF}, {0xD6F0, 0xD6F0, 0xD6F0}, {0xD6F1, 0xD6F1, 0xD6F1}, {0xD6F2, 0xD6F2, 0xD6F2}, {0xD6F3, 0xD6F3, 0xD6F3}, {0xD6F4, 0xD6F4, 0xD6F4}, {0xD6F5, 0xD6F5, 0xD6F5}, {0xD6F6, 0xD6F6, 0xD6F6}, {0xD6F7, 0xD6F7, 0xD6F7}, {0xD6F8, 0xD6F8, 0xD6F8}, {0xD6F9, 0xD6F9, 0xD6F9}, {0xD6FA, 0xD6FA, 0xD6FA}, {0xD6FB, 0xD6FB, 0xD6FB}, {0xD6FC, 0xD6FC, 0xD6FC}, {0xD6FD, 0xD6FD, 0xD6FD}, {0xD6FE, 0xD6FE, 0xD6FE}, {0xD6FF, 0xD6FF, 0xD6FF}, {0xD700, 0xD700, 0xD700}, {0xD701, 0xD701, 0xD701}, {0xD702, 0xD702, 0xD702}, {0xD703, 0xD703, 0xD703}, {0xD704, 0xD704, 0xD704}, {0xD705, 0xD705, 0xD705}, {0xD706, 0xD706, 0xD706}, {0xD707, 0xD707, 0xD707}, {0xD708, 0xD708, 0xD708}, {0xD709, 0xD709, 0xD709}, {0xD70A, 0xD70A, 0xD70A}, {0xD70B, 0xD70B, 0xD70B}, {0xD70C, 0xD70C, 0xD70C}, {0xD70D, 0xD70D, 0xD70D}, {0xD70E, 0xD70E, 0xD70E}, {0xD70F, 0xD70F, 0xD70F}, {0xD710, 0xD710, 0xD710}, {0xD711, 0xD711, 0xD711}, {0xD712, 0xD712, 0xD712}, {0xD713, 0xD713, 0xD713}, {0xD714, 0xD714, 0xD714}, {0xD715, 0xD715, 0xD715}, {0xD716, 0xD716, 0xD716}, {0xD717, 0xD717, 0xD717}, {0xD718, 0xD718, 0xD718}, {0xD719, 0xD719, 0xD719}, {0xD71A, 0xD71A, 0xD71A}, {0xD71B, 0xD71B, 0xD71B}, {0xD71C, 0xD71C, 0xD71C}, {0xD71D, 0xD71D, 0xD71D}, {0xD71E, 0xD71E, 0xD71E}, {0xD71F, 0xD71F, 0xD71F}, {0xD720, 0xD720, 0xD720}, {0xD721, 0xD721, 0xD721}, {0xD722, 0xD722, 0xD722}, {0xD723, 0xD723, 0xD723}, {0xD724, 0xD724, 0xD724}, {0xD725, 0xD725, 0xD725}, {0xD726, 0xD726, 0xD726}, {0xD727, 0xD727, 0xD727}, {0xD728, 0xD728, 0xD728}, {0xD729, 0xD729, 0xD729}, {0xD72A, 0xD72A, 0xD72A}, {0xD72B, 0xD72B, 0xD72B}, {0xD72C, 0xD72C, 0xD72C}, {0xD72D, 0xD72D, 0xD72D}, {0xD72E, 0xD72E, 0xD72E}, {0xD72F, 0xD72F, 0xD72F}, {0xD730, 0xD730, 0xD730}, {0xD731, 0xD731, 0xD731}, {0xD732, 0xD732, 0xD732}, {0xD733, 0xD733, 0xD733}, {0xD734, 0xD734, 0xD734}, {0xD735, 0xD735, 0xD735}, {0xD736, 0xD736, 0xD736}, {0xD737, 0xD737, 0xD737}, {0xD738, 0xD738, 0xD738}, {0xD739, 0xD739, 0xD739}, {0xD73A, 0xD73A, 0xD73A}, {0xD73B, 0xD73B, 0xD73B}, {0xD73C, 0xD73C, 0xD73C}, {0xD73D, 0xD73D, 0xD73D}, {0xD73E, 0xD73E, 0xD73E}, {0xD73F, 0xD73F, 0xD73F}, {0xD740, 0xD740, 0xD740}, {0xD741, 0xD741, 0xD741}, {0xD742, 0xD742, 0xD742}, {0xD743, 0xD743, 0xD743}, {0xD744, 0xD744, 0xD744}, {0xD745, 0xD745, 0xD745}, {0xD746, 0xD746, 0xD746}, {0xD747, 0xD747, 0xD747}, {0xD748, 0xD748, 0xD748}, {0xD749, 0xD749, 0xD749}, {0xD74A, 0xD74A, 0xD74A}, {0xD74B, 0xD74B, 0xD74B}, {0xD74C, 0xD74C, 0xD74C}, {0xD74D, 0xD74D, 0xD74D}, {0xD74E, 0xD74E, 0xD74E}, {0xD74F, 0xD74F, 0xD74F}, {0xD750, 0xD750, 0xD750}, {0xD751, 0xD751, 0xD751}, {0xD752, 0xD752, 0xD752}, {0xD753, 0xD753, 0xD753}, {0xD754, 0xD754, 0xD754}, {0xD755, 0xD755, 0xD755}, {0xD756, 0xD756, 0xD756}, {0xD757, 0xD757, 0xD757}, {0xD758, 0xD758, 0xD758}, {0xD759, 0xD759, 0xD759}, {0xD75A, 0xD75A, 0xD75A}, {0xD75B, 0xD75B, 0xD75B}, {0xD75C, 0xD75C, 0xD75C}, {0xD75D, 0xD75D, 0xD75D}, {0xD75E, 0xD75E, 0xD75E}, {0xD75F, 0xD75F, 0xD75F}, {0xD760, 0xD760, 0xD760}, {0xD761, 0xD761, 0xD761}, {0xD762, 0xD762, 0xD762}, {0xD763, 0xD763, 0xD763}, {0xD764, 0xD764, 0xD764}, {0xD765, 0xD765, 0xD765}, {0xD766, 0xD766, 0xD766}, {0xD767, 0xD767, 0xD767}, {0xD768, 0xD768, 0xD768}, {0xD769, 0xD769, 0xD769}, {0xD76A, 0xD76A, 0xD76A}, {0xD76B, 0xD76B, 0xD76B}, {0xD76C, 0xD76C, 0xD76C}, {0xD76D, 0xD76D, 0xD76D}, {0xD76E, 0xD76E, 0xD76E}, {0xD76F, 0xD76F, 0xD76F}, {0xD770, 0xD770, 0xD770}, {0xD771, 0xD771, 0xD771}, {0xD772, 0xD772, 0xD772}, {0xD773, 0xD773, 0xD773}, {0xD774, 0xD774, 0xD774}, {0xD775, 0xD775, 0xD775}, {0xD776, 0xD776, 0xD776}, {0xD777, 0xD777, 0xD777}, {0xD778, 0xD778, 0xD778}, {0xD779, 0xD779, 0xD779}, {0xD77A, 0xD77A, 0xD77A}, {0xD77B, 0xD77B, 0xD77B}, {0xD77C, 0xD77C, 0xD77C}, {0xD77D, 0xD77D, 0xD77D}, {0xD77E, 0xD77E, 0xD77E}, {0xD77F, 0xD77F, 0xD77F}, {0xD780, 0xD780, 0xD780}, {0xD781, 0xD781, 0xD781}, {0xD782, 0xD782, 0xD782}, {0xD783, 0xD783, 0xD783}, {0xD784, 0xD784, 0xD784}, {0xD785, 0xD785, 0xD785}, {0xD786, 0xD786, 0xD786}, {0xD787, 0xD787, 0xD787}, {0xD788, 0xD788, 0xD788}, {0xD789, 0xD789, 0xD789}, {0xD78A, 0xD78A, 0xD78A}, {0xD78B, 0xD78B, 0xD78B}, {0xD78C, 0xD78C, 0xD78C}, {0xD78D, 0xD78D, 0xD78D}, {0xD78E, 0xD78E, 0xD78E}, {0xD78F, 0xD78F, 0xD78F}, {0xD790, 0xD790, 0xD790}, {0xD791, 0xD791, 0xD791}, {0xD792, 0xD792, 0xD792}, {0xD793, 0xD793, 0xD793}, {0xD794, 0xD794, 0xD794}, {0xD795, 0xD795, 0xD795}, {0xD796, 0xD796, 0xD796}, {0xD797, 0xD797, 0xD797}, {0xD798, 0xD798, 0xD798}, {0xD799, 0xD799, 0xD799}, {0xD79A, 0xD79A, 0xD79A}, {0xD79B, 0xD79B, 0xD79B}, {0xD79C, 0xD79C, 0xD79C}, {0xD79D, 0xD79D, 0xD79D}, {0xD79E, 0xD79E, 0xD79E}, {0xD79F, 0xD79F, 0xD79F}, {0xD7A0, 0xD7A0, 0xD7A0}, {0xD7A1, 0xD7A1, 0xD7A1}, {0xD7A2, 0xD7A2, 0xD7A2}, {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}}; hunspell-1.7.0/src/hunspell/w_char.hxx000066400000000000000000000050531337236234000177740ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 W_CHAR_HXX_ #define W_CHAR_HXX_ #include #ifndef GCC struct w_char { #else struct __attribute__((packed)) w_char { #endif unsigned char l; unsigned char h; friend bool operator<(const w_char a, const w_char b) { unsigned short a_idx = (a.h << 8) + a.l; unsigned short b_idx = (b.h << 8) + b.l; return a_idx < b_idx; } friend bool operator==(const w_char a, const w_char b) { return (((a).l == (b).l) && ((a).h == (b).h)); } friend bool operator!=(const w_char a, const w_char b) { return !(a == b);; } }; // two character arrays struct replentry { std::string pattern; std::string outstrings[4]; // med, ini, fin, isol }; #endif hunspell-1.7.0/src/parsers/000077500000000000000000000000001337236234000156225ustar00rootroot00000000000000hunspell-1.7.0/src/parsers/.gitignore000066400000000000000000000000131337236234000176040ustar00rootroot00000000000000testparser hunspell-1.7.0/src/parsers/Makefile.am000066400000000000000000000011271337236234000176570ustar00rootroot00000000000000 AM_CPPFLAGS=-I${top_builddir}/src/hunspell noinst_LIBRARIES=libparsers.a libparsers_a_SOURCES=firstparser.cxx xmlparser.cxx \ latexparser.cxx manparser.cxx \ textparser.cxx htmlparser.cxx \ odfparser.cxx noinst_PROGRAMS=testparser testparser_SOURCES=firstparser.cxx firstparser.hxx xmlparser.cxx \ xmlparser.hxx latexparser.cxx latexparser.hxx \ manparser.cxx manparser.hxx testparser.cxx \ textparser.cxx textparser.hxx htmlparser.cxx \ htmlparser.hxx odfparser.hxx odfparser.cxx # need mystrdup() LDADD = ../hunspell/libhunspell-1.7.la hunspell-1.7.0/src/parsers/firstparser.cxx000066400000000000000000000046371337236234000207240ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/csutil.hxx" #include "firstparser.hxx" #ifndef W32 using namespace std; #endif FirstParser::FirstParser(const char* wordchars) : TextParser(wordchars) { } FirstParser::~FirstParser() {} bool FirstParser::next_token(std::string& t) { t.clear(); const size_t tabpos = line[actual].find('\t'); if (tabpos != std::string::npos && tabpos > token) { token = tabpos; t = line[actual].substr(0, tabpos); return true; } return false; } hunspell-1.7.0/src/parsers/firstparser.hxx000066400000000000000000000042351337236234000207230ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 FIRSTPARSER_HXX_ #define FIRSTPARSER_HXX_ #include "textparser.hxx" /* * Check first word of the input line * */ class FirstParser : public TextParser { public: explicit FirstParser(const char* wc); virtual ~FirstParser(); virtual bool next_token(std::string&); }; #endif hunspell-1.7.0/src/parsers/htmlparser.cxx000066400000000000000000000066231337236234000205360ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/csutil.hxx" #include "htmlparser.hxx" #ifndef W32 using namespace std; #endif static const char* PATTERN[][2] = {{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {"<[cdata[", "]]>"}, // XML comment {"<", ">"}}; #define PATTERN_LEN (sizeof(PATTERN) / (sizeof(char*) * 2)) static const char* PATTERN2[][2] = { {" #include #include #include #include "../hunspell/csutil.hxx" #include "latexparser.hxx" #ifndef W32 using namespace std; #endif #define UTF8_APOS "\xe2\x80\x99" #define APOSTROPHE "'" static struct { const char* pat[2]; int arg; } PATTERN[] = {{{"\\(", "\\)"}, 0}, {{"$$", "$$"}, 0}, {{"$", "$"}, 0}, {{"\\begin{math}", "\\end{math}"}, 0}, {{"\\[", "\\]"}, 0}, {{"\\begin{displaymath}", "\\end{displaymath}"}, 0}, {{"\\begin{equation}", "\\end{equation}"}, 0}, {{"\\begin{equation*}", "\\end{equation*}"}, 0}, {{"\\cite", NULL}, 1}, {{"\\nocite", NULL}, 1}, {{"\\index", NULL}, 1}, {{"\\label", NULL}, 1}, {{"\\ref", NULL}, 1}, {{"\\pageref", NULL}, 1}, {{"\\autoref", NULL}, 1}, {{"\\parbox", NULL}, 1}, {{"\\begin{verbatim}", "\\end{verbatim}"}, 0}, {{"\\verb+", "+"}, 0}, {{"\\verb|", "|"}, 0}, {{"\\verb#", "#"}, 0}, {{"\\verb*", "*"}, 0}, {{"\\documentstyle", "\\begin{document}"}, 0}, {{"\\documentclass", "\\begin{document}"}, 0}, // { { "\\documentclass", NULL } , 1 }, {{"\\usepackage", NULL}, 1}, {{"\\includeonly", NULL}, 1}, {{"\\include", NULL}, 1}, {{"\\input", NULL}, 1}, {{"\\vspace", NULL}, 1}, {{"\\setlength", NULL}, 2}, {{"\\addtolength", NULL}, 2}, {{"\\settowidth", NULL}, 2}, {{"\\rule", NULL}, 2}, {{"\\hspace", NULL}, 1}, {{"\\vspace", NULL}, 1}, {{"\\\\[", "]"}, 0}, {{"\\pagebreak[", "]"}, 0}, {{"\\nopagebreak[", "]"}, 0}, {{"\\enlargethispage", NULL}, 1}, {{"\\begin{tabular}", NULL}, 1}, {{"\\addcontentsline", NULL}, 2}, {{"\\begin{thebibliography}", NULL}, 1}, {{"\\bibliography", NULL}, 1}, {{"\\bibliographystyle", NULL}, 1}, {{"\\bibitem", NULL}, 1}, {{"\\begin", NULL}, 1}, {{"\\end", NULL}, 1}, {{"\\pagestyle", NULL}, 1}, {{"\\pagenumbering", NULL}, 1}, {{"\\thispagestyle", NULL}, 1}, {{"\\newtheorem", NULL}, 2}, {{"\\newcommand", NULL}, 2}, {{"\\renewcommand", NULL}, 2}, {{"\\setcounter", NULL}, 2}, {{"\\addtocounter", NULL}, 1}, {{"\\stepcounter", NULL}, 1}, {{"\\selectlanguage", NULL}, 1}, {{"\\inputencoding", NULL}, 1}, {{"\\hyphenation", NULL}, 1}, {{"\\definecolor", NULL}, 3}, {{"\\color", NULL}, 1}, {{"\\textcolor", NULL}, 1}, {{"\\pagecolor", NULL}, 1}, {{"\\colorbox", NULL}, 2}, {{"\\fcolorbox", NULL}, 2}, {{"\\declaregraphicsextensions", NULL}, 1}, {{"\\psfig", NULL}, 1}, {{"\\url", NULL}, 1}, {{"\\eqref", NULL}, 1}, {{"\\vskip", NULL}, 1}, {{"\\vglue", NULL}, 1}, {{"\'\'", NULL}, 1}}; #define PATTERN_LEN (sizeof(PATTERN) / sizeof(PATTERN[0])) LaTeXParser::LaTeXParser(const char* wordchars) : TextParser(wordchars) , pattern_num(0), depth(0), arg(0), opt(0) { } LaTeXParser::LaTeXParser(const w_char* wordchars, int len) : TextParser(wordchars, len) , pattern_num(0), depth(0), arg(0), opt(0) { } LaTeXParser::~LaTeXParser() {} int LaTeXParser::look_pattern(int col) { for (unsigned int i = 0; i < PATTERN_LEN; i++) { const char* j = line[actual].c_str() + head; const char* k = PATTERN[i].pat[col]; if (!k) continue; while ((*k != '\0') && (tolower(*j) == *k)) { j++; k++; } if (*k == '\0') return i; } return -1; } /* * LaTeXParser * * state 0: not wordchar * state 1: wordchar * state 2: comments * state 3: commands * state 4: commands with arguments * state 5: % comment * */ bool LaTeXParser::next_token(std::string& t) { t.clear(); int i; int slash = 0; int apostrophe; for (;;) { // fprintf(stderr,"depth: %d, state: %d, , arg: %d, token: // %s\n",depth,state,arg,line[actual]+head); switch (state) { case 0: // non word chars if ((pattern_num = look_pattern(0)) != -1) { if (PATTERN[pattern_num].pat[1]) { state = 2; } else { state = 4; depth = 0; arg = 0; opt = 1; } head += strlen(PATTERN[pattern_num].pat[0]) - 1; } else if (line[actual][head] == '%') { state = 5; } else if (is_wordchar(line[actual].c_str() + head)) { state = 1; token = head; } else if (line[actual][head] == '\\') { if (line[actual][head + 1] == '\\' || // \\ (linebreak) (line[actual][head + 1] == '$') || // \$ (dollar sign) (line[actual][head + 1] == '%')) { // \% (percent) head++; break; } state = 3; } break; case 1: // wordchar apostrophe = 0; if ((is_wordchar((char*)APOSTROPHE) || (is_utf8() && is_wordchar((char*)UTF8_APOS))) && !line[actual].empty() && line[actual][head] == '\'' && is_wordchar(line[actual].c_str() + head + 1)) { head++; } else if (is_utf8() && is_wordchar((char*)APOSTROPHE) && // add Unicode apostrophe // to the WORDCHARS, if // needed strncmp(line[actual].c_str() + head, UTF8_APOS, strlen(UTF8_APOS)) == 0 && is_wordchar(line[actual].c_str() + head + strlen(UTF8_APOS))) { head += strlen(UTF8_APOS) - 1; } else if (!is_wordchar(line[actual].c_str() + head) || (line[actual][head] == '\'' && line[actual][head + 1] == '\'' && ++apostrophe)) { state = 0; bool ok = alloc_token(token, &head, t); if (apostrophe) head += 2; if (ok) return true; } break; case 2: // comment, labels, etc if (((i = look_pattern(1)) != -1) && (strcmp(PATTERN[i].pat[1], PATTERN[pattern_num].pat[1]) == 0)) { state = 0; head += strlen(PATTERN[pattern_num].pat[1]) - 1; } break; case 3: // command if ((tolower(line[actual][head]) < 'a') || (tolower(line[actual][head]) > 'z')) { state = 0; head--; } break; case 4: // command with arguments if (slash && (line[actual][head] != '\0')) { slash = 0; head++; break; } else if (line[actual][head] == '\\') { slash = 1; } else if ((line[actual][head] == '{') || ((opt) && (line[actual][head] == '['))) { depth++; opt = 0; } else if (line[actual][head] == '}') { depth--; if (depth == 0) { opt = 1; arg++; } if (((depth == 0) && (arg == PATTERN[pattern_num].arg)) || (depth < 0)) { state = 0; // XXX not handles the last optional arg. } } else if (line[actual][head] == ']') depth--; } // case if (next_char(line[actual].c_str(), &head)) { if (state == 5) state = 0; return false; } } } hunspell-1.7.0/src/parsers/latexparser.hxx000066400000000000000000000046131337236234000207110ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 LATEXPARSER_HXX_ #define LATEXPARSER_HXX_ #include "textparser.hxx" /* * HTML Parser * */ class LaTeXParser : public TextParser { int pattern_num; // number of comment int depth; // depth of blocks int arg; // arguments's number int opt; // optional argument attrib. public: explicit LaTeXParser(const char* wc); LaTeXParser(const w_char* wordchars, int len); virtual ~LaTeXParser(); virtual bool next_token(std::string&); private: int look_pattern(int col); }; #endif hunspell-1.7.0/src/parsers/manparser.cxx000066400000000000000000000063461337236234000203470ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/csutil.hxx" #include "manparser.hxx" #ifndef W32 using namespace std; #endif ManParser::ManParser(const char* wordchars) : TextParser(wordchars) { } ManParser::ManParser(const w_char* wordchars, int len) : TextParser(wordchars, len) { } ManParser::~ManParser() {} bool ManParser::next_token(std::string& t) { for (;;) { switch (state) { case 1: // command arguments if (line[actual][head] == ' ') state = 2; break; case 0: // dot in begin of line if (line[actual][0] == '.') { state = 1; break; } else { state = 2; } /* FALLTHROUGH */ case 2: // non word chars if (is_wordchar(line[actual].c_str() + head)) { state = 3; token = head; } else if ((line[actual][head] == '\\') && (line[actual][head + 1] == 'f') && (line[actual][head + 2] != '\0')) { head += 2; } break; case 3: // wordchar if (!is_wordchar(line[actual].c_str() + head)) { state = 2; if (alloc_token(token, &head, t)) return true; } break; } if (next_char(line[actual].c_str(), &head)) { state = 0; return false; } } } hunspell-1.7.0/src/parsers/manparser.hxx000066400000000000000000000042731337236234000203510ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 MANPARSER_HXX_ #define MANPARSER_HXX_ #include "textparser.hxx" /* * Manparse Parser * */ class ManParser : public TextParser { protected: public: explicit ManParser(const char* wc); ManParser(const w_char* wordchars, int len); virtual ~ManParser(); virtual bool next_token(std::string&); }; #endif hunspell-1.7.0/src/parsers/odfparser.cxx000066400000000000000000000061311337236234000203340ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/csutil.hxx" #include "odfparser.hxx" #ifndef W32 using namespace std; #endif static const char* PATTERN[][2] = { {"", ""}, {"", ""}, {"", ""}, {""}, {"<[cdata[", "]]>"}, // XML comment {"<", ">"}}; #define PATTERN_LEN (sizeof(PATTERN) / (sizeof(char*) * 2)) static const char* (*PATTERN2)[2] = NULL; #define PATTERN_LEN2 0 static const char* PATTERN3[][2] = { {""}, // part of the reedited words {""}}; // for example, an inserted letter #define PATTERN_LEN3 (sizeof(PATTERN3) / (sizeof(char*) * 2)) ODFParser::ODFParser(const char* wordchars) : XMLParser(wordchars) { } ODFParser::ODFParser(const w_char* wordchars, int len) : XMLParser(wordchars, len) { } bool ODFParser::next_token(std::string& t) { return XMLParser::next_token(PATTERN, PATTERN_LEN, PATTERN2, PATTERN_LEN2, PATTERN3, PATTERN_LEN3, t); } std::string ODFParser::get_word(const std::string &tok) { return XMLParser::get_word2(PATTERN3, PATTERN_LEN3, tok); } ODFParser::~ODFParser() {} hunspell-1.7.0/src/parsers/odfparser.hxx000066400000000000000000000043401337236234000203410ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ODFPARSER_HXX_ #define ODFPARSER_HXX_ #include "xmlparser.hxx" /* * HTML Parser * */ class ODFParser : public XMLParser { public: explicit ODFParser(const char* wc); ODFParser(const w_char* wordchars, int len); virtual bool next_token(std::string&); virtual std::string get_word(const std::string &tok); virtual ~ODFParser(); }; #endif hunspell-1.7.0/src/parsers/testparser.cxx000066400000000000000000000055431337236234000205510ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "textparser.hxx" #include "htmlparser.hxx" #include "latexparser.hxx" #include "xmlparser.hxx" #ifndef W32 using namespace std; #endif int main(int argc, char** argv) { FILE* f; /* first parse the command line options */ if (argc < 2) { fprintf(stderr, "correct syntax is:\n"); fprintf(stderr, "testparser file\n"); fprintf(stderr, "example: testparser /dev/stdin\n"); exit(1); } /* open the words to check list */ f = fopen(argv[1], "r"); if (!f) { fprintf(stderr, "Error - could not open file of words to check\n"); exit(1); } TextParser* p = new TextParser( "qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM"); char buf[MAXLNLEN]; while (fgets(buf, MAXLNLEN, f)) { p->put_line(buf); p->set_url_checking(1); std::string next; while (p->next_token(next)) { fprintf(stdout, "token: %s\n", next.c_str()); } } delete p; fclose(f); return 0; } hunspell-1.7.0/src/parsers/textparser.cxx000066400000000000000000000215211337236234000205500ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/csutil.hxx" #include "textparser.hxx" #include #ifndef W32 using namespace std; #endif // ISO-8859-1 HTML character entities static const char* LATIN1[] = { "À", "Ã", "Å", "Æ", "È", "Ê", "Ì", "Ï", "Ð", "Ñ", "Ò", "Ø", "Ù", "Þ", "à", "ã", "å", "æ", "è", "ê", "ì", "ï", "ð", "ñ", "ò", "ø", "ù", "þ", "ÿ"}; #define LATIN1_LEN (sizeof(LATIN1) / sizeof(char*)) #define ENTITY_APOS "'" #define UTF8_APOS "\xe2\x80\x99" #define APOSTROPHE "'" TextParser::TextParser(const char* wordchars) { init(wordchars); } TextParser::TextParser(const w_char* wordchars, int len) { init(wordchars, len); } TextParser::~TextParser() {} int TextParser::is_wordchar(const char* w) { if (*w == '\0') return 0; if (utf8) { std::vector wc; unsigned short idx; u8_u16(wc, w); if (wc.empty()) return 0; idx = (wc[0].h << 8) + wc[0].l; return (unicodeisalpha(idx) || (wordchars_utf16 && std::binary_search(wordchars_utf16, wordchars_utf16 + wclen, wc[0]))); } else { return wordcharacters[(*w + 256) % 256]; } } const char* TextParser::get_latin1(const char* s) { if (s[0] == '&') { unsigned int i = 0; while ((i < LATIN1_LEN) && strncmp(LATIN1[i], s, strlen(LATIN1[i]))) i++; if (i != LATIN1_LEN) return LATIN1[i]; } return NULL; } void TextParser::init(const char* wordchars) { actual = 0; head = 0; token = 0; state = 0; utf8 = 0; checkurl = 0; wordchars_utf16 = NULL; wclen = 0; wordcharacters.resize(256, 0); if (!wordchars) wordchars = "qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM"; for (unsigned int j = 0; j < strlen(wordchars); ++j) { wordcharacters[(wordchars[j] + 256) % 256] = 1; } } void TextParser::init(const w_char* wc, int len) { actual = 0; head = 0; token = 0; state = 0; utf8 = 1; checkurl = 0; wordchars_utf16 = wc; wclen = len; } int TextParser::next_char(const char* ln, size_t* pos) { if (*(ln + *pos) == '\0') return 1; if (utf8) { if (*(ln + *pos) >> 7) { // jump to next UTF-8 character for ((*pos)++; (*(ln + *pos) & 0xc0) == 0x80; (*pos)++) ; } else { (*pos)++; } } else (*pos)++; return 0; } void TextParser::put_line(const char* word) { actual = (actual + 1) % MAXPREVLINE; line[actual].assign(word); token = 0; head = 0; check_urls(); } std::string TextParser::get_prevline(int n) const { return line[(actual + MAXPREVLINE - n) % MAXPREVLINE]; } std::string TextParser::get_line() const { return get_prevline(0); } bool TextParser::next_token(std::string &t) { const char* latin1; for (;;) { switch (state) { case 0: // non word chars if (is_wordchar(line[actual].c_str() + head)) { state = 1; token = head; } else if ((latin1 = get_latin1(line[actual].c_str() + head))) { state = 1; token = head; head += strlen(latin1); } break; case 1: // wordchar if ((latin1 = get_latin1(line[actual].c_str() + head))) { head += strlen(latin1); } else if ((is_wordchar((char*)APOSTROPHE) || (is_utf8() && is_wordchar((char*)UTF8_APOS))) && !line[actual].empty() && line[actual][head] == '\'' && is_wordchar(line[actual].c_str() + head + 1)) { head++; } else if (is_utf8() && is_wordchar((char*)APOSTROPHE) && // add Unicode apostrophe // to the WORDCHARS, if // needed strncmp(line[actual].c_str() + head, UTF8_APOS, strlen(UTF8_APOS)) == 0 && is_wordchar(line[actual].c_str() + head + strlen(UTF8_APOS))) { head += strlen(UTF8_APOS) - 1; } else if (!is_wordchar(line[actual].c_str() + head)) { state = 0; if (alloc_token(token, &head, t)) return true; } break; } if (next_char(line[actual].c_str(), &head)) return false; } } size_t TextParser::get_tokenpos() { return token; } int TextParser::change_token(const char* word) { if (word) { std::string remainder(line[actual].substr(head)); line[actual].resize(token); line[actual].append(word); line[actual].append(remainder); head = token; return 1; } return 0; } std::string TextParser::get_word(const std::string &tok) { return tok; } void TextParser::check_urls() { urlline.resize(line[actual].size() + 1); int url_state = 0; size_t url_head = 0; size_t url_token = 0; int url = 0; for (;;) { switch (url_state) { case 0: // non word chars if (is_wordchar(line[actual].c_str() + url_head)) { url_state = 1; url_token = url_head; // Unix path } else if (line[actual][url_head] == '/') { url_state = 1; url_token = url_head; url = 1; } break; case 1: // wordchar char ch = line[actual][url_head]; // e-mail address if ((ch == '@') || // MS-DOS, Windows path (strncmp(line[actual].c_str() + url_head, ":\\", 2) == 0) || // URL (strncmp(line[actual].c_str() + url_head, "://", 3) == 0)) { url = 1; } else if (!(is_wordchar(line[actual].c_str() + url_head) || (ch == '-') || (ch == '_') || (ch == '\\') || (ch == '.') || (ch == ':') || (ch == '/') || (ch == '~') || (ch == '%') || (ch == '*') || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '?') || (ch == '!') || ((ch >= '0') && (ch <= '9')))) { url_state = 0; if (url == 1) { for (size_t i = url_token; i < url_head; ++i) { urlline[i] = true; } } url = 0; } break; } urlline[url_head] = false; if (next_char(line[actual].c_str(), &url_head)) return; } } int TextParser::get_url(size_t token_pos, size_t* hd) { for (size_t i = *hd; i < line[actual].size() && urlline[i]; i++, (*hd)++) ; return checkurl ? 0 : urlline[token_pos]; } void TextParser::set_url_checking(int check) { checkurl = check; } bool TextParser::alloc_token(size_t tokn, size_t* hd, std::string& t) { size_t url_head = *hd; if (get_url(tokn, &url_head)) return false; t = line[actual].substr(tokn, *hd - tokn); // remove colon for Finnish and Swedish language if (!t.empty() && t[t.size() - 1] == ':') { t.resize(t.size() - 1); if (t.empty()) { return false; } } return true; } hunspell-1.7.0/src/parsers/textparser.hxx000066400000000000000000000066401337236234000205620ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 TEXTPARSER_HXX_ #define TEXTPARSER_HXX_ // set sum of actual and previous lines #define MAXPREVLINE 4 #ifndef MAXLNLEN #define MAXLNLEN 8192 #endif #include "../hunspell/w_char.hxx" #include /* * Base Text Parser * */ class TextParser { protected: std::vector wordcharacters;// for detection of the word boundaries std::string line[MAXPREVLINE]; // parsed and previous lines std::vector urlline; // mask for url detection int checkurl; int actual; // actual line size_t head; // head position size_t token;// begin of token int state; // state of automata int utf8; // UTF-8 character encoding int next_char(const char* line, size_t* pos); const w_char* wordchars_utf16; int wclen; public: TextParser(const w_char* wordchars, int len); explicit TextParser(const char* wc); virtual ~TextParser(); void put_line(const char* line); std::string get_line() const; std::string get_prevline(int n) const; virtual bool next_token(std::string&); virtual std::string get_word(const std::string &tok); virtual int change_token(const char* word); void set_url_checking(int check); size_t get_tokenpos(); int is_wordchar(const char* w); inline int is_utf8() { return utf8; } const char* get_latin1(const char* s); char* next_char(); int tokenize_urls(); void check_urls(); int get_url(size_t token_pos, size_t* head); bool alloc_token(size_t token, size_t* head, std::string& out); private: void init(const char*); void init(const w_char* wordchars, int len); }; #endif hunspell-1.7.0/src/parsers/xmlparser.cxx000066400000000000000000000221501337236234000203630ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/csutil.hxx" #include "xmlparser.hxx" #ifndef W32 using namespace std; #endif enum { ST_NON_WORD, ST_WORD, ST_TAG, ST_CHAR_ENTITY, ST_OTHER_TAG, ST_ATTRIB }; static const char* __PATTERN__[][2] = {{""}, {"<[cdata[", "]]>"}, // XML comment {"<", ">"}}; #define __PATTERN_LEN__ (sizeof(__PATTERN__) / (sizeof(char*) * 2)) // for checking attributes, eg. text in HTML static const char* (*__PATTERN2__)[2] = NULL; #define __PATTERN_LEN2__ 0 // for checking words with in-word patterns // for example, "example" in ODT static const char* (*__PATTERN3__)[2] = NULL; #define __PATTERN_LEN3__ 0 #define ENTITY_APOS "'" #define UTF8_APOS "\xe2\x80\x99" #define APOSTROPHE "'" XMLParser::XMLParser(const char* wordchars) : TextParser(wordchars) , pattern_num(0), pattern2_num(0), pattern3_num(0), prevstate(0), checkattr(0), quotmark(0) { } XMLParser::XMLParser(const w_char* wordchars, int len) : TextParser(wordchars, len) , pattern_num(0), pattern2_num(0), pattern3_num(0), prevstate(0), checkattr(0), quotmark(0) { } XMLParser::~XMLParser() {} int XMLParser::look_pattern(const char* p[][2], unsigned int len, int column) { for (unsigned int i = 0; i < len; i++) { const char* j = line[actual].c_str() + head; const char* k = p[i][column]; while ((*k != '\0') && (tolower(*j) == *k)) { j++; k++; } if (*k == '\0') return i; } return -1; } /* * XML parser * */ bool XMLParser::next_token(const char* PATTERN[][2], unsigned int PATTERN_LEN, const char* PATTERN2[][2], unsigned int PATTERN_LEN2, const char* PATTERN3[][2], unsigned int PATTERN_LEN3, std::string& t) { t.clear(); const char* latin1; for (;;) { switch (state) { case ST_NON_WORD: // non word chars prevstate = ST_NON_WORD; if ((pattern_num = look_pattern(PATTERN, PATTERN_LEN, 0)) != -1) { checkattr = 0; if ((pattern2_num = look_pattern(PATTERN2, PATTERN_LEN2, 0)) != -1) { checkattr = 1; } state = ST_TAG; } else if (is_wordchar(line[actual].c_str() + head)) { state = ST_WORD; token = head; } else if ((latin1 = get_latin1(line[actual].c_str() + head))) { state = ST_WORD; token = head; head += strlen(latin1); } else if (line[actual][head] == '&') { state = ST_CHAR_ENTITY; } break; case ST_WORD: // wordchar if ((latin1 = get_latin1(line[actual].c_str() + head))) { head += strlen(latin1); } else if ((is_wordchar((char*)APOSTROPHE) || (is_utf8() && is_wordchar((char*)UTF8_APOS))) && strncmp(line[actual].c_str() + head, ENTITY_APOS, strlen(ENTITY_APOS)) == 0 && is_wordchar(line[actual].c_str() + head + strlen(ENTITY_APOS))) { head += strlen(ENTITY_APOS) - 1; } else if (is_utf8() && is_wordchar((char*)APOSTROPHE) && // add Unicode apostrophe // to the WORDCHARS, if // needed strncmp(line[actual].c_str() + head, UTF8_APOS, strlen(UTF8_APOS)) == 0 && is_wordchar(line[actual].c_str() + head + strlen(UTF8_APOS))) { head += strlen(UTF8_APOS) - 1; } else if (!is_wordchar(line[actual].c_str() + head)) { // in-word patterns if ((pattern3_num = look_pattern(PATTERN3, PATTERN_LEN3, 0)) != -1) { size_t pos = line[actual].find(PATTERN3[pattern3_num][1], head); if (pos != std::string::npos) { size_t endpos = pos + strlen(PATTERN3[pattern3_num][1]) - 1; if (is_wordchar(line[actual].c_str() + endpos + 1)) { head = endpos; break; } } } state = prevstate; // return with the token, except in the case of in-word patterns if (alloc_token(token, &head, t)) return true; } break; case ST_TAG: // comment, labels, etc int i; if ((checkattr == 1) && ((i = look_pattern(PATTERN2, PATTERN_LEN2, 1)) != -1) && (strcmp(PATTERN2[i][0], PATTERN2[pattern2_num][0]) == 0)) { checkattr = 2; } else if ((checkattr > 0) && (line[actual][head] == '>')) { state = ST_NON_WORD; } else if (((i = look_pattern(PATTERN, PATTERN_LEN, 1)) != -1) && (strcmp(PATTERN[i][1], PATTERN[pattern_num][1]) == 0)) { state = ST_NON_WORD; head += strlen(PATTERN[pattern_num][1]) - 1; } else if ((strcmp(PATTERN[pattern_num][0], "<") == 0) && ((line[actual][head] == '"') || (line[actual][head] == '\''))) { quotmark = line[actual][head]; state = ST_ATTRIB; } break; case ST_ATTRIB: // non word chars prevstate = ST_ATTRIB; if (line[actual][head] == quotmark) { state = ST_TAG; if (checkattr == 2) checkattr = 1; // for IMG ALT } else if (is_wordchar(line[actual].c_str() + head) && (checkattr == 2)) { state = ST_WORD; token = head; } else if (line[actual][head] == '&') { state = ST_CHAR_ENTITY; } break; case ST_CHAR_ENTITY: // SGML element if ((tolower(line[actual][head]) == ';')) { state = prevstate; head--; } } if (next_char(line[actual].c_str(), &head)) return false; } //FIXME No return, in function returning non-void } bool XMLParser::next_token(std::string& t) { return next_token(__PATTERN__, __PATTERN_LEN__, __PATTERN2__, __PATTERN_LEN2__, __PATTERN3__, __PATTERN_LEN3__, t); } // remove in-word patterns std::string XMLParser::get_word2( const char* PATTERN3[][2], unsigned int PATTERN_LEN3, const std::string &tok) { std::string word = tok; for (unsigned int i = 0; i < PATTERN_LEN3; i++) { size_t pos; while ((pos = word.find(PATTERN3[i][0])) != word.npos) { size_t endpos = word.find(PATTERN3[i][1], pos); if (endpos != word.npos) { word.erase(pos, endpos + strlen(PATTERN3[i][1]) - pos); } else return word; } } return word; } int XMLParser::change_token(const char* word) { if (strstr(word, APOSTROPHE) != NULL || strchr(word, '"') != NULL || strchr(word, '&') != NULL || strchr(word, '<') != NULL || strchr(word, '>') != NULL) { std::string r(word); mystrrep(r, "&", "__namp;__"); mystrrep(r, "__namp;__", "&"); mystrrep(r, APOSTROPHE, ENTITY_APOS); mystrrep(r, "\"", """); mystrrep(r, ">", ">"); mystrrep(r, "<", "<"); return TextParser::change_token(r.c_str()); } return TextParser::change_token(word); } hunspell-1.7.0/src/parsers/xmlparser.hxx000066400000000000000000000054161337236234000203760ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 XMLPARSER_HXX_ #define XMLPARSER_HXX_ #include "textparser.hxx" /* * XML Parser * */ class XMLParser : public TextParser { public: explicit XMLParser(const char* wc); XMLParser(const w_char* wordchars, int len); bool next_token(const char* p[][2], unsigned int len, const char* p2[][2], unsigned int len2, const char* p3[][2], unsigned int len3, std::string&); virtual bool next_token(std::string&); std::string get_word2(const char* p2[][2], unsigned int len2, const std::string &tok); int change_token(const char* word); virtual ~XMLParser(); private: int look_pattern(const char* p[][2], unsigned int len, int column); int pattern_num; int pattern2_num; int pattern3_num; int prevstate; int checkattr; char quotmark; }; #endif hunspell-1.7.0/src/tools/000077500000000000000000000000001337236234000153035ustar00rootroot00000000000000hunspell-1.7.0/src/tools/.gitignore000066400000000000000000000001051337236234000172670ustar00rootroot00000000000000analyze bulkcheck chmorph example hunspell hunzip hzip munch unmunch hunspell-1.7.0/src/tools/Makefile.am000066400000000000000000000015721337236234000173440ustar00rootroot00000000000000bin_PROGRAMS=analyze chmorph hunspell munch unmunch hzip hunzip AM_CPPFLAGS=-I${top_builddir}/src/hunspell -I${top_srcdir}/src/hunspell -I${top_srcdir}/src/parsers hzip_SOURCES=hzip.cxx hunzip_SOURCES=hunzip.cxx hunzip_LDADD = ../hunspell/libhunspell-1.7.la munch_SOURCES=munch.cxx munch.h unmunch_SOURCES=unmunch.cxx unmunch.h example_SOURCES=example.cxx example_LDADD = ../hunspell/libhunspell-1.7.la hunspell_SOURCES=hunspell.cxx nodist_hunspell_SOURCES= ../../config.h hunspell_LDADD = @LIBINTL@ @LIBICONV@ ../parsers/libparsers.a \ ../hunspell/libhunspell-1.7.la @CURSESLIB@ @READLINELIB@ analyze_SOURCES=analyze.cxx analyze_LDADD = ../hunspell/libhunspell-1.7.la chmorph_SOURCES=chmorph.cxx chmorph_LDADD = ../parsers/libparsers.a ../hunspell/libhunspell-1.7.la noinst_PROGRAMS=example dist_bin_SCRIPTS=makealias affixcompress wordforms ispellaff2myspell wordlist2hunspell hunspell-1.7.0/src/tools/affixcompress000077500000000000000000000121531337236234000201040ustar00rootroot00000000000000#!/bin/sh # affix compressor utility for Hunspell # 2008 (c) László Németh, version 0.3 # usage: affixcompress sorted_word_list_file [max_affix_rules] case $# in 0) echo \ "affixcompress - compress a huge sorted word list to Hunspell format Usage: LC_ALL=C sort word_list >sorted_word_list affixcompress sorted_word_list [max_affix_rules] Default value of max_affix_rules = 5000 Note: output may need manually added affix parameters (SET character_encoding, TRY suggestion_characters etc., see man(4) hunspell)" exit 0;; esac MAXAFFIX=${2:-5000} # profiling #AWK="pgawk --profile" AWK="awk" if which gawk; then AWK="gawk" fi rm -f $1.aff $1.dic cat $1 | $AWK ' { # calculate frequent suffixes A[$1] = 1 len = length($1) if (len > 2) { # print $1, substr($1, 1, len - 1), substr($1, len, 1) >"/dev/stderr" B[substr($1, 1, len - 1)] = substr($1, len, 1); } for(i = 2; i < len; i++) { r = substr($1, 1, i) if (i == 2) { if (prev != r) { delete A delete B print "Deleted roots: ", prev > "/dev/stderr" A[$1] = 1 } prev = r } if (A[r]) { # print $1 ": " r " és "substr($1, i + 1, len - i + 1) >"/dev/stderr" sfx[substr($1, i + 1, len - i + 1)]++ } else if (B[r] && B[r] != substr($1, i + 1, 1)) { r2 = substr($1, i + 1, len - i + 1) sfy[r2,B[r]]++ } } } END { for (i in sfx) print i, 0, sfx[i] for (i in sfy) print i, sfy[i] } ' | tr '\034' ' ' >affixcompress0.tmp sort -rnk 3 affixcompress0.tmp | $AWK '$3 >= 1{print $0}' | head -$MAXAFFIX >affixcompress1.tmp cat affixcompress1.tmp | $AWK ' function potential_roots() { # potential roots with most frequent suffixes for(word in W) if (W[word]==1) { print word >"word" len = length(word); for(i = 2; i < len; i++) { root = substr(word, 1, i) suff = substr(word, i + 1, len - i + 1) if ((W[root]!="") && (sfxfr[suff] > 100)) C[root]++ if (sfz[suff]) { l = split(sfz[suff], a) for (k=1; k <= l; k++) if ((W[root a[k]]!="") && (sfyfr[root a[k]] > 100)) { C[root a[k]]++ } } } } # calculate roots for(word in W) if (W[word]==1) { print word >"word2" len = length(word); z = 0 # choose most frequent root (maybe the original word) max = C[word] maxword = word maxsuff = 0 for(i = 2; i < len; i++) { root = substr(word, 1, i) suff = substr(word, i + 1, len - i + 1) if ((sfx[suff] != "") && (C[root] > max)) { max = C[root] maxword = root maxsuff = sfx[suff] } if (sfz[suff] != "") { l = split(sfz[suff], a) for (k=1; k <= l; k++) if (C[root a[k]] > max) { max = C[root a[k]] maxword = root a[k] maxsuff = sfy[suff,a[k]] } } } if (max > 0) { if (maxsuff > 0) print maxword, maxsuff; else print maxword A[maxword]++ z=1 } else { for(i = 2; i < len; i++) { root = substr(word, 1, i) suff = substr(word, i + 1, len - i + 1) if ((A[root] > 0) && sfx[suff]!="") { print root, sfx[suff] z = 1 break } if (sfz[suff]) { l = split(sfz[suff], a) for (k=1; k <= l; k++) if (A[root a[k]]!="") { print root a[k], sfy[suff,a[k]] z = 1 break } } } } if (z == 0) { print word A[word]++ } } delete A delete C } FILENAME == "-" { if ($2 == 0) { sfx[$1] = NR sfxfr[$1] = $3 } else { sfy[$1,$2] = NR sfyfr[$1,$2] = $3 sfz[$1] = sfz[$1] " " $2 } maxsuf = NR next } { cap = substr($1, 1, 3) if (cap != prev) { potential_roots() delete W print "Deleted class:", prev > "/dev/stderr" } prev = cap W[$1] = 1 } END { potential_roots() # write out frequent suffixes out=FILENAME ".aff" print "FLAG num" >out for (i in sfx) if (sfx[i] > 0) { print "SFX", sfx[i], "Y 1" >out print "SFX", sfx[i], "0", i, "." >out } for (i in sfy) if (sfy[i] > 0) { print "SFX", sfy[i], "Y 1" >out split(i, c, "\034"); print "SFX", sfy[i], c[2], c[1], c[2] >out } } ' - $1 >affixcompress2.tmp sort -nk 2 affixcompress2.tmp >affixcompress3.tmp cat affixcompress3.tmp | $AWK -v out="$1.dic" ' { if (A[$1]=="") A[$1]=$2; else if ($2!="") A[$1] = A[$1] "," $2 } END { for (i in A) n++ print n >out for (i in A) { if (A[i]=="") print i else print i "/" A[i] } } ' | sort >>$1.dic hunspell-1.7.0/src/tools/analyze.cxx000066400000000000000000000072441337236234000175010ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/hunspell.hxx" #ifndef WIN32 using namespace std; #endif int main(int, char** argv) { /* first parse the command line options */ for (int i = 1; i < 3; ++i) if (!argv[i]) { fprintf(stderr, "correct syntax is:\nanalyze affix_file"); fprintf(stderr, " dictionary_file file_of_words_to_check\n"); fprintf(stderr, "use two words per line for morphological generation\n"); exit(1); } /* open the words to check list */ FILE* wtclst = fopen(argv[3], "r"); if (!wtclst) { fprintf(stderr, "Error - could not open file to check\n"); exit(1); } Hunspell* pMS = new Hunspell(argv[1], argv[2]); char buf[100]; while (fgets(buf, sizeof(buf), wtclst)) { buf[strcspn(buf, "\n")] = 0; if (*buf == '\0') continue; // morphgen demo char* s = strchr(buf, ' '); if (s) { *s = '\0'; std::vector result = pMS->generate(buf, s + 1); for (size_t i = 0; i < result.size(); ++i) { fprintf(stdout, "generate(%s, %s) = %s\n", buf, s + 1, result[i].c_str()); } if (result.empty()) fprintf(stdout, "generate(%s, %s) = NO DATA\n", buf, s + 1); } else { int dp = pMS->spell(std::string(buf)); fprintf(stdout, "> %s\n", buf); if (dp) { std::vector result = pMS->analyze(buf); for (size_t i = 0; i < result.size(); ++i) { fprintf(stdout, "analyze(%s) = %s\n", buf, result[i].c_str()); } result = pMS->stem(buf); for (size_t i = 0; i < result.size(); ++i) { fprintf(stdout, "stem(%s) = %s\n", buf, result[i].c_str()); } } else { fprintf(stdout, "Unknown word.\n"); } } } delete pMS; fclose(wtclst); return 0; } hunspell-1.7.0/src/tools/chmorph.cxx000066400000000000000000000076071337236234000175010ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/hunspell.hxx" #include "../parsers/textparser.hxx" #ifndef W32 using namespace std; #endif int main(int, char** argv) { FILE* f; /* first parse the command line options */ for (int i = 1; i < 6; i++) if (!argv[i]) { fprintf( stderr, "chmorph - change affixes by morphological analysis and generation\n" "correct syntax is:\nchmorph affix_file " "dictionary_file file_to_convert STRING1 STRING2\n" "STRINGS may be arbitrary parts of the morphological descriptions\n" "example: chmorph hu.aff hu.dic hu.txt SG_2 SG_3 " " (convert informal Hungarian second person texts to formal third " "person texts)\n"); exit(1); } /* open the words to check list */ f = fopen(argv[3], "r"); if (!f) { fprintf(stderr, "Error - could not open file to check\n"); exit(1); } Hunspell* pMS = new Hunspell(argv[1], argv[2]); TextParser* p = new TextParser( "qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM"); char buf[MAXLNLEN]; while (fgets(buf, MAXLNLEN, f)) { p->put_line(buf); std::string next; while (p->next_token(next)) { std::vector pl = pMS->analyze(next); if (!pl.empty()) { int gen = 0; for (size_t i = 0; i < pl.size(); ++i) { const char* pos = strstr(pl[i].c_str(), argv[4]); if (pos) { std::string r(pl[i], pos - pl[i].c_str()); r.append(argv[5]); r.append(pos + strlen(argv[4])); pl[i] = r; gen = 1; } } if (gen) { std::vector pl2 = pMS->generate(next, pl); if (!pl2.empty()) { p->change_token(pl2[0].c_str()); // jump over the (possibly un)modified word (void)p->next_token(next); } } } } fprintf(stdout, "%s\n", p->get_line().c_str()); } delete p; fclose(f); return 0; } hunspell-1.7.0/src/tools/example.cxx000066400000000000000000000064611337236234000174710ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/hunspell.hxx" using namespace std; int main(int argc, char** argv) { /* first parse the command line options */ if (argc < 4) { fprintf(stderr, "example (now it works with more dictionary files):\n"); fprintf(stderr, "example affix_file dictionary_file(s) file_of_words_to_check\n"); exit(1); } /* open the words to check list */ std::ifstream wtclst(argv[argc - 1], std::ios_base::in); if (!wtclst.is_open()) { fprintf(stderr, "Error - could not open file of words to check\n"); exit(1); } Hunspell* pMS = new Hunspell(argv[1], argv[2]); // load extra dictionaries if (argc > 4) for (int k = 3; k < argc - 1; ++k) pMS->add_dic(argv[k]); std::string buf; while (std::getline(wtclst, buf)) { int dp = pMS->spell(buf); if (dp) { fprintf(stdout, "\"%s\" is okay\n", buf.c_str()); fprintf(stdout, "\n"); } else { fprintf(stdout, "\"%s\" is incorrect!\n", buf.c_str()); fprintf(stdout, " suggestions:\n"); std::vector wlst = pMS->suggest(buf.c_str()); for (size_t i = 0; i < wlst.size(); ++i) { fprintf(stdout, " ...\"%s\"\n", wlst[i].c_str()); } fprintf(stdout, "\n"); } // for the same of testing this code path // do an analysis here and throw away the results pMS->analyze(buf); } delete pMS; return 0; } hunspell-1.7.0/src/tools/fuzzer.cxx000066400000000000000000000055111337236234000173560ustar00rootroot00000000000000/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** 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. * * 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 std::vector dictionaries; bool endswith(const std::string &str, const std::string &suffix) { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; } extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { char* exe_path = (*argv)[0]; // dirname() can modify its argument. char* exe_path_copy = strdup(exe_path); char* dir = dirname(exe_path_copy); DIR* d = opendir(dir); struct dirent *direntry; while ((direntry = readdir(d)) != NULL) { std::string entry(direntry->d_name); if (endswith(entry, ".aff")) { std::string dic = entry.substr(0, entry.size() - 4) + ".dic"; dictionaries.push_back(new Hunspell(entry.c_str(), dic.c_str())); } } closedir(d); free(exe_path_copy); return 0; } extern "C" int LLVMFuzzerTestOneInput(const char* data, size_t size) { std::string word(data, size); for (std::vector::const_iterator it = dictionaries.begin(); it != dictionaries.end(); ++it) { Hunspell *dict = *it; if (!dict->spell(word)) dict->suggest(word); } return 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ hunspell-1.7.0/src/tools/hunspell.cxx000066400000000000000000002072671337236234000176770ustar00rootroot00000000000000/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ // glibc < 3.0 (for mkstemp) #ifndef __USE_MISC #define __USE_MISC #endif #include #include #include #include #include #include #include "../hunspell/atypes.hxx" #include "../hunspell/hunspell.hxx" #include "../hunspell/csutil.hxx" #include "../hunspell/hunzip.hxx" #define HUNSPELL_VERSION VERSION #define INPUTLEN 50 #define HUNSPELL_PIPE_HEADING \ "@(#) International Ispell Version 3.2.06 (but really Hunspell " VERSION ")" \ "\n" #define HUNSPELL_HEADING "Hunspell " #define ODF_EXT "odt|ott|odp|otp|odg|otg|ods|ots" #define ENTITY_APOS "'" #define UTF8_APOS "\xe2\x80\x99" // for debugging only //#define LOG #define DEFAULTDICNAME "default" #ifdef WIN32 #define LIBDIR "C:\\Hunspell\\" #define USEROOODIR { "Application Data\\OpenOffice.org 2\\user\\wordbook" } #define OOODIR \ "C:\\Program files\\OpenOffice.org 2.4\\share\\dict\\ooo\\;" \ "C:\\Program files\\OpenOffice.org 2.3\\share\\dict\\ooo\\;" \ "C:\\Program files\\OpenOffice.org 2.2\\share\\dict\\ooo\\;" \ "C:\\Program files\\OpenOffice.org 2.1\\share\\dict\\ooo\\;" \ "C:\\Program files\\OpenOffice.org 2.0\\share\\dict\\ooo\\" #define HOME "%USERPROFILE%\\" #define DICBASENAME "hunspell_" #define LOGFILE "C:\\Hunspell\\log" #define DIRSEPCH '\\' #define DIRSEP "\\" #define PATHSEP ";" #ifdef __MINGW32__ #include #include #include #include #endif #include "../parsers/textparser.hxx" #include "../parsers/htmlparser.hxx" #include "../parsers/latexparser.hxx" #include "../parsers/manparser.hxx" #include "../parsers/firstparser.hxx" #include "../parsers/xmlparser.hxx" #include "../parsers/odfparser.hxx" #else // Not Windows #include #include #include #include #include "../parsers/textparser.hxx" #include "../parsers/htmlparser.hxx" #include "../parsers/latexparser.hxx" #include "../parsers/manparser.hxx" #include "../parsers/firstparser.hxx" #include "../parsers/xmlparser.hxx" #include "../parsers/odfparser.hxx" #define LIBDIR \ "/usr/share/hunspell:" \ "/usr/share/myspell:" \ "/usr/share/myspell/dicts:" \ "/Library/Spelling" #define USEROOODIR { \ ".openoffice.org/3/user/wordbook", \ ".openoffice.org2/user/wordbook", \ ".openoffice.org2.0/user/wordbook",\ "Library/Spelling" } #define OOODIR \ "/opt/openoffice.org/basis3.0/share/dict/ooo:" \ "/usr/lib/openoffice.org/basis3.0/share/dict/ooo:" \ "/opt/openoffice.org2.4/share/dict/ooo:" \ "/usr/lib/openoffice.org2.4/share/dict/ooo:" \ "/opt/openoffice.org2.3/share/dict/ooo:" \ "/usr/lib/openoffice.org2.3/share/dict/ooo:" \ "/opt/openoffice.org2.2/share/dict/ooo:" \ "/usr/lib/openoffice.org2.2/share/dict/ooo:" \ "/opt/openoffice.org2.1/share/dict/ooo:" \ "/usr/lib/openoffice.org2.1/share/dict/ooo:" \ "/opt/openoffice.org2.0/share/dict/ooo:" \ "/usr/lib/openoffice.org2.0/share/dict/ooo" #define HOME getenv("HOME") #define DICBASENAME ".hunspell_" #define LOGFILE "/tmp/hunspell.log" #define DIRSEPCH '/' #define DIRSEP "/" #define PATHSEP ":" #endif #ifdef HAVE_ICONV #include #include char text_conv[MAXLNLEN]; #endif #ifdef HAVE_LOCALE_H # include #endif #ifdef HAVE_LANGINFO_H # include #endif #ifdef ENABLE_NLS # include #else # undef gettext # define gettext(Msgid) ((const char *) (Msgid)) # undef textdomain # define textdomain(Domainname) ((const char *) (Domainname)) #endif #ifdef HAVE_CURSES_H #ifdef HAVE_NCURSESW_CURSES_H #include #else #include #endif #endif #ifdef HAVE_READLINE #include #else #define readline scanline #endif // file formats: enum { FMT_TEXT, FMT_LATEX, FMT_HTML, FMT_MAN, FMT_FIRST, FMT_XML, FMT_ODF }; // global variables std::string wordchars; char* dicpath = NULL; const w_char* wordchars_utf16 = NULL; std::vector new_wordchars_utf16; int wordchars_utf16_len; char* dicname = NULL; char* privdicname = NULL; const char* currentfilename = NULL; int modified; // modified file sign bool multiple_files; // for listing file names in pipe interface enum { NORMAL, BADWORD, // print only bad words WORDFILTER, // print only bad words from 1 word/line input BADLINE, // print only lines with bad words STEM, // stem input words ANALYZE, // analyze input words PIPE, // print only stars for LyX compatibility AUTO0, // search typical error (based on SuggestMgr::suggest()) AUTO, // automatic spelling to standard output AUTO2, // automatic spelling to standard output with sed log AUTO3, SUFFIX // print suffixes that can be attached to a given word }; // automatic spelling to standard output with gcc error format int filter_mode = NORMAL; int printgood = 0; // print only good words and lines int showpath = 0; // show detected path of the dictionary int checkurl = 0; // check URLs and mail addresses int checkapos = 0; // force typographic apostrophe int warn = 0; // warn potential mistakes (dictionary words with WARN flags) const char* ui_enc = NULL; // locale character encoding (default for I/O) const char* io_enc = NULL; // I/O character encoding #define DMAX 10 // maximal count of loaded dictionaries const char* dic_enc[DMAX]; // dictionary encoding char* path = NULL; int dmax = 0; // dictionary count // functions #ifdef HAVE_ICONV static const char* fix_encoding_name(const char* enc) { if (strcmp(enc, "TIS620-2533") == 0) enc = "TIS620"; return enc; } #endif /* change character encoding */ std::string chenc(const std::string& st, const char* enc1, const char* enc2) { #ifndef HAVE_ICONV (void)enc1; (void)enc2; return st; #else if (st.empty()) return st; if (!enc1 || !enc2 || strcmp(enc1, enc2) == 0) return st; std::string out(st.size() < 15 ? 15 : st.size(), '\0'); size_t c1(st.size()); size_t c2(out.size()); ICONV_CONST char* source = (ICONV_CONST char*) &st[0]; char* dest = &out[0]; iconv_t conv = iconv_open(fix_encoding_name(enc2), fix_encoding_name(enc1)); if (conv == (iconv_t)-1) { fprintf(stderr, gettext("error - iconv_open: %s -> %s\n"), enc2, enc1); } else { size_t res; while ((res = iconv(conv, &source, &c1, &dest, &c2)) == size_t(-1)) { if (errno == E2BIG) { //c2 is zero or close to zero size_t next_start = out.size() - c2; c2 += c1*2; out.resize(out.size() + c1*2); dest = &out[next_start]; } else break; } if (res == (size_t)-1) { fprintf(stderr, gettext("error - iconv: %s -> %s\n"), enc2, enc1); } iconv_close(conv); out.resize(dest - &out[0]); return out; } return st; #endif } TextParser* get_parser(int format, const char* extension, Hunspell* pMS) { TextParser* p = NULL; int io_utf8 = 0; const char* denc = pMS->get_dict_encoding().c_str(); #ifdef HAVE_ICONV initialize_utf_tbl(); // also need for 8-bit tokenization if (io_enc) { if ((strcmp(io_enc, "UTF-8") == 0) || (strcmp(io_enc, "utf-8") == 0) || (strcmp(io_enc, "UTF8") == 0) || (strcmp(io_enc, "utf8") == 0)) { io_utf8 = 1; io_enc = "UTF-8"; } } else if (ui_enc) { io_enc = ui_enc; if (strcmp(ui_enc, "UTF-8") == 0) io_utf8 = 1; } else { io_enc = denc; if (strcmp(denc, "UTF-8") == 0) io_utf8 = 1; } if (io_utf8) { const std::vector& vec_wordchars_utf16 = pMS->get_wordchars_utf16(); const std::string& vec_wordchars = pMS->get_wordchars_cpp(); wordchars_utf16_len = vec_wordchars_utf16.size(); wordchars_utf16 = wordchars_utf16_len ? &vec_wordchars_utf16[0] : NULL; if ((strcmp(denc, "UTF-8") != 0) && !vec_wordchars.empty()) { const char* wchars = vec_wordchars.c_str(); size_t c1 = vec_wordchars.size(); size_t c2 = MAXLNLEN; char* dest = text_conv; iconv_t conv = iconv_open("UTF-8", fix_encoding_name(denc)); if (conv == (iconv_t)-1) { fprintf(stderr, gettext("error - iconv_open: UTF-8 -> %s\n"), denc); wordchars_utf16 = NULL; wordchars_utf16_len = 0; } else { iconv(conv, (ICONV_CONST char**)&wchars, &c1, &dest, &c2); iconv_close(conv); u8_u16(new_wordchars_utf16, text_conv); std::sort(new_wordchars_utf16.begin(), new_wordchars_utf16.end()); wordchars_utf16 = &new_wordchars_utf16[0]; wordchars_utf16_len = new_wordchars_utf16.size(); } } } else { // 8-bit input encoding // detect letters by unicodeisalpha() for tokenization char letters[MAXLNLEN]; char* pletters = letters; char ch[2]; char u8[10]; *pletters = '\0'; iconv_t conv = iconv_open("UTF-8", fix_encoding_name(io_enc)); if (conv == (iconv_t)-1) { fprintf(stderr, gettext("error - iconv_open: UTF-8 -> %s\n"), io_enc); } else { for (int i = 32; i < 256; i++) { size_t c1 = 1; size_t c2 = 10; char* dest = u8; u8[0] = '\0'; char* ch8bit = ch; ch[0] = (char)i; ch[1] = '\0'; size_t res = iconv(conv, (ICONV_CONST char**)&ch8bit, &c1, &dest, &c2); if (res != (size_t)-1) { std::vector w; u8_u16(w, std::string(u8, dest)); unsigned short idx = w.empty() ? 0 : (w[0].h << 8) + w[0].l; if (unicodeisalpha(idx)) { *pletters = (char)i; pletters++; } } } iconv_close(conv); } *pletters = '\0'; // UTF-8 wordchars -> 8 bit wordchars const std::string& vec_wordchars = pMS->get_wordchars_cpp(); size_t len = vec_wordchars.size(); if (len) { if ((strcmp(denc, "UTF-8") == 0)) { len = pMS->get_wordchars_utf16().size(); } char* dest = letters + strlen(letters); // append wordchars size_t c1 = len + 1; size_t c2 = len + 1; conv = iconv_open(fix_encoding_name(io_enc), fix_encoding_name(denc)); if (conv == (iconv_t)-1) { fprintf(stderr, gettext("error - iconv_open: %s -> %s\n"), io_enc, denc); } else { const char* wchars = vec_wordchars.c_str(); iconv(conv, (ICONV_CONST char**)&wchars, &c1, &dest, &c2); iconv_close(conv); *dest = '\0'; } } if (*letters) wordchars.assign(letters); } #else if (strcmp(denc, "UTF-8") == 0) { const std::vector& vec_wordchars_utf16 = pMS->get_wordchars_utf16(); wordchars_utf16 = (vec_wordchars_utf16.size() == 0) ? NULL : &vec_wordchars_utf16[0]; wordchars_utf16_len = vec_wordchars_utf16.size(); io_utf8 = 1; } else { std::string casechars = get_casechars(denc); std::string wchars = pMS->get_wordchars_cpp(); wordchars = casechars + wchars; } io_enc = denc; #endif if (io_utf8) { switch (format) { case FMT_LATEX: p = new LaTeXParser(wordchars_utf16, wordchars_utf16_len); break; case FMT_HTML: p = new HTMLParser(wordchars_utf16, wordchars_utf16_len); break; case FMT_MAN: p = new ManParser(wordchars_utf16, wordchars_utf16_len); break; case FMT_XML: p = new XMLParser(wordchars_utf16, wordchars_utf16_len); break; case FMT_ODF: p = new ODFParser(wordchars_utf16, wordchars_utf16_len); break; case FMT_FIRST: p = new FirstParser(wordchars.c_str()); } } else { switch (format) { case FMT_LATEX: p = new LaTeXParser(wordchars.c_str()); break; case FMT_HTML: p = new HTMLParser(wordchars.c_str()); break; case FMT_MAN: p = new ManParser(wordchars.c_str()); break; case FMT_XML: p = new XMLParser(wordchars.c_str()); break; case FMT_ODF: p = new ODFParser(wordchars.c_str()); break; case FMT_FIRST: p = new FirstParser(wordchars.c_str()); } } if ((!p) && (extension)) { if ((strcmp(extension, "html") == 0) || (strcmp(extension, "htm") == 0) || (strcmp(extension, "xhtml") == 0)) { if (io_utf8) { p = new HTMLParser(wordchars_utf16, wordchars_utf16_len); } else { p = new HTMLParser(wordchars.c_str()); } } else if ((strcmp(extension, "xml") == 0)) { if (io_utf8) { p = new XMLParser(wordchars_utf16, wordchars_utf16_len); } else { p = new XMLParser(wordchars.c_str()); } } else if (((strlen(extension) == 3) && (strstr(ODF_EXT, extension) != NULL)) || ((strlen(extension) == 4) && (extension[0] == 'f') && (strstr(ODF_EXT, extension + 1) != NULL))) { if (io_utf8) { p = new ODFParser(wordchars_utf16, wordchars_utf16_len); } else { p = new ODFParser(wordchars.c_str()); } } else if (((extension[0] > '0') && (extension[0] <= '9'))) { if (io_utf8) { p = new ManParser(wordchars_utf16, wordchars_utf16_len); } else { p = new ManParser(wordchars.c_str()); } } else if ((strcmp(extension, "tex") == 0)) { if (io_utf8) { p = new LaTeXParser(wordchars_utf16, wordchars_utf16_len); } else { p = new LaTeXParser(wordchars.c_str()); } } } if (!p) { if (io_utf8) { p = new TextParser(wordchars_utf16, wordchars_utf16_len); } else { p = new TextParser(wordchars.c_str()); } } p->set_url_checking(checkurl); return p; } #ifdef LOG void log(char* message) { FILE* f = fopen(LOGFILE, "a"); if (f) { fprintf(f, "%s\n", message); fclose(f); } else { fprintf(stderr, "Logfile..."); } } #endif int putdic(const std::string& in_word, Hunspell* pMS) { std::string word = chenc(in_word, ui_enc, dic_enc[0]); std::string buf; pMS->input_conv(word.c_str(), buf); word = buf; if (word.empty()) return 0; int ret(0); size_t w = word.find('/', 1); if (w == std::string::npos) { if (word[0] == '*') ret = pMS->remove(word.substr(1)); else ret = pMS->add(word); } else { std::string affix = word.substr(w + 1); word.resize(w); if (!affix.empty() && affix[0] == '/') // word//pattern (back comp.) affix.erase(0, 1); ret = pMS->add_with_affix(word, affix); // word/pattern } return ret; } void load_privdic(const char* filename, Hunspell* pMS) { std::ifstream dic; dic.open(filename, std::ios_base::in); if (dic.is_open()) { std::string buf; while (std::getline(dic, buf)) { putdic(buf, pMS); } } } bool exist(const char* filename) { std::ifstream f; f.open(filename, std::ios_base::in); if (f.is_open()) { return true; } return false; } int save_privdic(const std::string& filename, const std::string& filename2, std::vector& w) { FILE* dic = fopen(filename.c_str(), "r"); if (dic) { fclose(dic); dic = fopen(filename.c_str(), "a"); } else { dic = fopen(filename2.c_str(), "a"); } if (!dic) return 0; for (size_t i = 0; i < w.size(); ++i) { w[i] = chenc(w[i], io_enc, ui_enc); fprintf(dic, "%s\n", w[i].c_str()); } fclose(dic); return 1; } const char* basename(const char* s, char c) { const char* p = s + strlen(s); while ((*p != c) && (p != s)) p--; if (*p == c) p++; return p; } #ifdef HAVE_CURSES_H char* scanline(char* message) { char input[INPUTLEN]; printw(message); echo(); getnstr(input, INPUTLEN); noecho(); return mystrdup(input); } #endif // check words in the dictionaries (and set first checked dictionary) bool check(Hunspell** pMS, int* d, const std::string& token, int* info, std::string* root) { for (int i = 0; i < dmax; ++i) { std::string buf = chenc(token, io_enc, dic_enc[*d]); mystrrep(buf, ENTITY_APOS, "'"); if (checkapos && buf.find('\'') != std::string::npos) return false; // 8-bit encoded dictionaries need ASCII apostrophes (eg. English // dictionaries) if (strcmp(dic_enc[*d], "UTF-8") != 0) mystrrep(buf, UTF8_APOS, "'"); if ((pMS[*d]->spell(buf, info, root) && !(warn && (*info & SPELL_WARN))) || // UTF-8 encoded dictionaries with ASCII apostrophes, but without ICONV // support, // need also ASCII apostrophes (eg. French dictionaries) ((strcmp(dic_enc[*d], "UTF-8") == 0) && buf.find(UTF8_APOS) != std::string::npos && pMS[*d]->spell(mystrrep(buf, UTF8_APOS, "'"), info, root) && !(warn && (*info & SPELL_WARN)))) { return true; } if (++(*d) == dmax) *d = 0; } return false; } static bool is_zipped_odf(TextParser* parser, const char* extension) { // ODFParser and not flat ODF return dynamic_cast(parser) && (extension && extension[0] != 'f'); } static bool secure_filename(const char* filename) { const char* hasapostrophe = strchr(filename, '\''); if (hasapostrophe) return false; return true; } char* mymkdtemp(char *templ) { #ifdef WIN32 (void)templ; char *odftmpdir = tmpnam(NULL); if (!odftmpdir) { return NULL; } if (system((std::string("mkdir ") + odftmpdir).c_str()) != 0) { return NULL; } return odftmpdir; #else return mkdtemp(templ); #endif } void pipe_interface(Hunspell** pMS, int format, FILE* fileid, char* filename) { char buf[MAXLNLEN]; std::vector dicwords; int pos; int bad; int lineno = 0; int terse_mode = 0; int verbose_mode = 0; int d = 0; char* odftmpdir = NULL; std::string filename_prefix = (multiple_files) ? filename + std::string(": ") : ""; const char* extension = (filename) ? basename(filename, '.') : NULL; TextParser* parser = get_parser(format, extension, pMS[0]); char tmpdirtemplate[] = "/tmp/hunspellXXXXXX"; bool bZippedOdf = is_zipped_odf(parser, extension); // access content.xml of ODF if (bZippedOdf) { odftmpdir = mymkdtemp(tmpdirtemplate); if (!odftmpdir) { perror(gettext("Can't create tmp dir")); exit(1); } // break 1-line XML of zipped ODT documents at and // to avoid tokenization problems (fgets could stop within an XML tag) std::ostringstream sbuf; sbuf << "unzip -p \"" << filename << "\" content.xml | sed " "\"s/\\(<\\/text:p>\\|<\\/style:style>\\)\\(.\\)/\\1\\n\\2/g;s/<\\/\\?text:span[^>]*>//g\" " ">" << odftmpdir << "/content.xml"; if (!secure_filename(filename) || system(sbuf.str().c_str()) != 0) { if (secure_filename(filename)) perror(gettext("Can't open inputfile")); else fprintf(stderr, gettext("Can't open %s.\n"), filename); if (system((std::string("rmdir ") + odftmpdir).c_str()) != 0) { perror("temp dir delete failed"); } exit(1); } std::string file(odftmpdir); file.append("/content.xml"); fileid = fopen(file.c_str(), "r"); if (fileid == NULL) { perror(gettext("Can't open inputfile")); if (system((std::string("rmdir ") + odftmpdir).c_str()) != 0) { perror("temp dir delete failed"); } exit(1); } } if (filter_mode == NORMAL) { fprintf(stdout, "%s", gettext(HUNSPELL_HEADING)); fprintf(stdout, HUNSPELL_VERSION); const std::string& version = pMS[0]->get_version_cpp(); if (!version.empty()) fprintf(stdout, " - %s", version.c_str()); fprintf(stdout, "\n"); fflush(stdout); } nextline: while (fgets(buf, MAXLNLEN, fileid)) { buf[strcspn(buf, "\n")] = 0; lineno++; #ifdef LOG log(buf); #endif bad = 0; pos = 0; // execute commands if (filter_mode == PIPE) { pos = -1; switch (buf[0]) { case '%': { verbose_mode = terse_mode = 0; break; } case '!': { terse_mode = 1; break; } case '`': { verbose_mode = 1; break; } case '+': { delete parser; parser = get_parser(FMT_LATEX, NULL, pMS[0]); parser->set_url_checking(checkurl); break; } case '-': { delete parser; parser = get_parser(format, NULL, pMS[0]); break; } case '@': { putdic(buf + 1, pMS[d]); break; } case '*': { std::string word(buf + 1); dicwords.push_back(word); putdic(word, pMS[d]); break; } case '#': { std::string sbuf; if (HOME) { sbuf.append(HOME); } else { fprintf(stderr, "%s", gettext("error - missing HOME variable\n")); continue; } #ifndef WIN32 sbuf.append("/"); #endif size_t offset = sbuf.size(); if (!privdicname) { sbuf.append(DICBASENAME); sbuf.append(basename(dicname, DIRSEPCH)); } else { sbuf.append(privdicname); } if (save_privdic(sbuf.substr(offset), sbuf, dicwords)) { dicwords.clear(); } break; } case '^': { pos = 1; break; } default: { pos = 0; break; } } // end switch } // end filter_mode == PIPE if (pos >= 0) { parser->put_line(buf + pos); std::string token; while (parser->next_token(token)) { token = parser->get_word(token); mystrrep(token, ENTITY_APOS, "'"); switch (filter_mode) { case BADWORD: { if (!check(pMS, &d, token, NULL, NULL)) { bad = 1; if (!printgood) fprintf(stdout, "%s%s\n", filename_prefix.c_str(), token.c_str()); } else { if (printgood) fprintf(stdout, "%s%s\n", filename_prefix.c_str(), token.c_str()); } continue; } case WORDFILTER: { if (!check(pMS, &d, parser->get_word(token), NULL, NULL)) { if (!printgood) fprintf(stdout, "%s\n", buf); } else { if (printgood) fprintf(stdout, "%s\n", buf); } goto nextline; } case BADLINE: { if (!check(pMS, &d, parser->get_word(token), NULL, NULL)) { bad = 1; } continue; } case AUTO0: case AUTO: case AUTO2: case AUTO3: { FILE* f = (filter_mode == AUTO) ? stderr : stdout; if (!check(pMS, &d, parser->get_word(token), NULL, NULL)) { bad = 1; std::vector wlst = pMS[d]->suggest(chenc(parser->get_word(token), io_enc, dic_enc[d])); if (!wlst.empty()) { parser->change_token(chenc(wlst[0], dic_enc[d], io_enc).c_str()); if (filter_mode == AUTO3) { fprintf(f, "%s:%d: Locate: %s | Try: %s\n", currentfilename, lineno, token.c_str(), chenc(wlst[0], dic_enc[d], io_enc).c_str()); } else if (filter_mode == AUTO2) { fprintf(f, "%ds/%s/%s/g; # %s\n", lineno, token.c_str(), chenc(wlst[0], dic_enc[d], io_enc).c_str(), buf); } else { fprintf(f, gettext("Line %d: %s -> "), lineno, chenc(token, io_enc, ui_enc).c_str()); fprintf(f, "%s\n", chenc(wlst[0], dic_enc[d], ui_enc).c_str()); } } } continue; } case STEM: { std::vector result = pMS[d]->stem(chenc(token, io_enc, dic_enc[d])); for (size_t i = 0; i < result.size(); ++i) { fprintf(stdout, "%s %s\n", token.c_str(), chenc(result[i], dic_enc[d], ui_enc).c_str()); } if (result.empty() && !token.empty() && token[token.size() - 1] == '.') { token.resize(token.size() - 1); result = pMS[d]->stem(token); for (size_t i = 0; i < result.size(); ++i) { fprintf(stdout, "%s %s\n", token.c_str(), chenc(result[i], dic_enc[d], ui_enc).c_str()); } } if (result.empty()) fprintf(stdout, "%s\n", chenc(token, dic_enc[d], ui_enc).c_str()); fprintf(stdout, "\n"); continue; } case SUFFIX: { std::vector wlst = pMS[d]->suffix_suggest(token); for (size_t j = 0; j < wlst.size(); ++j) { fprintf(stdout, "Suffix Suggestions are %s \n", chenc(wlst[j], dic_enc[d], io_enc).c_str()); } fflush(stdout); continue; } case ANALYZE: { std::vector result = pMS[d]->analyze(chenc(token, io_enc, dic_enc[d])); for (size_t i = 0; i < result.size(); ++i) { fprintf(stdout, "%s %s\n", token.c_str(), chenc(result[i], dic_enc[d], ui_enc).c_str()); } if (result.empty() && !token.empty() && token[token.size() - 1] == '.') { token.resize(token.size() - 1); result = pMS[d]->analyze(token); for (size_t i = 0; i < result.size(); ++i) { fprintf(stdout, "%s %s\n", token.c_str(), chenc(result[i], dic_enc[d], ui_enc).c_str()); } } if (result.empty()) fprintf(stdout, "%s\n", chenc(token, dic_enc[d], ui_enc).c_str()); fprintf(stdout, "\n"); continue; } case PIPE: { int info; std::string root; if (check(pMS, &d, parser->get_word(token), &info, &root)) { if (!terse_mode) { if (verbose_mode) fprintf(stdout, "* %s\n", token.c_str()); else fprintf(stdout, "*\n"); } fflush(stdout); } else { int byte_offset = parser->get_tokenpos() + pos; int char_offset = 0; if (strcmp(io_enc, "UTF-8") == 0) { for (int i = 0; i < byte_offset; i++) { if ((buf[i] & 0xc0) != 0x80) char_offset++; } } else { char_offset = byte_offset; } std::vector wlst = pMS[d]->suggest(chenc(token, io_enc, dic_enc[d])); if (wlst.empty()) { fprintf(stdout, "# %s %d", token.c_str(), char_offset); } else { fprintf(stdout, "& %s %u %d: ", token.c_str(), static_cast(wlst.size()), char_offset); fprintf(stdout, "%s", chenc(wlst[0], dic_enc[d], io_enc).c_str()); } for (size_t j = 1; j < wlst.size(); ++j) { fprintf(stdout, ", %s", chenc(wlst[j], dic_enc[d], io_enc).c_str()); } fprintf(stdout, "\n"); fflush(stdout); } continue; } case NORMAL: { int info; std::string root; if (check(pMS, &d, token, &info, &root)) { if (info & SPELL_COMPOUND) { fprintf(stdout, "-\n"); } else if (!root.empty()) { fprintf(stdout, "+ %s\n", chenc(root, dic_enc[d], ui_enc).c_str()); } else { fprintf(stdout, "*\n"); } fflush(stdout); } else { int byte_offset = parser->get_tokenpos() + pos; int char_offset = 0; if (strcmp(io_enc, "UTF-8") == 0) { for (int i = 0; i < byte_offset; i++) { if ((buf[i] & 0xc0) != 0x80) char_offset++; } } else { char_offset = byte_offset; } std::vector wlst = pMS[d]->suggest(chenc(token, io_enc, dic_enc[d])); if (wlst.empty()) { fprintf(stdout, "# %s %d", chenc(token, io_enc, ui_enc).c_str(), char_offset); } else { fprintf(stdout, "& %s %u %d: ", chenc(token, io_enc, ui_enc).c_str(), static_cast(wlst.size()), char_offset); fprintf(stdout, "%s", chenc(wlst[0], dic_enc[d], ui_enc).c_str()); } for (size_t j = 1; j < wlst.size(); ++j) { fprintf(stdout, ", %s", chenc(wlst[j], dic_enc[d], ui_enc).c_str()); } fprintf(stdout, "\n"); fflush(stdout); } } } } switch (filter_mode) { case AUTO: { std::string pLine = parser->get_line(); fprintf(stdout, "%s\n", pLine.c_str()); break; } case BADLINE: { if (((printgood) && (!bad)) || (!printgood && (bad))) fprintf(stdout, "%s\n", buf); break; } case PIPE: case NORMAL: { fprintf(stdout, "\n"); fflush(stdout); break; } } } // if } // while if (bZippedOdf) { fclose(fileid); std::ostringstream sbuf; sbuf << odftmpdir << "/content.xml"; if (remove(sbuf.str().c_str()) != 0) { perror("temp file delete failed"); } sbuf.str(""); sbuf << "rmdir " << odftmpdir; if (system(sbuf.str().c_str()) != 0) { perror("temp dir delete failed"); } } delete parser; } // pipe_interface #ifdef HAVE_READLINE #ifdef HAVE_CURSES_H static const char* rltext; // set base text of input line static int set_rltext() { if (rltext) { rl_insert_text(rltext); rltext = NULL; rl_startup_hook = (rl_hook_func_t*)NULL; } return 0; } #endif // Readline escape static int rl_escape(int count, int key) { rl_delete_text(0, rl_end); rl_done = 1; return 0; } #endif #ifdef HAVE_CURSES_H int expand_tab(std::string& dest, const std::string& in_src) { dest.clear(); const char *src = in_src.c_str(); int u8 = ((ui_enc != NULL) && (strcmp(ui_enc, "UTF-8") == 0)) ? 1 : 0; int chpos = 0; for (int j = 0; (src[j] != '\0') && (src[j] != '\r'); j++) { if (src[j] == '\t') { int end = 8 - (chpos % 8); for (int k = 0; k < end; k++) { dest.push_back(' '); chpos++; } } else { dest.push_back(src[j]); if (!u8 || (src[j] & 0xc0) != 0x80) chpos++; } } return chpos; } // UTF-8-aware version of strncpy (but output is always null terminated) // What we should deal in is cursor position cells in a terminal emulator, // i.e. the number of visual columns occupied like wcwidth/wcswidth does // What we're really current doing is to deal in the number of characters, // like mbstowcs which isn't quite correct, but close enough for western // text in UTF-8 void strncpyu8(std::string& dest, const std::string& in_src, int begin, int n) { dest.clear(); const char *src = in_src.c_str(); if (n) { int u8 = ((ui_enc != NULL) && (strcmp(ui_enc, "UTF-8") == 0)) ? 1 : 0; for (int i = 0; i < begin + n;) { if (!*src) break; // source is at it's end if (!u8 || (*src & 0xc0) != 0x80) i++; // new character if (i > begin) { // copy char (w/ utf-8 bytes) dest.push_back(*src++); while (u8 && (*src & 0xc0) == 0x80) dest.push_back(*src++); } else { // skip char (w/ utf-8 bytes) ++src; while (u8 && (*src & 0xc0) == 0x80) ++src; } } } } // See strncpyu8 for gotchas int strlenu8(const std::string& in_src) { const char *src = in_src.c_str(); int u8 = ((ui_enc != NULL) && (strcmp(ui_enc, "UTF-8") == 0)) ? 1 : 0; int i = 0; while (*src) { if (!u8 || (*src & 0xc0) != 0x80) i++; ++src; } return i; } void dialogscreen(TextParser* parser, std::string& token, char* filename, int forbidden, std::vector& wlst) { int x, y; getmaxyx(stdscr, y, x); clear(); if (forbidden & SPELL_FORBIDDEN) printw(gettext("FORBIDDEN!")); else if (forbidden & SPELL_WARN) printw(gettext("Spelling mistake?")); printw(gettext("\t%s\t\tFile: %s\n\n"), chenc(token, io_enc, ui_enc).c_str(), filename); // handle long lines and tabulators std::string lines[MAXPREVLINE]; std::string prevLine; for (int i = 0; i < MAXPREVLINE; i++) { prevLine = parser->get_prevline(i); expand_tab(lines[i], chenc(prevLine, io_enc, ui_enc)); } prevLine = parser->get_prevline(0); std::string line = prevLine.substr(0, parser->get_tokenpos()); std::string line2; int tokenbeg = expand_tab(line2, chenc(line, io_enc, ui_enc)); prevLine = parser->get_prevline(0); line = prevLine.substr(0, parser->get_tokenpos() + token.size()); int tokenend = expand_tab(line2, chenc(line, io_enc, ui_enc)); int rowindex = (tokenend - 1) / x; int beginrow = rowindex - tokenbeg / x; if (beginrow >= MAXPREVLINE) beginrow = MAXPREVLINE - 1; int ri = rowindex; int prevline = 0; for (int i = 0; i < MAXPREVLINE; i++) { strncpyu8(line, lines[prevline], x * rowindex, x); mvprintw(MAXPREVLINE + 1 - i, 0, "%s", line.c_str()); const bool finished = i == MAXPREVLINE - 1; if (!finished) { rowindex--; if (rowindex == -1) { prevline++; rowindex = strlenu8(lines[prevline]) / x; } } } strncpyu8(line, lines[0], x * (ri - beginrow), tokenbeg % x); mvprintw(MAXPREVLINE + 1 - beginrow, 0, "%s", line.c_str()); attron(A_REVERSE); printw("%s", chenc(token, io_enc, ui_enc).c_str()); attroff(A_REVERSE); mvprintw(MAXPREVLINE + 2, 0, "\n"); for (size_t i = 0; i < wlst.size(); ++i) { if ((wlst.size() > 10) && (i < 10)) { printw(" 0%d: %s\n", i, chenc(wlst[i], io_enc, ui_enc).c_str()); } else { printw(" %d: %s\n", i, chenc(wlst[i], io_enc, ui_enc).c_str()); } } /* TRANSLATORS: the capital letters are shortcuts, mark one letter similarly in your translation and translate the standalone letter accordingly later */ mvprintw(y - 3, 0, "%s\n", gettext("\n[SPACE] R)epl A)ccept I)nsert U)ncap " "S)tem Q)uit e(X)it or ? for help\n")); } std::string lower_first_char(const std::string& token, const char* ioenc, int langnum) { std::string utf8str = chenc(token, ioenc, "UTF-8"); std::vector u; u8_u16(u, utf8str); if (!u.empty()) { unsigned short idx = (u[0].h << 8) + u[0].l; idx = unicodetolower(idx, langnum); u[0].h = (unsigned char)(idx >> 8); u[0].l = (unsigned char)(idx & 0x00FF); } std::string scratch; u16_u8(scratch, u); return chenc(scratch, "UTF-8", ioenc); } // for terminal interface int dialog(TextParser* parser, Hunspell* pMS, std::string& token, char* filename, std::vector& wlst, int forbidden) { std::vector dicwords; int c; dialogscreen(parser, token, filename, forbidden, wlst); char firstletter = '\0'; while ((c = getch())) { switch (c) { case '0': case '1': if ((firstletter == '\0') && (wlst.size() > 10)) { firstletter = c; break; } case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': modified = 1; if (firstletter == '1') { c += 10; } c -= '0'; if (c >= static_cast(wlst.size())) break; if (checkapos) { std::string sbuf(wlst[c]); mystrrep(sbuf, "'", UTF8_APOS); parser->change_token(sbuf.c_str()); } else { parser->change_token(wlst[c].c_str()); } return 0; case ' ': return 0; case '?': clear(); printw(gettext( "Whenever a word is found that is not in the dictionary\n" "it is printed on the first line of the screen. If the " "dictionary\n" "contains any similar words, they are listed with a number\n" "next to each one. You have the option of replacing the word\n" "completely, or choosing one of the suggested words.\n")); printw(gettext("\nCommands are:\n\n")); printw(gettext("R Replace the misspelled word completely.\n")); printw(gettext("Space Accept the word this time only.\n")); printw( gettext("A Accept the word for the rest of this session.\n")); printw(gettext( "I Accept the word, and put it in your private dictionary.\n")); printw(gettext( "U Accept and add lowercase version to private dictionary.\n")); printw( gettext("S\tAsk a stem and a model word and store them in the " "private dictionary.\n" "\tThe stem will be accepted also with the affixes of the " "model word.\n")); printw(gettext("0-n Replace with one of the suggested words.\n")); printw(gettext( "X Write the rest of this file, ignoring misspellings, and start " "next file.\n")); printw( gettext("Q Quit immediately. Asks for confirmation. Leaves file " "unchanged.\n")); printw(gettext("^Z Suspend program. Restart with fg command.\n")); printw(gettext("? Show this help screen.\n")); printw(gettext("\n-- Type space to continue -- \n")); while (getch() != ' ') ; // fall-through case 12: { dialogscreen(parser, token, filename, forbidden, wlst); break; } default: { /* TRANSLATORS: translate this letter according to the shortcut letter used previously in the translation of "R)epl" before */ if (c == (gettext("r"))[0]) { modified = 1; #ifdef HAVE_READLINE endwin(); rltext = ""; if (rltext && *rltext) rl_startup_hook = set_rltext; #endif char* temp = readline(gettext("Replace with: ")); #ifdef HAVE_READLINE initscr(); cbreak(); #endif if ((!temp) || (temp[0] == '\0')) { free(temp); dialogscreen(parser, token, filename, forbidden, wlst); break; } std::string i(temp); free(temp); if (checkapos) { mystrrep(i, "'", UTF8_APOS); } parser->change_token(i.c_str()); return 2; // replace } /* TRANSLATORS: translate these letters according to the shortcut letter used previously in the translation of "U)ncap" and I)nsert before */ int u_key = gettext("u")[0]; int i_key = gettext("i")[0]; if (c == u_key || c == i_key) { std::string word = (c == i_key) ? token : lower_first_char(token, io_enc, pMS->get_langnum()); dicwords.push_back(word); std::string sbuf; // save if (HOME) { sbuf.append(HOME); } else { fprintf(stderr, gettext("error - missing HOME variable\n")); break; } #ifndef WIN32 sbuf.append("/"); #endif size_t offset = sbuf.size(); if (!privdicname) { sbuf.append(DICBASENAME); sbuf.append(basename(dicname, DIRSEPCH)); } else { sbuf.append(privdicname); } if (save_privdic(sbuf.substr(offset), sbuf, dicwords)) { dicwords.clear(); } else { fprintf(stderr, gettext("Cannot update personal dictionary.")); break; } } // no break /* TRANSLATORS: translate this letter according to the shortcut letter used previously in the translation of "U)ncap" and I)nsert before */ if ((c == (gettext("u"))[0]) || (c == (gettext("i"))[0]) || (c == (gettext("a"))[0])) { modified = 1; putdic(token, pMS); return 0; } /* TRANSLATORS: translate this letter according to the shortcut letter used previously in the translation of "S)tem" before */ if (c == (gettext("s"))[0]) { modified = 1; std::string w(token); size_t n_last_of = w.find_last_of('-'); if (n_last_of != std::string::npos) { w.resize(n_last_of); } #ifdef HAVE_READLINE endwin(); rltext = w.c_str(); if (rltext && *rltext) rl_startup_hook = set_rltext; #endif char* temp = readline(gettext("New word (stem): ")); if ((!temp) || (temp[0] == '\0')) { free(temp); #ifdef HAVE_READLINE initscr(); cbreak(); #endif dialogscreen(parser, token, filename, forbidden, wlst); break; } w.assign(temp); free(temp); #ifdef HAVE_READLINE initscr(); cbreak(); #endif dialogscreen(parser, token, filename, forbidden, wlst); refresh(); #ifdef HAVE_READLINE endwin(); rltext = ""; if (rltext && *rltext) rl_startup_hook = set_rltext; #endif temp = readline(gettext("Model word (a similar dictionary word): ")); #ifdef HAVE_READLINE initscr(); cbreak(); #endif if ((!temp) || (temp[0] == '\0')) { free(temp); dialogscreen(parser, token, filename, forbidden, wlst); break; } std::string w2(temp); free(temp); std::string w3; w3.append(w); w3.append("/"); w3.append(w2); if (!putdic(w3, pMS)) { dicwords.push_back(w3); w3.clear(); w3.append(w); w3.append("-/"); w3.append(w2); w3.append("-"); if (putdic(w3, pMS)) { dicwords.push_back(w3); } // save std::string sbuf; if (HOME) { sbuf.append(HOME); } else { fprintf(stderr, gettext("error - missing HOME variable\n")); continue; } #ifndef WIN32 sbuf.append("/"); #endif size_t offset = sbuf.size(); if (!privdicname) { sbuf.append(DICBASENAME); sbuf.append(basename(dicname, DIRSEPCH)); } else { sbuf.append(privdicname); } if (save_privdic(sbuf.substr(offset), sbuf, dicwords)) { dicwords.clear(); } else { fprintf(stderr, gettext("Cannot update personal dictionary.")); break; } } else { dialogscreen(parser, token, filename, forbidden, wlst); printw(gettext( "Model word must be in the dictionary. Press any key!")); getch(); dialogscreen(parser, token, filename, forbidden, wlst); break; } return 0; } /* TRANSLATORS: translate this letter according to the shortcut letter used previously in the translation of "e(X)it" before */ if (c == (gettext("x"))[0]) { return 1; } /* TRANSLATORS: translate this letter according to the shortcut letter used previously in the translation of "Q)uit" before */ if (c == (gettext("q"))[0]) { if (modified) { printw( gettext("Are you sure you want to throw away your changes? ")); /* TRANSLATORS: translate this letter according to the shortcut * letter y)es */ if (getch() == (gettext("y"))[0]) { return -1; } dialogscreen(parser, token, filename, forbidden, wlst); break; } else { return -1; } } } } } return 0; } int interactive_line(TextParser* parser, Hunspell** pMS, char* filename, FILE* tempfile) { int dialogexit = 0; int info = 0; int d = 0; std::string token; while (parser->next_token(token)) { if (!check(pMS, &d, parser->get_word(token), &info, NULL)) { std::vector wlst; dialogscreen(parser, token, filename, info, wlst); // preview refresh(); std::string dicbuf = chenc(parser->get_word(token), io_enc, dic_enc[d]); wlst = pMS[d]->suggest(mystrrep(dicbuf, ENTITY_APOS, "'").c_str()); if (wlst.empty()) { dialogexit = dialog(parser, pMS[d], token, filename, wlst, info); } else { for (size_t j = 0; j < wlst.size(); ++j) { wlst[j] = chenc(wlst[j], dic_enc[d], io_enc); } dialogexit = dialog(parser, pMS[d], token, filename, wlst, info); } } if ((dialogexit == -1) || (dialogexit == 1)) goto ki2; } ki2: fprintf(tempfile, "%s", parser->get_line().c_str()); return dialogexit; } void interactive_interface(Hunspell** pMS, char* filename, int format) { char buf[MAXLNLEN]; char* odffilename = NULL; char* odftmpdir = NULL; // external zip works only with temporary directories // (option -j) FILE* text = fopen(filename, "r"); if (!text) { perror(gettext("Can't open inputfile")); endwin(); exit(1); } int dialogexit; int check = 1; const char* extension = basename(filename, '.'); TextParser* parser = get_parser(format, extension, pMS[0]); char tmpdirtemplate[] = "/tmp/hunspellXXXXXX"; bool bZippedOdf = is_zipped_odf(parser, extension); // access content.xml of ODF if (bZippedOdf) { odftmpdir = mymkdtemp(tmpdirtemplate); if (!odftmpdir) { perror(gettext("Can't create tmp dir")); endwin(); exit(1); } fclose(text); // break 1-line XML of zipped ODT documents at and // to avoid tokenization problems (fgets could stop within an XML tag) std::ostringstream sbuf; sbuf << "unzip -p \"" << filename << "\" content.xml | sed " "\"s/\\(<\\/text:p>\\|<\\/style:style>\\)\\(.\\)/\\1\\n\\2/g\" " ">" << odftmpdir << "/content.xml"; if (!secure_filename(filename) || system(sbuf.str().c_str()) != 0) { if (secure_filename(filename)) perror(gettext("Can't open inputfile")); else fprintf(stderr, gettext("Can't open %s.\n"), filename); endwin(); (void)system((std::string("rmdir ") + odftmpdir).c_str()); exit(1); } odffilename = filename; std::string file(odftmpdir); file.append("/content.xml"); filename = mystrdup(file.c_str()); text = fopen(filename, "r"); if (!text) { perror(gettext("Can't open inputfile")); endwin(); (void)system((std::string("rmdir ") + odftmpdir).c_str()); exit(1); } } FILE* tempfile = tmpfile(); if (!tempfile) { perror(gettext("Can't create tempfile")); delete parser; fclose(text); endwin(); exit(1); } while (fgets(buf, MAXLNLEN, text)) { if (check) { parser->put_line(buf); dialogexit = interactive_line( parser, pMS, odffilename ? odffilename : filename, tempfile); switch (dialogexit) { case -1: { clear(); refresh(); fclose(tempfile); // automatically deleted when closed if (bZippedOdf) { if (remove(filename) != 0) { perror("temp file delete failed"); } std::ostringstream sbuf; sbuf << "rmdir " << odftmpdir; if (system(sbuf.str().c_str()) != 0) { perror("temp dir delete failed"); } free(filename); } endwin(); exit(0); } case 1: { check = 0; } } } else { fprintf(tempfile, "%s", buf); } } fclose(text); if (modified) { rewind(tempfile); text = fopen(filename, "wb"); if (text == NULL) perror(gettext("Can't open outputfile")); else { size_t n; while ((n = fread(buf, 1, MAXLNLEN, tempfile)) > 0) { if (fwrite(buf, 1, n, text) != n) perror("write failed"); } fclose(text); if (bZippedOdf && odffilename) { std::ostringstream sbuf; sbuf << "zip -j '" << odffilename << "' " << filename; if (system(sbuf.str().c_str()) != 0) perror("write failed"); } } } if (bZippedOdf) { if (remove(filename) != 0) { perror("temp file delete failed"); } std::ostringstream sbuf; sbuf << "rmdir " << odftmpdir; if (system(sbuf.str().c_str()) != 0) { perror("temp dir delete failed"); } free(filename); } delete parser; fclose(tempfile); // automatically deleted when closed } #endif char* exist2(char* dir, int len, const char* name, const char* ext) { std::string buf; const char* sep = (len == 0) ? "" : DIRSEP; buf.assign(dir, len); buf.append(sep); buf.append(name); buf.append(ext); if (exist(buf.c_str())) return mystrdup(buf.c_str()); buf.append(HZIP_EXTENSION); if (exist(buf.c_str())) { buf.erase(buf.size() - strlen(HZIP_EXTENSION)); return mystrdup(buf.c_str()); } return NULL; } #if !defined(WIN32) || defined(__MINGW32__) int listdicpath(char* dir, int len) { std::string buf; const char* sep = (len == 0) ? "" : DIRSEP; buf.assign(dir, len); buf.append(sep); DIR* d = opendir(buf.c_str()); if (!d) return 0; struct dirent* de; while ((de = readdir(d))) { len = strlen(de->d_name); if ((len > 4 && strcmp(de->d_name + len - 4, ".dic") == 0) || (len > 7 && strcmp(de->d_name + len - 7, ".dic.hz") == 0)) { char* s = mystrdup(de->d_name); s[len - ((s[len - 1] == 'z') ? 7 : 4)] = '\0'; fprintf(stderr, "%s%s\n", buf.c_str(), s); free(s); } } closedir(d); return 1; } #endif // search existing path for file "name + ext" char* search(char* begin, char* name, const char* ext) { char* end = begin; while (1) { while (!((*end == *PATHSEP) || (*end == '\0'))) end++; char* res = NULL; if (name) { res = exist2(begin, int(end - begin), name, ext); } else { #if !defined(WIN32) || defined(__MINGW32__) listdicpath(begin, end - begin); #endif } if ((*end == '\0') || res) return res; end++; begin = end; } } int main(int argc, char** argv) { std::string buf; Hunspell* pMS[DMAX]; char* key = NULL; int arg_files = -1; // first filename argumentum position in argv int format = FMT_TEXT; int argstate = 0; #ifdef HAVE_LOCALE_H setlocale(LC_ALL, ""); #endif #ifdef HAVE_LANGINFO_H ui_enc = nl_langinfo(CODESET); #endif textdomain("hunspell"); //for gettext #ifdef HAVE_READLINE rl_set_key("\x1b\x1b", rl_escape, rl_get_keymap()); rl_bind_key('\t', rl_insert); #endif #ifdef LOG log("START"); #endif for (int i = 1; i < argc; i++) { #ifdef LOG log(argv[i]); #endif if (argstate == 1) { if (dicname) free(dicname); dicname = mystrdup(argv[i]); argstate = 0; } else if (argstate == 2) { if (privdicname) free(privdicname); privdicname = mystrdup(argv[i]); argstate = 0; } else if (argstate == 3) { io_enc = argv[i]; argstate = 0; } else if (argstate == 4) { key = argv[i]; argstate = 0; } else if (strcmp(argv[i], "-d") == 0) argstate = 1; else if (strcmp(argv[i], "-p") == 0) argstate = 2; else if (strcmp(argv[i], "-i") == 0) argstate = 3; else if (strcmp(argv[i], "-P") == 0) argstate = 4; else if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) { fprintf(stderr, "%s", gettext("Usage: hunspell [OPTION]... [FILE]...\n")); fprintf(stderr, "%s", gettext("Check spelling of each FILE. Without FILE, " "check standard input.\n\n")); fprintf(stderr, "%s", gettext(" -1\t\tcheck only first field in lines " "(delimiter = tabulator)\n")); fprintf(stderr, "%s", gettext(" -a\t\tIspell's pipe interface\n")); fprintf(stderr, "%s", gettext(" --check-url\tcheck URLs, e-mail addresses and " "directory paths\n")); fprintf( stderr, "%s", gettext( " --check-apostrophe\tcheck Unicode typographic apostrophe\n")); fprintf(stderr, "%s", gettext(" -d d[,d2,...]\tuse d (d2 etc.) dictionaries\n")); fprintf(stderr, "%s", gettext(" -D\t\tshow available dictionaries\n")); fprintf(stderr, "%s", gettext(" -G\t\tprint only correct words or lines\n")); fprintf(stderr, "%s", gettext(" -h, --help\tdisplay this help and exit\n")); fprintf(stderr, "%s", gettext(" -H\t\tHTML input file format\n")); fprintf(stderr, "%s", gettext(" -i enc\tinput encoding\n")); fprintf(stderr, "%s", gettext(" -l\t\tprint misspelled words\n")); fprintf(stderr, "%s", gettext(" -L\t\tprint lines with misspelled words\n")); fprintf(stderr, "%s", gettext(" -m \t\tanalyze the words of the input text\n")); fprintf(stderr, "%s", gettext(" -n\t\tnroff/troff input file format\n")); fprintf( stderr, "%s", gettext( " -O\t\tOpenDocument (ODF or Flat ODF) input file format\n")); fprintf(stderr, "%s", gettext(" -p dict\tset dict custom dictionary\n")); fprintf(stderr, "%s", gettext(" -r\t\twarn of the potential mistakes (rare words)\n")); fprintf( stderr, "%s", gettext(" -P password\tset password for encrypted dictionaries\n")); fprintf(stderr, "%s", gettext(" -s \t\tstem the words of the input text\n")); fprintf(stderr, "%s", gettext(" -S \t\tsuffix words of the input text\n")); fprintf(stderr, "%s", gettext(" -t\t\tTeX/LaTeX input file format\n")); fprintf(stderr, "%s", gettext(" -v, --version\tprint version number\n")); fprintf(stderr, "%s", gettext(" -vv\t\tprint Ispell compatible version number\n")); fprintf(stderr, "%s", gettext(" -w\t\tprint misspelled words (= lines) from " "one word/line input.\n")); fprintf(stderr, "%s", gettext(" -X\t\tXML input file format\n\n")); fprintf( stderr, "%s", gettext( "Example: hunspell -d en_US file.txt # interactive spelling\n" " hunspell -i utf-8 file.txt # check UTF-8 encoded " "file\n" " hunspell -l *.odt # print misspelled words " "of ODF files\n\n" " # Quick fix of ODF documents by personal dictionary " "creation\n\n" " # 1 Make a reduced list from misspelled and unknown " "words:\n\n" " hunspell -l *.odt | sort | uniq >words\n\n" " # 2 Delete misspelled words of the file by a text " "editor.\n" " # 3 Use this personal dictionary to fix the deleted " "words:\n\n" " hunspell -p words *.odt\n\n")); fprintf(stderr, "%s", gettext("Bug reports: http://hunspell.github.io/\n")); exit(0); } else if ((strcmp(argv[i], "-vv") == 0) || (strcmp(argv[i], "-v") == 0) || (strcmp(argv[i], "--version") == 0)) { fprintf(stdout, "%s", gettext(HUNSPELL_PIPE_HEADING)); fprintf(stdout, "\n"); if (strcmp(argv[i], "-vv") != 0) { fprintf(stdout, "%s", gettext("\nCopyright (C) 2002-2014 L\303\241szl\303\263 " "N\303\251meth. License: MPL/GPL/LGPL.\n\n" "Based on OpenOffice.org's Myspell library.\n" "Myspell's copyright (C) Kevin Hendricks, 2001-2002, " "License: BSD.\n\n")); fprintf(stdout, "%s", gettext("This is free software; see the source for " "copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or " "FITNESS FOR A PARTICULAR PURPOSE,\n" "to the extent permitted by law.\n")); } exit(0); } else if ((strcmp(argv[i], "-a") == 0)) { filter_mode = PIPE; } else if ((strcmp(argv[i], "-m") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: Make possible root/affix combinations that aren't in the dictionary. hunspell: Analyze the words of the input text */ if (filter_mode != PIPE) filter_mode = ANALYZE; } else if ((strcmp(argv[i], "-s") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: Stop itself with a SIGTSTP signal after each line of input. hunspell: Stem the words of the input text */ if (filter_mode != PIPE) filter_mode = STEM; } else if ((strcmp(argv[i], "-S") == 0)) { if (filter_mode != PIPE) filter_mode = SUFFIX; } else if ((strcmp(argv[i], "-t") == 0)) { format = FMT_LATEX; } else if ((strcmp(argv[i], "-n") == 0)) { format = FMT_MAN; } else if ((strcmp(argv[i], "-H") == 0)) { format = FMT_HTML; } else if ((strcmp(argv[i], "-X") == 0)) { format = FMT_XML; } else if ((strcmp(argv[i], "-O") == 0)) { format = FMT_ODF; } else if ((strcmp(argv[i], "-l") == 0)) { filter_mode = BADWORD; } else if ((strcmp(argv[i], "-w") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: Specify additional characters that can be part of a word. hunspell: Print misspelled words (= lines) from one word/line input */ if (filter_mode != PIPE) filter_mode = WORDFILTER; } else if ((strcmp(argv[i], "-L") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: Number of lines of context to be shown at the bottom of the screen hunspell: Print lines with misspelled words */ if (filter_mode != PIPE) filter_mode = BADLINE; } else if ((strcmp(argv[i], "-u") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: None hunspell: Show typical misspellings */ if (filter_mode != PIPE) filter_mode = AUTO0; } else if ((strcmp(argv[i], "-U") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: None hunspell: Automatic correction of typical misspellings to stdout */ if (filter_mode != PIPE) filter_mode = AUTO; } else if ((strcmp(argv[i], "-u2") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: None hunspell: Print typical misspellings in sed format */ if (filter_mode != PIPE) filter_mode = AUTO2; } else if ((strcmp(argv[i], "-u3") == 0)) { /* if -a was used, don't override, i.e. keep ispell compatability ispell: None hunspell: Print typical misspellings in gcc error format */ if (filter_mode != PIPE) filter_mode = AUTO3; } else if ((strcmp(argv[i], "-G") == 0)) { printgood = 1; } else if ((strcmp(argv[i], "-1") == 0)) { format = FMT_FIRST; } else if ((strcmp(argv[i], "-D") == 0)) { showpath = 1; } else if ((strcmp(argv[i], "-r") == 0)) { warn = 1; } else if ((strcmp(argv[i], "--check-url") == 0)) { checkurl = 1; } else if ((strcmp(argv[i], "--check-apostrophe") == 0)) { checkapos = 1; } else if ((arg_files == -1) && ((argv[i][0] != '-') && (argv[i][0] != '\0'))) { arg_files = i; if (!exist(argv[i])) { // first check (before time-consuming dic. load) fprintf(stderr, gettext("Can't open %s.\n"), argv[i]); #ifdef HAVE_CURSES_H endwin(); #endif exit(1); } } } multiple_files = (arg_files > 0) && (argc - arg_files > 1); if (printgood && (filter_mode == NORMAL)) filter_mode = BADWORD; if (!dicname) { if (!(dicname = getenv("DICTIONARY"))) { /* * Search in order of LC_ALL, LC_MESSAGES & * LANG */ const char* tests[] = {"LC_ALL", "LC_MESSAGES", "LANG"}; for (size_t i = 0; i < sizeof(tests) / sizeof(const char*); ++i) { if ((dicname = getenv(tests[i])) && strcmp(dicname, "") != 0) { dicname = mystrdup(dicname); char* dot = strchr(dicname, '.'); if (dot) *dot = '\0'; char* at = strchr(dicname, '@'); if (at) *at = '\0'; break; } } if (dicname && ((strcmp(dicname, "C") == 0) || (strcmp(dicname, "POSIX") == 0))) { free(dicname); dicname = mystrdup("en_US"); } if (!dicname) { dicname = mystrdup(DEFAULTDICNAME); } } else { dicname = mystrdup(dicname); } } { std::string path_std_str = "."; path_std_str.append(PATHSEP); // <- check path in local directory path_std_str.append(PATHSEP); // <- check path in root directory if (getenv("DICPATH")) { path_std_str.append(getenv("DICPATH")).append(PATHSEP); } path_std_str.append(LIBDIR).append(PATHSEP); if (HOME) { const char * userooodir[] = USEROOODIR; for(size_t i = 0; i < sizeof(userooodir)/sizeof(userooodir[0]); ++i) { path_std_str += HOME; #ifndef _WIN32 path_std_str += DIRSEP; #endif path_std_str.append(userooodir[i]).append(PATHSEP); } path_std_str.append(OOODIR); } path = mystrdup(path_std_str.c_str()); } if (showpath) { fprintf(stderr, gettext("SEARCH PATH:\n%s\n"), path); fprintf( stderr, "%s", gettext( "AVAILABLE DICTIONARIES (path is not mandatory for -d option):\n")); search(path, NULL, NULL); if (-1 == arg_files) { exit(0); } } if (!privdicname) privdicname = mystrdup(getenv("WORDLIST")); char* dicplus = strchr(dicname, ','); if (dicplus) *dicplus = '\0'; char* aff = search(path, dicname, ".aff"); char* dic = search(path, dicname, ".dic"); if (aff && dic) { if (showpath) { fprintf(stderr, gettext("LOADED DICTIONARY:\n%s\n%s\n"), aff, dic); } pMS[0] = new Hunspell(aff, dic, key); dic_enc[0] = pMS[0]->get_dict_encoding().c_str(); dmax = 1; while (dicplus) { char* dicname2 = dicplus + 1; dicplus = strchr(dicname2, ','); if (dicplus) *dicplus = '\0'; free(aff); free(dic); aff = search(path, dicname2, ".aff"); dic = search(path, dicname2, ".dic"); if (aff && dic) { if (dmax < DMAX) { pMS[dmax] = new Hunspell(aff, dic, key); dic_enc[dmax] = pMS[dmax]->get_dict_encoding().c_str(); dmax++; if (showpath) { fprintf(stderr, gettext("LOADED DICTIONARY:\n%s\n%s\n"), aff, dic); } } else fprintf(stderr, gettext("error - %s exceeds dictionary limit.\n"), dicname2); } else if (dic) pMS[dmax - 1]->add_dic(dic); } } else { fprintf(stderr, gettext("Can't open affix or dictionary files for " "dictionary named \"%s\".\n"), dicname); exit(1); } /* open the private dictionaries */ if (HOME) { buf.assign(HOME); #ifndef WIN32 buf.append("/"); #endif buf.append(DICBASENAME); buf.append(basename(dicname, DIRSEPCH)); load_privdic(buf.c_str(), pMS[0]); buf.assign(HOME); #ifndef WIN32 buf.append("/"); #endif if (!privdicname) { buf.assign(DICBASENAME); buf.append(basename(dicname, DIRSEPCH)); load_privdic(buf.c_str(), pMS[0]); } else { buf.append(privdicname); load_privdic(buf.c_str(), pMS[0]); buf.assign(privdicname); load_privdic(buf.c_str(), pMS[0]); } } /* If in pipe mode, output pipe mode version string only when hunspell has properly been started. Emacs and may be others relies in the English version format. Do not gettextize. */ if (filter_mode == PIPE) { fprintf(stdout, HUNSPELL_PIPE_HEADING); fflush(stdout); } if (arg_files == -1) { pipe_interface(pMS, format, stdin, NULL); } else if (filter_mode != NORMAL) { for (int i = arg_files; i < argc; i++) { if (exist(argv[i])) { modified = 0; currentfilename = argv[i]; FILE* f = fopen(argv[i], "r"); pipe_interface(pMS, format, f, argv[i]); fclose(f); } else { fprintf(stderr, gettext("Can't open %s.\n"), argv[i]); exit(1); } } } else /*filter_mode == NORMAL*/ { #ifdef HAVE_CURSES_H initscr(); cbreak(); noecho(); nonl(); intrflush(stdscr, FALSE); for (int i = arg_files; i < argc; i++) { if (exist(argv[i])) { modified = 0; interactive_interface(pMS, argv[i], format); } else { fprintf(stderr, gettext("Can't open %s.\n"), argv[i]); endwin(); exit(1); } } clear(); refresh(); endwin(); #else fprintf( stderr, "%s", gettext( "Hunspell has been compiled without Ncurses user interface.\n")); #endif } if (dicname) free(dicname); if (privdicname) free(privdicname); if (path) free(path); if (aff) free(aff); if (dic) free(dic); #ifdef HAVE_ICONV free_utf_tbl(); #endif for (int i = 0; i < dmax; i++) delete pMS[i]; return 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ hunspell-1.7.0/src/tools/hunzip.cxx000066400000000000000000000046421337236234000173520ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 "../hunspell/hunzip.hxx" #define DESC \ "hunzip - decompress a hzip file to the standard output\n" \ "Usage: hunzip file.hz [password]\n" int main(int argc, char** argv) { if (argc == 1 || strcmp(argv[1], "-h") == 0) { fprintf(stderr, DESC); return 1; } Hunzip h(argv[1], (argc > 2) ? argv[2] : NULL); if (!h.is_open()) return 0; std::string s; while (h.getline(s)) printf("%s", s.c_str()); return 0; } hunspell-1.7.0/src/tools/hzip.cxx000066400000000000000000000257531337236234000170150ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* hzip: file compression for sorted dictionaries with optional encryption, * algorithm: prefix-suffix encoding and 16-bit Huffman encoding */ #include #include #include #include #include #include #define CODELEN 65536 #define BUFSIZE 65536 #define EXTENSION ".hz" #define ESCAPE 31 #define MAGIC "hz0" #define MAGIC_ENCRYPTED "hz1" #define DESC \ "hzip - dictionary compression utility\n" \ "Usage: hzip [-h | -P password ] [file1 file2 ..]\n" \ " -P password encrypted compression\n" \ " -h display this help and exit\n" enum { code_LEAF, code_TERM, code_NODE }; struct item { unsigned short word; int count; char type; struct item* left; struct item* right; }; int fail(const char* err, const char* par) { fprintf(stderr, err, par); return 1; } void code2table(struct item* tree, char** table, char* code, int deep) { int first = 0; if (!code) { first = 1; code = (char*)malloc(CODELEN); } code[deep] = '1'; if (tree->left) code2table(tree->left, table, code, deep + 1); if (tree->type != code_NODE) { int i = tree->word; code[deep] = '\0'; if (tree->type == code_TERM) i = CODELEN; /* terminal code */ table[i] = (char*)malloc(deep + 1); strcpy(table[i], code); } code[deep] = '0'; if (tree->right) code2table(tree->right, table, code, deep + 1); if (first) free(code); } struct item* newitem(int c, struct item* l, struct item* r, int t) { struct item* ni = (struct item*)malloc(sizeof(struct item)); ni->type = t; ni->word = 0; ni->count = c; ni->left = l; ni->right = r; return ni; } /* return length of the freq array */ int get_freqdata(struct item*** dest, FILE* f, unsigned short* termword) { int freq[CODELEN]; int i, j, k, n; union { char c[2]; unsigned short word; } u; for (i = 0; i < CODELEN; i++) freq[i] = 0; while ((j = getc(f)) != -1 && (k = getc(f)) != -1) { u.c[0] = j; u.c[1] = k; freq[u.word]++; } if (j != -1) { u.c[0] = 1; u.c[1] = j; } else { u.c[0] = 0; u.c[1] = 0; } *dest = (struct item**)malloc((CODELEN + 1) * sizeof(struct item*)); if (!*dest) return -1; for (i = 0, n = 0; i < CODELEN; i++) if (freq[i]) { (*dest)[n] = newitem(freq[i], NULL, NULL, code_LEAF); (*dest)[n]->word = i; n++; } /* terminal sequence (also contains the last odd byte of the file) */ (*dest)[n] = newitem(1, NULL, NULL, code_TERM); *termword = u.word; return n + 1; } void get_codetable(struct item** l, int n, char** table) { int i; while (n > 1) { int min = 0; int mi2 = 1; for (i = 1; i < n; i++) { if (l[i]->count < l[min]->count) { mi2 = min; min = i; } else if (l[i]->count < l[mi2]->count) mi2 = i; } l[min] = newitem(l[min]->count + l[mi2]->count, l[min], l[mi2], code_NODE); for (i = mi2 + 1; i < n; i++) l[i - 1] = l[i]; n--; } code2table(l[0], table, NULL, 0); } int write_bits(FILE* f, char* bitbuf, int* bits, char* code) { while (*code) { int b = (*bits) % 8; if (!b) bitbuf[(*bits) / 8] = ((*code) - '0') << 7; else bitbuf[(*bits) / 8] |= (((*code) - '0') << (7 - b)); (*bits)++; code++; if (*bits == BUFSIZE * 8) { if (BUFSIZE != fwrite(bitbuf, 1, BUFSIZE, f)) return 1; *bits = 0; } } return 0; } int encode_file(char** table, int n, FILE* f, FILE* f2, unsigned short tw, char* key) { char bitbuf[BUFSIZE]; int i, bits = 0; unsigned char cl, ch; int cx[2]; union { char c[2]; unsigned short word; } u; char* enc = key; /* header and codes */ fprintf(f2, "%s", (key ? MAGIC_ENCRYPTED : MAGIC)); /* 3-byte HEADER */ cl = (unsigned char)(n & 0x00ff); ch = (unsigned char)(n >> 8); if (key) { unsigned char cs; for (cs = 0; *enc; enc++) cs ^= *enc; fprintf(f2, "%c", cs); /* 1-byte check sum */ enc = key; ch ^= *enc; if ((*(++enc)) == '\0') enc = key; cl ^= *enc; } fprintf(f2, "%c%c", ch, cl); /* upper and lower byte of record count */ for (i = 0; i < BUFSIZE; i++) bitbuf[i] = '\0'; for (i = 0; i < CODELEN + 1; i++) if (table[i]) { size_t nmemb; u.word = (unsigned short)i; if (i == CODELEN) u.word = tw; if (key) { if (*(++enc) == '\0') enc = key; u.c[0] ^= *enc; if (*(++enc) == '\0') enc = key; u.c[1] ^= *enc; } fprintf(f2, "%c%c", u.c[0], u.c[1]); /* 2-character code id */ bits = 0; if (write_bits(f2, bitbuf, &bits, table[i]) != 0) return 1; if (key) { if (*(++enc) == '\0') enc = key; fprintf(f2, "%c", ((unsigned char)bits) ^ *enc); for (cl = 0; cl <= bits / 8; cl++) { if (*(++enc) == '\0') enc = key; bitbuf[cl] ^= *enc; } } else fprintf(f2, "%c", (unsigned char)bits); /* 1-byte code length */ nmemb = bits / 8 + 1; if (fwrite(bitbuf, 1, bits / 8 + 1, f2) != nmemb) /* x-byte code */ return 1; } /* file encoding */ bits = 0; while ((cx[0] = getc(f)) != -1 && (cx[1] = getc(f)) != -1) { u.c[0] = cx[0]; u.c[1] = cx[1]; if (write_bits(f2, bitbuf, &bits, table[u.word]) != 0) return 1; } /* terminal suffixes */ if (write_bits(f2, bitbuf, &bits, table[CODELEN]) != 0) return 1; if (bits > 0) { size_t nmemb = bits / 8 + 1; if (fwrite(bitbuf, 1, nmemb, f2) != nmemb) return 1; } return 0; } int prefixcompress(FILE* f, FILE* tempfile) { char buf[BUFSIZE]; char buf2[BUFSIZE * 2]; char prev[BUFSIZE]; int prevlen = 0; while (fgets(buf, BUFSIZE, f)) { int i, j, k, m, c = 0; int pfx = prevlen; char* p = buf2; m = j = 0; for (i = 0; buf[i]; i++) { if ((pfx > 0) && (buf[i] == prev[i])) { j++; } else pfx = 0; } if (i > 0 && buf[i - 1] == '\n') { if (j == i) j--; /* line duplicate */ if (j > 29) j = 29; c = j; if (c == '\t') c = 30; /* common suffix */ for (; (m < i - j - 1) && (m < 15) && (prevlen - m - 2 >= 0) && buf[i - m - 2] == prev[prevlen - m - 2]; m++) ; if (m == 1) m = 0; } else { j = 0; m = -1; } for (k = j; k < i - m - 1; k++, p++) { if (((unsigned char)buf[k]) < 47 && buf[k] != '\t' && buf[k] != ' ') { *p = ESCAPE; p++; } *p = buf[k]; } if (m > 0) { *p = m + 31; /* 33-46 */ p++; } if (i > 0 && buf[i - 1] == '\n') { size_t nmemb = p - buf2 + 1; *p = c; if (fwrite(buf2, 1, nmemb, tempfile) != nmemb) return 1; } else { size_t nmemb = p - buf2; if (fwrite(buf2, 1, nmemb, tempfile) != nmemb) return 1; } memcpy(prev, buf, i); prevlen = i; } return 0; } int hzip(const char* filename, char* key) { struct item** list; char* table[CODELEN + 1]; int n; unsigned short termword; FILE* f = fopen(filename, "r"); if (!f) return fail("hzip: %s: Permission denied\n", filename); char tmpfiletemplate[] = "/tmp/hunspellXXXXXX"; mode_t mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); int tempfileno = mkstemp(tmpfiletemplate); umask(mask); if (tempfileno == -1) { fclose(f); return fail("hzip: cannot create temporary file\n", NULL); } FILE *tempfile = fdopen(tempfileno, "rw"); if (!tempfile) { close(tempfileno); unlink(tmpfiletemplate); fclose(f); return fail("hzip: cannot create temporary file\n", NULL); } std::string out(filename); out.append(EXTENSION); FILE* f2 = fopen(out.c_str(), "wb"); if (!f2) { fclose(tempfile); fclose(f); unlink(tmpfiletemplate); return fail("hzip: %s: Permission denied\n", out.c_str()); } for (n = 0; n < CODELEN; n++) table[n] = NULL; if (prefixcompress(f, tempfile) != 0) { fclose(f2); fclose(tempfile); fclose(f); unlink(tmpfiletemplate); return fail("hzip: cannot write file\n", NULL); } rewind(tempfile); n = get_freqdata(&list, tempfile, &termword); get_codetable(list, n, table); rewind(tempfile); n = encode_file(table, n, tempfile, f2, termword, key); free(list); fclose(f2); fclose(tempfile); fclose(f); unlink(tmpfiletemplate); if (n != 0) return fail("hzip: cannot write file\n", NULL); return n; } int main(int argc, char** argv) { int i, j = 0; char* key = NULL; for (i = 1; i < argc; i++) { if (*(argv[i]) == '-') { if (*(argv[i] + 1) == 'h') return fail(DESC, NULL); if (*(argv[i] + 1) == 'P') { if (i + 1 == argc) return fail("hzip: missing password\n", NULL); key = argv[i + 1]; i++; continue; } return fail("hzip: no such option: %s\n", argv[i]); } else if (hzip(argv[i], key) != 0) return 1; else j = 1; } if (j == 0) return fail("hzip: need a filename parameter\n", NULL); return 0; } hunspell-1.7.0/src/tools/ispellaff2myspell000066400000000000000000000314511337236234000206670ustar00rootroot00000000000000#!/usr/bin/perl -w # -*- coding: iso-8859-1 -*- # $Id$ # # (C) 2002-2005 Agustin Martin Domingo # # This program 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 2 of the License, or # (at your option) any later version. # # This program 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 this program. If not, see . sub usage { print "ispellaff2myspell: A program to convert ispell affix tables to myspell format (C) 2002-2005 Agustin Martin Domingo License: GPL Usage: ispellaff2myspell [options] Options: --affixfile=s Affix file --bylocale Use current locale setup for upper/lowercase conversion --charset=s Use specified charset for upper/lowercase conversion (defaults to latin1) --debug Print debugging info --extraflags Allow some non alphabetic flags --lowercase=s Lowercase string --myheader=s Header file --printcomments Print commented lines in output --replacements=s Replacements file --split=i Split flags with more that i entries --uppercase=s Uppercase string --wordlist=s Still unused Currently allowed valued for charset are: latin1, latin2, latin3 This script does not create the dict file. Something like ( echo `cat mydict.words+ | wc -l`; cat mydict.words+ ) > mydict.dict should do the work, with mydict.words+ being the ispell munched wordlist "; exit; } sub debugprint { if ( $debug ){ print STDERR "@_"; } } sub shipoutflag{ my $flag_entries=scalar @flag_array; if ( $flag_entries != 0 ){ if ( $split ){ while ( @flag_array ){ my @flag_subarray=splice(@flag_array,0,$split); my $subflag_entries=scalar @flag_subarray; if ( scalar @flag_array ){ print "$myaffix $flagname $flagcombine $subflag_entries S\n"; } else { print "$myaffix $flagname $flagcombine $subflag_entries\n"; } print join("\n",@flag_subarray); print "\n\n"; } } else { print "$myaffix $flagname $flagcombine $flag_entries\n"; print join("\n",@flag_array); print "\n\n"; } } @flag_array=(); $flagname=''; $flagcombine=''; } sub mylc{ my $inputstring=shift; my $outputstring; if ( $bylocale ){ { use locale; $outputstring = lc $inputstring; } } else { if ( $charset eq "latin0" ){ $lowercase='a-z'; $uppercase='A-Z޼'; } elsif ( $charset eq "latin1" ){ $lowercase='a-z'; $uppercase='A-Z'; } elsif ( $charset eq "latin2" ){ $lowercase='a-z'; $uppercase='A-Z'; } elsif ( $charset eq "latin3" ){ $lowercase='a-z'; $uppercase='A-Z'; # } elsif ( $charset eq "other_charset" ){ # die "latin2 still unimplemented"; } else { if ( not $lowercase and not $uppercase ){ die "Unsupported charset [$charset] Explicitly use --lowercase=string and --uppercase=string options. Remember that both string must match exactly, but case changed. "; } } $outputstring=$inputstring; eval "\$outputstring=~tr/$uppercase/$lowercase/"; } return $outputstring; } sub validate_flag (){ my $flag = shift; if ($flag=~m/[a-zA-Z]+/){ return $flag; } elsif ( $hasextraflags ){ foreach ( keys %theextraflags ){ if ($flag =~ m/^$_/){ $flag =~ s/^$_//; return $flag; } } } return ''; } sub process_replacements{ my $file = shift; my @replaces = (); open (REPLACE,"< $file") || die "Error: Could not open replacements file: $file\n"; while (){ next unless m/^REP[\s\t]*\D.*/; next if m/^REP\s+[0-9]+/; s/\015\012//; s/\015//; chomp; push @replaces, $_; } close REPLACE; my $number = scalar @replaces; print "REP $number\n"; foreach ( @replaces ){ print $_ . "\n"; } } # ----------------------------------------------------------- # Now the progran start, after the functions are defined # ----------------------------------------------------------- use Getopt::Long; # Initializing option values $affixfile = ''; $bylocale = ''; $charset = ''; $debug = ''; $lowercase = ''; $myheader = ''; $printcomments = ''; $replacements = ''; $split = ''; $uppercase = ''; $wordlist = ''; $hasextraflags = ''; @flag_array = (); %theextraflags = (); # Initializing root values $rootremove = "0"; $rootname = ''; $addtoroot = ''; $comment = ''; # Initializing flag values $flagname = ''; $flagcombine = ''; $inflags = ''; GetOptions ('affixfile=s' => \$affixfile, 'bylocale' => \$bylocale, 'charset=s' => \$charset, 'debug' => \$debug, 'extraflags:s' => sub { $hasextraflags = 1; shift; $theflag = shift; $theextraflags{$theflag}++ if $theflag}, 'lowercase=s' => \$lowercase, 'myheader=s' => \$myheader, 'printcomments' => \$printcomments, 'replacements=s'=> \$replacements, 'split=i' => \$split, 'uppercase=s' => \$uppercase, 'wordlist=s' => \$wordlist) or usage; if ( not $affixfile ){ $affixfile=shift or usage; } if ( $charset and ( $lowercase or $uppercase )){ die "Error: charset and lowercase/uppercase options are incompatible. Use either charset or lowercase/uppercase options to specify the patterns " } elsif ( not $lowercase and not $uppercase and not $charset ){ $charset="latin1"; } if ( scalar(keys %theextraflags) == 0 && $hasextraflags ){ $theextraflags{"\\\\"}++; } debugprint "$affixfile $charset"; open (AFFIXFILE,"< $affixfile") || die "Error: Could not open affix file: $affixfile"; if ( $myheader ){ my $myspell_header=`cat $myheader`; print $myspell_header . "\n"; } while (){ chomp; if (/^\s*\#.*/){ debugprint "Ignoring line $.\n"; print "$_\n" if $printcomments; } elsif (/^\s*$/){ debugprint "Ignoring line $.\n"; } elsif (/^\s*prefixes/){ debugprint "Prefixes starting in line $.\n"; $affix="PFX"; } elsif (/^\s*suffixes/){ debugprint "Suffixes starting in line $.\n"; $affix="SFX"; } elsif (/^[\s\t]*flag.*/){ next if not $affix; # In case we are still in the preamble shipoutflag if $inflags; $inflags="yes"; s/^[\s\t]*flag[\s\t]*//; s/[\s\t]*:.*$//; debugprint "Found flag $_ in line $.\n"; if (/\*/){ s/[\*\s]//g; $flagcombine="Y"; debugprint "Flag renamed to $_ with combine=$flagcombine\n"; } else { $flagcombine="N"; } if ( $flagname = &validate_flag($_) ){ $myaffix = $affix; } else { $myaffix = "\# $affix"; $flagname = $_; print STDERR "Ignoring invalid flag $flagname in line $.\n"; } } elsif ( $affix and $inflags ) { ($rootname,@comments) = split('#',$_); $comment = '# ' . join('#',@comments); $rootname =~ s/\s*//g; $rootname = mylc $rootname; ($rootname,$addtoroot) = split('>',$rootname); if ( $addtoroot =~ s/^\-//g ){ ($rootremove,$addtoroot) = split(',',$addtoroot); $addtoroot = "0" unless $addtoroot; $addtoroot = "0" if ( $addtoroot eq "-"); } else { $rootremove = "0"; } $addtoroot =~ s/\\\-/\-/g; # prefix ANTI\- to anti- if ( $rootname eq '.' && $rootremove ne "0" ){ $rootname = $rootremove; } debugprint "$rootname, $addtoroot, $rootremove\n"; if ( $printcomments ){ $affix_line=sprintf("%s %s %-5s %-11s %-24s %s", $myaffix, $flagname, $rootremove, $addtoroot, $rootname, $comment); } else { $affix_line=sprintf("%s %s %-5s %-11s %s", $myaffix, $flagname, $rootremove, $addtoroot, $rootname); } $rootremove = "0"; $rootname = ''; $addtoroot = ''; $comment = ''; @comments = (); push @flag_array,$affix_line; debugprint "$affix_line\n"; } else { # } } shipoutflag; close AFFIXFILE; if ( $replacements ){ &process_replacements($replacements); } __END__ =head1 NAME B - A program to convert ispell affix tables to myspell format. =head1 SYNOPSIS ispellaff2myspell [options] --myheader your_header Options: --affixfile=s Affix file --bylocale Use current locale setup for upper/lowercase conversion --charset=s Use specified charset for upper/lowercase conversion (defaults to latin1) --debug Print debugging info --extraflags=s Allow some non alphabetic flags --lowercase=s Lowercase string --myheader=s Header file --printcomments Print commented lines in output --replacements=s Replacements file --split=i Split flags with more that i entries --uppercase=s Uppercase string =head1 DESCRIPTION B is a script that will convert ispell affix tables to myspell format in a more or less successful way. This script does not create the dict file. Something like ( echo `cat mydict.words+ | wc -l`; cat mydict.words+ ) > mydict.dict should do the work, with mydict.words+ being the munched wordlist =head1 OPTIONS =over 8 =item B<--affixfile=s> Affix file. You can put it directly in the command line. =item B<--bylocale> Use current locale setup for upper/lowercase conversion. Make sure that the selected locale match the dictionary one, or you might get into trouble. =item B<--charset=s> Use specified charset for upper/lowercase conversion (defaults to latin1). Currently allowed values for charset are: latin0, latin1, latin2, latin3. =item B<--debug> Print some debugging info. =item B<--extraflags:s> Allows some non alphabetic flags. When invoked with no value the supported flags are currently those corresponding to chars represented with the escape char B<\> as first char. B<\> will be stripped. When given with the flag prefix will allow that flag and strip the given prefix. Be careful when giving the prefix to properly escape chars, e.g. you will need B<-e "\\\\"> or B<-e '\\'> for flags like B<\[> to be stripped to B<[>. Otherwise you might even get errors. Use B<-e "^"> to allow all flags and pass them unmodified. You will need a call to -e for each flag type, e.g., B<-e "\\\\" -e "~\\\\"> (or B<-e '\\' -e '~\\'>). When a prefix is explicitely set, the default value (anything starting by B<\>) is disabled and you need to enable it explicitely as in previous example. =item B<--lowercase=s> Lowercase string. Manually set the string of lowercase chars. This requires B<--uppercase> having exactly that string but uppercase. =item B<--myheader=s> Header file. The myspell aff header. You need to write it manually. This can contain everything you want to be before the affix table =item B<--printcomments> Print commented lines in output. =item B<--replacements=file> Add a pre-defined replacements table taken from 'file' to the .aff file. Will skip lines not beginning with REP, and set the replacements number appropriately. =item B<--split=i> Split flags with more that i entries. This can be of interest for flags having a lot of entries. Will split the flag in chunks containing B entries. =item B<--uppercase=s> Uppercase string. Manually set the sring of uppercase chars. This requires B<--lowercase> having exactly that string but lowercase. =back If your encoding is currently unsupported you can send me a file with the two strings of lower and uppercase chars. Note that they must match exactly but case changed. It will look something like $lowercase='a-z'; $uppercase='A-Z'; =head1 SEE ALSO The OpenOffice.org Lingucomponent Project home page L and the document L that provides information about the basics of the myspell affix file format. You can also take a look at /usr/share/doc/libmyspell-dev/affix.readme.gz /usr/share/doc/libmyspell-dev/README.compoundwords /usr/share/doc/libmyspell-dev/README.replacetable in your Debian system. =head1 AUTHORS Agustin Martin =cut hunspell-1.7.0/src/tools/makealias000077500000000000000000000116251337236234000171650ustar00rootroot00000000000000#!/bin/sh # makealias: make alias compressed dic and aff files # Usage: alias.sh dic aff (not alias.sh aff dic!) # Author: László Németh # Version: 2018-05-16 export LC_ALL=C case $# in 0|1) echo 'makealias: make alias compressed dic and aff files Usage: makealias [--minimize-diff old_file_without_file_extension] file.dic file.aff' >/dev/stderr exit;; esac if [ "$1" = "--minimize-diff" ]; then AWK_ARG="-v mindiff=$2.aff" shift; shift fi DIC=`basename $1 .dic` AFF=`basename $2 .aff` # FLAG type definition must be before alias definitions grep '^FLAG' $2 >"${AFF}_alias.aff" # space conversion (space separated multi-word expressions # are allowed in the dictionary) cat $1 | sed 's/ /_/g' > "${DIC}_alias.tmp.dic" awk $AWK_ARG ' BEGIN{ n=1;m=1 # make smaller and more readable diff for LibreOffice git if (mindiff != "") { n=0;m=0 # load old AF and AM fields while ((getline var < mindiff) > 0) { if (var~/^AF /) { b[n] = gensub(" #.*$", "", 1, substr(var, 4)) a[b[n]] = n n = n + 1 } if (var~/^AM /) { c[m] = substr(var, 4) a2[c[m]] = m m = m + 1 } } # reuse unused AF and AM items # first load dic while ((getline $0 < ARGV[1]) > 0) { if (match($0, "^([^ \t/]+)(/([^ \t]*))?([ \t]*(.*))?", flds)) { if (length(flds[3]) > 0) { if(a[flds[3]]) { used[flds[3]] = 1 } else if (!not_used_registered[flds[3]]) { not_used[un] = flds[3] not_used_registered[flds[3]] = 1 un++ } } if (length(flds[5]) > 0) { mfld = ltrim(flds[5]) if(a2[mfld] || not_used2[mfld]) { used2[mfld] = 1 } else if (!not_used2_registered[mfld]) { not_used2[um] = mfld not_used2_registered[mfld] = 1 um++ } } } } # load aff file while ((getline $0 < ARGV[2]) > 0) { if ($0 ~ /^[PS]FX/ && NF > 4) { if ($4 ~ /\/[^ \t]/) { split($4,t,"/") if(a[t[2]]){ used[t[2]] = 1 } else { not_used[un++] = t[2] } } if ($6 != "") { $1 = $2 = $3 = $4 = $5 = "" $0 = ltrim($0) if(a2[$0]) { used2[$0] = 1 } else { not_used2[um++] = $0 } } } } # reuse unused items j = 0 for (i=0; i < n && j < un; i++) { if (!(b[i] in used)) { b[i] = not_used[j] a[b[i]] = i used[b[i]] = 1 j++ } } j = 0 for (i=0; i < m && j < um; i++) { if (!(c[i] in used2)) { c[i] = not_used2[j] a2[c[i]] = i used2[c[i]] = 1 j++ } } } } function cutslash(st) { if (split(st,t,"/") > 1) return t[1] return st } function ltrim(st) { sub(/^ +/,"",st) gsub("[ \t]+"," ",st) return st } FILENAME ~ /.dic$/ && match($0, "^([^ \t/]+)(/([^ \t]*))?([ \t]*(.*))?", flds) { # flag vector? flags = "" if(length(flds[3]) > 0) { if (!a[flds[3]]) { a[flds[3]]=n b[n]=flds[3] n++ } flags = "/" a[flds[3]] } end = "" # morphological fields? if (length(flds[5]) > 0) { mfld = ltrim(flds[5]) if(!a2[mfld]){ a2[mfld]=m c[m]=mfld m++ } end = "\t" a2[mfld] } print flds[1] flags end next } FILENAME ~ /.aff$/ && /^[PS]FX/ && NF > 4 { if ($4 ~ /\/[^ \t]/) { split($4,t,"/") if(!a[t[2]]){ a[t[2]]=n b[n]=t[2] n++ } begin = $1 " " $2 " " $3 " " (t[1]"/"a[t[2]]) " " $5 } else { begin = $1 " " $2 " " $3 " " cutslash($4) " " $5 } end = "" if ($6 != "") { $1 = $2 = $3 = $4 = $5 = "" $0 = ltrim($0) if(!a2[$0]) { a2[$0]=m c[m]=$0 m++ } end = " " a2[$0] } print begin end >>"/dev/stderr" next } FILENAME ~ /.aff$/ { print $0 >>"/dev/stderr" } END { if (n>1) { print "AF", n-1 >>"'${AFF}_alias.aff'" for(i=1;i>"'${AFF}_alias.aff'" } if (m>1) { print "AM", m-1 >>"'${AFF}_alias.aff'" for(i=1;i>"'${AFF}_alias.aff'" } }' "${DIC}_alias.tmp.dic" $2 >"${DIC}_alias.tmp" 2>"${AFF}_alias.$$" cat "${DIC}_alias.tmp" | sed 's/_/ /g' > "${DIC}_alias.dic" grep -v '^FLAG' "${AFF}_alias.$$" | sed 's/\s\+$//' >>"${AFF}_alias.aff" echo "output: ${DIC}_alias.dic, ${AFF}_alias.aff" rm ${DIC}_alias.tmp ${DIC}_alias.tmp.dic ${AFF}_alias.$$ hunspell-1.7.0/src/tools/munch.cxx000066400000000000000000000544471337236234000171570ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* Munch a word list and generate a smaller root word list with affixes*/ #include #include #include #include #include #include #include #include #include #include #include #include #include "munch.h" int main(int argc, char** argv) { int i, j, k, n; int rl, p, nwl; int al; FILE* wrdlst; FILE* afflst; char *nword, *wf, *af; char as[(MAX_PREFIXES + MAX_SUFFIXES)]; char* ap; struct hentry* ep; struct hentry* ep1; struct affent* pfxp; struct affent* sfxp; (void)argc; /* first parse the command line options */ /* arg1 - wordlist, arg2 - affix file */ if (argv[1]) { wf = mystrdup(argv[1]); } else { fprintf(stderr, "correct syntax is:\n"); fprintf(stderr, "munch word_list_file affix_file\n"); exit(1); } if (argv[2]) { af = mystrdup(argv[2]); } else { fprintf(stderr, "correct syntax is:\n"); fprintf(stderr, "munch word_list_file affix_file\n"); exit(1); } /* open the affix file */ afflst = fopen(af, "r"); if (!afflst) { fprintf(stderr, "Error - could not open affix description file\n"); exit(1); } /* step one is to parse the affix file building up the internal affix data structures */ numpfx = 0; numsfx = 0; if (parse_aff_file(afflst)) { fprintf(stderr, "Error - in affix file loading\n"); exit(1); } fclose(afflst); fprintf(stderr, "parsed in %d prefixes and %d suffixes\n", numpfx, numsfx); /* affix file is now parsed so create hash table of wordlist on the fly */ /* open the wordlist */ wrdlst = fopen(wf, "r"); if (!wrdlst) { fprintf(stderr, "Error - could not open word list file\n"); exit(1); } if (load_tables(wrdlst)) { fprintf(stderr, "Error building hash tables\n"); exit(1); } fclose(wrdlst); for (i = 0; i < tablesize; i++) { ep = &tableptr[i]; if (ep->word == NULL) continue; for (; ep != NULL; ep = ep->next) { numroots = 0; aff_chk(ep->word, strlen(ep->word)); if (numroots) { /* now there might be a number of combinations */ /* of prefixes and suffixes that might match this */ /* word. So how to choose? As a first shot look */ /* for the shortest remaining root word to */ /* to maximize the combinatorial power */ /* but be careful, do not REQUIRE a specific combination */ /* of a prefix and a suffix to generate the word since */ /* that violates the rule that the root word with just */ /* the prefix or just the suffix must also exist in the */ /* wordlist as well */ /* in fact because of the cross product issue, this not a */ /* simple choice since some combinations of previous */ /* prefixes and new suffixes may not be valid. */ /* The only way to know is to simply try them all */ rl = 1000; p = -1; for (j = 0; j < numroots; j++) { /* first collect the root word info and build up */ /* the potential new affix string */ nword = (roots[j].hashent)->word; nwl = strlen(nword); *as = '\0'; ap = as; if (roots[j].prefix) *ap++ = (roots[j].prefix)->achar; if (roots[j].suffix) *ap++ = (roots[j].suffix)->achar; if ((roots[j].hashent)->affstr) { strcpy(ap, (roots[j].hashent)->affstr); } else { *ap = '\0'; } al = strlen(as); /* now expand the potential affix string to generate */ /* all legal words and make sure they all exist in the */ /* word list */ numwords = 0; wlist[numwords].word = mystrdup(nword); wlist[numwords].pallow = 0; numwords++; n = 0; if (al) expand_rootword(nword, nwl, as); for (k = 0; k < numwords; k++) { if (lookup(wlist[k].word)) n++; free(wlist[k].word); wlist[k].word = NULL; wlist[k].pallow = 0; } /* if all exist in word list then okay */ if (n == numwords) { if (nwl < rl) { rl = nwl; p = j; } } } if (p != -1) { ep1 = roots[p].hashent; pfxp = roots[p].prefix; sfxp = roots[p].suffix; ep1->keep = 1; if (pfxp != NULL) add_affix_char(ep1, pfxp->achar); if (sfxp != NULL) add_affix_char(ep1, sfxp->achar); } else { ep->keep = 1; } } else { ep->keep = 1; } } } /* now output only the words to keep along with affixes info */ /* first count how many words that is */ k = 0; for (i = 0; i < tablesize; i++) { ep = &tableptr[i]; if (ep->word == NULL) continue; for (; ep != NULL; ep = ep->next) { if (ep->keep > 0) k++; } } fprintf(stdout, "%d\n", k); for (i = 0; i < tablesize; i++) { ep = &tableptr[i]; if (ep->word == NULL) continue; for (; ep != NULL; ep = ep->next) { if (ep->keep > 0) { if (ep->affstr != NULL) { fprintf(stdout, "%s/%s\n", ep->word, ep->affstr); } else { fprintf(stdout, "%s\n", ep->word); } } } } return 0; } int parse_aff_file(FILE* afflst) { int i, j; int numents = 0; char achar = '\0'; short ff = 0; struct affent* ptr = NULL; struct affent* nptr = NULL; char* line = (char*)malloc(MAX_LN_LEN); while (fgets(line, MAX_LN_LEN, afflst)) { mychomp(line); char ft = ' '; fprintf(stderr, "parsing line: %s\n", line); if (strncmp(line, "PFX", 3) == 0) ft = 'P'; if (strncmp(line, "SFX", 3) == 0) ft = 'S'; if (ft != ' ') { char* tp = line; char* piece; i = 0; ff = 0; while ((piece = mystrsep(&tp, ' '))) { if (*piece != '\0') { switch (i) { case 0: break; case 1: { achar = *piece; break; } case 2: { if (*piece == 'Y') ff = XPRODUCT; break; } case 3: { numents = atoi(piece); if ((numents <= 0) || ((std::numeric_limits::max() / sizeof(struct affent)) < static_cast(numents))) { fprintf(stderr, "Error: too many entries: %d\n", numents); numents = 0; } else { ptr = (struct affent*)malloc(numents * sizeof(struct affent)); ptr->achar = achar; ptr->xpflg = ff; fprintf(stderr, "parsing %c entries %d\n", achar, numents); } break; } default: break; } i++; } free(piece); } /* now parse all of the sub entries*/ nptr = ptr; for (j = 0; j < numents; j++) { if (!fgets(line, MAX_LN_LEN, afflst)) return 1; mychomp(line); tp = line; i = 0; while ((piece = mystrsep(&tp, ' '))) { if (*piece != '\0') { switch (i) { case 0: { if (nptr != ptr) { nptr->achar = ptr->achar; nptr->xpflg = ptr->xpflg; } break; } case 1: break; case 2: { nptr->strip = mystrdup(piece); nptr->stripl = strlen(nptr->strip); if (strcmp(nptr->strip, "0") == 0) { free(nptr->strip); nptr->strip = mystrdup(""); nptr->stripl = 0; } break; } case 3: { nptr->appnd = mystrdup(piece); nptr->appndl = strlen(nptr->appnd); if (strcmp(nptr->appnd, "0") == 0) { free(nptr->appnd); nptr->appnd = mystrdup(""); nptr->appndl = 0; } break; } case 4: { encodeit(nptr, piece); } fprintf(stderr, " affix: %s %d, strip: %s %d\n", nptr->appnd, nptr->appndl, nptr->strip, nptr->stripl); // no break default: break; } i++; } free(piece); } nptr++; } if (ft == 'P') { if (numpfx < MAX_PREFIXES) { ptable[numpfx].aep = ptr; ptable[numpfx].num = numents; fprintf(stderr, "ptable %d num is %d\n", numpfx, ptable[numpfx].num); numpfx++; } else { fprintf(stderr, "prefix buffer ptable is full\n"); } } else { if (numsfx < MAX_SUFFIXES) { stable[numsfx].aep = ptr; stable[numsfx].num = numents; fprintf(stderr, "stable %d num is %d\n", numsfx, stable[numsfx].num); numsfx++; } else { fprintf(stderr, "suffix buffer stable is full\n"); } } ptr = NULL; nptr = NULL; numents = 0; achar = '\0'; } } free(line); return 0; } void encodeit(struct affent* ptr, char* cs) { int nc; int neg; int grp; int n; int ec; int nm; int i, j, k; unsigned char mbr[MAX_WD_LEN]; /* now clear the conditions array */ for (i = 0; i < SET_SIZE; i++) ptr->conds[i] = (unsigned char)0; /* now parse the string to create the conds array */ nc = strlen(cs); neg = 0; /* complement indicator */ grp = 0; /* group indicator */ n = 0; /* number of conditions */ ec = 0; /* end condition indicator */ nm = 0; /* number of member in group */ i = 0; if (strcmp(cs, ".") == 0) { ptr->numconds = 0; return; } while (i < nc) { unsigned char c = *((unsigned char*)(cs + i)); if (c == '[') { grp = 1; c = 0; } if ((grp == 1) && (c == '^')) { neg = 1; c = 0; } if (c == ']') { ec = 1; c = 0; } if ((grp == 1) && (c != 0)) { *(mbr + nm) = c; nm++; c = 0; } if (c != 0) { ec = 1; } if (ec) { if (grp == 1) { if (neg == 0) { for (j = 0; j < nm; j++) { k = (unsigned int)mbr[j]; ptr->conds[k] = ptr->conds[k] | (1 << n); } } else { for (j = 0; j < SET_SIZE; j++) ptr->conds[j] = ptr->conds[j] | (1 << n); for (j = 0; j < nm; j++) { k = (unsigned int)mbr[j]; ptr->conds[k] = ptr->conds[k] & ~(1 << n); } } neg = 0; grp = 0; nm = 0; } else { /* not a group so just set the proper bit for this char */ /* but first handle special case of . inside condition */ if (c == '.') { /* wild card character so set them all */ for (j = 0; j < SET_SIZE; j++) ptr->conds[j] = ptr->conds[j] | (1 << n); } else { ptr->conds[(unsigned int)c] = ptr->conds[(unsigned int)c] | (1 << n); } } n++; ec = 0; } i++; } ptr->numconds = n; return; } /* search for a prefix */ void pfx_chk(const char* word, int len, struct affent* ep, int num) { struct affent* aent; int cond; struct hentry* hent; int i; for (aent = ep, i = num; i > 0; aent++, i--) { int tlen = len - aent->appndl; if (tlen > 0 && (aent->appndl == 0 || strncmp(aent->appnd, word, aent->appndl) == 0) && tlen + aent->stripl >= aent->numconds) { std::string tword(aent->strip); tword.append(word + aent->appndl); /* now go through the conds and make sure they all match */ unsigned char* cp = (unsigned char*)tword.c_str(); for (cond = 0; cond < aent->numconds; cond++) { if ((aent->conds[*cp++] & (1 << cond)) == 0) break; } if (cond >= aent->numconds) { if ((hent = lookup(tword.c_str())) != NULL) { if (numroots < MAX_ROOTS) { roots[numroots].hashent = hent; roots[numroots].prefix = aent; roots[numroots].suffix = NULL; numroots++; } } } } } } void suf_chk(const char* word, int len, struct affent* ep, int num, struct affent* pfxent, int cpflag) { struct affent* aent; int cond; struct hentry* hent; int i; for (aent = ep, i = num; i > 0; aent++, i--) { if ((cpflag & XPRODUCT) != 0 && (aent->xpflg & XPRODUCT) == 0) continue; int tlen = len - aent->appndl; if (tlen > 0 && (aent->appndl == 0 || strcmp(aent->appnd, (word + tlen)) == 0) && tlen + aent->stripl >= aent->numconds) { std::string tword(word); tword.resize(tlen); tword.append(aent->strip); unsigned char* cp = (unsigned char*)(tword.c_str() + tword.size()); for (cond = aent->numconds; --cond >= 0;) { if ((aent->conds[*--cp] & (1 << cond)) == 0) break; } if (cond < 0) { if ((hent = lookup(tword.c_str())) != NULL) { if (numroots < MAX_ROOTS) { roots[numroots].hashent = hent; roots[numroots].prefix = pfxent; roots[numroots].suffix = aent; numroots++; } } } } } } void aff_chk(const char* word, int len) { int i; int nh = 0; if (len < 4) return; for (i = 0; i < numpfx; i++) { pfx_chk(word, len, ptable[i].aep, ptable[i].num); } nh = numroots; if (nh > 0) { for (int j = 0; j < nh; j++) { if (roots[j].prefix->xpflg & XPRODUCT) { char* nword = mystrdup((roots[j].hashent)->word); int nwl = strlen(nword); for (i = 0; i < numsfx; i++) { suf_chk(nword, nwl, stable[i].aep, stable[i].num, roots[j].prefix, XPRODUCT); } free(nword); } } } for (i = 0; i < numsfx; i++) { suf_chk(word, len, stable[i].aep, stable[i].num, NULL, 0); } } /* lookup a root word in the hashtable */ struct hentry* lookup(const char* word) { struct hentry* dp; dp = &tableptr[hash(word)]; if (dp->word == NULL) return NULL; for (; dp != NULL; dp = dp->next) { if (strcmp(word, dp->word) == 0) return dp; } return NULL; } /* add a word to the hash table */ int add_word(char* word) { int i; struct hentry* dp; struct hentry* hp = (struct hentry*)malloc(sizeof(struct hentry)); hp->word = word; hp->affstr = NULL; hp->keep = 0; hp->next = NULL; i = hash(word); dp = &tableptr[i]; if (dp->word == NULL) { *dp = *hp; free(hp); } else { while (dp->next != NULL) dp = dp->next; dp->next = hp; } return 0; } /* load a word list and build a hash table on the fly */ int load_tables(FILE* wdlst) { char ts[MAX_LN_LEN]; int nExtra = 5; /* first read the first line of file to get hash table size */ if (!fgets(ts, MAX_LN_LEN - 1, wdlst)) return 2; mychomp(ts); tablesize = atoi(ts); if (tablesize <= 0 || (tablesize >= (std::numeric_limits::max() - 1 - nExtra) / (int)sizeof(struct hentry*))) { return 3; } tablesize += nExtra; if ((tablesize % 2) == 0) tablesize++; /* allocate the hash table */ tableptr = (struct hentry*)calloc(tablesize, sizeof(struct hentry)); if (!tableptr) return 3; /* loop thorugh all words on much list and add to hash * table and store away word and affix strings in tmpfile */ while (fgets(ts, MAX_LN_LEN - 1, wdlst)) { mychomp(ts); char* ap = mystrdup(ts); add_word(ap); } return 0; } /* the hash function is a simple load and rotate * algorithm borrowed */ int hash(const char* word) { int i; long hv = 0; for (i = 0; i < 4 && *word != 0; i++) hv = (hv << 8) | (*word++); while (*word != 0) { ROTATE(hv, ROTATE_LEN); hv ^= (*word++); } return (unsigned long)hv % tablesize; } void add_affix_char(struct hentry* ep, char ac) { int al; int i; char* tmp; if (ep->affstr == NULL) { ep->affstr = (char*)malloc(2); *(ep->affstr) = ac; *((ep->affstr) + 1) = '\0'; return; } al = strlen(ep->affstr); for (i = 0; i < al; i++) if (ac == (ep->affstr)[i]) return; tmp = (char*)calloc(al + 2, 1); memcpy(tmp, ep->affstr, (al + 1)); *(tmp + al) = ac; *(tmp + al + 1) = '\0'; free(ep->affstr); ep->affstr = tmp; return; } /* add a prefix to word */ void pfx_add(const char* word, int len, struct affent* ep, int num) { struct affent* aent; int cond; unsigned char* cp; int i; char* pp; char tword[MAX_WD_LEN]; for (aent = ep, i = num; i > 0; aent++, i--) { /* now make sure all conditions match */ if ((len > aent->stripl) && (len >= aent->numconds)) { cp = (unsigned char*)word; for (cond = 0; cond < aent->numconds; cond++) { if ((aent->conds[*cp++] & (1 << cond)) == 0) break; } if (cond >= aent->numconds) { /* we have a match so add prefix */ int tlen = 0; if (aent->appndl) { strncpy(tword, aent->appnd, MAX_WD_LEN - 1); tword[MAX_WD_LEN - 1] = '\0'; tlen += aent->appndl; } pp = tword + tlen; strcpy(pp, (word + aent->stripl)); if (numwords < MAX_WORDS) { wlist[numwords].word = mystrdup(tword); wlist[numwords].pallow = 0; numwords++; } } } } } /* add a suffix to a word */ void suf_add(const char* word, int len, struct affent* ep, int num) { struct affent* aent; int cond; unsigned char* cp; int i; char tword[MAX_WD_LEN]; char* pp; for (aent = ep, i = num; i > 0; aent++, i--) { /* if conditions hold on root word * then strip off strip string and add suffix */ if ((len > aent->stripl) && (len >= aent->numconds)) { cp = (unsigned char*)(word + len); for (cond = aent->numconds; --cond >= 0;) { if ((aent->conds[*--cp] & (1 << cond)) == 0) break; } if (cond < 0) { /* we have a matching condition */ int tlen = len; strncpy(tword, word, MAX_WD_LEN - 1); tword[MAX_WD_LEN - 1] = '\0'; if (aent->stripl) { tlen -= aent->stripl; } pp = (tword + tlen); if (aent->appndl) { strcpy(pp, aent->appnd); } else *pp = '\0'; if (numwords < MAX_WORDS) { wlist[numwords].word = mystrdup(tword); wlist[numwords].pallow = (aent->xpflg & XPRODUCT); numwords++; } } } } } int expand_rootword(const char* ts, int wl, const char* ap) { int i; int nh = 0; for (i = 0; i < numsfx; i++) { if (strchr(ap, (stable[i].aep)->achar)) { suf_add(ts, wl, stable[i].aep, stable[i].num); } } nh = numwords; if (nh > 1) { for (int j = 1; j < nh; j++) { if (wlist[j].pallow) { for (i = 0; i < numpfx; i++) { if (strchr(ap, (ptable[i].aep)->achar)) { if ((ptable[i].aep)->xpflg & XPRODUCT) { int nwl = strlen(wlist[j].word); pfx_add(wlist[j].word, nwl, ptable[i].aep, ptable[i].num); } } } } } } for (i = 0; i < numpfx; i++) { if (strchr(ap, (ptable[i].aep)->achar)) { pfx_add(ts, wl, ptable[i].aep, ptable[i].num); } } return 0; } /* strip strings into token based on single char delimiter * acts like strsep() but only uses a delim char and not * a delim string */ char* 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) { ptrdiff_t nc; *stringp = dp + 1; nc = dp - mp; rv = (char*)malloc(nc + 1); if (rv) { memcpy(rv, mp, nc); *(rv + nc) = '\0'; } } else { rv = (char*)malloc(n + 1); if (rv) { memcpy(rv, mp, n); *(rv + n) = '\0'; *stringp = mp + n; } } } return rv; } char* mystrdup(const char* s) { char* d = NULL; if (s) { int sl = strlen(s) + 1; d = (char*)malloc(sl); if (d) memcpy(d, s, sl); } return d; } void mychomp(char* s) { int k = strlen(s); if (k > 0) *(s + k - 1) = '\0'; if ((k > 1) && (*(s + k - 2) == '\r')) *(s + k - 2) = '\0'; } hunspell-1.7.0/src/tools/munch.h000066400000000000000000000104701337236234000165700ustar00rootroot00000000000000/* ***** 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 Németh László (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 János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* munch header file */ #define MAX_LN_LEN 200 #define MAX_WD_LEN 200 #define MAX_PREFIXES 2048 #define MAX_SUFFIXES 2048 #define MAX_ROOTS 20 #define MAX_WORDS 5000 #define ROTATE_LEN 5 #define ROTATE(v, q) \ (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q)) - 1)); #define SET_SIZE 256 #define XPRODUCT (1 << 0) /* the affix table entry */ struct affent { char* appnd; char* strip; short appndl; short stripl; char achar; char xpflg; short numconds; char conds[SET_SIZE]; }; struct affixptr { struct affent* aep; int num; }; /* the prefix and suffix table */ int numpfx; /* Number of prefixes in table */ int numsfx; /* Number of suffixes in table */ /* the prefix table */ struct affixptr ptable[MAX_PREFIXES]; /* the suffix table */ struct affixptr stable[MAX_SUFFIXES]; /* data structure to store results of lookups */ struct matches { struct hentry* hashent; /* hash table entry */ struct affent* prefix; /* Prefix used, or NULL */ struct affent* suffix; /* Suffix used, or NULL */ }; int numroots; /* number of root words found */ struct matches roots[MAX_ROOTS]; /* list of root words found */ /* hashing stuff */ struct hentry { char* word; char* affstr; struct hentry* next; int keep; }; int tablesize; struct hentry* tableptr; /* unmunch stuff */ int numwords; /* number of words found */ struct dwords { char* word; int pallow; }; struct dwords wlist[MAX_WORDS]; /* list words found */ /* the routines */ int parse_aff_file(FILE* afflst); void encodeit(struct affent* ptr, char* cs); int load_tables(FILE* wrdlst); int hash(const char*); int add_word(char*); struct hentry* lookup(const char*); void aff_chk(const char* word, int len); void pfx_chk(const char* word, int len, struct affent* ep, int num); void suf_chk(const char* word, int len, struct affent* ep, int num, struct affent* pfxent, int cpflag); void add_affix_char(struct hentry* hent, char ac); int expand_rootword(const char*, int, const char*); void pfx_add(const char* word, int len, struct affent* ep, int num); void suf_add(const char* word, int len, struct affent* ep, int num); char* mystrsep(char** stringp, const char delim); char* mystrdup(const char* s); void mychomp(char* s); hunspell-1.7.0/src/tools/unmunch.cxx000066400000000000000000000345671337236234000175230ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* Un-munch a root word list with affix tags * to recreate the original word list */ #include #include #include #include #include #include #include #include #include #include #include #include #include "unmunch.h" int main(int argc, char** argv) { int i; int al; FILE* wrdlst; FILE* afflst; char *wf, *af; char ts[MAX_LN_LEN]; (void)argc; /* first parse the command line options */ /* arg1 - munched wordlist, arg2 - affix file */ if (argv[1]) { wf = mystrdup(argv[1]); } else { fprintf(stderr, "correct syntax is:\n"); fprintf(stderr, "unmunch dic_file affix_file\n"); exit(1); } if (argv[2]) { af = mystrdup(argv[2]); } else { fprintf(stderr, "correct syntax is:\n"); fprintf(stderr, "unmunch dic_file affix_file\n"); exit(1); } /* open the affix file */ afflst = fopen(af, "r"); if (!afflst) { fprintf(stderr, "Error - could not open affix description file\n"); exit(1); } /* step one is to parse the affix file building up the internal affix data structures */ numpfx = 0; numsfx = 0; fullstrip = 0; if (parse_aff_file(afflst)) { fprintf(stderr, "Error - in affix file loading\n"); exit(1); } fclose(afflst); fprintf(stderr, "parsed in %d prefixes and %d suffixes\n", numpfx, numsfx); /* affix file is now parsed so create hash table of wordlist on the fly */ /* open the wordlist */ wrdlst = fopen(wf, "r"); if (!wrdlst) { fprintf(stderr, "Error - could not open word list file\n"); exit(1); } /* skip over the hash table size */ if (!fgets(ts, MAX_LN_LEN - 1, wrdlst)) { fclose(wrdlst); return 2; } mychomp(ts); while (fgets(ts, MAX_LN_LEN - 1, wrdlst)) { mychomp(ts); /* split each line into word and affix char strings */ char* ap = strchr(ts, '/'); if (ap) { *ap = '\0'; ap++; al = strlen(ap); } else { al = 0; ap = NULL; } int wl = strlen(ts); numwords = 0; wlist[numwords].word = mystrdup(ts); wlist[numwords].pallow = 0; numwords++; if (al) expand_rootword(ts, wl, ap); for (i = 0; i < numwords; i++) { fprintf(stdout, "%s\n", wlist[i].word); free(wlist[i].word); wlist[i].word = NULL; wlist[i].pallow = 0; } } fclose(wrdlst); return 0; } int parse_aff_file(FILE* afflst) { int i, j; int numents = 0; char achar = '\0'; short ff = 0; struct affent* ptr = NULL; struct affent* nptr = NULL; char* line = (char*)malloc(MAX_LN_LEN); while (fgets(line, MAX_LN_LEN, afflst)) { mychomp(line); char ft = ' '; fprintf(stderr, "parsing line: %s\n", line); if (strncmp(line, "FULLSTRIP", 9) == 0) fullstrip = 1; if (strncmp(line, "PFX", 3) == 0) ft = 'P'; if (strncmp(line, "SFX", 3) == 0) ft = 'S'; if (ft != ' ') { char* tp = line; char* piece; ff = 0; i = 0; while ((piece = mystrsep(&tp, ' '))) { if (*piece != '\0') { switch (i) { case 0: break; case 1: { achar = *piece; break; } case 2: { if (*piece == 'Y') ff = XPRODUCT; break; } case 3: { numents = atoi(piece); if ((numents <= 0) || ((std::numeric_limits::max() / sizeof(struct affent)) < static_cast(numents))) { fprintf(stderr, "Error: too many entries: %d\n", numents); numents = 0; } else { ptr = (struct affent*)malloc(numents * sizeof(struct affent)); ptr->achar = achar; ptr->xpflg = ff; fprintf(stderr, "parsing %c entries %d\n", achar, numents); } break; } default: break; } i++; } free(piece); } /* now parse all of the sub entries*/ nptr = ptr; for (j = 0; j < numents; j++) { if (!fgets(line, MAX_LN_LEN, afflst)) return 1; mychomp(line); tp = line; i = 0; while ((piece = mystrsep(&tp, ' '))) { if (*piece != '\0') { switch (i) { case 0: { if (nptr != ptr) { nptr->achar = ptr->achar; nptr->xpflg = ptr->xpflg; } break; } case 1: break; case 2: { nptr->strip = mystrdup(piece); nptr->stripl = strlen(nptr->strip); if (strcmp(nptr->strip, "0") == 0) { free(nptr->strip); nptr->strip = mystrdup(""); nptr->stripl = 0; } break; } case 3: { nptr->appnd = mystrdup(piece); nptr->appndl = strlen(nptr->appnd); if (strcmp(nptr->appnd, "0") == 0) { free(nptr->appnd); nptr->appnd = mystrdup(""); nptr->appndl = 0; } if (strchr(nptr->appnd, '/')) { char* addseparator = (char*)realloc(nptr->appnd, nptr->appndl + 2); if (addseparator) { nptr->appndl++; addseparator[nptr->appndl - 1] = '|'; addseparator[nptr->appndl] = '\0'; nptr->appnd = addseparator; } } break; } case 4: { encodeit(nptr, piece); } fprintf(stderr, " affix: %s %d, strip: %s %d\n", nptr->appnd, nptr->appndl, nptr->strip, nptr->stripl); // no break default: break; } i++; } free(piece); } nptr++; } if (ptr) { if (ft == 'P') { ptable[numpfx].aep = ptr; ptable[numpfx].num = numents; fprintf(stderr, "ptable %d num is %d flag %c\n", numpfx, ptable[numpfx].num, ptr->achar); numpfx++; } else if (ft == 'S') { stable[numsfx].aep = ptr; stable[numsfx].num = numents; fprintf(stderr, "stable %d num is %d flag %c\n", numsfx, stable[numsfx].num, ptr->achar); numsfx++; } ptr = NULL; } nptr = NULL; numents = 0; achar = '\0'; } } free(line); return 0; } void encodeit(struct affent* ptr, char* cs) { int nc; int neg; int grp; int n; int ec; int nm; int i, j, k; unsigned char mbr[MAX_WD_LEN]; /* now clear the conditions array */ for (i = 0; i < SET_SIZE; i++) ptr->conds[i] = (unsigned char)0; /* now parse the string to create the conds array */ nc = strlen(cs); neg = 0; /* complement indicator */ grp = 0; /* group indicator */ n = 0; /* number of conditions */ ec = 0; /* end condition indicator */ nm = 0; /* number of member in group */ i = 0; if (strcmp(cs, ".") == 0) { ptr->numconds = 0; return; } while (i < nc) { unsigned char c = *((unsigned char*)(cs + i)); if (c == '[') { grp = 1; c = 0; } if ((grp == 1) && (c == '^')) { neg = 1; c = 0; } if (c == ']') { ec = 1; c = 0; } if ((grp == 1) && (c != 0)) { *(mbr + nm) = c; nm++; c = 0; } if (c != 0) { ec = 1; } if (ec) { if (grp == 1) { if (neg == 0) { for (j = 0; j < nm; j++) { k = (unsigned int)mbr[j]; ptr->conds[k] = ptr->conds[k] | (1 << n); } } else { for (j = 0; j < SET_SIZE; j++) ptr->conds[j] = ptr->conds[j] | (1 << n); for (j = 0; j < nm; j++) { k = (unsigned int)mbr[j]; ptr->conds[k] = ptr->conds[k] & ~(1 << n); } } neg = 0; grp = 0; nm = 0; } else { /* not a group so just set the proper bit for this char */ /* but first handle special case of . inside condition */ if (c == '.') { /* wild card character so set them all */ for (j = 0; j < SET_SIZE; j++) ptr->conds[j] = ptr->conds[j] | (1 << n); } else { ptr->conds[(unsigned int)c] = ptr->conds[(unsigned int)c] | (1 << n); } } n++; ec = 0; } i++; } ptr->numconds = n; return; } /* add a prefix to word */ void pfx_add(const char* word, int len, struct affent* ep, int num) { struct affent* aent; int cond; unsigned char* cp; int i; for (aent = ep, i = num; i > 0; aent++, i--) { /* now make sure all conditions match */ if ((len + fullstrip > aent->stripl) && (len >= aent->numconds) && ((aent->stripl == 0) || (strncmp(aent->strip, word, aent->stripl) == 0))) { cp = (unsigned char*)word; for (cond = 0; cond < aent->numconds; cond++) { if ((aent->conds[*cp++] & (1 << cond)) == 0) break; } if (cond >= aent->numconds) { std::string tword; /* we have a match so add prefix */ if (aent->appndl) { tword.append(aent->appnd); } tword.append(word + aent->stripl); if (numwords < MAX_WORDS) { wlist[numwords].word = mystrdup(tword.c_str()); wlist[numwords].pallow = 0; numwords++; } } } } } /* add a suffix to a word */ void suf_add(const char* word, int len, struct affent* ep, int num) { struct affent* aent; int cond; unsigned char* cp; int i; for (aent = ep, i = num; i > 0; aent++, i--) { /* if conditions hold on root word * then strip off strip string and add suffix */ if ((len + fullstrip > aent->stripl) && (len >= aent->numconds) && ((aent->stripl == 0) || (strcmp(aent->strip, word + len - aent->stripl) == 0))) { cp = (unsigned char*)(word + len); for (cond = aent->numconds; --cond >= 0;) { if ((aent->conds[*--cp] & (1 << cond)) == 0) break; } if (cond < 0) { /* we have a matching condition */ std::string tword(word); tword.resize(len - aent->stripl); tword.append(aent->appnd); if (numwords < MAX_WORDS) { wlist[numwords].word = mystrdup(tword.c_str()); wlist[numwords].pallow = (aent->xpflg & XPRODUCT); numwords++; } } } } } int expand_rootword(const char* ts, int wl, const char* ap) { int i; int nh = 0; for (i = 0; i < numsfx; i++) { if (strchr(ap, (stable[i].aep)->achar)) { suf_add(ts, wl, stable[i].aep, stable[i].num); } } nh = numwords; if (nh > 1) { for (int j = 1; j < nh; j++) { if (wlist[j].pallow) { for (i = 0; i < numpfx; i++) { if (strchr(ap, (ptable[i].aep)->achar)) { if ((ptable[i].aep)->xpflg & XPRODUCT) { int nwl = strlen(wlist[j].word); pfx_add(wlist[j].word, nwl, ptable[i].aep, ptable[i].num); } } } } } } for (i = 0; i < numpfx; i++) { if (strchr(ap, (ptable[i].aep)->achar)) { pfx_add(ts, wl, ptable[i].aep, ptable[i].num); } } return 0; } /* strip strings into token based on single char delimiter * acts like strsep() but only uses a delim char and not * a delim string */ char* 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) { ptrdiff_t nc; *stringp = dp + 1; nc = dp - mp; rv = (char*)malloc(nc + 1); if (rv) { memcpy(rv, mp, nc); *(rv + nc) = '\0'; } } else { rv = (char*)malloc(n + 1); if (rv) { memcpy(rv, mp, n); *(rv + n) = '\0'; *stringp = mp + n; } } } return rv; } char* mystrdup(const char* s) { char* d = NULL; if (s) { int sl = strlen(s) + 1; d = (char*)malloc(sl); if (d) memcpy(d, s, sl); } return d; } void mychomp(char* s) { int k = strlen(s); if ((k > 0) && (*(s + k - 1) == '\n')) *(s + k - 1) = '\0'; if ((k > 1) && (*(s + k - 2) == '\r')) *(s + k - 2) = '\0'; } hunspell-1.7.0/src/tools/unmunch.h000066400000000000000000000063021337236234000171320ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * Copyright (C) 2002-2017 Németh László * * 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. * * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. * * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno, * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád, * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter, * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls, * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen * * 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 ***** */ /* unmunch header file */ #define MAX_LN_LEN 200 #define MAX_WD_LEN 200 #define MAX_PREFIXES 256 #define MAX_SUFFIXES 256 #define MAX_WORDS 500000 #define ROTATE_LEN 5 #define ROTATE(v, q) \ (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q)) - 1)); #define SET_SIZE 256 #define XPRODUCT (1 << 0) /* the affix table entry */ struct affent { char* appnd; char* strip; short appndl; short stripl; char achar; char xpflg; short numconds; char conds[SET_SIZE]; }; struct affixptr { struct affent* aep; int num; }; /* the prefix and suffix table */ int numpfx; /* Number of prefixes in table */ int numsfx; /* Number of suffixes in table */ /* the prefix table */ struct affixptr ptable[MAX_PREFIXES]; /* the suffix table */ struct affixptr stable[MAX_SUFFIXES]; int fullstrip; int numwords; /* number of words found */ struct dwords { char* word; int pallow; }; struct dwords wlist[MAX_WORDS]; /* list words found */ /* the routines */ int parse_aff_file(FILE* afflst); void encodeit(struct affent* ptr, char* cs); int expand_rootword(const char*, int, const char*); void pfx_add(const char* word, int len, struct affent* ep, int num); void suf_add(const char* word, int len, struct affent* ep, int num); char* mystrsep(char** stringp, const char delim); char* mystrdup(const char* s); void mychomp(char* s); hunspell-1.7.0/src/tools/wordforms000077500000000000000000000024671337236234000172640ustar00rootroot00000000000000#!/bin/sh case $# in 0|1|2) echo "Usage: wordforms [-s | -p] dictionary.aff dictionary.dic word -s: print only suffixed forms -p: print only prefixed forms "; exit 1;; esac fx=0 case $1 in -s) fx=1; shift;; -p) fx=2; shift;; esac test -h /tmp/wordforms.aff && rm /tmp/wordforms.aff ln -s $PWD/$1 /tmp/wordforms.aff # prepared dic only with the query word echo 1 >/tmp/wordforms.dic grep "^$3/" $2 >>/tmp/wordforms.dic echo $3 | awk -v "fx=$fx" ' fx!=2 && FILENAME!="-" && /^SFX/ && NF > 4{split($4,a,"/");clen=($3=="0") ? 0 : length($3);sfx[a[1],clen]=a[1];sfxc[a[1],clen]=clen;next} fx!=1 && FILENAME!="-" && /^PFX/ && NF > 4{split($4,a,"/");clen=($3=="0") ? 0 : length($3);pfx[a[1],clen]=a[1];pfxc[a[1],clen]=clen;next} FILENAME=="-"{ wlen=length($1) if (fx==0 || fx==2) { for (j in pfx) {if (wlen<=pfxc[j]) continue; print (pfx[j]=="0" ? "" : pfx[j]) substr($1, pfxc[j]+1)} } if (fx==0 || fx==1) { for(i in sfx){clen=sfxc[i];if (wlen<=clen) continue; print substr($1, 1, wlen-clen) (sfx[i]=="0" ? "": sfx[i]) } } if (fx==0) { for (j in pfx) {if (wlen<=pfxc[j]) continue; for(i in sfx){clen=sfxc[i];if (wlen<=clen || wlen <= (clen + pfxc[j]))continue; print (pfx[j]=="0" ? "" : pfx[j]) substr($1, pfxc[j]+1, wlen-clen-pfxc[j]) (sfx[i]=="0" ? "": sfx[i]) }} } } ' /tmp/wordforms.aff - | hunspell -d /tmp/wordforms -G -l hunspell-1.7.0/src/tools/wordlist2hunspell000066400000000000000000000031601337236234000207320ustar00rootroot00000000000000#!/bin/sh # # (C) 2008 Caolán McNamara # # This program 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 2 of the License, or # (at your option) any later version. # # This program 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 this program. If not, see . # This creates a LANG_TERRITORY .aff & .dic from a wordlist. # It is only a simple wordlist spellchecking dictionary output, no # knowledge of language rules can be extrapolated to shrink the # wordlist or provide .aff rules for extending wordstems if [ $# -lt 2 ]; then echo "Usage: wordlist2hunspell wordlist_file locale" echo "e.g. wordlist2hunspell breton.words br_FR to create br_FR.dic and br_FR.aff in cwd" exit 1 fi export LANG=$2.utf8 echo "# A basic .aff for a raw wordlist, created through wordlist2hunspell" > $2.aff echo SET UTF-8 >> $2.aff #see https://bugzilla.redhat.com/show_bug.cgi?id=462184 for the "C" hacks echo TRY `sed 's/./&\n/g' $1 | sed '/^$/d' | LC_ALL=C sort -n | LC_ALL=C uniq -c | LC_ALL=C sort -rn | tr -s ' ' | cut -d ' ' -f 3 | tr -d '\n'` >> $2.aff cat $1 | sed '/^$/d' | wc -l > $2.dic LC_ALL=C sort $1 | sed '/^$/d' >> $2.dic echo Basic $2.dic and $2.aff created hunspell-1.7.0/tests/000077500000000000000000000000001337236234000145165ustar00rootroot00000000000000hunspell-1.7.0/tests/.gitattributes000066400000000000000000000001151337236234000174060ustar00rootroot00000000000000*.sug text eol=lf *.good text eol=lf *.wrong text eol=lf *.morph text eol=lf hunspell-1.7.0/tests/.gitignore000066400000000000000000000000271337236234000165050ustar00rootroot00000000000000testSubDir *.log *.trs hunspell-1.7.0/tests/1463589.aff000066400000000000000000000001721337236234000160370ustar00rootroot00000000000000# capitalized ngram suggestion test data for # Sf.net Bug ID 1463589, reported by Frederik Fouvry. MAXNGRAMSUGS 1 LANG de hunspell-1.7.0/tests/1463589.dic000066400000000000000000000000161337236234000160370ustar00rootroot000000000000001 Khlschrank hunspell-1.7.0/tests/1463589.sug000066400000000000000000000001011337236234000160710ustar00rootroot00000000000000Kühlschrank Kühlschrank Kühlschrank Kühlschrank Kühlschrank hunspell-1.7.0/tests/1463589.wrong000066400000000000000000000000771337236234000164430ustar00rootroot00000000000000kuhlschrank kuehlschrank kühlschrank Kuhlschrank Kuehlschrank hunspell-1.7.0/tests/1463589_utf.aff000066400000000000000000000002261337236234000167150ustar00rootroot00000000000000# capitalized ngram suggestion test data (Unicode version) for # Sf.net Bug ID 1463589, reported by Frederik Fouvry. SET UTF-8 MAXNGRAMSUGS 1 LANG de hunspell-1.7.0/tests/1463589_utf.dic000066400000000000000000000000171337236234000167160ustar00rootroot000000000000001 Kühlschrank hunspell-1.7.0/tests/1463589_utf.sug000066400000000000000000000001011337236234000167470ustar00rootroot00000000000000Kühlschrank Kühlschrank Kühlschrank Kühlschrank Kühlschrank hunspell-1.7.0/tests/1463589_utf.wrong000066400000000000000000000000771337236234000173210ustar00rootroot00000000000000kuhlschrank kuehlschrank kühlschrank Kuhlschrank Kuehlschrank hunspell-1.7.0/tests/1592880.aff000066400000000000000000000004271337236234000160370ustar00rootroot00000000000000# fix homonym handling for German dictionary project, # reported by Björn Jacke (sf.net Bug ID 1592880). SET ISO8859-1 SFX N Y 1 SFX N 0 n . SFX S Y 1 SFX S 0 s . SFX P Y 1 SFX P 0 en . SFX Q Y 2 SFX Q 0 e . SFX Q 0 en . COMPOUNDEND z COMPOUNDPERMITFLAG c ONLYINCOMPOUND o hunspell-1.7.0/tests/1592880.dic000066400000000000000000000000251337236234000160340ustar00rootroot000000000000003 weg/Qoz weg/P wege hunspell-1.7.0/tests/1592880.good000066400000000000000000000000171337236234000162260ustar00rootroot00000000000000weg wege wegen hunspell-1.7.0/tests/1695964.aff000066400000000000000000000003201337236234000160360ustar00rootroot00000000000000# fix NEEDAFFIX homonym suggestion. # Sf.net Bug ID 1695964, reported by Björn Jacke. TRY esianrtolcdugmphbyfvkwESIANRTOLCDUGMPHBYFVKW MAXNGRAMSUGS 0 NEEDAFFIX h SFX S Y 1 SFX S 0 s . SFX e Y 1 SFX e 0 e . hunspell-1.7.0/tests/1695964.dic000066400000000000000000000000211337236234000160370ustar00rootroot000000000000002 Mull/he Mull/S hunspell-1.7.0/tests/1695964.sug000066400000000000000000000000211337236234000160760ustar00rootroot00000000000000Mull Mulle Mulls hunspell-1.7.0/tests/1695964.wrong000066400000000000000000000000211337236234000164340ustar00rootroot00000000000000Mall Malle Malls hunspell-1.7.0/tests/1706659.aff000066400000000000000000000003111337236234000160300ustar00rootroot00000000000000# test COMPOUNDRULE bug reported by Björn Jacke SET ISO8859-1 TRY esijanrtolcdugmphbyfvkwqxz SFX A Y 5 SFX A 0 e . SFX A 0 er . SFX A 0 en . SFX A 0 em . SFX A 0 es . COMPOUNDRULE 1 COMPOUNDRULE vw hunspell-1.7.0/tests/1706659.dic000066400000000000000000000000361337236234000160370ustar00rootroot000000000000003 arbeits/v scheu/Aw farbig/A hunspell-1.7.0/tests/1706659.wrong000066400000000000000000000000551337236234000164350ustar00rootroot00000000000000arbeitsfarbig arbeitsfarbige arbeitsfarbiger hunspell-1.7.0/tests/1975530.aff000066400000000000000000000001021337236234000160220ustar00rootroot00000000000000SET UTF-8 IGNORE ٌٍَُِّْـ PFX x N 1 PFX x أ ت أ[^ي] hunspell-1.7.0/tests/1975530.dic000066400000000000000000000000261337236234000160320ustar00rootroot000000000000002 أرى/x أيار/x hunspell-1.7.0/tests/1975530.good000066400000000000000000000000271337236234000162240ustar00rootroot00000000000000أرى أيار ترى hunspell-1.7.0/tests/1975530.wrong000066400000000000000000000000111337236234000164210ustar00rootroot00000000000000تيار hunspell-1.7.0/tests/2970240.aff000066400000000000000000000001401337236234000160160ustar00rootroot00000000000000# test words with three parts CHECKCOMPOUNDPATTERN 1 CHECKCOMPOUNDPATTERN le fi COMPOUNDFLAG c hunspell-1.7.0/tests/2970240.dic000066400000000000000000000000321337236234000160210ustar00rootroot000000000000003 first/c middle/c last/c hunspell-1.7.0/tests/2970240.good000066400000000000000000000000201337236234000162070ustar00rootroot00000000000000firstmiddlelast hunspell-1.7.0/tests/2970240.wrong000066400000000000000000000000201337236234000164130ustar00rootroot00000000000000lastmiddlefirst hunspell-1.7.0/tests/2970242.aff000066400000000000000000000001021337236234000160160ustar00rootroot00000000000000CHECKCOMPOUNDPATTERN 1 CHECKCOMPOUNDPATTERN /a /b COMPOUNDFLAG c hunspell-1.7.0/tests/2970242.dic000066400000000000000000000000261337236234000160260ustar00rootroot000000000000003 foo/ac bar/c baz/bc hunspell-1.7.0/tests/2970242.good000066400000000000000000000000431337236234000162160ustar00rootroot00000000000000foobar barfoo bazfoo barbaz bazbar hunspell-1.7.0/tests/2970242.wrong000066400000000000000000000000071337236234000164220ustar00rootroot00000000000000foobaz hunspell-1.7.0/tests/2999225.aff000066400000000000000000000000771337236234000160450ustar00rootroot00000000000000COMPOUNDRULE 1 COMPOUNDRULE ab COMPOUNDBEGIN A COMPOUNDEND B hunspell-1.7.0/tests/2999225.dic000066400000000000000000000000251337236234000160410ustar00rootroot000000000000003 foo/aA bar/b baz/B hunspell-1.7.0/tests/2999225.good000066400000000000000000000000161337236234000162320ustar00rootroot00000000000000foobar foobaz hunspell-1.7.0/tests/IJ.aff000066400000000000000000000001571337236234000155010ustar00rootroot00000000000000# check bad capitalisation of Dutch letter IJ. TRY i FORBIDDENWORD * PFX i N 1 PFX i ij IJ ij REP 1 REP ij IJ hunspell-1.7.0/tests/IJ.dic000066400000000000000000000000161337236234000154760ustar00rootroot000000000000001 ijs/i Ijs/* hunspell-1.7.0/tests/IJ.good000066400000000000000000000000101337236234000156610ustar00rootroot00000000000000ijs IJs hunspell-1.7.0/tests/IJ.sug000066400000000000000000000000111337236234000155300ustar00rootroot00000000000000IJs, ijs hunspell-1.7.0/tests/IJ.wrong000066400000000000000000000000041337236234000160700ustar00rootroot00000000000000Ijs hunspell-1.7.0/tests/Makefile.am000066400000000000000000000263341337236234000165620ustar00rootroot00000000000000## Process this file with automake to create Makefile.in SUBDIRS = suggestiontest TEST_EXTENSIONS = .dic AM_TESTS_ENVIRONMENT = export HUNSPELL=$(top_builddir)/src/tools/hunspell; \ export ANALYZE=$(top_builddir)/src/tools/analyze; \ export LIBTOOL=$(top_builddir)/libtool; DIC_LOG_COMPILER = $(top_srcdir)/tests/test.sh TESTS = \ affixes.dic \ condition.dic \ condition_utf.dic \ base.dic \ base_utf.dic \ allcaps.dic \ allcaps_utf.dic \ allcaps2.dic \ allcaps3.dic \ keepcase.dic \ dotless_i.dic \ i58202.dic \ map.dic \ rep.dic \ sug.dic \ sug2.dic \ wordpair.dic \ sugutf.dic \ phone.dic \ ph.dic \ ph2.dic \ flag.dic \ flaglong.dic \ flagnum.dic \ flagutf8.dic \ slash.dic \ forbiddenword.dic \ nosuggest.dic \ alias.dic \ alias2.dic \ alias3.dic \ breakdefault.dic \ break.dic \ needaffix.dic \ needaffix2.dic \ needaffix3.dic \ needaffix4.dic \ needaffix5.dic \ circumfix.dic \ fogemorpheme.dic \ onlyincompound.dic \ complexprefixes.dic \ complexprefixes2.dic \ complexprefixesutf.dic \ conditionalprefix.dic \ zeroaffix.dic \ utf8.dic \ utf8_bom.dic \ utf8_bom2.dic \ utf8_nonbmp.test \ compoundflag.dic \ compoundrule.dic \ compoundrule2.dic \ compoundrule3.dic \ compoundrule4.dic \ compoundrule5.dic \ compoundrule6.dic \ compoundrule7.dic \ compoundrule8.dic \ compoundaffix.dic \ compoundaffix2.dic \ compoundaffix3.dic \ compoundforbid.dic \ checkcompounddup.dic \ checkcompoundtriple.dic \ simplifiedtriple.dic \ checkcompoundrep.dic \ checkcompoundcase2.dic \ checkcompoundcaseutf.dic \ checkcompoundpattern.dic \ checkcompoundpattern2.dic \ checkcompoundpattern3.dic \ checkcompoundpattern4.dic \ utfcompound.dic \ checksharps.dic \ checksharpsutf.dic \ germancompounding.dic \ germancompoundingold.dic \ i35725.dic \ i53643.dic \ i54633.dic \ i54980.dic \ maputf.dic \ reputf.dic \ ignore.dic \ ignoreutf.dic \ 1592880.dic \ 1695964.dic \ 1463589.dic \ 1463589_utf.dic \ IJ.dic \ i68568.dic \ i68568utf.dic \ 1706659.dic \ digits_in_words.dic \ colons_in_words.dic \ ngram_utf_fix.dic \ morph.dic \ 1975530.dic \ fullstrip.dic \ iconv.dic \ iconv2.dic \ oconv.dic \ oconv2.dic \ encoding.dic \ korean.dic \ opentaal_forbiddenword1.dic \ opentaal_forbiddenword2.dic \ opentaal_keepcase.dic \ arabic.dic \ 2970240.dic \ 2970242.dic \ breakoff.dic \ opentaal_cpdpat.dic \ opentaal_cpdpat2.dic \ 2999225.dic \ onlyincompound2.dic \ forceucase.dic \ nepali.dic \ hu.dic \ warn.dic \ timelimit.dic \ ignoresug.dic clean-local: -rm -rf testSubDir EXTRA_DIST = \ test.sh \ affixes.aff \ affixes.dic \ affixes.good \ condition.aff \ condition.dic \ condition.good \ condition.wrong \ condition_utf.aff \ condition_utf.dic \ condition_utf.good \ condition_utf.wrong \ base.aff \ base.dic \ base.good \ base.sug \ base.wrong \ base_utf.aff \ base_utf.dic \ base_utf.good \ base_utf.sug \ base_utf.wrong \ allcaps.aff \ allcaps.dic \ allcaps.good \ allcaps.sug \ allcaps.wrong \ allcaps2.aff \ allcaps2.dic \ allcaps2.good \ allcaps2.sug \ allcaps2.wrong \ allcaps3.aff \ allcaps3.dic \ allcaps3.good \ allcaps3.wrong \ allcaps_utf.aff \ allcaps_utf.dic \ allcaps_utf.good \ allcaps_utf.sug \ allcaps_utf.wrong \ keepcase.aff \ keepcase.dic \ keepcase.good \ keepcase.sug \ keepcase.wrong \ dotless_i.aff \ dotless_i.dic \ dotless_i.good \ dotless_i.wrong \ map.aff \ map.dic \ map.sug \ map.wrong \ rep.aff \ rep.dic \ rep.sug \ rep.wrong \ sug.aff \ sug.dic \ sug.sug \ sug.wrong \ sug2.aff \ sug2.dic \ sug2.sug \ sug2.wrong \ wordpair.aff \ wordpair.dic \ wordpair.wrong \ sugutf.aff \ sugutf.dic \ sugutf.sug \ sugutf.wrong \ phone.aff \ phone.dic \ phone.sug \ phone.wrong \ ph.aff \ ph.dic \ ph.sug \ ph.wrong \ ph2.aff \ ph2.dic \ ph2.sug \ ph2.wrong \ alias.aff \ alias.dic \ alias.good \ alias2.aff \ alias2.dic \ alias2.good \ alias2.morph \ alias3.aff \ alias3.dic \ alias3.good \ alias3.morph \ break.aff \ break.dic \ break.good \ break.wrong \ breakdefault.aff \ breakdefault.dic \ breakdefault.good \ breakdefault.sug \ breakdefault.wrong \ circumfix.aff \ circumfix.dic \ circumfix.good \ circumfix.morph \ circumfix.wrong \ fogemorpheme.aff \ fogemorpheme.dic \ fogemorpheme.good \ fogemorpheme.wrong \ onlyincompound.aff \ onlyincompound.dic \ onlyincompound.good \ onlyincompound.sug \ onlyincompound.wrong \ forbiddenword.aff \ forbiddenword.dic \ forbiddenword.good \ forbiddenword.wrong \ nosuggest.aff \ nosuggest.dic \ nosuggest.good \ nosuggest.sug \ nosuggest.wrong \ germancompounding.aff \ germancompounding.dic \ germancompounding.good \ germancompounding.wrong \ germancompoundingold.aff \ germancompoundingold.dic \ germancompoundingold.good \ germancompoundingold.wrong \ needaffix2.aff \ needaffix2.dic \ needaffix2.good \ needaffix2.morph \ needaffix3.aff \ needaffix3.dic \ needaffix3.good \ needaffix3.wrong \ needaffix4.aff \ needaffix4.dic \ needaffix4.good \ needaffix5.aff \ needaffix5.dic \ needaffix5.good \ needaffix5.wrong \ needaffix.aff \ needaffix.dic \ needaffix.good \ needaffix.wrong \ zeroaffix.aff \ zeroaffix.dic \ zeroaffix.good \ zeroaffix.morph \ utf8.aff \ utf8.dic \ utf8.good \ utf8_bom.aff \ utf8_bom.dic \ utf8_bom.good \ utf8_bom2.aff \ utf8_bom2.dic \ utf8_bom2.good \ utf8_nonbmp.aff \ utf8_nonbmp.dic \ utf8_nonbmp.good \ utf8_nonbmp.sug \ utf8_nonbmp.wrong \ utfcompound.aff \ utfcompound.dic \ utfcompound.good \ utfcompound.wrong \ compoundflag.aff \ compoundflag.dic \ compoundflag.good \ compoundflag.wrong \ compoundrule.aff \ compoundrule.dic \ compoundrule.good \ compoundrule.wrong \ compoundrule2.aff \ compoundrule2.dic \ compoundrule2.good \ compoundrule2.wrong \ compoundrule3.aff \ compoundrule3.dic \ compoundrule3.good \ compoundrule3.wrong \ compoundrule4.aff \ compoundrule4.dic \ compoundrule4.good \ compoundrule4.wrong \ compoundrule5.aff \ compoundrule5.dic \ compoundrule5.good \ compoundrule5.morph \ compoundrule5.wrong \ compoundrule6.aff \ compoundrule6.dic \ compoundrule6.good \ compoundrule6.wrong \ compoundrule7.aff \ compoundrule7.dic \ compoundrule7.good \ compoundrule7.wrong \ compoundrule8.aff \ compoundrule8.dic \ compoundrule8.good \ compoundrule8.wrong \ compoundaffix.aff \ compoundaffix.dic \ compoundaffix.good \ compoundaffix.wrong \ compoundaffix2.aff \ compoundaffix2.dic \ compoundaffix2.good \ compoundaffix3.aff \ compoundaffix3.dic \ compoundaffix3.good \ compoundaffix3.wrong \ compoundforbid.aff \ compoundforbid.dic \ compoundforbid.good \ compoundforbid.wrong \ checkcompounddup.aff \ checkcompounddup.dic \ checkcompounddup.good \ checkcompounddup.wrong \ checkcompoundcase.aff \ checkcompoundcase.dic \ checkcompoundcase.good \ checkcompoundcase.wrong \ checkcompoundcase2.aff \ checkcompoundcase2.dic \ checkcompoundcase2.good \ checkcompoundcase2.wrong \ checkcompoundcaseutf.aff \ checkcompoundcaseutf.dic \ checkcompoundcaseutf.good \ checkcompoundcaseutf.wrong \ checkcompoundrep.aff \ checkcompoundrep.dic \ checkcompoundrep.good \ checkcompoundrep.wrong \ checkcompoundtriple.aff \ checkcompoundtriple.dic \ checkcompoundtriple.good \ checkcompoundtriple.wrong \ simplifiedtriple.aff \ simplifiedtriple.dic \ simplifiedtriple.good \ simplifiedtriple.wrong \ checkcompoundpattern.aff \ checkcompoundpattern.dic \ checkcompoundpattern.good \ checkcompoundpattern.wrong \ checkcompoundpattern2.aff \ checkcompoundpattern2.dic \ checkcompoundpattern2.good \ checkcompoundpattern2.wrong \ checkcompoundpattern3.aff \ checkcompoundpattern3.dic \ checkcompoundpattern3.good \ checkcompoundpattern3.wrong \ checkcompoundpattern4.aff \ checkcompoundpattern4.dic \ checkcompoundpattern4.good \ checkcompoundpattern4.wrong \ checksharps.aff \ checksharps.dic \ checksharps.good \ checksharps.sug \ checksharps.wrong \ checksharpsutf.aff \ checksharpsutf.dic \ checksharpsutf.good \ checksharpsutf.sug \ checksharpsutf.wrong \ conditionalprefix.aff \ conditionalprefix.dic \ conditionalprefix.good \ conditionalprefix.morph \ conditionalprefix.wrong \ flaglong.aff \ flaglong.dic \ flaglong.good \ flagnum.aff \ flagnum.dic \ flagnum.good \ flag.aff \ flag.dic \ flag.good \ flagutf8.aff \ flagutf8.dic \ flagutf8.good \ complexprefixes.aff \ complexprefixes.dic \ complexprefixes.good \ complexprefixes.wrong \ complexprefixes2.aff \ complexprefixes2.dic \ complexprefixes2.good \ complexprefixesutf.aff \ complexprefixesutf.dic \ complexprefixesutf.good \ complexprefixesutf.wrong \ i35725.aff \ i35725.dic \ i35725.good \ i35725.sug \ i35725.wrong \ i53643.aff \ i53643.dic \ i53643.good \ i53643.wrong \ i54633.aff \ i54633.dic \ i54633.good \ i54633.sug \ i54633.wrong \ i54980.aff \ i54980.dic \ i54980.good \ i58202.aff \ i58202.dic \ i58202.good \ i58202.sug \ i58202.wrong \ maputf.aff \ maputf.dic \ maputf.sug \ maputf.wrong \ reputf.aff \ reputf.dic \ reputf.sug \ reputf.wrong \ slash.aff \ slash.dic \ slash.good \ ignore.aff \ ignore.dic \ ignore.good \ ignoreutf.aff \ ignoreutf.dic \ ignoreutf.good \ 1592880.aff \ 1592880.dic \ 1592880.good \ 1695964.aff \ 1695964.dic \ 1695964.sug \ 1695964.wrong \ 1463589.aff \ 1463589.dic \ 1463589.sug \ 1463589.wrong \ 1463589_utf.aff \ 1463589_utf.dic \ 1463589_utf.sug \ 1463589_utf.wrong \ IJ.aff \ IJ.dic \ IJ.good \ IJ.sug \ IJ.wrong \ i68568.aff \ i68568.dic \ i68568.wrong \ i68568utf.aff \ i68568utf.dic \ i68568utf.wrong \ 1706659.aff \ 1706659.dic \ 1706659.wrong \ digits_in_words.aff \ digits_in_words.dic \ digits_in_words.wrong \ colons_in_words.aff \ colons_in_words.dic \ ngram_utf_fix.aff \ ngram_utf_fix.dic \ ngram_utf_fix.good \ ngram_utf_fix.sug \ ngram_utf_fix.wrong \ morph.aff \ morph.dic \ morph.good \ morph.morph \ 1975530.aff \ 1975530.dic \ 1975530.good \ 1975530.wrong \ fullstrip.aff \ fullstrip.dic \ fullstrip.good \ iconv.aff \ iconv.dic \ iconv.good \ iconv2.aff \ iconv2.dic \ iconv2.good \ oconv.aff \ oconv.dic \ oconv.good \ oconv.sug \ oconv.wrong \ oconv2.aff \ oconv2.dic \ oconv2.good \ oconv2.morph \ oconv2.root \ oconv2.test \ encoding.aff \ encoding.dic \ encoding.good \ opentaal_forbiddenword1.aff \ opentaal_forbiddenword1.dic \ opentaal_forbiddenword1.good \ opentaal_forbiddenword1.sug \ opentaal_forbiddenword1.wrong \ opentaal_forbiddenword2.aff \ opentaal_forbiddenword2.dic \ opentaal_forbiddenword2.good \ opentaal_forbiddenword2.sug \ opentaal_forbiddenword2.wrong \ opentaal_forbiddenword2.aff \ opentaal_forbiddenword2.dic \ opentaal_forbiddenword2.good \ opentaal_forbiddenword2.sug \ opentaal_forbiddenword2.wrong \ opentaal_keepcase.aff \ opentaal_keepcase.dic \ opentaal_keepcase.good \ opentaal_keepcase.sug \ opentaal_keepcase.wrong \ arabic.aff \ arabic.dic \ arabic.wrong \ 2970240.aff \ 2970240.dic \ 2970240.good \ 2970240.wrong \ 2970242.aff \ 2970242.dic \ 2970242.good \ 2970242.wrong \ breakoff.aff \ breakoff.dic \ breakoff.good \ breakoff.wrong \ opentaal_cpdpat.aff \ opentaal_cpdpat.dic \ opentaal_cpdpat.good \ opentaal_cpdpat.wrong \ opentaal_cpdpat2.aff \ opentaal_cpdpat2.dic \ opentaal_cpdpat2.good \ opentaal_cpdpat2.wrong \ 2999225.aff \ 2999225.dic \ 2999225.good \ korean.aff \ korean.dic \ korean.good \ korean.wrong \ onlyincompound2.aff \ onlyincompound2.dic \ onlyincompound2.good \ onlyincompound2.wrong \ forceucase.aff \ forceucase.dic \ forceucase.good \ forceucase.sug \ forceucase.wrong \ nepali.aff \ nepali.dic \ nepali.good \ hu.aff \ hu.dic \ hu.good \ warn.aff \ warn.dic \ warn.good \ timelimit.aff \ timelimit.dic \ timelimit.good \ timelimit.wrong \ ignoresug.aff \ ignoresug.dic \ ignoresug.good \ ignoresug.morph \ \ utf8_nonbmp.test hunspell-1.7.0/tests/affixes.aff000066400000000000000000000001711337236234000166200ustar00rootroot00000000000000# simple example for affix compression (see Hunspell(4)) PFX A Y 1 PFX A 0 re . SFX B Y 2 SFX B 0 ed [^y] SFX B y ied y hunspell-1.7.0/tests/affixes.dic000066400000000000000000000000261337236234000166220ustar00rootroot000000000000003 hello try/B work/AB hunspell-1.7.0/tests/affixes.good000066400000000000000000000000541337236234000170140ustar00rootroot00000000000000hello try tried work worked rework reworked hunspell-1.7.0/tests/alias.aff000066400000000000000000000001631337236234000162650ustar00rootroot00000000000000# aliases for flag vectors (AF) # AB -> 1 # A -> 2 AF 2 AF AB AF A SFX A Y 1 SFX A 0 x . SFX B Y 1 SFX B 0 y/2 . hunspell-1.7.0/tests/alias.dic000066400000000000000000000000101337236234000162570ustar00rootroot000000000000001 foo/1 hunspell-1.7.0/tests/alias.good000066400000000000000000000000241337236234000164550ustar00rootroot00000000000000foo foox fooy fooyx hunspell-1.7.0/tests/alias2.aff000066400000000000000000000003261337236234000163500ustar00rootroot00000000000000# aliases for flag vectors (AF) and morphological descriptions (AM) # AB -> 1 # A -> 2 AF 2 AF AB AF A AM 3 AM is:affix_x AM ds:affix_y AM po:noun xx:other_data SFX A Y 1 SFX A 0 x . 1 SFX B Y 1 SFX B 0 y/2 . 2 hunspell-1.7.0/tests/alias2.dic000066400000000000000000000000121337236234000163430ustar00rootroot000000000000001 foo/1 3 hunspell-1.7.0/tests/alias2.good000066400000000000000000000000241337236234000165370ustar00rootroot00000000000000foo foox fooy fooyx hunspell-1.7.0/tests/alias2.morph000066400000000000000000000005061337236234000167410ustar00rootroot00000000000000> foo analyze(foo) = st:foo po:noun xx:other_data stem(foo) = foo > foox analyze(foox) = st:foo po:noun xx:other_data is:affix_x stem(foox) = foo > fooy analyze(fooy) = st:foo po:noun xx:other_data ds:affix_y stem(fooy) = fooy > fooyx analyze(fooyx) = st:foo po:noun xx:other_data ds:affix_y is:affix_x stem(fooyx) = fooy hunspell-1.7.0/tests/alias3.aff000066400000000000000000000003201337236234000163430ustar00rootroot00000000000000# morph. aliases with complex prefixes COMPLEXPREFIXES WORDCHARS _ AM 4 AM affix_1/ AM affix_2/ AM /suffix_1 AM [stem_1] PFX A Y 1 PFX A 0 tek . 1 PFX B Y 1 PFX B 0 met/A . 2 SFX C Y 1 SFX C 0 _test_ . 3 hunspell-1.7.0/tests/alias3.dic000066400000000000000000000000141337236234000163460ustar00rootroot000000000000001 ouro/BC 4 hunspell-1.7.0/tests/alias3.good000066400000000000000000000000431337236234000165410ustar00rootroot00000000000000ouro metouro tekmetouro ouro_test_ hunspell-1.7.0/tests/alias3.morph000066400000000000000000000003451337236234000167430ustar00rootroot00000000000000> ouro analyze(ouro) = [stem_1] ouro:ts > metouro analyze(metouro) = affix_2/ ouro:ts [stem_1] > tekmetouro analyze(tekmetouro) = affix_1/ affix_2/ ouro:ts [stem_1] > ouro_test_ analyze(ouro_test_) = [stem_1] ouro:ts /suffix_1 hunspell-1.7.0/tests/allcaps.aff000066400000000000000000000001741337236234000166150ustar00rootroot00000000000000# check uppercase forms of allcaps word + affix and words with mixed casing WORDCHARS '. SFX S N 1 SFX S 0 's . hunspell-1.7.0/tests/allcaps.dic000066400000000000000000000000321337236234000166110ustar00rootroot000000000000002 OpenOffice.org UNICEF/S hunspell-1.7.0/tests/allcaps.good000066400000000000000000000000601337236234000170030ustar00rootroot00000000000000OpenOffice.org OPENOFFICE.ORG UNICEF's UNICEF'S hunspell-1.7.0/tests/allcaps.sug000066400000000000000000000000371337236234000166550ustar00rootroot00000000000000OpenOffice.org UNICEF UNICEF's hunspell-1.7.0/tests/allcaps.wrong000066400000000000000000000000371337236234000172130ustar00rootroot00000000000000Openoffice.org Unicef Unicef's hunspell-1.7.0/tests/allcaps2.aff000066400000000000000000000001771337236234000167020ustar00rootroot00000000000000# forbidden all caps words are case sensitive # iPod -> ipodos ("iPodic" in Hungarian) FORBIDDENWORD * SFX s N 1 SFX s 0 os . hunspell-1.7.0/tests/allcaps2.dic000066400000000000000000000000311337236234000166720ustar00rootroot000000000000003 iPod/s iPodos/* ipodos hunspell-1.7.0/tests/allcaps2.good000066400000000000000000000000301337236234000170620ustar00rootroot00000000000000iPod IPOD ipodos IPODOS hunspell-1.7.0/tests/allcaps2.sug000066400000000000000000000000141337236234000167320ustar00rootroot00000000000000iPod ipodos hunspell-1.7.0/tests/allcaps2.wrong000066400000000000000000000000141337236234000172700ustar00rootroot00000000000000ipod iPodos hunspell-1.7.0/tests/allcaps3.aff000066400000000000000000000001171337236234000166750ustar00rootroot00000000000000# homonym support WORDCHARS ' SFX s N 1 SFX s 0 s . SFX S N 1 SFX S 0 's . hunspell-1.7.0/tests/allcaps3.dic000066400000000000000000000000551337236234000167010ustar00rootroot000000000000004 UNESCO/S Unesco/S Nasa/S NASA/S ACTS act/s hunspell-1.7.0/tests/allcaps3.good000066400000000000000000000001271337236234000170720ustar00rootroot00000000000000UNESCO Unesco UNESCO's Unesco's UNESCO'S NASA Nasa NASA's Nasa's NASA'S ACTS acts Acts hunspell-1.7.0/tests/allcaps3.wrong000066400000000000000000000000341337236234000172730ustar00rootroot00000000000000unesco unesco's nasa nasa's hunspell-1.7.0/tests/allcaps_utf.aff000066400000000000000000000000601337236234000174650ustar00rootroot00000000000000SET UTF-8 WORDCHARS '. SFX S N 1 SFX S 0 's . hunspell-1.7.0/tests/allcaps_utf.dic000066400000000000000000000000321337236234000174670ustar00rootroot000000000000002 OpenOffice.org UNICEF/S hunspell-1.7.0/tests/allcaps_utf.good000066400000000000000000000000601337236234000176610ustar00rootroot00000000000000OpenOffice.org OPENOFFICE.ORG UNICEF's UNICEF'S hunspell-1.7.0/tests/allcaps_utf.sug000066400000000000000000000000371337236234000175330ustar00rootroot00000000000000OpenOffice.org UNICEF UNICEF's hunspell-1.7.0/tests/allcaps_utf.wrong000066400000000000000000000000371337236234000200710ustar00rootroot00000000000000Openoffice.org Unicef Unicef's hunspell-1.7.0/tests/arabic.aff000066400000000000000000000001111337236234000164060ustar00rootroot00000000000000SET UTF-8 TRY أ IGNORE ٌٍَُِّْ PFX Aa Y 1 PFX Aa 0 0/X0 أ[^ي] hunspell-1.7.0/tests/arabic.dic000066400000000000000000000000051337236234000164130ustar00rootroot000000000000001 ب hunspell-1.7.0/tests/arabic.wrong000066400000000000000000000000031337236234000170060ustar00rootroot00000000000000ـ hunspell-1.7.0/tests/base.aff000066400000000000000000000053051337236234000161110ustar00rootroot00000000000000# OpenOffice.org's en_US.aff file SET ISO8859-1 TRY esianrtolcdugmphbyfvkwz' WORDCHARS .' PFX A Y 1 PFX A 0 re . PFX I Y 1 PFX I 0 in . PFX U Y 1 PFX U 0 un . PFX C Y 1 PFX C 0 de . PFX E Y 1 PFX E 0 dis . PFX F Y 1 PFX F 0 con . PFX K Y 1 PFX K 0 pro . SFX V N 2 SFX V e ive e SFX V 0 ive [^e] SFX N Y 3 SFX N e ion e SFX N y ication y SFX N 0 en [^ey] SFX X Y 3 SFX X e ions e SFX X y ications y SFX X 0 ens [^ey] SFX H N 2 SFX H y ieth y SFX H 0 th [^y] SFX Y Y 1 SFX Y 0 ly . SFX G Y 2 SFX G e ing e SFX G 0 ing [^e] SFX J Y 2 SFX J e ings e SFX J 0 ings [^e] SFX D Y 4 SFX D 0 d e SFX D y ied [^aeiou]y SFX D 0 ed [^ey] SFX D 0 ed [aeiou]y SFX T N 4 SFX T 0 st e SFX T y iest [^aeiou]y SFX T 0 est [aeiou]y SFX T 0 est [^ey] SFX R Y 4 SFX R 0 r e SFX R y ier [^aeiou]y SFX R 0 er [aeiou]y SFX R 0 er [^ey] SFX Z Y 4 SFX Z 0 rs e SFX Z y iers [^aeiou]y SFX Z 0 ers [aeiou]y SFX Z 0 ers [^ey] SFX S Y 4 SFX S y ies [^aeiou]y SFX S 0 s [aeiou]y SFX S 0 es [sxzh] SFX S 0 s [^sxzhy] SFX P Y 3 SFX P y iness [^aeiou]y SFX P 0 ness [aeiou]y SFX P 0 ness [^y] SFX M Y 1 SFX M 0 's . SFX B Y 3 SFX B 0 able [^aeiou] SFX B 0 able ee SFX B e able [^aeiou]e SFX L Y 1 SFX L 0 ment . REP 88 REP a ei REP ei a REP a ey REP ey a REP ai ie REP ie ai REP are air REP are ear REP are eir REP air are REP air ere REP ere air REP ere ear REP ere eir REP ear are REP ear air REP ear ere REP eir are REP eir ere REP ch te REP te ch REP ch ti REP ti ch REP ch tu REP tu ch REP ch s REP s ch REP ch k REP k ch REP f ph REP ph f REP gh f REP f gh REP i igh REP igh i REP i uy REP uy i REP i ee REP ee i REP j di REP di j REP j gg REP gg j REP j ge REP ge j REP s ti REP ti s REP s ci REP ci s REP k cc REP cc k REP k qu REP qu k REP kw qu REP o eau REP eau o REP o ew REP ew o REP oo ew REP ew oo REP ew ui REP ui ew REP oo ui REP ui oo REP ew u REP u ew REP oo u REP u oo REP u oe REP oe u REP u ieu REP ieu u REP ue ew REP ew ue REP uff ough REP oo ieu REP ieu oo REP ier ear REP ear ier REP ear air REP air ear REP w qu REP qu w REP z ss REP ss z REP shun tion REP shun sion REP shun cion hunspell-1.7.0/tests/base.dic000066400000000000000000000003431337236234000161110ustar00rootroot0000000000000028 created/U create/XKVNGADS imply/GNSDX natural/PUY like/USPBY convey/BDGS look/GZRDS text hello said sawyer NASA rotten day tomorrow seven FAQ/SM can't doesn't etc won't lip text horrifying speech suggest uncreate/V Hunspell hunspell-1.7.0/tests/base.good000066400000000000000000000002721337236234000163030ustar00rootroot00000000000000created uncreate uncreated imply implied unnatural conveyed sawyer NASA FAQs can't doesn't won't Created Hello HELLO NASA etc. etc HELLO lip. text. NASA. Text. TEXT. Hunspell. HUNSPELL. hunspell-1.7.0/tests/base.sug000066400000000000000000000001521337236234000161460ustar00rootroot00000000000000looked, look text hello said rotten day, rotten-day, rotten tomorrow seven NASA horrifying speech suggest hunspell-1.7.0/tests/base.wrong000066400000000000000000000001221337236234000165010ustar00rootroot00000000000000loooked texxt hlelo seid rottenday tomorow seeeven Nasa horrorfying peech sugesst hunspell-1.7.0/tests/base_utf.aff000066400000000000000000000056511337236234000167730ustar00rootroot00000000000000# OpenOffice.org’s en_US.aff file # with Unicode apostrophe: ’ SET UTF-8 TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ' MAXNGRAMSUGS 1 WORDCHARS .'’ PFX A Y 1 PFX A 0 re . PFX I Y 1 PFX I 0 in . PFX U Y 1 PFX U 0 un . PFX C Y 1 PFX C 0 de . PFX E Y 1 PFX E 0 dis . PFX F Y 1 PFX F 0 con . PFX K Y 1 PFX K 0 pro . SFX V N 2 SFX V e ive e SFX V 0 ive [^e] SFX N Y 3 SFX N e ion e SFX N y ication y SFX N 0 en [^ey] SFX X Y 3 SFX X e ions e SFX X y ications y SFX X 0 ens [^ey] SFX H N 2 SFX H y ieth y SFX H 0 th [^y] SFX Y Y 1 SFX Y 0 ly . SFX G Y 2 SFX G e ing e SFX G 0 ing [^e] SFX J Y 2 SFX J e ings e SFX J 0 ings [^e] SFX D Y 4 SFX D 0 d e SFX D y ied [^aeiou]y SFX D 0 ed [^ey] SFX D 0 ed [aeiou]y SFX T N 4 SFX T 0 st e SFX T y iest [^aeiou]y SFX T 0 est [aeiou]y SFX T 0 est [^ey] SFX R Y 4 SFX R 0 r e SFX R y ier [^aeiou]y SFX R 0 er [aeiou]y SFX R 0 er [^ey] SFX Z Y 4 SFX Z 0 rs e SFX Z y iers [^aeiou]y SFX Z 0 ers [aeiou]y SFX Z 0 ers [^ey] SFX S Y 4 SFX S y ies [^aeiou]y SFX S 0 s [aeiou]y SFX S 0 es [sxzh] SFX S 0 s [^sxzhy] SFX P Y 3 SFX P y iness [^aeiou]y SFX P 0 ness [aeiou]y SFX P 0 ness [^y] SFX M Y 1 SFX M 0 's . SFX B Y 3 SFX B 0 able [^aeiou] SFX B 0 able ee SFX B e able [^aeiou]e SFX L Y 1 SFX L 0 ment . REP 88 REP a ei REP ei a REP a ey REP ey a REP ai ie REP ie ai REP are air REP are ear REP are eir REP air are REP air ere REP ere air REP ere ear REP ere eir REP ear are REP ear air REP ear ere REP eir are REP eir ere REP ch te REP te ch REP ch ti REP ti ch REP ch tu REP tu ch REP ch s REP s ch REP ch k REP k ch REP f ph REP ph f REP gh f REP f gh REP i igh REP igh i REP i uy REP uy i REP i ee REP ee i REP j di REP di j REP j gg REP gg j REP j ge REP ge j REP s ti REP ti s REP s ci REP ci s REP k cc REP cc k REP k qu REP qu k REP kw qu REP o eau REP eau o REP o ew REP ew o REP oo ew REP ew oo REP ew ui REP ui ew REP oo ui REP ui oo REP ew u REP u ew REP oo u REP u oo REP u oe REP oe u REP u ieu REP ieu u REP ue ew REP ew ue REP uff ough REP oo ieu REP ieu oo REP ier ear REP ear ier REP ear air REP air ear REP w qu REP qu w REP z ss REP ss z REP shun tion REP shun sion REP shun cion McDonalds’sá/w McDonald’sszá/g3) st:McDonald’s po:noun_prs is:TRANS McDonald’sszal/g4) st:McDonald’s po:noun_prs is:INSTR McDonald’ssal/w hunspell-1.7.0/tests/base_utf.dic000066400000000000000000000003601337236234000167660ustar00rootroot0000000000000028 created/U create/XKVNGADS imply/GNSDX natural/PUY like/USPBY convey/BDGS look/GZRDS text hello said sawyer NASA rotten day tomorrow seven FAQ/SM can’t doesn’t etc won’t lip text horrifying speech suggest uncreate/V Hunspell İzmir hunspell-1.7.0/tests/base_utf.good000066400000000000000000000003541337236234000171620ustar00rootroot00000000000000created uncreate uncreated imply implied unnatural conveyed sawyer NASA FAQs can’t doesn’t won’t Created Hello HELLO NASA etc. etc HELLO lip. text. NASA. Text. TEXT. Hunspell. HUNSPELL. İzmir İZMİR İzmir. İZMİR. Imply IMPLY hunspell-1.7.0/tests/base_utf.sug000066400000000000000000000001661337236234000170310ustar00rootroot00000000000000looked, look text hello said rotten day, rotten-day, rotten tomorrow seven NASA horrifying speech suggest Imply IMPLY hunspell-1.7.0/tests/base_utf.wrong000066400000000000000000000001401337236234000173570ustar00rootroot00000000000000loooked texxt hlelo seid rottenday tomorow seeeven Nasa horrorfying peech sugesst İmply İMPLY hunspell-1.7.0/tests/break.aff000066400000000000000000000002031337236234000162530ustar00rootroot00000000000000# word break points test, recursive break at dash and n-dash SET UTF-8 BREAK 2 BREAK - BREAK – WORDCHARS -– FORBIDDENWORD ! hunspell-1.7.0/tests/break.dic000066400000000000000000000000471337236234000162640ustar00rootroot000000000000006 foo bar baz fox-bax foo-baz/! e-mail hunspell-1.7.0/tests/break.good000066400000000000000000000002161337236234000164530ustar00rootroot00000000000000foo bar fox-bax foo-bar foo–bar foo-bar-foo-bar foo-bar–foo-bar bar-baz baz-foo foo-bar-foo-bar-foo-bar-foo-bar-foo-bar e-mail e-mail-foo hunspell-1.7.0/tests/break.wrong000066400000000000000000000002021337236234000166520ustar00rootroot00000000000000fox bax -foo bar- fox-bar foo-bax foo–bax fox–bar foo-bar-fox-bar foo-bax-foo-bar foo-bar–fox-bar foo-bax–foo-bar foo-baz hunspell-1.7.0/tests/breakdefault.aff000066400000000000000000000001321337236234000176210ustar00rootroot00000000000000# default word break at hyphens and n-dashes SET UTF-8 MAXNGRAMSUGS 0 WORDCHARS - TRY ot hunspell-1.7.0/tests/breakdefault.dic000066400000000000000000000000371337236234000176300ustar00rootroot000000000000003 foo bar free scott scot-free hunspell-1.7.0/tests/breakdefault.good000066400000000000000000000000641337236234000200210ustar00rootroot00000000000000foo bar foo- -foo scot-free foo-bar foo-bar-foo-bar hunspell-1.7.0/tests/breakdefault.sug000066400000000000000000000000601337236234000176630ustar00rootroot00000000000000scott scot-free foo-bar foo-foo-bar foo-foo-foo hunspell-1.7.0/tests/breakdefault.wrong000066400000000000000000000000531337236234000202230ustar00rootroot00000000000000scot sco-free fo-bar foo-fo-bar foo-foo-fo hunspell-1.7.0/tests/breakoff.aff000066400000000000000000000001701337236234000167510ustar00rootroot00000000000000# switch off default word break at hyphens and n-dashes by BREAK 0 SET UTF-8 MAXNGRAMSUGS 0 WORDCHARS - TRY ot BREAK 0 hunspell-1.7.0/tests/breakoff.dic000066400000000000000000000000371337236234000167560ustar00rootroot000000000000003 foo bar free scott scot-free hunspell-1.7.0/tests/breakoff.good000066400000000000000000000000221337236234000171410ustar00rootroot00000000000000foo bar scot-free hunspell-1.7.0/tests/breakoff.wrong000066400000000000000000000000471337236234000173540ustar00rootroot00000000000000foo- -foo foo-bar foo-bar-foo-bar scot hunspell-1.7.0/tests/checkcompoundcase.aff000066400000000000000000000001331337236234000206470ustar00rootroot00000000000000# forbid upper case letters at word bounds in compounding CHECKCOMPOUNDCASE COMPOUNDFLAG A hunspell-1.7.0/tests/checkcompoundcase.dic000066400000000000000000000000301337236234000206460ustar00rootroot000000000000004 foo/A Bar/A BAZ/A -/A hunspell-1.7.0/tests/checkcompoundcase.good000066400000000000000000000000471337236234000210470ustar00rootroot00000000000000Barfoo foo-Bar foo-BAZ BAZ-foo BAZ-Bar hunspell-1.7.0/tests/checkcompoundcase.wrong000066400000000000000000000000251337236234000212470ustar00rootroot00000000000000fooBar BAZBar BAZfoo hunspell-1.7.0/tests/checkcompoundcase2.aff000066400000000000000000000000701337236234000207310ustar00rootroot00000000000000# check extended ascii CHECKCOMPOUNDCASE COMPOUNDFLAG A hunspell-1.7.0/tests/checkcompoundcase2.dic000066400000000000000000000000161337236234000207340ustar00rootroot000000000000002 o/A o/A hunspell-1.7.0/tests/checkcompoundcase2.good000066400000000000000000000000261337236234000211260ustar00rootroot00000000000000áoóáoó Óoááoó hunspell-1.7.0/tests/checkcompoundcase2.wrong000066400000000000000000000000131337236234000213260ustar00rootroot00000000000000áoóÓoá hunspell-1.7.0/tests/checkcompoundcaseutf.aff000066400000000000000000000000531337236234000213670ustar00rootroot00000000000000SET UTF-8 CHECKCOMPOUNDCASE COMPOUNDFLAG A hunspell-1.7.0/tests/checkcompoundcaseutf.dic000066400000000000000000000000221337236234000213660ustar00rootroot000000000000002 áoó/A Óoá/A hunspell-1.7.0/tests/checkcompoundcaseutf.good000066400000000000000000000000261337236234000215630ustar00rootroot00000000000000áoóáoó Óoááoó hunspell-1.7.0/tests/checkcompoundcaseutf.wrong000066400000000000000000000000131337236234000217630ustar00rootroot00000000000000áoóÓoá hunspell-1.7.0/tests/checkcompounddup.aff000066400000000000000000000001131337236234000205220ustar00rootroot00000000000000# Forbid compound word with triple letters CHECKCOMPOUNDDUP COMPOUNDFLAG A hunspell-1.7.0/tests/checkcompounddup.dic000066400000000000000000000000161337236234000205270ustar00rootroot000000000000002 foo/A bar/A hunspell-1.7.0/tests/checkcompounddup.good000066400000000000000000000000571337236234000207250ustar00rootroot00000000000000barfoo foobar foofoobar foobarfoo barfoobarfoo hunspell-1.7.0/tests/checkcompounddup.wrong000066400000000000000000000000331337236234000211230ustar00rootroot00000000000000foofoo foofoofoo foobarbar hunspell-1.7.0/tests/checkcompoundpattern.aff000066400000000000000000000002231337236234000214110ustar00rootroot00000000000000# forbid compounds with spec. pattern at word bounds COMPOUNDFLAG A CHECKCOMPOUNDPATTERN 2 CHECKCOMPOUNDPATTERN nny ny CHECKCOMPOUNDPATTERN ssz sz hunspell-1.7.0/tests/checkcompoundpattern.dic000066400000000000000000000000461337236234000214170ustar00rootroot000000000000004 knny/A nyels/A hossz/A szmts/A hunspell-1.7.0/tests/checkcompoundpattern.good000066400000000000000000000000371337236234000216100ustar00rootroot00000000000000könnyszámítás hossznyelés hunspell-1.7.0/tests/checkcompoundpattern.wrong000066400000000000000000000001051337236234000220100ustar00rootroot00000000000000könnynyelés hosszszámítás hosszkönnynyelés könnynyeléshossz hunspell-1.7.0/tests/checkcompoundpattern2.aff000066400000000000000000000003371337236234000215010ustar00rootroot00000000000000# forbid compounds with spec. pattern at word bound and allow modificated form # (for German and Indian languages) COMPOUNDFLAG A CHECKCOMPOUNDPATTERN 2 CHECKCOMPOUNDPATTERN o b z CHECKCOMPOUNDPATTERN oo ba u COMPOUNDMIN 1 hunspell-1.7.0/tests/checkcompoundpattern2.dic000066400000000000000000000000161337236234000214760ustar00rootroot000000000000002 foo/A bar/A hunspell-1.7.0/tests/checkcompoundpattern2.good000066400000000000000000000000211337236234000216630ustar00rootroot00000000000000barfoo fozar fur hunspell-1.7.0/tests/checkcompoundpattern2.wrong000066400000000000000000000000071337236234000220730ustar00rootroot00000000000000foobar hunspell-1.7.0/tests/checkcompoundpattern3.aff000066400000000000000000000002731337236234000215010ustar00rootroot00000000000000# forbid compounds with spec. pattern at word bound and allow modificated form # (for Indian languages) COMPOUNDFLAG A CHECKCOMPOUNDPATTERN 1 CHECKCOMPOUNDPATTERN o/X b/Y z COMPOUNDMIN 1 hunspell-1.7.0/tests/checkcompoundpattern3.dic000066400000000000000000000000341337236234000214770ustar00rootroot000000000000004 foo/A boo/AX bar/A ban/AY hunspell-1.7.0/tests/checkcompoundpattern3.good000066400000000000000000000001041337236234000216660ustar00rootroot00000000000000bozan barfoo banfoo banbar foobar fooban foobanbar boobar boobarfoo hunspell-1.7.0/tests/checkcompoundpattern3.wrong000066400000000000000000000000761337236234000221020ustar00rootroot00000000000000booban boobanfoo fozar fozarfoo fozan fozanfoo bozar bozarfoo hunspell-1.7.0/tests/checkcompoundpattern4.aff000066400000000000000000000002761337236234000215050ustar00rootroot00000000000000# sandhi in Telugu writing system, based on the Kiran Chittella's example COMPOUNDFLAG x COMPOUNDMIN 1 CHECKCOMPOUNDPATTERN 2 CHECKCOMPOUNDPATTERN a/A u/A O CHECKCOMPOUNDPATTERN u/B u/B u hunspell-1.7.0/tests/checkcompoundpattern4.dic000066400000000000000000000000461337236234000215030ustar00rootroot000000000000004 sUrya/Ax udayaM/Ax pEru/Bx unna/Bx hunspell-1.7.0/tests/checkcompoundpattern4.good000066400000000000000000000000231337236234000216670ustar00rootroot00000000000000sUryOdayaM pErunna hunspell-1.7.0/tests/checkcompoundpattern4.wrong000066400000000000000000000000251337236234000220750ustar00rootroot00000000000000sUryaudayaM pEruunna hunspell-1.7.0/tests/checkcompoundrep.aff000066400000000000000000000004311337236234000205230ustar00rootroot00000000000000// forbid compound word, if it is also a non-compound word with a REP fault // In example: Hungarian `szervz' (szer+vz) compound word is forbidden, because // this word is also a dictionary word (szerviz) with typical fault (i->) CHECKCOMPOUNDREP COMPOUNDFLAG A REP 1 REP i hunspell-1.7.0/tests/checkcompoundrep.dic000066400000000000000000000000371337236234000205300ustar00rootroot000000000000003 szer/A vz/A szerviz kocsi/A hunspell-1.7.0/tests/checkcompoundrep.good000066400000000000000000000000231337236234000207140ustar00rootroot00000000000000vízszer szerkocsi hunspell-1.7.0/tests/checkcompoundrep.wrong000066400000000000000000000000451337236234000211240ustar00rootroot00000000000000szervíz szervízkocsi kocsiszervíz hunspell-1.7.0/tests/checkcompoundtriple.aff000066400000000000000000000001161337236234000212340ustar00rootroot00000000000000# Forbid compound word with triple letters CHECKCOMPOUNDTRIPLE COMPOUNDFLAG A hunspell-1.7.0/tests/checkcompoundtriple.dic000066400000000000000000000000351337236234000212370ustar00rootroot000000000000004 foo/A opera/A eel/A bare/A hunspell-1.7.0/tests/checkcompoundtriple.good000066400000000000000000000000641337236234000214320ustar00rootroot00000000000000operafoo operaeel operabare eelbare eelfoo eelopera hunspell-1.7.0/tests/checkcompoundtriple.wrong000066400000000000000000000000211337236234000216270ustar00rootroot00000000000000fooopera bareeel hunspell-1.7.0/tests/checksharps.aff000066400000000000000000000001071337236234000174700ustar00rootroot00000000000000# test - SS special capitalizing CHECKSHARPS WORDCHARS . KEEPCASE k hunspell-1.7.0/tests/checksharps.dic000066400000000000000000000001051337236234000174710ustar00rootroot000000000000006 mig/k Aussto Absto. Auenabmessung Prozessionsstrae Auenmae hunspell-1.7.0/tests/checksharps.good000066400000000000000000000002321337236234000176630ustar00rootroot00000000000000müßig Müßig MÜSSIG Ausstoß Abstoß. Außenabmessung Prozessionsstraße Außenmaße AUSSTOSS ABSTOSS. AUSSENABMESSUNG PROZESSIONSSTRASSE AUSSENMASSE hunspell-1.7.0/tests/checksharps.sug000066400000000000000000000000211337236234000175250ustar00rootroot00000000000000MÜSSIG, müßig hunspell-1.7.0/tests/checksharps.wrong000066400000000000000000000000101337236234000200610ustar00rootroot00000000000000MÜßIG hunspell-1.7.0/tests/checksharpsutf.aff000066400000000000000000000001331337236234000202060ustar00rootroot00000000000000# test - SS special capitalizing in UTF-8 SET UTF-8 CHECKSHARPS WORDCHARS ß. KEEPCASE k hunspell-1.7.0/tests/checksharpsutf.dic000066400000000000000000000001151337236234000202110ustar00rootroot000000000000006 müßig/k Ausstoß Abstoß. Außenabmessung Prozessionsstraße Außenmaße hunspell-1.7.0/tests/checksharpsutf.good000066400000000000000000000002321337236234000204020ustar00rootroot00000000000000müßig Müßig MÜSSIG Ausstoß Abstoß. Außenabmessung Prozessionsstraße Außenmaße AUSSTOSS ABSTOSS. AUSSENABMESSUNG PROZESSIONSSTRASSE AUSSENMASSE hunspell-1.7.0/tests/checksharpsutf.sug000066400000000000000000000000211337236234000202440ustar00rootroot00000000000000MÜSSIG, müßig hunspell-1.7.0/tests/checksharpsutf.wrong000066400000000000000000000000101337236234000206000ustar00rootroot00000000000000MÜßIG hunspell-1.7.0/tests/circumfix.aff000066400000000000000000000004461337236234000171710ustar00rootroot00000000000000# circumfixes: ~ obligate prefix/suffix combinations # superlative in Hungarian: leg- (prefix) AND -bb (suffix) CIRCUMFIX X PFX A Y 1 PFX A 0 leg/X . PFX B Y 1 PFX B 0 legesleg/X . SFX C Y 3 SFX C 0 obb . is:COMPARATIVE SFX C 0 obb/AX . is:SUPERLATIVE SFX C 0 obb/BX . is:SUPERSUPERLATIVE hunspell-1.7.0/tests/circumfix.dic000066400000000000000000000000201337236234000171600ustar00rootroot000000000000001 nagy/C po:adj hunspell-1.7.0/tests/circumfix.good000066400000000000000000000000501337236234000173540ustar00rootroot00000000000000nagy nagyobb legnagyobb legeslegnagyobb hunspell-1.7.0/tests/circumfix.morph000066400000000000000000000005341337236234000175600ustar00rootroot00000000000000> nagy analyze(nagy) = st:nagy po:adj stem(nagy) = nagy > nagyobb analyze(nagyobb) = st:nagy po:adj is:COMPARATIVE stem(nagyobb) = nagy > legnagyobb analyze(legnagyobb) = fl:A st:nagy po:adj is:SUPERLATIVE stem(legnagyobb) = nagy > legeslegnagyobb analyze(legeslegnagyobb) = fl:B st:nagy po:adj is:SUPERSUPERLATIVE stem(legeslegnagyobb) = nagy hunspell-1.7.0/tests/circumfix.wrong000066400000000000000000000000251337236234000175620ustar00rootroot00000000000000legnagy legeslegnagy hunspell-1.7.0/tests/colons_in_words.aff000066400000000000000000000001631337236234000203750ustar00rootroot00000000000000# Colons in Finnish and Swedish words. Problem reported by Lars Aronsson. # Parsing test (src/parsers) WORDCHARS : hunspell-1.7.0/tests/colons_in_words.dic000066400000000000000000000000161337236234000203750ustar00rootroot000000000000002 c:a S:t foo hunspell-1.7.0/tests/complexprefixes.aff000066400000000000000000000002061337236234000204070ustar00rootroot00000000000000# set twofold prefix stripping # Coptic example by Moheb Mekhaiel COMPLEXPREFIXES PFX A Y 1 PFX A 0 tek . PFX B Y 1 PFX B 0 met/A . hunspell-1.7.0/tests/complexprefixes.dic000066400000000000000000000000121337236234000204050ustar00rootroot000000000000001 ouro/B hunspell-1.7.0/tests/complexprefixes.good000066400000000000000000000000301337236234000205760ustar00rootroot00000000000000ouro metouro tekmetouro hunspell-1.7.0/tests/complexprefixes.wrong000066400000000000000000000000231337236234000210040ustar00rootroot00000000000000tekouro mettekouro hunspell-1.7.0/tests/complexprefixes2.aff000066400000000000000000000002671337236234000205000ustar00rootroot00000000000000# complex prefixes with morphological analysis COMPLEXPREFIXES WORDCHARS _ PFX A Y 1 PFX A 0 tek . affix_1/ PFX B Y 1 PFX B 0 met/A . affix_2/ SFX C Y 1 SFX C 0 _test_ . /suffix_1 hunspell-1.7.0/tests/complexprefixes2.dic000066400000000000000000000000241337236234000204720ustar00rootroot000000000000001 ouro/BC [stem_1] hunspell-1.7.0/tests/complexprefixes2.good000066400000000000000000000000431337236234000206640ustar00rootroot00000000000000ouro metouro tekmetouro ouro_test_ hunspell-1.7.0/tests/complexprefixesutf.aff000066400000000000000000000003351337236234000211310ustar00rootroot00000000000000# Coptic example by Moheb Mekhaiel # Encoded with the new Coptic character encoding of Unicode 4.1 SET UTF-8 # set twofold prefix stripping COMPLEXPREFIXES PFX A Y 1 PFX A 0 ⲧⲉⲕ . PFX B Y 1 PFX B 0 ⲙⲉⲧ/A . hunspell-1.7.0/tests/complexprefixesutf.dic000066400000000000000000000000211337236234000211240ustar00rootroot000000000000001 ⲟⲩⲣⲟ/B hunspell-1.7.0/tests/complexprefixesutf.good000066400000000000000000000001021337236234000213150ustar00rootroot00000000000000ⲟⲩⲣⲟ ⲙⲉⲧⲟⲩⲣⲟ ⲧⲉⲕⲙⲉⲧⲟⲩⲣⲟ hunspell-1.7.0/tests/complexprefixesutf.wrong000066400000000000000000000000651337236234000215310ustar00rootroot00000000000000ⲧⲉⲕⲟⲩⲣⲟ ⲙⲉⲧⲧⲉⲕⲟⲩⲣⲟ hunspell-1.7.0/tests/compoundaffix.aff000066400000000000000000000001351337236234000200350ustar00rootroot00000000000000COMPOUNDFLAG X PFX P Y 1 PFX P 0 pre . SFX S Y 1 SFX S 0 suf . hunspell-1.7.0/tests/compoundaffix.dic000066400000000000000000000000221337236234000200330ustar00rootroot000000000000002 foo/XPS bar/XPS hunspell-1.7.0/tests/compoundaffix.good000066400000000000000000000000601337236234000202260ustar00rootroot00000000000000foo foofoo prefoo foosuf prefoosuf prefoobarsuf hunspell-1.7.0/tests/compoundaffix.wrong000066400000000000000000000000471337236234000204370ustar00rootroot00000000000000foosufbar fooprebarsuf prefooprebarsuf hunspell-1.7.0/tests/compoundaffix2.aff000066400000000000000000000001661337236234000201230ustar00rootroot00000000000000COMPOUNDFLAG X COMPOUNDPERMITFLAG Y PFX P Y 1 PFX P 0 pre/Y . SFX S Y 1 SFX S 0 suf/Y . hunspell-1.7.0/tests/compoundaffix2.dic000066400000000000000000000000221337236234000201150ustar00rootroot000000000000002 foo/XPS bar/XPS hunspell-1.7.0/tests/compoundaffix2.good000066400000000000000000000001201337236234000203050ustar00rootroot00000000000000foo prefoo foosuf prefoosuf prefoobarsuf foosufbar fooprebarsuf prefooprebarsuf hunspell-1.7.0/tests/compoundaffix3.aff000066400000000000000000000001661337236234000201240ustar00rootroot00000000000000COMPOUNDFLAG X COMPOUNDFORBIDFLAG Z PFX P Y 1 PFX P 0 pre/Z . SFX S Y 1 SFX S 0 suf/Z . hunspell-1.7.0/tests/compoundaffix3.dic000066400000000000000000000000221337236234000201160ustar00rootroot000000000000002 foo/XPS bar/XPS hunspell-1.7.0/tests/compoundaffix3.good000066400000000000000000000000431337236234000203120ustar00rootroot00000000000000foo foofoo prefoo foosuf prefoosuf hunspell-1.7.0/tests/compoundaffix3.wrong000066400000000000000000000001131337236234000205140ustar00rootroot00000000000000prefoobarsuf foosufbar fooprebar foosufprebar fooprebarsuf prefooprebarsuf hunspell-1.7.0/tests/compoundflag.aff000066400000000000000000000000361337236234000176510ustar00rootroot00000000000000COMPOUNDMIN 3 COMPOUNDFLAG A hunspell-1.7.0/tests/compoundflag.dic000066400000000000000000000000301337236234000176460ustar00rootroot000000000000004 foo/A bar/A xy/A yz/A hunspell-1.7.0/tests/compoundflag.good000066400000000000000000000000301337236234000200370ustar00rootroot00000000000000foobar barfoo foobarfoo hunspell-1.7.0/tests/compoundflag.wrong000066400000000000000000000000321337236234000202450ustar00rootroot00000000000000xyyz fooxy xyfoo fooxybar hunspell-1.7.0/tests/compoundforbid.aff000066400000000000000000000005431337236234000202100ustar00rootroot00000000000000# Dictionary words with COMPOUNDFORBIDFLAG are # removed from the beginning and middle of # compound words, overriding the effect of # COMPOUNDPERMITFLAG. # # See compoundaffix3 test for basic usage # of COMPOUNDFORBIDFLAG. COMPOUNDFLAG X COMPOUNDPERMITFLAG Y COMPOUNDFORBIDFLAG Z SFX S Y 2 SFX S 0 bar/YX . SFX S 0 baz/YX . hunspell-1.7.0/tests/compoundforbid.dic000066400000000000000000000000331337236234000202050ustar00rootroot000000000000003 foo/S example/X foobaz/Z hunspell-1.7.0/tests/compoundforbid.good000066400000000000000000000000501337236234000203750ustar00rootroot00000000000000foo example foobar foobaz foobarexample hunspell-1.7.0/tests/compoundforbid.wrong000066400000000000000000000000441337236234000206040ustar00rootroot00000000000000fooexample examplefoo foobazexample hunspell-1.7.0/tests/compoundrule.aff000066400000000000000000000000561337236234000177110ustar00rootroot00000000000000COMPOUNDMIN 1 COMPOUNDRULE 1 COMPOUNDRULE ABC hunspell-1.7.0/tests/compoundrule.dic000066400000000000000000000000201337236234000177030ustar00rootroot000000000000003 a/A b/B c/BC hunspell-1.7.0/tests/compoundrule.good000066400000000000000000000000101337236234000200730ustar00rootroot00000000000000abc acc hunspell-1.7.0/tests/compoundrule.wrong000066400000000000000000000003111337236234000203030ustar00rootroot00000000000000ba aaabaaa bbaaa aaaaba bbbbbaa aa aaa aaaa ab aab aaab aaaab abb aabb aaabbb bb bbb bbbb aaab abcc abbc abbcc aabc aabcc aabbc aabbcc aaabbbccc ac aac aacc aaaccc bc bcc bbc bbcc bbbccc cc ccc cccccc hunspell-1.7.0/tests/compoundrule2.aff000066400000000000000000000000611337236234000177670ustar00rootroot00000000000000COMPOUNDMIN 1 COMPOUNDRULE 1 COMPOUNDRULE A*B*C* hunspell-1.7.0/tests/compoundrule2.dic000066400000000000000000000000171337236234000177730ustar00rootroot000000000000003 a/A b/B c/C hunspell-1.7.0/tests/compoundrule2.good000066400000000000000000000002661337236234000201720ustar00rootroot00000000000000aa aaa aaaa ab aab aaab aaaab abb aabb aaabbb bb bbb bbbb aaab abc abcc abbc abbcc aabc aabcc aabbc aabbcc aaabbbccc ac acc aac aacc aaaccc bc bcc bbc bbcc bbbccc cc ccc cccccc abcc hunspell-1.7.0/tests/compoundrule2.wrong000066400000000000000000000000541337236234000203710ustar00rootroot00000000000000ba aaabaaa bbaaa aaaaba bbbbbaa cba cab acb hunspell-1.7.0/tests/compoundrule3.aff000066400000000000000000000000611337236234000177700ustar00rootroot00000000000000COMPOUNDMIN 1 COMPOUNDRULE 1 COMPOUNDRULE A?B?C? hunspell-1.7.0/tests/compoundrule3.dic000066400000000000000000000000171337236234000177740ustar00rootroot000000000000003 a/A b/B c/C hunspell-1.7.0/tests/compoundrule3.good000066400000000000000000000000231337236234000201620ustar00rootroot00000000000000a b c ab abc ac bc hunspell-1.7.0/tests/compoundrule3.wrong000066400000000000000000000003251337236234000203730ustar00rootroot00000000000000aa aaa aaaa aab aaab aaaab abb aabb aaabbb bb bbb bbbb aaab abcc abbc abbcc aabc aabcc aabbc aabbcc aaabbbccc acc aac aacc aaaccc bcc bbc bbcc bbbccc cc ccc cccccc abcc ba aaabaaa bbaaa aaaaba bbbbbaa cba cab acb hunspell-1.7.0/tests/compoundrule4.aff000066400000000000000000000002011337236234000177650ustar00rootroot00000000000000# English ordinal numbers WORDCHARS 0123456789 COMPOUNDMIN 1 ONLYINCOMPOUND c COMPOUNDRULE 2 COMPOUNDRULE n*1t COMPOUNDRULE n*mp hunspell-1.7.0/tests/compoundrule4.dic000066400000000000000000000002151337236234000177750ustar00rootroot0000000000000022 0/nm 1/n1 2/nm 3/nm 4/nm 5/nm 6/nm 7/nm 8/nm 9/nm 0th/pt 1st/p 1th/tc 2nd/p 2th/tc 3rd/p 3th/tc 4th/pt 5th/pt 6th/pt 7th/pt 8th/pt 9th/pt hunspell-1.7.0/tests/compoundrule4.good000066400000000000000000000002211337236234000201630ustar00rootroot000000000000001st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 100th 1000th 10001st 10011th hunspell-1.7.0/tests/compoundrule4.wrong000066400000000000000000000000341337236234000203710ustar00rootroot000000000000001th 2th 3th 10001th 10011st hunspell-1.7.0/tests/compoundrule5.aff000066400000000000000000000001741337236234000177770ustar00rootroot00000000000000# number + percent SET UTF-8 COMPOUNDMIN 1 COMPOUNDRULE 2 COMPOUNDRULE N*%? COMPOUNDRULE NN*.NN*%? WORDCHARS 0123456789‰. hunspell-1.7.0/tests/compoundrule5.dic000066400000000000000000000002551337236234000200020ustar00rootroot0000000000000013 0/N po:num 1/N po:num 2/N po:num 3/N po:num 4/N po:num 5/N po:num 6/N po:num 7/N po:num 8/N po:num 9/N po:num ./. po:sign_dot %/% po:sign_percent ‰/% po:sign_per_mille hunspell-1.7.0/tests/compoundrule5.good000066400000000000000000000000511337236234000201650ustar00rootroot0000000000000010% 0.2% 0.20% 123.4561‰ 10 0000 10.25 hunspell-1.7.0/tests/compoundrule5.morph000066400000000000000000000016341337236234000203720ustar00rootroot00000000000000> 10% analyze(10%) = pa:1 st:1 po:num pa:0 st:0 po:num pa:% st:% po:sign_percent stem(10%) = 10% > 0.2% analyze(0.2%) = pa:0 st:0 po:num pa:. st:. po:sign_dot pa:2 st:2 po:num pa:% st:% po:sign_percent stem(0.2%) = 0.2% > 0.20% analyze(0.20%) = pa:0 st:0 po:num pa:. st:. po:sign_dot pa:2 st:2 po:num pa:0 st:0 po:num pa:% st:% po:sign_percent stem(0.20%) = 0.20% > 123.4561‰ analyze(123.4561‰) = pa:1 st:1 po:num pa:2 st:2 po:num pa:3 st:3 po:num pa:. st:. po:sign_dot pa:4 st:4 po:num pa:5 st:5 po:num pa:6 st:6 po:num pa:1 st:1 po:num pa:‰ st:‰ po:sign_per_mille stem(123.4561‰) = 123.4561‰ > 10 analyze(10) = pa:1 st:1 po:num pa:0 st:0 po:num stem(10) = 10 > 0000 analyze(0000) = pa:0 st:0 po:num pa:0 st:0 po:num pa:0 st:0 po:num pa:0 st:0 po:num stem(0000) = 0000 > 10.25 analyze(10.25) = pa:1 st:1 po:num pa:0 st:0 po:num pa:. st:. po:sign_dot pa:2 st:2 po:num pa:5 st:5 po:num stem(10.25) = 10.25 hunspell-1.7.0/tests/compoundrule5.wrong000066400000000000000000000000041337236234000203670ustar00rootroot00000000000000.25 hunspell-1.7.0/tests/compoundrule6.aff000066400000000000000000000001101337236234000177660ustar00rootroot00000000000000COMPOUNDMIN 1 COMPOUNDRULE 2 COMPOUNDRULE A*A COMPOUNDRULE A*AAB*BBBC*C hunspell-1.7.0/tests/compoundrule6.dic000066400000000000000000000000171337236234000177770ustar00rootroot000000000000003 a/A b/B c/C hunspell-1.7.0/tests/compoundrule6.good000066400000000000000000000000431337236234000201670ustar00rootroot00000000000000aa aaaaaa aabbbc aaaaabbbbbbcccccc hunspell-1.7.0/tests/compoundrule6.wrong000066400000000000000000000000501337236234000203710ustar00rootroot00000000000000abc abbbbbccccccc aabbccccccc aabbbbbbb hunspell-1.7.0/tests/compoundrule7.aff000066400000000000000000000002711337236234000177770ustar00rootroot00000000000000# English ordinal numbers (parenthesized long flags) FLAG long WORDCHARS 0123456789 COMPOUNDMIN 1 ONLYINCOMPOUND cc COMPOUNDRULE 2 COMPOUNDRULE (nn)*(11)(tt) COMPOUNDRULE (nn)*(mm)(pp) hunspell-1.7.0/tests/compoundrule7.dic000066400000000000000000000002701337236234000200010ustar00rootroot0000000000000022 0/nnmm 1/nn11 2/nnmm 3/nnmm 4/nnmm 5/nnmm 6/nnmm 7/nnmm 8/nnmm 9/nnmm 0th/pptt 1st/pp 1th/ttcc 2nd/pp 2th/ttcc 3rd/pp 3th/ttcc 4th/pptt 5th/pptt 6th/pptt 7th/pptt 8th/pptt 9th/pptt hunspell-1.7.0/tests/compoundrule7.good000066400000000000000000000002211337236234000201660ustar00rootroot000000000000001st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 100th 1000th 10001st 10011th hunspell-1.7.0/tests/compoundrule7.wrong000066400000000000000000000000341337236234000203740ustar00rootroot000000000000001th 2th 3th 10001th 10011st hunspell-1.7.0/tests/compoundrule8.aff000066400000000000000000000003131337236234000177750ustar00rootroot00000000000000# English ordinal numbers (parenthesized numerical flags) FLAG num WORDCHARS 0123456789 COMPOUNDMIN 1 ONLYINCOMPOUND 1000 COMPOUNDRULE 2 COMPOUNDRULE (1001)*(1002)(2001) COMPOUNDRULE (1001)*(2002)(2000) hunspell-1.7.0/tests/compoundrule8.dic000066400000000000000000000004421337236234000200030ustar00rootroot0000000000000022 0/1001,2002 1/1001,1002 2/1001,2002 3/1001,2002 4/1001,2002 5/1001,2002 6/1001,2002 7/1001,2002 8/1001,2002 9/1001,2002 0th/2000,2001 1st/2000 1th/2001,1000 2nd/2000 2th/2001,1000 3rd/2000 3th/2001,1000 4th/2000,2001 5th/2000,2001 6th/2000,2001 7th/2000,2001 8th/2000,2001 9th/2000,2001 hunspell-1.7.0/tests/compoundrule8.good000066400000000000000000000002211337236234000201670ustar00rootroot000000000000001st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 100th 1000th 10001st 10011th hunspell-1.7.0/tests/compoundrule8.wrong000066400000000000000000000000341337236234000203750ustar00rootroot000000000000001th 2th 3th 10001th 10011st hunspell-1.7.0/tests/condition.aff000066400000000000000000000025011337236234000171600ustar00rootroot00000000000000SET ISO8859-2 WORDCHARS 0123456789 SFX S N 18 SFX S 0 suf1 . SFX S 0 suf2 o SFX S 0 suf3 [aeou] SFX S 0 suf4 [^o] SFX S 0 suf5 [^aeou] SFX S 0 suf6 fo SFX S 0 suf7 f[aeou] SFX S 0 suf8 f[^o] SFX S 0 suf9 f[^aeou] SFX S 0 suf10 [aefu]o SFX S 0 suf11 [^f]o SFX S 0 suf12 [^aefu]o SFX S 0 suf13 [aefu][^aefu] SFX S 0 suf14 [^aeou][aeou] SFX S 0 suf15 [aeou][^aefu] SFX S 0 suf16 [^aeou][^aefu] SFX S 0 suf17 [aeou][bcdfgkmnoprstvz] SFX S 0 suf18 [aeou]o SFX Q N 2 SFX Q 0 ning [^aeio][aeiou]n SFX Q 0 ing [aeio][aeiou][bcdfgkmnprstvz] SFX T N 1 SFX T y ies .[^aeiou]y PFX U N 1 PFX U 0 un wr. SFX Z Y 3 SFX Z 0 ch [].a SFX Z 0 m [].a SFX Z a 0 [].a PFX P N 18 PFX P 0 pre1 . PFX P 0 pre2 o PFX P 0 pre3 [aeou] PFX P 0 pre4 [^o] PFX P 0 pre5 [^aeou] PFX P 0 pre6 of PFX P 0 pre7 o[aefou] PFX P 0 pre8 o[^f] PFX P 0 pre9 o[^aefu] PFX P 0 pre10 [aefu]o PFX P 0 pre11 [^f]o PFX P 0 pre12 [^aefou]o PFX P 0 pre13 [aeou][aefu] PFX P 0 pre14 [aeou][^aeou] PFX P 0 pre15 [aeou][^aefu] PFX P 0 pre16 [^aefu][^aeou] PFX P 0 pre17 [bcdfgkmnoprstvz][aeou] PFX P 0 pre18 o[aeou] PFX R N 2 PFX R 0 gnin n[aeiou][^aeio] PFX R 0 gni [bcdfgkmnprstvz][aeiou][aeio] hunspell-1.7.0/tests/condition.dic000066400000000000000000000000561337236234000171660ustar00rootroot000000000000005 ofo/SP entertain/Q nianretne/R ra/Z wry/TU hunspell-1.7.0/tests/condition.good000066400000000000000000000003241337236234000173550ustar00rootroot00000000000000ofo ofosuf1 pre1ofo ofosuf2 pre2ofo ofosuf3 pre3ofo ofosuf6 pre6ofo ofosuf7 pre7ofo ofosuf10 ofosuf13 pre13ofo ofosuf14 pre14ofo ofosuf16 pre16ofo entertain entertaining gninianretne ér éram érach wries unwry hunspell-1.7.0/tests/condition.wrong000066400000000000000000000002771337236234000175700ustar00rootroot00000000000000ofosuf4 pre4ofo ofosuf5 pre5ofo ofosuf8 pre8ofo ofosuf9 pre9ofo ofosuf11 pre10ofo pre11ofo ofosuf12 pre12ofo ofosuf15 pre15ofo ofosuf17 pre17ofo ofosuf18 pre18ofo entertainning gninnianretne hunspell-1.7.0/tests/condition_utf.aff000066400000000000000000000021221337236234000200350ustar00rootroot00000000000000SET UTF-8 WORDCHARS 0123456789 SFX S N 18 SFX S 0 suf1 . SFX S 0 suf2 ó SFX S 0 suf3 [áéóú] SFX S 0 suf4 [^ó] SFX S 0 suf5 [^áéóú] SFX S 0 suf6 őó SFX S 0 suf7 ő[áéóú] SFX S 0 suf8 ő[^ó] SFX S 0 suf9 ő[^áéóú] SFX S 0 suf10 [áéóőú]ó SFX S 0 suf11 [^ő]ó SFX S 0 suf12 [^áéóőú]ó SFX S 0 suf13 [áéőú][^ú] SFX S 0 suf14 [^ú][áéóú] SFX S 0 suf15 [áéóú][^áéőú] SFX S 0 suf16 [^áéóú][^áéőú] SFX S 0 suf17 [áéóú][bcdfgkmnóprstvz] SFX S 0 suf18 [áéóú]ó PFX P N 18 PFX P 0 pre1 . PFX P 0 pre2 ó PFX P 0 pre3 [áéóú] PFX P 0 pre4 [^ó] PFX P 0 pre5 [^áéóú] PFX P 0 pre6 óő PFX P 0 pre7 ó[áéőú] PFX P 0 pre8 ó[^ő] PFX P 0 pre9 ó[^áéóőú] PFX P 0 pre10 [áéóőú]ő PFX P 0 pre11 [^ó]ő PFX P 0 pre12 [^áéóőú]ő PFX P 0 pre13 [áéóú][áéőú] PFX P 0 pre14 [áéóú][^áéóú] PFX P 0 pre15 [áéóú][^áéőú] PFX P 0 pre16 [^áéőú][^áéóú] PFX P 0 pre17 [bcdfgkmnóprstvz][áéóú] PFX P 0 pre18 ó[áéóú] hunspell-1.7.0/tests/condition_utf.dic000066400000000000000000000000141337236234000200360ustar00rootroot000000000000001 óőó/SP hunspell-1.7.0/tests/condition_utf.good000066400000000000000000000003251337236234000202340ustar00rootroot00000000000000óőó óőósuf1 pre1óőó óőósuf2 pre2óőó óőósuf3 pre3óőó óőósuf6 pre6óőó óőósuf7 pre7óőó óőósuf10 pre10óőó óőósuf13 pre13óőó óőósuf14 pre14óőó óőósuf16 pre16óőó hunspell-1.7.0/tests/condition_utf.wrong000066400000000000000000000003201337236234000204330ustar00rootroot00000000000000óőósuf4 pre4óőó óőósuf5 pre5óőó óőósuf8 pre8óőó óőósuf9 pre9óőó óőósuf11 pre11óőó óőósuf12 pre12óőó óőósuf15 pre15óőó óőósuf17 óőósuf18 pre17óőó pre18óőó hunspell-1.7.0/tests/conditionalprefix.aff000066400000000000000000000002201337236234000207070ustar00rootroot00000000000000PFX P Y 1 PFX P 0 un . ip:un SFX S Y 1 SFX S 0 s . is:PL SFX Q Y 1 SFX Q 0 s . is:3SGV SFX R Y 1 SFX R 0 able/PS . ds:DER_V_ADJ_ABLE hunspell-1.7.0/tests/conditionalprefix.dic000066400000000000000000000000431337236234000207150ustar00rootroot000000000000002 drink/RQ po:verb drink/S po:noun hunspell-1.7.0/tests/conditionalprefix.good000066400000000000000000000000731337236234000211110ustar00rootroot00000000000000drink drinks drinkable drinkables undrinkable undrinkables hunspell-1.7.0/tests/conditionalprefix.morph000066400000000000000000000012041337236234000213030ustar00rootroot00000000000000> drink analyze(drink) = st:drink po:verb analyze(drink) = st:drink po:noun stem(drink) = drink > drinks analyze(drinks) = st:drink po:verb is:3SGV analyze(drinks) = st:drink po:noun is:PL stem(drinks) = drink > drinkable analyze(drinkable) = st:drink po:verb ds:DER_V_ADJ_ABLE stem(drinkable) = drinkable > drinkables analyze(drinkables) = st:drink po:verb ds:DER_V_ADJ_ABLE is:PL stem(drinkables) = drinkable > undrinkable analyze(undrinkable) = ip:un st:drink po:verb ds:DER_V_ADJ_ABLE stem(undrinkable) = drinkable > undrinkables analyze(undrinkables) = ip:un st:drink po:verb ds:DER_V_ADJ_ABLE is:PL stem(undrinkables) = drinkable hunspell-1.7.0/tests/conditionalprefix.wrong000066400000000000000000000000211337236234000213060ustar00rootroot00000000000000undrink undrinks hunspell-1.7.0/tests/digits_in_words.aff000066400000000000000000000004021337236234000203570ustar00rootroot00000000000000# Digits in words, handled by COMPOUNDRULE. # 1-jährig, 2-jährig, 100-jährig etc. SET UTF-8 COMPOUNDMIN 1 # recognize ab, aab, aaab etc. compounds (a=digits, b=-jährig, see dic file) COMPOUNDRULE 1 COMPOUNDRULE a*b ONLYINCOMPOUND c WORDCHARS 0123456789- hunspell-1.7.0/tests/digits_in_words.dic000066400000000000000000000000671337236234000203710ustar00rootroot0000000000000011 0/a 1/a 2/a 3/a 4/a 5/a 6/a 7/a 8/a 9/a -jährig/bc hunspell-1.7.0/tests/digits_in_words.wrong000066400000000000000000000000111337236234000207530ustar00rootroot00000000000000-jährig hunspell-1.7.0/tests/dotless_i.aff000066400000000000000000000000221337236234000171530ustar00rootroot00000000000000SET UTF-8 LANG tr hunspell-1.7.0/tests/dotless_i.dic000066400000000000000000000000321337236234000171570ustar00rootroot000000000000003 iç ışık Diyarbakır hunspell-1.7.0/tests/dotless_i.good000066400000000000000000000000731337236234000173550ustar00rootroot00000000000000Diyarbakır DİYARBAKIR iç İç ışık Işık İÇ IŞIK hunspell-1.7.0/tests/dotless_i.wrong000066400000000000000000000000551337236234000175610ustar00rootroot00000000000000Diyarbakir DIYARBAKIR Iç İşık IÇ İŞIK hunspell-1.7.0/tests/encoding.aff000066400000000000000000000000201337236234000167520ustar00rootroot00000000000000SET ISO-8859-15 hunspell-1.7.0/tests/encoding.dic000066400000000000000000000000151337236234000167610ustar00rootroot000000000000002 cur uvre hunspell-1.7.0/tests/encoding.good000066400000000000000000000000321337236234000171510ustar00rootroot00000000000000cœur œuvre CŒUR ŒUVRE hunspell-1.7.0/tests/flag.aff000066400000000000000000000001761337236234000161110ustar00rootroot00000000000000# base 1-character flags SFX A Y 1 SFX A 0 s/123 . SFX 1 Y 1 SFX 1 0 bar . SFX 2 Y 1 SFX 2 0 baz . PFX 3 Y 1 PFX 3 0 un . hunspell-1.7.0/tests/flag.dic000066400000000000000000000000111337236234000161000ustar00rootroot000000000000001 foo/A3 hunspell-1.7.0/tests/flag.good000066400000000000000000000000721337236234000163000ustar00rootroot00000000000000foo foos foosbar foosbaz unfoo unfoos unfoosbar unfoosbaz hunspell-1.7.0/tests/flaglong.aff000066400000000000000000000002161337236234000167640ustar00rootroot00000000000000# 2-character flags FLAG long SFX zx Y 1 SFX zx 0 s/g?1G09 . SFX g? Y 1 SFX g? 0 bar . SFX 1G Y 1 SFX 1G 0 baz . PFX 09 Y 1 PFX 09 0 un . hunspell-1.7.0/tests/flaglong.dic000066400000000000000000000000131337236234000167620ustar00rootroot000000000000001 foo/zx09 hunspell-1.7.0/tests/flaglong.good000066400000000000000000000000721337236234000171600ustar00rootroot00000000000000foo foos foosbar foosbaz unfoo unfoos unfoosbar unfoosbaz hunspell-1.7.0/tests/flagnum.aff000066400000000000000000000002361337236234000166260ustar00rootroot00000000000000# numerical flags FLAG num SFX 999 Y 1 SFX 999 0 s/214,216,54321 . SFX 214 Y 1 SFX 214 0 bar . SFX 216 Y 1 SFX 216 0 baz . PFX 54321 Y 1 PFX 54321 0 un . hunspell-1.7.0/tests/flagnum.dic000066400000000000000000000000201337236234000166200ustar00rootroot000000000000001 foo/999,54321 hunspell-1.7.0/tests/flagnum.good000066400000000000000000000000721337236234000170200ustar00rootroot00000000000000foo foos foosbar foosbaz unfoo unfoos unfoosbar unfoosbaz hunspell-1.7.0/tests/flagutf8.aff000066400000000000000000000002351337236234000167140ustar00rootroot00000000000000# UTF-8 flags FLAG UTF-8 SFX A Y 1 SFX A 0 s/ÖüÜ . #SFX A 0 s/ÖüÖÜ . SFX Ö Y 1 SFX Ö 0 bar . SFX ü Y 1 SFX ü 0 baz . PFX Ü Y 1 PFX Ü 0 un . hunspell-1.7.0/tests/flagutf8.dic000066400000000000000000000000121337236234000167100ustar00rootroot000000000000001 foo/AÜ hunspell-1.7.0/tests/flagutf8.good000066400000000000000000000000721337236234000171070ustar00rootroot00000000000000foo foos foosbar foosbaz unfoo unfoos unfoosbar unfoosbaz hunspell-1.7.0/tests/fogemorpheme.aff000066400000000000000000000003071337236234000176510ustar00rootroot00000000000000# fogemorphemes: special morphemes in compounds # # Swedish example: # gata + kontoret = gatukontoret COMPOUNDFLAG X COMPOUNDBEGIN Y ONLYINCOMPOUND Z COMPOUNDPERMITFLAG P SFX A Y 1 SFX A a u/YPZ . hunspell-1.7.0/tests/fogemorpheme.dic000066400000000000000000000000241337236234000176500ustar00rootroot000000000000002 gata/A kontoret/X hunspell-1.7.0/tests/fogemorpheme.good000066400000000000000000000000331337236234000200410ustar00rootroot00000000000000gata kontoret gatukontoret hunspell-1.7.0/tests/fogemorpheme.wrong000066400000000000000000000000371337236234000202510ustar00rootroot00000000000000gatu gatakontoret kontoretgatu hunspell-1.7.0/tests/forbiddenword.aff000066400000000000000000000003411337236234000200220ustar00rootroot00000000000000# FORBIDDENWORD flag # The signed word, and its suffixed forms are all forbidden, # excepts with root homonyms. # Useful for forbidding bad suffixed forms or compounds. FORBIDDENWORD X COMPOUNDFLAG Y SFX A Y 1 SFX A 0 s . hunspell-1.7.0/tests/forbiddenword.dic000066400000000000000000000001041337236234000200220ustar00rootroot000000000000005 foo/S [1] foo/YX [2] foo/Y [3] foo/S [4] bar/YS [5] bars/X foos/X hunspell-1.7.0/tests/forbiddenword.good000066400000000000000000000000111337236234000202100ustar00rootroot00000000000000foo bar hunspell-1.7.0/tests/forbiddenword.wrong000066400000000000000000000000301337236234000204150ustar00rootroot00000000000000bars foos foobar barfoo hunspell-1.7.0/tests/forceucase.aff000066400000000000000000000000771337236234000173170ustar00rootroot00000000000000# force capitalized compound TRY F FORCEUCASE A COMPOUNDFLAG C hunspell-1.7.0/tests/forceucase.dic000066400000000000000000000000251337236234000173130ustar00rootroot000000000000003 foo/C bar/C baz/CA hunspell-1.7.0/tests/forceucase.good000066400000000000000000000000561337236234000175100ustar00rootroot00000000000000foo bar baz foobar Foobaz foobazbar Foobarbaz hunspell-1.7.0/tests/forceucase.sug000066400000000000000000000000211337236234000173460ustar00rootroot00000000000000Foobaz Foobarbaz hunspell-1.7.0/tests/forceucase.wrong000066400000000000000000000000211337236234000177040ustar00rootroot00000000000000foobaz foobarbaz hunspell-1.7.0/tests/fullstrip.aff000066400000000000000000000006121337236234000172170ustar00rootroot00000000000000# FULLSTRIP option: Hunspell can strip full words by affix rules # see OpenOffice.org Issue #80145 # test data from Davide Prina FULLSTRIP SET ISO8859-15 TRY aioertnsclmdpgubzfvhàq'ACMSkBGPLxEyRTVòIODNwFéùèìjUZKHWJYQX SFX A Y 3 # verbo andare (verb to go) SFX A andare vado andare # io vado (I go) SFX A andare va andare # tu vai (you go) SFX A are iamo andare # noi andiamo (we go) hunspell-1.7.0/tests/fullstrip.dic000066400000000000000000000000271337236234000172220ustar00rootroot000000000000002 andare/A riandare/A hunspell-1.7.0/tests/fullstrip.good000066400000000000000000000000671337236234000174170ustar00rootroot00000000000000andare vado va andiamo riandare rivado riva riandiamo hunspell-1.7.0/tests/germancompounding.aff000066400000000000000000000030531337236234000207110ustar00rootroot00000000000000# German compounding # handle special casing of German sharp s CHECKSHARPS # compound flags COMPOUNDBEGIN U COMPOUNDMIDDLE V COMPOUNDEND W # Prefixes are allowed at the beginning of compounds, # suffixes are allowed at the end of compounds by default: # (prefix)?(root)+(affix)? # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. COMPOUNDPERMITFLAG P # for German fogemorphemes (Fuge-element) # Hint: ONLYINCOMPOUND is not required everywhere, but the # checking will be a little faster with it. ONLYINCOMPOUND X # forbid uppercase characters at compound word bounds CHECKCOMPOUNDCASE # for handling Fuge-elements with dashes (Arbeits-) # dash will be a special word COMPOUNDMIN 1 WORDCHARS - # compound settings and fogemorpheme for `Arbeit' SFX A Y 3 SFX A 0 s/UPX . SFX A 0 s/VPDX . SFX A 0 0/WXD . SFX B Y 2 SFX B 0 0/UPX . SFX B 0 0/VWXDP . # a suffix for `Computer' SFX C Y 1 SFX C 0 n/WD . # for forbid exceptions (*Arbeitsnehmer) FORBIDDENWORD Z # dash prefix for compounds with dash (Arbeits-Computer) PFX - Y 1 PFX - 0 -/P . # decapitalizing prefix # circumfix for positioning in compounds PFX D Y 29 PFX D A a/PX A PFX D /PX PFX D B b/PX B PFX D C c/PX C PFX D D d/PX D PFX D E e/PX E PFX D F f/PX F PFX D G g/PX G PFX D H h/PX H PFX D I i/PX I PFX D J j/PX J PFX D K k/PX K PFX D L l/PX L PFX D M m/PX M PFX D N n/PX N PFX D O o/PX O PFX D /PX PFX D P p/PX P PFX D Q q/PX Q PFX D R r/PX R PFX D S s/PX S PFX D T t/PX T PFX D U u/PX U PFX D /PX PFX D V v/PX V PFX D W w/PX W PFX D X x/PX X PFX D Y y/PX Y PFX D Z z/PX Z hunspell-1.7.0/tests/germancompounding.dic000066400000000000000000000000551337236234000207130ustar00rootroot000000000000004 Arbeit/A- Computer/BC- -/W Arbeitsnehmer/Z hunspell-1.7.0/tests/germancompounding.good000066400000000000000000000005531337236234000211070ustar00rootroot00000000000000Computer Computern Arbeit Arbeits- Computerarbeit Computerarbeits- Arbeitscomputer Computercomputer Computercomputern Arbeitscomputern Computerarbeitscomputer Computerarbeitscomputern Arbeitscomputercomputer Computercomputerarbeit Arbeitscomputerarbeit Arbeitsarbeitsarbeit Computerarbeitsarbeit Computerarbeits-Computer Computerarbeits-Computern Computer-Arbeit hunspell-1.7.0/tests/germancompounding.wrong000066400000000000000000000016011337236234000213060ustar00rootroot00000000000000computer computern arbeit Arbeits arbeits ComputerArbeit ComputernArbeit Computernarbeit ComputerArbeits Arbeitcomputer Arbeitcomputern ArbeitsComputer ArbeitsComputern Computerarbeitcomputer ComputerArbeitcomputer ComputerArbeitscomputer Computerarbeitcomputern ComputerArbeitcomputern ComputerArbeitscomputern Arbeitscomputerarbeits Arbeitscomputernarbeits Computerarbeits-computer Arbeitsnehmer computers computern computernarbeit computernArbeit computerArbeit computerArbeits arbeitcomputer arbeitsComputer computerarbeitcomputer computerArbeitcomputer computerArbeitscomputer arbeitscomputerarbeits computerarbeits-computer arbeitsnehmer computernarbeit computernArbeit arbeits- computerarbeit computerarbeits- arbeitscomputer arbeitscomputern computerarbeitscomputer computerarbeitscomputern computerarbeitscomputers arbeitscomputerarbeit computerarbeits-Computer computerarbeits-Computern hunspell-1.7.0/tests/germancompoundingold.aff000066400000000000000000000032021337236234000214040ustar00rootroot00000000000000# German compounding # handle special casing of German sharp s CHECKSHARPS # compound flags COMPOUNDBEGIN U COMPOUNDMIDDLE V COMPOUNDEND W # Prefixes are allowed at the beginning of compounds, # suffixes are allowed at the end of compounds by default: # (prefix)?(root)+(affix)? # Affixes with COMPOUNDPERMITFLAG may be inside of compounds. COMPOUNDPERMITFLAG P # for German fogemorphemes (Fuge-element) # Hint: ONLYINCOMPOUND is not required everywhere, but the # checking will be a little faster with it. ONLYINCOMPOUND X # for decapitalizing nouns with fogemorphemes CIRCUMFIX Y # for handling Fuge-elements with dashes (Arbeits-) # dash will be a special word COMPOUNDMIN 1 WORDCHARS - # compound settings and fogemorpheme for `Arbeit' SFX A Y 3 SFX A 0 s/UPX . SFX A 0 s/VPXDY . SFX A 0 0/WXDY . # compound settings for `Computer' SFX B Y 2 SFX B 0 0/UPX . SFX B 0 0/VWPXDY . # a suffix for `Computer' SFX C Y 2 SFX C 0 n . SFX C 0 n/WXDY . # for forbid exceptions (*Arbeitsnehmer) FORBIDDENWORD Z # dash prefix for compounds with dash (Arbeits-Computer) PFX - Y 2 PFX - 0 -/PUVW . PFX - 0 -/PY . # decapitalizing prefix # circumfix for positioning in compounds PFX D Y 29 PFX D A a/PXY A PFX D /PXY PFX D B b/PXY B PFX D C c/PXY C PFX D D d/PXY D PFX D E e/PXY E PFX D F f/PXY F PFX D G g/PXY G PFX D H h/PXY H PFX D I i/PXY I PFX D J j/PXY J PFX D K k/PXY K PFX D L l/PXY L PFX D M m/PXY M PFX D N n/PXY N PFX D O o/PXY O PFX D /PXY PFX D P p/PXY P PFX D Q q/PXY Q PFX D R r/PXY R PFX D S s/PXY S PFX D T t/PXY T PFX D U u/PXY U PFX D /PXY PFX D V v/PXY V PFX D W w/PXY W PFX D X x/PXY X PFX D Y y/PXY Y PFX D Z z/PXY Z hunspell-1.7.0/tests/germancompoundingold.dic000066400000000000000000000000551337236234000214120ustar00rootroot000000000000004 Arbeit/A- Computer/BC- -/W Arbeitsnehmer/Z hunspell-1.7.0/tests/germancompoundingold.good000066400000000000000000000003561337236234000216070ustar00rootroot00000000000000Computer Computern Arbeit Arbeits- Computerarbeit Computerarbeits- Arbeitscomputer Arbeitscomputern Computerarbeitscomputer Computerarbeitscomputern Arbeitscomputerarbeit Computerarbeits-Computer Computerarbeits-Computern Computer-Arbeit hunspell-1.7.0/tests/germancompoundingold.wrong000066400000000000000000000016011337236234000220050ustar00rootroot00000000000000computer computern arbeit Arbeits arbeits ComputerArbeit ComputernArbeit Computernarbeit ComputerArbeits Arbeitcomputer Arbeitcomputern ArbeitsComputer ArbeitsComputern Computerarbeitcomputer ComputerArbeitcomputer ComputerArbeitscomputer Computerarbeitcomputern ComputerArbeitcomputern ComputerArbeitscomputern Arbeitscomputerarbeits Arbeitscomputernarbeits Computerarbeits-computer Arbeitsnehmer computers computern computernarbeit computernArbeit computerArbeit computerArbeits arbeitcomputer arbeitsComputer computerarbeitcomputer computerArbeitcomputer computerArbeitscomputer arbeitscomputerarbeits computerarbeits-computer arbeitsnehmer computernarbeit computernArbeit arbeits- computerarbeit computerarbeits- arbeitscomputer arbeitscomputern computerarbeitscomputer computerarbeitscomputern computerarbeitscomputers arbeitscomputerarbeit computerarbeits-Computer computerarbeits-Computern hunspell-1.7.0/tests/hu.aff000066400000000000000000000020031337236234000156030ustar00rootroot00000000000000SET UTF-8 LANG hu_HU # words with flag Y can form compound words COMPOUNDFLAG Y # min. word length in compounds: # allow 2-letter words COMPOUNDMIN 2 # max. word count in compounds COMPOUNDWORDMAX 2 # exception for Hungarian: # allow more words in a compound, than COMPOUNDWORDMAX, # if syllable count of the compound is 6 or less COMPOUNDSYLLABLE 6 aáeéiíoóöőuúüű # test case for commit 1fada01 "fix other regression in compounding" REP 1 REP kor _kor CHECKCOMPOUNDREP # to check word breaking WORDCHARS - BREAK 1 BREAK - # to check COMPOUNDFORBIDFLAG and spec. Hungarian compounding COMPOUNDPERMITFLAG + COMPOUNDFORBIDFLAG ! # SFX F suffix "-ó" is allowed in compounds by COMPOUNDPERMITFLAG, # but the generated word form "forró" is forbidden in compound # by the dictionary item "forró" with COMPOUNDFORBIDFLAG # # Exception: in special Hungarian "moving rule" (hard-wired to the # flag "F" in a LANG_hu code), "forró" can be in similar compounds: # "forróvíz-tartály" SFX S Y 1 SFX S 0 ó/Y+ . hunspell-1.7.0/tests/hu.dic000066400000000000000000000003321337236234000156110ustar00rootroot0000000000000020 majom/Y kenyér/Y fa/Y ág/Y virág/Y sárkány/Y fog/Y vetemény/Y iskola/Y tej/Y akció/Y devon/Y kor/Y társ/Y devon kor e-mail cím Strattmann Strattmann-nal Batthyány áll/S forr/S víz/Y tartály/Y forró/F! hunspell-1.7.0/tests/hu.good000066400000000000000000000004101337236234000157770ustar00rootroot00000000000000majomkenyér majomkenyérfa majomkenyérfaág majomkenyérvirág kenyérfavirág sárkányfogvetemény kortárs e-mail-cím Batthyány Strattmann Strattmann-nal Batthyány-Strattmann Batthyány-Strattmann-nal áll álló forr forró állóvíz forróvíz-tartály hunspell-1.7.0/tests/hu.wrong000066400000000000000000000000711337236234000162060ustar00rootroot00000000000000majomkenyérfavirág iskolatejakció devonkor forróvíz hunspell-1.7.0/tests/i35725.aff000066400000000000000000000060411337236234000160330ustar00rootroot00000000000000# Ngram suggestions # - fix case problem # - detect character swapping (keep only these suggestions) # - lesser suggestions # - weight with common subsequence algorithm # - suggest uppercased words # 2007-02-05: # now not neighbour character replacements and character movings are # detected by not ngram suggestions, too. # OpenOffice.org's en_US.aff file SET ISO8859-1 TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ' WORDCHARS ' PFX A Y 1 PFX A 0 re . PFX I Y 1 PFX I 0 in . PFX U Y 1 PFX U 0 un . PFX C Y 1 PFX C 0 de . PFX E Y 1 PFX E 0 dis . PFX F Y 1 PFX F 0 con . PFX K Y 1 PFX K 0 pro . SFX V N 2 SFX V e ive e SFX V 0 ive [^e] SFX N Y 3 SFX N e ion e SFX N y ication y SFX N 0 en [^ey] SFX X Y 3 SFX X e ions e SFX X y ications y SFX X 0 ens [^ey] SFX H N 2 SFX H y ieth y SFX H 0 th [^y] SFX Y Y 1 SFX Y 0 ly . SFX G Y 2 SFX G e ing e SFX G 0 ing [^e] SFX J Y 2 SFX J e ings e SFX J 0 ings [^e] SFX D Y 4 SFX D 0 d e SFX D y ied [^aeiou]y SFX D 0 ed [^ey] SFX D 0 ed [aeiou]y SFX T N 4 SFX T 0 st e SFX T y iest [^aeiou]y SFX T 0 est [aeiou]y SFX T 0 est [^ey] SFX R Y 4 SFX R 0 r e SFX R y ier [^aeiou]y SFX R 0 er [aeiou]y SFX R 0 er [^ey] SFX Z Y 4 SFX Z 0 rs e SFX Z y iers [^aeiou]y SFX Z 0 ers [aeiou]y SFX Z 0 ers [^ey] SFX S Y 4 SFX S y ies [^aeiou]y SFX S 0 s [aeiou]y SFX S 0 es [sxzh] SFX S 0 s [^sxzhy] SFX P Y 3 SFX P y iness [^aeiou]y SFX P 0 ness [aeiou]y SFX P 0 ness [^y] SFX M Y 1 SFX M 0 's . SFX B Y 3 SFX B 0 able [^aeiou] SFX B 0 able ee SFX B e able [^aeiou]e SFX L Y 1 SFX L 0 ment . REP 88 REP a ei REP ei a REP a ey REP ey a REP ai ie REP ie ai REP are air REP are ear REP are eir REP air are REP air ere REP ere air REP ere ear REP ere eir REP ear are REP ear air REP ear ere REP eir are REP eir ere REP ch te REP te ch REP ch ti REP ti ch REP ch tu REP tu ch REP ch s REP s ch REP ch k REP k ch REP f ph REP ph f REP gh f REP f gh REP i igh REP igh i REP i uy REP uy i REP i ee REP ee i REP j di REP di j REP j gg REP gg j REP j ge REP ge j REP s ti REP ti s REP s ci REP ci s REP k cc REP cc k REP k qu REP qu k REP kw qu REP o eau REP eau o REP o ew REP ew o REP oo ew REP ew oo REP ew ui REP ui ew REP oo ui REP ui oo REP ew u REP u ew REP oo u REP u oo REP u oe REP oe u REP u ieu REP ieu u REP ue ew REP ew ue REP uff ough REP oo ieu REP ieu oo REP ier ear REP ear ier REP ear air REP air ear REP w qu REP qu w REP z ss REP ss z REP shun tion REP shun sion REP shun cion hunspell-1.7.0/tests/i35725.dic000066400000000000000000000002731337236234000160370ustar00rootroot0000000000000015 endangerment/SM ferment/FSCM preferment/SM impermanent/Y permanent/YSP semipermanent/Y empowerment/MS supermen tournament/MS ornamental/SY ornament/GSDM supernatant pimpernel UNESCO/M hunspell-1.7.0/tests/i35725.good000066400000000000000000000000121337236234000162170ustar00rootroot00000000000000permanent hunspell-1.7.0/tests/i35725.sug000066400000000000000000000002101337236234000160650ustar00rootroot00000000000000permanent, preferment permanent, ornament permanent Permanent, Preferment Permanent, Ornament Permanent UNESCO UNESCO UNESCO's UNESCO's hunspell-1.7.0/tests/i35725.wrong000066400000000000000000000001341337236234000164300ustar00rootroot00000000000000permenant pernament pernemant Permenant Pernament Pernemant unesco Unesco unesco's Unesco's hunspell-1.7.0/tests/i53643.aff000066400000000000000000000000701337236234000160260ustar00rootroot00000000000000# check numbers with separators WORDCHARS 0123456789.-, hunspell-1.7.0/tests/i53643.dic000066400000000000000000000000061337236234000160300ustar00rootroot000000000000001 foo hunspell-1.7.0/tests/i53643.good000066400000000000000000000002061337236234000162230ustar00rootroot000000000000001 12 123 1234 12345 123456 1234567 1.1 1.12 1.123 1.1234 1.12345 1.123456 12.1 123.12 1234.123 12345.1234 123456.12345 1234567.123456 hunspell-1.7.0/tests/i53643.wrong000066400000000000000000000000241337236234000164250ustar00rootroot000000000000001..2 1,,2 1.,2 1,.2 hunspell-1.7.0/tests/i54633.aff000066400000000000000000000001111337236234000160220ustar00rootroot00000000000000# Missing capitalized suggestion for capitalized bad words SET ISO8859-1 hunspell-1.7.0/tests/i54633.dic000066400000000000000000000000111337236234000160240ustar00rootroot000000000000001 diter hunspell-1.7.0/tests/i54633.good000066400000000000000000000000201337236234000162150ustar00rootroot00000000000000éditer Éditer hunspell-1.7.0/tests/i54633.sug000066400000000000000000000000201337236234000160630ustar00rootroot00000000000000éditer Éditer hunspell-1.7.0/tests/i54633.wrong000066400000000000000000000000161337236234000164260ustar00rootroot00000000000000editer Editer hunspell-1.7.0/tests/i54980.aff000066400000000000000000000001341337236234000160340ustar00rootroot00000000000000# ISO-8859-15 (extended latin-1) support for French, Finnish and EURO symbol SET ISO8859-15 hunspell-1.7.0/tests/i54980.dic000066400000000000000000000000151337236234000160350ustar00rootroot000000000000002 cur uvre hunspell-1.7.0/tests/i54980.good000066400000000000000000000000321337236234000162250ustar00rootroot00000000000000cœur œuvre CŒUR ŒUVRE hunspell-1.7.0/tests/i58202.aff000066400000000000000000000000761337236234000160300ustar00rootroot00000000000000# case suggestions MAXNGRAMSUGS 0 # capitalise baz->Baz TRY B hunspell-1.7.0/tests/i58202.dic000066400000000000000000000000221337236234000160220ustar00rootroot000000000000004 foo bar Baz Boo hunspell-1.7.0/tests/i58202.good000066400000000000000000000000501337236234000162140ustar00rootroot00000000000000foo bar Foo Bar Baz Boo FOO BAR BAZ BOO hunspell-1.7.0/tests/i58202.sug000066400000000000000000000001351337236234000160660ustar00rootroot00000000000000foo, Boo Bar Baz Boo foo bar foo Bar Foo bar Foo Bar foo Baz Foo Baz Baz foo Baz Foo Baz Boo hunspell-1.7.0/tests/i58202.wrong000066400000000000000000000001171337236234000164240ustar00rootroot00000000000000fOO BAr baz BOo foobar fooBar Foobar FooBar fooBaz FooBaz Bazfoo BazFoo BazBoo hunspell-1.7.0/tests/i68568.aff000066400000000000000000000001501337236234000160410ustar00rootroot00000000000000# Sant'Elia -> SANT'ELIA (Italian) # OpenOffice.org Issue 68658 PFX a Y 1 PFX a 0 Sant' E WORDCHARS ' hunspell-1.7.0/tests/i68568.dic000066400000000000000000000000111337236234000160400ustar00rootroot000000000000001 Elia/a hunspell-1.7.0/tests/i68568.wrong000066400000000000000000000000521337236234000164420ustar00rootroot00000000000000sant'elia sant'Elia Sant'elia Sant' SANT' hunspell-1.7.0/tests/i68568utf.aff000066400000000000000000000001621337236234000165630ustar00rootroot00000000000000# Sant'Elia -> SANT'ELIA (Italian) # OpenOffice.org Issue 68658 SET UTF-8 PFX a Y 1 PFX a 0 Foó' B WORDCHARS ' hunspell-1.7.0/tests/i68568utf.dic000066400000000000000000000000111337236234000165570ustar00rootroot000000000000001 Bár/a hunspell-1.7.0/tests/i68568utf.wrong000066400000000000000000000000521337236234000171610ustar00rootroot00000000000000foó'bár foó'Bár Foó'bár foó' FOÓ' hunspell-1.7.0/tests/iconv.aff000066400000000000000000000002731337236234000163140ustar00rootroot00000000000000# input conversion (accept comma acuted letters also with cedilla, # as de facto replacement of the Romanian standard) SET UTF-8 ICONV 4 ICONV ş ș ICONV ţ ț ICONV Ş Ș ICONV Ţ Ț hunspell-1.7.0/tests/iconv.dic000066400000000000000000000000321337236234000163100ustar00rootroot000000000000004 Chișinău Țepes ț Ș hunspell-1.7.0/tests/iconv.good000066400000000000000000000000521337236234000165030ustar00rootroot00000000000000Chișinău Chişinău Țepes Ţepes Ş ţ hunspell-1.7.0/tests/iconv2.aff000066400000000000000000000002151337236234000163720ustar00rootroot00000000000000# The longer input pattern should be used if matched ICONV 6 ICONV Da DA ICONV Ga GA ICONV Gag GAG ICONV Gagg GAGG ICONV Na NA ICONV Nan NAN hunspell-1.7.0/tests/iconv2.dic000066400000000000000000000000301337236234000163700ustar00rootroot000000000000004 GAG GAGGNA GANA NANDA hunspell-1.7.0/tests/iconv2.good000066400000000000000000000000261337236234000165660ustar00rootroot00000000000000GaNa Gag GaggNa NanDa hunspell-1.7.0/tests/ignore.aff000066400000000000000000000001501337236234000164530ustar00rootroot00000000000000# ignore characters in words (for Arabic Harakat or Hebrew niqqud) IGNORE aeiou PFX A Y 1 PFX A 0 re . hunspell-1.7.0/tests/ignore.dic000066400000000000000000000000241337236234000164560ustar00rootroot000000000000002 xmpl expression/A hunspell-1.7.0/tests/ignore.good000066400000000000000000000000641337236234000166530ustar00rootroot00000000000000example expression xmpl xprssn reexpression rxprssn hunspell-1.7.0/tests/ignoresug.aff000066400000000000000000000005431337236234000172000ustar00rootroot00000000000000# Ignore punctuation marks used inside of Armenian words, and produce correct # suggestion (see issue #570). However, "suggestion test" cannot be used because # words in `.wrong` file are not wrong realy, so it leads to an error. # Therefore, we apply "morphological analysis" which has a similar result. SET UTF-8 WORDCHARS ֊՛՜՞՚ IGNORE ֊՛՜՞՚ hunspell-1.7.0/tests/ignoresug.dic000066400000000000000000000000351337236234000171770ustar00rootroot000000000000003 ինչ մնաս որտեղ hunspell-1.7.0/tests/ignoresug.good000066400000000000000000000000741337236234000173730ustar00rootroot00000000000000ինչ ի՞նչ մնաս մնա՜ս որտեղ որտե՞ղ hunspell-1.7.0/tests/ignoresug.morph000066400000000000000000000006661337236234000175770ustar00rootroot00000000000000> ինչ analyze(ինչ) = st:ինչ stem(ինչ) = ինչ > ի՞նչ analyze(ի՞նչ) = st:ինչ stem(ի՞նչ) = ինչ > մնաս analyze(մնաս) = st:մնաս stem(մնաս) = մնաս > մնա՜ս analyze(մնա՜ս) = st:մնաս stem(մնա՜ս) = մնաս > որտեղ analyze(որտեղ) = st:որտեղ stem(որտեղ) = որտեղ > որտե՞ղ analyze(որտե՞ղ) = st:որտեղ stem(որտե՞ղ) = որտեղ hunspell-1.7.0/tests/ignoreutf.aff000066400000000000000000000003361337236234000172000ustar00rootroot00000000000000# Arabic test for feature ignoring diacritics SET UTF-8 # Arabic diacritics (harakat): # sukun, shadda, kasra, damma, fatha, kasratan, dammantan, fathatan (left to right) IGNORE ًٌٍَُِّْ WORDCHARS ًٌٍَُِّْ hunspell-1.7.0/tests/ignoreutf.dic000066400000000000000000000001511337236234000171760ustar00rootroot000000000000009 طِير فَتحة ضُمة كِسرة فتحًتان ضمتانٌ كسرتاٍن شدّة سكوْن hunspell-1.7.0/tests/ignoreutf.good000066400000000000000000000001361337236234000173720ustar00rootroot00000000000000طير فتحة ضمة كسرة فتحتان ضمتان كسرتان شدة سكون hunspell-1.7.0/tests/keepcase.aff000066400000000000000000000000631337236234000167530ustar00rootroot00000000000000# keep case in signed words KEEPCASE A WORDCHARS . hunspell-1.7.0/tests/keepcase.dic000066400000000000000000000000351337236234000167550ustar00rootroot000000000000004 foo/A Bar/A baz./A Quux./A hunspell-1.7.0/tests/keepcase.good000066400000000000000000000000231337236234000171430ustar00rootroot00000000000000foo Bar baz. Quux. hunspell-1.7.0/tests/keepcase.sug000066400000000000000000000000541337236234000170150ustar00rootroot00000000000000foo foo Bar Bar, baz. baz. baz. Quux. Quux. hunspell-1.7.0/tests/keepcase.wrong000066400000000000000000000000461337236234000173540ustar00rootroot00000000000000Foo FOO BAR bar Baz. BAZ. quux. QUUX. hunspell-1.7.0/tests/korean.aff000066400000000000000000000000121337236234000164440ustar00rootroot00000000000000SET UTF-8 hunspell-1.7.0/tests/korean.dic000066400000000000000000000000421337236234000164520ustar00rootroot000000000000002 들어오세요 안녕하세요 hunspell-1.7.0/tests/korean.good000066400000000000000000000000401337236234000166410ustar00rootroot00000000000000들어오세요 안녕하세요 hunspell-1.7.0/tests/korean.wrong000066400000000000000000000000151337236234000170470ustar00rootroot00000000000000들어오세 hunspell-1.7.0/tests/map.aff000066400000000000000000000002361337236234000157520ustar00rootroot00000000000000# With MAP suggestion, Hunspell can add missing accents to a word. # switch off ngram suggestion for testing MAXNGRAMSUGS 0 MAP 3 MAP u MAP o MAP (ss) hunspell-1.7.0/tests/map.dic000066400000000000000000000000331337236234000157500ustar00rootroot000000000000003 Frhstck tkrfr gro hunspell-1.7.0/tests/map.sug000066400000000000000000000000401337236234000160050ustar00rootroot00000000000000Frühstück tükörfúró groß hunspell-1.7.0/tests/map.wrong000066400000000000000000000000321337236234000163440ustar00rootroot00000000000000Fruhstuck tukorfuro gross hunspell-1.7.0/tests/maputf.aff000066400000000000000000000002561337236234000164730ustar00rootroot00000000000000# With MAP suggestion, Hunspell can add missing accents to a word. SET UTF-8 # switch off ngram suggestion for testing MAXNGRAMSUGS 0 MAP 3 MAP uúü MAP öóo MAP ß(ss) hunspell-1.7.0/tests/maputf.dic000066400000000000000000000000421337236234000164670ustar00rootroot000000000000003 Frühstück tükörfúró groß hunspell-1.7.0/tests/maputf.sug000066400000000000000000000000401337236234000165240ustar00rootroot00000000000000Frühstück tükörfúró groß hunspell-1.7.0/tests/maputf.wrong000066400000000000000000000000321337236234000170630ustar00rootroot00000000000000Fruhstuck tukorfuro gross hunspell-1.7.0/tests/morph.aff000066400000000000000000000003241337236234000163200ustar00rootroot00000000000000# example for morphological analysis, stemming and generation PFX P Y 1 PFX P 0 un . dp:pfx_un sp:un SFX S Y 1 SFX S 0 s . is:plur SFX Q Y 1 SFX Q 0 s . is:sg_3 SFX R Y 1 SFX R 0 able/PS . ds:der_able hunspell-1.7.0/tests/morph.dic000066400000000000000000000004601337236234000163240ustar00rootroot000000000000009 drink/S po:noun drink/RQ po:verb al:drank al:drunk ts:present drank po:verb st:drink is:past_1 drunk po:verb st:drink is:past_2 eat/RQ po:verb al:ate al:eaten ts:present ate po:verb st:eat is:past_1 eaten po:verb st:eat is:past_2 phenomenon po:noun al:phenomena phenomena po:noun st:phenomenon is:plur hunspell-1.7.0/tests/morph.good000066400000000000000000000004731337236234000165210ustar00rootroot00000000000000drink drinks drinkable drinkables undrinkable undrinkables drank drunk phenomenon phenomena drink eat drink eats drink ate drink eaten drink eatable drink eatables drink phenomena drinks eat drinks eats drinks ate drinks eaten drinks eatable drinks eatables drinks phenomena undrinkable phenomena phenomenon drinks hunspell-1.7.0/tests/morph.morph000066400000000000000000000032741337236234000167200ustar00rootroot00000000000000> drink analyze(drink) = st:drink po:noun analyze(drink) = st:drink po:verb al:drank al:drunk ts:present stem(drink) = drink > drinks analyze(drinks) = st:drink po:verb al:drank al:drunk ts:present is:sg_3 analyze(drinks) = st:drink po:noun is:plur stem(drinks) = drink > drinkable analyze(drinkable) = st:drink po:verb al:drank al:drunk ts:present ds:der_able stem(drinkable) = drinkable > drinkables analyze(drinkables) = st:drink po:verb al:drank al:drunk ts:present ds:der_able is:plur stem(drinkables) = drinkable > undrinkable analyze(undrinkable) = dp:pfx_un sp:un st:drink po:verb al:drank al:drunk ts:present ds:der_able stem(undrinkable) = undrinkable > undrinkables analyze(undrinkables) = dp:pfx_un sp:un st:drink po:verb al:drank al:drunk ts:present ds:der_able is:plur stem(undrinkables) = undrinkable > drank analyze(drank) = po:verb st:drink is:past_1 stem(drank) = drink > drunk analyze(drunk) = po:verb st:drink is:past_2 stem(drunk) = drink > phenomenon analyze(phenomenon) = st:phenomenon po:noun al:phenomena stem(phenomenon) = phenomenon > phenomena analyze(phenomena) = po:noun st:phenomenon is:plur stem(phenomena) = phenomenon generate(drink, eat) = drink generate(drink, eats) = drinks generate(drink, ate) = drank generate(drink, eaten) = drunk generate(drink, eatable) = drinkable generate(drink, eatables) = drinkables generate(drink, phenomena) = drinks generate(drinks, eat) = drink generate(drinks, eats) = drinks generate(drinks, ate) = drank generate(drinks, eaten) = drunk generate(drinks, eatable) = drinkable generate(drinks, eatables) = drinkables generate(drinks, phenomena) = drinks generate(undrinkable, phenomena) = undrinkables generate(phenomenon, drinks) = phenomena hunspell-1.7.0/tests/needaffix.aff000066400000000000000000000000641337236234000171250ustar00rootroot00000000000000NEEDAFFIX X COMPOUNDFLAG Y SFX A Y 1 SFX A 0 s/Y . hunspell-1.7.0/tests/needaffix.dic000066400000000000000000000000201337236234000171200ustar00rootroot000000000000002 foo/YXA bar/Y hunspell-1.7.0/tests/needaffix.good000066400000000000000000000000211337236234000173120ustar00rootroot00000000000000bar foos barfoos hunspell-1.7.0/tests/needaffix.wrong000066400000000000000000000000041337236234000175170ustar00rootroot00000000000000foo hunspell-1.7.0/tests/needaffix2.aff000066400000000000000000000000331337236234000172030ustar00rootroot00000000000000NEEDAFFIX X COMPOUNDFLAG Y hunspell-1.7.0/tests/needaffix2.dic000066400000000000000000000000751337236234000172140ustar00rootroot000000000000004 foo st:foo id:1 foo/YX st:foo id:2 foo/Y st:foo id:3 bar/Y hunspell-1.7.0/tests/needaffix2.good000066400000000000000000000000271337236234000174020ustar00rootroot00000000000000foo bar foobar barfoo hunspell-1.7.0/tests/needaffix2.morph000066400000000000000000000004271337236234000176030ustar00rootroot00000000000000> foo analyze(foo) = st:foo id:1 analyze(foo) = st:foo id:3 stem(foo) = foo > bar analyze(bar) = st:bar stem(bar) = bar > foobar analyze(foobar) = pa:foo st:foo id:3 pa:bar stem(foobar) = foo > barfoo analyze(barfoo) = pa:bar st:bar pa:foo st:foo id:3 stem(barfoo) = barfoo hunspell-1.7.0/tests/needaffix3.aff000066400000000000000000000001271337236234000172100ustar00rootroot00000000000000# neeadaffix on affixes NEEDAFFIX X SFX A Y 1 SFX A 0 s/XB . SFX B Y 1 SFX B 0 baz . hunspell-1.7.0/tests/needaffix3.dic000066400000000000000000000000101337236234000172020ustar00rootroot000000000000002 foo/A hunspell-1.7.0/tests/needaffix3.good000066400000000000000000000000141337236234000173770ustar00rootroot00000000000000foo foosbaz hunspell-1.7.0/tests/needaffix3.wrong000066400000000000000000000000051337236234000176030ustar00rootroot00000000000000foos hunspell-1.7.0/tests/needaffix4.aff000066400000000000000000000000331337236234000172050ustar00rootroot00000000000000NEEDAFFIX X COMPOUNDFLAG Y hunspell-1.7.0/tests/needaffix4.dic000066400000000000000000000000531337236234000172120ustar00rootroot000000000000004 foo/X [1] foo/Y [2] foo/YX [3] bar/Y [4] hunspell-1.7.0/tests/needaffix4.good000066400000000000000000000000271337236234000174040ustar00rootroot00000000000000foo bar foobar barfoo hunspell-1.7.0/tests/needaffix5.aff000066400000000000000000000002231337236234000172070ustar00rootroot00000000000000# on affixes NEEDAFFIX X SFX A Y 2 SFX A 0 suf/B . SFX A 0 pseudosuf/XB . SFX B Y 1 SFX B 0 bar . PFX C Y 2 PFX C 0 pre . PFX C 0 pseudopre/X . hunspell-1.7.0/tests/needaffix5.dic000066400000000000000000000000111337236234000172050ustar00rootroot000000000000001 foo/AC hunspell-1.7.0/tests/needaffix5.good000066400000000000000000000002221337236234000174020ustar00rootroot00000000000000foo prefoo foosuf prefoosuf foosufbar prefoosufbar pseudoprefoosuf pseudoprefoosufbar pseudoprefoopseudosufbar prefoopseudosuf prefoopseudosufbar hunspell-1.7.0/tests/needaffix5.wrong000066400000000000000000000000601337236234000176060ustar00rootroot00000000000000pseudoprefoo foopseudosuf pseudoprefoopseudosuf hunspell-1.7.0/tests/nepali.aff000066400000000000000000000003051337236234000164420ustar00rootroot00000000000000SET UTF-8 IGNORE ￰ WORDCHARS ःािीॉॊोौॎॏॕॖॗ‌‍ ICONV 5 ICONV ‌_ ‌ ICONV र्‌य र्‌य ICONV र्‌व र्‌व ICONV ‌ ￰ ICONV ‍_ ￰ hunspell-1.7.0/tests/nepali.dic000066400000000000000000000000661337236234000164510ustar00rootroot000000000000004 अलम् क्यार न्न र्‌य hunspell-1.7.0/tests/nepali.good000066400000000000000000000000641337236234000166400ustar00rootroot00000000000000न्न न्‌न अलम्‍ र्‌य hunspell-1.7.0/tests/nepali.wrong000066400000000000000000000000551337236234000170440ustar00rootroot00000000000000र्य क्‍यार अलम्‌ hunspell-1.7.0/tests/ngram_utf_fix.aff000066400000000000000000000005561337236234000200320ustar00rootroot00000000000000# Test fix of suffixed ngram suggestions with UTF-8 encoding and long flags. # Based on Vitaly Piryatinsky's bug report and example. SET UTF-8 FLAG num PFX 101 Y 1 PFX 101 0 пред . SFX 1381 Y 1 SFX 1381 0 о . SFX 2000 Y 3 SFX 2000 0 ам . SFX 2000 0 ами . SFX 2000 0 ах . SFX 2022 Y 4 SFX 2022 0 а . SFX 2022 0 у . SFX 2022 0 ом . SFX 2022 0 е . hunspell-1.7.0/tests/ngram_utf_fix.dic000066400000000000000000000000371337236234000200270ustar00rootroot000000000000001 человек/2022,2000,101 hunspell-1.7.0/tests/ngram_utf_fix.good000066400000000000000000000000171337236234000202160ustar00rootroot00000000000000человек hunspell-1.7.0/tests/ngram_utf_fix.sug000066400000000000000000000000171337236234000200640ustar00rootroot00000000000000человек hunspell-1.7.0/tests/ngram_utf_fix.wrong000066400000000000000000000000421337236234000204200ustar00rootroot00000000000000времячко человеко hunspell-1.7.0/tests/nosuggest.aff000066400000000000000000000002571337236234000172160ustar00rootroot00000000000000# don't suggest word with NOSUGGEST flag (for example vulgar or obscene words) # See OpenOffice.org Issue #55498 # (nosuggest.sug is an empty file) NOSUGGEST A COMPOUNDFLAG B hunspell-1.7.0/tests/nosuggest.dic000066400000000000000000000000171337236234000172130ustar00rootroot000000000000001 foo/AB bar/B hunspell-1.7.0/tests/nosuggest.good000066400000000000000000000000221337236234000174000ustar00rootroot00000000000000foo foobar barfoo hunspell-1.7.0/tests/nosuggest.sug000066400000000000000000000000001337236234000172420ustar00rootroot00000000000000hunspell-1.7.0/tests/nosuggest.wrong000066400000000000000000000000251337236234000176070ustar00rootroot00000000000000foox foobarx barfoox hunspell-1.7.0/tests/oconv.aff000066400000000000000000000006351337236234000163240ustar00rootroot00000000000000# output conversion SET UTF-8 # Testing also whitespace and comments. OCONV 7 # space, space OCONV a A # tab, space, space OCONV á Á # tab, tab, space OCONV b B # tab, tab, tab OCONV c C # 2xspace, 2xspace, 2xtab OCONV d D # tab+space, space+tab, space OCONV e E # OCONV é É # Only comment. Note that line above ends with space+tab. # space # 2xspace # tab # 2xtab # space+tab # tab+space hunspell-1.7.0/tests/oconv.dic000066400000000000000000000000321337236234000163160ustar00rootroot000000000000003 bébé dádá aábcdeé hunspell-1.7.0/tests/oconv.good000066400000000000000000000000161337236234000165110ustar00rootroot00000000000000bébé dádá hunspell-1.7.0/tests/oconv.sug000066400000000000000000000000301337236234000163530ustar00rootroot00000000000000BÉBÉ DÁDÁ AÁBCDEÉ hunspell-1.7.0/tests/oconv.wrong000066400000000000000000000000221337236234000167120ustar00rootroot00000000000000béb dád aábcde hunspell-1.7.0/tests/oconv2.aff000066400000000000000000000001741337236234000164040ustar00rootroot00000000000000# tests OCONV conversion of root and morphes output SET UTF-8 ICONV 1 ICONV a ei OCONV 1 OCONV ei a SFX A Y 1 SFX A 0 s . hunspell-1.7.0/tests/oconv2.dic000066400000000000000000000000111337236234000163750ustar00rootroot000000000000001 eiei/A hunspell-1.7.0/tests/oconv2.good000066400000000000000000000000041337236234000165700ustar00rootroot00000000000000aas hunspell-1.7.0/tests/oconv2.morph000066400000000000000000000000601337236234000167670ustar00rootroot00000000000000> aas analyze(aas) = st:aa fl:A stem(aas) = aa hunspell-1.7.0/tests/oconv2.root000066400000000000000000000000031337236234000166220ustar00rootroot00000000000000aa hunspell-1.7.0/tests/oconv2.test000077500000000000000000000001241337236234000166250ustar00rootroot00000000000000#!/bin/sh DIR="`dirname $0`" NAME="`basename $0 .test`" $DIR/test.sh $NAME -i utf-8 hunspell-1.7.0/tests/onlyincompound.aff000066400000000000000000000001601337236234000202460ustar00rootroot00000000000000# words only in compounds (see also fogemorpheme example) ONLYINCOMPOUND O COMPOUNDFLAG A SFX B Y 1 SFX B 0 s . hunspell-1.7.0/tests/onlyincompound.dic000066400000000000000000000000231337236234000202470ustar00rootroot000000000000002 foo/A pseudo/OAB hunspell-1.7.0/tests/onlyincompound.good000066400000000000000000000000431337236234000204420ustar00rootroot00000000000000foo pseudofoo foopseudo foopseudos hunspell-1.7.0/tests/onlyincompound.sug000066400000000000000000000000001337236234000203010ustar00rootroot00000000000000hunspell-1.7.0/tests/onlyincompound.wrong000066400000000000000000000000171337236234000206470ustar00rootroot00000000000000pseudo pseudos hunspell-1.7.0/tests/onlyincompound2.aff000066400000000000000000000004001337236234000203250ustar00rootroot00000000000000# affixes only in compounds (see also fogemorpheme example) ONLYINCOMPOUND O COMPOUNDFLAG A COMPOUNDPERMITFLAG P SFX B Y 1 SFX B 0 s/OP . # obligate fogemorpheme by forbidding the stem (0) in compounds CHECKCOMPOUNDPATTERN 1 CHECKCOMPOUNDPATTERN 0/B /A hunspell-1.7.0/tests/onlyincompound2.dic000066400000000000000000000000221337236234000203300ustar00rootroot000000000000002 foo/A pseudo/AB hunspell-1.7.0/tests/onlyincompound2.good000066400000000000000000000000311337236234000205210ustar00rootroot00000000000000foo foopseudo pseudosfoo hunspell-1.7.0/tests/onlyincompound2.wrong000066400000000000000000000000351337236234000207310ustar00rootroot00000000000000pseudos foopseudos pseudofoo hunspell-1.7.0/tests/opentaal_cpdpat.aff000066400000000000000000000003221337236234000203270ustar00rootroot00000000000000FLAG long COMPOUNDBEGIN Ca COMPOUNDMIDDLE Cb COMPOUNDEND Cc COMPOUNDPERMITFLAG Cp ONLYINCOMPOUND Cx CHECKCOMPOUNDPATTERN 1 CHECKCOMPOUNDPATTERN /Ch /Xs SFX Ch Y 2 SFX Ch 0 s/CaCbCxCp . SFX Ch 0 s-/CaCbCcCp . hunspell-1.7.0/tests/opentaal_cpdpat.dic000066400000000000000000000000431337236234000203320ustar00rootroot000000000000003 schoonheid/Ch port/CcXs sport/Cc hunspell-1.7.0/tests/opentaal_cpdpat.good000066400000000000000000000000211337236234000205170ustar00rootroot00000000000000schoonheidssport hunspell-1.7.0/tests/opentaal_cpdpat.wrong000066400000000000000000000000201337236234000207220ustar00rootroot00000000000000schoonheidsport hunspell-1.7.0/tests/opentaal_cpdpat2.aff000066400000000000000000000006571337236234000204240ustar00rootroot00000000000000# Test file based on OpenTaal's Dutch dictionary, coded by Ruud Baars WORDCHARS - NOSPLITSUGS FLAG long COMPOUNDBEGIN Ca COMPOUNDMIDDLE Cb COMPOUNDEND Cc COMPOUNDPERMITFLAG Cp ONLYINCOMPOUND Cx CHECKCOMPOUNDPATTERN 2 CHECKCOMPOUNDPATTERN 0/Ch /Xs CHECKCOMPOUNDPATTERN 0/Xm /Xm SFX CA Y 2 SFX CA 0 /CaCp . SFX CA 0 -/CaCp . SFX CB Y 2 SFX CB 0 /CbCp . SFX CB 0 -/CbCp . SFX Ch Y 2 SFX Ch 0 s/CaCbCxCp . SFX Ch 0 s-/CaCbCcCp . hunspell-1.7.0/tests/opentaal_cpdpat2.dic000066400000000000000000000000511337236234000204130ustar00rootroot00000000000000100 test/CACBCc zout/CACBXm suiker/CACBXmhunspell-1.7.0/tests/opentaal_cpdpat2.good000066400000000000000000000000201337236234000206000ustar00rootroot00000000000000zout-suikertest hunspell-1.7.0/tests/opentaal_cpdpat2.wrong000066400000000000000000000000171337236234000210120ustar00rootroot00000000000000zoutsuikertest hunspell-1.7.0/tests/opentaal_forbiddenword1.aff000066400000000000000000000001361337236234000217700ustar00rootroot00000000000000TRY r FORBIDDENWORD F COMPOUNDRULE 2 COMPOUNDRULE WW COMPOUNDRULE WWW SFX S Y 1 SFX S 0 s . hunspell-1.7.0/tests/opentaal_forbiddenword1.dic000066400000000000000000000000441337236234000217710ustar00rootroot000000000000004 foo/W word/W bar/WS foowordbar/FS hunspell-1.7.0/tests/opentaal_forbiddenword1.good000066400000000000000000000000331337236234000221600ustar00rootroot00000000000000fooword wordbar barwordfoo hunspell-1.7.0/tests/opentaal_forbiddenword1.sug000066400000000000000000000000131337236234000220240ustar00rootroot00000000000000barwordfoo hunspell-1.7.0/tests/opentaal_forbiddenword1.wrong000066400000000000000000000000661337236234000223720ustar00rootroot00000000000000foowordbar foowordbars foowordba foowordbas barwodfoo hunspell-1.7.0/tests/opentaal_forbiddenword2.aff000066400000000000000000000000751337236234000217730ustar00rootroot00000000000000TRY r FORBIDDENWORD F COMPOUNDFLAG W SFX S Y 1 SFX S 0 s . hunspell-1.7.0/tests/opentaal_forbiddenword2.dic000066400000000000000000000000441337236234000217720ustar00rootroot000000000000003 foo/WS word/W bar/WS foowordbar/FShunspell-1.7.0/tests/opentaal_forbiddenword2.good000066400000000000000000000000471337236234000221660ustar00rootroot00000000000000fooword wordbar barwordfoo barwordfoos hunspell-1.7.0/tests/opentaal_forbiddenword2.sug000066400000000000000000000000131337236234000220250ustar00rootroot00000000000000barwordfoo hunspell-1.7.0/tests/opentaal_forbiddenword2.wrong000066400000000000000000000000661337236234000223730ustar00rootroot00000000000000foowordbar foowordbars foowordba foowordbas barwodfoo hunspell-1.7.0/tests/opentaal_keepcase.aff000066400000000000000000000001421337236234000206340ustar00rootroot00000000000000KEEPCASE K COMPOUNDBEGIN B COMPOUNDEND E COMPOUNDFLAG C COMPOUNDMIN 1 WORDCHARS - BREAK 1 BREAK # hunspell-1.7.0/tests/opentaal_keepcase.dic000066400000000000000000000000501337236234000206350ustar00rootroot000000000000005 tv-/KB -tv/KE word/C NATO-/B -NATO/E hunspell-1.7.0/tests/opentaal_keepcase.good000066400000000000000000000000441337236234000210310ustar00rootroot00000000000000tv-word word-tv NATO-word word-NATO hunspell-1.7.0/tests/opentaal_keepcase.sug000066400000000000000000000001721337236234000207010ustar00rootroot00000000000000Tv-word, Tv- word, Word Tv- word, Word word -tv, word-tv, word word -tv, word-tv, word wordword-tv Tv-word-tv NATO- -NATO hunspell-1.7.0/tests/opentaal_keepcase.wrong000066400000000000000000000001131337236234000212320ustar00rootroot00000000000000TV-word Tv-word word-TV word-Tv wordword-TV TV-word-TV Nato-word word-nato hunspell-1.7.0/tests/ph.aff000066400000000000000000000013071337236234000156040ustar00rootroot00000000000000# new suggestion methods of Hunspell 1.7: # ph: for dictionary-based suggestions. # # For example, suggestions for "wich" # with this test dictonary: # # Hunspell 1.3.3 # wich # & wich 4 0: winch, witch, which, wish # # Hunspell 1.6.2 # wich # & wich 4 0: which, witch, winch, wish # # Suggestions will be limited for # the dictionary words with the same ph: field, # and for non-ngram suggestions. # # Order of the ph: suggestions for the # same mispelling, eg. wich -> which, witch # follows the order of the words in the dictionary: # # which ph:wich # witch ph:witch # # switch off ngram suggestions to check only # ph: based suggestions MAXNGRAMSUGS 0 TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'- hunspell-1.7.0/tests/ph.dic000066400000000000000000000002341337236234000156050ustar00rootroot000000000000008 a lot ph:alot in spite ph:inspite inspire what ph:whta ph:waht Wednesday ph:wendsay ph:wensday which ph:wich witch ph:wich winch wish Oh, my gosh! ph:omg hunspell-1.7.0/tests/ph.sug000066400000000000000000000001761337236234000156510ustar00rootroot00000000000000a lot in spite, inspire what what Wednesday Wednesday Wednesday Wednesday which, witch, winch, wish Oh, my gosh! OH, MY GOSH! hunspell-1.7.0/tests/ph.wrong000066400000000000000000000001041337236234000161760ustar00rootroot00000000000000alot inspite whta waht wensday wendsay Wensday Wendsay wich omg OMG hunspell-1.7.0/tests/ph2.aff000066400000000000000000000014101337236234000156610ustar00rootroot00000000000000# switch off ngram suggestion to test # usage of ph: dictionary fields in REP # suggestions SET UTF-8 MAXNGRAMSUGS 0 # test in compounds, too COMPOUNDFLAG Y # test also dictionary items with space, # and forbidden compounding, if there is # a ph: field with that compound as # mispelling in the dictionary CHECKCOMPOUNDREP # test in compound word with affixes SFX A Y 1 SFX A 0 's . # when the ph: field ends with the character *, # strip last character of the pattern and the replacement # to match in REP suggestions also at character changes, # for example, "pretty ph:prity*" results "prit->prett" # REP replacement instead of "prity->pretty", to get # prity->pretty and pritiest->prettiest suggestions. SFX B Y 2 SFX B y iest [^aeiou]y SFX B ö őt ö WORDCHARS ' hunspell-1.7.0/tests/ph2.dic000066400000000000000000000003021337236234000156630ustar00rootroot000000000000009 foo ph:bar ph:baz foo bar ph:foobar word/Y ph:baz stem/Y ph: ph: forbidden/Y root/YA forbidden root/A ph:forbiddenroot pretty/B ph:prity* foobarö/B ph:fubarő* happy/B ph:hepy ph:hepi->happi hunspell-1.7.0/tests/ph2.good000066400000000000000000000001101337236234000160510ustar00rootroot00000000000000foo word stem wordstem stemword rootforbidden root's foobarö foobarőt hunspell-1.7.0/tests/ph2.sug000066400000000000000000000002101337236234000157200ustar00rootroot00000000000000foo foo, word foo bar wordstem stemword stemwordstem forbidden root forbidden root's pretty prettiest foobarö foobarőt happy happiest hunspell-1.7.0/tests/ph2.wrong000066400000000000000000000002101337236234000162560ustar00rootroot00000000000000bar baz foobar bazstem stembaz stembazstem forbiddenroot forbiddenroot's rootforbiddenroot prity pritiest fubarö fubarőt hepy hepiest hunspell-1.7.0/tests/phone.aff000066400000000000000000000177451337236234000163230ustar00rootroot00000000000000# phonetic suggestions by PHONE and optional ph field of dictionary words # Documentationo of PHONE: http://aspell.net/man-html/Phonetic-Code.html # phonetic_english.h - phonetic transformation rules for use with phonetic.c # Copyright (C) 2000 Björn Jacke # # This rule set is based on Lawrence Phillips original metaphone # algorithm with modifications made by Michael Kuhn in his # C implantation, more modifications by Björn Jacke when # converting the algorithm to a rule set and minor # touch ups by Kevin Atkinson # # 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Björn Jacke may be reached by email at bjoern.jacke@gmx.de # # Changelog: # # 2000-01-05 Björn Jacke # - first version with translation rules derived from # metaphone.cc distributed with aspell 0.28.3 # - "TH" is now representated as "@" because "0" is a # meta character # - removed TH(!vowel) --> T; always use TH --> # instead # - dropped "^AE" -> "E" (redundant) # - "ing" is transformed to "N", not "NK" # - "SCH(EO)" transforms to "SK" now # - added R --> SILENT if (after a vowel) and no (vowel or # "y" follows) like in "Marcy" or "abort" # - H is SILENT in RH at beginning of words # - H is SILENT if vowel leads and "Y" follows # - some ".OUGH.." --> ...F exceptions added # - "^V" transforms to "W" # 2000-01-07 Kevin Atkinson # Converted from header to data file. # # 2007-08-23 László Németh # Add PHONE header and PHONE keywords # # version 1.1 PHONE 105 PHONE AH(AEIOUY)-^ *H PHONE AR(AEIOUY)-^ *R PHONE A(HR)^ * PHONE A^ * PHONE AH(AEIOUY)- H PHONE AR(AEIOUY)- R PHONE A(HR) _ PHONE BB- _ PHONE B B PHONE CQ- _ PHONE CIA X PHONE CH X PHONE C(EIY)- S PHONE CK K PHONE COUGH^ KF PHONE CC< C PHONE C K PHONE DG(EIY) K PHONE DD- _ PHONE D T PHONE < E PHONE EH(AEIOUY)-^ *H PHONE ER(AEIOUY)-^ *R PHONE E(HR)^ * PHONE ENOUGH^$ *NF PHONE E^ * PHONE EH(AEIOUY)- H PHONE ER(AEIOUY)- R PHONE E(HR) _ PHONE FF- _ PHONE F F PHONE GN^ N PHONE GN$ N PHONE GNS$ NS PHONE GNED$ N PHONE GH(AEIOUY)- K PHONE GH _ PHONE GG9 K PHONE G K PHONE H H PHONE IH(AEIOUY)-^ *H PHONE IR(AEIOUY)-^ *R PHONE I(HR)^ * PHONE I^ * PHONE ING6 N PHONE IH(AEIOUY)- H PHONE IR(AEIOUY)- R PHONE I(HR) _ PHONE J K PHONE KN^ N PHONE KK- _ PHONE K K PHONE LAUGH^ LF PHONE LL- _ PHONE L L PHONE MB$ M PHONE MM M PHONE M M PHONE NN- _ PHONE N N PHONE OH(AEIOUY)-^ *H PHONE OR(AEIOUY)-^ *R PHONE O(HR)^ * PHONE O^ * PHONE OH(AEIOUY)- H PHONE OR(AEIOUY)- R PHONE O(HR) _ PHONE PH F PHONE PN^ N PHONE PP- _ PHONE P P PHONE Q K PHONE RH^ R PHONE ROUGH^ RF PHONE RR- _ PHONE R R PHONE SCH(EOU)- SK PHONE SC(IEY)- S PHONE SH X PHONE SI(AO)- X PHONE SS- _ PHONE S S PHONE TI(AO)- X PHONE TH @ PHONE TCH-- _ PHONE TOUGH^ TF PHONE TT- _ PHONE T T PHONE UH(AEIOUY)-^ *H PHONE UR(AEIOUY)-^ *R PHONE U(HR)^ * PHONE U^ * PHONE UH(AEIOUY)- H PHONE UR(AEIOUY)- R PHONE U(HR) _ PHONE V^ W PHONE V F PHONE WR^ R PHONE WH^ W PHONE W(AEIOU)- W PHONE X^ S PHONE X KS PHONE Y(AEIOU)- Y PHONE ZZ- _ PHONE Z S #The rules in a different view: # # Exceptions: # # Beginning of word: "gn", "kn-", "pn-", "wr-" ----> drop first letter # "Aebersold", "Gnagy", "Knuth", "Pniewski", "Wright" # # Beginning of word: "x" ----> change to "s" # as in "Deng Xiaopeng" # # Beginning of word: "wh-" ----> change to "w" # as in "Whalen" # Beginning of word: leading vowels are transformed to "*" # # "[crt]ough" and "enough" are handled separately because of "F" sound # # # A --> A at beginning # _ otherwise # # B --> B unless at the end of word after "m", as in "dumb", "McComb" # # C --> X (sh) if "-cia-" or "-ch-" # S if "-ci-", "-ce-", or "-cy-" # SILENT if "-sci-", "-sce-", or "-scy-", or "-cq-" # K otherwise, including in "-sch-" # # D --> K if in "-dge-", "-dgy-", or "-dgi-" # T otherwise # # E --> A at beginnig # _ SILENT otherwise # # F --> F # # G --> SILENT if in "-gh-" and not at end or before a vowel # in "-gn" or "-gned" or "-gns" # in "-dge-" etc., as in above rule # K if before "i", or "e", or "y" if not double "gg" # # K otherwise (incl. "GG"!) # # H --> SILENT if after vowel and no vowel or "Y" follows # or after "-ch-", "-sh-", "-ph-", "-th-", "-gh-" # or after "rh-" at beginning # H otherwise # # I --> A at beginning # _ SILENT otherwise # # J --> K # # K --> SILENT if after "c" # K otherwise # # L --> L # # M --> M # # N --> N # # O --> A at beginning # _ SILENT otherwise # # P --> F if before "h" # P otherwise # # Q --> K # # R --> SILENT if after vowel and no vowel or "Y" follows # R otherwise # # S --> X (sh) if before "h" or in "-sio-" or "-sia-" # SK if followed by "ch(eo)" (SCH(EO)) # S otherwise # # T --> X (sh) if "-tia-" or "-tio-" # 0 (th) if before "h" # silent if in "-tch-" # T otherwise # # U --> A at beginning # _ SILENT otherwise # # V --> V if first letter of word # F otherwise # # W --> SILENT if not followed by a vowel # W if followed by a vowel # # X --> KS # # Y --> SILENT if not followed by a vowel # Y if followed by a vowel # # Z --> S hunspell-1.7.0/tests/phone.dic000066400000000000000000000001571337236234000163130ustar00rootroot0000000000000010 Brasilia brassily Brazilian brilliance brilliancy brilliant brain brass Churchillian xxxxxxxxxx ph:Brasilia hunspell-1.7.0/tests/phone.sug000066400000000000000000000001011337236234000163370ustar00rootroot00000000000000Brasilia, Xxxxxxxxxx, Brilliant, Brazilian, Brassily, Brilliance hunspell-1.7.0/tests/phone.wrong000066400000000000000000000000131337236234000166770ustar00rootroot00000000000000Brasillian hunspell-1.7.0/tests/rep.aff000066400000000000000000000005721337236234000157660ustar00rootroot00000000000000# With REP suggestions, we can fix typical language specific misspellings. # switch off ngram suggestion for testing MAXNGRAMSUGS 0 REP 8 REP f ph REP ph f REP shun$ tion REP ^alot$ a_lot # add the highest priority for "a lot" suggestion to "alot" REP ^foo$ bar REP ' _ # "un'alunno" -> "un alunno" REP ^vinten$ vinte_e_un REP s 's SFX A Y 1 SFX A 0 's . WORDCHARS ' hunspell-1.7.0/tests/rep.dic000066400000000000000000000001211337236234000157570ustar00rootroot0000000000000010 form phantom vacation vacations a lot un alunno bar barbars vinte e un auto/A hunspell-1.7.0/tests/rep.sug000066400000000000000000000001071337236234000160220ustar00rootroot00000000000000form phantom vacation a lot, lot un alunno bar vinte e un auto's, auto hunspell-1.7.0/tests/rep.wrong000066400000000000000000000001221337236234000163550ustar00rootroot00000000000000phorm fantom vacashun vacashuns alot un'alunno foo foobars barfoos vinteún autos hunspell-1.7.0/tests/reputf.aff000066400000000000000000000002431337236234000165000ustar00rootroot00000000000000# With REP suggestions, we can fix typical language specific misspellings. SET UTF-8 # switch off ngram suggestion for testing MAXNGRAMSUGS 0 REP 1 REP oo őő hunspell-1.7.0/tests/reputf.dic000066400000000000000000000000101337236234000164730ustar00rootroot000000000000001 főő hunspell-1.7.0/tests/reputf.sug000066400000000000000000000000061337236234000165370ustar00rootroot00000000000000főő hunspell-1.7.0/tests/reputf.wrong000066400000000000000000000000041337236234000170730ustar00rootroot00000000000000foo hunspell-1.7.0/tests/simplifiedtriple.aff000066400000000000000000000002101337236234000205320ustar00rootroot00000000000000# Forbid compound word with triple letters CHECKCOMPOUNDTRIPLE # Allow simplified forms SIMPLIFIEDTRIPLE COMPOUNDMIN 2 COMPOUNDFLAG A hunspell-1.7.0/tests/simplifiedtriple.dic000066400000000000000000000000201337236234000205340ustar00rootroot000000000000002 glass/A sko/A hunspell-1.7.0/tests/simplifiedtriple.good000066400000000000000000000000221337236234000207270ustar00rootroot00000000000000glass sko glassko hunspell-1.7.0/tests/simplifiedtriple.wrong000066400000000000000000000000111337236234000211310ustar00rootroot00000000000000glasssko hunspell-1.7.0/tests/slash.aff000066400000000000000000000001001337236234000162750ustar00rootroot00000000000000# slashes in words (\/) # (only for tokenization) WORDCHARS /: hunspell-1.7.0/tests/slash.dic000066400000000000000000000000531337236234000163070ustar00rootroot000000000000004 / 1\/2 http:\/\/ \/usr\/share\/myspell\/ hunspell-1.7.0/tests/slash.good000066400000000000000000000000421337236234000164760ustar00rootroot00000000000000/ 1/2 http:// /usr/share/myspell/ hunspell-1.7.0/tests/sug.aff000066400000000000000000000012101337236234000157640ustar00rootroot00000000000000# new suggestion methods of Hunspell 1.5: # capitalization: nasa -> NASA # long swap: permenant -> permanent # long mov: Ghandi -> Gandhi # double two characters: vacacation -> vacation # space with REP: "alot" -> "a lot" ("a lot" need to be in the dic file.) # # Note: see test "ph" for the newer and # more simple method to handle common misspellings, # for example, alot->a lot, inspite->in spite, # (that is giving the best suggestion, and limiting # ngram/phonetic suggestion) # switch off ngram suggestion for testing MAXNGRAMSUGS 0 REP 2 REP alot a_lot REP inspite in_spite KEY qwertzuiop|asdfghjkl|yxcvbnm|aq WORDCHARS .- FORBIDDENWORD ? hunspell-1.7.0/tests/sug.dic000066400000000000000000000001531337236234000157740ustar00rootroot0000000000000013 NASA Gandhi grateful permanent vacation a lot have which McDonald permanent-vacation/? in spite inspire hunspell-1.7.0/tests/sug.sug000066400000000000000000000002001337236234000160240ustar00rootroot00000000000000NASA Gandhi grateful permanent vacation a lot, lot in spite, inspire permanent. Vacation have which Gandhi McDonald permanent hunspell-1.7.0/tests/sug.wrong000066400000000000000000000002251337236234000163710ustar00rootroot00000000000000nasa Ghandi greatful permenant vacacation alot inspite permanent.Vacation ahev hwihc GAndhi Mcdonald permqnent permanent-vacation permqnent-vacation hunspell-1.7.0/tests/sug2.aff000066400000000000000000000011701337236234000160530ustar00rootroot00000000000000# new suggestion methods of Hunspell 1.7: # dictionary word pairs with spaces or dashes # got top priority, and removes other not # "good" (uppercase, REP, ph:) suggestions: # # "alot" -> "a lot" # # Note: use ph: at the dictionary word pair # with space or dash to keep the other not # "good" suggestions, for example # # a lot ph:alot # # results "alot" -> "a lot", "alto", "slot"... # switch off ngram suggestion for testing MAXNGRAMSUGS 0 KEY qwertzuiop|asdfghjkl|yxcvbnm|aq # Note: TRY with a letter "a" or "-" needs for # checking dictionary word pairs with dashes TRY esianrtolcdugmphbyfvkwz' WORDCHARS .- FORBIDDENWORD ? hunspell-1.7.0/tests/sug2.dic000066400000000000000000000001021337236234000160500ustar00rootroot0000000000000011 a lot a lot alto in spite in spite inspire scot free scot-free hunspell-1.7.0/tests/sug2.sug000066400000000000000000000000311337236234000161100ustar00rootroot00000000000000a lot in spite scot-free hunspell-1.7.0/tests/sug2.wrong000066400000000000000000000000261337236234000164520ustar00rootroot00000000000000alot inspite scotfree hunspell-1.7.0/tests/suggestiontest/000077500000000000000000000000001337236234000176055ustar00rootroot00000000000000hunspell-1.7.0/tests/suggestiontest/.gitignore000066400000000000000000000001041337236234000215700ustar00rootroot00000000000000result.aspell result.hunspell List_of_common_misspellings.txt.* x.* hunspell-1.7.0/tests/suggestiontest/List_of_common_misspellings.txt000066400000000000000000002413221337236234000261120ustar00rootroot00000000000000# source: http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines # released under the Creative Commons Attribution-Share-Alike License 3.0 # http://creativecommons.org/licenses/by-sa/3.0/ abandonned abandoned aberation aberration abilties abilities abilty ability abondon abandon abondoned abandoned abondoning abandoning abondons abandons aborigene aborigine abortificant abortifacient abreviated abbreviated abreviation abbreviation abritrary arbitrary absense absence absolutly absolutely absorbsion absorption absorbtion absorption abundacies abundances abundancies abundances abundunt abundant abutts abuts acadamy academy acadmic academic accademic academic accademy academy acccused accused accelleration acceleration accension accession, ascension acceptence acceptance acceptible acceptable accessable accessible accidentaly accidentally accidently accidentally acclimitization acclimatization acommodate accommodate accomadate accommodate accomadated accommodated accomadates accommodates accomadating accommodating accomadation accommodation accomadations accommodations accomdate accommodate accomodate accommodate accomodated accommodated accomodates accommodates accomodating accommodating accomodation accommodation accomodations accommodations accompanyed accompanied accordeon accordion accordian accordion accoring according accoustic acoustic accquainted acquainted accross across accussed accused acedemic academic acheive achieve acheived achieved acheivement achievement acheivements achievements acheives achieves acheiving achieving acheivment achievement acheivments achievements achievment achievement achievments achievements achive achieve, archive achived achieved, archived achivement achievement achivements achievements acknowldeged acknowledged acknowledgeing acknowledging ackward awkward, backward acomplish accomplish acomplished accomplished acomplishment accomplishment acomplishments accomplishments acording according acordingly accordingly acquaintence acquaintance acquaintences acquaintances acquiantence acquaintance acquiantences acquaintances acquited acquitted activites activities activly actively actualy actually acuracy accuracy acused accused acustom accustom acustommed accustomed adavanced advanced adbandon abandon additinally additionally additionaly additionally addmission admission addopt adopt addopted adopted addoptive adoptive addres address, adders addresable addressable addresed addressed addresing addressing addressess addresses addtion addition addtional additional adecuate adequate adhearing adhering adherance adherence admendment amendment admininistrative administrative adminstered administered adminstrate administrate adminstration administration adminstrative administrative adminstrator administrator admissability admissibility admissable admissible admited admitted admitedly admittedly adn and adolecent adolescent adquire acquire adquired acquired adquires acquires adquiring acquiring adres address adresable addressable adresing addressing adress address adressable addressable adressed addressed adressing addressing, dressing adventrous adventurous advertisment advertisement advertisments advertisements advesary adversary adviced advised aeriel aerial aeriels aerials afair affair afficianados aficionados afficionado aficionado afficionados aficionados affilate affiliate affilliate affiliate affort afford, effort aforememtioned aforementioned againnst against agains against agaisnt against aganist against aggaravates aggravates aggreed agreed aggreement agreement aggregious egregious aggresive aggressive agian again agianst against agin again agina again, angina aginst against agravate aggravate agre agree agred agreed agreeement agreement agreemnt agreement agregate aggregate agregates aggregates agreing agreeing agression aggression agressive aggressive agressively aggressively agressor aggressor agricuture agriculture agrieved aggrieved ahev have ahppen happen ahve have aicraft aircraft aiport airport airbourne airborne aircaft aircraft aircrafts aircraft airporta airports airrcraft aircraft aisian asian albiet albeit alchohol alcohol alchoholic alcoholic alchol alcohol alcholic alcoholic alcohal alcohol alcoholical alcoholic aledge allege aledged alleged aledges alleges alege allege aleged alleged alegience allegiance algebraical algebraic algorhitms algorithms algoritm algorithm algoritms algorithms alientating alienating alledge allege alledged alleged alledgedly allegedly alledges alleges allegedely allegedly allegedy allegedly allegely allegedly allegence allegiance allegience allegiance allign align alligned aligned alliviate alleviate allopone allophone allopones allophones allready already allthough although alltime all-time alltogether altogether almsot almost alochol alcohol alomst almost alot a lot, allot alotted allotted alowed allowed alowing allowing alreayd already alse else alsot also alternitives alternatives altho although althought although altough although alusion allusion, illusion alwasy always alwyas always amalgomated amalgamated amatuer amateur amature armature, amateur amendmant amendment amerliorate ameliorate amke make amking making ammend amend ammended amended ammendment amendment ammendments amendments ammount amount ammused amused amoung among amoungst amongst amung among analagous analogous analitic analytic analogeous analogous anarchim anarchism anarchistm anarchism anbd and ancestory ancestry ancilliary ancillary androgenous androgynous androgeny androgyny anihilation annihilation aniversary anniversary annoint anoint annointed anointed annointing anointing annoints anoints annouced announced annualy annually annuled annulled anohter another anomolies anomalies anomolous anomalous anomoly anomaly anonimity anonymity anounced announced ansalisation nasalisation ansalization nasalization ansestors ancestors antartic antarctic anthromorphization anthropomorphization anual annual, anal anulled annulled anwsered answered anyhwere anywhere anyother any other anytying anything aparent apparent aparment apartment apenines apennines, Apennines aplication application aplied applied apolegetics apologetics apon upon, apron apparant apparent apparantly apparently appart apart appartment apartment appartments apartments appealling appealing, appalling appeareance appearance appearence appearance appearences appearances appenines apennines, Apennines apperance appearance apperances appearances applicaiton application applicaitons applications appologies apologies appology apology apprearance appearance apprieciate appreciate approachs approaches appropiate appropriate appropraite appropriate appropropiate appropriate approproximate approximate approxamately approximately approxiately approximately approximitely approximately aprehensive apprehensive apropriate appropriate aproximate approximate aproximately approximately aquaintance acquaintance aquainted acquainted aquiantance acquaintance aquire acquire aquired acquired aquiring acquiring aquisition acquisition aquitted acquitted aranged arranged arangement arrangement arbitarily arbitrarily arbitary arbitrary archaelogists archaeologists archaelogy archaeology archaoelogy archeology, archaeology archaology archeology, archaeology archeaologist archeologist, archaeologist archeaologists archeologists, archaeologists archetect architect archetects architects archetectural architectural archetecturally architecturally archetecture architecture archiac archaic archictect architect archimedian archimedean architechturally architecturally architechture architecture architechtures architectures architectual architectural archtype archetype archtypes archetypes aready already areodynamics aerodynamics argubly arguably arguement argument arguements arguments arised arose arival arrival armamant armament armistace armistice aroud around arrangment arrangement arrangments arrangements arround around artical article artice article articel article artifical artificial artifically artificially artillary artillery arund around asetic ascetic asign assign aslo also asociated associated asorbed absorbed asphyxation asphyxiation assasin assassin assasinate assassinate assasinated assassinated assasinates assassinates assasination assassination assasinations assassinations assasined assassinated assasins assassins assassintation assassination assemple assemble assertation assertion asside aside assisnate assassinate assit assist assitant assistant assocation association assoicate associate assoicated associated assoicates associates assosication assassination asssassans assassins assualt assault assualted assaulted assymetric asymmetric assymetrical asymmetrical asteriod asteroid asthetic aesthetic asthetical aesthetical asthetically aesthetically asume assume aswell as well atain attain atempting attempting atheistical atheistic athenean athenian atheneans athenians athiesm atheism athiest atheist atorney attorney atribute attribute atributed attributed atributes attributes attaindre attainder, attained attemp attempt attemped attempted attemt attempt attemted attempted attemting attempting attemts attempts attendence attendance attendent attendant attendents attendants attened attended attension attention attitide attitude attributred attributed attrocities atrocities audeince audience auromated automated austrailia Australia austrailian Australian auther author authobiographic autobiographic authobiography autobiography authorative authoritative authorites authorities authorithy authority authoritiers authorities authoritive authoritative authrorities authorities autochtonous autochthonous autoctonous autochthonous automaticly automatically automibile automobile automonomous autonomous autor author autority authority auxilary auxiliary auxillaries auxiliaries auxillary auxiliary auxilliaries auxiliaries auxilliary auxiliary availablity availability availaible available availble available availiable available availible available avalable available avalance avalanche avaliable available avation aviation avengence a vengeance averageed averaged avilable available awared awarded awya away baceause because backgorund background backrounds backgrounds bakc back banannas bananas bandwith bandwidth bankrupcy bankruptcy banruptcy bankruptcy baout about, bout basicaly basically basicly basically bcak back beachead beachhead beacuse because beastiality bestiality beatiful beautiful beaurocracy bureaucracy beaurocratic bureaucratic beautyfull beautiful becamae became becasue because beccause because becomeing becoming becomming becoming becouse because becuase because bedore before befoer before beggin begin, begging begginer beginner begginers beginners beggining beginning begginings beginnings beggins begins begining beginning beginnig beginning behavour behavior, behaviour beleagured beleaguered beleif belief beleive believe beleived believed beleives believes beleiving believing beligum belgium belive believe belived believed belives believes, beliefs belligerant belligerent bellweather bellwether bemusemnt bemusement beneficary beneficiary beng being benificial beneficial benifit benefit benifits benefits bergamont bergamot Bernouilli Bernoulli beseige besiege beseiged besieged beseiging besieging betwen between beween between bewteen between bilateraly bilaterally billingualism bilingualism binominal binomial bizzare bizarre blaim blame blaimed blamed blessure blessing Blitzkreig Blitzkrieg boaut bout, boat, about bodydbuilder bodybuilder bombardement bombardment bombarment bombardment bondary boundary Bonnano Bonanno borke broke boundry boundary bouyancy buoyancy bouyant buoyant boyant buoyant Brasillian Brazilian breakthough breakthrough breakthroughts breakthroughs breif brief breifly briefly brethen brethren bretheren brethren briliant brilliant brillant brilliant brimestone brimstone Britian Britain Brittish British broacasted broadcast broadacasting broadcasting broady broadly Buddah Buddha buisness business buisnessman businessman buoancy buoyancy buring burying, burning, burin, during burried buried busineses business, businesses busness business bussiness business cacuses caucuses cahracters characters calaber caliber calander calendar, calender, colander calculs calculus calenders calendars caligraphy calligraphy caluclate calculate caluclated calculated caluculate calculate caluculated calculated calulate calculate calulated calculated Cambrige Cambridge camoflage camouflage campain campaign campains campaigns candadate candidate candiate candidate candidiate candidate cannister canister cannisters canisters cannnot cannot cannonical canonical cannotation connotation cannotations connotations cant cannot, can not, can't caost coast caperbility capability Capetown Cape Town capible capable captial capital captued captured capturd captured carachter character caracterized characterized carcas carcass, Caracas carefull careful careing caring carismatic charismatic Carmalite Carmelite carmel caramel, carmel-by-the-sea carniverous carnivorous carreer career carrers careers Carribbean Caribbean Carribean Caribbean cartdridge cartridge Carthagian Carthaginian carthographer cartographer cartilege cartilage cartilidge cartilage cartrige cartridge casette cassette casion caisson cassawory cassowary cassowarry cassowary casulaties casualties casulaty casualty catagories categories catagorized categorized catagory category catergorize categorize catergorized categorized Cataline Catiline, Catalina cathlic catholic catholocism catholicism catterpilar caterpillar catterpilars caterpillars cattleship battleship causalities casualties Ceasar Caesar Celcius Celsius cellpading cellpadding cementary cemetery cemetarey cemetery cemetaries cemeteries cemetary cemetery cencus census censur censor, censure cententenial centennial centruies centuries centruy century ceratin certain, keratin cerimonial ceremonial cerimonies ceremonies cerimonious ceremonious cerimony ceremony ceromony ceremony certainity certainty certian certain cervial cervical, servile, serval chalenging challenging challange challenge challanged challenged challege challenge Champange Champagne changable changeable charachter character charactor character charachters characters charactersistic characteristic charactors characters charasmatic charismatic charaterized characterized chariman chairman charistics characteristics chasr chaser, chase cheif chief chemcial chemical chemcially chemically chemestry chemistry chemicaly chemically childbird childbirth childen children choosen chosen chracter character chuch church churchs churches Cincinatti Cincinnati Cincinnatti Cincinnati circulaton circulation circumsicion circumcision circut circuit ciricuit circuit ciriculum curriculum civillian civilian claer clear claerer clearer claerly clearly claimes claims clas class clasic classic clasical classical clasically classically cleareance clearance clera clear, sclera clincial clinical clinicaly clinically cmo com cmoputer computer co-incided coincided coctail cocktail coform conform cognizent cognizant coincedentally coincidentally colaborations collaborations colateral collateral colelctive collective collaberative collaborative collecton collection collegue colleague collegues colleagues collonade colonnade collonies colonies collony colony collosal colossal colonizators colonizers comander commander, commandeer comando commando comandos commandos comany company comapany company comback comeback combanations combinations combinatins combinations combusion combustion comdemnation condemnation comemmorates commemorates comemoretion commemoration comision commission comisioned commissioned comisioner commissioner comisioning commissioning comisions commissions comission commission comissioned commissioned comissioner commissioner comissioning commissioning comissions commissions comited committed comiting committing comitted committed comittee committee comitting committing commandoes commandos commedic comedic commemerative commemorative commemmorate commemorate commemmorating commemorating commerical commercial commerically commercially commericial commercial commericially commercially commerorative commemorative comming coming comminication communication commision commission commisioned commissioned commisioner commissioner commisioning commissioning commisions commissions commited committed commitee committee commiting committing committe committee committment commitment committments commitments commmemorated commemorated commongly commonly commonweath commonwealth commuications communications commuinications communications communciation communication communiation communication communites communities compability compatibility comparision comparison comparisions comparisons comparitive comparative comparitively comparatively compatabilities compatibilities compatability compatibility compatable compatible compatablities compatibilities compatablity compatibility compatiable compatible compatiblities compatibilities compatiblity compatibility compeitions competitions compensantion compensation competance competence competant competent competative competitive competion competition, completion competitiion competition competive competitive competiveness competitiveness comphrehensive comprehensive compitent competent completedthe completed the completelyl completely completetion completion complier compiler componant component comprable comparable comprimise compromise compulsary compulsory compulsery compulsory computarized computerized concensus consensus concider consider concidered considered concidering considering conciders considers concieted conceited concieved conceived concious conscious conciously consciously conciousness consciousness condamned condemned condemmed condemned condidtion condition condidtions conditions conditionsof conditions of conected connected conection connection conesencus consensus confidental confidential confidentally confidentially confids confides configureable configurable confortable comfortable congradulations congratulations congresional congressional conived connived conjecutre conjecture conjuction conjunction Conneticut Connecticut conotations connotations conquerd conquered conquerer conqueror conquerers conquerors conqured conquered conscent consent consciouness consciousness consdider consider consdidered considered consdiered considered consectutive consecutive consenquently consequently consentrate concentrate consentrated concentrated consentrates concentrates consept concept consequentually consequently consequeseces consequences consern concern conserned concerned conserning concerning conservitive conservative consiciousness consciousness consicousness consciousness considerd considered consideres considered consious conscious consistant consistent consistantly consistently consituencies constituencies consituency constituency consituted constituted consitution constitution consitutional constitutional consolodate consolidate consolodated consolidated consonent consonant consonents consonants consorcium consortium conspiracys conspiracies conspiriator conspirator constaints constraints constanly constantly constarnation consternation constatn constant constinually continually constituant constituent constituants constituents constituion constitution constituional constitutional consttruction construction constuction construction consulant consultant consumate consummate consumated consummated contaiminate contaminate containes contains contamporaries contemporaries contamporary contemporary contempoary contemporary contemporaneus contemporaneous contempory contemporary contendor contender contined continued continous continuous continously continuously continueing continuing contravercial controversial contraversy controversy contributer contributor contributers contributors contritutions contributions controled controlled controling controlling controll control controlls controls controvercial controversial controvercy controversy controveries controversies controversal controversial controversey controversy controvertial controversial controvery controversy contruction construction conveinent convenient convenant covenant convential conventional convertables convertibles convertion conversion conveyer conveyor conviced convinced convienient convenient coordiantion coordination coorperation cooperation, corporation coorperations corporations copmetitors competitors coputer computer copywrite copyright coridal cordial cornmitted committed corosion corrosion corparate corporate corperations corporations correcters correctors correponding corresponding correposding corresponding correspondant correspondent correspondants correspondents corridoors corridors corrispond correspond corrispondant correspondent corrispondants correspondents corrisponded corresponded corrisponding corresponding corrisponds corresponds costitution constitution coucil council coudl could, cloud councellor councillor, counselor, councilor councellors councillors, counselors, councilors counries countries countains contains countires countries coururier courier, couturier coverted converted, covered, coveted cpoy coy, copy creaeted created creedence credence critereon criterion criterias criteria criticists critics critising criticising, criticizing critisising criticising critisism criticism critisisms criticisms critisize criticise, criticize critisized criticised, criticized critisizes criticises, criticizes critisizing criticising, criticizing critized criticized critizing criticizing crockodiles crocodiles crowm crown crtical critical crticised criticised crucifiction crucifixion crusies cruises crystalisation crystallisation culiminating culminating cumulatative cumulative curch church curcuit circuit currenly currently curriculem curriculum cxan cyan cyclinder cylinder dael deal, dial, dahl dalmation dalmatian damenor demeanor Dardenelles Dardanelles dacquiri daiquiri debateable debatable decendant descendant decendants descendants decendent descendant decendents descendants decideable decidable decidely decidedly decieved deceived decison decision decomissioned decommissioned decomposit decompose decomposited decomposed decompositing decomposing decomposits decomposes decress decrees decribe describe decribed described decribes describes decribing describing dectect detect defendent defendant defendents defendants deffensively defensively deffine define deffined defined definance defiance definate definite definately definitely definatly definitely definetly definitely definining defining definit definite definitly definitely definiton definition defintion definition degrate degrade delagates delegates delapidated dilapidated delerious delirious delevopment development deliberatly deliberately delusionally delusively demenor demeanor demographical demographic demolision demolition demorcracy democracy demostration demonstration denegrating denigrating densly densely deparment department deparments departments deparmental departmental dependance dependence dependancy dependency dependant dependent deram dram, dream deriviated derived derivitive derivative derogitory derogatory descendands descendants descibed described descision decision descisions decisions descriibes describes descripters descriptors descripton description desctruction destruction descuss discuss desgined designed deside decide desigining designing desinations destinations desintegrated disintegrated desintegration disintegration desireable desirable desitned destined desktiop desktop desorder disorder desoriented disoriented desparate desperate, disparate despatched dispatched despict depict despiration desperation dessicated desiccated dessigned designed destablized destabilized destory destroy detailled detailed detatched detached deteoriated deteriorated deteriate deteriorate deterioriating deteriorating determinining determining detremental detrimental devasted devastated develope develop developement development developped developed develpment development devels delves devestated devastated devestating devastating devide divide devided divided devistating devastating devolopement development diablical diabolical diamons diamonds diaster disaster dichtomy dichotomy diconnects disconnects dicover discover dicovered discovered dicovering discovering dicovers discovers dicovery discovery dicussed discussed didnt didn't diea idea, die dieing dying, dyeing dieties deities diety deity diferent different diferrent different differentiatiations differentiations differnt different difficulity difficulty diffrent different dificulties difficulties dificulty difficulty dimenions dimensions dimention dimension dimentional dimensional dimentions dimensions dimesnional dimensional diminuitive diminutive diosese diocese diphtong diphthong diphtongs diphthongs diplomancy diplomacy dipthong diphthong dipthongs diphthongs dirived derived disagreeed disagreed disapeared disappeared disapointing disappointing disappearred disappeared disaproval disapproval disasterous disastrous disatisfaction dissatisfaction disatisfied dissatisfied disatrous disastrous discontentment discontent discribe describe discribed described discribes describes discribing describing disctinction distinction disctinctive distinctive disemination dissemination disenchanged disenchanted disiplined disciplined disobediance disobedience disobediant disobedient disolved dissolved disover discover dispair despair disparingly disparagingly dispence dispense dispenced dispensed dispencing dispensing dispicable despicable dispite despite dispostion disposition disproportiate disproportionate disputandem disputandum disricts districts dissagreement disagreement dissapear disappear dissapearance disappearance dissapeared disappeared dissapearing disappearing dissapears disappears dissappear disappear dissappears disappears dissappointed disappointed dissarray disarray dissobediance disobedience dissobediant disobedient dissobedience disobedience dissobedient disobedient distiction distinction distingish distinguish distingished distinguished distingishes distinguishes distingishing distinguishing distingquished distinguished distrubution distribution distruction destruction distructive destructive ditributed distributed diversed diverse, diverged divice device divison division divisons divisions doccument document doccumented documented doccuments documents docrines doctrines doctines doctrines documenatry documentary doens does doesnt doesn't doign doing dominaton domination dominent dominant dominiant dominant donig doing dosen't doesn't doub doubt, daub doulbe double dowloads downloads dramtic dramatic draughtman draughtsman Dravadian Dravidian dreasm dreams driectly directly drnik drink druming drumming drummless drumless dupicate duplicate durig during durring during duting during dyas dryas eahc each ealier earlier earlies earliest earnt earned ecclectic eclectic eceonomy economy ecidious deciduous eclispe eclipse ecomonic economic ect etc eearly early efel evil effeciency efficiency effecient efficient effeciently efficiently efficency efficiency efficent efficient efficently efficiently efford effort, afford effords efforts, affords effulence effluence eigth eighth, eight eiter either elction election electic eclectic, electric electon election, electron electrial electrical electricly electrically electricty electricity elementay elementary eleminated eliminated eleminating eliminating eles eels eletricity electricity elicided elicited eligable eligible elimentary elementary ellected elected elphant elephant embarass embarrass embarassed embarrassed embarassing embarrassing embarassment embarrassment embargos embargoes embarras embarrass embarrased embarrassed embarrasing embarrassing embarrasment embarrassment embezelled embezzled emblamatic emblematic eminate emanate eminated emanated emision emission emited emitted emiting emitting emition emission, emotion emmediately immediately emmigrated emigrated emminent eminent, imminent emminently eminently emmisaries emissaries emmisarries emissaries emmisarry emissary emmisary emissary emmision emission emmisions emissions emmited emitted emmiting emitting emmitted emitted emmitting emitting emnity enmity emperical empirical emphaised emphasised emphsis emphasis emphysyma emphysema empirial empirical, imperial emprisoned imprisoned enameld enameled enchancement enhancement encouraing encouraging encryptiion encryption encylopedia encyclopedia endevors endeavors endevour endeavour endig ending endolithes endoliths enduce induce ened need enflamed inflamed enforceing enforcing engagment engagement engeneer engineer engeneering engineering engieneer engineer engieneers engineers enlargment enlargement enlargments enlargements Enlish English, enlist enourmous enormous enourmously enormously ensconsed ensconced entaglements entanglements enteratinment entertainment entitity entity entitlied entitled entrepeneur entrepreneur entrepeneurs entrepreneurs enviorment environment enviormental environmental enviormentally environmentally enviorments environments enviornment environment enviornmental environmental enviornmentalist environmentalist enviornmentally environmentally enviornments environments enviroment environment enviromental environmental enviromentalist environmentalist enviromentally environmentally enviroments environments envolutionary evolutionary envrionments environments enxt next epidsodes episodes epsiode episode equialent equivalent equilibium equilibrium equilibrum equilibrium equiped equipped equippment equipment equitorial equatorial equivelant equivalent equivelent equivalent equivilant equivalent equivilent equivalent equivlalent equivalent erally orally, really eratic erratic eratically erratically eraticly erratically erested arrested, erected errupted erupted esential essential esitmated estimated esle else especialy especially essencial essential essense essence essentail essential essentialy essentially essentual essential essesital essential estabishes establishes establising establishing ethnocentricm ethnocentrism ethose those, ethos Europian European Europians Europeans Eurpean European Eurpoean European evenhtually eventually eventally eventually eventially eventually eventualy eventually everthing everything everytime every time everyting everything eveyr every evidentally evidently exagerate exaggerate exagerated exaggerated exagerates exaggerates exagerating exaggerating exagerrate exaggerate exagerrated exaggerated exagerrates exaggerates exagerrating exaggerating examinated examined exampt exempt exapansion expansion excact exact excange exchange excecute execute excecuted executed excecutes executes excecuting executing excecution execution excedded exceeded excelent excellent excell excel excellance excellence excellant excellent excells excels excercise exercise exchanching exchanging excisted existed exculsivly exclusively execising exercising exection execution exectued executed exeedingly exceedingly exelent excellent exellent excellent exemple example exept except exeptional exceptional exerbate exacerbate exerbated exacerbated exerciese exercises exerpt excerpt exerpts excerpts exersize exercise exerternal external exhalted exalted exhibtion exhibition exibition exhibition exibitions exhibitions exicting exciting exinct extinct existance existence existant existent existince existence exliled exiled exludes excludes exmaple example exonorate exonerate exoskelaton exoskeleton expalin explain expeced expected expecially especially expeditonary expeditionary expeiments experiments expell expel expells expels experiance experience experianced experienced expiditions expeditions expierence experience explaination explanation explaning explaining explictly explicitly exploititive exploitative explotation exploitation expropiated expropriated expropiation expropriation exressed expressed extemely extremely extention extension extentions extensions extered exerted extermist extremist extint extinct, extant extradiction extradition extraterrestial extraterrestrial extraterrestials extraterrestrials extravagent extravagant extrememly extremely extremeophile extremophile extremly extremely extrordinarily extraordinarily extrordinary extraordinary eyar year, eyas eyars years, eyas eyasr years, eyas faciliate facilitate faciliated facilitated faciliates facilitates facilites facilities facillitate facilitate facinated fascinated facist fascist familes families familliar familiar famoust famous fanatism fanaticism Farenheit Fahrenheit fatc fact faught fought favoutrable favourable feasable feasible Febuary February fedreally federally feromone pheromone fertily fertility fianite finite fianlly finally ficticious fictitious fictious fictitious fidn find fiel feel, field, file, phial fiels feels, fields, files, phials fiercly fiercely fightings fighting filiament filament fimilies families finacial financial finaly finally financialy financially firends friends firts flirts, first fisionable fissionable flamable flammable flawess flawless fleed fled, freed Flemmish Flemish florescent fluorescent flourescent fluorescent fluorish flourish follwoing following folowing following fomed formed fomr from, form fonetic phonetic fontrier fontier foootball football forbad forbade forbiden forbidden foreward foreword forfiet forfeit forhead forehead foriegn foreign Formalhaut Fomalhaut formallize formalize formallized formalized formaly formally formelly formerly formidible formidable formost foremost forsaw foresaw forseeable foreseeable fortelling foretelling forunner forerunner foucs focus foudn found fougth fought foundaries foundries foundary foundry Foundland Newfoundland fourties forties fourty forty fouth fourth foward forward fucntion function fucntioning functioning Fransiscan Franciscan Fransiscans Franciscans freind friend freindly friendly frequentily frequently frome from fromed formed froniter frontier fufill fulfill fufilled fulfilled fulfiled fulfilled fundametal fundamental fundametals fundamentals funguses fungi funtion function furuther further futher further futhermore furthermore futhroc futhark, futhorc gae game, Gael, gale galatic galactic Galations Galatians gallaxies galaxies galvinized galvanized Gameboy Game Boy ganerate generate ganes games ganster gangster garantee guarantee garanteed guaranteed garantees guarantees garnison garrison gauarana guaraná gaurantee guarantee gauranteed guaranteed gaurantees guarantees gaurd guard, gourd gaurentee guarantee gaurenteed guaranteed gaurentees guarantees geneological genealogical geneologies genealogies geneology genealogy generaly generally generatting generating genialia genitalia geographicial geographical geometrician geometer geometricians geometers gerat great Ghandi Gandhi glight flight gnawwed gnawed godess goddess godesses goddesses Godounov Godunov gogin going, Gauguin goign going gonig going Gothenberg Gothenburg Gottleib Gottlieb gouvener governor govement government govenment government govenrment government goverance governance goverment government govermental governmental governer governor governmnet government govorment government govormental governmental govornment government gracefull graceful graet great grafitti graffiti gramatically grammatically grammaticaly grammatically grammer grammar grat great gratuitious gratuitous greatful grateful greatfully gratefully greif grief gridles griddles gropu group grwo grow Guaduloupe Guadalupe, Guadeloupe Guadulupe Guadalupe, Guadeloupe guage gauge guarentee guarantee guarenteed guaranteed guarentees guarantees Guatamala Guatemala Guatamalan Guatemalan guerilla guerrilla guerillas guerrillas guerrila guerrilla guerrilas guerrillas guidence guidance Guilia Giulia Guilio Giulio Guiness Guinness Guiseppe Giuseppe gunanine guanine gurantee guarantee guranteed guaranteed gurantees guarantees guttaral guttural gutteral guttural habaeus habeas habeus habeas Habsbourg Habsburg haemorrage haemorrhage haev have, heave Hallowean Hallowe'en, Halloween halp help hapen happen hapened happened hapening happening happend happened happended happened happenned happened harased harassed harases harasses harasment harassment harasments harassments harassement harassment harras harass harrased harassed harrases harasses harrasing harassing harrasment harassment harrasments harassments harrassed harassed harrasses harassed harrassing harassing harrassment harassment harrassments harassments hasnt hasn't haviest heaviest headquater headquarter headquarer headquarter headquatered headquartered headquaters headquarters healthercare healthcare heared heard heathy healthy Heidelburg Heidelberg heigher higher heirarchy hierarchy heiroglyphics hieroglyphics helment helmet helpfull helpful helpped helped hemmorhage hemorrhage herad heard, Hera heridity heredity heroe hero heros heroes hertzs hertz hesistant hesitant heterogenous heterogeneous hieght height hierachical hierarchical hierachies hierarchies hierachy hierarchy hierarcical hierarchical hierarcy hierarchy hieroglph hieroglyph hieroglphs hieroglyphs higer higher higest highest higway highway hillarious hilarious himselv himself hinderance hindrance hinderence hindrance hindrence hindrance hipopotamus hippopotamus hismelf himself histocompatability histocompatibility historicians historians hitsingles hit singles holliday holiday homestate home state homogeneize homogenize homogeneized homogenized honory honorary horrifing horrifying hosited hoisted hospitible hospitable hounour honour housr hours, house howver however hsitorians historians hstory history hten then, hen, the htere there, here htey they htikn think hting thing htink think htis this humer humor, humour humerous humorous, humerus huminoid humanoid humoural humoral humurous humorous husban husband hvae have hvaing having hvea have, heave hwihc which hwile while hwole whole hydogen hydrogen hydropile hydrophile hydropilic hydrophilic hydropobe hydrophobe hydropobic hydrophobic hygeine hygiene hypocracy hypocrisy hypocrasy hypocrisy hypocricy hypocrisy hypocrit hypocrite hypocrits hypocrites iconclastic iconoclastic idaeidae idea idaes ideas idealogies ideologies idealogy ideology identicial identical identifers identifiers ideosyncratic idiosyncratic idesa ideas, ides idiosyncracy idiosyncrasy Ihaca Ithaca illegimacy illegitimacy illegitmate illegitimate illess illness illiegal illegal illution illusion ilness illness ilogical illogical imagenary imaginary imagin imagine imaginery imaginary, imagery imanent eminent, imminent imcomplete incomplete imediately immediately imense immense imigrant emigrant, immigrant imigrated emigrated, immigrated imigration emigration, immigration iminent eminent, imminent, immanent immediatley immediately immediatly immediately immidately immediately immidiately immediately immitate imitate immitated imitated immitating imitating immitator imitator immunosupressant immunosuppressant impecabbly impeccably impedence impedance implamenting implementing impliment implement implimented implemented imploys employs importamt important imprioned imprisoned imprisonned imprisoned improvision improvisation improvments improvements inablility inability inaccessable inaccessible inadiquate inadequate inadquate inadequate inadvertant inadvertent inadvertantly inadvertently inagurated inaugurated inaguration inauguration inappropiate inappropriate inaugures inaugurates inbalance imbalance inbalanced imbalanced inbetween between incarcirated incarcerated incidentially incidentally incidently incidentally inclreased increased includ include includng including incompatabilities incompatibilities incompatability incompatibility incompatable incompatible incompatablities incompatibilities incompatablity incompatibility incompatiblities incompatibilities incompatiblity incompatibility incompetance incompetence incompetant incompetent incomptable incompatible incomptetent incompetent inconsistant inconsistent incorperation incorporation incorportaed incorporated incorprates incorporates incorruptable incorruptible incramentally incrementally increadible incredible incredable incredible inctroduce introduce inctroduced introduced incuding including incunabla incunabula indefinately indefinitely indefineable undefinable indefinitly indefinitely indentical identical indepedantly independently indepedence independence independance independence independant independent independantly independently independece independence independendet independent indictement indictment indigineous indigenous indipendence independence indipendent independent indipendently independently indespensible indispensable indespensable indispensable indispensible indispensable indisputible indisputable indisputibly indisputably indite indict individualy individually indpendent independent indpendently independently indulgue indulge indutrial industrial indviduals individuals inefficienty inefficiently inevatible inevitable inevitible inevitable inevititably inevitably infalability infallibility infallable infallible infectuous infectious infered inferred infilitrate infiltrate infilitrated infiltrated infilitration infiltration infinit infinite inflamation inflammation influencial influential influented influenced infomation information informtion information infrantryman infantryman infrigement infringement ingenius ingenious ingreediants ingredients inhabitans inhabitants inherantly inherently inheritage heritage, inheritance inheritence inheritance inital initial initally initially initation initiation initiaitive initiative inlcuding including inmigrant immigrant inmigrants immigrants innoculated inoculated inocence innocence inofficial unofficial inot into inpeach impeach inpolite impolite inprisonment imprisonment inproving improving insectiverous insectivorous insensative insensitive inseperable inseparable insistance insistence insitution institution insitutions institutions inspite in spite, inspire instade instead instatance instance institue institute instuction instruction instuments instruments instutionalized institutionalized instutions intuitions insurence insurance intelectual intellectual inteligence intelligence inteligent intelligent intenational international intepretation interpretation intepretator interpretor interational international interbread interbreed, interbred interchangable interchangeable interchangably interchangeably intercontinetal intercontinental intered interred, interned interelated interrelated interferance interference interfereing interfering intergrated integrated intergration integration interm interim internation international interpet interpret interrim interim interrugum interregnum intertaining entertaining interupt interrupt intervines intervenes intevene intervene intial initial intially initially intrduced introduced intrest interest introdued introduced intruduced introduced intrusted entrusted intutive intuitive intutively intuitively inudstry industry inumerable enumerable, innumerable inventer inventor invertibrates invertebrates investingate investigate involvment involvement irelevent irrelevant iresistable irresistible iresistably irresistibly iresistible irresistible iresistibly irresistibly iritable irritable iritated irritated ironicly ironically irregardless regardless irrelevent irrelevant irreplacable irreplaceable irresistable irresistible irresistably irresistibly isnt isn't Israelies Israelis issueing issuing itnroduced introduced iunior junior iwll will iwth with Japanes Japanese jaques jacques jeapardy jeopardy jewllery jewellery Johanine Johannine Jospeh Joseph jouney journey journied journeyed journies journeys jstu just jsut just Juadaism Judaism Juadism Judaism judical judicial judisuary judiciary juducial judicial juristiction jurisdiction juristictions jurisdictions kindergarden kindergarten klenex kleenex knifes knives knive knife knowlege knowledge knowlegeable knowledgeable knwo know knwos knows konw know konws knows kwno know labatory lavatory, laboratory labled labelled, labeled labratory laboratory laguage language laguages languages larg large largst largest larrry larry lastr last lattitude latitude launchs launch launhed launched lavae larvae layed laid lazyness laziness leaded led leage league leanr lean, learn, leaner leathal lethal lefted left legitamate legitimate legitmate legitimate leibnitz leibniz lenght length leran learn lerans learns lieuenant lieutenant leutenant lieutenant levetate levitate levetated levitated levetates levitates levetating levitating levle level liasion liaison liason liaison liasons liaisons libary library libell libel libguistic linguistic libguistics linguistics libitarianisn libertarianism lible libel, liable lieing lying liek like liekd liked liesure leisure lieved lived liftime lifetime lightyear light year lightyears light years likelyhood likelihood linnaena linnaean lippizaner lipizzaner liquify liquefy liscense license, licence lisence license, licence lisense license, licence listners listeners litature literature literture literature littel little litterally literally liuke like livley lively lmits limits loev love lonelyness loneliness longitudonal longitudinal lonley lonely lonly lonely, only loosing losing lotharingen lothringen lsat last lukid likud lveo love lvoe love Lybia Libya mackeral mackerel magasine magazine magincian magician magnificient magnificent magolia magnolia mailny mainly maintainance maintenance maintainence maintenance maintance maintenance maintenence maintenance maintinaing maintaining maintioned mentioned majoroty majority maked marked, made makse makes Malcom Malcolm maltesian Maltese mamal mammal mamalian mammalian managable manageable, manageably managment management manisfestations manifestations manoeuverability maneuverability manouver maneuver, manoeuvre manouverability maneuverability, manoeuvrability, manoeuverability manouverable maneuverable, manoeuvrable manouvers maneuvers, manoeuvres mantained maintained manuever maneuver, manoeuvre manuevers maneuvers, manoeuvres manufacturedd manufactured manufature manufacture manufatured manufactured manufaturing manufacturing manuver maneuver mariage marriage marjority majority markes marks marketting marketing marmelade marmalade marrage marriage marraige marriage marrtyred martyred marryied married Massachussets Massachusetts Massachussetts Massachusetts massmedia mass media masterbation masturbation mataphysical metaphysical materalists materialist mathamatics mathematics mathematican mathematician mathematicas mathematics matheticians mathematicians mathmatically mathematically mathmatician mathematician mathmaticians mathematicians mccarthyst mccarthyist mchanics mechanics meaninng meaning mear wear, mere, mare mechandise merchandise medacine medicine medeival medieval medevial medieval mediciney mediciny medievel medieval mediterainnean mediterranean Mediteranean Mediterranean meerkrat meerkat melieux milieux membranaphone membranophone memeber member menally mentally meranda veranda, Miranda mercentile mercantile messanger messenger messenging messaging metalic metallic metalurgic metallurgic metalurgical metallurgical metalurgy metallurgy metamorphysis metamorphosis metaphoricial metaphorical meterologist meteorologist meterology meteorology methaphor metaphor methaphors metaphors Michagan Michigan micoscopy microscopy midwifes midwives mileau milieu milennia millennia milennium millennium mileu milieu miliary military milion million miliraty military millenia millennia millenial millennial millenialism millennialism millenium millennium millepede millipede millioniare millionaire millitary military millon million miltary military minature miniature minerial mineral miniscule minuscule ministery ministry minstries ministries minstry ministry minumum minimum mirrorred mirrored miscelaneous miscellaneous miscellanious miscellaneous miscellanous miscellaneous mischeivous mischievous mischevious mischievous mischievious mischievous misdameanor misdemeanor misdameanors misdemeanors misdemenor misdemeanor misdemenors misdemeanors misfourtunes misfortunes misile missile Misouri Missouri mispell misspell mispelled misspelled mispelling misspelling missen mizzen Missisipi Mississippi Missisippi Mississippi missle missile missonary missionary misterious mysterious mistery mystery misteryous mysterious mkae make mkaes makes mkaing making mkea make moderm modem modle model moent moment moeny money mohammedans muslims moil mohel moleclues molecules momento memento monestaries monasteries monestary monastery, monetary monickers monikers monolite monolithic Monserrat Montserrat montains mountains montanous mountainous monts months montypic monotypic moreso more, more so morgage mortgage Morisette Morissette Morrisette Morissette morroccan moroccan morrocco morocco morroco morocco mosture moisture motiviated motivated mounth month movei movie movment movement mroe more mucuous mucous muder murder mudering murdering muhammadan muslim multicultralism multiculturalism multipled multiplied multiplers multipliers munbers numbers muncipalities municipalities muncipality municipality munnicipality municipality muscels mussels, muscles muscial musical muscician musician muscicians musicians mutiliated mutilated myraid myriad mysef myself mysogynist misogynist mysogyny misogyny mysterous mysterious Mythraic Mithraic naieve naive Napoleonian Napoleonic naturaly naturally naturely naturally naturual natural naturually naturally Nazereth Nazareth neccesarily necessarily neccesary necessary neccessarily necessarily neccessary necessary neccessities necessities necesarily necessarily necesary necessary necessiate necessitate neglible negligible negligable negligible negociate negotiate negociation negotiation negociations negotiations negotation negotiation neice niece, nice neigborhood neighborhood neigbour neighbour, neighbor neigbourhood neighbourhood neigbouring neighbouring, neighboring neigbours neighbours, neighbors neolitic neolithic nessasarily necessarily nessecary necessary nestin nesting neverthless nevertheless newletters newsletters Newyorker New Yorker nickle nickel nightfa;; nightfall nightime nighttime nineth ninth ninteenth nineteenth ninties 1990s ninty ninety nkow know nkwo know nmae name noncombatents noncombatants nonsence nonsense nontheless nonetheless noone no one norhern northern northen northern northereastern northeastern notabley notably noteable notable noteably notably noteriety notoriety noth north nothern northern noticable noticeable noticably noticeably noticeing noticing noticible noticeable notwhithstanding notwithstanding noveau nouveau nowdays nowadays nowe now nto not nucular nuclear nuculear nuclear nuisanse nuisance Nullabour Nullarbor numberous numerous Nuremburg Nuremberg nusance nuisance nutritent nutrient nutritents nutrients nuturing nurturing obediance obedience obediant obedient obession obsession obssessed obsessed obstacal obstacle obstancles obstacles obstruced obstructed ocasion occasion ocasional occasional ocasionally occasionally ocasionaly occasionally ocasioned occasioned ocasions occasions ocassion occasion ocassional occasional ocassionally occasionally ocassionaly occasionally ocassioned occasioned ocassions occasions occaison occasion occassion occasion occassional occasional occassionally occasionally occassionaly occasionally occassioned occasioned occassions occasions occationally occasionally occour occur occurance occurrence occurances occurrences occured occurred occurence occurrence occurences occurrences occuring occurring occurr occur occurrance occurrence occurrances occurrences octohedra octahedra octohedral octahedral octohedron octahedron ocuntries countries ocuntry country ocurr occur ocurrance occurrence ocurred occurred ocurrence occurrence offcers officers offcially officially offereings offerings offical official officals officials offically officially officaly officially officialy officially offred offered oftenly often oging going, ogling omision omission omited omitted omiting omitting omlette omelette ommision omission ommited omitted ommiting omitting ommitted omitted ommitting omitting omniverous omnivorous omniverously omnivorously omre more onot note, not onyl only openess openness oponent opponent oportunity opportunity opose oppose oposite opposite oposition opposition oppenly openly oppinion opinion opponant opponent oppononent opponent oppositition opposition oppossed opposed opprotunity opportunity opression oppression opressive oppressive opthalmic ophthalmic opthalmologist ophthalmologist opthalmology ophthalmology opthamologist ophthalmologist optmizations optimizations optomism optimism orded ordered organim organism organiztion organization orgin origin, organ orginal original orginally originally orginize organise oridinarily ordinarily origanaly originally originall original, originally originaly originally originially originally originnally originally origional original orignally originally orignially originally otehr other ouevre oeuvre overshaddowed overshadowed overthere over there overwelming overwhelming overwheliming overwhelming owrk work owudl would oxigen oxygen oximoron oxymoron paide paid paitience patience palce place, palace paleolitic paleolithic paliamentarian parliamentarian Palistian Palestinian Palistinian Palestinian Palistinians Palestinians pallete palette pamflet pamphlet pamplet pamphlet pantomine pantomime Papanicalou Papanicolaou paralel parallel paralell parallel paralelly parallelly paralely parallelly parallely parallelly paranthesis parenthesis paraphenalia paraphernalia parellels parallels parituclar particular parliment parliament parrakeets parakeets parralel parallel parrallel parallel parrallell parallel parrallelly parallelly parrallely parallelly partialy partially particually particularly particualr particular particuarly particularly particularily particularly particulary particularly pary party pased passed pasengers passengers passerbys passersby pasttime pastime pastural pastoral paticular particular pattented patented pavillion pavilion payed paid peacefuland peaceful and peageant pageant peculure peculiar pedestrain pedestrian peice piece Peloponnes Peloponnesus penatly penalty penerator penetrator penisula peninsula penisular peninsular penninsula peninsula penninsular peninsular pennisula peninsula pensinula peninsula peom poem peoms poems peopel people peotry poetry perade parade percepted perceived percieve perceive percieved perceived perenially perennially perfomers performers performence performance performes performed, performs perhasp perhaps perheaps perhaps perhpas perhaps peripathetic peripatetic peristent persistent perjery perjury perjorative pejorative permanant permanent permenant permanent permenantly permanently permissable permissible perogative prerogative peronal personal perosnality personality perphas perhaps perpindicular perpendicular perseverence perseverance persistance persistence persistant persistent personel personnel, personal personell personnel personnell personnel persuded persuaded persue pursue persued pursued persuing pursuing persuit pursuit persuits pursuits pertubation perturbation pertubations perturbations pessiary pessary petetion petition Pharoah Pharaoh phenomenom phenomenon phenomenonal phenomenal phenomenonly phenomenally phenomonenon phenomenon phenomonon phenomenon phenonmena phenomena Philipines Philippines philisopher philosopher philisophical philosophical philisophy philosophy Phillipine Philippine Phillipines Philippines Phillippines Philippines phillosophically philosophically philospher philosopher philosphies philosophies philosphy philosophy Phonecian Phoenecian phongraph phonograph phylosophical philosophical physicaly physically pich pitch pilgrimmage pilgrimage pilgrimmages pilgrimages pinapple pineapple pinnaple pineapple pinoneered pioneered plagarism plagiarism planation plantation planed planned plantiff plaintiff plateu plateau plausable plausible playright playwright playwrite playwright playwrites playwrights pleasent pleasant plebicite plebiscite plesant pleasant poeoples peoples poety poetry poisin poison polical political polinator pollinator polinators pollinators politican politician politicans politicians poltical political polute pollute poluted polluted polutes pollutes poluting polluting polution pollution polyphonyic polyphonic polysaccaride polysaccharide polysaccharid polysaccharide pomegranite pomegranate pomotion promotion poportional proportional popoulation population popularaty popularity populare popular populer popular portayed portrayed portraing portraying Portugese Portuguese portuguease portuguese posess possess posessed possessed posesses possesses posessing possessing posession possession posessions possessions posion poison positon position, positron possable possible possably possibly posseses possesses possesing possessing possesion possession possessess possesses possibile possible possibilty possibility possiblility possibility possiblilty possibility possiblities possibilities possiblity possibility possition position Postdam Potsdam posthomous posthumous postion position postive positive potatos potatoes portait portrait potrait portrait potrayed portrayed poulations populations poverful powerful poweful powerful powerfull powerful practial practical practially practically practicaly practically practicioner practitioner practicioners practitioners practicly practically practioner practitioner practioners practitioners prairy prairie prarie prairie praries prairies pratice practice preample preamble precedessor predecessor preceed precede preceeded preceded preceeding preceding preceeds precedes precentage percentage precice precise precisly precisely precurser precursor predecesors predecessors predicatble predictable predicitons predictions predomiantly predominately prefered preferred prefering preferring preferrably preferably pregancies pregnancies preiod period preliferation proliferation premeire premiere premeired premiered premillenial premillennial preminence preeminence premission permission Premonasterians Premonstratensians preocupation preoccupation prepair prepare prepartion preparation prepatory preparatory preperation preparation preperations preparations preriod period presedential presidential presense presence presidenital presidential presidental presidential presitgious prestigious prespective perspective prestigeous prestigious prestigous prestigious presumabely presumably presumibly presumably pretection protection prevelant prevalent preverse perverse previvous previous pricipal principal priciple principle priestood priesthood primarly primarily primative primitive primatively primitively primatives primitives primordal primordial priveledges privileges privelege privilege priveleged privileged priveleges privileges privelige privilege priveliged privileged priveliges privileges privelleges privileges privilage privilege priviledge privilege priviledges privileges privledge privilege privte private probabilaty probability probablistic probabilistic probablly probably probalibity probability probaly probably probelm problem proccess process proccessing processing procede proceed, precede proceded proceeded, preceded procedes proceeds, precedes procedger procedure proceding proceeding, preceding procedings proceedings proceedure procedure proces process processer processor proclaimation proclamation proclamed proclaimed proclaming proclaiming proclomation proclamation profesion profusion, profession profesor professor professer professor proffesed professed proffesion profession proffesional professional proffesor professor profilic prolific progessed progressed programable programmable progrom pogrom, program progroms pogroms, programs prohabition prohibition prologomena prolegomena prominance prominence prominant prominent prominantly prominently prominately prominently, predominately promiscous promiscuous promotted promoted pronomial pronominal pronouced pronounced pronounched pronounced pronounciation pronunciation proove prove prooved proved prophacy prophecy propietary proprietary propmted prompted propoganda propaganda propogate propagate propogates propagates propogation propagation propostion proposition propotions proportions propper proper propperly properly proprietory proprietary proseletyzing proselytizing protaganist protagonist protaganists protagonists protocal protocol protoganist protagonist protrayed portrayed protruberance protuberance protruberances protuberances prouncements pronouncements provacative provocative provded provided provicial provincial provinicial provincial provisonal provisional provisiosn provision proximty proximity pseudononymous pseudonymous pseudonyn pseudonym psuedo pseudo psycology psychology psyhic psychic publicaly publicly puchasing purchasing Pucini Puccini Puertorrican Puerto Rican Puertorricans Puerto Ricans pumkin pumpkin puritannical puritanical purposedly purposely purpotedly purportedly pursuade persuade pursuaded persuaded pursuades persuades pususading persuading puting putting pwoer power pyscic psychic qtuie quite, quiet quantaty quantity quantitiy quantity quarantaine quarantine Queenland Queensland questonable questionable quicklyu quickly quinessential quintessential quitted quit quizes quizzes qutie quite, quiet rabinnical rabbinical racaus raucous radiactive radioactive radify ratify raelly really rarified rarefied reaccurring recurring reacing reaching reacll recall readmition readmission realitvely relatively realsitic realistic realtions relations realy really realyl really reasearch research rebiulding rebuilding rebllions rebellions rebounce rebound reccomend recommend reccomendations recommendations reccomended recommended reccomending recommending reccommend recommend reccommended recommended reccommending recommending reccuring recurring receeded receded receeding receding receivedfrom received from recepient recipient recepients recipients receving receiving rechargable rechargeable reched reached recide reside recided resided recident resident recidents residents reciding residing reciepents recipients reciept receipt recieve receive recieved received reciever receiver recievers receivers recieves receives recieving receiving recipiant recipient recipiants recipients recived received recivership receivership recogise recognise recogize recognize recomend recommend recomended recommended recomending recommending recomends recommends recommedations recommendations reconaissance reconnaissance reconcilation reconciliation reconized recognized reconnaissence reconnaissance recontructed reconstructed recordproducer record producer recquired required recrational recreational recrod record recuiting recruiting recuring recurring recurrance recurrence rediculous ridiculous reedeming redeeming reenforced reinforced refect reflect refedendum referendum referal referral refered referred referiang referring refering referring refernces references referrence reference referrs refers reffered referred refference reference refrence reference refrences references refrers refers refridgeration refrigeration refridgerator refrigerator refromist reformist refusla refusal regardes regards regluar regular reguarly regularly regulaion regulation regulaotrs regulators regularily regularly rehersal rehearsal reicarnation reincarnation reigining reigning reknown renown reknowned renowned rela real relaly really relatiopnship relationship relativly relatively relected reelected releive relieve releived relieved releiver reliever releses releases relevence relevance relevent relevant reliablity reliability relient reliant religeous religious religous religious religously religiously relinqushment relinquishment relitavely relatively relized realised, realized relpacement replacement remaing remaining remeber remember rememberable memorable rememberance remembrance remembrence remembrance remenant remnant remenicent reminiscent reminent remnant reminescent reminiscent reminscent reminiscent reminsicent reminiscent rendevous rendezvous rendezous rendezvous renedered rende renewl renewal rentors renters reoccurrence recurrence reorganision reorganisation repatition repetition, repartition repentence repentance repentent repentant repeteadly repeatedly repetion repetition repid rapid reponse response reponsible responsible reportadly reportedly represantative representative representive representative representives representatives reproducable reproducible reprtoire repertoire repsectively respectively reptition repetition requirment requirement requred required resaurant restaurant resembelance resemblance resembes resembles resemblence resemblance resevoir reservoir resignement resignment resistable resistible resistence resistance resistent resistant respectivly respectively responce response responibilities responsibilities responisble responsible responnsibilty responsibility responsability responsibility responsibile responsible responsibilites responsibilities responsiblity responsibility ressemblance resemblance ressemble resemble ressembled resembled ressemblence resemblance ressembling resembling resssurecting resurrecting ressurect resurrect ressurected resurrected ressurection resurrection ressurrection resurrection restaraunt restaurant restaraunteur restaurateur restaraunteurs restaurateurs restaraunts restaurants restauranteurs restaurateurs restauration restoration restauraunt restaurant resteraunt restaurant resteraunts restaurants resticted restricted restraunt restraint, restaurant resturant restaurant resturaunt restaurant resurecting resurrecting retalitated retaliated retalitation retaliation retreive retrieve returnd returned revaluated reevaluated reveral reversal reversable reversible revolutionar revolutionary rewitten rewritten rewriet rewrite rhymme rhyme rhythem rhythm rhythim rhythm rhytmic rhythmic rigeur rigueur, rigour, rigor rigourous rigorous rininging ringing rised rose Rockerfeller Rockefeller rococco rococo rocord record roomate roommate rougly roughly rucuperate recuperate rudimentatry rudimentary rulle rule runing running runnung running russina Russian Russion Russian rwite write rythem rhythm rythim rhythm rythm rhythm rythmic rhythmic rythyms rhythms sacrafice sacrifice sacreligious sacrilegious sacrifical sacrificial saftey safety safty safety salery salary sanctionning sanctioning sandwhich sandwich Sanhedrim Sanhedrin santioned sanctioned sargant sergeant sargeant sergeant sasy says, sassy satelite satellite satelites satellites Saterday Saturday Saterdays Saturdays satisfactority satisfactorily satric satiric satrical satirical satrically satirically sattelite satellite sattelites satellites saught sought saveing saving saxaphone saxophone scaleable scalable scandanavia Scandinavia scaricity scarcity scavanged scavenged schedual schedule scholarhip scholarship scholarstic scholastic, scholarly scientfic scientific scientifc scientific scientis scientist scince science scinece science scirpt script scoll scroll screenwrighter screenwriter scrutinity scrutiny scuptures sculptures seach search seached searched seaches searches secceeded seceded, succeeded seceed succeed, secede seceeded succeeded, seceded secratary secretary secretery secretary sedereal sidereal seeked sought segementation segmentation seguoys segues seige siege seing seeing seinor senior seldomly seldom senarios scenarios sence sense senstive sensitive sensure censure seperate separate seperated separated seperately separately seperates separates seperating separating seperation separation seperatism separatism seperatist separatist sepina subpoena sepulchure sepulchre, sepulcher sepulcre sepulchre, sepulcher sergent sergeant settelement settlement settlment settlement severeal several severley severely severly severely sevice service shaddow shadow shamen shaman, shamans sheat sheath, sheet, cheat sheild shield sherif sheriff shineing shining shiped shipped shiping shipping shopkeeepers shopkeepers shorly shortly shortwhile short while shoudl should shoudln should, shouldn't shouldnt shouldn't shreak shriek shrinked shrunk sicne since sideral sidereal sieze seize, size siezed seized, sized siezing seizing, sizing siezure seizure siezures seizures siginificant significant signficant significant signficiant significant signfies signifies signifantly significantly significently significantly signifigant significant signifigantly significantly signitories signatories signitory signatory similarily similarly similiar similar similiarity similarity similiarly similarly simmilar similar simpley simply simplier simpler simultanous simultaneous simultanously simultaneously sincerley sincerely singsog singsong sinse sines, since Sionist Zionist Sionists Zionists Sixtin Sistine Skagerak Skagerrak skateing skating slaugterhouses slaughterhouses slowy slowly smae same smealting smelting smoe some sneeks sneaks snese sneeze socalism socialism socities societies soem some sofware software sohw show soilders soldiers solatary solitary soley solely soliders soldiers soliliquy soliloquy soluable soluble somene someone somtimes sometimes somwhere somewhere sophicated sophisticated sorceror sorcerer sorrounding surrounding sotry story sotyr satyr, story soudn sound soudns sounds sould could, should, sold sountrack soundtrack sourth south sourthern southern souvenier souvenir souveniers souvenirs soveits soviets sovereignity sovereignty soverign sovereign soverignity sovereignty soverignty sovereignty spainish Spanish speach speech specfic specific speciallized specialised, specialized specif specific, specify specifiying specifying speciman specimen spectauclar spectacular spectaulars spectaculars spects aspects, expects spectum spectrum speices species spendour splendour spermatozoan spermatozoon spoace space sponser sponsor sponsered sponsored spontanous spontaneous sponzored sponsored spoonfulls spoonfuls sppeches speeches spreaded spread sprech speech spred spread spriritual spiritual spritual spiritual sqaure square stablility stability stainlees stainless staion station standars standards stange strange startegic strategic startegies strategies startegy strategy stateman statesman statememts statements statment statement steriods steroids sterotypes stereotypes stilus stylus stingent stringent stiring stirring stirrs stirs stlye style stong strong stopry story storeis stories storise stories stornegst strongest stoyr story stpo stop stradegies strategies stradegy strategy strat start, strata stratagically strategically streemlining streamlining stregth strength strenghen strengthen strenghened strengthened strenghening strengthening strenght strength strenghten strengthen strenghtened strengthened strenghtening strengthening strengtened strengthened strenous strenuous strictist strictest strikely strikingly strnad strand stroy story, destroy structual structural stubborness stubbornness stucture structure stuctured structured studdy study studing studying stuggling struggling sturcture structure subcatagories subcategories subcatagory subcategory subconsiously subconsciously subjudgation subjugation submachne submachine subpecies subspecies subsidary subsidiary subsiduary subsidiary subsquent subsequent subsquently subsequently substace substance substancial substantial substatial substantial substituded substituted substract subtract substracted subtracted substracting subtracting substraction subtraction substracts subtracts subtances substances subterranian subterranean suburburban suburban succceeded succeeded succcesses successes succedded succeeded succeded succeeded succeds succeeds succesful successful succesfully successfully succesfuly successfully succesion succession succesive successive successfull successful successully successfully succsess success succsessfull successful suceed succeed suceeded succeeded suceeding succeeding suceeds succeeds sucesful successful sucesfully successfully sucesfuly successfully sucesion succession sucess success sucesses successes sucessful successful sucessfull successful sucessfully successfully sucessfuly successfully sucession succession sucessive successive sucessor successor sucessot successor sucide suicide sucidial suicidal sufferage suffrage sufferred suffered sufferring suffering sufficent sufficient sufficently sufficiently sumary summary sunglases sunglasses suop soup superceeded superseded superintendant superintendent suphisticated sophisticated suplimented supplemented supose suppose suposed supposed suposedly supposedly suposes supposes suposing supposing supplamented supplemented suppliementing supplementing suppoed supposed supposingly supposedly suppy supply supress suppress supressed suppressed supresses suppresses supressing suppressing suprise surprise suprised surprised suprising surprising suprisingly surprisingly suprize surprise suprized surprised suprizing surprising suprizingly surprisingly surfce surface surley surly, surely suround surround surounded surrounded surounding surrounding suroundings surroundings surounds surrounds surplanted supplanted surpress suppress surpressed suppressed surprize surprise surprized surprised surprizing surprising surprizingly surprisingly surrended surrounded, surrendered surrepetitious surreptitious surrepetitiously surreptitiously surreptious surreptitious surreptiously surreptitiously surronded surrounded surrouded surrounded surrouding surrounding surrundering surrendering surveilence surveillance surveill surveil surveyer surveyor surviver survivor survivers survivors survivied survived suseptable susceptible suseptible susceptible suspention suspension swaer swear swaers swears swepth swept swiming swimming syas says symetrical symmetrical symetrically symmetrically symetry symmetry symettric symmetric symmetral symmetric symmetricaly symmetrically synagouge synagogue syncronization synchronization synonomous synonymous synonymns synonyms synphony symphony syphyllis syphilis sypmtoms symptoms syrap syrup sysmatically systematically sytem system sytle style tabacco tobacco tahn than taht that talekd talked targetted targeted targetting targeting tast taste tath that tattooes tattoos taxanomic taxonomic taxanomy taxonomy teached taught techician technician techicians technicians techiniques techniques technitian technician technnology technology technolgy technology teh the tehy they telelevision television televsion television telphony telephony temerature temperature temparate temperate temperarily temporarily temperment temperament tempertaure temperature temperture temperature temprary temporary tenacle tentacle tenacles tentacles tendacy tendency tendancies tendencies tendancy tendency tennisplayer tennis player tepmorarily temporarily terrestial terrestrial terriories territories terriory territory territorist terrorist territoy territory terroist terrorist testiclular testicular tghe the thast that, that's theather theater, theatre theese these theif thief theives thieves themselfs themselves themslves themselves ther there, their, the therafter thereafter therby thereby theri their thgat that thge the thier their thign thing thigns things thigsn things thikn think thikning thinking, thickening thikns thinks thiunk think thn then thna than thne then thnig thing thnigs things thoughout throughout threatend threatened threatning threatening threee three threshhold threshold thrid third throrough thorough throughly thoroughly throught thought, through, throughout througout throughout thru through thsi this thsoe those thta that thyat that tiem time, Tim tihkn think tihs this timne time tiome time, tome tje the tjhe the tjpanishad upanishad tkae take tkaes takes tkaing taking tlaking talking tobbaco tobacco todays today's todya today toghether together tolerence tolerance Tolkein Tolkien tomatos tomatoes tommorow tomorrow tommorrow tomorrow tongiht tonight toriodal toroidal tormenters tormentors torpeados torpedoes torpedos torpedoes tothe to the toubles troubles tounge tongue tourch torch, touch towords towards towrad toward tradionally traditionally traditionaly traditionally traditionnal traditional traditition tradition tradtionally traditionally trafficed trafficked trafficing trafficking trafic traffic trancendent transcendent trancending transcending tranform transform tranformed transformed transcendance transcendence transcendant transcendent transcendentational transcendental transcripting transcribing, transcription transending transcending transesxuals transsexuals transfered transferred transfering transferring transformaton transformation transistion transition translater translator translaters translators transmissable transmissible transporation transportation tremelo tremolo tremelos tremolos triguered triggered triology trilogy troling trolling troup troupe troups troupes, troops truely truly trustworthyness trustworthiness turnk turnkey, trunk Tuscon Tucson tust trust twelth twelfth twon town twpo two tyhat that tyhe they typcial typical typicaly typically tyranies tyrannies tyrany tyranny tyrranies tyrannies tyrrany tyranny ubiquitious ubiquitous uise use Ukranian Ukrainian ultimely ultimately unacompanied unaccompanied unahppy unhappy unanymous unanimous unathorised unauthorised unavailible unavailable unballance unbalance unbeleivable unbelievable uncertainity uncertainty unchallengable unchallengeable unchangable unchangeable uncompetive uncompetitive unconcious unconscious unconciousness unconsciousness unconfortability discomfort uncontitutional unconstitutional unconvential unconventional undecideable undecidable understoon understood undesireable undesirable undetecable undetectable undoubtely undoubtedly undreground underground uneccesary unnecessary unecessary unnecessary unequalities inequalities unforetunately unfortunately unforgetable unforgettable unforgiveable unforgivable unfortunatley unfortunately unfortunatly unfortunately unfourtunately unfortunately unihabited uninhabited unilateraly unilaterally unilatreal unilateral unilatreally unilaterally uninterruped uninterrupted uninterupted uninterrupted UnitesStates UnitedStates univeral universal univeristies universities univeristy university universtiy university univesities universities univesity university unkown unknown unlikey unlikely unmanouverable unmaneuverable, unmanoeuvrable unmistakeably unmistakably unneccesarily unnecessarily unneccesary unnecessary unneccessarily unnecessarily unneccessary unnecessary unnecesarily unnecessarily unnecesary unnecessary unoffical unofficial unoperational nonoperational unoticeable unnoticeable unplease displease unplesant unpleasant unprecendented unprecedented unprecidented unprecedented unrepentent unrepentant unrepetant unrepentant unrepetent unrepentant unsed used, unused, unsaid unsubstanciated unsubstantiated unsuccesful unsuccessful unsuccesfully unsuccessfully unsuccessfull unsuccessful unsucesful unsuccessful unsucesfuly unsuccessfully unsucessful unsuccessful unsucessfull unsuccessful unsucessfully unsuccessfully unsuprised unsurprised unsuprising unsurprising unsuprisingly unsurprisingly unsuprized unsurprised unsuprizing unsurprising unsuprizingly unsurprisingly unsurprized unsurprised unsurprizing unsurprising unsurprizingly unsurprisingly untill until untranslateable untranslatable unuseable unusable unusuable unusable unviersity university unwarrented unwarranted unweildly unwieldy unwieldly unwieldy upcomming upcoming upgradded upgraded usally usually useage usage usefull useful usefuly usefully useing using usualy usually ususally usually vaccum vacuum vaccume vacuum vacinity vicinity vaguaries vagaries vaieties varieties vailidty validity valetta valletta valuble valuable valueable valuable varations variations varient variant variey variety varing varying varities varieties varity variety vasall vassal vasalls vassals vegatarian vegetarian vegitable vegetable vegitables vegetables vegtable vegetable vehicule vehicle vell well venemous venomous vengance vengeance vengence vengeance verfication verification verison version verisons versions vermillion vermilion versitilaty versatility versitlity versatility vetween between veyr very vigeur vigueur, vigour, vigor vigilence vigilance vigourous vigorous villian villain villification vilification villify vilify villin villi, villain, villein vincinity vicinity violentce violence virutal virtual virtualy virtually virutally virtually visable visible visably visibly visting visiting vistors visitors vitories victories volcanoe volcano voleyball volleyball volontary voluntary volonteer volunteer volonteered volunteered volonteering volunteering volonteers volunteers volounteer volunteer volounteered volunteered volounteering volunteering volounteers volunteers vreity variety vrey very vriety variety vulnerablility vulnerability vyer very vyre very waht what wanna want to warantee warranty wardobe wardrobe warrent warrant warrriors warriors wasnt wasn't wass was watn want wayword wayward weaponary weaponry weas was wehn when weild wield, wild weilded wielded wendsay Wednesday wensday Wednesday wereabouts whereabouts whant want whants wants whcih which wheras whereas wherease whereas whereever wherever whic which whihc which whith with whlch which whn when wholey wholly wholy wholly, holy whta what whther whether wich which, witch widesread widespread wief wife wierd weird wiew view wih with wiht with wille will willingless willingness wirting writing withdrawl withdrawal, withdraw witheld withheld withing within withold withhold witht with witn with wiull will wnat want wnated wanted wnats wants wohle whole wokr work wokring working wonderfull wonderful workststion workstation worls world wordlwide worldwide worshipper worshiper worshipping worshiping worstened worsened woudl would wresters wrestlers wriet write writen written wroet wrote wrok work wroking working ws was wtih with wupport support xenophoby xenophobia yaching yachting yatch yacht yeasr years yeild yield yeilding yielding Yementite Yemenite, Yemeni yearm year yera year yeras years yersa years youseff yousef youself yourself ytou you yuo you joo you zeebra zebra [[Category:Wikipedia tools]] hunspell-1.7.0/tests/suggestiontest/Makefile.am000066400000000000000000000001311337236234000216340ustar00rootroot00000000000000EXTRA_DIST= \ List_of_common_misspellings.txt \ Makefile.orig \ prepare \ README \ test hunspell-1.7.0/tests/suggestiontest/Makefile.orig000066400000000000000000000001231337236234000222000ustar00rootroot00000000000000all: ./prepare ./test single: ./prepare2 ./test clean: rm *.[1-5] result.* hunspell-1.7.0/tests/suggestiontest/README000066400000000000000000000006671337236234000204760ustar00rootroot00000000000000source of text data: Wikipedia http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines For testing Hunspell you need the extended en_US dictionary with phonetic table: http://hunspell.sourceforge.net/en_US.zip test: make -f Makefile.orig test only with Hunspell: make -f Makefile.orig single test with different input file and dictionaries: INPUT=dutchlist.txt HUNSPELL=nl_NL ASPELL=nl make -f Makefile.orig hunspell-1.7.0/tests/suggestiontest/prepare000077500000000000000000000024121337236234000211700ustar00rootroot00000000000000#!/bin/bash # Check common misspellings # input file format: # word->word1, ... # Source: http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines hunspell=../../src/tools/hunspell hlang=${HUNSPELL:-en_US} alang=${ASPELL:-en_US} input=${INPUT:-List_of_common_misspellings.txt} # remove bad words recognised by Hunspell as good cat $input | sed 's/[-]>/ /' | $hunspell -d $hlang -1 -L | # remove items with dash for Aspell grep '^[^-]* ' | # remove spaces from end of lines sed 's/ *$//' >$input.1 # remove bad words recognised by Aspell as good cut -f 1 -d ' ' $input.1 | aspell -l $alang --list | awk 'FILENAME=="-"{a[$1]=1;next}a[$1]{print$0}' - $input.1 | # change commas with tabs sed 's/, */ /g' >$input.2 # remove lines with unrecognised suggestions (except suggestion with spaces) cut -d ' ' -f 2- $input.2 | tr "\t" "\n" | grep -v ' ' >x.1 cat x.1 | $hunspell -l -d $hlang >x.2 cat x.1 | aspell -l $alang --list >>x.2 cat x.2 | awk 'BEGIN{FS="\t"} FILENAME=="-"{a[$1]=1;next}a[$2]!=1 && a[$3]!=1{print $0}' - $input.2 >$input.3 cut -f 1 -d ' ' $input.3 | aspell -l $alang -a | grep -v ^$ | sed -n '2,$p' | sed 's/^.*: //;s/, / /g' >$input.4 cat $input.3 | $hunspell -d $hlang -a -1 | grep -v ^$ | sed -n '2,$p' | sed 's/^.*: //;s/, / /g' >$input.5 hunspell-1.7.0/tests/suggestiontest/prepare2000077500000000000000000000016601337236234000212560ustar00rootroot00000000000000#!/bin/bash # Check common misspellings # input file format: # word->word1, ... # Source: http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines hunspell=../../src/tools/hunspell hlang=${HUNSPELL:-en_US} input=${INPUT:-List_of_common_misspellings.txt} # remove bad words recognised by Hunspell as good cat $input | sed 's/[-]>/ /' | $hunspell -d $hlang -1 -L | # remove spaces from end of lines sed 's/ *$//' >$input.1 # change commas with tabs cat $input.1 | sed 's/, */ /g' >$input.2 # remove lines with unrecognised suggestions (except suggestion with spaces) cut -d ' ' -f 2- $input.2 | tr "\t" "\n" | grep -v ' ' >x.1 cat x.1 | $hunspell -l -d $hlang >x.2 cat x.2 | awk 'BEGIN{FS="\t"} FILENAME=="-"{a[$1]=1;next}a[$2]!=1 && a[$3]!=1{print $0}' - $input.2 >$input.3 test -f $input.4 && rm $input.4 cat $input.3 | $hunspell -d $hlang -a -1 | grep -v ^$ | sed -n '2,$p' | sed 's/^.*: //;s/, / /g' >$input.5 hunspell-1.7.0/tests/suggestiontest/test000077500000000000000000000016541337236234000205200ustar00rootroot00000000000000#!/bin/bash # Check common misspellings # input file format: # word->word1, ... # Source: http://en.wikipedia.org/wiki/Wikipedia:Lists_of_common_misspellings/For_machines input=${INPUT:-List_of_common_misspellings.txt} function check() { cat $1 | awk 'BEGIN{maxord=0;FS="\t"}FILENAME=="-"{for (i=1; i<=NF; i++){a[NR,$(i)]=i};max=NR;next}{x1=a[NR-max,$2];x2=a[NR-max,$3];sug++;if($3)sug++;if (!x1&&!x2){mis2++;misrow=misrow"\n"$0};if(!x1||($3 && !x2))mis++;ord+=x1+x2;}END{ print "Missed rows", misrow; print "=======================================" print maxord, "max. suggestion for a word"; print max, "input rows"; print mis2, "missing rows"; print sug, "expected suggestions"; print mis, "missing suggestions"; print ord/(sug-mis), "average ranking"; }' - $2 } test -f $input.4 && check $input.4 $input.3 >result.aspell check $input.5 $input.3 >result.hunspell test -f result.aspell && tail -6 result.aspell tail -6 result.hunspell hunspell-1.7.0/tests/sugutf.aff000066400000000000000000000006351337236234000165150ustar00rootroot00000000000000# new suggestion methods of Hunspell 1.5: # capitalization: nasa -> NASA # long swap: permenant -> permanent # long mov: Ghandi -> Gandhi # double two characters: vacacation -> vacation # space with REP: "alot" -> "a lot" ("a lot" need to be in the dic file.) SET UTF-8 # switch off ngram suggestion for testing MAXNGRAMSUGS 0 REP 1 REP alot a_lot KEY qwertzuiop|asdfghjkl|yxcvbnm|aq WORDCHARS . FORBIDDENWORD ? hunspell-1.7.0/tests/sugutf.dic000066400000000000000000000001051337236234000165100ustar00rootroot0000000000000010 NASA Gandhi grateful permanent vacation a lot have which McDonald hunspell-1.7.0/tests/sugutf.sug000066400000000000000000000001541337236234000165530ustar00rootroot00000000000000NASA Gandhi grateful permanent vacation a lot, lot permanent. Vacation have which Gandhi McDonald permanent hunspell-1.7.0/tests/sugutf.wrong000066400000000000000000000001471337236234000171130ustar00rootroot00000000000000nasa Ghandi greatful permenant vacacation alot permanent.Vacation ahev hwihc GAndhi Mcdonald permqnent hunspell-1.7.0/tests/test.sh000077500000000000000000000132351337236234000160400ustar00rootroot00000000000000#!/bin/bash # ##### BEGIN LICENSE BLOCK ##### # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # Copyright (C) 2002-2017 Németh László # # 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. # # Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks. # # 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 ##### # set -x # uncomment for debugging set -o pipefail export LC_ALL="C" function check_valgrind_log () { if [[ "$VALGRIND" != "" && -f $TEMPDIR/test.pid* ]]; then log=$(ls $TEMPDIR/test.pid*) if ! grep -q 'ERROR SUMMARY: 0 error' $log; then echo "Fail in $NAME $1 checking detected by Valgrind" echo "$log Valgrind log file moved to $TEMPDIR/badlogs" mv $log $TEMPDIR/badlogs exit 1 fi if grep -q 'LEAK SUMMARY' $log; then echo "Memory leak in $NAME $1 checking detected by Valgrind" echo "$log Valgrind log file moved to $TEMPDIR/badlogs" mv $log $TEMPDIR/badlogs exit 1 fi rm -f $log fi } TEMPDIR=./testSubDir NAME="${1%.dic}" shift ENCODING=UTF-8 #io encoding passed with -i if [[ "$1" == "-i" && -n "$2" ]]; then ENCODING="$2" shift 2 fi shopt -s expand_aliases [[ "$HUNSPELL" = "" ]] && HUNSPELL="$(dirname $0)"/../src/tools/hunspell [[ "$ANALYZE" = "" ]] && ANALYZE="$(dirname $0)"/../src/tools/analyze [[ "$LIBTOOL" = "" ]] && LIBTOOL="$(dirname $0)"/../libtool alias hunspell='"$LIBTOOL" --mode=execute "$HUNSPELL"' alias analyze='"$LIBTOOL" --mode=execute "$ANALYZE"' if [[ "$VALGRIND" != "" ]]; then mkdir $TEMPDIR 2> /dev/null || : rm -f $TEMPDIR/test.pid* || : mkdir $TEMPDIR/badlogs 2> /dev/null || : alias hunspell='"$LIBTOOL" --mode=execute valgrind --tool=$VALGRIND --leak-check=yes --show-reachable=yes --log-file=$TEMPDIR/test.pid "$HUNSPELL"' alias analyze='"$LIBTOOL" --mode=execute valgrind --tool=$VALGRIND --leak-check=yes --show-reachable=yes --log-file=$TEMPDIR/test.pid "$ANALYZE"' fi CR=$(printf "\r") in_dict="$NAME" if [[ ! -f "$in_dict.dic" ]]; then echo "Dictionary $in_dict.dic does not exists" exit 3 fi # Tests good words in_file="$in_dict.good" if [[ -f $in_file ]]; then out=$(hunspell -l -i "$ENCODING" "$@" -d "$in_dict" < "$in_file" \ | tr -d "$CR") if [[ $? -ne 0 ]]; then exit 2; fi if [[ "$out" != "" ]]; then echo "=============================================" echo "Fail in $NAME.good. Good words recognised as wrong:" echo "$out" exit 1 fi fi check_valgrind_log "good words" # Tests bad words in_file="$in_dict.wrong" if [[ -f $in_file ]]; then out=$(hunspell -G -i "$ENCODING" "$@" -d "$in_dict" < "$in_file" \ | tr -d "$CR") #strip carriage return for mingw builds if [[ $? -ne 0 ]]; then exit 2; fi if [[ "$out" != "" ]]; then echo "=============================================" echo "Fail in $NAME.wrong. Bad words recognised as good:" echo "$out" exit 1 fi fi check_valgrind_log "bad words" # Tests good words' root in_file="$in_dict.good" expected_file="$in_dict.root" if [[ -f $expected_file ]]; then # Extract the root words of the affixed words, after '+' out=$(hunspell -d "$in_dict" < "$in_file" | grep -a '^+ ' \ | sed 's/^+ //') if [[ $? -ne 0 ]]; then exit 2; fi expected=$(<"$expected_file") if [[ "$out" != "$expected" ]]; then echo "=============================================" echo "Fail in $NAME.root. Bad analysis?" diff "$expected_file" <(echo "$out") | grep '^<' | sed 's/^..//' exit 1 fi fi check_valgrind_log "root" # Tests morphological analysis in_file="$in_dict.good" expected_file="$in_dict.morph" if [[ -f $expected_file ]]; then #in=$(sed 's/ $//' "$in_file") #passes without this. out=$(analyze "$in_dict.aff" "$in_dict.dic" "$in_file" \ | tr -d "$CR") #strip carige return for mingw builds if [[ $? -ne 0 ]]; then exit 2; fi expected=$(<"$expected_file") if [[ "$out" != "$expected" ]]; then echo "=============================================" echo "Fail in $NAME.morph. Bad analysis?" diff "$expected_file" <(echo "$out") | grep '^<' | sed 's/^..//' exit 1 fi fi check_valgrind_log "morphological analysis" # Tests suggestions in_file=$in_dict.wrong expected_file=$in_dict.sug if [[ -f $expected_file ]]; then out=$(hunspell -i "$ENCODING" "$@" -a -d "$in_dict" <"$in_file" | \ { grep -a '^&' || true; } | sed 's/^[^:]*: //') if [[ $? -ne 0 ]]; then exit 2; fi expected=$(<"$expected_file") if [[ "$out" != "$expected" ]]; then echo "=============================================" echo "Fail in $NAME.sug. Bad suggestion?" diff "$expected_file" <(echo "$out") exit 1 fi fi check_valgrind_log "suggestion" hunspell-1.7.0/tests/timelimit.aff000066400000000000000000000000521337236234000171660ustar00rootroot00000000000000WORDCHARS 01 COMPOUNDMIN 1 COMPOUNDFLAG Y hunspell-1.7.0/tests/timelimit.dic000066400000000000000000000000251337236234000171710ustar00rootroot000000000000004 0/Y 00/Y 000/Y 1/Y hunspell-1.7.0/tests/timelimit.good000066400000000000000000000000271337236234000173640ustar00rootroot000000000000001000000000000000000000 hunspell-1.7.0/tests/timelimit.wrong000066400000000000000000000000301337236234000175620ustar00rootroot000000000000001000000000000000000000x hunspell-1.7.0/tests/utf8.aff000066400000000000000000000002011337236234000160530ustar00rootroot00000000000000SET UTF-8 SFX A Y 7 SFX A 0 őő . SFX A 0 ő o SFX A 0 ő ó SFX A ó ő ó SFX A ó őoo ó SFX A o őo o SFX A 0 ó [abcdó] hunspell-1.7.0/tests/utf8.dic000066400000000000000000000000171337236234000160630ustar00rootroot000000000000002 foo/A foó/A hunspell-1.7.0/tests/utf8.good000066400000000000000000000000671337236234000162610ustar00rootroot00000000000000foo foó fooőő fooő foóő foő foőo foőoo foóó hunspell-1.7.0/tests/utf8_bom.aff000066400000000000000000000000711337236234000167150ustar00rootroot00000000000000SET UTF-8 # removing byte order mark from affix file hunspell-1.7.0/tests/utf8_bom.dic000066400000000000000000000000141337236234000167150ustar00rootroot000000000000001 apéritif hunspell-1.7.0/tests/utf8_bom.good000066400000000000000000000000261337236234000171110ustar00rootroot00000000000000apéritif APÉRITIF hunspell-1.7.0/tests/utf8_bom2.aff000066400000000000000000000000641337236234000170010ustar00rootroot00000000000000SET UTF-8 # removing byte order mark from dic file hunspell-1.7.0/tests/utf8_bom2.dic000066400000000000000000000000171337236234000170020ustar00rootroot000000000000001 apéritif hunspell-1.7.0/tests/utf8_bom2.good000066400000000000000000000000261337236234000171730ustar00rootroot00000000000000apéritif APÉRITIF hunspell-1.7.0/tests/utf8_nonbmp.aff000066400000000000000000000000121337236234000174240ustar00rootroot00000000000000SET UTF-8 hunspell-1.7.0/tests/utf8_nonbmp.dic000066400000000000000000000001151337236234000174330ustar00rootroot000000000000004 # Old Persian numbers (1-4), source: Wikipedia 𐏑 𐏒 𐏒𐏑 𐏒𐏒 hunspell-1.7.0/tests/utf8_nonbmp.good000066400000000000000000000000411337236234000176220ustar00rootroot00000000000000𐏑 𐏒 𐏒𐏑 𐏒𐏒 hunspell-1.7.0/tests/utf8_nonbmp.sug000066400000000000000000000000461337236234000174750ustar00rootroot00000000000000𐏒𐏑, 𐏒𐏒 𐏒𐏑, 𐏒𐏒 hunspell-1.7.0/tests/utf8_nonbmp.test000077500000000000000000000001221337236234000176540ustar00rootroot00000000000000#!/bin/sh DIR="`dirname $0`" NAME="${0%.test}" "$DIR"/test.sh "$NAME" -i utf-8 -1 hunspell-1.7.0/tests/utf8_nonbmp.wrong000066400000000000000000000000341337236234000200300ustar00rootroot00000000000000𐏑𐏒𐏒 𐏑𐏒𐏒 hunspell-1.7.0/tests/utfcompound.aff000066400000000000000000000000471337236234000175400ustar00rootroot00000000000000SET UTF-8 COMPOUNDMIN 3 COMPOUNDFLAG A hunspell-1.7.0/tests/utfcompound.dic000066400000000000000000000000661337236234000175440ustar00rootroot000000000000008 foo/A bar/A fóó/A áár/A xy/A yz/A éé/A őő/A hunspell-1.7.0/tests/utfcompound.good000066400000000000000000000000561337236234000177340ustar00rootroot00000000000000foobar barfoo foobarfoo fóóáár áárfóó hunspell-1.7.0/tests/utfcompound.wrong000066400000000000000000000000671337236234000201420ustar00rootroot00000000000000xyyz fooxy xyfoo fooxybar ééőő fóóéé őőáár hunspell-1.7.0/tests/warn.aff000066400000000000000000000003051337236234000161410ustar00rootroot00000000000000# WARN flag # The signed word, and its suffixed forms result warning message in command-line #Use to forbid the words with flag WARN #FORBIDWARN WARN W SFX A Y 1 SFX A 0 s . REP 1 REP foo bar hunspell-1.7.0/tests/warn.dic000066400000000000000000000000151337236234000161420ustar00rootroot000000000000001 foo/WA bar hunspell-1.7.0/tests/warn.good000066400000000000000000000000111337236234000163270ustar00rootroot00000000000000foo foos hunspell-1.7.0/tests/wordpair.aff000066400000000000000000000002021337236234000170150ustar00rootroot00000000000000# a dictionary word pair separated by space # will avoid its recognition without space # at compound word analysis COMPOUNDFLAG Y hunspell-1.7.0/tests/wordpair.dic000066400000000000000000000000421337236234000170220ustar00rootroot000000000000003 word/Y compound/Y compound word hunspell-1.7.0/tests/wordpair.good000066400000000000000000000000331337236234000172130ustar00rootroot00000000000000word compound wordcompound hunspell-1.7.0/tests/wordpair.wrong000066400000000000000000000000151337236234000174170ustar00rootroot00000000000000compoundword hunspell-1.7.0/tests/zeroaffix.aff000066400000000000000000000002251337236234000171700ustar00rootroot00000000000000PSEUDOROOT X COMPOUNDFLAG Y SFX A Y 1 SFX A 0 0 . > SFX B Y 1 SFX B 0 0 . > SFX C Y 2 SFX C 0 0/XAB . SFX C 0 baz/XAB . hunspell-1.7.0/tests/zeroaffix.dic000066400000000000000000000000341337236234000171710ustar00rootroot000000000000002 foo/XA bar analyze(bar) = st:bar > analyze(bar) = st:bar analyze(bar) = st:bar > analyze(bar) = st:bar > stem(bar) = bar > foo analyze(foo) = st:foo stem(foo) = foo > barbaz analyze(barbaz) = st:bar > analyze(barbaz) = st:bar > stem(barbaz) = bar